qemu/target/mips/tcg/translate.c
<<
>>
Prefs
   1/*
   2 *  MIPS emulation for QEMU - main translation routines
   3 *
   4 *  Copyright (c) 2004-2005 Jocelyn Mayer
   5 *  Copyright (c) 2006 Marius Groeger (FPU operations)
   6 *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
   7 *  Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
   8 *  Copyright (c) 2012 Jia Liu & Dongxue Zhang (MIPS ASE DSP support)
   9 *  Copyright (c) 2020 Philippe Mathieu-Daudé
  10 *
  11 * This library is free software; you can redistribute it and/or
  12 * modify it under the terms of the GNU Lesser General Public
  13 * License as published by the Free Software Foundation; either
  14 * version 2.1 of the License, or (at your option) any later version.
  15 *
  16 * This library is distributed in the hope that it will be useful,
  17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  19 * Lesser General Public License for more details.
  20 *
  21 * You should have received a copy of the GNU Lesser General Public
  22 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  23 */
  24
  25#include "qemu/osdep.h"
  26#include "cpu.h"
  27#include "internal.h"
  28#include "tcg/tcg-op.h"
  29#include "exec/translator.h"
  30#include "exec/helper-proto.h"
  31#include "exec/helper-gen.h"
  32#include "semihosting/semihost.h"
  33
  34#include "trace.h"
  35#include "exec/translator.h"
  36#include "exec/log.h"
  37#include "qemu/qemu-print.h"
  38#include "fpu_helper.h"
  39#include "translate.h"
  40
  41/*
  42 * Many sysemu-only helpers are not reachable for user-only.
  43 * Define stub generators here, so that we need not either sprinkle
  44 * ifdefs through the translator, nor provide the helper function.
  45 */
  46#define STUB_HELPER(NAME, ...) \
  47    static inline void gen_helper_##NAME(__VA_ARGS__) \
  48    { g_assert_not_reached(); }
  49
  50#ifdef CONFIG_USER_ONLY
  51STUB_HELPER(cache, TCGv_env env, TCGv val, TCGv_i32 reg)
  52#endif
  53
  54enum {
  55    /* indirect opcode tables */
  56    OPC_SPECIAL  = (0x00 << 26),
  57    OPC_REGIMM   = (0x01 << 26),
  58    OPC_CP0      = (0x10 << 26),
  59    OPC_CP2      = (0x12 << 26),
  60    OPC_CP3      = (0x13 << 26),
  61    OPC_SPECIAL2 = (0x1C << 26),
  62    OPC_SPECIAL3 = (0x1F << 26),
  63    /* arithmetic with immediate */
  64    OPC_ADDI     = (0x08 << 26),
  65    OPC_ADDIU    = (0x09 << 26),
  66    OPC_SLTI     = (0x0A << 26),
  67    OPC_SLTIU    = (0x0B << 26),
  68    /* logic with immediate */
  69    OPC_ANDI     = (0x0C << 26),
  70    OPC_ORI      = (0x0D << 26),
  71    OPC_XORI     = (0x0E << 26),
  72    OPC_LUI      = (0x0F << 26),
  73    /* arithmetic with immediate */
  74    OPC_DADDI    = (0x18 << 26),
  75    OPC_DADDIU   = (0x19 << 26),
  76    /* Jump and branches */
  77    OPC_J        = (0x02 << 26),
  78    OPC_JAL      = (0x03 << 26),
  79    OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
  80    OPC_BEQL     = (0x14 << 26),
  81    OPC_BNE      = (0x05 << 26),
  82    OPC_BNEL     = (0x15 << 26),
  83    OPC_BLEZ     = (0x06 << 26),
  84    OPC_BLEZL    = (0x16 << 26),
  85    OPC_BGTZ     = (0x07 << 26),
  86    OPC_BGTZL    = (0x17 << 26),
  87    OPC_JALX     = (0x1D << 26),
  88    OPC_DAUI     = (0x1D << 26),
  89    /* Load and stores */
  90    OPC_LDL      = (0x1A << 26),
  91    OPC_LDR      = (0x1B << 26),
  92    OPC_LB       = (0x20 << 26),
  93    OPC_LH       = (0x21 << 26),
  94    OPC_LWL      = (0x22 << 26),
  95    OPC_LW       = (0x23 << 26),
  96    OPC_LWPC     = OPC_LW | 0x5,
  97    OPC_LBU      = (0x24 << 26),
  98    OPC_LHU      = (0x25 << 26),
  99    OPC_LWR      = (0x26 << 26),
 100    OPC_LWU      = (0x27 << 26),
 101    OPC_SB       = (0x28 << 26),
 102    OPC_SH       = (0x29 << 26),
 103    OPC_SWL      = (0x2A << 26),
 104    OPC_SW       = (0x2B << 26),
 105    OPC_SDL      = (0x2C << 26),
 106    OPC_SDR      = (0x2D << 26),
 107    OPC_SWR      = (0x2E << 26),
 108    OPC_LL       = (0x30 << 26),
 109    OPC_LLD      = (0x34 << 26),
 110    OPC_LD       = (0x37 << 26),
 111    OPC_LDPC     = OPC_LD | 0x5,
 112    OPC_SC       = (0x38 << 26),
 113    OPC_SCD      = (0x3C << 26),
 114    OPC_SD       = (0x3F << 26),
 115    /* Floating point load/store */
 116    OPC_LWC1     = (0x31 << 26),
 117    OPC_LWC2     = (0x32 << 26),
 118    OPC_LDC1     = (0x35 << 26),
 119    OPC_LDC2     = (0x36 << 26),
 120    OPC_SWC1     = (0x39 << 26),
 121    OPC_SWC2     = (0x3A << 26),
 122    OPC_SDC1     = (0x3D << 26),
 123    OPC_SDC2     = (0x3E << 26),
 124    /* Compact Branches */
 125    OPC_BLEZALC  = (0x06 << 26),
 126    OPC_BGEZALC  = (0x06 << 26),
 127    OPC_BGEUC    = (0x06 << 26),
 128    OPC_BGTZALC  = (0x07 << 26),
 129    OPC_BLTZALC  = (0x07 << 26),
 130    OPC_BLTUC    = (0x07 << 26),
 131    OPC_BOVC     = (0x08 << 26),
 132    OPC_BEQZALC  = (0x08 << 26),
 133    OPC_BEQC     = (0x08 << 26),
 134    OPC_BLEZC    = (0x16 << 26),
 135    OPC_BGEZC    = (0x16 << 26),
 136    OPC_BGEC     = (0x16 << 26),
 137    OPC_BGTZC    = (0x17 << 26),
 138    OPC_BLTZC    = (0x17 << 26),
 139    OPC_BLTC     = (0x17 << 26),
 140    OPC_BNVC     = (0x18 << 26),
 141    OPC_BNEZALC  = (0x18 << 26),
 142    OPC_BNEC     = (0x18 << 26),
 143    OPC_BC       = (0x32 << 26),
 144    OPC_BEQZC    = (0x36 << 26),
 145    OPC_JIC      = (0x36 << 26),
 146    OPC_BALC     = (0x3A << 26),
 147    OPC_BNEZC    = (0x3E << 26),
 148    OPC_JIALC    = (0x3E << 26),
 149    /* MDMX ASE specific */
 150    OPC_MDMX     = (0x1E << 26),
 151    /* Cache and prefetch */
 152    OPC_CACHE    = (0x2F << 26),
 153    OPC_PREF     = (0x33 << 26),
 154    /* PC-relative address computation / loads */
 155    OPC_PCREL    = (0x3B << 26),
 156};
 157
 158/* PC-relative address computation / loads  */
 159#define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
 160#define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
 161enum {
 162    /* Instructions determined by bits 19 and 20 */
 163    OPC_ADDIUPC = OPC_PCREL | (0 << 19),
 164    R6_OPC_LWPC = OPC_PCREL | (1 << 19),
 165    OPC_LWUPC   = OPC_PCREL | (2 << 19),
 166
 167    /* Instructions determined by bits 16 ... 20 */
 168    OPC_AUIPC   = OPC_PCREL | (0x1e << 16),
 169    OPC_ALUIPC  = OPC_PCREL | (0x1f << 16),
 170
 171    /* Other */
 172    R6_OPC_LDPC = OPC_PCREL | (6 << 18),
 173};
 174
 175/* MIPS special opcodes */
 176#define MASK_SPECIAL(op)            (MASK_OP_MAJOR(op) | (op & 0x3F))
 177
 178enum {
 179    /* Shifts */
 180    OPC_SLL      = 0x00 | OPC_SPECIAL,
 181    /* NOP is SLL r0, r0, 0   */
 182    /* SSNOP is SLL r0, r0, 1 */
 183    /* EHB is SLL r0, r0, 3 */
 184    OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
 185    OPC_ROTR     = OPC_SRL | (1 << 21),
 186    OPC_SRA      = 0x03 | OPC_SPECIAL,
 187    OPC_SLLV     = 0x04 | OPC_SPECIAL,
 188    OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
 189    OPC_ROTRV    = OPC_SRLV | (1 << 6),
 190    OPC_SRAV     = 0x07 | OPC_SPECIAL,
 191    OPC_DSLLV    = 0x14 | OPC_SPECIAL,
 192    OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
 193    OPC_DROTRV   = OPC_DSRLV | (1 << 6),
 194    OPC_DSRAV    = 0x17 | OPC_SPECIAL,
 195    OPC_DSLL     = 0x38 | OPC_SPECIAL,
 196    OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
 197    OPC_DROTR    = OPC_DSRL | (1 << 21),
 198    OPC_DSRA     = 0x3B | OPC_SPECIAL,
 199    OPC_DSLL32   = 0x3C | OPC_SPECIAL,
 200    OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
 201    OPC_DROTR32  = OPC_DSRL32 | (1 << 21),
 202    OPC_DSRA32   = 0x3F | OPC_SPECIAL,
 203    /* Multiplication / division */
 204    OPC_MULT     = 0x18 | OPC_SPECIAL,
 205    OPC_MULTU    = 0x19 | OPC_SPECIAL,
 206    OPC_DIV      = 0x1A | OPC_SPECIAL,
 207    OPC_DIVU     = 0x1B | OPC_SPECIAL,
 208    OPC_DMULT    = 0x1C | OPC_SPECIAL,
 209    OPC_DMULTU   = 0x1D | OPC_SPECIAL,
 210    OPC_DDIV     = 0x1E | OPC_SPECIAL,
 211    OPC_DDIVU    = 0x1F | OPC_SPECIAL,
 212
 213    /* 2 registers arithmetic / logic */
 214    OPC_ADD      = 0x20 | OPC_SPECIAL,
 215    OPC_ADDU     = 0x21 | OPC_SPECIAL,
 216    OPC_SUB      = 0x22 | OPC_SPECIAL,
 217    OPC_SUBU     = 0x23 | OPC_SPECIAL,
 218    OPC_AND      = 0x24 | OPC_SPECIAL,
 219    OPC_OR       = 0x25 | OPC_SPECIAL,
 220    OPC_XOR      = 0x26 | OPC_SPECIAL,
 221    OPC_NOR      = 0x27 | OPC_SPECIAL,
 222    OPC_SLT      = 0x2A | OPC_SPECIAL,
 223    OPC_SLTU     = 0x2B | OPC_SPECIAL,
 224    OPC_DADD     = 0x2C | OPC_SPECIAL,
 225    OPC_DADDU    = 0x2D | OPC_SPECIAL,
 226    OPC_DSUB     = 0x2E | OPC_SPECIAL,
 227    OPC_DSUBU    = 0x2F | OPC_SPECIAL,
 228    /* Jumps */
 229    OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
 230    OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
 231    /* Traps */
 232    OPC_TGE      = 0x30 | OPC_SPECIAL,
 233    OPC_TGEU     = 0x31 | OPC_SPECIAL,
 234    OPC_TLT      = 0x32 | OPC_SPECIAL,
 235    OPC_TLTU     = 0x33 | OPC_SPECIAL,
 236    OPC_TEQ      = 0x34 | OPC_SPECIAL,
 237    OPC_TNE      = 0x36 | OPC_SPECIAL,
 238    /* HI / LO registers load & stores */
 239    OPC_MFHI     = 0x10 | OPC_SPECIAL,
 240    OPC_MTHI     = 0x11 | OPC_SPECIAL,
 241    OPC_MFLO     = 0x12 | OPC_SPECIAL,
 242    OPC_MTLO     = 0x13 | OPC_SPECIAL,
 243    /* Conditional moves */
 244    OPC_MOVZ     = 0x0A | OPC_SPECIAL,
 245    OPC_MOVN     = 0x0B | OPC_SPECIAL,
 246
 247    OPC_SELEQZ   = 0x35 | OPC_SPECIAL,
 248    OPC_SELNEZ   = 0x37 | OPC_SPECIAL,
 249
 250    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
 251
 252    /* Special */
 253    OPC_PMON     = 0x05 | OPC_SPECIAL, /* unofficial */
 254    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
 255    OPC_BREAK    = 0x0D | OPC_SPECIAL,
 256    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
 257    OPC_SYNC     = 0x0F | OPC_SPECIAL,
 258
 259    OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
 260    OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
 261    OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
 262    OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
 263};
 264
 265/*
 266 * R6 Multiply and Divide instructions have the same opcode
 267 * and function field as legacy OPC_MULT[U]/OPC_DIV[U]
 268 */
 269#define MASK_R6_MULDIV(op)          (MASK_SPECIAL(op) | (op & (0x7ff)))
 270
 271enum {
 272    R6_OPC_MUL   = OPC_MULT  | (2 << 6),
 273    R6_OPC_MUH   = OPC_MULT  | (3 << 6),
 274    R6_OPC_MULU  = OPC_MULTU | (2 << 6),
 275    R6_OPC_MUHU  = OPC_MULTU | (3 << 6),
 276    R6_OPC_DIV   = OPC_DIV   | (2 << 6),
 277    R6_OPC_MOD   = OPC_DIV   | (3 << 6),
 278    R6_OPC_DIVU  = OPC_DIVU  | (2 << 6),
 279    R6_OPC_MODU  = OPC_DIVU  | (3 << 6),
 280
 281    R6_OPC_DMUL   = OPC_DMULT  | (2 << 6),
 282    R6_OPC_DMUH   = OPC_DMULT  | (3 << 6),
 283    R6_OPC_DMULU  = OPC_DMULTU | (2 << 6),
 284    R6_OPC_DMUHU  = OPC_DMULTU | (3 << 6),
 285    R6_OPC_DDIV   = OPC_DDIV   | (2 << 6),
 286    R6_OPC_DMOD   = OPC_DDIV   | (3 << 6),
 287    R6_OPC_DDIVU  = OPC_DDIVU  | (2 << 6),
 288    R6_OPC_DMODU  = OPC_DDIVU  | (3 << 6),
 289
 290    R6_OPC_CLZ      = 0x10 | OPC_SPECIAL,
 291    R6_OPC_CLO      = 0x11 | OPC_SPECIAL,
 292    R6_OPC_DCLZ     = 0x12 | OPC_SPECIAL,
 293    R6_OPC_DCLO     = 0x13 | OPC_SPECIAL,
 294    R6_OPC_SDBBP    = 0x0e | OPC_SPECIAL,
 295};
 296
 297/* REGIMM (rt field) opcodes */
 298#define MASK_REGIMM(op)             (MASK_OP_MAJOR(op) | (op & (0x1F << 16)))
 299
 300enum {
 301    OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
 302    OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
 303    OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
 304    OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
 305    OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
 306    OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
 307    OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
 308    OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
 309    OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
 310    OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
 311    OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
 312    OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
 313    OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
 314    OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
 315    OPC_SIGRIE   = (0x17 << 16) | OPC_REGIMM,
 316    OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
 317
 318    OPC_DAHI     = (0x06 << 16) | OPC_REGIMM,
 319    OPC_DATI     = (0x1e << 16) | OPC_REGIMM,
 320};
 321
 322/* Special2 opcodes */
 323#define MASK_SPECIAL2(op)           (MASK_OP_MAJOR(op) | (op & 0x3F))
 324
 325enum {
 326    /* Multiply & xxx operations */
 327    OPC_MADD     = 0x00 | OPC_SPECIAL2,
 328    OPC_MADDU    = 0x01 | OPC_SPECIAL2,
 329    OPC_MUL      = 0x02 | OPC_SPECIAL2,
 330    OPC_MSUB     = 0x04 | OPC_SPECIAL2,
 331    OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
 332    /* Loongson 2F */
 333    OPC_MULT_G_2F   = 0x10 | OPC_SPECIAL2,
 334    OPC_DMULT_G_2F  = 0x11 | OPC_SPECIAL2,
 335    OPC_MULTU_G_2F  = 0x12 | OPC_SPECIAL2,
 336    OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
 337    OPC_DIV_G_2F    = 0x14 | OPC_SPECIAL2,
 338    OPC_DDIV_G_2F   = 0x15 | OPC_SPECIAL2,
 339    OPC_DIVU_G_2F   = 0x16 | OPC_SPECIAL2,
 340    OPC_DDIVU_G_2F  = 0x17 | OPC_SPECIAL2,
 341    OPC_MOD_G_2F    = 0x1c | OPC_SPECIAL2,
 342    OPC_DMOD_G_2F   = 0x1d | OPC_SPECIAL2,
 343    OPC_MODU_G_2F   = 0x1e | OPC_SPECIAL2,
 344    OPC_DMODU_G_2F  = 0x1f | OPC_SPECIAL2,
 345    /* Misc */
 346    OPC_CLZ      = 0x20 | OPC_SPECIAL2,
 347    OPC_CLO      = 0x21 | OPC_SPECIAL2,
 348    OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
 349    OPC_DCLO     = 0x25 | OPC_SPECIAL2,
 350    /* Special */
 351    OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
 352};
 353
 354/* Special3 opcodes */
 355#define MASK_SPECIAL3(op)           (MASK_OP_MAJOR(op) | (op & 0x3F))
 356
 357enum {
 358    OPC_EXT      = 0x00 | OPC_SPECIAL3,
 359    OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
 360    OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
 361    OPC_DEXT     = 0x03 | OPC_SPECIAL3,
 362    OPC_INS      = 0x04 | OPC_SPECIAL3,
 363    OPC_DINSM    = 0x05 | OPC_SPECIAL3,
 364    OPC_DINSU    = 0x06 | OPC_SPECIAL3,
 365    OPC_DINS     = 0x07 | OPC_SPECIAL3,
 366    OPC_FORK     = 0x08 | OPC_SPECIAL3,
 367    OPC_YIELD    = 0x09 | OPC_SPECIAL3,
 368    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
 369    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
 370    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
 371    OPC_GINV     = 0x3D | OPC_SPECIAL3,
 372
 373    /* Loongson 2E */
 374    OPC_MULT_G_2E   = 0x18 | OPC_SPECIAL3,
 375    OPC_MULTU_G_2E  = 0x19 | OPC_SPECIAL3,
 376    OPC_DIV_G_2E    = 0x1A | OPC_SPECIAL3,
 377    OPC_DIVU_G_2E   = 0x1B | OPC_SPECIAL3,
 378    OPC_DMULT_G_2E  = 0x1C | OPC_SPECIAL3,
 379    OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
 380    OPC_DDIV_G_2E   = 0x1E | OPC_SPECIAL3,
 381    OPC_DDIVU_G_2E  = 0x1F | OPC_SPECIAL3,
 382    OPC_MOD_G_2E    = 0x22 | OPC_SPECIAL3,
 383    OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
 384    OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
 385    OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
 386
 387    /* MIPS DSP Load */
 388    OPC_LX_DSP         = 0x0A | OPC_SPECIAL3,
 389    /* MIPS DSP Arithmetic */
 390    OPC_ADDU_QB_DSP    = 0x10 | OPC_SPECIAL3,
 391    OPC_ADDU_OB_DSP    = 0x14 | OPC_SPECIAL3,
 392    OPC_ABSQ_S_PH_DSP  = 0x12 | OPC_SPECIAL3,
 393    OPC_ABSQ_S_QH_DSP  = 0x16 | OPC_SPECIAL3,
 394    /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E.  */
 395    /* OPC_ADDUH_QB_DSP   = 0x18 | OPC_SPECIAL3,  */
 396    OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
 397    OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
 398    /* MIPS DSP GPR-Based Shift Sub-class */
 399    OPC_SHLL_QB_DSP    = 0x13 | OPC_SPECIAL3,
 400    OPC_SHLL_OB_DSP    = 0x17 | OPC_SPECIAL3,
 401    /* MIPS DSP Multiply Sub-class insns */
 402    /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP.  */
 403    /* OPC_MUL_PH_DSP     = 0x18 | OPC_SPECIAL3,  */
 404    OPC_DPA_W_PH_DSP   = 0x30 | OPC_SPECIAL3,
 405    OPC_DPAQ_W_QH_DSP  = 0x34 | OPC_SPECIAL3,
 406    /* DSP Bit/Manipulation Sub-class */
 407    OPC_INSV_DSP       = 0x0C | OPC_SPECIAL3,
 408    OPC_DINSV_DSP      = 0x0D | OPC_SPECIAL3,
 409    /* MIPS DSP Append Sub-class */
 410    OPC_APPEND_DSP     = 0x31 | OPC_SPECIAL3,
 411    OPC_DAPPEND_DSP    = 0x35 | OPC_SPECIAL3,
 412    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 413    OPC_EXTR_W_DSP     = 0x38 | OPC_SPECIAL3,
 414    OPC_DEXTR_W_DSP    = 0x3C | OPC_SPECIAL3,
 415
 416    /* EVA */
 417    OPC_LWLE           = 0x19 | OPC_SPECIAL3,
 418    OPC_LWRE           = 0x1A | OPC_SPECIAL3,
 419    OPC_CACHEE         = 0x1B | OPC_SPECIAL3,
 420    OPC_SBE            = 0x1C | OPC_SPECIAL3,
 421    OPC_SHE            = 0x1D | OPC_SPECIAL3,
 422    OPC_SCE            = 0x1E | OPC_SPECIAL3,
 423    OPC_SWE            = 0x1F | OPC_SPECIAL3,
 424    OPC_SWLE           = 0x21 | OPC_SPECIAL3,
 425    OPC_SWRE           = 0x22 | OPC_SPECIAL3,
 426    OPC_PREFE          = 0x23 | OPC_SPECIAL3,
 427    OPC_LBUE           = 0x28 | OPC_SPECIAL3,
 428    OPC_LHUE           = 0x29 | OPC_SPECIAL3,
 429    OPC_LBE            = 0x2C | OPC_SPECIAL3,
 430    OPC_LHE            = 0x2D | OPC_SPECIAL3,
 431    OPC_LLE            = 0x2E | OPC_SPECIAL3,
 432    OPC_LWE            = 0x2F | OPC_SPECIAL3,
 433
 434    /* R6 */
 435    R6_OPC_PREF        = 0x35 | OPC_SPECIAL3,
 436    R6_OPC_CACHE       = 0x25 | OPC_SPECIAL3,
 437    R6_OPC_LL          = 0x36 | OPC_SPECIAL3,
 438    R6_OPC_SC          = 0x26 | OPC_SPECIAL3,
 439    R6_OPC_LLD         = 0x37 | OPC_SPECIAL3,
 440    R6_OPC_SCD         = 0x27 | OPC_SPECIAL3,
 441};
 442
 443/* Loongson EXT load/store quad word opcodes */
 444#define MASK_LOONGSON_GSLSQ(op)           (MASK_OP_MAJOR(op) | (op & 0x8020))
 445enum {
 446    OPC_GSLQ        = 0x0020 | OPC_LWC2,
 447    OPC_GSLQC1      = 0x8020 | OPC_LWC2,
 448    OPC_GSSHFL      = OPC_LWC2,
 449    OPC_GSSQ        = 0x0020 | OPC_SWC2,
 450    OPC_GSSQC1      = 0x8020 | OPC_SWC2,
 451    OPC_GSSHFS      = OPC_SWC2,
 452};
 453
 454/* Loongson EXT shifted load/store opcodes */
 455#define MASK_LOONGSON_GSSHFLS(op)         (MASK_OP_MAJOR(op) | (op & 0xc03f))
 456enum {
 457    OPC_GSLWLC1     = 0x4 | OPC_GSSHFL,
 458    OPC_GSLWRC1     = 0x5 | OPC_GSSHFL,
 459    OPC_GSLDLC1     = 0x6 | OPC_GSSHFL,
 460    OPC_GSLDRC1     = 0x7 | OPC_GSSHFL,
 461    OPC_GSSWLC1     = 0x4 | OPC_GSSHFS,
 462    OPC_GSSWRC1     = 0x5 | OPC_GSSHFS,
 463    OPC_GSSDLC1     = 0x6 | OPC_GSSHFS,
 464    OPC_GSSDRC1     = 0x7 | OPC_GSSHFS,
 465};
 466
 467/* Loongson EXT LDC2/SDC2 opcodes */
 468#define MASK_LOONGSON_LSDC2(op)           (MASK_OP_MAJOR(op) | (op & 0x7))
 469
 470enum {
 471    OPC_GSLBX      = 0x0 | OPC_LDC2,
 472    OPC_GSLHX      = 0x1 | OPC_LDC2,
 473    OPC_GSLWX      = 0x2 | OPC_LDC2,
 474    OPC_GSLDX      = 0x3 | OPC_LDC2,
 475    OPC_GSLWXC1    = 0x6 | OPC_LDC2,
 476    OPC_GSLDXC1    = 0x7 | OPC_LDC2,
 477    OPC_GSSBX      = 0x0 | OPC_SDC2,
 478    OPC_GSSHX      = 0x1 | OPC_SDC2,
 479    OPC_GSSWX      = 0x2 | OPC_SDC2,
 480    OPC_GSSDX      = 0x3 | OPC_SDC2,
 481    OPC_GSSWXC1    = 0x6 | OPC_SDC2,
 482    OPC_GSSDXC1    = 0x7 | OPC_SDC2,
 483};
 484
 485/* BSHFL opcodes */
 486#define MASK_BSHFL(op)              (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 487
 488enum {
 489    OPC_WSBH      = (0x02 << 6) | OPC_BSHFL,
 490    OPC_SEB       = (0x10 << 6) | OPC_BSHFL,
 491    OPC_SEH       = (0x18 << 6) | OPC_BSHFL,
 492    OPC_ALIGN     = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */
 493    OPC_ALIGN_1   = (0x09 << 6) | OPC_BSHFL,
 494    OPC_ALIGN_2   = (0x0A << 6) | OPC_BSHFL,
 495    OPC_ALIGN_3   = (0x0B << 6) | OPC_BSHFL,
 496    OPC_BITSWAP   = (0x00 << 6) | OPC_BSHFL  /* 00000 */
 497};
 498
 499/* DBSHFL opcodes */
 500#define MASK_DBSHFL(op)             (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 501
 502enum {
 503    OPC_DSBH       = (0x02 << 6) | OPC_DBSHFL,
 504    OPC_DSHD       = (0x05 << 6) | OPC_DBSHFL,
 505    OPC_DALIGN     = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */
 506    OPC_DALIGN_1   = (0x09 << 6) | OPC_DBSHFL,
 507    OPC_DALIGN_2   = (0x0A << 6) | OPC_DBSHFL,
 508    OPC_DALIGN_3   = (0x0B << 6) | OPC_DBSHFL,
 509    OPC_DALIGN_4   = (0x0C << 6) | OPC_DBSHFL,
 510    OPC_DALIGN_5   = (0x0D << 6) | OPC_DBSHFL,
 511    OPC_DALIGN_6   = (0x0E << 6) | OPC_DBSHFL,
 512    OPC_DALIGN_7   = (0x0F << 6) | OPC_DBSHFL,
 513    OPC_DBITSWAP   = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
 514};
 515
 516/* MIPS DSP REGIMM opcodes */
 517enum {
 518    OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
 519    OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
 520};
 521
 522#define MASK_LX(op)                 (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 523/* MIPS DSP Load */
 524enum {
 525    OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
 526    OPC_LHX  = (0x04 << 6) | OPC_LX_DSP,
 527    OPC_LWX  = (0x00 << 6) | OPC_LX_DSP,
 528    OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
 529};
 530
 531#define MASK_ADDU_QB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 532enum {
 533    /* MIPS DSP Arithmetic Sub-class */
 534    OPC_ADDQ_PH        = (0x0A << 6) | OPC_ADDU_QB_DSP,
 535    OPC_ADDQ_S_PH      = (0x0E << 6) | OPC_ADDU_QB_DSP,
 536    OPC_ADDQ_S_W       = (0x16 << 6) | OPC_ADDU_QB_DSP,
 537    OPC_ADDU_QB        = (0x00 << 6) | OPC_ADDU_QB_DSP,
 538    OPC_ADDU_S_QB      = (0x04 << 6) | OPC_ADDU_QB_DSP,
 539    OPC_ADDU_PH        = (0x08 << 6) | OPC_ADDU_QB_DSP,
 540    OPC_ADDU_S_PH      = (0x0C << 6) | OPC_ADDU_QB_DSP,
 541    OPC_SUBQ_PH        = (0x0B << 6) | OPC_ADDU_QB_DSP,
 542    OPC_SUBQ_S_PH      = (0x0F << 6) | OPC_ADDU_QB_DSP,
 543    OPC_SUBQ_S_W       = (0x17 << 6) | OPC_ADDU_QB_DSP,
 544    OPC_SUBU_QB        = (0x01 << 6) | OPC_ADDU_QB_DSP,
 545    OPC_SUBU_S_QB      = (0x05 << 6) | OPC_ADDU_QB_DSP,
 546    OPC_SUBU_PH        = (0x09 << 6) | OPC_ADDU_QB_DSP,
 547    OPC_SUBU_S_PH      = (0x0D << 6) | OPC_ADDU_QB_DSP,
 548    OPC_ADDSC          = (0x10 << 6) | OPC_ADDU_QB_DSP,
 549    OPC_ADDWC          = (0x11 << 6) | OPC_ADDU_QB_DSP,
 550    OPC_MODSUB         = (0x12 << 6) | OPC_ADDU_QB_DSP,
 551    OPC_RADDU_W_QB     = (0x14 << 6) | OPC_ADDU_QB_DSP,
 552    /* MIPS DSP Multiply Sub-class insns */
 553    OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
 554    OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
 555    OPC_MULQ_RS_PH     = (0x1F << 6) | OPC_ADDU_QB_DSP,
 556    OPC_MULEQ_S_W_PHL  = (0x1C << 6) | OPC_ADDU_QB_DSP,
 557    OPC_MULEQ_S_W_PHR  = (0x1D << 6) | OPC_ADDU_QB_DSP,
 558    OPC_MULQ_S_PH      = (0x1E << 6) | OPC_ADDU_QB_DSP,
 559};
 560
 561#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
 562#define MASK_ADDUH_QB(op)           (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 563enum {
 564    /* MIPS DSP Arithmetic Sub-class */
 565    OPC_ADDUH_QB   = (0x00 << 6) | OPC_ADDUH_QB_DSP,
 566    OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
 567    OPC_ADDQH_PH   = (0x08 << 6) | OPC_ADDUH_QB_DSP,
 568    OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
 569    OPC_ADDQH_W    = (0x10 << 6) | OPC_ADDUH_QB_DSP,
 570    OPC_ADDQH_R_W  = (0x12 << 6) | OPC_ADDUH_QB_DSP,
 571    OPC_SUBUH_QB   = (0x01 << 6) | OPC_ADDUH_QB_DSP,
 572    OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
 573    OPC_SUBQH_PH   = (0x09 << 6) | OPC_ADDUH_QB_DSP,
 574    OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
 575    OPC_SUBQH_W    = (0x11 << 6) | OPC_ADDUH_QB_DSP,
 576    OPC_SUBQH_R_W  = (0x13 << 6) | OPC_ADDUH_QB_DSP,
 577    /* MIPS DSP Multiply Sub-class insns */
 578    OPC_MUL_PH     = (0x0C << 6) | OPC_ADDUH_QB_DSP,
 579    OPC_MUL_S_PH   = (0x0E << 6) | OPC_ADDUH_QB_DSP,
 580    OPC_MULQ_S_W   = (0x16 << 6) | OPC_ADDUH_QB_DSP,
 581    OPC_MULQ_RS_W  = (0x17 << 6) | OPC_ADDUH_QB_DSP,
 582};
 583
 584#define MASK_ABSQ_S_PH(op)          (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 585enum {
 586    /* MIPS DSP Arithmetic Sub-class */
 587    OPC_ABSQ_S_QB       = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
 588    OPC_ABSQ_S_PH       = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
 589    OPC_ABSQ_S_W        = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
 590    OPC_PRECEQ_W_PHL    = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
 591    OPC_PRECEQ_W_PHR    = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
 592    OPC_PRECEQU_PH_QBL  = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
 593    OPC_PRECEQU_PH_QBR  = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
 594    OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
 595    OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
 596    OPC_PRECEU_PH_QBL   = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
 597    OPC_PRECEU_PH_QBR   = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
 598    OPC_PRECEU_PH_QBLA  = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
 599    OPC_PRECEU_PH_QBRA  = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
 600    /* DSP Bit/Manipulation Sub-class */
 601    OPC_BITREV          = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
 602    OPC_REPL_QB         = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
 603    OPC_REPLV_QB        = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
 604    OPC_REPL_PH         = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
 605    OPC_REPLV_PH        = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
 606};
 607
 608#define MASK_CMPU_EQ_QB(op)         (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 609enum {
 610    /* MIPS DSP Arithmetic Sub-class */
 611    OPC_PRECR_QB_PH      = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
 612    OPC_PRECRQ_QB_PH     = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
 613    OPC_PRECR_SRA_PH_W   = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
 614    OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
 615    OPC_PRECRQ_PH_W      = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
 616    OPC_PRECRQ_RS_PH_W   = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
 617    OPC_PRECRQU_S_QB_PH  = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
 618    /* DSP Compare-Pick Sub-class */
 619    OPC_CMPU_EQ_QB       = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
 620    OPC_CMPU_LT_QB       = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
 621    OPC_CMPU_LE_QB       = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
 622    OPC_CMPGU_EQ_QB      = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
 623    OPC_CMPGU_LT_QB      = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
 624    OPC_CMPGU_LE_QB      = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
 625    OPC_CMPGDU_EQ_QB     = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
 626    OPC_CMPGDU_LT_QB     = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
 627    OPC_CMPGDU_LE_QB     = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
 628    OPC_CMP_EQ_PH        = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
 629    OPC_CMP_LT_PH        = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
 630    OPC_CMP_LE_PH        = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
 631    OPC_PICK_QB          = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
 632    OPC_PICK_PH          = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
 633    OPC_PACKRL_PH        = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
 634};
 635
 636#define MASK_SHLL_QB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 637enum {
 638    /* MIPS DSP GPR-Based Shift Sub-class */
 639    OPC_SHLL_QB    = (0x00 << 6) | OPC_SHLL_QB_DSP,
 640    OPC_SHLLV_QB   = (0x02 << 6) | OPC_SHLL_QB_DSP,
 641    OPC_SHLL_PH    = (0x08 << 6) | OPC_SHLL_QB_DSP,
 642    OPC_SHLLV_PH   = (0x0A << 6) | OPC_SHLL_QB_DSP,
 643    OPC_SHLL_S_PH  = (0x0C << 6) | OPC_SHLL_QB_DSP,
 644    OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
 645    OPC_SHLL_S_W   = (0x14 << 6) | OPC_SHLL_QB_DSP,
 646    OPC_SHLLV_S_W  = (0x16 << 6) | OPC_SHLL_QB_DSP,
 647    OPC_SHRL_QB    = (0x01 << 6) | OPC_SHLL_QB_DSP,
 648    OPC_SHRLV_QB   = (0x03 << 6) | OPC_SHLL_QB_DSP,
 649    OPC_SHRL_PH    = (0x19 << 6) | OPC_SHLL_QB_DSP,
 650    OPC_SHRLV_PH   = (0x1B << 6) | OPC_SHLL_QB_DSP,
 651    OPC_SHRA_QB    = (0x04 << 6) | OPC_SHLL_QB_DSP,
 652    OPC_SHRA_R_QB  = (0x05 << 6) | OPC_SHLL_QB_DSP,
 653    OPC_SHRAV_QB   = (0x06 << 6) | OPC_SHLL_QB_DSP,
 654    OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
 655    OPC_SHRA_PH    = (0x09 << 6) | OPC_SHLL_QB_DSP,
 656    OPC_SHRAV_PH   = (0x0B << 6) | OPC_SHLL_QB_DSP,
 657    OPC_SHRA_R_PH  = (0x0D << 6) | OPC_SHLL_QB_DSP,
 658    OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
 659    OPC_SHRA_R_W   = (0x15 << 6) | OPC_SHLL_QB_DSP,
 660    OPC_SHRAV_R_W  = (0x17 << 6) | OPC_SHLL_QB_DSP,
 661};
 662
 663#define MASK_DPA_W_PH(op)           (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 664enum {
 665    /* MIPS DSP Multiply Sub-class insns */
 666    OPC_DPAU_H_QBL    = (0x03 << 6) | OPC_DPA_W_PH_DSP,
 667    OPC_DPAU_H_QBR    = (0x07 << 6) | OPC_DPA_W_PH_DSP,
 668    OPC_DPSU_H_QBL    = (0x0B << 6) | OPC_DPA_W_PH_DSP,
 669    OPC_DPSU_H_QBR    = (0x0F << 6) | OPC_DPA_W_PH_DSP,
 670    OPC_DPA_W_PH      = (0x00 << 6) | OPC_DPA_W_PH_DSP,
 671    OPC_DPAX_W_PH     = (0x08 << 6) | OPC_DPA_W_PH_DSP,
 672    OPC_DPAQ_S_W_PH   = (0x04 << 6) | OPC_DPA_W_PH_DSP,
 673    OPC_DPAQX_S_W_PH  = (0x18 << 6) | OPC_DPA_W_PH_DSP,
 674    OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
 675    OPC_DPS_W_PH      = (0x01 << 6) | OPC_DPA_W_PH_DSP,
 676    OPC_DPSX_W_PH     = (0x09 << 6) | OPC_DPA_W_PH_DSP,
 677    OPC_DPSQ_S_W_PH   = (0x05 << 6) | OPC_DPA_W_PH_DSP,
 678    OPC_DPSQX_S_W_PH  = (0x19 << 6) | OPC_DPA_W_PH_DSP,
 679    OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
 680    OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
 681    OPC_DPAQ_SA_L_W   = (0x0C << 6) | OPC_DPA_W_PH_DSP,
 682    OPC_DPSQ_SA_L_W   = (0x0D << 6) | OPC_DPA_W_PH_DSP,
 683    OPC_MAQ_S_W_PHL   = (0x14 << 6) | OPC_DPA_W_PH_DSP,
 684    OPC_MAQ_S_W_PHR   = (0x16 << 6) | OPC_DPA_W_PH_DSP,
 685    OPC_MAQ_SA_W_PHL  = (0x10 << 6) | OPC_DPA_W_PH_DSP,
 686    OPC_MAQ_SA_W_PHR  = (0x12 << 6) | OPC_DPA_W_PH_DSP,
 687    OPC_MULSA_W_PH    = (0x02 << 6) | OPC_DPA_W_PH_DSP,
 688};
 689
 690#define MASK_INSV(op)               (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 691enum {
 692    /* DSP Bit/Manipulation Sub-class */
 693    OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
 694};
 695
 696#define MASK_APPEND(op)             (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 697enum {
 698    /* MIPS DSP Append Sub-class */
 699    OPC_APPEND  = (0x00 << 6) | OPC_APPEND_DSP,
 700    OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
 701    OPC_BALIGN  = (0x10 << 6) | OPC_APPEND_DSP,
 702};
 703
 704#define MASK_EXTR_W(op)             (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 705enum {
 706    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 707    OPC_EXTR_W     = (0x00 << 6) | OPC_EXTR_W_DSP,
 708    OPC_EXTR_R_W   = (0x04 << 6) | OPC_EXTR_W_DSP,
 709    OPC_EXTR_RS_W  = (0x06 << 6) | OPC_EXTR_W_DSP,
 710    OPC_EXTR_S_H   = (0x0E << 6) | OPC_EXTR_W_DSP,
 711    OPC_EXTRV_S_H  = (0x0F << 6) | OPC_EXTR_W_DSP,
 712    OPC_EXTRV_W    = (0x01 << 6) | OPC_EXTR_W_DSP,
 713    OPC_EXTRV_R_W  = (0x05 << 6) | OPC_EXTR_W_DSP,
 714    OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
 715    OPC_EXTP       = (0x02 << 6) | OPC_EXTR_W_DSP,
 716    OPC_EXTPV      = (0x03 << 6) | OPC_EXTR_W_DSP,
 717    OPC_EXTPDP     = (0x0A << 6) | OPC_EXTR_W_DSP,
 718    OPC_EXTPDPV    = (0x0B << 6) | OPC_EXTR_W_DSP,
 719    OPC_SHILO      = (0x1A << 6) | OPC_EXTR_W_DSP,
 720    OPC_SHILOV     = (0x1B << 6) | OPC_EXTR_W_DSP,
 721    OPC_MTHLIP     = (0x1F << 6) | OPC_EXTR_W_DSP,
 722    OPC_WRDSP      = (0x13 << 6) | OPC_EXTR_W_DSP,
 723    OPC_RDDSP      = (0x12 << 6) | OPC_EXTR_W_DSP,
 724};
 725
 726#define MASK_ABSQ_S_QH(op)          (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 727enum {
 728    /* MIPS DSP Arithmetic Sub-class */
 729    OPC_PRECEQ_L_PWL    = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
 730    OPC_PRECEQ_L_PWR    = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
 731    OPC_PRECEQ_PW_QHL   = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
 732    OPC_PRECEQ_PW_QHR   = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
 733    OPC_PRECEQ_PW_QHLA  = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
 734    OPC_PRECEQ_PW_QHRA  = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
 735    OPC_PRECEQU_QH_OBL  = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
 736    OPC_PRECEQU_QH_OBR  = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
 737    OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
 738    OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
 739    OPC_PRECEU_QH_OBL   = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
 740    OPC_PRECEU_QH_OBR   = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
 741    OPC_PRECEU_QH_OBLA  = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
 742    OPC_PRECEU_QH_OBRA  = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
 743    OPC_ABSQ_S_OB       = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
 744    OPC_ABSQ_S_PW       = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
 745    OPC_ABSQ_S_QH       = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
 746    /* DSP Bit/Manipulation Sub-class */
 747    OPC_REPL_OB         = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
 748    OPC_REPL_PW         = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
 749    OPC_REPL_QH         = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
 750    OPC_REPLV_OB        = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
 751    OPC_REPLV_PW        = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
 752    OPC_REPLV_QH        = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
 753};
 754
 755#define MASK_ADDU_OB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 756enum {
 757    /* MIPS DSP Multiply Sub-class insns */
 758    OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
 759    OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
 760    OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
 761    OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
 762    OPC_MULQ_RS_QH     = (0x1F << 6) | OPC_ADDU_OB_DSP,
 763    /* MIPS DSP Arithmetic Sub-class */
 764    OPC_RADDU_L_OB     = (0x14 << 6) | OPC_ADDU_OB_DSP,
 765    OPC_SUBQ_PW        = (0x13 << 6) | OPC_ADDU_OB_DSP,
 766    OPC_SUBQ_S_PW      = (0x17 << 6) | OPC_ADDU_OB_DSP,
 767    OPC_SUBQ_QH        = (0x0B << 6) | OPC_ADDU_OB_DSP,
 768    OPC_SUBQ_S_QH      = (0x0F << 6) | OPC_ADDU_OB_DSP,
 769    OPC_SUBU_OB        = (0x01 << 6) | OPC_ADDU_OB_DSP,
 770    OPC_SUBU_S_OB      = (0x05 << 6) | OPC_ADDU_OB_DSP,
 771    OPC_SUBU_QH        = (0x09 << 6) | OPC_ADDU_OB_DSP,
 772    OPC_SUBU_S_QH      = (0x0D << 6) | OPC_ADDU_OB_DSP,
 773    OPC_SUBUH_OB       = (0x19 << 6) | OPC_ADDU_OB_DSP,
 774    OPC_SUBUH_R_OB     = (0x1B << 6) | OPC_ADDU_OB_DSP,
 775    OPC_ADDQ_PW        = (0x12 << 6) | OPC_ADDU_OB_DSP,
 776    OPC_ADDQ_S_PW      = (0x16 << 6) | OPC_ADDU_OB_DSP,
 777    OPC_ADDQ_QH        = (0x0A << 6) | OPC_ADDU_OB_DSP,
 778    OPC_ADDQ_S_QH      = (0x0E << 6) | OPC_ADDU_OB_DSP,
 779    OPC_ADDU_OB        = (0x00 << 6) | OPC_ADDU_OB_DSP,
 780    OPC_ADDU_S_OB      = (0x04 << 6) | OPC_ADDU_OB_DSP,
 781    OPC_ADDU_QH        = (0x08 << 6) | OPC_ADDU_OB_DSP,
 782    OPC_ADDU_S_QH      = (0x0C << 6) | OPC_ADDU_OB_DSP,
 783    OPC_ADDUH_OB       = (0x18 << 6) | OPC_ADDU_OB_DSP,
 784    OPC_ADDUH_R_OB     = (0x1A << 6) | OPC_ADDU_OB_DSP,
 785};
 786
 787#define MASK_CMPU_EQ_OB(op)         (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 788enum {
 789    /* DSP Compare-Pick Sub-class */
 790    OPC_CMP_EQ_PW         = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
 791    OPC_CMP_LT_PW         = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
 792    OPC_CMP_LE_PW         = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
 793    OPC_CMP_EQ_QH         = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
 794    OPC_CMP_LT_QH         = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
 795    OPC_CMP_LE_QH         = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
 796    OPC_CMPGDU_EQ_OB      = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
 797    OPC_CMPGDU_LT_OB      = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
 798    OPC_CMPGDU_LE_OB      = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
 799    OPC_CMPGU_EQ_OB       = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
 800    OPC_CMPGU_LT_OB       = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
 801    OPC_CMPGU_LE_OB       = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
 802    OPC_CMPU_EQ_OB        = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
 803    OPC_CMPU_LT_OB        = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
 804    OPC_CMPU_LE_OB        = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
 805    OPC_PACKRL_PW         = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
 806    OPC_PICK_OB           = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
 807    OPC_PICK_PW           = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
 808    OPC_PICK_QH           = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
 809    /* MIPS DSP Arithmetic Sub-class */
 810    OPC_PRECR_OB_QH       = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
 811    OPC_PRECR_SRA_QH_PW   = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
 812    OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
 813    OPC_PRECRQ_OB_QH      = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
 814    OPC_PRECRQ_PW_L       = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
 815    OPC_PRECRQ_QH_PW      = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
 816    OPC_PRECRQ_RS_QH_PW   = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
 817    OPC_PRECRQU_S_OB_QH   = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
 818};
 819
 820#define MASK_DAPPEND(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 821enum {
 822    /* DSP Append Sub-class */
 823    OPC_DAPPEND  = (0x00 << 6) | OPC_DAPPEND_DSP,
 824    OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
 825    OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
 826    OPC_DBALIGN  = (0x10 << 6) | OPC_DAPPEND_DSP,
 827};
 828
 829#define MASK_DEXTR_W(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 830enum {
 831    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 832    OPC_DMTHLIP     = (0x1F << 6) | OPC_DEXTR_W_DSP,
 833    OPC_DSHILO      = (0x1A << 6) | OPC_DEXTR_W_DSP,
 834    OPC_DEXTP       = (0x02 << 6) | OPC_DEXTR_W_DSP,
 835    OPC_DEXTPDP     = (0x0A << 6) | OPC_DEXTR_W_DSP,
 836    OPC_DEXTPDPV    = (0x0B << 6) | OPC_DEXTR_W_DSP,
 837    OPC_DEXTPV      = (0x03 << 6) | OPC_DEXTR_W_DSP,
 838    OPC_DEXTR_L     = (0x10 << 6) | OPC_DEXTR_W_DSP,
 839    OPC_DEXTR_R_L   = (0x14 << 6) | OPC_DEXTR_W_DSP,
 840    OPC_DEXTR_RS_L  = (0x16 << 6) | OPC_DEXTR_W_DSP,
 841    OPC_DEXTR_W     = (0x00 << 6) | OPC_DEXTR_W_DSP,
 842    OPC_DEXTR_R_W   = (0x04 << 6) | OPC_DEXTR_W_DSP,
 843    OPC_DEXTR_RS_W  = (0x06 << 6) | OPC_DEXTR_W_DSP,
 844    OPC_DEXTR_S_H   = (0x0E << 6) | OPC_DEXTR_W_DSP,
 845    OPC_DEXTRV_L    = (0x11 << 6) | OPC_DEXTR_W_DSP,
 846    OPC_DEXTRV_R_L  = (0x15 << 6) | OPC_DEXTR_W_DSP,
 847    OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
 848    OPC_DEXTRV_S_H  = (0x0F << 6) | OPC_DEXTR_W_DSP,
 849    OPC_DEXTRV_W    = (0x01 << 6) | OPC_DEXTR_W_DSP,
 850    OPC_DEXTRV_R_W  = (0x05 << 6) | OPC_DEXTR_W_DSP,
 851    OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
 852    OPC_DSHILOV     = (0x1B << 6) | OPC_DEXTR_W_DSP,
 853};
 854
 855#define MASK_DINSV(op)              (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 856enum {
 857    /* DSP Bit/Manipulation Sub-class */
 858    OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
 859};
 860
 861#define MASK_DPAQ_W_QH(op)          (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 862enum {
 863    /* MIPS DSP Multiply Sub-class insns */
 864    OPC_DMADD         = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
 865    OPC_DMADDU        = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
 866    OPC_DMSUB         = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
 867    OPC_DMSUBU        = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
 868    OPC_DPA_W_QH      = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
 869    OPC_DPAQ_S_W_QH   = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
 870    OPC_DPAQ_SA_L_PW  = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
 871    OPC_DPAU_H_OBL    = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
 872    OPC_DPAU_H_OBR    = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
 873    OPC_DPS_W_QH      = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
 874    OPC_DPSQ_S_W_QH   = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
 875    OPC_DPSQ_SA_L_PW  = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
 876    OPC_DPSU_H_OBL    = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
 877    OPC_DPSU_H_OBR    = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
 878    OPC_MAQ_S_L_PWL   = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
 879    OPC_MAQ_S_L_PWR   = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
 880    OPC_MAQ_S_W_QHLL  = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
 881    OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
 882    OPC_MAQ_S_W_QHLR  = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
 883    OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
 884    OPC_MAQ_S_W_QHRL  = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
 885    OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
 886    OPC_MAQ_S_W_QHRR  = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
 887    OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
 888    OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
 889    OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
 890};
 891
 892#define MASK_SHLL_OB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 893enum {
 894    /* MIPS DSP GPR-Based Shift Sub-class */
 895    OPC_SHLL_PW    = (0x10 << 6) | OPC_SHLL_OB_DSP,
 896    OPC_SHLL_S_PW  = (0x14 << 6) | OPC_SHLL_OB_DSP,
 897    OPC_SHLLV_OB   = (0x02 << 6) | OPC_SHLL_OB_DSP,
 898    OPC_SHLLV_PW   = (0x12 << 6) | OPC_SHLL_OB_DSP,
 899    OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
 900    OPC_SHLLV_QH   = (0x0A << 6) | OPC_SHLL_OB_DSP,
 901    OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
 902    OPC_SHRA_PW    = (0x11 << 6) | OPC_SHLL_OB_DSP,
 903    OPC_SHRA_R_PW  = (0x15 << 6) | OPC_SHLL_OB_DSP,
 904    OPC_SHRAV_OB   = (0x06 << 6) | OPC_SHLL_OB_DSP,
 905    OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
 906    OPC_SHRAV_PW   = (0x13 << 6) | OPC_SHLL_OB_DSP,
 907    OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
 908    OPC_SHRAV_QH   = (0x0B << 6) | OPC_SHLL_OB_DSP,
 909    OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
 910    OPC_SHRLV_OB   = (0x03 << 6) | OPC_SHLL_OB_DSP,
 911    OPC_SHRLV_QH   = (0x1B << 6) | OPC_SHLL_OB_DSP,
 912    OPC_SHLL_OB    = (0x00 << 6) | OPC_SHLL_OB_DSP,
 913    OPC_SHLL_QH    = (0x08 << 6) | OPC_SHLL_OB_DSP,
 914    OPC_SHLL_S_QH  = (0x0C << 6) | OPC_SHLL_OB_DSP,
 915    OPC_SHRA_OB    = (0x04 << 6) | OPC_SHLL_OB_DSP,
 916    OPC_SHRA_R_OB  = (0x05 << 6) | OPC_SHLL_OB_DSP,
 917    OPC_SHRA_QH    = (0x09 << 6) | OPC_SHLL_OB_DSP,
 918    OPC_SHRA_R_QH  = (0x0D << 6) | OPC_SHLL_OB_DSP,
 919    OPC_SHRL_OB    = (0x01 << 6) | OPC_SHLL_OB_DSP,
 920    OPC_SHRL_QH    = (0x19 << 6) | OPC_SHLL_OB_DSP,
 921};
 922
 923/* Coprocessor 0 (rs field) */
 924#define MASK_CP0(op)                (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
 925
 926enum {
 927    OPC_MFC0     = (0x00 << 21) | OPC_CP0,
 928    OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
 929    OPC_MFHC0    = (0x02 << 21) | OPC_CP0,
 930    OPC_MTC0     = (0x04 << 21) | OPC_CP0,
 931    OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
 932    OPC_MTHC0    = (0x06 << 21) | OPC_CP0,
 933    OPC_MFTR     = (0x08 << 21) | OPC_CP0,
 934    OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
 935    OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
 936    OPC_MTTR     = (0x0C << 21) | OPC_CP0,
 937    OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
 938    OPC_C0       = (0x10 << 21) | OPC_CP0,
 939    OPC_C0_1     = (0x11 << 21) | OPC_CP0,
 940    OPC_C0_2     = (0x12 << 21) | OPC_CP0,
 941    OPC_C0_3     = (0x13 << 21) | OPC_CP0,
 942    OPC_C0_4     = (0x14 << 21) | OPC_CP0,
 943    OPC_C0_5     = (0x15 << 21) | OPC_CP0,
 944    OPC_C0_6     = (0x16 << 21) | OPC_CP0,
 945    OPC_C0_7     = (0x17 << 21) | OPC_CP0,
 946    OPC_C0_8     = (0x18 << 21) | OPC_CP0,
 947    OPC_C0_9     = (0x19 << 21) | OPC_CP0,
 948    OPC_C0_A     = (0x1A << 21) | OPC_CP0,
 949    OPC_C0_B     = (0x1B << 21) | OPC_CP0,
 950    OPC_C0_C     = (0x1C << 21) | OPC_CP0,
 951    OPC_C0_D     = (0x1D << 21) | OPC_CP0,
 952    OPC_C0_E     = (0x1E << 21) | OPC_CP0,
 953    OPC_C0_F     = (0x1F << 21) | OPC_CP0,
 954};
 955
 956/* MFMC0 opcodes */
 957#define MASK_MFMC0(op)              (MASK_CP0(op) | (op & 0xFFFF))
 958
 959enum {
 960    OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
 961    OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
 962    OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
 963    OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
 964    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
 965    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
 966    OPC_DVP      = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
 967    OPC_EVP      = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
 968};
 969
 970/* Coprocessor 0 (with rs == C0) */
 971#define MASK_C0(op)                 (MASK_CP0(op) | (op & 0x3F))
 972
 973enum {
 974    OPC_TLBR     = 0x01 | OPC_C0,
 975    OPC_TLBWI    = 0x02 | OPC_C0,
 976    OPC_TLBINV   = 0x03 | OPC_C0,
 977    OPC_TLBINVF  = 0x04 | OPC_C0,
 978    OPC_TLBWR    = 0x06 | OPC_C0,
 979    OPC_TLBP     = 0x08 | OPC_C0,
 980    OPC_RFE      = 0x10 | OPC_C0,
 981    OPC_ERET     = 0x18 | OPC_C0,
 982    OPC_DERET    = 0x1F | OPC_C0,
 983    OPC_WAIT     = 0x20 | OPC_C0,
 984};
 985
 986#define MASK_CP2(op)                (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
 987
 988enum {
 989    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
 990    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
 991    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
 992    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
 993    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
 994    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
 995    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
 996    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
 997    OPC_BC2     = (0x08 << 21) | OPC_CP2,
 998    OPC_BC2EQZ  = (0x09 << 21) | OPC_CP2,
 999    OPC_BC2NEZ  = (0x0D << 21) | OPC_CP2,
1000};
1001
1002#define MASK_LMMI(op)    (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1003
1004enum {
1005    OPC_PADDSH      = (24 << 21) | (0x00) | OPC_CP2,
1006    OPC_PADDUSH     = (25 << 21) | (0x00) | OPC_CP2,
1007    OPC_PADDH       = (26 << 21) | (0x00) | OPC_CP2,
1008    OPC_PADDW       = (27 << 21) | (0x00) | OPC_CP2,
1009    OPC_PADDSB      = (28 << 21) | (0x00) | OPC_CP2,
1010    OPC_PADDUSB     = (29 << 21) | (0x00) | OPC_CP2,
1011    OPC_PADDB       = (30 << 21) | (0x00) | OPC_CP2,
1012    OPC_PADDD       = (31 << 21) | (0x00) | OPC_CP2,
1013
1014    OPC_PSUBSH      = (24 << 21) | (0x01) | OPC_CP2,
1015    OPC_PSUBUSH     = (25 << 21) | (0x01) | OPC_CP2,
1016    OPC_PSUBH       = (26 << 21) | (0x01) | OPC_CP2,
1017    OPC_PSUBW       = (27 << 21) | (0x01) | OPC_CP2,
1018    OPC_PSUBSB      = (28 << 21) | (0x01) | OPC_CP2,
1019    OPC_PSUBUSB     = (29 << 21) | (0x01) | OPC_CP2,
1020    OPC_PSUBB       = (30 << 21) | (0x01) | OPC_CP2,
1021    OPC_PSUBD       = (31 << 21) | (0x01) | OPC_CP2,
1022
1023    OPC_PSHUFH      = (24 << 21) | (0x02) | OPC_CP2,
1024    OPC_PACKSSWH    = (25 << 21) | (0x02) | OPC_CP2,
1025    OPC_PACKSSHB    = (26 << 21) | (0x02) | OPC_CP2,
1026    OPC_PACKUSHB    = (27 << 21) | (0x02) | OPC_CP2,
1027    OPC_XOR_CP2     = (28 << 21) | (0x02) | OPC_CP2,
1028    OPC_NOR_CP2     = (29 << 21) | (0x02) | OPC_CP2,
1029    OPC_AND_CP2     = (30 << 21) | (0x02) | OPC_CP2,
1030    OPC_PANDN       = (31 << 21) | (0x02) | OPC_CP2,
1031
1032    OPC_PUNPCKLHW   = (24 << 21) | (0x03) | OPC_CP2,
1033    OPC_PUNPCKHHW   = (25 << 21) | (0x03) | OPC_CP2,
1034    OPC_PUNPCKLBH   = (26 << 21) | (0x03) | OPC_CP2,
1035    OPC_PUNPCKHBH   = (27 << 21) | (0x03) | OPC_CP2,
1036    OPC_PINSRH_0    = (28 << 21) | (0x03) | OPC_CP2,
1037    OPC_PINSRH_1    = (29 << 21) | (0x03) | OPC_CP2,
1038    OPC_PINSRH_2    = (30 << 21) | (0x03) | OPC_CP2,
1039    OPC_PINSRH_3    = (31 << 21) | (0x03) | OPC_CP2,
1040
1041    OPC_PAVGH       = (24 << 21) | (0x08) | OPC_CP2,
1042    OPC_PAVGB       = (25 << 21) | (0x08) | OPC_CP2,
1043    OPC_PMAXSH      = (26 << 21) | (0x08) | OPC_CP2,
1044    OPC_PMINSH      = (27 << 21) | (0x08) | OPC_CP2,
1045    OPC_PMAXUB      = (28 << 21) | (0x08) | OPC_CP2,
1046    OPC_PMINUB      = (29 << 21) | (0x08) | OPC_CP2,
1047
1048    OPC_PCMPEQW     = (24 << 21) | (0x09) | OPC_CP2,
1049    OPC_PCMPGTW     = (25 << 21) | (0x09) | OPC_CP2,
1050    OPC_PCMPEQH     = (26 << 21) | (0x09) | OPC_CP2,
1051    OPC_PCMPGTH     = (27 << 21) | (0x09) | OPC_CP2,
1052    OPC_PCMPEQB     = (28 << 21) | (0x09) | OPC_CP2,
1053    OPC_PCMPGTB     = (29 << 21) | (0x09) | OPC_CP2,
1054
1055    OPC_PSLLW       = (24 << 21) | (0x0A) | OPC_CP2,
1056    OPC_PSLLH       = (25 << 21) | (0x0A) | OPC_CP2,
1057    OPC_PMULLH      = (26 << 21) | (0x0A) | OPC_CP2,
1058    OPC_PMULHH      = (27 << 21) | (0x0A) | OPC_CP2,
1059    OPC_PMULUW      = (28 << 21) | (0x0A) | OPC_CP2,
1060    OPC_PMULHUH     = (29 << 21) | (0x0A) | OPC_CP2,
1061
1062    OPC_PSRLW       = (24 << 21) | (0x0B) | OPC_CP2,
1063    OPC_PSRLH       = (25 << 21) | (0x0B) | OPC_CP2,
1064    OPC_PSRAW       = (26 << 21) | (0x0B) | OPC_CP2,
1065    OPC_PSRAH       = (27 << 21) | (0x0B) | OPC_CP2,
1066    OPC_PUNPCKLWD   = (28 << 21) | (0x0B) | OPC_CP2,
1067    OPC_PUNPCKHWD   = (29 << 21) | (0x0B) | OPC_CP2,
1068
1069    OPC_ADDU_CP2    = (24 << 21) | (0x0C) | OPC_CP2,
1070    OPC_OR_CP2      = (25 << 21) | (0x0C) | OPC_CP2,
1071    OPC_ADD_CP2     = (26 << 21) | (0x0C) | OPC_CP2,
1072    OPC_DADD_CP2    = (27 << 21) | (0x0C) | OPC_CP2,
1073    OPC_SEQU_CP2    = (28 << 21) | (0x0C) | OPC_CP2,
1074    OPC_SEQ_CP2     = (29 << 21) | (0x0C) | OPC_CP2,
1075
1076    OPC_SUBU_CP2    = (24 << 21) | (0x0D) | OPC_CP2,
1077    OPC_PASUBUB     = (25 << 21) | (0x0D) | OPC_CP2,
1078    OPC_SUB_CP2     = (26 << 21) | (0x0D) | OPC_CP2,
1079    OPC_DSUB_CP2    = (27 << 21) | (0x0D) | OPC_CP2,
1080    OPC_SLTU_CP2    = (28 << 21) | (0x0D) | OPC_CP2,
1081    OPC_SLT_CP2     = (29 << 21) | (0x0D) | OPC_CP2,
1082
1083    OPC_SLL_CP2     = (24 << 21) | (0x0E) | OPC_CP2,
1084    OPC_DSLL_CP2    = (25 << 21) | (0x0E) | OPC_CP2,
1085    OPC_PEXTRH      = (26 << 21) | (0x0E) | OPC_CP2,
1086    OPC_PMADDHW     = (27 << 21) | (0x0E) | OPC_CP2,
1087    OPC_SLEU_CP2    = (28 << 21) | (0x0E) | OPC_CP2,
1088    OPC_SLE_CP2     = (29 << 21) | (0x0E) | OPC_CP2,
1089
1090    OPC_SRL_CP2     = (24 << 21) | (0x0F) | OPC_CP2,
1091    OPC_DSRL_CP2    = (25 << 21) | (0x0F) | OPC_CP2,
1092    OPC_SRA_CP2     = (26 << 21) | (0x0F) | OPC_CP2,
1093    OPC_DSRA_CP2    = (27 << 21) | (0x0F) | OPC_CP2,
1094    OPC_BIADD       = (28 << 21) | (0x0F) | OPC_CP2,
1095    OPC_PMOVMSKB    = (29 << 21) | (0x0F) | OPC_CP2,
1096};
1097
1098
1099#define MASK_CP3(op)                (MASK_OP_MAJOR(op) | (op & 0x3F))
1100
1101enum {
1102    OPC_LWXC1       = 0x00 | OPC_CP3,
1103    OPC_LDXC1       = 0x01 | OPC_CP3,
1104    OPC_LUXC1       = 0x05 | OPC_CP3,
1105    OPC_SWXC1       = 0x08 | OPC_CP3,
1106    OPC_SDXC1       = 0x09 | OPC_CP3,
1107    OPC_SUXC1       = 0x0D | OPC_CP3,
1108    OPC_PREFX       = 0x0F | OPC_CP3,
1109    OPC_ALNV_PS     = 0x1E | OPC_CP3,
1110    OPC_MADD_S      = 0x20 | OPC_CP3,
1111    OPC_MADD_D      = 0x21 | OPC_CP3,
1112    OPC_MADD_PS     = 0x26 | OPC_CP3,
1113    OPC_MSUB_S      = 0x28 | OPC_CP3,
1114    OPC_MSUB_D      = 0x29 | OPC_CP3,
1115    OPC_MSUB_PS     = 0x2E | OPC_CP3,
1116    OPC_NMADD_S     = 0x30 | OPC_CP3,
1117    OPC_NMADD_D     = 0x31 | OPC_CP3,
1118    OPC_NMADD_PS    = 0x36 | OPC_CP3,
1119    OPC_NMSUB_S     = 0x38 | OPC_CP3,
1120    OPC_NMSUB_D     = 0x39 | OPC_CP3,
1121    OPC_NMSUB_PS    = 0x3E | OPC_CP3,
1122};
1123
1124/*
1125 *     MMI (MultiMedia Instruction) encodings
1126 *     ======================================
1127 *
1128 * MMI instructions encoding table keys:
1129 *
1130 *     *   This code is reserved for future use. An attempt to execute it
1131 *         causes a Reserved Instruction exception.
1132 *     %   This code indicates an instruction class. The instruction word
1133 *         must be further decoded by examining additional tables that show
1134 *         the values for other instruction fields.
1135 *     #   This code is reserved for the unsupported instructions DMULT,
1136 *         DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
1137 *         to execute it causes a Reserved Instruction exception.
1138 *
1139 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
1140 *
1141 *  31    26                                        0
1142 * +--------+----------------------------------------+
1143 * | opcode |                                        |
1144 * +--------+----------------------------------------+
1145 *
1146 *   opcode  bits 28..26
1147 *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
1148 *   31..29 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
1149 *   -------+-------+-------+-------+-------+-------+-------+-------+-------
1150 *    0 000 |SPECIAL| REGIMM|   J   |  JAL  |  BEQ  |  BNE  |  BLEZ |  BGTZ
1151 *    1 001 |  ADDI | ADDIU |  SLTI | SLTIU |  ANDI |  ORI  |  XORI |  LUI
1152 *    2 010 |  COP0 |  COP1 |   *   |   *   |  BEQL |  BNEL | BLEZL | BGTZL
1153 *    3 011 | DADDI | DADDIU|  LDL  |  LDR  |  MMI% |   *   |   LQ  |   SQ
1154 *    4 100 |   LB  |   LH  |  LWL  |   LW  |  LBU  |  LHU  |  LWR  |  LWU
1155 *    5 101 |   SB  |   SH  |  SWL  |   SW  |  SDL  |  SDR  |  SWR  | CACHE
1156 *    6 110 |   #   |  LWC1 |   #   |  PREF |   #   |  LDC1 |   #   |   LD
1157 *    7 111 |   #   |  SWC1 |   #   |   *   |   #   |  SDC1 |   #   |   SD
1158 */
1159
1160enum {
1161    MMI_OPC_CLASS_MMI = 0x1C << 26,    /* Same as OPC_SPECIAL2 */
1162    MMI_OPC_SQ        = 0x1F << 26,    /* Same as OPC_SPECIAL3 */
1163};
1164
1165/*
1166 * MMI instructions with opcode field = MMI:
1167 *
1168 *  31    26                                 5      0
1169 * +--------+-------------------------------+--------+
1170 * |   MMI  |                               |function|
1171 * +--------+-------------------------------+--------+
1172 *
1173 * function  bits 2..0
1174 *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
1175 *     5..3 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
1176 *   -------+-------+-------+-------+-------+-------+-------+-------+-------
1177 *    0 000 |  MADD | MADDU |   *   |   *   | PLZCW |   *   |   *   |   *
1178 *    1 001 | MMI0% | MMI2% |   *   |   *   |   *   |   *   |   *   |   *
1179 *    2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 |   *   |   *   |   *   |   *
1180 *    3 011 | MULT1 | MULTU1|  DIV1 | DIVU1 |   *   |   *   |   *   |   *
1181 *    4 100 | MADD1 | MADDU1|   *   |   *   |   *   |   *   |   *   |   *
1182 *    5 101 | MMI1% | MMI3% |   *   |   *   |   *   |   *   |   *   |   *
1183 *    6 110 | PMFHL | PMTHL |   *   |   *   | PSLLH |   *   | PSRLH | PSRAH
1184 *    7 111 |   *   |   *   |   *   |   *   | PSLLW |   *   | PSRLW | PSRAW
1185 */
1186
1187#define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
1188enum {
1189    MMI_OPC_MADD       = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */
1190    MMI_OPC_MADDU      = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */
1191    MMI_OPC_MULT1      = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */
1192    MMI_OPC_MULTU1     = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */
1193    MMI_OPC_DIV1       = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV  */
1194    MMI_OPC_DIVU1      = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */
1195    MMI_OPC_MADD1      = 0x20 | MMI_OPC_CLASS_MMI,
1196    MMI_OPC_MADDU1     = 0x21 | MMI_OPC_CLASS_MMI,
1197};
1198
1199/* global register indices */
1200TCGv cpu_gpr[32], cpu_PC;
1201/*
1202 * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[])
1203 * and the upper halves in cpu_gpr_hi[].
1204 */
1205TCGv_i64 cpu_gpr_hi[32];
1206TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1207static TCGv cpu_dspctrl, btarget;
1208TCGv bcond;
1209static TCGv cpu_lladdr, cpu_llval;
1210static TCGv_i32 hflags;
1211TCGv_i32 fpu_fcr0, fpu_fcr31;
1212TCGv_i64 fpu_f64[32];
1213
1214#include "exec/gen-icount.h"
1215
1216#define DISAS_STOP       DISAS_TARGET_0
1217#define DISAS_EXIT       DISAS_TARGET_1
1218
1219static const char regnames_HI[][4] = {
1220    "HI0", "HI1", "HI2", "HI3",
1221};
1222
1223static const char regnames_LO[][4] = {
1224    "LO0", "LO1", "LO2", "LO3",
1225};
1226
1227/* General purpose registers moves. */
1228void gen_load_gpr(TCGv t, int reg)
1229{
1230    if (reg == 0) {
1231        tcg_gen_movi_tl(t, 0);
1232    } else {
1233        tcg_gen_mov_tl(t, cpu_gpr[reg]);
1234    }
1235}
1236
1237void gen_store_gpr(TCGv t, int reg)
1238{
1239    if (reg != 0) {
1240        tcg_gen_mov_tl(cpu_gpr[reg], t);
1241    }
1242}
1243
1244#if defined(TARGET_MIPS64)
1245void gen_load_gpr_hi(TCGv_i64 t, int reg)
1246{
1247    if (reg == 0) {
1248        tcg_gen_movi_i64(t, 0);
1249    } else {
1250        tcg_gen_mov_i64(t, cpu_gpr_hi[reg]);
1251    }
1252}
1253
1254void gen_store_gpr_hi(TCGv_i64 t, int reg)
1255{
1256    if (reg != 0) {
1257        tcg_gen_mov_i64(cpu_gpr_hi[reg], t);
1258    }
1259}
1260#endif /* TARGET_MIPS64 */
1261
1262/* Moves to/from shadow registers. */
1263static inline void gen_load_srsgpr(int from, int to)
1264{
1265    TCGv t0 = tcg_temp_new();
1266
1267    if (from == 0) {
1268        tcg_gen_movi_tl(t0, 0);
1269    } else {
1270        TCGv_i32 t2 = tcg_temp_new_i32();
1271        TCGv_ptr addr = tcg_temp_new_ptr();
1272
1273        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1274        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1275        tcg_gen_andi_i32(t2, t2, 0xf);
1276        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1277        tcg_gen_ext_i32_ptr(addr, t2);
1278        tcg_gen_add_ptr(addr, cpu_env, addr);
1279
1280        tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1281        tcg_temp_free_ptr(addr);
1282        tcg_temp_free_i32(t2);
1283    }
1284    gen_store_gpr(t0, to);
1285    tcg_temp_free(t0);
1286}
1287
1288static inline void gen_store_srsgpr(int from, int to)
1289{
1290    if (to != 0) {
1291        TCGv t0 = tcg_temp_new();
1292        TCGv_i32 t2 = tcg_temp_new_i32();
1293        TCGv_ptr addr = tcg_temp_new_ptr();
1294
1295        gen_load_gpr(t0, from);
1296        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1297        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1298        tcg_gen_andi_i32(t2, t2, 0xf);
1299        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1300        tcg_gen_ext_i32_ptr(addr, t2);
1301        tcg_gen_add_ptr(addr, cpu_env, addr);
1302
1303        tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1304        tcg_temp_free_ptr(addr);
1305        tcg_temp_free_i32(t2);
1306        tcg_temp_free(t0);
1307    }
1308}
1309
1310/* Tests */
1311static inline void gen_save_pc(target_ulong pc)
1312{
1313    tcg_gen_movi_tl(cpu_PC, pc);
1314}
1315
1316static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1317{
1318    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1319    if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
1320        gen_save_pc(ctx->base.pc_next);
1321        ctx->saved_pc = ctx->base.pc_next;
1322    }
1323    if (ctx->hflags != ctx->saved_hflags) {
1324        tcg_gen_movi_i32(hflags, ctx->hflags);
1325        ctx->saved_hflags = ctx->hflags;
1326        switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1327        case MIPS_HFLAG_BR:
1328            break;
1329        case MIPS_HFLAG_BC:
1330        case MIPS_HFLAG_BL:
1331        case MIPS_HFLAG_B:
1332            tcg_gen_movi_tl(btarget, ctx->btarget);
1333            break;
1334        }
1335    }
1336}
1337
1338static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1339{
1340    ctx->saved_hflags = ctx->hflags;
1341    switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1342    case MIPS_HFLAG_BR:
1343        break;
1344    case MIPS_HFLAG_BC:
1345    case MIPS_HFLAG_BL:
1346    case MIPS_HFLAG_B:
1347        ctx->btarget = env->btarget;
1348        break;
1349    }
1350}
1351
1352void generate_exception_err(DisasContext *ctx, int excp, int err)
1353{
1354    save_cpu_state(ctx, 1);
1355    gen_helper_raise_exception_err(cpu_env, tcg_constant_i32(excp),
1356                                   tcg_constant_i32(err));
1357    ctx->base.is_jmp = DISAS_NORETURN;
1358}
1359
1360void generate_exception(DisasContext *ctx, int excp)
1361{
1362    gen_helper_raise_exception(cpu_env, tcg_constant_i32(excp));
1363}
1364
1365void generate_exception_end(DisasContext *ctx, int excp)
1366{
1367    generate_exception_err(ctx, excp, 0);
1368}
1369
1370void gen_reserved_instruction(DisasContext *ctx)
1371{
1372    generate_exception_end(ctx, EXCP_RI);
1373}
1374
1375/* Floating point register moves. */
1376void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1377{
1378    if (ctx->hflags & MIPS_HFLAG_FRE) {
1379        generate_exception(ctx, EXCP_RI);
1380    }
1381    tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
1382}
1383
1384void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1385{
1386    TCGv_i64 t64;
1387    if (ctx->hflags & MIPS_HFLAG_FRE) {
1388        generate_exception(ctx, EXCP_RI);
1389    }
1390    t64 = tcg_temp_new_i64();
1391    tcg_gen_extu_i32_i64(t64, t);
1392    tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1393    tcg_temp_free_i64(t64);
1394}
1395
1396static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1397{
1398    if (ctx->hflags & MIPS_HFLAG_F64) {
1399        tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
1400    } else {
1401        gen_load_fpr32(ctx, t, reg | 1);
1402    }
1403}
1404
1405static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1406{
1407    if (ctx->hflags & MIPS_HFLAG_F64) {
1408        TCGv_i64 t64 = tcg_temp_new_i64();
1409        tcg_gen_extu_i32_i64(t64, t);
1410        tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1411        tcg_temp_free_i64(t64);
1412    } else {
1413        gen_store_fpr32(ctx, t, reg | 1);
1414    }
1415}
1416
1417void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1418{
1419    if (ctx->hflags & MIPS_HFLAG_F64) {
1420        tcg_gen_mov_i64(t, fpu_f64[reg]);
1421    } else {
1422        tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1423    }
1424}
1425
1426void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1427{
1428    if (ctx->hflags & MIPS_HFLAG_F64) {
1429        tcg_gen_mov_i64(fpu_f64[reg], t);
1430    } else {
1431        TCGv_i64 t0;
1432        tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1433        t0 = tcg_temp_new_i64();
1434        tcg_gen_shri_i64(t0, t, 32);
1435        tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1436        tcg_temp_free_i64(t0);
1437    }
1438}
1439
1440int get_fp_bit(int cc)
1441{
1442    if (cc) {
1443        return 24 + cc;
1444    } else {
1445        return 23;
1446    }
1447}
1448
1449/* Addresses computation */
1450void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1451{
1452    tcg_gen_add_tl(ret, arg0, arg1);
1453
1454#if defined(TARGET_MIPS64)
1455    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1456        tcg_gen_ext32s_i64(ret, ret);
1457    }
1458#endif
1459}
1460
1461static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
1462                                    target_long ofs)
1463{
1464    tcg_gen_addi_tl(ret, base, ofs);
1465
1466#if defined(TARGET_MIPS64)
1467    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1468        tcg_gen_ext32s_i64(ret, ret);
1469    }
1470#endif
1471}
1472
1473/* Addresses computation (translation time) */
1474static target_long addr_add(DisasContext *ctx, target_long base,
1475                            target_long offset)
1476{
1477    target_long sum = base + offset;
1478
1479#if defined(TARGET_MIPS64)
1480    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1481        sum = (int32_t)sum;
1482    }
1483#endif
1484    return sum;
1485}
1486
1487/* Sign-extract the low 32-bits to a target_long.  */
1488void gen_move_low32(TCGv ret, TCGv_i64 arg)
1489{
1490#if defined(TARGET_MIPS64)
1491    tcg_gen_ext32s_i64(ret, arg);
1492#else
1493    tcg_gen_extrl_i64_i32(ret, arg);
1494#endif
1495}
1496
1497/* Sign-extract the high 32-bits to a target_long.  */
1498void gen_move_high32(TCGv ret, TCGv_i64 arg)
1499{
1500#if defined(TARGET_MIPS64)
1501    tcg_gen_sari_i64(ret, arg, 32);
1502#else
1503    tcg_gen_extrh_i64_i32(ret, arg);
1504#endif
1505}
1506
1507bool check_cp0_enabled(DisasContext *ctx)
1508{
1509    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
1510        generate_exception_end(ctx, EXCP_CpU);
1511        return false;
1512    }
1513    return true;
1514}
1515
1516void check_cp1_enabled(DisasContext *ctx)
1517{
1518    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) {
1519        generate_exception_err(ctx, EXCP_CpU, 1);
1520    }
1521}
1522
1523/*
1524 * Verify that the processor is running with COP1X instructions enabled.
1525 * This is associated with the nabla symbol in the MIPS32 and MIPS64
1526 * opcode tables.
1527 */
1528void check_cop1x(DisasContext *ctx)
1529{
1530    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) {
1531        gen_reserved_instruction(ctx);
1532    }
1533}
1534
1535/*
1536 * Verify that the processor is running with 64-bit floating-point
1537 * operations enabled.
1538 */
1539void check_cp1_64bitmode(DisasContext *ctx)
1540{
1541    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) {
1542        gen_reserved_instruction(ctx);
1543    }
1544}
1545
1546/*
1547 * Verify if floating point register is valid; an operation is not defined
1548 * if bit 0 of any register specification is set and the FR bit in the
1549 * Status register equals zero, since the register numbers specify an
1550 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1551 * in the Status register equals one, both even and odd register numbers
1552 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1553 *
1554 * Multiple 64 bit wide registers can be checked by calling
1555 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1556 */
1557void check_cp1_registers(DisasContext *ctx, int regs)
1558{
1559    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) {
1560        gen_reserved_instruction(ctx);
1561    }
1562}
1563
1564/*
1565 * Verify that the processor is running with DSP instructions enabled.
1566 * This is enabled by CP0 Status register MX(24) bit.
1567 */
1568static inline void check_dsp(DisasContext *ctx)
1569{
1570    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1571        if (ctx->insn_flags & ASE_DSP) {
1572            generate_exception_end(ctx, EXCP_DSPDIS);
1573        } else {
1574            gen_reserved_instruction(ctx);
1575        }
1576    }
1577}
1578
1579static inline void check_dsp_r2(DisasContext *ctx)
1580{
1581    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
1582        if (ctx->insn_flags & ASE_DSP) {
1583            generate_exception_end(ctx, EXCP_DSPDIS);
1584        } else {
1585            gen_reserved_instruction(ctx);
1586        }
1587    }
1588}
1589
1590static inline void check_dsp_r3(DisasContext *ctx)
1591{
1592    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
1593        if (ctx->insn_flags & ASE_DSP) {
1594            generate_exception_end(ctx, EXCP_DSPDIS);
1595        } else {
1596            gen_reserved_instruction(ctx);
1597        }
1598    }
1599}
1600
1601/*
1602 * This code generates a "reserved instruction" exception if the
1603 * CPU does not support the instruction set corresponding to flags.
1604 */
1605void check_insn(DisasContext *ctx, uint64_t flags)
1606{
1607    if (unlikely(!(ctx->insn_flags & flags))) {
1608        gen_reserved_instruction(ctx);
1609    }
1610}
1611
1612/*
1613 * This code generates a "reserved instruction" exception if the
1614 * CPU has corresponding flag set which indicates that the instruction
1615 * has been removed.
1616 */
1617static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
1618{
1619    if (unlikely(ctx->insn_flags & flags)) {
1620        gen_reserved_instruction(ctx);
1621    }
1622}
1623
1624/*
1625 * The Linux kernel traps certain reserved instruction exceptions to
1626 * emulate the corresponding instructions. QEMU is the kernel in user
1627 * mode, so those traps are emulated by accepting the instructions.
1628 *
1629 * A reserved instruction exception is generated for flagged CPUs if
1630 * QEMU runs in system mode.
1631 */
1632static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
1633{
1634#ifndef CONFIG_USER_ONLY
1635    check_insn_opc_removed(ctx, flags);
1636#endif
1637}
1638
1639/*
1640 * This code generates a "reserved instruction" exception if the
1641 * CPU does not support 64-bit paired-single (PS) floating point data type.
1642 */
1643static inline void check_ps(DisasContext *ctx)
1644{
1645    if (unlikely(!ctx->ps)) {
1646        generate_exception(ctx, EXCP_RI);
1647    }
1648    check_cp1_64bitmode(ctx);
1649}
1650
1651/*
1652 * This code generates a "reserved instruction" exception if cpu is not
1653 * 64-bit or 64-bit instructions are not enabled.
1654 */
1655void check_mips_64(DisasContext *ctx)
1656{
1657    if (unlikely((TARGET_LONG_BITS != 64) || !(ctx->hflags & MIPS_HFLAG_64))) {
1658        gen_reserved_instruction(ctx);
1659    }
1660}
1661
1662#ifndef CONFIG_USER_ONLY
1663static inline void check_mvh(DisasContext *ctx)
1664{
1665    if (unlikely(!ctx->mvh)) {
1666        generate_exception(ctx, EXCP_RI);
1667    }
1668}
1669#endif
1670
1671/*
1672 * This code generates a "reserved instruction" exception if the
1673 * Config5 XNP bit is set.
1674 */
1675static inline void check_xnp(DisasContext *ctx)
1676{
1677    if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
1678        gen_reserved_instruction(ctx);
1679    }
1680}
1681
1682#ifndef CONFIG_USER_ONLY
1683/*
1684 * This code generates a "reserved instruction" exception if the
1685 * Config3 PW bit is NOT set.
1686 */
1687static inline void check_pw(DisasContext *ctx)
1688{
1689    if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
1690        gen_reserved_instruction(ctx);
1691    }
1692}
1693#endif
1694
1695/*
1696 * This code generates a "reserved instruction" exception if the
1697 * Config3 MT bit is NOT set.
1698 */
1699static inline void check_mt(DisasContext *ctx)
1700{
1701    if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
1702        gen_reserved_instruction(ctx);
1703    }
1704}
1705
1706#ifndef CONFIG_USER_ONLY
1707/*
1708 * This code generates a "coprocessor unusable" exception if CP0 is not
1709 * available, and, if that is not the case, generates a "reserved instruction"
1710 * exception if the Config5 MT bit is NOT set. This is needed for availability
1711 * control of some of MT ASE instructions.
1712 */
1713static inline void check_cp0_mt(DisasContext *ctx)
1714{
1715    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
1716        generate_exception_end(ctx, EXCP_CpU);
1717    } else {
1718        if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
1719            gen_reserved_instruction(ctx);
1720        }
1721    }
1722}
1723#endif
1724
1725/*
1726 * This code generates a "reserved instruction" exception if the
1727 * Config5 NMS bit is set.
1728 */
1729static inline void check_nms(DisasContext *ctx)
1730{
1731    if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
1732        gen_reserved_instruction(ctx);
1733    }
1734}
1735
1736/*
1737 * This code generates a "reserved instruction" exception if the
1738 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
1739 * Config2 TL, and Config5 L2C are unset.
1740 */
1741static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
1742{
1743    if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
1744                 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
1745                 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
1746                 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
1747                 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
1748                 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) {
1749        gen_reserved_instruction(ctx);
1750    }
1751}
1752
1753/*
1754 * This code generates a "reserved instruction" exception if the
1755 * Config5 EVA bit is NOT set.
1756 */
1757static inline void check_eva(DisasContext *ctx)
1758{
1759    if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
1760        gen_reserved_instruction(ctx);
1761    }
1762}
1763
1764
1765/*
1766 * Define small wrappers for gen_load_fpr* so that we have a uniform
1767 * calling interface for 32 and 64-bit FPRs.  No sense in changing
1768 * all callers for gen_load_fpr32 when we need the CTX parameter for
1769 * this one use.
1770 */
1771#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1772#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1773#define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
1774static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
1775                                               int ft, int fs, int cc)        \
1776{                                                                             \
1777    TCGv_i##bits fp0 = tcg_temp_new_i##bits();                                \
1778    TCGv_i##bits fp1 = tcg_temp_new_i##bits();                                \
1779    switch (ifmt) {                                                           \
1780    case FMT_PS:                                                              \
1781        check_ps(ctx);                                                        \
1782        break;                                                                \
1783    case FMT_D:                                                               \
1784        if (abs) {                                                            \
1785            check_cop1x(ctx);                                                 \
1786        }                                                                     \
1787        check_cp1_registers(ctx, fs | ft);                                    \
1788        break;                                                                \
1789    case FMT_S:                                                               \
1790        if (abs) {                                                            \
1791            check_cop1x(ctx);                                                 \
1792        }                                                                     \
1793        break;                                                                \
1794    }                                                                         \
1795    gen_ldcmp_fpr##bits(ctx, fp0, fs);                                        \
1796    gen_ldcmp_fpr##bits(ctx, fp1, ft);                                        \
1797    switch (n) {                                                              \
1798    case  0:                                                                  \
1799        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);         \
1800    break;                                                                    \
1801    case  1:                                                                  \
1802        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);        \
1803    break;                                                                    \
1804    case  2:                                                                  \
1805        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);        \
1806    break;                                                                    \
1807    case  3:                                                                  \
1808        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);       \
1809    break;                                                                    \
1810    case  4:                                                                  \
1811        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);       \
1812    break;                                                                    \
1813    case  5:                                                                  \
1814        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);       \
1815    break;                                                                    \
1816    case  6:                                                                  \
1817        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);       \
1818    break;                                                                    \
1819    case  7:                                                                  \
1820        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);       \
1821    break;                                                                    \
1822    case  8:                                                                  \
1823        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);        \
1824    break;                                                                    \
1825    case  9:                                                                  \
1826        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc);      \
1827    break;                                                                    \
1828    case 10:                                                                  \
1829        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);       \
1830    break;                                                                    \
1831    case 11:                                                                  \
1832        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);       \
1833    break;                                                                    \
1834    case 12:                                                                  \
1835        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);        \
1836    break;                                                                    \
1837    case 13:                                                                  \
1838        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);       \
1839    break;                                                                    \
1840    case 14:                                                                  \
1841        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);        \
1842    break;                                                                    \
1843    case 15:                                                                  \
1844        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);       \
1845    break;                                                                    \
1846    default:                                                                  \
1847        abort();                                                              \
1848    }                                                                         \
1849    tcg_temp_free_i##bits(fp0);                                               \
1850    tcg_temp_free_i##bits(fp1);                                               \
1851}
1852
1853FOP_CONDS(, 0, d, FMT_D, 64)
1854FOP_CONDS(abs, 1, d, FMT_D, 64)
1855FOP_CONDS(, 0, s, FMT_S, 32)
1856FOP_CONDS(abs, 1, s, FMT_S, 32)
1857FOP_CONDS(, 0, ps, FMT_PS, 64)
1858FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1859#undef FOP_CONDS
1860
1861#define FOP_CONDNS(fmt, ifmt, bits, STORE)                              \
1862static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n,         \
1863                                      int ft, int fs, int fd)           \
1864{                                                                       \
1865    TCGv_i ## bits fp0 = tcg_temp_new_i ## bits();                      \
1866    TCGv_i ## bits fp1 = tcg_temp_new_i ## bits();                      \
1867    if (ifmt == FMT_D) {                                                \
1868        check_cp1_registers(ctx, fs | ft | fd);                         \
1869    }                                                                   \
1870    gen_ldcmp_fpr ## bits(ctx, fp0, fs);                                \
1871    gen_ldcmp_fpr ## bits(ctx, fp1, ft);                                \
1872    switch (n) {                                                        \
1873    case  0:                                                            \
1874        gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1);       \
1875        break;                                                          \
1876    case  1:                                                            \
1877        gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1);       \
1878        break;                                                          \
1879    case  2:                                                            \
1880        gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1);       \
1881        break;                                                          \
1882    case  3:                                                            \
1883        gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1);      \
1884        break;                                                          \
1885    case  4:                                                            \
1886        gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1);       \
1887        break;                                                          \
1888    case  5:                                                            \
1889        gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1);      \
1890        break;                                                          \
1891    case  6:                                                            \
1892        gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1);       \
1893        break;                                                          \
1894    case  7:                                                            \
1895        gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1);      \
1896        break;                                                          \
1897    case  8:                                                            \
1898        gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1);      \
1899        break;                                                          \
1900    case  9:                                                            \
1901        gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1);      \
1902        break;                                                          \
1903    case 10:                                                            \
1904        gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1);      \
1905        break;                                                          \
1906    case 11:                                                            \
1907        gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1);     \
1908        break;                                                          \
1909    case 12:                                                            \
1910        gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1);      \
1911        break;                                                          \
1912    case 13:                                                            \
1913        gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1);     \
1914        break;                                                          \
1915    case 14:                                                            \
1916        gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1);      \
1917        break;                                                          \
1918    case 15:                                                            \
1919        gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1);     \
1920        break;                                                          \
1921    case 17:                                                            \
1922        gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1);       \
1923        break;                                                          \
1924    case 18:                                                            \
1925        gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1);      \
1926        break;                                                          \
1927    case 19:                                                            \
1928        gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1);       \
1929        break;                                                          \
1930    case 25:                                                            \
1931        gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1);      \
1932        break;                                                          \
1933    case 26:                                                            \
1934        gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1);     \
1935        break;                                                          \
1936    case 27:                                                            \
1937        gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1);      \
1938        break;                                                          \
1939    default:                                                            \
1940        abort();                                                        \
1941    }                                                                   \
1942    STORE;                                                              \
1943    tcg_temp_free_i ## bits(fp0);                                       \
1944    tcg_temp_free_i ## bits(fp1);                                       \
1945}
1946
1947FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
1948FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
1949#undef FOP_CONDNS
1950#undef gen_ldcmp_fpr32
1951#undef gen_ldcmp_fpr64
1952
1953/* load/store instructions. */
1954#ifdef CONFIG_USER_ONLY
1955#define OP_LD_ATOMIC(insn, fname)                                          \
1956static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
1957                                DisasContext *ctx)                         \
1958{                                                                          \
1959    TCGv t0 = tcg_temp_new();                                              \
1960    tcg_gen_mov_tl(t0, arg1);                                              \
1961    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
1962    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));            \
1963    tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval));            \
1964    tcg_temp_free(t0);                                                     \
1965}
1966#else
1967#define OP_LD_ATOMIC(insn, fname)                                          \
1968static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
1969                                DisasContext *ctx)                         \
1970{                                                                          \
1971    gen_helper_##insn(ret, cpu_env, arg1, tcg_constant_i32(mem_idx));      \
1972}
1973#endif
1974OP_LD_ATOMIC(ll, ld32s);
1975#if defined(TARGET_MIPS64)
1976OP_LD_ATOMIC(lld, ld64);
1977#endif
1978#undef OP_LD_ATOMIC
1979
1980void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset)
1981{
1982    if (base == 0) {
1983        tcg_gen_movi_tl(addr, offset);
1984    } else if (offset == 0) {
1985        gen_load_gpr(addr, base);
1986    } else {
1987        tcg_gen_movi_tl(addr, offset);
1988        gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1989    }
1990}
1991
1992static target_ulong pc_relative_pc(DisasContext *ctx)
1993{
1994    target_ulong pc = ctx->base.pc_next;
1995
1996    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1997        int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1998
1999        pc -= branch_bytes;
2000    }
2001
2002    pc &= ~(target_ulong)3;
2003    return pc;
2004}
2005
2006/* Load */
2007static void gen_ld(DisasContext *ctx, uint32_t opc,
2008                   int rt, int base, int offset)
2009{
2010    TCGv t0, t1, t2;
2011    int mem_idx = ctx->mem_idx;
2012
2013    if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F |
2014                                      INSN_LOONGSON3A)) {
2015        /*
2016         * Loongson CPU uses a load to zero register for prefetch.
2017         * We emulate it as a NOP. On other CPU we must perform the
2018         * actual memory access.
2019         */
2020        return;
2021    }
2022
2023    t0 = tcg_temp_new();
2024    gen_base_offset_addr(ctx, t0, base, offset);
2025
2026    switch (opc) {
2027#if defined(TARGET_MIPS64)
2028    case OPC_LWU:
2029        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
2030                           ctx->default_tcg_memop_mask);
2031        gen_store_gpr(t0, rt);
2032        break;
2033    case OPC_LD:
2034        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
2035                           ctx->default_tcg_memop_mask);
2036        gen_store_gpr(t0, rt);
2037        break;
2038    case OPC_LLD:
2039    case R6_OPC_LLD:
2040        op_ld_lld(t0, t0, mem_idx, ctx);
2041        gen_store_gpr(t0, rt);
2042        break;
2043    case OPC_LDL:
2044        t1 = tcg_temp_new();
2045        /*
2046         * Do a byte access to possibly trigger a page
2047         * fault with the unaligned address.
2048         */
2049        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2050        tcg_gen_andi_tl(t1, t0, 7);
2051        if (!cpu_is_bigendian(ctx)) {
2052            tcg_gen_xori_tl(t1, t1, 7);
2053        }
2054        tcg_gen_shli_tl(t1, t1, 3);
2055        tcg_gen_andi_tl(t0, t0, ~7);
2056        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2057        tcg_gen_shl_tl(t0, t0, t1);
2058        t2 = tcg_const_tl(-1);
2059        tcg_gen_shl_tl(t2, t2, t1);
2060        gen_load_gpr(t1, rt);
2061        tcg_gen_andc_tl(t1, t1, t2);
2062        tcg_temp_free(t2);
2063        tcg_gen_or_tl(t0, t0, t1);
2064        tcg_temp_free(t1);
2065        gen_store_gpr(t0, rt);
2066        break;
2067    case OPC_LDR:
2068        t1 = tcg_temp_new();
2069        /*
2070         * Do a byte access to possibly trigger a page
2071         * fault with the unaligned address.
2072         */
2073        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2074        tcg_gen_andi_tl(t1, t0, 7);
2075        if (cpu_is_bigendian(ctx)) {
2076            tcg_gen_xori_tl(t1, t1, 7);
2077        }
2078        tcg_gen_shli_tl(t1, t1, 3);
2079        tcg_gen_andi_tl(t0, t0, ~7);
2080        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2081        tcg_gen_shr_tl(t0, t0, t1);
2082        tcg_gen_xori_tl(t1, t1, 63);
2083        t2 = tcg_const_tl(0xfffffffffffffffeull);
2084        tcg_gen_shl_tl(t2, t2, t1);
2085        gen_load_gpr(t1, rt);
2086        tcg_gen_and_tl(t1, t1, t2);
2087        tcg_temp_free(t2);
2088        tcg_gen_or_tl(t0, t0, t1);
2089        tcg_temp_free(t1);
2090        gen_store_gpr(t0, rt);
2091        break;
2092    case OPC_LDPC:
2093        t1 = tcg_const_tl(pc_relative_pc(ctx));
2094        gen_op_addr_add(ctx, t0, t0, t1);
2095        tcg_temp_free(t1);
2096        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2097        gen_store_gpr(t0, rt);
2098        break;
2099#endif
2100    case OPC_LWPC:
2101        t1 = tcg_const_tl(pc_relative_pc(ctx));
2102        gen_op_addr_add(ctx, t0, t0, t1);
2103        tcg_temp_free(t1);
2104        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
2105        gen_store_gpr(t0, rt);
2106        break;
2107    case OPC_LWE:
2108        mem_idx = MIPS_HFLAG_UM;
2109        /* fall through */
2110    case OPC_LW:
2111        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
2112                           ctx->default_tcg_memop_mask);
2113        gen_store_gpr(t0, rt);
2114        break;
2115    case OPC_LHE:
2116        mem_idx = MIPS_HFLAG_UM;
2117        /* fall through */
2118    case OPC_LH:
2119        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
2120                           ctx->default_tcg_memop_mask);
2121        gen_store_gpr(t0, rt);
2122        break;
2123    case OPC_LHUE:
2124        mem_idx = MIPS_HFLAG_UM;
2125        /* fall through */
2126    case OPC_LHU:
2127        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
2128                           ctx->default_tcg_memop_mask);
2129        gen_store_gpr(t0, rt);
2130        break;
2131    case OPC_LBE:
2132        mem_idx = MIPS_HFLAG_UM;
2133        /* fall through */
2134    case OPC_LB:
2135        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
2136        gen_store_gpr(t0, rt);
2137        break;
2138    case OPC_LBUE:
2139        mem_idx = MIPS_HFLAG_UM;
2140        /* fall through */
2141    case OPC_LBU:
2142        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
2143        gen_store_gpr(t0, rt);
2144        break;
2145    case OPC_LWLE:
2146        mem_idx = MIPS_HFLAG_UM;
2147        /* fall through */
2148    case OPC_LWL:
2149        t1 = tcg_temp_new();
2150        /*
2151         * Do a byte access to possibly trigger a page
2152         * fault with the unaligned address.
2153         */
2154        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2155        tcg_gen_andi_tl(t1, t0, 3);
2156        if (!cpu_is_bigendian(ctx)) {
2157            tcg_gen_xori_tl(t1, t1, 3);
2158        }
2159        tcg_gen_shli_tl(t1, t1, 3);
2160        tcg_gen_andi_tl(t0, t0, ~3);
2161        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
2162        tcg_gen_shl_tl(t0, t0, t1);
2163        t2 = tcg_const_tl(-1);
2164        tcg_gen_shl_tl(t2, t2, t1);
2165        gen_load_gpr(t1, rt);
2166        tcg_gen_andc_tl(t1, t1, t2);
2167        tcg_temp_free(t2);
2168        tcg_gen_or_tl(t0, t0, t1);
2169        tcg_temp_free(t1);
2170        tcg_gen_ext32s_tl(t0, t0);
2171        gen_store_gpr(t0, rt);
2172        break;
2173    case OPC_LWRE:
2174        mem_idx = MIPS_HFLAG_UM;
2175        /* fall through */
2176    case OPC_LWR:
2177        t1 = tcg_temp_new();
2178        /*
2179         * Do a byte access to possibly trigger a page
2180         * fault with the unaligned address.
2181         */
2182        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2183        tcg_gen_andi_tl(t1, t0, 3);
2184        if (cpu_is_bigendian(ctx)) {
2185            tcg_gen_xori_tl(t1, t1, 3);
2186        }
2187        tcg_gen_shli_tl(t1, t1, 3);
2188        tcg_gen_andi_tl(t0, t0, ~3);
2189        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
2190        tcg_gen_shr_tl(t0, t0, t1);
2191        tcg_gen_xori_tl(t1, t1, 31);
2192        t2 = tcg_const_tl(0xfffffffeull);
2193        tcg_gen_shl_tl(t2, t2, t1);
2194        gen_load_gpr(t1, rt);
2195        tcg_gen_and_tl(t1, t1, t2);
2196        tcg_temp_free(t2);
2197        tcg_gen_or_tl(t0, t0, t1);
2198        tcg_temp_free(t1);
2199        tcg_gen_ext32s_tl(t0, t0);
2200        gen_store_gpr(t0, rt);
2201        break;
2202    case OPC_LLE:
2203        mem_idx = MIPS_HFLAG_UM;
2204        /* fall through */
2205    case OPC_LL:
2206    case R6_OPC_LL:
2207        op_ld_ll(t0, t0, mem_idx, ctx);
2208        gen_store_gpr(t0, rt);
2209        break;
2210    }
2211    tcg_temp_free(t0);
2212}
2213
2214/* Store */
2215static void gen_st(DisasContext *ctx, uint32_t opc, int rt,
2216                   int base, int offset)
2217{
2218    TCGv t0 = tcg_temp_new();
2219    TCGv t1 = tcg_temp_new();
2220    int mem_idx = ctx->mem_idx;
2221
2222    gen_base_offset_addr(ctx, t0, base, offset);
2223    gen_load_gpr(t1, rt);
2224    switch (opc) {
2225#if defined(TARGET_MIPS64)
2226    case OPC_SD:
2227        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
2228                           ctx->default_tcg_memop_mask);
2229        break;
2230    case OPC_SDL:
2231        gen_helper_0e2i(sdl, t1, t0, mem_idx);
2232        break;
2233    case OPC_SDR:
2234        gen_helper_0e2i(sdr, t1, t0, mem_idx);
2235        break;
2236#endif
2237    case OPC_SWE:
2238        mem_idx = MIPS_HFLAG_UM;
2239        /* fall through */
2240    case OPC_SW:
2241        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
2242                           ctx->default_tcg_memop_mask);
2243        break;
2244    case OPC_SHE:
2245        mem_idx = MIPS_HFLAG_UM;
2246        /* fall through */
2247    case OPC_SH:
2248        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
2249                           ctx->default_tcg_memop_mask);
2250        break;
2251    case OPC_SBE:
2252        mem_idx = MIPS_HFLAG_UM;
2253        /* fall through */
2254    case OPC_SB:
2255        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
2256        break;
2257    case OPC_SWLE:
2258        mem_idx = MIPS_HFLAG_UM;
2259        /* fall through */
2260    case OPC_SWL:
2261        gen_helper_0e2i(swl, t1, t0, mem_idx);
2262        break;
2263    case OPC_SWRE:
2264        mem_idx = MIPS_HFLAG_UM;
2265        /* fall through */
2266    case OPC_SWR:
2267        gen_helper_0e2i(swr, t1, t0, mem_idx);
2268        break;
2269    }
2270    tcg_temp_free(t0);
2271    tcg_temp_free(t1);
2272}
2273
2274
2275/* Store conditional */
2276static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
2277                        MemOp tcg_mo, bool eva)
2278{
2279    TCGv addr, t0, val;
2280    TCGLabel *l1 = gen_new_label();
2281    TCGLabel *done = gen_new_label();
2282
2283    t0 = tcg_temp_new();
2284    addr = tcg_temp_new();
2285    /* compare the address against that of the preceding LL */
2286    gen_base_offset_addr(ctx, addr, base, offset);
2287    tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1);
2288    tcg_temp_free(addr);
2289    tcg_gen_movi_tl(t0, 0);
2290    gen_store_gpr(t0, rt);
2291    tcg_gen_br(done);
2292
2293    gen_set_label(l1);
2294    /* generate cmpxchg */
2295    val = tcg_temp_new();
2296    gen_load_gpr(val, rt);
2297    tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val,
2298                              eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo);
2299    tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval);
2300    gen_store_gpr(t0, rt);
2301    tcg_temp_free(val);
2302
2303    gen_set_label(done);
2304    tcg_temp_free(t0);
2305}
2306
2307/* Load and store */
2308static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft,
2309                         TCGv t0)
2310{
2311    /*
2312     * Don't do NOP if destination is zero: we must perform the actual
2313     * memory access.
2314     */
2315    switch (opc) {
2316    case OPC_LWC1:
2317        {
2318            TCGv_i32 fp0 = tcg_temp_new_i32();
2319            tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2320                                ctx->default_tcg_memop_mask);
2321            gen_store_fpr32(ctx, fp0, ft);
2322            tcg_temp_free_i32(fp0);
2323        }
2324        break;
2325    case OPC_SWC1:
2326        {
2327            TCGv_i32 fp0 = tcg_temp_new_i32();
2328            gen_load_fpr32(ctx, fp0, ft);
2329            tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2330                                ctx->default_tcg_memop_mask);
2331            tcg_temp_free_i32(fp0);
2332        }
2333        break;
2334    case OPC_LDC1:
2335        {
2336            TCGv_i64 fp0 = tcg_temp_new_i64();
2337            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2338                                ctx->default_tcg_memop_mask);
2339            gen_store_fpr64(ctx, fp0, ft);
2340            tcg_temp_free_i64(fp0);
2341        }
2342        break;
2343    case OPC_SDC1:
2344        {
2345            TCGv_i64 fp0 = tcg_temp_new_i64();
2346            gen_load_fpr64(ctx, fp0, ft);
2347            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2348                                ctx->default_tcg_memop_mask);
2349            tcg_temp_free_i64(fp0);
2350        }
2351        break;
2352    default:
2353        MIPS_INVAL("flt_ldst");
2354        gen_reserved_instruction(ctx);
2355        break;
2356    }
2357}
2358
2359static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2360                          int rs, int16_t imm)
2361{
2362    TCGv t0 = tcg_temp_new();
2363
2364    if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2365        check_cp1_enabled(ctx);
2366        switch (op) {
2367        case OPC_LDC1:
2368        case OPC_SDC1:
2369            check_insn(ctx, ISA_MIPS2);
2370            /* Fallthrough */
2371        default:
2372            gen_base_offset_addr(ctx, t0, rs, imm);
2373            gen_flt_ldst(ctx, op, rt, t0);
2374        }
2375    } else {
2376        generate_exception_err(ctx, EXCP_CpU, 1);
2377    }
2378    tcg_temp_free(t0);
2379}
2380
2381/* Arithmetic with immediate operand */
2382static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2383                          int rt, int rs, int imm)
2384{
2385    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2386
2387    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
2388        /*
2389         * If no destination, treat it as a NOP.
2390         * For addi, we must generate the overflow exception when needed.
2391         */
2392        return;
2393    }
2394    switch (opc) {
2395    case OPC_ADDI:
2396        {
2397            TCGv t0 = tcg_temp_local_new();
2398            TCGv t1 = tcg_temp_new();
2399            TCGv t2 = tcg_temp_new();
2400            TCGLabel *l1 = gen_new_label();
2401
2402            gen_load_gpr(t1, rs);
2403            tcg_gen_addi_tl(t0, t1, uimm);
2404            tcg_gen_ext32s_tl(t0, t0);
2405
2406            tcg_gen_xori_tl(t1, t1, ~uimm);
2407            tcg_gen_xori_tl(t2, t0, uimm);
2408            tcg_gen_and_tl(t1, t1, t2);
2409            tcg_temp_free(t2);
2410            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2411            tcg_temp_free(t1);
2412            /* operands of same sign, result different sign */
2413            generate_exception(ctx, EXCP_OVERFLOW);
2414            gen_set_label(l1);
2415            tcg_gen_ext32s_tl(t0, t0);
2416            gen_store_gpr(t0, rt);
2417            tcg_temp_free(t0);
2418        }
2419        break;
2420    case OPC_ADDIU:
2421        if (rs != 0) {
2422            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2423            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2424        } else {
2425            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2426        }
2427        break;
2428#if defined(TARGET_MIPS64)
2429    case OPC_DADDI:
2430        {
2431            TCGv t0 = tcg_temp_local_new();
2432            TCGv t1 = tcg_temp_new();
2433            TCGv t2 = tcg_temp_new();
2434            TCGLabel *l1 = gen_new_label();
2435
2436            gen_load_gpr(t1, rs);
2437            tcg_gen_addi_tl(t0, t1, uimm);
2438
2439            tcg_gen_xori_tl(t1, t1, ~uimm);
2440            tcg_gen_xori_tl(t2, t0, uimm);
2441            tcg_gen_and_tl(t1, t1, t2);
2442            tcg_temp_free(t2);
2443            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2444            tcg_temp_free(t1);
2445            /* operands of same sign, result different sign */
2446            generate_exception(ctx, EXCP_OVERFLOW);
2447            gen_set_label(l1);
2448            gen_store_gpr(t0, rt);
2449            tcg_temp_free(t0);
2450        }
2451        break;
2452    case OPC_DADDIU:
2453        if (rs != 0) {
2454            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2455        } else {
2456            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2457        }
2458        break;
2459#endif
2460    }
2461}
2462
2463/* Logic with immediate operand */
2464static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2465                          int rt, int rs, int16_t imm)
2466{
2467    target_ulong uimm;
2468
2469    if (rt == 0) {
2470        /* If no destination, treat it as a NOP. */
2471        return;
2472    }
2473    uimm = (uint16_t)imm;
2474    switch (opc) {
2475    case OPC_ANDI:
2476        if (likely(rs != 0)) {
2477            tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2478        } else {
2479            tcg_gen_movi_tl(cpu_gpr[rt], 0);
2480        }
2481        break;
2482    case OPC_ORI:
2483        if (rs != 0) {
2484            tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2485        } else {
2486            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2487        }
2488        break;
2489    case OPC_XORI:
2490        if (likely(rs != 0)) {
2491            tcg_gen_xori_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_LUI:
2497        if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) {
2498            /* OPC_AUI */
2499            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2500            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2501        } else {
2502            tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2503        }
2504        break;
2505
2506    default:
2507        break;
2508    }
2509}
2510
2511/* Set on less than with immediate operand */
2512static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2513                        int rt, int rs, int16_t imm)
2514{
2515    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2516    TCGv t0;
2517
2518    if (rt == 0) {
2519        /* If no destination, treat it as a NOP. */
2520        return;
2521    }
2522    t0 = tcg_temp_new();
2523    gen_load_gpr(t0, rs);
2524    switch (opc) {
2525    case OPC_SLTI:
2526        tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2527        break;
2528    case OPC_SLTIU:
2529        tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2530        break;
2531    }
2532    tcg_temp_free(t0);
2533}
2534
2535/* Shifts with immediate operand */
2536static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2537                          int rt, int rs, int16_t imm)
2538{
2539    target_ulong uimm = ((uint16_t)imm) & 0x1f;
2540    TCGv t0;
2541
2542    if (rt == 0) {
2543        /* If no destination, treat it as a NOP. */
2544        return;
2545    }
2546
2547    t0 = tcg_temp_new();
2548    gen_load_gpr(t0, rs);
2549    switch (opc) {
2550    case OPC_SLL:
2551        tcg_gen_shli_tl(t0, t0, uimm);
2552        tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2553        break;
2554    case OPC_SRA:
2555        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2556        break;
2557    case OPC_SRL:
2558        if (uimm != 0) {
2559            tcg_gen_ext32u_tl(t0, t0);
2560            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2561        } else {
2562            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2563        }
2564        break;
2565    case OPC_ROTR:
2566        if (uimm != 0) {
2567            TCGv_i32 t1 = tcg_temp_new_i32();
2568
2569            tcg_gen_trunc_tl_i32(t1, t0);
2570            tcg_gen_rotri_i32(t1, t1, uimm);
2571            tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2572            tcg_temp_free_i32(t1);
2573        } else {
2574            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2575        }
2576        break;
2577#if defined(TARGET_MIPS64)
2578    case OPC_DSLL:
2579        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2580        break;
2581    case OPC_DSRA:
2582        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2583        break;
2584    case OPC_DSRL:
2585        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2586        break;
2587    case OPC_DROTR:
2588        if (uimm != 0) {
2589            tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2590        } else {
2591            tcg_gen_mov_tl(cpu_gpr[rt], t0);
2592        }
2593        break;
2594    case OPC_DSLL32:
2595        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2596        break;
2597    case OPC_DSRA32:
2598        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2599        break;
2600    case OPC_DSRL32:
2601        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2602        break;
2603    case OPC_DROTR32:
2604        tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2605        break;
2606#endif
2607    }
2608    tcg_temp_free(t0);
2609}
2610
2611/* Arithmetic */
2612static void gen_arith(DisasContext *ctx, uint32_t opc,
2613                      int rd, int rs, int rt)
2614{
2615    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2616       && opc != OPC_DADD && opc != OPC_DSUB) {
2617        /*
2618         * If no destination, treat it as a NOP.
2619         * For add & sub, we must generate the overflow exception when needed.
2620         */
2621        return;
2622    }
2623
2624    switch (opc) {
2625    case OPC_ADD:
2626        {
2627            TCGv t0 = tcg_temp_local_new();
2628            TCGv t1 = tcg_temp_new();
2629            TCGv t2 = tcg_temp_new();
2630            TCGLabel *l1 = gen_new_label();
2631
2632            gen_load_gpr(t1, rs);
2633            gen_load_gpr(t2, rt);
2634            tcg_gen_add_tl(t0, t1, t2);
2635            tcg_gen_ext32s_tl(t0, t0);
2636            tcg_gen_xor_tl(t1, t1, t2);
2637            tcg_gen_xor_tl(t2, t0, t2);
2638            tcg_gen_andc_tl(t1, t2, t1);
2639            tcg_temp_free(t2);
2640            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2641            tcg_temp_free(t1);
2642            /* operands of same sign, result different sign */
2643            generate_exception(ctx, EXCP_OVERFLOW);
2644            gen_set_label(l1);
2645            gen_store_gpr(t0, rd);
2646            tcg_temp_free(t0);
2647        }
2648        break;
2649    case OPC_ADDU:
2650        if (rs != 0 && rt != 0) {
2651            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2652            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2653        } else if (rs == 0 && rt != 0) {
2654            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2655        } else if (rs != 0 && rt == 0) {
2656            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2657        } else {
2658            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2659        }
2660        break;
2661    case OPC_SUB:
2662        {
2663            TCGv t0 = tcg_temp_local_new();
2664            TCGv t1 = tcg_temp_new();
2665            TCGv t2 = tcg_temp_new();
2666            TCGLabel *l1 = gen_new_label();
2667
2668            gen_load_gpr(t1, rs);
2669            gen_load_gpr(t2, rt);
2670            tcg_gen_sub_tl(t0, t1, t2);
2671            tcg_gen_ext32s_tl(t0, t0);
2672            tcg_gen_xor_tl(t2, t1, t2);
2673            tcg_gen_xor_tl(t1, t0, t1);
2674            tcg_gen_and_tl(t1, t1, t2);
2675            tcg_temp_free(t2);
2676            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2677            tcg_temp_free(t1);
2678            /*
2679             * operands of different sign, first operand and the result
2680             * of different sign
2681             */
2682            generate_exception(ctx, EXCP_OVERFLOW);
2683            gen_set_label(l1);
2684            gen_store_gpr(t0, rd);
2685            tcg_temp_free(t0);
2686        }
2687        break;
2688    case OPC_SUBU:
2689        if (rs != 0 && rt != 0) {
2690            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2691            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2692        } else if (rs == 0 && rt != 0) {
2693            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2694            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2695        } else if (rs != 0 && rt == 0) {
2696            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2697        } else {
2698            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2699        }
2700        break;
2701#if defined(TARGET_MIPS64)
2702    case OPC_DADD:
2703        {
2704            TCGv t0 = tcg_temp_local_new();
2705            TCGv t1 = tcg_temp_new();
2706            TCGv t2 = tcg_temp_new();
2707            TCGLabel *l1 = gen_new_label();
2708
2709            gen_load_gpr(t1, rs);
2710            gen_load_gpr(t2, rt);
2711            tcg_gen_add_tl(t0, t1, t2);
2712            tcg_gen_xor_tl(t1, t1, t2);
2713            tcg_gen_xor_tl(t2, t0, t2);
2714            tcg_gen_andc_tl(t1, t2, t1);
2715            tcg_temp_free(t2);
2716            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2717            tcg_temp_free(t1);
2718            /* operands of same sign, result different sign */
2719            generate_exception(ctx, EXCP_OVERFLOW);
2720            gen_set_label(l1);
2721            gen_store_gpr(t0, rd);
2722            tcg_temp_free(t0);
2723        }
2724        break;
2725    case OPC_DADDU:
2726        if (rs != 0 && rt != 0) {
2727            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2728        } else if (rs == 0 && rt != 0) {
2729            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2730        } else if (rs != 0 && rt == 0) {
2731            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2732        } else {
2733            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2734        }
2735        break;
2736    case OPC_DSUB:
2737        {
2738            TCGv t0 = tcg_temp_local_new();
2739            TCGv t1 = tcg_temp_new();
2740            TCGv t2 = tcg_temp_new();
2741            TCGLabel *l1 = gen_new_label();
2742
2743            gen_load_gpr(t1, rs);
2744            gen_load_gpr(t2, rt);
2745            tcg_gen_sub_tl(t0, t1, t2);
2746            tcg_gen_xor_tl(t2, t1, t2);
2747            tcg_gen_xor_tl(t1, t0, t1);
2748            tcg_gen_and_tl(t1, t1, t2);
2749            tcg_temp_free(t2);
2750            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2751            tcg_temp_free(t1);
2752            /*
2753             * Operands of different sign, first operand and result different
2754             * sign.
2755             */
2756            generate_exception(ctx, EXCP_OVERFLOW);
2757            gen_set_label(l1);
2758            gen_store_gpr(t0, rd);
2759            tcg_temp_free(t0);
2760        }
2761        break;
2762    case OPC_DSUBU:
2763        if (rs != 0 && rt != 0) {
2764            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2765        } else if (rs == 0 && rt != 0) {
2766            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2767        } else if (rs != 0 && rt == 0) {
2768            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2769        } else {
2770            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2771        }
2772        break;
2773#endif
2774    case OPC_MUL:
2775        if (likely(rs != 0 && rt != 0)) {
2776            tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2777            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2778        } else {
2779            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2780        }
2781        break;
2782    }
2783}
2784
2785/* Conditional move */
2786static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2787                          int rd, int rs, int rt)
2788{
2789    TCGv t0, t1, t2;
2790
2791    if (rd == 0) {
2792        /* If no destination, treat it as a NOP. */
2793        return;
2794    }
2795
2796    t0 = tcg_temp_new();
2797    gen_load_gpr(t0, rt);
2798    t1 = tcg_const_tl(0);
2799    t2 = tcg_temp_new();
2800    gen_load_gpr(t2, rs);
2801    switch (opc) {
2802    case OPC_MOVN:
2803        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2804        break;
2805    case OPC_MOVZ:
2806        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2807        break;
2808    case OPC_SELNEZ:
2809        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2810        break;
2811    case OPC_SELEQZ:
2812        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2813        break;
2814    }
2815    tcg_temp_free(t2);
2816    tcg_temp_free(t1);
2817    tcg_temp_free(t0);
2818}
2819
2820/* Logic */
2821static void gen_logic(DisasContext *ctx, uint32_t opc,
2822                      int rd, int rs, int rt)
2823{
2824    if (rd == 0) {
2825        /* If no destination, treat it as a NOP. */
2826        return;
2827    }
2828
2829    switch (opc) {
2830    case OPC_AND:
2831        if (likely(rs != 0 && rt != 0)) {
2832            tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2833        } else {
2834            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2835        }
2836        break;
2837    case OPC_NOR:
2838        if (rs != 0 && rt != 0) {
2839            tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2840        } else if (rs == 0 && rt != 0) {
2841            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2842        } else if (rs != 0 && rt == 0) {
2843            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2844        } else {
2845            tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2846        }
2847        break;
2848    case OPC_OR:
2849        if (likely(rs != 0 && rt != 0)) {
2850            tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2851        } else if (rs == 0 && rt != 0) {
2852            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2853        } else if (rs != 0 && rt == 0) {
2854            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2855        } else {
2856            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2857        }
2858        break;
2859    case OPC_XOR:
2860        if (likely(rs != 0 && rt != 0)) {
2861            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2862        } else if (rs == 0 && rt != 0) {
2863            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2864        } else if (rs != 0 && rt == 0) {
2865            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2866        } else {
2867            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2868        }
2869        break;
2870    }
2871}
2872
2873/* Set on lower than */
2874static void gen_slt(DisasContext *ctx, uint32_t opc,
2875                    int rd, int rs, int rt)
2876{
2877    TCGv t0, t1;
2878
2879    if (rd == 0) {
2880        /* If no destination, treat it as a NOP. */
2881        return;
2882    }
2883
2884    t0 = tcg_temp_new();
2885    t1 = tcg_temp_new();
2886    gen_load_gpr(t0, rs);
2887    gen_load_gpr(t1, rt);
2888    switch (opc) {
2889    case OPC_SLT:
2890        tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2891        break;
2892    case OPC_SLTU:
2893        tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2894        break;
2895    }
2896    tcg_temp_free(t0);
2897    tcg_temp_free(t1);
2898}
2899
2900/* Shifts */
2901static void gen_shift(DisasContext *ctx, uint32_t opc,
2902                      int rd, int rs, int rt)
2903{
2904    TCGv t0, t1;
2905
2906    if (rd == 0) {
2907        /*
2908         * If no destination, treat it as a NOP.
2909         * For add & sub, we must generate the overflow exception when needed.
2910         */
2911        return;
2912    }
2913
2914    t0 = tcg_temp_new();
2915    t1 = tcg_temp_new();
2916    gen_load_gpr(t0, rs);
2917    gen_load_gpr(t1, rt);
2918    switch (opc) {
2919    case OPC_SLLV:
2920        tcg_gen_andi_tl(t0, t0, 0x1f);
2921        tcg_gen_shl_tl(t0, t1, t0);
2922        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2923        break;
2924    case OPC_SRAV:
2925        tcg_gen_andi_tl(t0, t0, 0x1f);
2926        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2927        break;
2928    case OPC_SRLV:
2929        tcg_gen_ext32u_tl(t1, t1);
2930        tcg_gen_andi_tl(t0, t0, 0x1f);
2931        tcg_gen_shr_tl(t0, t1, t0);
2932        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2933        break;
2934    case OPC_ROTRV:
2935        {
2936            TCGv_i32 t2 = tcg_temp_new_i32();
2937            TCGv_i32 t3 = tcg_temp_new_i32();
2938
2939            tcg_gen_trunc_tl_i32(t2, t0);
2940            tcg_gen_trunc_tl_i32(t3, t1);
2941            tcg_gen_andi_i32(t2, t2, 0x1f);
2942            tcg_gen_rotr_i32(t2, t3, t2);
2943            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2944            tcg_temp_free_i32(t2);
2945            tcg_temp_free_i32(t3);
2946        }
2947        break;
2948#if defined(TARGET_MIPS64)
2949    case OPC_DSLLV:
2950        tcg_gen_andi_tl(t0, t0, 0x3f);
2951        tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2952        break;
2953    case OPC_DSRAV:
2954        tcg_gen_andi_tl(t0, t0, 0x3f);
2955        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2956        break;
2957    case OPC_DSRLV:
2958        tcg_gen_andi_tl(t0, t0, 0x3f);
2959        tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2960        break;
2961    case OPC_DROTRV:
2962        tcg_gen_andi_tl(t0, t0, 0x3f);
2963        tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2964        break;
2965#endif
2966    }
2967    tcg_temp_free(t0);
2968    tcg_temp_free(t1);
2969}
2970
2971/* Arithmetic on HI/LO registers */
2972static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
2973{
2974    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2975        /* Treat as NOP. */
2976        return;
2977    }
2978
2979    if (acc != 0) {
2980        check_dsp(ctx);
2981    }
2982
2983    switch (opc) {
2984    case OPC_MFHI:
2985#if defined(TARGET_MIPS64)
2986        if (acc != 0) {
2987            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2988        } else
2989#endif
2990        {
2991            tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2992        }
2993        break;
2994    case OPC_MFLO:
2995#if defined(TARGET_MIPS64)
2996        if (acc != 0) {
2997            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2998        } else
2999#endif
3000        {
3001            tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3002        }
3003        break;
3004    case OPC_MTHI:
3005        if (reg != 0) {
3006#if defined(TARGET_MIPS64)
3007            if (acc != 0) {
3008                tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3009            } else
3010#endif
3011            {
3012                tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3013            }
3014        } else {
3015            tcg_gen_movi_tl(cpu_HI[acc], 0);
3016        }
3017        break;
3018    case OPC_MTLO:
3019        if (reg != 0) {
3020#if defined(TARGET_MIPS64)
3021            if (acc != 0) {
3022                tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3023            } else
3024#endif
3025            {
3026                tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3027            }
3028        } else {
3029            tcg_gen_movi_tl(cpu_LO[acc], 0);
3030        }
3031        break;
3032    }
3033}
3034
3035static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3036                             MemOp memop)
3037{
3038    TCGv t0 = tcg_const_tl(addr);
3039    tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3040    gen_store_gpr(t0, reg);
3041    tcg_temp_free(t0);
3042}
3043
3044static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3045                             int rs)
3046{
3047    target_long offset;
3048    target_long addr;
3049
3050    switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
3051    case OPC_ADDIUPC:
3052        if (rs != 0) {
3053            offset = sextract32(ctx->opcode << 2, 0, 21);
3054            addr = addr_add(ctx, pc, offset);
3055            tcg_gen_movi_tl(cpu_gpr[rs], addr);
3056        }
3057        break;
3058    case R6_OPC_LWPC:
3059        offset = sextract32(ctx->opcode << 2, 0, 21);
3060        addr = addr_add(ctx, pc, offset);
3061        gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3062        break;
3063#if defined(TARGET_MIPS64)
3064    case OPC_LWUPC:
3065        check_mips_64(ctx);
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_TEUL);
3069        break;
3070#endif
3071    default:
3072        switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
3073        case OPC_AUIPC:
3074            if (rs != 0) {
3075                offset = sextract32(ctx->opcode, 0, 16) << 16;
3076                addr = addr_add(ctx, pc, offset);
3077                tcg_gen_movi_tl(cpu_gpr[rs], addr);
3078            }
3079            break;
3080        case OPC_ALUIPC:
3081            if (rs != 0) {
3082                offset = sextract32(ctx->opcode, 0, 16) << 16;
3083                addr = ~0xFFFF & addr_add(ctx, pc, offset);
3084                tcg_gen_movi_tl(cpu_gpr[rs], addr);
3085            }
3086            break;
3087#if defined(TARGET_MIPS64)
3088        case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3089        case R6_OPC_LDPC + (1 << 16):
3090        case R6_OPC_LDPC + (2 << 16):
3091        case R6_OPC_LDPC + (3 << 16):
3092            check_mips_64(ctx);
3093            offset = sextract32(ctx->opcode << 3, 0, 21);
3094            addr = addr_add(ctx, (pc & ~0x7), offset);
3095            gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3096            break;
3097#endif
3098        default:
3099            MIPS_INVAL("OPC_PCREL");
3100            gen_reserved_instruction(ctx);
3101            break;
3102        }
3103        break;
3104    }
3105}
3106
3107static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3108{
3109    TCGv t0, t1;
3110
3111    if (rd == 0) {
3112        /* Treat as NOP. */
3113        return;
3114    }
3115
3116    t0 = tcg_temp_new();
3117    t1 = tcg_temp_new();
3118
3119    gen_load_gpr(t0, rs);
3120    gen_load_gpr(t1, rt);
3121
3122    switch (opc) {
3123    case R6_OPC_DIV:
3124        {
3125            TCGv t2 = tcg_temp_new();
3126            TCGv t3 = tcg_temp_new();
3127            tcg_gen_ext32s_tl(t0, t0);
3128            tcg_gen_ext32s_tl(t1, t1);
3129            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3130            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3131            tcg_gen_and_tl(t2, t2, t3);
3132            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3133            tcg_gen_or_tl(t2, t2, t3);
3134            tcg_gen_movi_tl(t3, 0);
3135            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3136            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3137            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3138            tcg_temp_free(t3);
3139            tcg_temp_free(t2);
3140        }
3141        break;
3142    case R6_OPC_MOD:
3143        {
3144            TCGv t2 = tcg_temp_new();
3145            TCGv t3 = tcg_temp_new();
3146            tcg_gen_ext32s_tl(t0, t0);
3147            tcg_gen_ext32s_tl(t1, t1);
3148            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3149            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3150            tcg_gen_and_tl(t2, t2, t3);
3151            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3152            tcg_gen_or_tl(t2, t2, t3);
3153            tcg_gen_movi_tl(t3, 0);
3154            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3155            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3156            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3157            tcg_temp_free(t3);
3158            tcg_temp_free(t2);
3159        }
3160        break;
3161    case R6_OPC_DIVU:
3162        {
3163            TCGv t2 = tcg_const_tl(0);
3164            TCGv t3 = tcg_const_tl(1);
3165            tcg_gen_ext32u_tl(t0, t0);
3166            tcg_gen_ext32u_tl(t1, t1);
3167            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3168            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3169            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3170            tcg_temp_free(t3);
3171            tcg_temp_free(t2);
3172        }
3173        break;
3174    case R6_OPC_MODU:
3175        {
3176            TCGv t2 = tcg_const_tl(0);
3177            TCGv t3 = tcg_const_tl(1);
3178            tcg_gen_ext32u_tl(t0, t0);
3179            tcg_gen_ext32u_tl(t1, t1);
3180            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3181            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3182            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3183            tcg_temp_free(t3);
3184            tcg_temp_free(t2);
3185        }
3186        break;
3187    case R6_OPC_MUL:
3188        {
3189            TCGv_i32 t2 = tcg_temp_new_i32();
3190            TCGv_i32 t3 = tcg_temp_new_i32();
3191            tcg_gen_trunc_tl_i32(t2, t0);
3192            tcg_gen_trunc_tl_i32(t3, t1);
3193            tcg_gen_mul_i32(t2, t2, t3);
3194            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3195            tcg_temp_free_i32(t2);
3196            tcg_temp_free_i32(t3);
3197        }
3198        break;
3199    case R6_OPC_MUH:
3200        {
3201            TCGv_i32 t2 = tcg_temp_new_i32();
3202            TCGv_i32 t3 = tcg_temp_new_i32();
3203            tcg_gen_trunc_tl_i32(t2, t0);
3204            tcg_gen_trunc_tl_i32(t3, t1);
3205            tcg_gen_muls2_i32(t2, t3, t2, t3);
3206            tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3207            tcg_temp_free_i32(t2);
3208            tcg_temp_free_i32(t3);
3209        }
3210        break;
3211    case R6_OPC_MULU:
3212        {
3213            TCGv_i32 t2 = tcg_temp_new_i32();
3214            TCGv_i32 t3 = tcg_temp_new_i32();
3215            tcg_gen_trunc_tl_i32(t2, t0);
3216            tcg_gen_trunc_tl_i32(t3, t1);
3217            tcg_gen_mul_i32(t2, t2, t3);
3218            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3219            tcg_temp_free_i32(t2);
3220            tcg_temp_free_i32(t3);
3221        }
3222        break;
3223    case R6_OPC_MUHU:
3224        {
3225            TCGv_i32 t2 = tcg_temp_new_i32();
3226            TCGv_i32 t3 = tcg_temp_new_i32();
3227            tcg_gen_trunc_tl_i32(t2, t0);
3228            tcg_gen_trunc_tl_i32(t3, t1);
3229            tcg_gen_mulu2_i32(t2, t3, t2, t3);
3230            tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3231            tcg_temp_free_i32(t2);
3232            tcg_temp_free_i32(t3);
3233        }
3234        break;
3235#if defined(TARGET_MIPS64)
3236    case R6_OPC_DDIV:
3237        {
3238            TCGv t2 = tcg_temp_new();
3239            TCGv t3 = tcg_temp_new();
3240            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3241            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3242            tcg_gen_and_tl(t2, t2, t3);
3243            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3244            tcg_gen_or_tl(t2, t2, t3);
3245            tcg_gen_movi_tl(t3, 0);
3246            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3247            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3248            tcg_temp_free(t3);
3249            tcg_temp_free(t2);
3250        }
3251        break;
3252    case R6_OPC_DMOD:
3253        {
3254            TCGv t2 = tcg_temp_new();
3255            TCGv t3 = tcg_temp_new();
3256            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3257            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3258            tcg_gen_and_tl(t2, t2, t3);
3259            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3260            tcg_gen_or_tl(t2, t2, t3);
3261            tcg_gen_movi_tl(t3, 0);
3262            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3263            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3264            tcg_temp_free(t3);
3265            tcg_temp_free(t2);
3266        }
3267        break;
3268    case R6_OPC_DDIVU:
3269        {
3270            TCGv t2 = tcg_const_tl(0);
3271            TCGv t3 = tcg_const_tl(1);
3272            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3273            tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3274            tcg_temp_free(t3);
3275            tcg_temp_free(t2);
3276        }
3277        break;
3278    case R6_OPC_DMODU:
3279        {
3280            TCGv t2 = tcg_const_tl(0);
3281            TCGv t3 = tcg_const_tl(1);
3282            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3283            tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3284            tcg_temp_free(t3);
3285            tcg_temp_free(t2);
3286        }
3287        break;
3288    case R6_OPC_DMUL:
3289        tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3290        break;
3291    case R6_OPC_DMUH:
3292        {
3293            TCGv t2 = tcg_temp_new();
3294            tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3295            tcg_temp_free(t2);
3296        }
3297        break;
3298    case R6_OPC_DMULU:
3299        tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3300        break;
3301    case R6_OPC_DMUHU:
3302        {
3303            TCGv t2 = tcg_temp_new();
3304            tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3305            tcg_temp_free(t2);
3306        }
3307        break;
3308#endif
3309    default:
3310        MIPS_INVAL("r6 mul/div");
3311        gen_reserved_instruction(ctx);
3312        goto out;
3313    }
3314 out:
3315    tcg_temp_free(t0);
3316    tcg_temp_free(t1);
3317}
3318
3319#if defined(TARGET_MIPS64)
3320static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
3321{
3322    TCGv t0, t1;
3323
3324    t0 = tcg_temp_new();
3325    t1 = tcg_temp_new();
3326
3327    gen_load_gpr(t0, rs);
3328    gen_load_gpr(t1, rt);
3329
3330    switch (opc) {
3331    case MMI_OPC_DIV1:
3332        {
3333            TCGv t2 = tcg_temp_new();
3334            TCGv t3 = tcg_temp_new();
3335            tcg_gen_ext32s_tl(t0, t0);
3336            tcg_gen_ext32s_tl(t1, t1);
3337            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3338            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3339            tcg_gen_and_tl(t2, t2, t3);
3340            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3341            tcg_gen_or_tl(t2, t2, t3);
3342            tcg_gen_movi_tl(t3, 0);
3343            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3344            tcg_gen_div_tl(cpu_LO[1], t0, t1);
3345            tcg_gen_rem_tl(cpu_HI[1], t0, t1);
3346            tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3347            tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3348            tcg_temp_free(t3);
3349            tcg_temp_free(t2);
3350        }
3351        break;
3352    case MMI_OPC_DIVU1:
3353        {
3354            TCGv t2 = tcg_const_tl(0);
3355            TCGv t3 = tcg_const_tl(1);
3356            tcg_gen_ext32u_tl(t0, t0);
3357            tcg_gen_ext32u_tl(t1, t1);
3358            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3359            tcg_gen_divu_tl(cpu_LO[1], t0, t1);
3360            tcg_gen_remu_tl(cpu_HI[1], t0, t1);
3361            tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3362            tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3363            tcg_temp_free(t3);
3364            tcg_temp_free(t2);
3365        }
3366        break;
3367    default:
3368        MIPS_INVAL("div1 TX79");
3369        gen_reserved_instruction(ctx);
3370        goto out;
3371    }
3372 out:
3373    tcg_temp_free(t0);
3374    tcg_temp_free(t1);
3375}
3376#endif
3377
3378static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3379                       int acc, int rs, int rt)
3380{
3381    TCGv t0, t1;
3382
3383    t0 = tcg_temp_new();
3384    t1 = tcg_temp_new();
3385
3386    gen_load_gpr(t0, rs);
3387    gen_load_gpr(t1, rt);
3388
3389    if (acc != 0) {
3390        check_dsp(ctx);
3391    }
3392
3393    switch (opc) {
3394    case OPC_DIV:
3395        {
3396            TCGv t2 = tcg_temp_new();
3397            TCGv t3 = tcg_temp_new();
3398            tcg_gen_ext32s_tl(t0, t0);
3399            tcg_gen_ext32s_tl(t1, t1);
3400            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3401            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3402            tcg_gen_and_tl(t2, t2, t3);
3403            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3404            tcg_gen_or_tl(t2, t2, t3);
3405            tcg_gen_movi_tl(t3, 0);
3406            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3407            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3408            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3409            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3410            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3411            tcg_temp_free(t3);
3412            tcg_temp_free(t2);
3413        }
3414        break;
3415    case OPC_DIVU:
3416        {
3417            TCGv t2 = tcg_const_tl(0);
3418            TCGv t3 = tcg_const_tl(1);
3419            tcg_gen_ext32u_tl(t0, t0);
3420            tcg_gen_ext32u_tl(t1, t1);
3421            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3422            tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3423            tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3424            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3425            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3426            tcg_temp_free(t3);
3427            tcg_temp_free(t2);
3428        }
3429        break;
3430    case OPC_MULT:
3431        {
3432            TCGv_i32 t2 = tcg_temp_new_i32();
3433            TCGv_i32 t3 = tcg_temp_new_i32();
3434            tcg_gen_trunc_tl_i32(t2, t0);
3435            tcg_gen_trunc_tl_i32(t3, t1);
3436            tcg_gen_muls2_i32(t2, t3, t2, t3);
3437            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3438            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3439            tcg_temp_free_i32(t2);
3440            tcg_temp_free_i32(t3);
3441        }
3442        break;
3443    case OPC_MULTU:
3444        {
3445            TCGv_i32 t2 = tcg_temp_new_i32();
3446            TCGv_i32 t3 = tcg_temp_new_i32();
3447            tcg_gen_trunc_tl_i32(t2, t0);
3448            tcg_gen_trunc_tl_i32(t3, t1);
3449            tcg_gen_mulu2_i32(t2, t3, t2, t3);
3450            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3451            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3452            tcg_temp_free_i32(t2);
3453            tcg_temp_free_i32(t3);
3454        }
3455        break;
3456#if defined(TARGET_MIPS64)
3457    case OPC_DDIV:
3458        {
3459            TCGv t2 = tcg_temp_new();
3460            TCGv t3 = tcg_temp_new();
3461            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3462            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3463            tcg_gen_and_tl(t2, t2, t3);
3464            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3465            tcg_gen_or_tl(t2, t2, t3);
3466            tcg_gen_movi_tl(t3, 0);
3467            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3468            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3469            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3470            tcg_temp_free(t3);
3471            tcg_temp_free(t2);
3472        }
3473        break;
3474    case OPC_DDIVU:
3475        {
3476            TCGv t2 = tcg_const_tl(0);
3477            TCGv t3 = tcg_const_tl(1);
3478            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3479            tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3480            tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
3481            tcg_temp_free(t3);
3482            tcg_temp_free(t2);
3483        }
3484        break;
3485    case OPC_DMULT:
3486        tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3487        break;
3488    case OPC_DMULTU:
3489        tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3490        break;
3491#endif
3492    case OPC_MADD:
3493        {
3494            TCGv_i64 t2 = tcg_temp_new_i64();
3495            TCGv_i64 t3 = tcg_temp_new_i64();
3496
3497            tcg_gen_ext_tl_i64(t2, t0);
3498            tcg_gen_ext_tl_i64(t3, t1);
3499            tcg_gen_mul_i64(t2, t2, t3);
3500            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3501            tcg_gen_add_i64(t2, t2, t3);
3502            tcg_temp_free_i64(t3);
3503            gen_move_low32(cpu_LO[acc], t2);
3504            gen_move_high32(cpu_HI[acc], t2);
3505            tcg_temp_free_i64(t2);
3506        }
3507        break;
3508    case OPC_MADDU:
3509        {
3510            TCGv_i64 t2 = tcg_temp_new_i64();
3511            TCGv_i64 t3 = tcg_temp_new_i64();
3512
3513            tcg_gen_ext32u_tl(t0, t0);
3514            tcg_gen_ext32u_tl(t1, t1);
3515            tcg_gen_extu_tl_i64(t2, t0);
3516            tcg_gen_extu_tl_i64(t3, t1);
3517            tcg_gen_mul_i64(t2, t2, t3);
3518            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3519            tcg_gen_add_i64(t2, t2, t3);
3520            tcg_temp_free_i64(t3);
3521            gen_move_low32(cpu_LO[acc], t2);
3522            gen_move_high32(cpu_HI[acc], t2);
3523            tcg_temp_free_i64(t2);
3524        }
3525        break;
3526    case OPC_MSUB:
3527        {
3528            TCGv_i64 t2 = tcg_temp_new_i64();
3529            TCGv_i64 t3 = tcg_temp_new_i64();
3530
3531            tcg_gen_ext_tl_i64(t2, t0);
3532            tcg_gen_ext_tl_i64(t3, t1);
3533            tcg_gen_mul_i64(t2, t2, t3);
3534            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3535            tcg_gen_sub_i64(t2, t3, t2);
3536            tcg_temp_free_i64(t3);
3537            gen_move_low32(cpu_LO[acc], t2);
3538            gen_move_high32(cpu_HI[acc], t2);
3539            tcg_temp_free_i64(t2);
3540        }
3541        break;
3542    case OPC_MSUBU:
3543        {
3544            TCGv_i64 t2 = tcg_temp_new_i64();
3545            TCGv_i64 t3 = tcg_temp_new_i64();
3546
3547            tcg_gen_ext32u_tl(t0, t0);
3548            tcg_gen_ext32u_tl(t1, t1);
3549            tcg_gen_extu_tl_i64(t2, t0);
3550            tcg_gen_extu_tl_i64(t3, t1);
3551            tcg_gen_mul_i64(t2, t2, t3);
3552            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3553            tcg_gen_sub_i64(t2, t3, t2);
3554            tcg_temp_free_i64(t3);
3555            gen_move_low32(cpu_LO[acc], t2);
3556            gen_move_high32(cpu_HI[acc], t2);
3557            tcg_temp_free_i64(t2);
3558        }
3559        break;
3560    default:
3561        MIPS_INVAL("mul/div");
3562        gen_reserved_instruction(ctx);
3563        goto out;
3564    }
3565 out:
3566    tcg_temp_free(t0);
3567    tcg_temp_free(t1);
3568}
3569
3570/*
3571 * These MULT[U] and MADD[U] instructions implemented in for example
3572 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
3573 * architectures are special three-operand variants with the syntax
3574 *
3575 *     MULT[U][1] rd, rs, rt
3576 *
3577 * such that
3578 *
3579 *     (rd, LO, HI) <- rs * rt
3580 *
3581 * and
3582 *
3583 *     MADD[U][1] rd, rs, rt
3584 *
3585 * such that
3586 *
3587 *     (rd, LO, HI) <- (LO, HI) + rs * rt
3588 *
3589 * where the low-order 32-bits of the result is placed into both the
3590 * GPR rd and the special register LO. The high-order 32-bits of the
3591 * result is placed into the special register HI.
3592 *
3593 * If the GPR rd is omitted in assembly language, it is taken to be 0,
3594 * which is the zero register that always reads as 0.
3595 */
3596static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
3597                         int rd, int rs, int rt)
3598{
3599    TCGv t0 = tcg_temp_new();
3600    TCGv t1 = tcg_temp_new();
3601    int acc = 0;
3602
3603    gen_load_gpr(t0, rs);
3604    gen_load_gpr(t1, rt);
3605
3606    switch (opc) {
3607    case MMI_OPC_MULT1:
3608        acc = 1;
3609        /* Fall through */
3610    case OPC_MULT:
3611        {
3612            TCGv_i32 t2 = tcg_temp_new_i32();
3613            TCGv_i32 t3 = tcg_temp_new_i32();
3614            tcg_gen_trunc_tl_i32(t2, t0);
3615            tcg_gen_trunc_tl_i32(t3, t1);
3616            tcg_gen_muls2_i32(t2, t3, t2, t3);
3617            if (rd) {
3618                tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3619            }
3620            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3621            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3622            tcg_temp_free_i32(t2);
3623            tcg_temp_free_i32(t3);
3624        }
3625        break;
3626    case MMI_OPC_MULTU1:
3627        acc = 1;
3628        /* Fall through */
3629    case OPC_MULTU:
3630        {
3631            TCGv_i32 t2 = tcg_temp_new_i32();
3632            TCGv_i32 t3 = tcg_temp_new_i32();
3633            tcg_gen_trunc_tl_i32(t2, t0);
3634            tcg_gen_trunc_tl_i32(t3, t1);
3635            tcg_gen_mulu2_i32(t2, t3, t2, t3);
3636            if (rd) {
3637                tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3638            }
3639            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3640            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3641            tcg_temp_free_i32(t2);
3642            tcg_temp_free_i32(t3);
3643        }
3644        break;
3645    case MMI_OPC_MADD1:
3646        acc = 1;
3647        /* Fall through */
3648    case MMI_OPC_MADD:
3649        {
3650            TCGv_i64 t2 = tcg_temp_new_i64();
3651            TCGv_i64 t3 = tcg_temp_new_i64();
3652
3653            tcg_gen_ext_tl_i64(t2, t0);
3654            tcg_gen_ext_tl_i64(t3, t1);
3655            tcg_gen_mul_i64(t2, t2, t3);
3656            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3657            tcg_gen_add_i64(t2, t2, t3);
3658            tcg_temp_free_i64(t3);
3659            gen_move_low32(cpu_LO[acc], t2);
3660            gen_move_high32(cpu_HI[acc], t2);
3661            if (rd) {
3662                gen_move_low32(cpu_gpr[rd], t2);
3663            }
3664            tcg_temp_free_i64(t2);
3665        }
3666        break;
3667    case MMI_OPC_MADDU1:
3668        acc = 1;
3669        /* Fall through */
3670    case MMI_OPC_MADDU:
3671        {
3672            TCGv_i64 t2 = tcg_temp_new_i64();
3673            TCGv_i64 t3 = tcg_temp_new_i64();
3674
3675            tcg_gen_ext32u_tl(t0, t0);
3676            tcg_gen_ext32u_tl(t1, t1);
3677            tcg_gen_extu_tl_i64(t2, t0);
3678            tcg_gen_extu_tl_i64(t3, t1);
3679            tcg_gen_mul_i64(t2, t2, t3);
3680            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3681            tcg_gen_add_i64(t2, t2, t3);
3682            tcg_temp_free_i64(t3);
3683            gen_move_low32(cpu_LO[acc], t2);
3684            gen_move_high32(cpu_HI[acc], t2);
3685            if (rd) {
3686                gen_move_low32(cpu_gpr[rd], t2);
3687            }
3688            tcg_temp_free_i64(t2);
3689        }
3690        break;
3691    default:
3692        MIPS_INVAL("mul/madd TXx9");
3693        gen_reserved_instruction(ctx);
3694        goto out;
3695    }
3696
3697 out:
3698    tcg_temp_free(t0);
3699    tcg_temp_free(t1);
3700}
3701
3702static void gen_cl(DisasContext *ctx, uint32_t opc,
3703                   int rd, int rs)
3704{
3705    TCGv t0;
3706
3707    if (rd == 0) {
3708        /* Treat as NOP. */
3709        return;
3710    }
3711    t0 = cpu_gpr[rd];
3712    gen_load_gpr(t0, rs);
3713
3714    switch (opc) {
3715    case OPC_CLO:
3716    case R6_OPC_CLO:
3717#if defined(TARGET_MIPS64)
3718    case OPC_DCLO:
3719    case R6_OPC_DCLO:
3720#endif
3721        tcg_gen_not_tl(t0, t0);
3722        break;
3723    }
3724
3725    switch (opc) {
3726    case OPC_CLO:
3727    case R6_OPC_CLO:
3728    case OPC_CLZ:
3729    case R6_OPC_CLZ:
3730        tcg_gen_ext32u_tl(t0, t0);
3731        tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
3732        tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
3733        break;
3734#if defined(TARGET_MIPS64)
3735    case OPC_DCLO:
3736    case R6_OPC_DCLO:
3737    case OPC_DCLZ:
3738    case R6_OPC_DCLZ:
3739        tcg_gen_clzi_i64(t0, t0, 64);
3740        break;
3741#endif
3742    }
3743}
3744
3745/* Godson integer instructions */
3746static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3747                                 int rd, int rs, int rt)
3748{
3749    TCGv t0, t1;
3750
3751    if (rd == 0) {
3752        /* Treat as NOP. */
3753        return;
3754    }
3755
3756    switch (opc) {
3757    case OPC_MULT_G_2E:
3758    case OPC_MULT_G_2F:
3759    case OPC_MULTU_G_2E:
3760    case OPC_MULTU_G_2F:
3761#if defined(TARGET_MIPS64)
3762    case OPC_DMULT_G_2E:
3763    case OPC_DMULT_G_2F:
3764    case OPC_DMULTU_G_2E:
3765    case OPC_DMULTU_G_2F:
3766#endif
3767        t0 = tcg_temp_new();
3768        t1 = tcg_temp_new();
3769        break;
3770    default:
3771        t0 = tcg_temp_local_new();
3772        t1 = tcg_temp_local_new();
3773        break;
3774    }
3775
3776    gen_load_gpr(t0, rs);
3777    gen_load_gpr(t1, rt);
3778
3779    switch (opc) {
3780    case OPC_MULT_G_2E:
3781    case OPC_MULT_G_2F:
3782        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3783        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3784        break;
3785    case OPC_MULTU_G_2E:
3786    case OPC_MULTU_G_2F:
3787        tcg_gen_ext32u_tl(t0, t0);
3788        tcg_gen_ext32u_tl(t1, t1);
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_DIV_G_2E:
3793    case OPC_DIV_G_2F:
3794        {
3795            TCGLabel *l1 = gen_new_label();
3796            TCGLabel *l2 = gen_new_label();
3797            TCGLabel *l3 = gen_new_label();
3798            tcg_gen_ext32s_tl(t0, t0);
3799            tcg_gen_ext32s_tl(t1, t1);
3800            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3801            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3802            tcg_gen_br(l3);
3803            gen_set_label(l1);
3804            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3805            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3806            tcg_gen_mov_tl(cpu_gpr[rd], t0);
3807            tcg_gen_br(l3);
3808            gen_set_label(l2);
3809            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3810            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3811            gen_set_label(l3);
3812        }
3813        break;
3814    case OPC_DIVU_G_2E:
3815    case OPC_DIVU_G_2F:
3816        {
3817            TCGLabel *l1 = gen_new_label();
3818            TCGLabel *l2 = gen_new_label();
3819            tcg_gen_ext32u_tl(t0, t0);
3820            tcg_gen_ext32u_tl(t1, t1);
3821            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3822            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3823            tcg_gen_br(l2);
3824            gen_set_label(l1);
3825            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3826            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3827            gen_set_label(l2);
3828        }
3829        break;
3830    case OPC_MOD_G_2E:
3831    case OPC_MOD_G_2F:
3832        {
3833            TCGLabel *l1 = gen_new_label();
3834            TCGLabel *l2 = gen_new_label();
3835            TCGLabel *l3 = gen_new_label();
3836            tcg_gen_ext32u_tl(t0, t0);
3837            tcg_gen_ext32u_tl(t1, t1);
3838            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3839            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3840            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3841            gen_set_label(l1);
3842            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3843            tcg_gen_br(l3);
3844            gen_set_label(l2);
3845            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3846            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3847            gen_set_label(l3);
3848        }
3849        break;
3850    case OPC_MODU_G_2E:
3851    case OPC_MODU_G_2F:
3852        {
3853            TCGLabel *l1 = gen_new_label();
3854            TCGLabel *l2 = gen_new_label();
3855            tcg_gen_ext32u_tl(t0, t0);
3856            tcg_gen_ext32u_tl(t1, t1);
3857            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3858            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3859            tcg_gen_br(l2);
3860            gen_set_label(l1);
3861            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3862            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3863            gen_set_label(l2);
3864        }
3865        break;
3866#if defined(TARGET_MIPS64)
3867    case OPC_DMULT_G_2E:
3868    case OPC_DMULT_G_2F:
3869        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3870        break;
3871    case OPC_DMULTU_G_2E:
3872    case OPC_DMULTU_G_2F:
3873        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3874        break;
3875    case OPC_DDIV_G_2E:
3876    case OPC_DDIV_G_2F:
3877        {
3878            TCGLabel *l1 = gen_new_label();
3879            TCGLabel *l2 = gen_new_label();
3880            TCGLabel *l3 = gen_new_label();
3881            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3882            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3883            tcg_gen_br(l3);
3884            gen_set_label(l1);
3885            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3886            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3887            tcg_gen_mov_tl(cpu_gpr[rd], t0);
3888            tcg_gen_br(l3);
3889            gen_set_label(l2);
3890            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3891            gen_set_label(l3);
3892        }
3893        break;
3894    case OPC_DDIVU_G_2E:
3895    case OPC_DDIVU_G_2F:
3896        {
3897            TCGLabel *l1 = gen_new_label();
3898            TCGLabel *l2 = gen_new_label();
3899            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3900            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3901            tcg_gen_br(l2);
3902            gen_set_label(l1);
3903            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3904            gen_set_label(l2);
3905        }
3906        break;
3907    case OPC_DMOD_G_2E:
3908    case OPC_DMOD_G_2F:
3909        {
3910            TCGLabel *l1 = gen_new_label();
3911            TCGLabel *l2 = gen_new_label();
3912            TCGLabel *l3 = gen_new_label();
3913            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3914            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3915            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3916            gen_set_label(l1);
3917            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3918            tcg_gen_br(l3);
3919            gen_set_label(l2);
3920            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3921            gen_set_label(l3);
3922        }
3923        break;
3924    case OPC_DMODU_G_2E:
3925    case OPC_DMODU_G_2F:
3926        {
3927            TCGLabel *l1 = gen_new_label();
3928            TCGLabel *l2 = gen_new_label();
3929            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3930            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3931            tcg_gen_br(l2);
3932            gen_set_label(l1);
3933            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3934            gen_set_label(l2);
3935        }
3936        break;
3937#endif
3938    }
3939
3940    tcg_temp_free(t0);
3941    tcg_temp_free(t1);
3942}
3943
3944/* Loongson multimedia instructions */
3945static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3946{
3947    uint32_t opc, shift_max;
3948    TCGv_i64 t0, t1;
3949    TCGCond cond;
3950
3951    opc = MASK_LMMI(ctx->opcode);
3952    switch (opc) {
3953    case OPC_ADD_CP2:
3954    case OPC_SUB_CP2:
3955    case OPC_DADD_CP2:
3956    case OPC_DSUB_CP2:
3957        t0 = tcg_temp_local_new_i64();
3958        t1 = tcg_temp_local_new_i64();
3959        break;
3960    default:
3961        t0 = tcg_temp_new_i64();
3962        t1 = tcg_temp_new_i64();
3963        break;
3964    }
3965
3966    check_cp1_enabled(ctx);
3967    gen_load_fpr64(ctx, t0, rs);
3968    gen_load_fpr64(ctx, t1, rt);
3969
3970    switch (opc) {
3971    case OPC_PADDSH:
3972        gen_helper_paddsh(t0, t0, t1);
3973        break;
3974    case OPC_PADDUSH:
3975        gen_helper_paddush(t0, t0, t1);
3976        break;
3977    case OPC_PADDH:
3978        gen_helper_paddh(t0, t0, t1);
3979        break;
3980    case OPC_PADDW:
3981        gen_helper_paddw(t0, t0, t1);
3982        break;
3983    case OPC_PADDSB:
3984        gen_helper_paddsb(t0, t0, t1);
3985        break;
3986    case OPC_PADDUSB:
3987        gen_helper_paddusb(t0, t0, t1);
3988        break;
3989    case OPC_PADDB:
3990        gen_helper_paddb(t0, t0, t1);
3991        break;
3992
3993    case OPC_PSUBSH:
3994        gen_helper_psubsh(t0, t0, t1);
3995        break;
3996    case OPC_PSUBUSH:
3997        gen_helper_psubush(t0, t0, t1);
3998        break;
3999    case OPC_PSUBH:
4000        gen_helper_psubh(t0, t0, t1);
4001        break;
4002    case OPC_PSUBW:
4003        gen_helper_psubw(t0, t0, t1);
4004        break;
4005    case OPC_PSUBSB:
4006        gen_helper_psubsb(t0, t0, t1);
4007        break;
4008    case OPC_PSUBUSB:
4009        gen_helper_psubusb(t0, t0, t1);
4010        break;
4011    case OPC_PSUBB:
4012        gen_helper_psubb(t0, t0, t1);
4013        break;
4014
4015    case OPC_PSHUFH:
4016        gen_helper_pshufh(t0, t0, t1);
4017        break;
4018    case OPC_PACKSSWH:
4019        gen_helper_packsswh(t0, t0, t1);
4020        break;
4021    case OPC_PACKSSHB:
4022        gen_helper_packsshb(t0, t0, t1);
4023        break;
4024    case OPC_PACKUSHB:
4025        gen_helper_packushb(t0, t0, t1);
4026        break;
4027
4028    case OPC_PUNPCKLHW:
4029        gen_helper_punpcklhw(t0, t0, t1);
4030        break;
4031    case OPC_PUNPCKHHW:
4032        gen_helper_punpckhhw(t0, t0, t1);
4033        break;
4034    case OPC_PUNPCKLBH:
4035        gen_helper_punpcklbh(t0, t0, t1);
4036        break;
4037    case OPC_PUNPCKHBH:
4038        gen_helper_punpckhbh(t0, t0, t1);
4039        break;
4040    case OPC_PUNPCKLWD:
4041        gen_helper_punpcklwd(t0, t0, t1);
4042        break;
4043    case OPC_PUNPCKHWD:
4044        gen_helper_punpckhwd(t0, t0, t1);
4045        break;
4046
4047    case OPC_PAVGH:
4048        gen_helper_pavgh(t0, t0, t1);
4049        break;
4050    case OPC_PAVGB:
4051        gen_helper_pavgb(t0, t0, t1);
4052        break;
4053    case OPC_PMAXSH:
4054        gen_helper_pmaxsh(t0, t0, t1);
4055        break;
4056    case OPC_PMINSH:
4057        gen_helper_pminsh(t0, t0, t1);
4058        break;
4059    case OPC_PMAXUB:
4060        gen_helper_pmaxub(t0, t0, t1);
4061        break;
4062    case OPC_PMINUB:
4063        gen_helper_pminub(t0, t0, t1);
4064        break;
4065
4066    case OPC_PCMPEQW:
4067        gen_helper_pcmpeqw(t0, t0, t1);
4068        break;
4069    case OPC_PCMPGTW:
4070        gen_helper_pcmpgtw(t0, t0, t1);
4071        break;
4072    case OPC_PCMPEQH:
4073        gen_helper_pcmpeqh(t0, t0, t1);
4074        break;
4075    case OPC_PCMPGTH:
4076        gen_helper_pcmpgth(t0, t0, t1);
4077        break;
4078    case OPC_PCMPEQB:
4079        gen_helper_pcmpeqb(t0, t0, t1);
4080        break;
4081    case OPC_PCMPGTB:
4082        gen_helper_pcmpgtb(t0, t0, t1);
4083        break;
4084
4085    case OPC_PSLLW:
4086        gen_helper_psllw(t0, t0, t1);
4087        break;
4088    case OPC_PSLLH:
4089        gen_helper_psllh(t0, t0, t1);
4090        break;
4091    case OPC_PSRLW:
4092        gen_helper_psrlw(t0, t0, t1);
4093        break;
4094    case OPC_PSRLH:
4095        gen_helper_psrlh(t0, t0, t1);
4096        break;
4097    case OPC_PSRAW:
4098        gen_helper_psraw(t0, t0, t1);
4099        break;
4100    case OPC_PSRAH:
4101        gen_helper_psrah(t0, t0, t1);
4102        break;
4103
4104    case OPC_PMULLH:
4105        gen_helper_pmullh(t0, t0, t1);
4106        break;
4107    case OPC_PMULHH:
4108        gen_helper_pmulhh(t0, t0, t1);
4109        break;
4110    case OPC_PMULHUH:
4111        gen_helper_pmulhuh(t0, t0, t1);
4112        break;
4113    case OPC_PMADDHW:
4114        gen_helper_pmaddhw(t0, t0, t1);
4115        break;
4116
4117    case OPC_PASUBUB:
4118        gen_helper_pasubub(t0, t0, t1);
4119        break;
4120    case OPC_BIADD:
4121        gen_helper_biadd(t0, t0);
4122        break;
4123    case OPC_PMOVMSKB:
4124        gen_helper_pmovmskb(t0, t0);
4125        break;
4126
4127    case OPC_PADDD:
4128        tcg_gen_add_i64(t0, t0, t1);
4129        break;
4130    case OPC_PSUBD:
4131        tcg_gen_sub_i64(t0, t0, t1);
4132        break;
4133    case OPC_XOR_CP2:
4134        tcg_gen_xor_i64(t0, t0, t1);
4135        break;
4136    case OPC_NOR_CP2:
4137        tcg_gen_nor_i64(t0, t0, t1);
4138        break;
4139    case OPC_AND_CP2:
4140        tcg_gen_and_i64(t0, t0, t1);
4141        break;
4142    case OPC_OR_CP2:
4143        tcg_gen_or_i64(t0, t0, t1);
4144        break;
4145
4146    case OPC_PANDN:
4147        tcg_gen_andc_i64(t0, t1, t0);
4148        break;
4149
4150    case OPC_PINSRH_0:
4151        tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
4152        break;
4153    case OPC_PINSRH_1:
4154        tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
4155        break;
4156    case OPC_PINSRH_2:
4157        tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
4158        break;
4159    case OPC_PINSRH_3:
4160        tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
4161        break;
4162
4163    case OPC_PEXTRH:
4164        tcg_gen_andi_i64(t1, t1, 3);
4165        tcg_gen_shli_i64(t1, t1, 4);
4166        tcg_gen_shr_i64(t0, t0, t1);
4167        tcg_gen_ext16u_i64(t0, t0);
4168        break;
4169
4170    case OPC_ADDU_CP2:
4171        tcg_gen_add_i64(t0, t0, t1);
4172        tcg_gen_ext32s_i64(t0, t0);
4173        break;
4174    case OPC_SUBU_CP2:
4175        tcg_gen_sub_i64(t0, t0, t1);
4176        tcg_gen_ext32s_i64(t0, t0);
4177        break;
4178
4179    case OPC_SLL_CP2:
4180        shift_max = 32;
4181        goto do_shift;
4182    case OPC_SRL_CP2:
4183        shift_max = 32;
4184        goto do_shift;
4185    case OPC_SRA_CP2:
4186        shift_max = 32;
4187        goto do_shift;
4188    case OPC_DSLL_CP2:
4189        shift_max = 64;
4190        goto do_shift;
4191    case OPC_DSRL_CP2:
4192        shift_max = 64;
4193        goto do_shift;
4194    case OPC_DSRA_CP2:
4195        shift_max = 64;
4196        goto do_shift;
4197    do_shift:
4198        /* Make sure shift count isn't TCG undefined behaviour.  */
4199        tcg_gen_andi_i64(t1, t1, shift_max - 1);
4200
4201        switch (opc) {
4202        case OPC_SLL_CP2:
4203        case OPC_DSLL_CP2:
4204            tcg_gen_shl_i64(t0, t0, t1);
4205            break;
4206        case OPC_SRA_CP2:
4207        case OPC_DSRA_CP2:
4208            /*
4209             * Since SRA is UndefinedResult without sign-extended inputs,
4210             * we can treat SRA and DSRA the same.
4211             */
4212            tcg_gen_sar_i64(t0, t0, t1);
4213            break;
4214        case OPC_SRL_CP2:
4215            /* We want to shift in zeros for SRL; zero-extend first.  */
4216            tcg_gen_ext32u_i64(t0, t0);
4217            /* FALLTHRU */
4218        case OPC_DSRL_CP2:
4219            tcg_gen_shr_i64(t0, t0, t1);
4220            break;
4221        }
4222
4223        if (shift_max == 32) {
4224            tcg_gen_ext32s_i64(t0, t0);
4225        }
4226
4227        /* Shifts larger than MAX produce zero.  */
4228        tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4229        tcg_gen_neg_i64(t1, t1);
4230        tcg_gen_and_i64(t0, t0, t1);
4231        break;
4232
4233    case OPC_ADD_CP2:
4234    case OPC_DADD_CP2:
4235        {
4236            TCGv_i64 t2 = tcg_temp_new_i64();
4237            TCGLabel *lab = gen_new_label();
4238
4239            tcg_gen_mov_i64(t2, t0);
4240            tcg_gen_add_i64(t0, t1, t2);
4241            if (opc == OPC_ADD_CP2) {
4242                tcg_gen_ext32s_i64(t0, t0);
4243            }
4244            tcg_gen_xor_i64(t1, t1, t2);
4245            tcg_gen_xor_i64(t2, t2, t0);
4246            tcg_gen_andc_i64(t1, t2, t1);
4247            tcg_temp_free_i64(t2);
4248            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4249            generate_exception(ctx, EXCP_OVERFLOW);
4250            gen_set_label(lab);
4251            break;
4252        }
4253
4254    case OPC_SUB_CP2:
4255    case OPC_DSUB_CP2:
4256        {
4257            TCGv_i64 t2 = tcg_temp_new_i64();
4258            TCGLabel *lab = gen_new_label();
4259
4260            tcg_gen_mov_i64(t2, t0);
4261            tcg_gen_sub_i64(t0, t1, t2);
4262            if (opc == OPC_SUB_CP2) {
4263                tcg_gen_ext32s_i64(t0, t0);
4264            }
4265            tcg_gen_xor_i64(t1, t1, t2);
4266            tcg_gen_xor_i64(t2, t2, t0);
4267            tcg_gen_and_i64(t1, t1, t2);
4268            tcg_temp_free_i64(t2);
4269            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4270            generate_exception(ctx, EXCP_OVERFLOW);
4271            gen_set_label(lab);
4272            break;
4273        }
4274
4275    case OPC_PMULUW:
4276        tcg_gen_ext32u_i64(t0, t0);
4277        tcg_gen_ext32u_i64(t1, t1);
4278        tcg_gen_mul_i64(t0, t0, t1);
4279        break;
4280
4281    case OPC_SEQU_CP2:
4282    case OPC_SEQ_CP2:
4283        cond = TCG_COND_EQ;
4284        goto do_cc_cond;
4285        break;
4286    case OPC_SLTU_CP2:
4287        cond = TCG_COND_LTU;
4288        goto do_cc_cond;
4289        break;
4290    case OPC_SLT_CP2:
4291        cond = TCG_COND_LT;
4292        goto do_cc_cond;
4293        break;
4294    case OPC_SLEU_CP2:
4295        cond = TCG_COND_LEU;
4296        goto do_cc_cond;
4297        break;
4298    case OPC_SLE_CP2:
4299        cond = TCG_COND_LE;
4300    do_cc_cond:
4301        {
4302            int cc = (ctx->opcode >> 8) & 0x7;
4303            TCGv_i64 t64 = tcg_temp_new_i64();
4304            TCGv_i32 t32 = tcg_temp_new_i32();
4305
4306            tcg_gen_setcond_i64(cond, t64, t0, t1);
4307            tcg_gen_extrl_i64_i32(t32, t64);
4308            tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32,
4309                                get_fp_bit(cc), 1);
4310
4311            tcg_temp_free_i32(t32);
4312            tcg_temp_free_i64(t64);
4313        }
4314        goto no_rd;
4315        break;
4316    default:
4317        MIPS_INVAL("loongson_cp2");
4318        gen_reserved_instruction(ctx);
4319        return;
4320    }
4321
4322    gen_store_fpr64(ctx, t0, rd);
4323
4324no_rd:
4325    tcg_temp_free_i64(t0);
4326    tcg_temp_free_i64(t1);
4327}
4328
4329static void gen_loongson_lswc2(DisasContext *ctx, int rt,
4330                               int rs, int rd)
4331{
4332    TCGv t0, t1, t2;
4333    TCGv_i32 fp0;
4334#if defined(TARGET_MIPS64)
4335    int lsq_rt1 = ctx->opcode & 0x1f;
4336    int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4;
4337#endif
4338    int shf_offset = sextract32(ctx->opcode, 6, 8);
4339
4340    t0 = tcg_temp_new();
4341
4342    switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) {
4343#if defined(TARGET_MIPS64)
4344    case OPC_GSLQ:
4345        t1 = tcg_temp_new();
4346        gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4347        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4348                           ctx->default_tcg_memop_mask);
4349        gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4350        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
4351                           ctx->default_tcg_memop_mask);
4352        gen_store_gpr(t1, rt);
4353        gen_store_gpr(t0, lsq_rt1);
4354        tcg_temp_free(t1);
4355        break;
4356    case OPC_GSLQC1:
4357        check_cp1_enabled(ctx);
4358        t1 = tcg_temp_new();
4359        gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4360        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4361                           ctx->default_tcg_memop_mask);
4362        gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4363        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
4364                           ctx->default_tcg_memop_mask);
4365        gen_store_fpr64(ctx, t1, rt);
4366        gen_store_fpr64(ctx, t0, lsq_rt1);
4367        tcg_temp_free(t1);
4368        break;
4369    case OPC_GSSQ:
4370        t1 = tcg_temp_new();
4371        gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4372        gen_load_gpr(t1, rt);
4373        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4374                           ctx->default_tcg_memop_mask);
4375        gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4376        gen_load_gpr(t1, lsq_rt1);
4377        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4378                           ctx->default_tcg_memop_mask);
4379        tcg_temp_free(t1);
4380        break;
4381    case OPC_GSSQC1:
4382        check_cp1_enabled(ctx);
4383        t1 = tcg_temp_new();
4384        gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4385        gen_load_fpr64(ctx, t1, rt);
4386        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4387                           ctx->default_tcg_memop_mask);
4388        gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4389        gen_load_fpr64(ctx, t1, lsq_rt1);
4390        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4391                           ctx->default_tcg_memop_mask);
4392        tcg_temp_free(t1);
4393        break;
4394#endif
4395    case OPC_GSSHFL:
4396        switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4397        case OPC_GSLWLC1:
4398            check_cp1_enabled(ctx);
4399            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4400            t1 = tcg_temp_new();
4401            tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4402            tcg_gen_andi_tl(t1, t0, 3);
4403            if (!cpu_is_bigendian(ctx)) {
4404                tcg_gen_xori_tl(t1, t1, 3);
4405            }
4406            tcg_gen_shli_tl(t1, t1, 3);
4407            tcg_gen_andi_tl(t0, t0, ~3);
4408            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
4409            tcg_gen_shl_tl(t0, t0, t1);
4410            t2 = tcg_const_tl(-1);
4411            tcg_gen_shl_tl(t2, t2, t1);
4412            fp0 = tcg_temp_new_i32();
4413            gen_load_fpr32(ctx, fp0, rt);
4414            tcg_gen_ext_i32_tl(t1, fp0);
4415            tcg_gen_andc_tl(t1, t1, t2);
4416            tcg_temp_free(t2);
4417            tcg_gen_or_tl(t0, t0, t1);
4418            tcg_temp_free(t1);
4419#if defined(TARGET_MIPS64)
4420            tcg_gen_extrl_i64_i32(fp0, t0);
4421#else
4422            tcg_gen_ext32s_tl(fp0, t0);
4423#endif
4424            gen_store_fpr32(ctx, fp0, rt);
4425            tcg_temp_free_i32(fp0);
4426            break;
4427        case OPC_GSLWRC1:
4428            check_cp1_enabled(ctx);
4429            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4430            t1 = tcg_temp_new();
4431            tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4432            tcg_gen_andi_tl(t1, t0, 3);
4433            if (cpu_is_bigendian(ctx)) {
4434                tcg_gen_xori_tl(t1, t1, 3);
4435            }
4436            tcg_gen_shli_tl(t1, t1, 3);
4437            tcg_gen_andi_tl(t0, t0, ~3);
4438            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
4439            tcg_gen_shr_tl(t0, t0, t1);
4440            tcg_gen_xori_tl(t1, t1, 31);
4441            t2 = tcg_const_tl(0xfffffffeull);
4442            tcg_gen_shl_tl(t2, t2, t1);
4443            fp0 = tcg_temp_new_i32();
4444            gen_load_fpr32(ctx, fp0, rt);
4445            tcg_gen_ext_i32_tl(t1, fp0);
4446            tcg_gen_and_tl(t1, t1, t2);
4447            tcg_temp_free(t2);
4448            tcg_gen_or_tl(t0, t0, t1);
4449            tcg_temp_free(t1);
4450#if defined(TARGET_MIPS64)
4451            tcg_gen_extrl_i64_i32(fp0, t0);
4452#else
4453            tcg_gen_ext32s_tl(fp0, t0);
4454#endif
4455            gen_store_fpr32(ctx, fp0, rt);
4456            tcg_temp_free_i32(fp0);
4457            break;
4458#if defined(TARGET_MIPS64)
4459        case OPC_GSLDLC1:
4460            check_cp1_enabled(ctx);
4461            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4462            t1 = tcg_temp_new();
4463            tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4464            tcg_gen_andi_tl(t1, t0, 7);
4465            if (!cpu_is_bigendian(ctx)) {
4466                tcg_gen_xori_tl(t1, t1, 7);
4467            }
4468            tcg_gen_shli_tl(t1, t1, 3);
4469            tcg_gen_andi_tl(t0, t0, ~7);
4470            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
4471            tcg_gen_shl_tl(t0, t0, t1);
4472            t2 = tcg_const_tl(-1);
4473            tcg_gen_shl_tl(t2, t2, t1);
4474            gen_load_fpr64(ctx, t1, rt);
4475            tcg_gen_andc_tl(t1, t1, t2);
4476            tcg_temp_free(t2);
4477            tcg_gen_or_tl(t0, t0, t1);
4478            tcg_temp_free(t1);
4479            gen_store_fpr64(ctx, t0, rt);
4480            break;
4481        case OPC_GSLDRC1:
4482            check_cp1_enabled(ctx);
4483            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4484            t1 = tcg_temp_new();
4485            tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4486            tcg_gen_andi_tl(t1, t0, 7);
4487            if (cpu_is_bigendian(ctx)) {
4488                tcg_gen_xori_tl(t1, t1, 7);
4489            }
4490            tcg_gen_shli_tl(t1, t1, 3);
4491            tcg_gen_andi_tl(t0, t0, ~7);
4492            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
4493            tcg_gen_shr_tl(t0, t0, t1);
4494            tcg_gen_xori_tl(t1, t1, 63);
4495            t2 = tcg_const_tl(0xfffffffffffffffeull);
4496            tcg_gen_shl_tl(t2, t2, t1);
4497            gen_load_fpr64(ctx, t1, rt);
4498            tcg_gen_and_tl(t1, t1, t2);
4499            tcg_temp_free(t2);
4500            tcg_gen_or_tl(t0, t0, t1);
4501            tcg_temp_free(t1);
4502            gen_store_fpr64(ctx, t0, rt);
4503            break;
4504#endif
4505        default:
4506            MIPS_INVAL("loongson_gsshfl");
4507            gen_reserved_instruction(ctx);
4508            break;
4509        }
4510        break;
4511    case OPC_GSSHFS:
4512        switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4513        case OPC_GSSWLC1:
4514            check_cp1_enabled(ctx);
4515            t1 = tcg_temp_new();
4516            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4517            fp0 = tcg_temp_new_i32();
4518            gen_load_fpr32(ctx, fp0, rt);
4519            tcg_gen_ext_i32_tl(t1, fp0);
4520            gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
4521            tcg_temp_free_i32(fp0);
4522            tcg_temp_free(t1);
4523            break;
4524        case OPC_GSSWRC1:
4525            check_cp1_enabled(ctx);
4526            t1 = tcg_temp_new();
4527            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4528            fp0 = tcg_temp_new_i32();
4529            gen_load_fpr32(ctx, fp0, rt);
4530            tcg_gen_ext_i32_tl(t1, fp0);
4531            gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
4532            tcg_temp_free_i32(fp0);
4533            tcg_temp_free(t1);
4534            break;
4535#if defined(TARGET_MIPS64)
4536        case OPC_GSSDLC1:
4537            check_cp1_enabled(ctx);
4538            t1 = tcg_temp_new();
4539            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4540            gen_load_fpr64(ctx, t1, rt);
4541            gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
4542            tcg_temp_free(t1);
4543            break;
4544        case OPC_GSSDRC1:
4545            check_cp1_enabled(ctx);
4546            t1 = tcg_temp_new();
4547            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4548            gen_load_fpr64(ctx, t1, rt);
4549            gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
4550            tcg_temp_free(t1);
4551            break;
4552#endif
4553        default:
4554            MIPS_INVAL("loongson_gsshfs");
4555            gen_reserved_instruction(ctx);
4556            break;
4557        }
4558        break;
4559    default:
4560        MIPS_INVAL("loongson_gslsq");
4561        gen_reserved_instruction(ctx);
4562        break;
4563    }
4564    tcg_temp_free(t0);
4565}
4566
4567/* Loongson EXT LDC2/SDC2 */
4568static void gen_loongson_lsdc2(DisasContext *ctx, int rt,
4569                               int rs, int rd)
4570{
4571    int offset = sextract32(ctx->opcode, 3, 8);
4572    uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode);
4573    TCGv t0, t1;
4574    TCGv_i32 fp0;
4575
4576    /* Pre-conditions */
4577    switch (opc) {
4578    case OPC_GSLBX:
4579    case OPC_GSLHX:
4580    case OPC_GSLWX:
4581    case OPC_GSLDX:
4582        /* prefetch, implement as NOP */
4583        if (rt == 0) {
4584            return;
4585        }
4586        break;
4587    case OPC_GSSBX:
4588    case OPC_GSSHX:
4589    case OPC_GSSWX:
4590    case OPC_GSSDX:
4591        break;
4592    case OPC_GSLWXC1:
4593#if defined(TARGET_MIPS64)
4594    case OPC_GSLDXC1:
4595#endif
4596        check_cp1_enabled(ctx);
4597        /* prefetch, implement as NOP */
4598        if (rt == 0) {
4599            return;
4600        }
4601        break;
4602    case OPC_GSSWXC1:
4603#if defined(TARGET_MIPS64)
4604    case OPC_GSSDXC1:
4605#endif
4606        check_cp1_enabled(ctx);
4607        break;
4608    default:
4609        MIPS_INVAL("loongson_lsdc2");
4610        gen_reserved_instruction(ctx);
4611        return;
4612        break;
4613    }
4614
4615    t0 = tcg_temp_new();
4616
4617    gen_base_offset_addr(ctx, t0, rs, offset);
4618    gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4619
4620    switch (opc) {
4621    case OPC_GSLBX:
4622        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
4623        gen_store_gpr(t0, rt);
4624        break;
4625    case OPC_GSLHX:
4626        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
4627                           ctx->default_tcg_memop_mask);
4628        gen_store_gpr(t0, rt);
4629        break;
4630    case OPC_GSLWX:
4631        gen_base_offset_addr(ctx, t0, rs, offset);
4632        if (rd) {
4633            gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4634        }
4635        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
4636                           ctx->default_tcg_memop_mask);
4637        gen_store_gpr(t0, rt);
4638        break;
4639#if defined(TARGET_MIPS64)
4640    case OPC_GSLDX:
4641        gen_base_offset_addr(ctx, t0, rs, offset);
4642        if (rd) {
4643            gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4644        }
4645        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
4646                           ctx->default_tcg_memop_mask);
4647        gen_store_gpr(t0, rt);
4648        break;
4649#endif
4650    case OPC_GSLWXC1:
4651        gen_base_offset_addr(ctx, t0, rs, offset);
4652        if (rd) {
4653            gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4654        }
4655        fp0 = tcg_temp_new_i32();
4656        tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
4657                            ctx->default_tcg_memop_mask);
4658        gen_store_fpr32(ctx, fp0, rt);
4659        tcg_temp_free_i32(fp0);
4660        break;
4661#if defined(TARGET_MIPS64)
4662    case OPC_GSLDXC1:
4663        gen_base_offset_addr(ctx, t0, rs, offset);
4664        if (rd) {
4665            gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4666        }
4667        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
4668                           ctx->default_tcg_memop_mask);
4669        gen_store_fpr64(ctx, t0, rt);
4670        break;
4671#endif
4672    case OPC_GSSBX:
4673        t1 = tcg_temp_new();
4674        gen_load_gpr(t1, rt);
4675        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB);
4676        tcg_temp_free(t1);
4677        break;
4678    case OPC_GSSHX:
4679        t1 = tcg_temp_new();
4680        gen_load_gpr(t1, rt);
4681        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
4682                           ctx->default_tcg_memop_mask);
4683        tcg_temp_free(t1);
4684        break;
4685    case OPC_GSSWX:
4686        t1 = tcg_temp_new();
4687        gen_load_gpr(t1, rt);
4688        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
4689                           ctx->default_tcg_memop_mask);
4690        tcg_temp_free(t1);
4691        break;
4692#if defined(TARGET_MIPS64)
4693    case OPC_GSSDX:
4694        t1 = tcg_temp_new();
4695        gen_load_gpr(t1, rt);
4696        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4697                           ctx->default_tcg_memop_mask);
4698        tcg_temp_free(t1);
4699        break;
4700#endif
4701    case OPC_GSSWXC1:
4702        fp0 = tcg_temp_new_i32();
4703        gen_load_fpr32(ctx, fp0, rt);
4704        tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
4705                            ctx->default_tcg_memop_mask);
4706        tcg_temp_free_i32(fp0);
4707        break;
4708#if defined(TARGET_MIPS64)
4709    case OPC_GSSDXC1:
4710        t1 = tcg_temp_new();
4711        gen_load_fpr64(ctx, t1, rt);
4712        tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, MO_TEQ |
4713                            ctx->default_tcg_memop_mask);
4714        tcg_temp_free(t1);
4715        break;
4716#endif
4717    default:
4718        break;
4719    }
4720
4721    tcg_temp_free(t0);
4722}
4723
4724/* Traps */
4725static void gen_trap(DisasContext *ctx, uint32_t opc,
4726                     int rs, int rt, int16_t imm)
4727{
4728    int cond;
4729    TCGv t0 = tcg_temp_new();
4730    TCGv t1 = tcg_temp_new();
4731
4732    cond = 0;
4733    /* Load needed operands */
4734    switch (opc) {
4735    case OPC_TEQ:
4736    case OPC_TGE:
4737    case OPC_TGEU:
4738    case OPC_TLT:
4739    case OPC_TLTU:
4740    case OPC_TNE:
4741        /* Compare two registers */
4742        if (rs != rt) {
4743            gen_load_gpr(t0, rs);
4744            gen_load_gpr(t1, rt);
4745            cond = 1;
4746        }
4747        break;
4748    case OPC_TEQI:
4749    case OPC_TGEI:
4750    case OPC_TGEIU:
4751    case OPC_TLTI:
4752    case OPC_TLTIU:
4753    case OPC_TNEI:
4754        /* Compare register to immediate */
4755        if (rs != 0 || imm != 0) {
4756            gen_load_gpr(t0, rs);
4757            tcg_gen_movi_tl(t1, (int32_t)imm);
4758            cond = 1;
4759        }
4760        break;
4761    }
4762    if (cond == 0) {
4763        switch (opc) {
4764        case OPC_TEQ:   /* rs == rs */
4765        case OPC_TEQI:  /* r0 == 0  */
4766        case OPC_TGE:   /* rs >= rs */
4767        case OPC_TGEI:  /* r0 >= 0  */
4768        case OPC_TGEU:  /* rs >= rs unsigned */
4769        case OPC_TGEIU: /* r0 >= 0  unsigned */
4770            /* Always trap */
4771            generate_exception_end(ctx, EXCP_TRAP);
4772            break;
4773        case OPC_TLT:   /* rs < rs           */
4774        case OPC_TLTI:  /* r0 < 0            */
4775        case OPC_TLTU:  /* rs < rs unsigned  */
4776        case OPC_TLTIU: /* r0 < 0  unsigned  */
4777        case OPC_TNE:   /* rs != rs          */
4778        case OPC_TNEI:  /* r0 != 0           */
4779            /* Never trap: treat as NOP. */
4780            break;
4781        }
4782    } else {
4783        TCGLabel *l1 = gen_new_label();
4784
4785        switch (opc) {
4786        case OPC_TEQ:
4787        case OPC_TEQI:
4788            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4789            break;
4790        case OPC_TGE:
4791        case OPC_TGEI:
4792            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4793            break;
4794        case OPC_TGEU:
4795        case OPC_TGEIU:
4796            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
4797            break;
4798        case OPC_TLT:
4799        case OPC_TLTI:
4800            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
4801            break;
4802        case OPC_TLTU:
4803        case OPC_TLTIU:
4804            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
4805            break;
4806        case OPC_TNE:
4807        case OPC_TNEI:
4808            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
4809            break;
4810        }
4811        generate_exception(ctx, EXCP_TRAP);
4812        gen_set_label(l1);
4813    }
4814    tcg_temp_free(t0);
4815    tcg_temp_free(t1);
4816}
4817
4818static void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
4819{
4820    if (translator_use_goto_tb(&ctx->base, dest)) {
4821        tcg_gen_goto_tb(n);
4822        gen_save_pc(dest);
4823        tcg_gen_exit_tb(ctx->base.tb, n);
4824    } else {
4825        gen_save_pc(dest);
4826        tcg_gen_lookup_and_goto_ptr();
4827    }
4828}
4829
4830/* Branches (before delay slot) */
4831static void gen_compute_branch(DisasContext *ctx, uint32_t opc,
4832                               int insn_bytes,
4833                               int rs, int rt, int32_t offset,
4834                               int delayslot_size)
4835{
4836    target_ulong btgt = -1;
4837    int blink = 0;
4838    int bcond_compute = 0;
4839    TCGv t0 = tcg_temp_new();
4840    TCGv t1 = tcg_temp_new();
4841
4842    if (ctx->hflags & MIPS_HFLAG_BMASK) {
4843#ifdef MIPS_DEBUG_DISAS
4844        LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
4845                  TARGET_FMT_lx "\n", ctx->base.pc_next);
4846#endif
4847        gen_reserved_instruction(ctx);
4848        goto out;
4849    }
4850
4851    /* Load needed operands */
4852    switch (opc) {
4853    case OPC_BEQ:
4854    case OPC_BEQL:
4855    case OPC_BNE:
4856    case OPC_BNEL:
4857        /* Compare two registers */
4858        if (rs != rt) {
4859            gen_load_gpr(t0, rs);
4860            gen_load_gpr(t1, rt);
4861            bcond_compute = 1;
4862        }
4863        btgt = ctx->base.pc_next + insn_bytes + offset;
4864        break;
4865    case OPC_BGEZ:
4866    case OPC_BGEZAL:
4867    case OPC_BGEZALL:
4868    case OPC_BGEZL:
4869    case OPC_BGTZ:
4870    case OPC_BGTZL:
4871    case OPC_BLEZ:
4872    case OPC_BLEZL:
4873    case OPC_BLTZ:
4874    case OPC_BLTZAL:
4875    case OPC_BLTZALL:
4876    case OPC_BLTZL:
4877        /* Compare to zero */
4878        if (rs != 0) {
4879            gen_load_gpr(t0, rs);
4880            bcond_compute = 1;
4881        }
4882        btgt = ctx->base.pc_next + insn_bytes + offset;
4883        break;
4884    case OPC_BPOSGE32:
4885#if defined(TARGET_MIPS64)
4886    case OPC_BPOSGE64:
4887        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
4888#else
4889        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
4890#endif
4891        bcond_compute = 1;
4892        btgt = ctx->base.pc_next + insn_bytes + offset;
4893        break;
4894    case OPC_J:
4895    case OPC_JAL:
4896    case OPC_JALX:
4897        /* Jump to immediate */
4898        btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
4899            (uint32_t)offset;
4900        break;
4901    case OPC_JR:
4902    case OPC_JALR:
4903        /* Jump to register */
4904        if (offset != 0 && offset != 16) {
4905            /*
4906             * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
4907             * others are reserved.
4908             */
4909            MIPS_INVAL("jump hint");
4910            gen_reserved_instruction(ctx);
4911            goto out;
4912        }
4913        gen_load_gpr(btarget, rs);
4914        break;
4915    default:
4916        MIPS_INVAL("branch/jump");
4917        gen_reserved_instruction(ctx);
4918        goto out;
4919    }
4920    if (bcond_compute == 0) {
4921        /* No condition to be computed */
4922        switch (opc) {
4923        case OPC_BEQ:     /* rx == rx        */
4924        case OPC_BEQL:    /* rx == rx likely */
4925        case OPC_BGEZ:    /* 0 >= 0          */
4926        case OPC_BGEZL:   /* 0 >= 0 likely   */
4927        case OPC_BLEZ:    /* 0 <= 0          */
4928        case OPC_BLEZL:   /* 0 <= 0 likely   */
4929            /* Always take */
4930            ctx->hflags |= MIPS_HFLAG_B;
4931            break;
4932        case OPC_BGEZAL:  /* 0 >= 0          */
4933        case OPC_BGEZALL: /* 0 >= 0 likely   */
4934            /* Always take and link */
4935            blink = 31;
4936            ctx->hflags |= MIPS_HFLAG_B;
4937            break;
4938        case OPC_BNE:     /* rx != rx        */
4939        case OPC_BGTZ:    /* 0 > 0           */
4940        case OPC_BLTZ:    /* 0 < 0           */
4941            /* Treat as NOP. */
4942            goto out;
4943        case OPC_BLTZAL:  /* 0 < 0           */
4944            /*
4945             * Handle as an unconditional branch to get correct delay
4946             * slot checking.
4947             */
4948            blink = 31;
4949            btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
4950            ctx->hflags |= MIPS_HFLAG_B;
4951            break;
4952        case OPC_BLTZALL: /* 0 < 0 likely */
4953            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
4954            /* Skip the instruction in the delay slot */
4955            ctx->base.pc_next += 4;
4956            goto out;
4957        case OPC_BNEL:    /* rx != rx likely */
4958        case OPC_BGTZL:   /* 0 > 0 likely */
4959        case OPC_BLTZL:   /* 0 < 0 likely */
4960            /* Skip the instruction in the delay slot */
4961            ctx->base.pc_next += 4;
4962            goto out;
4963        case OPC_J:
4964            ctx->hflags |= MIPS_HFLAG_B;
4965            break;
4966        case OPC_JALX:
4967            ctx->hflags |= MIPS_HFLAG_BX;
4968            /* Fallthrough */
4969        case OPC_JAL:
4970            blink = 31;
4971            ctx->hflags |= MIPS_HFLAG_B;
4972            break;
4973        case OPC_JR:
4974            ctx->hflags |= MIPS_HFLAG_BR;
4975            break;
4976        case OPC_JALR:
4977            blink = rt;
4978            ctx->hflags |= MIPS_HFLAG_BR;
4979            break;
4980        default:
4981            MIPS_INVAL("branch/jump");
4982            gen_reserved_instruction(ctx);
4983            goto out;
4984        }
4985    } else {
4986        switch (opc) {
4987        case OPC_BEQ:
4988            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4989            goto not_likely;
4990        case OPC_BEQL:
4991            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
4992            goto likely;
4993        case OPC_BNE:
4994            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4995            goto not_likely;
4996        case OPC_BNEL:
4997            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
4998            goto likely;
4999        case OPC_BGEZ:
5000            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5001            goto not_likely;
5002        case OPC_BGEZL:
5003            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5004            goto likely;
5005        case OPC_BGEZAL:
5006            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5007            blink = 31;
5008            goto not_likely;
5009        case OPC_BGEZALL:
5010            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5011            blink = 31;
5012            goto likely;
5013        case OPC_BGTZ:
5014            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5015            goto not_likely;
5016        case OPC_BGTZL:
5017            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5018            goto likely;
5019        case OPC_BLEZ:
5020            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5021            goto not_likely;
5022        case OPC_BLEZL:
5023            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5024            goto likely;
5025        case OPC_BLTZ:
5026            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5027            goto not_likely;
5028        case OPC_BLTZL:
5029            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5030            goto likely;
5031        case OPC_BPOSGE32:
5032            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5033            goto not_likely;
5034#if defined(TARGET_MIPS64)
5035        case OPC_BPOSGE64:
5036            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
5037            goto not_likely;
5038#endif
5039        case OPC_BLTZAL:
5040            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5041            blink = 31;
5042        not_likely:
5043            ctx->hflags |= MIPS_HFLAG_BC;
5044            break;
5045        case OPC_BLTZALL:
5046            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5047            blink = 31;
5048        likely:
5049            ctx->hflags |= MIPS_HFLAG_BL;
5050            break;
5051        default:
5052            MIPS_INVAL("conditional branch/jump");
5053            gen_reserved_instruction(ctx);
5054            goto out;
5055        }
5056    }
5057
5058    ctx->btarget = btgt;
5059
5060    switch (delayslot_size) {
5061    case 2:
5062        ctx->hflags |= MIPS_HFLAG_BDS16;
5063        break;
5064    case 4:
5065        ctx->hflags |= MIPS_HFLAG_BDS32;
5066        break;
5067    }
5068
5069    if (blink > 0) {
5070        int post_delay = insn_bytes + delayslot_size;
5071        int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
5072
5073        tcg_gen_movi_tl(cpu_gpr[blink],
5074                        ctx->base.pc_next + post_delay + lowbit);
5075    }
5076
5077 out:
5078    if (insn_bytes == 2) {
5079        ctx->hflags |= MIPS_HFLAG_B16;
5080    }
5081    tcg_temp_free(t0);
5082    tcg_temp_free(t1);
5083}
5084
5085
5086/* special3 bitfield operations */
5087static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt,
5088                       int rs, int lsb, int msb)
5089{
5090    TCGv t0 = tcg_temp_new();
5091    TCGv t1 = tcg_temp_new();
5092
5093    gen_load_gpr(t1, rs);
5094    switch (opc) {
5095    case OPC_EXT:
5096        if (lsb + msb > 31) {
5097            goto fail;
5098        }
5099        if (msb != 31) {
5100            tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
5101        } else {
5102            /*
5103             * The two checks together imply that lsb == 0,
5104             * so this is a simple sign-extension.
5105             */
5106            tcg_gen_ext32s_tl(t0, t1);
5107        }
5108        break;
5109#if defined(TARGET_MIPS64)
5110    case OPC_DEXTU:
5111        lsb += 32;
5112        goto do_dext;
5113    case OPC_DEXTM:
5114        msb += 32;
5115        goto do_dext;
5116    case OPC_DEXT:
5117    do_dext:
5118        if (lsb + msb > 63) {
5119            goto fail;
5120        }
5121        tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
5122        break;
5123#endif
5124    case OPC_INS:
5125        if (lsb > msb) {
5126            goto fail;
5127        }
5128        gen_load_gpr(t0, rt);
5129        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
5130        tcg_gen_ext32s_tl(t0, t0);
5131        break;
5132#if defined(TARGET_MIPS64)
5133    case OPC_DINSU:
5134        lsb += 32;
5135        /* FALLTHRU */
5136    case OPC_DINSM:
5137        msb += 32;
5138        /* FALLTHRU */
5139    case OPC_DINS:
5140        if (lsb > msb) {
5141            goto fail;
5142        }
5143        gen_load_gpr(t0, rt);
5144        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
5145        break;
5146#endif
5147    default:
5148fail:
5149        MIPS_INVAL("bitops");
5150        gen_reserved_instruction(ctx);
5151        tcg_temp_free(t0);
5152        tcg_temp_free(t1);
5153        return;
5154    }
5155    gen_store_gpr(t0, rt);
5156    tcg_temp_free(t0);
5157    tcg_temp_free(t1);
5158}
5159
5160static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd)
5161{
5162    TCGv t0;
5163
5164    if (rd == 0) {
5165        /* If no destination, treat it as a NOP. */
5166        return;
5167    }
5168
5169    t0 = tcg_temp_new();
5170    gen_load_gpr(t0, rt);
5171    switch (op2) {
5172    case OPC_WSBH:
5173        {
5174            TCGv t1 = tcg_temp_new();
5175            TCGv t2 = tcg_const_tl(0x00FF00FF);
5176
5177            tcg_gen_shri_tl(t1, t0, 8);
5178            tcg_gen_and_tl(t1, t1, t2);
5179            tcg_gen_and_tl(t0, t0, t2);
5180            tcg_gen_shli_tl(t0, t0, 8);
5181            tcg_gen_or_tl(t0, t0, t1);
5182            tcg_temp_free(t2);
5183            tcg_temp_free(t1);
5184            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5185        }
5186        break;
5187    case OPC_SEB:
5188        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
5189        break;
5190    case OPC_SEH:
5191        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
5192        break;
5193#if defined(TARGET_MIPS64)
5194    case OPC_DSBH:
5195        {
5196            TCGv t1 = tcg_temp_new();
5197            TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
5198
5199            tcg_gen_shri_tl(t1, t0, 8);
5200            tcg_gen_and_tl(t1, t1, t2);
5201            tcg_gen_and_tl(t0, t0, t2);
5202            tcg_gen_shli_tl(t0, t0, 8);
5203            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
5204            tcg_temp_free(t2);
5205            tcg_temp_free(t1);
5206        }
5207        break;
5208    case OPC_DSHD:
5209        {
5210            TCGv t1 = tcg_temp_new();
5211            TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
5212
5213            tcg_gen_shri_tl(t1, t0, 16);
5214            tcg_gen_and_tl(t1, t1, t2);
5215            tcg_gen_and_tl(t0, t0, t2);
5216            tcg_gen_shli_tl(t0, t0, 16);
5217            tcg_gen_or_tl(t0, t0, t1);
5218            tcg_gen_shri_tl(t1, t0, 32);
5219            tcg_gen_shli_tl(t0, t0, 32);
5220            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
5221            tcg_temp_free(t2);
5222            tcg_temp_free(t1);
5223        }
5224        break;
5225#endif
5226    default:
5227        MIPS_INVAL("bsfhl");
5228        gen_reserved_instruction(ctx);
5229        tcg_temp_free(t0);
5230        return;
5231    }
5232    tcg_temp_free(t0);
5233}
5234
5235static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
5236                           int rt, int bits)
5237{
5238    TCGv t0;
5239    if (rd == 0) {
5240        /* Treat as NOP. */
5241        return;
5242    }
5243    t0 = tcg_temp_new();
5244    if (bits == 0 || bits == wordsz) {
5245        if (bits == 0) {
5246            gen_load_gpr(t0, rt);
5247        } else {
5248            gen_load_gpr(t0, rs);
5249        }
5250        switch (wordsz) {
5251        case 32:
5252            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5253            break;
5254#if defined(TARGET_MIPS64)
5255        case 64:
5256            tcg_gen_mov_tl(cpu_gpr[rd], t0);
5257            break;
5258#endif
5259        }
5260    } else {
5261        TCGv t1 = tcg_temp_new();
5262        gen_load_gpr(t0, rt);
5263        gen_load_gpr(t1, rs);
5264        switch (wordsz) {
5265        case 32:
5266            {
5267                TCGv_i64 t2 = tcg_temp_new_i64();
5268                tcg_gen_concat_tl_i64(t2, t1, t0);
5269                tcg_gen_shri_i64(t2, t2, 32 - bits);
5270                gen_move_low32(cpu_gpr[rd], t2);
5271                tcg_temp_free_i64(t2);
5272            }
5273            break;
5274#if defined(TARGET_MIPS64)
5275        case 64:
5276            tcg_gen_shli_tl(t0, t0, bits);
5277            tcg_gen_shri_tl(t1, t1, 64 - bits);
5278            tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
5279            break;
5280#endif
5281        }
5282        tcg_temp_free(t1);
5283    }
5284
5285    tcg_temp_free(t0);
5286}
5287
5288void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt, int bp)
5289{
5290    gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
5291}
5292
5293static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
5294{
5295    TCGv t0;
5296    if (rd == 0) {
5297        /* Treat as NOP. */
5298        return;
5299    }
5300    t0 = tcg_temp_new();
5301    gen_load_gpr(t0, rt);
5302    switch (opc) {
5303    case OPC_BITSWAP:
5304        gen_helper_bitswap(cpu_gpr[rd], t0);
5305        break;
5306#if defined(TARGET_MIPS64)
5307    case OPC_DBITSWAP:
5308        gen_helper_dbitswap(cpu_gpr[rd], t0);
5309        break;
5310#endif
5311    }
5312    tcg_temp_free(t0);
5313}
5314
5315#ifndef CONFIG_USER_ONLY
5316/* CP0 (MMU and control) */
5317static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
5318{
5319    TCGv_i64 t0 = tcg_temp_new_i64();
5320    TCGv_i64 t1 = tcg_temp_new_i64();
5321
5322    tcg_gen_ext_tl_i64(t0, arg);
5323    tcg_gen_ld_i64(t1, cpu_env, off);
5324#if defined(TARGET_MIPS64)
5325    tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
5326#else
5327    tcg_gen_concat32_i64(t1, t1, t0);
5328#endif
5329    tcg_gen_st_i64(t1, cpu_env, off);
5330    tcg_temp_free_i64(t1);
5331    tcg_temp_free_i64(t0);
5332}
5333
5334static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
5335{
5336    TCGv_i64 t0 = tcg_temp_new_i64();
5337    TCGv_i64 t1 = tcg_temp_new_i64();
5338
5339    tcg_gen_ext_tl_i64(t0, arg);
5340    tcg_gen_ld_i64(t1, cpu_env, off);
5341    tcg_gen_concat32_i64(t1, t1, t0);
5342    tcg_gen_st_i64(t1, cpu_env, off);
5343    tcg_temp_free_i64(t1);
5344    tcg_temp_free_i64(t0);
5345}
5346
5347static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
5348{
5349    TCGv_i64 t0 = tcg_temp_new_i64();
5350
5351    tcg_gen_ld_i64(t0, cpu_env, off);
5352#if defined(TARGET_MIPS64)
5353    tcg_gen_shri_i64(t0, t0, 30);
5354#else
5355    tcg_gen_shri_i64(t0, t0, 32);
5356#endif
5357    gen_move_low32(arg, t0);
5358    tcg_temp_free_i64(t0);
5359}
5360
5361static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
5362{
5363    TCGv_i64 t0 = tcg_temp_new_i64();
5364
5365    tcg_gen_ld_i64(t0, cpu_env, off);
5366    tcg_gen_shri_i64(t0, t0, 32 + shift);
5367    gen_move_low32(arg, t0);
5368    tcg_temp_free_i64(t0);
5369}
5370
5371static inline void gen_mfc0_load32(TCGv arg, target_ulong off)
5372{
5373    TCGv_i32 t0 = tcg_temp_new_i32();
5374
5375    tcg_gen_ld_i32(t0, cpu_env, off);
5376    tcg_gen_ext_i32_tl(arg, t0);
5377    tcg_temp_free_i32(t0);
5378}
5379
5380static inline void gen_mfc0_load64(TCGv arg, target_ulong off)
5381{
5382    tcg_gen_ld_tl(arg, cpu_env, off);
5383    tcg_gen_ext32s_tl(arg, arg);
5384}
5385
5386static inline void gen_mtc0_store32(TCGv arg, target_ulong off)
5387{
5388    TCGv_i32 t0 = tcg_temp_new_i32();
5389
5390    tcg_gen_trunc_tl_i32(t0, arg);
5391    tcg_gen_st_i32(t0, cpu_env, off);
5392    tcg_temp_free_i32(t0);
5393}
5394
5395#define CP0_CHECK(c)                            \
5396    do {                                        \
5397        if (!(c)) {                             \
5398            goto cp0_unimplemented;             \
5399        }                                       \
5400    } while (0)
5401
5402static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5403{
5404    const char *register_name = "invalid";
5405
5406    switch (reg) {
5407    case CP0_REGISTER_02:
5408        switch (sel) {
5409        case 0:
5410            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5411            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5412            register_name = "EntryLo0";
5413            break;
5414        default:
5415            goto cp0_unimplemented;
5416        }
5417        break;
5418    case CP0_REGISTER_03:
5419        switch (sel) {
5420        case CP0_REG03__ENTRYLO1:
5421            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5422            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5423            register_name = "EntryLo1";
5424            break;
5425        default:
5426            goto cp0_unimplemented;
5427        }
5428        break;
5429    case CP0_REGISTER_09:
5430        switch (sel) {
5431        case CP0_REG09__SAAR:
5432            CP0_CHECK(ctx->saar);
5433            gen_helper_mfhc0_saar(arg, cpu_env);
5434            register_name = "SAAR";
5435            break;
5436        default:
5437            goto cp0_unimplemented;
5438        }
5439        break;
5440    case CP0_REGISTER_17:
5441        switch (sel) {
5442        case CP0_REG17__LLADDR:
5443            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr),
5444                             ctx->CP0_LLAddr_shift);
5445            register_name = "LLAddr";
5446            break;
5447        case CP0_REG17__MAAR:
5448            CP0_CHECK(ctx->mrp);
5449            gen_helper_mfhc0_maar(arg, cpu_env);
5450            register_name = "MAAR";
5451            break;
5452        default:
5453            goto cp0_unimplemented;
5454        }
5455        break;
5456    case CP0_REGISTER_19:
5457        switch (sel) {
5458        case CP0_REG19__WATCHHI0:
5459        case CP0_REG19__WATCHHI1:
5460        case CP0_REG19__WATCHHI2:
5461        case CP0_REG19__WATCHHI3:
5462        case CP0_REG19__WATCHHI4:
5463        case CP0_REG19__WATCHHI5:
5464        case CP0_REG19__WATCHHI6:
5465        case CP0_REG19__WATCHHI7:
5466            /* upper 32 bits are only available when Config5MI != 0 */
5467            CP0_CHECK(ctx->mi);
5468            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0);
5469            register_name = "WatchHi";
5470            break;
5471        default:
5472            goto cp0_unimplemented;
5473        }
5474        break;
5475    case CP0_REGISTER_28:
5476        switch (sel) {
5477        case 0:
5478        case 2:
5479        case 4:
5480        case 6:
5481            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
5482            register_name = "TagLo";
5483            break;
5484        default:
5485            goto cp0_unimplemented;
5486        }
5487        break;
5488    default:
5489        goto cp0_unimplemented;
5490    }
5491    trace_mips_translate_c0("mfhc0", register_name, reg, sel);
5492    return;
5493
5494cp0_unimplemented:
5495    qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
5496                  register_name, reg, sel);
5497    tcg_gen_movi_tl(arg, 0);
5498}
5499
5500static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5501{
5502    const char *register_name = "invalid";
5503    uint64_t mask = ctx->PAMask >> 36;
5504
5505    switch (reg) {
5506    case CP0_REGISTER_02:
5507        switch (sel) {
5508        case 0:
5509            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5510            tcg_gen_andi_tl(arg, arg, mask);
5511            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5512            register_name = "EntryLo0";
5513            break;
5514        default:
5515            goto cp0_unimplemented;
5516        }
5517        break;
5518    case CP0_REGISTER_03:
5519        switch (sel) {
5520        case CP0_REG03__ENTRYLO1:
5521            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5522            tcg_gen_andi_tl(arg, arg, mask);
5523            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5524            register_name = "EntryLo1";
5525            break;
5526        default:
5527            goto cp0_unimplemented;
5528        }
5529        break;
5530    case CP0_REGISTER_09:
5531        switch (sel) {
5532        case CP0_REG09__SAAR:
5533            CP0_CHECK(ctx->saar);
5534            gen_helper_mthc0_saar(cpu_env, arg);
5535            register_name = "SAAR";
5536            break;
5537        default:
5538            goto cp0_unimplemented;
5539        }
5540        break;
5541    case CP0_REGISTER_17:
5542        switch (sel) {
5543        case CP0_REG17__LLADDR:
5544            /*
5545             * LLAddr is read-only (the only exception is bit 0 if LLB is
5546             * supported); the CP0_LLAddr_rw_bitmask does not seem to be
5547             * relevant for modern MIPS cores supporting MTHC0, therefore
5548             * treating MTHC0 to LLAddr as NOP.
5549             */
5550            register_name = "LLAddr";
5551            break;
5552        case CP0_REG17__MAAR:
5553            CP0_CHECK(ctx->mrp);
5554            gen_helper_mthc0_maar(cpu_env, arg);
5555            register_name = "MAAR";
5556            break;
5557        default:
5558            goto cp0_unimplemented;
5559        }
5560        break;
5561    case CP0_REGISTER_19:
5562        switch (sel) {
5563        case CP0_REG19__WATCHHI0:
5564        case CP0_REG19__WATCHHI1:
5565        case CP0_REG19__WATCHHI2:
5566        case CP0_REG19__WATCHHI3:
5567        case CP0_REG19__WATCHHI4:
5568        case CP0_REG19__WATCHHI5:
5569        case CP0_REG19__WATCHHI6:
5570        case CP0_REG19__WATCHHI7:
5571            /* upper 32 bits are only available when Config5MI != 0 */
5572            CP0_CHECK(ctx->mi);
5573            gen_helper_0e1i(mthc0_watchhi, arg, sel);
5574            register_name = "WatchHi";
5575            break;
5576        default:
5577            goto cp0_unimplemented;
5578        }
5579        break;
5580    case CP0_REGISTER_28:
5581        switch (sel) {
5582        case 0:
5583        case 2:
5584        case 4:
5585        case 6:
5586            tcg_gen_andi_tl(arg, arg, mask);
5587            gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
5588            register_name = "TagLo";
5589            break;
5590        default:
5591            goto cp0_unimplemented;
5592        }
5593        break;
5594    default:
5595        goto cp0_unimplemented;
5596    }
5597    trace_mips_translate_c0("mthc0", register_name, reg, sel);
5598    return;
5599
5600cp0_unimplemented:
5601    qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
5602                  register_name, reg, sel);
5603}
5604
5605static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
5606{
5607    if (ctx->insn_flags & ISA_MIPS_R6) {
5608        tcg_gen_movi_tl(arg, 0);
5609    } else {
5610        tcg_gen_movi_tl(arg, ~0);
5611    }
5612}
5613
5614static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5615{
5616    const char *register_name = "invalid";
5617
5618    if (sel != 0) {
5619        check_insn(ctx, ISA_MIPS_R1);
5620    }
5621
5622    switch (reg) {
5623    case CP0_REGISTER_00:
5624        switch (sel) {
5625        case CP0_REG00__INDEX:
5626            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5627            register_name = "Index";
5628            break;
5629        case CP0_REG00__MVPCONTROL:
5630            CP0_CHECK(ctx->insn_flags & ASE_MT);
5631            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5632            register_name = "MVPControl";
5633            break;
5634        case CP0_REG00__MVPCONF0:
5635            CP0_CHECK(ctx->insn_flags & ASE_MT);
5636            gen_helper_mfc0_mvpconf0(arg, cpu_env);
5637            register_name = "MVPConf0";
5638            break;
5639        case CP0_REG00__MVPCONF1:
5640            CP0_CHECK(ctx->insn_flags & ASE_MT);
5641            gen_helper_mfc0_mvpconf1(arg, cpu_env);
5642            register_name = "MVPConf1";
5643            break;
5644        case CP0_REG00__VPCONTROL:
5645            CP0_CHECK(ctx->vp);
5646            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
5647            register_name = "VPControl";
5648            break;
5649        default:
5650            goto cp0_unimplemented;
5651        }
5652        break;
5653    case CP0_REGISTER_01:
5654        switch (sel) {
5655        case CP0_REG01__RANDOM:
5656            CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
5657            gen_helper_mfc0_random(arg, cpu_env);
5658            register_name = "Random";
5659            break;
5660        case CP0_REG01__VPECONTROL:
5661            CP0_CHECK(ctx->insn_flags & ASE_MT);
5662            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5663            register_name = "VPEControl";
5664            break;
5665        case CP0_REG01__VPECONF0:
5666            CP0_CHECK(ctx->insn_flags & ASE_MT);
5667            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5668            register_name = "VPEConf0";
5669            break;
5670        case CP0_REG01__VPECONF1:
5671            CP0_CHECK(ctx->insn_flags & ASE_MT);
5672            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5673            register_name = "VPEConf1";
5674            break;
5675        case CP0_REG01__YQMASK:
5676            CP0_CHECK(ctx->insn_flags & ASE_MT);
5677            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
5678            register_name = "YQMask";
5679            break;
5680        case CP0_REG01__VPESCHEDULE:
5681            CP0_CHECK(ctx->insn_flags & ASE_MT);
5682            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
5683            register_name = "VPESchedule";
5684            break;
5685        case CP0_REG01__VPESCHEFBACK:
5686            CP0_CHECK(ctx->insn_flags & ASE_MT);
5687            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5688            register_name = "VPEScheFBack";
5689            break;
5690        case CP0_REG01__VPEOPT:
5691            CP0_CHECK(ctx->insn_flags & ASE_MT);
5692            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5693            register_name = "VPEOpt";
5694            break;
5695        default:
5696            goto cp0_unimplemented;
5697        }
5698        break;
5699    case CP0_REGISTER_02:
5700        switch (sel) {
5701        case CP0_REG02__ENTRYLO0:
5702            {
5703                TCGv_i64 tmp = tcg_temp_new_i64();
5704                tcg_gen_ld_i64(tmp, cpu_env,
5705                               offsetof(CPUMIPSState, CP0_EntryLo0));
5706#if defined(TARGET_MIPS64)
5707                if (ctx->rxi) {
5708                    /* Move RI/XI fields to bits 31:30 */
5709                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5710                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5711                }
5712#endif
5713                gen_move_low32(arg, tmp);
5714                tcg_temp_free_i64(tmp);
5715            }
5716            register_name = "EntryLo0";
5717            break;
5718        case CP0_REG02__TCSTATUS:
5719            CP0_CHECK(ctx->insn_flags & ASE_MT);
5720            gen_helper_mfc0_tcstatus(arg, cpu_env);
5721            register_name = "TCStatus";
5722            break;
5723        case CP0_REG02__TCBIND:
5724            CP0_CHECK(ctx->insn_flags & ASE_MT);
5725            gen_helper_mfc0_tcbind(arg, cpu_env);
5726            register_name = "TCBind";
5727            break;
5728        case CP0_REG02__TCRESTART:
5729            CP0_CHECK(ctx->insn_flags & ASE_MT);
5730            gen_helper_mfc0_tcrestart(arg, cpu_env);
5731            register_name = "TCRestart";
5732            break;
5733        case CP0_REG02__TCHALT:
5734            CP0_CHECK(ctx->insn_flags & ASE_MT);
5735            gen_helper_mfc0_tchalt(arg, cpu_env);
5736            register_name = "TCHalt";
5737            break;
5738        case CP0_REG02__TCCONTEXT:
5739            CP0_CHECK(ctx->insn_flags & ASE_MT);
5740            gen_helper_mfc0_tccontext(arg, cpu_env);
5741            register_name = "TCContext";
5742            break;
5743        case CP0_REG02__TCSCHEDULE:
5744            CP0_CHECK(ctx->insn_flags & ASE_MT);
5745            gen_helper_mfc0_tcschedule(arg, cpu_env);
5746            register_name = "TCSchedule";
5747            break;
5748        case CP0_REG02__TCSCHEFBACK:
5749            CP0_CHECK(ctx->insn_flags & ASE_MT);
5750            gen_helper_mfc0_tcschefback(arg, cpu_env);
5751            register_name = "TCScheFBack";
5752            break;
5753        default:
5754            goto cp0_unimplemented;
5755        }
5756        break;
5757    case CP0_REGISTER_03:
5758        switch (sel) {
5759        case CP0_REG03__ENTRYLO1:
5760            {
5761                TCGv_i64 tmp = tcg_temp_new_i64();
5762                tcg_gen_ld_i64(tmp, cpu_env,
5763                               offsetof(CPUMIPSState, CP0_EntryLo1));
5764#if defined(TARGET_MIPS64)
5765                if (ctx->rxi) {
5766                    /* Move RI/XI fields to bits 31:30 */
5767                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
5768                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
5769                }
5770#endif
5771                gen_move_low32(arg, tmp);
5772                tcg_temp_free_i64(tmp);
5773            }
5774            register_name = "EntryLo1";
5775            break;
5776        case CP0_REG03__GLOBALNUM:
5777            CP0_CHECK(ctx->vp);
5778            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
5779            register_name = "GlobalNumber";
5780            break;
5781        default:
5782            goto cp0_unimplemented;
5783        }
5784        break;
5785    case CP0_REGISTER_04:
5786        switch (sel) {
5787        case CP0_REG04__CONTEXT:
5788            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5789            tcg_gen_ext32s_tl(arg, arg);
5790            register_name = "Context";
5791            break;
5792        case CP0_REG04__CONTEXTCONFIG:
5793            /* SmartMIPS ASE */
5794            /* gen_helper_mfc0_contextconfig(arg); */
5795            register_name = "ContextConfig";
5796            goto cp0_unimplemented;
5797        case CP0_REG04__USERLOCAL:
5798            CP0_CHECK(ctx->ulri);
5799            tcg_gen_ld_tl(arg, cpu_env,
5800                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
5801            tcg_gen_ext32s_tl(arg, arg);
5802            register_name = "UserLocal";
5803            break;
5804        case CP0_REG04__MMID:
5805            CP0_CHECK(ctx->mi);
5806            gen_helper_mtc0_memorymapid(cpu_env, arg);
5807            register_name = "MMID";
5808            break;
5809        default:
5810            goto cp0_unimplemented;
5811        }
5812        break;
5813    case CP0_REGISTER_05:
5814        switch (sel) {
5815        case CP0_REG05__PAGEMASK:
5816            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5817            register_name = "PageMask";
5818            break;
5819        case CP0_REG05__PAGEGRAIN:
5820            check_insn(ctx, ISA_MIPS_R2);
5821            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5822            register_name = "PageGrain";
5823            break;
5824        case CP0_REG05__SEGCTL0:
5825            CP0_CHECK(ctx->sc);
5826            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
5827            tcg_gen_ext32s_tl(arg, arg);
5828            register_name = "SegCtl0";
5829            break;
5830        case CP0_REG05__SEGCTL1:
5831            CP0_CHECK(ctx->sc);
5832            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
5833            tcg_gen_ext32s_tl(arg, arg);
5834            register_name = "SegCtl1";
5835            break;
5836        case CP0_REG05__SEGCTL2:
5837            CP0_CHECK(ctx->sc);
5838            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
5839            tcg_gen_ext32s_tl(arg, arg);
5840            register_name = "SegCtl2";
5841            break;
5842        case CP0_REG05__PWBASE:
5843            check_pw(ctx);
5844            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
5845            register_name = "PWBase";
5846            break;
5847        case CP0_REG05__PWFIELD:
5848            check_pw(ctx);
5849            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
5850            register_name = "PWField";
5851            break;
5852        case CP0_REG05__PWSIZE:
5853            check_pw(ctx);
5854            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
5855            register_name = "PWSize";
5856            break;
5857        default:
5858            goto cp0_unimplemented;
5859        }
5860        break;
5861    case CP0_REGISTER_06:
5862        switch (sel) {
5863        case CP0_REG06__WIRED:
5864            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5865            register_name = "Wired";
5866            break;
5867        case CP0_REG06__SRSCONF0:
5868            check_insn(ctx, ISA_MIPS_R2);
5869            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5870            register_name = "SRSConf0";
5871            break;
5872        case CP0_REG06__SRSCONF1:
5873            check_insn(ctx, ISA_MIPS_R2);
5874            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5875            register_name = "SRSConf1";
5876            break;
5877        case CP0_REG06__SRSCONF2:
5878            check_insn(ctx, ISA_MIPS_R2);
5879            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5880            register_name = "SRSConf2";
5881            break;
5882        case CP0_REG06__SRSCONF3:
5883            check_insn(ctx, ISA_MIPS_R2);
5884            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5885            register_name = "SRSConf3";
5886            break;
5887        case CP0_REG06__SRSCONF4:
5888            check_insn(ctx, ISA_MIPS_R2);
5889            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5890            register_name = "SRSConf4";
5891            break;
5892        case CP0_REG06__PWCTL:
5893            check_pw(ctx);
5894            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
5895            register_name = "PWCtl";
5896            break;
5897        default:
5898            goto cp0_unimplemented;
5899        }
5900        break;
5901    case CP0_REGISTER_07:
5902        switch (sel) {
5903        case CP0_REG07__HWRENA:
5904            check_insn(ctx, ISA_MIPS_R2);
5905            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5906            register_name = "HWREna";
5907            break;
5908        default:
5909            goto cp0_unimplemented;
5910        }
5911        break;
5912    case CP0_REGISTER_08:
5913        switch (sel) {
5914        case CP0_REG08__BADVADDR:
5915            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5916            tcg_gen_ext32s_tl(arg, arg);
5917            register_name = "BadVAddr";
5918            break;
5919        case CP0_REG08__BADINSTR:
5920            CP0_CHECK(ctx->bi);
5921            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
5922            register_name = "BadInstr";
5923            break;
5924        case CP0_REG08__BADINSTRP:
5925            CP0_CHECK(ctx->bp);
5926            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
5927            register_name = "BadInstrP";
5928            break;
5929        case CP0_REG08__BADINSTRX:
5930            CP0_CHECK(ctx->bi);
5931            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
5932            tcg_gen_andi_tl(arg, arg, ~0xffff);
5933            register_name = "BadInstrX";
5934            break;
5935        default:
5936            goto cp0_unimplemented;
5937        }
5938        break;
5939    case CP0_REGISTER_09:
5940        switch (sel) {
5941        case CP0_REG09__COUNT:
5942            /* Mark as an IO operation because we read the time.  */
5943            if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
5944                gen_io_start();
5945            }
5946            gen_helper_mfc0_count(arg, cpu_env);
5947            /*
5948             * Break the TB to be able to take timer interrupts immediately
5949             * after reading count. DISAS_STOP isn't sufficient, we need to
5950             * ensure we break completely out of translated code.
5951             */
5952            gen_save_pc(ctx->base.pc_next + 4);
5953            ctx->base.is_jmp = DISAS_EXIT;
5954            register_name = "Count";
5955            break;
5956        case CP0_REG09__SAARI:
5957            CP0_CHECK(ctx->saar);
5958            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
5959            register_name = "SAARI";
5960            break;
5961        case CP0_REG09__SAAR:
5962            CP0_CHECK(ctx->saar);
5963            gen_helper_mfc0_saar(arg, cpu_env);
5964            register_name = "SAAR";
5965            break;
5966        default:
5967            goto cp0_unimplemented;
5968        }
5969        break;
5970    case CP0_REGISTER_10:
5971        switch (sel) {
5972        case CP0_REG10__ENTRYHI:
5973            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5974            tcg_gen_ext32s_tl(arg, arg);
5975            register_name = "EntryHi";
5976            break;
5977        default:
5978            goto cp0_unimplemented;
5979        }
5980        break;
5981    case CP0_REGISTER_11:
5982        switch (sel) {
5983        case CP0_REG11__COMPARE:
5984            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5985            register_name = "Compare";
5986            break;
5987        /* 6,7 are implementation dependent */
5988        default:
5989            goto cp0_unimplemented;
5990        }
5991        break;
5992    case CP0_REGISTER_12:
5993        switch (sel) {
5994        case CP0_REG12__STATUS:
5995            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5996            register_name = "Status";
5997            break;
5998        case CP0_REG12__INTCTL:
5999            check_insn(ctx, ISA_MIPS_R2);
6000            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6001            register_name = "IntCtl";
6002            break;
6003        case CP0_REG12__SRSCTL:
6004            check_insn(ctx, ISA_MIPS_R2);
6005            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6006            register_name = "SRSCtl";
6007            break;
6008        case CP0_REG12__SRSMAP:
6009            check_insn(ctx, ISA_MIPS_R2);
6010            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6011            register_name = "SRSMap";
6012            break;
6013        default:
6014            goto cp0_unimplemented;
6015       }
6016        break;
6017    case CP0_REGISTER_13:
6018        switch (sel) {
6019        case CP0_REG13__CAUSE:
6020            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6021            register_name = "Cause";
6022            break;
6023        default:
6024            goto cp0_unimplemented;
6025       }
6026        break;
6027    case CP0_REGISTER_14:
6028        switch (sel) {
6029        case CP0_REG14__EPC:
6030            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6031            tcg_gen_ext32s_tl(arg, arg);
6032            register_name = "EPC";
6033            break;
6034        default:
6035            goto cp0_unimplemented;
6036        }
6037        break;
6038    case CP0_REGISTER_15:
6039        switch (sel) {
6040        case CP0_REG15__PRID:
6041            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6042            register_name = "PRid";
6043            break;
6044        case CP0_REG15__EBASE:
6045            check_insn(ctx, ISA_MIPS_R2);
6046            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
6047            tcg_gen_ext32s_tl(arg, arg);
6048            register_name = "EBase";
6049            break;
6050        case CP0_REG15__CMGCRBASE:
6051            check_insn(ctx, ISA_MIPS_R2);
6052            CP0_CHECK(ctx->cmgcr);
6053            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6054            tcg_gen_ext32s_tl(arg, arg);
6055            register_name = "CMGCRBase";
6056            break;
6057        default:
6058            goto cp0_unimplemented;
6059       }
6060        break;
6061    case CP0_REGISTER_16:
6062        switch (sel) {
6063        case CP0_REG16__CONFIG:
6064            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
6065            register_name = "Config";
6066            break;
6067        case CP0_REG16__CONFIG1:
6068            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
6069            register_name = "Config1";
6070            break;
6071        case CP0_REG16__CONFIG2:
6072            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
6073            register_name = "Config2";
6074            break;
6075        case CP0_REG16__CONFIG3:
6076            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
6077            register_name = "Config3";
6078            break;
6079        case CP0_REG16__CONFIG4:
6080            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6081            register_name = "Config4";
6082            break;
6083        case CP0_REG16__CONFIG5:
6084            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6085            register_name = "Config5";
6086            break;
6087        /* 6,7 are implementation dependent */
6088        case CP0_REG16__CONFIG6:
6089            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
6090            register_name = "Config6";
6091            break;
6092        case CP0_REG16__CONFIG7:
6093            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
6094            register_name = "Config7";
6095            break;
6096        default:
6097            goto cp0_unimplemented;
6098        }
6099        break;
6100    case CP0_REGISTER_17:
6101        switch (sel) {
6102        case CP0_REG17__LLADDR:
6103            gen_helper_mfc0_lladdr(arg, cpu_env);
6104            register_name = "LLAddr";
6105            break;
6106        case CP0_REG17__MAAR:
6107            CP0_CHECK(ctx->mrp);
6108            gen_helper_mfc0_maar(arg, cpu_env);
6109            register_name = "MAAR";
6110            break;
6111        case CP0_REG17__MAARI:
6112            CP0_CHECK(ctx->mrp);
6113            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6114            register_name = "MAARI";
6115            break;
6116        default:
6117            goto cp0_unimplemented;
6118        }
6119        break;
6120    case CP0_REGISTER_18:
6121        switch (sel) {
6122        case CP0_REG18__WATCHLO0:
6123        case CP0_REG18__WATCHLO1:
6124        case CP0_REG18__WATCHLO2:
6125        case CP0_REG18__WATCHLO3:
6126        case CP0_REG18__WATCHLO4:
6127        case CP0_REG18__WATCHLO5:
6128        case CP0_REG18__WATCHLO6:
6129        case CP0_REG18__WATCHLO7:
6130            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6131            gen_helper_1e0i(mfc0_watchlo, arg, sel);
6132            register_name = "WatchLo";
6133            break;
6134        default:
6135            goto cp0_unimplemented;
6136        }
6137        break;
6138    case CP0_REGISTER_19:
6139        switch (sel) {
6140        case CP0_REG19__WATCHHI0:
6141        case CP0_REG19__WATCHHI1:
6142        case CP0_REG19__WATCHHI2:
6143        case CP0_REG19__WATCHHI3:
6144        case CP0_REG19__WATCHHI4:
6145        case CP0_REG19__WATCHHI5:
6146        case CP0_REG19__WATCHHI6:
6147        case CP0_REG19__WATCHHI7:
6148            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6149            gen_helper_1e0i(mfc0_watchhi, arg, sel);
6150            register_name = "WatchHi";
6151            break;
6152        default:
6153            goto cp0_unimplemented;
6154        }
6155        break;
6156    case CP0_REGISTER_20:
6157        switch (sel) {
6158        case CP0_REG20__XCONTEXT:
6159#if defined(TARGET_MIPS64)
6160            check_insn(ctx, ISA_MIPS3);
6161            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
6162            tcg_gen_ext32s_tl(arg, arg);
6163            register_name = "XContext";
6164            break;
6165#endif
6166        default:
6167            goto cp0_unimplemented;
6168        }
6169        break;
6170    case CP0_REGISTER_21:
6171       /* Officially reserved, but sel 0 is used for R1x000 framemask */
6172        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
6173        switch (sel) {
6174        case 0:
6175            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
6176            register_name = "Framemask";
6177            break;
6178        default:
6179            goto cp0_unimplemented;
6180        }
6181        break;
6182    case CP0_REGISTER_22:
6183        tcg_gen_movi_tl(arg, 0); /* unimplemented */
6184        register_name = "'Diagnostic"; /* implementation dependent */
6185        break;
6186    case CP0_REGISTER_23:
6187        switch (sel) {
6188        case CP0_REG23__DEBUG:
6189            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
6190            register_name = "Debug";
6191            break;
6192        case CP0_REG23__TRACECONTROL:
6193            /* PDtrace support */
6194            /* gen_helper_mfc0_tracecontrol(arg);  */
6195            register_name = "TraceControl";
6196            goto cp0_unimplemented;
6197        case CP0_REG23__TRACECONTROL2:
6198            /* PDtrace support */
6199            /* gen_helper_mfc0_tracecontrol2(arg); */
6200            register_name = "TraceControl2";
6201            goto cp0_unimplemented;
6202        case CP0_REG23__USERTRACEDATA1:
6203            /* PDtrace support */
6204            /* gen_helper_mfc0_usertracedata1(arg);*/
6205            register_name = "UserTraceData1";
6206            goto cp0_unimplemented;
6207        case CP0_REG23__TRACEIBPC:
6208            /* PDtrace support */
6209            /* gen_helper_mfc0_traceibpc(arg);     */
6210            register_name = "TraceIBPC";
6211            goto cp0_unimplemented;
6212        case CP0_REG23__TRACEDBPC:
6213            /* PDtrace support */
6214            /* gen_helper_mfc0_tracedbpc(arg);     */
6215            register_name = "TraceDBPC";
6216            goto cp0_unimplemented;
6217        default:
6218            goto cp0_unimplemented;
6219        }
6220        break;
6221    case CP0_REGISTER_24:
6222        switch (sel) {
6223        case CP0_REG24__DEPC:
6224            /* EJTAG support */
6225            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6226            tcg_gen_ext32s_tl(arg, arg);
6227            register_name = "DEPC";
6228            break;
6229        default:
6230            goto cp0_unimplemented;
6231        }
6232        break;
6233    case CP0_REGISTER_25:
6234        switch (sel) {
6235        case CP0_REG25__PERFCTL0:
6236            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
6237            register_name = "Performance0";
6238            break;
6239        case CP0_REG25__PERFCNT0:
6240            /* gen_helper_mfc0_performance1(arg); */
6241            register_name = "Performance1";
6242            goto cp0_unimplemented;
6243        case CP0_REG25__PERFCTL1:
6244            /* gen_helper_mfc0_performance2(arg); */
6245            register_name = "Performance2";
6246            goto cp0_unimplemented;
6247        case CP0_REG25__PERFCNT1:
6248            /* gen_helper_mfc0_performance3(arg); */
6249            register_name = "Performance3";
6250            goto cp0_unimplemented;
6251        case CP0_REG25__PERFCTL2:
6252            /* gen_helper_mfc0_performance4(arg); */
6253            register_name = "Performance4";
6254            goto cp0_unimplemented;
6255        case CP0_REG25__PERFCNT2:
6256            /* gen_helper_mfc0_performance5(arg); */
6257            register_name = "Performance5";
6258            goto cp0_unimplemented;
6259        case CP0_REG25__PERFCTL3:
6260            /* gen_helper_mfc0_performance6(arg); */
6261            register_name = "Performance6";
6262            goto cp0_unimplemented;
6263        case CP0_REG25__PERFCNT3:
6264            /* gen_helper_mfc0_performance7(arg); */
6265            register_name = "Performance7";
6266            goto cp0_unimplemented;
6267        default:
6268            goto cp0_unimplemented;
6269        }
6270        break;
6271    case CP0_REGISTER_26:
6272        switch (sel) {
6273        case CP0_REG26__ERRCTL:
6274            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
6275            register_name = "ErrCtl";
6276            break;
6277        default:
6278            goto cp0_unimplemented;
6279        }
6280        break;
6281    case CP0_REGISTER_27:
6282        switch (sel) {
6283        case CP0_REG27__CACHERR:
6284            tcg_gen_movi_tl(arg, 0); /* unimplemented */
6285            register_name = "CacheErr";
6286            break;
6287        default:
6288            goto cp0_unimplemented;
6289        }
6290        break;
6291    case CP0_REGISTER_28:
6292        switch (sel) {
6293        case CP0_REG28__TAGLO:
6294        case CP0_REG28__TAGLO1:
6295        case CP0_REG28__TAGLO2:
6296        case CP0_REG28__TAGLO3:
6297            {
6298                TCGv_i64 tmp = tcg_temp_new_i64();
6299                tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
6300                gen_move_low32(arg, tmp);
6301                tcg_temp_free_i64(tmp);
6302            }
6303            register_name = "TagLo";
6304            break;
6305        case CP0_REG28__DATALO:
6306        case CP0_REG28__DATALO1:
6307        case CP0_REG28__DATALO2:
6308        case CP0_REG28__DATALO3:
6309            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
6310            register_name = "DataLo";
6311            break;
6312        default:
6313            goto cp0_unimplemented;
6314        }
6315        break;
6316    case CP0_REGISTER_29:
6317        switch (sel) {
6318        case CP0_REG29__TAGHI:
6319        case CP0_REG29__TAGHI1:
6320        case CP0_REG29__TAGHI2:
6321        case CP0_REG29__TAGHI3:
6322            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
6323            register_name = "TagHi";
6324            break;
6325        case CP0_REG29__DATAHI:
6326        case CP0_REG29__DATAHI1:
6327        case CP0_REG29__DATAHI2:
6328        case CP0_REG29__DATAHI3:
6329            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
6330            register_name = "DataHi";
6331            break;
6332        default:
6333            goto cp0_unimplemented;
6334        }
6335        break;
6336    case CP0_REGISTER_30:
6337        switch (sel) {
6338        case CP0_REG30__ERROREPC:
6339            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6340            tcg_gen_ext32s_tl(arg, arg);
6341            register_name = "ErrorEPC";
6342            break;
6343        default:
6344            goto cp0_unimplemented;
6345        }
6346        break;
6347    case CP0_REGISTER_31:
6348        switch (sel) {
6349        case CP0_REG31__DESAVE:
6350            /* EJTAG support */
6351            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6352            register_name = "DESAVE";
6353            break;
6354        case CP0_REG31__KSCRATCH1:
6355        case CP0_REG31__KSCRATCH2:
6356        case CP0_REG31__KSCRATCH3:
6357        case CP0_REG31__KSCRATCH4:
6358        case CP0_REG31__KSCRATCH5:
6359        case CP0_REG31__KSCRATCH6:
6360            CP0_CHECK(ctx->kscrexist & (1 << sel));
6361            tcg_gen_ld_tl(arg, cpu_env,
6362                          offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
6363            tcg_gen_ext32s_tl(arg, arg);
6364            register_name = "KScratch";
6365            break;
6366        default:
6367            goto cp0_unimplemented;
6368        }
6369        break;
6370    default:
6371       goto cp0_unimplemented;
6372    }
6373    trace_mips_translate_c0("mfc0", register_name, reg, sel);
6374    return;
6375
6376cp0_unimplemented:
6377    qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
6378                  register_name, reg, sel);
6379    gen_mfc0_unimplemented(ctx, arg);
6380}
6381
6382static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6383{
6384    const char *register_name = "invalid";
6385
6386    if (sel != 0) {
6387        check_insn(ctx, ISA_MIPS_R1);
6388    }
6389
6390    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6391        gen_io_start();
6392    }
6393
6394    switch (reg) {
6395    case CP0_REGISTER_00:
6396        switch (sel) {
6397        case CP0_REG00__INDEX:
6398            gen_helper_mtc0_index(cpu_env, arg);
6399            register_name = "Index";
6400            break;
6401        case CP0_REG00__MVPCONTROL:
6402            CP0_CHECK(ctx->insn_flags & ASE_MT);
6403            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
6404            register_name = "MVPControl";
6405            break;
6406        case CP0_REG00__MVPCONF0:
6407            CP0_CHECK(ctx->insn_flags & ASE_MT);
6408            /* ignored */
6409            register_name = "MVPConf0";
6410            break;
6411        case CP0_REG00__MVPCONF1:
6412            CP0_CHECK(ctx->insn_flags & ASE_MT);
6413            /* ignored */
6414            register_name = "MVPConf1";
6415            break;
6416        case CP0_REG00__VPCONTROL:
6417            CP0_CHECK(ctx->vp);
6418            /* ignored */
6419            register_name = "VPControl";
6420            break;
6421        default:
6422            goto cp0_unimplemented;
6423        }
6424        break;
6425    case CP0_REGISTER_01:
6426        switch (sel) {
6427        case CP0_REG01__RANDOM:
6428            /* ignored */
6429            register_name = "Random";
6430            break;
6431        case CP0_REG01__VPECONTROL:
6432            CP0_CHECK(ctx->insn_flags & ASE_MT);
6433            gen_helper_mtc0_vpecontrol(cpu_env, arg);
6434            register_name = "VPEControl";
6435            break;
6436        case CP0_REG01__VPECONF0:
6437            CP0_CHECK(ctx->insn_flags & ASE_MT);
6438            gen_helper_mtc0_vpeconf0(cpu_env, arg);
6439            register_name = "VPEConf0";
6440            break;
6441        case CP0_REG01__VPECONF1:
6442            CP0_CHECK(ctx->insn_flags & ASE_MT);
6443            gen_helper_mtc0_vpeconf1(cpu_env, arg);
6444            register_name = "VPEConf1";
6445            break;
6446        case CP0_REG01__YQMASK:
6447            CP0_CHECK(ctx->insn_flags & ASE_MT);
6448            gen_helper_mtc0_yqmask(cpu_env, arg);
6449            register_name = "YQMask";
6450            break;
6451        case CP0_REG01__VPESCHEDULE:
6452            CP0_CHECK(ctx->insn_flags & ASE_MT);
6453            tcg_gen_st_tl(arg, cpu_env,
6454                          offsetof(CPUMIPSState, CP0_VPESchedule));
6455            register_name = "VPESchedule";
6456            break;
6457        case CP0_REG01__VPESCHEFBACK:
6458            CP0_CHECK(ctx->insn_flags & ASE_MT);
6459            tcg_gen_st_tl(arg, cpu_env,
6460                          offsetof(CPUMIPSState, CP0_VPEScheFBack));
6461            register_name = "VPEScheFBack";
6462            break;
6463        case CP0_REG01__VPEOPT:
6464            CP0_CHECK(ctx->insn_flags & ASE_MT);
6465            gen_helper_mtc0_vpeopt(cpu_env, arg);
6466            register_name = "VPEOpt";
6467            break;
6468        default:
6469            goto cp0_unimplemented;
6470        }
6471        break;
6472    case CP0_REGISTER_02:
6473        switch (sel) {
6474        case CP0_REG02__ENTRYLO0:
6475            gen_helper_mtc0_entrylo0(cpu_env, arg);
6476            register_name = "EntryLo0";
6477            break;
6478        case CP0_REG02__TCSTATUS:
6479            CP0_CHECK(ctx->insn_flags & ASE_MT);
6480            gen_helper_mtc0_tcstatus(cpu_env, arg);
6481            register_name = "TCStatus";
6482            break;
6483        case CP0_REG02__TCBIND:
6484            CP0_CHECK(ctx->insn_flags & ASE_MT);
6485            gen_helper_mtc0_tcbind(cpu_env, arg);
6486            register_name = "TCBind";
6487            break;
6488        case CP0_REG02__TCRESTART:
6489            CP0_CHECK(ctx->insn_flags & ASE_MT);
6490            gen_helper_mtc0_tcrestart(cpu_env, arg);
6491            register_name = "TCRestart";
6492            break;
6493        case CP0_REG02__TCHALT:
6494            CP0_CHECK(ctx->insn_flags & ASE_MT);
6495            gen_helper_mtc0_tchalt(cpu_env, arg);
6496            register_name = "TCHalt";
6497            break;
6498        case CP0_REG02__TCCONTEXT:
6499            CP0_CHECK(ctx->insn_flags & ASE_MT);
6500            gen_helper_mtc0_tccontext(cpu_env, arg);
6501            register_name = "TCContext";
6502            break;
6503        case CP0_REG02__TCSCHEDULE:
6504            CP0_CHECK(ctx->insn_flags & ASE_MT);
6505            gen_helper_mtc0_tcschedule(cpu_env, arg);
6506            register_name = "TCSchedule";
6507            break;
6508        case CP0_REG02__TCSCHEFBACK:
6509            CP0_CHECK(ctx->insn_flags & ASE_MT);
6510            gen_helper_mtc0_tcschefback(cpu_env, arg);
6511            register_name = "TCScheFBack";
6512            break;
6513        default:
6514            goto cp0_unimplemented;
6515        }
6516        break;
6517    case CP0_REGISTER_03:
6518        switch (sel) {
6519        case CP0_REG03__ENTRYLO1:
6520            gen_helper_mtc0_entrylo1(cpu_env, arg);
6521            register_name = "EntryLo1";
6522            break;
6523        case CP0_REG03__GLOBALNUM:
6524            CP0_CHECK(ctx->vp);
6525            /* ignored */
6526            register_name = "GlobalNumber";
6527            break;
6528        default:
6529            goto cp0_unimplemented;
6530        }
6531        break;
6532    case CP0_REGISTER_04:
6533        switch (sel) {
6534        case CP0_REG04__CONTEXT:
6535            gen_helper_mtc0_context(cpu_env, arg);
6536            register_name = "Context";
6537            break;
6538        case CP0_REG04__CONTEXTCONFIG:
6539            /* SmartMIPS ASE */
6540            /* gen_helper_mtc0_contextconfig(arg); */
6541            register_name = "ContextConfig";
6542            goto cp0_unimplemented;
6543        case CP0_REG04__USERLOCAL:
6544            CP0_CHECK(ctx->ulri);
6545            tcg_gen_st_tl(arg, cpu_env,
6546                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6547            register_name = "UserLocal";
6548            break;
6549        case CP0_REG04__MMID:
6550            CP0_CHECK(ctx->mi);
6551            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
6552            register_name = "MMID";
6553            break;
6554        default:
6555            goto cp0_unimplemented;
6556        }
6557        break;
6558    case CP0_REGISTER_05:
6559        switch (sel) {
6560        case CP0_REG05__PAGEMASK:
6561            gen_helper_mtc0_pagemask(cpu_env, arg);
6562            register_name = "PageMask";
6563            break;
6564        case CP0_REG05__PAGEGRAIN:
6565            check_insn(ctx, ISA_MIPS_R2);
6566            gen_helper_mtc0_pagegrain(cpu_env, arg);
6567            register_name = "PageGrain";
6568            ctx->base.is_jmp = DISAS_STOP;
6569            break;
6570        case CP0_REG05__SEGCTL0:
6571            CP0_CHECK(ctx->sc);
6572            gen_helper_mtc0_segctl0(cpu_env, arg);
6573            register_name = "SegCtl0";
6574            break;
6575        case CP0_REG05__SEGCTL1:
6576            CP0_CHECK(ctx->sc);
6577            gen_helper_mtc0_segctl1(cpu_env, arg);
6578            register_name = "SegCtl1";
6579            break;
6580        case CP0_REG05__SEGCTL2:
6581            CP0_CHECK(ctx->sc);
6582            gen_helper_mtc0_segctl2(cpu_env, arg);
6583            register_name = "SegCtl2";
6584            break;
6585        case CP0_REG05__PWBASE:
6586            check_pw(ctx);
6587            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6588            register_name = "PWBase";
6589            break;
6590        case CP0_REG05__PWFIELD:
6591            check_pw(ctx);
6592            gen_helper_mtc0_pwfield(cpu_env, arg);
6593            register_name = "PWField";
6594            break;
6595        case CP0_REG05__PWSIZE:
6596            check_pw(ctx);
6597            gen_helper_mtc0_pwsize(cpu_env, arg);
6598            register_name = "PWSize";
6599            break;
6600        default:
6601            goto cp0_unimplemented;
6602        }
6603        break;
6604    case CP0_REGISTER_06:
6605        switch (sel) {
6606        case CP0_REG06__WIRED:
6607            gen_helper_mtc0_wired(cpu_env, arg);
6608            register_name = "Wired";
6609            break;
6610        case CP0_REG06__SRSCONF0:
6611            check_insn(ctx, ISA_MIPS_R2);
6612            gen_helper_mtc0_srsconf0(cpu_env, arg);
6613            register_name = "SRSConf0";
6614            break;
6615        case CP0_REG06__SRSCONF1:
6616            check_insn(ctx, ISA_MIPS_R2);
6617            gen_helper_mtc0_srsconf1(cpu_env, arg);
6618            register_name = "SRSConf1";
6619            break;
6620        case CP0_REG06__SRSCONF2:
6621            check_insn(ctx, ISA_MIPS_R2);
6622            gen_helper_mtc0_srsconf2(cpu_env, arg);
6623            register_name = "SRSConf2";
6624            break;
6625        case CP0_REG06__SRSCONF3:
6626            check_insn(ctx, ISA_MIPS_R2);
6627            gen_helper_mtc0_srsconf3(cpu_env, arg);
6628            register_name = "SRSConf3";
6629            break;
6630        case CP0_REG06__SRSCONF4:
6631            check_insn(ctx, ISA_MIPS_R2);
6632            gen_helper_mtc0_srsconf4(cpu_env, arg);
6633            register_name = "SRSConf4";
6634            break;
6635        case CP0_REG06__PWCTL:
6636            check_pw(ctx);
6637            gen_helper_mtc0_pwctl(cpu_env, arg);
6638            register_name = "PWCtl";
6639            break;
6640        default:
6641            goto cp0_unimplemented;
6642        }
6643        break;
6644    case CP0_REGISTER_07:
6645        switch (sel) {
6646        case CP0_REG07__HWRENA:
6647            check_insn(ctx, ISA_MIPS_R2);
6648            gen_helper_mtc0_hwrena(cpu_env, arg);
6649            ctx->base.is_jmp = DISAS_STOP;
6650            register_name = "HWREna";
6651            break;
6652        default:
6653            goto cp0_unimplemented;
6654        }
6655        break;
6656    case CP0_REGISTER_08:
6657        switch (sel) {
6658        case CP0_REG08__BADVADDR:
6659            /* ignored */
6660            register_name = "BadVAddr";
6661            break;
6662        case CP0_REG08__BADINSTR:
6663            /* ignored */
6664            register_name = "BadInstr";
6665            break;
6666        case CP0_REG08__BADINSTRP:
6667            /* ignored */
6668            register_name = "BadInstrP";
6669            break;
6670        case CP0_REG08__BADINSTRX:
6671            /* ignored */
6672            register_name = "BadInstrX";
6673            break;
6674        default:
6675            goto cp0_unimplemented;
6676        }
6677        break;
6678    case CP0_REGISTER_09:
6679        switch (sel) {
6680        case CP0_REG09__COUNT:
6681            gen_helper_mtc0_count(cpu_env, arg);
6682            register_name = "Count";
6683            break;
6684        case CP0_REG09__SAARI:
6685            CP0_CHECK(ctx->saar);
6686            gen_helper_mtc0_saari(cpu_env, arg);
6687            register_name = "SAARI";
6688            break;
6689        case CP0_REG09__SAAR:
6690            CP0_CHECK(ctx->saar);
6691            gen_helper_mtc0_saar(cpu_env, arg);
6692            register_name = "SAAR";
6693            break;
6694        default:
6695            goto cp0_unimplemented;
6696        }
6697        break;
6698    case CP0_REGISTER_10:
6699        switch (sel) {
6700        case CP0_REG10__ENTRYHI:
6701            gen_helper_mtc0_entryhi(cpu_env, arg);
6702            register_name = "EntryHi";
6703            break;
6704        default:
6705            goto cp0_unimplemented;
6706        }
6707        break;
6708    case CP0_REGISTER_11:
6709        switch (sel) {
6710        case CP0_REG11__COMPARE:
6711            gen_helper_mtc0_compare(cpu_env, arg);
6712            register_name = "Compare";
6713            break;
6714        /* 6,7 are implementation dependent */
6715        default:
6716            goto cp0_unimplemented;
6717        }
6718        break;
6719    case CP0_REGISTER_12:
6720        switch (sel) {
6721        case CP0_REG12__STATUS:
6722            save_cpu_state(ctx, 1);
6723            gen_helper_mtc0_status(cpu_env, arg);
6724            /* DISAS_STOP isn't good enough here, hflags may have changed. */
6725            gen_save_pc(ctx->base.pc_next + 4);
6726            ctx->base.is_jmp = DISAS_EXIT;
6727            register_name = "Status";
6728            break;
6729        case CP0_REG12__INTCTL:
6730            check_insn(ctx, ISA_MIPS_R2);
6731            gen_helper_mtc0_intctl(cpu_env, arg);
6732            /* Stop translation as we may have switched the execution mode */
6733            ctx->base.is_jmp = DISAS_STOP;
6734            register_name = "IntCtl";
6735            break;
6736        case CP0_REG12__SRSCTL:
6737            check_insn(ctx, ISA_MIPS_R2);
6738            gen_helper_mtc0_srsctl(cpu_env, arg);
6739            /* Stop translation as we may have switched the execution mode */
6740            ctx->base.is_jmp = DISAS_STOP;
6741            register_name = "SRSCtl";
6742            break;
6743        case CP0_REG12__SRSMAP:
6744            check_insn(ctx, ISA_MIPS_R2);
6745            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6746            /* Stop translation as we may have switched the execution mode */
6747            ctx->base.is_jmp = DISAS_STOP;
6748            register_name = "SRSMap";
6749            break;
6750        default:
6751            goto cp0_unimplemented;
6752        }
6753        break;
6754    case CP0_REGISTER_13:
6755        switch (sel) {
6756        case CP0_REG13__CAUSE:
6757            save_cpu_state(ctx, 1);
6758            gen_helper_mtc0_cause(cpu_env, arg);
6759            /*
6760             * Stop translation as we may have triggered an interrupt.
6761             * DISAS_STOP isn't sufficient, we need to ensure we break out of
6762             * translated code to check for pending interrupts.
6763             */
6764            gen_save_pc(ctx->base.pc_next + 4);
6765            ctx->base.is_jmp = DISAS_EXIT;
6766            register_name = "Cause";
6767            break;
6768        default:
6769            goto cp0_unimplemented;
6770        }
6771        break;
6772    case CP0_REGISTER_14:
6773        switch (sel) {
6774        case CP0_REG14__EPC:
6775            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6776            register_name = "EPC";
6777            break;
6778        default:
6779            goto cp0_unimplemented;
6780        }
6781        break;
6782    case CP0_REGISTER_15:
6783        switch (sel) {
6784        case CP0_REG15__PRID:
6785            /* ignored */
6786            register_name = "PRid";
6787            break;
6788        case CP0_REG15__EBASE:
6789            check_insn(ctx, ISA_MIPS_R2);
6790            gen_helper_mtc0_ebase(cpu_env, arg);
6791            register_name = "EBase";
6792            break;
6793        default:
6794            goto cp0_unimplemented;
6795        }
6796        break;
6797    case CP0_REGISTER_16:
6798        switch (sel) {
6799        case CP0_REG16__CONFIG:
6800            gen_helper_mtc0_config0(cpu_env, arg);
6801            register_name = "Config";
6802            /* Stop translation as we may have switched the execution mode */
6803            ctx->base.is_jmp = DISAS_STOP;
6804            break;
6805        case CP0_REG16__CONFIG1:
6806            /* ignored, read only */
6807            register_name = "Config1";
6808            break;
6809        case CP0_REG16__CONFIG2:
6810            gen_helper_mtc0_config2(cpu_env, arg);
6811            register_name = "Config2";
6812            /* Stop translation as we may have switched the execution mode */
6813            ctx->base.is_jmp = DISAS_STOP;
6814            break;
6815        case CP0_REG16__CONFIG3:
6816            gen_helper_mtc0_config3(cpu_env, arg);
6817            register_name = "Config3";
6818            /* Stop translation as we may have switched the execution mode */
6819            ctx->base.is_jmp = DISAS_STOP;
6820            break;
6821        case CP0_REG16__CONFIG4:
6822            gen_helper_mtc0_config4(cpu_env, arg);
6823            register_name = "Config4";
6824            ctx->base.is_jmp = DISAS_STOP;
6825            break;
6826        case CP0_REG16__CONFIG5:
6827            gen_helper_mtc0_config5(cpu_env, arg);
6828            register_name = "Config5";
6829            /* Stop translation as we may have switched the execution mode */
6830            ctx->base.is_jmp = DISAS_STOP;
6831            break;
6832        /* 6,7 are implementation dependent */
6833        case CP0_REG16__CONFIG6:
6834            /* ignored */
6835            register_name = "Config6";
6836            break;
6837        case CP0_REG16__CONFIG7:
6838            /* ignored */
6839            register_name = "Config7";
6840            break;
6841        default:
6842            register_name = "Invalid config selector";
6843            goto cp0_unimplemented;
6844        }
6845        break;
6846    case CP0_REGISTER_17:
6847        switch (sel) {
6848        case CP0_REG17__LLADDR:
6849            gen_helper_mtc0_lladdr(cpu_env, arg);
6850            register_name = "LLAddr";
6851            break;
6852        case CP0_REG17__MAAR:
6853            CP0_CHECK(ctx->mrp);
6854            gen_helper_mtc0_maar(cpu_env, arg);
6855            register_name = "MAAR";
6856            break;
6857        case CP0_REG17__MAARI:
6858            CP0_CHECK(ctx->mrp);
6859            gen_helper_mtc0_maari(cpu_env, arg);
6860            register_name = "MAARI";
6861            break;
6862        default:
6863            goto cp0_unimplemented;
6864        }
6865        break;
6866    case CP0_REGISTER_18:
6867        switch (sel) {
6868        case CP0_REG18__WATCHLO0:
6869        case CP0_REG18__WATCHLO1:
6870        case CP0_REG18__WATCHLO2:
6871        case CP0_REG18__WATCHLO3:
6872        case CP0_REG18__WATCHLO4:
6873        case CP0_REG18__WATCHLO5:
6874        case CP0_REG18__WATCHLO6:
6875        case CP0_REG18__WATCHLO7:
6876            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6877            gen_helper_0e1i(mtc0_watchlo, arg, sel);
6878            register_name = "WatchLo";
6879            break;
6880        default:
6881            goto cp0_unimplemented;
6882        }
6883        break;
6884    case CP0_REGISTER_19:
6885        switch (sel) {
6886        case CP0_REG19__WATCHHI0:
6887        case CP0_REG19__WATCHHI1:
6888        case CP0_REG19__WATCHHI2:
6889        case CP0_REG19__WATCHHI3:
6890        case CP0_REG19__WATCHHI4:
6891        case CP0_REG19__WATCHHI5:
6892        case CP0_REG19__WATCHHI6:
6893        case CP0_REG19__WATCHHI7:
6894            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6895            gen_helper_0e1i(mtc0_watchhi, arg, sel);
6896            register_name = "WatchHi";
6897            break;
6898        default:
6899            goto cp0_unimplemented;
6900        }
6901        break;
6902    case CP0_REGISTER_20:
6903        switch (sel) {
6904        case CP0_REG20__XCONTEXT:
6905#if defined(TARGET_MIPS64)
6906            check_insn(ctx, ISA_MIPS3);
6907            gen_helper_mtc0_xcontext(cpu_env, arg);
6908            register_name = "XContext";
6909            break;
6910#endif
6911        default:
6912            goto cp0_unimplemented;
6913        }
6914        break;
6915    case CP0_REGISTER_21:
6916       /* Officially reserved, but sel 0 is used for R1x000 framemask */
6917        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
6918        switch (sel) {
6919        case 0:
6920            gen_helper_mtc0_framemask(cpu_env, arg);
6921            register_name = "Framemask";
6922            break;
6923        default:
6924            goto cp0_unimplemented;
6925        }
6926        break;
6927    case CP0_REGISTER_22:
6928        /* ignored */
6929        register_name = "Diagnostic"; /* implementation dependent */
6930        break;
6931    case CP0_REGISTER_23:
6932        switch (sel) {
6933        case CP0_REG23__DEBUG:
6934            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6935            /* DISAS_STOP isn't good enough here, hflags may have changed. */
6936            gen_save_pc(ctx->base.pc_next + 4);
6937            ctx->base.is_jmp = DISAS_EXIT;
6938            register_name = "Debug";
6939            break;
6940        case CP0_REG23__TRACECONTROL:
6941            /* PDtrace support */
6942            /* gen_helper_mtc0_tracecontrol(cpu_env, arg);  */
6943            register_name = "TraceControl";
6944            /* Stop translation as we may have switched the execution mode */
6945            ctx->base.is_jmp = DISAS_STOP;
6946            goto cp0_unimplemented;
6947        case CP0_REG23__TRACECONTROL2:
6948            /* PDtrace support */
6949            /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
6950            register_name = "TraceControl2";
6951            /* Stop translation as we may have switched the execution mode */
6952            ctx->base.is_jmp = DISAS_STOP;
6953            goto cp0_unimplemented;
6954        case CP0_REG23__USERTRACEDATA1:
6955            /* Stop translation as we may have switched the execution mode */
6956            ctx->base.is_jmp = DISAS_STOP;
6957            /* PDtrace support */
6958            /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
6959            register_name = "UserTraceData";
6960            /* Stop translation as we may have switched the execution mode */
6961            ctx->base.is_jmp = DISAS_STOP;
6962            goto cp0_unimplemented;
6963        case CP0_REG23__TRACEIBPC:
6964            /* PDtrace support */
6965            /* gen_helper_mtc0_traceibpc(cpu_env, arg);     */
6966            /* Stop translation as we may have switched the execution mode */
6967            ctx->base.is_jmp = DISAS_STOP;
6968            register_name = "TraceIBPC";
6969            goto cp0_unimplemented;
6970        case CP0_REG23__TRACEDBPC:
6971            /* PDtrace support */
6972            /* gen_helper_mtc0_tracedbpc(cpu_env, arg);     */
6973            /* Stop translation as we may have switched the execution mode */
6974            ctx->base.is_jmp = DISAS_STOP;
6975            register_name = "TraceDBPC";
6976            goto cp0_unimplemented;
6977        default:
6978            goto cp0_unimplemented;
6979        }
6980        break;
6981    case CP0_REGISTER_24:
6982        switch (sel) {
6983        case CP0_REG24__DEPC:
6984            /* EJTAG support */
6985            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6986            register_name = "DEPC";
6987            break;
6988        default:
6989            goto cp0_unimplemented;
6990        }
6991        break;
6992    case CP0_REGISTER_25:
6993        switch (sel) {
6994        case CP0_REG25__PERFCTL0:
6995            gen_helper_mtc0_performance0(cpu_env, arg);
6996            register_name = "Performance0";
6997            break;
6998        case CP0_REG25__PERFCNT0:
6999            /* gen_helper_mtc0_performance1(arg); */
7000            register_name = "Performance1";
7001            goto cp0_unimplemented;
7002        case CP0_REG25__PERFCTL1:
7003            /* gen_helper_mtc0_performance2(arg); */
7004            register_name = "Performance2";
7005            goto cp0_unimplemented;
7006        case CP0_REG25__PERFCNT1:
7007            /* gen_helper_mtc0_performance3(arg); */
7008            register_name = "Performance3";
7009            goto cp0_unimplemented;
7010        case CP0_REG25__PERFCTL2:
7011            /* gen_helper_mtc0_performance4(arg); */
7012            register_name = "Performance4";
7013            goto cp0_unimplemented;
7014        case CP0_REG25__PERFCNT2:
7015            /* gen_helper_mtc0_performance5(arg); */
7016            register_name = "Performance5";
7017            goto cp0_unimplemented;
7018        case CP0_REG25__PERFCTL3:
7019            /* gen_helper_mtc0_performance6(arg); */
7020            register_name = "Performance6";
7021            goto cp0_unimplemented;
7022        case CP0_REG25__PERFCNT3:
7023            /* gen_helper_mtc0_performance7(arg); */
7024            register_name = "Performance7";
7025            goto cp0_unimplemented;
7026        default:
7027            goto cp0_unimplemented;
7028        }
7029       break;
7030    case CP0_REGISTER_26:
7031        switch (sel) {
7032        case CP0_REG26__ERRCTL:
7033            gen_helper_mtc0_errctl(cpu_env, arg);
7034            ctx->base.is_jmp = DISAS_STOP;
7035            register_name = "ErrCtl";
7036            break;
7037        default:
7038            goto cp0_unimplemented;
7039        }
7040        break;
7041    case CP0_REGISTER_27:
7042        switch (sel) {
7043        case CP0_REG27__CACHERR:
7044            /* ignored */
7045            register_name = "CacheErr";
7046            break;
7047        default:
7048            goto cp0_unimplemented;
7049        }
7050       break;
7051    case CP0_REGISTER_28:
7052        switch (sel) {
7053        case CP0_REG28__TAGLO:
7054        case CP0_REG28__TAGLO1:
7055        case CP0_REG28__TAGLO2:
7056        case CP0_REG28__TAGLO3:
7057            gen_helper_mtc0_taglo(cpu_env, arg);
7058            register_name = "TagLo";
7059            break;
7060        case CP0_REG28__DATALO:
7061        case CP0_REG28__DATALO1:
7062        case CP0_REG28__DATALO2:
7063        case CP0_REG28__DATALO3:
7064            gen_helper_mtc0_datalo(cpu_env, arg);
7065            register_name = "DataLo";
7066            break;
7067        default:
7068            goto cp0_unimplemented;
7069        }
7070        break;
7071    case CP0_REGISTER_29:
7072        switch (sel) {
7073        case CP0_REG29__TAGHI:
7074        case CP0_REG29__TAGHI1:
7075        case CP0_REG29__TAGHI2:
7076        case CP0_REG29__TAGHI3:
7077            gen_helper_mtc0_taghi(cpu_env, arg);
7078            register_name = "TagHi";
7079            break;
7080        case CP0_REG29__DATAHI:
7081        case CP0_REG29__DATAHI1:
7082        case CP0_REG29__DATAHI2:
7083        case CP0_REG29__DATAHI3:
7084            gen_helper_mtc0_datahi(cpu_env, arg);
7085            register_name = "DataHi";
7086            break;
7087        default:
7088            register_name = "invalid sel";
7089            goto cp0_unimplemented;
7090        }
7091       break;
7092    case CP0_REGISTER_30:
7093        switch (sel) {
7094        case CP0_REG30__ERROREPC:
7095            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7096            register_name = "ErrorEPC";
7097            break;
7098        default:
7099            goto cp0_unimplemented;
7100        }
7101        break;
7102    case CP0_REGISTER_31:
7103        switch (sel) {
7104        case CP0_REG31__DESAVE:
7105            /* EJTAG support */
7106            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7107            register_name = "DESAVE";
7108            break;
7109        case CP0_REG31__KSCRATCH1:
7110        case CP0_REG31__KSCRATCH2:
7111        case CP0_REG31__KSCRATCH3:
7112        case CP0_REG31__KSCRATCH4:
7113        case CP0_REG31__KSCRATCH5:
7114        case CP0_REG31__KSCRATCH6:
7115            CP0_CHECK(ctx->kscrexist & (1 << sel));
7116            tcg_gen_st_tl(arg, cpu_env,
7117                          offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
7118            register_name = "KScratch";
7119            break;
7120        default:
7121            goto cp0_unimplemented;
7122        }
7123        break;
7124    default:
7125       goto cp0_unimplemented;
7126    }
7127    trace_mips_translate_c0("mtc0", register_name, reg, sel);
7128
7129    /* For simplicity assume that all writes can cause interrupts.  */
7130    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7131        /*
7132         * DISAS_STOP isn't sufficient, we need to ensure we break out of
7133         * translated code to check for pending interrupts.
7134         */
7135        gen_save_pc(ctx->base.pc_next + 4);
7136        ctx->base.is_jmp = DISAS_EXIT;
7137    }
7138    return;
7139
7140cp0_unimplemented:
7141    qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
7142                  register_name, reg, sel);
7143}
7144
7145#if defined(TARGET_MIPS64)
7146static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7147{
7148    const char *register_name = "invalid";
7149
7150    if (sel != 0) {
7151        check_insn(ctx, ISA_MIPS_R1);
7152    }
7153
7154    switch (reg) {
7155    case CP0_REGISTER_00:
7156        switch (sel) {
7157        case CP0_REG00__INDEX:
7158            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7159            register_name = "Index";
7160            break;
7161        case CP0_REG00__MVPCONTROL:
7162            CP0_CHECK(ctx->insn_flags & ASE_MT);
7163            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7164            register_name = "MVPControl";
7165            break;
7166        case CP0_REG00__MVPCONF0:
7167            CP0_CHECK(ctx->insn_flags & ASE_MT);
7168            gen_helper_mfc0_mvpconf0(arg, cpu_env);
7169            register_name = "MVPConf0";
7170            break;
7171        case CP0_REG00__MVPCONF1:
7172            CP0_CHECK(ctx->insn_flags & ASE_MT);
7173            gen_helper_mfc0_mvpconf1(arg, cpu_env);
7174            register_name = "MVPConf1";
7175            break;
7176        case CP0_REG00__VPCONTROL:
7177            CP0_CHECK(ctx->vp);
7178            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
7179            register_name = "VPControl";
7180            break;
7181        default:
7182            goto cp0_unimplemented;
7183        }
7184        break;
7185    case CP0_REGISTER_01:
7186        switch (sel) {
7187        case CP0_REG01__RANDOM:
7188            CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7189            gen_helper_mfc0_random(arg, cpu_env);
7190            register_name = "Random";
7191            break;
7192        case CP0_REG01__VPECONTROL:
7193            CP0_CHECK(ctx->insn_flags & ASE_MT);
7194            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7195            register_name = "VPEControl";
7196            break;
7197        case CP0_REG01__VPECONF0:
7198            CP0_CHECK(ctx->insn_flags & ASE_MT);
7199            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7200            register_name = "VPEConf0";
7201            break;
7202        case CP0_REG01__VPECONF1:
7203            CP0_CHECK(ctx->insn_flags & ASE_MT);
7204            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7205            register_name = "VPEConf1";
7206            break;
7207        case CP0_REG01__YQMASK:
7208            CP0_CHECK(ctx->insn_flags & ASE_MT);
7209            tcg_gen_ld_tl(arg, cpu_env,
7210                          offsetof(CPUMIPSState, CP0_YQMask));
7211            register_name = "YQMask";
7212            break;
7213        case CP0_REG01__VPESCHEDULE:
7214            CP0_CHECK(ctx->insn_flags & ASE_MT);
7215            tcg_gen_ld_tl(arg, cpu_env,
7216                          offsetof(CPUMIPSState, CP0_VPESchedule));
7217            register_name = "VPESchedule";
7218            break;
7219        case CP0_REG01__VPESCHEFBACK:
7220            CP0_CHECK(ctx->insn_flags & ASE_MT);
7221            tcg_gen_ld_tl(arg, cpu_env,
7222                          offsetof(CPUMIPSState, CP0_VPEScheFBack));
7223            register_name = "VPEScheFBack";
7224            break;
7225        case CP0_REG01__VPEOPT:
7226            CP0_CHECK(ctx->insn_flags & ASE_MT);
7227            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7228            register_name = "VPEOpt";
7229            break;
7230        default:
7231            goto cp0_unimplemented;
7232        }
7233        break;
7234    case CP0_REGISTER_02:
7235        switch (sel) {
7236        case CP0_REG02__ENTRYLO0:
7237            tcg_gen_ld_tl(arg, cpu_env,
7238                          offsetof(CPUMIPSState, CP0_EntryLo0));
7239            register_name = "EntryLo0";
7240            break;
7241        case CP0_REG02__TCSTATUS:
7242            CP0_CHECK(ctx->insn_flags & ASE_MT);
7243            gen_helper_mfc0_tcstatus(arg, cpu_env);
7244            register_name = "TCStatus";
7245            break;
7246        case CP0_REG02__TCBIND:
7247            CP0_CHECK(ctx->insn_flags & ASE_MT);
7248            gen_helper_mfc0_tcbind(arg, cpu_env);
7249            register_name = "TCBind";
7250            break;
7251        case CP0_REG02__TCRESTART:
7252            CP0_CHECK(ctx->insn_flags & ASE_MT);
7253            gen_helper_dmfc0_tcrestart(arg, cpu_env);
7254            register_name = "TCRestart";
7255            break;
7256        case CP0_REG02__TCHALT:
7257            CP0_CHECK(ctx->insn_flags & ASE_MT);
7258            gen_helper_dmfc0_tchalt(arg, cpu_env);
7259            register_name = "TCHalt";
7260            break;
7261        case CP0_REG02__TCCONTEXT:
7262            CP0_CHECK(ctx->insn_flags & ASE_MT);
7263            gen_helper_dmfc0_tccontext(arg, cpu_env);
7264            register_name = "TCContext";
7265            break;
7266        case CP0_REG02__TCSCHEDULE:
7267            CP0_CHECK(ctx->insn_flags & ASE_MT);
7268            gen_helper_dmfc0_tcschedule(arg, cpu_env);
7269            register_name = "TCSchedule";
7270            break;
7271        case CP0_REG02__TCSCHEFBACK:
7272            CP0_CHECK(ctx->insn_flags & ASE_MT);
7273            gen_helper_dmfc0_tcschefback(arg, cpu_env);
7274            register_name = "TCScheFBack";
7275            break;
7276        default:
7277            goto cp0_unimplemented;
7278        }
7279        break;
7280    case CP0_REGISTER_03:
7281        switch (sel) {
7282        case CP0_REG03__ENTRYLO1:
7283            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
7284            register_name = "EntryLo1";
7285            break;
7286        case CP0_REG03__GLOBALNUM:
7287            CP0_CHECK(ctx->vp);
7288            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
7289            register_name = "GlobalNumber";
7290            break;
7291        default:
7292            goto cp0_unimplemented;
7293        }
7294        break;
7295    case CP0_REGISTER_04:
7296        switch (sel) {
7297        case CP0_REG04__CONTEXT:
7298            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
7299            register_name = "Context";
7300            break;
7301        case CP0_REG04__CONTEXTCONFIG:
7302            /* SmartMIPS ASE */
7303            /* gen_helper_dmfc0_contextconfig(arg); */
7304            register_name = "ContextConfig";
7305            goto cp0_unimplemented;
7306        case CP0_REG04__USERLOCAL:
7307            CP0_CHECK(ctx->ulri);
7308            tcg_gen_ld_tl(arg, cpu_env,
7309                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7310            register_name = "UserLocal";
7311            break;
7312        case CP0_REG04__MMID:
7313            CP0_CHECK(ctx->mi);
7314            gen_helper_mtc0_memorymapid(cpu_env, arg);
7315            register_name = "MMID";
7316            break;
7317        default:
7318            goto cp0_unimplemented;
7319        }
7320        break;
7321    case CP0_REGISTER_05:
7322        switch (sel) {
7323        case CP0_REG05__PAGEMASK:
7324            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
7325            register_name = "PageMask";
7326            break;
7327        case CP0_REG05__PAGEGRAIN:
7328            check_insn(ctx, ISA_MIPS_R2);
7329            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
7330            register_name = "PageGrain";
7331            break;
7332        case CP0_REG05__SEGCTL0:
7333            CP0_CHECK(ctx->sc);
7334            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
7335            register_name = "SegCtl0";
7336            break;
7337        case CP0_REG05__SEGCTL1:
7338            CP0_CHECK(ctx->sc);
7339            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
7340            register_name = "SegCtl1";
7341            break;
7342        case CP0_REG05__SEGCTL2:
7343            CP0_CHECK(ctx->sc);
7344            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
7345            register_name = "SegCtl2";
7346            break;
7347        case CP0_REG05__PWBASE:
7348            check_pw(ctx);
7349            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
7350            register_name = "PWBase";
7351            break;
7352        case CP0_REG05__PWFIELD:
7353            check_pw(ctx);
7354            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
7355            register_name = "PWField";
7356            break;
7357        case CP0_REG05__PWSIZE:
7358            check_pw(ctx);
7359            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
7360            register_name = "PWSize";
7361            break;
7362        default:
7363            goto cp0_unimplemented;
7364        }
7365        break;
7366    case CP0_REGISTER_06:
7367        switch (sel) {
7368        case CP0_REG06__WIRED:
7369            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
7370            register_name = "Wired";
7371            break;
7372        case CP0_REG06__SRSCONF0:
7373            check_insn(ctx, ISA_MIPS_R2);
7374            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
7375            register_name = "SRSConf0";
7376            break;
7377        case CP0_REG06__SRSCONF1:
7378            check_insn(ctx, ISA_MIPS_R2);
7379            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
7380            register_name = "SRSConf1";
7381            break;
7382        case CP0_REG06__SRSCONF2:
7383            check_insn(ctx, ISA_MIPS_R2);
7384            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
7385            register_name = "SRSConf2";
7386            break;
7387        case CP0_REG06__SRSCONF3:
7388            check_insn(ctx, ISA_MIPS_R2);
7389            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
7390            register_name = "SRSConf3";
7391            break;
7392        case CP0_REG06__SRSCONF4:
7393            check_insn(ctx, ISA_MIPS_R2);
7394            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
7395            register_name = "SRSConf4";
7396            break;
7397        case CP0_REG06__PWCTL:
7398            check_pw(ctx);
7399            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
7400            register_name = "PWCtl";
7401            break;
7402        default:
7403            goto cp0_unimplemented;
7404        }
7405        break;
7406    case CP0_REGISTER_07:
7407        switch (sel) {
7408        case CP0_REG07__HWRENA:
7409            check_insn(ctx, ISA_MIPS_R2);
7410            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
7411            register_name = "HWREna";
7412            break;
7413        default:
7414            goto cp0_unimplemented;
7415        }
7416        break;
7417    case CP0_REGISTER_08:
7418        switch (sel) {
7419        case CP0_REG08__BADVADDR:
7420            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
7421            register_name = "BadVAddr";
7422            break;
7423        case CP0_REG08__BADINSTR:
7424            CP0_CHECK(ctx->bi);
7425            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7426            register_name = "BadInstr";
7427            break;
7428        case CP0_REG08__BADINSTRP:
7429            CP0_CHECK(ctx->bp);
7430            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7431            register_name = "BadInstrP";
7432            break;
7433        case CP0_REG08__BADINSTRX:
7434            CP0_CHECK(ctx->bi);
7435            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7436            tcg_gen_andi_tl(arg, arg, ~0xffff);
7437            register_name = "BadInstrX";
7438            break;
7439        default:
7440            goto cp0_unimplemented;
7441        }
7442        break;
7443    case CP0_REGISTER_09:
7444        switch (sel) {
7445        case CP0_REG09__COUNT:
7446            /* Mark as an IO operation because we read the time.  */
7447            if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7448                gen_io_start();
7449            }
7450            gen_helper_mfc0_count(arg, cpu_env);
7451            /*
7452             * Break the TB to be able to take timer interrupts immediately
7453             * after reading count. DISAS_STOP isn't sufficient, we need to
7454             * ensure we break completely out of translated code.
7455             */
7456            gen_save_pc(ctx->base.pc_next + 4);
7457            ctx->base.is_jmp = DISAS_EXIT;
7458            register_name = "Count";
7459            break;
7460        case CP0_REG09__SAARI:
7461            CP0_CHECK(ctx->saar);
7462            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
7463            register_name = "SAARI";
7464            break;
7465        case CP0_REG09__SAAR:
7466            CP0_CHECK(ctx->saar);
7467            gen_helper_dmfc0_saar(arg, cpu_env);
7468            register_name = "SAAR";
7469            break;
7470        default:
7471            goto cp0_unimplemented;
7472        }
7473        break;
7474    case CP0_REGISTER_10:
7475        switch (sel) {
7476        case CP0_REG10__ENTRYHI:
7477            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
7478            register_name = "EntryHi";
7479            break;
7480        default:
7481            goto cp0_unimplemented;
7482        }
7483        break;
7484    case CP0_REGISTER_11:
7485        switch (sel) {
7486        case CP0_REG11__COMPARE:
7487            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
7488            register_name = "Compare";
7489            break;
7490        /* 6,7 are implementation dependent */
7491        default:
7492            goto cp0_unimplemented;
7493        }
7494        break;
7495    case CP0_REGISTER_12:
7496        switch (sel) {
7497        case CP0_REG12__STATUS:
7498            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
7499            register_name = "Status";
7500            break;
7501        case CP0_REG12__INTCTL:
7502            check_insn(ctx, ISA_MIPS_R2);
7503            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
7504            register_name = "IntCtl";
7505            break;
7506        case CP0_REG12__SRSCTL:
7507            check_insn(ctx, ISA_MIPS_R2);
7508            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
7509            register_name = "SRSCtl";
7510            break;
7511        case CP0_REG12__SRSMAP:
7512            check_insn(ctx, ISA_MIPS_R2);
7513            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7514            register_name = "SRSMap";
7515            break;
7516        default:
7517            goto cp0_unimplemented;
7518        }
7519        break;
7520    case CP0_REGISTER_13:
7521        switch (sel) {
7522        case CP0_REG13__CAUSE:
7523            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7524            register_name = "Cause";
7525            break;
7526        default:
7527            goto cp0_unimplemented;
7528        }
7529        break;
7530    case CP0_REGISTER_14:
7531        switch (sel) {
7532        case CP0_REG14__EPC:
7533            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7534            register_name = "EPC";
7535            break;
7536        default:
7537            goto cp0_unimplemented;
7538        }
7539        break;
7540    case CP0_REGISTER_15:
7541        switch (sel) {
7542        case CP0_REG15__PRID:
7543            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7544            register_name = "PRid";
7545            break;
7546        case CP0_REG15__EBASE:
7547            check_insn(ctx, ISA_MIPS_R2);
7548            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7549            register_name = "EBase";
7550            break;
7551        case CP0_REG15__CMGCRBASE:
7552            check_insn(ctx, ISA_MIPS_R2);
7553            CP0_CHECK(ctx->cmgcr);
7554            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7555            register_name = "CMGCRBase";
7556            break;
7557        default:
7558            goto cp0_unimplemented;
7559        }
7560        break;
7561    case CP0_REGISTER_16:
7562        switch (sel) {
7563        case CP0_REG16__CONFIG:
7564            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7565            register_name = "Config";
7566            break;
7567        case CP0_REG16__CONFIG1:
7568            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7569            register_name = "Config1";
7570            break;
7571        case CP0_REG16__CONFIG2:
7572            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7573            register_name = "Config2";
7574            break;
7575        case CP0_REG16__CONFIG3:
7576            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7577            register_name = "Config3";
7578            break;
7579        case CP0_REG16__CONFIG4:
7580            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7581            register_name = "Config4";
7582            break;
7583        case CP0_REG16__CONFIG5:
7584            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7585            register_name = "Config5";
7586            break;
7587        /* 6,7 are implementation dependent */
7588        case CP0_REG16__CONFIG6:
7589            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7590            register_name = "Config6";
7591            break;
7592        case CP0_REG16__CONFIG7:
7593            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7594            register_name = "Config7";
7595            break;
7596        default:
7597            goto cp0_unimplemented;
7598        }
7599        break;
7600    case CP0_REGISTER_17:
7601        switch (sel) {
7602        case CP0_REG17__LLADDR:
7603            gen_helper_dmfc0_lladdr(arg, cpu_env);
7604            register_name = "LLAddr";
7605            break;
7606        case CP0_REG17__MAAR:
7607            CP0_CHECK(ctx->mrp);
7608            gen_helper_dmfc0_maar(arg, cpu_env);
7609            register_name = "MAAR";
7610            break;
7611        case CP0_REG17__MAARI:
7612            CP0_CHECK(ctx->mrp);
7613            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7614            register_name = "MAARI";
7615            break;
7616        default:
7617            goto cp0_unimplemented;
7618        }
7619        break;
7620    case CP0_REGISTER_18:
7621        switch (sel) {
7622        case CP0_REG18__WATCHLO0:
7623        case CP0_REG18__WATCHLO1:
7624        case CP0_REG18__WATCHLO2:
7625        case CP0_REG18__WATCHLO3:
7626        case CP0_REG18__WATCHLO4:
7627        case CP0_REG18__WATCHLO5:
7628        case CP0_REG18__WATCHLO6:
7629        case CP0_REG18__WATCHLO7:
7630            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7631            gen_helper_1e0i(dmfc0_watchlo, arg, sel);
7632            register_name = "WatchLo";
7633            break;
7634        default:
7635            goto cp0_unimplemented;
7636        }
7637        break;
7638    case CP0_REGISTER_19:
7639        switch (sel) {
7640        case CP0_REG19__WATCHHI0:
7641        case CP0_REG19__WATCHHI1:
7642        case CP0_REG19__WATCHHI2:
7643        case CP0_REG19__WATCHHI3:
7644        case CP0_REG19__WATCHHI4:
7645        case CP0_REG19__WATCHHI5:
7646        case CP0_REG19__WATCHHI6:
7647        case CP0_REG19__WATCHHI7:
7648            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7649            gen_helper_1e0i(dmfc0_watchhi, arg, sel);
7650            register_name = "WatchHi";
7651            break;
7652        default:
7653            goto cp0_unimplemented;
7654        }
7655        break;
7656    case CP0_REGISTER_20:
7657        switch (sel) {
7658        case CP0_REG20__XCONTEXT:
7659            check_insn(ctx, ISA_MIPS3);
7660            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
7661            register_name = "XContext";
7662            break;
7663        default:
7664            goto cp0_unimplemented;
7665        }
7666        break;
7667    case CP0_REGISTER_21:
7668        /* Officially reserved, but sel 0 is used for R1x000 framemask */
7669        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7670        switch (sel) {
7671        case 0:
7672            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
7673            register_name = "Framemask";
7674            break;
7675        default:
7676            goto cp0_unimplemented;
7677        }
7678        break;
7679    case CP0_REGISTER_22:
7680        tcg_gen_movi_tl(arg, 0); /* unimplemented */
7681        register_name = "'Diagnostic"; /* implementation dependent */
7682        break;
7683    case CP0_REGISTER_23:
7684        switch (sel) {
7685        case CP0_REG23__DEBUG:
7686            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
7687            register_name = "Debug";
7688            break;
7689        case CP0_REG23__TRACECONTROL:
7690            /* PDtrace support */
7691            /* gen_helper_dmfc0_tracecontrol(arg, cpu_env);  */
7692            register_name = "TraceControl";
7693            goto cp0_unimplemented;
7694        case CP0_REG23__TRACECONTROL2:
7695            /* PDtrace support */
7696            /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */
7697            register_name = "TraceControl2";
7698            goto cp0_unimplemented;
7699        case CP0_REG23__USERTRACEDATA1:
7700            /* PDtrace support */
7701            /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/
7702            register_name = "UserTraceData1";
7703            goto cp0_unimplemented;
7704        case CP0_REG23__TRACEIBPC:
7705            /* PDtrace support */
7706            /* gen_helper_dmfc0_traceibpc(arg, cpu_env);     */
7707            register_name = "TraceIBPC";
7708            goto cp0_unimplemented;
7709        case CP0_REG23__TRACEDBPC:
7710            /* PDtrace support */
7711            /* gen_helper_dmfc0_tracedbpc(arg, cpu_env);     */
7712            register_name = "TraceDBPC";
7713            goto cp0_unimplemented;
7714        default:
7715            goto cp0_unimplemented;
7716        }
7717        break;
7718    case CP0_REGISTER_24:
7719        switch (sel) {
7720        case CP0_REG24__DEPC:
7721            /* EJTAG support */
7722            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7723            register_name = "DEPC";
7724            break;
7725        default:
7726            goto cp0_unimplemented;
7727        }
7728        break;
7729    case CP0_REGISTER_25:
7730        switch (sel) {
7731        case CP0_REG25__PERFCTL0:
7732            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
7733            register_name = "Performance0";
7734            break;
7735        case CP0_REG25__PERFCNT0:
7736            /* gen_helper_dmfc0_performance1(arg); */
7737            register_name = "Performance1";
7738            goto cp0_unimplemented;
7739        case CP0_REG25__PERFCTL1:
7740            /* gen_helper_dmfc0_performance2(arg); */
7741            register_name = "Performance2";
7742            goto cp0_unimplemented;
7743        case CP0_REG25__PERFCNT1:
7744            /* gen_helper_dmfc0_performance3(arg); */
7745            register_name = "Performance3";
7746            goto cp0_unimplemented;
7747        case CP0_REG25__PERFCTL2:
7748            /* gen_helper_dmfc0_performance4(arg); */
7749            register_name = "Performance4";
7750            goto cp0_unimplemented;
7751        case CP0_REG25__PERFCNT2:
7752            /* gen_helper_dmfc0_performance5(arg); */
7753            register_name = "Performance5";
7754            goto cp0_unimplemented;
7755        case CP0_REG25__PERFCTL3:
7756            /* gen_helper_dmfc0_performance6(arg); */
7757            register_name = "Performance6";
7758            goto cp0_unimplemented;
7759        case CP0_REG25__PERFCNT3:
7760            /* gen_helper_dmfc0_performance7(arg); */
7761            register_name = "Performance7";
7762            goto cp0_unimplemented;
7763        default:
7764            goto cp0_unimplemented;
7765        }
7766        break;
7767    case CP0_REGISTER_26:
7768        switch (sel) {
7769        case CP0_REG26__ERRCTL:
7770            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
7771            register_name = "ErrCtl";
7772            break;
7773        default:
7774            goto cp0_unimplemented;
7775        }
7776        break;
7777    case CP0_REGISTER_27:
7778        switch (sel) {
7779        /* ignored */
7780        case CP0_REG27__CACHERR:
7781            tcg_gen_movi_tl(arg, 0); /* unimplemented */
7782            register_name = "CacheErr";
7783            break;
7784        default:
7785            goto cp0_unimplemented;
7786        }
7787        break;
7788    case CP0_REGISTER_28:
7789        switch (sel) {
7790        case CP0_REG28__TAGLO:
7791        case CP0_REG28__TAGLO1:
7792        case CP0_REG28__TAGLO2:
7793        case CP0_REG28__TAGLO3:
7794            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
7795            register_name = "TagLo";
7796            break;
7797        case CP0_REG28__DATALO:
7798        case CP0_REG28__DATALO1:
7799        case CP0_REG28__DATALO2:
7800        case CP0_REG28__DATALO3:
7801            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
7802            register_name = "DataLo";
7803            break;
7804        default:
7805            goto cp0_unimplemented;
7806        }
7807        break;
7808    case CP0_REGISTER_29:
7809        switch (sel) {
7810        case CP0_REG29__TAGHI:
7811        case CP0_REG29__TAGHI1:
7812        case CP0_REG29__TAGHI2:
7813        case CP0_REG29__TAGHI3:
7814            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
7815            register_name = "TagHi";
7816            break;
7817        case CP0_REG29__DATAHI:
7818        case CP0_REG29__DATAHI1:
7819        case CP0_REG29__DATAHI2:
7820        case CP0_REG29__DATAHI3:
7821            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
7822            register_name = "DataHi";
7823            break;
7824        default:
7825            goto cp0_unimplemented;
7826        }
7827        break;
7828    case CP0_REGISTER_30:
7829        switch (sel) {
7830        case CP0_REG30__ERROREPC:
7831            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7832            register_name = "ErrorEPC";
7833            break;
7834        default:
7835            goto cp0_unimplemented;
7836        }
7837        break;
7838    case CP0_REGISTER_31:
7839        switch (sel) {
7840        case CP0_REG31__DESAVE:
7841            /* EJTAG support */
7842            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7843            register_name = "DESAVE";
7844            break;
7845        case CP0_REG31__KSCRATCH1:
7846        case CP0_REG31__KSCRATCH2:
7847        case CP0_REG31__KSCRATCH3:
7848        case CP0_REG31__KSCRATCH4:
7849        case CP0_REG31__KSCRATCH5:
7850        case CP0_REG31__KSCRATCH6:
7851            CP0_CHECK(ctx->kscrexist & (1 << sel));
7852            tcg_gen_ld_tl(arg, cpu_env,
7853                          offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
7854            register_name = "KScratch";
7855            break;
7856        default:
7857            goto cp0_unimplemented;
7858        }
7859        break;
7860    default:
7861        goto cp0_unimplemented;
7862    }
7863    trace_mips_translate_c0("dmfc0", register_name, reg, sel);
7864    return;
7865
7866cp0_unimplemented:
7867    qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
7868                  register_name, reg, sel);
7869    gen_mfc0_unimplemented(ctx, arg);
7870}
7871
7872static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7873{
7874    const char *register_name = "invalid";
7875
7876    if (sel != 0) {
7877        check_insn(ctx, ISA_MIPS_R1);
7878    }
7879
7880    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7881        gen_io_start();
7882    }
7883
7884    switch (reg) {
7885    case CP0_REGISTER_00:
7886        switch (sel) {
7887        case CP0_REG00__INDEX:
7888            gen_helper_mtc0_index(cpu_env, arg);
7889            register_name = "Index";
7890            break;
7891        case CP0_REG00__MVPCONTROL:
7892            CP0_CHECK(ctx->insn_flags & ASE_MT);
7893            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
7894            register_name = "MVPControl";
7895            break;
7896        case CP0_REG00__MVPCONF0:
7897            CP0_CHECK(ctx->insn_flags & ASE_MT);
7898            /* ignored */
7899            register_name = "MVPConf0";
7900            break;
7901        case CP0_REG00__MVPCONF1:
7902            CP0_CHECK(ctx->insn_flags & ASE_MT);
7903            /* ignored */
7904            register_name = "MVPConf1";
7905            break;
7906        case CP0_REG00__VPCONTROL:
7907            CP0_CHECK(ctx->vp);
7908            /* ignored */
7909            register_name = "VPControl";
7910            break;
7911        default:
7912            goto cp0_unimplemented;
7913        }
7914        break;
7915    case CP0_REGISTER_01:
7916        switch (sel) {
7917        case CP0_REG01__RANDOM:
7918            /* ignored */
7919            register_name = "Random";
7920            break;
7921        case CP0_REG01__VPECONTROL:
7922            CP0_CHECK(ctx->insn_flags & ASE_MT);
7923            gen_helper_mtc0_vpecontrol(cpu_env, arg);
7924            register_name = "VPEControl";
7925            break;
7926        case CP0_REG01__VPECONF0:
7927            CP0_CHECK(ctx->insn_flags & ASE_MT);
7928            gen_helper_mtc0_vpeconf0(cpu_env, arg);
7929            register_name = "VPEConf0";
7930            break;
7931        case CP0_REG01__VPECONF1:
7932            CP0_CHECK(ctx->insn_flags & ASE_MT);
7933            gen_helper_mtc0_vpeconf1(cpu_env, arg);
7934            register_name = "VPEConf1";
7935            break;
7936        case CP0_REG01__YQMASK:
7937            CP0_CHECK(ctx->insn_flags & ASE_MT);
7938            gen_helper_mtc0_yqmask(cpu_env, arg);
7939            register_name = "YQMask";
7940            break;
7941        case CP0_REG01__VPESCHEDULE:
7942            CP0_CHECK(ctx->insn_flags & ASE_MT);
7943            tcg_gen_st_tl(arg, cpu_env,
7944                          offsetof(CPUMIPSState, CP0_VPESchedule));
7945            register_name = "VPESchedule";
7946            break;
7947        case CP0_REG01__VPESCHEFBACK:
7948            CP0_CHECK(ctx->insn_flags & ASE_MT);
7949            tcg_gen_st_tl(arg, cpu_env,
7950                          offsetof(CPUMIPSState, CP0_VPEScheFBack));
7951            register_name = "VPEScheFBack";
7952            break;
7953        case CP0_REG01__VPEOPT:
7954            CP0_CHECK(ctx->insn_flags & ASE_MT);
7955            gen_helper_mtc0_vpeopt(cpu_env, arg);
7956            register_name = "VPEOpt";
7957            break;
7958        default:
7959            goto cp0_unimplemented;
7960        }
7961        break;
7962    case CP0_REGISTER_02:
7963        switch (sel) {
7964        case CP0_REG02__ENTRYLO0:
7965            gen_helper_dmtc0_entrylo0(cpu_env, arg);
7966            register_name = "EntryLo0";
7967            break;
7968        case CP0_REG02__TCSTATUS:
7969            CP0_CHECK(ctx->insn_flags & ASE_MT);
7970            gen_helper_mtc0_tcstatus(cpu_env, arg);
7971            register_name = "TCStatus";
7972            break;
7973        case CP0_REG02__TCBIND:
7974            CP0_CHECK(ctx->insn_flags & ASE_MT);
7975            gen_helper_mtc0_tcbind(cpu_env, arg);
7976            register_name = "TCBind";
7977            break;
7978        case CP0_REG02__TCRESTART:
7979            CP0_CHECK(ctx->insn_flags & ASE_MT);
7980            gen_helper_mtc0_tcrestart(cpu_env, arg);
7981            register_name = "TCRestart";
7982            break;
7983        case CP0_REG02__TCHALT:
7984            CP0_CHECK(ctx->insn_flags & ASE_MT);
7985            gen_helper_mtc0_tchalt(cpu_env, arg);
7986            register_name = "TCHalt";
7987            break;
7988        case CP0_REG02__TCCONTEXT:
7989            CP0_CHECK(ctx->insn_flags & ASE_MT);
7990            gen_helper_mtc0_tccontext(cpu_env, arg);
7991            register_name = "TCContext";
7992            break;
7993        case CP0_REG02__TCSCHEDULE:
7994            CP0_CHECK(ctx->insn_flags & ASE_MT);
7995            gen_helper_mtc0_tcschedule(cpu_env, arg);
7996            register_name = "TCSchedule";
7997            break;
7998        case CP0_REG02__TCSCHEFBACK:
7999            CP0_CHECK(ctx->insn_flags & ASE_MT);
8000            gen_helper_mtc0_tcschefback(cpu_env, arg);
8001            register_name = "TCScheFBack";
8002            break;
8003        default:
8004            goto cp0_unimplemented;
8005        }
8006        break;
8007    case CP0_REGISTER_03:
8008        switch (sel) {
8009        case CP0_REG03__ENTRYLO1:
8010            gen_helper_dmtc0_entrylo1(cpu_env, arg);
8011            register_name = "EntryLo1";
8012            break;
8013        case CP0_REG03__GLOBALNUM:
8014            CP0_CHECK(ctx->vp);
8015            /* ignored */
8016            register_name = "GlobalNumber";
8017            break;
8018        default:
8019            goto cp0_unimplemented;
8020        }
8021        break;
8022    case CP0_REGISTER_04:
8023        switch (sel) {
8024        case CP0_REG04__CONTEXT:
8025            gen_helper_mtc0_context(cpu_env, arg);
8026            register_name = "Context";
8027            break;
8028        case CP0_REG04__CONTEXTCONFIG:
8029            /* SmartMIPS ASE */
8030            /* gen_helper_dmtc0_contextconfig(arg); */
8031            register_name = "ContextConfig";
8032            goto cp0_unimplemented;
8033        case CP0_REG04__USERLOCAL:
8034            CP0_CHECK(ctx->ulri);
8035            tcg_gen_st_tl(arg, cpu_env,
8036                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8037            register_name = "UserLocal";
8038            break;
8039        case CP0_REG04__MMID:
8040            CP0_CHECK(ctx->mi);
8041            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
8042            register_name = "MMID";
8043            break;
8044        default:
8045            goto cp0_unimplemented;
8046        }
8047        break;
8048    case CP0_REGISTER_05:
8049        switch (sel) {
8050        case CP0_REG05__PAGEMASK:
8051            gen_helper_mtc0_pagemask(cpu_env, arg);
8052            register_name = "PageMask";
8053            break;
8054        case CP0_REG05__PAGEGRAIN:
8055            check_insn(ctx, ISA_MIPS_R2);
8056            gen_helper_mtc0_pagegrain(cpu_env, arg);
8057            register_name = "PageGrain";
8058            break;
8059        case CP0_REG05__SEGCTL0:
8060            CP0_CHECK(ctx->sc);
8061            gen_helper_mtc0_segctl0(cpu_env, arg);
8062            register_name = "SegCtl0";
8063            break;
8064        case CP0_REG05__SEGCTL1:
8065            CP0_CHECK(ctx->sc);
8066            gen_helper_mtc0_segctl1(cpu_env, arg);
8067            register_name = "SegCtl1";
8068            break;
8069        case CP0_REG05__SEGCTL2:
8070            CP0_CHECK(ctx->sc);
8071            gen_helper_mtc0_segctl2(cpu_env, arg);
8072            register_name = "SegCtl2";
8073            break;
8074        case CP0_REG05__PWBASE:
8075            check_pw(ctx);
8076            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8077            register_name = "PWBase";
8078            break;
8079        case CP0_REG05__PWFIELD:
8080            check_pw(ctx);
8081            gen_helper_mtc0_pwfield(cpu_env, arg);
8082            register_name = "PWField";
8083            break;
8084        case CP0_REG05__PWSIZE:
8085            check_pw(ctx);
8086            gen_helper_mtc0_pwsize(cpu_env, arg);
8087            register_name = "PWSize";
8088            break;
8089        default:
8090            goto cp0_unimplemented;
8091        }
8092        break;
8093    case CP0_REGISTER_06:
8094        switch (sel) {
8095        case CP0_REG06__WIRED:
8096            gen_helper_mtc0_wired(cpu_env, arg);
8097            register_name = "Wired";
8098            break;
8099        case CP0_REG06__SRSCONF0:
8100            check_insn(ctx, ISA_MIPS_R2);
8101            gen_helper_mtc0_srsconf0(cpu_env, arg);
8102            register_name = "SRSConf0";
8103            break;
8104        case CP0_REG06__SRSCONF1:
8105            check_insn(ctx, ISA_MIPS_R2);
8106            gen_helper_mtc0_srsconf1(cpu_env, arg);
8107            register_name = "SRSConf1";
8108            break;
8109        case CP0_REG06__SRSCONF2:
8110            check_insn(ctx, ISA_MIPS_R2);
8111            gen_helper_mtc0_srsconf2(cpu_env, arg);
8112            register_name = "SRSConf2";
8113            break;
8114        case CP0_REG06__SRSCONF3:
8115            check_insn(ctx, ISA_MIPS_R2);
8116            gen_helper_mtc0_srsconf3(cpu_env, arg);
8117            register_name = "SRSConf3";
8118            break;
8119        case CP0_REG06__SRSCONF4:
8120            check_insn(ctx, ISA_MIPS_R2);
8121            gen_helper_mtc0_srsconf4(cpu_env, arg);
8122            register_name = "SRSConf4";
8123            break;
8124        case CP0_REG06__PWCTL:
8125            check_pw(ctx);
8126            gen_helper_mtc0_pwctl(cpu_env, arg);
8127            register_name = "PWCtl";
8128            break;
8129        default:
8130            goto cp0_unimplemented;
8131        }
8132        break;
8133    case CP0_REGISTER_07:
8134        switch (sel) {
8135        case CP0_REG07__HWRENA:
8136            check_insn(ctx, ISA_MIPS_R2);
8137            gen_helper_mtc0_hwrena(cpu_env, arg);
8138            ctx->base.is_jmp = DISAS_STOP;
8139            register_name = "HWREna";
8140            break;
8141        default:
8142            goto cp0_unimplemented;
8143        }
8144        break;
8145    case CP0_REGISTER_08:
8146        switch (sel) {
8147        case CP0_REG08__BADVADDR:
8148            /* ignored */
8149            register_name = "BadVAddr";
8150            break;
8151        case CP0_REG08__BADINSTR:
8152            /* ignored */
8153            register_name = "BadInstr";
8154            break;
8155        case CP0_REG08__BADINSTRP:
8156            /* ignored */
8157            register_name = "BadInstrP";
8158            break;
8159        case CP0_REG08__BADINSTRX:
8160            /* ignored */
8161            register_name = "BadInstrX";
8162            break;
8163        default:
8164            goto cp0_unimplemented;
8165        }
8166        break;
8167    case CP0_REGISTER_09:
8168        switch (sel) {
8169        case CP0_REG09__COUNT:
8170            gen_helper_mtc0_count(cpu_env, arg);
8171            register_name = "Count";
8172            break;
8173        case CP0_REG09__SAARI:
8174            CP0_CHECK(ctx->saar);
8175            gen_helper_mtc0_saari(cpu_env, arg);
8176            register_name = "SAARI";
8177            break;
8178        case CP0_REG09__SAAR:
8179            CP0_CHECK(ctx->saar);
8180            gen_helper_mtc0_saar(cpu_env, arg);
8181            register_name = "SAAR";
8182            break;
8183        default:
8184            goto cp0_unimplemented;
8185        }
8186        /* Stop translation as we may have switched the execution mode */
8187        ctx->base.is_jmp = DISAS_STOP;
8188        break;
8189    case CP0_REGISTER_10:
8190        switch (sel) {
8191        case CP0_REG10__ENTRYHI:
8192            gen_helper_mtc0_entryhi(cpu_env, arg);
8193            register_name = "EntryHi";
8194            break;
8195        default:
8196            goto cp0_unimplemented;
8197        }
8198        break;
8199    case CP0_REGISTER_11:
8200        switch (sel) {
8201        case CP0_REG11__COMPARE:
8202            gen_helper_mtc0_compare(cpu_env, arg);
8203            register_name = "Compare";
8204            break;
8205        /* 6,7 are implementation dependent */
8206        default:
8207            goto cp0_unimplemented;
8208        }
8209        /* Stop translation as we may have switched the execution mode */
8210        ctx->base.is_jmp = DISAS_STOP;
8211        break;
8212    case CP0_REGISTER_12:
8213        switch (sel) {
8214        case CP0_REG12__STATUS:
8215            save_cpu_state(ctx, 1);
8216            gen_helper_mtc0_status(cpu_env, arg);
8217            /* DISAS_STOP isn't good enough here, hflags may have changed. */
8218            gen_save_pc(ctx->base.pc_next + 4);
8219            ctx->base.is_jmp = DISAS_EXIT;
8220            register_name = "Status";
8221            break;
8222        case CP0_REG12__INTCTL:
8223            check_insn(ctx, ISA_MIPS_R2);
8224            gen_helper_mtc0_intctl(cpu_env, arg);
8225            /* Stop translation as we may have switched the execution mode */
8226            ctx->base.is_jmp = DISAS_STOP;
8227            register_name = "IntCtl";
8228            break;
8229        case CP0_REG12__SRSCTL:
8230            check_insn(ctx, ISA_MIPS_R2);
8231            gen_helper_mtc0_srsctl(cpu_env, arg);
8232            /* Stop translation as we may have switched the execution mode */
8233            ctx->base.is_jmp = DISAS_STOP;
8234            register_name = "SRSCtl";
8235            break;
8236        case CP0_REG12__SRSMAP:
8237            check_insn(ctx, ISA_MIPS_R2);
8238            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8239            /* Stop translation as we may have switched the execution mode */
8240            ctx->base.is_jmp = DISAS_STOP;
8241            register_name = "SRSMap";
8242            break;
8243        default:
8244            goto cp0_unimplemented;
8245        }
8246        break;
8247    case CP0_REGISTER_13:
8248        switch (sel) {
8249        case CP0_REG13__CAUSE:
8250            save_cpu_state(ctx, 1);
8251            gen_helper_mtc0_cause(cpu_env, arg);
8252            /*
8253             * Stop translation as we may have triggered an interrupt.
8254             * DISAS_STOP isn't sufficient, we need to ensure we break out of
8255             * translated code to check for pending interrupts.
8256             */
8257            gen_save_pc(ctx->base.pc_next + 4);
8258            ctx->base.is_jmp = DISAS_EXIT;
8259            register_name = "Cause";
8260            break;
8261        default:
8262            goto cp0_unimplemented;
8263        }
8264        break;
8265    case CP0_REGISTER_14:
8266        switch (sel) {
8267        case CP0_REG14__EPC:
8268            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8269            register_name = "EPC";
8270            break;
8271        default:
8272            goto cp0_unimplemented;
8273        }
8274        break;
8275    case CP0_REGISTER_15:
8276        switch (sel) {
8277        case CP0_REG15__PRID:
8278            /* ignored */
8279            register_name = "PRid";
8280            break;
8281        case CP0_REG15__EBASE:
8282            check_insn(ctx, ISA_MIPS_R2);
8283            gen_helper_mtc0_ebase(cpu_env, arg);
8284            register_name = "EBase";
8285            break;
8286        default:
8287            goto cp0_unimplemented;
8288        }
8289        break;
8290    case CP0_REGISTER_16:
8291        switch (sel) {
8292        case CP0_REG16__CONFIG:
8293            gen_helper_mtc0_config0(cpu_env, arg);
8294            register_name = "Config";
8295            /* Stop translation as we may have switched the execution mode */
8296            ctx->base.is_jmp = DISAS_STOP;
8297            break;
8298        case CP0_REG16__CONFIG1:
8299            /* ignored, read only */
8300            register_name = "Config1";
8301            break;
8302        case CP0_REG16__CONFIG2:
8303            gen_helper_mtc0_config2(cpu_env, arg);
8304            register_name = "Config2";
8305            /* Stop translation as we may have switched the execution mode */
8306            ctx->base.is_jmp = DISAS_STOP;
8307            break;
8308        case CP0_REG16__CONFIG3:
8309            gen_helper_mtc0_config3(cpu_env, arg);
8310            register_name = "Config3";
8311            /* Stop translation as we may have switched the execution mode */
8312            ctx->base.is_jmp = DISAS_STOP;
8313            break;
8314        case CP0_REG16__CONFIG4:
8315            /* currently ignored */
8316            register_name = "Config4";
8317            break;
8318        case CP0_REG16__CONFIG5:
8319            gen_helper_mtc0_config5(cpu_env, arg);
8320            register_name = "Config5";
8321            /* Stop translation as we may have switched the execution mode */
8322            ctx->base.is_jmp = DISAS_STOP;
8323            break;
8324        /* 6,7 are implementation dependent */
8325        default:
8326            register_name = "Invalid config selector";
8327            goto cp0_unimplemented;
8328        }
8329        break;
8330    case CP0_REGISTER_17:
8331        switch (sel) {
8332        case CP0_REG17__LLADDR:
8333            gen_helper_mtc0_lladdr(cpu_env, arg);
8334            register_name = "LLAddr";
8335            break;
8336        case CP0_REG17__MAAR:
8337            CP0_CHECK(ctx->mrp);
8338            gen_helper_mtc0_maar(cpu_env, arg);
8339            register_name = "MAAR";
8340            break;
8341        case CP0_REG17__MAARI:
8342            CP0_CHECK(ctx->mrp);
8343            gen_helper_mtc0_maari(cpu_env, arg);
8344            register_name = "MAARI";
8345            break;
8346        default:
8347            goto cp0_unimplemented;
8348        }
8349        break;
8350    case CP0_REGISTER_18:
8351        switch (sel) {
8352        case CP0_REG18__WATCHLO0:
8353        case CP0_REG18__WATCHLO1:
8354        case CP0_REG18__WATCHLO2:
8355        case CP0_REG18__WATCHLO3:
8356        case CP0_REG18__WATCHLO4:
8357        case CP0_REG18__WATCHLO5:
8358        case CP0_REG18__WATCHLO6:
8359        case CP0_REG18__WATCHLO7:
8360            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8361            gen_helper_0e1i(mtc0_watchlo, arg, sel);
8362            register_name = "WatchLo";
8363            break;
8364        default:
8365            goto cp0_unimplemented;
8366        }
8367        break;
8368    case CP0_REGISTER_19:
8369        switch (sel) {
8370        case CP0_REG19__WATCHHI0:
8371        case CP0_REG19__WATCHHI1:
8372        case CP0_REG19__WATCHHI2:
8373        case CP0_REG19__WATCHHI3:
8374        case CP0_REG19__WATCHHI4:
8375        case CP0_REG19__WATCHHI5:
8376        case CP0_REG19__WATCHHI6:
8377        case CP0_REG19__WATCHHI7:
8378            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8379            gen_helper_0e1i(mtc0_watchhi, arg, sel);
8380            register_name = "WatchHi";
8381            break;
8382        default:
8383            goto cp0_unimplemented;
8384        }
8385        break;
8386    case CP0_REGISTER_20:
8387        switch (sel) {
8388        case CP0_REG20__XCONTEXT:
8389            check_insn(ctx, ISA_MIPS3);
8390            gen_helper_mtc0_xcontext(cpu_env, arg);
8391            register_name = "XContext";
8392            break;
8393        default:
8394            goto cp0_unimplemented;
8395        }
8396        break;
8397    case CP0_REGISTER_21:
8398       /* Officially reserved, but sel 0 is used for R1x000 framemask */
8399        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
8400        switch (sel) {
8401        case 0:
8402            gen_helper_mtc0_framemask(cpu_env, arg);
8403            register_name = "Framemask";
8404            break;
8405        default:
8406            goto cp0_unimplemented;
8407        }
8408        break;
8409    case CP0_REGISTER_22:
8410        /* ignored */
8411        register_name = "Diagnostic"; /* implementation dependent */
8412        break;
8413    case CP0_REGISTER_23:
8414        switch (sel) {
8415        case CP0_REG23__DEBUG:
8416            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8417            /* DISAS_STOP isn't good enough here, hflags may have changed. */
8418            gen_save_pc(ctx->base.pc_next + 4);
8419            ctx->base.is_jmp = DISAS_EXIT;
8420            register_name = "Debug";
8421            break;
8422        case CP0_REG23__TRACECONTROL:
8423            /* PDtrace support */
8424            /* gen_helper_mtc0_tracecontrol(cpu_env, arg);  */
8425            /* Stop translation as we may have switched the execution mode */
8426            ctx->base.is_jmp = DISAS_STOP;
8427            register_name = "TraceControl";
8428            goto cp0_unimplemented;
8429        case CP0_REG23__TRACECONTROL2:
8430            /* PDtrace support */
8431            /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
8432            /* Stop translation as we may have switched the execution mode */
8433            ctx->base.is_jmp = DISAS_STOP;
8434            register_name = "TraceControl2";
8435            goto cp0_unimplemented;
8436        case CP0_REG23__USERTRACEDATA1:
8437            /* PDtrace support */
8438            /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
8439            /* Stop translation as we may have switched the execution mode */
8440            ctx->base.is_jmp = DISAS_STOP;
8441            register_name = "UserTraceData1";
8442            goto cp0_unimplemented;
8443        case CP0_REG23__TRACEIBPC:
8444            /* PDtrace support */
8445            /* gen_helper_mtc0_traceibpc(cpu_env, arg);     */
8446            /* Stop translation as we may have switched the execution mode */
8447            ctx->base.is_jmp = DISAS_STOP;
8448            register_name = "TraceIBPC";
8449            goto cp0_unimplemented;
8450        case CP0_REG23__TRACEDBPC:
8451            /* PDtrace support */
8452            /* gen_helper_mtc0_tracedbpc(cpu_env, arg);     */
8453            /* Stop translation as we may have switched the execution mode */
8454            ctx->base.is_jmp = DISAS_STOP;
8455            register_name = "TraceDBPC";
8456            goto cp0_unimplemented;
8457        default:
8458            goto cp0_unimplemented;
8459        }
8460        break;
8461    case CP0_REGISTER_24:
8462        switch (sel) {
8463        case CP0_REG24__DEPC:
8464            /* EJTAG support */
8465            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8466            register_name = "DEPC";
8467            break;
8468        default:
8469            goto cp0_unimplemented;
8470        }
8471        break;
8472    case CP0_REGISTER_25:
8473        switch (sel) {
8474        case CP0_REG25__PERFCTL0:
8475            gen_helper_mtc0_performance0(cpu_env, arg);
8476            register_name = "Performance0";
8477            break;
8478        case CP0_REG25__PERFCNT0:
8479            /* gen_helper_mtc0_performance1(cpu_env, arg); */
8480            register_name = "Performance1";
8481            goto cp0_unimplemented;
8482        case CP0_REG25__PERFCTL1:
8483            /* gen_helper_mtc0_performance2(cpu_env, arg); */
8484            register_name = "Performance2";
8485            goto cp0_unimplemented;
8486        case CP0_REG25__PERFCNT1:
8487            /* gen_helper_mtc0_performance3(cpu_env, arg); */
8488            register_name = "Performance3";
8489            goto cp0_unimplemented;
8490        case CP0_REG25__PERFCTL2:
8491            /* gen_helper_mtc0_performance4(cpu_env, arg); */
8492            register_name = "Performance4";
8493            goto cp0_unimplemented;
8494        case CP0_REG25__PERFCNT2:
8495            /* gen_helper_mtc0_performance5(cpu_env, arg); */
8496            register_name = "Performance5";
8497            goto cp0_unimplemented;
8498        case CP0_REG25__PERFCTL3:
8499            /* gen_helper_mtc0_performance6(cpu_env, arg); */
8500            register_name = "Performance6";
8501            goto cp0_unimplemented;
8502        case CP0_REG25__PERFCNT3:
8503            /* gen_helper_mtc0_performance7(cpu_env, arg); */
8504            register_name = "Performance7";
8505            goto cp0_unimplemented;
8506        default:
8507            goto cp0_unimplemented;
8508        }
8509        break;
8510    case CP0_REGISTER_26:
8511        switch (sel) {
8512        case CP0_REG26__ERRCTL:
8513            gen_helper_mtc0_errctl(cpu_env, arg);
8514            ctx->base.is_jmp = DISAS_STOP;
8515            register_name = "ErrCtl";
8516            break;
8517        default:
8518            goto cp0_unimplemented;
8519        }
8520        break;
8521    case CP0_REGISTER_27:
8522        switch (sel) {
8523        case CP0_REG27__CACHERR:
8524            /* ignored */
8525            register_name = "CacheErr";
8526            break;
8527        default:
8528            goto cp0_unimplemented;
8529        }
8530        break;
8531    case CP0_REGISTER_28:
8532        switch (sel) {
8533        case CP0_REG28__TAGLO:
8534        case CP0_REG28__TAGLO1:
8535        case CP0_REG28__TAGLO2:
8536        case CP0_REG28__TAGLO3:
8537            gen_helper_mtc0_taglo(cpu_env, arg);
8538            register_name = "TagLo";
8539            break;
8540        case CP0_REG28__DATALO:
8541        case CP0_REG28__DATALO1:
8542        case CP0_REG28__DATALO2:
8543        case CP0_REG28__DATALO3:
8544            gen_helper_mtc0_datalo(cpu_env, arg);
8545            register_name = "DataLo";
8546            break;
8547        default:
8548            goto cp0_unimplemented;
8549        }
8550        break;
8551    case CP0_REGISTER_29:
8552        switch (sel) {
8553        case CP0_REG29__TAGHI:
8554        case CP0_REG29__TAGHI1:
8555        case CP0_REG29__TAGHI2:
8556        case CP0_REG29__TAGHI3:
8557            gen_helper_mtc0_taghi(cpu_env, arg);
8558            register_name = "TagHi";
8559            break;
8560        case CP0_REG29__DATAHI:
8561        case CP0_REG29__DATAHI1:
8562        case CP0_REG29__DATAHI2:
8563        case CP0_REG29__DATAHI3:
8564            gen_helper_mtc0_datahi(cpu_env, arg);
8565            register_name = "DataHi";
8566            break;
8567        default:
8568            register_name = "invalid sel";
8569            goto cp0_unimplemented;
8570        }
8571        break;
8572    case CP0_REGISTER_30:
8573        switch (sel) {
8574        case CP0_REG30__ERROREPC:
8575            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8576            register_name = "ErrorEPC";
8577            break;
8578        default:
8579            goto cp0_unimplemented;
8580        }
8581        break;
8582    case CP0_REGISTER_31:
8583        switch (sel) {
8584        case CP0_REG31__DESAVE:
8585            /* EJTAG support */
8586            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8587            register_name = "DESAVE";
8588            break;
8589        case CP0_REG31__KSCRATCH1:
8590        case CP0_REG31__KSCRATCH2:
8591        case CP0_REG31__KSCRATCH3:
8592        case CP0_REG31__KSCRATCH4:
8593        case CP0_REG31__KSCRATCH5:
8594        case CP0_REG31__KSCRATCH6:
8595            CP0_CHECK(ctx->kscrexist & (1 << sel));
8596            tcg_gen_st_tl(arg, cpu_env,
8597                          offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
8598            register_name = "KScratch";
8599            break;
8600        default:
8601            goto cp0_unimplemented;
8602        }
8603        break;
8604    default:
8605        goto cp0_unimplemented;
8606    }
8607    trace_mips_translate_c0("dmtc0", register_name, reg, sel);
8608
8609    /* For simplicity assume that all writes can cause interrupts.  */
8610    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8611        /*
8612         * DISAS_STOP isn't sufficient, we need to ensure we break out of
8613         * translated code to check for pending interrupts.
8614         */
8615        gen_save_pc(ctx->base.pc_next + 4);
8616        ctx->base.is_jmp = DISAS_EXIT;
8617    }
8618    return;
8619
8620cp0_unimplemented:
8621    qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
8622                  register_name, reg, sel);
8623}
8624#endif /* TARGET_MIPS64 */
8625
8626static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
8627                     int u, int sel, int h)
8628{
8629    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8630    TCGv t0 = tcg_temp_local_new();
8631
8632    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8633        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8634         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
8635        tcg_gen_movi_tl(t0, -1);
8636    } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8637               (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
8638        tcg_gen_movi_tl(t0, -1);
8639    } else if (u == 0) {
8640        switch (rt) {
8641        case 1:
8642            switch (sel) {
8643            case 1:
8644                gen_helper_mftc0_vpecontrol(t0, cpu_env);
8645                break;
8646            case 2:
8647                gen_helper_mftc0_vpeconf0(t0, cpu_env);
8648                break;
8649            default:
8650                goto die;
8651                break;
8652            }
8653            break;
8654        case 2:
8655            switch (sel) {
8656            case 1:
8657                gen_helper_mftc0_tcstatus(t0, cpu_env);
8658                break;
8659            case 2:
8660                gen_helper_mftc0_tcbind(t0, cpu_env);
8661                break;
8662            case 3:
8663                gen_helper_mftc0_tcrestart(t0, cpu_env);
8664                break;
8665            case 4:
8666                gen_helper_mftc0_tchalt(t0, cpu_env);
8667                break;
8668            case 5:
8669                gen_helper_mftc0_tccontext(t0, cpu_env);
8670                break;
8671            case 6:
8672                gen_helper_mftc0_tcschedule(t0, cpu_env);
8673                break;
8674            case 7:
8675                gen_helper_mftc0_tcschefback(t0, cpu_env);
8676                break;
8677            default:
8678                gen_mfc0(ctx, t0, rt, sel);
8679                break;
8680            }
8681            break;
8682        case 10:
8683            switch (sel) {
8684            case 0:
8685                gen_helper_mftc0_entryhi(t0, cpu_env);
8686                break;
8687            default:
8688                gen_mfc0(ctx, t0, rt, sel);
8689                break;
8690            }
8691            break;
8692        case 12:
8693            switch (sel) {
8694            case 0:
8695                gen_helper_mftc0_status(t0, cpu_env);
8696                break;
8697            default:
8698                gen_mfc0(ctx, t0, rt, sel);
8699                break;
8700            }
8701            break;
8702        case 13:
8703            switch (sel) {
8704            case 0:
8705                gen_helper_mftc0_cause(t0, cpu_env);
8706                break;
8707            default:
8708                goto die;
8709                break;
8710            }
8711            break;
8712        case 14:
8713            switch (sel) {
8714            case 0:
8715                gen_helper_mftc0_epc(t0, cpu_env);
8716                break;
8717            default:
8718                goto die;
8719                break;
8720            }
8721            break;
8722        case 15:
8723            switch (sel) {
8724            case 1:
8725                gen_helper_mftc0_ebase(t0, cpu_env);
8726                break;
8727            default:
8728                goto die;
8729                break;
8730            }
8731            break;
8732        case 16:
8733            switch (sel) {
8734            case 0:
8735            case 1:
8736            case 2:
8737            case 3:
8738            case 4:
8739            case 5:
8740            case 6:
8741            case 7:
8742                gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
8743                break;
8744            default:
8745                goto die;
8746                break;
8747            }
8748            break;
8749        case 23:
8750            switch (sel) {
8751            case 0:
8752                gen_helper_mftc0_debug(t0, cpu_env);
8753                break;
8754            default:
8755                gen_mfc0(ctx, t0, rt, sel);
8756                break;
8757            }
8758            break;
8759        default:
8760            gen_mfc0(ctx, t0, rt, sel);
8761        }
8762    } else {
8763        switch (sel) {
8764        /* GPR registers. */
8765        case 0:
8766            gen_helper_1e0i(mftgpr, t0, rt);
8767            break;
8768        /* Auxiliary CPU registers */
8769        case 1:
8770            switch (rt) {
8771            case 0:
8772                gen_helper_1e0i(mftlo, t0, 0);
8773                break;
8774            case 1:
8775                gen_helper_1e0i(mfthi, t0, 0);
8776                break;
8777            case 2:
8778                gen_helper_1e0i(mftacx, t0, 0);
8779                break;
8780            case 4:
8781                gen_helper_1e0i(mftlo, t0, 1);
8782                break;
8783            case 5:
8784                gen_helper_1e0i(mfthi, t0, 1);
8785                break;
8786            case 6:
8787                gen_helper_1e0i(mftacx, t0, 1);
8788                break;
8789            case 8:
8790                gen_helper_1e0i(mftlo, t0, 2);
8791                break;
8792            case 9:
8793                gen_helper_1e0i(mfthi, t0, 2);
8794                break;
8795            case 10:
8796                gen_helper_1e0i(mftacx, t0, 2);
8797                break;
8798            case 12:
8799                gen_helper_1e0i(mftlo, t0, 3);
8800                break;
8801            case 13:
8802                gen_helper_1e0i(mfthi, t0, 3);
8803                break;
8804            case 14:
8805                gen_helper_1e0i(mftacx, t0, 3);
8806                break;
8807            case 16:
8808                gen_helper_mftdsp(t0, cpu_env);
8809                break;
8810            default:
8811                goto die;
8812            }
8813            break;
8814        /* Floating point (COP1). */
8815        case 2:
8816            /* XXX: For now we support only a single FPU context. */
8817            if (h == 0) {
8818                TCGv_i32 fp0 = tcg_temp_new_i32();
8819
8820                gen_load_fpr32(ctx, fp0, rt);
8821                tcg_gen_ext_i32_tl(t0, fp0);
8822                tcg_temp_free_i32(fp0);
8823            } else {
8824                TCGv_i32 fp0 = tcg_temp_new_i32();
8825
8826                gen_load_fpr32h(ctx, fp0, rt);
8827                tcg_gen_ext_i32_tl(t0, fp0);
8828                tcg_temp_free_i32(fp0);
8829            }
8830            break;
8831        case 3:
8832            /* XXX: For now we support only a single FPU context. */
8833            gen_helper_1e0i(cfc1, t0, rt);
8834            break;
8835        /* COP2: Not implemented. */
8836        case 4:
8837        case 5:
8838            /* fall through */
8839        default:
8840            goto die;
8841        }
8842    }
8843    trace_mips_translate_tr("mftr", rt, u, sel, h);
8844    gen_store_gpr(t0, rd);
8845    tcg_temp_free(t0);
8846    return;
8847
8848die:
8849    tcg_temp_free(t0);
8850    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
8851    gen_reserved_instruction(ctx);
8852}
8853
8854static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
8855                     int u, int sel, int h)
8856{
8857    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8858    TCGv t0 = tcg_temp_local_new();
8859
8860    gen_load_gpr(t0, rt);
8861    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8862        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8863         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
8864        /* NOP */
8865        ;
8866    } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8867             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
8868        /* NOP */
8869        ;
8870    } else if (u == 0) {
8871        switch (rd) {
8872        case 1:
8873            switch (sel) {
8874            case 1:
8875                gen_helper_mttc0_vpecontrol(cpu_env, t0);
8876                break;
8877            case 2:
8878                gen_helper_mttc0_vpeconf0(cpu_env, t0);
8879                break;
8880            default:
8881                goto die;
8882                break;
8883            }
8884            break;
8885        case 2:
8886            switch (sel) {
8887            case 1:
8888                gen_helper_mttc0_tcstatus(cpu_env, t0);
8889                break;
8890            case 2:
8891                gen_helper_mttc0_tcbind(cpu_env, t0);
8892                break;
8893            case 3:
8894                gen_helper_mttc0_tcrestart(cpu_env, t0);
8895                break;
8896            case 4:
8897                gen_helper_mttc0_tchalt(cpu_env, t0);
8898                break;
8899            case 5:
8900                gen_helper_mttc0_tccontext(cpu_env, t0);
8901                break;
8902            case 6:
8903                gen_helper_mttc0_tcschedule(cpu_env, t0);
8904                break;
8905            case 7:
8906                gen_helper_mttc0_tcschefback(cpu_env, t0);
8907                break;
8908            default:
8909                gen_mtc0(ctx, t0, rd, sel);
8910                break;
8911            }
8912            break;
8913        case 10:
8914            switch (sel) {
8915            case 0:
8916                gen_helper_mttc0_entryhi(cpu_env, t0);
8917                break;
8918            default:
8919                gen_mtc0(ctx, t0, rd, sel);
8920                break;
8921            }
8922            break;
8923        case 12:
8924            switch (sel) {
8925            case 0:
8926                gen_helper_mttc0_status(cpu_env, t0);
8927                break;
8928            default:
8929                gen_mtc0(ctx, t0, rd, sel);
8930                break;
8931            }
8932            break;
8933        case 13:
8934            switch (sel) {
8935            case 0:
8936                gen_helper_mttc0_cause(cpu_env, t0);
8937                break;
8938            default:
8939                goto die;
8940                break;
8941            }
8942            break;
8943        case 15:
8944            switch (sel) {
8945            case 1:
8946                gen_helper_mttc0_ebase(cpu_env, t0);
8947                break;
8948            default:
8949                goto die;
8950                break;
8951            }
8952            break;
8953        case 23:
8954            switch (sel) {
8955            case 0:
8956                gen_helper_mttc0_debug(cpu_env, t0);
8957                break;
8958            default:
8959                gen_mtc0(ctx, t0, rd, sel);
8960                break;
8961            }
8962            break;
8963        default:
8964            gen_mtc0(ctx, t0, rd, sel);
8965        }
8966    } else {
8967        switch (sel) {
8968        /* GPR registers. */
8969        case 0:
8970            gen_helper_0e1i(mttgpr, t0, rd);
8971            break;
8972        /* Auxiliary CPU registers */
8973        case 1:
8974            switch (rd) {
8975            case 0:
8976                gen_helper_0e1i(mttlo, t0, 0);
8977                break;
8978            case 1:
8979                gen_helper_0e1i(mtthi, t0, 0);
8980                break;
8981            case 2:
8982                gen_helper_0e1i(mttacx, t0, 0);
8983                break;
8984            case 4:
8985                gen_helper_0e1i(mttlo, t0, 1);
8986                break;
8987            case 5:
8988                gen_helper_0e1i(mtthi, t0, 1);
8989                break;
8990            case 6:
8991                gen_helper_0e1i(mttacx, t0, 1);
8992                break;
8993            case 8:
8994                gen_helper_0e1i(mttlo, t0, 2);
8995                break;
8996            case 9:
8997                gen_helper_0e1i(mtthi, t0, 2);
8998                break;
8999            case 10:
9000                gen_helper_0e1i(mttacx, t0, 2);
9001                break;
9002            case 12:
9003                gen_helper_0e1i(mttlo, t0, 3);
9004                break;
9005            case 13:
9006                gen_helper_0e1i(mtthi, t0, 3);
9007                break;
9008            case 14:
9009                gen_helper_0e1i(mttacx, t0, 3);
9010                break;
9011            case 16:
9012                gen_helper_mttdsp(cpu_env, t0);
9013                break;
9014            default:
9015                goto die;
9016            }
9017            break;
9018        /* Floating point (COP1). */
9019        case 2:
9020            /* XXX: For now we support only a single FPU context. */
9021            if (h == 0) {
9022                TCGv_i32 fp0 = tcg_temp_new_i32();
9023
9024                tcg_gen_trunc_tl_i32(fp0, t0);
9025                gen_store_fpr32(ctx, fp0, rd);
9026                tcg_temp_free_i32(fp0);
9027            } else {
9028                TCGv_i32 fp0 = tcg_temp_new_i32();
9029
9030                tcg_gen_trunc_tl_i32(fp0, t0);
9031                gen_store_fpr32h(ctx, fp0, rd);
9032                tcg_temp_free_i32(fp0);
9033            }
9034            break;
9035        case 3:
9036            /* XXX: For now we support only a single FPU context. */
9037            gen_helper_0e2i(ctc1, t0, tcg_constant_i32(rd), rt);
9038            /* Stop translation as we may have changed hflags */
9039            ctx->base.is_jmp = DISAS_STOP;
9040            break;
9041        /* COP2: Not implemented. */
9042        case 4:
9043        case 5:
9044            /* fall through */
9045        default:
9046            goto die;
9047        }
9048    }
9049    trace_mips_translate_tr("mttr", rd, u, sel, h);
9050    tcg_temp_free(t0);
9051    return;
9052
9053die:
9054    tcg_temp_free(t0);
9055    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9056    gen_reserved_instruction(ctx);
9057}
9058
9059static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
9060                    int rt, int rd)
9061{
9062    const char *opn = "ldst";
9063
9064    check_cp0_enabled(ctx);
9065    switch (opc) {
9066    case OPC_MFC0:
9067        if (rt == 0) {
9068            /* Treat as NOP. */
9069            return;
9070        }
9071        gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9072        opn = "mfc0";
9073        break;
9074    case OPC_MTC0:
9075        {
9076            TCGv t0 = tcg_temp_new();
9077
9078            gen_load_gpr(t0, rt);
9079            gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
9080            tcg_temp_free(t0);
9081        }
9082        opn = "mtc0";
9083        break;
9084#if defined(TARGET_MIPS64)
9085    case OPC_DMFC0:
9086        check_insn(ctx, ISA_MIPS3);
9087        if (rt == 0) {
9088            /* Treat as NOP. */
9089            return;
9090        }
9091        gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9092        opn = "dmfc0";
9093        break;
9094    case OPC_DMTC0:
9095        check_insn(ctx, ISA_MIPS3);
9096        {
9097            TCGv t0 = tcg_temp_new();
9098
9099            gen_load_gpr(t0, rt);
9100            gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
9101            tcg_temp_free(t0);
9102        }
9103        opn = "dmtc0";
9104        break;
9105#endif
9106    case OPC_MFHC0:
9107        check_mvh(ctx);
9108        if (rt == 0) {
9109            /* Treat as NOP. */
9110            return;
9111        }
9112        gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9113        opn = "mfhc0";
9114        break;
9115    case OPC_MTHC0:
9116        check_mvh(ctx);
9117        {
9118            TCGv t0 = tcg_temp_new();
9119            gen_load_gpr(t0, rt);
9120            gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
9121            tcg_temp_free(t0);
9122        }
9123        opn = "mthc0";
9124        break;
9125    case OPC_MFTR:
9126        check_cp0_enabled(ctx);
9127        if (rd == 0) {
9128            /* Treat as NOP. */
9129            return;
9130        }
9131        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
9132                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9133        opn = "mftr";
9134        break;
9135    case OPC_MTTR:
9136        check_cp0_enabled(ctx);
9137        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
9138                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9139        opn = "mttr";
9140        break;
9141    case OPC_TLBWI:
9142        opn = "tlbwi";
9143        if (!env->tlb->helper_tlbwi) {
9144            goto die;
9145        }
9146        gen_helper_tlbwi(cpu_env);
9147        break;
9148    case OPC_TLBINV:
9149        opn = "tlbinv";
9150        if (ctx->ie >= 2) {
9151            if (!env->tlb->helper_tlbinv) {
9152                goto die;
9153            }
9154            gen_helper_tlbinv(cpu_env);
9155        } /* treat as nop if TLBINV not supported */
9156        break;
9157    case OPC_TLBINVF:
9158        opn = "tlbinvf";
9159        if (ctx->ie >= 2) {
9160            if (!env->tlb->helper_tlbinvf) {
9161                goto die;
9162            }
9163            gen_helper_tlbinvf(cpu_env);
9164        } /* treat as nop if TLBINV not supported */
9165        break;
9166    case OPC_TLBWR:
9167        opn = "tlbwr";
9168        if (!env->tlb->helper_tlbwr) {
9169            goto die;
9170        }
9171        gen_helper_tlbwr(cpu_env);
9172        break;
9173    case OPC_TLBP:
9174        opn = "tlbp";
9175        if (!env->tlb->helper_tlbp) {
9176            goto die;
9177        }
9178        gen_helper_tlbp(cpu_env);
9179        break;
9180    case OPC_TLBR:
9181        opn = "tlbr";
9182        if (!env->tlb->helper_tlbr) {
9183            goto die;
9184        }
9185        gen_helper_tlbr(cpu_env);
9186        break;
9187    case OPC_ERET: /* OPC_ERETNC */
9188        if ((ctx->insn_flags & ISA_MIPS_R6) &&
9189            (ctx->hflags & MIPS_HFLAG_BMASK)) {
9190            goto die;
9191        } else {
9192            int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
9193            if (ctx->opcode & (1 << bit_shift)) {
9194                /* OPC_ERETNC */
9195                opn = "eretnc";
9196                check_insn(ctx, ISA_MIPS_R5);
9197                gen_helper_eretnc(cpu_env);
9198            } else {
9199                /* OPC_ERET */
9200                opn = "eret";
9201                check_insn(ctx, ISA_MIPS2);
9202                gen_helper_eret(cpu_env);
9203            }
9204            ctx->base.is_jmp = DISAS_EXIT;
9205        }
9206        break;
9207    case OPC_DERET:
9208        opn = "deret";
9209        check_insn(ctx, ISA_MIPS_R1);
9210        if ((ctx->insn_flags & ISA_MIPS_R6) &&
9211            (ctx->hflags & MIPS_HFLAG_BMASK)) {
9212            goto die;
9213        }
9214        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9215            MIPS_INVAL(opn);
9216            gen_reserved_instruction(ctx);
9217        } else {
9218            gen_helper_deret(cpu_env);
9219            ctx->base.is_jmp = DISAS_EXIT;
9220        }
9221        break;
9222    case OPC_WAIT:
9223        opn = "wait";
9224        check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
9225        if ((ctx->insn_flags & ISA_MIPS_R6) &&
9226            (ctx->hflags & MIPS_HFLAG_BMASK)) {
9227            goto die;
9228        }
9229        /* If we get an exception, we want to restart at next instruction */
9230        ctx->base.pc_next += 4;
9231        save_cpu_state(ctx, 1);
9232        ctx->base.pc_next -= 4;
9233        gen_helper_wait(cpu_env);
9234        ctx->base.is_jmp = DISAS_NORETURN;
9235        break;
9236    default:
9237 die:
9238        MIPS_INVAL(opn);
9239        gen_reserved_instruction(ctx);
9240        return;
9241    }
9242    (void)opn; /* avoid a compiler warning */
9243}
9244#endif /* !CONFIG_USER_ONLY */
9245
9246/* CP1 Branches (before delay slot) */
9247static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
9248                                int32_t cc, int32_t offset)
9249{
9250    target_ulong btarget;
9251    TCGv_i32 t0 = tcg_temp_new_i32();
9252
9253    if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9254        gen_reserved_instruction(ctx);
9255        goto out;
9256    }
9257
9258    if (cc != 0) {
9259        check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
9260    }
9261
9262    btarget = ctx->base.pc_next + 4 + offset;
9263
9264    switch (op) {
9265    case OPC_BC1F:
9266        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9267        tcg_gen_not_i32(t0, t0);
9268        tcg_gen_andi_i32(t0, t0, 1);
9269        tcg_gen_extu_i32_tl(bcond, t0);
9270        goto not_likely;
9271    case OPC_BC1FL:
9272        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9273        tcg_gen_not_i32(t0, t0);
9274        tcg_gen_andi_i32(t0, t0, 1);
9275        tcg_gen_extu_i32_tl(bcond, t0);
9276        goto likely;
9277    case OPC_BC1T:
9278        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9279        tcg_gen_andi_i32(t0, t0, 1);
9280        tcg_gen_extu_i32_tl(bcond, t0);
9281        goto not_likely;
9282    case OPC_BC1TL:
9283        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9284        tcg_gen_andi_i32(t0, t0, 1);
9285        tcg_gen_extu_i32_tl(bcond, t0);
9286    likely:
9287        ctx->hflags |= MIPS_HFLAG_BL;
9288        break;
9289    case OPC_BC1FANY2:
9290        {
9291            TCGv_i32 t1 = tcg_temp_new_i32();
9292            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9293            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9294            tcg_gen_nand_i32(t0, t0, t1);
9295            tcg_temp_free_i32(t1);
9296            tcg_gen_andi_i32(t0, t0, 1);
9297            tcg_gen_extu_i32_tl(bcond, t0);
9298        }
9299        goto not_likely;
9300    case OPC_BC1TANY2:
9301        {
9302            TCGv_i32 t1 = tcg_temp_new_i32();
9303            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9304            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9305            tcg_gen_or_i32(t0, t0, t1);
9306            tcg_temp_free_i32(t1);
9307            tcg_gen_andi_i32(t0, t0, 1);
9308            tcg_gen_extu_i32_tl(bcond, t0);
9309        }
9310        goto not_likely;
9311    case OPC_BC1FANY4:
9312        {
9313            TCGv_i32 t1 = tcg_temp_new_i32();
9314            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9315            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9316            tcg_gen_and_i32(t0, t0, t1);
9317            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
9318            tcg_gen_and_i32(t0, t0, t1);
9319            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
9320            tcg_gen_nand_i32(t0, t0, t1);
9321            tcg_temp_free_i32(t1);
9322            tcg_gen_andi_i32(t0, t0, 1);
9323            tcg_gen_extu_i32_tl(bcond, t0);
9324        }
9325        goto not_likely;
9326    case OPC_BC1TANY4:
9327        {
9328            TCGv_i32 t1 = tcg_temp_new_i32();
9329            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9330            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9331            tcg_gen_or_i32(t0, t0, t1);
9332            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
9333            tcg_gen_or_i32(t0, t0, t1);
9334            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
9335            tcg_gen_or_i32(t0, t0, t1);
9336            tcg_temp_free_i32(t1);
9337            tcg_gen_andi_i32(t0, t0, 1);
9338            tcg_gen_extu_i32_tl(bcond, t0);
9339        }
9340    not_likely:
9341        ctx->hflags |= MIPS_HFLAG_BC;
9342        break;
9343    default:
9344        MIPS_INVAL("cp1 cond branch");
9345        gen_reserved_instruction(ctx);
9346        goto out;
9347    }
9348    ctx->btarget = btarget;
9349    ctx->hflags |= MIPS_HFLAG_BDS32;
9350 out:
9351    tcg_temp_free_i32(t0);
9352}
9353
9354/* R6 CP1 Branches */
9355static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
9356                                   int32_t ft, int32_t offset,
9357                                   int delayslot_size)
9358{
9359    target_ulong btarget;
9360    TCGv_i64 t0 = tcg_temp_new_i64();
9361
9362    if (ctx->hflags & MIPS_HFLAG_BMASK) {
9363#ifdef MIPS_DEBUG_DISAS
9364        LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
9365                  "\n", ctx->base.pc_next);
9366#endif
9367        gen_reserved_instruction(ctx);
9368        goto out;
9369    }
9370
9371    gen_load_fpr64(ctx, t0, ft);
9372    tcg_gen_andi_i64(t0, t0, 1);
9373
9374    btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
9375
9376    switch (op) {
9377    case OPC_BC1EQZ:
9378        tcg_gen_xori_i64(t0, t0, 1);
9379        ctx->hflags |= MIPS_HFLAG_BC;
9380        break;
9381    case OPC_BC1NEZ:
9382        /* t0 already set */
9383        ctx->hflags |= MIPS_HFLAG_BC;
9384        break;
9385    default:
9386        MIPS_INVAL("cp1 cond branch");
9387        gen_reserved_instruction(ctx);
9388        goto out;
9389    }
9390
9391    tcg_gen_trunc_i64_tl(bcond, t0);
9392
9393    ctx->btarget = btarget;
9394
9395    switch (delayslot_size) {
9396    case 2:
9397        ctx->hflags |= MIPS_HFLAG_BDS16;
9398        break;
9399    case 4:
9400        ctx->hflags |= MIPS_HFLAG_BDS32;
9401        break;
9402    }
9403
9404out:
9405    tcg_temp_free_i64(t0);
9406}
9407
9408/* Coprocessor 1 (FPU) */
9409
9410#define FOP(func, fmt) (((fmt) << 21) | (func))
9411
9412enum fopcode {
9413    OPC_ADD_S = FOP(0, FMT_S),
9414    OPC_SUB_S = FOP(1, FMT_S),
9415    OPC_MUL_S = FOP(2, FMT_S),
9416    OPC_DIV_S = FOP(3, FMT_S),
9417    OPC_SQRT_S = FOP(4, FMT_S),
9418    OPC_ABS_S = FOP(5, FMT_S),
9419    OPC_MOV_S = FOP(6, FMT_S),
9420    OPC_NEG_S = FOP(7, FMT_S),
9421    OPC_ROUND_L_S = FOP(8, FMT_S),
9422    OPC_TRUNC_L_S = FOP(9, FMT_S),
9423    OPC_CEIL_L_S = FOP(10, FMT_S),
9424    OPC_FLOOR_L_S = FOP(11, FMT_S),
9425    OPC_ROUND_W_S = FOP(12, FMT_S),
9426    OPC_TRUNC_W_S = FOP(13, FMT_S),
9427    OPC_CEIL_W_S = FOP(14, FMT_S),
9428    OPC_FLOOR_W_S = FOP(15, FMT_S),
9429    OPC_SEL_S = FOP(16, FMT_S),
9430    OPC_MOVCF_S = FOP(17, FMT_S),
9431    OPC_MOVZ_S = FOP(18, FMT_S),
9432    OPC_MOVN_S = FOP(19, FMT_S),
9433    OPC_SELEQZ_S = FOP(20, FMT_S),
9434    OPC_RECIP_S = FOP(21, FMT_S),
9435    OPC_RSQRT_S = FOP(22, FMT_S),
9436    OPC_SELNEZ_S = FOP(23, FMT_S),
9437    OPC_MADDF_S = FOP(24, FMT_S),
9438    OPC_MSUBF_S = FOP(25, FMT_S),
9439    OPC_RINT_S = FOP(26, FMT_S),
9440    OPC_CLASS_S = FOP(27, FMT_S),
9441    OPC_MIN_S = FOP(28, FMT_S),
9442    OPC_RECIP2_S = FOP(28, FMT_S),
9443    OPC_MINA_S = FOP(29, FMT_S),
9444    OPC_RECIP1_S = FOP(29, FMT_S),
9445    OPC_MAX_S = FOP(30, FMT_S),
9446    OPC_RSQRT1_S = FOP(30, FMT_S),
9447    OPC_MAXA_S = FOP(31, FMT_S),
9448    OPC_RSQRT2_S = FOP(31, FMT_S),
9449    OPC_CVT_D_S = FOP(33, FMT_S),
9450    OPC_CVT_W_S = FOP(36, FMT_S),
9451    OPC_CVT_L_S = FOP(37, FMT_S),
9452    OPC_CVT_PS_S = FOP(38, FMT_S),
9453    OPC_CMP_F_S = FOP(48, FMT_S),
9454    OPC_CMP_UN_S = FOP(49, FMT_S),
9455    OPC_CMP_EQ_S = FOP(50, FMT_S),
9456    OPC_CMP_UEQ_S = FOP(51, FMT_S),
9457    OPC_CMP_OLT_S = FOP(52, FMT_S),
9458    OPC_CMP_ULT_S = FOP(53, FMT_S),
9459    OPC_CMP_OLE_S = FOP(54, FMT_S),
9460    OPC_CMP_ULE_S = FOP(55, FMT_S),
9461    OPC_CMP_SF_S = FOP(56, FMT_S),
9462    OPC_CMP_NGLE_S = FOP(57, FMT_S),
9463    OPC_CMP_SEQ_S = FOP(58, FMT_S),
9464    OPC_CMP_NGL_S = FOP(59, FMT_S),
9465    OPC_CMP_LT_S = FOP(60, FMT_S),
9466    OPC_CMP_NGE_S = FOP(61, FMT_S),
9467    OPC_CMP_LE_S = FOP(62, FMT_S),
9468    OPC_CMP_NGT_S = FOP(63, FMT_S),
9469
9470    OPC_ADD_D = FOP(0, FMT_D),
9471    OPC_SUB_D = FOP(1, FMT_D),
9472    OPC_MUL_D = FOP(2, FMT_D),
9473    OPC_DIV_D = FOP(3, FMT_D),
9474    OPC_SQRT_D = FOP(4, FMT_D),
9475    OPC_ABS_D = FOP(5, FMT_D),
9476    OPC_MOV_D = FOP(6, FMT_D),
9477    OPC_NEG_D = FOP(7, FMT_D),
9478    OPC_ROUND_L_D = FOP(8, FMT_D),
9479    OPC_TRUNC_L_D = FOP(9, FMT_D),
9480    OPC_CEIL_L_D = FOP(10, FMT_D),
9481    OPC_FLOOR_L_D = FOP(11, FMT_D),
9482    OPC_ROUND_W_D = FOP(12, FMT_D),
9483    OPC_TRUNC_W_D = FOP(13, FMT_D),
9484    OPC_CEIL_W_D = FOP(14, FMT_D),
9485    OPC_FLOOR_W_D = FOP(15, FMT_D),
9486    OPC_SEL_D = FOP(16, FMT_D),
9487    OPC_MOVCF_D = FOP(17, FMT_D),
9488    OPC_MOVZ_D = FOP(18, FMT_D),
9489    OPC_MOVN_D = FOP(19, FMT_D),
9490    OPC_SELEQZ_D = FOP(20, FMT_D),
9491    OPC_RECIP_D = FOP(21, FMT_D),
9492    OPC_RSQRT_D = FOP(22, FMT_D),
9493    OPC_SELNEZ_D = FOP(23, FMT_D),
9494    OPC_MADDF_D = FOP(24, FMT_D),
9495    OPC_MSUBF_D = FOP(25, FMT_D),
9496    OPC_RINT_D = FOP(26, FMT_D),
9497    OPC_CLASS_D = FOP(27, FMT_D),
9498    OPC_MIN_D = FOP(28, FMT_D),
9499    OPC_RECIP2_D = FOP(28, FMT_D),
9500    OPC_MINA_D = FOP(29, FMT_D),
9501    OPC_RECIP1_D = FOP(29, FMT_D),
9502    OPC_MAX_D = FOP(30, FMT_D),
9503    OPC_RSQRT1_D = FOP(30, FMT_D),
9504    OPC_MAXA_D = FOP(31, FMT_D),
9505    OPC_RSQRT2_D = FOP(31, FMT_D),
9506    OPC_CVT_S_D = FOP(32, FMT_D),
9507    OPC_CVT_W_D = FOP(36, FMT_D),
9508    OPC_CVT_L_D = FOP(37, FMT_D),
9509    OPC_CMP_F_D = FOP(48, FMT_D),
9510    OPC_CMP_UN_D = FOP(49, FMT_D),
9511    OPC_CMP_EQ_D = FOP(50, FMT_D),
9512    OPC_CMP_UEQ_D = FOP(51, FMT_D),
9513    OPC_CMP_OLT_D = FOP(52, FMT_D),
9514    OPC_CMP_ULT_D = FOP(53, FMT_D),
9515    OPC_CMP_OLE_D = FOP(54, FMT_D),
9516    OPC_CMP_ULE_D = FOP(55, FMT_D),
9517    OPC_CMP_SF_D = FOP(56, FMT_D),
9518    OPC_CMP_NGLE_D = FOP(57, FMT_D),
9519    OPC_CMP_SEQ_D = FOP(58, FMT_D),
9520    OPC_CMP_NGL_D = FOP(59, FMT_D),
9521    OPC_CMP_LT_D = FOP(60, FMT_D),
9522    OPC_CMP_NGE_D = FOP(61, FMT_D),
9523    OPC_CMP_LE_D = FOP(62, FMT_D),
9524    OPC_CMP_NGT_D = FOP(63, FMT_D),
9525
9526    OPC_CVT_S_W = FOP(32, FMT_W),
9527    OPC_CVT_D_W = FOP(33, FMT_W),
9528    OPC_CVT_S_L = FOP(32, FMT_L),
9529    OPC_CVT_D_L = FOP(33, FMT_L),
9530    OPC_CVT_PS_PW = FOP(38, FMT_W),
9531
9532    OPC_ADD_PS = FOP(0, FMT_PS),
9533    OPC_SUB_PS = FOP(1, FMT_PS),
9534    OPC_MUL_PS = FOP(2, FMT_PS),
9535    OPC_DIV_PS = FOP(3, FMT_PS),
9536    OPC_ABS_PS = FOP(5, FMT_PS),
9537    OPC_MOV_PS = FOP(6, FMT_PS),
9538    OPC_NEG_PS = FOP(7, FMT_PS),
9539    OPC_MOVCF_PS = FOP(17, FMT_PS),
9540    OPC_MOVZ_PS = FOP(18, FMT_PS),
9541    OPC_MOVN_PS = FOP(19, FMT_PS),
9542    OPC_ADDR_PS = FOP(24, FMT_PS),
9543    OPC_MULR_PS = FOP(26, FMT_PS),
9544    OPC_RECIP2_PS = FOP(28, FMT_PS),
9545    OPC_RECIP1_PS = FOP(29, FMT_PS),
9546    OPC_RSQRT1_PS = FOP(30, FMT_PS),
9547    OPC_RSQRT2_PS = FOP(31, FMT_PS),
9548
9549    OPC_CVT_S_PU = FOP(32, FMT_PS),
9550    OPC_CVT_PW_PS = FOP(36, FMT_PS),
9551    OPC_CVT_S_PL = FOP(40, FMT_PS),
9552    OPC_PLL_PS = FOP(44, FMT_PS),
9553    OPC_PLU_PS = FOP(45, FMT_PS),
9554    OPC_PUL_PS = FOP(46, FMT_PS),
9555    OPC_PUU_PS = FOP(47, FMT_PS),
9556    OPC_CMP_F_PS = FOP(48, FMT_PS),
9557    OPC_CMP_UN_PS = FOP(49, FMT_PS),
9558    OPC_CMP_EQ_PS = FOP(50, FMT_PS),
9559    OPC_CMP_UEQ_PS = FOP(51, FMT_PS),
9560    OPC_CMP_OLT_PS = FOP(52, FMT_PS),
9561    OPC_CMP_ULT_PS = FOP(53, FMT_PS),
9562    OPC_CMP_OLE_PS = FOP(54, FMT_PS),
9563    OPC_CMP_ULE_PS = FOP(55, FMT_PS),
9564    OPC_CMP_SF_PS = FOP(56, FMT_PS),
9565    OPC_CMP_NGLE_PS = FOP(57, FMT_PS),
9566    OPC_CMP_SEQ_PS = FOP(58, FMT_PS),
9567    OPC_CMP_NGL_PS = FOP(59, FMT_PS),
9568    OPC_CMP_LT_PS = FOP(60, FMT_PS),
9569    OPC_CMP_NGE_PS = FOP(61, FMT_PS),
9570    OPC_CMP_LE_PS = FOP(62, FMT_PS),
9571    OPC_CMP_NGT_PS = FOP(63, FMT_PS),
9572};
9573
9574enum r6_f_cmp_op {
9575    R6_OPC_CMP_AF_S   = FOP(0, FMT_W),
9576    R6_OPC_CMP_UN_S   = FOP(1, FMT_W),
9577    R6_OPC_CMP_EQ_S   = FOP(2, FMT_W),
9578    R6_OPC_CMP_UEQ_S  = FOP(3, FMT_W),
9579    R6_OPC_CMP_LT_S   = FOP(4, FMT_W),
9580    R6_OPC_CMP_ULT_S  = FOP(5, FMT_W),
9581    R6_OPC_CMP_LE_S   = FOP(6, FMT_W),
9582    R6_OPC_CMP_ULE_S  = FOP(7, FMT_W),
9583    R6_OPC_CMP_SAF_S  = FOP(8, FMT_W),
9584    R6_OPC_CMP_SUN_S  = FOP(9, FMT_W),
9585    R6_OPC_CMP_SEQ_S  = FOP(10, FMT_W),
9586    R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
9587    R6_OPC_CMP_SLT_S  = FOP(12, FMT_W),
9588    R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
9589    R6_OPC_CMP_SLE_S  = FOP(14, FMT_W),
9590    R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
9591    R6_OPC_CMP_OR_S   = FOP(17, FMT_W),
9592    R6_OPC_CMP_UNE_S  = FOP(18, FMT_W),
9593    R6_OPC_CMP_NE_S   = FOP(19, FMT_W),
9594    R6_OPC_CMP_SOR_S  = FOP(25, FMT_W),
9595    R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
9596    R6_OPC_CMP_SNE_S  = FOP(27, FMT_W),
9597
9598    R6_OPC_CMP_AF_D   = FOP(0, FMT_L),
9599    R6_OPC_CMP_UN_D   = FOP(1, FMT_L),
9600    R6_OPC_CMP_EQ_D   = FOP(2, FMT_L),
9601    R6_OPC_CMP_UEQ_D  = FOP(3, FMT_L),
9602    R6_OPC_CMP_LT_D   = FOP(4, FMT_L),
9603    R6_OPC_CMP_ULT_D  = FOP(5, FMT_L),
9604    R6_OPC_CMP_LE_D   = FOP(6, FMT_L),
9605    R6_OPC_CMP_ULE_D  = FOP(7, FMT_L),
9606    R6_OPC_CMP_SAF_D  = FOP(8, FMT_L),
9607    R6_OPC_CMP_SUN_D  = FOP(9, FMT_L),
9608    R6_OPC_CMP_SEQ_D  = FOP(10, FMT_L),
9609    R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
9610    R6_OPC_CMP_SLT_D  = FOP(12, FMT_L),
9611    R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
9612    R6_OPC_CMP_SLE_D  = FOP(14, FMT_L),
9613    R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
9614    R6_OPC_CMP_OR_D   = FOP(17, FMT_L),
9615    R6_OPC_CMP_UNE_D  = FOP(18, FMT_L),
9616    R6_OPC_CMP_NE_D   = FOP(19, FMT_L),
9617    R6_OPC_CMP_SOR_D  = FOP(25, FMT_L),
9618    R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
9619    R6_OPC_CMP_SNE_D  = FOP(27, FMT_L),
9620};
9621
9622static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs)
9623{
9624    TCGv t0 = tcg_temp_new();
9625
9626    switch (opc) {
9627    case OPC_MFC1:
9628        {
9629            TCGv_i32 fp0 = tcg_temp_new_i32();
9630
9631            gen_load_fpr32(ctx, fp0, fs);
9632            tcg_gen_ext_i32_tl(t0, fp0);
9633            tcg_temp_free_i32(fp0);
9634        }
9635        gen_store_gpr(t0, rt);
9636        break;
9637    case OPC_MTC1:
9638        gen_load_gpr(t0, rt);
9639        {
9640            TCGv_i32 fp0 = tcg_temp_new_i32();
9641
9642            tcg_gen_trunc_tl_i32(fp0, t0);
9643            gen_store_fpr32(ctx, fp0, fs);
9644            tcg_temp_free_i32(fp0);
9645        }
9646        break;
9647    case OPC_CFC1:
9648        gen_helper_1e0i(cfc1, t0, fs);
9649        gen_store_gpr(t0, rt);
9650        break;
9651    case OPC_CTC1:
9652        gen_load_gpr(t0, rt);
9653        save_cpu_state(ctx, 0);
9654        gen_helper_0e2i(ctc1, t0, tcg_constant_i32(fs), rt);
9655        /* Stop translation as we may have changed hflags */
9656        ctx->base.is_jmp = DISAS_STOP;
9657        break;
9658#if defined(TARGET_MIPS64)
9659    case OPC_DMFC1:
9660        gen_load_fpr64(ctx, t0, fs);
9661        gen_store_gpr(t0, rt);
9662        break;
9663    case OPC_DMTC1:
9664        gen_load_gpr(t0, rt);
9665        gen_store_fpr64(ctx, t0, fs);
9666        break;
9667#endif
9668    case OPC_MFHC1:
9669        {
9670            TCGv_i32 fp0 = tcg_temp_new_i32();
9671
9672            gen_load_fpr32h(ctx, fp0, fs);
9673            tcg_gen_ext_i32_tl(t0, fp0);
9674            tcg_temp_free_i32(fp0);
9675        }
9676        gen_store_gpr(t0, rt);
9677        break;
9678    case OPC_MTHC1:
9679        gen_load_gpr(t0, rt);
9680        {
9681            TCGv_i32 fp0 = tcg_temp_new_i32();
9682
9683            tcg_gen_trunc_tl_i32(fp0, t0);
9684            gen_store_fpr32h(ctx, fp0, fs);
9685            tcg_temp_free_i32(fp0);
9686        }
9687        break;
9688    default:
9689        MIPS_INVAL("cp1 move");
9690        gen_reserved_instruction(ctx);
9691        goto out;
9692    }
9693
9694 out:
9695    tcg_temp_free(t0);
9696}
9697
9698static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf)
9699{
9700    TCGLabel *l1;
9701    TCGCond cond;
9702    TCGv_i32 t0;
9703
9704    if (rd == 0) {
9705        /* Treat as NOP. */
9706        return;
9707    }
9708
9709    if (tf) {
9710        cond = TCG_COND_EQ;
9711    } else {
9712        cond = TCG_COND_NE;
9713    }
9714
9715    l1 = gen_new_label();
9716    t0 = tcg_temp_new_i32();
9717    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9718    tcg_gen_brcondi_i32(cond, t0, 0, l1);
9719    tcg_temp_free_i32(t0);
9720    gen_load_gpr(cpu_gpr[rd], rs);
9721    gen_set_label(l1);
9722}
9723
9724static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
9725                               int tf)
9726{
9727    int cond;
9728    TCGv_i32 t0 = tcg_temp_new_i32();
9729    TCGLabel *l1 = gen_new_label();
9730
9731    if (tf) {
9732        cond = TCG_COND_EQ;
9733    } else {
9734        cond = TCG_COND_NE;
9735    }
9736
9737    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9738    tcg_gen_brcondi_i32(cond, t0, 0, l1);
9739    gen_load_fpr32(ctx, t0, fs);
9740    gen_store_fpr32(ctx, t0, fd);
9741    gen_set_label(l1);
9742    tcg_temp_free_i32(t0);
9743}
9744
9745static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc,
9746                               int tf)
9747{
9748    int cond;
9749    TCGv_i32 t0 = tcg_temp_new_i32();
9750    TCGv_i64 fp0;
9751    TCGLabel *l1 = gen_new_label();
9752
9753    if (tf) {
9754        cond = TCG_COND_EQ;
9755    } else {
9756        cond = TCG_COND_NE;
9757    }
9758
9759    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
9760    tcg_gen_brcondi_i32(cond, t0, 0, l1);
9761    tcg_temp_free_i32(t0);
9762    fp0 = tcg_temp_new_i64();
9763    gen_load_fpr64(ctx, fp0, fs);
9764    gen_store_fpr64(ctx, fp0, fd);
9765    tcg_temp_free_i64(fp0);
9766    gen_set_label(l1);
9767}
9768
9769static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
9770                                int cc, int tf)
9771{
9772    int cond;
9773    TCGv_i32 t0 = tcg_temp_new_i32();
9774    TCGLabel *l1 = gen_new_label();
9775    TCGLabel *l2 = 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    gen_load_fpr32(ctx, t0, fs);
9786    gen_store_fpr32(ctx, t0, fd);
9787    gen_set_label(l1);
9788
9789    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1));
9790    tcg_gen_brcondi_i32(cond, t0, 0, l2);
9791    gen_load_fpr32h(ctx, t0, fs);
9792    gen_store_fpr32h(ctx, t0, fd);
9793    tcg_temp_free_i32(t0);
9794    gen_set_label(l2);
9795}
9796
9797static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9798                      int fs)
9799{
9800    TCGv_i32 t1 = tcg_const_i32(0);
9801    TCGv_i32 fp0 = tcg_temp_new_i32();
9802    TCGv_i32 fp1 = tcg_temp_new_i32();
9803    TCGv_i32 fp2 = tcg_temp_new_i32();
9804    gen_load_fpr32(ctx, fp0, fd);
9805    gen_load_fpr32(ctx, fp1, ft);
9806    gen_load_fpr32(ctx, fp2, fs);
9807
9808    switch (op1) {
9809    case OPC_SEL_S:
9810        tcg_gen_andi_i32(fp0, fp0, 1);
9811        tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9812        break;
9813    case OPC_SELEQZ_S:
9814        tcg_gen_andi_i32(fp1, fp1, 1);
9815        tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9816        break;
9817    case OPC_SELNEZ_S:
9818        tcg_gen_andi_i32(fp1, fp1, 1);
9819        tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9820        break;
9821    default:
9822        MIPS_INVAL("gen_sel_s");
9823        gen_reserved_instruction(ctx);
9824        break;
9825    }
9826
9827    gen_store_fpr32(ctx, fp0, fd);
9828    tcg_temp_free_i32(fp2);
9829    tcg_temp_free_i32(fp1);
9830    tcg_temp_free_i32(fp0);
9831    tcg_temp_free_i32(t1);
9832}
9833
9834static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
9835                      int fs)
9836{
9837    TCGv_i64 t1 = tcg_const_i64(0);
9838    TCGv_i64 fp0 = tcg_temp_new_i64();
9839    TCGv_i64 fp1 = tcg_temp_new_i64();
9840    TCGv_i64 fp2 = tcg_temp_new_i64();
9841    gen_load_fpr64(ctx, fp0, fd);
9842    gen_load_fpr64(ctx, fp1, ft);
9843    gen_load_fpr64(ctx, fp2, fs);
9844
9845    switch (op1) {
9846    case OPC_SEL_D:
9847        tcg_gen_andi_i64(fp0, fp0, 1);
9848        tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
9849        break;
9850    case OPC_SELEQZ_D:
9851        tcg_gen_andi_i64(fp1, fp1, 1);
9852        tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
9853        break;
9854    case OPC_SELNEZ_D:
9855        tcg_gen_andi_i64(fp1, fp1, 1);
9856        tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
9857        break;
9858    default:
9859        MIPS_INVAL("gen_sel_d");
9860        gen_reserved_instruction(ctx);
9861        break;
9862    }
9863
9864    gen_store_fpr64(ctx, fp0, fd);
9865    tcg_temp_free_i64(fp2);
9866    tcg_temp_free_i64(fp1);
9867    tcg_temp_free_i64(fp0);
9868    tcg_temp_free_i64(t1);
9869}
9870
9871static void gen_farith(DisasContext *ctx, enum fopcode op1,
9872                       int ft, int fs, int fd, int cc)
9873{
9874    uint32_t func = ctx->opcode & 0x3f;
9875    switch (op1) {
9876    case OPC_ADD_S:
9877        {
9878            TCGv_i32 fp0 = tcg_temp_new_i32();
9879            TCGv_i32 fp1 = tcg_temp_new_i32();
9880
9881            gen_load_fpr32(ctx, fp0, fs);
9882            gen_load_fpr32(ctx, fp1, ft);
9883            gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
9884            tcg_temp_free_i32(fp1);
9885            gen_store_fpr32(ctx, fp0, fd);
9886            tcg_temp_free_i32(fp0);
9887        }
9888        break;
9889    case OPC_SUB_S:
9890        {
9891            TCGv_i32 fp0 = tcg_temp_new_i32();
9892            TCGv_i32 fp1 = tcg_temp_new_i32();
9893
9894            gen_load_fpr32(ctx, fp0, fs);
9895            gen_load_fpr32(ctx, fp1, ft);
9896            gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
9897            tcg_temp_free_i32(fp1);
9898            gen_store_fpr32(ctx, fp0, fd);
9899            tcg_temp_free_i32(fp0);
9900        }
9901        break;
9902    case OPC_MUL_S:
9903        {
9904            TCGv_i32 fp0 = tcg_temp_new_i32();
9905            TCGv_i32 fp1 = tcg_temp_new_i32();
9906
9907            gen_load_fpr32(ctx, fp0, fs);
9908            gen_load_fpr32(ctx, fp1, ft);
9909            gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
9910            tcg_temp_free_i32(fp1);
9911            gen_store_fpr32(ctx, fp0, fd);
9912            tcg_temp_free_i32(fp0);
9913        }
9914        break;
9915    case OPC_DIV_S:
9916        {
9917            TCGv_i32 fp0 = tcg_temp_new_i32();
9918            TCGv_i32 fp1 = tcg_temp_new_i32();
9919
9920            gen_load_fpr32(ctx, fp0, fs);
9921            gen_load_fpr32(ctx, fp1, ft);
9922            gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
9923            tcg_temp_free_i32(fp1);
9924            gen_store_fpr32(ctx, fp0, fd);
9925            tcg_temp_free_i32(fp0);
9926        }
9927        break;
9928    case OPC_SQRT_S:
9929        {
9930            TCGv_i32 fp0 = tcg_temp_new_i32();
9931
9932            gen_load_fpr32(ctx, fp0, fs);
9933            gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
9934            gen_store_fpr32(ctx, fp0, fd);
9935            tcg_temp_free_i32(fp0);
9936        }
9937        break;
9938    case OPC_ABS_S:
9939        {
9940            TCGv_i32 fp0 = tcg_temp_new_i32();
9941
9942            gen_load_fpr32(ctx, fp0, fs);
9943            if (ctx->abs2008) {
9944                tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
9945            } else {
9946                gen_helper_float_abs_s(fp0, fp0);
9947            }
9948            gen_store_fpr32(ctx, fp0, fd);
9949            tcg_temp_free_i32(fp0);
9950        }
9951        break;
9952    case OPC_MOV_S:
9953        {
9954            TCGv_i32 fp0 = tcg_temp_new_i32();
9955
9956            gen_load_fpr32(ctx, fp0, fs);
9957            gen_store_fpr32(ctx, fp0, fd);
9958            tcg_temp_free_i32(fp0);
9959        }
9960        break;
9961    case OPC_NEG_S:
9962        {
9963            TCGv_i32 fp0 = tcg_temp_new_i32();
9964
9965            gen_load_fpr32(ctx, fp0, fs);
9966            if (ctx->abs2008) {
9967                tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
9968            } else {
9969                gen_helper_float_chs_s(fp0, fp0);
9970            }
9971            gen_store_fpr32(ctx, fp0, fd);
9972            tcg_temp_free_i32(fp0);
9973        }
9974        break;
9975    case OPC_ROUND_L_S:
9976        check_cp1_64bitmode(ctx);
9977        {
9978            TCGv_i32 fp32 = tcg_temp_new_i32();
9979            TCGv_i64 fp64 = tcg_temp_new_i64();
9980
9981            gen_load_fpr32(ctx, fp32, fs);
9982            if (ctx->nan2008) {
9983                gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
9984            } else {
9985                gen_helper_float_round_l_s(fp64, cpu_env, fp32);
9986            }
9987            tcg_temp_free_i32(fp32);
9988            gen_store_fpr64(ctx, fp64, fd);
9989            tcg_temp_free_i64(fp64);
9990        }
9991        break;
9992    case OPC_TRUNC_L_S:
9993        check_cp1_64bitmode(ctx);
9994        {
9995            TCGv_i32 fp32 = tcg_temp_new_i32();
9996            TCGv_i64 fp64 = tcg_temp_new_i64();
9997
9998            gen_load_fpr32(ctx, fp32, fs);
9999            if (ctx->nan2008) {
10000                gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
10001            } else {
10002                gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
10003            }
10004            tcg_temp_free_i32(fp32);
10005            gen_store_fpr64(ctx, fp64, fd);
10006            tcg_temp_free_i64(fp64);
10007        }
10008        break;
10009    case OPC_CEIL_L_S:
10010        check_cp1_64bitmode(ctx);
10011        {
10012            TCGv_i32 fp32 = tcg_temp_new_i32();
10013            TCGv_i64 fp64 = tcg_temp_new_i64();
10014
10015            gen_load_fpr32(ctx, fp32, fs);
10016            if (ctx->nan2008) {
10017                gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
10018            } else {
10019                gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
10020            }
10021            tcg_temp_free_i32(fp32);
10022            gen_store_fpr64(ctx, fp64, fd);
10023            tcg_temp_free_i64(fp64);
10024        }
10025        break;
10026    case OPC_FLOOR_L_S:
10027        check_cp1_64bitmode(ctx);
10028        {
10029            TCGv_i32 fp32 = tcg_temp_new_i32();
10030            TCGv_i64 fp64 = tcg_temp_new_i64();
10031
10032            gen_load_fpr32(ctx, fp32, fs);
10033            if (ctx->nan2008) {
10034                gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
10035            } else {
10036                gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
10037            }
10038            tcg_temp_free_i32(fp32);
10039            gen_store_fpr64(ctx, fp64, fd);
10040            tcg_temp_free_i64(fp64);
10041        }
10042        break;
10043    case OPC_ROUND_W_S:
10044        {
10045            TCGv_i32 fp0 = tcg_temp_new_i32();
10046
10047            gen_load_fpr32(ctx, fp0, fs);
10048            if (ctx->nan2008) {
10049                gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
10050            } else {
10051                gen_helper_float_round_w_s(fp0, cpu_env, fp0);
10052            }
10053            gen_store_fpr32(ctx, fp0, fd);
10054            tcg_temp_free_i32(fp0);
10055        }
10056        break;
10057    case OPC_TRUNC_W_S:
10058        {
10059            TCGv_i32 fp0 = tcg_temp_new_i32();
10060
10061            gen_load_fpr32(ctx, fp0, fs);
10062            if (ctx->nan2008) {
10063                gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
10064            } else {
10065                gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
10066            }
10067            gen_store_fpr32(ctx, fp0, fd);
10068            tcg_temp_free_i32(fp0);
10069        }
10070        break;
10071    case OPC_CEIL_W_S:
10072        {
10073            TCGv_i32 fp0 = tcg_temp_new_i32();
10074
10075            gen_load_fpr32(ctx, fp0, fs);
10076            if (ctx->nan2008) {
10077                gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
10078            } else {
10079                gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
10080            }
10081            gen_store_fpr32(ctx, fp0, fd);
10082            tcg_temp_free_i32(fp0);
10083        }
10084        break;
10085    case OPC_FLOOR_W_S:
10086        {
10087            TCGv_i32 fp0 = tcg_temp_new_i32();
10088
10089            gen_load_fpr32(ctx, fp0, fs);
10090            if (ctx->nan2008) {
10091                gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
10092            } else {
10093                gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
10094            }
10095            gen_store_fpr32(ctx, fp0, fd);
10096            tcg_temp_free_i32(fp0);
10097        }
10098        break;
10099    case OPC_SEL_S:
10100        check_insn(ctx, ISA_MIPS_R6);
10101        gen_sel_s(ctx, op1, fd, ft, fs);
10102        break;
10103    case OPC_SELEQZ_S:
10104        check_insn(ctx, ISA_MIPS_R6);
10105        gen_sel_s(ctx, op1, fd, ft, fs);
10106        break;
10107    case OPC_SELNEZ_S:
10108        check_insn(ctx, ISA_MIPS_R6);
10109        gen_sel_s(ctx, op1, fd, ft, fs);
10110        break;
10111    case OPC_MOVCF_S:
10112        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10113        gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10114        break;
10115    case OPC_MOVZ_S:
10116        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10117        {
10118            TCGLabel *l1 = gen_new_label();
10119            TCGv_i32 fp0;
10120
10121            if (ft != 0) {
10122                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10123            }
10124            fp0 = tcg_temp_new_i32();
10125            gen_load_fpr32(ctx, fp0, fs);
10126            gen_store_fpr32(ctx, fp0, fd);
10127            tcg_temp_free_i32(fp0);
10128            gen_set_label(l1);
10129        }
10130        break;
10131    case OPC_MOVN_S:
10132        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10133        {
10134            TCGLabel *l1 = gen_new_label();
10135            TCGv_i32 fp0;
10136
10137            if (ft != 0) {
10138                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10139                fp0 = tcg_temp_new_i32();
10140                gen_load_fpr32(ctx, fp0, fs);
10141                gen_store_fpr32(ctx, fp0, fd);
10142                tcg_temp_free_i32(fp0);
10143                gen_set_label(l1);
10144            }
10145        }
10146        break;
10147    case OPC_RECIP_S:
10148        {
10149            TCGv_i32 fp0 = tcg_temp_new_i32();
10150
10151            gen_load_fpr32(ctx, fp0, fs);
10152            gen_helper_float_recip_s(fp0, cpu_env, fp0);
10153            gen_store_fpr32(ctx, fp0, fd);
10154            tcg_temp_free_i32(fp0);
10155        }
10156        break;
10157    case OPC_RSQRT_S:
10158        {
10159            TCGv_i32 fp0 = tcg_temp_new_i32();
10160
10161            gen_load_fpr32(ctx, fp0, fs);
10162            gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
10163            gen_store_fpr32(ctx, fp0, fd);
10164            tcg_temp_free_i32(fp0);
10165        }
10166        break;
10167    case OPC_MADDF_S:
10168        check_insn(ctx, ISA_MIPS_R6);
10169        {
10170            TCGv_i32 fp0 = tcg_temp_new_i32();
10171            TCGv_i32 fp1 = tcg_temp_new_i32();
10172            TCGv_i32 fp2 = tcg_temp_new_i32();
10173            gen_load_fpr32(ctx, fp0, fs);
10174            gen_load_fpr32(ctx, fp1, ft);
10175            gen_load_fpr32(ctx, fp2, fd);
10176            gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
10177            gen_store_fpr32(ctx, fp2, fd);
10178            tcg_temp_free_i32(fp2);
10179            tcg_temp_free_i32(fp1);
10180            tcg_temp_free_i32(fp0);
10181        }
10182        break;
10183    case OPC_MSUBF_S:
10184        check_insn(ctx, ISA_MIPS_R6);
10185        {
10186            TCGv_i32 fp0 = tcg_temp_new_i32();
10187            TCGv_i32 fp1 = tcg_temp_new_i32();
10188            TCGv_i32 fp2 = tcg_temp_new_i32();
10189            gen_load_fpr32(ctx, fp0, fs);
10190            gen_load_fpr32(ctx, fp1, ft);
10191            gen_load_fpr32(ctx, fp2, fd);
10192            gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
10193            gen_store_fpr32(ctx, fp2, fd);
10194            tcg_temp_free_i32(fp2);
10195            tcg_temp_free_i32(fp1);
10196            tcg_temp_free_i32(fp0);
10197        }
10198        break;
10199    case OPC_RINT_S:
10200        check_insn(ctx, ISA_MIPS_R6);
10201        {
10202            TCGv_i32 fp0 = tcg_temp_new_i32();
10203            gen_load_fpr32(ctx, fp0, fs);
10204            gen_helper_float_rint_s(fp0, cpu_env, fp0);
10205            gen_store_fpr32(ctx, fp0, fd);
10206            tcg_temp_free_i32(fp0);
10207        }
10208        break;
10209    case OPC_CLASS_S:
10210        check_insn(ctx, ISA_MIPS_R6);
10211        {
10212            TCGv_i32 fp0 = tcg_temp_new_i32();
10213            gen_load_fpr32(ctx, fp0, fs);
10214            gen_helper_float_class_s(fp0, cpu_env, fp0);
10215            gen_store_fpr32(ctx, fp0, fd);
10216            tcg_temp_free_i32(fp0);
10217        }
10218        break;
10219    case OPC_MIN_S: /* OPC_RECIP2_S */
10220        if (ctx->insn_flags & ISA_MIPS_R6) {
10221            /* OPC_MIN_S */
10222            TCGv_i32 fp0 = tcg_temp_new_i32();
10223            TCGv_i32 fp1 = tcg_temp_new_i32();
10224            TCGv_i32 fp2 = tcg_temp_new_i32();
10225            gen_load_fpr32(ctx, fp0, fs);
10226            gen_load_fpr32(ctx, fp1, ft);
10227            gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
10228            gen_store_fpr32(ctx, fp2, fd);
10229            tcg_temp_free_i32(fp2);
10230            tcg_temp_free_i32(fp1);
10231            tcg_temp_free_i32(fp0);
10232        } else {
10233            /* OPC_RECIP2_S */
10234            check_cp1_64bitmode(ctx);
10235            {
10236                TCGv_i32 fp0 = tcg_temp_new_i32();
10237                TCGv_i32 fp1 = tcg_temp_new_i32();
10238
10239                gen_load_fpr32(ctx, fp0, fs);
10240                gen_load_fpr32(ctx, fp1, ft);
10241                gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
10242                tcg_temp_free_i32(fp1);
10243                gen_store_fpr32(ctx, fp0, fd);
10244                tcg_temp_free_i32(fp0);
10245            }
10246        }
10247        break;
10248    case OPC_MINA_S: /* OPC_RECIP1_S */
10249        if (ctx->insn_flags & ISA_MIPS_R6) {
10250            /* OPC_MINA_S */
10251            TCGv_i32 fp0 = tcg_temp_new_i32();
10252            TCGv_i32 fp1 = tcg_temp_new_i32();
10253            TCGv_i32 fp2 = tcg_temp_new_i32();
10254            gen_load_fpr32(ctx, fp0, fs);
10255            gen_load_fpr32(ctx, fp1, ft);
10256            gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
10257            gen_store_fpr32(ctx, fp2, fd);
10258            tcg_temp_free_i32(fp2);
10259            tcg_temp_free_i32(fp1);
10260            tcg_temp_free_i32(fp0);
10261        } else {
10262            /* OPC_RECIP1_S */
10263            check_cp1_64bitmode(ctx);
10264            {
10265                TCGv_i32 fp0 = tcg_temp_new_i32();
10266
10267                gen_load_fpr32(ctx, fp0, fs);
10268                gen_helper_float_recip1_s(fp0, cpu_env, fp0);
10269                gen_store_fpr32(ctx, fp0, fd);
10270                tcg_temp_free_i32(fp0);
10271            }
10272        }
10273        break;
10274    case OPC_MAX_S: /* OPC_RSQRT1_S */
10275        if (ctx->insn_flags & ISA_MIPS_R6) {
10276            /* OPC_MAX_S */
10277            TCGv_i32 fp0 = tcg_temp_new_i32();
10278            TCGv_i32 fp1 = tcg_temp_new_i32();
10279            gen_load_fpr32(ctx, fp0, fs);
10280            gen_load_fpr32(ctx, fp1, ft);
10281            gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
10282            gen_store_fpr32(ctx, fp1, fd);
10283            tcg_temp_free_i32(fp1);
10284            tcg_temp_free_i32(fp0);
10285        } else {
10286            /* OPC_RSQRT1_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_rsqrt1_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_MAXA_S: /* OPC_RSQRT2_S */
10299        if (ctx->insn_flags & ISA_MIPS_R6) {
10300            /* OPC_MAXA_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_maxa_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_RSQRT2_S */
10311            check_cp1_64bitmode(ctx);
10312            {
10313                TCGv_i32 fp0 = tcg_temp_new_i32();
10314                TCGv_i32 fp1 = tcg_temp_new_i32();
10315
10316                gen_load_fpr32(ctx, fp0, fs);
10317                gen_load_fpr32(ctx, fp1, ft);
10318                gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
10319                tcg_temp_free_i32(fp1);
10320                gen_store_fpr32(ctx, fp0, fd);
10321                tcg_temp_free_i32(fp0);
10322            }
10323        }
10324        break;
10325    case OPC_CVT_D_S:
10326        check_cp1_registers(ctx, fd);
10327        {
10328            TCGv_i32 fp32 = tcg_temp_new_i32();
10329            TCGv_i64 fp64 = tcg_temp_new_i64();
10330
10331            gen_load_fpr32(ctx, fp32, fs);
10332            gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
10333            tcg_temp_free_i32(fp32);
10334            gen_store_fpr64(ctx, fp64, fd);
10335            tcg_temp_free_i64(fp64);
10336        }
10337        break;
10338    case OPC_CVT_W_S:
10339        {
10340            TCGv_i32 fp0 = tcg_temp_new_i32();
10341
10342            gen_load_fpr32(ctx, fp0, fs);
10343            if (ctx->nan2008) {
10344                gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
10345            } else {
10346                gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
10347            }
10348            gen_store_fpr32(ctx, fp0, fd);
10349            tcg_temp_free_i32(fp0);
10350        }
10351        break;
10352    case OPC_CVT_L_S:
10353        check_cp1_64bitmode(ctx);
10354        {
10355            TCGv_i32 fp32 = tcg_temp_new_i32();
10356            TCGv_i64 fp64 = tcg_temp_new_i64();
10357
10358            gen_load_fpr32(ctx, fp32, fs);
10359            if (ctx->nan2008) {
10360                gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
10361            } else {
10362                gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
10363            }
10364            tcg_temp_free_i32(fp32);
10365            gen_store_fpr64(ctx, fp64, fd);
10366            tcg_temp_free_i64(fp64);
10367        }
10368        break;
10369    case OPC_CVT_PS_S:
10370        check_ps(ctx);
10371        {
10372            TCGv_i64 fp64 = tcg_temp_new_i64();
10373            TCGv_i32 fp32_0 = tcg_temp_new_i32();
10374            TCGv_i32 fp32_1 = tcg_temp_new_i32();
10375
10376            gen_load_fpr32(ctx, fp32_0, fs);
10377            gen_load_fpr32(ctx, fp32_1, ft);
10378            tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
10379            tcg_temp_free_i32(fp32_1);
10380            tcg_temp_free_i32(fp32_0);
10381            gen_store_fpr64(ctx, fp64, fd);
10382            tcg_temp_free_i64(fp64);
10383        }
10384        break;
10385    case OPC_CMP_F_S:
10386    case OPC_CMP_UN_S:
10387    case OPC_CMP_EQ_S:
10388    case OPC_CMP_UEQ_S:
10389    case OPC_CMP_OLT_S:
10390    case OPC_CMP_ULT_S:
10391    case OPC_CMP_OLE_S:
10392    case OPC_CMP_ULE_S:
10393    case OPC_CMP_SF_S:
10394    case OPC_CMP_NGLE_S:
10395    case OPC_CMP_SEQ_S:
10396    case OPC_CMP_NGL_S:
10397    case OPC_CMP_LT_S:
10398    case OPC_CMP_NGE_S:
10399    case OPC_CMP_LE_S:
10400    case OPC_CMP_NGT_S:
10401        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10402        if (ctx->opcode & (1 << 6)) {
10403            gen_cmpabs_s(ctx, func - 48, ft, fs, cc);
10404        } else {
10405            gen_cmp_s(ctx, func - 48, ft, fs, cc);
10406        }
10407        break;
10408    case OPC_ADD_D:
10409        check_cp1_registers(ctx, fs | ft | fd);
10410        {
10411            TCGv_i64 fp0 = tcg_temp_new_i64();
10412            TCGv_i64 fp1 = tcg_temp_new_i64();
10413
10414            gen_load_fpr64(ctx, fp0, fs);
10415            gen_load_fpr64(ctx, fp1, ft);
10416            gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
10417            tcg_temp_free_i64(fp1);
10418            gen_store_fpr64(ctx, fp0, fd);
10419            tcg_temp_free_i64(fp0);
10420        }
10421        break;
10422    case OPC_SUB_D:
10423        check_cp1_registers(ctx, fs | ft | fd);
10424        {
10425            TCGv_i64 fp0 = tcg_temp_new_i64();
10426            TCGv_i64 fp1 = tcg_temp_new_i64();
10427
10428            gen_load_fpr64(ctx, fp0, fs);
10429            gen_load_fpr64(ctx, fp1, ft);
10430            gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
10431            tcg_temp_free_i64(fp1);
10432            gen_store_fpr64(ctx, fp0, fd);
10433            tcg_temp_free_i64(fp0);
10434        }
10435        break;
10436    case OPC_MUL_D:
10437        check_cp1_registers(ctx, fs | ft | fd);
10438        {
10439            TCGv_i64 fp0 = tcg_temp_new_i64();
10440            TCGv_i64 fp1 = tcg_temp_new_i64();
10441
10442            gen_load_fpr64(ctx, fp0, fs);
10443            gen_load_fpr64(ctx, fp1, ft);
10444            gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
10445            tcg_temp_free_i64(fp1);
10446            gen_store_fpr64(ctx, fp0, fd);
10447            tcg_temp_free_i64(fp0);
10448        }
10449        break;
10450    case OPC_DIV_D:
10451        check_cp1_registers(ctx, fs | ft | fd);
10452        {
10453            TCGv_i64 fp0 = tcg_temp_new_i64();
10454            TCGv_i64 fp1 = tcg_temp_new_i64();
10455
10456            gen_load_fpr64(ctx, fp0, fs);
10457            gen_load_fpr64(ctx, fp1, ft);
10458            gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
10459            tcg_temp_free_i64(fp1);
10460            gen_store_fpr64(ctx, fp0, fd);
10461            tcg_temp_free_i64(fp0);
10462        }
10463        break;
10464    case OPC_SQRT_D:
10465        check_cp1_registers(ctx, fs | fd);
10466        {
10467            TCGv_i64 fp0 = tcg_temp_new_i64();
10468
10469            gen_load_fpr64(ctx, fp0, fs);
10470            gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
10471            gen_store_fpr64(ctx, fp0, fd);
10472            tcg_temp_free_i64(fp0);
10473        }
10474        break;
10475    case OPC_ABS_D:
10476        check_cp1_registers(ctx, fs | fd);
10477        {
10478            TCGv_i64 fp0 = tcg_temp_new_i64();
10479
10480            gen_load_fpr64(ctx, fp0, fs);
10481            if (ctx->abs2008) {
10482                tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
10483            } else {
10484                gen_helper_float_abs_d(fp0, fp0);
10485            }
10486            gen_store_fpr64(ctx, fp0, fd);
10487            tcg_temp_free_i64(fp0);
10488        }
10489        break;
10490    case OPC_MOV_D:
10491        check_cp1_registers(ctx, fs | fd);
10492        {
10493            TCGv_i64 fp0 = tcg_temp_new_i64();
10494
10495            gen_load_fpr64(ctx, fp0, fs);
10496            gen_store_fpr64(ctx, fp0, fd);
10497            tcg_temp_free_i64(fp0);
10498        }
10499        break;
10500    case OPC_NEG_D:
10501        check_cp1_registers(ctx, fs | fd);
10502        {
10503            TCGv_i64 fp0 = tcg_temp_new_i64();
10504
10505            gen_load_fpr64(ctx, fp0, fs);
10506            if (ctx->abs2008) {
10507                tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
10508            } else {
10509                gen_helper_float_chs_d(fp0, fp0);
10510            }
10511            gen_store_fpr64(ctx, fp0, fd);
10512            tcg_temp_free_i64(fp0);
10513        }
10514        break;
10515    case OPC_ROUND_L_D:
10516        check_cp1_64bitmode(ctx);
10517        {
10518            TCGv_i64 fp0 = tcg_temp_new_i64();
10519
10520            gen_load_fpr64(ctx, fp0, fs);
10521            if (ctx->nan2008) {
10522                gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
10523            } else {
10524                gen_helper_float_round_l_d(fp0, cpu_env, fp0);
10525            }
10526            gen_store_fpr64(ctx, fp0, fd);
10527            tcg_temp_free_i64(fp0);
10528        }
10529        break;
10530    case OPC_TRUNC_L_D:
10531        check_cp1_64bitmode(ctx);
10532        {
10533            TCGv_i64 fp0 = tcg_temp_new_i64();
10534
10535            gen_load_fpr64(ctx, fp0, fs);
10536            if (ctx->nan2008) {
10537                gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
10538            } else {
10539                gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
10540            }
10541            gen_store_fpr64(ctx, fp0, fd);
10542            tcg_temp_free_i64(fp0);
10543        }
10544        break;
10545    case OPC_CEIL_L_D:
10546        check_cp1_64bitmode(ctx);
10547        {
10548            TCGv_i64 fp0 = tcg_temp_new_i64();
10549
10550            gen_load_fpr64(ctx, fp0, fs);
10551            if (ctx->nan2008) {
10552                gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
10553            } else {
10554                gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
10555            }
10556            gen_store_fpr64(ctx, fp0, fd);
10557            tcg_temp_free_i64(fp0);
10558        }
10559        break;
10560    case OPC_FLOOR_L_D:
10561        check_cp1_64bitmode(ctx);
10562        {
10563            TCGv_i64 fp0 = tcg_temp_new_i64();
10564
10565            gen_load_fpr64(ctx, fp0, fs);
10566            if (ctx->nan2008) {
10567                gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
10568            } else {
10569                gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
10570            }
10571            gen_store_fpr64(ctx, fp0, fd);
10572            tcg_temp_free_i64(fp0);
10573        }
10574        break;
10575    case OPC_ROUND_W_D:
10576        check_cp1_registers(ctx, fs);
10577        {
10578            TCGv_i32 fp32 = tcg_temp_new_i32();
10579            TCGv_i64 fp64 = tcg_temp_new_i64();
10580
10581            gen_load_fpr64(ctx, fp64, fs);
10582            if (ctx->nan2008) {
10583                gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
10584            } else {
10585                gen_helper_float_round_w_d(fp32, cpu_env, fp64);
10586            }
10587            tcg_temp_free_i64(fp64);
10588            gen_store_fpr32(ctx, fp32, fd);
10589            tcg_temp_free_i32(fp32);
10590        }
10591        break;
10592    case OPC_TRUNC_W_D:
10593        check_cp1_registers(ctx, fs);
10594        {
10595            TCGv_i32 fp32 = tcg_temp_new_i32();
10596            TCGv_i64 fp64 = tcg_temp_new_i64();
10597
10598            gen_load_fpr64(ctx, fp64, fs);
10599            if (ctx->nan2008) {
10600                gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
10601            } else {
10602                gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
10603            }
10604            tcg_temp_free_i64(fp64);
10605            gen_store_fpr32(ctx, fp32, fd);
10606            tcg_temp_free_i32(fp32);
10607        }
10608        break;
10609    case OPC_CEIL_W_D:
10610        check_cp1_registers(ctx, fs);
10611        {
10612            TCGv_i32 fp32 = tcg_temp_new_i32();
10613            TCGv_i64 fp64 = tcg_temp_new_i64();
10614
10615            gen_load_fpr64(ctx, fp64, fs);
10616            if (ctx->nan2008) {
10617                gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
10618            } else {
10619                gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
10620            }
10621            tcg_temp_free_i64(fp64);
10622            gen_store_fpr32(ctx, fp32, fd);
10623            tcg_temp_free_i32(fp32);
10624        }
10625        break;
10626    case OPC_FLOOR_W_D:
10627        check_cp1_registers(ctx, fs);
10628        {
10629            TCGv_i32 fp32 = tcg_temp_new_i32();
10630            TCGv_i64 fp64 = tcg_temp_new_i64();
10631
10632            gen_load_fpr64(ctx, fp64, fs);
10633            if (ctx->nan2008) {
10634                gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
10635            } else {
10636                gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
10637            }
10638            tcg_temp_free_i64(fp64);
10639            gen_store_fpr32(ctx, fp32, fd);
10640            tcg_temp_free_i32(fp32);
10641        }
10642        break;
10643    case OPC_SEL_D:
10644        check_insn(ctx, ISA_MIPS_R6);
10645        gen_sel_d(ctx, op1, fd, ft, fs);
10646        break;
10647    case OPC_SELEQZ_D:
10648        check_insn(ctx, ISA_MIPS_R6);
10649        gen_sel_d(ctx, op1, fd, ft, fs);
10650        break;
10651    case OPC_SELNEZ_D:
10652        check_insn(ctx, ISA_MIPS_R6);
10653        gen_sel_d(ctx, op1, fd, ft, fs);
10654        break;
10655    case OPC_MOVCF_D:
10656        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10657        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10658        break;
10659    case OPC_MOVZ_D:
10660        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10661        {
10662            TCGLabel *l1 = gen_new_label();
10663            TCGv_i64 fp0;
10664
10665            if (ft != 0) {
10666                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10667            }
10668            fp0 = tcg_temp_new_i64();
10669            gen_load_fpr64(ctx, fp0, fs);
10670            gen_store_fpr64(ctx, fp0, fd);
10671            tcg_temp_free_i64(fp0);
10672            gen_set_label(l1);
10673        }
10674        break;
10675    case OPC_MOVN_D:
10676        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10677        {
10678            TCGLabel *l1 = gen_new_label();
10679            TCGv_i64 fp0;
10680
10681            if (ft != 0) {
10682                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10683                fp0 = tcg_temp_new_i64();
10684                gen_load_fpr64(ctx, fp0, fs);
10685                gen_store_fpr64(ctx, fp0, fd);
10686                tcg_temp_free_i64(fp0);
10687                gen_set_label(l1);
10688            }
10689        }
10690        break;
10691    case OPC_RECIP_D:
10692        check_cp1_registers(ctx, fs | fd);
10693        {
10694            TCGv_i64 fp0 = tcg_temp_new_i64();
10695
10696            gen_load_fpr64(ctx, fp0, fs);
10697            gen_helper_float_recip_d(fp0, cpu_env, fp0);
10698            gen_store_fpr64(ctx, fp0, fd);
10699            tcg_temp_free_i64(fp0);
10700        }
10701        break;
10702    case OPC_RSQRT_D:
10703        check_cp1_registers(ctx, fs | fd);
10704        {
10705            TCGv_i64 fp0 = tcg_temp_new_i64();
10706
10707            gen_load_fpr64(ctx, fp0, fs);
10708            gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
10709            gen_store_fpr64(ctx, fp0, fd);
10710            tcg_temp_free_i64(fp0);
10711        }
10712        break;
10713    case OPC_MADDF_D:
10714        check_insn(ctx, ISA_MIPS_R6);
10715        {
10716            TCGv_i64 fp0 = tcg_temp_new_i64();
10717            TCGv_i64 fp1 = tcg_temp_new_i64();
10718            TCGv_i64 fp2 = tcg_temp_new_i64();
10719            gen_load_fpr64(ctx, fp0, fs);
10720            gen_load_fpr64(ctx, fp1, ft);
10721            gen_load_fpr64(ctx, fp2, fd);
10722            gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
10723            gen_store_fpr64(ctx, fp2, fd);
10724            tcg_temp_free_i64(fp2);
10725            tcg_temp_free_i64(fp1);
10726            tcg_temp_free_i64(fp0);
10727        }
10728        break;
10729    case OPC_MSUBF_D:
10730        check_insn(ctx, ISA_MIPS_R6);
10731        {
10732            TCGv_i64 fp0 = tcg_temp_new_i64();
10733            TCGv_i64 fp1 = tcg_temp_new_i64();
10734            TCGv_i64 fp2 = tcg_temp_new_i64();
10735            gen_load_fpr64(ctx, fp0, fs);
10736            gen_load_fpr64(ctx, fp1, ft);
10737            gen_load_fpr64(ctx, fp2, fd);
10738            gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
10739            gen_store_fpr64(ctx, fp2, fd);
10740            tcg_temp_free_i64(fp2);
10741            tcg_temp_free_i64(fp1);
10742            tcg_temp_free_i64(fp0);
10743        }
10744        break;
10745    case OPC_RINT_D:
10746        check_insn(ctx, ISA_MIPS_R6);
10747        {
10748            TCGv_i64 fp0 = tcg_temp_new_i64();
10749            gen_load_fpr64(ctx, fp0, fs);
10750            gen_helper_float_rint_d(fp0, cpu_env, fp0);
10751            gen_store_fpr64(ctx, fp0, fd);
10752            tcg_temp_free_i64(fp0);
10753        }
10754        break;
10755    case OPC_CLASS_D:
10756        check_insn(ctx, ISA_MIPS_R6);
10757        {
10758            TCGv_i64 fp0 = tcg_temp_new_i64();
10759            gen_load_fpr64(ctx, fp0, fs);
10760            gen_helper_float_class_d(fp0, cpu_env, fp0);
10761            gen_store_fpr64(ctx, fp0, fd);
10762            tcg_temp_free_i64(fp0);
10763        }
10764        break;
10765    case OPC_MIN_D: /* OPC_RECIP2_D */
10766        if (ctx->insn_flags & ISA_MIPS_R6) {
10767            /* OPC_MIN_D */
10768            TCGv_i64 fp0 = tcg_temp_new_i64();
10769            TCGv_i64 fp1 = tcg_temp_new_i64();
10770            gen_load_fpr64(ctx, fp0, fs);
10771            gen_load_fpr64(ctx, fp1, ft);
10772            gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
10773            gen_store_fpr64(ctx, fp1, fd);
10774            tcg_temp_free_i64(fp1);
10775            tcg_temp_free_i64(fp0);
10776        } else {
10777            /* OPC_RECIP2_D */
10778            check_cp1_64bitmode(ctx);
10779            {
10780                TCGv_i64 fp0 = tcg_temp_new_i64();
10781                TCGv_i64 fp1 = tcg_temp_new_i64();
10782
10783                gen_load_fpr64(ctx, fp0, fs);
10784                gen_load_fpr64(ctx, fp1, ft);
10785                gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
10786                tcg_temp_free_i64(fp1);
10787                gen_store_fpr64(ctx, fp0, fd);
10788                tcg_temp_free_i64(fp0);
10789            }
10790        }
10791        break;
10792    case OPC_MINA_D: /* OPC_RECIP1_D */
10793        if (ctx->insn_flags & ISA_MIPS_R6) {
10794            /* OPC_MINA_D */
10795            TCGv_i64 fp0 = tcg_temp_new_i64();
10796            TCGv_i64 fp1 = tcg_temp_new_i64();
10797            gen_load_fpr64(ctx, fp0, fs);
10798            gen_load_fpr64(ctx, fp1, ft);
10799            gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
10800            gen_store_fpr64(ctx, fp1, fd);
10801            tcg_temp_free_i64(fp1);
10802            tcg_temp_free_i64(fp0);
10803        } else {
10804            /* OPC_RECIP1_D */
10805            check_cp1_64bitmode(ctx);
10806            {
10807                TCGv_i64 fp0 = tcg_temp_new_i64();
10808
10809                gen_load_fpr64(ctx, fp0, fs);
10810                gen_helper_float_recip1_d(fp0, cpu_env, fp0);
10811                gen_store_fpr64(ctx, fp0, fd);
10812                tcg_temp_free_i64(fp0);
10813            }
10814        }
10815        break;
10816    case OPC_MAX_D: /*  OPC_RSQRT1_D */
10817        if (ctx->insn_flags & ISA_MIPS_R6) {
10818            /* OPC_MAX_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_max_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_RSQRT1_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_rsqrt1_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_MAXA_D: /* OPC_RSQRT2_D */
10841        if (ctx->insn_flags & ISA_MIPS_R6) {
10842            /* OPC_MAXA_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_maxa_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_RSQRT2_D */
10853            check_cp1_64bitmode(ctx);
10854            {
10855                TCGv_i64 fp0 = tcg_temp_new_i64();
10856                TCGv_i64 fp1 = tcg_temp_new_i64();
10857
10858                gen_load_fpr64(ctx, fp0, fs);
10859                gen_load_fpr64(ctx, fp1, ft);
10860                gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
10861                tcg_temp_free_i64(fp1);
10862                gen_store_fpr64(ctx, fp0, fd);
10863                tcg_temp_free_i64(fp0);
10864            }
10865        }
10866        break;
10867    case OPC_CMP_F_D:
10868    case OPC_CMP_UN_D:
10869    case OPC_CMP_EQ_D:
10870    case OPC_CMP_UEQ_D:
10871    case OPC_CMP_OLT_D:
10872    case OPC_CMP_ULT_D:
10873    case OPC_CMP_OLE_D:
10874    case OPC_CMP_ULE_D:
10875    case OPC_CMP_SF_D:
10876    case OPC_CMP_NGLE_D:
10877    case OPC_CMP_SEQ_D:
10878    case OPC_CMP_NGL_D:
10879    case OPC_CMP_LT_D:
10880    case OPC_CMP_NGE_D:
10881    case OPC_CMP_LE_D:
10882    case OPC_CMP_NGT_D:
10883        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10884        if (ctx->opcode & (1 << 6)) {
10885            gen_cmpabs_d(ctx, func - 48, ft, fs, cc);
10886        } else {
10887            gen_cmp_d(ctx, func - 48, ft, fs, cc);
10888        }
10889        break;
10890    case OPC_CVT_S_D:
10891        check_cp1_registers(ctx, fs);
10892        {
10893            TCGv_i32 fp32 = tcg_temp_new_i32();
10894            TCGv_i64 fp64 = tcg_temp_new_i64();
10895
10896            gen_load_fpr64(ctx, fp64, fs);
10897            gen_helper_float_cvts_d(fp32, cpu_env, fp64);
10898            tcg_temp_free_i64(fp64);
10899            gen_store_fpr32(ctx, fp32, fd);
10900            tcg_temp_free_i32(fp32);
10901        }
10902        break;
10903    case OPC_CVT_W_D:
10904        check_cp1_registers(ctx, fs);
10905        {
10906            TCGv_i32 fp32 = tcg_temp_new_i32();
10907            TCGv_i64 fp64 = tcg_temp_new_i64();
10908
10909            gen_load_fpr64(ctx, fp64, fs);
10910            if (ctx->nan2008) {
10911                gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
10912            } else {
10913                gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
10914            }
10915            tcg_temp_free_i64(fp64);
10916            gen_store_fpr32(ctx, fp32, fd);
10917            tcg_temp_free_i32(fp32);
10918        }
10919        break;
10920    case OPC_CVT_L_D:
10921        check_cp1_64bitmode(ctx);
10922        {
10923            TCGv_i64 fp0 = tcg_temp_new_i64();
10924
10925            gen_load_fpr64(ctx, fp0, fs);
10926            if (ctx->nan2008) {
10927                gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
10928            } else {
10929                gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
10930            }
10931            gen_store_fpr64(ctx, fp0, fd);
10932            tcg_temp_free_i64(fp0);
10933        }
10934        break;
10935    case OPC_CVT_S_W:
10936        {
10937            TCGv_i32 fp0 = tcg_temp_new_i32();
10938
10939            gen_load_fpr32(ctx, fp0, fs);
10940            gen_helper_float_cvts_w(fp0, cpu_env, fp0);
10941            gen_store_fpr32(ctx, fp0, fd);
10942            tcg_temp_free_i32(fp0);
10943        }
10944        break;
10945    case OPC_CVT_D_W:
10946        check_cp1_registers(ctx, fd);
10947        {
10948            TCGv_i32 fp32 = tcg_temp_new_i32();
10949            TCGv_i64 fp64 = tcg_temp_new_i64();
10950
10951            gen_load_fpr32(ctx, fp32, fs);
10952            gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
10953            tcg_temp_free_i32(fp32);
10954            gen_store_fpr64(ctx, fp64, fd);
10955            tcg_temp_free_i64(fp64);
10956        }
10957        break;
10958    case OPC_CVT_S_L:
10959        check_cp1_64bitmode(ctx);
10960        {
10961            TCGv_i32 fp32 = tcg_temp_new_i32();
10962            TCGv_i64 fp64 = tcg_temp_new_i64();
10963
10964            gen_load_fpr64(ctx, fp64, fs);
10965            gen_helper_float_cvts_l(fp32, cpu_env, fp64);
10966            tcg_temp_free_i64(fp64);
10967            gen_store_fpr32(ctx, fp32, fd);
10968            tcg_temp_free_i32(fp32);
10969        }
10970        break;
10971    case OPC_CVT_D_L:
10972        check_cp1_64bitmode(ctx);
10973        {
10974            TCGv_i64 fp0 = tcg_temp_new_i64();
10975
10976            gen_load_fpr64(ctx, fp0, fs);
10977            gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
10978            gen_store_fpr64(ctx, fp0, fd);
10979            tcg_temp_free_i64(fp0);
10980        }
10981        break;
10982    case OPC_CVT_PS_PW:
10983        check_ps(ctx);
10984        {
10985            TCGv_i64 fp0 = tcg_temp_new_i64();
10986
10987            gen_load_fpr64(ctx, fp0, fs);
10988            gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
10989            gen_store_fpr64(ctx, fp0, fd);
10990            tcg_temp_free_i64(fp0);
10991        }
10992        break;
10993    case OPC_ADD_PS:
10994        check_ps(ctx);
10995        {
10996            TCGv_i64 fp0 = tcg_temp_new_i64();
10997            TCGv_i64 fp1 = tcg_temp_new_i64();
10998
10999            gen_load_fpr64(ctx, fp0, fs);
11000            gen_load_fpr64(ctx, fp1, ft);
11001            gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
11002            tcg_temp_free_i64(fp1);
11003            gen_store_fpr64(ctx, fp0, fd);
11004            tcg_temp_free_i64(fp0);
11005        }
11006        break;
11007    case OPC_SUB_PS:
11008        check_ps(ctx);
11009        {
11010            TCGv_i64 fp0 = tcg_temp_new_i64();
11011            TCGv_i64 fp1 = tcg_temp_new_i64();
11012
11013            gen_load_fpr64(ctx, fp0, fs);
11014            gen_load_fpr64(ctx, fp1, ft);
11015            gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
11016            tcg_temp_free_i64(fp1);
11017            gen_store_fpr64(ctx, fp0, fd);
11018            tcg_temp_free_i64(fp0);
11019        }
11020        break;
11021    case OPC_MUL_PS:
11022        check_ps(ctx);
11023        {
11024            TCGv_i64 fp0 = tcg_temp_new_i64();
11025            TCGv_i64 fp1 = tcg_temp_new_i64();
11026
11027            gen_load_fpr64(ctx, fp0, fs);
11028            gen_load_fpr64(ctx, fp1, ft);
11029            gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
11030            tcg_temp_free_i64(fp1);
11031            gen_store_fpr64(ctx, fp0, fd);
11032            tcg_temp_free_i64(fp0);
11033        }
11034        break;
11035    case OPC_ABS_PS:
11036        check_ps(ctx);
11037        {
11038            TCGv_i64 fp0 = tcg_temp_new_i64();
11039
11040            gen_load_fpr64(ctx, fp0, fs);
11041            gen_helper_float_abs_ps(fp0, fp0);
11042            gen_store_fpr64(ctx, fp0, fd);
11043            tcg_temp_free_i64(fp0);
11044        }
11045        break;
11046    case OPC_MOV_PS:
11047        check_ps(ctx);
11048        {
11049            TCGv_i64 fp0 = tcg_temp_new_i64();
11050
11051            gen_load_fpr64(ctx, fp0, fs);
11052            gen_store_fpr64(ctx, fp0, fd);
11053            tcg_temp_free_i64(fp0);
11054        }
11055        break;
11056    case OPC_NEG_PS:
11057        check_ps(ctx);
11058        {
11059            TCGv_i64 fp0 = tcg_temp_new_i64();
11060
11061            gen_load_fpr64(ctx, fp0, fs);
11062            gen_helper_float_chs_ps(fp0, fp0);
11063            gen_store_fpr64(ctx, fp0, fd);
11064            tcg_temp_free_i64(fp0);
11065        }
11066        break;
11067    case OPC_MOVCF_PS:
11068        check_ps(ctx);
11069        gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11070        break;
11071    case OPC_MOVZ_PS:
11072        check_ps(ctx);
11073        {
11074            TCGLabel *l1 = gen_new_label();
11075            TCGv_i64 fp0;
11076
11077            if (ft != 0) {
11078                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11079            }
11080            fp0 = tcg_temp_new_i64();
11081            gen_load_fpr64(ctx, fp0, fs);
11082            gen_store_fpr64(ctx, fp0, fd);
11083            tcg_temp_free_i64(fp0);
11084            gen_set_label(l1);
11085        }
11086        break;
11087    case OPC_MOVN_PS:
11088        check_ps(ctx);
11089        {
11090            TCGLabel *l1 = gen_new_label();
11091            TCGv_i64 fp0;
11092
11093            if (ft != 0) {
11094                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11095                fp0 = tcg_temp_new_i64();
11096                gen_load_fpr64(ctx, fp0, fs);
11097                gen_store_fpr64(ctx, fp0, fd);
11098                tcg_temp_free_i64(fp0);
11099                gen_set_label(l1);
11100            }
11101        }
11102        break;
11103    case OPC_ADDR_PS:
11104        check_ps(ctx);
11105        {
11106            TCGv_i64 fp0 = tcg_temp_new_i64();
11107            TCGv_i64 fp1 = tcg_temp_new_i64();
11108
11109            gen_load_fpr64(ctx, fp0, ft);
11110            gen_load_fpr64(ctx, fp1, fs);
11111            gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
11112            tcg_temp_free_i64(fp1);
11113            gen_store_fpr64(ctx, fp0, fd);
11114            tcg_temp_free_i64(fp0);
11115        }
11116        break;
11117    case OPC_MULR_PS:
11118        check_ps(ctx);
11119        {
11120            TCGv_i64 fp0 = tcg_temp_new_i64();
11121            TCGv_i64 fp1 = tcg_temp_new_i64();
11122
11123            gen_load_fpr64(ctx, fp0, ft);
11124            gen_load_fpr64(ctx, fp1, fs);
11125            gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
11126            tcg_temp_free_i64(fp1);
11127            gen_store_fpr64(ctx, fp0, fd);
11128            tcg_temp_free_i64(fp0);
11129        }
11130        break;
11131    case OPC_RECIP2_PS:
11132        check_ps(ctx);
11133        {
11134            TCGv_i64 fp0 = tcg_temp_new_i64();
11135            TCGv_i64 fp1 = tcg_temp_new_i64();
11136
11137            gen_load_fpr64(ctx, fp0, fs);
11138            gen_load_fpr64(ctx, fp1, ft);
11139            gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
11140            tcg_temp_free_i64(fp1);
11141            gen_store_fpr64(ctx, fp0, fd);
11142            tcg_temp_free_i64(fp0);
11143        }
11144        break;
11145    case OPC_RECIP1_PS:
11146        check_ps(ctx);
11147        {
11148            TCGv_i64 fp0 = tcg_temp_new_i64();
11149
11150            gen_load_fpr64(ctx, fp0, fs);
11151            gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
11152            gen_store_fpr64(ctx, fp0, fd);
11153            tcg_temp_free_i64(fp0);
11154        }
11155        break;
11156    case OPC_RSQRT1_PS:
11157        check_ps(ctx);
11158        {
11159            TCGv_i64 fp0 = tcg_temp_new_i64();
11160
11161            gen_load_fpr64(ctx, fp0, fs);
11162            gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
11163            gen_store_fpr64(ctx, fp0, fd);
11164            tcg_temp_free_i64(fp0);
11165        }
11166        break;
11167    case OPC_RSQRT2_PS:
11168        check_ps(ctx);
11169        {
11170            TCGv_i64 fp0 = tcg_temp_new_i64();
11171            TCGv_i64 fp1 = tcg_temp_new_i64();
11172
11173            gen_load_fpr64(ctx, fp0, fs);
11174            gen_load_fpr64(ctx, fp1, ft);
11175            gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
11176            tcg_temp_free_i64(fp1);
11177            gen_store_fpr64(ctx, fp0, fd);
11178            tcg_temp_free_i64(fp0);
11179        }
11180        break;
11181    case OPC_CVT_S_PU:
11182        check_cp1_64bitmode(ctx);
11183        {
11184            TCGv_i32 fp0 = tcg_temp_new_i32();
11185
11186            gen_load_fpr32h(ctx, fp0, fs);
11187            gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
11188            gen_store_fpr32(ctx, fp0, fd);
11189            tcg_temp_free_i32(fp0);
11190        }
11191        break;
11192    case OPC_CVT_PW_PS:
11193        check_ps(ctx);
11194        {
11195            TCGv_i64 fp0 = tcg_temp_new_i64();
11196
11197            gen_load_fpr64(ctx, fp0, fs);
11198            gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
11199            gen_store_fpr64(ctx, fp0, fd);
11200            tcg_temp_free_i64(fp0);
11201        }
11202        break;
11203    case OPC_CVT_S_PL:
11204        check_cp1_64bitmode(ctx);
11205        {
11206            TCGv_i32 fp0 = tcg_temp_new_i32();
11207
11208            gen_load_fpr32(ctx, fp0, fs);
11209            gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
11210            gen_store_fpr32(ctx, fp0, fd);
11211            tcg_temp_free_i32(fp0);
11212        }
11213        break;
11214    case OPC_PLL_PS:
11215        check_ps(ctx);
11216        {
11217            TCGv_i32 fp0 = tcg_temp_new_i32();
11218            TCGv_i32 fp1 = tcg_temp_new_i32();
11219
11220            gen_load_fpr32(ctx, fp0, fs);
11221            gen_load_fpr32(ctx, fp1, ft);
11222            gen_store_fpr32h(ctx, fp0, fd);
11223            gen_store_fpr32(ctx, fp1, fd);
11224            tcg_temp_free_i32(fp0);
11225            tcg_temp_free_i32(fp1);
11226        }
11227        break;
11228    case OPC_PLU_PS:
11229        check_ps(ctx);
11230        {
11231            TCGv_i32 fp0 = tcg_temp_new_i32();
11232            TCGv_i32 fp1 = tcg_temp_new_i32();
11233
11234            gen_load_fpr32(ctx, fp0, fs);
11235            gen_load_fpr32h(ctx, fp1, ft);
11236            gen_store_fpr32(ctx, fp1, fd);
11237            gen_store_fpr32h(ctx, fp0, fd);
11238            tcg_temp_free_i32(fp0);
11239            tcg_temp_free_i32(fp1);
11240        }
11241        break;
11242    case OPC_PUL_PS:
11243        check_ps(ctx);
11244        {
11245            TCGv_i32 fp0 = tcg_temp_new_i32();
11246            TCGv_i32 fp1 = tcg_temp_new_i32();
11247
11248            gen_load_fpr32h(ctx, fp0, fs);
11249            gen_load_fpr32(ctx, fp1, ft);
11250            gen_store_fpr32(ctx, fp1, fd);
11251            gen_store_fpr32h(ctx, fp0, fd);
11252            tcg_temp_free_i32(fp0);
11253            tcg_temp_free_i32(fp1);
11254        }
11255        break;
11256    case OPC_PUU_PS:
11257        check_ps(ctx);
11258        {
11259            TCGv_i32 fp0 = tcg_temp_new_i32();
11260            TCGv_i32 fp1 = tcg_temp_new_i32();
11261
11262            gen_load_fpr32h(ctx, fp0, fs);
11263            gen_load_fpr32h(ctx, fp1, ft);
11264            gen_store_fpr32(ctx, fp1, fd);
11265            gen_store_fpr32h(ctx, fp0, fd);
11266            tcg_temp_free_i32(fp0);
11267            tcg_temp_free_i32(fp1);
11268        }
11269        break;
11270    case OPC_CMP_F_PS:
11271    case OPC_CMP_UN_PS:
11272    case OPC_CMP_EQ_PS:
11273    case OPC_CMP_UEQ_PS:
11274    case OPC_CMP_OLT_PS:
11275    case OPC_CMP_ULT_PS:
11276    case OPC_CMP_OLE_PS:
11277    case OPC_CMP_ULE_PS:
11278    case OPC_CMP_SF_PS:
11279    case OPC_CMP_NGLE_PS:
11280    case OPC_CMP_SEQ_PS:
11281    case OPC_CMP_NGL_PS:
11282    case OPC_CMP_LT_PS:
11283    case OPC_CMP_NGE_PS:
11284    case OPC_CMP_LE_PS:
11285    case OPC_CMP_NGT_PS:
11286        if (ctx->opcode & (1 << 6)) {
11287            gen_cmpabs_ps(ctx, func - 48, ft, fs, cc);
11288        } else {
11289            gen_cmp_ps(ctx, func - 48, ft, fs, cc);
11290        }
11291        break;
11292    default:
11293        MIPS_INVAL("farith");
11294        gen_reserved_instruction(ctx);
11295        return;
11296    }
11297}
11298
11299/* Coprocessor 3 (FPU) */
11300static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc,
11301                          int fd, int fs, int base, int index)
11302{
11303    TCGv t0 = tcg_temp_new();
11304
11305    if (base == 0) {
11306        gen_load_gpr(t0, index);
11307    } else if (index == 0) {
11308        gen_load_gpr(t0, base);
11309    } else {
11310        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
11311    }
11312    /*
11313     * Don't do NOP if destination is zero: we must perform the actual
11314     * memory access.
11315     */
11316    switch (opc) {
11317    case OPC_LWXC1:
11318        check_cop1x(ctx);
11319        {
11320            TCGv_i32 fp0 = tcg_temp_new_i32();
11321
11322            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
11323            tcg_gen_trunc_tl_i32(fp0, t0);
11324            gen_store_fpr32(ctx, fp0, fd);
11325            tcg_temp_free_i32(fp0);
11326        }
11327        break;
11328    case OPC_LDXC1:
11329        check_cop1x(ctx);
11330        check_cp1_registers(ctx, fd);
11331        {
11332            TCGv_i64 fp0 = tcg_temp_new_i64();
11333            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11334            gen_store_fpr64(ctx, fp0, fd);
11335            tcg_temp_free_i64(fp0);
11336        }
11337        break;
11338    case OPC_LUXC1:
11339        check_cp1_64bitmode(ctx);
11340        tcg_gen_andi_tl(t0, t0, ~0x7);
11341        {
11342            TCGv_i64 fp0 = tcg_temp_new_i64();
11343
11344            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11345            gen_store_fpr64(ctx, fp0, fd);
11346            tcg_temp_free_i64(fp0);
11347        }
11348        break;
11349    case OPC_SWXC1:
11350        check_cop1x(ctx);
11351        {
11352            TCGv_i32 fp0 = tcg_temp_new_i32();
11353            gen_load_fpr32(ctx, fp0, fs);
11354            tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
11355            tcg_temp_free_i32(fp0);
11356        }
11357        break;
11358    case OPC_SDXC1:
11359        check_cop1x(ctx);
11360        check_cp1_registers(ctx, fs);
11361        {
11362            TCGv_i64 fp0 = tcg_temp_new_i64();
11363            gen_load_fpr64(ctx, fp0, fs);
11364            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11365            tcg_temp_free_i64(fp0);
11366        }
11367        break;
11368    case OPC_SUXC1:
11369        check_cp1_64bitmode(ctx);
11370        tcg_gen_andi_tl(t0, t0, ~0x7);
11371        {
11372            TCGv_i64 fp0 = tcg_temp_new_i64();
11373            gen_load_fpr64(ctx, fp0, fs);
11374            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11375            tcg_temp_free_i64(fp0);
11376        }
11377        break;
11378    }
11379    tcg_temp_free(t0);
11380}
11381
11382static void gen_flt3_arith(DisasContext *ctx, uint32_t opc,
11383                           int fd, int fr, int fs, int ft)
11384{
11385    switch (opc) {
11386    case OPC_ALNV_PS:
11387        check_ps(ctx);
11388        {
11389            TCGv t0 = tcg_temp_local_new();
11390            TCGv_i32 fp = tcg_temp_new_i32();
11391            TCGv_i32 fph = tcg_temp_new_i32();
11392            TCGLabel *l1 = gen_new_label();
11393            TCGLabel *l2 = gen_new_label();
11394
11395            gen_load_gpr(t0, fr);
11396            tcg_gen_andi_tl(t0, t0, 0x7);
11397
11398            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
11399            gen_load_fpr32(ctx, fp, fs);
11400            gen_load_fpr32h(ctx, fph, fs);
11401            gen_store_fpr32(ctx, fp, fd);
11402            gen_store_fpr32h(ctx, fph, fd);
11403            tcg_gen_br(l2);
11404            gen_set_label(l1);
11405            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
11406            tcg_temp_free(t0);
11407            if (cpu_is_bigendian(ctx)) {
11408                gen_load_fpr32(ctx, fp, fs);
11409                gen_load_fpr32h(ctx, fph, ft);
11410                gen_store_fpr32h(ctx, fp, fd);
11411                gen_store_fpr32(ctx, fph, fd);
11412            } else {
11413                gen_load_fpr32h(ctx, fph, fs);
11414                gen_load_fpr32(ctx, fp, ft);
11415                gen_store_fpr32(ctx, fph, fd);
11416                gen_store_fpr32h(ctx, fp, fd);
11417            }
11418            gen_set_label(l2);
11419            tcg_temp_free_i32(fp);
11420            tcg_temp_free_i32(fph);
11421        }
11422        break;
11423    case OPC_MADD_S:
11424        check_cop1x(ctx);
11425        {
11426            TCGv_i32 fp0 = tcg_temp_new_i32();
11427            TCGv_i32 fp1 = tcg_temp_new_i32();
11428            TCGv_i32 fp2 = tcg_temp_new_i32();
11429
11430            gen_load_fpr32(ctx, fp0, fs);
11431            gen_load_fpr32(ctx, fp1, ft);
11432            gen_load_fpr32(ctx, fp2, fr);
11433            gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
11434            tcg_temp_free_i32(fp0);
11435            tcg_temp_free_i32(fp1);
11436            gen_store_fpr32(ctx, fp2, fd);
11437            tcg_temp_free_i32(fp2);
11438        }
11439        break;
11440    case OPC_MADD_D:
11441        check_cop1x(ctx);
11442        check_cp1_registers(ctx, fd | fs | ft | fr);
11443        {
11444            TCGv_i64 fp0 = tcg_temp_new_i64();
11445            TCGv_i64 fp1 = tcg_temp_new_i64();
11446            TCGv_i64 fp2 = tcg_temp_new_i64();
11447
11448            gen_load_fpr64(ctx, fp0, fs);
11449            gen_load_fpr64(ctx, fp1, ft);
11450            gen_load_fpr64(ctx, fp2, fr);
11451            gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
11452            tcg_temp_free_i64(fp0);
11453            tcg_temp_free_i64(fp1);
11454            gen_store_fpr64(ctx, fp2, fd);
11455            tcg_temp_free_i64(fp2);
11456        }
11457        break;
11458    case OPC_MADD_PS:
11459        check_ps(ctx);
11460        {
11461            TCGv_i64 fp0 = tcg_temp_new_i64();
11462            TCGv_i64 fp1 = tcg_temp_new_i64();
11463            TCGv_i64 fp2 = tcg_temp_new_i64();
11464
11465            gen_load_fpr64(ctx, fp0, fs);
11466            gen_load_fpr64(ctx, fp1, ft);
11467            gen_load_fpr64(ctx, fp2, fr);
11468            gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
11469            tcg_temp_free_i64(fp0);
11470            tcg_temp_free_i64(fp1);
11471            gen_store_fpr64(ctx, fp2, fd);
11472            tcg_temp_free_i64(fp2);
11473        }
11474        break;
11475    case OPC_MSUB_S:
11476        check_cop1x(ctx);
11477        {
11478            TCGv_i32 fp0 = tcg_temp_new_i32();
11479            TCGv_i32 fp1 = tcg_temp_new_i32();
11480            TCGv_i32 fp2 = tcg_temp_new_i32();
11481
11482            gen_load_fpr32(ctx, fp0, fs);
11483            gen_load_fpr32(ctx, fp1, ft);
11484            gen_load_fpr32(ctx, fp2, fr);
11485            gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
11486            tcg_temp_free_i32(fp0);
11487            tcg_temp_free_i32(fp1);
11488            gen_store_fpr32(ctx, fp2, fd);
11489            tcg_temp_free_i32(fp2);
11490        }
11491        break;
11492    case OPC_MSUB_D:
11493        check_cop1x(ctx);
11494        check_cp1_registers(ctx, fd | fs | ft | fr);
11495        {
11496            TCGv_i64 fp0 = tcg_temp_new_i64();
11497            TCGv_i64 fp1 = tcg_temp_new_i64();
11498            TCGv_i64 fp2 = tcg_temp_new_i64();
11499
11500            gen_load_fpr64(ctx, fp0, fs);
11501            gen_load_fpr64(ctx, fp1, ft);
11502            gen_load_fpr64(ctx, fp2, fr);
11503            gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
11504            tcg_temp_free_i64(fp0);
11505            tcg_temp_free_i64(fp1);
11506            gen_store_fpr64(ctx, fp2, fd);
11507            tcg_temp_free_i64(fp2);
11508        }
11509        break;
11510    case OPC_MSUB_PS:
11511        check_ps(ctx);
11512        {
11513            TCGv_i64 fp0 = tcg_temp_new_i64();
11514            TCGv_i64 fp1 = tcg_temp_new_i64();
11515            TCGv_i64 fp2 = tcg_temp_new_i64();
11516
11517            gen_load_fpr64(ctx, fp0, fs);
11518            gen_load_fpr64(ctx, fp1, ft);
11519            gen_load_fpr64(ctx, fp2, fr);
11520            gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
11521            tcg_temp_free_i64(fp0);
11522            tcg_temp_free_i64(fp1);
11523            gen_store_fpr64(ctx, fp2, fd);
11524            tcg_temp_free_i64(fp2);
11525        }
11526        break;
11527    case OPC_NMADD_S:
11528        check_cop1x(ctx);
11529        {
11530            TCGv_i32 fp0 = tcg_temp_new_i32();
11531            TCGv_i32 fp1 = tcg_temp_new_i32();
11532            TCGv_i32 fp2 = tcg_temp_new_i32();
11533
11534            gen_load_fpr32(ctx, fp0, fs);
11535            gen_load_fpr32(ctx, fp1, ft);
11536            gen_load_fpr32(ctx, fp2, fr);
11537            gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
11538            tcg_temp_free_i32(fp0);
11539            tcg_temp_free_i32(fp1);
11540            gen_store_fpr32(ctx, fp2, fd);
11541            tcg_temp_free_i32(fp2);
11542        }
11543        break;
11544    case OPC_NMADD_D:
11545        check_cop1x(ctx);
11546        check_cp1_registers(ctx, fd | fs | ft | fr);
11547        {
11548            TCGv_i64 fp0 = tcg_temp_new_i64();
11549            TCGv_i64 fp1 = tcg_temp_new_i64();
11550            TCGv_i64 fp2 = tcg_temp_new_i64();
11551
11552            gen_load_fpr64(ctx, fp0, fs);
11553            gen_load_fpr64(ctx, fp1, ft);
11554            gen_load_fpr64(ctx, fp2, fr);
11555            gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
11556            tcg_temp_free_i64(fp0);
11557            tcg_temp_free_i64(fp1);
11558            gen_store_fpr64(ctx, fp2, fd);
11559            tcg_temp_free_i64(fp2);
11560        }
11561        break;
11562    case OPC_NMADD_PS:
11563        check_ps(ctx);
11564        {
11565            TCGv_i64 fp0 = tcg_temp_new_i64();
11566            TCGv_i64 fp1 = tcg_temp_new_i64();
11567            TCGv_i64 fp2 = tcg_temp_new_i64();
11568
11569            gen_load_fpr64(ctx, fp0, fs);
11570            gen_load_fpr64(ctx, fp1, ft);
11571            gen_load_fpr64(ctx, fp2, fr);
11572            gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
11573            tcg_temp_free_i64(fp0);
11574            tcg_temp_free_i64(fp1);
11575            gen_store_fpr64(ctx, fp2, fd);
11576            tcg_temp_free_i64(fp2);
11577        }
11578        break;
11579    case OPC_NMSUB_S:
11580        check_cop1x(ctx);
11581        {
11582            TCGv_i32 fp0 = tcg_temp_new_i32();
11583            TCGv_i32 fp1 = tcg_temp_new_i32();
11584            TCGv_i32 fp2 = tcg_temp_new_i32();
11585
11586            gen_load_fpr32(ctx, fp0, fs);
11587            gen_load_fpr32(ctx, fp1, ft);
11588            gen_load_fpr32(ctx, fp2, fr);
11589            gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
11590            tcg_temp_free_i32(fp0);
11591            tcg_temp_free_i32(fp1);
11592            gen_store_fpr32(ctx, fp2, fd);
11593            tcg_temp_free_i32(fp2);
11594        }
11595        break;
11596    case OPC_NMSUB_D:
11597        check_cop1x(ctx);
11598        check_cp1_registers(ctx, fd | fs | ft | fr);
11599        {
11600            TCGv_i64 fp0 = tcg_temp_new_i64();
11601            TCGv_i64 fp1 = tcg_temp_new_i64();
11602            TCGv_i64 fp2 = tcg_temp_new_i64();
11603
11604            gen_load_fpr64(ctx, fp0, fs);
11605            gen_load_fpr64(ctx, fp1, ft);
11606            gen_load_fpr64(ctx, fp2, fr);
11607            gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
11608            tcg_temp_free_i64(fp0);
11609            tcg_temp_free_i64(fp1);
11610            gen_store_fpr64(ctx, fp2, fd);
11611            tcg_temp_free_i64(fp2);
11612        }
11613        break;
11614    case OPC_NMSUB_PS:
11615        check_ps(ctx);
11616        {
11617            TCGv_i64 fp0 = tcg_temp_new_i64();
11618            TCGv_i64 fp1 = tcg_temp_new_i64();
11619            TCGv_i64 fp2 = tcg_temp_new_i64();
11620
11621            gen_load_fpr64(ctx, fp0, fs);
11622            gen_load_fpr64(ctx, fp1, ft);
11623            gen_load_fpr64(ctx, fp2, fr);
11624            gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
11625            tcg_temp_free_i64(fp0);
11626            tcg_temp_free_i64(fp1);
11627            gen_store_fpr64(ctx, fp2, fd);
11628            tcg_temp_free_i64(fp2);
11629        }
11630        break;
11631    default:
11632        MIPS_INVAL("flt3_arith");
11633        gen_reserved_instruction(ctx);
11634        return;
11635    }
11636}
11637
11638void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
11639{
11640    TCGv t0;
11641
11642#if !defined(CONFIG_USER_ONLY)
11643    /*
11644     * The Linux kernel will emulate rdhwr if it's not supported natively.
11645     * Therefore only check the ISA in system mode.
11646     */
11647    check_insn(ctx, ISA_MIPS_R2);
11648#endif
11649    t0 = tcg_temp_new();
11650
11651    switch (rd) {
11652    case 0:
11653        gen_helper_rdhwr_cpunum(t0, cpu_env);
11654        gen_store_gpr(t0, rt);
11655        break;
11656    case 1:
11657        gen_helper_rdhwr_synci_step(t0, cpu_env);
11658        gen_store_gpr(t0, rt);
11659        break;
11660    case 2:
11661        if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
11662            gen_io_start();
11663        }
11664        gen_helper_rdhwr_cc(t0, cpu_env);
11665        gen_store_gpr(t0, rt);
11666        /*
11667         * Break the TB to be able to take timer interrupts immediately
11668         * after reading count. DISAS_STOP isn't sufficient, we need to ensure
11669         * we break completely out of translated code.
11670         */
11671        gen_save_pc(ctx->base.pc_next + 4);
11672        ctx->base.is_jmp = DISAS_EXIT;
11673        break;
11674    case 3:
11675        gen_helper_rdhwr_ccres(t0, cpu_env);
11676        gen_store_gpr(t0, rt);
11677        break;
11678    case 4:
11679        check_insn(ctx, ISA_MIPS_R6);
11680        if (sel != 0) {
11681            /*
11682             * Performance counter registers are not implemented other than
11683             * control register 0.
11684             */
11685            generate_exception(ctx, EXCP_RI);
11686        }
11687        gen_helper_rdhwr_performance(t0, cpu_env);
11688        gen_store_gpr(t0, rt);
11689        break;
11690    case 5:
11691        check_insn(ctx, ISA_MIPS_R6);
11692        gen_helper_rdhwr_xnp(t0, cpu_env);
11693        gen_store_gpr(t0, rt);
11694        break;
11695    case 29:
11696#if defined(CONFIG_USER_ONLY)
11697        tcg_gen_ld_tl(t0, cpu_env,
11698                      offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11699        gen_store_gpr(t0, rt);
11700        break;
11701#else
11702        if ((ctx->hflags & MIPS_HFLAG_CP0) ||
11703            (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
11704            tcg_gen_ld_tl(t0, cpu_env,
11705                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
11706            gen_store_gpr(t0, rt);
11707        } else {
11708            gen_reserved_instruction(ctx);
11709        }
11710        break;
11711#endif
11712    default:            /* Invalid */
11713        MIPS_INVAL("rdhwr");
11714        gen_reserved_instruction(ctx);
11715        break;
11716    }
11717    tcg_temp_free(t0);
11718}
11719
11720static inline void clear_branch_hflags(DisasContext *ctx)
11721{
11722    ctx->hflags &= ~MIPS_HFLAG_BMASK;
11723    if (ctx->base.is_jmp == DISAS_NEXT) {
11724        save_cpu_state(ctx, 0);
11725    } else {
11726        /*
11727         * It is not safe to save ctx->hflags as hflags may be changed
11728         * in execution time by the instruction in delay / forbidden slot.
11729         */
11730        tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
11731    }
11732}
11733
11734static void gen_branch(DisasContext *ctx, int insn_bytes)
11735{
11736    if (ctx->hflags & MIPS_HFLAG_BMASK) {
11737        int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
11738        /* Branches completion */
11739        clear_branch_hflags(ctx);
11740        ctx->base.is_jmp = DISAS_NORETURN;
11741        /* FIXME: Need to clear can_do_io.  */
11742        switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
11743        case MIPS_HFLAG_FBNSLOT:
11744            gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
11745            break;
11746        case MIPS_HFLAG_B:
11747            /* unconditional branch */
11748            if (proc_hflags & MIPS_HFLAG_BX) {
11749                tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
11750            }
11751            gen_goto_tb(ctx, 0, ctx->btarget);
11752            break;
11753        case MIPS_HFLAG_BL:
11754            /* blikely taken case */
11755            gen_goto_tb(ctx, 0, ctx->btarget);
11756            break;
11757        case MIPS_HFLAG_BC:
11758            /* Conditional branch */
11759            {
11760                TCGLabel *l1 = gen_new_label();
11761
11762                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
11763                gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
11764                gen_set_label(l1);
11765                gen_goto_tb(ctx, 0, ctx->btarget);
11766            }
11767            break;
11768        case MIPS_HFLAG_BR:
11769            /* unconditional branch to register */
11770            if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
11771                TCGv t0 = tcg_temp_new();
11772                TCGv_i32 t1 = tcg_temp_new_i32();
11773
11774                tcg_gen_andi_tl(t0, btarget, 0x1);
11775                tcg_gen_trunc_tl_i32(t1, t0);
11776                tcg_temp_free(t0);
11777                tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
11778                tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
11779                tcg_gen_or_i32(hflags, hflags, t1);
11780                tcg_temp_free_i32(t1);
11781
11782                tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
11783            } else {
11784                tcg_gen_mov_tl(cpu_PC, btarget);
11785            }
11786            tcg_gen_lookup_and_goto_ptr();
11787            break;
11788        default:
11789            LOG_DISAS("unknown branch 0x%x\n", proc_hflags);
11790            gen_reserved_instruction(ctx);
11791        }
11792    }
11793}
11794
11795/* Compact Branches */
11796static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
11797                                       int rs, int rt, int32_t offset)
11798{
11799    int bcond_compute = 0;
11800    TCGv t0 = tcg_temp_new();
11801    TCGv t1 = tcg_temp_new();
11802    int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
11803
11804    if (ctx->hflags & MIPS_HFLAG_BMASK) {
11805#ifdef MIPS_DEBUG_DISAS
11806        LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
11807                  "\n", ctx->base.pc_next);
11808#endif
11809        gen_reserved_instruction(ctx);
11810        goto out;
11811    }
11812
11813    /* Load needed operands and calculate btarget */
11814    switch (opc) {
11815    /* compact branch */
11816    case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11817    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11818        gen_load_gpr(t0, rs);
11819        gen_load_gpr(t1, rt);
11820        bcond_compute = 1;
11821        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11822        if (rs <= rt && rs == 0) {
11823            /* OPC_BEQZALC, OPC_BNEZALC */
11824            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11825        }
11826        break;
11827    case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11828    case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11829        gen_load_gpr(t0, rs);
11830        gen_load_gpr(t1, rt);
11831        bcond_compute = 1;
11832        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11833        break;
11834    case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11835    case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11836        if (rs == 0 || rs == rt) {
11837            /* OPC_BLEZALC, OPC_BGEZALC */
11838            /* OPC_BGTZALC, OPC_BLTZALC */
11839            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11840        }
11841        gen_load_gpr(t0, rs);
11842        gen_load_gpr(t1, rt);
11843        bcond_compute = 1;
11844        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11845        break;
11846    case OPC_BC:
11847    case OPC_BALC:
11848        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11849        break;
11850    case OPC_BEQZC:
11851    case OPC_BNEZC:
11852        if (rs != 0) {
11853            /* OPC_BEQZC, OPC_BNEZC */
11854            gen_load_gpr(t0, rs);
11855            bcond_compute = 1;
11856            ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
11857        } else {
11858            /* OPC_JIC, OPC_JIALC */
11859            TCGv tbase = tcg_temp_new();
11860            TCGv toffset = tcg_constant_tl(offset);
11861
11862            gen_load_gpr(tbase, rt);
11863            gen_op_addr_add(ctx, btarget, tbase, toffset);
11864            tcg_temp_free(tbase);
11865        }
11866        break;
11867    default:
11868        MIPS_INVAL("Compact branch/jump");
11869        gen_reserved_instruction(ctx);
11870        goto out;
11871    }
11872
11873    if (bcond_compute == 0) {
11874        /* Unconditional compact branch */
11875        switch (opc) {
11876        case OPC_JIALC:
11877            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11878            /* Fallthrough */
11879        case OPC_JIC:
11880            ctx->hflags |= MIPS_HFLAG_BR;
11881            break;
11882        case OPC_BALC:
11883            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
11884            /* Fallthrough */
11885        case OPC_BC:
11886            ctx->hflags |= MIPS_HFLAG_B;
11887            break;
11888        default:
11889            MIPS_INVAL("Compact branch/jump");
11890            gen_reserved_instruction(ctx);
11891            goto out;
11892        }
11893
11894        /* Generating branch here as compact branches don't have delay slot */
11895        gen_branch(ctx, 4);
11896    } else {
11897        /* Conditional compact branch */
11898        TCGLabel *fs = gen_new_label();
11899        save_cpu_state(ctx, 0);
11900
11901        switch (opc) {
11902        case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
11903            if (rs == 0 && rt != 0) {
11904                /* OPC_BLEZALC */
11905                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
11906            } else if (rs != 0 && rt != 0 && rs == rt) {
11907                /* OPC_BGEZALC */
11908                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11909            } else {
11910                /* OPC_BGEUC */
11911                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
11912            }
11913            break;
11914        case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
11915            if (rs == 0 && rt != 0) {
11916                /* OPC_BGTZALC */
11917                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
11918            } else if (rs != 0 && rt != 0 && rs == rt) {
11919                /* OPC_BLTZALC */
11920                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11921            } else {
11922                /* OPC_BLTUC */
11923                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
11924            }
11925            break;
11926        case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
11927            if (rs == 0 && rt != 0) {
11928                /* OPC_BLEZC */
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_BGEZC */
11932                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
11933            } else {
11934                /* OPC_BGEC */
11935                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
11936            }
11937            break;
11938        case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
11939            if (rs == 0 && rt != 0) {
11940                /* OPC_BGTZC */
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_BLTZC */
11944                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
11945            } else {
11946                /* OPC_BLTC */
11947                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
11948            }
11949            break;
11950        case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
11951        case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
11952            if (rs >= rt) {
11953                /* OPC_BOVC, OPC_BNVC */
11954                TCGv t2 = tcg_temp_new();
11955                TCGv t3 = tcg_temp_new();
11956                TCGv t4 = tcg_temp_new();
11957                TCGv input_overflow = tcg_temp_new();
11958
11959                gen_load_gpr(t0, rs);
11960                gen_load_gpr(t1, rt);
11961                tcg_gen_ext32s_tl(t2, t0);
11962                tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
11963                tcg_gen_ext32s_tl(t3, t1);
11964                tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
11965                tcg_gen_or_tl(input_overflow, input_overflow, t4);
11966
11967                tcg_gen_add_tl(t4, t2, t3);
11968                tcg_gen_ext32s_tl(t4, t4);
11969                tcg_gen_xor_tl(t2, t2, t3);
11970                tcg_gen_xor_tl(t3, t4, t3);
11971                tcg_gen_andc_tl(t2, t3, t2);
11972                tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
11973                tcg_gen_or_tl(t4, t4, input_overflow);
11974                if (opc == OPC_BOVC) {
11975                    /* OPC_BOVC */
11976                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
11977                } else {
11978                    /* OPC_BNVC */
11979                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
11980                }
11981                tcg_temp_free(input_overflow);
11982                tcg_temp_free(t4);
11983                tcg_temp_free(t3);
11984                tcg_temp_free(t2);
11985            } else if (rs < rt && rs == 0) {
11986                /* OPC_BEQZALC, OPC_BNEZALC */
11987                if (opc == OPC_BEQZALC) {
11988                    /* OPC_BEQZALC */
11989                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
11990                } else {
11991                    /* OPC_BNEZALC */
11992                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
11993                }
11994            } else {
11995                /* OPC_BEQC, OPC_BNEC */
11996                if (opc == OPC_BEQC) {
11997                    /* OPC_BEQC */
11998                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
11999                } else {
12000                    /* OPC_BNEC */
12001                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
12002                }
12003            }
12004            break;
12005        case OPC_BEQZC:
12006            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
12007            break;
12008        case OPC_BNEZC:
12009            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
12010            break;
12011        default:
12012            MIPS_INVAL("Compact conditional branch/jump");
12013            gen_reserved_instruction(ctx);
12014            goto out;
12015        }
12016
12017        /* Generating branch here as compact branches don't have delay slot */
12018        gen_goto_tb(ctx, 1, ctx->btarget);
12019        gen_set_label(fs);
12020
12021        ctx->hflags |= MIPS_HFLAG_FBNSLOT;
12022    }
12023
12024out:
12025    tcg_temp_free(t0);
12026    tcg_temp_free(t1);
12027}
12028
12029void gen_addiupc(DisasContext *ctx, int rx, int imm,
12030                 int is_64_bit, int extended)
12031{
12032    TCGv t0;
12033
12034    if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
12035        gen_reserved_instruction(ctx);
12036        return;
12037    }
12038
12039    t0 = tcg_temp_new();
12040
12041    tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
12042    tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
12043    if (!is_64_bit) {
12044        tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12045    }
12046
12047    tcg_temp_free(t0);
12048}
12049
12050static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
12051                                int16_t offset)
12052{
12053    TCGv_i32 t0 = tcg_const_i32(op);
12054    TCGv t1 = tcg_temp_new();
12055    gen_base_offset_addr(ctx, t1, base, offset);
12056    gen_helper_cache(cpu_env, t1, t0);
12057    tcg_temp_free(t1);
12058    tcg_temp_free_i32(t0);
12059}
12060
12061static inline bool is_uhi(int sdbbp_code)
12062{
12063#ifdef CONFIG_USER_ONLY
12064    return false;
12065#else
12066    return semihosting_enabled() && sdbbp_code == 1;
12067#endif
12068}
12069
12070#ifdef CONFIG_USER_ONLY
12071/* The above should dead-code away any calls to this..*/
12072static inline void gen_helper_do_semihosting(void *env)
12073{
12074    g_assert_not_reached();
12075}
12076#endif
12077
12078void gen_ldxs(DisasContext *ctx, int base, int index, int rd)
12079{
12080    TCGv t0 = tcg_temp_new();
12081    TCGv t1 = tcg_temp_new();
12082
12083    gen_load_gpr(t0, base);
12084
12085    if (index != 0) {
12086        gen_load_gpr(t1, index);
12087        tcg_gen_shli_tl(t1, t1, 2);
12088        gen_op_addr_add(ctx, t0, t1, t0);
12089    }
12090
12091    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
12092    gen_store_gpr(t1, rd);
12093
12094    tcg_temp_free(t0);
12095    tcg_temp_free(t1);
12096}
12097
12098static void gen_sync(int stype)
12099{
12100    TCGBar tcg_mo = TCG_BAR_SC;
12101
12102    switch (stype) {
12103    case 0x4: /* SYNC_WMB */
12104        tcg_mo |= TCG_MO_ST_ST;
12105        break;
12106    case 0x10: /* SYNC_MB */
12107        tcg_mo |= TCG_MO_ALL;
12108        break;
12109    case 0x11: /* SYNC_ACQUIRE */
12110        tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
12111        break;
12112    case 0x12: /* SYNC_RELEASE */
12113        tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
12114        break;
12115    case 0x13: /* SYNC_RMB */
12116        tcg_mo |= TCG_MO_LD_LD;
12117        break;
12118    default:
12119        tcg_mo |= TCG_MO_ALL;
12120        break;
12121    }
12122
12123    tcg_gen_mb(tcg_mo);
12124}
12125
12126/* ISA extensions (ASEs) */
12127
12128/* MIPS16 extension to MIPS32 */
12129#include "mips16e_translate.c.inc"
12130
12131/* microMIPS extension to MIPS32/MIPS64 */
12132
12133/*
12134 * Values for microMIPS fmt field.  Variable-width, depending on which
12135 * formats the instruction supports.
12136 */
12137enum {
12138    FMT_SD_S = 0,
12139    FMT_SD_D = 1,
12140
12141    FMT_SDPS_S = 0,
12142    FMT_SDPS_D = 1,
12143    FMT_SDPS_PS = 2,
12144
12145    FMT_SWL_S = 0,
12146    FMT_SWL_W = 1,
12147    FMT_SWL_L = 2,
12148
12149    FMT_DWL_D = 0,
12150    FMT_DWL_W = 1,
12151    FMT_DWL_L = 2
12152};
12153
12154#include "micromips_translate.c.inc"
12155
12156#include "nanomips_translate.c.inc"
12157
12158/* MIPSDSP functions. */
12159static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
12160                           int rd, int base, int offset)
12161{
12162    TCGv t0;
12163
12164    check_dsp(ctx);
12165    t0 = tcg_temp_new();
12166
12167    if (base == 0) {
12168        gen_load_gpr(t0, offset);
12169    } else if (offset == 0) {
12170        gen_load_gpr(t0, base);
12171    } else {
12172        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12173    }
12174
12175    switch (opc) {
12176    case OPC_LBUX:
12177        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
12178        gen_store_gpr(t0, rd);
12179        break;
12180    case OPC_LHX:
12181        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
12182        gen_store_gpr(t0, rd);
12183        break;
12184    case OPC_LWX:
12185        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
12186        gen_store_gpr(t0, rd);
12187        break;
12188#if defined(TARGET_MIPS64)
12189    case OPC_LDX:
12190        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
12191        gen_store_gpr(t0, rd);
12192        break;
12193#endif
12194    }
12195    tcg_temp_free(t0);
12196}
12197
12198static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12199                              int ret, int v1, int v2)
12200{
12201    TCGv v1_t;
12202    TCGv v2_t;
12203
12204    if (ret == 0) {
12205        /* Treat as NOP. */
12206        return;
12207    }
12208
12209    v1_t = tcg_temp_new();
12210    v2_t = tcg_temp_new();
12211
12212    gen_load_gpr(v1_t, v1);
12213    gen_load_gpr(v2_t, v2);
12214
12215    switch (op1) {
12216    /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12217    case OPC_MULT_G_2E:
12218        check_dsp_r2(ctx);
12219        switch (op2) {
12220        case OPC_ADDUH_QB:
12221            gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12222            break;
12223        case OPC_ADDUH_R_QB:
12224            gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12225            break;
12226        case OPC_ADDQH_PH:
12227            gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12228            break;
12229        case OPC_ADDQH_R_PH:
12230            gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12231            break;
12232        case OPC_ADDQH_W:
12233            gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12234            break;
12235        case OPC_ADDQH_R_W:
12236            gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12237            break;
12238        case OPC_SUBUH_QB:
12239            gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12240            break;
12241        case OPC_SUBUH_R_QB:
12242            gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12243            break;
12244        case OPC_SUBQH_PH:
12245            gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12246            break;
12247        case OPC_SUBQH_R_PH:
12248            gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12249            break;
12250        case OPC_SUBQH_W:
12251            gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12252            break;
12253        case OPC_SUBQH_R_W:
12254            gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12255            break;
12256        }
12257        break;
12258    case OPC_ABSQ_S_PH_DSP:
12259        switch (op2) {
12260        case OPC_ABSQ_S_QB:
12261            check_dsp_r2(ctx);
12262            gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12263            break;
12264        case OPC_ABSQ_S_PH:
12265            check_dsp(ctx);
12266            gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12267            break;
12268        case OPC_ABSQ_S_W:
12269            check_dsp(ctx);
12270            gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12271            break;
12272        case OPC_PRECEQ_W_PHL:
12273            check_dsp(ctx);
12274            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12275            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12276            break;
12277        case OPC_PRECEQ_W_PHR:
12278            check_dsp(ctx);
12279            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12280            tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12281            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12282            break;
12283        case OPC_PRECEQU_PH_QBL:
12284            check_dsp(ctx);
12285            gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12286            break;
12287        case OPC_PRECEQU_PH_QBR:
12288            check_dsp(ctx);
12289            gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12290            break;
12291        case OPC_PRECEQU_PH_QBLA:
12292            check_dsp(ctx);
12293            gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12294            break;
12295        case OPC_PRECEQU_PH_QBRA:
12296            check_dsp(ctx);
12297            gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12298            break;
12299        case OPC_PRECEU_PH_QBL:
12300            check_dsp(ctx);
12301            gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12302            break;
12303        case OPC_PRECEU_PH_QBR:
12304            check_dsp(ctx);
12305            gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12306            break;
12307        case OPC_PRECEU_PH_QBLA:
12308            check_dsp(ctx);
12309            gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12310            break;
12311        case OPC_PRECEU_PH_QBRA:
12312            check_dsp(ctx);
12313            gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12314            break;
12315        }
12316        break;
12317    case OPC_ADDU_QB_DSP:
12318        switch (op2) {
12319        case OPC_ADDQ_PH:
12320            check_dsp(ctx);
12321            gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12322            break;
12323        case OPC_ADDQ_S_PH:
12324            check_dsp(ctx);
12325            gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12326            break;
12327        case OPC_ADDQ_S_W:
12328            check_dsp(ctx);
12329            gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12330            break;
12331        case OPC_ADDU_QB:
12332            check_dsp(ctx);
12333            gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12334            break;
12335        case OPC_ADDU_S_QB:
12336            check_dsp(ctx);
12337            gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12338            break;
12339        case OPC_ADDU_PH:
12340            check_dsp_r2(ctx);
12341            gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12342            break;
12343        case OPC_ADDU_S_PH:
12344            check_dsp_r2(ctx);
12345            gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12346            break;
12347        case OPC_SUBQ_PH:
12348            check_dsp(ctx);
12349            gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12350            break;
12351        case OPC_SUBQ_S_PH:
12352            check_dsp(ctx);
12353            gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12354            break;
12355        case OPC_SUBQ_S_W:
12356            check_dsp(ctx);
12357            gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12358            break;
12359        case OPC_SUBU_QB:
12360            check_dsp(ctx);
12361            gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12362            break;
12363        case OPC_SUBU_S_QB:
12364            check_dsp(ctx);
12365            gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12366            break;
12367        case OPC_SUBU_PH:
12368            check_dsp_r2(ctx);
12369            gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12370            break;
12371        case OPC_SUBU_S_PH:
12372            check_dsp_r2(ctx);
12373            gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12374            break;
12375        case OPC_ADDSC:
12376            check_dsp(ctx);
12377            gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12378            break;
12379        case OPC_ADDWC:
12380            check_dsp(ctx);
12381            gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12382            break;
12383        case OPC_MODSUB:
12384            check_dsp(ctx);
12385            gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12386            break;
12387        case OPC_RADDU_W_QB:
12388            check_dsp(ctx);
12389            gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12390            break;
12391        }
12392        break;
12393    case OPC_CMPU_EQ_QB_DSP:
12394        switch (op2) {
12395        case OPC_PRECR_QB_PH:
12396            check_dsp_r2(ctx);
12397            gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12398            break;
12399        case OPC_PRECRQ_QB_PH:
12400            check_dsp(ctx);
12401            gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12402            break;
12403        case OPC_PRECR_SRA_PH_W:
12404            check_dsp_r2(ctx);
12405            {
12406                TCGv_i32 sa_t = tcg_const_i32(v2);
12407                gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12408                                          cpu_gpr[ret]);
12409                tcg_temp_free_i32(sa_t);
12410                break;
12411            }
12412        case OPC_PRECR_SRA_R_PH_W:
12413            check_dsp_r2(ctx);
12414            {
12415                TCGv_i32 sa_t = tcg_const_i32(v2);
12416                gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12417                                            cpu_gpr[ret]);
12418                tcg_temp_free_i32(sa_t);
12419                break;
12420            }
12421        case OPC_PRECRQ_PH_W:
12422            check_dsp(ctx);
12423            gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12424            break;
12425        case OPC_PRECRQ_RS_PH_W:
12426            check_dsp(ctx);
12427            gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12428            break;
12429        case OPC_PRECRQU_S_QB_PH:
12430            check_dsp(ctx);
12431            gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12432            break;
12433        }
12434        break;
12435#ifdef TARGET_MIPS64
12436    case OPC_ABSQ_S_QH_DSP:
12437        switch (op2) {
12438        case OPC_PRECEQ_L_PWL:
12439            check_dsp(ctx);
12440            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12441            break;
12442        case OPC_PRECEQ_L_PWR:
12443            check_dsp(ctx);
12444            tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12445            break;
12446        case OPC_PRECEQ_PW_QHL:
12447            check_dsp(ctx);
12448            gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12449            break;
12450        case OPC_PRECEQ_PW_QHR:
12451            check_dsp(ctx);
12452            gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12453            break;
12454        case OPC_PRECEQ_PW_QHLA:
12455            check_dsp(ctx);
12456            gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12457            break;
12458        case OPC_PRECEQ_PW_QHRA:
12459            check_dsp(ctx);
12460            gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12461            break;
12462        case OPC_PRECEQU_QH_OBL:
12463            check_dsp(ctx);
12464            gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12465            break;
12466        case OPC_PRECEQU_QH_OBR:
12467            check_dsp(ctx);
12468            gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12469            break;
12470        case OPC_PRECEQU_QH_OBLA:
12471            check_dsp(ctx);
12472            gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12473            break;
12474        case OPC_PRECEQU_QH_OBRA:
12475            check_dsp(ctx);
12476            gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12477            break;
12478        case OPC_PRECEU_QH_OBL:
12479            check_dsp(ctx);
12480            gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12481            break;
12482        case OPC_PRECEU_QH_OBR:
12483            check_dsp(ctx);
12484            gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12485            break;
12486        case OPC_PRECEU_QH_OBLA:
12487            check_dsp(ctx);
12488            gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
12489            break;
12490        case OPC_PRECEU_QH_OBRA:
12491            check_dsp(ctx);
12492            gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
12493            break;
12494        case OPC_ABSQ_S_OB:
12495            check_dsp_r2(ctx);
12496            gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
12497            break;
12498        case OPC_ABSQ_S_PW:
12499            check_dsp(ctx);
12500            gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
12501            break;
12502        case OPC_ABSQ_S_QH:
12503            check_dsp(ctx);
12504            gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
12505            break;
12506        }
12507        break;
12508    case OPC_ADDU_OB_DSP:
12509        switch (op2) {
12510        case OPC_RADDU_L_OB:
12511            check_dsp(ctx);
12512            gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
12513            break;
12514        case OPC_SUBQ_PW:
12515            check_dsp(ctx);
12516            gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12517            break;
12518        case OPC_SUBQ_S_PW:
12519            check_dsp(ctx);
12520            gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12521            break;
12522        case OPC_SUBQ_QH:
12523            check_dsp(ctx);
12524            gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12525            break;
12526        case OPC_SUBQ_S_QH:
12527            check_dsp(ctx);
12528            gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12529            break;
12530        case OPC_SUBU_OB:
12531            check_dsp(ctx);
12532            gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12533            break;
12534        case OPC_SUBU_S_OB:
12535            check_dsp(ctx);
12536            gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12537            break;
12538        case OPC_SUBU_QH:
12539            check_dsp_r2(ctx);
12540            gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12541            break;
12542        case OPC_SUBU_S_QH:
12543            check_dsp_r2(ctx);
12544            gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12545            break;
12546        case OPC_SUBUH_OB:
12547            check_dsp_r2(ctx);
12548            gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
12549            break;
12550        case OPC_SUBUH_R_OB:
12551            check_dsp_r2(ctx);
12552            gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
12553            break;
12554        case OPC_ADDQ_PW:
12555            check_dsp(ctx);
12556            gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12557            break;
12558        case OPC_ADDQ_S_PW:
12559            check_dsp(ctx);
12560            gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12561            break;
12562        case OPC_ADDQ_QH:
12563            check_dsp(ctx);
12564            gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12565            break;
12566        case OPC_ADDQ_S_QH:
12567            check_dsp(ctx);
12568            gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12569            break;
12570        case OPC_ADDU_OB:
12571            check_dsp(ctx);
12572            gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12573            break;
12574        case OPC_ADDU_S_OB:
12575            check_dsp(ctx);
12576            gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12577            break;
12578        case OPC_ADDU_QH:
12579            check_dsp_r2(ctx);
12580            gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12581            break;
12582        case OPC_ADDU_S_QH:
12583            check_dsp_r2(ctx);
12584            gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12585            break;
12586        case OPC_ADDUH_OB:
12587            check_dsp_r2(ctx);
12588            gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
12589            break;
12590        case OPC_ADDUH_R_OB:
12591            check_dsp_r2(ctx);
12592            gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
12593            break;
12594        }
12595        break;
12596    case OPC_CMPU_EQ_OB_DSP:
12597        switch (op2) {
12598        case OPC_PRECR_OB_QH:
12599            check_dsp_r2(ctx);
12600            gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
12601            break;
12602        case OPC_PRECR_SRA_QH_PW:
12603            check_dsp_r2(ctx);
12604            {
12605                TCGv_i32 ret_t = tcg_const_i32(ret);
12606                gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
12607                tcg_temp_free_i32(ret_t);
12608                break;
12609            }
12610        case OPC_PRECR_SRA_R_QH_PW:
12611            check_dsp_r2(ctx);
12612            {
12613                TCGv_i32 sa_v = tcg_const_i32(ret);
12614                gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
12615                tcg_temp_free_i32(sa_v);
12616                break;
12617            }
12618        case OPC_PRECRQ_OB_QH:
12619            check_dsp(ctx);
12620            gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
12621            break;
12622        case OPC_PRECRQ_PW_L:
12623            check_dsp(ctx);
12624            gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
12625            break;
12626        case OPC_PRECRQ_QH_PW:
12627            check_dsp(ctx);
12628            gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
12629            break;
12630        case OPC_PRECRQ_RS_QH_PW:
12631            check_dsp(ctx);
12632            gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12633            break;
12634        case OPC_PRECRQU_S_OB_QH:
12635            check_dsp(ctx);
12636            gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12637            break;
12638        }
12639        break;
12640#endif
12641    }
12642
12643    tcg_temp_free(v1_t);
12644    tcg_temp_free(v2_t);
12645}
12646
12647static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
12648                              int ret, int v1, int v2)
12649{
12650    uint32_t op2;
12651    TCGv t0;
12652    TCGv v1_t;
12653    TCGv v2_t;
12654
12655    if (ret == 0) {
12656        /* Treat as NOP. */
12657        return;
12658    }
12659
12660    t0 = tcg_temp_new();
12661    v1_t = tcg_temp_new();
12662    v2_t = tcg_temp_new();
12663
12664    tcg_gen_movi_tl(t0, v1);
12665    gen_load_gpr(v1_t, v1);
12666    gen_load_gpr(v2_t, v2);
12667
12668    switch (opc) {
12669    case OPC_SHLL_QB_DSP:
12670        {
12671            op2 = MASK_SHLL_QB(ctx->opcode);
12672            switch (op2) {
12673            case OPC_SHLL_QB:
12674                check_dsp(ctx);
12675                gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
12676                break;
12677            case OPC_SHLLV_QB:
12678                check_dsp(ctx);
12679                gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12680                break;
12681            case OPC_SHLL_PH:
12682                check_dsp(ctx);
12683                gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
12684                break;
12685            case OPC_SHLLV_PH:
12686                check_dsp(ctx);
12687                gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12688                break;
12689            case OPC_SHLL_S_PH:
12690                check_dsp(ctx);
12691                gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
12692                break;
12693            case OPC_SHLLV_S_PH:
12694                check_dsp(ctx);
12695                gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12696                break;
12697            case OPC_SHLL_S_W:
12698                check_dsp(ctx);
12699                gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
12700                break;
12701            case OPC_SHLLV_S_W:
12702                check_dsp(ctx);
12703                gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12704                break;
12705            case OPC_SHRL_QB:
12706                check_dsp(ctx);
12707                gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
12708                break;
12709            case OPC_SHRLV_QB:
12710                check_dsp(ctx);
12711                gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
12712                break;
12713            case OPC_SHRL_PH:
12714                check_dsp_r2(ctx);
12715                gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
12716                break;
12717            case OPC_SHRLV_PH:
12718                check_dsp_r2(ctx);
12719                gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
12720                break;
12721            case OPC_SHRA_QB:
12722                check_dsp_r2(ctx);
12723                gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
12724                break;
12725            case OPC_SHRA_R_QB:
12726                check_dsp_r2(ctx);
12727                gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
12728                break;
12729            case OPC_SHRAV_QB:
12730                check_dsp_r2(ctx);
12731                gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
12732                break;
12733            case OPC_SHRAV_R_QB:
12734                check_dsp_r2(ctx);
12735                gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
12736                break;
12737            case OPC_SHRA_PH:
12738                check_dsp(ctx);
12739                gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
12740                break;
12741            case OPC_SHRA_R_PH:
12742                check_dsp(ctx);
12743                gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
12744                break;
12745            case OPC_SHRAV_PH:
12746                check_dsp(ctx);
12747                gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
12748                break;
12749            case OPC_SHRAV_R_PH:
12750                check_dsp(ctx);
12751                gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
12752                break;
12753            case OPC_SHRA_R_W:
12754                check_dsp(ctx);
12755                gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
12756                break;
12757            case OPC_SHRAV_R_W:
12758                check_dsp(ctx);
12759                gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
12760                break;
12761            default:            /* Invalid */
12762                MIPS_INVAL("MASK SHLL.QB");
12763                gen_reserved_instruction(ctx);
12764                break;
12765            }
12766            break;
12767        }
12768#ifdef TARGET_MIPS64
12769    case OPC_SHLL_OB_DSP:
12770        op2 = MASK_SHLL_OB(ctx->opcode);
12771        switch (op2) {
12772        case OPC_SHLL_PW:
12773            check_dsp(ctx);
12774            gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
12775            break;
12776        case OPC_SHLLV_PW:
12777            check_dsp(ctx);
12778            gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12779            break;
12780        case OPC_SHLL_S_PW:
12781            check_dsp(ctx);
12782            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
12783            break;
12784        case OPC_SHLLV_S_PW:
12785            check_dsp(ctx);
12786            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12787            break;
12788        case OPC_SHLL_OB:
12789            check_dsp(ctx);
12790            gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
12791            break;
12792        case OPC_SHLLV_OB:
12793            check_dsp(ctx);
12794            gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12795            break;
12796        case OPC_SHLL_QH:
12797            check_dsp(ctx);
12798            gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
12799            break;
12800        case OPC_SHLLV_QH:
12801            check_dsp(ctx);
12802            gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12803            break;
12804        case OPC_SHLL_S_QH:
12805            check_dsp(ctx);
12806            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
12807            break;
12808        case OPC_SHLLV_S_QH:
12809            check_dsp(ctx);
12810            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
12811            break;
12812        case OPC_SHRA_OB:
12813            check_dsp_r2(ctx);
12814            gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
12815            break;
12816        case OPC_SHRAV_OB:
12817            check_dsp_r2(ctx);
12818            gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
12819            break;
12820        case OPC_SHRA_R_OB:
12821            check_dsp_r2(ctx);
12822            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
12823            break;
12824        case OPC_SHRAV_R_OB:
12825            check_dsp_r2(ctx);
12826            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
12827            break;
12828        case OPC_SHRA_PW:
12829            check_dsp(ctx);
12830            gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
12831            break;
12832        case OPC_SHRAV_PW:
12833            check_dsp(ctx);
12834            gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
12835            break;
12836        case OPC_SHRA_R_PW:
12837            check_dsp(ctx);
12838            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
12839            break;
12840        case OPC_SHRAV_R_PW:
12841            check_dsp(ctx);
12842            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
12843            break;
12844        case OPC_SHRA_QH:
12845            check_dsp(ctx);
12846            gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
12847            break;
12848        case OPC_SHRAV_QH:
12849            check_dsp(ctx);
12850            gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
12851            break;
12852        case OPC_SHRA_R_QH:
12853            check_dsp(ctx);
12854            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
12855            break;
12856        case OPC_SHRAV_R_QH:
12857            check_dsp(ctx);
12858            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
12859            break;
12860        case OPC_SHRL_OB:
12861            check_dsp(ctx);
12862            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
12863            break;
12864        case OPC_SHRLV_OB:
12865            check_dsp(ctx);
12866            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
12867            break;
12868        case OPC_SHRL_QH:
12869            check_dsp_r2(ctx);
12870            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
12871            break;
12872        case OPC_SHRLV_QH:
12873            check_dsp_r2(ctx);
12874            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
12875            break;
12876        default:            /* Invalid */
12877            MIPS_INVAL("MASK SHLL.OB");
12878            gen_reserved_instruction(ctx);
12879            break;
12880        }
12881        break;
12882#endif
12883    }
12884
12885    tcg_temp_free(t0);
12886    tcg_temp_free(v1_t);
12887    tcg_temp_free(v2_t);
12888}
12889
12890static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
12891                                 int ret, int v1, int v2, int check_ret)
12892{
12893    TCGv_i32 t0;
12894    TCGv v1_t;
12895    TCGv v2_t;
12896
12897    if ((ret == 0) && (check_ret == 1)) {
12898        /* Treat as NOP. */
12899        return;
12900    }
12901
12902    t0 = tcg_temp_new_i32();
12903    v1_t = tcg_temp_new();
12904    v2_t = tcg_temp_new();
12905
12906    tcg_gen_movi_i32(t0, ret);
12907    gen_load_gpr(v1_t, v1);
12908    gen_load_gpr(v2_t, v2);
12909
12910    switch (op1) {
12911    /*
12912     * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
12913     * the same mask and op1.
12914     */
12915    case OPC_MULT_G_2E:
12916        check_dsp_r2(ctx);
12917        switch (op2) {
12918        case  OPC_MUL_PH:
12919            gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12920            break;
12921        case  OPC_MUL_S_PH:
12922            gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12923            break;
12924        case OPC_MULQ_S_W:
12925            gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12926            break;
12927        case OPC_MULQ_RS_W:
12928            gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12929            break;
12930        }
12931        break;
12932    case OPC_DPA_W_PH_DSP:
12933        switch (op2) {
12934        case OPC_DPAU_H_QBL:
12935            check_dsp(ctx);
12936            gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
12937            break;
12938        case OPC_DPAU_H_QBR:
12939            check_dsp(ctx);
12940            gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
12941            break;
12942        case OPC_DPSU_H_QBL:
12943            check_dsp(ctx);
12944            gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
12945            break;
12946        case OPC_DPSU_H_QBR:
12947            check_dsp(ctx);
12948            gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
12949            break;
12950        case OPC_DPA_W_PH:
12951            check_dsp_r2(ctx);
12952            gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
12953            break;
12954        case OPC_DPAX_W_PH:
12955            check_dsp_r2(ctx);
12956            gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
12957            break;
12958        case OPC_DPAQ_S_W_PH:
12959            check_dsp(ctx);
12960            gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
12961            break;
12962        case OPC_DPAQX_S_W_PH:
12963            check_dsp_r2(ctx);
12964            gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
12965            break;
12966        case OPC_DPAQX_SA_W_PH:
12967            check_dsp_r2(ctx);
12968            gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
12969            break;
12970        case OPC_DPS_W_PH:
12971            check_dsp_r2(ctx);
12972            gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
12973            break;
12974        case OPC_DPSX_W_PH:
12975            check_dsp_r2(ctx);
12976            gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
12977            break;
12978        case OPC_DPSQ_S_W_PH:
12979            check_dsp(ctx);
12980            gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
12981            break;
12982        case OPC_DPSQX_S_W_PH:
12983            check_dsp_r2(ctx);
12984            gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
12985            break;
12986        case OPC_DPSQX_SA_W_PH:
12987            check_dsp_r2(ctx);
12988            gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
12989            break;
12990        case OPC_MULSAQ_S_W_PH:
12991            check_dsp(ctx);
12992            gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
12993            break;
12994        case OPC_DPAQ_SA_L_W:
12995            check_dsp(ctx);
12996            gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
12997            break;
12998        case OPC_DPSQ_SA_L_W:
12999            check_dsp(ctx);
13000            gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13001            break;
13002        case OPC_MAQ_S_W_PHL:
13003            check_dsp(ctx);
13004            gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13005            break;
13006        case OPC_MAQ_S_W_PHR:
13007            check_dsp(ctx);
13008            gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13009            break;
13010        case OPC_MAQ_SA_W_PHL:
13011            check_dsp(ctx);
13012            gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13013            break;
13014        case OPC_MAQ_SA_W_PHR:
13015            check_dsp(ctx);
13016            gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13017            break;
13018        case OPC_MULSA_W_PH:
13019            check_dsp_r2(ctx);
13020            gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13021            break;
13022        }
13023        break;
13024#ifdef TARGET_MIPS64
13025    case OPC_DPAQ_W_QH_DSP:
13026        {
13027            int ac = ret & 0x03;
13028            tcg_gen_movi_i32(t0, ac);
13029
13030            switch (op2) {
13031            case OPC_DMADD:
13032                check_dsp(ctx);
13033                gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13034                break;
13035            case OPC_DMADDU:
13036                check_dsp(ctx);
13037                gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13038                break;
13039            case OPC_DMSUB:
13040                check_dsp(ctx);
13041                gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13042                break;
13043            case OPC_DMSUBU:
13044                check_dsp(ctx);
13045                gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13046                break;
13047            case OPC_DPA_W_QH:
13048                check_dsp_r2(ctx);
13049                gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13050                break;
13051            case OPC_DPAQ_S_W_QH:
13052                check_dsp(ctx);
13053                gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13054                break;
13055            case OPC_DPAQ_SA_L_PW:
13056                check_dsp(ctx);
13057                gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13058                break;
13059            case OPC_DPAU_H_OBL:
13060                check_dsp(ctx);
13061                gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13062                break;
13063            case OPC_DPAU_H_OBR:
13064                check_dsp(ctx);
13065                gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13066                break;
13067            case OPC_DPS_W_QH:
13068                check_dsp_r2(ctx);
13069                gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13070                break;
13071            case OPC_DPSQ_S_W_QH:
13072                check_dsp(ctx);
13073                gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13074                break;
13075            case OPC_DPSQ_SA_L_PW:
13076                check_dsp(ctx);
13077                gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13078                break;
13079            case OPC_DPSU_H_OBL:
13080                check_dsp(ctx);
13081                gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13082                break;
13083            case OPC_DPSU_H_OBR:
13084                check_dsp(ctx);
13085                gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13086                break;
13087            case OPC_MAQ_S_L_PWL:
13088                check_dsp(ctx);
13089                gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13090                break;
13091            case OPC_MAQ_S_L_PWR:
13092                check_dsp(ctx);
13093                gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13094                break;
13095            case OPC_MAQ_S_W_QHLL:
13096                check_dsp(ctx);
13097                gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13098                break;
13099            case OPC_MAQ_SA_W_QHLL:
13100                check_dsp(ctx);
13101                gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13102                break;
13103            case OPC_MAQ_S_W_QHLR:
13104                check_dsp(ctx);
13105                gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13106                break;
13107            case OPC_MAQ_SA_W_QHLR:
13108                check_dsp(ctx);
13109                gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13110                break;
13111            case OPC_MAQ_S_W_QHRL:
13112                check_dsp(ctx);
13113                gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13114                break;
13115            case OPC_MAQ_SA_W_QHRL:
13116                check_dsp(ctx);
13117                gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13118                break;
13119            case OPC_MAQ_S_W_QHRR:
13120                check_dsp(ctx);
13121                gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13122                break;
13123            case OPC_MAQ_SA_W_QHRR:
13124                check_dsp(ctx);
13125                gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13126                break;
13127            case OPC_MULSAQ_S_L_PW:
13128                check_dsp(ctx);
13129                gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13130                break;
13131            case OPC_MULSAQ_S_W_QH:
13132                check_dsp(ctx);
13133                gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13134                break;
13135            }
13136        }
13137        break;
13138#endif
13139    case OPC_ADDU_QB_DSP:
13140        switch (op2) {
13141        case OPC_MULEU_S_PH_QBL:
13142            check_dsp(ctx);
13143            gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13144            break;
13145        case OPC_MULEU_S_PH_QBR:
13146            check_dsp(ctx);
13147            gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13148            break;
13149        case OPC_MULQ_RS_PH:
13150            check_dsp(ctx);
13151            gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13152            break;
13153        case OPC_MULEQ_S_W_PHL:
13154            check_dsp(ctx);
13155            gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13156            break;
13157        case OPC_MULEQ_S_W_PHR:
13158            check_dsp(ctx);
13159            gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13160            break;
13161        case OPC_MULQ_S_PH:
13162            check_dsp_r2(ctx);
13163            gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13164            break;
13165        }
13166        break;
13167#ifdef TARGET_MIPS64
13168    case OPC_ADDU_OB_DSP:
13169        switch (op2) {
13170        case OPC_MULEQ_S_PW_QHL:
13171            check_dsp(ctx);
13172            gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13173            break;
13174        case OPC_MULEQ_S_PW_QHR:
13175            check_dsp(ctx);
13176            gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13177            break;
13178        case OPC_MULEU_S_QH_OBL:
13179            check_dsp(ctx);
13180            gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13181            break;
13182        case OPC_MULEU_S_QH_OBR:
13183            check_dsp(ctx);
13184            gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13185            break;
13186        case OPC_MULQ_RS_QH:
13187            check_dsp(ctx);
13188            gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13189            break;
13190        }
13191        break;
13192#endif
13193    }
13194
13195    tcg_temp_free_i32(t0);
13196    tcg_temp_free(v1_t);
13197    tcg_temp_free(v2_t);
13198}
13199
13200static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
13201                                int ret, int val)
13202{
13203    int16_t imm;
13204    TCGv t0;
13205    TCGv val_t;
13206
13207    if (ret == 0) {
13208        /* Treat as NOP. */
13209        return;
13210    }
13211
13212    t0 = tcg_temp_new();
13213    val_t = tcg_temp_new();
13214    gen_load_gpr(val_t, val);
13215
13216    switch (op1) {
13217    case OPC_ABSQ_S_PH_DSP:
13218        switch (op2) {
13219        case OPC_BITREV:
13220            check_dsp(ctx);
13221            gen_helper_bitrev(cpu_gpr[ret], val_t);
13222            break;
13223        case OPC_REPL_QB:
13224            check_dsp(ctx);
13225            {
13226                target_long result;
13227                imm = (ctx->opcode >> 16) & 0xFF;
13228                result = (uint32_t)imm << 24 |
13229                         (uint32_t)imm << 16 |
13230                         (uint32_t)imm << 8  |
13231                         (uint32_t)imm;
13232                result = (int32_t)result;
13233                tcg_gen_movi_tl(cpu_gpr[ret], result);
13234            }
13235            break;
13236        case OPC_REPLV_QB:
13237            check_dsp(ctx);
13238            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13239            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13240            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13241            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13242            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13243            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13244            break;
13245        case OPC_REPL_PH:
13246            check_dsp(ctx);
13247            {
13248                imm = (ctx->opcode >> 16) & 0x03FF;
13249                imm = (int16_t)(imm << 6) >> 6;
13250                tcg_gen_movi_tl(cpu_gpr[ret], \
13251                                (target_long)((int32_t)imm << 16 | \
13252                                (uint16_t)imm));
13253            }
13254            break;
13255        case OPC_REPLV_PH:
13256            check_dsp(ctx);
13257            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13258            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13259            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13260            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13261            break;
13262        }
13263        break;
13264#ifdef TARGET_MIPS64
13265    case OPC_ABSQ_S_QH_DSP:
13266        switch (op2) {
13267        case OPC_REPL_OB:
13268            check_dsp(ctx);
13269            {
13270                target_long temp;
13271
13272                imm = (ctx->opcode >> 16) & 0xFF;
13273                temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13274                temp = (temp << 16) | temp;
13275                temp = (temp << 32) | temp;
13276                tcg_gen_movi_tl(cpu_gpr[ret], temp);
13277                break;
13278            }
13279        case OPC_REPL_PW:
13280            check_dsp(ctx);
13281            {
13282                target_long temp;
13283
13284                imm = (ctx->opcode >> 16) & 0x03FF;
13285                imm = (int16_t)(imm << 6) >> 6;
13286                temp = ((target_long)imm << 32) \
13287                       | ((target_long)imm & 0xFFFFFFFF);
13288                tcg_gen_movi_tl(cpu_gpr[ret], temp);
13289                break;
13290            }
13291        case OPC_REPL_QH:
13292            check_dsp(ctx);
13293            {
13294                target_long temp;
13295
13296                imm = (ctx->opcode >> 16) & 0x03FF;
13297                imm = (int16_t)(imm << 6) >> 6;
13298
13299                temp = ((uint64_t)(uint16_t)imm << 48) |
13300                       ((uint64_t)(uint16_t)imm << 32) |
13301                       ((uint64_t)(uint16_t)imm << 16) |
13302                       (uint64_t)(uint16_t)imm;
13303                tcg_gen_movi_tl(cpu_gpr[ret], temp);
13304                break;
13305            }
13306        case OPC_REPLV_OB:
13307            check_dsp(ctx);
13308            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13309            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13310            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13311            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13312            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13313            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13314            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13315            break;
13316        case OPC_REPLV_PW:
13317            check_dsp(ctx);
13318            tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13319            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13320            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13321            break;
13322        case OPC_REPLV_QH:
13323            check_dsp(ctx);
13324            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13325            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13326            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13327            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13328            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13329            break;
13330        }
13331        break;
13332#endif
13333    }
13334    tcg_temp_free(t0);
13335    tcg_temp_free(val_t);
13336}
13337
13338static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13339                                     uint32_t op1, uint32_t op2,
13340                                     int ret, int v1, int v2, int check_ret)
13341{
13342    TCGv t1;
13343    TCGv v1_t;
13344    TCGv v2_t;
13345
13346    if ((ret == 0) && (check_ret == 1)) {
13347        /* Treat as NOP. */
13348        return;
13349    }
13350
13351    t1 = tcg_temp_new();
13352    v1_t = tcg_temp_new();
13353    v2_t = tcg_temp_new();
13354
13355    gen_load_gpr(v1_t, v1);
13356    gen_load_gpr(v2_t, v2);
13357
13358    switch (op1) {
13359    case OPC_CMPU_EQ_QB_DSP:
13360        switch (op2) {
13361        case OPC_CMPU_EQ_QB:
13362            check_dsp(ctx);
13363            gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13364            break;
13365        case OPC_CMPU_LT_QB:
13366            check_dsp(ctx);
13367            gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13368            break;
13369        case OPC_CMPU_LE_QB:
13370            check_dsp(ctx);
13371            gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13372            break;
13373        case OPC_CMPGU_EQ_QB:
13374            check_dsp(ctx);
13375            gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13376            break;
13377        case OPC_CMPGU_LT_QB:
13378            check_dsp(ctx);
13379            gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13380            break;
13381        case OPC_CMPGU_LE_QB:
13382            check_dsp(ctx);
13383            gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13384            break;
13385        case OPC_CMPGDU_EQ_QB:
13386            check_dsp_r2(ctx);
13387            gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13388            tcg_gen_mov_tl(cpu_gpr[ret], t1);
13389            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13390            tcg_gen_shli_tl(t1, t1, 24);
13391            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13392            break;
13393        case OPC_CMPGDU_LT_QB:
13394            check_dsp_r2(ctx);
13395            gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13396            tcg_gen_mov_tl(cpu_gpr[ret], t1);
13397            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13398            tcg_gen_shli_tl(t1, t1, 24);
13399            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13400            break;
13401        case OPC_CMPGDU_LE_QB:
13402            check_dsp_r2(ctx);
13403            gen_helper_cmpgu_le_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_CMP_EQ_PH:
13410            check_dsp(ctx);
13411            gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13412            break;
13413        case OPC_CMP_LT_PH:
13414            check_dsp(ctx);
13415            gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13416            break;
13417        case OPC_CMP_LE_PH:
13418            check_dsp(ctx);
13419            gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13420            break;
13421        case OPC_PICK_QB:
13422            check_dsp(ctx);
13423            gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13424            break;
13425        case OPC_PICK_PH:
13426            check_dsp(ctx);
13427            gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13428            break;
13429        case OPC_PACKRL_PH:
13430            check_dsp(ctx);
13431            gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13432            break;
13433        }
13434        break;
13435#ifdef TARGET_MIPS64
13436    case OPC_CMPU_EQ_OB_DSP:
13437        switch (op2) {
13438        case OPC_CMP_EQ_PW:
13439            check_dsp(ctx);
13440            gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13441            break;
13442        case OPC_CMP_LT_PW:
13443            check_dsp(ctx);
13444            gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13445            break;
13446        case OPC_CMP_LE_PW:
13447            check_dsp(ctx);
13448            gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13449            break;
13450        case OPC_CMP_EQ_QH:
13451            check_dsp(ctx);
13452            gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13453            break;
13454        case OPC_CMP_LT_QH:
13455            check_dsp(ctx);
13456            gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
13457            break;
13458        case OPC_CMP_LE_QH:
13459            check_dsp(ctx);
13460            gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
13461            break;
13462        case OPC_CMPGDU_EQ_OB:
13463            check_dsp_r2(ctx);
13464            gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13465            break;
13466        case OPC_CMPGDU_LT_OB:
13467            check_dsp_r2(ctx);
13468            gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13469            break;
13470        case OPC_CMPGDU_LE_OB:
13471            check_dsp_r2(ctx);
13472            gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13473            break;
13474        case OPC_CMPGU_EQ_OB:
13475            check_dsp(ctx);
13476            gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
13477            break;
13478        case OPC_CMPGU_LT_OB:
13479            check_dsp(ctx);
13480            gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
13481            break;
13482        case OPC_CMPGU_LE_OB:
13483            check_dsp(ctx);
13484            gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
13485            break;
13486        case OPC_CMPU_EQ_OB:
13487            check_dsp(ctx);
13488            gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
13489            break;
13490        case OPC_CMPU_LT_OB:
13491            check_dsp(ctx);
13492            gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
13493            break;
13494        case OPC_CMPU_LE_OB:
13495            check_dsp(ctx);
13496            gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
13497            break;
13498        case OPC_PACKRL_PW:
13499            check_dsp(ctx);
13500            gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
13501            break;
13502        case OPC_PICK_OB:
13503            check_dsp(ctx);
13504            gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13505            break;
13506        case OPC_PICK_PW:
13507            check_dsp(ctx);
13508            gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13509            break;
13510        case OPC_PICK_QH:
13511            check_dsp(ctx);
13512            gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13513            break;
13514        }
13515        break;
13516#endif
13517    }
13518
13519    tcg_temp_free(t1);
13520    tcg_temp_free(v1_t);
13521    tcg_temp_free(v2_t);
13522}
13523
13524static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
13525                               uint32_t op1, int rt, int rs, int sa)
13526{
13527    TCGv t0;
13528
13529    check_dsp_r2(ctx);
13530
13531    if (rt == 0) {
13532        /* Treat as NOP. */
13533        return;
13534    }
13535
13536    t0 = tcg_temp_new();
13537    gen_load_gpr(t0, rs);
13538
13539    switch (op1) {
13540    case OPC_APPEND_DSP:
13541        switch (MASK_APPEND(ctx->opcode)) {
13542        case OPC_APPEND:
13543            if (sa != 0) {
13544                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
13545            }
13546            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
13547            break;
13548        case OPC_PREPEND:
13549            if (sa != 0) {
13550                tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
13551                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
13552                tcg_gen_shli_tl(t0, t0, 32 - sa);
13553                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13554            }
13555            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
13556            break;
13557        case OPC_BALIGN:
13558            sa &= 3;
13559            if (sa != 0 && sa != 2) {
13560                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
13561                tcg_gen_ext32u_tl(t0, t0);
13562                tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
13563                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13564            }
13565            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
13566            break;
13567        default:            /* Invalid */
13568            MIPS_INVAL("MASK APPEND");
13569            gen_reserved_instruction(ctx);
13570            break;
13571        }
13572        break;
13573#ifdef TARGET_MIPS64
13574    case OPC_DAPPEND_DSP:
13575        switch (MASK_DAPPEND(ctx->opcode)) {
13576        case OPC_DAPPEND:
13577            if (sa != 0) {
13578                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
13579            }
13580            break;
13581        case OPC_PREPENDD:
13582            tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
13583            tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
13584            tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
13585            break;
13586        case OPC_PREPENDW:
13587            if (sa != 0) {
13588                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
13589                tcg_gen_shli_tl(t0, t0, 64 - sa);
13590                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13591            }
13592            break;
13593        case OPC_DBALIGN:
13594            sa &= 7;
13595            if (sa != 0 && sa != 2 && sa != 4) {
13596                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
13597                tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
13598                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
13599            }
13600            break;
13601        default:            /* Invalid */
13602            MIPS_INVAL("MASK DAPPEND");
13603            gen_reserved_instruction(ctx);
13604            break;
13605        }
13606        break;
13607#endif
13608    }
13609    tcg_temp_free(t0);
13610}
13611
13612static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
13613                                int ret, int v1, int v2, int check_ret)
13614
13615{
13616    TCGv t0;
13617    TCGv t1;
13618    TCGv v1_t;
13619    int16_t imm;
13620
13621    if ((ret == 0) && (check_ret == 1)) {
13622        /* Treat as NOP. */
13623        return;
13624    }
13625
13626    t0 = tcg_temp_new();
13627    t1 = tcg_temp_new();
13628    v1_t = tcg_temp_new();
13629
13630    gen_load_gpr(v1_t, v1);
13631
13632    switch (op1) {
13633    case OPC_EXTR_W_DSP:
13634        check_dsp(ctx);
13635        switch (op2) {
13636        case OPC_EXTR_W:
13637            tcg_gen_movi_tl(t0, v2);
13638            tcg_gen_movi_tl(t1, v1);
13639            gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
13640            break;
13641        case OPC_EXTR_R_W:
13642            tcg_gen_movi_tl(t0, v2);
13643            tcg_gen_movi_tl(t1, v1);
13644            gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
13645            break;
13646        case OPC_EXTR_RS_W:
13647            tcg_gen_movi_tl(t0, v2);
13648            tcg_gen_movi_tl(t1, v1);
13649            gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
13650            break;
13651        case OPC_EXTR_S_H:
13652            tcg_gen_movi_tl(t0, v2);
13653            tcg_gen_movi_tl(t1, v1);
13654            gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
13655            break;
13656        case OPC_EXTRV_S_H:
13657            tcg_gen_movi_tl(t0, v2);
13658            gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
13659            break;
13660        case OPC_EXTRV_W:
13661            tcg_gen_movi_tl(t0, v2);
13662            gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13663            break;
13664        case OPC_EXTRV_R_W:
13665            tcg_gen_movi_tl(t0, v2);
13666            gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13667            break;
13668        case OPC_EXTRV_RS_W:
13669            tcg_gen_movi_tl(t0, v2);
13670            gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13671            break;
13672        case OPC_EXTP:
13673            tcg_gen_movi_tl(t0, v2);
13674            tcg_gen_movi_tl(t1, v1);
13675            gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
13676            break;
13677        case OPC_EXTPV:
13678            tcg_gen_movi_tl(t0, v2);
13679            gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
13680            break;
13681        case OPC_EXTPDP:
13682            tcg_gen_movi_tl(t0, v2);
13683            tcg_gen_movi_tl(t1, v1);
13684            gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
13685            break;
13686        case OPC_EXTPDPV:
13687            tcg_gen_movi_tl(t0, v2);
13688            gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
13689            break;
13690        case OPC_SHILO:
13691            imm = (ctx->opcode >> 20) & 0x3F;
13692            tcg_gen_movi_tl(t0, ret);
13693            tcg_gen_movi_tl(t1, imm);
13694            gen_helper_shilo(t0, t1, cpu_env);
13695            break;
13696        case OPC_SHILOV:
13697            tcg_gen_movi_tl(t0, ret);
13698            gen_helper_shilo(t0, v1_t, cpu_env);
13699            break;
13700        case OPC_MTHLIP:
13701            tcg_gen_movi_tl(t0, ret);
13702            gen_helper_mthlip(t0, v1_t, cpu_env);
13703            break;
13704        case OPC_WRDSP:
13705            imm = (ctx->opcode >> 11) & 0x3FF;
13706            tcg_gen_movi_tl(t0, imm);
13707            gen_helper_wrdsp(v1_t, t0, cpu_env);
13708            break;
13709        case OPC_RDDSP:
13710            imm = (ctx->opcode >> 16) & 0x03FF;
13711            tcg_gen_movi_tl(t0, imm);
13712            gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
13713            break;
13714        }
13715        break;
13716#ifdef TARGET_MIPS64
13717    case OPC_DEXTR_W_DSP:
13718        check_dsp(ctx);
13719        switch (op2) {
13720        case OPC_DMTHLIP:
13721            tcg_gen_movi_tl(t0, ret);
13722            gen_helper_dmthlip(v1_t, t0, cpu_env);
13723            break;
13724        case OPC_DSHILO:
13725            {
13726                int shift = (ctx->opcode >> 19) & 0x7F;
13727                int ac = (ctx->opcode >> 11) & 0x03;
13728                tcg_gen_movi_tl(t0, shift);
13729                tcg_gen_movi_tl(t1, ac);
13730                gen_helper_dshilo(t0, t1, cpu_env);
13731                break;
13732            }
13733        case OPC_DSHILOV:
13734            {
13735                int ac = (ctx->opcode >> 11) & 0x03;
13736                tcg_gen_movi_tl(t0, ac);
13737                gen_helper_dshilo(v1_t, t0, cpu_env);
13738                break;
13739            }
13740        case OPC_DEXTP:
13741            tcg_gen_movi_tl(t0, v2);
13742            tcg_gen_movi_tl(t1, v1);
13743
13744            gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
13745            break;
13746        case OPC_DEXTPV:
13747            tcg_gen_movi_tl(t0, v2);
13748            gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
13749            break;
13750        case OPC_DEXTPDP:
13751            tcg_gen_movi_tl(t0, v2);
13752            tcg_gen_movi_tl(t1, v1);
13753            gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
13754            break;
13755        case OPC_DEXTPDPV:
13756            tcg_gen_movi_tl(t0, v2);
13757            gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
13758            break;
13759        case OPC_DEXTR_L:
13760            tcg_gen_movi_tl(t0, v2);
13761            tcg_gen_movi_tl(t1, v1);
13762            gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
13763            break;
13764        case OPC_DEXTR_R_L:
13765            tcg_gen_movi_tl(t0, v2);
13766            tcg_gen_movi_tl(t1, v1);
13767            gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
13768            break;
13769        case OPC_DEXTR_RS_L:
13770            tcg_gen_movi_tl(t0, v2);
13771            tcg_gen_movi_tl(t1, v1);
13772            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
13773            break;
13774        case OPC_DEXTR_W:
13775            tcg_gen_movi_tl(t0, v2);
13776            tcg_gen_movi_tl(t1, v1);
13777            gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
13778            break;
13779        case OPC_DEXTR_R_W:
13780            tcg_gen_movi_tl(t0, v2);
13781            tcg_gen_movi_tl(t1, v1);
13782            gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
13783            break;
13784        case OPC_DEXTR_RS_W:
13785            tcg_gen_movi_tl(t0, v2);
13786            tcg_gen_movi_tl(t1, v1);
13787            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
13788            break;
13789        case OPC_DEXTR_S_H:
13790            tcg_gen_movi_tl(t0, v2);
13791            tcg_gen_movi_tl(t1, v1);
13792            gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
13793            break;
13794        case OPC_DEXTRV_S_H:
13795            tcg_gen_movi_tl(t0, v2);
13796            gen_helper_dextr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
13797            break;
13798        case OPC_DEXTRV_L:
13799            tcg_gen_movi_tl(t0, v2);
13800            gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
13801            break;
13802        case OPC_DEXTRV_R_L:
13803            tcg_gen_movi_tl(t0, v2);
13804            gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
13805            break;
13806        case OPC_DEXTRV_RS_L:
13807            tcg_gen_movi_tl(t0, v2);
13808            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
13809            break;
13810        case OPC_DEXTRV_W:
13811            tcg_gen_movi_tl(t0, v2);
13812            gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13813            break;
13814        case OPC_DEXTRV_R_W:
13815            tcg_gen_movi_tl(t0, v2);
13816            gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13817            break;
13818        case OPC_DEXTRV_RS_W:
13819            tcg_gen_movi_tl(t0, v2);
13820            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
13821            break;
13822        }
13823        break;
13824#endif
13825    }
13826
13827    tcg_temp_free(t0);
13828    tcg_temp_free(t1);
13829    tcg_temp_free(v1_t);
13830}
13831
13832/* End MIPSDSP functions. */
13833
13834static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
13835{
13836    int rs, rt, rd, sa;
13837    uint32_t op1, op2;
13838
13839    rs = (ctx->opcode >> 21) & 0x1f;
13840    rt = (ctx->opcode >> 16) & 0x1f;
13841    rd = (ctx->opcode >> 11) & 0x1f;
13842    sa = (ctx->opcode >> 6) & 0x1f;
13843
13844    op1 = MASK_SPECIAL(ctx->opcode);
13845    switch (op1) {
13846    case OPC_MULT:
13847    case OPC_MULTU:
13848    case OPC_DIV:
13849    case OPC_DIVU:
13850        op2 = MASK_R6_MULDIV(ctx->opcode);
13851        switch (op2) {
13852        case R6_OPC_MUL:
13853        case R6_OPC_MUH:
13854        case R6_OPC_MULU:
13855        case R6_OPC_MUHU:
13856        case R6_OPC_DIV:
13857        case R6_OPC_MOD:
13858        case R6_OPC_DIVU:
13859        case R6_OPC_MODU:
13860            gen_r6_muldiv(ctx, op2, rd, rs, rt);
13861            break;
13862        default:
13863            MIPS_INVAL("special_r6 muldiv");
13864            gen_reserved_instruction(ctx);
13865            break;
13866        }
13867        break;
13868    case OPC_SELEQZ:
13869    case OPC_SELNEZ:
13870        gen_cond_move(ctx, op1, rd, rs, rt);
13871        break;
13872    case R6_OPC_CLO:
13873    case R6_OPC_CLZ:
13874        if (rt == 0 && sa == 1) {
13875            /*
13876             * Major opcode and function field is shared with preR6 MFHI/MTHI.
13877             * We need additionally to check other fields.
13878             */
13879            gen_cl(ctx, op1, rd, rs);
13880        } else {
13881            gen_reserved_instruction(ctx);
13882        }
13883        break;
13884    case R6_OPC_SDBBP:
13885        if (is_uhi(extract32(ctx->opcode, 6, 20))) {
13886            gen_helper_do_semihosting(cpu_env);
13887        } else {
13888            if (ctx->hflags & MIPS_HFLAG_SBRI) {
13889                gen_reserved_instruction(ctx);
13890            } else {
13891                generate_exception_end(ctx, EXCP_DBp);
13892            }
13893        }
13894        break;
13895#if defined(TARGET_MIPS64)
13896    case R6_OPC_DCLO:
13897    case R6_OPC_DCLZ:
13898        if (rt == 0 && sa == 1) {
13899            /*
13900             * Major opcode and function field is shared with preR6 MFHI/MTHI.
13901             * We need additionally to check other fields.
13902             */
13903            check_mips_64(ctx);
13904            gen_cl(ctx, op1, rd, rs);
13905        } else {
13906            gen_reserved_instruction(ctx);
13907        }
13908        break;
13909    case OPC_DMULT:
13910    case OPC_DMULTU:
13911    case OPC_DDIV:
13912    case OPC_DDIVU:
13913
13914        op2 = MASK_R6_MULDIV(ctx->opcode);
13915        switch (op2) {
13916        case R6_OPC_DMUL:
13917        case R6_OPC_DMUH:
13918        case R6_OPC_DMULU:
13919        case R6_OPC_DMUHU:
13920        case R6_OPC_DDIV:
13921        case R6_OPC_DMOD:
13922        case R6_OPC_DDIVU:
13923        case R6_OPC_DMODU:
13924            check_mips_64(ctx);
13925            gen_r6_muldiv(ctx, op2, rd, rs, rt);
13926            break;
13927        default:
13928            MIPS_INVAL("special_r6 muldiv");
13929            gen_reserved_instruction(ctx);
13930            break;
13931        }
13932        break;
13933#endif
13934    default:            /* Invalid */
13935        MIPS_INVAL("special_r6");
13936        gen_reserved_instruction(ctx);
13937        break;
13938    }
13939}
13940
13941static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
13942{
13943    int rs = extract32(ctx->opcode, 21, 5);
13944    int rt = extract32(ctx->opcode, 16, 5);
13945    int rd = extract32(ctx->opcode, 11, 5);
13946    uint32_t op1 = MASK_SPECIAL(ctx->opcode);
13947
13948    switch (op1) {
13949    case OPC_MOVN:         /* Conditional move */
13950    case OPC_MOVZ:
13951        gen_cond_move(ctx, op1, rd, rs, rt);
13952        break;
13953    case OPC_MFHI:          /* Move from HI/LO */
13954    case OPC_MFLO:
13955        gen_HILO(ctx, op1, 0, rd);
13956        break;
13957    case OPC_MTHI:
13958    case OPC_MTLO:          /* Move to HI/LO */
13959        gen_HILO(ctx, op1, 0, rs);
13960        break;
13961    case OPC_MULT:
13962    case OPC_MULTU:
13963        gen_mul_txx9(ctx, op1, rd, rs, rt);
13964        break;
13965    case OPC_DIV:
13966    case OPC_DIVU:
13967        gen_muldiv(ctx, op1, 0, rs, rt);
13968        break;
13969#if defined(TARGET_MIPS64)
13970    case OPC_DMULT:
13971    case OPC_DMULTU:
13972    case OPC_DDIV:
13973    case OPC_DDIVU:
13974        check_insn_opc_user_only(ctx, INSN_R5900);
13975        gen_muldiv(ctx, op1, 0, rs, rt);
13976        break;
13977#endif
13978    case OPC_JR:
13979        gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
13980        break;
13981    default:            /* Invalid */
13982        MIPS_INVAL("special_tx79");
13983        gen_reserved_instruction(ctx);
13984        break;
13985    }
13986}
13987
13988static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
13989{
13990    int rs, rt, rd;
13991    uint32_t op1;
13992
13993    rs = (ctx->opcode >> 21) & 0x1f;
13994    rt = (ctx->opcode >> 16) & 0x1f;
13995    rd = (ctx->opcode >> 11) & 0x1f;
13996
13997    op1 = MASK_SPECIAL(ctx->opcode);
13998    switch (op1) {
13999    case OPC_MOVN:         /* Conditional move */
14000    case OPC_MOVZ:
14001        check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 |
14002                   INSN_LOONGSON2E | INSN_LOONGSON2F);
14003        gen_cond_move(ctx, op1, rd, rs, rt);
14004        break;
14005    case OPC_MFHI:          /* Move from HI/LO */
14006    case OPC_MFLO:
14007        gen_HILO(ctx, op1, rs & 3, rd);
14008        break;
14009    case OPC_MTHI:
14010    case OPC_MTLO:          /* Move to HI/LO */
14011        gen_HILO(ctx, op1, rd & 3, rs);
14012        break;
14013    case OPC_MOVCI:
14014        check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
14015        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14016            check_cp1_enabled(ctx);
14017            gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14018                      (ctx->opcode >> 16) & 1);
14019        } else {
14020            generate_exception_err(ctx, EXCP_CpU, 1);
14021        }
14022        break;
14023    case OPC_MULT:
14024    case OPC_MULTU:
14025        gen_muldiv(ctx, op1, rd & 3, rs, rt);
14026        break;
14027    case OPC_DIV:
14028    case OPC_DIVU:
14029        gen_muldiv(ctx, op1, 0, rs, rt);
14030        break;
14031#if defined(TARGET_MIPS64)
14032    case OPC_DMULT:
14033    case OPC_DMULTU:
14034    case OPC_DDIV:
14035    case OPC_DDIVU:
14036        check_insn(ctx, ISA_MIPS3);
14037        check_mips_64(ctx);
14038        gen_muldiv(ctx, op1, 0, rs, rt);
14039        break;
14040#endif
14041    case OPC_JR:
14042        gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
14043        break;
14044    case OPC_SPIM:
14045#ifdef MIPS_STRICT_STANDARD
14046        MIPS_INVAL("SPIM");
14047        gen_reserved_instruction(ctx);
14048#else
14049        /* Implemented as RI exception for now. */
14050        MIPS_INVAL("spim (unofficial)");
14051        gen_reserved_instruction(ctx);
14052#endif
14053        break;
14054    default:            /* Invalid */
14055        MIPS_INVAL("special_legacy");
14056        gen_reserved_instruction(ctx);
14057        break;
14058    }
14059}
14060
14061static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
14062{
14063    int rs, rt, rd, sa;
14064    uint32_t op1;
14065
14066    rs = (ctx->opcode >> 21) & 0x1f;
14067    rt = (ctx->opcode >> 16) & 0x1f;
14068    rd = (ctx->opcode >> 11) & 0x1f;
14069    sa = (ctx->opcode >> 6) & 0x1f;
14070
14071    op1 = MASK_SPECIAL(ctx->opcode);
14072    switch (op1) {
14073    case OPC_SLL:          /* Shift with immediate */
14074        if (sa == 5 && rd == 0 &&
14075            rs == 0 && rt == 0) { /* PAUSE */
14076            if ((ctx->insn_flags & ISA_MIPS_R6) &&
14077                (ctx->hflags & MIPS_HFLAG_BMASK)) {
14078                gen_reserved_instruction(ctx);
14079                break;
14080            }
14081        }
14082        /* Fallthrough */
14083    case OPC_SRA:
14084        gen_shift_imm(ctx, op1, rd, rt, sa);
14085        break;
14086    case OPC_SRL:
14087        switch ((ctx->opcode >> 21) & 0x1f) {
14088        case 1:
14089            /* rotr is decoded as srl on non-R2 CPUs */
14090            if (ctx->insn_flags & ISA_MIPS_R2) {
14091                op1 = OPC_ROTR;
14092            }
14093            /* Fallthrough */
14094        case 0:
14095            gen_shift_imm(ctx, op1, rd, rt, sa);
14096            break;
14097        default:
14098            gen_reserved_instruction(ctx);
14099            break;
14100        }
14101        break;
14102    case OPC_ADD:
14103    case OPC_ADDU:
14104    case OPC_SUB:
14105    case OPC_SUBU:
14106        gen_arith(ctx, op1, rd, rs, rt);
14107        break;
14108    case OPC_SLLV:         /* Shifts */
14109    case OPC_SRAV:
14110        gen_shift(ctx, op1, rd, rs, rt);
14111        break;
14112    case OPC_SRLV:
14113        switch ((ctx->opcode >> 6) & 0x1f) {
14114        case 1:
14115            /* rotrv is decoded as srlv on non-R2 CPUs */
14116            if (ctx->insn_flags & ISA_MIPS_R2) {
14117                op1 = OPC_ROTRV;
14118            }
14119            /* Fallthrough */
14120        case 0:
14121            gen_shift(ctx, op1, rd, rs, rt);
14122            break;
14123        default:
14124            gen_reserved_instruction(ctx);
14125            break;
14126        }
14127        break;
14128    case OPC_SLT:          /* Set on less than */
14129    case OPC_SLTU:
14130        gen_slt(ctx, op1, rd, rs, rt);
14131        break;
14132    case OPC_AND:          /* Logic*/
14133    case OPC_OR:
14134    case OPC_NOR:
14135    case OPC_XOR:
14136        gen_logic(ctx, op1, rd, rs, rt);
14137        break;
14138    case OPC_JALR:
14139        gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
14140        break;
14141    case OPC_TGE: /* Traps */
14142    case OPC_TGEU:
14143    case OPC_TLT:
14144    case OPC_TLTU:
14145    case OPC_TEQ:
14146    case OPC_TNE:
14147        check_insn(ctx, ISA_MIPS2);
14148        gen_trap(ctx, op1, rs, rt, -1);
14149        break;
14150    case OPC_PMON:
14151        /* Pmon entry point, also R4010 selsl */
14152#ifdef MIPS_STRICT_STANDARD
14153        MIPS_INVAL("PMON / selsl");
14154        gen_reserved_instruction(ctx);
14155#else
14156        gen_helper_pmon(cpu_env, tcg_constant_i32(sa));
14157#endif
14158        break;
14159    case OPC_SYSCALL:
14160        generate_exception_end(ctx, EXCP_SYSCALL);
14161        break;
14162    case OPC_BREAK:
14163        generate_exception_end(ctx, EXCP_BREAK);
14164        break;
14165    case OPC_SYNC:
14166        check_insn(ctx, ISA_MIPS2);
14167        gen_sync(extract32(ctx->opcode, 6, 5));
14168        break;
14169
14170#if defined(TARGET_MIPS64)
14171        /* MIPS64 specific opcodes */
14172    case OPC_DSLL:
14173    case OPC_DSRA:
14174    case OPC_DSLL32:
14175    case OPC_DSRA32:
14176        check_insn(ctx, ISA_MIPS3);
14177        check_mips_64(ctx);
14178        gen_shift_imm(ctx, op1, rd, rt, sa);
14179        break;
14180    case OPC_DSRL:
14181        switch ((ctx->opcode >> 21) & 0x1f) {
14182        case 1:
14183            /* drotr is decoded as dsrl on non-R2 CPUs */
14184            if (ctx->insn_flags & ISA_MIPS_R2) {
14185                op1 = OPC_DROTR;
14186            }
14187            /* Fallthrough */
14188        case 0:
14189            check_insn(ctx, ISA_MIPS3);
14190            check_mips_64(ctx);
14191            gen_shift_imm(ctx, op1, rd, rt, sa);
14192            break;
14193        default:
14194            gen_reserved_instruction(ctx);
14195            break;
14196        }
14197        break;
14198    case OPC_DSRL32:
14199        switch ((ctx->opcode >> 21) & 0x1f) {
14200        case 1:
14201            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14202            if (ctx->insn_flags & ISA_MIPS_R2) {
14203                op1 = OPC_DROTR32;
14204            }
14205            /* Fallthrough */
14206        case 0:
14207            check_insn(ctx, ISA_MIPS3);
14208            check_mips_64(ctx);
14209            gen_shift_imm(ctx, op1, rd, rt, sa);
14210            break;
14211        default:
14212            gen_reserved_instruction(ctx);
14213            break;
14214        }
14215        break;
14216    case OPC_DADD:
14217    case OPC_DADDU:
14218    case OPC_DSUB:
14219    case OPC_DSUBU:
14220        check_insn(ctx, ISA_MIPS3);
14221        check_mips_64(ctx);
14222        gen_arith(ctx, op1, rd, rs, rt);
14223        break;
14224    case OPC_DSLLV:
14225    case OPC_DSRAV:
14226        check_insn(ctx, ISA_MIPS3);
14227        check_mips_64(ctx);
14228        gen_shift(ctx, op1, rd, rs, rt);
14229        break;
14230    case OPC_DSRLV:
14231        switch ((ctx->opcode >> 6) & 0x1f) {
14232        case 1:
14233            /* drotrv is decoded as dsrlv on non-R2 CPUs */
14234            if (ctx->insn_flags & ISA_MIPS_R2) {
14235                op1 = OPC_DROTRV;
14236            }
14237            /* Fallthrough */
14238        case 0:
14239            check_insn(ctx, ISA_MIPS3);
14240            check_mips_64(ctx);
14241            gen_shift(ctx, op1, rd, rs, rt);
14242            break;
14243        default:
14244            gen_reserved_instruction(ctx);
14245            break;
14246        }
14247        break;
14248#endif
14249    default:
14250        if (ctx->insn_flags & ISA_MIPS_R6) {
14251            decode_opc_special_r6(env, ctx);
14252        } else if (ctx->insn_flags & INSN_R5900) {
14253            decode_opc_special_tx79(env, ctx);
14254        } else {
14255            decode_opc_special_legacy(env, ctx);
14256        }
14257    }
14258}
14259
14260
14261static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
14262{
14263    int rs, rt, rd;
14264    uint32_t op1;
14265
14266    rs = (ctx->opcode >> 21) & 0x1f;
14267    rt = (ctx->opcode >> 16) & 0x1f;
14268    rd = (ctx->opcode >> 11) & 0x1f;
14269
14270    op1 = MASK_SPECIAL2(ctx->opcode);
14271    switch (op1) {
14272    case OPC_MADD: /* Multiply and add/sub */
14273    case OPC_MADDU:
14274    case OPC_MSUB:
14275    case OPC_MSUBU:
14276        check_insn(ctx, ISA_MIPS_R1);
14277        gen_muldiv(ctx, op1, rd & 3, rs, rt);
14278        break;
14279    case OPC_MUL:
14280        gen_arith(ctx, op1, rd, rs, rt);
14281        break;
14282    case OPC_DIV_G_2F:
14283    case OPC_DIVU_G_2F:
14284    case OPC_MULT_G_2F:
14285    case OPC_MULTU_G_2F:
14286    case OPC_MOD_G_2F:
14287    case OPC_MODU_G_2F:
14288        check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
14289        gen_loongson_integer(ctx, op1, rd, rs, rt);
14290        break;
14291    case OPC_CLO:
14292    case OPC_CLZ:
14293        check_insn(ctx, ISA_MIPS_R1);
14294        gen_cl(ctx, op1, rd, rs);
14295        break;
14296    case OPC_SDBBP:
14297        if (is_uhi(extract32(ctx->opcode, 6, 20))) {
14298            gen_helper_do_semihosting(cpu_env);
14299        } else {
14300            /*
14301             * XXX: not clear which exception should be raised
14302             *      when in debug mode...
14303             */
14304            check_insn(ctx, ISA_MIPS_R1);
14305            generate_exception_end(ctx, EXCP_DBp);
14306        }
14307        break;
14308#if defined(TARGET_MIPS64)
14309    case OPC_DCLO:
14310    case OPC_DCLZ:
14311        check_insn(ctx, ISA_MIPS_R1);
14312        check_mips_64(ctx);
14313        gen_cl(ctx, op1, rd, rs);
14314        break;
14315    case OPC_DMULT_G_2F:
14316    case OPC_DMULTU_G_2F:
14317    case OPC_DDIV_G_2F:
14318    case OPC_DDIVU_G_2F:
14319    case OPC_DMOD_G_2F:
14320    case OPC_DMODU_G_2F:
14321        check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
14322        gen_loongson_integer(ctx, op1, rd, rs, rt);
14323        break;
14324#endif
14325    default:            /* Invalid */
14326        MIPS_INVAL("special2_legacy");
14327        gen_reserved_instruction(ctx);
14328        break;
14329    }
14330}
14331
14332static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
14333{
14334    int rs, rt, rd, sa;
14335    uint32_t op1, op2;
14336    int16_t imm;
14337
14338    rs = (ctx->opcode >> 21) & 0x1f;
14339    rt = (ctx->opcode >> 16) & 0x1f;
14340    rd = (ctx->opcode >> 11) & 0x1f;
14341    sa = (ctx->opcode >> 6) & 0x1f;
14342    imm = (int16_t)ctx->opcode >> 7;
14343
14344    op1 = MASK_SPECIAL3(ctx->opcode);
14345    switch (op1) {
14346    case R6_OPC_PREF:
14347        if (rt >= 24) {
14348            /* hint codes 24-31 are reserved and signal RI */
14349            gen_reserved_instruction(ctx);
14350        }
14351        /* Treat as NOP. */
14352        break;
14353    case R6_OPC_CACHE:
14354        check_cp0_enabled(ctx);
14355        if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
14356            gen_cache_operation(ctx, rt, rs, imm);
14357        }
14358        break;
14359    case R6_OPC_SC:
14360        gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
14361        break;
14362    case R6_OPC_LL:
14363        gen_ld(ctx, op1, rt, rs, imm);
14364        break;
14365    case OPC_BSHFL:
14366        {
14367            if (rd == 0) {
14368                /* Treat as NOP. */
14369                break;
14370            }
14371            op2 = MASK_BSHFL(ctx->opcode);
14372            switch (op2) {
14373            case OPC_ALIGN:
14374            case OPC_ALIGN_1:
14375            case OPC_ALIGN_2:
14376            case OPC_ALIGN_3:
14377                gen_align(ctx, 32, rd, rs, rt, sa & 3);
14378                break;
14379            case OPC_BITSWAP:
14380                gen_bitswap(ctx, op2, rd, rt);
14381                break;
14382            }
14383        }
14384        break;
14385#ifndef CONFIG_USER_ONLY
14386    case OPC_GINV:
14387        if (unlikely(ctx->gi <= 1)) {
14388            gen_reserved_instruction(ctx);
14389        }
14390        check_cp0_enabled(ctx);
14391        switch ((ctx->opcode >> 6) & 3) {
14392        case 0:    /* GINVI */
14393            /* Treat as NOP. */
14394            break;
14395        case 2:    /* GINVT */
14396            gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2));
14397            break;
14398        default:
14399            gen_reserved_instruction(ctx);
14400            break;
14401        }
14402        break;
14403#endif
14404#if defined(TARGET_MIPS64)
14405    case R6_OPC_SCD:
14406        gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
14407        break;
14408    case R6_OPC_LLD:
14409        gen_ld(ctx, op1, rt, rs, imm);
14410        break;
14411    case OPC_DBSHFL:
14412        check_mips_64(ctx);
14413        {
14414            if (rd == 0) {
14415                /* Treat as NOP. */
14416                break;
14417            }
14418            op2 = MASK_DBSHFL(ctx->opcode);
14419            switch (op2) {
14420            case OPC_DALIGN:
14421            case OPC_DALIGN_1:
14422            case OPC_DALIGN_2:
14423            case OPC_DALIGN_3:
14424            case OPC_DALIGN_4:
14425            case OPC_DALIGN_5:
14426            case OPC_DALIGN_6:
14427            case OPC_DALIGN_7:
14428                gen_align(ctx, 64, rd, rs, rt, sa & 7);
14429                break;
14430            case OPC_DBITSWAP:
14431                gen_bitswap(ctx, op2, rd, rt);
14432                break;
14433            }
14434
14435        }
14436        break;
14437#endif
14438    default:            /* Invalid */
14439        MIPS_INVAL("special3_r6");
14440        gen_reserved_instruction(ctx);
14441        break;
14442    }
14443}
14444
14445static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
14446{
14447    int rs, rt, rd;
14448    uint32_t op1, op2;
14449
14450    rs = (ctx->opcode >> 21) & 0x1f;
14451    rt = (ctx->opcode >> 16) & 0x1f;
14452    rd = (ctx->opcode >> 11) & 0x1f;
14453
14454    op1 = MASK_SPECIAL3(ctx->opcode);
14455    switch (op1) {
14456    case OPC_DIV_G_2E:
14457    case OPC_DIVU_G_2E:
14458    case OPC_MOD_G_2E:
14459    case OPC_MODU_G_2E:
14460    case OPC_MULT_G_2E:
14461    case OPC_MULTU_G_2E:
14462        /*
14463         * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14464         * the same mask and op1.
14465         */
14466        if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
14467            op2 = MASK_ADDUH_QB(ctx->opcode);
14468            switch (op2) {
14469            case OPC_ADDUH_QB:
14470            case OPC_ADDUH_R_QB:
14471            case OPC_ADDQH_PH:
14472            case OPC_ADDQH_R_PH:
14473            case OPC_ADDQH_W:
14474            case OPC_ADDQH_R_W:
14475            case OPC_SUBUH_QB:
14476            case OPC_SUBUH_R_QB:
14477            case OPC_SUBQH_PH:
14478            case OPC_SUBQH_R_PH:
14479            case OPC_SUBQH_W:
14480            case OPC_SUBQH_R_W:
14481                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14482                break;
14483            case OPC_MUL_PH:
14484            case OPC_MUL_S_PH:
14485            case OPC_MULQ_S_W:
14486            case OPC_MULQ_RS_W:
14487                gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14488                break;
14489            default:
14490                MIPS_INVAL("MASK ADDUH.QB");
14491                gen_reserved_instruction(ctx);
14492                break;
14493            }
14494        } else if (ctx->insn_flags & INSN_LOONGSON2E) {
14495            gen_loongson_integer(ctx, op1, rd, rs, rt);
14496        } else {
14497            gen_reserved_instruction(ctx);
14498        }
14499        break;
14500    case OPC_LX_DSP:
14501        op2 = MASK_LX(ctx->opcode);
14502        switch (op2) {
14503#if defined(TARGET_MIPS64)
14504        case OPC_LDX:
14505#endif
14506        case OPC_LBUX:
14507        case OPC_LHX:
14508        case OPC_LWX:
14509            gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
14510            break;
14511        default:            /* Invalid */
14512            MIPS_INVAL("MASK LX");
14513            gen_reserved_instruction(ctx);
14514            break;
14515        }
14516        break;
14517    case OPC_ABSQ_S_PH_DSP:
14518        op2 = MASK_ABSQ_S_PH(ctx->opcode);
14519        switch (op2) {
14520        case OPC_ABSQ_S_QB:
14521        case OPC_ABSQ_S_PH:
14522        case OPC_ABSQ_S_W:
14523        case OPC_PRECEQ_W_PHL:
14524        case OPC_PRECEQ_W_PHR:
14525        case OPC_PRECEQU_PH_QBL:
14526        case OPC_PRECEQU_PH_QBR:
14527        case OPC_PRECEQU_PH_QBLA:
14528        case OPC_PRECEQU_PH_QBRA:
14529        case OPC_PRECEU_PH_QBL:
14530        case OPC_PRECEU_PH_QBR:
14531        case OPC_PRECEU_PH_QBLA:
14532        case OPC_PRECEU_PH_QBRA:
14533            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14534            break;
14535        case OPC_BITREV:
14536        case OPC_REPL_QB:
14537        case OPC_REPLV_QB:
14538        case OPC_REPL_PH:
14539        case OPC_REPLV_PH:
14540            gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14541            break;
14542        default:
14543            MIPS_INVAL("MASK ABSQ_S.PH");
14544            gen_reserved_instruction(ctx);
14545            break;
14546        }
14547        break;
14548    case OPC_ADDU_QB_DSP:
14549        op2 = MASK_ADDU_QB(ctx->opcode);
14550        switch (op2) {
14551        case OPC_ADDQ_PH:
14552        case OPC_ADDQ_S_PH:
14553        case OPC_ADDQ_S_W:
14554        case OPC_ADDU_QB:
14555        case OPC_ADDU_S_QB:
14556        case OPC_ADDU_PH:
14557        case OPC_ADDU_S_PH:
14558        case OPC_SUBQ_PH:
14559        case OPC_SUBQ_S_PH:
14560        case OPC_SUBQ_S_W:
14561        case OPC_SUBU_QB:
14562        case OPC_SUBU_S_QB:
14563        case OPC_SUBU_PH:
14564        case OPC_SUBU_S_PH:
14565        case OPC_ADDSC:
14566        case OPC_ADDWC:
14567        case OPC_MODSUB:
14568        case OPC_RADDU_W_QB:
14569            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14570            break;
14571        case OPC_MULEU_S_PH_QBL:
14572        case OPC_MULEU_S_PH_QBR:
14573        case OPC_MULQ_RS_PH:
14574        case OPC_MULEQ_S_W_PHL:
14575        case OPC_MULEQ_S_W_PHR:
14576        case OPC_MULQ_S_PH:
14577            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14578            break;
14579        default:            /* Invalid */
14580            MIPS_INVAL("MASK ADDU.QB");
14581            gen_reserved_instruction(ctx);
14582            break;
14583
14584        }
14585        break;
14586    case OPC_CMPU_EQ_QB_DSP:
14587        op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14588        switch (op2) {
14589        case OPC_PRECR_SRA_PH_W:
14590        case OPC_PRECR_SRA_R_PH_W:
14591            gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14592            break;
14593        case OPC_PRECR_QB_PH:
14594        case OPC_PRECRQ_QB_PH:
14595        case OPC_PRECRQ_PH_W:
14596        case OPC_PRECRQ_RS_PH_W:
14597        case OPC_PRECRQU_S_QB_PH:
14598            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14599            break;
14600        case OPC_CMPU_EQ_QB:
14601        case OPC_CMPU_LT_QB:
14602        case OPC_CMPU_LE_QB:
14603        case OPC_CMP_EQ_PH:
14604        case OPC_CMP_LT_PH:
14605        case OPC_CMP_LE_PH:
14606            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14607            break;
14608        case OPC_CMPGU_EQ_QB:
14609        case OPC_CMPGU_LT_QB:
14610        case OPC_CMPGU_LE_QB:
14611        case OPC_CMPGDU_EQ_QB:
14612        case OPC_CMPGDU_LT_QB:
14613        case OPC_CMPGDU_LE_QB:
14614        case OPC_PICK_QB:
14615        case OPC_PICK_PH:
14616        case OPC_PACKRL_PH:
14617            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14618            break;
14619        default:            /* Invalid */
14620            MIPS_INVAL("MASK CMPU.EQ.QB");
14621            gen_reserved_instruction(ctx);
14622            break;
14623        }
14624        break;
14625    case OPC_SHLL_QB_DSP:
14626        gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14627        break;
14628    case OPC_DPA_W_PH_DSP:
14629        op2 = MASK_DPA_W_PH(ctx->opcode);
14630        switch (op2) {
14631        case OPC_DPAU_H_QBL:
14632        case OPC_DPAU_H_QBR:
14633        case OPC_DPSU_H_QBL:
14634        case OPC_DPSU_H_QBR:
14635        case OPC_DPA_W_PH:
14636        case OPC_DPAX_W_PH:
14637        case OPC_DPAQ_S_W_PH:
14638        case OPC_DPAQX_S_W_PH:
14639        case OPC_DPAQX_SA_W_PH:
14640        case OPC_DPS_W_PH:
14641        case OPC_DPSX_W_PH:
14642        case OPC_DPSQ_S_W_PH:
14643        case OPC_DPSQX_S_W_PH:
14644        case OPC_DPSQX_SA_W_PH:
14645        case OPC_MULSAQ_S_W_PH:
14646        case OPC_DPAQ_SA_L_W:
14647        case OPC_DPSQ_SA_L_W:
14648        case OPC_MAQ_S_W_PHL:
14649        case OPC_MAQ_S_W_PHR:
14650        case OPC_MAQ_SA_W_PHL:
14651        case OPC_MAQ_SA_W_PHR:
14652        case OPC_MULSA_W_PH:
14653            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14654            break;
14655        default:            /* Invalid */
14656            MIPS_INVAL("MASK DPAW.PH");
14657            gen_reserved_instruction(ctx);
14658            break;
14659        }
14660        break;
14661    case OPC_INSV_DSP:
14662        op2 = MASK_INSV(ctx->opcode);
14663        switch (op2) {
14664        case OPC_INSV:
14665            check_dsp(ctx);
14666            {
14667                TCGv t0, t1;
14668
14669                if (rt == 0) {
14670                    break;
14671                }
14672
14673                t0 = tcg_temp_new();
14674                t1 = tcg_temp_new();
14675
14676                gen_load_gpr(t0, rt);
14677                gen_load_gpr(t1, rs);
14678
14679                gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14680
14681                tcg_temp_free(t0);
14682                tcg_temp_free(t1);
14683                break;
14684            }
14685        default:            /* Invalid */
14686            MIPS_INVAL("MASK INSV");
14687            gen_reserved_instruction(ctx);
14688            break;
14689        }
14690        break;
14691    case OPC_APPEND_DSP:
14692        gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
14693        break;
14694    case OPC_EXTR_W_DSP:
14695        op2 = MASK_EXTR_W(ctx->opcode);
14696        switch (op2) {
14697        case OPC_EXTR_W:
14698        case OPC_EXTR_R_W:
14699        case OPC_EXTR_RS_W:
14700        case OPC_EXTR_S_H:
14701        case OPC_EXTRV_S_H:
14702        case OPC_EXTRV_W:
14703        case OPC_EXTRV_R_W:
14704        case OPC_EXTRV_RS_W:
14705        case OPC_EXTP:
14706        case OPC_EXTPV:
14707        case OPC_EXTPDP:
14708        case OPC_EXTPDPV:
14709            gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14710            break;
14711        case OPC_RDDSP:
14712            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14713            break;
14714        case OPC_SHILO:
14715        case OPC_SHILOV:
14716        case OPC_MTHLIP:
14717        case OPC_WRDSP:
14718            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14719            break;
14720        default:            /* Invalid */
14721            MIPS_INVAL("MASK EXTR.W");
14722            gen_reserved_instruction(ctx);
14723            break;
14724        }
14725        break;
14726#if defined(TARGET_MIPS64)
14727    case OPC_DDIV_G_2E:
14728    case OPC_DDIVU_G_2E:
14729    case OPC_DMULT_G_2E:
14730    case OPC_DMULTU_G_2E:
14731    case OPC_DMOD_G_2E:
14732    case OPC_DMODU_G_2E:
14733        check_insn(ctx, INSN_LOONGSON2E);
14734        gen_loongson_integer(ctx, op1, rd, rs, rt);
14735        break;
14736    case OPC_ABSQ_S_QH_DSP:
14737        op2 = MASK_ABSQ_S_QH(ctx->opcode);
14738        switch (op2) {
14739        case OPC_PRECEQ_L_PWL:
14740        case OPC_PRECEQ_L_PWR:
14741        case OPC_PRECEQ_PW_QHL:
14742        case OPC_PRECEQ_PW_QHR:
14743        case OPC_PRECEQ_PW_QHLA:
14744        case OPC_PRECEQ_PW_QHRA:
14745        case OPC_PRECEQU_QH_OBL:
14746        case OPC_PRECEQU_QH_OBR:
14747        case OPC_PRECEQU_QH_OBLA:
14748        case OPC_PRECEQU_QH_OBRA:
14749        case OPC_PRECEU_QH_OBL:
14750        case OPC_PRECEU_QH_OBR:
14751        case OPC_PRECEU_QH_OBLA:
14752        case OPC_PRECEU_QH_OBRA:
14753        case OPC_ABSQ_S_OB:
14754        case OPC_ABSQ_S_PW:
14755        case OPC_ABSQ_S_QH:
14756            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14757            break;
14758        case OPC_REPL_OB:
14759        case OPC_REPL_PW:
14760        case OPC_REPL_QH:
14761        case OPC_REPLV_OB:
14762        case OPC_REPLV_PW:
14763        case OPC_REPLV_QH:
14764            gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14765            break;
14766        default:            /* Invalid */
14767            MIPS_INVAL("MASK ABSQ_S.QH");
14768            gen_reserved_instruction(ctx);
14769            break;
14770        }
14771        break;
14772    case OPC_ADDU_OB_DSP:
14773        op2 = MASK_ADDU_OB(ctx->opcode);
14774        switch (op2) {
14775        case OPC_RADDU_L_OB:
14776        case OPC_SUBQ_PW:
14777        case OPC_SUBQ_S_PW:
14778        case OPC_SUBQ_QH:
14779        case OPC_SUBQ_S_QH:
14780        case OPC_SUBU_OB:
14781        case OPC_SUBU_S_OB:
14782        case OPC_SUBU_QH:
14783        case OPC_SUBU_S_QH:
14784        case OPC_SUBUH_OB:
14785        case OPC_SUBUH_R_OB:
14786        case OPC_ADDQ_PW:
14787        case OPC_ADDQ_S_PW:
14788        case OPC_ADDQ_QH:
14789        case OPC_ADDQ_S_QH:
14790        case OPC_ADDU_OB:
14791        case OPC_ADDU_S_OB:
14792        case OPC_ADDU_QH:
14793        case OPC_ADDU_S_QH:
14794        case OPC_ADDUH_OB:
14795        case OPC_ADDUH_R_OB:
14796            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14797            break;
14798        case OPC_MULEQ_S_PW_QHL:
14799        case OPC_MULEQ_S_PW_QHR:
14800        case OPC_MULEU_S_QH_OBL:
14801        case OPC_MULEU_S_QH_OBR:
14802        case OPC_MULQ_RS_QH:
14803            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14804            break;
14805        default:            /* Invalid */
14806            MIPS_INVAL("MASK ADDU.OB");
14807            gen_reserved_instruction(ctx);
14808            break;
14809        }
14810        break;
14811    case OPC_CMPU_EQ_OB_DSP:
14812        op2 = MASK_CMPU_EQ_OB(ctx->opcode);
14813        switch (op2) {
14814        case OPC_PRECR_SRA_QH_PW:
14815        case OPC_PRECR_SRA_R_QH_PW:
14816            /* Return value is rt. */
14817            gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14818            break;
14819        case OPC_PRECR_OB_QH:
14820        case OPC_PRECRQ_OB_QH:
14821        case OPC_PRECRQ_PW_L:
14822        case OPC_PRECRQ_QH_PW:
14823        case OPC_PRECRQ_RS_QH_PW:
14824        case OPC_PRECRQU_S_OB_QH:
14825            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14826            break;
14827        case OPC_CMPU_EQ_OB:
14828        case OPC_CMPU_LT_OB:
14829        case OPC_CMPU_LE_OB:
14830        case OPC_CMP_EQ_QH:
14831        case OPC_CMP_LT_QH:
14832        case OPC_CMP_LE_QH:
14833        case OPC_CMP_EQ_PW:
14834        case OPC_CMP_LT_PW:
14835        case OPC_CMP_LE_PW:
14836            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14837            break;
14838        case OPC_CMPGDU_EQ_OB:
14839        case OPC_CMPGDU_LT_OB:
14840        case OPC_CMPGDU_LE_OB:
14841        case OPC_CMPGU_EQ_OB:
14842        case OPC_CMPGU_LT_OB:
14843        case OPC_CMPGU_LE_OB:
14844        case OPC_PACKRL_PW:
14845        case OPC_PICK_OB:
14846        case OPC_PICK_PW:
14847        case OPC_PICK_QH:
14848            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14849            break;
14850        default:            /* Invalid */
14851            MIPS_INVAL("MASK CMPU_EQ.OB");
14852            gen_reserved_instruction(ctx);
14853            break;
14854        }
14855        break;
14856    case OPC_DAPPEND_DSP:
14857        gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
14858        break;
14859    case OPC_DEXTR_W_DSP:
14860        op2 = MASK_DEXTR_W(ctx->opcode);
14861        switch (op2) {
14862        case OPC_DEXTP:
14863        case OPC_DEXTPDP:
14864        case OPC_DEXTPDPV:
14865        case OPC_DEXTPV:
14866        case OPC_DEXTR_L:
14867        case OPC_DEXTR_R_L:
14868        case OPC_DEXTR_RS_L:
14869        case OPC_DEXTR_W:
14870        case OPC_DEXTR_R_W:
14871        case OPC_DEXTR_RS_W:
14872        case OPC_DEXTR_S_H:
14873        case OPC_DEXTRV_L:
14874        case OPC_DEXTRV_R_L:
14875        case OPC_DEXTRV_RS_L:
14876        case OPC_DEXTRV_S_H:
14877        case OPC_DEXTRV_W:
14878        case OPC_DEXTRV_R_W:
14879        case OPC_DEXTRV_RS_W:
14880            gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14881            break;
14882        case OPC_DMTHLIP:
14883        case OPC_DSHILO:
14884        case OPC_DSHILOV:
14885            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14886            break;
14887        default:            /* Invalid */
14888            MIPS_INVAL("MASK EXTR.W");
14889            gen_reserved_instruction(ctx);
14890            break;
14891        }
14892        break;
14893    case OPC_DPAQ_W_QH_DSP:
14894        op2 = MASK_DPAQ_W_QH(ctx->opcode);
14895        switch (op2) {
14896        case OPC_DPAU_H_OBL:
14897        case OPC_DPAU_H_OBR:
14898        case OPC_DPSU_H_OBL:
14899        case OPC_DPSU_H_OBR:
14900        case OPC_DPA_W_QH:
14901        case OPC_DPAQ_S_W_QH:
14902        case OPC_DPS_W_QH:
14903        case OPC_DPSQ_S_W_QH:
14904        case OPC_MULSAQ_S_W_QH:
14905        case OPC_DPAQ_SA_L_PW:
14906        case OPC_DPSQ_SA_L_PW:
14907        case OPC_MULSAQ_S_L_PW:
14908            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14909            break;
14910        case OPC_MAQ_S_W_QHLL:
14911        case OPC_MAQ_S_W_QHLR:
14912        case OPC_MAQ_S_W_QHRL:
14913        case OPC_MAQ_S_W_QHRR:
14914        case OPC_MAQ_SA_W_QHLL:
14915        case OPC_MAQ_SA_W_QHLR:
14916        case OPC_MAQ_SA_W_QHRL:
14917        case OPC_MAQ_SA_W_QHRR:
14918        case OPC_MAQ_S_L_PWL:
14919        case OPC_MAQ_S_L_PWR:
14920        case OPC_DMADD:
14921        case OPC_DMADDU:
14922        case OPC_DMSUB:
14923        case OPC_DMSUBU:
14924            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14925            break;
14926        default:            /* Invalid */
14927            MIPS_INVAL("MASK DPAQ.W.QH");
14928            gen_reserved_instruction(ctx);
14929            break;
14930        }
14931        break;
14932    case OPC_DINSV_DSP:
14933        op2 = MASK_INSV(ctx->opcode);
14934        switch (op2) {
14935        case OPC_DINSV:
14936        {
14937            TCGv t0, t1;
14938
14939            check_dsp(ctx);
14940
14941            if (rt == 0) {
14942                break;
14943            }
14944
14945            t0 = tcg_temp_new();
14946            t1 = tcg_temp_new();
14947
14948            gen_load_gpr(t0, rt);
14949            gen_load_gpr(t1, rs);
14950
14951            gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
14952
14953            tcg_temp_free(t0);
14954            tcg_temp_free(t1);
14955            break;
14956        }
14957        default:            /* Invalid */
14958            MIPS_INVAL("MASK DINSV");
14959            gen_reserved_instruction(ctx);
14960            break;
14961        }
14962        break;
14963    case OPC_SHLL_OB_DSP:
14964        gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14965        break;
14966#endif
14967    default:            /* Invalid */
14968        MIPS_INVAL("special3_legacy");
14969        gen_reserved_instruction(ctx);
14970        break;
14971    }
14972}
14973
14974
14975#if defined(TARGET_MIPS64)
14976
14977static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
14978{
14979    uint32_t opc = MASK_MMI(ctx->opcode);
14980    int rs = extract32(ctx->opcode, 21, 5);
14981    int rt = extract32(ctx->opcode, 16, 5);
14982    int rd = extract32(ctx->opcode, 11, 5);
14983
14984    switch (opc) {
14985    case MMI_OPC_MULT1:
14986    case MMI_OPC_MULTU1:
14987    case MMI_OPC_MADD:
14988    case MMI_OPC_MADDU:
14989    case MMI_OPC_MADD1:
14990    case MMI_OPC_MADDU1:
14991        gen_mul_txx9(ctx, opc, rd, rs, rt);
14992        break;
14993    case MMI_OPC_DIV1:
14994    case MMI_OPC_DIVU1:
14995        gen_div1_tx79(ctx, opc, rs, rt);
14996        break;
14997    default:
14998        MIPS_INVAL("TX79 MMI class");
14999        gen_reserved_instruction(ctx);
15000        break;
15001    }
15002}
15003
15004static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
15005{
15006    gen_reserved_instruction(ctx);    /* TODO: MMI_OPC_SQ */
15007}
15008
15009/*
15010 * The TX79-specific instruction Store Quadword
15011 *
15012 * +--------+-------+-------+------------------------+
15013 * | 011111 |  base |   rt  |           offset       | SQ
15014 * +--------+-------+-------+------------------------+
15015 *      6       5       5                 16
15016 *
15017 * has the same opcode as the Read Hardware Register instruction
15018 *
15019 * +--------+-------+-------+-------+-------+--------+
15020 * | 011111 | 00000 |   rt  |   rd  | 00000 | 111011 | RDHWR
15021 * +--------+-------+-------+-------+-------+--------+
15022 *      6       5       5       5       5        6
15023 *
15024 * that is required, trapped and emulated by the Linux kernel. However, all
15025 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
15026 * offset is odd. Therefore all valid SQ instructions can execute normally.
15027 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
15028 * between SQ and RDHWR, as the Linux kernel does.
15029 */
15030static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
15031{
15032    int base = extract32(ctx->opcode, 21, 5);
15033    int rt = extract32(ctx->opcode, 16, 5);
15034    int offset = extract32(ctx->opcode, 0, 16);
15035
15036#ifdef CONFIG_USER_ONLY
15037    uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
15038    uint32_t op2 = extract32(ctx->opcode, 6, 5);
15039
15040    if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
15041        int rd = extract32(ctx->opcode, 11, 5);
15042
15043        gen_rdhwr(ctx, rt, rd, 0);
15044        return;
15045    }
15046#endif
15047
15048    gen_mmi_sq(ctx, base, rt, offset);
15049}
15050
15051#endif
15052
15053static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
15054{
15055    int rs, rt, rd, sa;
15056    uint32_t op1, op2;
15057    int16_t imm;
15058
15059    rs = (ctx->opcode >> 21) & 0x1f;
15060    rt = (ctx->opcode >> 16) & 0x1f;
15061    rd = (ctx->opcode >> 11) & 0x1f;
15062    sa = (ctx->opcode >> 6) & 0x1f;
15063    imm = sextract32(ctx->opcode, 7, 9);
15064
15065    op1 = MASK_SPECIAL3(ctx->opcode);
15066
15067    /*
15068     * EVA loads and stores overlap Loongson 2E instructions decoded by
15069     * decode_opc_special3_legacy(), so be careful to allow their decoding when
15070     * EVA is absent.
15071     */
15072    if (ctx->eva) {
15073        switch (op1) {
15074        case OPC_LWLE:
15075        case OPC_LWRE:
15076        case OPC_LBUE:
15077        case OPC_LHUE:
15078        case OPC_LBE:
15079        case OPC_LHE:
15080        case OPC_LLE:
15081        case OPC_LWE:
15082            check_cp0_enabled(ctx);
15083            gen_ld(ctx, op1, rt, rs, imm);
15084            return;
15085        case OPC_SWLE:
15086        case OPC_SWRE:
15087        case OPC_SBE:
15088        case OPC_SHE:
15089        case OPC_SWE:
15090            check_cp0_enabled(ctx);
15091            gen_st(ctx, op1, rt, rs, imm);
15092            return;
15093        case OPC_SCE:
15094            check_cp0_enabled(ctx);
15095            gen_st_cond(ctx, rt, rs, imm, MO_TESL, true);
15096            return;
15097        case OPC_CACHEE:
15098            check_eva(ctx);
15099            check_cp0_enabled(ctx);
15100            if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15101                gen_cache_operation(ctx, rt, rs, imm);
15102            }
15103            return;
15104        case OPC_PREFE:
15105            check_cp0_enabled(ctx);
15106            /* Treat as NOP. */
15107            return;
15108        }
15109    }
15110
15111    switch (op1) {
15112    case OPC_EXT:
15113    case OPC_INS:
15114        check_insn(ctx, ISA_MIPS_R2);
15115        gen_bitops(ctx, op1, rt, rs, sa, rd);
15116        break;
15117    case OPC_BSHFL:
15118        op2 = MASK_BSHFL(ctx->opcode);
15119        switch (op2) {
15120        case OPC_ALIGN:
15121        case OPC_ALIGN_1:
15122        case OPC_ALIGN_2:
15123        case OPC_ALIGN_3:
15124        case OPC_BITSWAP:
15125            check_insn(ctx, ISA_MIPS_R6);
15126            decode_opc_special3_r6(env, ctx);
15127            break;
15128        default:
15129            check_insn(ctx, ISA_MIPS_R2);
15130            gen_bshfl(ctx, op2, rt, rd);
15131            break;
15132        }
15133        break;
15134#if defined(TARGET_MIPS64)
15135    case OPC_DEXTM:
15136    case OPC_DEXTU:
15137    case OPC_DEXT:
15138    case OPC_DINSM:
15139    case OPC_DINSU:
15140    case OPC_DINS:
15141        check_insn(ctx, ISA_MIPS_R2);
15142        check_mips_64(ctx);
15143        gen_bitops(ctx, op1, rt, rs, sa, rd);
15144        break;
15145    case OPC_DBSHFL:
15146        op2 = MASK_DBSHFL(ctx->opcode);
15147        switch (op2) {
15148        case OPC_DALIGN:
15149        case OPC_DALIGN_1:
15150        case OPC_DALIGN_2:
15151        case OPC_DALIGN_3:
15152        case OPC_DALIGN_4:
15153        case OPC_DALIGN_5:
15154        case OPC_DALIGN_6:
15155        case OPC_DALIGN_7:
15156        case OPC_DBITSWAP:
15157            check_insn(ctx, ISA_MIPS_R6);
15158            decode_opc_special3_r6(env, ctx);
15159            break;
15160        default:
15161            check_insn(ctx, ISA_MIPS_R2);
15162            check_mips_64(ctx);
15163            op2 = MASK_DBSHFL(ctx->opcode);
15164            gen_bshfl(ctx, op2, rt, rd);
15165            break;
15166        }
15167        break;
15168#endif
15169    case OPC_RDHWR:
15170        gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
15171        break;
15172    case OPC_FORK:
15173        check_mt(ctx);
15174        {
15175            TCGv t0 = tcg_temp_new();
15176            TCGv t1 = tcg_temp_new();
15177
15178            gen_load_gpr(t0, rt);
15179            gen_load_gpr(t1, rs);
15180            gen_helper_fork(t0, t1);
15181            tcg_temp_free(t0);
15182            tcg_temp_free(t1);
15183        }
15184        break;
15185    case OPC_YIELD:
15186        check_mt(ctx);
15187        {
15188            TCGv t0 = tcg_temp_new();
15189
15190            gen_load_gpr(t0, rs);
15191            gen_helper_yield(t0, cpu_env, t0);
15192            gen_store_gpr(t0, rd);
15193            tcg_temp_free(t0);
15194        }
15195        break;
15196    default:
15197        if (ctx->insn_flags & ISA_MIPS_R6) {
15198            decode_opc_special3_r6(env, ctx);
15199        } else {
15200            decode_opc_special3_legacy(env, ctx);
15201        }
15202    }
15203}
15204
15205static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
15206{
15207    int32_t offset;
15208    int rs, rt, rd, sa;
15209    uint32_t op, op1;
15210    int16_t imm;
15211
15212    op = MASK_OP_MAJOR(ctx->opcode);
15213    rs = (ctx->opcode >> 21) & 0x1f;
15214    rt = (ctx->opcode >> 16) & 0x1f;
15215    rd = (ctx->opcode >> 11) & 0x1f;
15216    sa = (ctx->opcode >> 6) & 0x1f;
15217    imm = (int16_t)ctx->opcode;
15218    switch (op) {
15219    case OPC_SPECIAL:
15220        decode_opc_special(env, ctx);
15221        break;
15222    case OPC_SPECIAL2:
15223#if defined(TARGET_MIPS64)
15224        if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
15225            decode_mmi(env, ctx);
15226            break;
15227        }
15228#endif
15229        if (TARGET_LONG_BITS == 32 && (ctx->insn_flags & ASE_MXU)) {
15230            if (MASK_SPECIAL2(ctx->opcode) == OPC_MUL) {
15231                gen_arith(ctx, OPC_MUL, rd, rs, rt);
15232            } else {
15233                decode_ase_mxu(ctx, ctx->opcode);
15234            }
15235            break;
15236        }
15237        decode_opc_special2_legacy(env, ctx);
15238        break;
15239    case OPC_SPECIAL3:
15240#if defined(TARGET_MIPS64)
15241        if (ctx->insn_flags & INSN_R5900) {
15242            decode_mmi_sq(env, ctx);    /* MMI_OPC_SQ */
15243        } else {
15244            decode_opc_special3(env, ctx);
15245        }
15246#else
15247        decode_opc_special3(env, ctx);
15248#endif
15249        break;
15250    case OPC_REGIMM:
15251        op1 = MASK_REGIMM(ctx->opcode);
15252        switch (op1) {
15253        case OPC_BLTZL: /* REGIMM branches */
15254        case OPC_BGEZL:
15255        case OPC_BLTZALL:
15256        case OPC_BGEZALL:
15257            check_insn(ctx, ISA_MIPS2);
15258            check_insn_opc_removed(ctx, ISA_MIPS_R6);
15259            /* Fallthrough */
15260        case OPC_BLTZ:
15261        case OPC_BGEZ:
15262            gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
15263            break;
15264        case OPC_BLTZAL:
15265        case OPC_BGEZAL:
15266            if (ctx->insn_flags & ISA_MIPS_R6) {
15267                if (rs == 0) {
15268                    /* OPC_NAL, OPC_BAL */
15269                    gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
15270                } else {
15271                    gen_reserved_instruction(ctx);
15272                }
15273            } else {
15274                gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
15275            }
15276            break;
15277        case OPC_TGEI: /* REGIMM traps */
15278        case OPC_TGEIU:
15279        case OPC_TLTI:
15280        case OPC_TLTIU:
15281        case OPC_TEQI:
15282
15283        case OPC_TNEI:
15284            check_insn(ctx, ISA_MIPS2);
15285            check_insn_opc_removed(ctx, ISA_MIPS_R6);
15286            gen_trap(ctx, op1, rs, -1, imm);
15287            break;
15288        case OPC_SIGRIE:
15289            check_insn(ctx, ISA_MIPS_R6);
15290            gen_reserved_instruction(ctx);
15291            break;
15292        case OPC_SYNCI:
15293            check_insn(ctx, ISA_MIPS_R2);
15294            /*
15295             * Break the TB to be able to sync copied instructions
15296             * immediately.
15297             */
15298            ctx->base.is_jmp = DISAS_STOP;
15299            break;
15300        case OPC_BPOSGE32:    /* MIPS DSP branch */
15301#if defined(TARGET_MIPS64)
15302        case OPC_BPOSGE64:
15303#endif
15304            check_dsp(ctx);
15305            gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
15306            break;
15307#if defined(TARGET_MIPS64)
15308        case OPC_DAHI:
15309            check_insn(ctx, ISA_MIPS_R6);
15310            check_mips_64(ctx);
15311            if (rs != 0) {
15312                tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
15313            }
15314            break;
15315        case OPC_DATI:
15316            check_insn(ctx, ISA_MIPS_R6);
15317            check_mips_64(ctx);
15318            if (rs != 0) {
15319                tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
15320            }
15321            break;
15322#endif
15323        default:            /* Invalid */
15324            MIPS_INVAL("regimm");
15325            gen_reserved_instruction(ctx);
15326            break;
15327        }
15328        break;
15329    case OPC_CP0:
15330        check_cp0_enabled(ctx);
15331        op1 = MASK_CP0(ctx->opcode);
15332        switch (op1) {
15333        case OPC_MFC0:
15334        case OPC_MTC0:
15335        case OPC_MFTR:
15336        case OPC_MTTR:
15337        case OPC_MFHC0:
15338        case OPC_MTHC0:
15339#if defined(TARGET_MIPS64)
15340        case OPC_DMFC0:
15341        case OPC_DMTC0:
15342#endif
15343#ifndef CONFIG_USER_ONLY
15344            gen_cp0(env, ctx, op1, rt, rd);
15345#endif /* !CONFIG_USER_ONLY */
15346            break;
15347        case OPC_C0:
15348        case OPC_C0_1:
15349        case OPC_C0_2:
15350        case OPC_C0_3:
15351        case OPC_C0_4:
15352        case OPC_C0_5:
15353        case OPC_C0_6:
15354        case OPC_C0_7:
15355        case OPC_C0_8:
15356        case OPC_C0_9:
15357        case OPC_C0_A:
15358        case OPC_C0_B:
15359        case OPC_C0_C:
15360        case OPC_C0_D:
15361        case OPC_C0_E:
15362        case OPC_C0_F:
15363#ifndef CONFIG_USER_ONLY
15364            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15365#endif /* !CONFIG_USER_ONLY */
15366            break;
15367        case OPC_MFMC0:
15368#ifndef CONFIG_USER_ONLY
15369            {
15370                uint32_t op2;
15371                TCGv t0 = tcg_temp_new();
15372
15373                op2 = MASK_MFMC0(ctx->opcode);
15374                switch (op2) {
15375                case OPC_DMT:
15376                    check_cp0_mt(ctx);
15377                    gen_helper_dmt(t0);
15378                    gen_store_gpr(t0, rt);
15379                    break;
15380                case OPC_EMT:
15381                    check_cp0_mt(ctx);
15382                    gen_helper_emt(t0);
15383                    gen_store_gpr(t0, rt);
15384                    break;
15385                case OPC_DVPE:
15386                    check_cp0_mt(ctx);
15387                    gen_helper_dvpe(t0, cpu_env);
15388                    gen_store_gpr(t0, rt);
15389                    break;
15390                case OPC_EVPE:
15391                    check_cp0_mt(ctx);
15392                    gen_helper_evpe(t0, cpu_env);
15393                    gen_store_gpr(t0, rt);
15394                    break;
15395                case OPC_DVP:
15396                    check_insn(ctx, ISA_MIPS_R6);
15397                    if (ctx->vp) {
15398                        gen_helper_dvp(t0, cpu_env);
15399                        gen_store_gpr(t0, rt);
15400                    }
15401                    break;
15402                case OPC_EVP:
15403                    check_insn(ctx, ISA_MIPS_R6);
15404                    if (ctx->vp) {
15405                        gen_helper_evp(t0, cpu_env);
15406                        gen_store_gpr(t0, rt);
15407                    }
15408                    break;
15409                case OPC_DI:
15410                    check_insn(ctx, ISA_MIPS_R2);
15411                    save_cpu_state(ctx, 1);
15412                    gen_helper_di(t0, cpu_env);
15413                    gen_store_gpr(t0, rt);
15414                    /*
15415                     * Stop translation as we may have switched
15416                     * the execution mode.
15417                     */
15418                    ctx->base.is_jmp = DISAS_STOP;
15419                    break;
15420                case OPC_EI:
15421                    check_insn(ctx, ISA_MIPS_R2);
15422                    save_cpu_state(ctx, 1);
15423                    gen_helper_ei(t0, cpu_env);
15424                    gen_store_gpr(t0, rt);
15425                    /*
15426                     * DISAS_STOP isn't sufficient, we need to ensure we break
15427                     * out of translated code to check for pending interrupts.
15428                     */
15429                    gen_save_pc(ctx->base.pc_next + 4);
15430                    ctx->base.is_jmp = DISAS_EXIT;
15431                    break;
15432                default:            /* Invalid */
15433                    MIPS_INVAL("mfmc0");
15434                    gen_reserved_instruction(ctx);
15435                    break;
15436                }
15437                tcg_temp_free(t0);
15438            }
15439#endif /* !CONFIG_USER_ONLY */
15440            break;
15441        case OPC_RDPGPR:
15442            check_insn(ctx, ISA_MIPS_R2);
15443            gen_load_srsgpr(rt, rd);
15444            break;
15445        case OPC_WRPGPR:
15446            check_insn(ctx, ISA_MIPS_R2);
15447            gen_store_srsgpr(rt, rd);
15448            break;
15449        default:
15450            MIPS_INVAL("cp0");
15451            gen_reserved_instruction(ctx);
15452            break;
15453        }
15454        break;
15455    case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
15456        if (ctx->insn_flags & ISA_MIPS_R6) {
15457            /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
15458            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15459        } else {
15460            /* OPC_ADDI */
15461            /* Arithmetic with immediate opcode */
15462            gen_arith_imm(ctx, op, rt, rs, imm);
15463        }
15464        break;
15465    case OPC_ADDIU:
15466         gen_arith_imm(ctx, op, rt, rs, imm);
15467         break;
15468    case OPC_SLTI: /* Set on less than with immediate opcode */
15469    case OPC_SLTIU:
15470         gen_slt_imm(ctx, op, rt, rs, imm);
15471         break;
15472    case OPC_ANDI: /* Arithmetic with immediate opcode */
15473    case OPC_LUI: /* OPC_AUI */
15474    case OPC_ORI:
15475    case OPC_XORI:
15476         gen_logic_imm(ctx, op, rt, rs, imm);
15477         break;
15478    case OPC_J: /* Jump */
15479    case OPC_JAL:
15480         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15481         gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
15482         break;
15483    /* Branch */
15484    case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
15485        if (ctx->insn_flags & ISA_MIPS_R6) {
15486            if (rt == 0) {
15487                gen_reserved_instruction(ctx);
15488                break;
15489            }
15490            /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
15491            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15492        } else {
15493            /* OPC_BLEZL */
15494            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15495        }
15496        break;
15497    case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
15498        if (ctx->insn_flags & ISA_MIPS_R6) {
15499            if (rt == 0) {
15500                gen_reserved_instruction(ctx);
15501                break;
15502            }
15503            /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
15504            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15505        } else {
15506            /* OPC_BGTZL */
15507            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15508        }
15509        break;
15510    case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
15511        if (rt == 0) {
15512            /* OPC_BLEZ */
15513            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15514        } else {
15515            check_insn(ctx, ISA_MIPS_R6);
15516            /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
15517            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15518        }
15519        break;
15520    case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
15521        if (rt == 0) {
15522            /* OPC_BGTZ */
15523            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15524        } else {
15525            check_insn(ctx, ISA_MIPS_R6);
15526            /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
15527            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15528        }
15529        break;
15530    case OPC_BEQL:
15531    case OPC_BNEL:
15532        check_insn(ctx, ISA_MIPS2);
15533         check_insn_opc_removed(ctx, ISA_MIPS_R6);
15534        /* Fallthrough */
15535    case OPC_BEQ:
15536    case OPC_BNE:
15537         gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
15538         break;
15539    case OPC_LL: /* Load and stores */
15540        check_insn(ctx, ISA_MIPS2);
15541        if (ctx->insn_flags & INSN_R5900) {
15542            check_insn_opc_user_only(ctx, INSN_R5900);
15543        }
15544        /* Fallthrough */
15545    case OPC_LWL:
15546    case OPC_LWR:
15547    case OPC_LB:
15548    case OPC_LH:
15549    case OPC_LW:
15550    case OPC_LWPC:
15551    case OPC_LBU:
15552    case OPC_LHU:
15553         gen_ld(ctx, op, rt, rs, imm);
15554         break;
15555    case OPC_SWL:
15556    case OPC_SWR:
15557    case OPC_SB:
15558    case OPC_SH:
15559    case OPC_SW:
15560         gen_st(ctx, op, rt, rs, imm);
15561         break;
15562    case OPC_SC:
15563        check_insn(ctx, ISA_MIPS2);
15564        if (ctx->insn_flags & INSN_R5900) {
15565            check_insn_opc_user_only(ctx, INSN_R5900);
15566        }
15567        gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
15568        break;
15569    case OPC_CACHE:
15570        check_cp0_enabled(ctx);
15571        check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
15572        if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15573            gen_cache_operation(ctx, rt, rs, imm);
15574        }
15575        /* Treat as NOP. */
15576        break;
15577    case OPC_PREF:
15578        check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 | INSN_R5900);
15579        /* Treat as NOP. */
15580        break;
15581
15582    /* Floating point (COP1). */
15583    case OPC_LWC1:
15584    case OPC_LDC1:
15585    case OPC_SWC1:
15586    case OPC_SDC1:
15587        gen_cop1_ldst(ctx, op, rt, rs, imm);
15588        break;
15589
15590    case OPC_CP1:
15591        op1 = MASK_CP1(ctx->opcode);
15592
15593        switch (op1) {
15594        case OPC_MFHC1:
15595        case OPC_MTHC1:
15596            check_cp1_enabled(ctx);
15597            check_insn(ctx, ISA_MIPS_R2);
15598            /* fall through */
15599        case OPC_MFC1:
15600        case OPC_CFC1:
15601        case OPC_MTC1:
15602        case OPC_CTC1:
15603            check_cp1_enabled(ctx);
15604            gen_cp1(ctx, op1, rt, rd);
15605            break;
15606#if defined(TARGET_MIPS64)
15607        case OPC_DMFC1:
15608        case OPC_DMTC1:
15609            check_cp1_enabled(ctx);
15610            check_insn(ctx, ISA_MIPS3);
15611            check_mips_64(ctx);
15612            gen_cp1(ctx, op1, rt, rd);
15613            break;
15614#endif
15615        case OPC_BC1EQZ: /* OPC_BC1ANY2 */
15616            check_cp1_enabled(ctx);
15617            if (ctx->insn_flags & ISA_MIPS_R6) {
15618                /* OPC_BC1EQZ */
15619                gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
15620                                       rt, imm << 2, 4);
15621            } else {
15622                /* OPC_BC1ANY2 */
15623                check_cop1x(ctx);
15624                check_insn(ctx, ASE_MIPS3D);
15625                gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
15626                                    (rt >> 2) & 0x7, imm << 2);
15627            }
15628            break;
15629        case OPC_BC1NEZ:
15630            check_cp1_enabled(ctx);
15631            check_insn(ctx, ISA_MIPS_R6);
15632            gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
15633                                   rt, imm << 2, 4);
15634            break;
15635        case OPC_BC1ANY4:
15636            check_cp1_enabled(ctx);
15637            check_insn_opc_removed(ctx, ISA_MIPS_R6);
15638            check_cop1x(ctx);
15639            check_insn(ctx, ASE_MIPS3D);
15640            /* fall through */
15641        case OPC_BC1:
15642            check_cp1_enabled(ctx);
15643            check_insn_opc_removed(ctx, ISA_MIPS_R6);
15644            gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
15645                                (rt >> 2) & 0x7, imm << 2);
15646            break;
15647        case OPC_PS_FMT:
15648            check_ps(ctx);
15649            /* fall through */
15650        case OPC_S_FMT:
15651        case OPC_D_FMT:
15652            check_cp1_enabled(ctx);
15653            gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15654                       (imm >> 8) & 0x7);
15655            break;
15656        case OPC_W_FMT:
15657        case OPC_L_FMT:
15658        {
15659            int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
15660            check_cp1_enabled(ctx);
15661            if (ctx->insn_flags & ISA_MIPS_R6) {
15662                switch (r6_op) {
15663                case R6_OPC_CMP_AF_S:
15664                case R6_OPC_CMP_UN_S:
15665                case R6_OPC_CMP_EQ_S:
15666                case R6_OPC_CMP_UEQ_S:
15667                case R6_OPC_CMP_LT_S:
15668                case R6_OPC_CMP_ULT_S:
15669                case R6_OPC_CMP_LE_S:
15670                case R6_OPC_CMP_ULE_S:
15671                case R6_OPC_CMP_SAF_S:
15672                case R6_OPC_CMP_SUN_S:
15673                case R6_OPC_CMP_SEQ_S:
15674                case R6_OPC_CMP_SEUQ_S:
15675                case R6_OPC_CMP_SLT_S:
15676                case R6_OPC_CMP_SULT_S:
15677                case R6_OPC_CMP_SLE_S:
15678                case R6_OPC_CMP_SULE_S:
15679                case R6_OPC_CMP_OR_S:
15680                case R6_OPC_CMP_UNE_S:
15681                case R6_OPC_CMP_NE_S:
15682                case R6_OPC_CMP_SOR_S:
15683                case R6_OPC_CMP_SUNE_S:
15684                case R6_OPC_CMP_SNE_S:
15685                    gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
15686                    break;
15687                case R6_OPC_CMP_AF_D:
15688                case R6_OPC_CMP_UN_D:
15689                case R6_OPC_CMP_EQ_D:
15690                case R6_OPC_CMP_UEQ_D:
15691                case R6_OPC_CMP_LT_D:
15692                case R6_OPC_CMP_ULT_D:
15693                case R6_OPC_CMP_LE_D:
15694                case R6_OPC_CMP_ULE_D:
15695                case R6_OPC_CMP_SAF_D:
15696                case R6_OPC_CMP_SUN_D:
15697                case R6_OPC_CMP_SEQ_D:
15698                case R6_OPC_CMP_SEUQ_D:
15699                case R6_OPC_CMP_SLT_D:
15700                case R6_OPC_CMP_SULT_D:
15701                case R6_OPC_CMP_SLE_D:
15702                case R6_OPC_CMP_SULE_D:
15703                case R6_OPC_CMP_OR_D:
15704                case R6_OPC_CMP_UNE_D:
15705                case R6_OPC_CMP_NE_D:
15706                case R6_OPC_CMP_SOR_D:
15707                case R6_OPC_CMP_SUNE_D:
15708                case R6_OPC_CMP_SNE_D:
15709                    gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
15710                    break;
15711                default:
15712                    gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
15713                               rt, rd, sa, (imm >> 8) & 0x7);
15714
15715                    break;
15716                }
15717            } else {
15718                gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15719                           (imm >> 8) & 0x7);
15720            }
15721            break;
15722        }
15723        default:
15724            MIPS_INVAL("cp1");
15725            gen_reserved_instruction(ctx);
15726            break;
15727        }
15728        break;
15729
15730    /* Compact branches [R6] and COP2 [non-R6] */
15731    case OPC_BC: /* OPC_LWC2 */
15732    case OPC_BALC: /* OPC_SWC2 */
15733        if (ctx->insn_flags & ISA_MIPS_R6) {
15734            /* OPC_BC, OPC_BALC */
15735            gen_compute_compact_branch(ctx, op, 0, 0,
15736                                       sextract32(ctx->opcode << 2, 0, 28));
15737        } else if (ctx->insn_flags & ASE_LEXT) {
15738            gen_loongson_lswc2(ctx, rt, rs, rd);
15739        } else {
15740            /* OPC_LWC2, OPC_SWC2 */
15741            /* COP2: Not implemented. */
15742            generate_exception_err(ctx, EXCP_CpU, 2);
15743        }
15744        break;
15745    case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
15746    case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
15747        if (ctx->insn_flags & ISA_MIPS_R6) {
15748            if (rs != 0) {
15749                /* OPC_BEQZC, OPC_BNEZC */
15750                gen_compute_compact_branch(ctx, op, rs, 0,
15751                                           sextract32(ctx->opcode << 2, 0, 23));
15752            } else {
15753                /* OPC_JIC, OPC_JIALC */
15754                gen_compute_compact_branch(ctx, op, 0, rt, imm);
15755            }
15756        } else if (ctx->insn_flags & ASE_LEXT) {
15757            gen_loongson_lsdc2(ctx, rt, rs, rd);
15758        } else {
15759            /* OPC_LWC2, OPC_SWC2 */
15760            /* COP2: Not implemented. */
15761            generate_exception_err(ctx, EXCP_CpU, 2);
15762        }
15763        break;
15764    case OPC_CP2:
15765        check_insn(ctx, ASE_LMMI);
15766        /* Note that these instructions use different fields.  */
15767        gen_loongson_multimedia(ctx, sa, rd, rt);
15768        break;
15769
15770    case OPC_CP3:
15771        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
15772            check_cp1_enabled(ctx);
15773            op1 = MASK_CP3(ctx->opcode);
15774            switch (op1) {
15775            case OPC_LUXC1:
15776            case OPC_SUXC1:
15777                check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
15778                /* Fallthrough */
15779            case OPC_LWXC1:
15780            case OPC_LDXC1:
15781            case OPC_SWXC1:
15782            case OPC_SDXC1:
15783                check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
15784                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15785                break;
15786            case OPC_PREFX:
15787                check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
15788                /* Treat as NOP. */
15789                break;
15790            case OPC_ALNV_PS:
15791                check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
15792                /* Fallthrough */
15793            case OPC_MADD_S:
15794            case OPC_MADD_D:
15795            case OPC_MADD_PS:
15796            case OPC_MSUB_S:
15797            case OPC_MSUB_D:
15798            case OPC_MSUB_PS:
15799            case OPC_NMADD_S:
15800            case OPC_NMADD_D:
15801            case OPC_NMADD_PS:
15802            case OPC_NMSUB_S:
15803            case OPC_NMSUB_D:
15804            case OPC_NMSUB_PS:
15805                check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
15806                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15807                break;
15808            default:
15809                MIPS_INVAL("cp3");
15810                gen_reserved_instruction(ctx);
15811                break;
15812            }
15813        } else {
15814            generate_exception_err(ctx, EXCP_CpU, 1);
15815        }
15816        break;
15817
15818#if defined(TARGET_MIPS64)
15819    /* MIPS64 opcodes */
15820    case OPC_LLD:
15821        if (ctx->insn_flags & INSN_R5900) {
15822            check_insn_opc_user_only(ctx, INSN_R5900);
15823        }
15824        /* fall through */
15825    case OPC_LDL:
15826    case OPC_LDR:
15827    case OPC_LWU:
15828    case OPC_LD:
15829        check_insn(ctx, ISA_MIPS3);
15830        check_mips_64(ctx);
15831        gen_ld(ctx, op, rt, rs, imm);
15832        break;
15833    case OPC_SDL:
15834    case OPC_SDR:
15835    case OPC_SD:
15836        check_insn(ctx, ISA_MIPS3);
15837        check_mips_64(ctx);
15838        gen_st(ctx, op, rt, rs, imm);
15839        break;
15840    case OPC_SCD:
15841        check_insn(ctx, ISA_MIPS3);
15842        if (ctx->insn_flags & INSN_R5900) {
15843            check_insn_opc_user_only(ctx, INSN_R5900);
15844        }
15845        check_mips_64(ctx);
15846        gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
15847        break;
15848    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
15849        if (ctx->insn_flags & ISA_MIPS_R6) {
15850            /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
15851            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15852        } else {
15853            /* OPC_DADDI */
15854            check_insn(ctx, ISA_MIPS3);
15855            check_mips_64(ctx);
15856            gen_arith_imm(ctx, op, rt, rs, imm);
15857        }
15858        break;
15859    case OPC_DADDIU:
15860        check_insn(ctx, ISA_MIPS3);
15861        check_mips_64(ctx);
15862        gen_arith_imm(ctx, op, rt, rs, imm);
15863        break;
15864#else
15865    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
15866        if (ctx->insn_flags & ISA_MIPS_R6) {
15867            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
15868        } else {
15869            MIPS_INVAL("major opcode");
15870            gen_reserved_instruction(ctx);
15871        }
15872        break;
15873#endif
15874    case OPC_DAUI: /* OPC_JALX */
15875        if (ctx->insn_flags & ISA_MIPS_R6) {
15876#if defined(TARGET_MIPS64)
15877            /* OPC_DAUI */
15878            check_mips_64(ctx);
15879            if (rs == 0) {
15880                generate_exception(ctx, EXCP_RI);
15881            } else if (rt != 0) {
15882                TCGv t0 = tcg_temp_new();
15883                gen_load_gpr(t0, rs);
15884                tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
15885                tcg_temp_free(t0);
15886            }
15887#else
15888            gen_reserved_instruction(ctx);
15889            MIPS_INVAL("major opcode");
15890#endif
15891        } else {
15892            /* OPC_JALX */
15893            check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
15894            offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15895            gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
15896        }
15897        break;
15898    case OPC_MDMX:
15899        /* MDMX: Not implemented. */
15900        break;
15901    case OPC_PCREL:
15902        check_insn(ctx, ISA_MIPS_R6);
15903        gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
15904        break;
15905    default:            /* Invalid */
15906        MIPS_INVAL("major opcode");
15907        return false;
15908    }
15909    return true;
15910}
15911
15912static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
15913{
15914    /* make sure instructions are on a word boundary */
15915    if (ctx->base.pc_next & 0x3) {
15916        env->CP0_BadVAddr = ctx->base.pc_next;
15917        generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
15918        return;
15919    }
15920
15921    /* Handle blikely not taken case */
15922    if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
15923        TCGLabel *l1 = gen_new_label();
15924
15925        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
15926        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
15927        gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
15928        gen_set_label(l1);
15929    }
15930
15931    /* Transition to the auto-generated decoder.  */
15932
15933    /* Vendor specific extensions */
15934    if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) {
15935        return;
15936    }
15937    if (cpu_supports_isa(env, INSN_VR54XX) && decode_ext_vr54xx(ctx, ctx->opcode)) {
15938        return;
15939    }
15940
15941    /* ISA extensions */
15942    if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) {
15943        return;
15944    }
15945
15946    /* ISA (from latest to oldest) */
15947    if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) {
15948        return;
15949    }
15950
15951    if (decode_opc_legacy(env, ctx)) {
15952        return;
15953    }
15954
15955    gen_reserved_instruction(ctx);
15956}
15957
15958static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
15959{
15960    DisasContext *ctx = container_of(dcbase, DisasContext, base);
15961    CPUMIPSState *env = cs->env_ptr;
15962
15963    ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
15964    ctx->saved_pc = -1;
15965    ctx->insn_flags = env->insn_flags;
15966    ctx->CP0_Config0 = env->CP0_Config0;
15967    ctx->CP0_Config1 = env->CP0_Config1;
15968    ctx->CP0_Config2 = env->CP0_Config2;
15969    ctx->CP0_Config3 = env->CP0_Config3;
15970    ctx->CP0_Config5 = env->CP0_Config5;
15971    ctx->btarget = 0;
15972    ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
15973    ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
15974    ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
15975    ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
15976    ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
15977    ctx->PAMask = env->PAMask;
15978    ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
15979    ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
15980    ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
15981    ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
15982    ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
15983    /* Restore delay slot state from the tb context.  */
15984    ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
15985    ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
15986    ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
15987             (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
15988    ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
15989    ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
15990    ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
15991    ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
15992    ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1;
15993    ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3;
15994    restore_cpu_state(env, ctx);
15995#ifdef CONFIG_USER_ONLY
15996        ctx->mem_idx = MIPS_HFLAG_UM;
15997#else
15998        ctx->mem_idx = hflags_mmu_index(ctx->hflags);
15999#endif
16000    ctx->default_tcg_memop_mask = (ctx->insn_flags & (ISA_MIPS_R6 |
16001                                  INSN_LOONGSON3A)) ? MO_UNALN : MO_ALIGN;
16002
16003    /*
16004     * Execute a branch and its delay slot as a single instruction.
16005     * This is what GDB expects and is consistent with what the
16006     * hardware does (e.g. if a delay slot instruction faults, the
16007     * reported PC is the PC of the branch).
16008     */
16009    if (ctx->base.singlestep_enabled && (ctx->hflags & MIPS_HFLAG_BMASK)) {
16010        ctx->base.max_insns = 2;
16011    }
16012
16013    LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
16014              ctx->hflags);
16015}
16016
16017static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
16018{
16019}
16020
16021static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
16022{
16023    DisasContext *ctx = container_of(dcbase, DisasContext, base);
16024
16025    tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
16026                       ctx->btarget);
16027}
16028
16029static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
16030{
16031    CPUMIPSState *env = cs->env_ptr;
16032    DisasContext *ctx = container_of(dcbase, DisasContext, base);
16033    int insn_bytes;
16034    int is_slot;
16035
16036    is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
16037    if (ctx->insn_flags & ISA_NANOMIPS32) {
16038        ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
16039        insn_bytes = decode_isa_nanomips(env, ctx);
16040    } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
16041        ctx->opcode = translator_ldl(env, &ctx->base, ctx->base.pc_next);
16042        insn_bytes = 4;
16043        decode_opc(env, ctx);
16044    } else if (ctx->insn_flags & ASE_MICROMIPS) {
16045        ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
16046        insn_bytes = decode_isa_micromips(env, ctx);
16047    } else if (ctx->insn_flags & ASE_MIPS16) {
16048        ctx->opcode = translator_lduw(env, &ctx->base, ctx->base.pc_next);
16049        insn_bytes = decode_ase_mips16e(env, ctx);
16050    } else {
16051        gen_reserved_instruction(ctx);
16052        g_assert(ctx->base.is_jmp == DISAS_NORETURN);
16053        return;
16054    }
16055
16056    if (ctx->hflags & MIPS_HFLAG_BMASK) {
16057        if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
16058                             MIPS_HFLAG_FBNSLOT))) {
16059            /*
16060             * Force to generate branch as there is neither delay nor
16061             * forbidden slot.
16062             */
16063            is_slot = 1;
16064        }
16065        if ((ctx->hflags & MIPS_HFLAG_M16) &&
16066            (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
16067            /*
16068             * Force to generate branch as microMIPS R6 doesn't restrict
16069             * branches in the forbidden slot.
16070             */
16071            is_slot = 1;
16072        }
16073    }
16074    if (is_slot) {
16075        gen_branch(ctx, insn_bytes);
16076    }
16077    ctx->base.pc_next += insn_bytes;
16078
16079    if (ctx->base.is_jmp != DISAS_NEXT) {
16080        return;
16081    }
16082
16083    /*
16084     * End the TB on (most) page crossings.
16085     * See mips_tr_init_disas_context about single-stepping a branch
16086     * together with its delay slot.
16087     */
16088    if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE
16089        && !ctx->base.singlestep_enabled) {
16090        ctx->base.is_jmp = DISAS_TOO_MANY;
16091    }
16092}
16093
16094static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
16095{
16096    DisasContext *ctx = container_of(dcbase, DisasContext, base);
16097
16098    switch (ctx->base.is_jmp) {
16099    case DISAS_STOP:
16100        gen_save_pc(ctx->base.pc_next);
16101        tcg_gen_lookup_and_goto_ptr();
16102        break;
16103    case DISAS_NEXT:
16104    case DISAS_TOO_MANY:
16105        save_cpu_state(ctx, 0);
16106        gen_goto_tb(ctx, 0, ctx->base.pc_next);
16107        break;
16108    case DISAS_EXIT:
16109        tcg_gen_exit_tb(NULL, 0);
16110        break;
16111    case DISAS_NORETURN:
16112        break;
16113    default:
16114        g_assert_not_reached();
16115    }
16116}
16117
16118static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
16119{
16120    qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
16121    log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
16122}
16123
16124static const TranslatorOps mips_tr_ops = {
16125    .init_disas_context = mips_tr_init_disas_context,
16126    .tb_start           = mips_tr_tb_start,
16127    .insn_start         = mips_tr_insn_start,
16128    .translate_insn     = mips_tr_translate_insn,
16129    .tb_stop            = mips_tr_tb_stop,
16130    .disas_log          = mips_tr_disas_log,
16131};
16132
16133void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
16134{
16135    DisasContext ctx;
16136
16137    translator_loop(&mips_tr_ops, &ctx.base, cs, tb, max_insns);
16138}
16139
16140void mips_tcg_init(void)
16141{
16142    int i;
16143
16144    cpu_gpr[0] = NULL;
16145    for (i = 1; i < 32; i++)
16146        cpu_gpr[i] = tcg_global_mem_new(cpu_env,
16147                                        offsetof(CPUMIPSState,
16148                                                 active_tc.gpr[i]),
16149                                        regnames[i]);
16150#if defined(TARGET_MIPS64)
16151    cpu_gpr_hi[0] = NULL;
16152
16153    for (unsigned i = 1; i < 32; i++) {
16154        g_autofree char *rname = g_strdup_printf("%s[hi]", regnames[i]);
16155
16156        cpu_gpr_hi[i] = tcg_global_mem_new_i64(cpu_env,
16157                                               offsetof(CPUMIPSState,
16158                                                        active_tc.gpr_hi[i]),
16159                                               rname);
16160    }
16161#endif /* !TARGET_MIPS64 */
16162    for (i = 0; i < 32; i++) {
16163        int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
16164
16165        fpu_f64[i] = tcg_global_mem_new_i64(cpu_env, off, fregnames[i]);
16166    }
16167    msa_translate_init();
16168    cpu_PC = tcg_global_mem_new(cpu_env,
16169                                offsetof(CPUMIPSState, active_tc.PC), "PC");
16170    for (i = 0; i < MIPS_DSP_ACC; i++) {
16171        cpu_HI[i] = tcg_global_mem_new(cpu_env,
16172                                       offsetof(CPUMIPSState, active_tc.HI[i]),
16173                                       regnames_HI[i]);
16174        cpu_LO[i] = tcg_global_mem_new(cpu_env,
16175                                       offsetof(CPUMIPSState, active_tc.LO[i]),
16176                                       regnames_LO[i]);
16177    }
16178    cpu_dspctrl = tcg_global_mem_new(cpu_env,
16179                                     offsetof(CPUMIPSState,
16180                                              active_tc.DSPControl),
16181                                     "DSPControl");
16182    bcond = tcg_global_mem_new(cpu_env,
16183                               offsetof(CPUMIPSState, bcond), "bcond");
16184    btarget = tcg_global_mem_new(cpu_env,
16185                                 offsetof(CPUMIPSState, btarget), "btarget");
16186    hflags = tcg_global_mem_new_i32(cpu_env,
16187                                    offsetof(CPUMIPSState, hflags), "hflags");
16188
16189    fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
16190                                      offsetof(CPUMIPSState, active_fpu.fcr0),
16191                                      "fcr0");
16192    fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
16193                                       offsetof(CPUMIPSState, active_fpu.fcr31),
16194                                       "fcr31");
16195    cpu_lladdr = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, lladdr),
16196                                    "lladdr");
16197    cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval),
16198                                   "llval");
16199
16200    if (TARGET_LONG_BITS == 32) {
16201        mxu_translate_init();
16202    }
16203}
16204
16205void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
16206                          target_ulong *data)
16207{
16208    env->active_tc.PC = data[0];
16209    env->hflags &= ~MIPS_HFLAG_BMASK;
16210    env->hflags |= data[1];
16211    switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16212    case MIPS_HFLAG_BR:
16213        break;
16214    case MIPS_HFLAG_BC:
16215    case MIPS_HFLAG_BL:
16216    case MIPS_HFLAG_B:
16217        env->btarget = data[2];
16218        break;
16219    }
16220}
16221