qemu/target/mips/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 "target/mips/trace.h"
  35#include "trace-tcg.h"
  36#include "exec/translator.h"
  37#include "exec/log.h"
  38#include "qemu/qemu-print.h"
  39#include "fpu_helper.h"
  40#include "translate.h"
  41
  42enum {
  43    /* indirect opcode tables */
  44    OPC_SPECIAL  = (0x00 << 26),
  45    OPC_REGIMM   = (0x01 << 26),
  46    OPC_CP0      = (0x10 << 26),
  47    OPC_CP2      = (0x12 << 26),
  48    OPC_CP3      = (0x13 << 26),
  49    OPC_SPECIAL2 = (0x1C << 26),
  50    OPC_SPECIAL3 = (0x1F << 26),
  51    /* arithmetic with immediate */
  52    OPC_ADDI     = (0x08 << 26),
  53    OPC_ADDIU    = (0x09 << 26),
  54    OPC_SLTI     = (0x0A << 26),
  55    OPC_SLTIU    = (0x0B << 26),
  56    /* logic with immediate */
  57    OPC_ANDI     = (0x0C << 26),
  58    OPC_ORI      = (0x0D << 26),
  59    OPC_XORI     = (0x0E << 26),
  60    OPC_LUI      = (0x0F << 26),
  61    /* arithmetic with immediate */
  62    OPC_DADDI    = (0x18 << 26),
  63    OPC_DADDIU   = (0x19 << 26),
  64    /* Jump and branches */
  65    OPC_J        = (0x02 << 26),
  66    OPC_JAL      = (0x03 << 26),
  67    OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
  68    OPC_BEQL     = (0x14 << 26),
  69    OPC_BNE      = (0x05 << 26),
  70    OPC_BNEL     = (0x15 << 26),
  71    OPC_BLEZ     = (0x06 << 26),
  72    OPC_BLEZL    = (0x16 << 26),
  73    OPC_BGTZ     = (0x07 << 26),
  74    OPC_BGTZL    = (0x17 << 26),
  75    OPC_JALX     = (0x1D << 26),
  76    OPC_DAUI     = (0x1D << 26),
  77    /* Load and stores */
  78    OPC_LDL      = (0x1A << 26),
  79    OPC_LDR      = (0x1B << 26),
  80    OPC_LB       = (0x20 << 26),
  81    OPC_LH       = (0x21 << 26),
  82    OPC_LWL      = (0x22 << 26),
  83    OPC_LW       = (0x23 << 26),
  84    OPC_LWPC     = OPC_LW | 0x5,
  85    OPC_LBU      = (0x24 << 26),
  86    OPC_LHU      = (0x25 << 26),
  87    OPC_LWR      = (0x26 << 26),
  88    OPC_LWU      = (0x27 << 26),
  89    OPC_SB       = (0x28 << 26),
  90    OPC_SH       = (0x29 << 26),
  91    OPC_SWL      = (0x2A << 26),
  92    OPC_SW       = (0x2B << 26),
  93    OPC_SDL      = (0x2C << 26),
  94    OPC_SDR      = (0x2D << 26),
  95    OPC_SWR      = (0x2E << 26),
  96    OPC_LL       = (0x30 << 26),
  97    OPC_LLD      = (0x34 << 26),
  98    OPC_LD       = (0x37 << 26),
  99    OPC_LDPC     = OPC_LD | 0x5,
 100    OPC_SC       = (0x38 << 26),
 101    OPC_SCD      = (0x3C << 26),
 102    OPC_SD       = (0x3F << 26),
 103    /* Floating point load/store */
 104    OPC_LWC1     = (0x31 << 26),
 105    OPC_LWC2     = (0x32 << 26),
 106    OPC_LDC1     = (0x35 << 26),
 107    OPC_LDC2     = (0x36 << 26),
 108    OPC_SWC1     = (0x39 << 26),
 109    OPC_SWC2     = (0x3A << 26),
 110    OPC_SDC1     = (0x3D << 26),
 111    OPC_SDC2     = (0x3E << 26),
 112    /* Compact Branches */
 113    OPC_BLEZALC  = (0x06 << 26),
 114    OPC_BGEZALC  = (0x06 << 26),
 115    OPC_BGEUC    = (0x06 << 26),
 116    OPC_BGTZALC  = (0x07 << 26),
 117    OPC_BLTZALC  = (0x07 << 26),
 118    OPC_BLTUC    = (0x07 << 26),
 119    OPC_BOVC     = (0x08 << 26),
 120    OPC_BEQZALC  = (0x08 << 26),
 121    OPC_BEQC     = (0x08 << 26),
 122    OPC_BLEZC    = (0x16 << 26),
 123    OPC_BGEZC    = (0x16 << 26),
 124    OPC_BGEC     = (0x16 << 26),
 125    OPC_BGTZC    = (0x17 << 26),
 126    OPC_BLTZC    = (0x17 << 26),
 127    OPC_BLTC     = (0x17 << 26),
 128    OPC_BNVC     = (0x18 << 26),
 129    OPC_BNEZALC  = (0x18 << 26),
 130    OPC_BNEC     = (0x18 << 26),
 131    OPC_BC       = (0x32 << 26),
 132    OPC_BEQZC    = (0x36 << 26),
 133    OPC_JIC      = (0x36 << 26),
 134    OPC_BALC     = (0x3A << 26),
 135    OPC_BNEZC    = (0x3E << 26),
 136    OPC_JIALC    = (0x3E << 26),
 137    /* MDMX ASE specific */
 138    OPC_MDMX     = (0x1E << 26),
 139    /* Cache and prefetch */
 140    OPC_CACHE    = (0x2F << 26),
 141    OPC_PREF     = (0x33 << 26),
 142    /* PC-relative address computation / loads */
 143    OPC_PCREL    = (0x3B << 26),
 144};
 145
 146/* PC-relative address computation / loads  */
 147#define MASK_OPC_PCREL_TOP2BITS(op) (MASK_OP_MAJOR(op) | (op & (3 << 19)))
 148#define MASK_OPC_PCREL_TOP5BITS(op) (MASK_OP_MAJOR(op) | (op & (0x1f << 16)))
 149enum {
 150    /* Instructions determined by bits 19 and 20 */
 151    OPC_ADDIUPC = OPC_PCREL | (0 << 19),
 152    R6_OPC_LWPC = OPC_PCREL | (1 << 19),
 153    OPC_LWUPC   = OPC_PCREL | (2 << 19),
 154
 155    /* Instructions determined by bits 16 ... 20 */
 156    OPC_AUIPC   = OPC_PCREL | (0x1e << 16),
 157    OPC_ALUIPC  = OPC_PCREL | (0x1f << 16),
 158
 159    /* Other */
 160    R6_OPC_LDPC = OPC_PCREL | (6 << 18),
 161};
 162
 163/* MIPS special opcodes */
 164#define MASK_SPECIAL(op)            (MASK_OP_MAJOR(op) | (op & 0x3F))
 165
 166enum {
 167    /* Shifts */
 168    OPC_SLL      = 0x00 | OPC_SPECIAL,
 169    /* NOP is SLL r0, r0, 0   */
 170    /* SSNOP is SLL r0, r0, 1 */
 171    /* EHB is SLL r0, r0, 3 */
 172    OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
 173    OPC_ROTR     = OPC_SRL | (1 << 21),
 174    OPC_SRA      = 0x03 | OPC_SPECIAL,
 175    OPC_SLLV     = 0x04 | OPC_SPECIAL,
 176    OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
 177    OPC_ROTRV    = OPC_SRLV | (1 << 6),
 178    OPC_SRAV     = 0x07 | OPC_SPECIAL,
 179    OPC_DSLLV    = 0x14 | OPC_SPECIAL,
 180    OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
 181    OPC_DROTRV   = OPC_DSRLV | (1 << 6),
 182    OPC_DSRAV    = 0x17 | OPC_SPECIAL,
 183    OPC_DSLL     = 0x38 | OPC_SPECIAL,
 184    OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
 185    OPC_DROTR    = OPC_DSRL | (1 << 21),
 186    OPC_DSRA     = 0x3B | OPC_SPECIAL,
 187    OPC_DSLL32   = 0x3C | OPC_SPECIAL,
 188    OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
 189    OPC_DROTR32  = OPC_DSRL32 | (1 << 21),
 190    OPC_DSRA32   = 0x3F | OPC_SPECIAL,
 191    /* Multiplication / division */
 192    OPC_MULT     = 0x18 | OPC_SPECIAL,
 193    OPC_MULTU    = 0x19 | OPC_SPECIAL,
 194    OPC_DIV      = 0x1A | OPC_SPECIAL,
 195    OPC_DIVU     = 0x1B | OPC_SPECIAL,
 196    OPC_DMULT    = 0x1C | OPC_SPECIAL,
 197    OPC_DMULTU   = 0x1D | OPC_SPECIAL,
 198    OPC_DDIV     = 0x1E | OPC_SPECIAL,
 199    OPC_DDIVU    = 0x1F | OPC_SPECIAL,
 200
 201    /* 2 registers arithmetic / logic */
 202    OPC_ADD      = 0x20 | OPC_SPECIAL,
 203    OPC_ADDU     = 0x21 | OPC_SPECIAL,
 204    OPC_SUB      = 0x22 | OPC_SPECIAL,
 205    OPC_SUBU     = 0x23 | OPC_SPECIAL,
 206    OPC_AND      = 0x24 | OPC_SPECIAL,
 207    OPC_OR       = 0x25 | OPC_SPECIAL,
 208    OPC_XOR      = 0x26 | OPC_SPECIAL,
 209    OPC_NOR      = 0x27 | OPC_SPECIAL,
 210    OPC_SLT      = 0x2A | OPC_SPECIAL,
 211    OPC_SLTU     = 0x2B | OPC_SPECIAL,
 212    OPC_DADD     = 0x2C | OPC_SPECIAL,
 213    OPC_DADDU    = 0x2D | OPC_SPECIAL,
 214    OPC_DSUB     = 0x2E | OPC_SPECIAL,
 215    OPC_DSUBU    = 0x2F | OPC_SPECIAL,
 216    /* Jumps */
 217    OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
 218    OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
 219    /* Traps */
 220    OPC_TGE      = 0x30 | OPC_SPECIAL,
 221    OPC_TGEU     = 0x31 | OPC_SPECIAL,
 222    OPC_TLT      = 0x32 | OPC_SPECIAL,
 223    OPC_TLTU     = 0x33 | OPC_SPECIAL,
 224    OPC_TEQ      = 0x34 | OPC_SPECIAL,
 225    OPC_TNE      = 0x36 | OPC_SPECIAL,
 226    /* HI / LO registers load & stores */
 227    OPC_MFHI     = 0x10 | OPC_SPECIAL,
 228    OPC_MTHI     = 0x11 | OPC_SPECIAL,
 229    OPC_MFLO     = 0x12 | OPC_SPECIAL,
 230    OPC_MTLO     = 0x13 | OPC_SPECIAL,
 231    /* Conditional moves */
 232    OPC_MOVZ     = 0x0A | OPC_SPECIAL,
 233    OPC_MOVN     = 0x0B | OPC_SPECIAL,
 234
 235    OPC_SELEQZ   = 0x35 | OPC_SPECIAL,
 236    OPC_SELNEZ   = 0x37 | OPC_SPECIAL,
 237
 238    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
 239
 240    /* Special */
 241    OPC_PMON     = 0x05 | OPC_SPECIAL, /* unofficial */
 242    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
 243    OPC_BREAK    = 0x0D | OPC_SPECIAL,
 244    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
 245    OPC_SYNC     = 0x0F | OPC_SPECIAL,
 246
 247    OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
 248    OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
 249    OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
 250    OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
 251};
 252
 253/*
 254 * R6 Multiply and Divide instructions have the same opcode
 255 * and function field as legacy OPC_MULT[U]/OPC_DIV[U]
 256 */
 257#define MASK_R6_MULDIV(op)          (MASK_SPECIAL(op) | (op & (0x7ff)))
 258
 259enum {
 260    R6_OPC_MUL   = OPC_MULT  | (2 << 6),
 261    R6_OPC_MUH   = OPC_MULT  | (3 << 6),
 262    R6_OPC_MULU  = OPC_MULTU | (2 << 6),
 263    R6_OPC_MUHU  = OPC_MULTU | (3 << 6),
 264    R6_OPC_DIV   = OPC_DIV   | (2 << 6),
 265    R6_OPC_MOD   = OPC_DIV   | (3 << 6),
 266    R6_OPC_DIVU  = OPC_DIVU  | (2 << 6),
 267    R6_OPC_MODU  = OPC_DIVU  | (3 << 6),
 268
 269    R6_OPC_DMUL   = OPC_DMULT  | (2 << 6),
 270    R6_OPC_DMUH   = OPC_DMULT  | (3 << 6),
 271    R6_OPC_DMULU  = OPC_DMULTU | (2 << 6),
 272    R6_OPC_DMUHU  = OPC_DMULTU | (3 << 6),
 273    R6_OPC_DDIV   = OPC_DDIV   | (2 << 6),
 274    R6_OPC_DMOD   = OPC_DDIV   | (3 << 6),
 275    R6_OPC_DDIVU  = OPC_DDIVU  | (2 << 6),
 276    R6_OPC_DMODU  = OPC_DDIVU  | (3 << 6),
 277
 278    R6_OPC_CLZ      = 0x10 | OPC_SPECIAL,
 279    R6_OPC_CLO      = 0x11 | OPC_SPECIAL,
 280    R6_OPC_DCLZ     = 0x12 | OPC_SPECIAL,
 281    R6_OPC_DCLO     = 0x13 | OPC_SPECIAL,
 282    R6_OPC_SDBBP    = 0x0e | OPC_SPECIAL,
 283};
 284
 285/* Multiplication variants of the vr54xx. */
 286#define MASK_MUL_VR54XX(op)         (MASK_SPECIAL(op) | (op & (0x1F << 6)))
 287
 288enum {
 289    OPC_VR54XX_MULS    = (0x03 << 6) | OPC_MULT,
 290    OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,
 291    OPC_VR54XX_MACC    = (0x05 << 6) | OPC_MULT,
 292    OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,
 293    OPC_VR54XX_MSAC    = (0x07 << 6) | OPC_MULT,
 294    OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,
 295    OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,
 296    OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,
 297    OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,
 298    OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
 299    OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,
 300    OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
 301    OPC_VR54XX_MSACHI  = (0x0F << 6) | OPC_MULT,
 302    OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
 303};
 304
 305/* REGIMM (rt field) opcodes */
 306#define MASK_REGIMM(op)             (MASK_OP_MAJOR(op) | (op & (0x1F << 16)))
 307
 308enum {
 309    OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
 310    OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
 311    OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
 312    OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
 313    OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
 314    OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
 315    OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
 316    OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
 317    OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
 318    OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
 319    OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
 320    OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
 321    OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
 322    OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
 323    OPC_SIGRIE   = (0x17 << 16) | OPC_REGIMM,
 324    OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
 325
 326    OPC_DAHI     = (0x06 << 16) | OPC_REGIMM,
 327    OPC_DATI     = (0x1e << 16) | OPC_REGIMM,
 328};
 329
 330/* Special2 opcodes */
 331#define MASK_SPECIAL2(op)           (MASK_OP_MAJOR(op) | (op & 0x3F))
 332
 333enum {
 334    /* Multiply & xxx operations */
 335    OPC_MADD     = 0x00 | OPC_SPECIAL2,
 336    OPC_MADDU    = 0x01 | OPC_SPECIAL2,
 337    OPC_MUL      = 0x02 | OPC_SPECIAL2,
 338    OPC_MSUB     = 0x04 | OPC_SPECIAL2,
 339    OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
 340    /* Loongson 2F */
 341    OPC_MULT_G_2F   = 0x10 | OPC_SPECIAL2,
 342    OPC_DMULT_G_2F  = 0x11 | OPC_SPECIAL2,
 343    OPC_MULTU_G_2F  = 0x12 | OPC_SPECIAL2,
 344    OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
 345    OPC_DIV_G_2F    = 0x14 | OPC_SPECIAL2,
 346    OPC_DDIV_G_2F   = 0x15 | OPC_SPECIAL2,
 347    OPC_DIVU_G_2F   = 0x16 | OPC_SPECIAL2,
 348    OPC_DDIVU_G_2F  = 0x17 | OPC_SPECIAL2,
 349    OPC_MOD_G_2F    = 0x1c | OPC_SPECIAL2,
 350    OPC_DMOD_G_2F   = 0x1d | OPC_SPECIAL2,
 351    OPC_MODU_G_2F   = 0x1e | OPC_SPECIAL2,
 352    OPC_DMODU_G_2F  = 0x1f | OPC_SPECIAL2,
 353    /* Misc */
 354    OPC_CLZ      = 0x20 | OPC_SPECIAL2,
 355    OPC_CLO      = 0x21 | OPC_SPECIAL2,
 356    OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
 357    OPC_DCLO     = 0x25 | OPC_SPECIAL2,
 358    /* Special */
 359    OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
 360};
 361
 362/* Special3 opcodes */
 363#define MASK_SPECIAL3(op)           (MASK_OP_MAJOR(op) | (op & 0x3F))
 364
 365enum {
 366    OPC_EXT      = 0x00 | OPC_SPECIAL3,
 367    OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
 368    OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
 369    OPC_DEXT     = 0x03 | OPC_SPECIAL3,
 370    OPC_INS      = 0x04 | OPC_SPECIAL3,
 371    OPC_DINSM    = 0x05 | OPC_SPECIAL3,
 372    OPC_DINSU    = 0x06 | OPC_SPECIAL3,
 373    OPC_DINS     = 0x07 | OPC_SPECIAL3,
 374    OPC_FORK     = 0x08 | OPC_SPECIAL3,
 375    OPC_YIELD    = 0x09 | OPC_SPECIAL3,
 376    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
 377    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
 378    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
 379    OPC_GINV     = 0x3D | OPC_SPECIAL3,
 380
 381    /* Loongson 2E */
 382    OPC_MULT_G_2E   = 0x18 | OPC_SPECIAL3,
 383    OPC_MULTU_G_2E  = 0x19 | OPC_SPECIAL3,
 384    OPC_DIV_G_2E    = 0x1A | OPC_SPECIAL3,
 385    OPC_DIVU_G_2E   = 0x1B | OPC_SPECIAL3,
 386    OPC_DMULT_G_2E  = 0x1C | OPC_SPECIAL3,
 387    OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
 388    OPC_DDIV_G_2E   = 0x1E | OPC_SPECIAL3,
 389    OPC_DDIVU_G_2E  = 0x1F | OPC_SPECIAL3,
 390    OPC_MOD_G_2E    = 0x22 | OPC_SPECIAL3,
 391    OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
 392    OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
 393    OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
 394
 395    /* MIPS DSP Load */
 396    OPC_LX_DSP         = 0x0A | OPC_SPECIAL3,
 397    /* MIPS DSP Arithmetic */
 398    OPC_ADDU_QB_DSP    = 0x10 | OPC_SPECIAL3,
 399    OPC_ADDU_OB_DSP    = 0x14 | OPC_SPECIAL3,
 400    OPC_ABSQ_S_PH_DSP  = 0x12 | OPC_SPECIAL3,
 401    OPC_ABSQ_S_QH_DSP  = 0x16 | OPC_SPECIAL3,
 402    /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E.  */
 403    /* OPC_ADDUH_QB_DSP   = 0x18 | OPC_SPECIAL3,  */
 404    OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
 405    OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
 406    /* MIPS DSP GPR-Based Shift Sub-class */
 407    OPC_SHLL_QB_DSP    = 0x13 | OPC_SPECIAL3,
 408    OPC_SHLL_OB_DSP    = 0x17 | OPC_SPECIAL3,
 409    /* MIPS DSP Multiply Sub-class insns */
 410    /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP.  */
 411    /* OPC_MUL_PH_DSP     = 0x18 | OPC_SPECIAL3,  */
 412    OPC_DPA_W_PH_DSP   = 0x30 | OPC_SPECIAL3,
 413    OPC_DPAQ_W_QH_DSP  = 0x34 | OPC_SPECIAL3,
 414    /* DSP Bit/Manipulation Sub-class */
 415    OPC_INSV_DSP       = 0x0C | OPC_SPECIAL3,
 416    OPC_DINSV_DSP      = 0x0D | OPC_SPECIAL3,
 417    /* MIPS DSP Append Sub-class */
 418    OPC_APPEND_DSP     = 0x31 | OPC_SPECIAL3,
 419    OPC_DAPPEND_DSP    = 0x35 | OPC_SPECIAL3,
 420    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 421    OPC_EXTR_W_DSP     = 0x38 | OPC_SPECIAL3,
 422    OPC_DEXTR_W_DSP    = 0x3C | OPC_SPECIAL3,
 423
 424    /* EVA */
 425    OPC_LWLE           = 0x19 | OPC_SPECIAL3,
 426    OPC_LWRE           = 0x1A | OPC_SPECIAL3,
 427    OPC_CACHEE         = 0x1B | OPC_SPECIAL3,
 428    OPC_SBE            = 0x1C | OPC_SPECIAL3,
 429    OPC_SHE            = 0x1D | OPC_SPECIAL3,
 430    OPC_SCE            = 0x1E | OPC_SPECIAL3,
 431    OPC_SWE            = 0x1F | OPC_SPECIAL3,
 432    OPC_SWLE           = 0x21 | OPC_SPECIAL3,
 433    OPC_SWRE           = 0x22 | OPC_SPECIAL3,
 434    OPC_PREFE          = 0x23 | OPC_SPECIAL3,
 435    OPC_LBUE           = 0x28 | OPC_SPECIAL3,
 436    OPC_LHUE           = 0x29 | OPC_SPECIAL3,
 437    OPC_LBE            = 0x2C | OPC_SPECIAL3,
 438    OPC_LHE            = 0x2D | OPC_SPECIAL3,
 439    OPC_LLE            = 0x2E | OPC_SPECIAL3,
 440    OPC_LWE            = 0x2F | OPC_SPECIAL3,
 441
 442    /* R6 */
 443    R6_OPC_PREF        = 0x35 | OPC_SPECIAL3,
 444    R6_OPC_CACHE       = 0x25 | OPC_SPECIAL3,
 445    R6_OPC_LL          = 0x36 | OPC_SPECIAL3,
 446    R6_OPC_SC          = 0x26 | OPC_SPECIAL3,
 447    R6_OPC_LLD         = 0x37 | OPC_SPECIAL3,
 448    R6_OPC_SCD         = 0x27 | OPC_SPECIAL3,
 449};
 450
 451/* Loongson EXT load/store quad word opcodes */
 452#define MASK_LOONGSON_GSLSQ(op)           (MASK_OP_MAJOR(op) | (op & 0x8020))
 453enum {
 454    OPC_GSLQ        = 0x0020 | OPC_LWC2,
 455    OPC_GSLQC1      = 0x8020 | OPC_LWC2,
 456    OPC_GSSHFL      = OPC_LWC2,
 457    OPC_GSSQ        = 0x0020 | OPC_SWC2,
 458    OPC_GSSQC1      = 0x8020 | OPC_SWC2,
 459    OPC_GSSHFS      = OPC_SWC2,
 460};
 461
 462/* Loongson EXT shifted load/store opcodes */
 463#define MASK_LOONGSON_GSSHFLS(op)         (MASK_OP_MAJOR(op) | (op & 0xc03f))
 464enum {
 465    OPC_GSLWLC1     = 0x4 | OPC_GSSHFL,
 466    OPC_GSLWRC1     = 0x5 | OPC_GSSHFL,
 467    OPC_GSLDLC1     = 0x6 | OPC_GSSHFL,
 468    OPC_GSLDRC1     = 0x7 | OPC_GSSHFL,
 469    OPC_GSSWLC1     = 0x4 | OPC_GSSHFS,
 470    OPC_GSSWRC1     = 0x5 | OPC_GSSHFS,
 471    OPC_GSSDLC1     = 0x6 | OPC_GSSHFS,
 472    OPC_GSSDRC1     = 0x7 | OPC_GSSHFS,
 473};
 474
 475/* Loongson EXT LDC2/SDC2 opcodes */
 476#define MASK_LOONGSON_LSDC2(op)           (MASK_OP_MAJOR(op) | (op & 0x7))
 477
 478enum {
 479    OPC_GSLBX      = 0x0 | OPC_LDC2,
 480    OPC_GSLHX      = 0x1 | OPC_LDC2,
 481    OPC_GSLWX      = 0x2 | OPC_LDC2,
 482    OPC_GSLDX      = 0x3 | OPC_LDC2,
 483    OPC_GSLWXC1    = 0x6 | OPC_LDC2,
 484    OPC_GSLDXC1    = 0x7 | OPC_LDC2,
 485    OPC_GSSBX      = 0x0 | OPC_SDC2,
 486    OPC_GSSHX      = 0x1 | OPC_SDC2,
 487    OPC_GSSWX      = 0x2 | OPC_SDC2,
 488    OPC_GSSDX      = 0x3 | OPC_SDC2,
 489    OPC_GSSWXC1    = 0x6 | OPC_SDC2,
 490    OPC_GSSDXC1    = 0x7 | OPC_SDC2,
 491};
 492
 493/* BSHFL opcodes */
 494#define MASK_BSHFL(op)              (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 495
 496enum {
 497    OPC_WSBH      = (0x02 << 6) | OPC_BSHFL,
 498    OPC_SEB       = (0x10 << 6) | OPC_BSHFL,
 499    OPC_SEH       = (0x18 << 6) | OPC_BSHFL,
 500    OPC_ALIGN     = (0x08 << 6) | OPC_BSHFL, /* 010.bp (010.00 to 010.11) */
 501    OPC_ALIGN_1   = (0x09 << 6) | OPC_BSHFL,
 502    OPC_ALIGN_2   = (0x0A << 6) | OPC_BSHFL,
 503    OPC_ALIGN_3   = (0x0B << 6) | OPC_BSHFL,
 504    OPC_BITSWAP   = (0x00 << 6) | OPC_BSHFL  /* 00000 */
 505};
 506
 507/* DBSHFL opcodes */
 508#define MASK_DBSHFL(op)             (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 509
 510enum {
 511    OPC_DSBH       = (0x02 << 6) | OPC_DBSHFL,
 512    OPC_DSHD       = (0x05 << 6) | OPC_DBSHFL,
 513    OPC_DALIGN     = (0x08 << 6) | OPC_DBSHFL, /* 01.bp (01.000 to 01.111) */
 514    OPC_DALIGN_1   = (0x09 << 6) | OPC_DBSHFL,
 515    OPC_DALIGN_2   = (0x0A << 6) | OPC_DBSHFL,
 516    OPC_DALIGN_3   = (0x0B << 6) | OPC_DBSHFL,
 517    OPC_DALIGN_4   = (0x0C << 6) | OPC_DBSHFL,
 518    OPC_DALIGN_5   = (0x0D << 6) | OPC_DBSHFL,
 519    OPC_DALIGN_6   = (0x0E << 6) | OPC_DBSHFL,
 520    OPC_DALIGN_7   = (0x0F << 6) | OPC_DBSHFL,
 521    OPC_DBITSWAP   = (0x00 << 6) | OPC_DBSHFL, /* 00000 */
 522};
 523
 524/* MIPS DSP REGIMM opcodes */
 525enum {
 526    OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
 527    OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
 528};
 529
 530#define MASK_LX(op)                 (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 531/* MIPS DSP Load */
 532enum {
 533    OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
 534    OPC_LHX  = (0x04 << 6) | OPC_LX_DSP,
 535    OPC_LWX  = (0x00 << 6) | OPC_LX_DSP,
 536    OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
 537};
 538
 539#define MASK_ADDU_QB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 540enum {
 541    /* MIPS DSP Arithmetic Sub-class */
 542    OPC_ADDQ_PH        = (0x0A << 6) | OPC_ADDU_QB_DSP,
 543    OPC_ADDQ_S_PH      = (0x0E << 6) | OPC_ADDU_QB_DSP,
 544    OPC_ADDQ_S_W       = (0x16 << 6) | OPC_ADDU_QB_DSP,
 545    OPC_ADDU_QB        = (0x00 << 6) | OPC_ADDU_QB_DSP,
 546    OPC_ADDU_S_QB      = (0x04 << 6) | OPC_ADDU_QB_DSP,
 547    OPC_ADDU_PH        = (0x08 << 6) | OPC_ADDU_QB_DSP,
 548    OPC_ADDU_S_PH      = (0x0C << 6) | OPC_ADDU_QB_DSP,
 549    OPC_SUBQ_PH        = (0x0B << 6) | OPC_ADDU_QB_DSP,
 550    OPC_SUBQ_S_PH      = (0x0F << 6) | OPC_ADDU_QB_DSP,
 551    OPC_SUBQ_S_W       = (0x17 << 6) | OPC_ADDU_QB_DSP,
 552    OPC_SUBU_QB        = (0x01 << 6) | OPC_ADDU_QB_DSP,
 553    OPC_SUBU_S_QB      = (0x05 << 6) | OPC_ADDU_QB_DSP,
 554    OPC_SUBU_PH        = (0x09 << 6) | OPC_ADDU_QB_DSP,
 555    OPC_SUBU_S_PH      = (0x0D << 6) | OPC_ADDU_QB_DSP,
 556    OPC_ADDSC          = (0x10 << 6) | OPC_ADDU_QB_DSP,
 557    OPC_ADDWC          = (0x11 << 6) | OPC_ADDU_QB_DSP,
 558    OPC_MODSUB         = (0x12 << 6) | OPC_ADDU_QB_DSP,
 559    OPC_RADDU_W_QB     = (0x14 << 6) | OPC_ADDU_QB_DSP,
 560    /* MIPS DSP Multiply Sub-class insns */
 561    OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
 562    OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
 563    OPC_MULQ_RS_PH     = (0x1F << 6) | OPC_ADDU_QB_DSP,
 564    OPC_MULEQ_S_W_PHL  = (0x1C << 6) | OPC_ADDU_QB_DSP,
 565    OPC_MULEQ_S_W_PHR  = (0x1D << 6) | OPC_ADDU_QB_DSP,
 566    OPC_MULQ_S_PH      = (0x1E << 6) | OPC_ADDU_QB_DSP,
 567};
 568
 569#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
 570#define MASK_ADDUH_QB(op)           (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 571enum {
 572    /* MIPS DSP Arithmetic Sub-class */
 573    OPC_ADDUH_QB   = (0x00 << 6) | OPC_ADDUH_QB_DSP,
 574    OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
 575    OPC_ADDQH_PH   = (0x08 << 6) | OPC_ADDUH_QB_DSP,
 576    OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
 577    OPC_ADDQH_W    = (0x10 << 6) | OPC_ADDUH_QB_DSP,
 578    OPC_ADDQH_R_W  = (0x12 << 6) | OPC_ADDUH_QB_DSP,
 579    OPC_SUBUH_QB   = (0x01 << 6) | OPC_ADDUH_QB_DSP,
 580    OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
 581    OPC_SUBQH_PH   = (0x09 << 6) | OPC_ADDUH_QB_DSP,
 582    OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
 583    OPC_SUBQH_W    = (0x11 << 6) | OPC_ADDUH_QB_DSP,
 584    OPC_SUBQH_R_W  = (0x13 << 6) | OPC_ADDUH_QB_DSP,
 585    /* MIPS DSP Multiply Sub-class insns */
 586    OPC_MUL_PH     = (0x0C << 6) | OPC_ADDUH_QB_DSP,
 587    OPC_MUL_S_PH   = (0x0E << 6) | OPC_ADDUH_QB_DSP,
 588    OPC_MULQ_S_W   = (0x16 << 6) | OPC_ADDUH_QB_DSP,
 589    OPC_MULQ_RS_W  = (0x17 << 6) | OPC_ADDUH_QB_DSP,
 590};
 591
 592#define MASK_ABSQ_S_PH(op)          (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 593enum {
 594    /* MIPS DSP Arithmetic Sub-class */
 595    OPC_ABSQ_S_QB       = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
 596    OPC_ABSQ_S_PH       = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
 597    OPC_ABSQ_S_W        = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
 598    OPC_PRECEQ_W_PHL    = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
 599    OPC_PRECEQ_W_PHR    = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
 600    OPC_PRECEQU_PH_QBL  = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
 601    OPC_PRECEQU_PH_QBR  = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
 602    OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
 603    OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
 604    OPC_PRECEU_PH_QBL   = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
 605    OPC_PRECEU_PH_QBR   = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
 606    OPC_PRECEU_PH_QBLA  = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
 607    OPC_PRECEU_PH_QBRA  = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
 608    /* DSP Bit/Manipulation Sub-class */
 609    OPC_BITREV          = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
 610    OPC_REPL_QB         = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
 611    OPC_REPLV_QB        = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
 612    OPC_REPL_PH         = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
 613    OPC_REPLV_PH        = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
 614};
 615
 616#define MASK_CMPU_EQ_QB(op)         (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 617enum {
 618    /* MIPS DSP Arithmetic Sub-class */
 619    OPC_PRECR_QB_PH      = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
 620    OPC_PRECRQ_QB_PH     = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
 621    OPC_PRECR_SRA_PH_W   = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
 622    OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
 623    OPC_PRECRQ_PH_W      = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
 624    OPC_PRECRQ_RS_PH_W   = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
 625    OPC_PRECRQU_S_QB_PH  = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
 626    /* DSP Compare-Pick Sub-class */
 627    OPC_CMPU_EQ_QB       = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
 628    OPC_CMPU_LT_QB       = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
 629    OPC_CMPU_LE_QB       = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
 630    OPC_CMPGU_EQ_QB      = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
 631    OPC_CMPGU_LT_QB      = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
 632    OPC_CMPGU_LE_QB      = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
 633    OPC_CMPGDU_EQ_QB     = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
 634    OPC_CMPGDU_LT_QB     = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
 635    OPC_CMPGDU_LE_QB     = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
 636    OPC_CMP_EQ_PH        = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
 637    OPC_CMP_LT_PH        = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
 638    OPC_CMP_LE_PH        = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
 639    OPC_PICK_QB          = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
 640    OPC_PICK_PH          = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
 641    OPC_PACKRL_PH        = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
 642};
 643
 644#define MASK_SHLL_QB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 645enum {
 646    /* MIPS DSP GPR-Based Shift Sub-class */
 647    OPC_SHLL_QB    = (0x00 << 6) | OPC_SHLL_QB_DSP,
 648    OPC_SHLLV_QB   = (0x02 << 6) | OPC_SHLL_QB_DSP,
 649    OPC_SHLL_PH    = (0x08 << 6) | OPC_SHLL_QB_DSP,
 650    OPC_SHLLV_PH   = (0x0A << 6) | OPC_SHLL_QB_DSP,
 651    OPC_SHLL_S_PH  = (0x0C << 6) | OPC_SHLL_QB_DSP,
 652    OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
 653    OPC_SHLL_S_W   = (0x14 << 6) | OPC_SHLL_QB_DSP,
 654    OPC_SHLLV_S_W  = (0x16 << 6) | OPC_SHLL_QB_DSP,
 655    OPC_SHRL_QB    = (0x01 << 6) | OPC_SHLL_QB_DSP,
 656    OPC_SHRLV_QB   = (0x03 << 6) | OPC_SHLL_QB_DSP,
 657    OPC_SHRL_PH    = (0x19 << 6) | OPC_SHLL_QB_DSP,
 658    OPC_SHRLV_PH   = (0x1B << 6) | OPC_SHLL_QB_DSP,
 659    OPC_SHRA_QB    = (0x04 << 6) | OPC_SHLL_QB_DSP,
 660    OPC_SHRA_R_QB  = (0x05 << 6) | OPC_SHLL_QB_DSP,
 661    OPC_SHRAV_QB   = (0x06 << 6) | OPC_SHLL_QB_DSP,
 662    OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
 663    OPC_SHRA_PH    = (0x09 << 6) | OPC_SHLL_QB_DSP,
 664    OPC_SHRAV_PH   = (0x0B << 6) | OPC_SHLL_QB_DSP,
 665    OPC_SHRA_R_PH  = (0x0D << 6) | OPC_SHLL_QB_DSP,
 666    OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
 667    OPC_SHRA_R_W   = (0x15 << 6) | OPC_SHLL_QB_DSP,
 668    OPC_SHRAV_R_W  = (0x17 << 6) | OPC_SHLL_QB_DSP,
 669};
 670
 671#define MASK_DPA_W_PH(op)           (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 672enum {
 673    /* MIPS DSP Multiply Sub-class insns */
 674    OPC_DPAU_H_QBL    = (0x03 << 6) | OPC_DPA_W_PH_DSP,
 675    OPC_DPAU_H_QBR    = (0x07 << 6) | OPC_DPA_W_PH_DSP,
 676    OPC_DPSU_H_QBL    = (0x0B << 6) | OPC_DPA_W_PH_DSP,
 677    OPC_DPSU_H_QBR    = (0x0F << 6) | OPC_DPA_W_PH_DSP,
 678    OPC_DPA_W_PH      = (0x00 << 6) | OPC_DPA_W_PH_DSP,
 679    OPC_DPAX_W_PH     = (0x08 << 6) | OPC_DPA_W_PH_DSP,
 680    OPC_DPAQ_S_W_PH   = (0x04 << 6) | OPC_DPA_W_PH_DSP,
 681    OPC_DPAQX_S_W_PH  = (0x18 << 6) | OPC_DPA_W_PH_DSP,
 682    OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
 683    OPC_DPS_W_PH      = (0x01 << 6) | OPC_DPA_W_PH_DSP,
 684    OPC_DPSX_W_PH     = (0x09 << 6) | OPC_DPA_W_PH_DSP,
 685    OPC_DPSQ_S_W_PH   = (0x05 << 6) | OPC_DPA_W_PH_DSP,
 686    OPC_DPSQX_S_W_PH  = (0x19 << 6) | OPC_DPA_W_PH_DSP,
 687    OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
 688    OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
 689    OPC_DPAQ_SA_L_W   = (0x0C << 6) | OPC_DPA_W_PH_DSP,
 690    OPC_DPSQ_SA_L_W   = (0x0D << 6) | OPC_DPA_W_PH_DSP,
 691    OPC_MAQ_S_W_PHL   = (0x14 << 6) | OPC_DPA_W_PH_DSP,
 692    OPC_MAQ_S_W_PHR   = (0x16 << 6) | OPC_DPA_W_PH_DSP,
 693    OPC_MAQ_SA_W_PHL  = (0x10 << 6) | OPC_DPA_W_PH_DSP,
 694    OPC_MAQ_SA_W_PHR  = (0x12 << 6) | OPC_DPA_W_PH_DSP,
 695    OPC_MULSA_W_PH    = (0x02 << 6) | OPC_DPA_W_PH_DSP,
 696};
 697
 698#define MASK_INSV(op)               (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 699enum {
 700    /* DSP Bit/Manipulation Sub-class */
 701    OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
 702};
 703
 704#define MASK_APPEND(op)             (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 705enum {
 706    /* MIPS DSP Append Sub-class */
 707    OPC_APPEND  = (0x00 << 6) | OPC_APPEND_DSP,
 708    OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
 709    OPC_BALIGN  = (0x10 << 6) | OPC_APPEND_DSP,
 710};
 711
 712#define MASK_EXTR_W(op)             (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 713enum {
 714    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 715    OPC_EXTR_W     = (0x00 << 6) | OPC_EXTR_W_DSP,
 716    OPC_EXTR_R_W   = (0x04 << 6) | OPC_EXTR_W_DSP,
 717    OPC_EXTR_RS_W  = (0x06 << 6) | OPC_EXTR_W_DSP,
 718    OPC_EXTR_S_H   = (0x0E << 6) | OPC_EXTR_W_DSP,
 719    OPC_EXTRV_S_H  = (0x0F << 6) | OPC_EXTR_W_DSP,
 720    OPC_EXTRV_W    = (0x01 << 6) | OPC_EXTR_W_DSP,
 721    OPC_EXTRV_R_W  = (0x05 << 6) | OPC_EXTR_W_DSP,
 722    OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
 723    OPC_EXTP       = (0x02 << 6) | OPC_EXTR_W_DSP,
 724    OPC_EXTPV      = (0x03 << 6) | OPC_EXTR_W_DSP,
 725    OPC_EXTPDP     = (0x0A << 6) | OPC_EXTR_W_DSP,
 726    OPC_EXTPDPV    = (0x0B << 6) | OPC_EXTR_W_DSP,
 727    OPC_SHILO      = (0x1A << 6) | OPC_EXTR_W_DSP,
 728    OPC_SHILOV     = (0x1B << 6) | OPC_EXTR_W_DSP,
 729    OPC_MTHLIP     = (0x1F << 6) | OPC_EXTR_W_DSP,
 730    OPC_WRDSP      = (0x13 << 6) | OPC_EXTR_W_DSP,
 731    OPC_RDDSP      = (0x12 << 6) | OPC_EXTR_W_DSP,
 732};
 733
 734#define MASK_ABSQ_S_QH(op)          (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 735enum {
 736    /* MIPS DSP Arithmetic Sub-class */
 737    OPC_PRECEQ_L_PWL    = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
 738    OPC_PRECEQ_L_PWR    = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
 739    OPC_PRECEQ_PW_QHL   = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
 740    OPC_PRECEQ_PW_QHR   = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
 741    OPC_PRECEQ_PW_QHLA  = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
 742    OPC_PRECEQ_PW_QHRA  = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
 743    OPC_PRECEQU_QH_OBL  = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
 744    OPC_PRECEQU_QH_OBR  = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
 745    OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
 746    OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
 747    OPC_PRECEU_QH_OBL   = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
 748    OPC_PRECEU_QH_OBR   = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
 749    OPC_PRECEU_QH_OBLA  = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
 750    OPC_PRECEU_QH_OBRA  = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
 751    OPC_ABSQ_S_OB       = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
 752    OPC_ABSQ_S_PW       = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
 753    OPC_ABSQ_S_QH       = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
 754    /* DSP Bit/Manipulation Sub-class */
 755    OPC_REPL_OB         = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
 756    OPC_REPL_PW         = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
 757    OPC_REPL_QH         = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
 758    OPC_REPLV_OB        = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
 759    OPC_REPLV_PW        = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
 760    OPC_REPLV_QH        = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
 761};
 762
 763#define MASK_ADDU_OB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 764enum {
 765    /* MIPS DSP Multiply Sub-class insns */
 766    OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
 767    OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
 768    OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
 769    OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
 770    OPC_MULQ_RS_QH     = (0x1F << 6) | OPC_ADDU_OB_DSP,
 771    /* MIPS DSP Arithmetic Sub-class */
 772    OPC_RADDU_L_OB     = (0x14 << 6) | OPC_ADDU_OB_DSP,
 773    OPC_SUBQ_PW        = (0x13 << 6) | OPC_ADDU_OB_DSP,
 774    OPC_SUBQ_S_PW      = (0x17 << 6) | OPC_ADDU_OB_DSP,
 775    OPC_SUBQ_QH        = (0x0B << 6) | OPC_ADDU_OB_DSP,
 776    OPC_SUBQ_S_QH      = (0x0F << 6) | OPC_ADDU_OB_DSP,
 777    OPC_SUBU_OB        = (0x01 << 6) | OPC_ADDU_OB_DSP,
 778    OPC_SUBU_S_OB      = (0x05 << 6) | OPC_ADDU_OB_DSP,
 779    OPC_SUBU_QH        = (0x09 << 6) | OPC_ADDU_OB_DSP,
 780    OPC_SUBU_S_QH      = (0x0D << 6) | OPC_ADDU_OB_DSP,
 781    OPC_SUBUH_OB       = (0x19 << 6) | OPC_ADDU_OB_DSP,
 782    OPC_SUBUH_R_OB     = (0x1B << 6) | OPC_ADDU_OB_DSP,
 783    OPC_ADDQ_PW        = (0x12 << 6) | OPC_ADDU_OB_DSP,
 784    OPC_ADDQ_S_PW      = (0x16 << 6) | OPC_ADDU_OB_DSP,
 785    OPC_ADDQ_QH        = (0x0A << 6) | OPC_ADDU_OB_DSP,
 786    OPC_ADDQ_S_QH      = (0x0E << 6) | OPC_ADDU_OB_DSP,
 787    OPC_ADDU_OB        = (0x00 << 6) | OPC_ADDU_OB_DSP,
 788    OPC_ADDU_S_OB      = (0x04 << 6) | OPC_ADDU_OB_DSP,
 789    OPC_ADDU_QH        = (0x08 << 6) | OPC_ADDU_OB_DSP,
 790    OPC_ADDU_S_QH      = (0x0C << 6) | OPC_ADDU_OB_DSP,
 791    OPC_ADDUH_OB       = (0x18 << 6) | OPC_ADDU_OB_DSP,
 792    OPC_ADDUH_R_OB     = (0x1A << 6) | OPC_ADDU_OB_DSP,
 793};
 794
 795#define MASK_CMPU_EQ_OB(op)         (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 796enum {
 797    /* DSP Compare-Pick Sub-class */
 798    OPC_CMP_EQ_PW         = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
 799    OPC_CMP_LT_PW         = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
 800    OPC_CMP_LE_PW         = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
 801    OPC_CMP_EQ_QH         = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
 802    OPC_CMP_LT_QH         = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
 803    OPC_CMP_LE_QH         = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
 804    OPC_CMPGDU_EQ_OB      = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
 805    OPC_CMPGDU_LT_OB      = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
 806    OPC_CMPGDU_LE_OB      = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
 807    OPC_CMPGU_EQ_OB       = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
 808    OPC_CMPGU_LT_OB       = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
 809    OPC_CMPGU_LE_OB       = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
 810    OPC_CMPU_EQ_OB        = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
 811    OPC_CMPU_LT_OB        = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
 812    OPC_CMPU_LE_OB        = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
 813    OPC_PACKRL_PW         = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
 814    OPC_PICK_OB           = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
 815    OPC_PICK_PW           = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
 816    OPC_PICK_QH           = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
 817    /* MIPS DSP Arithmetic Sub-class */
 818    OPC_PRECR_OB_QH       = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
 819    OPC_PRECR_SRA_QH_PW   = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
 820    OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
 821    OPC_PRECRQ_OB_QH      = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
 822    OPC_PRECRQ_PW_L       = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
 823    OPC_PRECRQ_QH_PW      = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
 824    OPC_PRECRQ_RS_QH_PW   = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
 825    OPC_PRECRQU_S_OB_QH   = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
 826};
 827
 828#define MASK_DAPPEND(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 829enum {
 830    /* DSP Append Sub-class */
 831    OPC_DAPPEND  = (0x00 << 6) | OPC_DAPPEND_DSP,
 832    OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
 833    OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
 834    OPC_DBALIGN  = (0x10 << 6) | OPC_DAPPEND_DSP,
 835};
 836
 837#define MASK_DEXTR_W(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 838enum {
 839    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 840    OPC_DMTHLIP     = (0x1F << 6) | OPC_DEXTR_W_DSP,
 841    OPC_DSHILO      = (0x1A << 6) | OPC_DEXTR_W_DSP,
 842    OPC_DEXTP       = (0x02 << 6) | OPC_DEXTR_W_DSP,
 843    OPC_DEXTPDP     = (0x0A << 6) | OPC_DEXTR_W_DSP,
 844    OPC_DEXTPDPV    = (0x0B << 6) | OPC_DEXTR_W_DSP,
 845    OPC_DEXTPV      = (0x03 << 6) | OPC_DEXTR_W_DSP,
 846    OPC_DEXTR_L     = (0x10 << 6) | OPC_DEXTR_W_DSP,
 847    OPC_DEXTR_R_L   = (0x14 << 6) | OPC_DEXTR_W_DSP,
 848    OPC_DEXTR_RS_L  = (0x16 << 6) | OPC_DEXTR_W_DSP,
 849    OPC_DEXTR_W     = (0x00 << 6) | OPC_DEXTR_W_DSP,
 850    OPC_DEXTR_R_W   = (0x04 << 6) | OPC_DEXTR_W_DSP,
 851    OPC_DEXTR_RS_W  = (0x06 << 6) | OPC_DEXTR_W_DSP,
 852    OPC_DEXTR_S_H   = (0x0E << 6) | OPC_DEXTR_W_DSP,
 853    OPC_DEXTRV_L    = (0x11 << 6) | OPC_DEXTR_W_DSP,
 854    OPC_DEXTRV_R_L  = (0x15 << 6) | OPC_DEXTR_W_DSP,
 855    OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
 856    OPC_DEXTRV_S_H  = (0x0F << 6) | OPC_DEXTR_W_DSP,
 857    OPC_DEXTRV_W    = (0x01 << 6) | OPC_DEXTR_W_DSP,
 858    OPC_DEXTRV_R_W  = (0x05 << 6) | OPC_DEXTR_W_DSP,
 859    OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
 860    OPC_DSHILOV     = (0x1B << 6) | OPC_DEXTR_W_DSP,
 861};
 862
 863#define MASK_DINSV(op)              (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 864enum {
 865    /* DSP Bit/Manipulation Sub-class */
 866    OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
 867};
 868
 869#define MASK_DPAQ_W_QH(op)          (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 870enum {
 871    /* MIPS DSP Multiply Sub-class insns */
 872    OPC_DMADD         = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
 873    OPC_DMADDU        = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
 874    OPC_DMSUB         = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
 875    OPC_DMSUBU        = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
 876    OPC_DPA_W_QH      = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
 877    OPC_DPAQ_S_W_QH   = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
 878    OPC_DPAQ_SA_L_PW  = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
 879    OPC_DPAU_H_OBL    = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
 880    OPC_DPAU_H_OBR    = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
 881    OPC_DPS_W_QH      = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
 882    OPC_DPSQ_S_W_QH   = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
 883    OPC_DPSQ_SA_L_PW  = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
 884    OPC_DPSU_H_OBL    = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
 885    OPC_DPSU_H_OBR    = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
 886    OPC_MAQ_S_L_PWL   = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
 887    OPC_MAQ_S_L_PWR   = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
 888    OPC_MAQ_S_W_QHLL  = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
 889    OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
 890    OPC_MAQ_S_W_QHLR  = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
 891    OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
 892    OPC_MAQ_S_W_QHRL  = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
 893    OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
 894    OPC_MAQ_S_W_QHRR  = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
 895    OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
 896    OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
 897    OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
 898};
 899
 900#define MASK_SHLL_OB(op)            (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 901enum {
 902    /* MIPS DSP GPR-Based Shift Sub-class */
 903    OPC_SHLL_PW    = (0x10 << 6) | OPC_SHLL_OB_DSP,
 904    OPC_SHLL_S_PW  = (0x14 << 6) | OPC_SHLL_OB_DSP,
 905    OPC_SHLLV_OB   = (0x02 << 6) | OPC_SHLL_OB_DSP,
 906    OPC_SHLLV_PW   = (0x12 << 6) | OPC_SHLL_OB_DSP,
 907    OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
 908    OPC_SHLLV_QH   = (0x0A << 6) | OPC_SHLL_OB_DSP,
 909    OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
 910    OPC_SHRA_PW    = (0x11 << 6) | OPC_SHLL_OB_DSP,
 911    OPC_SHRA_R_PW  = (0x15 << 6) | OPC_SHLL_OB_DSP,
 912    OPC_SHRAV_OB   = (0x06 << 6) | OPC_SHLL_OB_DSP,
 913    OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
 914    OPC_SHRAV_PW   = (0x13 << 6) | OPC_SHLL_OB_DSP,
 915    OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
 916    OPC_SHRAV_QH   = (0x0B << 6) | OPC_SHLL_OB_DSP,
 917    OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
 918    OPC_SHRLV_OB   = (0x03 << 6) | OPC_SHLL_OB_DSP,
 919    OPC_SHRLV_QH   = (0x1B << 6) | OPC_SHLL_OB_DSP,
 920    OPC_SHLL_OB    = (0x00 << 6) | OPC_SHLL_OB_DSP,
 921    OPC_SHLL_QH    = (0x08 << 6) | OPC_SHLL_OB_DSP,
 922    OPC_SHLL_S_QH  = (0x0C << 6) | OPC_SHLL_OB_DSP,
 923    OPC_SHRA_OB    = (0x04 << 6) | OPC_SHLL_OB_DSP,
 924    OPC_SHRA_R_OB  = (0x05 << 6) | OPC_SHLL_OB_DSP,
 925    OPC_SHRA_QH    = (0x09 << 6) | OPC_SHLL_OB_DSP,
 926    OPC_SHRA_R_QH  = (0x0D << 6) | OPC_SHLL_OB_DSP,
 927    OPC_SHRL_OB    = (0x01 << 6) | OPC_SHLL_OB_DSP,
 928    OPC_SHRL_QH    = (0x19 << 6) | OPC_SHLL_OB_DSP,
 929};
 930
 931/* Coprocessor 0 (rs field) */
 932#define MASK_CP0(op)                (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
 933
 934enum {
 935    OPC_MFC0     = (0x00 << 21) | OPC_CP0,
 936    OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
 937    OPC_MFHC0    = (0x02 << 21) | OPC_CP0,
 938    OPC_MTC0     = (0x04 << 21) | OPC_CP0,
 939    OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
 940    OPC_MTHC0    = (0x06 << 21) | OPC_CP0,
 941    OPC_MFTR     = (0x08 << 21) | OPC_CP0,
 942    OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
 943    OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
 944    OPC_MTTR     = (0x0C << 21) | OPC_CP0,
 945    OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
 946    OPC_C0       = (0x10 << 21) | OPC_CP0,
 947    OPC_C0_1     = (0x11 << 21) | OPC_CP0,
 948    OPC_C0_2     = (0x12 << 21) | OPC_CP0,
 949    OPC_C0_3     = (0x13 << 21) | OPC_CP0,
 950    OPC_C0_4     = (0x14 << 21) | OPC_CP0,
 951    OPC_C0_5     = (0x15 << 21) | OPC_CP0,
 952    OPC_C0_6     = (0x16 << 21) | OPC_CP0,
 953    OPC_C0_7     = (0x17 << 21) | OPC_CP0,
 954    OPC_C0_8     = (0x18 << 21) | OPC_CP0,
 955    OPC_C0_9     = (0x19 << 21) | OPC_CP0,
 956    OPC_C0_A     = (0x1A << 21) | OPC_CP0,
 957    OPC_C0_B     = (0x1B << 21) | OPC_CP0,
 958    OPC_C0_C     = (0x1C << 21) | OPC_CP0,
 959    OPC_C0_D     = (0x1D << 21) | OPC_CP0,
 960    OPC_C0_E     = (0x1E << 21) | OPC_CP0,
 961    OPC_C0_F     = (0x1F << 21) | OPC_CP0,
 962};
 963
 964/* MFMC0 opcodes */
 965#define MASK_MFMC0(op)              (MASK_CP0(op) | (op & 0xFFFF))
 966
 967enum {
 968    OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
 969    OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
 970    OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
 971    OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
 972    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
 973    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
 974    OPC_DVP      = 0x04 | (0 << 3) | (1 << 5) | (0 << 11) | OPC_MFMC0,
 975    OPC_EVP      = 0x04 | (0 << 3) | (0 << 5) | (0 << 11) | OPC_MFMC0,
 976};
 977
 978/* Coprocessor 0 (with rs == C0) */
 979#define MASK_C0(op)                 (MASK_CP0(op) | (op & 0x3F))
 980
 981enum {
 982    OPC_TLBR     = 0x01 | OPC_C0,
 983    OPC_TLBWI    = 0x02 | OPC_C0,
 984    OPC_TLBINV   = 0x03 | OPC_C0,
 985    OPC_TLBINVF  = 0x04 | OPC_C0,
 986    OPC_TLBWR    = 0x06 | OPC_C0,
 987    OPC_TLBP     = 0x08 | OPC_C0,
 988    OPC_RFE      = 0x10 | OPC_C0,
 989    OPC_ERET     = 0x18 | OPC_C0,
 990    OPC_DERET    = 0x1F | OPC_C0,
 991    OPC_WAIT     = 0x20 | OPC_C0,
 992};
 993
 994#define MASK_CP2(op)                (MASK_OP_MAJOR(op) | (op & (0x1F << 21)))
 995
 996enum {
 997    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
 998    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
 999    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
1000    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
1001    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
1002    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
1003    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
1004    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
1005    OPC_BC2     = (0x08 << 21) | OPC_CP2,
1006    OPC_BC2EQZ  = (0x09 << 21) | OPC_CP2,
1007    OPC_BC2NEZ  = (0x0D << 21) | OPC_CP2,
1008};
1009
1010#define MASK_LMMI(op)    (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
1011
1012enum {
1013    OPC_PADDSH      = (24 << 21) | (0x00) | OPC_CP2,
1014    OPC_PADDUSH     = (25 << 21) | (0x00) | OPC_CP2,
1015    OPC_PADDH       = (26 << 21) | (0x00) | OPC_CP2,
1016    OPC_PADDW       = (27 << 21) | (0x00) | OPC_CP2,
1017    OPC_PADDSB      = (28 << 21) | (0x00) | OPC_CP2,
1018    OPC_PADDUSB     = (29 << 21) | (0x00) | OPC_CP2,
1019    OPC_PADDB       = (30 << 21) | (0x00) | OPC_CP2,
1020    OPC_PADDD       = (31 << 21) | (0x00) | OPC_CP2,
1021
1022    OPC_PSUBSH      = (24 << 21) | (0x01) | OPC_CP2,
1023    OPC_PSUBUSH     = (25 << 21) | (0x01) | OPC_CP2,
1024    OPC_PSUBH       = (26 << 21) | (0x01) | OPC_CP2,
1025    OPC_PSUBW       = (27 << 21) | (0x01) | OPC_CP2,
1026    OPC_PSUBSB      = (28 << 21) | (0x01) | OPC_CP2,
1027    OPC_PSUBUSB     = (29 << 21) | (0x01) | OPC_CP2,
1028    OPC_PSUBB       = (30 << 21) | (0x01) | OPC_CP2,
1029    OPC_PSUBD       = (31 << 21) | (0x01) | OPC_CP2,
1030
1031    OPC_PSHUFH      = (24 << 21) | (0x02) | OPC_CP2,
1032    OPC_PACKSSWH    = (25 << 21) | (0x02) | OPC_CP2,
1033    OPC_PACKSSHB    = (26 << 21) | (0x02) | OPC_CP2,
1034    OPC_PACKUSHB    = (27 << 21) | (0x02) | OPC_CP2,
1035    OPC_XOR_CP2     = (28 << 21) | (0x02) | OPC_CP2,
1036    OPC_NOR_CP2     = (29 << 21) | (0x02) | OPC_CP2,
1037    OPC_AND_CP2     = (30 << 21) | (0x02) | OPC_CP2,
1038    OPC_PANDN       = (31 << 21) | (0x02) | OPC_CP2,
1039
1040    OPC_PUNPCKLHW   = (24 << 21) | (0x03) | OPC_CP2,
1041    OPC_PUNPCKHHW   = (25 << 21) | (0x03) | OPC_CP2,
1042    OPC_PUNPCKLBH   = (26 << 21) | (0x03) | OPC_CP2,
1043    OPC_PUNPCKHBH   = (27 << 21) | (0x03) | OPC_CP2,
1044    OPC_PINSRH_0    = (28 << 21) | (0x03) | OPC_CP2,
1045    OPC_PINSRH_1    = (29 << 21) | (0x03) | OPC_CP2,
1046    OPC_PINSRH_2    = (30 << 21) | (0x03) | OPC_CP2,
1047    OPC_PINSRH_3    = (31 << 21) | (0x03) | OPC_CP2,
1048
1049    OPC_PAVGH       = (24 << 21) | (0x08) | OPC_CP2,
1050    OPC_PAVGB       = (25 << 21) | (0x08) | OPC_CP2,
1051    OPC_PMAXSH      = (26 << 21) | (0x08) | OPC_CP2,
1052    OPC_PMINSH      = (27 << 21) | (0x08) | OPC_CP2,
1053    OPC_PMAXUB      = (28 << 21) | (0x08) | OPC_CP2,
1054    OPC_PMINUB      = (29 << 21) | (0x08) | OPC_CP2,
1055
1056    OPC_PCMPEQW     = (24 << 21) | (0x09) | OPC_CP2,
1057    OPC_PCMPGTW     = (25 << 21) | (0x09) | OPC_CP2,
1058    OPC_PCMPEQH     = (26 << 21) | (0x09) | OPC_CP2,
1059    OPC_PCMPGTH     = (27 << 21) | (0x09) | OPC_CP2,
1060    OPC_PCMPEQB     = (28 << 21) | (0x09) | OPC_CP2,
1061    OPC_PCMPGTB     = (29 << 21) | (0x09) | OPC_CP2,
1062
1063    OPC_PSLLW       = (24 << 21) | (0x0A) | OPC_CP2,
1064    OPC_PSLLH       = (25 << 21) | (0x0A) | OPC_CP2,
1065    OPC_PMULLH      = (26 << 21) | (0x0A) | OPC_CP2,
1066    OPC_PMULHH      = (27 << 21) | (0x0A) | OPC_CP2,
1067    OPC_PMULUW      = (28 << 21) | (0x0A) | OPC_CP2,
1068    OPC_PMULHUH     = (29 << 21) | (0x0A) | OPC_CP2,
1069
1070    OPC_PSRLW       = (24 << 21) | (0x0B) | OPC_CP2,
1071    OPC_PSRLH       = (25 << 21) | (0x0B) | OPC_CP2,
1072    OPC_PSRAW       = (26 << 21) | (0x0B) | OPC_CP2,
1073    OPC_PSRAH       = (27 << 21) | (0x0B) | OPC_CP2,
1074    OPC_PUNPCKLWD   = (28 << 21) | (0x0B) | OPC_CP2,
1075    OPC_PUNPCKHWD   = (29 << 21) | (0x0B) | OPC_CP2,
1076
1077    OPC_ADDU_CP2    = (24 << 21) | (0x0C) | OPC_CP2,
1078    OPC_OR_CP2      = (25 << 21) | (0x0C) | OPC_CP2,
1079    OPC_ADD_CP2     = (26 << 21) | (0x0C) | OPC_CP2,
1080    OPC_DADD_CP2    = (27 << 21) | (0x0C) | OPC_CP2,
1081    OPC_SEQU_CP2    = (28 << 21) | (0x0C) | OPC_CP2,
1082    OPC_SEQ_CP2     = (29 << 21) | (0x0C) | OPC_CP2,
1083
1084    OPC_SUBU_CP2    = (24 << 21) | (0x0D) | OPC_CP2,
1085    OPC_PASUBUB     = (25 << 21) | (0x0D) | OPC_CP2,
1086    OPC_SUB_CP2     = (26 << 21) | (0x0D) | OPC_CP2,
1087    OPC_DSUB_CP2    = (27 << 21) | (0x0D) | OPC_CP2,
1088    OPC_SLTU_CP2    = (28 << 21) | (0x0D) | OPC_CP2,
1089    OPC_SLT_CP2     = (29 << 21) | (0x0D) | OPC_CP2,
1090
1091    OPC_SLL_CP2     = (24 << 21) | (0x0E) | OPC_CP2,
1092    OPC_DSLL_CP2    = (25 << 21) | (0x0E) | OPC_CP2,
1093    OPC_PEXTRH      = (26 << 21) | (0x0E) | OPC_CP2,
1094    OPC_PMADDHW     = (27 << 21) | (0x0E) | OPC_CP2,
1095    OPC_SLEU_CP2    = (28 << 21) | (0x0E) | OPC_CP2,
1096    OPC_SLE_CP2     = (29 << 21) | (0x0E) | OPC_CP2,
1097
1098    OPC_SRL_CP2     = (24 << 21) | (0x0F) | OPC_CP2,
1099    OPC_DSRL_CP2    = (25 << 21) | (0x0F) | OPC_CP2,
1100    OPC_SRA_CP2     = (26 << 21) | (0x0F) | OPC_CP2,
1101    OPC_DSRA_CP2    = (27 << 21) | (0x0F) | OPC_CP2,
1102    OPC_BIADD       = (28 << 21) | (0x0F) | OPC_CP2,
1103    OPC_PMOVMSKB    = (29 << 21) | (0x0F) | OPC_CP2,
1104};
1105
1106
1107#define MASK_CP3(op)                (MASK_OP_MAJOR(op) | (op & 0x3F))
1108
1109enum {
1110    OPC_LWXC1       = 0x00 | OPC_CP3,
1111    OPC_LDXC1       = 0x01 | OPC_CP3,
1112    OPC_LUXC1       = 0x05 | OPC_CP3,
1113    OPC_SWXC1       = 0x08 | OPC_CP3,
1114    OPC_SDXC1       = 0x09 | OPC_CP3,
1115    OPC_SUXC1       = 0x0D | OPC_CP3,
1116    OPC_PREFX       = 0x0F | OPC_CP3,
1117    OPC_ALNV_PS     = 0x1E | OPC_CP3,
1118    OPC_MADD_S      = 0x20 | OPC_CP3,
1119    OPC_MADD_D      = 0x21 | OPC_CP3,
1120    OPC_MADD_PS     = 0x26 | OPC_CP3,
1121    OPC_MSUB_S      = 0x28 | OPC_CP3,
1122    OPC_MSUB_D      = 0x29 | OPC_CP3,
1123    OPC_MSUB_PS     = 0x2E | OPC_CP3,
1124    OPC_NMADD_S     = 0x30 | OPC_CP3,
1125    OPC_NMADD_D     = 0x31 | OPC_CP3,
1126    OPC_NMADD_PS    = 0x36 | OPC_CP3,
1127    OPC_NMSUB_S     = 0x38 | OPC_CP3,
1128    OPC_NMSUB_D     = 0x39 | OPC_CP3,
1129    OPC_NMSUB_PS    = 0x3E | OPC_CP3,
1130};
1131
1132/*
1133 *     MMI (MultiMedia Instruction) encodings
1134 *     ======================================
1135 *
1136 * MMI instructions encoding table keys:
1137 *
1138 *     *   This code is reserved for future use. An attempt to execute it
1139 *         causes a Reserved Instruction exception.
1140 *     %   This code indicates an instruction class. The instruction word
1141 *         must be further decoded by examining additional tables that show
1142 *         the values for other instruction fields.
1143 *     #   This code is reserved for the unsupported instructions DMULT,
1144 *         DMULTU, DDIV, DDIVU, LL, LLD, SC, SCD, LWC2 and SWC2. An attempt
1145 *         to execute it causes a Reserved Instruction exception.
1146 *
1147 * MMI instructions encoded by opcode field (MMI, LQ, SQ):
1148 *
1149 *  31    26                                        0
1150 * +--------+----------------------------------------+
1151 * | opcode |                                        |
1152 * +--------+----------------------------------------+
1153 *
1154 *   opcode  bits 28..26
1155 *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
1156 *   31..29 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
1157 *   -------+-------+-------+-------+-------+-------+-------+-------+-------
1158 *    0 000 |SPECIAL| REGIMM|   J   |  JAL  |  BEQ  |  BNE  |  BLEZ |  BGTZ
1159 *    1 001 |  ADDI | ADDIU |  SLTI | SLTIU |  ANDI |  ORI  |  XORI |  LUI
1160 *    2 010 |  COP0 |  COP1 |   *   |   *   |  BEQL |  BNEL | BLEZL | BGTZL
1161 *    3 011 | DADDI | DADDIU|  LDL  |  LDR  |  MMI% |   *   |   LQ  |   SQ
1162 *    4 100 |   LB  |   LH  |  LWL  |   LW  |  LBU  |  LHU  |  LWR  |  LWU
1163 *    5 101 |   SB  |   SH  |  SWL  |   SW  |  SDL  |  SDR  |  SWR  | CACHE
1164 *    6 110 |   #   |  LWC1 |   #   |  PREF |   #   |  LDC1 |   #   |   LD
1165 *    7 111 |   #   |  SWC1 |   #   |   *   |   #   |  SDC1 |   #   |   SD
1166 */
1167
1168enum {
1169    MMI_OPC_CLASS_MMI = 0x1C << 26,    /* Same as OPC_SPECIAL2 */
1170    MMI_OPC_LQ        = 0x1E << 26,    /* Same as OPC_MSA */
1171    MMI_OPC_SQ        = 0x1F << 26,    /* Same as OPC_SPECIAL3 */
1172};
1173
1174/*
1175 * MMI instructions with opcode field = MMI:
1176 *
1177 *  31    26                                 5      0
1178 * +--------+-------------------------------+--------+
1179 * |   MMI  |                               |function|
1180 * +--------+-------------------------------+--------+
1181 *
1182 * function  bits 2..0
1183 *     bits |   0   |   1   |   2   |   3   |   4   |   5   |   6   |   7
1184 *     5..3 |  000  |  001  |  010  |  011  |  100  |  101  |  110  |  111
1185 *   -------+-------+-------+-------+-------+-------+-------+-------+-------
1186 *    0 000 |  MADD | MADDU |   *   |   *   | PLZCW |   *   |   *   |   *
1187 *    1 001 | MMI0% | MMI2% |   *   |   *   |   *   |   *   |   *   |   *
1188 *    2 010 | MFHI1 | MTHI1 | MFLO1 | MTLO1 |   *   |   *   |   *   |   *
1189 *    3 011 | MULT1 | MULTU1|  DIV1 | DIVU1 |   *   |   *   |   *   |   *
1190 *    4 100 | MADD1 | MADDU1|   *   |   *   |   *   |   *   |   *   |   *
1191 *    5 101 | MMI1% | MMI3% |   *   |   *   |   *   |   *   |   *   |   *
1192 *    6 110 | PMFHL | PMTHL |   *   |   *   | PSLLH |   *   | PSRLH | PSRAH
1193 *    7 111 |   *   |   *   |   *   |   *   | PSLLW |   *   | PSRLW | PSRAW
1194 */
1195
1196#define MASK_MMI(op) (MASK_OP_MAJOR(op) | ((op) & 0x3F))
1197enum {
1198    MMI_OPC_MADD       = 0x00 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADD */
1199    MMI_OPC_MADDU      = 0x01 | MMI_OPC_CLASS_MMI, /* Same as OPC_MADDU */
1200    MMI_OPC_MULT1      = 0x18 | MMI_OPC_CLASS_MMI, /* Same minor as OPC_MULT */
1201    MMI_OPC_MULTU1     = 0x19 | MMI_OPC_CLASS_MMI, /* Same min. as OPC_MULTU */
1202    MMI_OPC_DIV1       = 0x1A | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIV  */
1203    MMI_OPC_DIVU1      = 0x1B | MMI_OPC_CLASS_MMI, /* Same minor as OPC_DIVU */
1204    MMI_OPC_MADD1      = 0x20 | MMI_OPC_CLASS_MMI,
1205    MMI_OPC_MADDU1     = 0x21 | MMI_OPC_CLASS_MMI,
1206};
1207
1208/* global register indices */
1209TCGv cpu_gpr[32], cpu_PC;
1210/*
1211 * For CPUs using 128-bit GPR registers, we put the lower halves in cpu_gpr[])
1212 * and the upper halves in cpu_gpr_hi[].
1213 */
1214TCGv_i64 cpu_gpr_hi[32];
1215TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC];
1216static TCGv cpu_dspctrl, btarget;
1217TCGv bcond;
1218static TCGv cpu_lladdr, cpu_llval;
1219static TCGv_i32 hflags;
1220TCGv_i32 fpu_fcr0, fpu_fcr31;
1221TCGv_i64 fpu_f64[32];
1222
1223#include "exec/gen-icount.h"
1224
1225#define gen_helper_0e0i(name, arg) do {                           \
1226    TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
1227    gen_helper_##name(cpu_env, helper_tmp);                       \
1228    tcg_temp_free_i32(helper_tmp);                                \
1229    } while (0)
1230
1231#define gen_helper_0e1i(name, arg1, arg2) do {                    \
1232    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
1233    gen_helper_##name(cpu_env, arg1, helper_tmp);                 \
1234    tcg_temp_free_i32(helper_tmp);                                \
1235    } while (0)
1236
1237#define gen_helper_1e0i(name, ret, arg1) do {                     \
1238    TCGv_i32 helper_tmp = tcg_const_i32(arg1);                    \
1239    gen_helper_##name(ret, cpu_env, helper_tmp);                  \
1240    tcg_temp_free_i32(helper_tmp);                                \
1241    } while (0)
1242
1243#define gen_helper_1e1i(name, ret, arg1, arg2) do {               \
1244    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
1245    gen_helper_##name(ret, cpu_env, arg1, helper_tmp);            \
1246    tcg_temp_free_i32(helper_tmp);                                \
1247    } while (0)
1248
1249#define gen_helper_0e2i(name, arg1, arg2, arg3) do {              \
1250    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
1251    gen_helper_##name(cpu_env, arg1, arg2, helper_tmp);           \
1252    tcg_temp_free_i32(helper_tmp);                                \
1253    } while (0)
1254
1255#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do {         \
1256    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
1257    gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp);      \
1258    tcg_temp_free_i32(helper_tmp);                                \
1259    } while (0)
1260
1261#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do {        \
1262    TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
1263    gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp);     \
1264    tcg_temp_free_i32(helper_tmp);                                \
1265    } while (0)
1266
1267#define DISAS_STOP       DISAS_TARGET_0
1268#define DISAS_EXIT       DISAS_TARGET_1
1269
1270static const char * const regnames[] = {
1271    "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1272    "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1273    "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1274    "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1275};
1276
1277static const char * const regnames_HI[] = {
1278    "HI0", "HI1", "HI2", "HI3",
1279};
1280
1281static const char * const regnames_LO[] = {
1282    "LO0", "LO1", "LO2", "LO3",
1283};
1284
1285static const char * const fregnames[] = {
1286    "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
1287    "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
1288    "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1289    "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1290};
1291
1292/* General purpose registers moves. */
1293void gen_load_gpr(TCGv t, int reg)
1294{
1295    if (reg == 0) {
1296        tcg_gen_movi_tl(t, 0);
1297    } else {
1298        tcg_gen_mov_tl(t, cpu_gpr[reg]);
1299    }
1300}
1301
1302void gen_store_gpr(TCGv t, int reg)
1303{
1304    if (reg != 0) {
1305        tcg_gen_mov_tl(cpu_gpr[reg], t);
1306    }
1307}
1308
1309#if defined(TARGET_MIPS64)
1310void gen_load_gpr_hi(TCGv_i64 t, int reg)
1311{
1312    if (reg == 0) {
1313        tcg_gen_movi_i64(t, 0);
1314    } else {
1315        tcg_gen_mov_i64(t, cpu_gpr_hi[reg]);
1316    }
1317}
1318
1319void gen_store_gpr_hi(TCGv_i64 t, int reg)
1320{
1321    if (reg != 0) {
1322        tcg_gen_mov_i64(cpu_gpr_hi[reg], t);
1323    }
1324}
1325#endif /* TARGET_MIPS64 */
1326
1327/* Moves to/from shadow registers. */
1328static inline void gen_load_srsgpr(int from, int to)
1329{
1330    TCGv t0 = tcg_temp_new();
1331
1332    if (from == 0) {
1333        tcg_gen_movi_tl(t0, 0);
1334    } else {
1335        TCGv_i32 t2 = tcg_temp_new_i32();
1336        TCGv_ptr addr = tcg_temp_new_ptr();
1337
1338        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1339        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1340        tcg_gen_andi_i32(t2, t2, 0xf);
1341        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1342        tcg_gen_ext_i32_ptr(addr, t2);
1343        tcg_gen_add_ptr(addr, cpu_env, addr);
1344
1345        tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1346        tcg_temp_free_ptr(addr);
1347        tcg_temp_free_i32(t2);
1348    }
1349    gen_store_gpr(t0, to);
1350    tcg_temp_free(t0);
1351}
1352
1353static inline void gen_store_srsgpr(int from, int to)
1354{
1355    if (to != 0) {
1356        TCGv t0 = tcg_temp_new();
1357        TCGv_i32 t2 = tcg_temp_new_i32();
1358        TCGv_ptr addr = tcg_temp_new_ptr();
1359
1360        gen_load_gpr(t0, from);
1361        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1362        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1363        tcg_gen_andi_i32(t2, t2, 0xf);
1364        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1365        tcg_gen_ext_i32_ptr(addr, t2);
1366        tcg_gen_add_ptr(addr, cpu_env, addr);
1367
1368        tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1369        tcg_temp_free_ptr(addr);
1370        tcg_temp_free_i32(t2);
1371        tcg_temp_free(t0);
1372    }
1373}
1374
1375/* Tests */
1376static inline void gen_save_pc(target_ulong pc)
1377{
1378    tcg_gen_movi_tl(cpu_PC, pc);
1379}
1380
1381static inline void save_cpu_state(DisasContext *ctx, int do_save_pc)
1382{
1383    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1384    if (do_save_pc && ctx->base.pc_next != ctx->saved_pc) {
1385        gen_save_pc(ctx->base.pc_next);
1386        ctx->saved_pc = ctx->base.pc_next;
1387    }
1388    if (ctx->hflags != ctx->saved_hflags) {
1389        tcg_gen_movi_i32(hflags, ctx->hflags);
1390        ctx->saved_hflags = ctx->hflags;
1391        switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1392        case MIPS_HFLAG_BR:
1393            break;
1394        case MIPS_HFLAG_BC:
1395        case MIPS_HFLAG_BL:
1396        case MIPS_HFLAG_B:
1397            tcg_gen_movi_tl(btarget, ctx->btarget);
1398            break;
1399        }
1400    }
1401}
1402
1403static inline void restore_cpu_state(CPUMIPSState *env, DisasContext *ctx)
1404{
1405    ctx->saved_hflags = ctx->hflags;
1406    switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1407    case MIPS_HFLAG_BR:
1408        break;
1409    case MIPS_HFLAG_BC:
1410    case MIPS_HFLAG_BL:
1411    case MIPS_HFLAG_B:
1412        ctx->btarget = env->btarget;
1413        break;
1414    }
1415}
1416
1417void generate_exception_err(DisasContext *ctx, int excp, int err)
1418{
1419    TCGv_i32 texcp = tcg_const_i32(excp);
1420    TCGv_i32 terr = tcg_const_i32(err);
1421    save_cpu_state(ctx, 1);
1422    gen_helper_raise_exception_err(cpu_env, texcp, terr);
1423    tcg_temp_free_i32(terr);
1424    tcg_temp_free_i32(texcp);
1425    ctx->base.is_jmp = DISAS_NORETURN;
1426}
1427
1428void generate_exception(DisasContext *ctx, int excp)
1429{
1430    gen_helper_0e0i(raise_exception, excp);
1431}
1432
1433void generate_exception_end(DisasContext *ctx, int excp)
1434{
1435    generate_exception_err(ctx, excp, 0);
1436}
1437
1438void gen_reserved_instruction(DisasContext *ctx)
1439{
1440    generate_exception_end(ctx, EXCP_RI);
1441}
1442
1443/* Floating point register moves. */
1444void gen_load_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1445{
1446    if (ctx->hflags & MIPS_HFLAG_FRE) {
1447        generate_exception(ctx, EXCP_RI);
1448    }
1449    tcg_gen_extrl_i64_i32(t, fpu_f64[reg]);
1450}
1451
1452void gen_store_fpr32(DisasContext *ctx, TCGv_i32 t, int reg)
1453{
1454    TCGv_i64 t64;
1455    if (ctx->hflags & MIPS_HFLAG_FRE) {
1456        generate_exception(ctx, EXCP_RI);
1457    }
1458    t64 = tcg_temp_new_i64();
1459    tcg_gen_extu_i32_i64(t64, t);
1460    tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1461    tcg_temp_free_i64(t64);
1462}
1463
1464static void gen_load_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1465{
1466    if (ctx->hflags & MIPS_HFLAG_F64) {
1467        tcg_gen_extrh_i64_i32(t, fpu_f64[reg]);
1468    } else {
1469        gen_load_fpr32(ctx, t, reg | 1);
1470    }
1471}
1472
1473static void gen_store_fpr32h(DisasContext *ctx, TCGv_i32 t, int reg)
1474{
1475    if (ctx->hflags & MIPS_HFLAG_F64) {
1476        TCGv_i64 t64 = tcg_temp_new_i64();
1477        tcg_gen_extu_i32_i64(t64, t);
1478        tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1479        tcg_temp_free_i64(t64);
1480    } else {
1481        gen_store_fpr32(ctx, t, reg | 1);
1482    }
1483}
1484
1485void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1486{
1487    if (ctx->hflags & MIPS_HFLAG_F64) {
1488        tcg_gen_mov_i64(t, fpu_f64[reg]);
1489    } else {
1490        tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1491    }
1492}
1493
1494void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1495{
1496    if (ctx->hflags & MIPS_HFLAG_F64) {
1497        tcg_gen_mov_i64(fpu_f64[reg], t);
1498    } else {
1499        TCGv_i64 t0;
1500        tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1501        t0 = tcg_temp_new_i64();
1502        tcg_gen_shri_i64(t0, t, 32);
1503        tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1504        tcg_temp_free_i64(t0);
1505    }
1506}
1507
1508int get_fp_bit(int cc)
1509{
1510    if (cc) {
1511        return 24 + cc;
1512    } else {
1513        return 23;
1514    }
1515}
1516
1517/* Addresses computation */
1518void gen_op_addr_add(DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1519{
1520    tcg_gen_add_tl(ret, arg0, arg1);
1521
1522#if defined(TARGET_MIPS64)
1523    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1524        tcg_gen_ext32s_i64(ret, ret);
1525    }
1526#endif
1527}
1528
1529static inline void gen_op_addr_addi(DisasContext *ctx, TCGv ret, TCGv base,
1530                                    target_long ofs)
1531{
1532    tcg_gen_addi_tl(ret, base, ofs);
1533
1534#if defined(TARGET_MIPS64)
1535    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1536        tcg_gen_ext32s_i64(ret, ret);
1537    }
1538#endif
1539}
1540
1541/* Addresses computation (translation time) */
1542static target_long addr_add(DisasContext *ctx, target_long base,
1543                            target_long offset)
1544{
1545    target_long sum = base + offset;
1546
1547#if defined(TARGET_MIPS64)
1548    if (ctx->hflags & MIPS_HFLAG_AWRAP) {
1549        sum = (int32_t)sum;
1550    }
1551#endif
1552    return sum;
1553}
1554
1555/* Sign-extract the low 32-bits to a target_long.  */
1556void gen_move_low32(TCGv ret, TCGv_i64 arg)
1557{
1558#if defined(TARGET_MIPS64)
1559    tcg_gen_ext32s_i64(ret, arg);
1560#else
1561    tcg_gen_extrl_i64_i32(ret, arg);
1562#endif
1563}
1564
1565/* Sign-extract the high 32-bits to a target_long.  */
1566void gen_move_high32(TCGv ret, TCGv_i64 arg)
1567{
1568#if defined(TARGET_MIPS64)
1569    tcg_gen_sari_i64(ret, arg, 32);
1570#else
1571    tcg_gen_extrh_i64_i32(ret, arg);
1572#endif
1573}
1574
1575void check_cp0_enabled(DisasContext *ctx)
1576{
1577    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
1578        generate_exception_end(ctx, EXCP_CpU);
1579    }
1580}
1581
1582void check_cp1_enabled(DisasContext *ctx)
1583{
1584    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU))) {
1585        generate_exception_err(ctx, EXCP_CpU, 1);
1586    }
1587}
1588
1589/*
1590 * Verify that the processor is running with COP1X instructions enabled.
1591 * This is associated with the nabla symbol in the MIPS32 and MIPS64
1592 * opcode tables.
1593 */
1594void check_cop1x(DisasContext *ctx)
1595{
1596    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X))) {
1597        gen_reserved_instruction(ctx);
1598    }
1599}
1600
1601/*
1602 * Verify that the processor is running with 64-bit floating-point
1603 * operations enabled.
1604 */
1605void check_cp1_64bitmode(DisasContext *ctx)
1606{
1607    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X))) {
1608        gen_reserved_instruction(ctx);
1609    }
1610}
1611
1612/*
1613 * Verify if floating point register is valid; an operation is not defined
1614 * if bit 0 of any register specification is set and the FR bit in the
1615 * Status register equals zero, since the register numbers specify an
1616 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1617 * in the Status register equals one, both even and odd register numbers
1618 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1619 *
1620 * Multiple 64 bit wide registers can be checked by calling
1621 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1622 */
1623void check_cp1_registers(DisasContext *ctx, int regs)
1624{
1625    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1))) {
1626        gen_reserved_instruction(ctx);
1627    }
1628}
1629
1630/*
1631 * Verify that the processor is running with DSP instructions enabled.
1632 * This is enabled by CP0 Status register MX(24) bit.
1633 */
1634static inline void check_dsp(DisasContext *ctx)
1635{
1636    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1637        if (ctx->insn_flags & ASE_DSP) {
1638            generate_exception_end(ctx, EXCP_DSPDIS);
1639        } else {
1640            gen_reserved_instruction(ctx);
1641        }
1642    }
1643}
1644
1645static inline void check_dsp_r2(DisasContext *ctx)
1646{
1647    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R2))) {
1648        if (ctx->insn_flags & ASE_DSP) {
1649            generate_exception_end(ctx, EXCP_DSPDIS);
1650        } else {
1651            gen_reserved_instruction(ctx);
1652        }
1653    }
1654}
1655
1656static inline void check_dsp_r3(DisasContext *ctx)
1657{
1658    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP_R3))) {
1659        if (ctx->insn_flags & ASE_DSP) {
1660            generate_exception_end(ctx, EXCP_DSPDIS);
1661        } else {
1662            gen_reserved_instruction(ctx);
1663        }
1664    }
1665}
1666
1667/*
1668 * This code generates a "reserved instruction" exception if the
1669 * CPU does not support the instruction set corresponding to flags.
1670 */
1671void check_insn(DisasContext *ctx, uint64_t flags)
1672{
1673    if (unlikely(!(ctx->insn_flags & flags))) {
1674        gen_reserved_instruction(ctx);
1675    }
1676}
1677
1678/*
1679 * This code generates a "reserved instruction" exception if the
1680 * CPU has corresponding flag set which indicates that the instruction
1681 * has been removed.
1682 */
1683static inline void check_insn_opc_removed(DisasContext *ctx, uint64_t flags)
1684{
1685    if (unlikely(ctx->insn_flags & flags)) {
1686        gen_reserved_instruction(ctx);
1687    }
1688}
1689
1690/*
1691 * The Linux kernel traps certain reserved instruction exceptions to
1692 * emulate the corresponding instructions. QEMU is the kernel in user
1693 * mode, so those traps are emulated by accepting the instructions.
1694 *
1695 * A reserved instruction exception is generated for flagged CPUs if
1696 * QEMU runs in system mode.
1697 */
1698static inline void check_insn_opc_user_only(DisasContext *ctx, uint64_t flags)
1699{
1700#ifndef CONFIG_USER_ONLY
1701    check_insn_opc_removed(ctx, flags);
1702#endif
1703}
1704
1705/*
1706 * This code generates a "reserved instruction" exception if the
1707 * CPU does not support 64-bit paired-single (PS) floating point data type.
1708 */
1709static inline void check_ps(DisasContext *ctx)
1710{
1711    if (unlikely(!ctx->ps)) {
1712        generate_exception(ctx, EXCP_RI);
1713    }
1714    check_cp1_64bitmode(ctx);
1715}
1716
1717/*
1718 * This code generates a "reserved instruction" exception if cpu is not
1719 * 64-bit or 64-bit instructions are not enabled.
1720 */
1721void check_mips_64(DisasContext *ctx)
1722{
1723    if (unlikely((TARGET_LONG_BITS != 64) || !(ctx->hflags & MIPS_HFLAG_64))) {
1724        gen_reserved_instruction(ctx);
1725    }
1726}
1727
1728#ifndef CONFIG_USER_ONLY
1729static inline void check_mvh(DisasContext *ctx)
1730{
1731    if (unlikely(!ctx->mvh)) {
1732        generate_exception(ctx, EXCP_RI);
1733    }
1734}
1735#endif
1736
1737/*
1738 * This code generates a "reserved instruction" exception if the
1739 * Config5 XNP bit is set.
1740 */
1741static inline void check_xnp(DisasContext *ctx)
1742{
1743    if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_XNP))) {
1744        gen_reserved_instruction(ctx);
1745    }
1746}
1747
1748#ifndef CONFIG_USER_ONLY
1749/*
1750 * This code generates a "reserved instruction" exception if the
1751 * Config3 PW bit is NOT set.
1752 */
1753static inline void check_pw(DisasContext *ctx)
1754{
1755    if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_PW)))) {
1756        gen_reserved_instruction(ctx);
1757    }
1758}
1759#endif
1760
1761/*
1762 * This code generates a "reserved instruction" exception if the
1763 * Config3 MT bit is NOT set.
1764 */
1765static inline void check_mt(DisasContext *ctx)
1766{
1767    if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
1768        gen_reserved_instruction(ctx);
1769    }
1770}
1771
1772#ifndef CONFIG_USER_ONLY
1773/*
1774 * This code generates a "coprocessor unusable" exception if CP0 is not
1775 * available, and, if that is not the case, generates a "reserved instruction"
1776 * exception if the Config5 MT bit is NOT set. This is needed for availability
1777 * control of some of MT ASE instructions.
1778 */
1779static inline void check_cp0_mt(DisasContext *ctx)
1780{
1781    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0))) {
1782        generate_exception_end(ctx, EXCP_CpU);
1783    } else {
1784        if (unlikely(!(ctx->CP0_Config3 & (1 << CP0C3_MT)))) {
1785            gen_reserved_instruction(ctx);
1786        }
1787    }
1788}
1789#endif
1790
1791/*
1792 * This code generates a "reserved instruction" exception if the
1793 * Config5 NMS bit is set.
1794 */
1795static inline void check_nms(DisasContext *ctx)
1796{
1797    if (unlikely(ctx->CP0_Config5 & (1 << CP0C5_NMS))) {
1798        gen_reserved_instruction(ctx);
1799    }
1800}
1801
1802/*
1803 * This code generates a "reserved instruction" exception if the
1804 * Config5 NMS bit is set, and Config1 DL, Config1 IL, Config2 SL,
1805 * Config2 TL, and Config5 L2C are unset.
1806 */
1807static inline void check_nms_dl_il_sl_tl_l2c(DisasContext *ctx)
1808{
1809    if (unlikely((ctx->CP0_Config5 & (1 << CP0C5_NMS)) &&
1810                 !(ctx->CP0_Config1 & (1 << CP0C1_DL)) &&
1811                 !(ctx->CP0_Config1 & (1 << CP0C1_IL)) &&
1812                 !(ctx->CP0_Config2 & (1 << CP0C2_SL)) &&
1813                 !(ctx->CP0_Config2 & (1 << CP0C2_TL)) &&
1814                 !(ctx->CP0_Config5 & (1 << CP0C5_L2C)))) {
1815        gen_reserved_instruction(ctx);
1816    }
1817}
1818
1819/*
1820 * This code generates a "reserved instruction" exception if the
1821 * Config5 EVA bit is NOT set.
1822 */
1823static inline void check_eva(DisasContext *ctx)
1824{
1825    if (unlikely(!(ctx->CP0_Config5 & (1 << CP0C5_EVA)))) {
1826        gen_reserved_instruction(ctx);
1827    }
1828}
1829
1830
1831/*
1832 * Define small wrappers for gen_load_fpr* so that we have a uniform
1833 * calling interface for 32 and 64-bit FPRs.  No sense in changing
1834 * all callers for gen_load_fpr32 when we need the CTX parameter for
1835 * this one use.
1836 */
1837#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(ctx, x, y)
1838#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1839#define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
1840static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
1841                                               int ft, int fs, int cc)        \
1842{                                                                             \
1843    TCGv_i##bits fp0 = tcg_temp_new_i##bits();                                \
1844    TCGv_i##bits fp1 = tcg_temp_new_i##bits();                                \
1845    switch (ifmt) {                                                           \
1846    case FMT_PS:                                                              \
1847        check_ps(ctx);                                                        \
1848        break;                                                                \
1849    case FMT_D:                                                               \
1850        if (abs) {                                                            \
1851            check_cop1x(ctx);                                                 \
1852        }                                                                     \
1853        check_cp1_registers(ctx, fs | ft);                                    \
1854        break;                                                                \
1855    case FMT_S:                                                               \
1856        if (abs) {                                                            \
1857            check_cop1x(ctx);                                                 \
1858        }                                                                     \
1859        break;                                                                \
1860    }                                                                         \
1861    gen_ldcmp_fpr##bits(ctx, fp0, fs);                                        \
1862    gen_ldcmp_fpr##bits(ctx, fp1, ft);                                        \
1863    switch (n) {                                                              \
1864    case  0:                                                                  \
1865        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);         \
1866    break;                                                                    \
1867    case  1:                                                                  \
1868        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);        \
1869    break;                                                                    \
1870    case  2:                                                                  \
1871        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);        \
1872    break;                                                                    \
1873    case  3:                                                                  \
1874        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);       \
1875    break;                                                                    \
1876    case  4:                                                                  \
1877        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);       \
1878    break;                                                                    \
1879    case  5:                                                                  \
1880        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);       \
1881    break;                                                                    \
1882    case  6:                                                                  \
1883        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);       \
1884    break;                                                                    \
1885    case  7:                                                                  \
1886        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);       \
1887    break;                                                                    \
1888    case  8:                                                                  \
1889        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);        \
1890    break;                                                                    \
1891    case  9:                                                                  \
1892        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc);      \
1893    break;                                                                    \
1894    case 10:                                                                  \
1895        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);       \
1896    break;                                                                    \
1897    case 11:                                                                  \
1898        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);       \
1899    break;                                                                    \
1900    case 12:                                                                  \
1901        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);        \
1902    break;                                                                    \
1903    case 13:                                                                  \
1904        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);       \
1905    break;                                                                    \
1906    case 14:                                                                  \
1907        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);        \
1908    break;                                                                    \
1909    case 15:                                                                  \
1910        gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);       \
1911    break;                                                                    \
1912    default:                                                                  \
1913        abort();                                                              \
1914    }                                                                         \
1915    tcg_temp_free_i##bits(fp0);                                               \
1916    tcg_temp_free_i##bits(fp1);                                               \
1917}
1918
1919FOP_CONDS(, 0, d, FMT_D, 64)
1920FOP_CONDS(abs, 1, d, FMT_D, 64)
1921FOP_CONDS(, 0, s, FMT_S, 32)
1922FOP_CONDS(abs, 1, s, FMT_S, 32)
1923FOP_CONDS(, 0, ps, FMT_PS, 64)
1924FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1925#undef FOP_CONDS
1926
1927#define FOP_CONDNS(fmt, ifmt, bits, STORE)                              \
1928static inline void gen_r6_cmp_ ## fmt(DisasContext *ctx, int n,         \
1929                                      int ft, int fs, int fd)           \
1930{                                                                       \
1931    TCGv_i ## bits fp0 = tcg_temp_new_i ## bits();                      \
1932    TCGv_i ## bits fp1 = tcg_temp_new_i ## bits();                      \
1933    if (ifmt == FMT_D) {                                                \
1934        check_cp1_registers(ctx, fs | ft | fd);                         \
1935    }                                                                   \
1936    gen_ldcmp_fpr ## bits(ctx, fp0, fs);                                \
1937    gen_ldcmp_fpr ## bits(ctx, fp1, ft);                                \
1938    switch (n) {                                                        \
1939    case  0:                                                            \
1940        gen_helper_r6_cmp_ ## fmt ## _af(fp0, cpu_env, fp0, fp1);       \
1941        break;                                                          \
1942    case  1:                                                            \
1943        gen_helper_r6_cmp_ ## fmt ## _un(fp0, cpu_env, fp0, fp1);       \
1944        break;                                                          \
1945    case  2:                                                            \
1946        gen_helper_r6_cmp_ ## fmt ## _eq(fp0, cpu_env, fp0, fp1);       \
1947        break;                                                          \
1948    case  3:                                                            \
1949        gen_helper_r6_cmp_ ## fmt ## _ueq(fp0, cpu_env, fp0, fp1);      \
1950        break;                                                          \
1951    case  4:                                                            \
1952        gen_helper_r6_cmp_ ## fmt ## _lt(fp0, cpu_env, fp0, fp1);       \
1953        break;                                                          \
1954    case  5:                                                            \
1955        gen_helper_r6_cmp_ ## fmt ## _ult(fp0, cpu_env, fp0, fp1);      \
1956        break;                                                          \
1957    case  6:                                                            \
1958        gen_helper_r6_cmp_ ## fmt ## _le(fp0, cpu_env, fp0, fp1);       \
1959        break;                                                          \
1960    case  7:                                                            \
1961        gen_helper_r6_cmp_ ## fmt ## _ule(fp0, cpu_env, fp0, fp1);      \
1962        break;                                                          \
1963    case  8:                                                            \
1964        gen_helper_r6_cmp_ ## fmt ## _saf(fp0, cpu_env, fp0, fp1);      \
1965        break;                                                          \
1966    case  9:                                                            \
1967        gen_helper_r6_cmp_ ## fmt ## _sun(fp0, cpu_env, fp0, fp1);      \
1968        break;                                                          \
1969    case 10:                                                            \
1970        gen_helper_r6_cmp_ ## fmt ## _seq(fp0, cpu_env, fp0, fp1);      \
1971        break;                                                          \
1972    case 11:                                                            \
1973        gen_helper_r6_cmp_ ## fmt ## _sueq(fp0, cpu_env, fp0, fp1);     \
1974        break;                                                          \
1975    case 12:                                                            \
1976        gen_helper_r6_cmp_ ## fmt ## _slt(fp0, cpu_env, fp0, fp1);      \
1977        break;                                                          \
1978    case 13:                                                            \
1979        gen_helper_r6_cmp_ ## fmt ## _sult(fp0, cpu_env, fp0, fp1);     \
1980        break;                                                          \
1981    case 14:                                                            \
1982        gen_helper_r6_cmp_ ## fmt ## _sle(fp0, cpu_env, fp0, fp1);      \
1983        break;                                                          \
1984    case 15:                                                            \
1985        gen_helper_r6_cmp_ ## fmt ## _sule(fp0, cpu_env, fp0, fp1);     \
1986        break;                                                          \
1987    case 17:                                                            \
1988        gen_helper_r6_cmp_ ## fmt ## _or(fp0, cpu_env, fp0, fp1);       \
1989        break;                                                          \
1990    case 18:                                                            \
1991        gen_helper_r6_cmp_ ## fmt ## _une(fp0, cpu_env, fp0, fp1);      \
1992        break;                                                          \
1993    case 19:                                                            \
1994        gen_helper_r6_cmp_ ## fmt ## _ne(fp0, cpu_env, fp0, fp1);       \
1995        break;                                                          \
1996    case 25:                                                            \
1997        gen_helper_r6_cmp_ ## fmt ## _sor(fp0, cpu_env, fp0, fp1);      \
1998        break;                                                          \
1999    case 26:                                                            \
2000        gen_helper_r6_cmp_ ## fmt ## _sune(fp0, cpu_env, fp0, fp1);     \
2001        break;                                                          \
2002    case 27:                                                            \
2003        gen_helper_r6_cmp_ ## fmt ## _sne(fp0, cpu_env, fp0, fp1);      \
2004        break;                                                          \
2005    default:                                                            \
2006        abort();                                                        \
2007    }                                                                   \
2008    STORE;                                                              \
2009    tcg_temp_free_i ## bits(fp0);                                       \
2010    tcg_temp_free_i ## bits(fp1);                                       \
2011}
2012
2013FOP_CONDNS(d, FMT_D, 64, gen_store_fpr64(ctx, fp0, fd))
2014FOP_CONDNS(s, FMT_S, 32, gen_store_fpr32(ctx, fp0, fd))
2015#undef FOP_CONDNS
2016#undef gen_ldcmp_fpr32
2017#undef gen_ldcmp_fpr64
2018
2019/* load/store instructions. */
2020#ifdef CONFIG_USER_ONLY
2021#define OP_LD_ATOMIC(insn, fname)                                          \
2022static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
2023                                DisasContext *ctx)                         \
2024{                                                                          \
2025    TCGv t0 = tcg_temp_new();                                              \
2026    tcg_gen_mov_tl(t0, arg1);                                              \
2027    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
2028    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));            \
2029    tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval));            \
2030    tcg_temp_free(t0);                                                     \
2031}
2032#else
2033#define OP_LD_ATOMIC(insn, fname)                                          \
2034static inline void op_ld_##insn(TCGv ret, TCGv arg1, int mem_idx,          \
2035                                DisasContext *ctx)                         \
2036{                                                                          \
2037    gen_helper_1e1i(insn, ret, arg1, mem_idx);                             \
2038}
2039#endif
2040OP_LD_ATOMIC(ll, ld32s);
2041#if defined(TARGET_MIPS64)
2042OP_LD_ATOMIC(lld, ld64);
2043#endif
2044#undef OP_LD_ATOMIC
2045
2046void gen_base_offset_addr(DisasContext *ctx, TCGv addr, int base, int offset)
2047{
2048    if (base == 0) {
2049        tcg_gen_movi_tl(addr, offset);
2050    } else if (offset == 0) {
2051        gen_load_gpr(addr, base);
2052    } else {
2053        tcg_gen_movi_tl(addr, offset);
2054        gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
2055    }
2056}
2057
2058static target_ulong pc_relative_pc(DisasContext *ctx)
2059{
2060    target_ulong pc = ctx->base.pc_next;
2061
2062    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2063        int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
2064
2065        pc -= branch_bytes;
2066    }
2067
2068    pc &= ~(target_ulong)3;
2069    return pc;
2070}
2071
2072/* Load */
2073static void gen_ld(DisasContext *ctx, uint32_t opc,
2074                   int rt, int base, int offset)
2075{
2076    TCGv t0, t1, t2;
2077    int mem_idx = ctx->mem_idx;
2078
2079    if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F |
2080                                      INSN_LOONGSON3A)) {
2081        /*
2082         * Loongson CPU uses a load to zero register for prefetch.
2083         * We emulate it as a NOP. On other CPU we must perform the
2084         * actual memory access.
2085         */
2086        return;
2087    }
2088
2089    t0 = tcg_temp_new();
2090    gen_base_offset_addr(ctx, t0, base, offset);
2091
2092    switch (opc) {
2093#if defined(TARGET_MIPS64)
2094    case OPC_LWU:
2095        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL |
2096                           ctx->default_tcg_memop_mask);
2097        gen_store_gpr(t0, rt);
2098        break;
2099    case OPC_LD:
2100        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ |
2101                           ctx->default_tcg_memop_mask);
2102        gen_store_gpr(t0, rt);
2103        break;
2104    case OPC_LLD:
2105    case R6_OPC_LLD:
2106        op_ld_lld(t0, t0, mem_idx, ctx);
2107        gen_store_gpr(t0, rt);
2108        break;
2109    case OPC_LDL:
2110        t1 = tcg_temp_new();
2111        /*
2112         * Do a byte access to possibly trigger a page
2113         * fault with the unaligned address.
2114         */
2115        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2116        tcg_gen_andi_tl(t1, t0, 7);
2117#ifndef TARGET_WORDS_BIGENDIAN
2118        tcg_gen_xori_tl(t1, t1, 7);
2119#endif
2120        tcg_gen_shli_tl(t1, t1, 3);
2121        tcg_gen_andi_tl(t0, t0, ~7);
2122        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2123        tcg_gen_shl_tl(t0, t0, t1);
2124        t2 = tcg_const_tl(-1);
2125        tcg_gen_shl_tl(t2, t2, t1);
2126        gen_load_gpr(t1, rt);
2127        tcg_gen_andc_tl(t1, t1, t2);
2128        tcg_temp_free(t2);
2129        tcg_gen_or_tl(t0, t0, t1);
2130        tcg_temp_free(t1);
2131        gen_store_gpr(t0, rt);
2132        break;
2133    case OPC_LDR:
2134        t1 = tcg_temp_new();
2135        /*
2136         * Do a byte access to possibly trigger a page
2137         * fault with the unaligned address.
2138         */
2139        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2140        tcg_gen_andi_tl(t1, t0, 7);
2141#ifdef TARGET_WORDS_BIGENDIAN
2142        tcg_gen_xori_tl(t1, t1, 7);
2143#endif
2144        tcg_gen_shli_tl(t1, t1, 3);
2145        tcg_gen_andi_tl(t0, t0, ~7);
2146        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2147        tcg_gen_shr_tl(t0, t0, t1);
2148        tcg_gen_xori_tl(t1, t1, 63);
2149        t2 = tcg_const_tl(0xfffffffffffffffeull);
2150        tcg_gen_shl_tl(t2, t2, t1);
2151        gen_load_gpr(t1, rt);
2152        tcg_gen_and_tl(t1, t1, t2);
2153        tcg_temp_free(t2);
2154        tcg_gen_or_tl(t0, t0, t1);
2155        tcg_temp_free(t1);
2156        gen_store_gpr(t0, rt);
2157        break;
2158    case OPC_LDPC:
2159        t1 = tcg_const_tl(pc_relative_pc(ctx));
2160        gen_op_addr_add(ctx, t0, t0, t1);
2161        tcg_temp_free(t1);
2162        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEQ);
2163        gen_store_gpr(t0, rt);
2164        break;
2165#endif
2166    case OPC_LWPC:
2167        t1 = tcg_const_tl(pc_relative_pc(ctx));
2168        gen_op_addr_add(ctx, t0, t0, t1);
2169        tcg_temp_free(t1);
2170        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL);
2171        gen_store_gpr(t0, rt);
2172        break;
2173    case OPC_LWE:
2174        mem_idx = MIPS_HFLAG_UM;
2175        /* fall through */
2176    case OPC_LW:
2177        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESL |
2178                           ctx->default_tcg_memop_mask);
2179        gen_store_gpr(t0, rt);
2180        break;
2181    case OPC_LHE:
2182        mem_idx = MIPS_HFLAG_UM;
2183        /* fall through */
2184    case OPC_LH:
2185        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TESW |
2186                           ctx->default_tcg_memop_mask);
2187        gen_store_gpr(t0, rt);
2188        break;
2189    case OPC_LHUE:
2190        mem_idx = MIPS_HFLAG_UM;
2191        /* fall through */
2192    case OPC_LHU:
2193        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUW |
2194                           ctx->default_tcg_memop_mask);
2195        gen_store_gpr(t0, rt);
2196        break;
2197    case OPC_LBE:
2198        mem_idx = MIPS_HFLAG_UM;
2199        /* fall through */
2200    case OPC_LB:
2201        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_SB);
2202        gen_store_gpr(t0, rt);
2203        break;
2204    case OPC_LBUE:
2205        mem_idx = MIPS_HFLAG_UM;
2206        /* fall through */
2207    case OPC_LBU:
2208        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_UB);
2209        gen_store_gpr(t0, rt);
2210        break;
2211    case OPC_LWLE:
2212        mem_idx = MIPS_HFLAG_UM;
2213        /* fall through */
2214    case OPC_LWL:
2215        t1 = tcg_temp_new();
2216        /*
2217         * Do a byte access to possibly trigger a page
2218         * fault with the unaligned address.
2219         */
2220        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2221        tcg_gen_andi_tl(t1, t0, 3);
2222#ifndef TARGET_WORDS_BIGENDIAN
2223        tcg_gen_xori_tl(t1, t1, 3);
2224#endif
2225        tcg_gen_shli_tl(t1, t1, 3);
2226        tcg_gen_andi_tl(t0, t0, ~3);
2227        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
2228        tcg_gen_shl_tl(t0, t0, t1);
2229        t2 = tcg_const_tl(-1);
2230        tcg_gen_shl_tl(t2, t2, t1);
2231        gen_load_gpr(t1, rt);
2232        tcg_gen_andc_tl(t1, t1, t2);
2233        tcg_temp_free(t2);
2234        tcg_gen_or_tl(t0, t0, t1);
2235        tcg_temp_free(t1);
2236        tcg_gen_ext32s_tl(t0, t0);
2237        gen_store_gpr(t0, rt);
2238        break;
2239    case OPC_LWRE:
2240        mem_idx = MIPS_HFLAG_UM;
2241        /* fall through */
2242    case OPC_LWR:
2243        t1 = tcg_temp_new();
2244        /*
2245         * Do a byte access to possibly trigger a page
2246         * fault with the unaligned address.
2247         */
2248        tcg_gen_qemu_ld_tl(t1, t0, mem_idx, MO_UB);
2249        tcg_gen_andi_tl(t1, t0, 3);
2250#ifdef TARGET_WORDS_BIGENDIAN
2251        tcg_gen_xori_tl(t1, t1, 3);
2252#endif
2253        tcg_gen_shli_tl(t1, t1, 3);
2254        tcg_gen_andi_tl(t0, t0, ~3);
2255        tcg_gen_qemu_ld_tl(t0, t0, mem_idx, MO_TEUL);
2256        tcg_gen_shr_tl(t0, t0, t1);
2257        tcg_gen_xori_tl(t1, t1, 31);
2258        t2 = tcg_const_tl(0xfffffffeull);
2259        tcg_gen_shl_tl(t2, t2, t1);
2260        gen_load_gpr(t1, rt);
2261        tcg_gen_and_tl(t1, t1, t2);
2262        tcg_temp_free(t2);
2263        tcg_gen_or_tl(t0, t0, t1);
2264        tcg_temp_free(t1);
2265        tcg_gen_ext32s_tl(t0, t0);
2266        gen_store_gpr(t0, rt);
2267        break;
2268    case OPC_LLE:
2269        mem_idx = MIPS_HFLAG_UM;
2270        /* fall through */
2271    case OPC_LL:
2272    case R6_OPC_LL:
2273        op_ld_ll(t0, t0, mem_idx, ctx);
2274        gen_store_gpr(t0, rt);
2275        break;
2276    }
2277    tcg_temp_free(t0);
2278}
2279
2280static void gen_llwp(DisasContext *ctx, uint32_t base, int16_t offset,
2281                    uint32_t reg1, uint32_t reg2)
2282{
2283    TCGv taddr = tcg_temp_new();
2284    TCGv_i64 tval = tcg_temp_new_i64();
2285    TCGv tmp1 = tcg_temp_new();
2286    TCGv tmp2 = tcg_temp_new();
2287
2288    gen_base_offset_addr(ctx, taddr, base, offset);
2289    tcg_gen_qemu_ld64(tval, taddr, ctx->mem_idx);
2290#ifdef TARGET_WORDS_BIGENDIAN
2291    tcg_gen_extr_i64_tl(tmp2, tmp1, tval);
2292#else
2293    tcg_gen_extr_i64_tl(tmp1, tmp2, tval);
2294#endif
2295    gen_store_gpr(tmp1, reg1);
2296    tcg_temp_free(tmp1);
2297    gen_store_gpr(tmp2, reg2);
2298    tcg_temp_free(tmp2);
2299    tcg_gen_st_i64(tval, cpu_env, offsetof(CPUMIPSState, llval_wp));
2300    tcg_temp_free_i64(tval);
2301    tcg_gen_st_tl(taddr, cpu_env, offsetof(CPUMIPSState, lladdr));
2302    tcg_temp_free(taddr);
2303}
2304
2305/* Store */
2306static void gen_st(DisasContext *ctx, uint32_t opc, int rt,
2307                   int base, int offset)
2308{
2309    TCGv t0 = tcg_temp_new();
2310    TCGv t1 = tcg_temp_new();
2311    int mem_idx = ctx->mem_idx;
2312
2313    gen_base_offset_addr(ctx, t0, base, offset);
2314    gen_load_gpr(t1, rt);
2315    switch (opc) {
2316#if defined(TARGET_MIPS64)
2317    case OPC_SD:
2318        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEQ |
2319                           ctx->default_tcg_memop_mask);
2320        break;
2321    case OPC_SDL:
2322        gen_helper_0e2i(sdl, t1, t0, mem_idx);
2323        break;
2324    case OPC_SDR:
2325        gen_helper_0e2i(sdr, t1, t0, mem_idx);
2326        break;
2327#endif
2328    case OPC_SWE:
2329        mem_idx = MIPS_HFLAG_UM;
2330        /* fall through */
2331    case OPC_SW:
2332        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUL |
2333                           ctx->default_tcg_memop_mask);
2334        break;
2335    case OPC_SHE:
2336        mem_idx = MIPS_HFLAG_UM;
2337        /* fall through */
2338    case OPC_SH:
2339        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_TEUW |
2340                           ctx->default_tcg_memop_mask);
2341        break;
2342    case OPC_SBE:
2343        mem_idx = MIPS_HFLAG_UM;
2344        /* fall through */
2345    case OPC_SB:
2346        tcg_gen_qemu_st_tl(t1, t0, mem_idx, MO_8);
2347        break;
2348    case OPC_SWLE:
2349        mem_idx = MIPS_HFLAG_UM;
2350        /* fall through */
2351    case OPC_SWL:
2352        gen_helper_0e2i(swl, t1, t0, mem_idx);
2353        break;
2354    case OPC_SWRE:
2355        mem_idx = MIPS_HFLAG_UM;
2356        /* fall through */
2357    case OPC_SWR:
2358        gen_helper_0e2i(swr, t1, t0, mem_idx);
2359        break;
2360    }
2361    tcg_temp_free(t0);
2362    tcg_temp_free(t1);
2363}
2364
2365
2366/* Store conditional */
2367static void gen_st_cond(DisasContext *ctx, int rt, int base, int offset,
2368                        MemOp tcg_mo, bool eva)
2369{
2370    TCGv addr, t0, val;
2371    TCGLabel *l1 = gen_new_label();
2372    TCGLabel *done = gen_new_label();
2373
2374    t0 = tcg_temp_new();
2375    addr = tcg_temp_new();
2376    /* compare the address against that of the preceding LL */
2377    gen_base_offset_addr(ctx, addr, base, offset);
2378    tcg_gen_brcond_tl(TCG_COND_EQ, addr, cpu_lladdr, l1);
2379    tcg_temp_free(addr);
2380    tcg_gen_movi_tl(t0, 0);
2381    gen_store_gpr(t0, rt);
2382    tcg_gen_br(done);
2383
2384    gen_set_label(l1);
2385    /* generate cmpxchg */
2386    val = tcg_temp_new();
2387    gen_load_gpr(val, rt);
2388    tcg_gen_atomic_cmpxchg_tl(t0, cpu_lladdr, cpu_llval, val,
2389                              eva ? MIPS_HFLAG_UM : ctx->mem_idx, tcg_mo);
2390    tcg_gen_setcond_tl(TCG_COND_EQ, t0, t0, cpu_llval);
2391    gen_store_gpr(t0, rt);
2392    tcg_temp_free(val);
2393
2394    gen_set_label(done);
2395    tcg_temp_free(t0);
2396}
2397
2398
2399static void gen_scwp(DisasContext *ctx, uint32_t base, int16_t offset,
2400                    uint32_t reg1, uint32_t reg2, bool eva)
2401{
2402    TCGv taddr = tcg_temp_local_new();
2403    TCGv lladdr = tcg_temp_local_new();
2404    TCGv_i64 tval = tcg_temp_new_i64();
2405    TCGv_i64 llval = tcg_temp_new_i64();
2406    TCGv_i64 val = tcg_temp_new_i64();
2407    TCGv tmp1 = tcg_temp_new();
2408    TCGv tmp2 = tcg_temp_new();
2409    TCGLabel *lab_fail = gen_new_label();
2410    TCGLabel *lab_done = gen_new_label();
2411
2412    gen_base_offset_addr(ctx, taddr, base, offset);
2413
2414    tcg_gen_ld_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
2415    tcg_gen_brcond_tl(TCG_COND_NE, taddr, lladdr, lab_fail);
2416
2417    gen_load_gpr(tmp1, reg1);
2418    gen_load_gpr(tmp2, reg2);
2419
2420#ifdef TARGET_WORDS_BIGENDIAN
2421    tcg_gen_concat_tl_i64(tval, tmp2, tmp1);
2422#else
2423    tcg_gen_concat_tl_i64(tval, tmp1, tmp2);
2424#endif
2425
2426    tcg_gen_ld_i64(llval, cpu_env, offsetof(CPUMIPSState, llval_wp));
2427    tcg_gen_atomic_cmpxchg_i64(val, taddr, llval, tval,
2428                               eva ? MIPS_HFLAG_UM : ctx->mem_idx, MO_64);
2429    if (reg1 != 0) {
2430        tcg_gen_movi_tl(cpu_gpr[reg1], 1);
2431    }
2432    tcg_gen_brcond_i64(TCG_COND_EQ, val, llval, lab_done);
2433
2434    gen_set_label(lab_fail);
2435
2436    if (reg1 != 0) {
2437        tcg_gen_movi_tl(cpu_gpr[reg1], 0);
2438    }
2439    gen_set_label(lab_done);
2440    tcg_gen_movi_tl(lladdr, -1);
2441    tcg_gen_st_tl(lladdr, cpu_env, offsetof(CPUMIPSState, lladdr));
2442}
2443
2444/* Load and store */
2445static void gen_flt_ldst(DisasContext *ctx, uint32_t opc, int ft,
2446                         TCGv t0)
2447{
2448    /*
2449     * Don't do NOP if destination is zero: we must perform the actual
2450     * memory access.
2451     */
2452    switch (opc) {
2453    case OPC_LWC1:
2454        {
2455            TCGv_i32 fp0 = tcg_temp_new_i32();
2456            tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
2457                                ctx->default_tcg_memop_mask);
2458            gen_store_fpr32(ctx, fp0, ft);
2459            tcg_temp_free_i32(fp0);
2460        }
2461        break;
2462    case OPC_SWC1:
2463        {
2464            TCGv_i32 fp0 = tcg_temp_new_i32();
2465            gen_load_fpr32(ctx, fp0, ft);
2466            tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
2467                                ctx->default_tcg_memop_mask);
2468            tcg_temp_free_i32(fp0);
2469        }
2470        break;
2471    case OPC_LDC1:
2472        {
2473            TCGv_i64 fp0 = tcg_temp_new_i64();
2474            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2475                                ctx->default_tcg_memop_mask);
2476            gen_store_fpr64(ctx, fp0, ft);
2477            tcg_temp_free_i64(fp0);
2478        }
2479        break;
2480    case OPC_SDC1:
2481        {
2482            TCGv_i64 fp0 = tcg_temp_new_i64();
2483            gen_load_fpr64(ctx, fp0, ft);
2484            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ |
2485                                ctx->default_tcg_memop_mask);
2486            tcg_temp_free_i64(fp0);
2487        }
2488        break;
2489    default:
2490        MIPS_INVAL("flt_ldst");
2491        gen_reserved_instruction(ctx);
2492        break;
2493    }
2494}
2495
2496static void gen_cop1_ldst(DisasContext *ctx, uint32_t op, int rt,
2497                          int rs, int16_t imm)
2498{
2499    TCGv t0 = tcg_temp_new();
2500
2501    if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
2502        check_cp1_enabled(ctx);
2503        switch (op) {
2504        case OPC_LDC1:
2505        case OPC_SDC1:
2506            check_insn(ctx, ISA_MIPS2);
2507            /* Fallthrough */
2508        default:
2509            gen_base_offset_addr(ctx, t0, rs, imm);
2510            gen_flt_ldst(ctx, op, rt, t0);
2511        }
2512    } else {
2513        generate_exception_err(ctx, EXCP_CpU, 1);
2514    }
2515    tcg_temp_free(t0);
2516}
2517
2518/* Arithmetic with immediate operand */
2519static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
2520                          int rt, int rs, int imm)
2521{
2522    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2523
2524    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
2525        /*
2526         * If no destination, treat it as a NOP.
2527         * For addi, we must generate the overflow exception when needed.
2528         */
2529        return;
2530    }
2531    switch (opc) {
2532    case OPC_ADDI:
2533        {
2534            TCGv t0 = tcg_temp_local_new();
2535            TCGv t1 = tcg_temp_new();
2536            TCGv t2 = tcg_temp_new();
2537            TCGLabel *l1 = gen_new_label();
2538
2539            gen_load_gpr(t1, rs);
2540            tcg_gen_addi_tl(t0, t1, uimm);
2541            tcg_gen_ext32s_tl(t0, t0);
2542
2543            tcg_gen_xori_tl(t1, t1, ~uimm);
2544            tcg_gen_xori_tl(t2, t0, uimm);
2545            tcg_gen_and_tl(t1, t1, t2);
2546            tcg_temp_free(t2);
2547            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2548            tcg_temp_free(t1);
2549            /* operands of same sign, result different sign */
2550            generate_exception(ctx, EXCP_OVERFLOW);
2551            gen_set_label(l1);
2552            tcg_gen_ext32s_tl(t0, t0);
2553            gen_store_gpr(t0, rt);
2554            tcg_temp_free(t0);
2555        }
2556        break;
2557    case OPC_ADDIU:
2558        if (rs != 0) {
2559            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2560            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2561        } else {
2562            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2563        }
2564        break;
2565#if defined(TARGET_MIPS64)
2566    case OPC_DADDI:
2567        {
2568            TCGv t0 = tcg_temp_local_new();
2569            TCGv t1 = tcg_temp_new();
2570            TCGv t2 = tcg_temp_new();
2571            TCGLabel *l1 = gen_new_label();
2572
2573            gen_load_gpr(t1, rs);
2574            tcg_gen_addi_tl(t0, t1, uimm);
2575
2576            tcg_gen_xori_tl(t1, t1, ~uimm);
2577            tcg_gen_xori_tl(t2, t0, uimm);
2578            tcg_gen_and_tl(t1, t1, t2);
2579            tcg_temp_free(t2);
2580            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2581            tcg_temp_free(t1);
2582            /* operands of same sign, result different sign */
2583            generate_exception(ctx, EXCP_OVERFLOW);
2584            gen_set_label(l1);
2585            gen_store_gpr(t0, rt);
2586            tcg_temp_free(t0);
2587        }
2588        break;
2589    case OPC_DADDIU:
2590        if (rs != 0) {
2591            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2592        } else {
2593            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2594        }
2595        break;
2596#endif
2597    }
2598}
2599
2600/* Logic with immediate operand */
2601static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2602                          int rt, int rs, int16_t imm)
2603{
2604    target_ulong uimm;
2605
2606    if (rt == 0) {
2607        /* If no destination, treat it as a NOP. */
2608        return;
2609    }
2610    uimm = (uint16_t)imm;
2611    switch (opc) {
2612    case OPC_ANDI:
2613        if (likely(rs != 0)) {
2614            tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2615        } else {
2616            tcg_gen_movi_tl(cpu_gpr[rt], 0);
2617        }
2618        break;
2619    case OPC_ORI:
2620        if (rs != 0) {
2621            tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2622        } else {
2623            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2624        }
2625        break;
2626    case OPC_XORI:
2627        if (likely(rs != 0)) {
2628            tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2629        } else {
2630            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2631        }
2632        break;
2633    case OPC_LUI:
2634        if (rs != 0 && (ctx->insn_flags & ISA_MIPS_R6)) {
2635            /* OPC_AUI */
2636            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm << 16);
2637            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
2638        } else {
2639            tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2640        }
2641        break;
2642
2643    default:
2644        break;
2645    }
2646}
2647
2648/* Set on less than with immediate operand */
2649static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2650                        int rt, int rs, int16_t imm)
2651{
2652    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2653    TCGv t0;
2654
2655    if (rt == 0) {
2656        /* If no destination, treat it as a NOP. */
2657        return;
2658    }
2659    t0 = tcg_temp_new();
2660    gen_load_gpr(t0, rs);
2661    switch (opc) {
2662    case OPC_SLTI:
2663        tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2664        break;
2665    case OPC_SLTIU:
2666        tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2667        break;
2668    }
2669    tcg_temp_free(t0);
2670}
2671
2672/* Shifts with immediate operand */
2673static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2674                          int rt, int rs, int16_t imm)
2675{
2676    target_ulong uimm = ((uint16_t)imm) & 0x1f;
2677    TCGv t0;
2678
2679    if (rt == 0) {
2680        /* If no destination, treat it as a NOP. */
2681        return;
2682    }
2683
2684    t0 = tcg_temp_new();
2685    gen_load_gpr(t0, rs);
2686    switch (opc) {
2687    case OPC_SLL:
2688        tcg_gen_shli_tl(t0, t0, uimm);
2689        tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2690        break;
2691    case OPC_SRA:
2692        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2693        break;
2694    case OPC_SRL:
2695        if (uimm != 0) {
2696            tcg_gen_ext32u_tl(t0, t0);
2697            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2698        } else {
2699            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2700        }
2701        break;
2702    case OPC_ROTR:
2703        if (uimm != 0) {
2704            TCGv_i32 t1 = tcg_temp_new_i32();
2705
2706            tcg_gen_trunc_tl_i32(t1, t0);
2707            tcg_gen_rotri_i32(t1, t1, uimm);
2708            tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2709            tcg_temp_free_i32(t1);
2710        } else {
2711            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2712        }
2713        break;
2714#if defined(TARGET_MIPS64)
2715    case OPC_DSLL:
2716        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2717        break;
2718    case OPC_DSRA:
2719        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2720        break;
2721    case OPC_DSRL:
2722        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2723        break;
2724    case OPC_DROTR:
2725        if (uimm != 0) {
2726            tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2727        } else {
2728            tcg_gen_mov_tl(cpu_gpr[rt], t0);
2729        }
2730        break;
2731    case OPC_DSLL32:
2732        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2733        break;
2734    case OPC_DSRA32:
2735        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2736        break;
2737    case OPC_DSRL32:
2738        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2739        break;
2740    case OPC_DROTR32:
2741        tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2742        break;
2743#endif
2744    }
2745    tcg_temp_free(t0);
2746}
2747
2748/* Arithmetic */
2749static void gen_arith(DisasContext *ctx, uint32_t opc,
2750                      int rd, int rs, int rt)
2751{
2752    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2753       && opc != OPC_DADD && opc != OPC_DSUB) {
2754        /*
2755         * If no destination, treat it as a NOP.
2756         * For add & sub, we must generate the overflow exception when needed.
2757         */
2758        return;
2759    }
2760
2761    switch (opc) {
2762    case OPC_ADD:
2763        {
2764            TCGv t0 = tcg_temp_local_new();
2765            TCGv t1 = tcg_temp_new();
2766            TCGv t2 = tcg_temp_new();
2767            TCGLabel *l1 = gen_new_label();
2768
2769            gen_load_gpr(t1, rs);
2770            gen_load_gpr(t2, rt);
2771            tcg_gen_add_tl(t0, t1, t2);
2772            tcg_gen_ext32s_tl(t0, t0);
2773            tcg_gen_xor_tl(t1, t1, t2);
2774            tcg_gen_xor_tl(t2, t0, t2);
2775            tcg_gen_andc_tl(t1, t2, t1);
2776            tcg_temp_free(t2);
2777            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2778            tcg_temp_free(t1);
2779            /* operands of same sign, result different sign */
2780            generate_exception(ctx, EXCP_OVERFLOW);
2781            gen_set_label(l1);
2782            gen_store_gpr(t0, rd);
2783            tcg_temp_free(t0);
2784        }
2785        break;
2786    case OPC_ADDU:
2787        if (rs != 0 && rt != 0) {
2788            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2789            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2790        } else if (rs == 0 && rt != 0) {
2791            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2792        } else if (rs != 0 && rt == 0) {
2793            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2794        } else {
2795            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2796        }
2797        break;
2798    case OPC_SUB:
2799        {
2800            TCGv t0 = tcg_temp_local_new();
2801            TCGv t1 = tcg_temp_new();
2802            TCGv t2 = tcg_temp_new();
2803            TCGLabel *l1 = gen_new_label();
2804
2805            gen_load_gpr(t1, rs);
2806            gen_load_gpr(t2, rt);
2807            tcg_gen_sub_tl(t0, t1, t2);
2808            tcg_gen_ext32s_tl(t0, t0);
2809            tcg_gen_xor_tl(t2, t1, t2);
2810            tcg_gen_xor_tl(t1, t0, t1);
2811            tcg_gen_and_tl(t1, t1, t2);
2812            tcg_temp_free(t2);
2813            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2814            tcg_temp_free(t1);
2815            /*
2816             * operands of different sign, first operand and the result
2817             * of different sign
2818             */
2819            generate_exception(ctx, EXCP_OVERFLOW);
2820            gen_set_label(l1);
2821            gen_store_gpr(t0, rd);
2822            tcg_temp_free(t0);
2823        }
2824        break;
2825    case OPC_SUBU:
2826        if (rs != 0 && rt != 0) {
2827            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2828            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2829        } else if (rs == 0 && rt != 0) {
2830            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2831            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2832        } else if (rs != 0 && rt == 0) {
2833            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2834        } else {
2835            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2836        }
2837        break;
2838#if defined(TARGET_MIPS64)
2839    case OPC_DADD:
2840        {
2841            TCGv t0 = tcg_temp_local_new();
2842            TCGv t1 = tcg_temp_new();
2843            TCGv t2 = tcg_temp_new();
2844            TCGLabel *l1 = gen_new_label();
2845
2846            gen_load_gpr(t1, rs);
2847            gen_load_gpr(t2, rt);
2848            tcg_gen_add_tl(t0, t1, t2);
2849            tcg_gen_xor_tl(t1, t1, t2);
2850            tcg_gen_xor_tl(t2, t0, t2);
2851            tcg_gen_andc_tl(t1, t2, t1);
2852            tcg_temp_free(t2);
2853            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2854            tcg_temp_free(t1);
2855            /* operands of same sign, result different sign */
2856            generate_exception(ctx, EXCP_OVERFLOW);
2857            gen_set_label(l1);
2858            gen_store_gpr(t0, rd);
2859            tcg_temp_free(t0);
2860        }
2861        break;
2862    case OPC_DADDU:
2863        if (rs != 0 && rt != 0) {
2864            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2865        } else if (rs == 0 && rt != 0) {
2866            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2867        } else if (rs != 0 && rt == 0) {
2868            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2869        } else {
2870            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2871        }
2872        break;
2873    case OPC_DSUB:
2874        {
2875            TCGv t0 = tcg_temp_local_new();
2876            TCGv t1 = tcg_temp_new();
2877            TCGv t2 = tcg_temp_new();
2878            TCGLabel *l1 = gen_new_label();
2879
2880            gen_load_gpr(t1, rs);
2881            gen_load_gpr(t2, rt);
2882            tcg_gen_sub_tl(t0, t1, t2);
2883            tcg_gen_xor_tl(t2, t1, t2);
2884            tcg_gen_xor_tl(t1, t0, t1);
2885            tcg_gen_and_tl(t1, t1, t2);
2886            tcg_temp_free(t2);
2887            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2888            tcg_temp_free(t1);
2889            /*
2890             * Operands of different sign, first operand and result different
2891             * sign.
2892             */
2893            generate_exception(ctx, EXCP_OVERFLOW);
2894            gen_set_label(l1);
2895            gen_store_gpr(t0, rd);
2896            tcg_temp_free(t0);
2897        }
2898        break;
2899    case OPC_DSUBU:
2900        if (rs != 0 && rt != 0) {
2901            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2902        } else if (rs == 0 && rt != 0) {
2903            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2904        } else if (rs != 0 && rt == 0) {
2905            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2906        } else {
2907            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2908        }
2909        break;
2910#endif
2911    case OPC_MUL:
2912        if (likely(rs != 0 && rt != 0)) {
2913            tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2914            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2915        } else {
2916            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2917        }
2918        break;
2919    }
2920}
2921
2922/* Conditional move */
2923static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2924                          int rd, int rs, int rt)
2925{
2926    TCGv t0, t1, t2;
2927
2928    if (rd == 0) {
2929        /* If no destination, treat it as a NOP. */
2930        return;
2931    }
2932
2933    t0 = tcg_temp_new();
2934    gen_load_gpr(t0, rt);
2935    t1 = tcg_const_tl(0);
2936    t2 = tcg_temp_new();
2937    gen_load_gpr(t2, rs);
2938    switch (opc) {
2939    case OPC_MOVN:
2940        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2941        break;
2942    case OPC_MOVZ:
2943        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2944        break;
2945    case OPC_SELNEZ:
2946        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, t1);
2947        break;
2948    case OPC_SELEQZ:
2949        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, t1);
2950        break;
2951    }
2952    tcg_temp_free(t2);
2953    tcg_temp_free(t1);
2954    tcg_temp_free(t0);
2955}
2956
2957/* Logic */
2958static void gen_logic(DisasContext *ctx, uint32_t opc,
2959                      int rd, int rs, int rt)
2960{
2961    if (rd == 0) {
2962        /* If no destination, treat it as a NOP. */
2963        return;
2964    }
2965
2966    switch (opc) {
2967    case OPC_AND:
2968        if (likely(rs != 0 && rt != 0)) {
2969            tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2970        } else {
2971            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2972        }
2973        break;
2974    case OPC_NOR:
2975        if (rs != 0 && rt != 0) {
2976            tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2977        } else if (rs == 0 && rt != 0) {
2978            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2979        } else if (rs != 0 && rt == 0) {
2980            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2981        } else {
2982            tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2983        }
2984        break;
2985    case OPC_OR:
2986        if (likely(rs != 0 && rt != 0)) {
2987            tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2988        } else if (rs == 0 && rt != 0) {
2989            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2990        } else if (rs != 0 && rt == 0) {
2991            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2992        } else {
2993            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2994        }
2995        break;
2996    case OPC_XOR:
2997        if (likely(rs != 0 && rt != 0)) {
2998            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2999        } else if (rs == 0 && rt != 0) {
3000            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
3001        } else if (rs != 0 && rt == 0) {
3002            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
3003        } else {
3004            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3005        }
3006        break;
3007    }
3008}
3009
3010/* Set on lower than */
3011static void gen_slt(DisasContext *ctx, uint32_t opc,
3012                    int rd, int rs, int rt)
3013{
3014    TCGv t0, t1;
3015
3016    if (rd == 0) {
3017        /* If no destination, treat it as a NOP. */
3018        return;
3019    }
3020
3021    t0 = tcg_temp_new();
3022    t1 = tcg_temp_new();
3023    gen_load_gpr(t0, rs);
3024    gen_load_gpr(t1, rt);
3025    switch (opc) {
3026    case OPC_SLT:
3027        tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
3028        break;
3029    case OPC_SLTU:
3030        tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
3031        break;
3032    }
3033    tcg_temp_free(t0);
3034    tcg_temp_free(t1);
3035}
3036
3037/* Shifts */
3038static void gen_shift(DisasContext *ctx, uint32_t opc,
3039                      int rd, int rs, int rt)
3040{
3041    TCGv t0, t1;
3042
3043    if (rd == 0) {
3044        /*
3045         * If no destination, treat it as a NOP.
3046         * For add & sub, we must generate the overflow exception when needed.
3047         */
3048        return;
3049    }
3050
3051    t0 = tcg_temp_new();
3052    t1 = tcg_temp_new();
3053    gen_load_gpr(t0, rs);
3054    gen_load_gpr(t1, rt);
3055    switch (opc) {
3056    case OPC_SLLV:
3057        tcg_gen_andi_tl(t0, t0, 0x1f);
3058        tcg_gen_shl_tl(t0, t1, t0);
3059        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3060        break;
3061    case OPC_SRAV:
3062        tcg_gen_andi_tl(t0, t0, 0x1f);
3063        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
3064        break;
3065    case OPC_SRLV:
3066        tcg_gen_ext32u_tl(t1, t1);
3067        tcg_gen_andi_tl(t0, t0, 0x1f);
3068        tcg_gen_shr_tl(t0, t1, t0);
3069        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3070        break;
3071    case OPC_ROTRV:
3072        {
3073            TCGv_i32 t2 = tcg_temp_new_i32();
3074            TCGv_i32 t3 = tcg_temp_new_i32();
3075
3076            tcg_gen_trunc_tl_i32(t2, t0);
3077            tcg_gen_trunc_tl_i32(t3, t1);
3078            tcg_gen_andi_i32(t2, t2, 0x1f);
3079            tcg_gen_rotr_i32(t2, t3, t2);
3080            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3081            tcg_temp_free_i32(t2);
3082            tcg_temp_free_i32(t3);
3083        }
3084        break;
3085#if defined(TARGET_MIPS64)
3086    case OPC_DSLLV:
3087        tcg_gen_andi_tl(t0, t0, 0x3f);
3088        tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
3089        break;
3090    case OPC_DSRAV:
3091        tcg_gen_andi_tl(t0, t0, 0x3f);
3092        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
3093        break;
3094    case OPC_DSRLV:
3095        tcg_gen_andi_tl(t0, t0, 0x3f);
3096        tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
3097        break;
3098    case OPC_DROTRV:
3099        tcg_gen_andi_tl(t0, t0, 0x3f);
3100        tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
3101        break;
3102#endif
3103    }
3104    tcg_temp_free(t0);
3105    tcg_temp_free(t1);
3106}
3107
3108/* Arithmetic on HI/LO registers */
3109static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
3110{
3111    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
3112        /* Treat as NOP. */
3113        return;
3114    }
3115
3116    if (acc != 0) {
3117        check_dsp(ctx);
3118    }
3119
3120    switch (opc) {
3121    case OPC_MFHI:
3122#if defined(TARGET_MIPS64)
3123        if (acc != 0) {
3124            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
3125        } else
3126#endif
3127        {
3128            tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
3129        }
3130        break;
3131    case OPC_MFLO:
3132#if defined(TARGET_MIPS64)
3133        if (acc != 0) {
3134            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
3135        } else
3136#endif
3137        {
3138            tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
3139        }
3140        break;
3141    case OPC_MTHI:
3142        if (reg != 0) {
3143#if defined(TARGET_MIPS64)
3144            if (acc != 0) {
3145                tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
3146            } else
3147#endif
3148            {
3149                tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
3150            }
3151        } else {
3152            tcg_gen_movi_tl(cpu_HI[acc], 0);
3153        }
3154        break;
3155    case OPC_MTLO:
3156        if (reg != 0) {
3157#if defined(TARGET_MIPS64)
3158            if (acc != 0) {
3159                tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
3160            } else
3161#endif
3162            {
3163                tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
3164            }
3165        } else {
3166            tcg_gen_movi_tl(cpu_LO[acc], 0);
3167        }
3168        break;
3169    }
3170}
3171
3172static inline void gen_r6_ld(target_long addr, int reg, int memidx,
3173                             MemOp memop)
3174{
3175    TCGv t0 = tcg_const_tl(addr);
3176    tcg_gen_qemu_ld_tl(t0, t0, memidx, memop);
3177    gen_store_gpr(t0, reg);
3178    tcg_temp_free(t0);
3179}
3180
3181static inline void gen_pcrel(DisasContext *ctx, int opc, target_ulong pc,
3182                             int rs)
3183{
3184    target_long offset;
3185    target_long addr;
3186
3187    switch (MASK_OPC_PCREL_TOP2BITS(opc)) {
3188    case OPC_ADDIUPC:
3189        if (rs != 0) {
3190            offset = sextract32(ctx->opcode << 2, 0, 21);
3191            addr = addr_add(ctx, pc, offset);
3192            tcg_gen_movi_tl(cpu_gpr[rs], addr);
3193        }
3194        break;
3195    case R6_OPC_LWPC:
3196        offset = sextract32(ctx->opcode << 2, 0, 21);
3197        addr = addr_add(ctx, pc, offset);
3198        gen_r6_ld(addr, rs, ctx->mem_idx, MO_TESL);
3199        break;
3200#if defined(TARGET_MIPS64)
3201    case OPC_LWUPC:
3202        check_mips_64(ctx);
3203        offset = sextract32(ctx->opcode << 2, 0, 21);
3204        addr = addr_add(ctx, pc, offset);
3205        gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEUL);
3206        break;
3207#endif
3208    default:
3209        switch (MASK_OPC_PCREL_TOP5BITS(opc)) {
3210        case OPC_AUIPC:
3211            if (rs != 0) {
3212                offset = sextract32(ctx->opcode, 0, 16) << 16;
3213                addr = addr_add(ctx, pc, offset);
3214                tcg_gen_movi_tl(cpu_gpr[rs], addr);
3215            }
3216            break;
3217        case OPC_ALUIPC:
3218            if (rs != 0) {
3219                offset = sextract32(ctx->opcode, 0, 16) << 16;
3220                addr = ~0xFFFF & addr_add(ctx, pc, offset);
3221                tcg_gen_movi_tl(cpu_gpr[rs], addr);
3222            }
3223            break;
3224#if defined(TARGET_MIPS64)
3225        case R6_OPC_LDPC: /* bits 16 and 17 are part of immediate */
3226        case R6_OPC_LDPC + (1 << 16):
3227        case R6_OPC_LDPC + (2 << 16):
3228        case R6_OPC_LDPC + (3 << 16):
3229            check_mips_64(ctx);
3230            offset = sextract32(ctx->opcode << 3, 0, 21);
3231            addr = addr_add(ctx, (pc & ~0x7), offset);
3232            gen_r6_ld(addr, rs, ctx->mem_idx, MO_TEQ);
3233            break;
3234#endif
3235        default:
3236            MIPS_INVAL("OPC_PCREL");
3237            gen_reserved_instruction(ctx);
3238            break;
3239        }
3240        break;
3241    }
3242}
3243
3244static void gen_r6_muldiv(DisasContext *ctx, int opc, int rd, int rs, int rt)
3245{
3246    TCGv t0, t1;
3247
3248    if (rd == 0) {
3249        /* Treat as NOP. */
3250        return;
3251    }
3252
3253    t0 = tcg_temp_new();
3254    t1 = tcg_temp_new();
3255
3256    gen_load_gpr(t0, rs);
3257    gen_load_gpr(t1, rt);
3258
3259    switch (opc) {
3260    case R6_OPC_DIV:
3261        {
3262            TCGv t2 = tcg_temp_new();
3263            TCGv t3 = tcg_temp_new();
3264            tcg_gen_ext32s_tl(t0, t0);
3265            tcg_gen_ext32s_tl(t1, t1);
3266            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3267            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3268            tcg_gen_and_tl(t2, t2, t3);
3269            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3270            tcg_gen_or_tl(t2, t2, t3);
3271            tcg_gen_movi_tl(t3, 0);
3272            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3273            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3274            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3275            tcg_temp_free(t3);
3276            tcg_temp_free(t2);
3277        }
3278        break;
3279    case R6_OPC_MOD:
3280        {
3281            TCGv t2 = tcg_temp_new();
3282            TCGv t3 = tcg_temp_new();
3283            tcg_gen_ext32s_tl(t0, t0);
3284            tcg_gen_ext32s_tl(t1, t1);
3285            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3286            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3287            tcg_gen_and_tl(t2, t2, t3);
3288            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3289            tcg_gen_or_tl(t2, t2, t3);
3290            tcg_gen_movi_tl(t3, 0);
3291            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3292            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3293            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3294            tcg_temp_free(t3);
3295            tcg_temp_free(t2);
3296        }
3297        break;
3298    case R6_OPC_DIVU:
3299        {
3300            TCGv t2 = tcg_const_tl(0);
3301            TCGv t3 = tcg_const_tl(1);
3302            tcg_gen_ext32u_tl(t0, t0);
3303            tcg_gen_ext32u_tl(t1, t1);
3304            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3305            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3306            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3307            tcg_temp_free(t3);
3308            tcg_temp_free(t2);
3309        }
3310        break;
3311    case R6_OPC_MODU:
3312        {
3313            TCGv t2 = tcg_const_tl(0);
3314            TCGv t3 = tcg_const_tl(1);
3315            tcg_gen_ext32u_tl(t0, t0);
3316            tcg_gen_ext32u_tl(t1, t1);
3317            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3318            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3319            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3320            tcg_temp_free(t3);
3321            tcg_temp_free(t2);
3322        }
3323        break;
3324    case R6_OPC_MUL:
3325        {
3326            TCGv_i32 t2 = tcg_temp_new_i32();
3327            TCGv_i32 t3 = tcg_temp_new_i32();
3328            tcg_gen_trunc_tl_i32(t2, t0);
3329            tcg_gen_trunc_tl_i32(t3, t1);
3330            tcg_gen_mul_i32(t2, t2, t3);
3331            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3332            tcg_temp_free_i32(t2);
3333            tcg_temp_free_i32(t3);
3334        }
3335        break;
3336    case R6_OPC_MUH:
3337        {
3338            TCGv_i32 t2 = tcg_temp_new_i32();
3339            TCGv_i32 t3 = tcg_temp_new_i32();
3340            tcg_gen_trunc_tl_i32(t2, t0);
3341            tcg_gen_trunc_tl_i32(t3, t1);
3342            tcg_gen_muls2_i32(t2, t3, t2, t3);
3343            tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3344            tcg_temp_free_i32(t2);
3345            tcg_temp_free_i32(t3);
3346        }
3347        break;
3348    case R6_OPC_MULU:
3349        {
3350            TCGv_i32 t2 = tcg_temp_new_i32();
3351            TCGv_i32 t3 = tcg_temp_new_i32();
3352            tcg_gen_trunc_tl_i32(t2, t0);
3353            tcg_gen_trunc_tl_i32(t3, t1);
3354            tcg_gen_mul_i32(t2, t2, t3);
3355            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3356            tcg_temp_free_i32(t2);
3357            tcg_temp_free_i32(t3);
3358        }
3359        break;
3360    case R6_OPC_MUHU:
3361        {
3362            TCGv_i32 t2 = tcg_temp_new_i32();
3363            TCGv_i32 t3 = tcg_temp_new_i32();
3364            tcg_gen_trunc_tl_i32(t2, t0);
3365            tcg_gen_trunc_tl_i32(t3, t1);
3366            tcg_gen_mulu2_i32(t2, t3, t2, t3);
3367            tcg_gen_ext_i32_tl(cpu_gpr[rd], t3);
3368            tcg_temp_free_i32(t2);
3369            tcg_temp_free_i32(t3);
3370        }
3371        break;
3372#if defined(TARGET_MIPS64)
3373    case R6_OPC_DDIV:
3374        {
3375            TCGv t2 = tcg_temp_new();
3376            TCGv t3 = tcg_temp_new();
3377            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3378            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3379            tcg_gen_and_tl(t2, t2, t3);
3380            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3381            tcg_gen_or_tl(t2, t2, t3);
3382            tcg_gen_movi_tl(t3, 0);
3383            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3384            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3385            tcg_temp_free(t3);
3386            tcg_temp_free(t2);
3387        }
3388        break;
3389    case R6_OPC_DMOD:
3390        {
3391            TCGv t2 = tcg_temp_new();
3392            TCGv t3 = tcg_temp_new();
3393            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3394            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3395            tcg_gen_and_tl(t2, t2, t3);
3396            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3397            tcg_gen_or_tl(t2, t2, t3);
3398            tcg_gen_movi_tl(t3, 0);
3399            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3400            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3401            tcg_temp_free(t3);
3402            tcg_temp_free(t2);
3403        }
3404        break;
3405    case R6_OPC_DDIVU:
3406        {
3407            TCGv t2 = tcg_const_tl(0);
3408            TCGv t3 = tcg_const_tl(1);
3409            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3410            tcg_gen_divu_i64(cpu_gpr[rd], t0, t1);
3411            tcg_temp_free(t3);
3412            tcg_temp_free(t2);
3413        }
3414        break;
3415    case R6_OPC_DMODU:
3416        {
3417            TCGv t2 = tcg_const_tl(0);
3418            TCGv t3 = tcg_const_tl(1);
3419            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3420            tcg_gen_remu_i64(cpu_gpr[rd], t0, t1);
3421            tcg_temp_free(t3);
3422            tcg_temp_free(t2);
3423        }
3424        break;
3425    case R6_OPC_DMUL:
3426        tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3427        break;
3428    case R6_OPC_DMUH:
3429        {
3430            TCGv t2 = tcg_temp_new();
3431            tcg_gen_muls2_i64(t2, cpu_gpr[rd], t0, t1);
3432            tcg_temp_free(t2);
3433        }
3434        break;
3435    case R6_OPC_DMULU:
3436        tcg_gen_mul_i64(cpu_gpr[rd], t0, t1);
3437        break;
3438    case R6_OPC_DMUHU:
3439        {
3440            TCGv t2 = tcg_temp_new();
3441            tcg_gen_mulu2_i64(t2, cpu_gpr[rd], t0, t1);
3442            tcg_temp_free(t2);
3443        }
3444        break;
3445#endif
3446    default:
3447        MIPS_INVAL("r6 mul/div");
3448        gen_reserved_instruction(ctx);
3449        goto out;
3450    }
3451 out:
3452    tcg_temp_free(t0);
3453    tcg_temp_free(t1);
3454}
3455
3456#if defined(TARGET_MIPS64)
3457static void gen_div1_tx79(DisasContext *ctx, uint32_t opc, int rs, int rt)
3458{
3459    TCGv t0, t1;
3460
3461    t0 = tcg_temp_new();
3462    t1 = tcg_temp_new();
3463
3464    gen_load_gpr(t0, rs);
3465    gen_load_gpr(t1, rt);
3466
3467    switch (opc) {
3468    case MMI_OPC_DIV1:
3469        {
3470            TCGv t2 = tcg_temp_new();
3471            TCGv t3 = tcg_temp_new();
3472            tcg_gen_ext32s_tl(t0, t0);
3473            tcg_gen_ext32s_tl(t1, t1);
3474            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3475            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3476            tcg_gen_and_tl(t2, t2, t3);
3477            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3478            tcg_gen_or_tl(t2, t2, t3);
3479            tcg_gen_movi_tl(t3, 0);
3480            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3481            tcg_gen_div_tl(cpu_LO[1], t0, t1);
3482            tcg_gen_rem_tl(cpu_HI[1], t0, t1);
3483            tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3484            tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3485            tcg_temp_free(t3);
3486            tcg_temp_free(t2);
3487        }
3488        break;
3489    case MMI_OPC_DIVU1:
3490        {
3491            TCGv t2 = tcg_const_tl(0);
3492            TCGv t3 = tcg_const_tl(1);
3493            tcg_gen_ext32u_tl(t0, t0);
3494            tcg_gen_ext32u_tl(t1, t1);
3495            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3496            tcg_gen_divu_tl(cpu_LO[1], t0, t1);
3497            tcg_gen_remu_tl(cpu_HI[1], t0, t1);
3498            tcg_gen_ext32s_tl(cpu_LO[1], cpu_LO[1]);
3499            tcg_gen_ext32s_tl(cpu_HI[1], cpu_HI[1]);
3500            tcg_temp_free(t3);
3501            tcg_temp_free(t2);
3502        }
3503        break;
3504    default:
3505        MIPS_INVAL("div1 TX79");
3506        gen_reserved_instruction(ctx);
3507        goto out;
3508    }
3509 out:
3510    tcg_temp_free(t0);
3511    tcg_temp_free(t1);
3512}
3513#endif
3514
3515static void gen_muldiv(DisasContext *ctx, uint32_t opc,
3516                       int acc, int rs, int rt)
3517{
3518    TCGv t0, t1;
3519
3520    t0 = tcg_temp_new();
3521    t1 = tcg_temp_new();
3522
3523    gen_load_gpr(t0, rs);
3524    gen_load_gpr(t1, rt);
3525
3526    if (acc != 0) {
3527        check_dsp(ctx);
3528    }
3529
3530    switch (opc) {
3531    case OPC_DIV:
3532        {
3533            TCGv t2 = tcg_temp_new();
3534            TCGv t3 = tcg_temp_new();
3535            tcg_gen_ext32s_tl(t0, t0);
3536            tcg_gen_ext32s_tl(t1, t1);
3537            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
3538            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
3539            tcg_gen_and_tl(t2, t2, t3);
3540            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3541            tcg_gen_or_tl(t2, t2, t3);
3542            tcg_gen_movi_tl(t3, 0);
3543            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3544            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3545            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3546            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3547            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3548            tcg_temp_free(t3);
3549            tcg_temp_free(t2);
3550        }
3551        break;
3552    case OPC_DIVU:
3553        {
3554            TCGv t2 = tcg_const_tl(0);
3555            TCGv t3 = tcg_const_tl(1);
3556            tcg_gen_ext32u_tl(t0, t0);
3557            tcg_gen_ext32u_tl(t1, t1);
3558            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3559            tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
3560            tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
3561            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
3562            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
3563            tcg_temp_free(t3);
3564            tcg_temp_free(t2);
3565        }
3566        break;
3567    case OPC_MULT:
3568        {
3569            TCGv_i32 t2 = tcg_temp_new_i32();
3570            TCGv_i32 t3 = tcg_temp_new_i32();
3571            tcg_gen_trunc_tl_i32(t2, t0);
3572            tcg_gen_trunc_tl_i32(t3, t1);
3573            tcg_gen_muls2_i32(t2, t3, t2, t3);
3574            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3575            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3576            tcg_temp_free_i32(t2);
3577            tcg_temp_free_i32(t3);
3578        }
3579        break;
3580    case OPC_MULTU:
3581        {
3582            TCGv_i32 t2 = tcg_temp_new_i32();
3583            TCGv_i32 t3 = tcg_temp_new_i32();
3584            tcg_gen_trunc_tl_i32(t2, t0);
3585            tcg_gen_trunc_tl_i32(t3, t1);
3586            tcg_gen_mulu2_i32(t2, t3, t2, t3);
3587            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3588            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3589            tcg_temp_free_i32(t2);
3590            tcg_temp_free_i32(t3);
3591        }
3592        break;
3593#if defined(TARGET_MIPS64)
3594    case OPC_DDIV:
3595        {
3596            TCGv t2 = tcg_temp_new();
3597            TCGv t3 = tcg_temp_new();
3598            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
3599            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
3600            tcg_gen_and_tl(t2, t2, t3);
3601            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
3602            tcg_gen_or_tl(t2, t2, t3);
3603            tcg_gen_movi_tl(t3, 0);
3604            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
3605            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
3606            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
3607            tcg_temp_free(t3);
3608            tcg_temp_free(t2);
3609        }
3610        break;
3611    case OPC_DDIVU:
3612        {
3613            TCGv t2 = tcg_const_tl(0);
3614            TCGv t3 = tcg_const_tl(1);
3615            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
3616            tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
3617            tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
3618            tcg_temp_free(t3);
3619            tcg_temp_free(t2);
3620        }
3621        break;
3622    case OPC_DMULT:
3623        tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3624        break;
3625    case OPC_DMULTU:
3626        tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
3627        break;
3628#endif
3629    case OPC_MADD:
3630        {
3631            TCGv_i64 t2 = tcg_temp_new_i64();
3632            TCGv_i64 t3 = tcg_temp_new_i64();
3633
3634            tcg_gen_ext_tl_i64(t2, t0);
3635            tcg_gen_ext_tl_i64(t3, t1);
3636            tcg_gen_mul_i64(t2, t2, t3);
3637            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3638            tcg_gen_add_i64(t2, t2, t3);
3639            tcg_temp_free_i64(t3);
3640            gen_move_low32(cpu_LO[acc], t2);
3641            gen_move_high32(cpu_HI[acc], t2);
3642            tcg_temp_free_i64(t2);
3643        }
3644        break;
3645    case OPC_MADDU:
3646        {
3647            TCGv_i64 t2 = tcg_temp_new_i64();
3648            TCGv_i64 t3 = tcg_temp_new_i64();
3649
3650            tcg_gen_ext32u_tl(t0, t0);
3651            tcg_gen_ext32u_tl(t1, t1);
3652            tcg_gen_extu_tl_i64(t2, t0);
3653            tcg_gen_extu_tl_i64(t3, t1);
3654            tcg_gen_mul_i64(t2, t2, t3);
3655            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3656            tcg_gen_add_i64(t2, t2, t3);
3657            tcg_temp_free_i64(t3);
3658            gen_move_low32(cpu_LO[acc], t2);
3659            gen_move_high32(cpu_HI[acc], t2);
3660            tcg_temp_free_i64(t2);
3661        }
3662        break;
3663    case OPC_MSUB:
3664        {
3665            TCGv_i64 t2 = tcg_temp_new_i64();
3666            TCGv_i64 t3 = tcg_temp_new_i64();
3667
3668            tcg_gen_ext_tl_i64(t2, t0);
3669            tcg_gen_ext_tl_i64(t3, t1);
3670            tcg_gen_mul_i64(t2, t2, t3);
3671            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3672            tcg_gen_sub_i64(t2, t3, t2);
3673            tcg_temp_free_i64(t3);
3674            gen_move_low32(cpu_LO[acc], t2);
3675            gen_move_high32(cpu_HI[acc], t2);
3676            tcg_temp_free_i64(t2);
3677        }
3678        break;
3679    case OPC_MSUBU:
3680        {
3681            TCGv_i64 t2 = tcg_temp_new_i64();
3682            TCGv_i64 t3 = tcg_temp_new_i64();
3683
3684            tcg_gen_ext32u_tl(t0, t0);
3685            tcg_gen_ext32u_tl(t1, t1);
3686            tcg_gen_extu_tl_i64(t2, t0);
3687            tcg_gen_extu_tl_i64(t3, t1);
3688            tcg_gen_mul_i64(t2, t2, t3);
3689            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3690            tcg_gen_sub_i64(t2, t3, t2);
3691            tcg_temp_free_i64(t3);
3692            gen_move_low32(cpu_LO[acc], t2);
3693            gen_move_high32(cpu_HI[acc], t2);
3694            tcg_temp_free_i64(t2);
3695        }
3696        break;
3697    default:
3698        MIPS_INVAL("mul/div");
3699        gen_reserved_instruction(ctx);
3700        goto out;
3701    }
3702 out:
3703    tcg_temp_free(t0);
3704    tcg_temp_free(t1);
3705}
3706
3707/*
3708 * These MULT[U] and MADD[U] instructions implemented in for example
3709 * the Toshiba/Sony R5900 and the Toshiba TX19, TX39 and TX79 core
3710 * architectures are special three-operand variants with the syntax
3711 *
3712 *     MULT[U][1] rd, rs, rt
3713 *
3714 * such that
3715 *
3716 *     (rd, LO, HI) <- rs * rt
3717 *
3718 * and
3719 *
3720 *     MADD[U][1] rd, rs, rt
3721 *
3722 * such that
3723 *
3724 *     (rd, LO, HI) <- (LO, HI) + rs * rt
3725 *
3726 * where the low-order 32-bits of the result is placed into both the
3727 * GPR rd and the special register LO. The high-order 32-bits of the
3728 * result is placed into the special register HI.
3729 *
3730 * If the GPR rd is omitted in assembly language, it is taken to be 0,
3731 * which is the zero register that always reads as 0.
3732 */
3733static void gen_mul_txx9(DisasContext *ctx, uint32_t opc,
3734                         int rd, int rs, int rt)
3735{
3736    TCGv t0 = tcg_temp_new();
3737    TCGv t1 = tcg_temp_new();
3738    int acc = 0;
3739
3740    gen_load_gpr(t0, rs);
3741    gen_load_gpr(t1, rt);
3742
3743    switch (opc) {
3744    case MMI_OPC_MULT1:
3745        acc = 1;
3746        /* Fall through */
3747    case OPC_MULT:
3748        {
3749            TCGv_i32 t2 = tcg_temp_new_i32();
3750            TCGv_i32 t3 = tcg_temp_new_i32();
3751            tcg_gen_trunc_tl_i32(t2, t0);
3752            tcg_gen_trunc_tl_i32(t3, t1);
3753            tcg_gen_muls2_i32(t2, t3, t2, t3);
3754            if (rd) {
3755                tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3756            }
3757            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3758            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3759            tcg_temp_free_i32(t2);
3760            tcg_temp_free_i32(t3);
3761        }
3762        break;
3763    case MMI_OPC_MULTU1:
3764        acc = 1;
3765        /* Fall through */
3766    case OPC_MULTU:
3767        {
3768            TCGv_i32 t2 = tcg_temp_new_i32();
3769            TCGv_i32 t3 = tcg_temp_new_i32();
3770            tcg_gen_trunc_tl_i32(t2, t0);
3771            tcg_gen_trunc_tl_i32(t3, t1);
3772            tcg_gen_mulu2_i32(t2, t3, t2, t3);
3773            if (rd) {
3774                tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
3775            }
3776            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
3777            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
3778            tcg_temp_free_i32(t2);
3779            tcg_temp_free_i32(t3);
3780        }
3781        break;
3782    case MMI_OPC_MADD1:
3783        acc = 1;
3784        /* Fall through */
3785    case MMI_OPC_MADD:
3786        {
3787            TCGv_i64 t2 = tcg_temp_new_i64();
3788            TCGv_i64 t3 = tcg_temp_new_i64();
3789
3790            tcg_gen_ext_tl_i64(t2, t0);
3791            tcg_gen_ext_tl_i64(t3, t1);
3792            tcg_gen_mul_i64(t2, t2, t3);
3793            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3794            tcg_gen_add_i64(t2, t2, t3);
3795            tcg_temp_free_i64(t3);
3796            gen_move_low32(cpu_LO[acc], t2);
3797            gen_move_high32(cpu_HI[acc], t2);
3798            if (rd) {
3799                gen_move_low32(cpu_gpr[rd], t2);
3800            }
3801            tcg_temp_free_i64(t2);
3802        }
3803        break;
3804    case MMI_OPC_MADDU1:
3805        acc = 1;
3806        /* Fall through */
3807    case MMI_OPC_MADDU:
3808        {
3809            TCGv_i64 t2 = tcg_temp_new_i64();
3810            TCGv_i64 t3 = tcg_temp_new_i64();
3811
3812            tcg_gen_ext32u_tl(t0, t0);
3813            tcg_gen_ext32u_tl(t1, t1);
3814            tcg_gen_extu_tl_i64(t2, t0);
3815            tcg_gen_extu_tl_i64(t3, t1);
3816            tcg_gen_mul_i64(t2, t2, t3);
3817            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
3818            tcg_gen_add_i64(t2, t2, t3);
3819            tcg_temp_free_i64(t3);
3820            gen_move_low32(cpu_LO[acc], t2);
3821            gen_move_high32(cpu_HI[acc], t2);
3822            if (rd) {
3823                gen_move_low32(cpu_gpr[rd], t2);
3824            }
3825            tcg_temp_free_i64(t2);
3826        }
3827        break;
3828    default:
3829        MIPS_INVAL("mul/madd TXx9");
3830        gen_reserved_instruction(ctx);
3831        goto out;
3832    }
3833
3834 out:
3835    tcg_temp_free(t0);
3836    tcg_temp_free(t1);
3837}
3838
3839static void gen_mul_vr54xx(DisasContext *ctx, uint32_t opc,
3840                           int rd, int rs, int rt)
3841{
3842    TCGv t0 = tcg_temp_new();
3843    TCGv t1 = tcg_temp_new();
3844
3845    gen_load_gpr(t0, rs);
3846    gen_load_gpr(t1, rt);
3847
3848    switch (opc) {
3849    case OPC_VR54XX_MULS:
3850        gen_helper_muls(t0, cpu_env, t0, t1);
3851        break;
3852    case OPC_VR54XX_MULSU:
3853        gen_helper_mulsu(t0, cpu_env, t0, t1);
3854        break;
3855    case OPC_VR54XX_MACC:
3856        gen_helper_macc(t0, cpu_env, t0, t1);
3857        break;
3858    case OPC_VR54XX_MACCU:
3859        gen_helper_maccu(t0, cpu_env, t0, t1);
3860        break;
3861    case OPC_VR54XX_MSAC:
3862        gen_helper_msac(t0, cpu_env, t0, t1);
3863        break;
3864    case OPC_VR54XX_MSACU:
3865        gen_helper_msacu(t0, cpu_env, t0, t1);
3866        break;
3867    case OPC_VR54XX_MULHI:
3868        gen_helper_mulhi(t0, cpu_env, t0, t1);
3869        break;
3870    case OPC_VR54XX_MULHIU:
3871        gen_helper_mulhiu(t0, cpu_env, t0, t1);
3872        break;
3873    case OPC_VR54XX_MULSHI:
3874        gen_helper_mulshi(t0, cpu_env, t0, t1);
3875        break;
3876    case OPC_VR54XX_MULSHIU:
3877        gen_helper_mulshiu(t0, cpu_env, t0, t1);
3878        break;
3879    case OPC_VR54XX_MACCHI:
3880        gen_helper_macchi(t0, cpu_env, t0, t1);
3881        break;
3882    case OPC_VR54XX_MACCHIU:
3883        gen_helper_macchiu(t0, cpu_env, t0, t1);
3884        break;
3885    case OPC_VR54XX_MSACHI:
3886        gen_helper_msachi(t0, cpu_env, t0, t1);
3887        break;
3888    case OPC_VR54XX_MSACHIU:
3889        gen_helper_msachiu(t0, cpu_env, t0, t1);
3890        break;
3891    default:
3892        MIPS_INVAL("mul vr54xx");
3893        gen_reserved_instruction(ctx);
3894        goto out;
3895    }
3896    gen_store_gpr(t0, rd);
3897
3898 out:
3899    tcg_temp_free(t0);
3900    tcg_temp_free(t1);
3901}
3902
3903static void gen_cl(DisasContext *ctx, uint32_t opc,
3904                   int rd, int rs)
3905{
3906    TCGv t0;
3907
3908    if (rd == 0) {
3909        /* Treat as NOP. */
3910        return;
3911    }
3912    t0 = cpu_gpr[rd];
3913    gen_load_gpr(t0, rs);
3914
3915    switch (opc) {
3916    case OPC_CLO:
3917    case R6_OPC_CLO:
3918#if defined(TARGET_MIPS64)
3919    case OPC_DCLO:
3920    case R6_OPC_DCLO:
3921#endif
3922        tcg_gen_not_tl(t0, t0);
3923        break;
3924    }
3925
3926    switch (opc) {
3927    case OPC_CLO:
3928    case R6_OPC_CLO:
3929    case OPC_CLZ:
3930    case R6_OPC_CLZ:
3931        tcg_gen_ext32u_tl(t0, t0);
3932        tcg_gen_clzi_tl(t0, t0, TARGET_LONG_BITS);
3933        tcg_gen_subi_tl(t0, t0, TARGET_LONG_BITS - 32);
3934        break;
3935#if defined(TARGET_MIPS64)
3936    case OPC_DCLO:
3937    case R6_OPC_DCLO:
3938    case OPC_DCLZ:
3939    case R6_OPC_DCLZ:
3940        tcg_gen_clzi_i64(t0, t0, 64);
3941        break;
3942#endif
3943    }
3944}
3945
3946/* Godson integer instructions */
3947static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
3948                                 int rd, int rs, int rt)
3949{
3950    TCGv t0, t1;
3951
3952    if (rd == 0) {
3953        /* Treat as NOP. */
3954        return;
3955    }
3956
3957    switch (opc) {
3958    case OPC_MULT_G_2E:
3959    case OPC_MULT_G_2F:
3960    case OPC_MULTU_G_2E:
3961    case OPC_MULTU_G_2F:
3962#if defined(TARGET_MIPS64)
3963    case OPC_DMULT_G_2E:
3964    case OPC_DMULT_G_2F:
3965    case OPC_DMULTU_G_2E:
3966    case OPC_DMULTU_G_2F:
3967#endif
3968        t0 = tcg_temp_new();
3969        t1 = tcg_temp_new();
3970        break;
3971    default:
3972        t0 = tcg_temp_local_new();
3973        t1 = tcg_temp_local_new();
3974        break;
3975    }
3976
3977    gen_load_gpr(t0, rs);
3978    gen_load_gpr(t1, rt);
3979
3980    switch (opc) {
3981    case OPC_MULT_G_2E:
3982    case OPC_MULT_G_2F:
3983        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3984        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3985        break;
3986    case OPC_MULTU_G_2E:
3987    case OPC_MULTU_G_2F:
3988        tcg_gen_ext32u_tl(t0, t0);
3989        tcg_gen_ext32u_tl(t1, t1);
3990        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3991        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3992        break;
3993    case OPC_DIV_G_2E:
3994    case OPC_DIV_G_2F:
3995        {
3996            TCGLabel *l1 = gen_new_label();
3997            TCGLabel *l2 = gen_new_label();
3998            TCGLabel *l3 = gen_new_label();
3999            tcg_gen_ext32s_tl(t0, t0);
4000            tcg_gen_ext32s_tl(t1, t1);
4001            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4002            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4003            tcg_gen_br(l3);
4004            gen_set_label(l1);
4005            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
4006            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
4007            tcg_gen_mov_tl(cpu_gpr[rd], t0);
4008            tcg_gen_br(l3);
4009            gen_set_label(l2);
4010            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4011            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4012            gen_set_label(l3);
4013        }
4014        break;
4015    case OPC_DIVU_G_2E:
4016    case OPC_DIVU_G_2F:
4017        {
4018            TCGLabel *l1 = gen_new_label();
4019            TCGLabel *l2 = gen_new_label();
4020            tcg_gen_ext32u_tl(t0, t0);
4021            tcg_gen_ext32u_tl(t1, t1);
4022            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4023            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4024            tcg_gen_br(l2);
4025            gen_set_label(l1);
4026            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4027            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4028            gen_set_label(l2);
4029        }
4030        break;
4031    case OPC_MOD_G_2E:
4032    case OPC_MOD_G_2F:
4033        {
4034            TCGLabel *l1 = gen_new_label();
4035            TCGLabel *l2 = gen_new_label();
4036            TCGLabel *l3 = gen_new_label();
4037            tcg_gen_ext32u_tl(t0, t0);
4038            tcg_gen_ext32u_tl(t1, t1);
4039            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
4040            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
4041            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
4042            gen_set_label(l1);
4043            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4044            tcg_gen_br(l3);
4045            gen_set_label(l2);
4046            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4047            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4048            gen_set_label(l3);
4049        }
4050        break;
4051    case OPC_MODU_G_2E:
4052    case OPC_MODU_G_2F:
4053        {
4054            TCGLabel *l1 = gen_new_label();
4055            TCGLabel *l2 = gen_new_label();
4056            tcg_gen_ext32u_tl(t0, t0);
4057            tcg_gen_ext32u_tl(t1, t1);
4058            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4059            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4060            tcg_gen_br(l2);
4061            gen_set_label(l1);
4062            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4063            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
4064            gen_set_label(l2);
4065        }
4066        break;
4067#if defined(TARGET_MIPS64)
4068    case OPC_DMULT_G_2E:
4069    case OPC_DMULT_G_2F:
4070        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
4071        break;
4072    case OPC_DMULTU_G_2E:
4073    case OPC_DMULTU_G_2F:
4074        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
4075        break;
4076    case OPC_DDIV_G_2E:
4077    case OPC_DDIV_G_2F:
4078        {
4079            TCGLabel *l1 = gen_new_label();
4080            TCGLabel *l2 = gen_new_label();
4081            TCGLabel *l3 = gen_new_label();
4082            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4083            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4084            tcg_gen_br(l3);
4085            gen_set_label(l1);
4086            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
4087            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
4088            tcg_gen_mov_tl(cpu_gpr[rd], t0);
4089            tcg_gen_br(l3);
4090            gen_set_label(l2);
4091            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
4092            gen_set_label(l3);
4093        }
4094        break;
4095    case OPC_DDIVU_G_2E:
4096    case OPC_DDIVU_G_2F:
4097        {
4098            TCGLabel *l1 = gen_new_label();
4099            TCGLabel *l2 = gen_new_label();
4100            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4101            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4102            tcg_gen_br(l2);
4103            gen_set_label(l1);
4104            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
4105            gen_set_label(l2);
4106        }
4107        break;
4108    case OPC_DMOD_G_2E:
4109    case OPC_DMOD_G_2F:
4110        {
4111            TCGLabel *l1 = gen_new_label();
4112            TCGLabel *l2 = gen_new_label();
4113            TCGLabel *l3 = gen_new_label();
4114            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
4115            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
4116            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
4117            gen_set_label(l1);
4118            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4119            tcg_gen_br(l3);
4120            gen_set_label(l2);
4121            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
4122            gen_set_label(l3);
4123        }
4124        break;
4125    case OPC_DMODU_G_2E:
4126    case OPC_DMODU_G_2F:
4127        {
4128            TCGLabel *l1 = gen_new_label();
4129            TCGLabel *l2 = gen_new_label();
4130            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
4131            tcg_gen_movi_tl(cpu_gpr[rd], 0);
4132            tcg_gen_br(l2);
4133            gen_set_label(l1);
4134            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
4135            gen_set_label(l2);
4136        }
4137        break;
4138#endif
4139    }
4140
4141    tcg_temp_free(t0);
4142    tcg_temp_free(t1);
4143}
4144
4145/* Loongson multimedia instructions */
4146static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
4147{
4148    uint32_t opc, shift_max;
4149    TCGv_i64 t0, t1;
4150    TCGCond cond;
4151
4152    opc = MASK_LMMI(ctx->opcode);
4153    switch (opc) {
4154    case OPC_ADD_CP2:
4155    case OPC_SUB_CP2:
4156    case OPC_DADD_CP2:
4157    case OPC_DSUB_CP2:
4158        t0 = tcg_temp_local_new_i64();
4159        t1 = tcg_temp_local_new_i64();
4160        break;
4161    default:
4162        t0 = tcg_temp_new_i64();
4163        t1 = tcg_temp_new_i64();
4164        break;
4165    }
4166
4167    check_cp1_enabled(ctx);
4168    gen_load_fpr64(ctx, t0, rs);
4169    gen_load_fpr64(ctx, t1, rt);
4170
4171    switch (opc) {
4172    case OPC_PADDSH:
4173        gen_helper_paddsh(t0, t0, t1);
4174        break;
4175    case OPC_PADDUSH:
4176        gen_helper_paddush(t0, t0, t1);
4177        break;
4178    case OPC_PADDH:
4179        gen_helper_paddh(t0, t0, t1);
4180        break;
4181    case OPC_PADDW:
4182        gen_helper_paddw(t0, t0, t1);
4183        break;
4184    case OPC_PADDSB:
4185        gen_helper_paddsb(t0, t0, t1);
4186        break;
4187    case OPC_PADDUSB:
4188        gen_helper_paddusb(t0, t0, t1);
4189        break;
4190    case OPC_PADDB:
4191        gen_helper_paddb(t0, t0, t1);
4192        break;
4193
4194    case OPC_PSUBSH:
4195        gen_helper_psubsh(t0, t0, t1);
4196        break;
4197    case OPC_PSUBUSH:
4198        gen_helper_psubush(t0, t0, t1);
4199        break;
4200    case OPC_PSUBH:
4201        gen_helper_psubh(t0, t0, t1);
4202        break;
4203    case OPC_PSUBW:
4204        gen_helper_psubw(t0, t0, t1);
4205        break;
4206    case OPC_PSUBSB:
4207        gen_helper_psubsb(t0, t0, t1);
4208        break;
4209    case OPC_PSUBUSB:
4210        gen_helper_psubusb(t0, t0, t1);
4211        break;
4212    case OPC_PSUBB:
4213        gen_helper_psubb(t0, t0, t1);
4214        break;
4215
4216    case OPC_PSHUFH:
4217        gen_helper_pshufh(t0, t0, t1);
4218        break;
4219    case OPC_PACKSSWH:
4220        gen_helper_packsswh(t0, t0, t1);
4221        break;
4222    case OPC_PACKSSHB:
4223        gen_helper_packsshb(t0, t0, t1);
4224        break;
4225    case OPC_PACKUSHB:
4226        gen_helper_packushb(t0, t0, t1);
4227        break;
4228
4229    case OPC_PUNPCKLHW:
4230        gen_helper_punpcklhw(t0, t0, t1);
4231        break;
4232    case OPC_PUNPCKHHW:
4233        gen_helper_punpckhhw(t0, t0, t1);
4234        break;
4235    case OPC_PUNPCKLBH:
4236        gen_helper_punpcklbh(t0, t0, t1);
4237        break;
4238    case OPC_PUNPCKHBH:
4239        gen_helper_punpckhbh(t0, t0, t1);
4240        break;
4241    case OPC_PUNPCKLWD:
4242        gen_helper_punpcklwd(t0, t0, t1);
4243        break;
4244    case OPC_PUNPCKHWD:
4245        gen_helper_punpckhwd(t0, t0, t1);
4246        break;
4247
4248    case OPC_PAVGH:
4249        gen_helper_pavgh(t0, t0, t1);
4250        break;
4251    case OPC_PAVGB:
4252        gen_helper_pavgb(t0, t0, t1);
4253        break;
4254    case OPC_PMAXSH:
4255        gen_helper_pmaxsh(t0, t0, t1);
4256        break;
4257    case OPC_PMINSH:
4258        gen_helper_pminsh(t0, t0, t1);
4259        break;
4260    case OPC_PMAXUB:
4261        gen_helper_pmaxub(t0, t0, t1);
4262        break;
4263    case OPC_PMINUB:
4264        gen_helper_pminub(t0, t0, t1);
4265        break;
4266
4267    case OPC_PCMPEQW:
4268        gen_helper_pcmpeqw(t0, t0, t1);
4269        break;
4270    case OPC_PCMPGTW:
4271        gen_helper_pcmpgtw(t0, t0, t1);
4272        break;
4273    case OPC_PCMPEQH:
4274        gen_helper_pcmpeqh(t0, t0, t1);
4275        break;
4276    case OPC_PCMPGTH:
4277        gen_helper_pcmpgth(t0, t0, t1);
4278        break;
4279    case OPC_PCMPEQB:
4280        gen_helper_pcmpeqb(t0, t0, t1);
4281        break;
4282    case OPC_PCMPGTB:
4283        gen_helper_pcmpgtb(t0, t0, t1);
4284        break;
4285
4286    case OPC_PSLLW:
4287        gen_helper_psllw(t0, t0, t1);
4288        break;
4289    case OPC_PSLLH:
4290        gen_helper_psllh(t0, t0, t1);
4291        break;
4292    case OPC_PSRLW:
4293        gen_helper_psrlw(t0, t0, t1);
4294        break;
4295    case OPC_PSRLH:
4296        gen_helper_psrlh(t0, t0, t1);
4297        break;
4298    case OPC_PSRAW:
4299        gen_helper_psraw(t0, t0, t1);
4300        break;
4301    case OPC_PSRAH:
4302        gen_helper_psrah(t0, t0, t1);
4303        break;
4304
4305    case OPC_PMULLH:
4306        gen_helper_pmullh(t0, t0, t1);
4307        break;
4308    case OPC_PMULHH:
4309        gen_helper_pmulhh(t0, t0, t1);
4310        break;
4311    case OPC_PMULHUH:
4312        gen_helper_pmulhuh(t0, t0, t1);
4313        break;
4314    case OPC_PMADDHW:
4315        gen_helper_pmaddhw(t0, t0, t1);
4316        break;
4317
4318    case OPC_PASUBUB:
4319        gen_helper_pasubub(t0, t0, t1);
4320        break;
4321    case OPC_BIADD:
4322        gen_helper_biadd(t0, t0);
4323        break;
4324    case OPC_PMOVMSKB:
4325        gen_helper_pmovmskb(t0, t0);
4326        break;
4327
4328    case OPC_PADDD:
4329        tcg_gen_add_i64(t0, t0, t1);
4330        break;
4331    case OPC_PSUBD:
4332        tcg_gen_sub_i64(t0, t0, t1);
4333        break;
4334    case OPC_XOR_CP2:
4335        tcg_gen_xor_i64(t0, t0, t1);
4336        break;
4337    case OPC_NOR_CP2:
4338        tcg_gen_nor_i64(t0, t0, t1);
4339        break;
4340    case OPC_AND_CP2:
4341        tcg_gen_and_i64(t0, t0, t1);
4342        break;
4343    case OPC_OR_CP2:
4344        tcg_gen_or_i64(t0, t0, t1);
4345        break;
4346
4347    case OPC_PANDN:
4348        tcg_gen_andc_i64(t0, t1, t0);
4349        break;
4350
4351    case OPC_PINSRH_0:
4352        tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
4353        break;
4354    case OPC_PINSRH_1:
4355        tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
4356        break;
4357    case OPC_PINSRH_2:
4358        tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
4359        break;
4360    case OPC_PINSRH_3:
4361        tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
4362        break;
4363
4364    case OPC_PEXTRH:
4365        tcg_gen_andi_i64(t1, t1, 3);
4366        tcg_gen_shli_i64(t1, t1, 4);
4367        tcg_gen_shr_i64(t0, t0, t1);
4368        tcg_gen_ext16u_i64(t0, t0);
4369        break;
4370
4371    case OPC_ADDU_CP2:
4372        tcg_gen_add_i64(t0, t0, t1);
4373        tcg_gen_ext32s_i64(t0, t0);
4374        break;
4375    case OPC_SUBU_CP2:
4376        tcg_gen_sub_i64(t0, t0, t1);
4377        tcg_gen_ext32s_i64(t0, t0);
4378        break;
4379
4380    case OPC_SLL_CP2:
4381        shift_max = 32;
4382        goto do_shift;
4383    case OPC_SRL_CP2:
4384        shift_max = 32;
4385        goto do_shift;
4386    case OPC_SRA_CP2:
4387        shift_max = 32;
4388        goto do_shift;
4389    case OPC_DSLL_CP2:
4390        shift_max = 64;
4391        goto do_shift;
4392    case OPC_DSRL_CP2:
4393        shift_max = 64;
4394        goto do_shift;
4395    case OPC_DSRA_CP2:
4396        shift_max = 64;
4397        goto do_shift;
4398    do_shift:
4399        /* Make sure shift count isn't TCG undefined behaviour.  */
4400        tcg_gen_andi_i64(t1, t1, shift_max - 1);
4401
4402        switch (opc) {
4403        case OPC_SLL_CP2:
4404        case OPC_DSLL_CP2:
4405            tcg_gen_shl_i64(t0, t0, t1);
4406            break;
4407        case OPC_SRA_CP2:
4408        case OPC_DSRA_CP2:
4409            /*
4410             * Since SRA is UndefinedResult without sign-extended inputs,
4411             * we can treat SRA and DSRA the same.
4412             */
4413            tcg_gen_sar_i64(t0, t0, t1);
4414            break;
4415        case OPC_SRL_CP2:
4416            /* We want to shift in zeros for SRL; zero-extend first.  */
4417            tcg_gen_ext32u_i64(t0, t0);
4418            /* FALLTHRU */
4419        case OPC_DSRL_CP2:
4420            tcg_gen_shr_i64(t0, t0, t1);
4421            break;
4422        }
4423
4424        if (shift_max == 32) {
4425            tcg_gen_ext32s_i64(t0, t0);
4426        }
4427
4428        /* Shifts larger than MAX produce zero.  */
4429        tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
4430        tcg_gen_neg_i64(t1, t1);
4431        tcg_gen_and_i64(t0, t0, t1);
4432        break;
4433
4434    case OPC_ADD_CP2:
4435    case OPC_DADD_CP2:
4436        {
4437            TCGv_i64 t2 = tcg_temp_new_i64();
4438            TCGLabel *lab = gen_new_label();
4439
4440            tcg_gen_mov_i64(t2, t0);
4441            tcg_gen_add_i64(t0, t1, t2);
4442            if (opc == OPC_ADD_CP2) {
4443                tcg_gen_ext32s_i64(t0, t0);
4444            }
4445            tcg_gen_xor_i64(t1, t1, t2);
4446            tcg_gen_xor_i64(t2, t2, t0);
4447            tcg_gen_andc_i64(t1, t2, t1);
4448            tcg_temp_free_i64(t2);
4449            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4450            generate_exception(ctx, EXCP_OVERFLOW);
4451            gen_set_label(lab);
4452            break;
4453        }
4454
4455    case OPC_SUB_CP2:
4456    case OPC_DSUB_CP2:
4457        {
4458            TCGv_i64 t2 = tcg_temp_new_i64();
4459            TCGLabel *lab = gen_new_label();
4460
4461            tcg_gen_mov_i64(t2, t0);
4462            tcg_gen_sub_i64(t0, t1, t2);
4463            if (opc == OPC_SUB_CP2) {
4464                tcg_gen_ext32s_i64(t0, t0);
4465            }
4466            tcg_gen_xor_i64(t1, t1, t2);
4467            tcg_gen_xor_i64(t2, t2, t0);
4468            tcg_gen_and_i64(t1, t1, t2);
4469            tcg_temp_free_i64(t2);
4470            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
4471            generate_exception(ctx, EXCP_OVERFLOW);
4472            gen_set_label(lab);
4473            break;
4474        }
4475
4476    case OPC_PMULUW:
4477        tcg_gen_ext32u_i64(t0, t0);
4478        tcg_gen_ext32u_i64(t1, t1);
4479        tcg_gen_mul_i64(t0, t0, t1);
4480        break;
4481
4482    case OPC_SEQU_CP2:
4483    case OPC_SEQ_CP2:
4484        cond = TCG_COND_EQ;
4485        goto do_cc_cond;
4486        break;
4487    case OPC_SLTU_CP2:
4488        cond = TCG_COND_LTU;
4489        goto do_cc_cond;
4490        break;
4491    case OPC_SLT_CP2:
4492        cond = TCG_COND_LT;
4493        goto do_cc_cond;
4494        break;
4495    case OPC_SLEU_CP2:
4496        cond = TCG_COND_LEU;
4497        goto do_cc_cond;
4498        break;
4499    case OPC_SLE_CP2:
4500        cond = TCG_COND_LE;
4501    do_cc_cond:
4502        {
4503            int cc = (ctx->opcode >> 8) & 0x7;
4504            TCGv_i64 t64 = tcg_temp_new_i64();
4505            TCGv_i32 t32 = tcg_temp_new_i32();
4506
4507            tcg_gen_setcond_i64(cond, t64, t0, t1);
4508            tcg_gen_extrl_i64_i32(t32, t64);
4509            tcg_gen_deposit_i32(fpu_fcr31, fpu_fcr31, t32,
4510                                get_fp_bit(cc), 1);
4511
4512            tcg_temp_free_i32(t32);
4513            tcg_temp_free_i64(t64);
4514        }
4515        goto no_rd;
4516        break;
4517    default:
4518        MIPS_INVAL("loongson_cp2");
4519        gen_reserved_instruction(ctx);
4520        return;
4521    }
4522
4523    gen_store_fpr64(ctx, t0, rd);
4524
4525no_rd:
4526    tcg_temp_free_i64(t0);
4527    tcg_temp_free_i64(t1);
4528}
4529
4530static void gen_loongson_lswc2(DisasContext *ctx, int rt,
4531                               int rs, int rd)
4532{
4533    TCGv t0, t1, t2;
4534    TCGv_i32 fp0;
4535#if defined(TARGET_MIPS64)
4536    int lsq_rt1 = ctx->opcode & 0x1f;
4537    int lsq_offset = sextract32(ctx->opcode, 6, 9) << 4;
4538#endif
4539    int shf_offset = sextract32(ctx->opcode, 6, 8);
4540
4541    t0 = tcg_temp_new();
4542
4543    switch (MASK_LOONGSON_GSLSQ(ctx->opcode)) {
4544#if defined(TARGET_MIPS64)
4545    case OPC_GSLQ:
4546        t1 = tcg_temp_new();
4547        gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4548        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4549                           ctx->default_tcg_memop_mask);
4550        gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4551        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
4552                           ctx->default_tcg_memop_mask);
4553        gen_store_gpr(t1, rt);
4554        gen_store_gpr(t0, lsq_rt1);
4555        tcg_temp_free(t1);
4556        break;
4557    case OPC_GSLQC1:
4558        check_cp1_enabled(ctx);
4559        t1 = tcg_temp_new();
4560        gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4561        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4562                           ctx->default_tcg_memop_mask);
4563        gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4564        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
4565                           ctx->default_tcg_memop_mask);
4566        gen_store_fpr64(ctx, t1, rt);
4567        gen_store_fpr64(ctx, t0, lsq_rt1);
4568        tcg_temp_free(t1);
4569        break;
4570    case OPC_GSSQ:
4571        t1 = tcg_temp_new();
4572        gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4573        gen_load_gpr(t1, rt);
4574        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4575                           ctx->default_tcg_memop_mask);
4576        gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4577        gen_load_gpr(t1, lsq_rt1);
4578        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4579                           ctx->default_tcg_memop_mask);
4580        tcg_temp_free(t1);
4581        break;
4582    case OPC_GSSQC1:
4583        check_cp1_enabled(ctx);
4584        t1 = tcg_temp_new();
4585        gen_base_offset_addr(ctx, t0, rs, lsq_offset);
4586        gen_load_fpr64(ctx, t1, rt);
4587        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4588                           ctx->default_tcg_memop_mask);
4589        gen_base_offset_addr(ctx, t0, rs, lsq_offset + 8);
4590        gen_load_fpr64(ctx, t1, lsq_rt1);
4591        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4592                           ctx->default_tcg_memop_mask);
4593        tcg_temp_free(t1);
4594        break;
4595#endif
4596    case OPC_GSSHFL:
4597        switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4598        case OPC_GSLWLC1:
4599            check_cp1_enabled(ctx);
4600            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4601            t1 = tcg_temp_new();
4602            tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4603            tcg_gen_andi_tl(t1, t0, 3);
4604#ifndef TARGET_WORDS_BIGENDIAN
4605            tcg_gen_xori_tl(t1, t1, 3);
4606#endif
4607            tcg_gen_shli_tl(t1, t1, 3);
4608            tcg_gen_andi_tl(t0, t0, ~3);
4609            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
4610            tcg_gen_shl_tl(t0, t0, t1);
4611            t2 = tcg_const_tl(-1);
4612            tcg_gen_shl_tl(t2, t2, t1);
4613            fp0 = tcg_temp_new_i32();
4614            gen_load_fpr32(ctx, fp0, rt);
4615            tcg_gen_ext_i32_tl(t1, fp0);
4616            tcg_gen_andc_tl(t1, t1, t2);
4617            tcg_temp_free(t2);
4618            tcg_gen_or_tl(t0, t0, t1);
4619            tcg_temp_free(t1);
4620#if defined(TARGET_MIPS64)
4621            tcg_gen_extrl_i64_i32(fp0, t0);
4622#else
4623            tcg_gen_ext32s_tl(fp0, t0);
4624#endif
4625            gen_store_fpr32(ctx, fp0, rt);
4626            tcg_temp_free_i32(fp0);
4627            break;
4628        case OPC_GSLWRC1:
4629            check_cp1_enabled(ctx);
4630            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4631            t1 = tcg_temp_new();
4632            tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4633            tcg_gen_andi_tl(t1, t0, 3);
4634#ifdef TARGET_WORDS_BIGENDIAN
4635            tcg_gen_xori_tl(t1, t1, 3);
4636#endif
4637            tcg_gen_shli_tl(t1, t1, 3);
4638            tcg_gen_andi_tl(t0, t0, ~3);
4639            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEUL);
4640            tcg_gen_shr_tl(t0, t0, t1);
4641            tcg_gen_xori_tl(t1, t1, 31);
4642            t2 = tcg_const_tl(0xfffffffeull);
4643            tcg_gen_shl_tl(t2, t2, t1);
4644            fp0 = tcg_temp_new_i32();
4645            gen_load_fpr32(ctx, fp0, rt);
4646            tcg_gen_ext_i32_tl(t1, fp0);
4647            tcg_gen_and_tl(t1, t1, t2);
4648            tcg_temp_free(t2);
4649            tcg_gen_or_tl(t0, t0, t1);
4650            tcg_temp_free(t1);
4651#if defined(TARGET_MIPS64)
4652            tcg_gen_extrl_i64_i32(fp0, t0);
4653#else
4654            tcg_gen_ext32s_tl(fp0, t0);
4655#endif
4656            gen_store_fpr32(ctx, fp0, rt);
4657            tcg_temp_free_i32(fp0);
4658            break;
4659#if defined(TARGET_MIPS64)
4660        case OPC_GSLDLC1:
4661            check_cp1_enabled(ctx);
4662            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4663            t1 = tcg_temp_new();
4664            tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4665            tcg_gen_andi_tl(t1, t0, 7);
4666#ifndef TARGET_WORDS_BIGENDIAN
4667            tcg_gen_xori_tl(t1, t1, 7);
4668#endif
4669            tcg_gen_shli_tl(t1, t1, 3);
4670            tcg_gen_andi_tl(t0, t0, ~7);
4671            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
4672            tcg_gen_shl_tl(t0, t0, t1);
4673            t2 = tcg_const_tl(-1);
4674            tcg_gen_shl_tl(t2, t2, t1);
4675            gen_load_fpr64(ctx, t1, rt);
4676            tcg_gen_andc_tl(t1, t1, t2);
4677            tcg_temp_free(t2);
4678            tcg_gen_or_tl(t0, t0, t1);
4679            tcg_temp_free(t1);
4680            gen_store_fpr64(ctx, t0, rt);
4681            break;
4682        case OPC_GSLDRC1:
4683            check_cp1_enabled(ctx);
4684            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4685            t1 = tcg_temp_new();
4686            tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_UB);
4687            tcg_gen_andi_tl(t1, t0, 7);
4688#ifdef TARGET_WORDS_BIGENDIAN
4689            tcg_gen_xori_tl(t1, t1, 7);
4690#endif
4691            tcg_gen_shli_tl(t1, t1, 3);
4692            tcg_gen_andi_tl(t0, t0, ~7);
4693            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
4694            tcg_gen_shr_tl(t0, t0, t1);
4695            tcg_gen_xori_tl(t1, t1, 63);
4696            t2 = tcg_const_tl(0xfffffffffffffffeull);
4697            tcg_gen_shl_tl(t2, t2, t1);
4698            gen_load_fpr64(ctx, t1, rt);
4699            tcg_gen_and_tl(t1, t1, t2);
4700            tcg_temp_free(t2);
4701            tcg_gen_or_tl(t0, t0, t1);
4702            tcg_temp_free(t1);
4703            gen_store_fpr64(ctx, t0, rt);
4704            break;
4705#endif
4706        default:
4707            MIPS_INVAL("loongson_gsshfl");
4708            gen_reserved_instruction(ctx);
4709            break;
4710        }
4711        break;
4712    case OPC_GSSHFS:
4713        switch (MASK_LOONGSON_GSSHFLS(ctx->opcode)) {
4714        case OPC_GSSWLC1:
4715            check_cp1_enabled(ctx);
4716            t1 = tcg_temp_new();
4717            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4718            fp0 = tcg_temp_new_i32();
4719            gen_load_fpr32(ctx, fp0, rt);
4720            tcg_gen_ext_i32_tl(t1, fp0);
4721            gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
4722            tcg_temp_free_i32(fp0);
4723            tcg_temp_free(t1);
4724            break;
4725        case OPC_GSSWRC1:
4726            check_cp1_enabled(ctx);
4727            t1 = tcg_temp_new();
4728            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4729            fp0 = tcg_temp_new_i32();
4730            gen_load_fpr32(ctx, fp0, rt);
4731            tcg_gen_ext_i32_tl(t1, fp0);
4732            gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
4733            tcg_temp_free_i32(fp0);
4734            tcg_temp_free(t1);
4735            break;
4736#if defined(TARGET_MIPS64)
4737        case OPC_GSSDLC1:
4738            check_cp1_enabled(ctx);
4739            t1 = tcg_temp_new();
4740            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4741            gen_load_fpr64(ctx, t1, rt);
4742            gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
4743            tcg_temp_free(t1);
4744            break;
4745        case OPC_GSSDRC1:
4746            check_cp1_enabled(ctx);
4747            t1 = tcg_temp_new();
4748            gen_base_offset_addr(ctx, t0, rs, shf_offset);
4749            gen_load_fpr64(ctx, t1, rt);
4750            gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
4751            tcg_temp_free(t1);
4752            break;
4753#endif
4754        default:
4755            MIPS_INVAL("loongson_gsshfs");
4756            gen_reserved_instruction(ctx);
4757            break;
4758        }
4759        break;
4760    default:
4761        MIPS_INVAL("loongson_gslsq");
4762        gen_reserved_instruction(ctx);
4763        break;
4764    }
4765    tcg_temp_free(t0);
4766}
4767
4768/* Loongson EXT LDC2/SDC2 */
4769static void gen_loongson_lsdc2(DisasContext *ctx, int rt,
4770                               int rs, int rd)
4771{
4772    int offset = sextract32(ctx->opcode, 3, 8);
4773    uint32_t opc = MASK_LOONGSON_LSDC2(ctx->opcode);
4774    TCGv t0, t1;
4775    TCGv_i32 fp0;
4776
4777    /* Pre-conditions */
4778    switch (opc) {
4779    case OPC_GSLBX:
4780    case OPC_GSLHX:
4781    case OPC_GSLWX:
4782    case OPC_GSLDX:
4783        /* prefetch, implement as NOP */
4784        if (rt == 0) {
4785            return;
4786        }
4787        break;
4788    case OPC_GSSBX:
4789    case OPC_GSSHX:
4790    case OPC_GSSWX:
4791    case OPC_GSSDX:
4792        break;
4793    case OPC_GSLWXC1:
4794#if defined(TARGET_MIPS64)
4795    case OPC_GSLDXC1:
4796#endif
4797        check_cp1_enabled(ctx);
4798        /* prefetch, implement as NOP */
4799        if (rt == 0) {
4800            return;
4801        }
4802        break;
4803    case OPC_GSSWXC1:
4804#if defined(TARGET_MIPS64)
4805    case OPC_GSSDXC1:
4806#endif
4807        check_cp1_enabled(ctx);
4808        break;
4809    default:
4810        MIPS_INVAL("loongson_lsdc2");
4811        gen_reserved_instruction(ctx);
4812        return;
4813        break;
4814    }
4815
4816    t0 = tcg_temp_new();
4817
4818    gen_base_offset_addr(ctx, t0, rs, offset);
4819    gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4820
4821    switch (opc) {
4822    case OPC_GSLBX:
4823        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_SB);
4824        gen_store_gpr(t0, rt);
4825        break;
4826    case OPC_GSLHX:
4827        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
4828                           ctx->default_tcg_memop_mask);
4829        gen_store_gpr(t0, rt);
4830        break;
4831    case OPC_GSLWX:
4832        gen_base_offset_addr(ctx, t0, rs, offset);
4833        if (rd) {
4834            gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4835        }
4836        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL |
4837                           ctx->default_tcg_memop_mask);
4838        gen_store_gpr(t0, rt);
4839        break;
4840#if defined(TARGET_MIPS64)
4841    case OPC_GSLDX:
4842        gen_base_offset_addr(ctx, t0, rs, offset);
4843        if (rd) {
4844            gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4845        }
4846        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
4847                           ctx->default_tcg_memop_mask);
4848        gen_store_gpr(t0, rt);
4849        break;
4850#endif
4851    case OPC_GSLWXC1:
4852        check_cp1_enabled(ctx);
4853        gen_base_offset_addr(ctx, t0, rs, offset);
4854        if (rd) {
4855            gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4856        }
4857        fp0 = tcg_temp_new_i32();
4858        tcg_gen_qemu_ld_i32(fp0, t0, ctx->mem_idx, MO_TESL |
4859                            ctx->default_tcg_memop_mask);
4860        gen_store_fpr32(ctx, fp0, rt);
4861        tcg_temp_free_i32(fp0);
4862        break;
4863#if defined(TARGET_MIPS64)
4864    case OPC_GSLDXC1:
4865        check_cp1_enabled(ctx);
4866        gen_base_offset_addr(ctx, t0, rs, offset);
4867        if (rd) {
4868            gen_op_addr_add(ctx, t0, cpu_gpr[rd], t0);
4869        }
4870        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ |
4871                           ctx->default_tcg_memop_mask);
4872        gen_store_fpr64(ctx, t0, rt);
4873        break;
4874#endif
4875    case OPC_GSSBX:
4876        t1 = tcg_temp_new();
4877        gen_load_gpr(t1, rt);
4878        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_SB);
4879        tcg_temp_free(t1);
4880        break;
4881    case OPC_GSSHX:
4882        t1 = tcg_temp_new();
4883        gen_load_gpr(t1, rt);
4884        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
4885                           ctx->default_tcg_memop_mask);
4886        tcg_temp_free(t1);
4887        break;
4888    case OPC_GSSWX:
4889        t1 = tcg_temp_new();
4890        gen_load_gpr(t1, rt);
4891        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL |
4892                           ctx->default_tcg_memop_mask);
4893        tcg_temp_free(t1);
4894        break;
4895#if defined(TARGET_MIPS64)
4896    case OPC_GSSDX:
4897        t1 = tcg_temp_new();
4898        gen_load_gpr(t1, rt);
4899        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ |
4900                           ctx->default_tcg_memop_mask);
4901        tcg_temp_free(t1);
4902        break;
4903#endif
4904    case OPC_GSSWXC1:
4905        fp0 = tcg_temp_new_i32();
4906        gen_load_fpr32(ctx, fp0, rt);
4907        tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL |
4908                            ctx->default_tcg_memop_mask);
4909        tcg_temp_free_i32(fp0);
4910        break;
4911#if defined(TARGET_MIPS64)
4912    case OPC_GSSDXC1:
4913        t1 = tcg_temp_new();
4914        gen_load_fpr64(ctx, t1, rt);
4915        tcg_gen_qemu_st_i64(t1, t0, ctx->mem_idx, MO_TEQ |
4916                            ctx->default_tcg_memop_mask);
4917        tcg_temp_free(t1);
4918        break;
4919#endif
4920    default:
4921        break;
4922    }
4923
4924    tcg_temp_free(t0);
4925}
4926
4927/* Traps */
4928static void gen_trap(DisasContext *ctx, uint32_t opc,
4929                     int rs, int rt, int16_t imm)
4930{
4931    int cond;
4932    TCGv t0 = tcg_temp_new();
4933    TCGv t1 = tcg_temp_new();
4934
4935    cond = 0;
4936    /* Load needed operands */
4937    switch (opc) {
4938    case OPC_TEQ:
4939    case OPC_TGE:
4940    case OPC_TGEU:
4941    case OPC_TLT:
4942    case OPC_TLTU:
4943    case OPC_TNE:
4944        /* Compare two registers */
4945        if (rs != rt) {
4946            gen_load_gpr(t0, rs);
4947            gen_load_gpr(t1, rt);
4948            cond = 1;
4949        }
4950        break;
4951    case OPC_TEQI:
4952    case OPC_TGEI:
4953    case OPC_TGEIU:
4954    case OPC_TLTI:
4955    case OPC_TLTIU:
4956    case OPC_TNEI:
4957        /* Compare register to immediate */
4958        if (rs != 0 || imm != 0) {
4959            gen_load_gpr(t0, rs);
4960            tcg_gen_movi_tl(t1, (int32_t)imm);
4961            cond = 1;
4962        }
4963        break;
4964    }
4965    if (cond == 0) {
4966        switch (opc) {
4967        case OPC_TEQ:   /* rs == rs */
4968        case OPC_TEQI:  /* r0 == 0  */
4969        case OPC_TGE:   /* rs >= rs */
4970        case OPC_TGEI:  /* r0 >= 0  */
4971        case OPC_TGEU:  /* rs >= rs unsigned */
4972        case OPC_TGEIU: /* r0 >= 0  unsigned */
4973            /* Always trap */
4974            generate_exception_end(ctx, EXCP_TRAP);
4975            break;
4976        case OPC_TLT:   /* rs < rs           */
4977        case OPC_TLTI:  /* r0 < 0            */
4978        case OPC_TLTU:  /* rs < rs unsigned  */
4979        case OPC_TLTIU: /* r0 < 0  unsigned  */
4980        case OPC_TNE:   /* rs != rs          */
4981        case OPC_TNEI:  /* r0 != 0           */
4982            /* Never trap: treat as NOP. */
4983            break;
4984        }
4985    } else {
4986        TCGLabel *l1 = gen_new_label();
4987
4988        switch (opc) {
4989        case OPC_TEQ:
4990        case OPC_TEQI:
4991            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
4992            break;
4993        case OPC_TGE:
4994        case OPC_TGEI:
4995            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
4996            break;
4997        case OPC_TGEU:
4998        case OPC_TGEIU:
4999            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
5000            break;
5001        case OPC_TLT:
5002        case OPC_TLTI:
5003            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
5004            break;
5005        case OPC_TLTU:
5006        case OPC_TLTIU:
5007            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
5008            break;
5009        case OPC_TNE:
5010        case OPC_TNEI:
5011            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
5012            break;
5013        }
5014        generate_exception(ctx, EXCP_TRAP);
5015        gen_set_label(l1);
5016    }
5017    tcg_temp_free(t0);
5018    tcg_temp_free(t1);
5019}
5020
5021static inline bool use_goto_tb(DisasContext *ctx, target_ulong dest)
5022{
5023    if (unlikely(ctx->base.singlestep_enabled)) {
5024        return false;
5025    }
5026
5027#ifndef CONFIG_USER_ONLY
5028    return (ctx->base.tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK);
5029#else
5030    return true;
5031#endif
5032}
5033
5034static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
5035{
5036    if (use_goto_tb(ctx, dest)) {
5037        tcg_gen_goto_tb(n);
5038        gen_save_pc(dest);
5039        tcg_gen_exit_tb(ctx->base.tb, n);
5040    } else {
5041        gen_save_pc(dest);
5042        if (ctx->base.singlestep_enabled) {
5043            save_cpu_state(ctx, 0);
5044            gen_helper_raise_exception_debug(cpu_env);
5045        }
5046        tcg_gen_lookup_and_goto_ptr();
5047    }
5048}
5049
5050/* Branches (before delay slot) */
5051static void gen_compute_branch(DisasContext *ctx, uint32_t opc,
5052                               int insn_bytes,
5053                               int rs, int rt, int32_t offset,
5054                               int delayslot_size)
5055{
5056    target_ulong btgt = -1;
5057    int blink = 0;
5058    int bcond_compute = 0;
5059    TCGv t0 = tcg_temp_new();
5060    TCGv t1 = tcg_temp_new();
5061
5062    if (ctx->hflags & MIPS_HFLAG_BMASK) {
5063#ifdef MIPS_DEBUG_DISAS
5064        LOG_DISAS("Branch in delay / forbidden slot at PC 0x"
5065                  TARGET_FMT_lx "\n", ctx->base.pc_next);
5066#endif
5067        gen_reserved_instruction(ctx);
5068        goto out;
5069    }
5070
5071    /* Load needed operands */
5072    switch (opc) {
5073    case OPC_BEQ:
5074    case OPC_BEQL:
5075    case OPC_BNE:
5076    case OPC_BNEL:
5077        /* Compare two registers */
5078        if (rs != rt) {
5079            gen_load_gpr(t0, rs);
5080            gen_load_gpr(t1, rt);
5081            bcond_compute = 1;
5082        }
5083        btgt = ctx->base.pc_next + insn_bytes + offset;
5084        break;
5085    case OPC_BGEZ:
5086    case OPC_BGEZAL:
5087    case OPC_BGEZALL:
5088    case OPC_BGEZL:
5089    case OPC_BGTZ:
5090    case OPC_BGTZL:
5091    case OPC_BLEZ:
5092    case OPC_BLEZL:
5093    case OPC_BLTZ:
5094    case OPC_BLTZAL:
5095    case OPC_BLTZALL:
5096    case OPC_BLTZL:
5097        /* Compare to zero */
5098        if (rs != 0) {
5099            gen_load_gpr(t0, rs);
5100            bcond_compute = 1;
5101        }
5102        btgt = ctx->base.pc_next + insn_bytes + offset;
5103        break;
5104    case OPC_BPOSGE32:
5105#if defined(TARGET_MIPS64)
5106    case OPC_BPOSGE64:
5107        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
5108#else
5109        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5110#endif
5111        bcond_compute = 1;
5112        btgt = ctx->base.pc_next + insn_bytes + offset;
5113        break;
5114    case OPC_J:
5115    case OPC_JAL:
5116    case OPC_JALX:
5117        /* Jump to immediate */
5118        btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
5119            (uint32_t)offset;
5120        break;
5121    case OPC_JR:
5122    case OPC_JALR:
5123        /* Jump to register */
5124        if (offset != 0 && offset != 16) {
5125            /*
5126             * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5127             * others are reserved.
5128             */
5129            MIPS_INVAL("jump hint");
5130            gen_reserved_instruction(ctx);
5131            goto out;
5132        }
5133        gen_load_gpr(btarget, rs);
5134        break;
5135    default:
5136        MIPS_INVAL("branch/jump");
5137        gen_reserved_instruction(ctx);
5138        goto out;
5139    }
5140    if (bcond_compute == 0) {
5141        /* No condition to be computed */
5142        switch (opc) {
5143        case OPC_BEQ:     /* rx == rx        */
5144        case OPC_BEQL:    /* rx == rx likely */
5145        case OPC_BGEZ:    /* 0 >= 0          */
5146        case OPC_BGEZL:   /* 0 >= 0 likely   */
5147        case OPC_BLEZ:    /* 0 <= 0          */
5148        case OPC_BLEZL:   /* 0 <= 0 likely   */
5149            /* Always take */
5150            ctx->hflags |= MIPS_HFLAG_B;
5151            break;
5152        case OPC_BGEZAL:  /* 0 >= 0          */
5153        case OPC_BGEZALL: /* 0 >= 0 likely   */
5154            /* Always take and link */
5155            blink = 31;
5156            ctx->hflags |= MIPS_HFLAG_B;
5157            break;
5158        case OPC_BNE:     /* rx != rx        */
5159        case OPC_BGTZ:    /* 0 > 0           */
5160        case OPC_BLTZ:    /* 0 < 0           */
5161            /* Treat as NOP. */
5162            goto out;
5163        case OPC_BLTZAL:  /* 0 < 0           */
5164            /*
5165             * Handle as an unconditional branch to get correct delay
5166             * slot checking.
5167             */
5168            blink = 31;
5169            btgt = ctx->base.pc_next + insn_bytes + delayslot_size;
5170            ctx->hflags |= MIPS_HFLAG_B;
5171            break;
5172        case OPC_BLTZALL: /* 0 < 0 likely */
5173            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5174            /* Skip the instruction in the delay slot */
5175            ctx->base.pc_next += 4;
5176            goto out;
5177        case OPC_BNEL:    /* rx != rx likely */
5178        case OPC_BGTZL:   /* 0 > 0 likely */
5179        case OPC_BLTZL:   /* 0 < 0 likely */
5180            /* Skip the instruction in the delay slot */
5181            ctx->base.pc_next += 4;
5182            goto out;
5183        case OPC_J:
5184            ctx->hflags |= MIPS_HFLAG_B;
5185            break;
5186        case OPC_JALX:
5187            ctx->hflags |= MIPS_HFLAG_BX;
5188            /* Fallthrough */
5189        case OPC_JAL:
5190            blink = 31;
5191            ctx->hflags |= MIPS_HFLAG_B;
5192            break;
5193        case OPC_JR:
5194            ctx->hflags |= MIPS_HFLAG_BR;
5195            break;
5196        case OPC_JALR:
5197            blink = rt;
5198            ctx->hflags |= MIPS_HFLAG_BR;
5199            break;
5200        default:
5201            MIPS_INVAL("branch/jump");
5202            gen_reserved_instruction(ctx);
5203            goto out;
5204        }
5205    } else {
5206        switch (opc) {
5207        case OPC_BEQ:
5208            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5209            goto not_likely;
5210        case OPC_BEQL:
5211            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5212            goto likely;
5213        case OPC_BNE:
5214            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5215            goto not_likely;
5216        case OPC_BNEL:
5217            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5218            goto likely;
5219        case OPC_BGEZ:
5220            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5221            goto not_likely;
5222        case OPC_BGEZL:
5223            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5224            goto likely;
5225        case OPC_BGEZAL:
5226            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5227            blink = 31;
5228            goto not_likely;
5229        case OPC_BGEZALL:
5230            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5231            blink = 31;
5232            goto likely;
5233        case OPC_BGTZ:
5234            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5235            goto not_likely;
5236        case OPC_BGTZL:
5237            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
5238            goto likely;
5239        case OPC_BLEZ:
5240            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5241            goto not_likely;
5242        case OPC_BLEZL:
5243            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
5244            goto likely;
5245        case OPC_BLTZ:
5246            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5247            goto not_likely;
5248        case OPC_BLTZL:
5249            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5250            goto likely;
5251        case OPC_BPOSGE32:
5252            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5253            goto not_likely;
5254#if defined(TARGET_MIPS64)
5255        case OPC_BPOSGE64:
5256            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
5257            goto not_likely;
5258#endif
5259        case OPC_BLTZAL:
5260            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5261            blink = 31;
5262        not_likely:
5263            ctx->hflags |= MIPS_HFLAG_BC;
5264            break;
5265        case OPC_BLTZALL:
5266            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
5267            blink = 31;
5268        likely:
5269            ctx->hflags |= MIPS_HFLAG_BL;
5270            break;
5271        default:
5272            MIPS_INVAL("conditional branch/jump");
5273            gen_reserved_instruction(ctx);
5274            goto out;
5275        }
5276    }
5277
5278    ctx->btarget = btgt;
5279
5280    switch (delayslot_size) {
5281    case 2:
5282        ctx->hflags |= MIPS_HFLAG_BDS16;
5283        break;
5284    case 4:
5285        ctx->hflags |= MIPS_HFLAG_BDS32;
5286        break;
5287    }
5288
5289    if (blink > 0) {
5290        int post_delay = insn_bytes + delayslot_size;
5291        int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
5292
5293        tcg_gen_movi_tl(cpu_gpr[blink],
5294                        ctx->base.pc_next + post_delay + lowbit);
5295    }
5296
5297 out:
5298    if (insn_bytes == 2) {
5299        ctx->hflags |= MIPS_HFLAG_B16;
5300    }
5301    tcg_temp_free(t0);
5302    tcg_temp_free(t1);
5303}
5304
5305
5306/* nanoMIPS Branches */
5307static void gen_compute_branch_nm(DisasContext *ctx, uint32_t opc,
5308                                int insn_bytes,
5309                                int rs, int rt, int32_t offset)
5310{
5311    target_ulong btgt = -1;
5312    int bcond_compute = 0;
5313    TCGv t0 = tcg_temp_new();
5314    TCGv t1 = tcg_temp_new();
5315
5316    /* Load needed operands */
5317    switch (opc) {
5318    case OPC_BEQ:
5319    case OPC_BNE:
5320        /* Compare two registers */
5321        if (rs != rt) {
5322            gen_load_gpr(t0, rs);
5323            gen_load_gpr(t1, rt);
5324            bcond_compute = 1;
5325        }
5326        btgt = ctx->base.pc_next + insn_bytes + offset;
5327        break;
5328    case OPC_BGEZAL:
5329        /* Compare to zero */
5330        if (rs != 0) {
5331            gen_load_gpr(t0, rs);
5332            bcond_compute = 1;
5333        }
5334        btgt = ctx->base.pc_next + insn_bytes + offset;
5335        break;
5336    case OPC_BPOSGE32:
5337        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
5338        bcond_compute = 1;
5339        btgt = ctx->base.pc_next + insn_bytes + offset;
5340        break;
5341    case OPC_JR:
5342    case OPC_JALR:
5343        /* Jump to register */
5344        if (offset != 0 && offset != 16) {
5345            /*
5346             * Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
5347             * others are reserved.
5348             */
5349            MIPS_INVAL("jump hint");
5350            gen_reserved_instruction(ctx);
5351            goto out;
5352        }
5353        gen_load_gpr(btarget, rs);
5354        break;
5355    default:
5356        MIPS_INVAL("branch/jump");
5357        gen_reserved_instruction(ctx);
5358        goto out;
5359    }
5360    if (bcond_compute == 0) {
5361        /* No condition to be computed */
5362        switch (opc) {
5363        case OPC_BEQ:     /* rx == rx        */
5364            /* Always take */
5365            ctx->hflags |= MIPS_HFLAG_B;
5366            break;
5367        case OPC_BGEZAL:  /* 0 >= 0          */
5368            /* Always take and link */
5369            tcg_gen_movi_tl(cpu_gpr[31],
5370                            ctx->base.pc_next + insn_bytes);
5371            ctx->hflags |= MIPS_HFLAG_B;
5372            break;
5373        case OPC_BNE:     /* rx != rx        */
5374            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 8);
5375            /* Skip the instruction in the delay slot */
5376            ctx->base.pc_next += 4;
5377            goto out;
5378        case OPC_JR:
5379            ctx->hflags |= MIPS_HFLAG_BR;
5380            break;
5381        case OPC_JALR:
5382            if (rt > 0) {
5383                tcg_gen_movi_tl(cpu_gpr[rt],
5384                                ctx->base.pc_next + insn_bytes);
5385            }
5386            ctx->hflags |= MIPS_HFLAG_BR;
5387            break;
5388        default:
5389            MIPS_INVAL("branch/jump");
5390            gen_reserved_instruction(ctx);
5391            goto out;
5392        }
5393    } else {
5394        switch (opc) {
5395        case OPC_BEQ:
5396            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
5397            goto not_likely;
5398        case OPC_BNE:
5399            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
5400            goto not_likely;
5401        case OPC_BGEZAL:
5402            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
5403            tcg_gen_movi_tl(cpu_gpr[31],
5404                            ctx->base.pc_next + insn_bytes);
5405            goto not_likely;
5406        case OPC_BPOSGE32:
5407            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
5408        not_likely:
5409            ctx->hflags |= MIPS_HFLAG_BC;
5410            break;
5411        default:
5412            MIPS_INVAL("conditional branch/jump");
5413            gen_reserved_instruction(ctx);
5414            goto out;
5415        }
5416    }
5417
5418    ctx->btarget = btgt;
5419
5420 out:
5421    if (insn_bytes == 2) {
5422        ctx->hflags |= MIPS_HFLAG_B16;
5423    }
5424    tcg_temp_free(t0);
5425    tcg_temp_free(t1);
5426}
5427
5428
5429/* special3 bitfield operations */
5430static void gen_bitops(DisasContext *ctx, uint32_t opc, int rt,
5431                       int rs, int lsb, int msb)
5432{
5433    TCGv t0 = tcg_temp_new();
5434    TCGv t1 = tcg_temp_new();
5435
5436    gen_load_gpr(t1, rs);
5437    switch (opc) {
5438    case OPC_EXT:
5439        if (lsb + msb > 31) {
5440            goto fail;
5441        }
5442        if (msb != 31) {
5443            tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
5444        } else {
5445            /*
5446             * The two checks together imply that lsb == 0,
5447             * so this is a simple sign-extension.
5448             */
5449            tcg_gen_ext32s_tl(t0, t1);
5450        }
5451        break;
5452#if defined(TARGET_MIPS64)
5453    case OPC_DEXTU:
5454        lsb += 32;
5455        goto do_dext;
5456    case OPC_DEXTM:
5457        msb += 32;
5458        goto do_dext;
5459    case OPC_DEXT:
5460    do_dext:
5461        if (lsb + msb > 63) {
5462            goto fail;
5463        }
5464        tcg_gen_extract_tl(t0, t1, lsb, msb + 1);
5465        break;
5466#endif
5467    case OPC_INS:
5468        if (lsb > msb) {
5469            goto fail;
5470        }
5471        gen_load_gpr(t0, rt);
5472        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
5473        tcg_gen_ext32s_tl(t0, t0);
5474        break;
5475#if defined(TARGET_MIPS64)
5476    case OPC_DINSU:
5477        lsb += 32;
5478        /* FALLTHRU */
5479    case OPC_DINSM:
5480        msb += 32;
5481        /* FALLTHRU */
5482    case OPC_DINS:
5483        if (lsb > msb) {
5484            goto fail;
5485        }
5486        gen_load_gpr(t0, rt);
5487        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
5488        break;
5489#endif
5490    default:
5491fail:
5492        MIPS_INVAL("bitops");
5493        gen_reserved_instruction(ctx);
5494        tcg_temp_free(t0);
5495        tcg_temp_free(t1);
5496        return;
5497    }
5498    gen_store_gpr(t0, rt);
5499    tcg_temp_free(t0);
5500    tcg_temp_free(t1);
5501}
5502
5503static void gen_bshfl(DisasContext *ctx, uint32_t op2, int rt, int rd)
5504{
5505    TCGv t0;
5506
5507    if (rd == 0) {
5508        /* If no destination, treat it as a NOP. */
5509        return;
5510    }
5511
5512    t0 = tcg_temp_new();
5513    gen_load_gpr(t0, rt);
5514    switch (op2) {
5515    case OPC_WSBH:
5516        {
5517            TCGv t1 = tcg_temp_new();
5518            TCGv t2 = tcg_const_tl(0x00FF00FF);
5519
5520            tcg_gen_shri_tl(t1, t0, 8);
5521            tcg_gen_and_tl(t1, t1, t2);
5522            tcg_gen_and_tl(t0, t0, t2);
5523            tcg_gen_shli_tl(t0, t0, 8);
5524            tcg_gen_or_tl(t0, t0, t1);
5525            tcg_temp_free(t2);
5526            tcg_temp_free(t1);
5527            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5528        }
5529        break;
5530    case OPC_SEB:
5531        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
5532        break;
5533    case OPC_SEH:
5534        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
5535        break;
5536#if defined(TARGET_MIPS64)
5537    case OPC_DSBH:
5538        {
5539            TCGv t1 = tcg_temp_new();
5540            TCGv t2 = tcg_const_tl(0x00FF00FF00FF00FFULL);
5541
5542            tcg_gen_shri_tl(t1, t0, 8);
5543            tcg_gen_and_tl(t1, t1, t2);
5544            tcg_gen_and_tl(t0, t0, t2);
5545            tcg_gen_shli_tl(t0, t0, 8);
5546            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
5547            tcg_temp_free(t2);
5548            tcg_temp_free(t1);
5549        }
5550        break;
5551    case OPC_DSHD:
5552        {
5553            TCGv t1 = tcg_temp_new();
5554            TCGv t2 = tcg_const_tl(0x0000FFFF0000FFFFULL);
5555
5556            tcg_gen_shri_tl(t1, t0, 16);
5557            tcg_gen_and_tl(t1, t1, t2);
5558            tcg_gen_and_tl(t0, t0, t2);
5559            tcg_gen_shli_tl(t0, t0, 16);
5560            tcg_gen_or_tl(t0, t0, t1);
5561            tcg_gen_shri_tl(t1, t0, 32);
5562            tcg_gen_shli_tl(t0, t0, 32);
5563            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
5564            tcg_temp_free(t2);
5565            tcg_temp_free(t1);
5566        }
5567        break;
5568#endif
5569    default:
5570        MIPS_INVAL("bsfhl");
5571        gen_reserved_instruction(ctx);
5572        tcg_temp_free(t0);
5573        return;
5574    }
5575    tcg_temp_free(t0);
5576}
5577
5578static void gen_align_bits(DisasContext *ctx, int wordsz, int rd, int rs,
5579                           int rt, int bits)
5580{
5581    TCGv t0;
5582    if (rd == 0) {
5583        /* Treat as NOP. */
5584        return;
5585    }
5586    t0 = tcg_temp_new();
5587    if (bits == 0 || bits == wordsz) {
5588        if (bits == 0) {
5589            gen_load_gpr(t0, rt);
5590        } else {
5591            gen_load_gpr(t0, rs);
5592        }
5593        switch (wordsz) {
5594        case 32:
5595            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
5596            break;
5597#if defined(TARGET_MIPS64)
5598        case 64:
5599            tcg_gen_mov_tl(cpu_gpr[rd], t0);
5600            break;
5601#endif
5602        }
5603    } else {
5604        TCGv t1 = tcg_temp_new();
5605        gen_load_gpr(t0, rt);
5606        gen_load_gpr(t1, rs);
5607        switch (wordsz) {
5608        case 32:
5609            {
5610                TCGv_i64 t2 = tcg_temp_new_i64();
5611                tcg_gen_concat_tl_i64(t2, t1, t0);
5612                tcg_gen_shri_i64(t2, t2, 32 - bits);
5613                gen_move_low32(cpu_gpr[rd], t2);
5614                tcg_temp_free_i64(t2);
5615            }
5616            break;
5617#if defined(TARGET_MIPS64)
5618        case 64:
5619            tcg_gen_shli_tl(t0, t0, bits);
5620            tcg_gen_shri_tl(t1, t1, 64 - bits);
5621            tcg_gen_or_tl(cpu_gpr[rd], t1, t0);
5622            break;
5623#endif
5624        }
5625        tcg_temp_free(t1);
5626    }
5627
5628    tcg_temp_free(t0);
5629}
5630
5631static void gen_align(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
5632                      int bp)
5633{
5634    gen_align_bits(ctx, wordsz, rd, rs, rt, bp * 8);
5635}
5636
5637static void gen_ext(DisasContext *ctx, int wordsz, int rd, int rs, int rt,
5638                    int shift)
5639{
5640    gen_align_bits(ctx, wordsz, rd, rs, rt, wordsz - shift);
5641}
5642
5643static void gen_bitswap(DisasContext *ctx, int opc, int rd, int rt)
5644{
5645    TCGv t0;
5646    if (rd == 0) {
5647        /* Treat as NOP. */
5648        return;
5649    }
5650    t0 = tcg_temp_new();
5651    gen_load_gpr(t0, rt);
5652    switch (opc) {
5653    case OPC_BITSWAP:
5654        gen_helper_bitswap(cpu_gpr[rd], t0);
5655        break;
5656#if defined(TARGET_MIPS64)
5657    case OPC_DBITSWAP:
5658        gen_helper_dbitswap(cpu_gpr[rd], t0);
5659        break;
5660#endif
5661    }
5662    tcg_temp_free(t0);
5663}
5664
5665#ifndef CONFIG_USER_ONLY
5666/* CP0 (MMU and control) */
5667static inline void gen_mthc0_entrylo(TCGv arg, target_ulong off)
5668{
5669    TCGv_i64 t0 = tcg_temp_new_i64();
5670    TCGv_i64 t1 = tcg_temp_new_i64();
5671
5672    tcg_gen_ext_tl_i64(t0, arg);
5673    tcg_gen_ld_i64(t1, cpu_env, off);
5674#if defined(TARGET_MIPS64)
5675    tcg_gen_deposit_i64(t1, t1, t0, 30, 32);
5676#else
5677    tcg_gen_concat32_i64(t1, t1, t0);
5678#endif
5679    tcg_gen_st_i64(t1, cpu_env, off);
5680    tcg_temp_free_i64(t1);
5681    tcg_temp_free_i64(t0);
5682}
5683
5684static inline void gen_mthc0_store64(TCGv arg, target_ulong off)
5685{
5686    TCGv_i64 t0 = tcg_temp_new_i64();
5687    TCGv_i64 t1 = tcg_temp_new_i64();
5688
5689    tcg_gen_ext_tl_i64(t0, arg);
5690    tcg_gen_ld_i64(t1, cpu_env, off);
5691    tcg_gen_concat32_i64(t1, t1, t0);
5692    tcg_gen_st_i64(t1, cpu_env, off);
5693    tcg_temp_free_i64(t1);
5694    tcg_temp_free_i64(t0);
5695}
5696
5697static inline void gen_mfhc0_entrylo(TCGv arg, target_ulong off)
5698{
5699    TCGv_i64 t0 = tcg_temp_new_i64();
5700
5701    tcg_gen_ld_i64(t0, cpu_env, off);
5702#if defined(TARGET_MIPS64)
5703    tcg_gen_shri_i64(t0, t0, 30);
5704#else
5705    tcg_gen_shri_i64(t0, t0, 32);
5706#endif
5707    gen_move_low32(arg, t0);
5708    tcg_temp_free_i64(t0);
5709}
5710
5711static inline void gen_mfhc0_load64(TCGv arg, target_ulong off, int shift)
5712{
5713    TCGv_i64 t0 = tcg_temp_new_i64();
5714
5715    tcg_gen_ld_i64(t0, cpu_env, off);
5716    tcg_gen_shri_i64(t0, t0, 32 + shift);
5717    gen_move_low32(arg, t0);
5718    tcg_temp_free_i64(t0);
5719}
5720
5721static inline void gen_mfc0_load32(TCGv arg, target_ulong off)
5722{
5723    TCGv_i32 t0 = tcg_temp_new_i32();
5724
5725    tcg_gen_ld_i32(t0, cpu_env, off);
5726    tcg_gen_ext_i32_tl(arg, t0);
5727    tcg_temp_free_i32(t0);
5728}
5729
5730static inline void gen_mfc0_load64(TCGv arg, target_ulong off)
5731{
5732    tcg_gen_ld_tl(arg, cpu_env, off);
5733    tcg_gen_ext32s_tl(arg, arg);
5734}
5735
5736static inline void gen_mtc0_store32(TCGv arg, target_ulong off)
5737{
5738    TCGv_i32 t0 = tcg_temp_new_i32();
5739
5740    tcg_gen_trunc_tl_i32(t0, arg);
5741    tcg_gen_st_i32(t0, cpu_env, off);
5742    tcg_temp_free_i32(t0);
5743}
5744
5745#define CP0_CHECK(c)                            \
5746    do {                                        \
5747        if (!(c)) {                             \
5748            goto cp0_unimplemented;             \
5749        }                                       \
5750    } while (0)
5751
5752static void gen_mfhc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5753{
5754    const char *register_name = "invalid";
5755
5756    switch (reg) {
5757    case CP0_REGISTER_02:
5758        switch (sel) {
5759        case 0:
5760            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5761            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5762            register_name = "EntryLo0";
5763            break;
5764        default:
5765            goto cp0_unimplemented;
5766        }
5767        break;
5768    case CP0_REGISTER_03:
5769        switch (sel) {
5770        case CP0_REG03__ENTRYLO1:
5771            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5772            gen_mfhc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5773            register_name = "EntryLo1";
5774            break;
5775        default:
5776            goto cp0_unimplemented;
5777        }
5778        break;
5779    case CP0_REGISTER_09:
5780        switch (sel) {
5781        case CP0_REG09__SAAR:
5782            CP0_CHECK(ctx->saar);
5783            gen_helper_mfhc0_saar(arg, cpu_env);
5784            register_name = "SAAR";
5785            break;
5786        default:
5787            goto cp0_unimplemented;
5788        }
5789        break;
5790    case CP0_REGISTER_17:
5791        switch (sel) {
5792        case CP0_REG17__LLADDR:
5793            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_LLAddr),
5794                             ctx->CP0_LLAddr_shift);
5795            register_name = "LLAddr";
5796            break;
5797        case CP0_REG17__MAAR:
5798            CP0_CHECK(ctx->mrp);
5799            gen_helper_mfhc0_maar(arg, cpu_env);
5800            register_name = "MAAR";
5801            break;
5802        default:
5803            goto cp0_unimplemented;
5804        }
5805        break;
5806    case CP0_REGISTER_19:
5807        switch (sel) {
5808        case CP0_REG19__WATCHHI0:
5809        case CP0_REG19__WATCHHI1:
5810        case CP0_REG19__WATCHHI2:
5811        case CP0_REG19__WATCHHI3:
5812        case CP0_REG19__WATCHHI4:
5813        case CP0_REG19__WATCHHI5:
5814        case CP0_REG19__WATCHHI6:
5815        case CP0_REG19__WATCHHI7:
5816            /* upper 32 bits are only available when Config5MI != 0 */
5817            CP0_CHECK(ctx->mi);
5818            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_WatchHi[sel]), 0);
5819            register_name = "WatchHi";
5820            break;
5821        default:
5822            goto cp0_unimplemented;
5823        }
5824        break;
5825    case CP0_REGISTER_28:
5826        switch (sel) {
5827        case 0:
5828        case 2:
5829        case 4:
5830        case 6:
5831            gen_mfhc0_load64(arg, offsetof(CPUMIPSState, CP0_TagLo), 0);
5832            register_name = "TagLo";
5833            break;
5834        default:
5835            goto cp0_unimplemented;
5836        }
5837        break;
5838    default:
5839        goto cp0_unimplemented;
5840    }
5841    trace_mips_translate_c0("mfhc0", register_name, reg, sel);
5842    return;
5843
5844cp0_unimplemented:
5845    qemu_log_mask(LOG_UNIMP, "mfhc0 %s (reg %d sel %d)\n",
5846                  register_name, reg, sel);
5847    tcg_gen_movi_tl(arg, 0);
5848}
5849
5850static void gen_mthc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5851{
5852    const char *register_name = "invalid";
5853    uint64_t mask = ctx->PAMask >> 36;
5854
5855    switch (reg) {
5856    case CP0_REGISTER_02:
5857        switch (sel) {
5858        case 0:
5859            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5860            tcg_gen_andi_tl(arg, arg, mask);
5861            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo0));
5862            register_name = "EntryLo0";
5863            break;
5864        default:
5865            goto cp0_unimplemented;
5866        }
5867        break;
5868    case CP0_REGISTER_03:
5869        switch (sel) {
5870        case CP0_REG03__ENTRYLO1:
5871            CP0_CHECK(ctx->hflags & MIPS_HFLAG_ELPA);
5872            tcg_gen_andi_tl(arg, arg, mask);
5873            gen_mthc0_entrylo(arg, offsetof(CPUMIPSState, CP0_EntryLo1));
5874            register_name = "EntryLo1";
5875            break;
5876        default:
5877            goto cp0_unimplemented;
5878        }
5879        break;
5880    case CP0_REGISTER_09:
5881        switch (sel) {
5882        case CP0_REG09__SAAR:
5883            CP0_CHECK(ctx->saar);
5884            gen_helper_mthc0_saar(cpu_env, arg);
5885            register_name = "SAAR";
5886            break;
5887        default:
5888            goto cp0_unimplemented;
5889        }
5890        break;
5891    case CP0_REGISTER_17:
5892        switch (sel) {
5893        case CP0_REG17__LLADDR:
5894            /*
5895             * LLAddr is read-only (the only exception is bit 0 if LLB is
5896             * supported); the CP0_LLAddr_rw_bitmask does not seem to be
5897             * relevant for modern MIPS cores supporting MTHC0, therefore
5898             * treating MTHC0 to LLAddr as NOP.
5899             */
5900            register_name = "LLAddr";
5901            break;
5902        case CP0_REG17__MAAR:
5903            CP0_CHECK(ctx->mrp);
5904            gen_helper_mthc0_maar(cpu_env, arg);
5905            register_name = "MAAR";
5906            break;
5907        default:
5908            goto cp0_unimplemented;
5909        }
5910        break;
5911    case CP0_REGISTER_19:
5912        switch (sel) {
5913        case CP0_REG19__WATCHHI0:
5914        case CP0_REG19__WATCHHI1:
5915        case CP0_REG19__WATCHHI2:
5916        case CP0_REG19__WATCHHI3:
5917        case CP0_REG19__WATCHHI4:
5918        case CP0_REG19__WATCHHI5:
5919        case CP0_REG19__WATCHHI6:
5920        case CP0_REG19__WATCHHI7:
5921            /* upper 32 bits are only available when Config5MI != 0 */
5922            CP0_CHECK(ctx->mi);
5923            gen_helper_0e1i(mthc0_watchhi, arg, sel);
5924            register_name = "WatchHi";
5925            break;
5926        default:
5927            goto cp0_unimplemented;
5928        }
5929        break;
5930    case CP0_REGISTER_28:
5931        switch (sel) {
5932        case 0:
5933        case 2:
5934        case 4:
5935        case 6:
5936            tcg_gen_andi_tl(arg, arg, mask);
5937            gen_mthc0_store64(arg, offsetof(CPUMIPSState, CP0_TagLo));
5938            register_name = "TagLo";
5939            break;
5940        default:
5941            goto cp0_unimplemented;
5942        }
5943        break;
5944    default:
5945        goto cp0_unimplemented;
5946    }
5947    trace_mips_translate_c0("mthc0", register_name, reg, sel);
5948
5949cp0_unimplemented:
5950    qemu_log_mask(LOG_UNIMP, "mthc0 %s (reg %d sel %d)\n",
5951                  register_name, reg, sel);
5952}
5953
5954static inline void gen_mfc0_unimplemented(DisasContext *ctx, TCGv arg)
5955{
5956    if (ctx->insn_flags & ISA_MIPS_R6) {
5957        tcg_gen_movi_tl(arg, 0);
5958    } else {
5959        tcg_gen_movi_tl(arg, ~0);
5960    }
5961}
5962
5963static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5964{
5965    const char *register_name = "invalid";
5966
5967    if (sel != 0) {
5968        check_insn(ctx, ISA_MIPS_R1);
5969    }
5970
5971    switch (reg) {
5972    case CP0_REGISTER_00:
5973        switch (sel) {
5974        case CP0_REG00__INDEX:
5975            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5976            register_name = "Index";
5977            break;
5978        case CP0_REG00__MVPCONTROL:
5979            CP0_CHECK(ctx->insn_flags & ASE_MT);
5980            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5981            register_name = "MVPControl";
5982            break;
5983        case CP0_REG00__MVPCONF0:
5984            CP0_CHECK(ctx->insn_flags & ASE_MT);
5985            gen_helper_mfc0_mvpconf0(arg, cpu_env);
5986            register_name = "MVPConf0";
5987            break;
5988        case CP0_REG00__MVPCONF1:
5989            CP0_CHECK(ctx->insn_flags & ASE_MT);
5990            gen_helper_mfc0_mvpconf1(arg, cpu_env);
5991            register_name = "MVPConf1";
5992            break;
5993        case CP0_REG00__VPCONTROL:
5994            CP0_CHECK(ctx->vp);
5995            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
5996            register_name = "VPControl";
5997            break;
5998        default:
5999            goto cp0_unimplemented;
6000        }
6001        break;
6002    case CP0_REGISTER_01:
6003        switch (sel) {
6004        case CP0_REG01__RANDOM:
6005            CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
6006            gen_helper_mfc0_random(arg, cpu_env);
6007            register_name = "Random";
6008            break;
6009        case CP0_REG01__VPECONTROL:
6010            CP0_CHECK(ctx->insn_flags & ASE_MT);
6011            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
6012            register_name = "VPEControl";
6013            break;
6014        case CP0_REG01__VPECONF0:
6015            CP0_CHECK(ctx->insn_flags & ASE_MT);
6016            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
6017            register_name = "VPEConf0";
6018            break;
6019        case CP0_REG01__VPECONF1:
6020            CP0_CHECK(ctx->insn_flags & ASE_MT);
6021            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
6022            register_name = "VPEConf1";
6023            break;
6024        case CP0_REG01__YQMASK:
6025            CP0_CHECK(ctx->insn_flags & ASE_MT);
6026            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
6027            register_name = "YQMask";
6028            break;
6029        case CP0_REG01__VPESCHEDULE:
6030            CP0_CHECK(ctx->insn_flags & ASE_MT);
6031            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
6032            register_name = "VPESchedule";
6033            break;
6034        case CP0_REG01__VPESCHEFBACK:
6035            CP0_CHECK(ctx->insn_flags & ASE_MT);
6036            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
6037            register_name = "VPEScheFBack";
6038            break;
6039        case CP0_REG01__VPEOPT:
6040            CP0_CHECK(ctx->insn_flags & ASE_MT);
6041            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
6042            register_name = "VPEOpt";
6043            break;
6044        default:
6045            goto cp0_unimplemented;
6046        }
6047        break;
6048    case CP0_REGISTER_02:
6049        switch (sel) {
6050        case CP0_REG02__ENTRYLO0:
6051            {
6052                TCGv_i64 tmp = tcg_temp_new_i64();
6053                tcg_gen_ld_i64(tmp, cpu_env,
6054                               offsetof(CPUMIPSState, CP0_EntryLo0));
6055#if defined(TARGET_MIPS64)
6056                if (ctx->rxi) {
6057                    /* Move RI/XI fields to bits 31:30 */
6058                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6059                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6060                }
6061#endif
6062                gen_move_low32(arg, tmp);
6063                tcg_temp_free_i64(tmp);
6064            }
6065            register_name = "EntryLo0";
6066            break;
6067        case CP0_REG02__TCSTATUS:
6068            CP0_CHECK(ctx->insn_flags & ASE_MT);
6069            gen_helper_mfc0_tcstatus(arg, cpu_env);
6070            register_name = "TCStatus";
6071            break;
6072        case CP0_REG02__TCBIND:
6073            CP0_CHECK(ctx->insn_flags & ASE_MT);
6074            gen_helper_mfc0_tcbind(arg, cpu_env);
6075            register_name = "TCBind";
6076            break;
6077        case CP0_REG02__TCRESTART:
6078            CP0_CHECK(ctx->insn_flags & ASE_MT);
6079            gen_helper_mfc0_tcrestart(arg, cpu_env);
6080            register_name = "TCRestart";
6081            break;
6082        case CP0_REG02__TCHALT:
6083            CP0_CHECK(ctx->insn_flags & ASE_MT);
6084            gen_helper_mfc0_tchalt(arg, cpu_env);
6085            register_name = "TCHalt";
6086            break;
6087        case CP0_REG02__TCCONTEXT:
6088            CP0_CHECK(ctx->insn_flags & ASE_MT);
6089            gen_helper_mfc0_tccontext(arg, cpu_env);
6090            register_name = "TCContext";
6091            break;
6092        case CP0_REG02__TCSCHEDULE:
6093            CP0_CHECK(ctx->insn_flags & ASE_MT);
6094            gen_helper_mfc0_tcschedule(arg, cpu_env);
6095            register_name = "TCSchedule";
6096            break;
6097        case CP0_REG02__TCSCHEFBACK:
6098            CP0_CHECK(ctx->insn_flags & ASE_MT);
6099            gen_helper_mfc0_tcschefback(arg, cpu_env);
6100            register_name = "TCScheFBack";
6101            break;
6102        default:
6103            goto cp0_unimplemented;
6104        }
6105        break;
6106    case CP0_REGISTER_03:
6107        switch (sel) {
6108        case CP0_REG03__ENTRYLO1:
6109            {
6110                TCGv_i64 tmp = tcg_temp_new_i64();
6111                tcg_gen_ld_i64(tmp, cpu_env,
6112                               offsetof(CPUMIPSState, CP0_EntryLo1));
6113#if defined(TARGET_MIPS64)
6114                if (ctx->rxi) {
6115                    /* Move RI/XI fields to bits 31:30 */
6116                    tcg_gen_shri_tl(arg, tmp, CP0EnLo_XI);
6117                    tcg_gen_deposit_tl(tmp, tmp, arg, 30, 2);
6118                }
6119#endif
6120                gen_move_low32(arg, tmp);
6121                tcg_temp_free_i64(tmp);
6122            }
6123            register_name = "EntryLo1";
6124            break;
6125        case CP0_REG03__GLOBALNUM:
6126            CP0_CHECK(ctx->vp);
6127            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
6128            register_name = "GlobalNumber";
6129            break;
6130        default:
6131            goto cp0_unimplemented;
6132        }
6133        break;
6134    case CP0_REGISTER_04:
6135        switch (sel) {
6136        case CP0_REG04__CONTEXT:
6137            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
6138            tcg_gen_ext32s_tl(arg, arg);
6139            register_name = "Context";
6140            break;
6141        case CP0_REG04__CONTEXTCONFIG:
6142            /* SmartMIPS ASE */
6143            /* gen_helper_mfc0_contextconfig(arg); */
6144            register_name = "ContextConfig";
6145            goto cp0_unimplemented;
6146        case CP0_REG04__USERLOCAL:
6147            CP0_CHECK(ctx->ulri);
6148            tcg_gen_ld_tl(arg, cpu_env,
6149                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6150            tcg_gen_ext32s_tl(arg, arg);
6151            register_name = "UserLocal";
6152            break;
6153        case CP0_REG04__MMID:
6154            CP0_CHECK(ctx->mi);
6155            gen_helper_mtc0_memorymapid(cpu_env, arg);
6156            register_name = "MMID";
6157            break;
6158        default:
6159            goto cp0_unimplemented;
6160        }
6161        break;
6162    case CP0_REGISTER_05:
6163        switch (sel) {
6164        case CP0_REG05__PAGEMASK:
6165            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
6166            register_name = "PageMask";
6167            break;
6168        case CP0_REG05__PAGEGRAIN:
6169            check_insn(ctx, ISA_MIPS_R2);
6170            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
6171            register_name = "PageGrain";
6172            break;
6173        case CP0_REG05__SEGCTL0:
6174            CP0_CHECK(ctx->sc);
6175            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
6176            tcg_gen_ext32s_tl(arg, arg);
6177            register_name = "SegCtl0";
6178            break;
6179        case CP0_REG05__SEGCTL1:
6180            CP0_CHECK(ctx->sc);
6181            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
6182            tcg_gen_ext32s_tl(arg, arg);
6183            register_name = "SegCtl1";
6184            break;
6185        case CP0_REG05__SEGCTL2:
6186            CP0_CHECK(ctx->sc);
6187            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
6188            tcg_gen_ext32s_tl(arg, arg);
6189            register_name = "SegCtl2";
6190            break;
6191        case CP0_REG05__PWBASE:
6192            check_pw(ctx);
6193            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6194            register_name = "PWBase";
6195            break;
6196        case CP0_REG05__PWFIELD:
6197            check_pw(ctx);
6198            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWField));
6199            register_name = "PWField";
6200            break;
6201        case CP0_REG05__PWSIZE:
6202            check_pw(ctx);
6203            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWSize));
6204            register_name = "PWSize";
6205            break;
6206        default:
6207            goto cp0_unimplemented;
6208        }
6209        break;
6210    case CP0_REGISTER_06:
6211        switch (sel) {
6212        case CP0_REG06__WIRED:
6213            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
6214            register_name = "Wired";
6215            break;
6216        case CP0_REG06__SRSCONF0:
6217            check_insn(ctx, ISA_MIPS_R2);
6218            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
6219            register_name = "SRSConf0";
6220            break;
6221        case CP0_REG06__SRSCONF1:
6222            check_insn(ctx, ISA_MIPS_R2);
6223            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
6224            register_name = "SRSConf1";
6225            break;
6226        case CP0_REG06__SRSCONF2:
6227            check_insn(ctx, ISA_MIPS_R2);
6228            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
6229            register_name = "SRSConf2";
6230            break;
6231        case CP0_REG06__SRSCONF3:
6232            check_insn(ctx, ISA_MIPS_R2);
6233            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
6234            register_name = "SRSConf3";
6235            break;
6236        case CP0_REG06__SRSCONF4:
6237            check_insn(ctx, ISA_MIPS_R2);
6238            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
6239            register_name = "SRSConf4";
6240            break;
6241        case CP0_REG06__PWCTL:
6242            check_pw(ctx);
6243            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
6244            register_name = "PWCtl";
6245            break;
6246        default:
6247            goto cp0_unimplemented;
6248        }
6249        break;
6250    case CP0_REGISTER_07:
6251        switch (sel) {
6252        case CP0_REG07__HWRENA:
6253            check_insn(ctx, ISA_MIPS_R2);
6254            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
6255            register_name = "HWREna";
6256            break;
6257        default:
6258            goto cp0_unimplemented;
6259        }
6260        break;
6261    case CP0_REGISTER_08:
6262        switch (sel) {
6263        case CP0_REG08__BADVADDR:
6264            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
6265            tcg_gen_ext32s_tl(arg, arg);
6266            register_name = "BadVAddr";
6267            break;
6268        case CP0_REG08__BADINSTR:
6269            CP0_CHECK(ctx->bi);
6270            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
6271            register_name = "BadInstr";
6272            break;
6273        case CP0_REG08__BADINSTRP:
6274            CP0_CHECK(ctx->bp);
6275            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
6276            register_name = "BadInstrP";
6277            break;
6278        case CP0_REG08__BADINSTRX:
6279            CP0_CHECK(ctx->bi);
6280            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
6281            tcg_gen_andi_tl(arg, arg, ~0xffff);
6282            register_name = "BadInstrX";
6283            break;
6284        default:
6285            goto cp0_unimplemented;
6286        }
6287        break;
6288    case CP0_REGISTER_09:
6289        switch (sel) {
6290        case CP0_REG09__COUNT:
6291            /* Mark as an IO operation because we read the time.  */
6292            if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6293                gen_io_start();
6294            }
6295            gen_helper_mfc0_count(arg, cpu_env);
6296            /*
6297             * Break the TB to be able to take timer interrupts immediately
6298             * after reading count. DISAS_STOP isn't sufficient, we need to
6299             * ensure we break completely out of translated code.
6300             */
6301            gen_save_pc(ctx->base.pc_next + 4);
6302            ctx->base.is_jmp = DISAS_EXIT;
6303            register_name = "Count";
6304            break;
6305        case CP0_REG09__SAARI:
6306            CP0_CHECK(ctx->saar);
6307            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
6308            register_name = "SAARI";
6309            break;
6310        case CP0_REG09__SAAR:
6311            CP0_CHECK(ctx->saar);
6312            gen_helper_mfc0_saar(arg, cpu_env);
6313            register_name = "SAAR";
6314            break;
6315        default:
6316            goto cp0_unimplemented;
6317        }
6318        break;
6319    case CP0_REGISTER_10:
6320        switch (sel) {
6321        case CP0_REG10__ENTRYHI:
6322            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
6323            tcg_gen_ext32s_tl(arg, arg);
6324            register_name = "EntryHi";
6325            break;
6326        default:
6327            goto cp0_unimplemented;
6328        }
6329        break;
6330    case CP0_REGISTER_11:
6331        switch (sel) {
6332        case CP0_REG11__COMPARE:
6333            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
6334            register_name = "Compare";
6335            break;
6336        /* 6,7 are implementation dependent */
6337        default:
6338            goto cp0_unimplemented;
6339        }
6340        break;
6341    case CP0_REGISTER_12:
6342        switch (sel) {
6343        case CP0_REG12__STATUS:
6344            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
6345            register_name = "Status";
6346            break;
6347        case CP0_REG12__INTCTL:
6348            check_insn(ctx, ISA_MIPS_R2);
6349            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
6350            register_name = "IntCtl";
6351            break;
6352        case CP0_REG12__SRSCTL:
6353            check_insn(ctx, ISA_MIPS_R2);
6354            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
6355            register_name = "SRSCtl";
6356            break;
6357        case CP0_REG12__SRSMAP:
6358            check_insn(ctx, ISA_MIPS_R2);
6359            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6360            register_name = "SRSMap";
6361            break;
6362        default:
6363            goto cp0_unimplemented;
6364       }
6365        break;
6366    case CP0_REGISTER_13:
6367        switch (sel) {
6368        case CP0_REG13__CAUSE:
6369            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
6370            register_name = "Cause";
6371            break;
6372        default:
6373            goto cp0_unimplemented;
6374       }
6375        break;
6376    case CP0_REGISTER_14:
6377        switch (sel) {
6378        case CP0_REG14__EPC:
6379            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6380            tcg_gen_ext32s_tl(arg, arg);
6381            register_name = "EPC";
6382            break;
6383        default:
6384            goto cp0_unimplemented;
6385        }
6386        break;
6387    case CP0_REGISTER_15:
6388        switch (sel) {
6389        case CP0_REG15__PRID:
6390            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
6391            register_name = "PRid";
6392            break;
6393        case CP0_REG15__EBASE:
6394            check_insn(ctx, ISA_MIPS_R2);
6395            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
6396            tcg_gen_ext32s_tl(arg, arg);
6397            register_name = "EBase";
6398            break;
6399        case CP0_REG15__CMGCRBASE:
6400            check_insn(ctx, ISA_MIPS_R2);
6401            CP0_CHECK(ctx->cmgcr);
6402            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
6403            tcg_gen_ext32s_tl(arg, arg);
6404            register_name = "CMGCRBase";
6405            break;
6406        default:
6407            goto cp0_unimplemented;
6408       }
6409        break;
6410    case CP0_REGISTER_16:
6411        switch (sel) {
6412        case CP0_REG16__CONFIG:
6413            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
6414            register_name = "Config";
6415            break;
6416        case CP0_REG16__CONFIG1:
6417            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
6418            register_name = "Config1";
6419            break;
6420        case CP0_REG16__CONFIG2:
6421            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
6422            register_name = "Config2";
6423            break;
6424        case CP0_REG16__CONFIG3:
6425            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
6426            register_name = "Config3";
6427            break;
6428        case CP0_REG16__CONFIG4:
6429            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
6430            register_name = "Config4";
6431            break;
6432        case CP0_REG16__CONFIG5:
6433            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
6434            register_name = "Config5";
6435            break;
6436        /* 6,7 are implementation dependent */
6437        case CP0_REG16__CONFIG6:
6438            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
6439            register_name = "Config6";
6440            break;
6441        case CP0_REG16__CONFIG7:
6442            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
6443            register_name = "Config7";
6444            break;
6445        default:
6446            goto cp0_unimplemented;
6447        }
6448        break;
6449    case CP0_REGISTER_17:
6450        switch (sel) {
6451        case CP0_REG17__LLADDR:
6452            gen_helper_mfc0_lladdr(arg, cpu_env);
6453            register_name = "LLAddr";
6454            break;
6455        case CP0_REG17__MAAR:
6456            CP0_CHECK(ctx->mrp);
6457            gen_helper_mfc0_maar(arg, cpu_env);
6458            register_name = "MAAR";
6459            break;
6460        case CP0_REG17__MAARI:
6461            CP0_CHECK(ctx->mrp);
6462            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
6463            register_name = "MAARI";
6464            break;
6465        default:
6466            goto cp0_unimplemented;
6467        }
6468        break;
6469    case CP0_REGISTER_18:
6470        switch (sel) {
6471        case CP0_REG18__WATCHLO0:
6472        case CP0_REG18__WATCHLO1:
6473        case CP0_REG18__WATCHLO2:
6474        case CP0_REG18__WATCHLO3:
6475        case CP0_REG18__WATCHLO4:
6476        case CP0_REG18__WATCHLO5:
6477        case CP0_REG18__WATCHLO6:
6478        case CP0_REG18__WATCHLO7:
6479            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6480            gen_helper_1e0i(mfc0_watchlo, arg, sel);
6481            register_name = "WatchLo";
6482            break;
6483        default:
6484            goto cp0_unimplemented;
6485        }
6486        break;
6487    case CP0_REGISTER_19:
6488        switch (sel) {
6489        case CP0_REG19__WATCHHI0:
6490        case CP0_REG19__WATCHHI1:
6491        case CP0_REG19__WATCHHI2:
6492        case CP0_REG19__WATCHHI3:
6493        case CP0_REG19__WATCHHI4:
6494        case CP0_REG19__WATCHHI5:
6495        case CP0_REG19__WATCHHI6:
6496        case CP0_REG19__WATCHHI7:
6497            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
6498            gen_helper_1e0i(mfc0_watchhi, arg, sel);
6499            register_name = "WatchHi";
6500            break;
6501        default:
6502            goto cp0_unimplemented;
6503        }
6504        break;
6505    case CP0_REGISTER_20:
6506        switch (sel) {
6507        case CP0_REG20__XCONTEXT:
6508#if defined(TARGET_MIPS64)
6509            check_insn(ctx, ISA_MIPS3);
6510            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
6511            tcg_gen_ext32s_tl(arg, arg);
6512            register_name = "XContext";
6513            break;
6514#endif
6515        default:
6516            goto cp0_unimplemented;
6517        }
6518        break;
6519    case CP0_REGISTER_21:
6520       /* Officially reserved, but sel 0 is used for R1x000 framemask */
6521        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
6522        switch (sel) {
6523        case 0:
6524            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
6525            register_name = "Framemask";
6526            break;
6527        default:
6528            goto cp0_unimplemented;
6529        }
6530        break;
6531    case CP0_REGISTER_22:
6532        tcg_gen_movi_tl(arg, 0); /* unimplemented */
6533        register_name = "'Diagnostic"; /* implementation dependent */
6534        break;
6535    case CP0_REGISTER_23:
6536        switch (sel) {
6537        case CP0_REG23__DEBUG:
6538            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
6539            register_name = "Debug";
6540            break;
6541        case CP0_REG23__TRACECONTROL:
6542            /* PDtrace support */
6543            /* gen_helper_mfc0_tracecontrol(arg);  */
6544            register_name = "TraceControl";
6545            goto cp0_unimplemented;
6546        case CP0_REG23__TRACECONTROL2:
6547            /* PDtrace support */
6548            /* gen_helper_mfc0_tracecontrol2(arg); */
6549            register_name = "TraceControl2";
6550            goto cp0_unimplemented;
6551        case CP0_REG23__USERTRACEDATA1:
6552            /* PDtrace support */
6553            /* gen_helper_mfc0_usertracedata1(arg);*/
6554            register_name = "UserTraceData1";
6555            goto cp0_unimplemented;
6556        case CP0_REG23__TRACEIBPC:
6557            /* PDtrace support */
6558            /* gen_helper_mfc0_traceibpc(arg);     */
6559            register_name = "TraceIBPC";
6560            goto cp0_unimplemented;
6561        case CP0_REG23__TRACEDBPC:
6562            /* PDtrace support */
6563            /* gen_helper_mfc0_tracedbpc(arg);     */
6564            register_name = "TraceDBPC";
6565            goto cp0_unimplemented;
6566        default:
6567            goto cp0_unimplemented;
6568        }
6569        break;
6570    case CP0_REGISTER_24:
6571        switch (sel) {
6572        case CP0_REG24__DEPC:
6573            /* EJTAG support */
6574            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6575            tcg_gen_ext32s_tl(arg, arg);
6576            register_name = "DEPC";
6577            break;
6578        default:
6579            goto cp0_unimplemented;
6580        }
6581        break;
6582    case CP0_REGISTER_25:
6583        switch (sel) {
6584        case CP0_REG25__PERFCTL0:
6585            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
6586            register_name = "Performance0";
6587            break;
6588        case CP0_REG25__PERFCNT0:
6589            /* gen_helper_mfc0_performance1(arg); */
6590            register_name = "Performance1";
6591            goto cp0_unimplemented;
6592        case CP0_REG25__PERFCTL1:
6593            /* gen_helper_mfc0_performance2(arg); */
6594            register_name = "Performance2";
6595            goto cp0_unimplemented;
6596        case CP0_REG25__PERFCNT1:
6597            /* gen_helper_mfc0_performance3(arg); */
6598            register_name = "Performance3";
6599            goto cp0_unimplemented;
6600        case CP0_REG25__PERFCTL2:
6601            /* gen_helper_mfc0_performance4(arg); */
6602            register_name = "Performance4";
6603            goto cp0_unimplemented;
6604        case CP0_REG25__PERFCNT2:
6605            /* gen_helper_mfc0_performance5(arg); */
6606            register_name = "Performance5";
6607            goto cp0_unimplemented;
6608        case CP0_REG25__PERFCTL3:
6609            /* gen_helper_mfc0_performance6(arg); */
6610            register_name = "Performance6";
6611            goto cp0_unimplemented;
6612        case CP0_REG25__PERFCNT3:
6613            /* gen_helper_mfc0_performance7(arg); */
6614            register_name = "Performance7";
6615            goto cp0_unimplemented;
6616        default:
6617            goto cp0_unimplemented;
6618        }
6619        break;
6620    case CP0_REGISTER_26:
6621        switch (sel) {
6622        case CP0_REG26__ERRCTL:
6623            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
6624            register_name = "ErrCtl";
6625            break;
6626        default:
6627            goto cp0_unimplemented;
6628        }
6629        break;
6630    case CP0_REGISTER_27:
6631        switch (sel) {
6632        case CP0_REG27__CACHERR:
6633            tcg_gen_movi_tl(arg, 0); /* unimplemented */
6634            register_name = "CacheErr";
6635            break;
6636        default:
6637            goto cp0_unimplemented;
6638        }
6639        break;
6640    case CP0_REGISTER_28:
6641        switch (sel) {
6642        case CP0_REG28__TAGLO:
6643        case CP0_REG28__TAGLO1:
6644        case CP0_REG28__TAGLO2:
6645        case CP0_REG28__TAGLO3:
6646            {
6647                TCGv_i64 tmp = tcg_temp_new_i64();
6648                tcg_gen_ld_i64(tmp, cpu_env, offsetof(CPUMIPSState, CP0_TagLo));
6649                gen_move_low32(arg, tmp);
6650                tcg_temp_free_i64(tmp);
6651            }
6652            register_name = "TagLo";
6653            break;
6654        case CP0_REG28__DATALO:
6655        case CP0_REG28__DATALO1:
6656        case CP0_REG28__DATALO2:
6657        case CP0_REG28__DATALO3:
6658            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
6659            register_name = "DataLo";
6660            break;
6661        default:
6662            goto cp0_unimplemented;
6663        }
6664        break;
6665    case CP0_REGISTER_29:
6666        switch (sel) {
6667        case CP0_REG29__TAGHI:
6668        case CP0_REG29__TAGHI1:
6669        case CP0_REG29__TAGHI2:
6670        case CP0_REG29__TAGHI3:
6671            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
6672            register_name = "TagHi";
6673            break;
6674        case CP0_REG29__DATAHI:
6675        case CP0_REG29__DATAHI1:
6676        case CP0_REG29__DATAHI2:
6677        case CP0_REG29__DATAHI3:
6678            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
6679            register_name = "DataHi";
6680            break;
6681        default:
6682            goto cp0_unimplemented;
6683        }
6684        break;
6685    case CP0_REGISTER_30:
6686        switch (sel) {
6687        case CP0_REG30__ERROREPC:
6688            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6689            tcg_gen_ext32s_tl(arg, arg);
6690            register_name = "ErrorEPC";
6691            break;
6692        default:
6693            goto cp0_unimplemented;
6694        }
6695        break;
6696    case CP0_REGISTER_31:
6697        switch (sel) {
6698        case CP0_REG31__DESAVE:
6699            /* EJTAG support */
6700            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6701            register_name = "DESAVE";
6702            break;
6703        case CP0_REG31__KSCRATCH1:
6704        case CP0_REG31__KSCRATCH2:
6705        case CP0_REG31__KSCRATCH3:
6706        case CP0_REG31__KSCRATCH4:
6707        case CP0_REG31__KSCRATCH5:
6708        case CP0_REG31__KSCRATCH6:
6709            CP0_CHECK(ctx->kscrexist & (1 << sel));
6710            tcg_gen_ld_tl(arg, cpu_env,
6711                          offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
6712            tcg_gen_ext32s_tl(arg, arg);
6713            register_name = "KScratch";
6714            break;
6715        default:
6716            goto cp0_unimplemented;
6717        }
6718        break;
6719    default:
6720       goto cp0_unimplemented;
6721    }
6722    trace_mips_translate_c0("mfc0", register_name, reg, sel);
6723    return;
6724
6725cp0_unimplemented:
6726    qemu_log_mask(LOG_UNIMP, "mfc0 %s (reg %d sel %d)\n",
6727                  register_name, reg, sel);
6728    gen_mfc0_unimplemented(ctx, arg);
6729}
6730
6731static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
6732{
6733    const char *register_name = "invalid";
6734
6735    if (sel != 0) {
6736        check_insn(ctx, ISA_MIPS_R1);
6737    }
6738
6739    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
6740        gen_io_start();
6741    }
6742
6743    switch (reg) {
6744    case CP0_REGISTER_00:
6745        switch (sel) {
6746        case CP0_REG00__INDEX:
6747            gen_helper_mtc0_index(cpu_env, arg);
6748            register_name = "Index";
6749            break;
6750        case CP0_REG00__MVPCONTROL:
6751            CP0_CHECK(ctx->insn_flags & ASE_MT);
6752            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
6753            register_name = "MVPControl";
6754            break;
6755        case CP0_REG00__MVPCONF0:
6756            CP0_CHECK(ctx->insn_flags & ASE_MT);
6757            /* ignored */
6758            register_name = "MVPConf0";
6759            break;
6760        case CP0_REG00__MVPCONF1:
6761            CP0_CHECK(ctx->insn_flags & ASE_MT);
6762            /* ignored */
6763            register_name = "MVPConf1";
6764            break;
6765        case CP0_REG00__VPCONTROL:
6766            CP0_CHECK(ctx->vp);
6767            /* ignored */
6768            register_name = "VPControl";
6769            break;
6770        default:
6771            goto cp0_unimplemented;
6772        }
6773        break;
6774    case CP0_REGISTER_01:
6775        switch (sel) {
6776        case CP0_REG01__RANDOM:
6777            /* ignored */
6778            register_name = "Random";
6779            break;
6780        case CP0_REG01__VPECONTROL:
6781            CP0_CHECK(ctx->insn_flags & ASE_MT);
6782            gen_helper_mtc0_vpecontrol(cpu_env, arg);
6783            register_name = "VPEControl";
6784            break;
6785        case CP0_REG01__VPECONF0:
6786            CP0_CHECK(ctx->insn_flags & ASE_MT);
6787            gen_helper_mtc0_vpeconf0(cpu_env, arg);
6788            register_name = "VPEConf0";
6789            break;
6790        case CP0_REG01__VPECONF1:
6791            CP0_CHECK(ctx->insn_flags & ASE_MT);
6792            gen_helper_mtc0_vpeconf1(cpu_env, arg);
6793            register_name = "VPEConf1";
6794            break;
6795        case CP0_REG01__YQMASK:
6796            CP0_CHECK(ctx->insn_flags & ASE_MT);
6797            gen_helper_mtc0_yqmask(cpu_env, arg);
6798            register_name = "YQMask";
6799            break;
6800        case CP0_REG01__VPESCHEDULE:
6801            CP0_CHECK(ctx->insn_flags & ASE_MT);
6802            tcg_gen_st_tl(arg, cpu_env,
6803                          offsetof(CPUMIPSState, CP0_VPESchedule));
6804            register_name = "VPESchedule";
6805            break;
6806        case CP0_REG01__VPESCHEFBACK:
6807            CP0_CHECK(ctx->insn_flags & ASE_MT);
6808            tcg_gen_st_tl(arg, cpu_env,
6809                          offsetof(CPUMIPSState, CP0_VPEScheFBack));
6810            register_name = "VPEScheFBack";
6811            break;
6812        case CP0_REG01__VPEOPT:
6813            CP0_CHECK(ctx->insn_flags & ASE_MT);
6814            gen_helper_mtc0_vpeopt(cpu_env, arg);
6815            register_name = "VPEOpt";
6816            break;
6817        default:
6818            goto cp0_unimplemented;
6819        }
6820        break;
6821    case CP0_REGISTER_02:
6822        switch (sel) {
6823        case CP0_REG02__ENTRYLO0:
6824            gen_helper_mtc0_entrylo0(cpu_env, arg);
6825            register_name = "EntryLo0";
6826            break;
6827        case CP0_REG02__TCSTATUS:
6828            CP0_CHECK(ctx->insn_flags & ASE_MT);
6829            gen_helper_mtc0_tcstatus(cpu_env, arg);
6830            register_name = "TCStatus";
6831            break;
6832        case CP0_REG02__TCBIND:
6833            CP0_CHECK(ctx->insn_flags & ASE_MT);
6834            gen_helper_mtc0_tcbind(cpu_env, arg);
6835            register_name = "TCBind";
6836            break;
6837        case CP0_REG02__TCRESTART:
6838            CP0_CHECK(ctx->insn_flags & ASE_MT);
6839            gen_helper_mtc0_tcrestart(cpu_env, arg);
6840            register_name = "TCRestart";
6841            break;
6842        case CP0_REG02__TCHALT:
6843            CP0_CHECK(ctx->insn_flags & ASE_MT);
6844            gen_helper_mtc0_tchalt(cpu_env, arg);
6845            register_name = "TCHalt";
6846            break;
6847        case CP0_REG02__TCCONTEXT:
6848            CP0_CHECK(ctx->insn_flags & ASE_MT);
6849            gen_helper_mtc0_tccontext(cpu_env, arg);
6850            register_name = "TCContext";
6851            break;
6852        case CP0_REG02__TCSCHEDULE:
6853            CP0_CHECK(ctx->insn_flags & ASE_MT);
6854            gen_helper_mtc0_tcschedule(cpu_env, arg);
6855            register_name = "TCSchedule";
6856            break;
6857        case CP0_REG02__TCSCHEFBACK:
6858            CP0_CHECK(ctx->insn_flags & ASE_MT);
6859            gen_helper_mtc0_tcschefback(cpu_env, arg);
6860            register_name = "TCScheFBack";
6861            break;
6862        default:
6863            goto cp0_unimplemented;
6864        }
6865        break;
6866    case CP0_REGISTER_03:
6867        switch (sel) {
6868        case CP0_REG03__ENTRYLO1:
6869            gen_helper_mtc0_entrylo1(cpu_env, arg);
6870            register_name = "EntryLo1";
6871            break;
6872        case CP0_REG03__GLOBALNUM:
6873            CP0_CHECK(ctx->vp);
6874            /* ignored */
6875            register_name = "GlobalNumber";
6876            break;
6877        default:
6878            goto cp0_unimplemented;
6879        }
6880        break;
6881    case CP0_REGISTER_04:
6882        switch (sel) {
6883        case CP0_REG04__CONTEXT:
6884            gen_helper_mtc0_context(cpu_env, arg);
6885            register_name = "Context";
6886            break;
6887        case CP0_REG04__CONTEXTCONFIG:
6888            /* SmartMIPS ASE */
6889            /* gen_helper_mtc0_contextconfig(arg); */
6890            register_name = "ContextConfig";
6891            goto cp0_unimplemented;
6892        case CP0_REG04__USERLOCAL:
6893            CP0_CHECK(ctx->ulri);
6894            tcg_gen_st_tl(arg, cpu_env,
6895                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
6896            register_name = "UserLocal";
6897            break;
6898        case CP0_REG04__MMID:
6899            CP0_CHECK(ctx->mi);
6900            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
6901            register_name = "MMID";
6902            break;
6903        default:
6904            goto cp0_unimplemented;
6905        }
6906        break;
6907    case CP0_REGISTER_05:
6908        switch (sel) {
6909        case CP0_REG05__PAGEMASK:
6910            gen_helper_mtc0_pagemask(cpu_env, arg);
6911            register_name = "PageMask";
6912            break;
6913        case CP0_REG05__PAGEGRAIN:
6914            check_insn(ctx, ISA_MIPS_R2);
6915            gen_helper_mtc0_pagegrain(cpu_env, arg);
6916            register_name = "PageGrain";
6917            ctx->base.is_jmp = DISAS_STOP;
6918            break;
6919        case CP0_REG05__SEGCTL0:
6920            CP0_CHECK(ctx->sc);
6921            gen_helper_mtc0_segctl0(cpu_env, arg);
6922            register_name = "SegCtl0";
6923            break;
6924        case CP0_REG05__SEGCTL1:
6925            CP0_CHECK(ctx->sc);
6926            gen_helper_mtc0_segctl1(cpu_env, arg);
6927            register_name = "SegCtl1";
6928            break;
6929        case CP0_REG05__SEGCTL2:
6930            CP0_CHECK(ctx->sc);
6931            gen_helper_mtc0_segctl2(cpu_env, arg);
6932            register_name = "SegCtl2";
6933            break;
6934        case CP0_REG05__PWBASE:
6935            check_pw(ctx);
6936            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_PWBase));
6937            register_name = "PWBase";
6938            break;
6939        case CP0_REG05__PWFIELD:
6940            check_pw(ctx);
6941            gen_helper_mtc0_pwfield(cpu_env, arg);
6942            register_name = "PWField";
6943            break;
6944        case CP0_REG05__PWSIZE:
6945            check_pw(ctx);
6946            gen_helper_mtc0_pwsize(cpu_env, arg);
6947            register_name = "PWSize";
6948            break;
6949        default:
6950            goto cp0_unimplemented;
6951        }
6952        break;
6953    case CP0_REGISTER_06:
6954        switch (sel) {
6955        case CP0_REG06__WIRED:
6956            gen_helper_mtc0_wired(cpu_env, arg);
6957            register_name = "Wired";
6958            break;
6959        case CP0_REG06__SRSCONF0:
6960            check_insn(ctx, ISA_MIPS_R2);
6961            gen_helper_mtc0_srsconf0(cpu_env, arg);
6962            register_name = "SRSConf0";
6963            break;
6964        case CP0_REG06__SRSCONF1:
6965            check_insn(ctx, ISA_MIPS_R2);
6966            gen_helper_mtc0_srsconf1(cpu_env, arg);
6967            register_name = "SRSConf1";
6968            break;
6969        case CP0_REG06__SRSCONF2:
6970            check_insn(ctx, ISA_MIPS_R2);
6971            gen_helper_mtc0_srsconf2(cpu_env, arg);
6972            register_name = "SRSConf2";
6973            break;
6974        case CP0_REG06__SRSCONF3:
6975            check_insn(ctx, ISA_MIPS_R2);
6976            gen_helper_mtc0_srsconf3(cpu_env, arg);
6977            register_name = "SRSConf3";
6978            break;
6979        case CP0_REG06__SRSCONF4:
6980            check_insn(ctx, ISA_MIPS_R2);
6981            gen_helper_mtc0_srsconf4(cpu_env, arg);
6982            register_name = "SRSConf4";
6983            break;
6984        case CP0_REG06__PWCTL:
6985            check_pw(ctx);
6986            gen_helper_mtc0_pwctl(cpu_env, arg);
6987            register_name = "PWCtl";
6988            break;
6989        default:
6990            goto cp0_unimplemented;
6991        }
6992        break;
6993    case CP0_REGISTER_07:
6994        switch (sel) {
6995        case CP0_REG07__HWRENA:
6996            check_insn(ctx, ISA_MIPS_R2);
6997            gen_helper_mtc0_hwrena(cpu_env, arg);
6998            ctx->base.is_jmp = DISAS_STOP;
6999            register_name = "HWREna";
7000            break;
7001        default:
7002            goto cp0_unimplemented;
7003        }
7004        break;
7005    case CP0_REGISTER_08:
7006        switch (sel) {
7007        case CP0_REG08__BADVADDR:
7008            /* ignored */
7009            register_name = "BadVAddr";
7010            break;
7011        case CP0_REG08__BADINSTR:
7012            /* ignored */
7013            register_name = "BadInstr";
7014            break;
7015        case CP0_REG08__BADINSTRP:
7016            /* ignored */
7017            register_name = "BadInstrP";
7018            break;
7019        case CP0_REG08__BADINSTRX:
7020            /* ignored */
7021            register_name = "BadInstrX";
7022            break;
7023        default:
7024            goto cp0_unimplemented;
7025        }
7026        break;
7027    case CP0_REGISTER_09:
7028        switch (sel) {
7029        case CP0_REG09__COUNT:
7030            gen_helper_mtc0_count(cpu_env, arg);
7031            register_name = "Count";
7032            break;
7033        case CP0_REG09__SAARI:
7034            CP0_CHECK(ctx->saar);
7035            gen_helper_mtc0_saari(cpu_env, arg);
7036            register_name = "SAARI";
7037            break;
7038        case CP0_REG09__SAAR:
7039            CP0_CHECK(ctx->saar);
7040            gen_helper_mtc0_saar(cpu_env, arg);
7041            register_name = "SAAR";
7042            break;
7043        default:
7044            goto cp0_unimplemented;
7045        }
7046        break;
7047    case CP0_REGISTER_10:
7048        switch (sel) {
7049        case CP0_REG10__ENTRYHI:
7050            gen_helper_mtc0_entryhi(cpu_env, arg);
7051            register_name = "EntryHi";
7052            break;
7053        default:
7054            goto cp0_unimplemented;
7055        }
7056        break;
7057    case CP0_REGISTER_11:
7058        switch (sel) {
7059        case CP0_REG11__COMPARE:
7060            gen_helper_mtc0_compare(cpu_env, arg);
7061            register_name = "Compare";
7062            break;
7063        /* 6,7 are implementation dependent */
7064        default:
7065            goto cp0_unimplemented;
7066        }
7067        break;
7068    case CP0_REGISTER_12:
7069        switch (sel) {
7070        case CP0_REG12__STATUS:
7071            save_cpu_state(ctx, 1);
7072            gen_helper_mtc0_status(cpu_env, arg);
7073            /* DISAS_STOP isn't good enough here, hflags may have changed. */
7074            gen_save_pc(ctx->base.pc_next + 4);
7075            ctx->base.is_jmp = DISAS_EXIT;
7076            register_name = "Status";
7077            break;
7078        case CP0_REG12__INTCTL:
7079            check_insn(ctx, ISA_MIPS_R2);
7080            gen_helper_mtc0_intctl(cpu_env, arg);
7081            /* Stop translation as we may have switched the execution mode */
7082            ctx->base.is_jmp = DISAS_STOP;
7083            register_name = "IntCtl";
7084            break;
7085        case CP0_REG12__SRSCTL:
7086            check_insn(ctx, ISA_MIPS_R2);
7087            gen_helper_mtc0_srsctl(cpu_env, arg);
7088            /* Stop translation as we may have switched the execution mode */
7089            ctx->base.is_jmp = DISAS_STOP;
7090            register_name = "SRSCtl";
7091            break;
7092        case CP0_REG12__SRSMAP:
7093            check_insn(ctx, ISA_MIPS_R2);
7094            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7095            /* Stop translation as we may have switched the execution mode */
7096            ctx->base.is_jmp = DISAS_STOP;
7097            register_name = "SRSMap";
7098            break;
7099        default:
7100            goto cp0_unimplemented;
7101        }
7102        break;
7103    case CP0_REGISTER_13:
7104        switch (sel) {
7105        case CP0_REG13__CAUSE:
7106            save_cpu_state(ctx, 1);
7107            gen_helper_mtc0_cause(cpu_env, arg);
7108            /*
7109             * Stop translation as we may have triggered an interrupt.
7110             * DISAS_STOP isn't sufficient, we need to ensure we break out of
7111             * translated code to check for pending interrupts.
7112             */
7113            gen_save_pc(ctx->base.pc_next + 4);
7114            ctx->base.is_jmp = DISAS_EXIT;
7115            register_name = "Cause";
7116            break;
7117        default:
7118            goto cp0_unimplemented;
7119        }
7120        break;
7121    case CP0_REGISTER_14:
7122        switch (sel) {
7123        case CP0_REG14__EPC:
7124            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7125            register_name = "EPC";
7126            break;
7127        default:
7128            goto cp0_unimplemented;
7129        }
7130        break;
7131    case CP0_REGISTER_15:
7132        switch (sel) {
7133        case CP0_REG15__PRID:
7134            /* ignored */
7135            register_name = "PRid";
7136            break;
7137        case CP0_REG15__EBASE:
7138            check_insn(ctx, ISA_MIPS_R2);
7139            gen_helper_mtc0_ebase(cpu_env, arg);
7140            register_name = "EBase";
7141            break;
7142        default:
7143            goto cp0_unimplemented;
7144        }
7145        break;
7146    case CP0_REGISTER_16:
7147        switch (sel) {
7148        case CP0_REG16__CONFIG:
7149            gen_helper_mtc0_config0(cpu_env, arg);
7150            register_name = "Config";
7151            /* Stop translation as we may have switched the execution mode */
7152            ctx->base.is_jmp = DISAS_STOP;
7153            break;
7154        case CP0_REG16__CONFIG1:
7155            /* ignored, read only */
7156            register_name = "Config1";
7157            break;
7158        case CP0_REG16__CONFIG2:
7159            gen_helper_mtc0_config2(cpu_env, arg);
7160            register_name = "Config2";
7161            /* Stop translation as we may have switched the execution mode */
7162            ctx->base.is_jmp = DISAS_STOP;
7163            break;
7164        case CP0_REG16__CONFIG3:
7165            gen_helper_mtc0_config3(cpu_env, arg);
7166            register_name = "Config3";
7167            /* Stop translation as we may have switched the execution mode */
7168            ctx->base.is_jmp = DISAS_STOP;
7169            break;
7170        case CP0_REG16__CONFIG4:
7171            gen_helper_mtc0_config4(cpu_env, arg);
7172            register_name = "Config4";
7173            ctx->base.is_jmp = DISAS_STOP;
7174            break;
7175        case CP0_REG16__CONFIG5:
7176            gen_helper_mtc0_config5(cpu_env, arg);
7177            register_name = "Config5";
7178            /* Stop translation as we may have switched the execution mode */
7179            ctx->base.is_jmp = DISAS_STOP;
7180            break;
7181        /* 6,7 are implementation dependent */
7182        case CP0_REG16__CONFIG6:
7183            /* ignored */
7184            register_name = "Config6";
7185            break;
7186        case CP0_REG16__CONFIG7:
7187            /* ignored */
7188            register_name = "Config7";
7189            break;
7190        default:
7191            register_name = "Invalid config selector";
7192            goto cp0_unimplemented;
7193        }
7194        break;
7195    case CP0_REGISTER_17:
7196        switch (sel) {
7197        case CP0_REG17__LLADDR:
7198            gen_helper_mtc0_lladdr(cpu_env, arg);
7199            register_name = "LLAddr";
7200            break;
7201        case CP0_REG17__MAAR:
7202            CP0_CHECK(ctx->mrp);
7203            gen_helper_mtc0_maar(cpu_env, arg);
7204            register_name = "MAAR";
7205            break;
7206        case CP0_REG17__MAARI:
7207            CP0_CHECK(ctx->mrp);
7208            gen_helper_mtc0_maari(cpu_env, arg);
7209            register_name = "MAARI";
7210            break;
7211        default:
7212            goto cp0_unimplemented;
7213        }
7214        break;
7215    case CP0_REGISTER_18:
7216        switch (sel) {
7217        case CP0_REG18__WATCHLO0:
7218        case CP0_REG18__WATCHLO1:
7219        case CP0_REG18__WATCHLO2:
7220        case CP0_REG18__WATCHLO3:
7221        case CP0_REG18__WATCHLO4:
7222        case CP0_REG18__WATCHLO5:
7223        case CP0_REG18__WATCHLO6:
7224        case CP0_REG18__WATCHLO7:
7225            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7226            gen_helper_0e1i(mtc0_watchlo, arg, sel);
7227            register_name = "WatchLo";
7228            break;
7229        default:
7230            goto cp0_unimplemented;
7231        }
7232        break;
7233    case CP0_REGISTER_19:
7234        switch (sel) {
7235        case CP0_REG19__WATCHHI0:
7236        case CP0_REG19__WATCHHI1:
7237        case CP0_REG19__WATCHHI2:
7238        case CP0_REG19__WATCHHI3:
7239        case CP0_REG19__WATCHHI4:
7240        case CP0_REG19__WATCHHI5:
7241        case CP0_REG19__WATCHHI6:
7242        case CP0_REG19__WATCHHI7:
7243            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7244            gen_helper_0e1i(mtc0_watchhi, arg, sel);
7245            register_name = "WatchHi";
7246            break;
7247        default:
7248            goto cp0_unimplemented;
7249        }
7250        break;
7251    case CP0_REGISTER_20:
7252        switch (sel) {
7253        case CP0_REG20__XCONTEXT:
7254#if defined(TARGET_MIPS64)
7255            check_insn(ctx, ISA_MIPS3);
7256            gen_helper_mtc0_xcontext(cpu_env, arg);
7257            register_name = "XContext";
7258            break;
7259#endif
7260        default:
7261            goto cp0_unimplemented;
7262        }
7263        break;
7264    case CP0_REGISTER_21:
7265       /* Officially reserved, but sel 0 is used for R1x000 framemask */
7266        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7267        switch (sel) {
7268        case 0:
7269            gen_helper_mtc0_framemask(cpu_env, arg);
7270            register_name = "Framemask";
7271            break;
7272        default:
7273            goto cp0_unimplemented;
7274        }
7275        break;
7276    case CP0_REGISTER_22:
7277        /* ignored */
7278        register_name = "Diagnostic"; /* implementation dependent */
7279        break;
7280    case CP0_REGISTER_23:
7281        switch (sel) {
7282        case CP0_REG23__DEBUG:
7283            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
7284            /* DISAS_STOP isn't good enough here, hflags may have changed. */
7285            gen_save_pc(ctx->base.pc_next + 4);
7286            ctx->base.is_jmp = DISAS_EXIT;
7287            register_name = "Debug";
7288            break;
7289        case CP0_REG23__TRACECONTROL:
7290            /* PDtrace support */
7291            /* gen_helper_mtc0_tracecontrol(cpu_env, arg);  */
7292            register_name = "TraceControl";
7293            /* Stop translation as we may have switched the execution mode */
7294            ctx->base.is_jmp = DISAS_STOP;
7295            goto cp0_unimplemented;
7296        case CP0_REG23__TRACECONTROL2:
7297            /* PDtrace support */
7298            /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
7299            register_name = "TraceControl2";
7300            /* Stop translation as we may have switched the execution mode */
7301            ctx->base.is_jmp = DISAS_STOP;
7302            goto cp0_unimplemented;
7303        case CP0_REG23__USERTRACEDATA1:
7304            /* Stop translation as we may have switched the execution mode */
7305            ctx->base.is_jmp = DISAS_STOP;
7306            /* PDtrace support */
7307            /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
7308            register_name = "UserTraceData";
7309            /* Stop translation as we may have switched the execution mode */
7310            ctx->base.is_jmp = DISAS_STOP;
7311            goto cp0_unimplemented;
7312        case CP0_REG23__TRACEIBPC:
7313            /* PDtrace support */
7314            /* gen_helper_mtc0_traceibpc(cpu_env, arg);     */
7315            /* Stop translation as we may have switched the execution mode */
7316            ctx->base.is_jmp = DISAS_STOP;
7317            register_name = "TraceIBPC";
7318            goto cp0_unimplemented;
7319        case CP0_REG23__TRACEDBPC:
7320            /* PDtrace support */
7321            /* gen_helper_mtc0_tracedbpc(cpu_env, arg);     */
7322            /* Stop translation as we may have switched the execution mode */
7323            ctx->base.is_jmp = DISAS_STOP;
7324            register_name = "TraceDBPC";
7325            goto cp0_unimplemented;
7326        default:
7327            goto cp0_unimplemented;
7328        }
7329        break;
7330    case CP0_REGISTER_24:
7331        switch (sel) {
7332        case CP0_REG24__DEPC:
7333            /* EJTAG support */
7334            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
7335            register_name = "DEPC";
7336            break;
7337        default:
7338            goto cp0_unimplemented;
7339        }
7340        break;
7341    case CP0_REGISTER_25:
7342        switch (sel) {
7343        case CP0_REG25__PERFCTL0:
7344            gen_helper_mtc0_performance0(cpu_env, arg);
7345            register_name = "Performance0";
7346            break;
7347        case CP0_REG25__PERFCNT0:
7348            /* gen_helper_mtc0_performance1(arg); */
7349            register_name = "Performance1";
7350            goto cp0_unimplemented;
7351        case CP0_REG25__PERFCTL1:
7352            /* gen_helper_mtc0_performance2(arg); */
7353            register_name = "Performance2";
7354            goto cp0_unimplemented;
7355        case CP0_REG25__PERFCNT1:
7356            /* gen_helper_mtc0_performance3(arg); */
7357            register_name = "Performance3";
7358            goto cp0_unimplemented;
7359        case CP0_REG25__PERFCTL2:
7360            /* gen_helper_mtc0_performance4(arg); */
7361            register_name = "Performance4";
7362            goto cp0_unimplemented;
7363        case CP0_REG25__PERFCNT2:
7364            /* gen_helper_mtc0_performance5(arg); */
7365            register_name = "Performance5";
7366            goto cp0_unimplemented;
7367        case CP0_REG25__PERFCTL3:
7368            /* gen_helper_mtc0_performance6(arg); */
7369            register_name = "Performance6";
7370            goto cp0_unimplemented;
7371        case CP0_REG25__PERFCNT3:
7372            /* gen_helper_mtc0_performance7(arg); */
7373            register_name = "Performance7";
7374            goto cp0_unimplemented;
7375        default:
7376            goto cp0_unimplemented;
7377        }
7378       break;
7379    case CP0_REGISTER_26:
7380        switch (sel) {
7381        case CP0_REG26__ERRCTL:
7382            gen_helper_mtc0_errctl(cpu_env, arg);
7383            ctx->base.is_jmp = DISAS_STOP;
7384            register_name = "ErrCtl";
7385            break;
7386        default:
7387            goto cp0_unimplemented;
7388        }
7389        break;
7390    case CP0_REGISTER_27:
7391        switch (sel) {
7392        case CP0_REG27__CACHERR:
7393            /* ignored */
7394            register_name = "CacheErr";
7395            break;
7396        default:
7397            goto cp0_unimplemented;
7398        }
7399       break;
7400    case CP0_REGISTER_28:
7401        switch (sel) {
7402        case CP0_REG28__TAGLO:
7403        case CP0_REG28__TAGLO1:
7404        case CP0_REG28__TAGLO2:
7405        case CP0_REG28__TAGLO3:
7406            gen_helper_mtc0_taglo(cpu_env, arg);
7407            register_name = "TagLo";
7408            break;
7409        case CP0_REG28__DATALO:
7410        case CP0_REG28__DATALO1:
7411        case CP0_REG28__DATALO2:
7412        case CP0_REG28__DATALO3:
7413            gen_helper_mtc0_datalo(cpu_env, arg);
7414            register_name = "DataLo";
7415            break;
7416        default:
7417            goto cp0_unimplemented;
7418        }
7419        break;
7420    case CP0_REGISTER_29:
7421        switch (sel) {
7422        case CP0_REG29__TAGHI:
7423        case CP0_REG29__TAGHI1:
7424        case CP0_REG29__TAGHI2:
7425        case CP0_REG29__TAGHI3:
7426            gen_helper_mtc0_taghi(cpu_env, arg);
7427            register_name = "TagHi";
7428            break;
7429        case CP0_REG29__DATAHI:
7430        case CP0_REG29__DATAHI1:
7431        case CP0_REG29__DATAHI2:
7432        case CP0_REG29__DATAHI3:
7433            gen_helper_mtc0_datahi(cpu_env, arg);
7434            register_name = "DataHi";
7435            break;
7436        default:
7437            register_name = "invalid sel";
7438            goto cp0_unimplemented;
7439        }
7440       break;
7441    case CP0_REGISTER_30:
7442        switch (sel) {
7443        case CP0_REG30__ERROREPC:
7444            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
7445            register_name = "ErrorEPC";
7446            break;
7447        default:
7448            goto cp0_unimplemented;
7449        }
7450        break;
7451    case CP0_REGISTER_31:
7452        switch (sel) {
7453        case CP0_REG31__DESAVE:
7454            /* EJTAG support */
7455            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
7456            register_name = "DESAVE";
7457            break;
7458        case CP0_REG31__KSCRATCH1:
7459        case CP0_REG31__KSCRATCH2:
7460        case CP0_REG31__KSCRATCH3:
7461        case CP0_REG31__KSCRATCH4:
7462        case CP0_REG31__KSCRATCH5:
7463        case CP0_REG31__KSCRATCH6:
7464            CP0_CHECK(ctx->kscrexist & (1 << sel));
7465            tcg_gen_st_tl(arg, cpu_env,
7466                          offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
7467            register_name = "KScratch";
7468            break;
7469        default:
7470            goto cp0_unimplemented;
7471        }
7472        break;
7473    default:
7474       goto cp0_unimplemented;
7475    }
7476    trace_mips_translate_c0("mtc0", register_name, reg, sel);
7477
7478    /* For simplicity assume that all writes can cause interrupts.  */
7479    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7480        /*
7481         * DISAS_STOP isn't sufficient, we need to ensure we break out of
7482         * translated code to check for pending interrupts.
7483         */
7484        gen_save_pc(ctx->base.pc_next + 4);
7485        ctx->base.is_jmp = DISAS_EXIT;
7486    }
7487    return;
7488
7489cp0_unimplemented:
7490    qemu_log_mask(LOG_UNIMP, "mtc0 %s (reg %d sel %d)\n",
7491                  register_name, reg, sel);
7492}
7493
7494#if defined(TARGET_MIPS64)
7495static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
7496{
7497    const char *register_name = "invalid";
7498
7499    if (sel != 0) {
7500        check_insn(ctx, ISA_MIPS_R1);
7501    }
7502
7503    switch (reg) {
7504    case CP0_REGISTER_00:
7505        switch (sel) {
7506        case CP0_REG00__INDEX:
7507            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
7508            register_name = "Index";
7509            break;
7510        case CP0_REG00__MVPCONTROL:
7511            CP0_CHECK(ctx->insn_flags & ASE_MT);
7512            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
7513            register_name = "MVPControl";
7514            break;
7515        case CP0_REG00__MVPCONF0:
7516            CP0_CHECK(ctx->insn_flags & ASE_MT);
7517            gen_helper_mfc0_mvpconf0(arg, cpu_env);
7518            register_name = "MVPConf0";
7519            break;
7520        case CP0_REG00__MVPCONF1:
7521            CP0_CHECK(ctx->insn_flags & ASE_MT);
7522            gen_helper_mfc0_mvpconf1(arg, cpu_env);
7523            register_name = "MVPConf1";
7524            break;
7525        case CP0_REG00__VPCONTROL:
7526            CP0_CHECK(ctx->vp);
7527            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPControl));
7528            register_name = "VPControl";
7529            break;
7530        default:
7531            goto cp0_unimplemented;
7532        }
7533        break;
7534    case CP0_REGISTER_01:
7535        switch (sel) {
7536        case CP0_REG01__RANDOM:
7537            CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
7538            gen_helper_mfc0_random(arg, cpu_env);
7539            register_name = "Random";
7540            break;
7541        case CP0_REG01__VPECONTROL:
7542            CP0_CHECK(ctx->insn_flags & ASE_MT);
7543            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
7544            register_name = "VPEControl";
7545            break;
7546        case CP0_REG01__VPECONF0:
7547            CP0_CHECK(ctx->insn_flags & ASE_MT);
7548            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
7549            register_name = "VPEConf0";
7550            break;
7551        case CP0_REG01__VPECONF1:
7552            CP0_CHECK(ctx->insn_flags & ASE_MT);
7553            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
7554            register_name = "VPEConf1";
7555            break;
7556        case CP0_REG01__YQMASK:
7557            CP0_CHECK(ctx->insn_flags & ASE_MT);
7558            tcg_gen_ld_tl(arg, cpu_env,
7559                          offsetof(CPUMIPSState, CP0_YQMask));
7560            register_name = "YQMask";
7561            break;
7562        case CP0_REG01__VPESCHEDULE:
7563            CP0_CHECK(ctx->insn_flags & ASE_MT);
7564            tcg_gen_ld_tl(arg, cpu_env,
7565                          offsetof(CPUMIPSState, CP0_VPESchedule));
7566            register_name = "VPESchedule";
7567            break;
7568        case CP0_REG01__VPESCHEFBACK:
7569            CP0_CHECK(ctx->insn_flags & ASE_MT);
7570            tcg_gen_ld_tl(arg, cpu_env,
7571                          offsetof(CPUMIPSState, CP0_VPEScheFBack));
7572            register_name = "VPEScheFBack";
7573            break;
7574        case CP0_REG01__VPEOPT:
7575            CP0_CHECK(ctx->insn_flags & ASE_MT);
7576            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
7577            register_name = "VPEOpt";
7578            break;
7579        default:
7580            goto cp0_unimplemented;
7581        }
7582        break;
7583    case CP0_REGISTER_02:
7584        switch (sel) {
7585        case CP0_REG02__ENTRYLO0:
7586            tcg_gen_ld_tl(arg, cpu_env,
7587                          offsetof(CPUMIPSState, CP0_EntryLo0));
7588            register_name = "EntryLo0";
7589            break;
7590        case CP0_REG02__TCSTATUS:
7591            CP0_CHECK(ctx->insn_flags & ASE_MT);
7592            gen_helper_mfc0_tcstatus(arg, cpu_env);
7593            register_name = "TCStatus";
7594            break;
7595        case CP0_REG02__TCBIND:
7596            CP0_CHECK(ctx->insn_flags & ASE_MT);
7597            gen_helper_mfc0_tcbind(arg, cpu_env);
7598            register_name = "TCBind";
7599            break;
7600        case CP0_REG02__TCRESTART:
7601            CP0_CHECK(ctx->insn_flags & ASE_MT);
7602            gen_helper_dmfc0_tcrestart(arg, cpu_env);
7603            register_name = "TCRestart";
7604            break;
7605        case CP0_REG02__TCHALT:
7606            CP0_CHECK(ctx->insn_flags & ASE_MT);
7607            gen_helper_dmfc0_tchalt(arg, cpu_env);
7608            register_name = "TCHalt";
7609            break;
7610        case CP0_REG02__TCCONTEXT:
7611            CP0_CHECK(ctx->insn_flags & ASE_MT);
7612            gen_helper_dmfc0_tccontext(arg, cpu_env);
7613            register_name = "TCContext";
7614            break;
7615        case CP0_REG02__TCSCHEDULE:
7616            CP0_CHECK(ctx->insn_flags & ASE_MT);
7617            gen_helper_dmfc0_tcschedule(arg, cpu_env);
7618            register_name = "TCSchedule";
7619            break;
7620        case CP0_REG02__TCSCHEFBACK:
7621            CP0_CHECK(ctx->insn_flags & ASE_MT);
7622            gen_helper_dmfc0_tcschefback(arg, cpu_env);
7623            register_name = "TCScheFBack";
7624            break;
7625        default:
7626            goto cp0_unimplemented;
7627        }
7628        break;
7629    case CP0_REGISTER_03:
7630        switch (sel) {
7631        case CP0_REG03__ENTRYLO1:
7632            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
7633            register_name = "EntryLo1";
7634            break;
7635        case CP0_REG03__GLOBALNUM:
7636            CP0_CHECK(ctx->vp);
7637            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_GlobalNumber));
7638            register_name = "GlobalNumber";
7639            break;
7640        default:
7641            goto cp0_unimplemented;
7642        }
7643        break;
7644    case CP0_REGISTER_04:
7645        switch (sel) {
7646        case CP0_REG04__CONTEXT:
7647            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
7648            register_name = "Context";
7649            break;
7650        case CP0_REG04__CONTEXTCONFIG:
7651            /* SmartMIPS ASE */
7652            /* gen_helper_dmfc0_contextconfig(arg); */
7653            register_name = "ContextConfig";
7654            goto cp0_unimplemented;
7655        case CP0_REG04__USERLOCAL:
7656            CP0_CHECK(ctx->ulri);
7657            tcg_gen_ld_tl(arg, cpu_env,
7658                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
7659            register_name = "UserLocal";
7660            break;
7661        case CP0_REG04__MMID:
7662            CP0_CHECK(ctx->mi);
7663            gen_helper_mtc0_memorymapid(cpu_env, arg);
7664            register_name = "MMID";
7665            break;
7666        default:
7667            goto cp0_unimplemented;
7668        }
7669        break;
7670    case CP0_REGISTER_05:
7671        switch (sel) {
7672        case CP0_REG05__PAGEMASK:
7673            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
7674            register_name = "PageMask";
7675            break;
7676        case CP0_REG05__PAGEGRAIN:
7677            check_insn(ctx, ISA_MIPS_R2);
7678            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
7679            register_name = "PageGrain";
7680            break;
7681        case CP0_REG05__SEGCTL0:
7682            CP0_CHECK(ctx->sc);
7683            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl0));
7684            register_name = "SegCtl0";
7685            break;
7686        case CP0_REG05__SEGCTL1:
7687            CP0_CHECK(ctx->sc);
7688            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl1));
7689            register_name = "SegCtl1";
7690            break;
7691        case CP0_REG05__SEGCTL2:
7692            CP0_CHECK(ctx->sc);
7693            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_SegCtl2));
7694            register_name = "SegCtl2";
7695            break;
7696        case CP0_REG05__PWBASE:
7697            check_pw(ctx);
7698            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
7699            register_name = "PWBase";
7700            break;
7701        case CP0_REG05__PWFIELD:
7702            check_pw(ctx);
7703            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWField));
7704            register_name = "PWField";
7705            break;
7706        case CP0_REG05__PWSIZE:
7707            check_pw(ctx);
7708            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWSize));
7709            register_name = "PWSize";
7710            break;
7711        default:
7712            goto cp0_unimplemented;
7713        }
7714        break;
7715    case CP0_REGISTER_06:
7716        switch (sel) {
7717        case CP0_REG06__WIRED:
7718            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
7719            register_name = "Wired";
7720            break;
7721        case CP0_REG06__SRSCONF0:
7722            check_insn(ctx, ISA_MIPS_R2);
7723            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
7724            register_name = "SRSConf0";
7725            break;
7726        case CP0_REG06__SRSCONF1:
7727            check_insn(ctx, ISA_MIPS_R2);
7728            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
7729            register_name = "SRSConf1";
7730            break;
7731        case CP0_REG06__SRSCONF2:
7732            check_insn(ctx, ISA_MIPS_R2);
7733            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
7734            register_name = "SRSConf2";
7735            break;
7736        case CP0_REG06__SRSCONF3:
7737            check_insn(ctx, ISA_MIPS_R2);
7738            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
7739            register_name = "SRSConf3";
7740            break;
7741        case CP0_REG06__SRSCONF4:
7742            check_insn(ctx, ISA_MIPS_R2);
7743            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
7744            register_name = "SRSConf4";
7745            break;
7746        case CP0_REG06__PWCTL:
7747            check_pw(ctx);
7748            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PWCtl));
7749            register_name = "PWCtl";
7750            break;
7751        default:
7752            goto cp0_unimplemented;
7753        }
7754        break;
7755    case CP0_REGISTER_07:
7756        switch (sel) {
7757        case CP0_REG07__HWRENA:
7758            check_insn(ctx, ISA_MIPS_R2);
7759            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
7760            register_name = "HWREna";
7761            break;
7762        default:
7763            goto cp0_unimplemented;
7764        }
7765        break;
7766    case CP0_REGISTER_08:
7767        switch (sel) {
7768        case CP0_REG08__BADVADDR:
7769            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
7770            register_name = "BadVAddr";
7771            break;
7772        case CP0_REG08__BADINSTR:
7773            CP0_CHECK(ctx->bi);
7774            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstr));
7775            register_name = "BadInstr";
7776            break;
7777        case CP0_REG08__BADINSTRP:
7778            CP0_CHECK(ctx->bp);
7779            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrP));
7780            register_name = "BadInstrP";
7781            break;
7782        case CP0_REG08__BADINSTRX:
7783            CP0_CHECK(ctx->bi);
7784            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_BadInstrX));
7785            tcg_gen_andi_tl(arg, arg, ~0xffff);
7786            register_name = "BadInstrX";
7787            break;
7788        default:
7789            goto cp0_unimplemented;
7790        }
7791        break;
7792    case CP0_REGISTER_09:
7793        switch (sel) {
7794        case CP0_REG09__COUNT:
7795            /* Mark as an IO operation because we read the time.  */
7796            if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
7797                gen_io_start();
7798            }
7799            gen_helper_mfc0_count(arg, cpu_env);
7800            /*
7801             * Break the TB to be able to take timer interrupts immediately
7802             * after reading count. DISAS_STOP isn't sufficient, we need to
7803             * ensure we break completely out of translated code.
7804             */
7805            gen_save_pc(ctx->base.pc_next + 4);
7806            ctx->base.is_jmp = DISAS_EXIT;
7807            register_name = "Count";
7808            break;
7809        case CP0_REG09__SAARI:
7810            CP0_CHECK(ctx->saar);
7811            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SAARI));
7812            register_name = "SAARI";
7813            break;
7814        case CP0_REG09__SAAR:
7815            CP0_CHECK(ctx->saar);
7816            gen_helper_dmfc0_saar(arg, cpu_env);
7817            register_name = "SAAR";
7818            break;
7819        default:
7820            goto cp0_unimplemented;
7821        }
7822        break;
7823    case CP0_REGISTER_10:
7824        switch (sel) {
7825        case CP0_REG10__ENTRYHI:
7826            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
7827            register_name = "EntryHi";
7828            break;
7829        default:
7830            goto cp0_unimplemented;
7831        }
7832        break;
7833    case CP0_REGISTER_11:
7834        switch (sel) {
7835        case CP0_REG11__COMPARE:
7836            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
7837            register_name = "Compare";
7838            break;
7839        /* 6,7 are implementation dependent */
7840        default:
7841            goto cp0_unimplemented;
7842        }
7843        break;
7844    case CP0_REGISTER_12:
7845        switch (sel) {
7846        case CP0_REG12__STATUS:
7847            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
7848            register_name = "Status";
7849            break;
7850        case CP0_REG12__INTCTL:
7851            check_insn(ctx, ISA_MIPS_R2);
7852            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
7853            register_name = "IntCtl";
7854            break;
7855        case CP0_REG12__SRSCTL:
7856            check_insn(ctx, ISA_MIPS_R2);
7857            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
7858            register_name = "SRSCtl";
7859            break;
7860        case CP0_REG12__SRSMAP:
7861            check_insn(ctx, ISA_MIPS_R2);
7862            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
7863            register_name = "SRSMap";
7864            break;
7865        default:
7866            goto cp0_unimplemented;
7867        }
7868        break;
7869    case CP0_REGISTER_13:
7870        switch (sel) {
7871        case CP0_REG13__CAUSE:
7872            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
7873            register_name = "Cause";
7874            break;
7875        default:
7876            goto cp0_unimplemented;
7877        }
7878        break;
7879    case CP0_REGISTER_14:
7880        switch (sel) {
7881        case CP0_REG14__EPC:
7882            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
7883            register_name = "EPC";
7884            break;
7885        default:
7886            goto cp0_unimplemented;
7887        }
7888        break;
7889    case CP0_REGISTER_15:
7890        switch (sel) {
7891        case CP0_REG15__PRID:
7892            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
7893            register_name = "PRid";
7894            break;
7895        case CP0_REG15__EBASE:
7896            check_insn(ctx, ISA_MIPS_R2);
7897            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EBase));
7898            register_name = "EBase";
7899            break;
7900        case CP0_REG15__CMGCRBASE:
7901            check_insn(ctx, ISA_MIPS_R2);
7902            CP0_CHECK(ctx->cmgcr);
7903            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_CMGCRBase));
7904            register_name = "CMGCRBase";
7905            break;
7906        default:
7907            goto cp0_unimplemented;
7908        }
7909        break;
7910    case CP0_REGISTER_16:
7911        switch (sel) {
7912        case CP0_REG16__CONFIG:
7913            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
7914            register_name = "Config";
7915            break;
7916        case CP0_REG16__CONFIG1:
7917            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
7918            register_name = "Config1";
7919            break;
7920        case CP0_REG16__CONFIG2:
7921            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
7922            register_name = "Config2";
7923            break;
7924        case CP0_REG16__CONFIG3:
7925            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
7926            register_name = "Config3";
7927            break;
7928        case CP0_REG16__CONFIG4:
7929            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config4));
7930            register_name = "Config4";
7931            break;
7932        case CP0_REG16__CONFIG5:
7933            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config5));
7934            register_name = "Config5";
7935            break;
7936        /* 6,7 are implementation dependent */
7937        case CP0_REG16__CONFIG6:
7938            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
7939            register_name = "Config6";
7940            break;
7941        case CP0_REG16__CONFIG7:
7942            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
7943            register_name = "Config7";
7944            break;
7945        default:
7946            goto cp0_unimplemented;
7947        }
7948        break;
7949    case CP0_REGISTER_17:
7950        switch (sel) {
7951        case CP0_REG17__LLADDR:
7952            gen_helper_dmfc0_lladdr(arg, cpu_env);
7953            register_name = "LLAddr";
7954            break;
7955        case CP0_REG17__MAAR:
7956            CP0_CHECK(ctx->mrp);
7957            gen_helper_dmfc0_maar(arg, cpu_env);
7958            register_name = "MAAR";
7959            break;
7960        case CP0_REG17__MAARI:
7961            CP0_CHECK(ctx->mrp);
7962            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MAARI));
7963            register_name = "MAARI";
7964            break;
7965        default:
7966            goto cp0_unimplemented;
7967        }
7968        break;
7969    case CP0_REGISTER_18:
7970        switch (sel) {
7971        case CP0_REG18__WATCHLO0:
7972        case CP0_REG18__WATCHLO1:
7973        case CP0_REG18__WATCHLO2:
7974        case CP0_REG18__WATCHLO3:
7975        case CP0_REG18__WATCHLO4:
7976        case CP0_REG18__WATCHLO5:
7977        case CP0_REG18__WATCHLO6:
7978        case CP0_REG18__WATCHLO7:
7979            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7980            gen_helper_1e0i(dmfc0_watchlo, arg, sel);
7981            register_name = "WatchLo";
7982            break;
7983        default:
7984            goto cp0_unimplemented;
7985        }
7986        break;
7987    case CP0_REGISTER_19:
7988        switch (sel) {
7989        case CP0_REG19__WATCHHI0:
7990        case CP0_REG19__WATCHHI1:
7991        case CP0_REG19__WATCHHI2:
7992        case CP0_REG19__WATCHHI3:
7993        case CP0_REG19__WATCHHI4:
7994        case CP0_REG19__WATCHHI5:
7995        case CP0_REG19__WATCHHI6:
7996        case CP0_REG19__WATCHHI7:
7997            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
7998            gen_helper_1e0i(dmfc0_watchhi, arg, sel);
7999            register_name = "WatchHi";
8000            break;
8001        default:
8002            goto cp0_unimplemented;
8003        }
8004        break;
8005    case CP0_REGISTER_20:
8006        switch (sel) {
8007        case CP0_REG20__XCONTEXT:
8008            check_insn(ctx, ISA_MIPS3);
8009            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
8010            register_name = "XContext";
8011            break;
8012        default:
8013            goto cp0_unimplemented;
8014        }
8015        break;
8016    case CP0_REGISTER_21:
8017        /* Officially reserved, but sel 0 is used for R1x000 framemask */
8018        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
8019        switch (sel) {
8020        case 0:
8021            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
8022            register_name = "Framemask";
8023            break;
8024        default:
8025            goto cp0_unimplemented;
8026        }
8027        break;
8028    case CP0_REGISTER_22:
8029        tcg_gen_movi_tl(arg, 0); /* unimplemented */
8030        register_name = "'Diagnostic"; /* implementation dependent */
8031        break;
8032    case CP0_REGISTER_23:
8033        switch (sel) {
8034        case CP0_REG23__DEBUG:
8035            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
8036            register_name = "Debug";
8037            break;
8038        case CP0_REG23__TRACECONTROL:
8039            /* PDtrace support */
8040            /* gen_helper_dmfc0_tracecontrol(arg, cpu_env);  */
8041            register_name = "TraceControl";
8042            goto cp0_unimplemented;
8043        case CP0_REG23__TRACECONTROL2:
8044            /* PDtrace support */
8045            /* gen_helper_dmfc0_tracecontrol2(arg, cpu_env); */
8046            register_name = "TraceControl2";
8047            goto cp0_unimplemented;
8048        case CP0_REG23__USERTRACEDATA1:
8049            /* PDtrace support */
8050            /* gen_helper_dmfc0_usertracedata1(arg, cpu_env);*/
8051            register_name = "UserTraceData1";
8052            goto cp0_unimplemented;
8053        case CP0_REG23__TRACEIBPC:
8054            /* PDtrace support */
8055            /* gen_helper_dmfc0_traceibpc(arg, cpu_env);     */
8056            register_name = "TraceIBPC";
8057            goto cp0_unimplemented;
8058        case CP0_REG23__TRACEDBPC:
8059            /* PDtrace support */
8060            /* gen_helper_dmfc0_tracedbpc(arg, cpu_env);     */
8061            register_name = "TraceDBPC";
8062            goto cp0_unimplemented;
8063        default:
8064            goto cp0_unimplemented;
8065        }
8066        break;
8067    case CP0_REGISTER_24:
8068        switch (sel) {
8069        case CP0_REG24__DEPC:
8070            /* EJTAG support */
8071            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8072            register_name = "DEPC";
8073            break;
8074        default:
8075            goto cp0_unimplemented;
8076        }
8077        break;
8078    case CP0_REGISTER_25:
8079        switch (sel) {
8080        case CP0_REG25__PERFCTL0:
8081            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
8082            register_name = "Performance0";
8083            break;
8084        case CP0_REG25__PERFCNT0:
8085            /* gen_helper_dmfc0_performance1(arg); */
8086            register_name = "Performance1";
8087            goto cp0_unimplemented;
8088        case CP0_REG25__PERFCTL1:
8089            /* gen_helper_dmfc0_performance2(arg); */
8090            register_name = "Performance2";
8091            goto cp0_unimplemented;
8092        case CP0_REG25__PERFCNT1:
8093            /* gen_helper_dmfc0_performance3(arg); */
8094            register_name = "Performance3";
8095            goto cp0_unimplemented;
8096        case CP0_REG25__PERFCTL2:
8097            /* gen_helper_dmfc0_performance4(arg); */
8098            register_name = "Performance4";
8099            goto cp0_unimplemented;
8100        case CP0_REG25__PERFCNT2:
8101            /* gen_helper_dmfc0_performance5(arg); */
8102            register_name = "Performance5";
8103            goto cp0_unimplemented;
8104        case CP0_REG25__PERFCTL3:
8105            /* gen_helper_dmfc0_performance6(arg); */
8106            register_name = "Performance6";
8107            goto cp0_unimplemented;
8108        case CP0_REG25__PERFCNT3:
8109            /* gen_helper_dmfc0_performance7(arg); */
8110            register_name = "Performance7";
8111            goto cp0_unimplemented;
8112        default:
8113            goto cp0_unimplemented;
8114        }
8115        break;
8116    case CP0_REGISTER_26:
8117        switch (sel) {
8118        case CP0_REG26__ERRCTL:
8119            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_ErrCtl));
8120            register_name = "ErrCtl";
8121            break;
8122        default:
8123            goto cp0_unimplemented;
8124        }
8125        break;
8126    case CP0_REGISTER_27:
8127        switch (sel) {
8128        /* ignored */
8129        case CP0_REG27__CACHERR:
8130            tcg_gen_movi_tl(arg, 0); /* unimplemented */
8131            register_name = "CacheErr";
8132            break;
8133        default:
8134            goto cp0_unimplemented;
8135        }
8136        break;
8137    case CP0_REGISTER_28:
8138        switch (sel) {
8139        case CP0_REG28__TAGLO:
8140        case CP0_REG28__TAGLO1:
8141        case CP0_REG28__TAGLO2:
8142        case CP0_REG28__TAGLO3:
8143            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
8144            register_name = "TagLo";
8145            break;
8146        case CP0_REG28__DATALO:
8147        case CP0_REG28__DATALO1:
8148        case CP0_REG28__DATALO2:
8149        case CP0_REG28__DATALO3:
8150            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
8151            register_name = "DataLo";
8152            break;
8153        default:
8154            goto cp0_unimplemented;
8155        }
8156        break;
8157    case CP0_REGISTER_29:
8158        switch (sel) {
8159        case CP0_REG29__TAGHI:
8160        case CP0_REG29__TAGHI1:
8161        case CP0_REG29__TAGHI2:
8162        case CP0_REG29__TAGHI3:
8163            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
8164            register_name = "TagHi";
8165            break;
8166        case CP0_REG29__DATAHI:
8167        case CP0_REG29__DATAHI1:
8168        case CP0_REG29__DATAHI2:
8169        case CP0_REG29__DATAHI3:
8170            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
8171            register_name = "DataHi";
8172            break;
8173        default:
8174            goto cp0_unimplemented;
8175        }
8176        break;
8177    case CP0_REGISTER_30:
8178        switch (sel) {
8179        case CP0_REG30__ERROREPC:
8180            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8181            register_name = "ErrorEPC";
8182            break;
8183        default:
8184            goto cp0_unimplemented;
8185        }
8186        break;
8187    case CP0_REGISTER_31:
8188        switch (sel) {
8189        case CP0_REG31__DESAVE:
8190            /* EJTAG support */
8191            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8192            register_name = "DESAVE";
8193            break;
8194        case CP0_REG31__KSCRATCH1:
8195        case CP0_REG31__KSCRATCH2:
8196        case CP0_REG31__KSCRATCH3:
8197        case CP0_REG31__KSCRATCH4:
8198        case CP0_REG31__KSCRATCH5:
8199        case CP0_REG31__KSCRATCH6:
8200            CP0_CHECK(ctx->kscrexist & (1 << sel));
8201            tcg_gen_ld_tl(arg, cpu_env,
8202                          offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
8203            register_name = "KScratch";
8204            break;
8205        default:
8206            goto cp0_unimplemented;
8207        }
8208        break;
8209    default:
8210        goto cp0_unimplemented;
8211    }
8212    trace_mips_translate_c0("dmfc0", register_name, reg, sel);
8213    return;
8214
8215cp0_unimplemented:
8216    qemu_log_mask(LOG_UNIMP, "dmfc0 %s (reg %d sel %d)\n",
8217                  register_name, reg, sel);
8218    gen_mfc0_unimplemented(ctx, arg);
8219}
8220
8221static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
8222{
8223    const char *register_name = "invalid";
8224
8225    if (sel != 0) {
8226        check_insn(ctx, ISA_MIPS_R1);
8227    }
8228
8229    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8230        gen_io_start();
8231    }
8232
8233    switch (reg) {
8234    case CP0_REGISTER_00:
8235        switch (sel) {
8236        case CP0_REG00__INDEX:
8237            gen_helper_mtc0_index(cpu_env, arg);
8238            register_name = "Index";
8239            break;
8240        case CP0_REG00__MVPCONTROL:
8241            CP0_CHECK(ctx->insn_flags & ASE_MT);
8242            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
8243            register_name = "MVPControl";
8244            break;
8245        case CP0_REG00__MVPCONF0:
8246            CP0_CHECK(ctx->insn_flags & ASE_MT);
8247            /* ignored */
8248            register_name = "MVPConf0";
8249            break;
8250        case CP0_REG00__MVPCONF1:
8251            CP0_CHECK(ctx->insn_flags & ASE_MT);
8252            /* ignored */
8253            register_name = "MVPConf1";
8254            break;
8255        case CP0_REG00__VPCONTROL:
8256            CP0_CHECK(ctx->vp);
8257            /* ignored */
8258            register_name = "VPControl";
8259            break;
8260        default:
8261            goto cp0_unimplemented;
8262        }
8263        break;
8264    case CP0_REGISTER_01:
8265        switch (sel) {
8266        case CP0_REG01__RANDOM:
8267            /* ignored */
8268            register_name = "Random";
8269            break;
8270        case CP0_REG01__VPECONTROL:
8271            CP0_CHECK(ctx->insn_flags & ASE_MT);
8272            gen_helper_mtc0_vpecontrol(cpu_env, arg);
8273            register_name = "VPEControl";
8274            break;
8275        case CP0_REG01__VPECONF0:
8276            CP0_CHECK(ctx->insn_flags & ASE_MT);
8277            gen_helper_mtc0_vpeconf0(cpu_env, arg);
8278            register_name = "VPEConf0";
8279            break;
8280        case CP0_REG01__VPECONF1:
8281            CP0_CHECK(ctx->insn_flags & ASE_MT);
8282            gen_helper_mtc0_vpeconf1(cpu_env, arg);
8283            register_name = "VPEConf1";
8284            break;
8285        case CP0_REG01__YQMASK:
8286            CP0_CHECK(ctx->insn_flags & ASE_MT);
8287            gen_helper_mtc0_yqmask(cpu_env, arg);
8288            register_name = "YQMask";
8289            break;
8290        case CP0_REG01__VPESCHEDULE:
8291            CP0_CHECK(ctx->insn_flags & ASE_MT);
8292            tcg_gen_st_tl(arg, cpu_env,
8293                          offsetof(CPUMIPSState, CP0_VPESchedule));
8294            register_name = "VPESchedule";
8295            break;
8296        case CP0_REG01__VPESCHEFBACK:
8297            CP0_CHECK(ctx->insn_flags & ASE_MT);
8298            tcg_gen_st_tl(arg, cpu_env,
8299                          offsetof(CPUMIPSState, CP0_VPEScheFBack));
8300            register_name = "VPEScheFBack";
8301            break;
8302        case CP0_REG01__VPEOPT:
8303            CP0_CHECK(ctx->insn_flags & ASE_MT);
8304            gen_helper_mtc0_vpeopt(cpu_env, arg);
8305            register_name = "VPEOpt";
8306            break;
8307        default:
8308            goto cp0_unimplemented;
8309        }
8310        break;
8311    case CP0_REGISTER_02:
8312        switch (sel) {
8313        case CP0_REG02__ENTRYLO0:
8314            gen_helper_dmtc0_entrylo0(cpu_env, arg);
8315            register_name = "EntryLo0";
8316            break;
8317        case CP0_REG02__TCSTATUS:
8318            CP0_CHECK(ctx->insn_flags & ASE_MT);
8319            gen_helper_mtc0_tcstatus(cpu_env, arg);
8320            register_name = "TCStatus";
8321            break;
8322        case CP0_REG02__TCBIND:
8323            CP0_CHECK(ctx->insn_flags & ASE_MT);
8324            gen_helper_mtc0_tcbind(cpu_env, arg);
8325            register_name = "TCBind";
8326            break;
8327        case CP0_REG02__TCRESTART:
8328            CP0_CHECK(ctx->insn_flags & ASE_MT);
8329            gen_helper_mtc0_tcrestart(cpu_env, arg);
8330            register_name = "TCRestart";
8331            break;
8332        case CP0_REG02__TCHALT:
8333            CP0_CHECK(ctx->insn_flags & ASE_MT);
8334            gen_helper_mtc0_tchalt(cpu_env, arg);
8335            register_name = "TCHalt";
8336            break;
8337        case CP0_REG02__TCCONTEXT:
8338            CP0_CHECK(ctx->insn_flags & ASE_MT);
8339            gen_helper_mtc0_tccontext(cpu_env, arg);
8340            register_name = "TCContext";
8341            break;
8342        case CP0_REG02__TCSCHEDULE:
8343            CP0_CHECK(ctx->insn_flags & ASE_MT);
8344            gen_helper_mtc0_tcschedule(cpu_env, arg);
8345            register_name = "TCSchedule";
8346            break;
8347        case CP0_REG02__TCSCHEFBACK:
8348            CP0_CHECK(ctx->insn_flags & ASE_MT);
8349            gen_helper_mtc0_tcschefback(cpu_env, arg);
8350            register_name = "TCScheFBack";
8351            break;
8352        default:
8353            goto cp0_unimplemented;
8354        }
8355        break;
8356    case CP0_REGISTER_03:
8357        switch (sel) {
8358        case CP0_REG03__ENTRYLO1:
8359            gen_helper_dmtc0_entrylo1(cpu_env, arg);
8360            register_name = "EntryLo1";
8361            break;
8362        case CP0_REG03__GLOBALNUM:
8363            CP0_CHECK(ctx->vp);
8364            /* ignored */
8365            register_name = "GlobalNumber";
8366            break;
8367        default:
8368            goto cp0_unimplemented;
8369        }
8370        break;
8371    case CP0_REGISTER_04:
8372        switch (sel) {
8373        case CP0_REG04__CONTEXT:
8374            gen_helper_mtc0_context(cpu_env, arg);
8375            register_name = "Context";
8376            break;
8377        case CP0_REG04__CONTEXTCONFIG:
8378            /* SmartMIPS ASE */
8379            /* gen_helper_dmtc0_contextconfig(arg); */
8380            register_name = "ContextConfig";
8381            goto cp0_unimplemented;
8382        case CP0_REG04__USERLOCAL:
8383            CP0_CHECK(ctx->ulri);
8384            tcg_gen_st_tl(arg, cpu_env,
8385                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
8386            register_name = "UserLocal";
8387            break;
8388        case CP0_REG04__MMID:
8389            CP0_CHECK(ctx->mi);
8390            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_MemoryMapID));
8391            register_name = "MMID";
8392            break;
8393        default:
8394            goto cp0_unimplemented;
8395        }
8396        break;
8397    case CP0_REGISTER_05:
8398        switch (sel) {
8399        case CP0_REG05__PAGEMASK:
8400            gen_helper_mtc0_pagemask(cpu_env, arg);
8401            register_name = "PageMask";
8402            break;
8403        case CP0_REG05__PAGEGRAIN:
8404            check_insn(ctx, ISA_MIPS_R2);
8405            gen_helper_mtc0_pagegrain(cpu_env, arg);
8406            register_name = "PageGrain";
8407            break;
8408        case CP0_REG05__SEGCTL0:
8409            CP0_CHECK(ctx->sc);
8410            gen_helper_mtc0_segctl0(cpu_env, arg);
8411            register_name = "SegCtl0";
8412            break;
8413        case CP0_REG05__SEGCTL1:
8414            CP0_CHECK(ctx->sc);
8415            gen_helper_mtc0_segctl1(cpu_env, arg);
8416            register_name = "SegCtl1";
8417            break;
8418        case CP0_REG05__SEGCTL2:
8419            CP0_CHECK(ctx->sc);
8420            gen_helper_mtc0_segctl2(cpu_env, arg);
8421            register_name = "SegCtl2";
8422            break;
8423        case CP0_REG05__PWBASE:
8424            check_pw(ctx);
8425            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_PWBase));
8426            register_name = "PWBase";
8427            break;
8428        case CP0_REG05__PWFIELD:
8429            check_pw(ctx);
8430            gen_helper_mtc0_pwfield(cpu_env, arg);
8431            register_name = "PWField";
8432            break;
8433        case CP0_REG05__PWSIZE:
8434            check_pw(ctx);
8435            gen_helper_mtc0_pwsize(cpu_env, arg);
8436            register_name = "PWSize";
8437            break;
8438        default:
8439            goto cp0_unimplemented;
8440        }
8441        break;
8442    case CP0_REGISTER_06:
8443        switch (sel) {
8444        case CP0_REG06__WIRED:
8445            gen_helper_mtc0_wired(cpu_env, arg);
8446            register_name = "Wired";
8447            break;
8448        case CP0_REG06__SRSCONF0:
8449            check_insn(ctx, ISA_MIPS_R2);
8450            gen_helper_mtc0_srsconf0(cpu_env, arg);
8451            register_name = "SRSConf0";
8452            break;
8453        case CP0_REG06__SRSCONF1:
8454            check_insn(ctx, ISA_MIPS_R2);
8455            gen_helper_mtc0_srsconf1(cpu_env, arg);
8456            register_name = "SRSConf1";
8457            break;
8458        case CP0_REG06__SRSCONF2:
8459            check_insn(ctx, ISA_MIPS_R2);
8460            gen_helper_mtc0_srsconf2(cpu_env, arg);
8461            register_name = "SRSConf2";
8462            break;
8463        case CP0_REG06__SRSCONF3:
8464            check_insn(ctx, ISA_MIPS_R2);
8465            gen_helper_mtc0_srsconf3(cpu_env, arg);
8466            register_name = "SRSConf3";
8467            break;
8468        case CP0_REG06__SRSCONF4:
8469            check_insn(ctx, ISA_MIPS_R2);
8470            gen_helper_mtc0_srsconf4(cpu_env, arg);
8471            register_name = "SRSConf4";
8472            break;
8473        case CP0_REG06__PWCTL:
8474            check_pw(ctx);
8475            gen_helper_mtc0_pwctl(cpu_env, arg);
8476            register_name = "PWCtl";
8477            break;
8478        default:
8479            goto cp0_unimplemented;
8480        }
8481        break;
8482    case CP0_REGISTER_07:
8483        switch (sel) {
8484        case CP0_REG07__HWRENA:
8485            check_insn(ctx, ISA_MIPS_R2);
8486            gen_helper_mtc0_hwrena(cpu_env, arg);
8487            ctx->base.is_jmp = DISAS_STOP;
8488            register_name = "HWREna";
8489            break;
8490        default:
8491            goto cp0_unimplemented;
8492        }
8493        break;
8494    case CP0_REGISTER_08:
8495        switch (sel) {
8496        case CP0_REG08__BADVADDR:
8497            /* ignored */
8498            register_name = "BadVAddr";
8499            break;
8500        case CP0_REG08__BADINSTR:
8501            /* ignored */
8502            register_name = "BadInstr";
8503            break;
8504        case CP0_REG08__BADINSTRP:
8505            /* ignored */
8506            register_name = "BadInstrP";
8507            break;
8508        case CP0_REG08__BADINSTRX:
8509            /* ignored */
8510            register_name = "BadInstrX";
8511            break;
8512        default:
8513            goto cp0_unimplemented;
8514        }
8515        break;
8516    case CP0_REGISTER_09:
8517        switch (sel) {
8518        case CP0_REG09__COUNT:
8519            gen_helper_mtc0_count(cpu_env, arg);
8520            register_name = "Count";
8521            break;
8522        case CP0_REG09__SAARI:
8523            CP0_CHECK(ctx->saar);
8524            gen_helper_mtc0_saari(cpu_env, arg);
8525            register_name = "SAARI";
8526            break;
8527        case CP0_REG09__SAAR:
8528            CP0_CHECK(ctx->saar);
8529            gen_helper_mtc0_saar(cpu_env, arg);
8530            register_name = "SAAR";
8531            break;
8532        default:
8533            goto cp0_unimplemented;
8534        }
8535        /* Stop translation as we may have switched the execution mode */
8536        ctx->base.is_jmp = DISAS_STOP;
8537        break;
8538    case CP0_REGISTER_10:
8539        switch (sel) {
8540        case CP0_REG10__ENTRYHI:
8541            gen_helper_mtc0_entryhi(cpu_env, arg);
8542            register_name = "EntryHi";
8543            break;
8544        default:
8545            goto cp0_unimplemented;
8546        }
8547        break;
8548    case CP0_REGISTER_11:
8549        switch (sel) {
8550        case CP0_REG11__COMPARE:
8551            gen_helper_mtc0_compare(cpu_env, arg);
8552            register_name = "Compare";
8553            break;
8554        /* 6,7 are implementation dependent */
8555        default:
8556            goto cp0_unimplemented;
8557        }
8558        /* Stop translation as we may have switched the execution mode */
8559        ctx->base.is_jmp = DISAS_STOP;
8560        break;
8561    case CP0_REGISTER_12:
8562        switch (sel) {
8563        case CP0_REG12__STATUS:
8564            save_cpu_state(ctx, 1);
8565            gen_helper_mtc0_status(cpu_env, arg);
8566            /* DISAS_STOP isn't good enough here, hflags may have changed. */
8567            gen_save_pc(ctx->base.pc_next + 4);
8568            ctx->base.is_jmp = DISAS_EXIT;
8569            register_name = "Status";
8570            break;
8571        case CP0_REG12__INTCTL:
8572            check_insn(ctx, ISA_MIPS_R2);
8573            gen_helper_mtc0_intctl(cpu_env, arg);
8574            /* Stop translation as we may have switched the execution mode */
8575            ctx->base.is_jmp = DISAS_STOP;
8576            register_name = "IntCtl";
8577            break;
8578        case CP0_REG12__SRSCTL:
8579            check_insn(ctx, ISA_MIPS_R2);
8580            gen_helper_mtc0_srsctl(cpu_env, arg);
8581            /* Stop translation as we may have switched the execution mode */
8582            ctx->base.is_jmp = DISAS_STOP;
8583            register_name = "SRSCtl";
8584            break;
8585        case CP0_REG12__SRSMAP:
8586            check_insn(ctx, ISA_MIPS_R2);
8587            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
8588            /* Stop translation as we may have switched the execution mode */
8589            ctx->base.is_jmp = DISAS_STOP;
8590            register_name = "SRSMap";
8591            break;
8592        default:
8593            goto cp0_unimplemented;
8594        }
8595        break;
8596    case CP0_REGISTER_13:
8597        switch (sel) {
8598        case CP0_REG13__CAUSE:
8599            save_cpu_state(ctx, 1);
8600            gen_helper_mtc0_cause(cpu_env, arg);
8601            /*
8602             * Stop translation as we may have triggered an interrupt.
8603             * DISAS_STOP isn't sufficient, we need to ensure we break out of
8604             * translated code to check for pending interrupts.
8605             */
8606            gen_save_pc(ctx->base.pc_next + 4);
8607            ctx->base.is_jmp = DISAS_EXIT;
8608            register_name = "Cause";
8609            break;
8610        default:
8611            goto cp0_unimplemented;
8612        }
8613        break;
8614    case CP0_REGISTER_14:
8615        switch (sel) {
8616        case CP0_REG14__EPC:
8617            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
8618            register_name = "EPC";
8619            break;
8620        default:
8621            goto cp0_unimplemented;
8622        }
8623        break;
8624    case CP0_REGISTER_15:
8625        switch (sel) {
8626        case CP0_REG15__PRID:
8627            /* ignored */
8628            register_name = "PRid";
8629            break;
8630        case CP0_REG15__EBASE:
8631            check_insn(ctx, ISA_MIPS_R2);
8632            gen_helper_mtc0_ebase(cpu_env, arg);
8633            register_name = "EBase";
8634            break;
8635        default:
8636            goto cp0_unimplemented;
8637        }
8638        break;
8639    case CP0_REGISTER_16:
8640        switch (sel) {
8641        case CP0_REG16__CONFIG:
8642            gen_helper_mtc0_config0(cpu_env, arg);
8643            register_name = "Config";
8644            /* Stop translation as we may have switched the execution mode */
8645            ctx->base.is_jmp = DISAS_STOP;
8646            break;
8647        case CP0_REG16__CONFIG1:
8648            /* ignored, read only */
8649            register_name = "Config1";
8650            break;
8651        case CP0_REG16__CONFIG2:
8652            gen_helper_mtc0_config2(cpu_env, arg);
8653            register_name = "Config2";
8654            /* Stop translation as we may have switched the execution mode */
8655            ctx->base.is_jmp = DISAS_STOP;
8656            break;
8657        case CP0_REG16__CONFIG3:
8658            gen_helper_mtc0_config3(cpu_env, arg);
8659            register_name = "Config3";
8660            /* Stop translation as we may have switched the execution mode */
8661            ctx->base.is_jmp = DISAS_STOP;
8662            break;
8663        case CP0_REG16__CONFIG4:
8664            /* currently ignored */
8665            register_name = "Config4";
8666            break;
8667        case CP0_REG16__CONFIG5:
8668            gen_helper_mtc0_config5(cpu_env, arg);
8669            register_name = "Config5";
8670            /* Stop translation as we may have switched the execution mode */
8671            ctx->base.is_jmp = DISAS_STOP;
8672            break;
8673        /* 6,7 are implementation dependent */
8674        default:
8675            register_name = "Invalid config selector";
8676            goto cp0_unimplemented;
8677        }
8678        break;
8679    case CP0_REGISTER_17:
8680        switch (sel) {
8681        case CP0_REG17__LLADDR:
8682            gen_helper_mtc0_lladdr(cpu_env, arg);
8683            register_name = "LLAddr";
8684            break;
8685        case CP0_REG17__MAAR:
8686            CP0_CHECK(ctx->mrp);
8687            gen_helper_mtc0_maar(cpu_env, arg);
8688            register_name = "MAAR";
8689            break;
8690        case CP0_REG17__MAARI:
8691            CP0_CHECK(ctx->mrp);
8692            gen_helper_mtc0_maari(cpu_env, arg);
8693            register_name = "MAARI";
8694            break;
8695        default:
8696            goto cp0_unimplemented;
8697        }
8698        break;
8699    case CP0_REGISTER_18:
8700        switch (sel) {
8701        case CP0_REG18__WATCHLO0:
8702        case CP0_REG18__WATCHLO1:
8703        case CP0_REG18__WATCHLO2:
8704        case CP0_REG18__WATCHLO3:
8705        case CP0_REG18__WATCHLO4:
8706        case CP0_REG18__WATCHLO5:
8707        case CP0_REG18__WATCHLO6:
8708        case CP0_REG18__WATCHLO7:
8709            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8710            gen_helper_0e1i(mtc0_watchlo, arg, sel);
8711            register_name = "WatchLo";
8712            break;
8713        default:
8714            goto cp0_unimplemented;
8715        }
8716        break;
8717    case CP0_REGISTER_19:
8718        switch (sel) {
8719        case CP0_REG19__WATCHHI0:
8720        case CP0_REG19__WATCHHI1:
8721        case CP0_REG19__WATCHHI2:
8722        case CP0_REG19__WATCHHI3:
8723        case CP0_REG19__WATCHHI4:
8724        case CP0_REG19__WATCHHI5:
8725        case CP0_REG19__WATCHHI6:
8726        case CP0_REG19__WATCHHI7:
8727            CP0_CHECK(ctx->CP0_Config1 & (1 << CP0C1_WR));
8728            gen_helper_0e1i(mtc0_watchhi, arg, sel);
8729            register_name = "WatchHi";
8730            break;
8731        default:
8732            goto cp0_unimplemented;
8733        }
8734        break;
8735    case CP0_REGISTER_20:
8736        switch (sel) {
8737        case CP0_REG20__XCONTEXT:
8738            check_insn(ctx, ISA_MIPS3);
8739            gen_helper_mtc0_xcontext(cpu_env, arg);
8740            register_name = "XContext";
8741            break;
8742        default:
8743            goto cp0_unimplemented;
8744        }
8745        break;
8746    case CP0_REGISTER_21:
8747       /* Officially reserved, but sel 0 is used for R1x000 framemask */
8748        CP0_CHECK(!(ctx->insn_flags & ISA_MIPS_R6));
8749        switch (sel) {
8750        case 0:
8751            gen_helper_mtc0_framemask(cpu_env, arg);
8752            register_name = "Framemask";
8753            break;
8754        default:
8755            goto cp0_unimplemented;
8756        }
8757        break;
8758    case CP0_REGISTER_22:
8759        /* ignored */
8760        register_name = "Diagnostic"; /* implementation dependent */
8761        break;
8762    case CP0_REGISTER_23:
8763        switch (sel) {
8764        case CP0_REG23__DEBUG:
8765            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
8766            /* DISAS_STOP isn't good enough here, hflags may have changed. */
8767            gen_save_pc(ctx->base.pc_next + 4);
8768            ctx->base.is_jmp = DISAS_EXIT;
8769            register_name = "Debug";
8770            break;
8771        case CP0_REG23__TRACECONTROL:
8772            /* PDtrace support */
8773            /* gen_helper_mtc0_tracecontrol(cpu_env, arg);  */
8774            /* Stop translation as we may have switched the execution mode */
8775            ctx->base.is_jmp = DISAS_STOP;
8776            register_name = "TraceControl";
8777            goto cp0_unimplemented;
8778        case CP0_REG23__TRACECONTROL2:
8779            /* PDtrace support */
8780            /* gen_helper_mtc0_tracecontrol2(cpu_env, arg); */
8781            /* Stop translation as we may have switched the execution mode */
8782            ctx->base.is_jmp = DISAS_STOP;
8783            register_name = "TraceControl2";
8784            goto cp0_unimplemented;
8785        case CP0_REG23__USERTRACEDATA1:
8786            /* PDtrace support */
8787            /* gen_helper_mtc0_usertracedata1(cpu_env, arg);*/
8788            /* Stop translation as we may have switched the execution mode */
8789            ctx->base.is_jmp = DISAS_STOP;
8790            register_name = "UserTraceData1";
8791            goto cp0_unimplemented;
8792        case CP0_REG23__TRACEIBPC:
8793            /* PDtrace support */
8794            /* gen_helper_mtc0_traceibpc(cpu_env, arg);     */
8795            /* Stop translation as we may have switched the execution mode */
8796            ctx->base.is_jmp = DISAS_STOP;
8797            register_name = "TraceIBPC";
8798            goto cp0_unimplemented;
8799        case CP0_REG23__TRACEDBPC:
8800            /* PDtrace support */
8801            /* gen_helper_mtc0_tracedbpc(cpu_env, arg);     */
8802            /* Stop translation as we may have switched the execution mode */
8803            ctx->base.is_jmp = DISAS_STOP;
8804            register_name = "TraceDBPC";
8805            goto cp0_unimplemented;
8806        default:
8807            goto cp0_unimplemented;
8808        }
8809        break;
8810    case CP0_REGISTER_24:
8811        switch (sel) {
8812        case CP0_REG24__DEPC:
8813            /* EJTAG support */
8814            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
8815            register_name = "DEPC";
8816            break;
8817        default:
8818            goto cp0_unimplemented;
8819        }
8820        break;
8821    case CP0_REGISTER_25:
8822        switch (sel) {
8823        case CP0_REG25__PERFCTL0:
8824            gen_helper_mtc0_performance0(cpu_env, arg);
8825            register_name = "Performance0";
8826            break;
8827        case CP0_REG25__PERFCNT0:
8828            /* gen_helper_mtc0_performance1(cpu_env, arg); */
8829            register_name = "Performance1";
8830            goto cp0_unimplemented;
8831        case CP0_REG25__PERFCTL1:
8832            /* gen_helper_mtc0_performance2(cpu_env, arg); */
8833            register_name = "Performance2";
8834            goto cp0_unimplemented;
8835        case CP0_REG25__PERFCNT1:
8836            /* gen_helper_mtc0_performance3(cpu_env, arg); */
8837            register_name = "Performance3";
8838            goto cp0_unimplemented;
8839        case CP0_REG25__PERFCTL2:
8840            /* gen_helper_mtc0_performance4(cpu_env, arg); */
8841            register_name = "Performance4";
8842            goto cp0_unimplemented;
8843        case CP0_REG25__PERFCNT2:
8844            /* gen_helper_mtc0_performance5(cpu_env, arg); */
8845            register_name = "Performance5";
8846            goto cp0_unimplemented;
8847        case CP0_REG25__PERFCTL3:
8848            /* gen_helper_mtc0_performance6(cpu_env, arg); */
8849            register_name = "Performance6";
8850            goto cp0_unimplemented;
8851        case CP0_REG25__PERFCNT3:
8852            /* gen_helper_mtc0_performance7(cpu_env, arg); */
8853            register_name = "Performance7";
8854            goto cp0_unimplemented;
8855        default:
8856            goto cp0_unimplemented;
8857        }
8858        break;
8859    case CP0_REGISTER_26:
8860        switch (sel) {
8861        case CP0_REG26__ERRCTL:
8862            gen_helper_mtc0_errctl(cpu_env, arg);
8863            ctx->base.is_jmp = DISAS_STOP;
8864            register_name = "ErrCtl";
8865            break;
8866        default:
8867            goto cp0_unimplemented;
8868        }
8869        break;
8870    case CP0_REGISTER_27:
8871        switch (sel) {
8872        case CP0_REG27__CACHERR:
8873            /* ignored */
8874            register_name = "CacheErr";
8875            break;
8876        default:
8877            goto cp0_unimplemented;
8878        }
8879        break;
8880    case CP0_REGISTER_28:
8881        switch (sel) {
8882        case CP0_REG28__TAGLO:
8883        case CP0_REG28__TAGLO1:
8884        case CP0_REG28__TAGLO2:
8885        case CP0_REG28__TAGLO3:
8886            gen_helper_mtc0_taglo(cpu_env, arg);
8887            register_name = "TagLo";
8888            break;
8889        case CP0_REG28__DATALO:
8890        case CP0_REG28__DATALO1:
8891        case CP0_REG28__DATALO2:
8892        case CP0_REG28__DATALO3:
8893            gen_helper_mtc0_datalo(cpu_env, arg);
8894            register_name = "DataLo";
8895            break;
8896        default:
8897            goto cp0_unimplemented;
8898        }
8899        break;
8900    case CP0_REGISTER_29:
8901        switch (sel) {
8902        case CP0_REG29__TAGHI:
8903        case CP0_REG29__TAGHI1:
8904        case CP0_REG29__TAGHI2:
8905        case CP0_REG29__TAGHI3:
8906            gen_helper_mtc0_taghi(cpu_env, arg);
8907            register_name = "TagHi";
8908            break;
8909        case CP0_REG29__DATAHI:
8910        case CP0_REG29__DATAHI1:
8911        case CP0_REG29__DATAHI2:
8912        case CP0_REG29__DATAHI3:
8913            gen_helper_mtc0_datahi(cpu_env, arg);
8914            register_name = "DataHi";
8915            break;
8916        default:
8917            register_name = "invalid sel";
8918            goto cp0_unimplemented;
8919        }
8920        break;
8921    case CP0_REGISTER_30:
8922        switch (sel) {
8923        case CP0_REG30__ERROREPC:
8924            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
8925            register_name = "ErrorEPC";
8926            break;
8927        default:
8928            goto cp0_unimplemented;
8929        }
8930        break;
8931    case CP0_REGISTER_31:
8932        switch (sel) {
8933        case CP0_REG31__DESAVE:
8934            /* EJTAG support */
8935            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
8936            register_name = "DESAVE";
8937            break;
8938        case CP0_REG31__KSCRATCH1:
8939        case CP0_REG31__KSCRATCH2:
8940        case CP0_REG31__KSCRATCH3:
8941        case CP0_REG31__KSCRATCH4:
8942        case CP0_REG31__KSCRATCH5:
8943        case CP0_REG31__KSCRATCH6:
8944            CP0_CHECK(ctx->kscrexist & (1 << sel));
8945            tcg_gen_st_tl(arg, cpu_env,
8946                          offsetof(CPUMIPSState, CP0_KScratch[sel - 2]));
8947            register_name = "KScratch";
8948            break;
8949        default:
8950            goto cp0_unimplemented;
8951        }
8952        break;
8953    default:
8954        goto cp0_unimplemented;
8955    }
8956    trace_mips_translate_c0("dmtc0", register_name, reg, sel);
8957
8958    /* For simplicity assume that all writes can cause interrupts.  */
8959    if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
8960        /*
8961         * DISAS_STOP isn't sufficient, we need to ensure we break out of
8962         * translated code to check for pending interrupts.
8963         */
8964        gen_save_pc(ctx->base.pc_next + 4);
8965        ctx->base.is_jmp = DISAS_EXIT;
8966    }
8967    return;
8968
8969cp0_unimplemented:
8970    qemu_log_mask(LOG_UNIMP, "dmtc0 %s (reg %d sel %d)\n",
8971                  register_name, reg, sel);
8972}
8973#endif /* TARGET_MIPS64 */
8974
8975static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
8976                     int u, int sel, int h)
8977{
8978    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
8979    TCGv t0 = tcg_temp_local_new();
8980
8981    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
8982        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
8983         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
8984        tcg_gen_movi_tl(t0, -1);
8985    } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
8986               (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
8987        tcg_gen_movi_tl(t0, -1);
8988    } else if (u == 0) {
8989        switch (rt) {
8990        case 1:
8991            switch (sel) {
8992            case 1:
8993                gen_helper_mftc0_vpecontrol(t0, cpu_env);
8994                break;
8995            case 2:
8996                gen_helper_mftc0_vpeconf0(t0, cpu_env);
8997                break;
8998            default:
8999                goto die;
9000                break;
9001            }
9002            break;
9003        case 2:
9004            switch (sel) {
9005            case 1:
9006                gen_helper_mftc0_tcstatus(t0, cpu_env);
9007                break;
9008            case 2:
9009                gen_helper_mftc0_tcbind(t0, cpu_env);
9010                break;
9011            case 3:
9012                gen_helper_mftc0_tcrestart(t0, cpu_env);
9013                break;
9014            case 4:
9015                gen_helper_mftc0_tchalt(t0, cpu_env);
9016                break;
9017            case 5:
9018                gen_helper_mftc0_tccontext(t0, cpu_env);
9019                break;
9020            case 6:
9021                gen_helper_mftc0_tcschedule(t0, cpu_env);
9022                break;
9023            case 7:
9024                gen_helper_mftc0_tcschefback(t0, cpu_env);
9025                break;
9026            default:
9027                gen_mfc0(ctx, t0, rt, sel);
9028                break;
9029            }
9030            break;
9031        case 10:
9032            switch (sel) {
9033            case 0:
9034                gen_helper_mftc0_entryhi(t0, cpu_env);
9035                break;
9036            default:
9037                gen_mfc0(ctx, t0, rt, sel);
9038                break;
9039            }
9040            break;
9041        case 12:
9042            switch (sel) {
9043            case 0:
9044                gen_helper_mftc0_status(t0, cpu_env);
9045                break;
9046            default:
9047                gen_mfc0(ctx, t0, rt, sel);
9048                break;
9049            }
9050            break;
9051        case 13:
9052            switch (sel) {
9053            case 0:
9054                gen_helper_mftc0_cause(t0, cpu_env);
9055                break;
9056            default:
9057                goto die;
9058                break;
9059            }
9060            break;
9061        case 14:
9062            switch (sel) {
9063            case 0:
9064                gen_helper_mftc0_epc(t0, cpu_env);
9065                break;
9066            default:
9067                goto die;
9068                break;
9069            }
9070            break;
9071        case 15:
9072            switch (sel) {
9073            case 1:
9074                gen_helper_mftc0_ebase(t0, cpu_env);
9075                break;
9076            default:
9077                goto die;
9078                break;
9079            }
9080            break;
9081        case 16:
9082            switch (sel) {
9083            case 0:
9084            case 1:
9085            case 2:
9086            case 3:
9087            case 4:
9088            case 5:
9089            case 6:
9090            case 7:
9091                gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
9092                break;
9093            default:
9094                goto die;
9095                break;
9096            }
9097            break;
9098        case 23:
9099            switch (sel) {
9100            case 0:
9101                gen_helper_mftc0_debug(t0, cpu_env);
9102                break;
9103            default:
9104                gen_mfc0(ctx, t0, rt, sel);
9105                break;
9106            }
9107            break;
9108        default:
9109            gen_mfc0(ctx, t0, rt, sel);
9110        }
9111    } else {
9112        switch (sel) {
9113        /* GPR registers. */
9114        case 0:
9115            gen_helper_1e0i(mftgpr, t0, rt);
9116            break;
9117        /* Auxiliary CPU registers */
9118        case 1:
9119            switch (rt) {
9120            case 0:
9121                gen_helper_1e0i(mftlo, t0, 0);
9122                break;
9123            case 1:
9124                gen_helper_1e0i(mfthi, t0, 0);
9125                break;
9126            case 2:
9127                gen_helper_1e0i(mftacx, t0, 0);
9128                break;
9129            case 4:
9130                gen_helper_1e0i(mftlo, t0, 1);
9131                break;
9132            case 5:
9133                gen_helper_1e0i(mfthi, t0, 1);
9134                break;
9135            case 6:
9136                gen_helper_1e0i(mftacx, t0, 1);
9137                break;
9138            case 8:
9139                gen_helper_1e0i(mftlo, t0, 2);
9140                break;
9141            case 9:
9142                gen_helper_1e0i(mfthi, t0, 2);
9143                break;
9144            case 10:
9145                gen_helper_1e0i(mftacx, t0, 2);
9146                break;
9147            case 12:
9148                gen_helper_1e0i(mftlo, t0, 3);
9149                break;
9150            case 13:
9151                gen_helper_1e0i(mfthi, t0, 3);
9152                break;
9153            case 14:
9154                gen_helper_1e0i(mftacx, t0, 3);
9155                break;
9156            case 16:
9157                gen_helper_mftdsp(t0, cpu_env);
9158                break;
9159            default:
9160                goto die;
9161            }
9162            break;
9163        /* Floating point (COP1). */
9164        case 2:
9165            /* XXX: For now we support only a single FPU context. */
9166            if (h == 0) {
9167                TCGv_i32 fp0 = tcg_temp_new_i32();
9168
9169                gen_load_fpr32(ctx, fp0, rt);
9170                tcg_gen_ext_i32_tl(t0, fp0);
9171                tcg_temp_free_i32(fp0);
9172            } else {
9173                TCGv_i32 fp0 = tcg_temp_new_i32();
9174
9175                gen_load_fpr32h(ctx, fp0, rt);
9176                tcg_gen_ext_i32_tl(t0, fp0);
9177                tcg_temp_free_i32(fp0);
9178            }
9179            break;
9180        case 3:
9181            /* XXX: For now we support only a single FPU context. */
9182            gen_helper_1e0i(cfc1, t0, rt);
9183            break;
9184        /* COP2: Not implemented. */
9185        case 4:
9186        case 5:
9187            /* fall through */
9188        default:
9189            goto die;
9190        }
9191    }
9192    trace_mips_translate_tr("mftr", rt, u, sel, h);
9193    gen_store_gpr(t0, rd);
9194    tcg_temp_free(t0);
9195    return;
9196
9197die:
9198    tcg_temp_free(t0);
9199    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
9200    gen_reserved_instruction(ctx);
9201}
9202
9203static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
9204                     int u, int sel, int h)
9205{
9206    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
9207    TCGv t0 = tcg_temp_local_new();
9208
9209    gen_load_gpr(t0, rt);
9210    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
9211        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
9212         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE)))) {
9213        /* NOP */
9214        ;
9215    } else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
9216             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC))) {
9217        /* NOP */
9218        ;
9219    } else if (u == 0) {
9220        switch (rd) {
9221        case 1:
9222            switch (sel) {
9223            case 1:
9224                gen_helper_mttc0_vpecontrol(cpu_env, t0);
9225                break;
9226            case 2:
9227                gen_helper_mttc0_vpeconf0(cpu_env, t0);
9228                break;
9229            default:
9230                goto die;
9231                break;
9232            }
9233            break;
9234        case 2:
9235            switch (sel) {
9236            case 1:
9237                gen_helper_mttc0_tcstatus(cpu_env, t0);
9238                break;
9239            case 2:
9240                gen_helper_mttc0_tcbind(cpu_env, t0);
9241                break;
9242            case 3:
9243                gen_helper_mttc0_tcrestart(cpu_env, t0);
9244                break;
9245            case 4:
9246                gen_helper_mttc0_tchalt(cpu_env, t0);
9247                break;
9248            case 5:
9249                gen_helper_mttc0_tccontext(cpu_env, t0);
9250                break;
9251            case 6:
9252                gen_helper_mttc0_tcschedule(cpu_env, t0);
9253                break;
9254            case 7:
9255                gen_helper_mttc0_tcschefback(cpu_env, t0);
9256                break;
9257            default:
9258                gen_mtc0(ctx, t0, rd, sel);
9259                break;
9260            }
9261            break;
9262        case 10:
9263            switch (sel) {
9264            case 0:
9265                gen_helper_mttc0_entryhi(cpu_env, t0);
9266                break;
9267            default:
9268                gen_mtc0(ctx, t0, rd, sel);
9269                break;
9270            }
9271            break;
9272        case 12:
9273            switch (sel) {
9274            case 0:
9275                gen_helper_mttc0_status(cpu_env, t0);
9276                break;
9277            default:
9278                gen_mtc0(ctx, t0, rd, sel);
9279                break;
9280            }
9281            break;
9282        case 13:
9283            switch (sel) {
9284            case 0:
9285                gen_helper_mttc0_cause(cpu_env, t0);
9286                break;
9287            default:
9288                goto die;
9289                break;
9290            }
9291            break;
9292        case 15:
9293            switch (sel) {
9294            case 1:
9295                gen_helper_mttc0_ebase(cpu_env, t0);
9296                break;
9297            default:
9298                goto die;
9299                break;
9300            }
9301            break;
9302        case 23:
9303            switch (sel) {
9304            case 0:
9305                gen_helper_mttc0_debug(cpu_env, t0);
9306                break;
9307            default:
9308                gen_mtc0(ctx, t0, rd, sel);
9309                break;
9310            }
9311            break;
9312        default:
9313            gen_mtc0(ctx, t0, rd, sel);
9314        }
9315    } else {
9316        switch (sel) {
9317        /* GPR registers. */
9318        case 0:
9319            gen_helper_0e1i(mttgpr, t0, rd);
9320            break;
9321        /* Auxiliary CPU registers */
9322        case 1:
9323            switch (rd) {
9324            case 0:
9325                gen_helper_0e1i(mttlo, t0, 0);
9326                break;
9327            case 1:
9328                gen_helper_0e1i(mtthi, t0, 0);
9329                break;
9330            case 2:
9331                gen_helper_0e1i(mttacx, t0, 0);
9332                break;
9333            case 4:
9334                gen_helper_0e1i(mttlo, t0, 1);
9335                break;
9336            case 5:
9337                gen_helper_0e1i(mtthi, t0, 1);
9338                break;
9339            case 6:
9340                gen_helper_0e1i(mttacx, t0, 1);
9341                break;
9342            case 8:
9343                gen_helper_0e1i(mttlo, t0, 2);
9344                break;
9345            case 9:
9346                gen_helper_0e1i(mtthi, t0, 2);
9347                break;
9348            case 10:
9349                gen_helper_0e1i(mttacx, t0, 2);
9350                break;
9351            case 12:
9352                gen_helper_0e1i(mttlo, t0, 3);
9353                break;
9354            case 13:
9355                gen_helper_0e1i(mtthi, t0, 3);
9356                break;
9357            case 14:
9358                gen_helper_0e1i(mttacx, t0, 3);
9359                break;
9360            case 16:
9361                gen_helper_mttdsp(cpu_env, t0);
9362                break;
9363            default:
9364                goto die;
9365            }
9366            break;
9367        /* Floating point (COP1). */
9368        case 2:
9369            /* XXX: For now we support only a single FPU context. */
9370            if (h == 0) {
9371                TCGv_i32 fp0 = tcg_temp_new_i32();
9372
9373                tcg_gen_trunc_tl_i32(fp0, t0);
9374                gen_store_fpr32(ctx, fp0, rd);
9375                tcg_temp_free_i32(fp0);
9376            } else {
9377                TCGv_i32 fp0 = tcg_temp_new_i32();
9378
9379                tcg_gen_trunc_tl_i32(fp0, t0);
9380                gen_store_fpr32h(ctx, fp0, rd);
9381                tcg_temp_free_i32(fp0);
9382            }
9383            break;
9384        case 3:
9385            /* XXX: For now we support only a single FPU context. */
9386            {
9387                TCGv_i32 fs_tmp = tcg_const_i32(rd);
9388
9389                gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
9390                tcg_temp_free_i32(fs_tmp);
9391            }
9392            /* Stop translation as we may have changed hflags */
9393            ctx->base.is_jmp = DISAS_STOP;
9394            break;
9395        /* COP2: Not implemented. */
9396        case 4:
9397        case 5:
9398            /* fall through */
9399        default:
9400            goto die;
9401        }
9402    }
9403    trace_mips_translate_tr("mttr", rd, u, sel, h);
9404    tcg_temp_free(t0);
9405    return;
9406
9407die:
9408    tcg_temp_free(t0);
9409    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
9410    gen_reserved_instruction(ctx);
9411}
9412
9413static void gen_cp0(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
9414                    int rt, int rd)
9415{
9416    const char *opn = "ldst";
9417
9418    check_cp0_enabled(ctx);
9419    switch (opc) {
9420    case OPC_MFC0:
9421        if (rt == 0) {
9422            /* Treat as NOP. */
9423            return;
9424        }
9425        gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9426        opn = "mfc0";
9427        break;
9428    case OPC_MTC0:
9429        {
9430            TCGv t0 = tcg_temp_new();
9431
9432            gen_load_gpr(t0, rt);
9433            gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
9434            tcg_temp_free(t0);
9435        }
9436        opn = "mtc0";
9437        break;
9438#if defined(TARGET_MIPS64)
9439    case OPC_DMFC0:
9440        check_insn(ctx, ISA_MIPS3);
9441        if (rt == 0) {
9442            /* Treat as NOP. */
9443            return;
9444        }
9445        gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9446        opn = "dmfc0";
9447        break;
9448    case OPC_DMTC0:
9449        check_insn(ctx, ISA_MIPS3);
9450        {
9451            TCGv t0 = tcg_temp_new();
9452
9453            gen_load_gpr(t0, rt);
9454            gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
9455            tcg_temp_free(t0);
9456        }
9457        opn = "dmtc0";
9458        break;
9459#endif
9460    case OPC_MFHC0:
9461        check_mvh(ctx);
9462        if (rt == 0) {
9463            /* Treat as NOP. */
9464            return;
9465        }
9466        gen_mfhc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
9467        opn = "mfhc0";
9468        break;
9469    case OPC_MTHC0:
9470        check_mvh(ctx);
9471        {
9472            TCGv t0 = tcg_temp_new();
9473            gen_load_gpr(t0, rt);
9474            gen_mthc0(ctx, t0, rd, ctx->opcode & 0x7);
9475            tcg_temp_free(t0);
9476        }
9477        opn = "mthc0";
9478        break;
9479    case OPC_MFTR:
9480        check_cp0_enabled(ctx);
9481        if (rd == 0) {
9482            /* Treat as NOP. */
9483            return;
9484        }
9485        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
9486                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9487        opn = "mftr";
9488        break;
9489    case OPC_MTTR:
9490        check_cp0_enabled(ctx);
9491        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
9492                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
9493        opn = "mttr";
9494        break;
9495    case OPC_TLBWI:
9496        opn = "tlbwi";
9497        if (!env->tlb->helper_tlbwi) {
9498            goto die;
9499        }
9500        gen_helper_tlbwi(cpu_env);
9501        break;
9502    case OPC_TLBINV:
9503        opn = "tlbinv";
9504        if (ctx->ie >= 2) {
9505            if (!env->tlb->helper_tlbinv) {
9506                goto die;
9507            }
9508            gen_helper_tlbinv(cpu_env);
9509        } /* treat as nop if TLBINV not supported */
9510        break;
9511    case OPC_TLBINVF:
9512        opn = "tlbinvf";
9513        if (ctx->ie >= 2) {
9514            if (!env->tlb->helper_tlbinvf) {
9515                goto die;
9516            }
9517            gen_helper_tlbinvf(cpu_env);
9518        } /* treat as nop if TLBINV not supported */
9519        break;
9520    case OPC_TLBWR:
9521        opn = "tlbwr";
9522        if (!env->tlb->helper_tlbwr) {
9523            goto die;
9524        }
9525        gen_helper_tlbwr(cpu_env);
9526        break;
9527    case OPC_TLBP:
9528        opn = "tlbp";
9529        if (!env->tlb->helper_tlbp) {
9530            goto die;
9531        }
9532        gen_helper_tlbp(cpu_env);
9533        break;
9534    case OPC_TLBR:
9535        opn = "tlbr";
9536        if (!env->tlb->helper_tlbr) {
9537            goto die;
9538        }
9539        gen_helper_tlbr(cpu_env);
9540        break;
9541    case OPC_ERET: /* OPC_ERETNC */
9542        if ((ctx->insn_flags & ISA_MIPS_R6) &&
9543            (ctx->hflags & MIPS_HFLAG_BMASK)) {
9544            goto die;
9545        } else {
9546            int bit_shift = (ctx->hflags & MIPS_HFLAG_M16) ? 16 : 6;
9547            if (ctx->opcode & (1 << bit_shift)) {
9548                /* OPC_ERETNC */
9549                opn = "eretnc";
9550                check_insn(ctx, ISA_MIPS_R5);
9551                gen_helper_eretnc(cpu_env);
9552            } else {
9553                /* OPC_ERET */
9554                opn = "eret";
9555                check_insn(ctx, ISA_MIPS2);
9556                gen_helper_eret(cpu_env);
9557            }
9558            ctx->base.is_jmp = DISAS_EXIT;
9559        }
9560        break;
9561    case OPC_DERET:
9562        opn = "deret";
9563        check_insn(ctx, ISA_MIPS_R1);
9564        if ((ctx->insn_flags & ISA_MIPS_R6) &&
9565            (ctx->hflags & MIPS_HFLAG_BMASK)) {
9566            goto die;
9567        }
9568        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
9569            MIPS_INVAL(opn);
9570            gen_reserved_instruction(ctx);
9571        } else {
9572            gen_helper_deret(cpu_env);
9573            ctx->base.is_jmp = DISAS_EXIT;
9574        }
9575        break;
9576    case OPC_WAIT:
9577        opn = "wait";
9578        check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
9579        if ((ctx->insn_flags & ISA_MIPS_R6) &&
9580            (ctx->hflags & MIPS_HFLAG_BMASK)) {
9581            goto die;
9582        }
9583        /* If we get an exception, we want to restart at next instruction */
9584        ctx->base.pc_next += 4;
9585        save_cpu_state(ctx, 1);
9586        ctx->base.pc_next -= 4;
9587        gen_helper_wait(cpu_env);
9588        ctx->base.is_jmp = DISAS_NORETURN;
9589        break;
9590    default:
9591 die:
9592        MIPS_INVAL(opn);
9593        gen_reserved_instruction(ctx);
9594        return;
9595    }
9596    (void)opn; /* avoid a compiler warning */
9597}
9598#endif /* !CONFIG_USER_ONLY */
9599
9600/* CP1 Branches (before delay slot) */
9601static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
9602                                int32_t cc, int32_t offset)
9603{
9604    target_ulong btarget;
9605    TCGv_i32 t0 = tcg_temp_new_i32();
9606
9607    if ((ctx->insn_flags & ISA_MIPS_R6) && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9608        gen_reserved_instruction(ctx);
9609        goto out;
9610    }
9611
9612    if (cc != 0) {
9613        check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
9614    }
9615
9616    btarget = ctx->base.pc_next + 4 + offset;
9617
9618    switch (op) {
9619    case OPC_BC1F:
9620        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9621        tcg_gen_not_i32(t0, t0);
9622        tcg_gen_andi_i32(t0, t0, 1);
9623        tcg_gen_extu_i32_tl(bcond, t0);
9624        goto not_likely;
9625    case OPC_BC1FL:
9626        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9627        tcg_gen_not_i32(t0, t0);
9628        tcg_gen_andi_i32(t0, t0, 1);
9629        tcg_gen_extu_i32_tl(bcond, t0);
9630        goto likely;
9631    case OPC_BC1T:
9632        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9633        tcg_gen_andi_i32(t0, t0, 1);
9634        tcg_gen_extu_i32_tl(bcond, t0);
9635        goto not_likely;
9636    case OPC_BC1TL:
9637        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9638        tcg_gen_andi_i32(t0, t0, 1);
9639        tcg_gen_extu_i32_tl(bcond, t0);
9640    likely:
9641        ctx->hflags |= MIPS_HFLAG_BL;
9642        break;
9643    case OPC_BC1FANY2:
9644        {
9645            TCGv_i32 t1 = tcg_temp_new_i32();
9646            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9647            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9648            tcg_gen_nand_i32(t0, t0, t1);
9649            tcg_temp_free_i32(t1);
9650            tcg_gen_andi_i32(t0, t0, 1);
9651            tcg_gen_extu_i32_tl(bcond, t0);
9652        }
9653        goto not_likely;
9654    case OPC_BC1TANY2:
9655        {
9656            TCGv_i32 t1 = tcg_temp_new_i32();
9657            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9658            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9659            tcg_gen_or_i32(t0, t0, t1);
9660            tcg_temp_free_i32(t1);
9661            tcg_gen_andi_i32(t0, t0, 1);
9662            tcg_gen_extu_i32_tl(bcond, t0);
9663        }
9664        goto not_likely;
9665    case OPC_BC1FANY4:
9666        {
9667            TCGv_i32 t1 = tcg_temp_new_i32();
9668            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9669            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9670            tcg_gen_and_i32(t0, t0, t1);
9671            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
9672            tcg_gen_and_i32(t0, t0, t1);
9673            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
9674            tcg_gen_nand_i32(t0, t0, t1);
9675            tcg_temp_free_i32(t1);
9676            tcg_gen_andi_i32(t0, t0, 1);
9677            tcg_gen_extu_i32_tl(bcond, t0);
9678        }
9679        goto not_likely;
9680    case OPC_BC1TANY4:
9681        {
9682            TCGv_i32 t1 = tcg_temp_new_i32();
9683            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
9684            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 1));
9685            tcg_gen_or_i32(t0, t0, t1);
9686            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 2));
9687            tcg_gen_or_i32(t0, t0, t1);
9688            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc + 3));
9689            tcg_gen_or_i32(t0, t0, t1);
9690            tcg_temp_free_i32(t1);
9691            tcg_gen_andi_i32(t0, t0, 1);
9692            tcg_gen_extu_i32_tl(bcond, t0);
9693        }
9694    not_likely:
9695        ctx->hflags |= MIPS_HFLAG_BC;
9696        break;
9697    default:
9698        MIPS_INVAL("cp1 cond branch");
9699        gen_reserved_instruction(ctx);
9700        goto out;
9701    }
9702    ctx->btarget = btarget;
9703    ctx->hflags |= MIPS_HFLAG_BDS32;
9704 out:
9705    tcg_temp_free_i32(t0);
9706}
9707
9708/* R6 CP1 Branches */
9709static void gen_compute_branch1_r6(DisasContext *ctx, uint32_t op,
9710                                   int32_t ft, int32_t offset,
9711                                   int delayslot_size)
9712{
9713    target_ulong btarget;
9714    TCGv_i64 t0 = tcg_temp_new_i64();
9715
9716    if (ctx->hflags & MIPS_HFLAG_BMASK) {
9717#ifdef MIPS_DEBUG_DISAS
9718        LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
9719                  "\n", ctx->base.pc_next);
9720#endif
9721        gen_reserved_instruction(ctx);
9722        goto out;
9723    }
9724
9725    gen_load_fpr64(ctx, t0, ft);
9726    tcg_gen_andi_i64(t0, t0, 1);
9727
9728    btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
9729
9730    switch (op) {
9731    case OPC_BC1EQZ:
9732        tcg_gen_xori_i64(t0, t0, 1);
9733        ctx->hflags |= MIPS_HFLAG_BC;
9734        break;
9735    case OPC_BC1NEZ:
9736        /* t0 already set */
9737        ctx->hflags |= MIPS_HFLAG_BC;
9738        break;
9739    default:
9740        MIPS_INVAL("cp1 cond branch");
9741        gen_reserved_instruction(ctx);
9742        goto out;
9743    }
9744
9745    tcg_gen_trunc_i64_tl(bcond, t0);
9746
9747    ctx->btarget = btarget;
9748
9749    switch (delayslot_size) {
9750    case 2:
9751        ctx->hflags |= MIPS_HFLAG_BDS16;
9752        break;
9753    case 4:
9754        ctx->hflags |= MIPS_HFLAG_BDS32;
9755        break;
9756    }
9757
9758out:
9759    tcg_temp_free_i64(t0);
9760}
9761
9762/* Coprocessor 1 (FPU) */
9763
9764#define FOP(func, fmt) (((fmt) << 21) | (func))
9765
9766enum fopcode {
9767    OPC_ADD_S = FOP(0, FMT_S),
9768    OPC_SUB_S = FOP(1, FMT_S),
9769    OPC_MUL_S = FOP(2, FMT_S),
9770    OPC_DIV_S = FOP(3, FMT_S),
9771    OPC_SQRT_S = FOP(4, FMT_S),
9772    OPC_ABS_S = FOP(5, FMT_S),
9773    OPC_MOV_S = FOP(6, FMT_S),
9774    OPC_NEG_S = FOP(7, FMT_S),
9775    OPC_ROUND_L_S = FOP(8, FMT_S),
9776    OPC_TRUNC_L_S = FOP(9, FMT_S),
9777    OPC_CEIL_L_S = FOP(10, FMT_S),
9778    OPC_FLOOR_L_S = FOP(11, FMT_S),
9779    OPC_ROUND_W_S = FOP(12, FMT_S),
9780    OPC_TRUNC_W_S = FOP(13, FMT_S),
9781    OPC_CEIL_W_S = FOP(14, FMT_S),
9782    OPC_FLOOR_W_S = FOP(15, FMT_S),
9783    OPC_SEL_S = FOP(16, FMT_S),
9784    OPC_MOVCF_S = FOP(17, FMT_S),
9785    OPC_MOVZ_S = FOP(18, FMT_S),
9786    OPC_MOVN_S = FOP(19, FMT_S),
9787    OPC_SELEQZ_S = FOP(20, FMT_S),
9788    OPC_RECIP_S = FOP(21, FMT_S),
9789    OPC_RSQRT_S = FOP(22, FMT_S),
9790    OPC_SELNEZ_S = FOP(23, FMT_S),
9791    OPC_MADDF_S = FOP(24, FMT_S),
9792    OPC_MSUBF_S = FOP(25, FMT_S),
9793    OPC_RINT_S = FOP(26, FMT_S),
9794    OPC_CLASS_S = FOP(27, FMT_S),
9795    OPC_MIN_S = FOP(28, FMT_S),
9796    OPC_RECIP2_S = FOP(28, FMT_S),
9797    OPC_MINA_S = FOP(29, FMT_S),
9798    OPC_RECIP1_S = FOP(29, FMT_S),
9799    OPC_MAX_S = FOP(30, FMT_S),
9800    OPC_RSQRT1_S = FOP(30, FMT_S),
9801    OPC_MAXA_S = FOP(31, FMT_S),
9802    OPC_RSQRT2_S = FOP(31, FMT_S),
9803    OPC_CVT_D_S = FOP(33, FMT_S),
9804    OPC_CVT_W_S = FOP(36, FMT_S),
9805    OPC_CVT_L_S = FOP(37, FMT_S),
9806    OPC_CVT_PS_S = FOP(38, FMT_S),
9807    OPC_CMP_F_S = FOP(48, FMT_S),
9808    OPC_CMP_UN_S = FOP(49, FMT_S),
9809    OPC_CMP_EQ_S = FOP(50, FMT_S),
9810    OPC_CMP_UEQ_S = FOP(51, FMT_S),
9811    OPC_CMP_OLT_S = FOP(52, FMT_S),
9812    OPC_CMP_ULT_S = FOP(53, FMT_S),
9813    OPC_CMP_OLE_S = FOP(54, FMT_S),
9814    OPC_CMP_ULE_S = FOP(55, FMT_S),
9815    OPC_CMP_SF_S = FOP(56, FMT_S),
9816    OPC_CMP_NGLE_S = FOP(57, FMT_S),
9817    OPC_CMP_SEQ_S = FOP(58, FMT_S),
9818    OPC_CMP_NGL_S = FOP(59, FMT_S),
9819    OPC_CMP_LT_S = FOP(60, FMT_S),
9820    OPC_CMP_NGE_S = FOP(61, FMT_S),
9821    OPC_CMP_LE_S = FOP(62, FMT_S),
9822    OPC_CMP_NGT_S = FOP(63, FMT_S),
9823
9824    OPC_ADD_D = FOP(0, FMT_D),
9825    OPC_SUB_D = FOP(1, FMT_D),
9826    OPC_MUL_D = FOP(2, FMT_D),
9827    OPC_DIV_D = FOP(3, FMT_D),
9828    OPC_SQRT_D = FOP(4, FMT_D),
9829    OPC_ABS_D = FOP(5, FMT_D),
9830    OPC_MOV_D = FOP(6, FMT_D),
9831    OPC_NEG_D = FOP(7, FMT_D),
9832    OPC_ROUND_L_D = FOP(8, FMT_D),
9833    OPC_TRUNC_L_D = FOP(9, FMT_D),
9834    OPC_CEIL_L_D = FOP(10, FMT_D),
9835    OPC_FLOOR_L_D = FOP(11, FMT_D),
9836    OPC_ROUND_W_D = FOP(12, FMT_D),
9837    OPC_TRUNC_W_D = FOP(13, FMT_D),
9838    OPC_CEIL_W_D = FOP(14, FMT_D),
9839    OPC_FLOOR_W_D = FOP(15, FMT_D),
9840    OPC_SEL_D = FOP(16, FMT_D),
9841    OPC_MOVCF_D = FOP(17, FMT_D),
9842    OPC_MOVZ_D = FOP(18, FMT_D),
9843    OPC_MOVN_D = FOP(19, FMT_D),
9844    OPC_SELEQZ_D = FOP(20, FMT_D),
9845    OPC_RECIP_D = FOP(21, FMT_D),
9846    OPC_RSQRT_D = FOP(22, FMT_D),
9847    OPC_SELNEZ_D = FOP(23, FMT_D),
9848    OPC_MADDF_D = FOP(24, FMT_D),
9849    OPC_MSUBF_D = FOP(25, FMT_D),
9850    OPC_RINT_D = FOP(26, FMT_D),
9851    OPC_CLASS_D = FOP(27, FMT_D),
9852    OPC_MIN_D = FOP(28, FMT_D),
9853    OPC_RECIP2_D = FOP(28, FMT_D),
9854    OPC_MINA_D = FOP(29, FMT_D),
9855    OPC_RECIP1_D = FOP(29, FMT_D),
9856    OPC_MAX_D = FOP(30, FMT_D),
9857    OPC_RSQRT1_D = FOP(30, FMT_D),
9858    OPC_MAXA_D = FOP(31, FMT_D),
9859    OPC_RSQRT2_D = FOP(31, FMT_D),
9860    OPC_CVT_S_D = FOP(32, FMT_D),
9861    OPC_CVT_W_D = FOP(36, FMT_D),
9862    OPC_CVT_L_D = FOP(37, FMT_D),
9863    OPC_CMP_F_D = FOP(48, FMT_D),
9864    OPC_CMP_UN_D = FOP(49, FMT_D),
9865    OPC_CMP_EQ_D = FOP(50, FMT_D),
9866    OPC_CMP_UEQ_D = FOP(51, FMT_D),
9867    OPC_CMP_OLT_D = FOP(52, FMT_D),
9868    OPC_CMP_ULT_D = FOP(53, FMT_D),
9869    OPC_CMP_OLE_D = FOP(54, FMT_D),
9870    OPC_CMP_ULE_D = FOP(55, FMT_D),
9871    OPC_CMP_SF_D = FOP(56, FMT_D),
9872    OPC_CMP_NGLE_D = FOP(57, FMT_D),
9873    OPC_CMP_SEQ_D = FOP(58, FMT_D),
9874    OPC_CMP_NGL_D = FOP(59, FMT_D),
9875    OPC_CMP_LT_D = FOP(60, FMT_D),
9876    OPC_CMP_NGE_D = FOP(61, FMT_D),
9877    OPC_CMP_LE_D = FOP(62, FMT_D),
9878    OPC_CMP_NGT_D = FOP(63, FMT_D),
9879
9880    OPC_CVT_S_W = FOP(32, FMT_W),
9881    OPC_CVT_D_W = FOP(33, FMT_W),
9882    OPC_CVT_S_L = FOP(32, FMT_L),
9883    OPC_CVT_D_L = FOP(33, FMT_L),
9884    OPC_CVT_PS_PW = FOP(38, FMT_W),
9885
9886    OPC_ADD_PS = FOP(0, FMT_PS),
9887    OPC_SUB_PS = FOP(1, FMT_PS),
9888    OPC_MUL_PS = FOP(2, FMT_PS),
9889    OPC_DIV_PS = FOP(3, FMT_PS),
9890    OPC_ABS_PS = FOP(5, FMT_PS),
9891    OPC_MOV_PS = FOP(6, FMT_PS),
9892    OPC_NEG_PS = FOP(7, FMT_PS),
9893    OPC_MOVCF_PS = FOP(17, FMT_PS),
9894    OPC_MOVZ_PS = FOP(18, FMT_PS),
9895    OPC_MOVN_PS = FOP(19, FMT_PS),
9896    OPC_ADDR_PS = FOP(24, FMT_PS),
9897    OPC_MULR_PS = FOP(26, FMT_PS),
9898    OPC_RECIP2_PS = FOP(28, FMT_PS),
9899    OPC_RECIP1_PS = FOP(29, FMT_PS),
9900    OPC_RSQRT1_PS = FOP(30, FMT_PS),
9901    OPC_RSQRT2_PS = FOP(31, FMT_PS),
9902
9903    OPC_CVT_S_PU = FOP(32, FMT_PS),
9904    OPC_CVT_PW_PS = FOP(36, FMT_PS),
9905    OPC_CVT_S_PL = FOP(40, FMT_PS),
9906    OPC_PLL_PS = FOP(44, FMT_PS),
9907    OPC_PLU_PS = FOP(45, FMT_PS),
9908    OPC_PUL_PS = FOP(46, FMT_PS),
9909    OPC_PUU_PS = FOP(47, FMT_PS),
9910    OPC_CMP_F_PS = FOP(48, FMT_PS),
9911    OPC_CMP_UN_PS = FOP(49, FMT_PS),
9912    OPC_CMP_EQ_PS = FOP(50, FMT_PS),
9913    OPC_CMP_UEQ_PS = FOP(51, FMT_PS),
9914    OPC_CMP_OLT_PS = FOP(52, FMT_PS),
9915    OPC_CMP_ULT_PS = FOP(53, FMT_PS),
9916    OPC_CMP_OLE_PS = FOP(54, FMT_PS),
9917    OPC_CMP_ULE_PS = FOP(55, FMT_PS),
9918    OPC_CMP_SF_PS = FOP(56, FMT_PS),
9919    OPC_CMP_NGLE_PS = FOP(57, FMT_PS),
9920    OPC_CMP_SEQ_PS = FOP(58, FMT_PS),
9921    OPC_CMP_NGL_PS = FOP(59, FMT_PS),
9922    OPC_CMP_LT_PS = FOP(60, FMT_PS),
9923    OPC_CMP_NGE_PS = FOP(61, FMT_PS),
9924    OPC_CMP_LE_PS = FOP(62, FMT_PS),
9925    OPC_CMP_NGT_PS = FOP(63, FMT_PS),
9926};
9927
9928enum r6_f_cmp_op {
9929    R6_OPC_CMP_AF_S   = FOP(0, FMT_W),
9930    R6_OPC_CMP_UN_S   = FOP(1, FMT_W),
9931    R6_OPC_CMP_EQ_S   = FOP(2, FMT_W),
9932    R6_OPC_CMP_UEQ_S  = FOP(3, FMT_W),
9933    R6_OPC_CMP_LT_S   = FOP(4, FMT_W),
9934    R6_OPC_CMP_ULT_S  = FOP(5, FMT_W),
9935    R6_OPC_CMP_LE_S   = FOP(6, FMT_W),
9936    R6_OPC_CMP_ULE_S  = FOP(7, FMT_W),
9937    R6_OPC_CMP_SAF_S  = FOP(8, FMT_W),
9938    R6_OPC_CMP_SUN_S  = FOP(9, FMT_W),
9939    R6_OPC_CMP_SEQ_S  = FOP(10, FMT_W),
9940    R6_OPC_CMP_SEUQ_S = FOP(11, FMT_W),
9941    R6_OPC_CMP_SLT_S  = FOP(12, FMT_W),
9942    R6_OPC_CMP_SULT_S = FOP(13, FMT_W),
9943    R6_OPC_CMP_SLE_S  = FOP(14, FMT_W),
9944    R6_OPC_CMP_SULE_S = FOP(15, FMT_W),
9945    R6_OPC_CMP_OR_S   = FOP(17, FMT_W),
9946    R6_OPC_CMP_UNE_S  = FOP(18, FMT_W),
9947    R6_OPC_CMP_NE_S   = FOP(19, FMT_W),
9948    R6_OPC_CMP_SOR_S  = FOP(25, FMT_W),
9949    R6_OPC_CMP_SUNE_S = FOP(26, FMT_W),
9950    R6_OPC_CMP_SNE_S  = FOP(27, FMT_W),
9951
9952    R6_OPC_CMP_AF_D   = FOP(0, FMT_L),
9953    R6_OPC_CMP_UN_D   = FOP(1, FMT_L),
9954    R6_OPC_CMP_EQ_D   = FOP(2, FMT_L),
9955    R6_OPC_CMP_UEQ_D  = FOP(3, FMT_L),
9956    R6_OPC_CMP_LT_D   = FOP(4, FMT_L),
9957    R6_OPC_CMP_ULT_D  = FOP(5, FMT_L),
9958    R6_OPC_CMP_LE_D   = FOP(6, FMT_L),
9959    R6_OPC_CMP_ULE_D  = FOP(7, FMT_L),
9960    R6_OPC_CMP_SAF_D  = FOP(8, FMT_L),
9961    R6_OPC_CMP_SUN_D  = FOP(9, FMT_L),
9962    R6_OPC_CMP_SEQ_D  = FOP(10, FMT_L),
9963    R6_OPC_CMP_SEUQ_D = FOP(11, FMT_L),
9964    R6_OPC_CMP_SLT_D  = FOP(12, FMT_L),
9965    R6_OPC_CMP_SULT_D = FOP(13, FMT_L),
9966    R6_OPC_CMP_SLE_D  = FOP(14, FMT_L),
9967    R6_OPC_CMP_SULE_D = FOP(15, FMT_L),
9968    R6_OPC_CMP_OR_D   = FOP(17, FMT_L),
9969    R6_OPC_CMP_UNE_D  = FOP(18, FMT_L),
9970    R6_OPC_CMP_NE_D   = FOP(19, FMT_L),
9971    R6_OPC_CMP_SOR_D  = FOP(25, FMT_L),
9972    R6_OPC_CMP_SUNE_D = FOP(26, FMT_L),
9973    R6_OPC_CMP_SNE_D  = FOP(27, FMT_L),
9974};
9975
9976static void gen_cp1(DisasContext *ctx, uint32_t opc, int rt, int fs)
9977{
9978    TCGv t0 = tcg_temp_new();
9979
9980    switch (opc) {
9981    case OPC_MFC1:
9982        {
9983            TCGv_i32 fp0 = tcg_temp_new_i32();
9984
9985            gen_load_fpr32(ctx, fp0, fs);
9986            tcg_gen_ext_i32_tl(t0, fp0);
9987            tcg_temp_free_i32(fp0);
9988        }
9989        gen_store_gpr(t0, rt);
9990        break;
9991    case OPC_MTC1:
9992        gen_load_gpr(t0, rt);
9993        {
9994            TCGv_i32 fp0 = tcg_temp_new_i32();
9995
9996            tcg_gen_trunc_tl_i32(fp0, t0);
9997            gen_store_fpr32(ctx, fp0, fs);
9998            tcg_temp_free_i32(fp0);
9999        }
10000        break;
10001    case OPC_CFC1:
10002        gen_helper_1e0i(cfc1, t0, fs);
10003        gen_store_gpr(t0, rt);
10004        break;
10005    case OPC_CTC1:
10006        gen_load_gpr(t0, rt);
10007        save_cpu_state(ctx, 0);
10008        {
10009            TCGv_i32 fs_tmp = tcg_const_i32(fs);
10010
10011            gen_helper_0e2i(ctc1, t0, fs_tmp, rt);
10012            tcg_temp_free_i32(fs_tmp);
10013        }
10014        /* Stop translation as we may have changed hflags */
10015        ctx->base.is_jmp = DISAS_STOP;
10016        break;
10017#if defined(TARGET_MIPS64)
10018    case OPC_DMFC1:
10019        gen_load_fpr64(ctx, t0, fs);
10020        gen_store_gpr(t0, rt);
10021        break;
10022    case OPC_DMTC1:
10023        gen_load_gpr(t0, rt);
10024        gen_store_fpr64(ctx, t0, fs);
10025        break;
10026#endif
10027    case OPC_MFHC1:
10028        {
10029            TCGv_i32 fp0 = tcg_temp_new_i32();
10030
10031            gen_load_fpr32h(ctx, fp0, fs);
10032            tcg_gen_ext_i32_tl(t0, fp0);
10033            tcg_temp_free_i32(fp0);
10034        }
10035        gen_store_gpr(t0, rt);
10036        break;
10037    case OPC_MTHC1:
10038        gen_load_gpr(t0, rt);
10039        {
10040            TCGv_i32 fp0 = tcg_temp_new_i32();
10041
10042            tcg_gen_trunc_tl_i32(fp0, t0);
10043            gen_store_fpr32h(ctx, fp0, fs);
10044            tcg_temp_free_i32(fp0);
10045        }
10046        break;
10047    default:
10048        MIPS_INVAL("cp1 move");
10049        gen_reserved_instruction(ctx);
10050        goto out;
10051    }
10052
10053 out:
10054    tcg_temp_free(t0);
10055}
10056
10057static void gen_movci(DisasContext *ctx, int rd, int rs, int cc, int tf)
10058{
10059    TCGLabel *l1;
10060    TCGCond cond;
10061    TCGv_i32 t0;
10062
10063    if (rd == 0) {
10064        /* Treat as NOP. */
10065        return;
10066    }
10067
10068    if (tf) {
10069        cond = TCG_COND_EQ;
10070    } else {
10071        cond = TCG_COND_NE;
10072    }
10073
10074    l1 = gen_new_label();
10075    t0 = tcg_temp_new_i32();
10076    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10077    tcg_gen_brcondi_i32(cond, t0, 0, l1);
10078    tcg_temp_free_i32(t0);
10079    gen_load_gpr(cpu_gpr[rd], rs);
10080    gen_set_label(l1);
10081}
10082
10083static inline void gen_movcf_s(DisasContext *ctx, int fs, int fd, int cc,
10084                               int tf)
10085{
10086    int cond;
10087    TCGv_i32 t0 = tcg_temp_new_i32();
10088    TCGLabel *l1 = gen_new_label();
10089
10090    if (tf) {
10091        cond = TCG_COND_EQ;
10092    } else {
10093        cond = TCG_COND_NE;
10094    }
10095
10096    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10097    tcg_gen_brcondi_i32(cond, t0, 0, l1);
10098    gen_load_fpr32(ctx, t0, fs);
10099    gen_store_fpr32(ctx, t0, fd);
10100    gen_set_label(l1);
10101    tcg_temp_free_i32(t0);
10102}
10103
10104static inline void gen_movcf_d(DisasContext *ctx, int fs, int fd, int cc,
10105                               int tf)
10106{
10107    int cond;
10108    TCGv_i32 t0 = tcg_temp_new_i32();
10109    TCGv_i64 fp0;
10110    TCGLabel *l1 = gen_new_label();
10111
10112    if (tf) {
10113        cond = TCG_COND_EQ;
10114    } else {
10115        cond = TCG_COND_NE;
10116    }
10117
10118    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10119    tcg_gen_brcondi_i32(cond, t0, 0, l1);
10120    tcg_temp_free_i32(t0);
10121    fp0 = tcg_temp_new_i64();
10122    gen_load_fpr64(ctx, fp0, fs);
10123    gen_store_fpr64(ctx, fp0, fd);
10124    tcg_temp_free_i64(fp0);
10125    gen_set_label(l1);
10126}
10127
10128static inline void gen_movcf_ps(DisasContext *ctx, int fs, int fd,
10129                                int cc, int tf)
10130{
10131    int cond;
10132    TCGv_i32 t0 = tcg_temp_new_i32();
10133    TCGLabel *l1 = gen_new_label();
10134    TCGLabel *l2 = gen_new_label();
10135
10136    if (tf) {
10137        cond = TCG_COND_EQ;
10138    } else {
10139        cond = TCG_COND_NE;
10140    }
10141
10142    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
10143    tcg_gen_brcondi_i32(cond, t0, 0, l1);
10144    gen_load_fpr32(ctx, t0, fs);
10145    gen_store_fpr32(ctx, t0, fd);
10146    gen_set_label(l1);
10147
10148    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc + 1));
10149    tcg_gen_brcondi_i32(cond, t0, 0, l2);
10150    gen_load_fpr32h(ctx, t0, fs);
10151    gen_store_fpr32h(ctx, t0, fd);
10152    tcg_temp_free_i32(t0);
10153    gen_set_label(l2);
10154}
10155
10156static void gen_sel_s(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10157                      int fs)
10158{
10159    TCGv_i32 t1 = tcg_const_i32(0);
10160    TCGv_i32 fp0 = tcg_temp_new_i32();
10161    TCGv_i32 fp1 = tcg_temp_new_i32();
10162    TCGv_i32 fp2 = tcg_temp_new_i32();
10163    gen_load_fpr32(ctx, fp0, fd);
10164    gen_load_fpr32(ctx, fp1, ft);
10165    gen_load_fpr32(ctx, fp2, fs);
10166
10167    switch (op1) {
10168    case OPC_SEL_S:
10169        tcg_gen_andi_i32(fp0, fp0, 1);
10170        tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10171        break;
10172    case OPC_SELEQZ_S:
10173        tcg_gen_andi_i32(fp1, fp1, 1);
10174        tcg_gen_movcond_i32(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10175        break;
10176    case OPC_SELNEZ_S:
10177        tcg_gen_andi_i32(fp1, fp1, 1);
10178        tcg_gen_movcond_i32(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10179        break;
10180    default:
10181        MIPS_INVAL("gen_sel_s");
10182        gen_reserved_instruction(ctx);
10183        break;
10184    }
10185
10186    gen_store_fpr32(ctx, fp0, fd);
10187    tcg_temp_free_i32(fp2);
10188    tcg_temp_free_i32(fp1);
10189    tcg_temp_free_i32(fp0);
10190    tcg_temp_free_i32(t1);
10191}
10192
10193static void gen_sel_d(DisasContext *ctx, enum fopcode op1, int fd, int ft,
10194                      int fs)
10195{
10196    TCGv_i64 t1 = tcg_const_i64(0);
10197    TCGv_i64 fp0 = tcg_temp_new_i64();
10198    TCGv_i64 fp1 = tcg_temp_new_i64();
10199    TCGv_i64 fp2 = tcg_temp_new_i64();
10200    gen_load_fpr64(ctx, fp0, fd);
10201    gen_load_fpr64(ctx, fp1, ft);
10202    gen_load_fpr64(ctx, fp2, fs);
10203
10204    switch (op1) {
10205    case OPC_SEL_D:
10206        tcg_gen_andi_i64(fp0, fp0, 1);
10207        tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp0, t1, fp1, fp2);
10208        break;
10209    case OPC_SELEQZ_D:
10210        tcg_gen_andi_i64(fp1, fp1, 1);
10211        tcg_gen_movcond_i64(TCG_COND_EQ, fp0, fp1, t1, fp2, t1);
10212        break;
10213    case OPC_SELNEZ_D:
10214        tcg_gen_andi_i64(fp1, fp1, 1);
10215        tcg_gen_movcond_i64(TCG_COND_NE, fp0, fp1, t1, fp2, t1);
10216        break;
10217    default:
10218        MIPS_INVAL("gen_sel_d");
10219        gen_reserved_instruction(ctx);
10220        break;
10221    }
10222
10223    gen_store_fpr64(ctx, fp0, fd);
10224    tcg_temp_free_i64(fp2);
10225    tcg_temp_free_i64(fp1);
10226    tcg_temp_free_i64(fp0);
10227    tcg_temp_free_i64(t1);
10228}
10229
10230static void gen_farith(DisasContext *ctx, enum fopcode op1,
10231                       int ft, int fs, int fd, int cc)
10232{
10233    uint32_t func = ctx->opcode & 0x3f;
10234    switch (op1) {
10235    case OPC_ADD_S:
10236        {
10237            TCGv_i32 fp0 = tcg_temp_new_i32();
10238            TCGv_i32 fp1 = tcg_temp_new_i32();
10239
10240            gen_load_fpr32(ctx, fp0, fs);
10241            gen_load_fpr32(ctx, fp1, ft);
10242            gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
10243            tcg_temp_free_i32(fp1);
10244            gen_store_fpr32(ctx, fp0, fd);
10245            tcg_temp_free_i32(fp0);
10246        }
10247        break;
10248    case OPC_SUB_S:
10249        {
10250            TCGv_i32 fp0 = tcg_temp_new_i32();
10251            TCGv_i32 fp1 = tcg_temp_new_i32();
10252
10253            gen_load_fpr32(ctx, fp0, fs);
10254            gen_load_fpr32(ctx, fp1, ft);
10255            gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
10256            tcg_temp_free_i32(fp1);
10257            gen_store_fpr32(ctx, fp0, fd);
10258            tcg_temp_free_i32(fp0);
10259        }
10260        break;
10261    case OPC_MUL_S:
10262        {
10263            TCGv_i32 fp0 = tcg_temp_new_i32();
10264            TCGv_i32 fp1 = tcg_temp_new_i32();
10265
10266            gen_load_fpr32(ctx, fp0, fs);
10267            gen_load_fpr32(ctx, fp1, ft);
10268            gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
10269            tcg_temp_free_i32(fp1);
10270            gen_store_fpr32(ctx, fp0, fd);
10271            tcg_temp_free_i32(fp0);
10272        }
10273        break;
10274    case OPC_DIV_S:
10275        {
10276            TCGv_i32 fp0 = tcg_temp_new_i32();
10277            TCGv_i32 fp1 = tcg_temp_new_i32();
10278
10279            gen_load_fpr32(ctx, fp0, fs);
10280            gen_load_fpr32(ctx, fp1, ft);
10281            gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
10282            tcg_temp_free_i32(fp1);
10283            gen_store_fpr32(ctx, fp0, fd);
10284            tcg_temp_free_i32(fp0);
10285        }
10286        break;
10287    case OPC_SQRT_S:
10288        {
10289            TCGv_i32 fp0 = tcg_temp_new_i32();
10290
10291            gen_load_fpr32(ctx, fp0, fs);
10292            gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
10293            gen_store_fpr32(ctx, fp0, fd);
10294            tcg_temp_free_i32(fp0);
10295        }
10296        break;
10297    case OPC_ABS_S:
10298        {
10299            TCGv_i32 fp0 = tcg_temp_new_i32();
10300
10301            gen_load_fpr32(ctx, fp0, fs);
10302            if (ctx->abs2008) {
10303                tcg_gen_andi_i32(fp0, fp0, 0x7fffffffUL);
10304            } else {
10305                gen_helper_float_abs_s(fp0, fp0);
10306            }
10307            gen_store_fpr32(ctx, fp0, fd);
10308            tcg_temp_free_i32(fp0);
10309        }
10310        break;
10311    case OPC_MOV_S:
10312        {
10313            TCGv_i32 fp0 = tcg_temp_new_i32();
10314
10315            gen_load_fpr32(ctx, fp0, fs);
10316            gen_store_fpr32(ctx, fp0, fd);
10317            tcg_temp_free_i32(fp0);
10318        }
10319        break;
10320    case OPC_NEG_S:
10321        {
10322            TCGv_i32 fp0 = tcg_temp_new_i32();
10323
10324            gen_load_fpr32(ctx, fp0, fs);
10325            if (ctx->abs2008) {
10326                tcg_gen_xori_i32(fp0, fp0, 1UL << 31);
10327            } else {
10328                gen_helper_float_chs_s(fp0, fp0);
10329            }
10330            gen_store_fpr32(ctx, fp0, fd);
10331            tcg_temp_free_i32(fp0);
10332        }
10333        break;
10334    case OPC_ROUND_L_S:
10335        check_cp1_64bitmode(ctx);
10336        {
10337            TCGv_i32 fp32 = tcg_temp_new_i32();
10338            TCGv_i64 fp64 = tcg_temp_new_i64();
10339
10340            gen_load_fpr32(ctx, fp32, fs);
10341            if (ctx->nan2008) {
10342                gen_helper_float_round_2008_l_s(fp64, cpu_env, fp32);
10343            } else {
10344                gen_helper_float_round_l_s(fp64, cpu_env, fp32);
10345            }
10346            tcg_temp_free_i32(fp32);
10347            gen_store_fpr64(ctx, fp64, fd);
10348            tcg_temp_free_i64(fp64);
10349        }
10350        break;
10351    case OPC_TRUNC_L_S:
10352        check_cp1_64bitmode(ctx);
10353        {
10354            TCGv_i32 fp32 = tcg_temp_new_i32();
10355            TCGv_i64 fp64 = tcg_temp_new_i64();
10356
10357            gen_load_fpr32(ctx, fp32, fs);
10358            if (ctx->nan2008) {
10359                gen_helper_float_trunc_2008_l_s(fp64, cpu_env, fp32);
10360            } else {
10361                gen_helper_float_trunc_l_s(fp64, cpu_env, fp32);
10362            }
10363            tcg_temp_free_i32(fp32);
10364            gen_store_fpr64(ctx, fp64, fd);
10365            tcg_temp_free_i64(fp64);
10366        }
10367        break;
10368    case OPC_CEIL_L_S:
10369        check_cp1_64bitmode(ctx);
10370        {
10371            TCGv_i32 fp32 = tcg_temp_new_i32();
10372            TCGv_i64 fp64 = tcg_temp_new_i64();
10373
10374            gen_load_fpr32(ctx, fp32, fs);
10375            if (ctx->nan2008) {
10376                gen_helper_float_ceil_2008_l_s(fp64, cpu_env, fp32);
10377            } else {
10378                gen_helper_float_ceil_l_s(fp64, cpu_env, fp32);
10379            }
10380            tcg_temp_free_i32(fp32);
10381            gen_store_fpr64(ctx, fp64, fd);
10382            tcg_temp_free_i64(fp64);
10383        }
10384        break;
10385    case OPC_FLOOR_L_S:
10386        check_cp1_64bitmode(ctx);
10387        {
10388            TCGv_i32 fp32 = tcg_temp_new_i32();
10389            TCGv_i64 fp64 = tcg_temp_new_i64();
10390
10391            gen_load_fpr32(ctx, fp32, fs);
10392            if (ctx->nan2008) {
10393                gen_helper_float_floor_2008_l_s(fp64, cpu_env, fp32);
10394            } else {
10395                gen_helper_float_floor_l_s(fp64, cpu_env, fp32);
10396            }
10397            tcg_temp_free_i32(fp32);
10398            gen_store_fpr64(ctx, fp64, fd);
10399            tcg_temp_free_i64(fp64);
10400        }
10401        break;
10402    case OPC_ROUND_W_S:
10403        {
10404            TCGv_i32 fp0 = tcg_temp_new_i32();
10405
10406            gen_load_fpr32(ctx, fp0, fs);
10407            if (ctx->nan2008) {
10408                gen_helper_float_round_2008_w_s(fp0, cpu_env, fp0);
10409            } else {
10410                gen_helper_float_round_w_s(fp0, cpu_env, fp0);
10411            }
10412            gen_store_fpr32(ctx, fp0, fd);
10413            tcg_temp_free_i32(fp0);
10414        }
10415        break;
10416    case OPC_TRUNC_W_S:
10417        {
10418            TCGv_i32 fp0 = tcg_temp_new_i32();
10419
10420            gen_load_fpr32(ctx, fp0, fs);
10421            if (ctx->nan2008) {
10422                gen_helper_float_trunc_2008_w_s(fp0, cpu_env, fp0);
10423            } else {
10424                gen_helper_float_trunc_w_s(fp0, cpu_env, fp0);
10425            }
10426            gen_store_fpr32(ctx, fp0, fd);
10427            tcg_temp_free_i32(fp0);
10428        }
10429        break;
10430    case OPC_CEIL_W_S:
10431        {
10432            TCGv_i32 fp0 = tcg_temp_new_i32();
10433
10434            gen_load_fpr32(ctx, fp0, fs);
10435            if (ctx->nan2008) {
10436                gen_helper_float_ceil_2008_w_s(fp0, cpu_env, fp0);
10437            } else {
10438                gen_helper_float_ceil_w_s(fp0, cpu_env, fp0);
10439            }
10440            gen_store_fpr32(ctx, fp0, fd);
10441            tcg_temp_free_i32(fp0);
10442        }
10443        break;
10444    case OPC_FLOOR_W_S:
10445        {
10446            TCGv_i32 fp0 = tcg_temp_new_i32();
10447
10448            gen_load_fpr32(ctx, fp0, fs);
10449            if (ctx->nan2008) {
10450                gen_helper_float_floor_2008_w_s(fp0, cpu_env, fp0);
10451            } else {
10452                gen_helper_float_floor_w_s(fp0, cpu_env, fp0);
10453            }
10454            gen_store_fpr32(ctx, fp0, fd);
10455            tcg_temp_free_i32(fp0);
10456        }
10457        break;
10458    case OPC_SEL_S:
10459        check_insn(ctx, ISA_MIPS_R6);
10460        gen_sel_s(ctx, op1, fd, ft, fs);
10461        break;
10462    case OPC_SELEQZ_S:
10463        check_insn(ctx, ISA_MIPS_R6);
10464        gen_sel_s(ctx, op1, fd, ft, fs);
10465        break;
10466    case OPC_SELNEZ_S:
10467        check_insn(ctx, ISA_MIPS_R6);
10468        gen_sel_s(ctx, op1, fd, ft, fs);
10469        break;
10470    case OPC_MOVCF_S:
10471        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10472        gen_movcf_s(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
10473        break;
10474    case OPC_MOVZ_S:
10475        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10476        {
10477            TCGLabel *l1 = gen_new_label();
10478            TCGv_i32 fp0;
10479
10480            if (ft != 0) {
10481                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
10482            }
10483            fp0 = tcg_temp_new_i32();
10484            gen_load_fpr32(ctx, fp0, fs);
10485            gen_store_fpr32(ctx, fp0, fd);
10486            tcg_temp_free_i32(fp0);
10487            gen_set_label(l1);
10488        }
10489        break;
10490    case OPC_MOVN_S:
10491        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10492        {
10493            TCGLabel *l1 = gen_new_label();
10494            TCGv_i32 fp0;
10495
10496            if (ft != 0) {
10497                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
10498                fp0 = tcg_temp_new_i32();
10499                gen_load_fpr32(ctx, fp0, fs);
10500                gen_store_fpr32(ctx, fp0, fd);
10501                tcg_temp_free_i32(fp0);
10502                gen_set_label(l1);
10503            }
10504        }
10505        break;
10506    case OPC_RECIP_S:
10507        {
10508            TCGv_i32 fp0 = tcg_temp_new_i32();
10509
10510            gen_load_fpr32(ctx, fp0, fs);
10511            gen_helper_float_recip_s(fp0, cpu_env, fp0);
10512            gen_store_fpr32(ctx, fp0, fd);
10513            tcg_temp_free_i32(fp0);
10514        }
10515        break;
10516    case OPC_RSQRT_S:
10517        {
10518            TCGv_i32 fp0 = tcg_temp_new_i32();
10519
10520            gen_load_fpr32(ctx, fp0, fs);
10521            gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
10522            gen_store_fpr32(ctx, fp0, fd);
10523            tcg_temp_free_i32(fp0);
10524        }
10525        break;
10526    case OPC_MADDF_S:
10527        check_insn(ctx, ISA_MIPS_R6);
10528        {
10529            TCGv_i32 fp0 = tcg_temp_new_i32();
10530            TCGv_i32 fp1 = tcg_temp_new_i32();
10531            TCGv_i32 fp2 = tcg_temp_new_i32();
10532            gen_load_fpr32(ctx, fp0, fs);
10533            gen_load_fpr32(ctx, fp1, ft);
10534            gen_load_fpr32(ctx, fp2, fd);
10535            gen_helper_float_maddf_s(fp2, cpu_env, fp0, fp1, fp2);
10536            gen_store_fpr32(ctx, fp2, fd);
10537            tcg_temp_free_i32(fp2);
10538            tcg_temp_free_i32(fp1);
10539            tcg_temp_free_i32(fp0);
10540        }
10541        break;
10542    case OPC_MSUBF_S:
10543        check_insn(ctx, ISA_MIPS_R6);
10544        {
10545            TCGv_i32 fp0 = tcg_temp_new_i32();
10546            TCGv_i32 fp1 = tcg_temp_new_i32();
10547            TCGv_i32 fp2 = tcg_temp_new_i32();
10548            gen_load_fpr32(ctx, fp0, fs);
10549            gen_load_fpr32(ctx, fp1, ft);
10550            gen_load_fpr32(ctx, fp2, fd);
10551            gen_helper_float_msubf_s(fp2, cpu_env, fp0, fp1, fp2);
10552            gen_store_fpr32(ctx, fp2, fd);
10553            tcg_temp_free_i32(fp2);
10554            tcg_temp_free_i32(fp1);
10555            tcg_temp_free_i32(fp0);
10556        }
10557        break;
10558    case OPC_RINT_S:
10559        check_insn(ctx, ISA_MIPS_R6);
10560        {
10561            TCGv_i32 fp0 = tcg_temp_new_i32();
10562            gen_load_fpr32(ctx, fp0, fs);
10563            gen_helper_float_rint_s(fp0, cpu_env, fp0);
10564            gen_store_fpr32(ctx, fp0, fd);
10565            tcg_temp_free_i32(fp0);
10566        }
10567        break;
10568    case OPC_CLASS_S:
10569        check_insn(ctx, ISA_MIPS_R6);
10570        {
10571            TCGv_i32 fp0 = tcg_temp_new_i32();
10572            gen_load_fpr32(ctx, fp0, fs);
10573            gen_helper_float_class_s(fp0, cpu_env, fp0);
10574            gen_store_fpr32(ctx, fp0, fd);
10575            tcg_temp_free_i32(fp0);
10576        }
10577        break;
10578    case OPC_MIN_S: /* OPC_RECIP2_S */
10579        if (ctx->insn_flags & ISA_MIPS_R6) {
10580            /* OPC_MIN_S */
10581            TCGv_i32 fp0 = tcg_temp_new_i32();
10582            TCGv_i32 fp1 = tcg_temp_new_i32();
10583            TCGv_i32 fp2 = tcg_temp_new_i32();
10584            gen_load_fpr32(ctx, fp0, fs);
10585            gen_load_fpr32(ctx, fp1, ft);
10586            gen_helper_float_min_s(fp2, cpu_env, fp0, fp1);
10587            gen_store_fpr32(ctx, fp2, fd);
10588            tcg_temp_free_i32(fp2);
10589            tcg_temp_free_i32(fp1);
10590            tcg_temp_free_i32(fp0);
10591        } else {
10592            /* OPC_RECIP2_S */
10593            check_cp1_64bitmode(ctx);
10594            {
10595                TCGv_i32 fp0 = tcg_temp_new_i32();
10596                TCGv_i32 fp1 = tcg_temp_new_i32();
10597
10598                gen_load_fpr32(ctx, fp0, fs);
10599                gen_load_fpr32(ctx, fp1, ft);
10600                gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
10601                tcg_temp_free_i32(fp1);
10602                gen_store_fpr32(ctx, fp0, fd);
10603                tcg_temp_free_i32(fp0);
10604            }
10605        }
10606        break;
10607    case OPC_MINA_S: /* OPC_RECIP1_S */
10608        if (ctx->insn_flags & ISA_MIPS_R6) {
10609            /* OPC_MINA_S */
10610            TCGv_i32 fp0 = tcg_temp_new_i32();
10611            TCGv_i32 fp1 = tcg_temp_new_i32();
10612            TCGv_i32 fp2 = tcg_temp_new_i32();
10613            gen_load_fpr32(ctx, fp0, fs);
10614            gen_load_fpr32(ctx, fp1, ft);
10615            gen_helper_float_mina_s(fp2, cpu_env, fp0, fp1);
10616            gen_store_fpr32(ctx, fp2, fd);
10617            tcg_temp_free_i32(fp2);
10618            tcg_temp_free_i32(fp1);
10619            tcg_temp_free_i32(fp0);
10620        } else {
10621            /* OPC_RECIP1_S */
10622            check_cp1_64bitmode(ctx);
10623            {
10624                TCGv_i32 fp0 = tcg_temp_new_i32();
10625
10626                gen_load_fpr32(ctx, fp0, fs);
10627                gen_helper_float_recip1_s(fp0, cpu_env, fp0);
10628                gen_store_fpr32(ctx, fp0, fd);
10629                tcg_temp_free_i32(fp0);
10630            }
10631        }
10632        break;
10633    case OPC_MAX_S: /* OPC_RSQRT1_S */
10634        if (ctx->insn_flags & ISA_MIPS_R6) {
10635            /* OPC_MAX_S */
10636            TCGv_i32 fp0 = tcg_temp_new_i32();
10637            TCGv_i32 fp1 = tcg_temp_new_i32();
10638            gen_load_fpr32(ctx, fp0, fs);
10639            gen_load_fpr32(ctx, fp1, ft);
10640            gen_helper_float_max_s(fp1, cpu_env, fp0, fp1);
10641            gen_store_fpr32(ctx, fp1, fd);
10642            tcg_temp_free_i32(fp1);
10643            tcg_temp_free_i32(fp0);
10644        } else {
10645            /* OPC_RSQRT1_S */
10646            check_cp1_64bitmode(ctx);
10647            {
10648                TCGv_i32 fp0 = tcg_temp_new_i32();
10649
10650                gen_load_fpr32(ctx, fp0, fs);
10651                gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
10652                gen_store_fpr32(ctx, fp0, fd);
10653                tcg_temp_free_i32(fp0);
10654            }
10655        }
10656        break;
10657    case OPC_MAXA_S: /* OPC_RSQRT2_S */
10658        if (ctx->insn_flags & ISA_MIPS_R6) {
10659            /* OPC_MAXA_S */
10660            TCGv_i32 fp0 = tcg_temp_new_i32();
10661            TCGv_i32 fp1 = tcg_temp_new_i32();
10662            gen_load_fpr32(ctx, fp0, fs);
10663            gen_load_fpr32(ctx, fp1, ft);
10664            gen_helper_float_maxa_s(fp1, cpu_env, fp0, fp1);
10665            gen_store_fpr32(ctx, fp1, fd);
10666            tcg_temp_free_i32(fp1);
10667            tcg_temp_free_i32(fp0);
10668        } else {
10669            /* OPC_RSQRT2_S */
10670            check_cp1_64bitmode(ctx);
10671            {
10672                TCGv_i32 fp0 = tcg_temp_new_i32();
10673                TCGv_i32 fp1 = tcg_temp_new_i32();
10674
10675                gen_load_fpr32(ctx, fp0, fs);
10676                gen_load_fpr32(ctx, fp1, ft);
10677                gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
10678                tcg_temp_free_i32(fp1);
10679                gen_store_fpr32(ctx, fp0, fd);
10680                tcg_temp_free_i32(fp0);
10681            }
10682        }
10683        break;
10684    case OPC_CVT_D_S:
10685        check_cp1_registers(ctx, fd);
10686        {
10687            TCGv_i32 fp32 = tcg_temp_new_i32();
10688            TCGv_i64 fp64 = tcg_temp_new_i64();
10689
10690            gen_load_fpr32(ctx, fp32, fs);
10691            gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
10692            tcg_temp_free_i32(fp32);
10693            gen_store_fpr64(ctx, fp64, fd);
10694            tcg_temp_free_i64(fp64);
10695        }
10696        break;
10697    case OPC_CVT_W_S:
10698        {
10699            TCGv_i32 fp0 = tcg_temp_new_i32();
10700
10701            gen_load_fpr32(ctx, fp0, fs);
10702            if (ctx->nan2008) {
10703                gen_helper_float_cvt_2008_w_s(fp0, cpu_env, fp0);
10704            } else {
10705                gen_helper_float_cvt_w_s(fp0, cpu_env, fp0);
10706            }
10707            gen_store_fpr32(ctx, fp0, fd);
10708            tcg_temp_free_i32(fp0);
10709        }
10710        break;
10711    case OPC_CVT_L_S:
10712        check_cp1_64bitmode(ctx);
10713        {
10714            TCGv_i32 fp32 = tcg_temp_new_i32();
10715            TCGv_i64 fp64 = tcg_temp_new_i64();
10716
10717            gen_load_fpr32(ctx, fp32, fs);
10718            if (ctx->nan2008) {
10719                gen_helper_float_cvt_2008_l_s(fp64, cpu_env, fp32);
10720            } else {
10721                gen_helper_float_cvt_l_s(fp64, cpu_env, fp32);
10722            }
10723            tcg_temp_free_i32(fp32);
10724            gen_store_fpr64(ctx, fp64, fd);
10725            tcg_temp_free_i64(fp64);
10726        }
10727        break;
10728    case OPC_CVT_PS_S:
10729        check_ps(ctx);
10730        {
10731            TCGv_i64 fp64 = tcg_temp_new_i64();
10732            TCGv_i32 fp32_0 = tcg_temp_new_i32();
10733            TCGv_i32 fp32_1 = tcg_temp_new_i32();
10734
10735            gen_load_fpr32(ctx, fp32_0, fs);
10736            gen_load_fpr32(ctx, fp32_1, ft);
10737            tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
10738            tcg_temp_free_i32(fp32_1);
10739            tcg_temp_free_i32(fp32_0);
10740            gen_store_fpr64(ctx, fp64, fd);
10741            tcg_temp_free_i64(fp64);
10742        }
10743        break;
10744    case OPC_CMP_F_S:
10745    case OPC_CMP_UN_S:
10746    case OPC_CMP_EQ_S:
10747    case OPC_CMP_UEQ_S:
10748    case OPC_CMP_OLT_S:
10749    case OPC_CMP_ULT_S:
10750    case OPC_CMP_OLE_S:
10751    case OPC_CMP_ULE_S:
10752    case OPC_CMP_SF_S:
10753    case OPC_CMP_NGLE_S:
10754    case OPC_CMP_SEQ_S:
10755    case OPC_CMP_NGL_S:
10756    case OPC_CMP_LT_S:
10757    case OPC_CMP_NGE_S:
10758    case OPC_CMP_LE_S:
10759    case OPC_CMP_NGT_S:
10760        check_insn_opc_removed(ctx, ISA_MIPS_R6);
10761        if (ctx->opcode & (1 << 6)) {
10762            gen_cmpabs_s(ctx, func - 48, ft, fs, cc);
10763        } else {
10764            gen_cmp_s(ctx, func - 48, ft, fs, cc);
10765        }
10766        break;
10767    case OPC_ADD_D:
10768        check_cp1_registers(ctx, fs | ft | fd);
10769        {
10770            TCGv_i64 fp0 = tcg_temp_new_i64();
10771            TCGv_i64 fp1 = tcg_temp_new_i64();
10772
10773            gen_load_fpr64(ctx, fp0, fs);
10774            gen_load_fpr64(ctx, fp1, ft);
10775            gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
10776            tcg_temp_free_i64(fp1);
10777            gen_store_fpr64(ctx, fp0, fd);
10778            tcg_temp_free_i64(fp0);
10779        }
10780        break;
10781    case OPC_SUB_D:
10782        check_cp1_registers(ctx, fs | ft | fd);
10783        {
10784            TCGv_i64 fp0 = tcg_temp_new_i64();
10785            TCGv_i64 fp1 = tcg_temp_new_i64();
10786
10787            gen_load_fpr64(ctx, fp0, fs);
10788            gen_load_fpr64(ctx, fp1, ft);
10789            gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
10790            tcg_temp_free_i64(fp1);
10791            gen_store_fpr64(ctx, fp0, fd);
10792            tcg_temp_free_i64(fp0);
10793        }
10794        break;
10795    case OPC_MUL_D:
10796        check_cp1_registers(ctx, fs | ft | fd);
10797        {
10798            TCGv_i64 fp0 = tcg_temp_new_i64();
10799            TCGv_i64 fp1 = tcg_temp_new_i64();
10800
10801            gen_load_fpr64(ctx, fp0, fs);
10802            gen_load_fpr64(ctx, fp1, ft);
10803            gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
10804            tcg_temp_free_i64(fp1);
10805            gen_store_fpr64(ctx, fp0, fd);
10806            tcg_temp_free_i64(fp0);
10807        }
10808        break;
10809    case OPC_DIV_D:
10810        check_cp1_registers(ctx, fs | ft | fd);
10811        {
10812            TCGv_i64 fp0 = tcg_temp_new_i64();
10813            TCGv_i64 fp1 = tcg_temp_new_i64();
10814
10815            gen_load_fpr64(ctx, fp0, fs);
10816            gen_load_fpr64(ctx, fp1, ft);
10817            gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
10818            tcg_temp_free_i64(fp1);
10819            gen_store_fpr64(ctx, fp0, fd);
10820            tcg_temp_free_i64(fp0);
10821        }
10822        break;
10823    case OPC_SQRT_D:
10824        check_cp1_registers(ctx, fs | fd);
10825        {
10826            TCGv_i64 fp0 = tcg_temp_new_i64();
10827
10828            gen_load_fpr64(ctx, fp0, fs);
10829            gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
10830            gen_store_fpr64(ctx, fp0, fd);
10831            tcg_temp_free_i64(fp0);
10832        }
10833        break;
10834    case OPC_ABS_D:
10835        check_cp1_registers(ctx, fs | fd);
10836        {
10837            TCGv_i64 fp0 = tcg_temp_new_i64();
10838
10839            gen_load_fpr64(ctx, fp0, fs);
10840            if (ctx->abs2008) {
10841                tcg_gen_andi_i64(fp0, fp0, 0x7fffffffffffffffULL);
10842            } else {
10843                gen_helper_float_abs_d(fp0, fp0);
10844            }
10845            gen_store_fpr64(ctx, fp0, fd);
10846            tcg_temp_free_i64(fp0);
10847        }
10848        break;
10849    case OPC_MOV_D:
10850        check_cp1_registers(ctx, fs | fd);
10851        {
10852            TCGv_i64 fp0 = tcg_temp_new_i64();
10853
10854            gen_load_fpr64(ctx, fp0, fs);
10855            gen_store_fpr64(ctx, fp0, fd);
10856            tcg_temp_free_i64(fp0);
10857        }
10858        break;
10859    case OPC_NEG_D:
10860        check_cp1_registers(ctx, fs | fd);
10861        {
10862            TCGv_i64 fp0 = tcg_temp_new_i64();
10863
10864            gen_load_fpr64(ctx, fp0, fs);
10865            if (ctx->abs2008) {
10866                tcg_gen_xori_i64(fp0, fp0, 1ULL << 63);
10867            } else {
10868                gen_helper_float_chs_d(fp0, fp0);
10869            }
10870            gen_store_fpr64(ctx, fp0, fd);
10871            tcg_temp_free_i64(fp0);
10872        }
10873        break;
10874    case OPC_ROUND_L_D:
10875        check_cp1_64bitmode(ctx);
10876        {
10877            TCGv_i64 fp0 = tcg_temp_new_i64();
10878
10879            gen_load_fpr64(ctx, fp0, fs);
10880            if (ctx->nan2008) {
10881                gen_helper_float_round_2008_l_d(fp0, cpu_env, fp0);
10882            } else {
10883                gen_helper_float_round_l_d(fp0, cpu_env, fp0);
10884            }
10885            gen_store_fpr64(ctx, fp0, fd);
10886            tcg_temp_free_i64(fp0);
10887        }
10888        break;
10889    case OPC_TRUNC_L_D:
10890        check_cp1_64bitmode(ctx);
10891        {
10892            TCGv_i64 fp0 = tcg_temp_new_i64();
10893
10894            gen_load_fpr64(ctx, fp0, fs);
10895            if (ctx->nan2008) {
10896                gen_helper_float_trunc_2008_l_d(fp0, cpu_env, fp0);
10897            } else {
10898                gen_helper_float_trunc_l_d(fp0, cpu_env, fp0);
10899            }
10900            gen_store_fpr64(ctx, fp0, fd);
10901            tcg_temp_free_i64(fp0);
10902        }
10903        break;
10904    case OPC_CEIL_L_D:
10905        check_cp1_64bitmode(ctx);
10906        {
10907            TCGv_i64 fp0 = tcg_temp_new_i64();
10908
10909            gen_load_fpr64(ctx, fp0, fs);
10910            if (ctx->nan2008) {
10911                gen_helper_float_ceil_2008_l_d(fp0, cpu_env, fp0);
10912            } else {
10913                gen_helper_float_ceil_l_d(fp0, cpu_env, fp0);
10914            }
10915            gen_store_fpr64(ctx, fp0, fd);
10916            tcg_temp_free_i64(fp0);
10917        }
10918        break;
10919    case OPC_FLOOR_L_D:
10920        check_cp1_64bitmode(ctx);
10921        {
10922            TCGv_i64 fp0 = tcg_temp_new_i64();
10923
10924            gen_load_fpr64(ctx, fp0, fs);
10925            if (ctx->nan2008) {
10926                gen_helper_float_floor_2008_l_d(fp0, cpu_env, fp0);
10927            } else {
10928                gen_helper_float_floor_l_d(fp0, cpu_env, fp0);
10929            }
10930            gen_store_fpr64(ctx, fp0, fd);
10931            tcg_temp_free_i64(fp0);
10932        }
10933        break;
10934    case OPC_ROUND_W_D:
10935        check_cp1_registers(ctx, fs);
10936        {
10937            TCGv_i32 fp32 = tcg_temp_new_i32();
10938            TCGv_i64 fp64 = tcg_temp_new_i64();
10939
10940            gen_load_fpr64(ctx, fp64, fs);
10941            if (ctx->nan2008) {
10942                gen_helper_float_round_2008_w_d(fp32, cpu_env, fp64);
10943            } else {
10944                gen_helper_float_round_w_d(fp32, cpu_env, fp64);
10945            }
10946            tcg_temp_free_i64(fp64);
10947            gen_store_fpr32(ctx, fp32, fd);
10948            tcg_temp_free_i32(fp32);
10949        }
10950        break;
10951    case OPC_TRUNC_W_D:
10952        check_cp1_registers(ctx, fs);
10953        {
10954            TCGv_i32 fp32 = tcg_temp_new_i32();
10955            TCGv_i64 fp64 = tcg_temp_new_i64();
10956
10957            gen_load_fpr64(ctx, fp64, fs);
10958            if (ctx->nan2008) {
10959                gen_helper_float_trunc_2008_w_d(fp32, cpu_env, fp64);
10960            } else {
10961                gen_helper_float_trunc_w_d(fp32, cpu_env, fp64);
10962            }
10963            tcg_temp_free_i64(fp64);
10964            gen_store_fpr32(ctx, fp32, fd);
10965            tcg_temp_free_i32(fp32);
10966        }
10967        break;
10968    case OPC_CEIL_W_D:
10969        check_cp1_registers(ctx, fs);
10970        {
10971            TCGv_i32 fp32 = tcg_temp_new_i32();
10972            TCGv_i64 fp64 = tcg_temp_new_i64();
10973
10974            gen_load_fpr64(ctx, fp64, fs);
10975            if (ctx->nan2008) {
10976                gen_helper_float_ceil_2008_w_d(fp32, cpu_env, fp64);
10977            } else {
10978                gen_helper_float_ceil_w_d(fp32, cpu_env, fp64);
10979            }
10980            tcg_temp_free_i64(fp64);
10981            gen_store_fpr32(ctx, fp32, fd);
10982            tcg_temp_free_i32(fp32);
10983        }
10984        break;
10985    case OPC_FLOOR_W_D:
10986        check_cp1_registers(ctx, fs);
10987        {
10988            TCGv_i32 fp32 = tcg_temp_new_i32();
10989            TCGv_i64 fp64 = tcg_temp_new_i64();
10990
10991            gen_load_fpr64(ctx, fp64, fs);
10992            if (ctx->nan2008) {
10993                gen_helper_float_floor_2008_w_d(fp32, cpu_env, fp64);
10994            } else {
10995                gen_helper_float_floor_w_d(fp32, cpu_env, fp64);
10996            }
10997            tcg_temp_free_i64(fp64);
10998            gen_store_fpr32(ctx, fp32, fd);
10999            tcg_temp_free_i32(fp32);
11000        }
11001        break;
11002    case OPC_SEL_D:
11003        check_insn(ctx, ISA_MIPS_R6);
11004        gen_sel_d(ctx, op1, fd, ft, fs);
11005        break;
11006    case OPC_SELEQZ_D:
11007        check_insn(ctx, ISA_MIPS_R6);
11008        gen_sel_d(ctx, op1, fd, ft, fs);
11009        break;
11010    case OPC_SELNEZ_D:
11011        check_insn(ctx, ISA_MIPS_R6);
11012        gen_sel_d(ctx, op1, fd, ft, fs);
11013        break;
11014    case OPC_MOVCF_D:
11015        check_insn_opc_removed(ctx, ISA_MIPS_R6);
11016        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11017        break;
11018    case OPC_MOVZ_D:
11019        check_insn_opc_removed(ctx, ISA_MIPS_R6);
11020        {
11021            TCGLabel *l1 = gen_new_label();
11022            TCGv_i64 fp0;
11023
11024            if (ft != 0) {
11025                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11026            }
11027            fp0 = tcg_temp_new_i64();
11028            gen_load_fpr64(ctx, fp0, fs);
11029            gen_store_fpr64(ctx, fp0, fd);
11030            tcg_temp_free_i64(fp0);
11031            gen_set_label(l1);
11032        }
11033        break;
11034    case OPC_MOVN_D:
11035        check_insn_opc_removed(ctx, ISA_MIPS_R6);
11036        {
11037            TCGLabel *l1 = gen_new_label();
11038            TCGv_i64 fp0;
11039
11040            if (ft != 0) {
11041                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11042                fp0 = tcg_temp_new_i64();
11043                gen_load_fpr64(ctx, fp0, fs);
11044                gen_store_fpr64(ctx, fp0, fd);
11045                tcg_temp_free_i64(fp0);
11046                gen_set_label(l1);
11047            }
11048        }
11049        break;
11050    case OPC_RECIP_D:
11051        check_cp1_registers(ctx, fs | fd);
11052        {
11053            TCGv_i64 fp0 = tcg_temp_new_i64();
11054
11055            gen_load_fpr64(ctx, fp0, fs);
11056            gen_helper_float_recip_d(fp0, cpu_env, fp0);
11057            gen_store_fpr64(ctx, fp0, fd);
11058            tcg_temp_free_i64(fp0);
11059        }
11060        break;
11061    case OPC_RSQRT_D:
11062        check_cp1_registers(ctx, fs | fd);
11063        {
11064            TCGv_i64 fp0 = tcg_temp_new_i64();
11065
11066            gen_load_fpr64(ctx, fp0, fs);
11067            gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
11068            gen_store_fpr64(ctx, fp0, fd);
11069            tcg_temp_free_i64(fp0);
11070        }
11071        break;
11072    case OPC_MADDF_D:
11073        check_insn(ctx, ISA_MIPS_R6);
11074        {
11075            TCGv_i64 fp0 = tcg_temp_new_i64();
11076            TCGv_i64 fp1 = tcg_temp_new_i64();
11077            TCGv_i64 fp2 = tcg_temp_new_i64();
11078            gen_load_fpr64(ctx, fp0, fs);
11079            gen_load_fpr64(ctx, fp1, ft);
11080            gen_load_fpr64(ctx, fp2, fd);
11081            gen_helper_float_maddf_d(fp2, cpu_env, fp0, fp1, fp2);
11082            gen_store_fpr64(ctx, fp2, fd);
11083            tcg_temp_free_i64(fp2);
11084            tcg_temp_free_i64(fp1);
11085            tcg_temp_free_i64(fp0);
11086        }
11087        break;
11088    case OPC_MSUBF_D:
11089        check_insn(ctx, ISA_MIPS_R6);
11090        {
11091            TCGv_i64 fp0 = tcg_temp_new_i64();
11092            TCGv_i64 fp1 = tcg_temp_new_i64();
11093            TCGv_i64 fp2 = tcg_temp_new_i64();
11094            gen_load_fpr64(ctx, fp0, fs);
11095            gen_load_fpr64(ctx, fp1, ft);
11096            gen_load_fpr64(ctx, fp2, fd);
11097            gen_helper_float_msubf_d(fp2, cpu_env, fp0, fp1, fp2);
11098            gen_store_fpr64(ctx, fp2, fd);
11099            tcg_temp_free_i64(fp2);
11100            tcg_temp_free_i64(fp1);
11101            tcg_temp_free_i64(fp0);
11102        }
11103        break;
11104    case OPC_RINT_D:
11105        check_insn(ctx, ISA_MIPS_R6);
11106        {
11107            TCGv_i64 fp0 = tcg_temp_new_i64();
11108            gen_load_fpr64(ctx, fp0, fs);
11109            gen_helper_float_rint_d(fp0, cpu_env, fp0);
11110            gen_store_fpr64(ctx, fp0, fd);
11111            tcg_temp_free_i64(fp0);
11112        }
11113        break;
11114    case OPC_CLASS_D:
11115        check_insn(ctx, ISA_MIPS_R6);
11116        {
11117            TCGv_i64 fp0 = tcg_temp_new_i64();
11118            gen_load_fpr64(ctx, fp0, fs);
11119            gen_helper_float_class_d(fp0, cpu_env, fp0);
11120            gen_store_fpr64(ctx, fp0, fd);
11121            tcg_temp_free_i64(fp0);
11122        }
11123        break;
11124    case OPC_MIN_D: /* OPC_RECIP2_D */
11125        if (ctx->insn_flags & ISA_MIPS_R6) {
11126            /* OPC_MIN_D */
11127            TCGv_i64 fp0 = tcg_temp_new_i64();
11128            TCGv_i64 fp1 = tcg_temp_new_i64();
11129            gen_load_fpr64(ctx, fp0, fs);
11130            gen_load_fpr64(ctx, fp1, ft);
11131            gen_helper_float_min_d(fp1, cpu_env, fp0, fp1);
11132            gen_store_fpr64(ctx, fp1, fd);
11133            tcg_temp_free_i64(fp1);
11134            tcg_temp_free_i64(fp0);
11135        } else {
11136            /* OPC_RECIP2_D */
11137            check_cp1_64bitmode(ctx);
11138            {
11139                TCGv_i64 fp0 = tcg_temp_new_i64();
11140                TCGv_i64 fp1 = tcg_temp_new_i64();
11141
11142                gen_load_fpr64(ctx, fp0, fs);
11143                gen_load_fpr64(ctx, fp1, ft);
11144                gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
11145                tcg_temp_free_i64(fp1);
11146                gen_store_fpr64(ctx, fp0, fd);
11147                tcg_temp_free_i64(fp0);
11148            }
11149        }
11150        break;
11151    case OPC_MINA_D: /* OPC_RECIP1_D */
11152        if (ctx->insn_flags & ISA_MIPS_R6) {
11153            /* OPC_MINA_D */
11154            TCGv_i64 fp0 = tcg_temp_new_i64();
11155            TCGv_i64 fp1 = tcg_temp_new_i64();
11156            gen_load_fpr64(ctx, fp0, fs);
11157            gen_load_fpr64(ctx, fp1, ft);
11158            gen_helper_float_mina_d(fp1, cpu_env, fp0, fp1);
11159            gen_store_fpr64(ctx, fp1, fd);
11160            tcg_temp_free_i64(fp1);
11161            tcg_temp_free_i64(fp0);
11162        } else {
11163            /* OPC_RECIP1_D */
11164            check_cp1_64bitmode(ctx);
11165            {
11166                TCGv_i64 fp0 = tcg_temp_new_i64();
11167
11168                gen_load_fpr64(ctx, fp0, fs);
11169                gen_helper_float_recip1_d(fp0, cpu_env, fp0);
11170                gen_store_fpr64(ctx, fp0, fd);
11171                tcg_temp_free_i64(fp0);
11172            }
11173        }
11174        break;
11175    case OPC_MAX_D: /*  OPC_RSQRT1_D */
11176        if (ctx->insn_flags & ISA_MIPS_R6) {
11177            /* OPC_MAX_D */
11178            TCGv_i64 fp0 = tcg_temp_new_i64();
11179            TCGv_i64 fp1 = tcg_temp_new_i64();
11180            gen_load_fpr64(ctx, fp0, fs);
11181            gen_load_fpr64(ctx, fp1, ft);
11182            gen_helper_float_max_d(fp1, cpu_env, fp0, fp1);
11183            gen_store_fpr64(ctx, fp1, fd);
11184            tcg_temp_free_i64(fp1);
11185            tcg_temp_free_i64(fp0);
11186        } else {
11187            /* OPC_RSQRT1_D */
11188            check_cp1_64bitmode(ctx);
11189            {
11190                TCGv_i64 fp0 = tcg_temp_new_i64();
11191
11192                gen_load_fpr64(ctx, fp0, fs);
11193                gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
11194                gen_store_fpr64(ctx, fp0, fd);
11195                tcg_temp_free_i64(fp0);
11196            }
11197        }
11198        break;
11199    case OPC_MAXA_D: /* OPC_RSQRT2_D */
11200        if (ctx->insn_flags & ISA_MIPS_R6) {
11201            /* OPC_MAXA_D */
11202            TCGv_i64 fp0 = tcg_temp_new_i64();
11203            TCGv_i64 fp1 = tcg_temp_new_i64();
11204            gen_load_fpr64(ctx, fp0, fs);
11205            gen_load_fpr64(ctx, fp1, ft);
11206            gen_helper_float_maxa_d(fp1, cpu_env, fp0, fp1);
11207            gen_store_fpr64(ctx, fp1, fd);
11208            tcg_temp_free_i64(fp1);
11209            tcg_temp_free_i64(fp0);
11210        } else {
11211            /* OPC_RSQRT2_D */
11212            check_cp1_64bitmode(ctx);
11213            {
11214                TCGv_i64 fp0 = tcg_temp_new_i64();
11215                TCGv_i64 fp1 = tcg_temp_new_i64();
11216
11217                gen_load_fpr64(ctx, fp0, fs);
11218                gen_load_fpr64(ctx, fp1, ft);
11219                gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
11220                tcg_temp_free_i64(fp1);
11221                gen_store_fpr64(ctx, fp0, fd);
11222                tcg_temp_free_i64(fp0);
11223            }
11224        }
11225        break;
11226    case OPC_CMP_F_D:
11227    case OPC_CMP_UN_D:
11228    case OPC_CMP_EQ_D:
11229    case OPC_CMP_UEQ_D:
11230    case OPC_CMP_OLT_D:
11231    case OPC_CMP_ULT_D:
11232    case OPC_CMP_OLE_D:
11233    case OPC_CMP_ULE_D:
11234    case OPC_CMP_SF_D:
11235    case OPC_CMP_NGLE_D:
11236    case OPC_CMP_SEQ_D:
11237    case OPC_CMP_NGL_D:
11238    case OPC_CMP_LT_D:
11239    case OPC_CMP_NGE_D:
11240    case OPC_CMP_LE_D:
11241    case OPC_CMP_NGT_D:
11242        check_insn_opc_removed(ctx, ISA_MIPS_R6);
11243        if (ctx->opcode & (1 << 6)) {
11244            gen_cmpabs_d(ctx, func - 48, ft, fs, cc);
11245        } else {
11246            gen_cmp_d(ctx, func - 48, ft, fs, cc);
11247        }
11248        break;
11249    case OPC_CVT_S_D:
11250        check_cp1_registers(ctx, fs);
11251        {
11252            TCGv_i32 fp32 = tcg_temp_new_i32();
11253            TCGv_i64 fp64 = tcg_temp_new_i64();
11254
11255            gen_load_fpr64(ctx, fp64, fs);
11256            gen_helper_float_cvts_d(fp32, cpu_env, fp64);
11257            tcg_temp_free_i64(fp64);
11258            gen_store_fpr32(ctx, fp32, fd);
11259            tcg_temp_free_i32(fp32);
11260        }
11261        break;
11262    case OPC_CVT_W_D:
11263        check_cp1_registers(ctx, fs);
11264        {
11265            TCGv_i32 fp32 = tcg_temp_new_i32();
11266            TCGv_i64 fp64 = tcg_temp_new_i64();
11267
11268            gen_load_fpr64(ctx, fp64, fs);
11269            if (ctx->nan2008) {
11270                gen_helper_float_cvt_2008_w_d(fp32, cpu_env, fp64);
11271            } else {
11272                gen_helper_float_cvt_w_d(fp32, cpu_env, fp64);
11273            }
11274            tcg_temp_free_i64(fp64);
11275            gen_store_fpr32(ctx, fp32, fd);
11276            tcg_temp_free_i32(fp32);
11277        }
11278        break;
11279    case OPC_CVT_L_D:
11280        check_cp1_64bitmode(ctx);
11281        {
11282            TCGv_i64 fp0 = tcg_temp_new_i64();
11283
11284            gen_load_fpr64(ctx, fp0, fs);
11285            if (ctx->nan2008) {
11286                gen_helper_float_cvt_2008_l_d(fp0, cpu_env, fp0);
11287            } else {
11288                gen_helper_float_cvt_l_d(fp0, cpu_env, fp0);
11289            }
11290            gen_store_fpr64(ctx, fp0, fd);
11291            tcg_temp_free_i64(fp0);
11292        }
11293        break;
11294    case OPC_CVT_S_W:
11295        {
11296            TCGv_i32 fp0 = tcg_temp_new_i32();
11297
11298            gen_load_fpr32(ctx, fp0, fs);
11299            gen_helper_float_cvts_w(fp0, cpu_env, fp0);
11300            gen_store_fpr32(ctx, fp0, fd);
11301            tcg_temp_free_i32(fp0);
11302        }
11303        break;
11304    case OPC_CVT_D_W:
11305        check_cp1_registers(ctx, fd);
11306        {
11307            TCGv_i32 fp32 = tcg_temp_new_i32();
11308            TCGv_i64 fp64 = tcg_temp_new_i64();
11309
11310            gen_load_fpr32(ctx, fp32, fs);
11311            gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
11312            tcg_temp_free_i32(fp32);
11313            gen_store_fpr64(ctx, fp64, fd);
11314            tcg_temp_free_i64(fp64);
11315        }
11316        break;
11317    case OPC_CVT_S_L:
11318        check_cp1_64bitmode(ctx);
11319        {
11320            TCGv_i32 fp32 = tcg_temp_new_i32();
11321            TCGv_i64 fp64 = tcg_temp_new_i64();
11322
11323            gen_load_fpr64(ctx, fp64, fs);
11324            gen_helper_float_cvts_l(fp32, cpu_env, fp64);
11325            tcg_temp_free_i64(fp64);
11326            gen_store_fpr32(ctx, fp32, fd);
11327            tcg_temp_free_i32(fp32);
11328        }
11329        break;
11330    case OPC_CVT_D_L:
11331        check_cp1_64bitmode(ctx);
11332        {
11333            TCGv_i64 fp0 = tcg_temp_new_i64();
11334
11335            gen_load_fpr64(ctx, fp0, fs);
11336            gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
11337            gen_store_fpr64(ctx, fp0, fd);
11338            tcg_temp_free_i64(fp0);
11339        }
11340        break;
11341    case OPC_CVT_PS_PW:
11342        check_ps(ctx);
11343        {
11344            TCGv_i64 fp0 = tcg_temp_new_i64();
11345
11346            gen_load_fpr64(ctx, fp0, fs);
11347            gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
11348            gen_store_fpr64(ctx, fp0, fd);
11349            tcg_temp_free_i64(fp0);
11350        }
11351        break;
11352    case OPC_ADD_PS:
11353        check_ps(ctx);
11354        {
11355            TCGv_i64 fp0 = tcg_temp_new_i64();
11356            TCGv_i64 fp1 = tcg_temp_new_i64();
11357
11358            gen_load_fpr64(ctx, fp0, fs);
11359            gen_load_fpr64(ctx, fp1, ft);
11360            gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
11361            tcg_temp_free_i64(fp1);
11362            gen_store_fpr64(ctx, fp0, fd);
11363            tcg_temp_free_i64(fp0);
11364        }
11365        break;
11366    case OPC_SUB_PS:
11367        check_ps(ctx);
11368        {
11369            TCGv_i64 fp0 = tcg_temp_new_i64();
11370            TCGv_i64 fp1 = tcg_temp_new_i64();
11371
11372            gen_load_fpr64(ctx, fp0, fs);
11373            gen_load_fpr64(ctx, fp1, ft);
11374            gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
11375            tcg_temp_free_i64(fp1);
11376            gen_store_fpr64(ctx, fp0, fd);
11377            tcg_temp_free_i64(fp0);
11378        }
11379        break;
11380    case OPC_MUL_PS:
11381        check_ps(ctx);
11382        {
11383            TCGv_i64 fp0 = tcg_temp_new_i64();
11384            TCGv_i64 fp1 = tcg_temp_new_i64();
11385
11386            gen_load_fpr64(ctx, fp0, fs);
11387            gen_load_fpr64(ctx, fp1, ft);
11388            gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
11389            tcg_temp_free_i64(fp1);
11390            gen_store_fpr64(ctx, fp0, fd);
11391            tcg_temp_free_i64(fp0);
11392        }
11393        break;
11394    case OPC_ABS_PS:
11395        check_ps(ctx);
11396        {
11397            TCGv_i64 fp0 = tcg_temp_new_i64();
11398
11399            gen_load_fpr64(ctx, fp0, fs);
11400            gen_helper_float_abs_ps(fp0, fp0);
11401            gen_store_fpr64(ctx, fp0, fd);
11402            tcg_temp_free_i64(fp0);
11403        }
11404        break;
11405    case OPC_MOV_PS:
11406        check_ps(ctx);
11407        {
11408            TCGv_i64 fp0 = tcg_temp_new_i64();
11409
11410            gen_load_fpr64(ctx, fp0, fs);
11411            gen_store_fpr64(ctx, fp0, fd);
11412            tcg_temp_free_i64(fp0);
11413        }
11414        break;
11415    case OPC_NEG_PS:
11416        check_ps(ctx);
11417        {
11418            TCGv_i64 fp0 = tcg_temp_new_i64();
11419
11420            gen_load_fpr64(ctx, fp0, fs);
11421            gen_helper_float_chs_ps(fp0, fp0);
11422            gen_store_fpr64(ctx, fp0, fd);
11423            tcg_temp_free_i64(fp0);
11424        }
11425        break;
11426    case OPC_MOVCF_PS:
11427        check_ps(ctx);
11428        gen_movcf_ps(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
11429        break;
11430    case OPC_MOVZ_PS:
11431        check_ps(ctx);
11432        {
11433            TCGLabel *l1 = gen_new_label();
11434            TCGv_i64 fp0;
11435
11436            if (ft != 0) {
11437                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
11438            }
11439            fp0 = tcg_temp_new_i64();
11440            gen_load_fpr64(ctx, fp0, fs);
11441            gen_store_fpr64(ctx, fp0, fd);
11442            tcg_temp_free_i64(fp0);
11443            gen_set_label(l1);
11444        }
11445        break;
11446    case OPC_MOVN_PS:
11447        check_ps(ctx);
11448        {
11449            TCGLabel *l1 = gen_new_label();
11450            TCGv_i64 fp0;
11451
11452            if (ft != 0) {
11453                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
11454                fp0 = tcg_temp_new_i64();
11455                gen_load_fpr64(ctx, fp0, fs);
11456                gen_store_fpr64(ctx, fp0, fd);
11457                tcg_temp_free_i64(fp0);
11458                gen_set_label(l1);
11459            }
11460        }
11461        break;
11462    case OPC_ADDR_PS:
11463        check_ps(ctx);
11464        {
11465            TCGv_i64 fp0 = tcg_temp_new_i64();
11466            TCGv_i64 fp1 = tcg_temp_new_i64();
11467
11468            gen_load_fpr64(ctx, fp0, ft);
11469            gen_load_fpr64(ctx, fp1, fs);
11470            gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
11471            tcg_temp_free_i64(fp1);
11472            gen_store_fpr64(ctx, fp0, fd);
11473            tcg_temp_free_i64(fp0);
11474        }
11475        break;
11476    case OPC_MULR_PS:
11477        check_ps(ctx);
11478        {
11479            TCGv_i64 fp0 = tcg_temp_new_i64();
11480            TCGv_i64 fp1 = tcg_temp_new_i64();
11481
11482            gen_load_fpr64(ctx, fp0, ft);
11483            gen_load_fpr64(ctx, fp1, fs);
11484            gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
11485            tcg_temp_free_i64(fp1);
11486            gen_store_fpr64(ctx, fp0, fd);
11487            tcg_temp_free_i64(fp0);
11488        }
11489        break;
11490    case OPC_RECIP2_PS:
11491        check_ps(ctx);
11492        {
11493            TCGv_i64 fp0 = tcg_temp_new_i64();
11494            TCGv_i64 fp1 = tcg_temp_new_i64();
11495
11496            gen_load_fpr64(ctx, fp0, fs);
11497            gen_load_fpr64(ctx, fp1, ft);
11498            gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
11499            tcg_temp_free_i64(fp1);
11500            gen_store_fpr64(ctx, fp0, fd);
11501            tcg_temp_free_i64(fp0);
11502        }
11503        break;
11504    case OPC_RECIP1_PS:
11505        check_ps(ctx);
11506        {
11507            TCGv_i64 fp0 = tcg_temp_new_i64();
11508
11509            gen_load_fpr64(ctx, fp0, fs);
11510            gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
11511            gen_store_fpr64(ctx, fp0, fd);
11512            tcg_temp_free_i64(fp0);
11513        }
11514        break;
11515    case OPC_RSQRT1_PS:
11516        check_ps(ctx);
11517        {
11518            TCGv_i64 fp0 = tcg_temp_new_i64();
11519
11520            gen_load_fpr64(ctx, fp0, fs);
11521            gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
11522            gen_store_fpr64(ctx, fp0, fd);
11523            tcg_temp_free_i64(fp0);
11524        }
11525        break;
11526    case OPC_RSQRT2_PS:
11527        check_ps(ctx);
11528        {
11529            TCGv_i64 fp0 = tcg_temp_new_i64();
11530            TCGv_i64 fp1 = tcg_temp_new_i64();
11531
11532            gen_load_fpr64(ctx, fp0, fs);
11533            gen_load_fpr64(ctx, fp1, ft);
11534            gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
11535            tcg_temp_free_i64(fp1);
11536            gen_store_fpr64(ctx, fp0, fd);
11537            tcg_temp_free_i64(fp0);
11538        }
11539        break;
11540    case OPC_CVT_S_PU:
11541        check_cp1_64bitmode(ctx);
11542        {
11543            TCGv_i32 fp0 = tcg_temp_new_i32();
11544
11545            gen_load_fpr32h(ctx, fp0, fs);
11546            gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
11547            gen_store_fpr32(ctx, fp0, fd);
11548            tcg_temp_free_i32(fp0);
11549        }
11550        break;
11551    case OPC_CVT_PW_PS:
11552        check_ps(ctx);
11553        {
11554            TCGv_i64 fp0 = tcg_temp_new_i64();
11555
11556            gen_load_fpr64(ctx, fp0, fs);
11557            gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
11558            gen_store_fpr64(ctx, fp0, fd);
11559            tcg_temp_free_i64(fp0);
11560        }
11561        break;
11562    case OPC_CVT_S_PL:
11563        check_cp1_64bitmode(ctx);
11564        {
11565            TCGv_i32 fp0 = tcg_temp_new_i32();
11566
11567            gen_load_fpr32(ctx, fp0, fs);
11568            gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
11569            gen_store_fpr32(ctx, fp0, fd);
11570            tcg_temp_free_i32(fp0);
11571        }
11572        break;
11573    case OPC_PLL_PS:
11574        check_ps(ctx);
11575        {
11576            TCGv_i32 fp0 = tcg_temp_new_i32();
11577            TCGv_i32 fp1 = tcg_temp_new_i32();
11578
11579            gen_load_fpr32(ctx, fp0, fs);
11580            gen_load_fpr32(ctx, fp1, ft);
11581            gen_store_fpr32h(ctx, fp0, fd);
11582            gen_store_fpr32(ctx, fp1, fd);
11583            tcg_temp_free_i32(fp0);
11584            tcg_temp_free_i32(fp1);
11585        }
11586        break;
11587    case OPC_PLU_PS:
11588        check_ps(ctx);
11589        {
11590            TCGv_i32 fp0 = tcg_temp_new_i32();
11591            TCGv_i32 fp1 = tcg_temp_new_i32();
11592
11593            gen_load_fpr32(ctx, fp0, fs);
11594            gen_load_fpr32h(ctx, fp1, ft);
11595            gen_store_fpr32(ctx, fp1, fd);
11596            gen_store_fpr32h(ctx, fp0, fd);
11597            tcg_temp_free_i32(fp0);
11598            tcg_temp_free_i32(fp1);
11599        }
11600        break;
11601    case OPC_PUL_PS:
11602        check_ps(ctx);
11603        {
11604            TCGv_i32 fp0 = tcg_temp_new_i32();
11605            TCGv_i32 fp1 = tcg_temp_new_i32();
11606
11607            gen_load_fpr32h(ctx, fp0, fs);
11608            gen_load_fpr32(ctx, fp1, ft);
11609            gen_store_fpr32(ctx, fp1, fd);
11610            gen_store_fpr32h(ctx, fp0, fd);
11611            tcg_temp_free_i32(fp0);
11612            tcg_temp_free_i32(fp1);
11613        }
11614        break;
11615    case OPC_PUU_PS:
11616        check_ps(ctx);
11617        {
11618            TCGv_i32 fp0 = tcg_temp_new_i32();
11619            TCGv_i32 fp1 = tcg_temp_new_i32();
11620
11621            gen_load_fpr32h(ctx, fp0, fs);
11622            gen_load_fpr32h(ctx, fp1, ft);
11623            gen_store_fpr32(ctx, fp1, fd);
11624            gen_store_fpr32h(ctx, fp0, fd);
11625            tcg_temp_free_i32(fp0);
11626            tcg_temp_free_i32(fp1);
11627        }
11628        break;
11629    case OPC_CMP_F_PS:
11630    case OPC_CMP_UN_PS:
11631    case OPC_CMP_EQ_PS:
11632    case OPC_CMP_UEQ_PS:
11633    case OPC_CMP_OLT_PS:
11634    case OPC_CMP_ULT_PS:
11635    case OPC_CMP_OLE_PS:
11636    case OPC_CMP_ULE_PS:
11637    case OPC_CMP_SF_PS:
11638    case OPC_CMP_NGLE_PS:
11639    case OPC_CMP_SEQ_PS:
11640    case OPC_CMP_NGL_PS:
11641    case OPC_CMP_LT_PS:
11642    case OPC_CMP_NGE_PS:
11643    case OPC_CMP_LE_PS:
11644    case OPC_CMP_NGT_PS:
11645        if (ctx->opcode & (1 << 6)) {
11646            gen_cmpabs_ps(ctx, func - 48, ft, fs, cc);
11647        } else {
11648            gen_cmp_ps(ctx, func - 48, ft, fs, cc);
11649        }
11650        break;
11651    default:
11652        MIPS_INVAL("farith");
11653        gen_reserved_instruction(ctx);
11654        return;
11655    }
11656}
11657
11658/* Coprocessor 3 (FPU) */
11659static void gen_flt3_ldst(DisasContext *ctx, uint32_t opc,
11660                          int fd, int fs, int base, int index)
11661{
11662    TCGv t0 = tcg_temp_new();
11663
11664    if (base == 0) {
11665        gen_load_gpr(t0, index);
11666    } else if (index == 0) {
11667        gen_load_gpr(t0, base);
11668    } else {
11669        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
11670    }
11671    /*
11672     * Don't do NOP if destination is zero: we must perform the actual
11673     * memory access.
11674     */
11675    switch (opc) {
11676    case OPC_LWXC1:
11677        check_cop1x(ctx);
11678        {
11679            TCGv_i32 fp0 = tcg_temp_new_i32();
11680
11681            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
11682            tcg_gen_trunc_tl_i32(fp0, t0);
11683            gen_store_fpr32(ctx, fp0, fd);
11684            tcg_temp_free_i32(fp0);
11685        }
11686        break;
11687    case OPC_LDXC1:
11688        check_cop1x(ctx);
11689        check_cp1_registers(ctx, fd);
11690        {
11691            TCGv_i64 fp0 = tcg_temp_new_i64();
11692            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11693            gen_store_fpr64(ctx, fp0, fd);
11694            tcg_temp_free_i64(fp0);
11695        }
11696        break;
11697    case OPC_LUXC1:
11698        check_cp1_64bitmode(ctx);
11699        tcg_gen_andi_tl(t0, t0, ~0x7);
11700        {
11701            TCGv_i64 fp0 = tcg_temp_new_i64();
11702
11703            tcg_gen_qemu_ld_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11704            gen_store_fpr64(ctx, fp0, fd);
11705            tcg_temp_free_i64(fp0);
11706        }
11707        break;
11708    case OPC_SWXC1:
11709        check_cop1x(ctx);
11710        {
11711            TCGv_i32 fp0 = tcg_temp_new_i32();
11712            gen_load_fpr32(ctx, fp0, fs);
11713            tcg_gen_qemu_st_i32(fp0, t0, ctx->mem_idx, MO_TEUL);
11714            tcg_temp_free_i32(fp0);
11715        }
11716        break;
11717    case OPC_SDXC1:
11718        check_cop1x(ctx);
11719        check_cp1_registers(ctx, fs);
11720        {
11721            TCGv_i64 fp0 = tcg_temp_new_i64();
11722            gen_load_fpr64(ctx, fp0, fs);
11723            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11724            tcg_temp_free_i64(fp0);
11725        }
11726        break;
11727    case OPC_SUXC1:
11728        check_cp1_64bitmode(ctx);
11729        tcg_gen_andi_tl(t0, t0, ~0x7);
11730        {
11731            TCGv_i64 fp0 = tcg_temp_new_i64();
11732            gen_load_fpr64(ctx, fp0, fs);
11733            tcg_gen_qemu_st_i64(fp0, t0, ctx->mem_idx, MO_TEQ);
11734            tcg_temp_free_i64(fp0);
11735        }
11736        break;
11737    }
11738    tcg_temp_free(t0);
11739}
11740
11741static void gen_flt3_arith(DisasContext *ctx, uint32_t opc,
11742                           int fd, int fr, int fs, int ft)
11743{
11744    switch (opc) {
11745    case OPC_ALNV_PS:
11746        check_ps(ctx);
11747        {
11748            TCGv t0 = tcg_temp_local_new();
11749            TCGv_i32 fp = tcg_temp_new_i32();
11750            TCGv_i32 fph = tcg_temp_new_i32();
11751            TCGLabel *l1 = gen_new_label();
11752            TCGLabel *l2 = gen_new_label();
11753
11754            gen_load_gpr(t0, fr);
11755            tcg_gen_andi_tl(t0, t0, 0x7);
11756
11757            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
11758            gen_load_fpr32(ctx, fp, fs);
11759            gen_load_fpr32h(ctx, fph, fs);
11760            gen_store_fpr32(ctx, fp, fd);
11761            gen_store_fpr32h(ctx, fph, fd);
11762            tcg_gen_br(l2);
11763            gen_set_label(l1);
11764            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
11765            tcg_temp_free(t0);
11766#ifdef TARGET_WORDS_BIGENDIAN
11767            gen_load_fpr32(ctx, fp, fs);
11768            gen_load_fpr32h(ctx, fph, ft);
11769            gen_store_fpr32h(ctx, fp, fd);
11770            gen_store_fpr32(ctx, fph, fd);
11771#else
11772            gen_load_fpr32h(ctx, fph, fs);
11773            gen_load_fpr32(ctx, fp, ft);
11774            gen_store_fpr32(ctx, fph, fd);
11775            gen_store_fpr32h(ctx, fp, fd);
11776#endif
11777            gen_set_label(l2);
11778            tcg_temp_free_i32(fp);
11779            tcg_temp_free_i32(fph);
11780        }
11781        break;
11782    case OPC_MADD_S:
11783        check_cop1x(ctx);
11784        {
11785            TCGv_i32 fp0 = tcg_temp_new_i32();
11786            TCGv_i32 fp1 = tcg_temp_new_i32();
11787            TCGv_i32 fp2 = tcg_temp_new_i32();
11788
11789            gen_load_fpr32(ctx, fp0, fs);
11790            gen_load_fpr32(ctx, fp1, ft);
11791            gen_load_fpr32(ctx, fp2, fr);
11792            gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
11793            tcg_temp_free_i32(fp0);
11794            tcg_temp_free_i32(fp1);
11795            gen_store_fpr32(ctx, fp2, fd);
11796            tcg_temp_free_i32(fp2);
11797        }
11798        break;
11799    case OPC_MADD_D:
11800        check_cop1x(ctx);
11801        check_cp1_registers(ctx, fd | fs | ft | fr);
11802        {
11803            TCGv_i64 fp0 = tcg_temp_new_i64();
11804            TCGv_i64 fp1 = tcg_temp_new_i64();
11805            TCGv_i64 fp2 = tcg_temp_new_i64();
11806
11807            gen_load_fpr64(ctx, fp0, fs);
11808            gen_load_fpr64(ctx, fp1, ft);
11809            gen_load_fpr64(ctx, fp2, fr);
11810            gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
11811            tcg_temp_free_i64(fp0);
11812            tcg_temp_free_i64(fp1);
11813            gen_store_fpr64(ctx, fp2, fd);
11814            tcg_temp_free_i64(fp2);
11815        }
11816        break;
11817    case OPC_MADD_PS:
11818        check_ps(ctx);
11819        {
11820            TCGv_i64 fp0 = tcg_temp_new_i64();
11821            TCGv_i64 fp1 = tcg_temp_new_i64();
11822            TCGv_i64 fp2 = tcg_temp_new_i64();
11823
11824            gen_load_fpr64(ctx, fp0, fs);
11825            gen_load_fpr64(ctx, fp1, ft);
11826            gen_load_fpr64(ctx, fp2, fr);
11827            gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
11828            tcg_temp_free_i64(fp0);
11829            tcg_temp_free_i64(fp1);
11830            gen_store_fpr64(ctx, fp2, fd);
11831            tcg_temp_free_i64(fp2);
11832        }
11833        break;
11834    case OPC_MSUB_S:
11835        check_cop1x(ctx);
11836        {
11837            TCGv_i32 fp0 = tcg_temp_new_i32();
11838            TCGv_i32 fp1 = tcg_temp_new_i32();
11839            TCGv_i32 fp2 = tcg_temp_new_i32();
11840
11841            gen_load_fpr32(ctx, fp0, fs);
11842            gen_load_fpr32(ctx, fp1, ft);
11843            gen_load_fpr32(ctx, fp2, fr);
11844            gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
11845            tcg_temp_free_i32(fp0);
11846            tcg_temp_free_i32(fp1);
11847            gen_store_fpr32(ctx, fp2, fd);
11848            tcg_temp_free_i32(fp2);
11849        }
11850        break;
11851    case OPC_MSUB_D:
11852        check_cop1x(ctx);
11853        check_cp1_registers(ctx, fd | fs | ft | fr);
11854        {
11855            TCGv_i64 fp0 = tcg_temp_new_i64();
11856            TCGv_i64 fp1 = tcg_temp_new_i64();
11857            TCGv_i64 fp2 = tcg_temp_new_i64();
11858
11859            gen_load_fpr64(ctx, fp0, fs);
11860            gen_load_fpr64(ctx, fp1, ft);
11861            gen_load_fpr64(ctx, fp2, fr);
11862            gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
11863            tcg_temp_free_i64(fp0);
11864            tcg_temp_free_i64(fp1);
11865            gen_store_fpr64(ctx, fp2, fd);
11866            tcg_temp_free_i64(fp2);
11867        }
11868        break;
11869    case OPC_MSUB_PS:
11870        check_ps(ctx);
11871        {
11872            TCGv_i64 fp0 = tcg_temp_new_i64();
11873            TCGv_i64 fp1 = tcg_temp_new_i64();
11874            TCGv_i64 fp2 = tcg_temp_new_i64();
11875
11876            gen_load_fpr64(ctx, fp0, fs);
11877            gen_load_fpr64(ctx, fp1, ft);
11878            gen_load_fpr64(ctx, fp2, fr);
11879            gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
11880            tcg_temp_free_i64(fp0);
11881            tcg_temp_free_i64(fp1);
11882            gen_store_fpr64(ctx, fp2, fd);
11883            tcg_temp_free_i64(fp2);
11884        }
11885        break;
11886    case OPC_NMADD_S:
11887        check_cop1x(ctx);
11888        {
11889            TCGv_i32 fp0 = tcg_temp_new_i32();
11890            TCGv_i32 fp1 = tcg_temp_new_i32();
11891            TCGv_i32 fp2 = tcg_temp_new_i32();
11892
11893            gen_load_fpr32(ctx, fp0, fs);
11894            gen_load_fpr32(ctx, fp1, ft);
11895            gen_load_fpr32(ctx, fp2, fr);
11896            gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
11897            tcg_temp_free_i32(fp0);
11898            tcg_temp_free_i32(fp1);
11899            gen_store_fpr32(ctx, fp2, fd);
11900            tcg_temp_free_i32(fp2);
11901        }
11902        break;
11903    case OPC_NMADD_D:
11904        check_cop1x(ctx);
11905        check_cp1_registers(ctx, fd | fs | ft | fr);
11906        {
11907            TCGv_i64 fp0 = tcg_temp_new_i64();
11908            TCGv_i64 fp1 = tcg_temp_new_i64();
11909            TCGv_i64 fp2 = tcg_temp_new_i64();
11910
11911            gen_load_fpr64(ctx, fp0, fs);
11912            gen_load_fpr64(ctx, fp1, ft);
11913            gen_load_fpr64(ctx, fp2, fr);
11914            gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
11915            tcg_temp_free_i64(fp0);
11916            tcg_temp_free_i64(fp1);
11917            gen_store_fpr64(ctx, fp2, fd);
11918            tcg_temp_free_i64(fp2);
11919        }
11920        break;
11921    case OPC_NMADD_PS:
11922        check_ps(ctx);
11923        {
11924            TCGv_i64 fp0 = tcg_temp_new_i64();
11925            TCGv_i64 fp1 = tcg_temp_new_i64();
11926            TCGv_i64 fp2 = tcg_temp_new_i64();
11927
11928            gen_load_fpr64(ctx, fp0, fs);
11929            gen_load_fpr64(ctx, fp1, ft);
11930            gen_load_fpr64(ctx, fp2, fr);
11931            gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
11932            tcg_temp_free_i64(fp0);
11933            tcg_temp_free_i64(fp1);
11934            gen_store_fpr64(ctx, fp2, fd);
11935            tcg_temp_free_i64(fp2);
11936        }
11937        break;
11938    case OPC_NMSUB_S:
11939        check_cop1x(ctx);
11940        {
11941            TCGv_i32 fp0 = tcg_temp_new_i32();
11942            TCGv_i32 fp1 = tcg_temp_new_i32();
11943            TCGv_i32 fp2 = tcg_temp_new_i32();
11944
11945            gen_load_fpr32(ctx, fp0, fs);
11946            gen_load_fpr32(ctx, fp1, ft);
11947            gen_load_fpr32(ctx, fp2, fr);
11948            gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
11949            tcg_temp_free_i32(fp0);
11950            tcg_temp_free_i32(fp1);
11951            gen_store_fpr32(ctx, fp2, fd);
11952            tcg_temp_free_i32(fp2);
11953        }
11954        break;
11955    case OPC_NMSUB_D:
11956        check_cop1x(ctx);
11957        check_cp1_registers(ctx, fd | fs | ft | fr);
11958        {
11959            TCGv_i64 fp0 = tcg_temp_new_i64();
11960            TCGv_i64 fp1 = tcg_temp_new_i64();
11961            TCGv_i64 fp2 = tcg_temp_new_i64();
11962
11963            gen_load_fpr64(ctx, fp0, fs);
11964            gen_load_fpr64(ctx, fp1, ft);
11965            gen_load_fpr64(ctx, fp2, fr);
11966            gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
11967            tcg_temp_free_i64(fp0);
11968            tcg_temp_free_i64(fp1);
11969            gen_store_fpr64(ctx, fp2, fd);
11970            tcg_temp_free_i64(fp2);
11971        }
11972        break;
11973    case OPC_NMSUB_PS:
11974        check_ps(ctx);
11975        {
11976            TCGv_i64 fp0 = tcg_temp_new_i64();
11977            TCGv_i64 fp1 = tcg_temp_new_i64();
11978            TCGv_i64 fp2 = tcg_temp_new_i64();
11979
11980            gen_load_fpr64(ctx, fp0, fs);
11981            gen_load_fpr64(ctx, fp1, ft);
11982            gen_load_fpr64(ctx, fp2, fr);
11983            gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
11984            tcg_temp_free_i64(fp0);
11985            tcg_temp_free_i64(fp1);
11986            gen_store_fpr64(ctx, fp2, fd);
11987            tcg_temp_free_i64(fp2);
11988        }
11989        break;
11990    default:
11991        MIPS_INVAL("flt3_arith");
11992        gen_reserved_instruction(ctx);
11993        return;
11994    }
11995}
11996
11997void gen_rdhwr(DisasContext *ctx, int rt, int rd, int sel)
11998{
11999    TCGv t0;
12000
12001#if !defined(CONFIG_USER_ONLY)
12002    /*
12003     * The Linux kernel will emulate rdhwr if it's not supported natively.
12004     * Therefore only check the ISA in system mode.
12005     */
12006    check_insn(ctx, ISA_MIPS_R2);
12007#endif
12008    t0 = tcg_temp_new();
12009
12010    switch (rd) {
12011    case 0:
12012        gen_helper_rdhwr_cpunum(t0, cpu_env);
12013        gen_store_gpr(t0, rt);
12014        break;
12015    case 1:
12016        gen_helper_rdhwr_synci_step(t0, cpu_env);
12017        gen_store_gpr(t0, rt);
12018        break;
12019    case 2:
12020        if (tb_cflags(ctx->base.tb) & CF_USE_ICOUNT) {
12021            gen_io_start();
12022        }
12023        gen_helper_rdhwr_cc(t0, cpu_env);
12024        gen_store_gpr(t0, rt);
12025        /*
12026         * Break the TB to be able to take timer interrupts immediately
12027         * after reading count. DISAS_STOP isn't sufficient, we need to ensure
12028         * we break completely out of translated code.
12029         */
12030        gen_save_pc(ctx->base.pc_next + 4);
12031        ctx->base.is_jmp = DISAS_EXIT;
12032        break;
12033    case 3:
12034        gen_helper_rdhwr_ccres(t0, cpu_env);
12035        gen_store_gpr(t0, rt);
12036        break;
12037    case 4:
12038        check_insn(ctx, ISA_MIPS_R6);
12039        if (sel != 0) {
12040            /*
12041             * Performance counter registers are not implemented other than
12042             * control register 0.
12043             */
12044            generate_exception(ctx, EXCP_RI);
12045        }
12046        gen_helper_rdhwr_performance(t0, cpu_env);
12047        gen_store_gpr(t0, rt);
12048        break;
12049    case 5:
12050        check_insn(ctx, ISA_MIPS_R6);
12051        gen_helper_rdhwr_xnp(t0, cpu_env);
12052        gen_store_gpr(t0, rt);
12053        break;
12054    case 29:
12055#if defined(CONFIG_USER_ONLY)
12056        tcg_gen_ld_tl(t0, cpu_env,
12057                      offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12058        gen_store_gpr(t0, rt);
12059        break;
12060#else
12061        if ((ctx->hflags & MIPS_HFLAG_CP0) ||
12062            (ctx->hflags & MIPS_HFLAG_HWRENA_ULR)) {
12063            tcg_gen_ld_tl(t0, cpu_env,
12064                          offsetof(CPUMIPSState, active_tc.CP0_UserLocal));
12065            gen_store_gpr(t0, rt);
12066        } else {
12067            gen_reserved_instruction(ctx);
12068        }
12069        break;
12070#endif
12071    default:            /* Invalid */
12072        MIPS_INVAL("rdhwr");
12073        gen_reserved_instruction(ctx);
12074        break;
12075    }
12076    tcg_temp_free(t0);
12077}
12078
12079static inline void clear_branch_hflags(DisasContext *ctx)
12080{
12081    ctx->hflags &= ~MIPS_HFLAG_BMASK;
12082    if (ctx->base.is_jmp == DISAS_NEXT) {
12083        save_cpu_state(ctx, 0);
12084    } else {
12085        /*
12086         * It is not safe to save ctx->hflags as hflags may be changed
12087         * in execution time by the instruction in delay / forbidden slot.
12088         */
12089        tcg_gen_andi_i32(hflags, hflags, ~MIPS_HFLAG_BMASK);
12090    }
12091}
12092
12093static void gen_branch(DisasContext *ctx, int insn_bytes)
12094{
12095    if (ctx->hflags & MIPS_HFLAG_BMASK) {
12096        int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
12097        /* Branches completion */
12098        clear_branch_hflags(ctx);
12099        ctx->base.is_jmp = DISAS_NORETURN;
12100        /* FIXME: Need to clear can_do_io.  */
12101        switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
12102        case MIPS_HFLAG_FBNSLOT:
12103            gen_goto_tb(ctx, 0, ctx->base.pc_next + insn_bytes);
12104            break;
12105        case MIPS_HFLAG_B:
12106            /* unconditional branch */
12107            if (proc_hflags & MIPS_HFLAG_BX) {
12108                tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
12109            }
12110            gen_goto_tb(ctx, 0, ctx->btarget);
12111            break;
12112        case MIPS_HFLAG_BL:
12113            /* blikely taken case */
12114            gen_goto_tb(ctx, 0, ctx->btarget);
12115            break;
12116        case MIPS_HFLAG_BC:
12117            /* Conditional branch */
12118            {
12119                TCGLabel *l1 = gen_new_label();
12120
12121                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
12122                gen_goto_tb(ctx, 1, ctx->base.pc_next + insn_bytes);
12123                gen_set_label(l1);
12124                gen_goto_tb(ctx, 0, ctx->btarget);
12125            }
12126            break;
12127        case MIPS_HFLAG_BR:
12128            /* unconditional branch to register */
12129            if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
12130                TCGv t0 = tcg_temp_new();
12131                TCGv_i32 t1 = tcg_temp_new_i32();
12132
12133                tcg_gen_andi_tl(t0, btarget, 0x1);
12134                tcg_gen_trunc_tl_i32(t1, t0);
12135                tcg_temp_free(t0);
12136                tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
12137                tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
12138                tcg_gen_or_i32(hflags, hflags, t1);
12139                tcg_temp_free_i32(t1);
12140
12141                tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
12142            } else {
12143                tcg_gen_mov_tl(cpu_PC, btarget);
12144            }
12145            if (ctx->base.singlestep_enabled) {
12146                save_cpu_state(ctx, 0);
12147                gen_helper_raise_exception_debug(cpu_env);
12148            }
12149            tcg_gen_lookup_and_goto_ptr();
12150            break;
12151        default:
12152            fprintf(stderr, "unknown branch 0x%x\n", proc_hflags);
12153            abort();
12154        }
12155    }
12156}
12157
12158/* Compact Branches */
12159static void gen_compute_compact_branch(DisasContext *ctx, uint32_t opc,
12160                                       int rs, int rt, int32_t offset)
12161{
12162    int bcond_compute = 0;
12163    TCGv t0 = tcg_temp_new();
12164    TCGv t1 = tcg_temp_new();
12165    int m16_lowbit = (ctx->hflags & MIPS_HFLAG_M16) != 0;
12166
12167    if (ctx->hflags & MIPS_HFLAG_BMASK) {
12168#ifdef MIPS_DEBUG_DISAS
12169        LOG_DISAS("Branch in delay / forbidden slot at PC 0x" TARGET_FMT_lx
12170                  "\n", ctx->base.pc_next);
12171#endif
12172        gen_reserved_instruction(ctx);
12173        goto out;
12174    }
12175
12176    /* Load needed operands and calculate btarget */
12177    switch (opc) {
12178    /* compact branch */
12179    case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12180    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12181        gen_load_gpr(t0, rs);
12182        gen_load_gpr(t1, rt);
12183        bcond_compute = 1;
12184        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12185        if (rs <= rt && rs == 0) {
12186            /* OPC_BEQZALC, OPC_BNEZALC */
12187            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12188        }
12189        break;
12190    case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12191    case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12192        gen_load_gpr(t0, rs);
12193        gen_load_gpr(t1, rt);
12194        bcond_compute = 1;
12195        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12196        break;
12197    case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12198    case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12199        if (rs == 0 || rs == rt) {
12200            /* OPC_BLEZALC, OPC_BGEZALC */
12201            /* OPC_BGTZALC, OPC_BLTZALC */
12202            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12203        }
12204        gen_load_gpr(t0, rs);
12205        gen_load_gpr(t1, rt);
12206        bcond_compute = 1;
12207        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12208        break;
12209    case OPC_BC:
12210    case OPC_BALC:
12211        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12212        break;
12213    case OPC_BEQZC:
12214    case OPC_BNEZC:
12215        if (rs != 0) {
12216            /* OPC_BEQZC, OPC_BNEZC */
12217            gen_load_gpr(t0, rs);
12218            bcond_compute = 1;
12219            ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
12220        } else {
12221            /* OPC_JIC, OPC_JIALC */
12222            TCGv tbase = tcg_temp_new();
12223            TCGv toffset = tcg_temp_new();
12224
12225            gen_load_gpr(tbase, rt);
12226            tcg_gen_movi_tl(toffset, offset);
12227            gen_op_addr_add(ctx, btarget, tbase, toffset);
12228            tcg_temp_free(tbase);
12229            tcg_temp_free(toffset);
12230        }
12231        break;
12232    default:
12233        MIPS_INVAL("Compact branch/jump");
12234        gen_reserved_instruction(ctx);
12235        goto out;
12236    }
12237
12238    if (bcond_compute == 0) {
12239        /* Uncoditional compact branch */
12240        switch (opc) {
12241        case OPC_JIALC:
12242            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12243            /* Fallthrough */
12244        case OPC_JIC:
12245            ctx->hflags |= MIPS_HFLAG_BR;
12246            break;
12247        case OPC_BALC:
12248            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4 + m16_lowbit);
12249            /* Fallthrough */
12250        case OPC_BC:
12251            ctx->hflags |= MIPS_HFLAG_B;
12252            break;
12253        default:
12254            MIPS_INVAL("Compact branch/jump");
12255            gen_reserved_instruction(ctx);
12256            goto out;
12257        }
12258
12259        /* Generating branch here as compact branches don't have delay slot */
12260        gen_branch(ctx, 4);
12261    } else {
12262        /* Conditional compact branch */
12263        TCGLabel *fs = gen_new_label();
12264        save_cpu_state(ctx, 0);
12265
12266        switch (opc) {
12267        case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC */
12268            if (rs == 0 && rt != 0) {
12269                /* OPC_BLEZALC */
12270                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12271            } else if (rs != 0 && rt != 0 && rs == rt) {
12272                /* OPC_BGEZALC */
12273                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12274            } else {
12275                /* OPC_BGEUC */
12276                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
12277            }
12278            break;
12279        case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC */
12280            if (rs == 0 && rt != 0) {
12281                /* OPC_BGTZALC */
12282                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12283            } else if (rs != 0 && rt != 0 && rs == rt) {
12284                /* OPC_BLTZALC */
12285                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12286            } else {
12287                /* OPC_BLTUC */
12288                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
12289            }
12290            break;
12291        case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC */
12292            if (rs == 0 && rt != 0) {
12293                /* OPC_BLEZC */
12294                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
12295            } else if (rs != 0 && rt != 0 && rs == rt) {
12296                /* OPC_BGEZC */
12297                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
12298            } else {
12299                /* OPC_BGEC */
12300                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
12301            }
12302            break;
12303        case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC */
12304            if (rs == 0 && rt != 0) {
12305                /* OPC_BGTZC */
12306                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
12307            } else if (rs != 0 && rt != 0 && rs == rt) {
12308                /* OPC_BLTZC */
12309                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
12310            } else {
12311                /* OPC_BLTC */
12312                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
12313            }
12314            break;
12315        case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC */
12316        case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
12317            if (rs >= rt) {
12318                /* OPC_BOVC, OPC_BNVC */
12319                TCGv t2 = tcg_temp_new();
12320                TCGv t3 = tcg_temp_new();
12321                TCGv t4 = tcg_temp_new();
12322                TCGv input_overflow = tcg_temp_new();
12323
12324                gen_load_gpr(t0, rs);
12325                gen_load_gpr(t1, rt);
12326                tcg_gen_ext32s_tl(t2, t0);
12327                tcg_gen_setcond_tl(TCG_COND_NE, input_overflow, t2, t0);
12328                tcg_gen_ext32s_tl(t3, t1);
12329                tcg_gen_setcond_tl(TCG_COND_NE, t4, t3, t1);
12330                tcg_gen_or_tl(input_overflow, input_overflow, t4);
12331
12332                tcg_gen_add_tl(t4, t2, t3);
12333                tcg_gen_ext32s_tl(t4, t4);
12334                tcg_gen_xor_tl(t2, t2, t3);
12335                tcg_gen_xor_tl(t3, t4, t3);
12336                tcg_gen_andc_tl(t2, t3, t2);
12337                tcg_gen_setcondi_tl(TCG_COND_LT, t4, t2, 0);
12338                tcg_gen_or_tl(t4, t4, input_overflow);
12339                if (opc == OPC_BOVC) {
12340                    /* OPC_BOVC */
12341                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t4, 0, fs);
12342                } else {
12343                    /* OPC_BNVC */
12344                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t4, 0, fs);
12345                }
12346                tcg_temp_free(input_overflow);
12347                tcg_temp_free(t4);
12348                tcg_temp_free(t3);
12349                tcg_temp_free(t2);
12350            } else if (rs < rt && rs == 0) {
12351                /* OPC_BEQZALC, OPC_BNEZALC */
12352                if (opc == OPC_BEQZALC) {
12353                    /* OPC_BEQZALC */
12354                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t1, 0, fs);
12355                } else {
12356                    /* OPC_BNEZALC */
12357                    tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t1, 0, fs);
12358                }
12359            } else {
12360                /* OPC_BEQC, OPC_BNEC */
12361                if (opc == OPC_BEQC) {
12362                    /* OPC_BEQC */
12363                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_EQ), t0, t1, fs);
12364                } else {
12365                    /* OPC_BNEC */
12366                    tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_NE), t0, t1, fs);
12367                }
12368            }
12369            break;
12370        case OPC_BEQZC:
12371            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
12372            break;
12373        case OPC_BNEZC:
12374            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_NE), t0, 0, fs);
12375            break;
12376        default:
12377            MIPS_INVAL("Compact conditional branch/jump");
12378            gen_reserved_instruction(ctx);
12379            goto out;
12380        }
12381
12382        /* Generating branch here as compact branches don't have delay slot */
12383        gen_goto_tb(ctx, 1, ctx->btarget);
12384        gen_set_label(fs);
12385
12386        ctx->hflags |= MIPS_HFLAG_FBNSLOT;
12387    }
12388
12389out:
12390    tcg_temp_free(t0);
12391    tcg_temp_free(t1);
12392}
12393
12394/* ISA extensions (ASEs) */
12395/* MIPS16 extension to MIPS32 */
12396
12397/* MIPS16 major opcodes */
12398enum {
12399  M16_OPC_ADDIUSP = 0x00,
12400  M16_OPC_ADDIUPC = 0x01,
12401  M16_OPC_B = 0x02,
12402  M16_OPC_JAL = 0x03,
12403  M16_OPC_BEQZ = 0x04,
12404  M16_OPC_BNEQZ = 0x05,
12405  M16_OPC_SHIFT = 0x06,
12406  M16_OPC_LD = 0x07,
12407  M16_OPC_RRIA = 0x08,
12408  M16_OPC_ADDIU8 = 0x09,
12409  M16_OPC_SLTI = 0x0a,
12410  M16_OPC_SLTIU = 0x0b,
12411  M16_OPC_I8 = 0x0c,
12412  M16_OPC_LI = 0x0d,
12413  M16_OPC_CMPI = 0x0e,
12414  M16_OPC_SD = 0x0f,
12415  M16_OPC_LB = 0x10,
12416  M16_OPC_LH = 0x11,
12417  M16_OPC_LWSP = 0x12,
12418  M16_OPC_LW = 0x13,
12419  M16_OPC_LBU = 0x14,
12420  M16_OPC_LHU = 0x15,
12421  M16_OPC_LWPC = 0x16,
12422  M16_OPC_LWU = 0x17,
12423  M16_OPC_SB = 0x18,
12424  M16_OPC_SH = 0x19,
12425  M16_OPC_SWSP = 0x1a,
12426  M16_OPC_SW = 0x1b,
12427  M16_OPC_RRR = 0x1c,
12428  M16_OPC_RR = 0x1d,
12429  M16_OPC_EXTEND = 0x1e,
12430  M16_OPC_I64 = 0x1f
12431};
12432
12433/* I8 funct field */
12434enum {
12435  I8_BTEQZ = 0x0,
12436  I8_BTNEZ = 0x1,
12437  I8_SWRASP = 0x2,
12438  I8_ADJSP = 0x3,
12439  I8_SVRS = 0x4,
12440  I8_MOV32R = 0x5,
12441  I8_MOVR32 = 0x7
12442};
12443
12444/* RRR f field */
12445enum {
12446  RRR_DADDU = 0x0,
12447  RRR_ADDU = 0x1,
12448  RRR_DSUBU = 0x2,
12449  RRR_SUBU = 0x3
12450};
12451
12452/* RR funct field */
12453enum {
12454  RR_JR = 0x00,
12455  RR_SDBBP = 0x01,
12456  RR_SLT = 0x02,
12457  RR_SLTU = 0x03,
12458  RR_SLLV = 0x04,
12459  RR_BREAK = 0x05,
12460  RR_SRLV = 0x06,
12461  RR_SRAV = 0x07,
12462  RR_DSRL = 0x08,
12463  RR_CMP = 0x0a,
12464  RR_NEG = 0x0b,
12465  RR_AND = 0x0c,
12466  RR_OR = 0x0d,
12467  RR_XOR = 0x0e,
12468  RR_NOT = 0x0f,
12469  RR_MFHI = 0x10,
12470  RR_CNVT = 0x11,
12471  RR_MFLO = 0x12,
12472  RR_DSRA = 0x13,
12473  RR_DSLLV = 0x14,
12474  RR_DSRLV = 0x16,
12475  RR_DSRAV = 0x17,
12476  RR_MULT = 0x18,
12477  RR_MULTU = 0x19,
12478  RR_DIV = 0x1a,
12479  RR_DIVU = 0x1b,
12480  RR_DMULT = 0x1c,
12481  RR_DMULTU = 0x1d,
12482  RR_DDIV = 0x1e,
12483  RR_DDIVU = 0x1f
12484};
12485
12486/* I64 funct field */
12487enum {
12488  I64_LDSP = 0x0,
12489  I64_SDSP = 0x1,
12490  I64_SDRASP = 0x2,
12491  I64_DADJSP = 0x3,
12492  I64_LDPC = 0x4,
12493  I64_DADDIU5 = 0x5,
12494  I64_DADDIUPC = 0x6,
12495  I64_DADDIUSP = 0x7
12496};
12497
12498/* RR ry field for CNVT */
12499enum {
12500  RR_RY_CNVT_ZEB = 0x0,
12501  RR_RY_CNVT_ZEH = 0x1,
12502  RR_RY_CNVT_ZEW = 0x2,
12503  RR_RY_CNVT_SEB = 0x4,
12504  RR_RY_CNVT_SEH = 0x5,
12505  RR_RY_CNVT_SEW = 0x6,
12506};
12507
12508static int xlat(int r)
12509{
12510  static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
12511
12512  return map[r];
12513}
12514
12515static void gen_mips16_save(DisasContext *ctx,
12516                            int xsregs, int aregs,
12517                            int do_ra, int do_s0, int do_s1,
12518                            int framesize)
12519{
12520    TCGv t0 = tcg_temp_new();
12521    TCGv t1 = tcg_temp_new();
12522    TCGv t2 = tcg_temp_new();
12523    int args, astatic;
12524
12525    switch (aregs) {
12526    case 0:
12527    case 1:
12528    case 2:
12529    case 3:
12530    case 11:
12531        args = 0;
12532        break;
12533    case 4:
12534    case 5:
12535    case 6:
12536    case 7:
12537        args = 1;
12538        break;
12539    case 8:
12540    case 9:
12541    case 10:
12542        args = 2;
12543        break;
12544    case 12:
12545    case 13:
12546        args = 3;
12547        break;
12548    case 14:
12549        args = 4;
12550        break;
12551    default:
12552        gen_reserved_instruction(ctx);
12553        return;
12554    }
12555
12556    switch (args) {
12557    case 4:
12558        gen_base_offset_addr(ctx, t0, 29, 12);
12559        gen_load_gpr(t1, 7);
12560        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12561        /* Fall through */
12562    case 3:
12563        gen_base_offset_addr(ctx, t0, 29, 8);
12564        gen_load_gpr(t1, 6);
12565        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12566        /* Fall through */
12567    case 2:
12568        gen_base_offset_addr(ctx, t0, 29, 4);
12569        gen_load_gpr(t1, 5);
12570        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12571        /* Fall through */
12572    case 1:
12573        gen_base_offset_addr(ctx, t0, 29, 0);
12574        gen_load_gpr(t1, 4);
12575        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
12576    }
12577
12578    gen_load_gpr(t0, 29);
12579
12580#define DECR_AND_STORE(reg) do {                                 \
12581        tcg_gen_movi_tl(t2, -4);                                 \
12582        gen_op_addr_add(ctx, t0, t0, t2);                        \
12583        gen_load_gpr(t1, reg);                                   \
12584        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL); \
12585    } while (0)
12586
12587    if (do_ra) {
12588        DECR_AND_STORE(31);
12589    }
12590
12591    switch (xsregs) {
12592    case 7:
12593        DECR_AND_STORE(30);
12594        /* Fall through */
12595    case 6:
12596        DECR_AND_STORE(23);
12597        /* Fall through */
12598    case 5:
12599        DECR_AND_STORE(22);
12600        /* Fall through */
12601    case 4:
12602        DECR_AND_STORE(21);
12603        /* Fall through */
12604    case 3:
12605        DECR_AND_STORE(20);
12606        /* Fall through */
12607    case 2:
12608        DECR_AND_STORE(19);
12609        /* Fall through */
12610    case 1:
12611        DECR_AND_STORE(18);
12612    }
12613
12614    if (do_s1) {
12615        DECR_AND_STORE(17);
12616    }
12617    if (do_s0) {
12618        DECR_AND_STORE(16);
12619    }
12620
12621    switch (aregs) {
12622    case 0:
12623    case 4:
12624    case 8:
12625    case 12:
12626    case 14:
12627        astatic = 0;
12628        break;
12629    case 1:
12630    case 5:
12631    case 9:
12632    case 13:
12633        astatic = 1;
12634        break;
12635    case 2:
12636    case 6:
12637    case 10:
12638        astatic = 2;
12639        break;
12640    case 3:
12641    case 7:
12642        astatic = 3;
12643        break;
12644    case 11:
12645        astatic = 4;
12646        break;
12647    default:
12648        gen_reserved_instruction(ctx);
12649        return;
12650    }
12651
12652    if (astatic > 0) {
12653        DECR_AND_STORE(7);
12654        if (astatic > 1) {
12655            DECR_AND_STORE(6);
12656            if (astatic > 2) {
12657                DECR_AND_STORE(5);
12658                if (astatic > 3) {
12659                    DECR_AND_STORE(4);
12660                }
12661            }
12662        }
12663    }
12664#undef DECR_AND_STORE
12665
12666    tcg_gen_movi_tl(t2, -framesize);
12667    gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
12668    tcg_temp_free(t0);
12669    tcg_temp_free(t1);
12670    tcg_temp_free(t2);
12671}
12672
12673static void gen_mips16_restore(DisasContext *ctx,
12674                               int xsregs, int aregs,
12675                               int do_ra, int do_s0, int do_s1,
12676                               int framesize)
12677{
12678    int astatic;
12679    TCGv t0 = tcg_temp_new();
12680    TCGv t1 = tcg_temp_new();
12681    TCGv t2 = tcg_temp_new();
12682
12683    tcg_gen_movi_tl(t2, framesize);
12684    gen_op_addr_add(ctx, t0, cpu_gpr[29], t2);
12685
12686#define DECR_AND_LOAD(reg) do {                            \
12687        tcg_gen_movi_tl(t2, -4);                           \
12688        gen_op_addr_add(ctx, t0, t0, t2);                  \
12689        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL); \
12690        gen_store_gpr(t1, reg);                            \
12691    } while (0)
12692
12693    if (do_ra) {
12694        DECR_AND_LOAD(31);
12695    }
12696
12697    switch (xsregs) {
12698    case 7:
12699        DECR_AND_LOAD(30);
12700        /* Fall through */
12701    case 6:
12702        DECR_AND_LOAD(23);
12703        /* Fall through */
12704    case 5:
12705        DECR_AND_LOAD(22);
12706        /* Fall through */
12707    case 4:
12708        DECR_AND_LOAD(21);
12709        /* Fall through */
12710    case 3:
12711        DECR_AND_LOAD(20);
12712        /* Fall through */
12713    case 2:
12714        DECR_AND_LOAD(19);
12715        /* Fall through */
12716    case 1:
12717        DECR_AND_LOAD(18);
12718    }
12719
12720    if (do_s1) {
12721        DECR_AND_LOAD(17);
12722    }
12723    if (do_s0) {
12724        DECR_AND_LOAD(16);
12725    }
12726
12727    switch (aregs) {
12728    case 0:
12729    case 4:
12730    case 8:
12731    case 12:
12732    case 14:
12733        astatic = 0;
12734        break;
12735    case 1:
12736    case 5:
12737    case 9:
12738    case 13:
12739        astatic = 1;
12740        break;
12741    case 2:
12742    case 6:
12743    case 10:
12744        astatic = 2;
12745        break;
12746    case 3:
12747    case 7:
12748        astatic = 3;
12749        break;
12750    case 11:
12751        astatic = 4;
12752        break;
12753    default:
12754        gen_reserved_instruction(ctx);
12755        return;
12756    }
12757
12758    if (astatic > 0) {
12759        DECR_AND_LOAD(7);
12760        if (astatic > 1) {
12761            DECR_AND_LOAD(6);
12762            if (astatic > 2) {
12763                DECR_AND_LOAD(5);
12764                if (astatic > 3) {
12765                    DECR_AND_LOAD(4);
12766                }
12767            }
12768        }
12769    }
12770#undef DECR_AND_LOAD
12771
12772    tcg_gen_movi_tl(t2, framesize);
12773    gen_op_addr_add(ctx, cpu_gpr[29], cpu_gpr[29], t2);
12774    tcg_temp_free(t0);
12775    tcg_temp_free(t1);
12776    tcg_temp_free(t2);
12777}
12778
12779static void gen_addiupc(DisasContext *ctx, int rx, int imm,
12780                        int is_64_bit, int extended)
12781{
12782    TCGv t0;
12783
12784    if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
12785        gen_reserved_instruction(ctx);
12786        return;
12787    }
12788
12789    t0 = tcg_temp_new();
12790
12791    tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
12792    tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
12793    if (!is_64_bit) {
12794        tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
12795    }
12796
12797    tcg_temp_free(t0);
12798}
12799
12800static void gen_cache_operation(DisasContext *ctx, uint32_t op, int base,
12801                                int16_t offset)
12802{
12803    TCGv_i32 t0 = tcg_const_i32(op);
12804    TCGv t1 = tcg_temp_new();
12805    gen_base_offset_addr(ctx, t1, base, offset);
12806    gen_helper_cache(cpu_env, t1, t0);
12807    tcg_temp_free(t1);
12808    tcg_temp_free_i32(t0);
12809}
12810
12811#if defined(TARGET_MIPS64)
12812static void decode_i64_mips16(DisasContext *ctx,
12813                              int ry, int funct, int16_t offset,
12814                              int extended)
12815{
12816    switch (funct) {
12817    case I64_LDSP:
12818        check_insn(ctx, ISA_MIPS3);
12819        check_mips_64(ctx);
12820        offset = extended ? offset : offset << 3;
12821        gen_ld(ctx, OPC_LD, ry, 29, offset);
12822        break;
12823    case I64_SDSP:
12824        check_insn(ctx, ISA_MIPS3);
12825        check_mips_64(ctx);
12826        offset = extended ? offset : offset << 3;
12827        gen_st(ctx, OPC_SD, ry, 29, offset);
12828        break;
12829    case I64_SDRASP:
12830        check_insn(ctx, ISA_MIPS3);
12831        check_mips_64(ctx);
12832        offset = extended ? offset : (ctx->opcode & 0xff) << 3;
12833        gen_st(ctx, OPC_SD, 31, 29, offset);
12834        break;
12835    case I64_DADJSP:
12836        check_insn(ctx, ISA_MIPS3);
12837        check_mips_64(ctx);
12838        offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
12839        gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
12840        break;
12841    case I64_LDPC:
12842        check_insn(ctx, ISA_MIPS3);
12843        check_mips_64(ctx);
12844        if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
12845            gen_reserved_instruction(ctx);
12846        } else {
12847            offset = extended ? offset : offset << 3;
12848            gen_ld(ctx, OPC_LDPC, ry, 0, offset);
12849        }
12850        break;
12851    case I64_DADDIU5:
12852        check_insn(ctx, ISA_MIPS3);
12853        check_mips_64(ctx);
12854        offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
12855        gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
12856        break;
12857    case I64_DADDIUPC:
12858        check_insn(ctx, ISA_MIPS3);
12859        check_mips_64(ctx);
12860        offset = extended ? offset : offset << 2;
12861        gen_addiupc(ctx, ry, offset, 1, extended);
12862        break;
12863    case I64_DADDIUSP:
12864        check_insn(ctx, ISA_MIPS3);
12865        check_mips_64(ctx);
12866        offset = extended ? offset : offset << 2;
12867        gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
12868        break;
12869    }
12870}
12871#endif
12872
12873static int decode_extended_mips16_opc(CPUMIPSState *env, DisasContext *ctx)
12874{
12875    int extend = translator_lduw(env, ctx->base.pc_next + 2);
12876    int op, rx, ry, funct, sa;
12877    int16_t imm, offset;
12878
12879    ctx->opcode = (ctx->opcode << 16) | extend;
12880    op = (ctx->opcode >> 11) & 0x1f;
12881    sa = (ctx->opcode >> 22) & 0x1f;
12882    funct = (ctx->opcode >> 8) & 0x7;
12883    rx = xlat((ctx->opcode >> 8) & 0x7);
12884    ry = xlat((ctx->opcode >> 5) & 0x7);
12885    offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
12886                              | ((ctx->opcode >> 21) & 0x3f) << 5
12887                              | (ctx->opcode & 0x1f));
12888
12889    /*
12890     * The extended opcodes cleverly reuse the opcodes from their 16-bit
12891     * counterparts.
12892     */
12893    switch (op) {
12894    case M16_OPC_ADDIUSP:
12895        gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
12896        break;
12897    case M16_OPC_ADDIUPC:
12898        gen_addiupc(ctx, rx, imm, 0, 1);
12899        break;
12900    case M16_OPC_B:
12901        gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1, 0);
12902        /* No delay slot, so just process as a normal instruction */
12903        break;
12904    case M16_OPC_BEQZ:
12905        gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1, 0);
12906        /* No delay slot, so just process as a normal instruction */
12907        break;
12908    case M16_OPC_BNEQZ:
12909        gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1, 0);
12910        /* No delay slot, so just process as a normal instruction */
12911        break;
12912    case M16_OPC_SHIFT:
12913        switch (ctx->opcode & 0x3) {
12914        case 0x0:
12915            gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
12916            break;
12917        case 0x1:
12918#if defined(TARGET_MIPS64)
12919            check_mips_64(ctx);
12920            gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
12921#else
12922            gen_reserved_instruction(ctx);
12923#endif
12924            break;
12925        case 0x2:
12926            gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
12927            break;
12928        case 0x3:
12929            gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
12930            break;
12931        }
12932        break;
12933#if defined(TARGET_MIPS64)
12934    case M16_OPC_LD:
12935        check_insn(ctx, ISA_MIPS3);
12936        check_mips_64(ctx);
12937        gen_ld(ctx, OPC_LD, ry, rx, offset);
12938        break;
12939#endif
12940    case M16_OPC_RRIA:
12941        imm = ctx->opcode & 0xf;
12942        imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
12943        imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
12944        imm = (int16_t) (imm << 1) >> 1;
12945        if ((ctx->opcode >> 4) & 0x1) {
12946#if defined(TARGET_MIPS64)
12947            check_mips_64(ctx);
12948            gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
12949#else
12950            gen_reserved_instruction(ctx);
12951#endif
12952        } else {
12953            gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
12954        }
12955        break;
12956    case M16_OPC_ADDIU8:
12957        gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
12958        break;
12959    case M16_OPC_SLTI:
12960        gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
12961        break;
12962    case M16_OPC_SLTIU:
12963        gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
12964        break;
12965    case M16_OPC_I8:
12966        switch (funct) {
12967        case I8_BTEQZ:
12968            gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1, 0);
12969            break;
12970        case I8_BTNEZ:
12971            gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1, 0);
12972            break;
12973        case I8_SWRASP:
12974            gen_st(ctx, OPC_SW, 31, 29, imm);
12975            break;
12976        case I8_ADJSP:
12977            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
12978            break;
12979        case I8_SVRS:
12980            check_insn(ctx, ISA_MIPS_R1);
12981            {
12982                int xsregs = (ctx->opcode >> 24) & 0x7;
12983                int aregs = (ctx->opcode >> 16) & 0xf;
12984                int do_ra = (ctx->opcode >> 6) & 0x1;
12985                int do_s0 = (ctx->opcode >> 5) & 0x1;
12986                int do_s1 = (ctx->opcode >> 4) & 0x1;
12987                int framesize = (((ctx->opcode >> 20) & 0xf) << 4
12988                                 | (ctx->opcode & 0xf)) << 3;
12989
12990                if (ctx->opcode & (1 << 7)) {
12991                    gen_mips16_save(ctx, xsregs, aregs,
12992                                    do_ra, do_s0, do_s1,
12993                                    framesize);
12994                } else {
12995                    gen_mips16_restore(ctx, xsregs, aregs,
12996                                       do_ra, do_s0, do_s1,
12997                                       framesize);
12998                }
12999            }
13000            break;
13001        default:
13002            gen_reserved_instruction(ctx);
13003            break;
13004        }
13005        break;
13006    case M16_OPC_LI:
13007        tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
13008        break;
13009    case M16_OPC_CMPI:
13010        tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
13011        break;
13012#if defined(TARGET_MIPS64)
13013    case M16_OPC_SD:
13014        check_insn(ctx, ISA_MIPS3);
13015        check_mips_64(ctx);
13016        gen_st(ctx, OPC_SD, ry, rx, offset);
13017        break;
13018#endif
13019    case M16_OPC_LB:
13020        gen_ld(ctx, OPC_LB, ry, rx, offset);
13021        break;
13022    case M16_OPC_LH:
13023        gen_ld(ctx, OPC_LH, ry, rx, offset);
13024        break;
13025    case M16_OPC_LWSP:
13026        gen_ld(ctx, OPC_LW, rx, 29, offset);
13027        break;
13028    case M16_OPC_LW:
13029        gen_ld(ctx, OPC_LW, ry, rx, offset);
13030        break;
13031    case M16_OPC_LBU:
13032        gen_ld(ctx, OPC_LBU, ry, rx, offset);
13033        break;
13034    case M16_OPC_LHU:
13035        gen_ld(ctx, OPC_LHU, ry, rx, offset);
13036        break;
13037    case M16_OPC_LWPC:
13038        gen_ld(ctx, OPC_LWPC, rx, 0, offset);
13039        break;
13040#if defined(TARGET_MIPS64)
13041    case M16_OPC_LWU:
13042        check_insn(ctx, ISA_MIPS3);
13043        check_mips_64(ctx);
13044        gen_ld(ctx, OPC_LWU, ry, rx, offset);
13045        break;
13046#endif
13047    case M16_OPC_SB:
13048        gen_st(ctx, OPC_SB, ry, rx, offset);
13049        break;
13050    case M16_OPC_SH:
13051        gen_st(ctx, OPC_SH, ry, rx, offset);
13052        break;
13053    case M16_OPC_SWSP:
13054        gen_st(ctx, OPC_SW, rx, 29, offset);
13055        break;
13056    case M16_OPC_SW:
13057        gen_st(ctx, OPC_SW, ry, rx, offset);
13058        break;
13059#if defined(TARGET_MIPS64)
13060    case M16_OPC_I64:
13061        decode_i64_mips16(ctx, ry, funct, offset, 1);
13062        break;
13063#endif
13064    default:
13065        gen_reserved_instruction(ctx);
13066        break;
13067    }
13068
13069    return 4;
13070}
13071
13072static inline bool is_uhi(int sdbbp_code)
13073{
13074#ifdef CONFIG_USER_ONLY
13075    return false;
13076#else
13077    return semihosting_enabled() && sdbbp_code == 1;
13078#endif
13079}
13080
13081#ifdef CONFIG_USER_ONLY
13082/* The above should dead-code away any calls to this..*/
13083static inline void gen_helper_do_semihosting(void *env)
13084{
13085    g_assert_not_reached();
13086}
13087#endif
13088
13089static int decode_mips16_opc(CPUMIPSState *env, DisasContext *ctx)
13090{
13091    int rx, ry;
13092    int sa;
13093    int op, cnvt_op, op1, offset;
13094    int funct;
13095    int n_bytes;
13096
13097    op = (ctx->opcode >> 11) & 0x1f;
13098    sa = (ctx->opcode >> 2) & 0x7;
13099    sa = sa == 0 ? 8 : sa;
13100    rx = xlat((ctx->opcode >> 8) & 0x7);
13101    cnvt_op = (ctx->opcode >> 5) & 0x7;
13102    ry = xlat((ctx->opcode >> 5) & 0x7);
13103    op1 = offset = ctx->opcode & 0x1f;
13104
13105    n_bytes = 2;
13106
13107    switch (op) {
13108    case M16_OPC_ADDIUSP:
13109        {
13110            int16_t imm = ((uint8_t) ctx->opcode) << 2;
13111
13112            gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
13113        }
13114        break;
13115    case M16_OPC_ADDIUPC:
13116        gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
13117        break;
13118    case M16_OPC_B:
13119        offset = (ctx->opcode & 0x7ff) << 1;
13120        offset = (int16_t)(offset << 4) >> 4;
13121        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset, 0);
13122        /* No delay slot, so just process as a normal instruction */
13123        break;
13124    case M16_OPC_JAL:
13125        offset = translator_lduw(env, ctx->base.pc_next + 2);
13126        offset = (((ctx->opcode & 0x1f) << 21)
13127                  | ((ctx->opcode >> 5) & 0x1f) << 16
13128                  | offset) << 2;
13129        op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALX : OPC_JAL;
13130        gen_compute_branch(ctx, op, 4, rx, ry, offset, 2);
13131        n_bytes = 4;
13132        break;
13133    case M16_OPC_BEQZ:
13134        gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0,
13135                           ((int8_t)ctx->opcode) << 1, 0);
13136        /* No delay slot, so just process as a normal instruction */
13137        break;
13138    case M16_OPC_BNEQZ:
13139        gen_compute_branch(ctx, OPC_BNE, 2, rx, 0,
13140                           ((int8_t)ctx->opcode) << 1, 0);
13141        /* No delay slot, so just process as a normal instruction */
13142        break;
13143    case M16_OPC_SHIFT:
13144        switch (ctx->opcode & 0x3) {
13145        case 0x0:
13146            gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
13147            break;
13148        case 0x1:
13149#if defined(TARGET_MIPS64)
13150            check_insn(ctx, ISA_MIPS3);
13151            check_mips_64(ctx);
13152            gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
13153#else
13154            gen_reserved_instruction(ctx);
13155#endif
13156            break;
13157        case 0x2:
13158            gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
13159            break;
13160        case 0x3:
13161            gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
13162            break;
13163        }
13164        break;
13165#if defined(TARGET_MIPS64)
13166    case M16_OPC_LD:
13167        check_insn(ctx, ISA_MIPS3);
13168        check_mips_64(ctx);
13169        gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
13170        break;
13171#endif
13172    case M16_OPC_RRIA:
13173        {
13174            int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
13175
13176            if ((ctx->opcode >> 4) & 1) {
13177#if defined(TARGET_MIPS64)
13178                check_insn(ctx, ISA_MIPS3);
13179                check_mips_64(ctx);
13180                gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
13181#else
13182                gen_reserved_instruction(ctx);
13183#endif
13184            } else {
13185                gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
13186            }
13187        }
13188        break;
13189    case M16_OPC_ADDIU8:
13190        {
13191            int16_t imm = (int8_t) ctx->opcode;
13192
13193            gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
13194        }
13195        break;
13196    case M16_OPC_SLTI:
13197        {
13198            int16_t imm = (uint8_t) ctx->opcode;
13199            gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
13200        }
13201        break;
13202    case M16_OPC_SLTIU:
13203        {
13204            int16_t imm = (uint8_t) ctx->opcode;
13205            gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
13206        }
13207        break;
13208    case M16_OPC_I8:
13209        {
13210            int reg32;
13211
13212            funct = (ctx->opcode >> 8) & 0x7;
13213            switch (funct) {
13214            case I8_BTEQZ:
13215                gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
13216                                   ((int8_t)ctx->opcode) << 1, 0);
13217                break;
13218            case I8_BTNEZ:
13219                gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
13220                                   ((int8_t)ctx->opcode) << 1, 0);
13221                break;
13222            case I8_SWRASP:
13223                gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
13224                break;
13225            case I8_ADJSP:
13226                gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
13227                              ((int8_t)ctx->opcode) << 3);
13228                break;
13229            case I8_SVRS:
13230                check_insn(ctx, ISA_MIPS_R1);
13231                {
13232                    int do_ra = ctx->opcode & (1 << 6);
13233                    int do_s0 = ctx->opcode & (1 << 5);
13234                    int do_s1 = ctx->opcode & (1 << 4);
13235                    int framesize = ctx->opcode & 0xf;
13236
13237                    if (framesize == 0) {
13238                        framesize = 128;
13239                    } else {
13240                        framesize = framesize << 3;
13241                    }
13242
13243                    if (ctx->opcode & (1 << 7)) {
13244                        gen_mips16_save(ctx, 0, 0,
13245                                        do_ra, do_s0, do_s1, framesize);
13246                    } else {
13247                        gen_mips16_restore(ctx, 0, 0,
13248                                           do_ra, do_s0, do_s1, framesize);
13249                    }
13250                }
13251                break;
13252            case I8_MOV32R:
13253                {
13254                    int rz = xlat(ctx->opcode & 0x7);
13255
13256                    reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
13257                        ((ctx->opcode >> 5) & 0x7);
13258                    gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
13259                }
13260                break;
13261            case I8_MOVR32:
13262                reg32 = ctx->opcode & 0x1f;
13263                gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
13264                break;
13265            default:
13266                gen_reserved_instruction(ctx);
13267                break;
13268            }
13269        }
13270        break;
13271    case M16_OPC_LI:
13272        {
13273            int16_t imm = (uint8_t) ctx->opcode;
13274
13275            gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
13276        }
13277        break;
13278    case M16_OPC_CMPI:
13279        {
13280            int16_t imm = (uint8_t) ctx->opcode;
13281            gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
13282        }
13283        break;
13284#if defined(TARGET_MIPS64)
13285    case M16_OPC_SD:
13286        check_insn(ctx, ISA_MIPS3);
13287        check_mips_64(ctx);
13288        gen_st(ctx, OPC_SD, ry, rx, offset << 3);
13289        break;
13290#endif
13291    case M16_OPC_LB:
13292        gen_ld(ctx, OPC_LB, ry, rx, offset);
13293        break;
13294    case M16_OPC_LH:
13295        gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
13296        break;
13297    case M16_OPC_LWSP:
13298        gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13299        break;
13300    case M16_OPC_LW:
13301        gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
13302        break;
13303    case M16_OPC_LBU:
13304        gen_ld(ctx, OPC_LBU, ry, rx, offset);
13305        break;
13306    case M16_OPC_LHU:
13307        gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
13308        break;
13309    case M16_OPC_LWPC:
13310        gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
13311        break;
13312#if defined(TARGET_MIPS64)
13313    case M16_OPC_LWU:
13314        check_insn(ctx, ISA_MIPS3);
13315        check_mips_64(ctx);
13316        gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
13317        break;
13318#endif
13319    case M16_OPC_SB:
13320        gen_st(ctx, OPC_SB, ry, rx, offset);
13321        break;
13322    case M16_OPC_SH:
13323        gen_st(ctx, OPC_SH, ry, rx, offset << 1);
13324        break;
13325    case M16_OPC_SWSP:
13326        gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
13327        break;
13328    case M16_OPC_SW:
13329        gen_st(ctx, OPC_SW, ry, rx, offset << 2);
13330        break;
13331    case M16_OPC_RRR:
13332        {
13333            int rz = xlat((ctx->opcode >> 2) & 0x7);
13334            int mips32_op;
13335
13336            switch (ctx->opcode & 0x3) {
13337            case RRR_ADDU:
13338                mips32_op = OPC_ADDU;
13339                break;
13340            case RRR_SUBU:
13341                mips32_op = OPC_SUBU;
13342                break;
13343#if defined(TARGET_MIPS64)
13344            case RRR_DADDU:
13345                mips32_op = OPC_DADDU;
13346                check_insn(ctx, ISA_MIPS3);
13347                check_mips_64(ctx);
13348                break;
13349            case RRR_DSUBU:
13350                mips32_op = OPC_DSUBU;
13351                check_insn(ctx, ISA_MIPS3);
13352                check_mips_64(ctx);
13353                break;
13354#endif
13355            default:
13356                gen_reserved_instruction(ctx);
13357                goto done;
13358            }
13359
13360            gen_arith(ctx, mips32_op, rz, rx, ry);
13361        done:
13362            ;
13363        }
13364        break;
13365    case M16_OPC_RR:
13366        switch (op1) {
13367        case RR_JR:
13368            {
13369                int nd = (ctx->opcode >> 7) & 0x1;
13370                int link = (ctx->opcode >> 6) & 0x1;
13371                int ra = (ctx->opcode >> 5) & 0x1;
13372
13373                if (nd) {
13374                    check_insn(ctx, ISA_MIPS_R1);
13375                }
13376
13377                if (link) {
13378                    op = OPC_JALR;
13379                } else {
13380                    op = OPC_JR;
13381                }
13382
13383                gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0,
13384                                   (nd ? 0 : 2));
13385            }
13386            break;
13387        case RR_SDBBP:
13388            if (is_uhi(extract32(ctx->opcode, 5, 6))) {
13389                gen_helper_do_semihosting(cpu_env);
13390            } else {
13391                /*
13392                 * XXX: not clear which exception should be raised
13393                 *      when in debug mode...
13394                 */
13395                check_insn(ctx, ISA_MIPS_R1);
13396                generate_exception_end(ctx, EXCP_DBp);
13397            }
13398            break;
13399        case RR_SLT:
13400            gen_slt(ctx, OPC_SLT, 24, rx, ry);
13401            break;
13402        case RR_SLTU:
13403            gen_slt(ctx, OPC_SLTU, 24, rx, ry);
13404            break;
13405        case RR_BREAK:
13406            generate_exception_end(ctx, EXCP_BREAK);
13407            break;
13408        case RR_SLLV:
13409            gen_shift(ctx, OPC_SLLV, ry, rx, ry);
13410            break;
13411        case RR_SRLV:
13412            gen_shift(ctx, OPC_SRLV, ry, rx, ry);
13413            break;
13414        case RR_SRAV:
13415            gen_shift(ctx, OPC_SRAV, ry, rx, ry);
13416            break;
13417#if defined(TARGET_MIPS64)
13418        case RR_DSRL:
13419            check_insn(ctx, ISA_MIPS3);
13420            check_mips_64(ctx);
13421            gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
13422            break;
13423#endif
13424        case RR_CMP:
13425            gen_logic(ctx, OPC_XOR, 24, rx, ry);
13426            break;
13427        case RR_NEG:
13428            gen_arith(ctx, OPC_SUBU, rx, 0, ry);
13429            break;
13430        case RR_AND:
13431            gen_logic(ctx, OPC_AND, rx, rx, ry);
13432            break;
13433        case RR_OR:
13434            gen_logic(ctx, OPC_OR, rx, rx, ry);
13435            break;
13436        case RR_XOR:
13437            gen_logic(ctx, OPC_XOR, rx, rx, ry);
13438            break;
13439        case RR_NOT:
13440            gen_logic(ctx, OPC_NOR, rx, ry, 0);
13441            break;
13442        case RR_MFHI:
13443            gen_HILO(ctx, OPC_MFHI, 0, rx);
13444            break;
13445        case RR_CNVT:
13446            check_insn(ctx, ISA_MIPS_R1);
13447            switch (cnvt_op) {
13448            case RR_RY_CNVT_ZEB:
13449                tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13450                break;
13451            case RR_RY_CNVT_ZEH:
13452                tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13453                break;
13454            case RR_RY_CNVT_SEB:
13455                tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13456                break;
13457            case RR_RY_CNVT_SEH:
13458                tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13459                break;
13460#if defined(TARGET_MIPS64)
13461            case RR_RY_CNVT_ZEW:
13462                check_insn(ctx, ISA_MIPS_R1);
13463                check_mips_64(ctx);
13464                tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
13465                break;
13466            case RR_RY_CNVT_SEW:
13467                check_insn(ctx, ISA_MIPS_R1);
13468                check_mips_64(ctx);
13469                tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
13470                break;
13471#endif
13472            default:
13473                gen_reserved_instruction(ctx);
13474                break;
13475            }
13476            break;
13477        case RR_MFLO:
13478            gen_HILO(ctx, OPC_MFLO, 0, rx);
13479            break;
13480#if defined(TARGET_MIPS64)
13481        case RR_DSRA:
13482            check_insn(ctx, ISA_MIPS3);
13483            check_mips_64(ctx);
13484            gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
13485            break;
13486        case RR_DSLLV:
13487            check_insn(ctx, ISA_MIPS3);
13488            check_mips_64(ctx);
13489            gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
13490            break;
13491        case RR_DSRLV:
13492            check_insn(ctx, ISA_MIPS3);
13493            check_mips_64(ctx);
13494            gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
13495            break;
13496        case RR_DSRAV:
13497            check_insn(ctx, ISA_MIPS3);
13498            check_mips_64(ctx);
13499            gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
13500            break;
13501#endif
13502        case RR_MULT:
13503            gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
13504            break;
13505        case RR_MULTU:
13506            gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
13507            break;
13508        case RR_DIV:
13509            gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
13510            break;
13511        case RR_DIVU:
13512            gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
13513            break;
13514#if defined(TARGET_MIPS64)
13515        case RR_DMULT:
13516            check_insn(ctx, ISA_MIPS3);
13517            check_mips_64(ctx);
13518            gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
13519            break;
13520        case RR_DMULTU:
13521            check_insn(ctx, ISA_MIPS3);
13522            check_mips_64(ctx);
13523            gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
13524            break;
13525        case RR_DDIV:
13526            check_insn(ctx, ISA_MIPS3);
13527            check_mips_64(ctx);
13528            gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
13529            break;
13530        case RR_DDIVU:
13531            check_insn(ctx, ISA_MIPS3);
13532            check_mips_64(ctx);
13533            gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
13534            break;
13535#endif
13536        default:
13537            gen_reserved_instruction(ctx);
13538            break;
13539        }
13540        break;
13541    case M16_OPC_EXTEND:
13542        decode_extended_mips16_opc(env, ctx);
13543        n_bytes = 4;
13544        break;
13545#if defined(TARGET_MIPS64)
13546    case M16_OPC_I64:
13547        funct = (ctx->opcode >> 8) & 0x7;
13548        decode_i64_mips16(ctx, ry, funct, offset, 0);
13549        break;
13550#endif
13551    default:
13552        gen_reserved_instruction(ctx);
13553        break;
13554    }
13555
13556    return n_bytes;
13557}
13558
13559/* microMIPS extension to MIPS32/MIPS64 */
13560
13561/*
13562 * microMIPS32/microMIPS64 major opcodes
13563 *
13564 * 1. MIPS Architecture for Programmers Volume II-B:
13565 *      The microMIPS32 Instruction Set (Revision 3.05)
13566 *
13567 *    Table 6.2 microMIPS32 Encoding of Major Opcode Field
13568 *
13569 * 2. MIPS Architecture For Programmers Volume II-A:
13570 *      The MIPS64 Instruction Set (Revision 3.51)
13571 */
13572
13573enum {
13574    POOL32A = 0x00,
13575    POOL16A = 0x01,
13576    LBU16 = 0x02,
13577    MOVE16 = 0x03,
13578    ADDI32 = 0x04,
13579    R6_LUI = 0x04,
13580    AUI = 0x04,
13581    LBU32 = 0x05,
13582    SB32 = 0x06,
13583    LB32 = 0x07,
13584
13585    POOL32B = 0x08,
13586    POOL16B = 0x09,
13587    LHU16 = 0x0a,
13588    ANDI16 = 0x0b,
13589    ADDIU32 = 0x0c,
13590    LHU32 = 0x0d,
13591    SH32 = 0x0e,
13592    LH32 = 0x0f,
13593
13594    POOL32I = 0x10,
13595    POOL16C = 0x11,
13596    LWSP16 = 0x12,
13597    POOL16D = 0x13,
13598    ORI32 = 0x14,
13599    POOL32F = 0x15,
13600    POOL32S = 0x16,  /* MIPS64 */
13601    DADDIU32 = 0x17, /* MIPS64 */
13602
13603    POOL32C = 0x18,
13604    LWGP16 = 0x19,
13605    LW16 = 0x1a,
13606    POOL16E = 0x1b,
13607    XORI32 = 0x1c,
13608    JALS32 = 0x1d,
13609    BOVC = 0x1d,
13610    BEQC = 0x1d,
13611    BEQZALC = 0x1d,
13612    ADDIUPC = 0x1e,
13613    PCREL = 0x1e,
13614    BNVC = 0x1f,
13615    BNEC = 0x1f,
13616    BNEZALC = 0x1f,
13617
13618    R6_BEQZC = 0x20,
13619    JIC = 0x20,
13620    POOL16F = 0x21,
13621    SB16 = 0x22,
13622    BEQZ16 = 0x23,
13623    BEQZC16 = 0x23,
13624    SLTI32 = 0x24,
13625    BEQ32 = 0x25,
13626    BC = 0x25,
13627    SWC132 = 0x26,
13628    LWC132 = 0x27,
13629
13630    /* 0x29 is reserved */
13631    RES_29 = 0x29,
13632    R6_BNEZC = 0x28,
13633    JIALC = 0x28,
13634    SH16 = 0x2a,
13635    BNEZ16 = 0x2b,
13636    BNEZC16 = 0x2b,
13637    SLTIU32 = 0x2c,
13638    BNE32 = 0x2d,
13639    BALC = 0x2d,
13640    SDC132 = 0x2e,
13641    LDC132 = 0x2f,
13642
13643    /* 0x31 is reserved */
13644    RES_31 = 0x31,
13645    BLEZALC = 0x30,
13646    BGEZALC = 0x30,
13647    BGEUC = 0x30,
13648    SWSP16 = 0x32,
13649    B16 = 0x33,
13650    BC16 = 0x33,
13651    ANDI32 = 0x34,
13652    J32 = 0x35,
13653    BGTZC = 0x35,
13654    BLTZC = 0x35,
13655    BLTC = 0x35,
13656    SD32 = 0x36, /* MIPS64 */
13657    LD32 = 0x37, /* MIPS64 */
13658
13659    /* 0x39 is reserved */
13660    RES_39 = 0x39,
13661    BGTZALC = 0x38,
13662    BLTZALC = 0x38,
13663    BLTUC = 0x38,
13664    SW16 = 0x3a,
13665    LI16 = 0x3b,
13666    JALX32 = 0x3c,
13667    JAL32 = 0x3d,
13668    BLEZC = 0x3d,
13669    BGEZC = 0x3d,
13670    BGEC = 0x3d,
13671    SW32 = 0x3e,
13672    LW32 = 0x3f
13673};
13674
13675/* PCREL Instructions perform PC-Relative address calculation. bits 20..16 */
13676enum {
13677    ADDIUPC_00 = 0x00,
13678    ADDIUPC_01 = 0x01,
13679    ADDIUPC_02 = 0x02,
13680    ADDIUPC_03 = 0x03,
13681    ADDIUPC_04 = 0x04,
13682    ADDIUPC_05 = 0x05,
13683    ADDIUPC_06 = 0x06,
13684    ADDIUPC_07 = 0x07,
13685    AUIPC = 0x1e,
13686    ALUIPC = 0x1f,
13687    LWPC_08 = 0x08,
13688    LWPC_09 = 0x09,
13689    LWPC_0A = 0x0A,
13690    LWPC_0B = 0x0B,
13691    LWPC_0C = 0x0C,
13692    LWPC_0D = 0x0D,
13693    LWPC_0E = 0x0E,
13694    LWPC_0F = 0x0F,
13695};
13696
13697/* POOL32A encoding of minor opcode field */
13698
13699enum {
13700    /*
13701     * These opcodes are distinguished only by bits 9..6; those bits are
13702     * what are recorded below.
13703     */
13704    SLL32 = 0x0,
13705    SRL32 = 0x1,
13706    SRA = 0x2,
13707    ROTR = 0x3,
13708    SELEQZ = 0x5,
13709    SELNEZ = 0x6,
13710    R6_RDHWR = 0x7,
13711
13712    SLLV = 0x0,
13713    SRLV = 0x1,
13714    SRAV = 0x2,
13715    ROTRV = 0x3,
13716    ADD = 0x4,
13717    ADDU32 = 0x5,
13718    SUB = 0x6,
13719    SUBU32 = 0x7,
13720    MUL = 0x8,
13721    AND = 0x9,
13722    OR32 = 0xa,
13723    NOR = 0xb,
13724    XOR32 = 0xc,
13725    SLT = 0xd,
13726    SLTU = 0xe,
13727
13728    MOVN = 0x0,
13729    R6_MUL  = 0x0,
13730    MOVZ = 0x1,
13731    MUH  = 0x1,
13732    MULU = 0x2,
13733    MUHU = 0x3,
13734    LWXS = 0x4,
13735    R6_DIV  = 0x4,
13736    MOD  = 0x5,
13737    R6_DIVU = 0x6,
13738    MODU = 0x7,
13739
13740    /* The following can be distinguished by their lower 6 bits. */
13741    BREAK32 = 0x07,
13742    INS = 0x0c,
13743    LSA = 0x0f,
13744    ALIGN = 0x1f,
13745    EXT = 0x2c,
13746    POOL32AXF = 0x3c,
13747    SIGRIE = 0x3f
13748};
13749
13750/* POOL32AXF encoding of minor opcode field extension */
13751
13752/*
13753 * 1. MIPS Architecture for Programmers Volume II-B:
13754 *      The microMIPS32 Instruction Set (Revision 3.05)
13755 *
13756 *    Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
13757 *
13758 * 2. MIPS Architecture for Programmers VolumeIV-e:
13759 *      The MIPS DSP Application-Specific Extension
13760 *        to the microMIPS32 Architecture (Revision 2.34)
13761 *
13762 *    Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
13763 */
13764
13765enum {
13766    /* bits 11..6 */
13767    TEQ = 0x00,
13768    TGE = 0x08,
13769    TGEU = 0x10,
13770    TLT = 0x20,
13771    TLTU = 0x28,
13772    TNE = 0x30,
13773
13774    MFC0 = 0x03,
13775    MTC0 = 0x0b,
13776
13777    /* begin of microMIPS32 DSP */
13778
13779    /* bits 13..12 for 0x01 */
13780    MFHI_ACC = 0x0,
13781    MFLO_ACC = 0x1,
13782    MTHI_ACC = 0x2,
13783    MTLO_ACC = 0x3,
13784
13785    /* bits 13..12 for 0x2a */
13786    MADD_ACC = 0x0,
13787    MADDU_ACC = 0x1,
13788    MSUB_ACC = 0x2,
13789    MSUBU_ACC = 0x3,
13790
13791    /* bits 13..12 for 0x32 */
13792    MULT_ACC = 0x0,
13793    MULTU_ACC = 0x1,
13794
13795    /* end of microMIPS32 DSP */
13796
13797    /* bits 15..12 for 0x2c */
13798    BITSWAP = 0x0,
13799    SEB = 0x2,
13800    SEH = 0x3,
13801    CLO = 0x4,
13802    CLZ = 0x5,
13803    RDHWR = 0x6,
13804    WSBH = 0x7,
13805    MULT = 0x8,
13806    MULTU = 0x9,
13807    DIV = 0xa,
13808    DIVU = 0xb,
13809    MADD = 0xc,
13810    MADDU = 0xd,
13811    MSUB = 0xe,
13812    MSUBU = 0xf,
13813
13814    /* bits 15..12 for 0x34 */
13815    MFC2 = 0x4,
13816    MTC2 = 0x5,
13817    MFHC2 = 0x8,
13818    MTHC2 = 0x9,
13819    CFC2 = 0xc,
13820    CTC2 = 0xd,
13821
13822    /* bits 15..12 for 0x3c */
13823    JALR = 0x0,
13824    JR = 0x0,                   /* alias */
13825    JALRC = 0x0,
13826    JRC = 0x0,
13827    JALR_HB = 0x1,
13828    JALRC_HB = 0x1,
13829    JALRS = 0x4,
13830    JALRS_HB = 0x5,
13831
13832    /* bits 15..12 for 0x05 */
13833    RDPGPR = 0xe,
13834    WRPGPR = 0xf,
13835
13836    /* bits 15..12 for 0x0d */
13837    TLBP = 0x0,
13838    TLBR = 0x1,
13839    TLBWI = 0x2,
13840    TLBWR = 0x3,
13841    TLBINV = 0x4,
13842    TLBINVF = 0x5,
13843    WAIT = 0x9,
13844    IRET = 0xd,
13845    DERET = 0xe,
13846    ERET = 0xf,
13847
13848    /* bits 15..12 for 0x15 */
13849    DMT = 0x0,
13850    DVPE = 0x1,
13851    EMT = 0x2,
13852    EVPE = 0x3,
13853
13854    /* bits 15..12 for 0x1d */
13855    DI = 0x4,
13856    EI = 0x5,
13857
13858    /* bits 15..12 for 0x2d */
13859    SYNC = 0x6,
13860    SYSCALL = 0x8,
13861    SDBBP = 0xd,
13862
13863    /* bits 15..12 for 0x35 */
13864    MFHI32 = 0x0,
13865    MFLO32 = 0x1,
13866    MTHI32 = 0x2,
13867    MTLO32 = 0x3,
13868};
13869
13870/* POOL32B encoding of minor opcode field (bits 15..12) */
13871
13872enum {
13873    LWC2 = 0x0,
13874    LWP = 0x1,
13875    LDP = 0x4,
13876    LWM32 = 0x5,
13877    CACHE = 0x6,
13878    LDM = 0x7,
13879    SWC2 = 0x8,
13880    SWP = 0x9,
13881    SDP = 0xc,
13882    SWM32 = 0xd,
13883    SDM = 0xf
13884};
13885
13886/* POOL32C encoding of minor opcode field (bits 15..12) */
13887
13888enum {
13889    LWL = 0x0,
13890    SWL = 0x8,
13891    LWR = 0x1,
13892    SWR = 0x9,
13893    PREF = 0x2,
13894    ST_EVA = 0xa,
13895    LL = 0x3,
13896    SC = 0xb,
13897    LDL = 0x4,
13898    SDL = 0xc,
13899    LDR = 0x5,
13900    SDR = 0xd,
13901    LD_EVA = 0x6,
13902    LWU = 0xe,
13903    LLD = 0x7,
13904    SCD = 0xf
13905};
13906
13907/* POOL32C LD-EVA encoding of minor opcode field (bits 11..9) */
13908
13909enum {
13910    LBUE = 0x0,
13911    LHUE = 0x1,
13912    LWLE = 0x2,
13913    LWRE = 0x3,
13914    LBE = 0x4,
13915    LHE = 0x5,
13916    LLE = 0x6,
13917    LWE = 0x7,
13918};
13919
13920/* POOL32C ST-EVA encoding of minor opcode field (bits 11..9) */
13921
13922enum {
13923    SWLE = 0x0,
13924    SWRE = 0x1,
13925    PREFE = 0x2,
13926    CACHEE = 0x3,
13927    SBE = 0x4,
13928    SHE = 0x5,
13929    SCE = 0x6,
13930    SWE = 0x7,
13931};
13932
13933/* POOL32F encoding of minor opcode field (bits 5..0) */
13934
13935enum {
13936    /* These are the bit 7..6 values */
13937    ADD_FMT = 0x0,
13938
13939    SUB_FMT = 0x1,
13940
13941    MUL_FMT = 0x2,
13942
13943    DIV_FMT = 0x3,
13944
13945    /* These are the bit 8..6 values */
13946    MOVN_FMT = 0x0,
13947    RSQRT2_FMT = 0x0,
13948    MOVF_FMT = 0x0,
13949    RINT_FMT = 0x0,
13950    SELNEZ_FMT = 0x0,
13951
13952    MOVZ_FMT = 0x1,
13953    LWXC1 = 0x1,
13954    MOVT_FMT = 0x1,
13955    CLASS_FMT = 0x1,
13956    SELEQZ_FMT = 0x1,
13957
13958    PLL_PS = 0x2,
13959    SWXC1 = 0x2,
13960    SEL_FMT = 0x2,
13961
13962    PLU_PS = 0x3,
13963    LDXC1 = 0x3,
13964
13965    MOVN_FMT_04 = 0x4,
13966    PUL_PS = 0x4,
13967    SDXC1 = 0x4,
13968    RECIP2_FMT = 0x4,
13969
13970    MOVZ_FMT_05 = 0x05,
13971    PUU_PS = 0x5,
13972    LUXC1 = 0x5,
13973
13974    CVT_PS_S = 0x6,
13975    SUXC1 = 0x6,
13976    ADDR_PS = 0x6,
13977    PREFX = 0x6,
13978    MADDF_FMT = 0x6,
13979
13980    MULR_PS = 0x7,
13981    MSUBF_FMT = 0x7,
13982
13983    MADD_S = 0x01,
13984    MADD_D = 0x09,
13985    MADD_PS = 0x11,
13986    ALNV_PS = 0x19,
13987    MSUB_S = 0x21,
13988    MSUB_D = 0x29,
13989    MSUB_PS = 0x31,
13990
13991    NMADD_S = 0x02,
13992    NMADD_D = 0x0a,
13993    NMADD_PS = 0x12,
13994    NMSUB_S = 0x22,
13995    NMSUB_D = 0x2a,
13996    NMSUB_PS = 0x32,
13997
13998    MIN_FMT = 0x3,
13999    MAX_FMT = 0xb,
14000    MINA_FMT = 0x23,
14001    MAXA_FMT = 0x2b,
14002    POOL32FXF = 0x3b,
14003
14004    CABS_COND_FMT = 0x1c,              /* MIPS3D */
14005    C_COND_FMT = 0x3c,
14006
14007    CMP_CONDN_S = 0x5,
14008    CMP_CONDN_D = 0x15
14009};
14010
14011/* POOL32Fxf encoding of minor opcode extension field */
14012
14013enum {
14014    CVT_L = 0x04,
14015    RSQRT_FMT = 0x08,
14016    FLOOR_L = 0x0c,
14017    CVT_PW_PS = 0x1c,
14018    CVT_W = 0x24,
14019    SQRT_FMT = 0x28,
14020    FLOOR_W = 0x2c,
14021    CVT_PS_PW = 0x3c,
14022    CFC1 = 0x40,
14023    RECIP_FMT = 0x48,
14024    CEIL_L = 0x4c,
14025    CTC1 = 0x60,
14026    CEIL_W = 0x6c,
14027    MFC1 = 0x80,
14028    CVT_S_PL = 0x84,
14029    TRUNC_L = 0x8c,
14030    MTC1 = 0xa0,
14031    CVT_S_PU = 0xa4,
14032    TRUNC_W = 0xac,
14033    MFHC1 = 0xc0,
14034    ROUND_L = 0xcc,
14035    MTHC1 = 0xe0,
14036    ROUND_W = 0xec,
14037
14038    MOV_FMT = 0x01,
14039    MOVF = 0x05,
14040    ABS_FMT = 0x0d,
14041    RSQRT1_FMT = 0x1d,
14042    MOVT = 0x25,
14043    NEG_FMT = 0x2d,
14044    CVT_D = 0x4d,
14045    RECIP1_FMT = 0x5d,
14046    CVT_S = 0x6d
14047};
14048
14049/* POOL32I encoding of minor opcode field (bits 25..21) */
14050
14051enum {
14052    BLTZ = 0x00,
14053    BLTZAL = 0x01,
14054    BGEZ = 0x02,
14055    BGEZAL = 0x03,
14056    BLEZ = 0x04,
14057    BNEZC = 0x05,
14058    BGTZ = 0x06,
14059    BEQZC = 0x07,
14060    TLTI = 0x08,
14061    BC1EQZC = 0x08,
14062    TGEI = 0x09,
14063    BC1NEZC = 0x09,
14064    TLTIU = 0x0a,
14065    BC2EQZC = 0x0a,
14066    TGEIU = 0x0b,
14067    BC2NEZC = 0x0a,
14068    TNEI = 0x0c,
14069    R6_SYNCI = 0x0c,
14070    LUI = 0x0d,
14071    TEQI = 0x0e,
14072    SYNCI = 0x10,
14073    BLTZALS = 0x11,
14074    BGEZALS = 0x13,
14075    BC2F = 0x14,
14076    BC2T = 0x15,
14077    BPOSGE64 = 0x1a,
14078    BPOSGE32 = 0x1b,
14079    /* These overlap and are distinguished by bit16 of the instruction */
14080    BC1F = 0x1c,
14081    BC1T = 0x1d,
14082    BC1ANY2F = 0x1c,
14083    BC1ANY2T = 0x1d,
14084    BC1ANY4F = 0x1e,
14085    BC1ANY4T = 0x1f
14086};
14087
14088/* POOL16A encoding of minor opcode field */
14089
14090enum {
14091    ADDU16 = 0x0,
14092    SUBU16 = 0x1
14093};
14094
14095/* POOL16B encoding of minor opcode field */
14096
14097enum {
14098    SLL16 = 0x0,
14099    SRL16 = 0x1
14100};
14101
14102/* POOL16C encoding of minor opcode field */
14103
14104enum {
14105    NOT16 = 0x00,
14106    XOR16 = 0x04,
14107    AND16 = 0x08,
14108    OR16 = 0x0c,
14109    LWM16 = 0x10,
14110    SWM16 = 0x14,
14111    JR16 = 0x18,
14112    JRC16 = 0x1a,
14113    JALR16 = 0x1c,
14114    JALR16S = 0x1e,
14115    MFHI16 = 0x20,
14116    MFLO16 = 0x24,
14117    BREAK16 = 0x28,
14118    SDBBP16 = 0x2c,
14119    JRADDIUSP = 0x30
14120};
14121
14122/* R6 POOL16C encoding of minor opcode field (bits 0..5) */
14123
14124enum {
14125    R6_NOT16    = 0x00,
14126    R6_AND16    = 0x01,
14127    R6_LWM16    = 0x02,
14128    R6_JRC16    = 0x03,
14129    MOVEP       = 0x04,
14130    MOVEP_05    = 0x05,
14131    MOVEP_06    = 0x06,
14132    MOVEP_07    = 0x07,
14133    R6_XOR16    = 0x08,
14134    R6_OR16     = 0x09,
14135    R6_SWM16    = 0x0a,
14136    JALRC16     = 0x0b,
14137    MOVEP_0C    = 0x0c,
14138    MOVEP_0D    = 0x0d,
14139    MOVEP_0E    = 0x0e,
14140    MOVEP_0F    = 0x0f,
14141    JRCADDIUSP  = 0x13,
14142    R6_BREAK16  = 0x1b,
14143    R6_SDBBP16  = 0x3b
14144};
14145
14146/* POOL16D encoding of minor opcode field */
14147
14148enum {
14149    ADDIUS5 = 0x0,
14150    ADDIUSP = 0x1
14151};
14152
14153/* POOL16E encoding of minor opcode field */
14154
14155enum {
14156    ADDIUR2 = 0x0,
14157    ADDIUR1SP = 0x1
14158};
14159
14160static int mmreg(int r)
14161{
14162    static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
14163
14164    return map[r];
14165}
14166
14167/* Used for 16-bit store instructions.  */
14168static int mmreg2(int r)
14169{
14170    static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
14171
14172    return map[r];
14173}
14174
14175#define uMIPS_RD(op) ((op >> 7) & 0x7)
14176#define uMIPS_RS(op) ((op >> 4) & 0x7)
14177#define uMIPS_RS2(op) uMIPS_RS(op)
14178#define uMIPS_RS1(op) ((op >> 1) & 0x7)
14179#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
14180#define uMIPS_RS5(op) (op & 0x1f)
14181
14182/* Signed immediate */
14183#define SIMM(op, start, width)                                          \
14184    ((int32_t)(((op >> start) & ((~0U) >> (32 - width)))                \
14185               << (32 - width))                                         \
14186     >> (32 - width))
14187/* Zero-extended immediate */
14188#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32 - width)))
14189
14190static void gen_addiur1sp(DisasContext *ctx)
14191{
14192    int rd = mmreg(uMIPS_RD(ctx->opcode));
14193
14194    gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
14195}
14196
14197static void gen_addiur2(DisasContext *ctx)
14198{
14199    static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
14200    int rd = mmreg(uMIPS_RD(ctx->opcode));
14201    int rs = mmreg(uMIPS_RS(ctx->opcode));
14202
14203    gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
14204}
14205
14206static void gen_addiusp(DisasContext *ctx)
14207{
14208    int encoded = ZIMM(ctx->opcode, 1, 9);
14209    int decoded;
14210
14211    if (encoded <= 1) {
14212        decoded = 256 + encoded;
14213    } else if (encoded <= 255) {
14214        decoded = encoded;
14215    } else if (encoded <= 509) {
14216        decoded = encoded - 512;
14217    } else {
14218        decoded = encoded - 768;
14219    }
14220
14221    gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
14222}
14223
14224static void gen_addius5(DisasContext *ctx)
14225{
14226    int imm = SIMM(ctx->opcode, 1, 4);
14227    int rd = (ctx->opcode >> 5) & 0x1f;
14228
14229    gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
14230}
14231
14232static void gen_andi16(DisasContext *ctx)
14233{
14234    static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
14235                                 31, 32, 63, 64, 255, 32768, 65535 };
14236    int rd = mmreg(uMIPS_RD(ctx->opcode));
14237    int rs = mmreg(uMIPS_RS(ctx->opcode));
14238    int encoded = ZIMM(ctx->opcode, 0, 4);
14239
14240    gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
14241}
14242
14243static void gen_ldst_multiple(DisasContext *ctx, uint32_t opc, int reglist,
14244                              int base, int16_t offset)
14245{
14246    TCGv t0, t1;
14247    TCGv_i32 t2;
14248
14249    if (ctx->hflags & MIPS_HFLAG_BMASK) {
14250        gen_reserved_instruction(ctx);
14251        return;
14252    }
14253
14254    t0 = tcg_temp_new();
14255
14256    gen_base_offset_addr(ctx, t0, base, offset);
14257
14258    t1 = tcg_const_tl(reglist);
14259    t2 = tcg_const_i32(ctx->mem_idx);
14260
14261    save_cpu_state(ctx, 1);
14262    switch (opc) {
14263    case LWM32:
14264        gen_helper_lwm(cpu_env, t0, t1, t2);
14265        break;
14266    case SWM32:
14267        gen_helper_swm(cpu_env, t0, t1, t2);
14268        break;
14269#ifdef TARGET_MIPS64
14270    case LDM:
14271        gen_helper_ldm(cpu_env, t0, t1, t2);
14272        break;
14273    case SDM:
14274        gen_helper_sdm(cpu_env, t0, t1, t2);
14275        break;
14276#endif
14277    }
14278    tcg_temp_free(t0);
14279    tcg_temp_free(t1);
14280    tcg_temp_free_i32(t2);
14281}
14282
14283
14284static void gen_pool16c_insn(DisasContext *ctx)
14285{
14286    int rd = mmreg((ctx->opcode >> 3) & 0x7);
14287    int rs = mmreg(ctx->opcode & 0x7);
14288
14289    switch (((ctx->opcode) >> 4) & 0x3f) {
14290    case NOT16 + 0:
14291    case NOT16 + 1:
14292    case NOT16 + 2:
14293    case NOT16 + 3:
14294        gen_logic(ctx, OPC_NOR, rd, rs, 0);
14295        break;
14296    case XOR16 + 0:
14297    case XOR16 + 1:
14298    case XOR16 + 2:
14299    case XOR16 + 3:
14300        gen_logic(ctx, OPC_XOR, rd, rd, rs);
14301        break;
14302    case AND16 + 0:
14303    case AND16 + 1:
14304    case AND16 + 2:
14305    case AND16 + 3:
14306        gen_logic(ctx, OPC_AND, rd, rd, rs);
14307        break;
14308    case OR16 + 0:
14309    case OR16 + 1:
14310    case OR16 + 2:
14311    case OR16 + 3:
14312        gen_logic(ctx, OPC_OR, rd, rd, rs);
14313        break;
14314    case LWM16 + 0:
14315    case LWM16 + 1:
14316    case LWM16 + 2:
14317    case LWM16 + 3:
14318        {
14319            static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14320            int offset = ZIMM(ctx->opcode, 0, 4);
14321
14322            gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
14323                              29, offset << 2);
14324        }
14325        break;
14326    case SWM16 + 0:
14327    case SWM16 + 1:
14328    case SWM16 + 2:
14329    case SWM16 + 3:
14330        {
14331            static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
14332            int offset = ZIMM(ctx->opcode, 0, 4);
14333
14334            gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
14335                              29, offset << 2);
14336        }
14337        break;
14338    case JR16 + 0:
14339    case JR16 + 1:
14340        {
14341            int reg = ctx->opcode & 0x1f;
14342
14343            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 4);
14344        }
14345        break;
14346    case JRC16 + 0:
14347    case JRC16 + 1:
14348        {
14349            int reg = ctx->opcode & 0x1f;
14350            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0, 0);
14351            /*
14352             * Let normal delay slot handling in our caller take us
14353             * to the branch target.
14354             */
14355        }
14356        break;
14357    case JALR16 + 0:
14358    case JALR16 + 1:
14359        gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 4);
14360        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14361        break;
14362    case JALR16S + 0:
14363    case JALR16S + 1:
14364        gen_compute_branch(ctx, OPC_JALR, 2, ctx->opcode & 0x1f, 31, 0, 2);
14365        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14366        break;
14367    case MFHI16 + 0:
14368    case MFHI16 + 1:
14369        gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
14370        break;
14371    case MFLO16 + 0:
14372    case MFLO16 + 1:
14373        gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
14374        break;
14375    case BREAK16:
14376        generate_exception_end(ctx, EXCP_BREAK);
14377        break;
14378    case SDBBP16:
14379        if (is_uhi(extract32(ctx->opcode, 0, 4))) {
14380            gen_helper_do_semihosting(cpu_env);
14381        } else {
14382            /*
14383             * XXX: not clear which exception should be raised
14384             *      when in debug mode...
14385             */
14386            check_insn(ctx, ISA_MIPS_R1);
14387            generate_exception_end(ctx, EXCP_DBp);
14388        }
14389        break;
14390    case JRADDIUSP + 0:
14391    case JRADDIUSP + 1:
14392        {
14393            int imm = ZIMM(ctx->opcode, 0, 5);
14394            gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
14395            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
14396            /*
14397             * Let normal delay slot handling in our caller take us
14398             * to the branch target.
14399             */
14400        }
14401        break;
14402    default:
14403        gen_reserved_instruction(ctx);
14404        break;
14405    }
14406}
14407
14408static inline void gen_movep(DisasContext *ctx, int enc_dest, int enc_rt,
14409                             int enc_rs)
14410{
14411    int rd, re;
14412    static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
14413    static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
14414    static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
14415
14416    rd = rd_enc[enc_dest];
14417    re = re_enc[enc_dest];
14418    gen_load_gpr(cpu_gpr[rd], rs_rt_enc[enc_rs]);
14419    gen_load_gpr(cpu_gpr[re], rs_rt_enc[enc_rt]);
14420}
14421
14422static void gen_pool16c_r6_insn(DisasContext *ctx)
14423{
14424    int rt = mmreg((ctx->opcode >> 7) & 0x7);
14425    int rs = mmreg((ctx->opcode >> 4) & 0x7);
14426
14427    switch (ctx->opcode & 0xf) {
14428    case R6_NOT16:
14429        gen_logic(ctx, OPC_NOR, rt, rs, 0);
14430        break;
14431    case R6_AND16:
14432        gen_logic(ctx, OPC_AND, rt, rt, rs);
14433        break;
14434    case R6_LWM16:
14435        {
14436            int lwm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
14437            int offset = extract32(ctx->opcode, 4, 4);
14438            gen_ldst_multiple(ctx, LWM32, lwm_converted, 29, offset << 2);
14439        }
14440        break;
14441    case R6_JRC16: /* JRCADDIUSP */
14442        if ((ctx->opcode >> 4) & 1) {
14443            /* JRCADDIUSP */
14444            int imm = extract32(ctx->opcode, 5, 5);
14445            gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0, 0);
14446            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
14447        } else {
14448            /* JRC16 */
14449            rs = extract32(ctx->opcode, 5, 5);
14450            gen_compute_branch(ctx, OPC_JR, 2, rs, 0, 0, 0);
14451        }
14452        break;
14453    case MOVEP:
14454    case MOVEP_05:
14455    case MOVEP_06:
14456    case MOVEP_07:
14457    case MOVEP_0C:
14458    case MOVEP_0D:
14459    case MOVEP_0E:
14460    case MOVEP_0F:
14461        {
14462            int enc_dest = uMIPS_RD(ctx->opcode);
14463            int enc_rt = uMIPS_RS2(ctx->opcode);
14464            int enc_rs = (ctx->opcode & 3) | ((ctx->opcode >> 1) & 4);
14465            gen_movep(ctx, enc_dest, enc_rt, enc_rs);
14466        }
14467        break;
14468    case R6_XOR16:
14469        gen_logic(ctx, OPC_XOR, rt, rt, rs);
14470        break;
14471    case R6_OR16:
14472        gen_logic(ctx, OPC_OR, rt, rt, rs);
14473        break;
14474    case R6_SWM16:
14475        {
14476            int swm_converted = 0x11 + extract32(ctx->opcode, 8, 2);
14477            int offset = extract32(ctx->opcode, 4, 4);
14478            gen_ldst_multiple(ctx, SWM32, swm_converted, 29, offset << 2);
14479        }
14480        break;
14481    case JALRC16: /* BREAK16, SDBBP16 */
14482        switch (ctx->opcode & 0x3f) {
14483        case JALRC16:
14484        case JALRC16 + 0x20:
14485            /* JALRC16 */
14486            gen_compute_branch(ctx, OPC_JALR, 2, (ctx->opcode >> 5) & 0x1f,
14487                               31, 0, 0);
14488            break;
14489        case R6_BREAK16:
14490            /* BREAK16 */
14491            generate_exception(ctx, EXCP_BREAK);
14492            break;
14493        case R6_SDBBP16:
14494            /* SDBBP16 */
14495            if (is_uhi(extract32(ctx->opcode, 6, 4))) {
14496                gen_helper_do_semihosting(cpu_env);
14497            } else {
14498                if (ctx->hflags & MIPS_HFLAG_SBRI) {
14499                    generate_exception(ctx, EXCP_RI);
14500                } else {
14501                    generate_exception(ctx, EXCP_DBp);
14502                }
14503            }
14504            break;
14505        }
14506        break;
14507    default:
14508        generate_exception(ctx, EXCP_RI);
14509        break;
14510    }
14511}
14512
14513static void gen_ldxs(DisasContext *ctx, int base, int index, int rd)
14514{
14515    TCGv t0 = tcg_temp_new();
14516    TCGv t1 = tcg_temp_new();
14517
14518    gen_load_gpr(t0, base);
14519
14520    if (index != 0) {
14521        gen_load_gpr(t1, index);
14522        tcg_gen_shli_tl(t1, t1, 2);
14523        gen_op_addr_add(ctx, t0, t1, t0);
14524    }
14525
14526    tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
14527    gen_store_gpr(t1, rd);
14528
14529    tcg_temp_free(t0);
14530    tcg_temp_free(t1);
14531}
14532
14533static void gen_ldst_pair(DisasContext *ctx, uint32_t opc, int rd,
14534                          int base, int16_t offset)
14535{
14536    TCGv t0, t1;
14537
14538    if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
14539        gen_reserved_instruction(ctx);
14540        return;
14541    }
14542
14543    t0 = tcg_temp_new();
14544    t1 = tcg_temp_new();
14545
14546    gen_base_offset_addr(ctx, t0, base, offset);
14547
14548    switch (opc) {
14549    case LWP:
14550        if (rd == base) {
14551            gen_reserved_instruction(ctx);
14552            return;
14553        }
14554        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
14555        gen_store_gpr(t1, rd);
14556        tcg_gen_movi_tl(t1, 4);
14557        gen_op_addr_add(ctx, t0, t0, t1);
14558        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TESL);
14559        gen_store_gpr(t1, rd + 1);
14560        break;
14561    case SWP:
14562        gen_load_gpr(t1, rd);
14563        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
14564        tcg_gen_movi_tl(t1, 4);
14565        gen_op_addr_add(ctx, t0, t0, t1);
14566        gen_load_gpr(t1, rd + 1);
14567        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
14568        break;
14569#ifdef TARGET_MIPS64
14570    case LDP:
14571        if (rd == base) {
14572            gen_reserved_instruction(ctx);
14573            return;
14574        }
14575        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14576        gen_store_gpr(t1, rd);
14577        tcg_gen_movi_tl(t1, 8);
14578        gen_op_addr_add(ctx, t0, t0, t1);
14579        tcg_gen_qemu_ld_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14580        gen_store_gpr(t1, rd + 1);
14581        break;
14582    case SDP:
14583        gen_load_gpr(t1, rd);
14584        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14585        tcg_gen_movi_tl(t1, 8);
14586        gen_op_addr_add(ctx, t0, t0, t1);
14587        gen_load_gpr(t1, rd + 1);
14588        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEQ);
14589        break;
14590#endif
14591    }
14592    tcg_temp_free(t0);
14593    tcg_temp_free(t1);
14594}
14595
14596static void gen_sync(int stype)
14597{
14598    TCGBar tcg_mo = TCG_BAR_SC;
14599
14600    switch (stype) {
14601    case 0x4: /* SYNC_WMB */
14602        tcg_mo |= TCG_MO_ST_ST;
14603        break;
14604    case 0x10: /* SYNC_MB */
14605        tcg_mo |= TCG_MO_ALL;
14606        break;
14607    case 0x11: /* SYNC_ACQUIRE */
14608        tcg_mo |= TCG_MO_LD_LD | TCG_MO_LD_ST;
14609        break;
14610    case 0x12: /* SYNC_RELEASE */
14611        tcg_mo |= TCG_MO_ST_ST | TCG_MO_LD_ST;
14612        break;
14613    case 0x13: /* SYNC_RMB */
14614        tcg_mo |= TCG_MO_LD_LD;
14615        break;
14616    default:
14617        tcg_mo |= TCG_MO_ALL;
14618        break;
14619    }
14620
14621    tcg_gen_mb(tcg_mo);
14622}
14623
14624static void gen_pool32axf(CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
14625{
14626    int extension = (ctx->opcode >> 6) & 0x3f;
14627    int minor = (ctx->opcode >> 12) & 0xf;
14628    uint32_t mips32_op;
14629
14630    switch (extension) {
14631    case TEQ:
14632        mips32_op = OPC_TEQ;
14633        goto do_trap;
14634    case TGE:
14635        mips32_op = OPC_TGE;
14636        goto do_trap;
14637    case TGEU:
14638        mips32_op = OPC_TGEU;
14639        goto do_trap;
14640    case TLT:
14641        mips32_op = OPC_TLT;
14642        goto do_trap;
14643    case TLTU:
14644        mips32_op = OPC_TLTU;
14645        goto do_trap;
14646    case TNE:
14647        mips32_op = OPC_TNE;
14648    do_trap:
14649        gen_trap(ctx, mips32_op, rs, rt, -1);
14650        break;
14651#ifndef CONFIG_USER_ONLY
14652    case MFC0:
14653    case MFC0 + 32:
14654        check_cp0_enabled(ctx);
14655        if (rt == 0) {
14656            /* Treat as NOP. */
14657            break;
14658        }
14659        gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
14660        break;
14661    case MTC0:
14662    case MTC0 + 32:
14663        check_cp0_enabled(ctx);
14664        {
14665            TCGv t0 = tcg_temp_new();
14666
14667            gen_load_gpr(t0, rt);
14668            gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
14669            tcg_temp_free(t0);
14670        }
14671        break;
14672#endif
14673    case 0x2a:
14674        switch (minor & 3) {
14675        case MADD_ACC:
14676            gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
14677            break;
14678        case MADDU_ACC:
14679            gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
14680            break;
14681        case MSUB_ACC:
14682            gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
14683            break;
14684        case MSUBU_ACC:
14685            gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
14686            break;
14687        default:
14688            goto pool32axf_invalid;
14689        }
14690        break;
14691    case 0x32:
14692        switch (minor & 3) {
14693        case MULT_ACC:
14694            gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
14695            break;
14696        case MULTU_ACC:
14697            gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
14698            break;
14699        default:
14700            goto pool32axf_invalid;
14701        }
14702        break;
14703    case 0x2c:
14704        switch (minor) {
14705        case BITSWAP:
14706            check_insn(ctx, ISA_MIPS_R6);
14707            gen_bitswap(ctx, OPC_BITSWAP, rs, rt);
14708            break;
14709        case SEB:
14710            gen_bshfl(ctx, OPC_SEB, rs, rt);
14711            break;
14712        case SEH:
14713            gen_bshfl(ctx, OPC_SEH, rs, rt);
14714            break;
14715        case CLO:
14716            mips32_op = OPC_CLO;
14717            goto do_cl;
14718        case CLZ:
14719            mips32_op = OPC_CLZ;
14720        do_cl:
14721            check_insn(ctx, ISA_MIPS_R1);
14722            gen_cl(ctx, mips32_op, rt, rs);
14723            break;
14724        case RDHWR:
14725            check_insn_opc_removed(ctx, ISA_MIPS_R6);
14726            gen_rdhwr(ctx, rt, rs, 0);
14727            break;
14728        case WSBH:
14729            gen_bshfl(ctx, OPC_WSBH, rs, rt);
14730            break;
14731        case MULT:
14732            check_insn_opc_removed(ctx, ISA_MIPS_R6);
14733            mips32_op = OPC_MULT;
14734            goto do_mul;
14735        case MULTU:
14736            check_insn_opc_removed(ctx, ISA_MIPS_R6);
14737            mips32_op = OPC_MULTU;
14738            goto do_mul;
14739        case DIV:
14740            check_insn_opc_removed(ctx, ISA_MIPS_R6);
14741            mips32_op = OPC_DIV;
14742            goto do_div;
14743        case DIVU:
14744            check_insn_opc_removed(ctx, ISA_MIPS_R6);
14745            mips32_op = OPC_DIVU;
14746            goto do_div;
14747        do_div:
14748            check_insn(ctx, ISA_MIPS_R1);
14749            gen_muldiv(ctx, mips32_op, 0, rs, rt);
14750            break;
14751        case MADD:
14752            check_insn_opc_removed(ctx, ISA_MIPS_R6);
14753            mips32_op = OPC_MADD;
14754            goto do_mul;
14755        case MADDU:
14756            check_insn_opc_removed(ctx, ISA_MIPS_R6);
14757            mips32_op = OPC_MADDU;
14758            goto do_mul;
14759        case MSUB:
14760            check_insn_opc_removed(ctx, ISA_MIPS_R6);
14761            mips32_op = OPC_MSUB;
14762            goto do_mul;
14763        case MSUBU:
14764            check_insn_opc_removed(ctx, ISA_MIPS_R6);
14765            mips32_op = OPC_MSUBU;
14766        do_mul:
14767            check_insn(ctx, ISA_MIPS_R1);
14768            gen_muldiv(ctx, mips32_op, 0, rs, rt);
14769            break;
14770        default:
14771            goto pool32axf_invalid;
14772        }
14773        break;
14774    case 0x34:
14775        switch (minor) {
14776        case MFC2:
14777        case MTC2:
14778        case MFHC2:
14779        case MTHC2:
14780        case CFC2:
14781        case CTC2:
14782            generate_exception_err(ctx, EXCP_CpU, 2);
14783            break;
14784        default:
14785            goto pool32axf_invalid;
14786        }
14787        break;
14788    case 0x3c:
14789        switch (minor) {
14790        case JALR:    /* JALRC */
14791        case JALR_HB: /* JALRC_HB */
14792            if (ctx->insn_flags & ISA_MIPS_R6) {
14793                /* JALRC, JALRC_HB */
14794                gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 0);
14795            } else {
14796                /* JALR, JALR_HB */
14797                gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 4);
14798                ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14799            }
14800            break;
14801        case JALRS:
14802        case JALRS_HB:
14803            check_insn_opc_removed(ctx, ISA_MIPS_R6);
14804            gen_compute_branch(ctx, OPC_JALR, 4, rs, rt, 0, 2);
14805            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
14806            break;
14807        default:
14808            goto pool32axf_invalid;
14809        }
14810        break;
14811    case 0x05:
14812        switch (minor) {
14813        case RDPGPR:
14814            check_cp0_enabled(ctx);
14815            check_insn(ctx, ISA_MIPS_R2);
14816            gen_load_srsgpr(rs, rt);
14817            break;
14818        case WRPGPR:
14819            check_cp0_enabled(ctx);
14820            check_insn(ctx, ISA_MIPS_R2);
14821            gen_store_srsgpr(rs, rt);
14822            break;
14823        default:
14824            goto pool32axf_invalid;
14825        }
14826        break;
14827#ifndef CONFIG_USER_ONLY
14828    case 0x0d:
14829        switch (minor) {
14830        case TLBP:
14831            mips32_op = OPC_TLBP;
14832            goto do_cp0;
14833        case TLBR:
14834            mips32_op = OPC_TLBR;
14835            goto do_cp0;
14836        case TLBWI:
14837            mips32_op = OPC_TLBWI;
14838            goto do_cp0;
14839        case TLBWR:
14840            mips32_op = OPC_TLBWR;
14841            goto do_cp0;
14842        case TLBINV:
14843            mips32_op = OPC_TLBINV;
14844            goto do_cp0;
14845        case TLBINVF:
14846            mips32_op = OPC_TLBINVF;
14847            goto do_cp0;
14848        case WAIT:
14849            mips32_op = OPC_WAIT;
14850            goto do_cp0;
14851        case DERET:
14852            mips32_op = OPC_DERET;
14853            goto do_cp0;
14854        case ERET:
14855            mips32_op = OPC_ERET;
14856        do_cp0:
14857            gen_cp0(env, ctx, mips32_op, rt, rs);
14858            break;
14859        default:
14860            goto pool32axf_invalid;
14861        }
14862        break;
14863    case 0x1d:
14864        switch (minor) {
14865        case DI:
14866            check_cp0_enabled(ctx);
14867            {
14868                TCGv t0 = tcg_temp_new();
14869
14870                save_cpu_state(ctx, 1);
14871                gen_helper_di(t0, cpu_env);
14872                gen_store_gpr(t0, rs);
14873                /*
14874                 * Stop translation as we may have switched the execution
14875                 * mode.
14876                 */
14877                ctx->base.is_jmp = DISAS_STOP;
14878                tcg_temp_free(t0);
14879            }
14880            break;
14881        case EI:
14882            check_cp0_enabled(ctx);
14883            {
14884                TCGv t0 = tcg_temp_new();
14885
14886                save_cpu_state(ctx, 1);
14887                gen_helper_ei(t0, cpu_env);
14888                gen_store_gpr(t0, rs);
14889                /*
14890                 * DISAS_STOP isn't sufficient, we need to ensure we break out
14891                 * of translated code to check for pending interrupts.
14892                 */
14893                gen_save_pc(ctx->base.pc_next + 4);
14894                ctx->base.is_jmp = DISAS_EXIT;
14895                tcg_temp_free(t0);
14896            }
14897            break;
14898        default:
14899            goto pool32axf_invalid;
14900        }
14901        break;
14902#endif
14903    case 0x2d:
14904        switch (minor) {
14905        case SYNC:
14906            gen_sync(extract32(ctx->opcode, 16, 5));
14907            break;
14908        case SYSCALL:
14909            generate_exception_end(ctx, EXCP_SYSCALL);
14910            break;
14911        case SDBBP:
14912            if (is_uhi(extract32(ctx->opcode, 16, 10))) {
14913                gen_helper_do_semihosting(cpu_env);
14914            } else {
14915                check_insn(ctx, ISA_MIPS_R1);
14916                if (ctx->hflags & MIPS_HFLAG_SBRI) {
14917                    gen_reserved_instruction(ctx);
14918                } else {
14919                    generate_exception_end(ctx, EXCP_DBp);
14920                }
14921            }
14922            break;
14923        default:
14924            goto pool32axf_invalid;
14925        }
14926        break;
14927    case 0x01:
14928        switch (minor & 3) {
14929        case MFHI_ACC:
14930            gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
14931            break;
14932        case MFLO_ACC:
14933            gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
14934            break;
14935        case MTHI_ACC:
14936            gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
14937            break;
14938        case MTLO_ACC:
14939            gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
14940            break;
14941        default:
14942            goto pool32axf_invalid;
14943        }
14944        break;
14945    case 0x35:
14946        check_insn_opc_removed(ctx, ISA_MIPS_R6);
14947        switch (minor) {
14948        case MFHI32:
14949            gen_HILO(ctx, OPC_MFHI, 0, rs);
14950            break;
14951        case MFLO32:
14952            gen_HILO(ctx, OPC_MFLO, 0, rs);
14953            break;
14954        case MTHI32:
14955            gen_HILO(ctx, OPC_MTHI, 0, rs);
14956            break;
14957        case MTLO32:
14958            gen_HILO(ctx, OPC_MTLO, 0, rs);
14959            break;
14960        default:
14961            goto pool32axf_invalid;
14962        }
14963        break;
14964    default:
14965    pool32axf_invalid:
14966        MIPS_INVAL("pool32axf");
14967        gen_reserved_instruction(ctx);
14968        break;
14969    }
14970}
14971
14972/*
14973 * Values for microMIPS fmt field.  Variable-width, depending on which
14974 * formats the instruction supports.
14975 */
14976enum {
14977    FMT_SD_S = 0,
14978    FMT_SD_D = 1,
14979
14980    FMT_SDPS_S = 0,
14981    FMT_SDPS_D = 1,
14982    FMT_SDPS_PS = 2,
14983
14984    FMT_SWL_S = 0,
14985    FMT_SWL_W = 1,
14986    FMT_SWL_L = 2,
14987
14988    FMT_DWL_D = 0,
14989    FMT_DWL_W = 1,
14990    FMT_DWL_L = 2
14991};
14992
14993static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
14994{
14995    int extension = (ctx->opcode >> 6) & 0x3ff;
14996    uint32_t mips32_op;
14997
14998#define FLOAT_1BIT_FMT(opc, fmt)    ((fmt << 8) | opc)
14999#define FLOAT_2BIT_FMT(opc, fmt)    ((fmt << 7) | opc)
15000#define COND_FLOAT_MOV(opc, cond)   ((cond << 7) | opc)
15001
15002    switch (extension) {
15003    case FLOAT_1BIT_FMT(CFC1, 0):
15004        mips32_op = OPC_CFC1;
15005        goto do_cp1;
15006    case FLOAT_1BIT_FMT(CTC1, 0):
15007        mips32_op = OPC_CTC1;
15008        goto do_cp1;
15009    case FLOAT_1BIT_FMT(MFC1, 0):
15010        mips32_op = OPC_MFC1;
15011        goto do_cp1;
15012    case FLOAT_1BIT_FMT(MTC1, 0):
15013        mips32_op = OPC_MTC1;
15014        goto do_cp1;
15015    case FLOAT_1BIT_FMT(MFHC1, 0):
15016        mips32_op = OPC_MFHC1;
15017        goto do_cp1;
15018    case FLOAT_1BIT_FMT(MTHC1, 0):
15019        mips32_op = OPC_MTHC1;
15020    do_cp1:
15021        gen_cp1(ctx, mips32_op, rt, rs);
15022        break;
15023
15024        /* Reciprocal square root */
15025    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
15026        mips32_op = OPC_RSQRT_S;
15027        goto do_unaryfp;
15028    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
15029        mips32_op = OPC_RSQRT_D;
15030        goto do_unaryfp;
15031
15032        /* Square root */
15033    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
15034        mips32_op = OPC_SQRT_S;
15035        goto do_unaryfp;
15036    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
15037        mips32_op = OPC_SQRT_D;
15038        goto do_unaryfp;
15039
15040        /* Reciprocal */
15041    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
15042        mips32_op = OPC_RECIP_S;
15043        goto do_unaryfp;
15044    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
15045        mips32_op = OPC_RECIP_D;
15046        goto do_unaryfp;
15047
15048        /* Floor */
15049    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
15050        mips32_op = OPC_FLOOR_L_S;
15051        goto do_unaryfp;
15052    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
15053        mips32_op = OPC_FLOOR_L_D;
15054        goto do_unaryfp;
15055    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
15056        mips32_op = OPC_FLOOR_W_S;
15057        goto do_unaryfp;
15058    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
15059        mips32_op = OPC_FLOOR_W_D;
15060        goto do_unaryfp;
15061
15062        /* Ceiling */
15063    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
15064        mips32_op = OPC_CEIL_L_S;
15065        goto do_unaryfp;
15066    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
15067        mips32_op = OPC_CEIL_L_D;
15068        goto do_unaryfp;
15069    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
15070        mips32_op = OPC_CEIL_W_S;
15071        goto do_unaryfp;
15072    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
15073        mips32_op = OPC_CEIL_W_D;
15074        goto do_unaryfp;
15075
15076        /* Truncation */
15077    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
15078        mips32_op = OPC_TRUNC_L_S;
15079        goto do_unaryfp;
15080    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
15081        mips32_op = OPC_TRUNC_L_D;
15082        goto do_unaryfp;
15083    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
15084        mips32_op = OPC_TRUNC_W_S;
15085        goto do_unaryfp;
15086    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
15087        mips32_op = OPC_TRUNC_W_D;
15088        goto do_unaryfp;
15089
15090        /* Round */
15091    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
15092        mips32_op = OPC_ROUND_L_S;
15093        goto do_unaryfp;
15094    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
15095        mips32_op = OPC_ROUND_L_D;
15096        goto do_unaryfp;
15097    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
15098        mips32_op = OPC_ROUND_W_S;
15099        goto do_unaryfp;
15100    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
15101        mips32_op = OPC_ROUND_W_D;
15102        goto do_unaryfp;
15103
15104        /* Integer to floating-point conversion */
15105    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
15106        mips32_op = OPC_CVT_L_S;
15107        goto do_unaryfp;
15108    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
15109        mips32_op = OPC_CVT_L_D;
15110        goto do_unaryfp;
15111    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
15112        mips32_op = OPC_CVT_W_S;
15113        goto do_unaryfp;
15114    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
15115        mips32_op = OPC_CVT_W_D;
15116        goto do_unaryfp;
15117
15118        /* Paired-foo conversions */
15119    case FLOAT_1BIT_FMT(CVT_S_PL, 0):
15120        mips32_op = OPC_CVT_S_PL;
15121        goto do_unaryfp;
15122    case FLOAT_1BIT_FMT(CVT_S_PU, 0):
15123        mips32_op = OPC_CVT_S_PU;
15124        goto do_unaryfp;
15125    case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
15126        mips32_op = OPC_CVT_PW_PS;
15127        goto do_unaryfp;
15128    case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
15129        mips32_op = OPC_CVT_PS_PW;
15130        goto do_unaryfp;
15131
15132        /* Floating-point moves */
15133    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
15134        mips32_op = OPC_MOV_S;
15135        goto do_unaryfp;
15136    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
15137        mips32_op = OPC_MOV_D;
15138        goto do_unaryfp;
15139    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
15140        mips32_op = OPC_MOV_PS;
15141        goto do_unaryfp;
15142
15143        /* Absolute value */
15144    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
15145        mips32_op = OPC_ABS_S;
15146        goto do_unaryfp;
15147    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
15148        mips32_op = OPC_ABS_D;
15149        goto do_unaryfp;
15150    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
15151        mips32_op = OPC_ABS_PS;
15152        goto do_unaryfp;
15153
15154        /* Negation */
15155    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
15156        mips32_op = OPC_NEG_S;
15157        goto do_unaryfp;
15158    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
15159        mips32_op = OPC_NEG_D;
15160        goto do_unaryfp;
15161    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
15162        mips32_op = OPC_NEG_PS;
15163        goto do_unaryfp;
15164
15165        /* Reciprocal square root step */
15166    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
15167        mips32_op = OPC_RSQRT1_S;
15168        goto do_unaryfp;
15169    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
15170        mips32_op = OPC_RSQRT1_D;
15171        goto do_unaryfp;
15172    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
15173        mips32_op = OPC_RSQRT1_PS;
15174        goto do_unaryfp;
15175
15176        /* Reciprocal step */
15177    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
15178        mips32_op = OPC_RECIP1_S;
15179        goto do_unaryfp;
15180    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
15181        mips32_op = OPC_RECIP1_S;
15182        goto do_unaryfp;
15183    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
15184        mips32_op = OPC_RECIP1_PS;
15185        goto do_unaryfp;
15186
15187        /* Conversions from double */
15188    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
15189        mips32_op = OPC_CVT_D_S;
15190        goto do_unaryfp;
15191    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
15192        mips32_op = OPC_CVT_D_W;
15193        goto do_unaryfp;
15194    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
15195        mips32_op = OPC_CVT_D_L;
15196        goto do_unaryfp;
15197
15198        /* Conversions from single */
15199    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
15200        mips32_op = OPC_CVT_S_D;
15201        goto do_unaryfp;
15202    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
15203        mips32_op = OPC_CVT_S_W;
15204        goto do_unaryfp;
15205    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
15206        mips32_op = OPC_CVT_S_L;
15207    do_unaryfp:
15208        gen_farith(ctx, mips32_op, -1, rs, rt, 0);
15209        break;
15210
15211        /* Conditional moves on floating-point codes */
15212    case COND_FLOAT_MOV(MOVT, 0):
15213    case COND_FLOAT_MOV(MOVT, 1):
15214    case COND_FLOAT_MOV(MOVT, 2):
15215    case COND_FLOAT_MOV(MOVT, 3):
15216    case COND_FLOAT_MOV(MOVT, 4):
15217    case COND_FLOAT_MOV(MOVT, 5):
15218    case COND_FLOAT_MOV(MOVT, 6):
15219    case COND_FLOAT_MOV(MOVT, 7):
15220        check_insn_opc_removed(ctx, ISA_MIPS_R6);
15221        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
15222        break;
15223    case COND_FLOAT_MOV(MOVF, 0):
15224    case COND_FLOAT_MOV(MOVF, 1):
15225    case COND_FLOAT_MOV(MOVF, 2):
15226    case COND_FLOAT_MOV(MOVF, 3):
15227    case COND_FLOAT_MOV(MOVF, 4):
15228    case COND_FLOAT_MOV(MOVF, 5):
15229    case COND_FLOAT_MOV(MOVF, 6):
15230    case COND_FLOAT_MOV(MOVF, 7):
15231        check_insn_opc_removed(ctx, ISA_MIPS_R6);
15232        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
15233        break;
15234    default:
15235        MIPS_INVAL("pool32fxf");
15236        gen_reserved_instruction(ctx);
15237        break;
15238    }
15239}
15240
15241static void decode_micromips32_opc(CPUMIPSState *env, DisasContext *ctx)
15242{
15243    int32_t offset;
15244    uint16_t insn;
15245    int rt, rs, rd, rr;
15246    int16_t imm;
15247    uint32_t op, minor, minor2, mips32_op;
15248    uint32_t cond, fmt, cc;
15249
15250    insn = translator_lduw(env, ctx->base.pc_next + 2);
15251    ctx->opcode = (ctx->opcode << 16) | insn;
15252
15253    rt = (ctx->opcode >> 21) & 0x1f;
15254    rs = (ctx->opcode >> 16) & 0x1f;
15255    rd = (ctx->opcode >> 11) & 0x1f;
15256    rr = (ctx->opcode >> 6) & 0x1f;
15257    imm = (int16_t) ctx->opcode;
15258
15259    op = (ctx->opcode >> 26) & 0x3f;
15260    switch (op) {
15261    case POOL32A:
15262        minor = ctx->opcode & 0x3f;
15263        switch (minor) {
15264        case 0x00:
15265            minor = (ctx->opcode >> 6) & 0xf;
15266            switch (minor) {
15267            case SLL32:
15268                mips32_op = OPC_SLL;
15269                goto do_shifti;
15270            case SRA:
15271                mips32_op = OPC_SRA;
15272                goto do_shifti;
15273            case SRL32:
15274                mips32_op = OPC_SRL;
15275                goto do_shifti;
15276            case ROTR:
15277                mips32_op = OPC_ROTR;
15278            do_shifti:
15279                gen_shift_imm(ctx, mips32_op, rt, rs, rd);
15280                break;
15281            case SELEQZ:
15282                check_insn(ctx, ISA_MIPS_R6);
15283                gen_cond_move(ctx, OPC_SELEQZ, rd, rs, rt);
15284                break;
15285            case SELNEZ:
15286                check_insn(ctx, ISA_MIPS_R6);
15287                gen_cond_move(ctx, OPC_SELNEZ, rd, rs, rt);
15288                break;
15289            case R6_RDHWR:
15290                check_insn(ctx, ISA_MIPS_R6);
15291                gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
15292                break;
15293            default:
15294                goto pool32a_invalid;
15295            }
15296            break;
15297        case 0x10:
15298            minor = (ctx->opcode >> 6) & 0xf;
15299            switch (minor) {
15300                /* Arithmetic */
15301            case ADD:
15302                mips32_op = OPC_ADD;
15303                goto do_arith;
15304            case ADDU32:
15305                mips32_op = OPC_ADDU;
15306                goto do_arith;
15307            case SUB:
15308                mips32_op = OPC_SUB;
15309                goto do_arith;
15310            case SUBU32:
15311                mips32_op = OPC_SUBU;
15312                goto do_arith;
15313            case MUL:
15314                check_insn_opc_removed(ctx, ISA_MIPS_R6);
15315                mips32_op = OPC_MUL;
15316            do_arith:
15317                gen_arith(ctx, mips32_op, rd, rs, rt);
15318                break;
15319                /* Shifts */
15320            case SLLV:
15321                mips32_op = OPC_SLLV;
15322                goto do_shift;
15323            case SRLV:
15324                mips32_op = OPC_SRLV;
15325                goto do_shift;
15326            case SRAV:
15327                mips32_op = OPC_SRAV;
15328                goto do_shift;
15329            case ROTRV:
15330                mips32_op = OPC_ROTRV;
15331            do_shift:
15332                gen_shift(ctx, mips32_op, rd, rs, rt);
15333                break;
15334                /* Logical operations */
15335            case AND:
15336                mips32_op = OPC_AND;
15337                goto do_logic;
15338            case OR32:
15339                mips32_op = OPC_OR;
15340                goto do_logic;
15341            case NOR:
15342                mips32_op = OPC_NOR;
15343                goto do_logic;
15344            case XOR32:
15345                mips32_op = OPC_XOR;
15346            do_logic:
15347                gen_logic(ctx, mips32_op, rd, rs, rt);
15348                break;
15349                /* Set less than */
15350            case SLT:
15351                mips32_op = OPC_SLT;
15352                goto do_slt;
15353            case SLTU:
15354                mips32_op = OPC_SLTU;
15355            do_slt:
15356                gen_slt(ctx, mips32_op, rd, rs, rt);
15357                break;
15358            default:
15359                goto pool32a_invalid;
15360            }
15361            break;
15362        case 0x18:
15363            minor = (ctx->opcode >> 6) & 0xf;
15364            switch (minor) {
15365                /* Conditional moves */
15366            case MOVN: /* MUL */
15367                if (ctx->insn_flags & ISA_MIPS_R6) {
15368                    /* MUL */
15369                    gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
15370                } else {
15371                    /* MOVN */
15372                    gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
15373                }
15374                break;
15375            case MOVZ: /* MUH */
15376                if (ctx->insn_flags & ISA_MIPS_R6) {
15377                    /* MUH */
15378                    gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
15379                } else {
15380                    /* MOVZ */
15381                    gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
15382                }
15383                break;
15384            case MULU:
15385                check_insn(ctx, ISA_MIPS_R6);
15386                gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
15387                break;
15388            case MUHU:
15389                check_insn(ctx, ISA_MIPS_R6);
15390                gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
15391                break;
15392            case LWXS: /* DIV */
15393                if (ctx->insn_flags & ISA_MIPS_R6) {
15394                    /* DIV */
15395                    gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
15396                } else {
15397                    /* LWXS */
15398                    gen_ldxs(ctx, rs, rt, rd);
15399                }
15400                break;
15401            case MOD:
15402                check_insn(ctx, ISA_MIPS_R6);
15403                gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
15404                break;
15405            case R6_DIVU:
15406                check_insn(ctx, ISA_MIPS_R6);
15407                gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
15408                break;
15409            case MODU:
15410                check_insn(ctx, ISA_MIPS_R6);
15411                gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
15412                break;
15413            default:
15414                goto pool32a_invalid;
15415            }
15416            break;
15417        case INS:
15418            gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
15419            return;
15420        case LSA:
15421            check_insn(ctx, ISA_MIPS_R6);
15422            gen_lsa(ctx, rd, rt, rs, extract32(ctx->opcode, 9, 2));
15423            break;
15424        case ALIGN:
15425            check_insn(ctx, ISA_MIPS_R6);
15426            gen_align(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 9, 2));
15427            break;
15428        case EXT:
15429            gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
15430            return;
15431        case POOL32AXF:
15432            gen_pool32axf(env, ctx, rt, rs);
15433            break;
15434        case BREAK32:
15435            generate_exception_end(ctx, EXCP_BREAK);
15436            break;
15437        case SIGRIE:
15438            check_insn(ctx, ISA_MIPS_R6);
15439            gen_reserved_instruction(ctx);
15440            break;
15441        default:
15442        pool32a_invalid:
15443                MIPS_INVAL("pool32a");
15444                gen_reserved_instruction(ctx);
15445                break;
15446        }
15447        break;
15448    case POOL32B:
15449        minor = (ctx->opcode >> 12) & 0xf;
15450        switch (minor) {
15451        case CACHE:
15452            check_cp0_enabled(ctx);
15453            if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
15454                gen_cache_operation(ctx, rt, rs, imm);
15455            }
15456            break;
15457        case LWC2:
15458        case SWC2:
15459            /* COP2: Not implemented. */
15460            generate_exception_err(ctx, EXCP_CpU, 2);
15461            break;
15462#ifdef TARGET_MIPS64
15463        case LDP:
15464        case SDP:
15465            check_insn(ctx, ISA_MIPS3);
15466            check_mips_64(ctx);
15467#endif
15468            /* fall through */
15469        case LWP:
15470        case SWP:
15471            gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
15472            break;
15473#ifdef TARGET_MIPS64
15474        case LDM:
15475        case SDM:
15476            check_insn(ctx, ISA_MIPS3);
15477            check_mips_64(ctx);
15478#endif
15479            /* fall through */
15480        case LWM32:
15481        case SWM32:
15482            gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
15483            break;
15484        default:
15485            MIPS_INVAL("pool32b");
15486            gen_reserved_instruction(ctx);
15487            break;
15488        }
15489        break;
15490    case POOL32F:
15491        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
15492            minor = ctx->opcode & 0x3f;
15493            check_cp1_enabled(ctx);
15494            switch (minor) {
15495            case ALNV_PS:
15496                check_insn_opc_removed(ctx, ISA_MIPS_R6);
15497                mips32_op = OPC_ALNV_PS;
15498                goto do_madd;
15499            case MADD_S:
15500                check_insn_opc_removed(ctx, ISA_MIPS_R6);
15501                mips32_op = OPC_MADD_S;
15502                goto do_madd;
15503            case MADD_D:
15504                check_insn_opc_removed(ctx, ISA_MIPS_R6);
15505                mips32_op = OPC_MADD_D;
15506                goto do_madd;
15507            case MADD_PS:
15508                check_insn_opc_removed(ctx, ISA_MIPS_R6);
15509                mips32_op = OPC_MADD_PS;
15510                goto do_madd;
15511            case MSUB_S:
15512                check_insn_opc_removed(ctx, ISA_MIPS_R6);
15513                mips32_op = OPC_MSUB_S;
15514                goto do_madd;
15515            case MSUB_D:
15516                check_insn_opc_removed(ctx, ISA_MIPS_R6);
15517                mips32_op = OPC_MSUB_D;
15518                goto do_madd;
15519            case MSUB_PS:
15520                check_insn_opc_removed(ctx, ISA_MIPS_R6);
15521                mips32_op = OPC_MSUB_PS;
15522                goto do_madd;
15523            case NMADD_S:
15524                check_insn_opc_removed(ctx, ISA_MIPS_R6);
15525                mips32_op = OPC_NMADD_S;
15526                goto do_madd;
15527            case NMADD_D:
15528                check_insn_opc_removed(ctx, ISA_MIPS_R6);
15529                mips32_op = OPC_NMADD_D;
15530                goto do_madd;
15531            case NMADD_PS:
15532                check_insn_opc_removed(ctx, ISA_MIPS_R6);
15533                mips32_op = OPC_NMADD_PS;
15534                goto do_madd;
15535            case NMSUB_S:
15536                check_insn_opc_removed(ctx, ISA_MIPS_R6);
15537                mips32_op = OPC_NMSUB_S;
15538                goto do_madd;
15539            case NMSUB_D:
15540                check_insn_opc_removed(ctx, ISA_MIPS_R6);
15541                mips32_op = OPC_NMSUB_D;
15542                goto do_madd;
15543            case NMSUB_PS:
15544                check_insn_opc_removed(ctx, ISA_MIPS_R6);
15545                mips32_op = OPC_NMSUB_PS;
15546            do_madd:
15547                gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
15548                break;
15549            case CABS_COND_FMT:
15550                check_insn_opc_removed(ctx, ISA_MIPS_R6);
15551                cond = (ctx->opcode >> 6) & 0xf;
15552                cc = (ctx->opcode >> 13) & 0x7;
15553                fmt = (ctx->opcode >> 10) & 0x3;
15554                switch (fmt) {
15555                case 0x0:
15556                    gen_cmpabs_s(ctx, cond, rt, rs, cc);
15557                    break;
15558                case 0x1:
15559                    gen_cmpabs_d(ctx, cond, rt, rs, cc);
15560                    break;
15561                case 0x2:
15562                    gen_cmpabs_ps(ctx, cond, rt, rs, cc);
15563                    break;
15564                default:
15565                    goto pool32f_invalid;
15566                }
15567                break;
15568            case C_COND_FMT:
15569                check_insn_opc_removed(ctx, ISA_MIPS_R6);
15570                cond = (ctx->opcode >> 6) & 0xf;
15571                cc = (ctx->opcode >> 13) & 0x7;
15572                fmt = (ctx->opcode >> 10) & 0x3;
15573                switch (fmt) {
15574                case 0x0:
15575                    gen_cmp_s(ctx, cond, rt, rs, cc);
15576                    break;
15577                case 0x1:
15578                    gen_cmp_d(ctx, cond, rt, rs, cc);
15579                    break;
15580                case 0x2:
15581                    gen_cmp_ps(ctx, cond, rt, rs, cc);
15582                    break;
15583                default:
15584                    goto pool32f_invalid;
15585                }
15586                break;
15587            case CMP_CONDN_S:
15588                check_insn(ctx, ISA_MIPS_R6);
15589                gen_r6_cmp_s(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
15590                break;
15591            case CMP_CONDN_D:
15592                check_insn(ctx, ISA_MIPS_R6);
15593                gen_r6_cmp_d(ctx, (ctx->opcode >> 6) & 0x1f, rt, rs, rd);
15594                break;
15595            case POOL32FXF:
15596                gen_pool32fxf(ctx, rt, rs);
15597                break;
15598            case 0x00:
15599                /* PLL foo */
15600                switch ((ctx->opcode >> 6) & 0x7) {
15601                case PLL_PS:
15602                    mips32_op = OPC_PLL_PS;
15603                    goto do_ps;
15604                case PLU_PS:
15605                    mips32_op = OPC_PLU_PS;
15606                    goto do_ps;
15607                case PUL_PS:
15608                    mips32_op = OPC_PUL_PS;
15609                    goto do_ps;
15610                case PUU_PS:
15611                    mips32_op = OPC_PUU_PS;
15612                    goto do_ps;
15613                case CVT_PS_S:
15614                    check_insn_opc_removed(ctx, ISA_MIPS_R6);
15615                    mips32_op = OPC_CVT_PS_S;
15616                do_ps:
15617                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
15618                    break;
15619                default:
15620                    goto pool32f_invalid;
15621                }
15622                break;
15623            case MIN_FMT:
15624                check_insn(ctx, ISA_MIPS_R6);
15625                switch ((ctx->opcode >> 9) & 0x3) {
15626                case FMT_SDPS_S:
15627                    gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
15628                    break;
15629                case FMT_SDPS_D:
15630                    gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
15631                    break;
15632                default:
15633                    goto pool32f_invalid;
15634                }
15635                break;
15636            case 0x08:
15637                /* [LS][WDU]XC1 */
15638                switch ((ctx->opcode >> 6) & 0x7) {
15639                case LWXC1:
15640                    check_insn_opc_removed(ctx, ISA_MIPS_R6);
15641                    mips32_op = OPC_LWXC1;
15642                    goto do_ldst_cp1;
15643                case SWXC1:
15644                    check_insn_opc_removed(ctx, ISA_MIPS_R6);
15645                    mips32_op = OPC_SWXC1;
15646                    goto do_ldst_cp1;
15647                case LDXC1:
15648                    check_insn_opc_removed(ctx, ISA_MIPS_R6);
15649                    mips32_op = OPC_LDXC1;
15650                    goto do_ldst_cp1;
15651                case SDXC1:
15652                    check_insn_opc_removed(ctx, ISA_MIPS_R6);
15653                    mips32_op = OPC_SDXC1;
15654                    goto do_ldst_cp1;
15655                case LUXC1:
15656                    check_insn_opc_removed(ctx, ISA_MIPS_R6);
15657                    mips32_op = OPC_LUXC1;
15658                    goto do_ldst_cp1;
15659                case SUXC1:
15660                    check_insn_opc_removed(ctx, ISA_MIPS_R6);
15661                    mips32_op = OPC_SUXC1;
15662                do_ldst_cp1:
15663                    gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
15664                    break;
15665                default:
15666                    goto pool32f_invalid;
15667                }
15668                break;
15669            case MAX_FMT:
15670                check_insn(ctx, ISA_MIPS_R6);
15671                switch ((ctx->opcode >> 9) & 0x3) {
15672                case FMT_SDPS_S:
15673                    gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
15674                    break;
15675                case FMT_SDPS_D:
15676                    gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
15677                    break;
15678                default:
15679                    goto pool32f_invalid;
15680                }
15681                break;
15682            case 0x18:
15683                /* 3D insns */
15684                check_insn_opc_removed(ctx, ISA_MIPS_R6);
15685                fmt = (ctx->opcode >> 9) & 0x3;
15686                switch ((ctx->opcode >> 6) & 0x7) {
15687                case RSQRT2_FMT:
15688                    switch (fmt) {
15689                    case FMT_SDPS_S:
15690                        mips32_op = OPC_RSQRT2_S;
15691                        goto do_3d;
15692                    case FMT_SDPS_D:
15693                        mips32_op = OPC_RSQRT2_D;
15694                        goto do_3d;
15695                    case FMT_SDPS_PS:
15696                        mips32_op = OPC_RSQRT2_PS;
15697                        goto do_3d;
15698                    default:
15699                        goto pool32f_invalid;
15700                    }
15701                    break;
15702                case RECIP2_FMT:
15703                    switch (fmt) {
15704                    case FMT_SDPS_S:
15705                        mips32_op = OPC_RECIP2_S;
15706                        goto do_3d;
15707                    case FMT_SDPS_D:
15708                        mips32_op = OPC_RECIP2_D;
15709                        goto do_3d;
15710                    case FMT_SDPS_PS:
15711                        mips32_op = OPC_RECIP2_PS;
15712                        goto do_3d;
15713                    default:
15714                        goto pool32f_invalid;
15715                    }
15716                    break;
15717                case ADDR_PS:
15718                    mips32_op = OPC_ADDR_PS;
15719                    goto do_3d;
15720                case MULR_PS:
15721                    mips32_op = OPC_MULR_PS;
15722                do_3d:
15723                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
15724                    break;
15725                default:
15726                    goto pool32f_invalid;
15727                }
15728                break;
15729            case 0x20:
15730                /* MOV[FT].fmt, PREFX, RINT.fmt, CLASS.fmt*/
15731                cc = (ctx->opcode >> 13) & 0x7;
15732                fmt = (ctx->opcode >> 9) & 0x3;
15733                switch ((ctx->opcode >> 6) & 0x7) {
15734                case MOVF_FMT: /* RINT_FMT */
15735                    if (ctx->insn_flags & ISA_MIPS_R6) {
15736                        /* RINT_FMT */
15737                        switch (fmt) {
15738                        case FMT_SDPS_S:
15739                            gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
15740                            break;
15741                        case FMT_SDPS_D:
15742                            gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
15743                            break;
15744                        default:
15745                            goto pool32f_invalid;
15746                        }
15747                    } else {
15748                        /* MOVF_FMT */
15749                        switch (fmt) {
15750                        case FMT_SDPS_S:
15751                            gen_movcf_s(ctx, rs, rt, cc, 0);
15752                            break;
15753                        case FMT_SDPS_D:
15754                            gen_movcf_d(ctx, rs, rt, cc, 0);
15755                            break;
15756                        case FMT_SDPS_PS:
15757                            check_ps(ctx);
15758                            gen_movcf_ps(ctx, rs, rt, cc, 0);
15759                            break;
15760                        default:
15761                            goto pool32f_invalid;
15762                        }
15763                    }
15764                    break;
15765                case MOVT_FMT: /* CLASS_FMT */
15766                    if (ctx->insn_flags & ISA_MIPS_R6) {
15767                        /* CLASS_FMT */
15768                        switch (fmt) {
15769                        case FMT_SDPS_S:
15770                            gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
15771                            break;
15772                        case FMT_SDPS_D:
15773                            gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
15774                            break;
15775                        default:
15776                            goto pool32f_invalid;
15777                        }
15778                    } else {
15779                        /* MOVT_FMT */
15780                        switch (fmt) {
15781                        case FMT_SDPS_S:
15782                            gen_movcf_s(ctx, rs, rt, cc, 1);
15783                            break;
15784                        case FMT_SDPS_D:
15785                            gen_movcf_d(ctx, rs, rt, cc, 1);
15786                            break;
15787                        case FMT_SDPS_PS:
15788                            check_ps(ctx);
15789                            gen_movcf_ps(ctx, rs, rt, cc, 1);
15790                            break;
15791                        default:
15792                            goto pool32f_invalid;
15793                        }
15794                    }
15795                    break;
15796                case PREFX:
15797                    check_insn_opc_removed(ctx, ISA_MIPS_R6);
15798                    break;
15799                default:
15800                    goto pool32f_invalid;
15801                }
15802                break;
15803#define FINSN_3ARG_SDPS(prfx)                           \
15804                switch ((ctx->opcode >> 8) & 0x3) {     \
15805                case FMT_SDPS_S:                        \
15806                    mips32_op = OPC_##prfx##_S;         \
15807                    goto do_fpop;                       \
15808                case FMT_SDPS_D:                        \
15809                    mips32_op = OPC_##prfx##_D;         \
15810                    goto do_fpop;                       \
15811                case FMT_SDPS_PS:                       \
15812                    check_ps(ctx);                      \
15813                    mips32_op = OPC_##prfx##_PS;        \
15814                    goto do_fpop;                       \
15815                default:                                \
15816                    goto pool32f_invalid;               \
15817                }
15818            case MINA_FMT:
15819                check_insn(ctx, ISA_MIPS_R6);
15820                switch ((ctx->opcode >> 9) & 0x3) {
15821                case FMT_SDPS_S:
15822                    gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
15823                    break;
15824                case FMT_SDPS_D:
15825                    gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
15826                    break;
15827                default:
15828                    goto pool32f_invalid;
15829                }
15830                break;
15831            case MAXA_FMT:
15832                check_insn(ctx, ISA_MIPS_R6);
15833                switch ((ctx->opcode >> 9) & 0x3) {
15834                case FMT_SDPS_S:
15835                    gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
15836                    break;
15837                case FMT_SDPS_D:
15838                    gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
15839                    break;
15840                default:
15841                    goto pool32f_invalid;
15842                }
15843                break;
15844            case 0x30:
15845                /* regular FP ops */
15846                switch ((ctx->opcode >> 6) & 0x3) {
15847                case ADD_FMT:
15848                    FINSN_3ARG_SDPS(ADD);
15849                    break;
15850                case SUB_FMT:
15851                    FINSN_3ARG_SDPS(SUB);
15852                    break;
15853                case MUL_FMT:
15854                    FINSN_3ARG_SDPS(MUL);
15855                    break;
15856                case DIV_FMT:
15857                    fmt = (ctx->opcode >> 8) & 0x3;
15858                    if (fmt == 1) {
15859                        mips32_op = OPC_DIV_D;
15860                    } else if (fmt == 0) {
15861                        mips32_op = OPC_DIV_S;
15862                    } else {
15863                        goto pool32f_invalid;
15864                    }
15865                    goto do_fpop;
15866                default:
15867                    goto pool32f_invalid;
15868                }
15869                break;
15870            case 0x38:
15871                /* cmovs */
15872                switch ((ctx->opcode >> 6) & 0x7) {
15873                case MOVN_FMT: /* SELEQZ_FMT */
15874                    if (ctx->insn_flags & ISA_MIPS_R6) {
15875                        /* SELEQZ_FMT */
15876                        switch ((ctx->opcode >> 9) & 0x3) {
15877                        case FMT_SDPS_S:
15878                            gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
15879                            break;
15880                        case FMT_SDPS_D:
15881                            gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
15882                            break;
15883                        default:
15884                            goto pool32f_invalid;
15885                        }
15886                    } else {
15887                        /* MOVN_FMT */
15888                        FINSN_3ARG_SDPS(MOVN);
15889                    }
15890                    break;
15891                case MOVN_FMT_04:
15892                    check_insn_opc_removed(ctx, ISA_MIPS_R6);
15893                    FINSN_3ARG_SDPS(MOVN);
15894                    break;
15895                case MOVZ_FMT: /* SELNEZ_FMT */
15896                    if (ctx->insn_flags & ISA_MIPS_R6) {
15897                        /* SELNEZ_FMT */
15898                        switch ((ctx->opcode >> 9) & 0x3) {
15899                        case FMT_SDPS_S:
15900                            gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
15901                            break;
15902                        case FMT_SDPS_D:
15903                            gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
15904                            break;
15905                        default:
15906                            goto pool32f_invalid;
15907                        }
15908                    } else {
15909                        /* MOVZ_FMT */
15910                        FINSN_3ARG_SDPS(MOVZ);
15911                    }
15912                    break;
15913                case MOVZ_FMT_05:
15914                    check_insn_opc_removed(ctx, ISA_MIPS_R6);
15915                    FINSN_3ARG_SDPS(MOVZ);
15916                    break;
15917                case SEL_FMT:
15918                    check_insn(ctx, ISA_MIPS_R6);
15919                    switch ((ctx->opcode >> 9) & 0x3) {
15920                    case FMT_SDPS_S:
15921                        gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
15922                        break;
15923                    case FMT_SDPS_D:
15924                        gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
15925                        break;
15926                    default:
15927                        goto pool32f_invalid;
15928                    }
15929                    break;
15930                case MADDF_FMT:
15931                    check_insn(ctx, ISA_MIPS_R6);
15932                    switch ((ctx->opcode >> 9) & 0x3) {
15933                    case FMT_SDPS_S:
15934                        mips32_op = OPC_MADDF_S;
15935                        goto do_fpop;
15936                    case FMT_SDPS_D:
15937                        mips32_op = OPC_MADDF_D;
15938                        goto do_fpop;
15939                    default:
15940                        goto pool32f_invalid;
15941                    }
15942                    break;
15943                case MSUBF_FMT:
15944                    check_insn(ctx, ISA_MIPS_R6);
15945                    switch ((ctx->opcode >> 9) & 0x3) {
15946                    case FMT_SDPS_S:
15947                        mips32_op = OPC_MSUBF_S;
15948                        goto do_fpop;
15949                    case FMT_SDPS_D:
15950                        mips32_op = OPC_MSUBF_D;
15951                        goto do_fpop;
15952                    default:
15953                        goto pool32f_invalid;
15954                    }
15955                    break;
15956                default:
15957                    goto pool32f_invalid;
15958                }
15959                break;
15960            do_fpop:
15961                gen_farith(ctx, mips32_op, rt, rs, rd, 0);
15962                break;
15963            default:
15964            pool32f_invalid:
15965                MIPS_INVAL("pool32f");
15966                gen_reserved_instruction(ctx);
15967                break;
15968            }
15969        } else {
15970            generate_exception_err(ctx, EXCP_CpU, 1);
15971        }
15972        break;
15973    case POOL32I:
15974        minor = (ctx->opcode >> 21) & 0x1f;
15975        switch (minor) {
15976        case BLTZ:
15977            check_insn_opc_removed(ctx, ISA_MIPS_R6);
15978            gen_compute_branch(ctx, OPC_BLTZ, 4, rs, -1, imm << 1, 4);
15979            break;
15980        case BLTZAL:
15981            check_insn_opc_removed(ctx, ISA_MIPS_R6);
15982            gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 4);
15983            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15984            break;
15985        case BLTZALS:
15986            check_insn_opc_removed(ctx, ISA_MIPS_R6);
15987            gen_compute_branch(ctx, OPC_BLTZAL, 4, rs, -1, imm << 1, 2);
15988            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15989            break;
15990        case BGEZ:
15991            check_insn_opc_removed(ctx, ISA_MIPS_R6);
15992            gen_compute_branch(ctx, OPC_BGEZ, 4, rs, -1, imm << 1, 4);
15993            break;
15994        case BGEZAL:
15995            check_insn_opc_removed(ctx, ISA_MIPS_R6);
15996            gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 4);
15997            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
15998            break;
15999        case BGEZALS:
16000            check_insn_opc_removed(ctx, ISA_MIPS_R6);
16001            gen_compute_branch(ctx, OPC_BGEZAL, 4, rs, -1, imm << 1, 2);
16002            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16003            break;
16004        case BLEZ:
16005            check_insn_opc_removed(ctx, ISA_MIPS_R6);
16006            gen_compute_branch(ctx, OPC_BLEZ, 4, rs, -1, imm << 1, 4);
16007            break;
16008        case BGTZ:
16009            check_insn_opc_removed(ctx, ISA_MIPS_R6);
16010            gen_compute_branch(ctx, OPC_BGTZ, 4, rs, -1, imm << 1, 4);
16011            break;
16012
16013            /* Traps */
16014        case TLTI: /* BC1EQZC */
16015            if (ctx->insn_flags & ISA_MIPS_R6) {
16016                /* BC1EQZC */
16017                check_cp1_enabled(ctx);
16018                gen_compute_branch1_r6(ctx, OPC_BC1EQZ, rs, imm << 1, 0);
16019            } else {
16020                /* TLTI */
16021                mips32_op = OPC_TLTI;
16022                goto do_trapi;
16023            }
16024            break;
16025        case TGEI: /* BC1NEZC */
16026            if (ctx->insn_flags & ISA_MIPS_R6) {
16027                /* BC1NEZC */
16028                check_cp1_enabled(ctx);
16029                gen_compute_branch1_r6(ctx, OPC_BC1NEZ, rs, imm << 1, 0);
16030            } else {
16031                /* TGEI */
16032                mips32_op = OPC_TGEI;
16033                goto do_trapi;
16034            }
16035            break;
16036        case TLTIU:
16037            check_insn_opc_removed(ctx, ISA_MIPS_R6);
16038            mips32_op = OPC_TLTIU;
16039            goto do_trapi;
16040        case TGEIU:
16041            check_insn_opc_removed(ctx, ISA_MIPS_R6);
16042            mips32_op = OPC_TGEIU;
16043            goto do_trapi;
16044        case TNEI: /* SYNCI */
16045            if (ctx->insn_flags & ISA_MIPS_R6) {
16046                /* SYNCI */
16047                /*
16048                 * Break the TB to be able to sync copied instructions
16049                 * immediately.
16050                 */
16051                ctx->base.is_jmp = DISAS_STOP;
16052            } else {
16053                /* TNEI */
16054                mips32_op = OPC_TNEI;
16055                goto do_trapi;
16056            }
16057            break;
16058        case TEQI:
16059            check_insn_opc_removed(ctx, ISA_MIPS_R6);
16060            mips32_op = OPC_TEQI;
16061        do_trapi:
16062            gen_trap(ctx, mips32_op, rs, -1, imm);
16063            break;
16064
16065        case BNEZC:
16066        case BEQZC:
16067            check_insn_opc_removed(ctx, ISA_MIPS_R6);
16068            gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
16069                               4, rs, 0, imm << 1, 0);
16070            /*
16071             * Compact branches don't have a delay slot, so just let
16072             * the normal delay slot handling take us to the branch
16073             * target.
16074             */
16075            break;
16076        case LUI:
16077            check_insn_opc_removed(ctx, ISA_MIPS_R6);
16078            gen_logic_imm(ctx, OPC_LUI, rs, 0, imm);
16079            break;
16080        case SYNCI:
16081            check_insn_opc_removed(ctx, ISA_MIPS_R6);
16082            /*
16083             * Break the TB to be able to sync copied instructions
16084             * immediately.
16085             */
16086            ctx->base.is_jmp = DISAS_STOP;
16087            break;
16088        case BC2F:
16089        case BC2T:
16090            check_insn_opc_removed(ctx, ISA_MIPS_R6);
16091            /* COP2: Not implemented. */
16092            generate_exception_err(ctx, EXCP_CpU, 2);
16093            break;
16094        case BC1F:
16095            check_insn_opc_removed(ctx, ISA_MIPS_R6);
16096            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
16097            goto do_cp1branch;
16098        case BC1T:
16099            check_insn_opc_removed(ctx, ISA_MIPS_R6);
16100            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
16101            goto do_cp1branch;
16102        case BC1ANY4F:
16103            check_insn_opc_removed(ctx, ISA_MIPS_R6);
16104            mips32_op = OPC_BC1FANY4;
16105            goto do_cp1mips3d;
16106        case BC1ANY4T:
16107            check_insn_opc_removed(ctx, ISA_MIPS_R6);
16108            mips32_op = OPC_BC1TANY4;
16109        do_cp1mips3d:
16110            check_cop1x(ctx);
16111            check_insn(ctx, ASE_MIPS3D);
16112            /* Fall through */
16113        do_cp1branch:
16114            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
16115                check_cp1_enabled(ctx);
16116                gen_compute_branch1(ctx, mips32_op,
16117                                    (ctx->opcode >> 18) & 0x7, imm << 1);
16118            } else {
16119                generate_exception_err(ctx, EXCP_CpU, 1);
16120            }
16121            break;
16122        case BPOSGE64:
16123        case BPOSGE32:
16124            /* MIPS DSP: not implemented */
16125            /* Fall through */
16126        default:
16127            MIPS_INVAL("pool32i");
16128            gen_reserved_instruction(ctx);
16129            break;
16130        }
16131        break;
16132    case POOL32C:
16133        minor = (ctx->opcode >> 12) & 0xf;
16134        offset = sextract32(ctx->opcode, 0,
16135                            (ctx->insn_flags & ISA_MIPS_R6) ? 9 : 12);
16136        switch (minor) {
16137        case LWL:
16138            check_insn_opc_removed(ctx, ISA_MIPS_R6);
16139            mips32_op = OPC_LWL;
16140            goto do_ld_lr;
16141        case SWL:
16142            check_insn_opc_removed(ctx, ISA_MIPS_R6);
16143            mips32_op = OPC_SWL;
16144            goto do_st_lr;
16145        case LWR:
16146            check_insn_opc_removed(ctx, ISA_MIPS_R6);
16147            mips32_op = OPC_LWR;
16148            goto do_ld_lr;
16149        case SWR:
16150            check_insn_opc_removed(ctx, ISA_MIPS_R6);
16151            mips32_op = OPC_SWR;
16152            goto do_st_lr;
16153#if defined(TARGET_MIPS64)
16154        case LDL:
16155            check_insn(ctx, ISA_MIPS3);
16156            check_mips_64(ctx);
16157            check_insn_opc_removed(ctx, ISA_MIPS_R6);
16158            mips32_op = OPC_LDL;
16159            goto do_ld_lr;
16160        case SDL:
16161            check_insn(ctx, ISA_MIPS3);
16162            check_mips_64(ctx);
16163            check_insn_opc_removed(ctx, ISA_MIPS_R6);
16164            mips32_op = OPC_SDL;
16165            goto do_st_lr;
16166        case LDR:
16167            check_insn(ctx, ISA_MIPS3);
16168            check_mips_64(ctx);
16169            check_insn_opc_removed(ctx, ISA_MIPS_R6);
16170            mips32_op = OPC_LDR;
16171            goto do_ld_lr;
16172        case SDR:
16173            check_insn(ctx, ISA_MIPS3);
16174            check_mips_64(ctx);
16175            check_insn_opc_removed(ctx, ISA_MIPS_R6);
16176            mips32_op = OPC_SDR;
16177            goto do_st_lr;
16178        case LWU:
16179            check_insn(ctx, ISA_MIPS3);
16180            check_mips_64(ctx);
16181            mips32_op = OPC_LWU;
16182            goto do_ld_lr;
16183        case LLD:
16184            check_insn(ctx, ISA_MIPS3);
16185            check_mips_64(ctx);
16186            mips32_op = OPC_LLD;
16187            goto do_ld_lr;
16188#endif
16189        case LL:
16190            mips32_op = OPC_LL;
16191            goto do_ld_lr;
16192        do_ld_lr:
16193            gen_ld(ctx, mips32_op, rt, rs, offset);
16194            break;
16195        do_st_lr:
16196            gen_st(ctx, mips32_op, rt, rs, offset);
16197            break;
16198        case SC:
16199            gen_st_cond(ctx, rt, rs, offset, MO_TESL, false);
16200            break;
16201#if defined(TARGET_MIPS64)
16202        case SCD:
16203            check_insn(ctx, ISA_MIPS3);
16204            check_mips_64(ctx);
16205            gen_st_cond(ctx, rt, rs, offset, MO_TEQ, false);
16206            break;
16207#endif
16208        case LD_EVA:
16209            if (!ctx->eva) {
16210                MIPS_INVAL("pool32c ld-eva");
16211                gen_reserved_instruction(ctx);
16212                break;
16213            }
16214            check_cp0_enabled(ctx);
16215
16216            minor2 = (ctx->opcode >> 9) & 0x7;
16217            offset = sextract32(ctx->opcode, 0, 9);
16218            switch (minor2) {
16219            case LBUE:
16220                mips32_op = OPC_LBUE;
16221                goto do_ld_lr;
16222            case LHUE:
16223                mips32_op = OPC_LHUE;
16224                goto do_ld_lr;
16225            case LWLE:
16226                check_insn_opc_removed(ctx, ISA_MIPS_R6);
16227                mips32_op = OPC_LWLE;
16228                goto do_ld_lr;
16229            case LWRE:
16230                check_insn_opc_removed(ctx, ISA_MIPS_R6);
16231                mips32_op = OPC_LWRE;
16232                goto do_ld_lr;
16233            case LBE:
16234                mips32_op = OPC_LBE;
16235                goto do_ld_lr;
16236            case LHE:
16237                mips32_op = OPC_LHE;
16238                goto do_ld_lr;
16239            case LLE:
16240                mips32_op = OPC_LLE;
16241                goto do_ld_lr;
16242            case LWE:
16243                mips32_op = OPC_LWE;
16244                goto do_ld_lr;
16245            };
16246            break;
16247        case ST_EVA:
16248            if (!ctx->eva) {
16249                MIPS_INVAL("pool32c st-eva");
16250                gen_reserved_instruction(ctx);
16251                break;
16252            }
16253            check_cp0_enabled(ctx);
16254
16255            minor2 = (ctx->opcode >> 9) & 0x7;
16256            offset = sextract32(ctx->opcode, 0, 9);
16257            switch (minor2) {
16258            case SWLE:
16259                check_insn_opc_removed(ctx, ISA_MIPS_R6);
16260                mips32_op = OPC_SWLE;
16261                goto do_st_lr;
16262            case SWRE:
16263                check_insn_opc_removed(ctx, ISA_MIPS_R6);
16264                mips32_op = OPC_SWRE;
16265                goto do_st_lr;
16266            case PREFE:
16267                /* Treat as no-op */
16268                if ((ctx->insn_flags & ISA_MIPS_R6) && (rt >= 24)) {
16269                    /* hint codes 24-31 are reserved and signal RI */
16270                    generate_exception(ctx, EXCP_RI);
16271                }
16272                break;
16273            case CACHEE:
16274                /* Treat as no-op */
16275                if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
16276                    gen_cache_operation(ctx, rt, rs, offset);
16277                }
16278                break;
16279            case SBE:
16280                mips32_op = OPC_SBE;
16281                goto do_st_lr;
16282            case SHE:
16283                mips32_op = OPC_SHE;
16284                goto do_st_lr;
16285            case SCE:
16286                gen_st_cond(ctx, rt, rs, offset, MO_TESL, true);
16287                break;
16288            case SWE:
16289                mips32_op = OPC_SWE;
16290                goto do_st_lr;
16291            };
16292            break;
16293        case PREF:
16294            /* Treat as no-op */
16295            if ((ctx->insn_flags & ISA_MIPS_R6) && (rt >= 24)) {
16296                /* hint codes 24-31 are reserved and signal RI */
16297                generate_exception(ctx, EXCP_RI);
16298            }
16299            break;
16300        default:
16301            MIPS_INVAL("pool32c");
16302            gen_reserved_instruction(ctx);
16303            break;
16304        }
16305        break;
16306    case ADDI32: /* AUI, LUI */
16307        if (ctx->insn_flags & ISA_MIPS_R6) {
16308            /* AUI, LUI */
16309            gen_logic_imm(ctx, OPC_LUI, rt, rs, imm);
16310        } else {
16311            /* ADDI32 */
16312            mips32_op = OPC_ADDI;
16313            goto do_addi;
16314        }
16315        break;
16316    case ADDIU32:
16317        mips32_op = OPC_ADDIU;
16318    do_addi:
16319        gen_arith_imm(ctx, mips32_op, rt, rs, imm);
16320        break;
16321
16322        /* Logical operations */
16323    case ORI32:
16324        mips32_op = OPC_ORI;
16325        goto do_logici;
16326    case XORI32:
16327        mips32_op = OPC_XORI;
16328        goto do_logici;
16329    case ANDI32:
16330        mips32_op = OPC_ANDI;
16331    do_logici:
16332        gen_logic_imm(ctx, mips32_op, rt, rs, imm);
16333        break;
16334
16335        /* Set less than immediate */
16336    case SLTI32:
16337        mips32_op = OPC_SLTI;
16338        goto do_slti;
16339    case SLTIU32:
16340        mips32_op = OPC_SLTIU;
16341    do_slti:
16342        gen_slt_imm(ctx, mips32_op, rt, rs, imm);
16343        break;
16344    case JALX32:
16345        check_insn_opc_removed(ctx, ISA_MIPS_R6);
16346        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
16347        gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset, 4);
16348        ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16349        break;
16350    case JALS32: /* BOVC, BEQC, BEQZALC */
16351        if (ctx->insn_flags & ISA_MIPS_R6) {
16352            if (rs >= rt) {
16353                /* BOVC */
16354                mips32_op = OPC_BOVC;
16355            } else if (rs < rt && rs == 0) {
16356                /* BEQZALC */
16357                mips32_op = OPC_BEQZALC;
16358            } else {
16359                /* BEQC */
16360                mips32_op = OPC_BEQC;
16361            }
16362            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16363        } else {
16364            /* JALS32 */
16365            offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
16366            gen_compute_branch(ctx, OPC_JAL, 4, rt, rs, offset, 2);
16367            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16368        }
16369        break;
16370    case BEQ32: /* BC */
16371        if (ctx->insn_flags & ISA_MIPS_R6) {
16372            /* BC */
16373            gen_compute_compact_branch(ctx, OPC_BC, 0, 0,
16374                                       sextract32(ctx->opcode << 1, 0, 27));
16375        } else {
16376            /* BEQ32 */
16377            gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1, 4);
16378        }
16379        break;
16380    case BNE32: /* BALC */
16381        if (ctx->insn_flags & ISA_MIPS_R6) {
16382            /* BALC */
16383            gen_compute_compact_branch(ctx, OPC_BALC, 0, 0,
16384                                       sextract32(ctx->opcode << 1, 0, 27));
16385        } else {
16386            /* BNE32 */
16387            gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1, 4);
16388        }
16389        break;
16390    case J32: /* BGTZC, BLTZC, BLTC */
16391        if (ctx->insn_flags & ISA_MIPS_R6) {
16392            if (rs == 0 && rt != 0) {
16393                /* BGTZC */
16394                mips32_op = OPC_BGTZC;
16395            } else if (rs != 0 && rt != 0 && rs == rt) {
16396                /* BLTZC */
16397                mips32_op = OPC_BLTZC;
16398            } else {
16399                /* BLTC */
16400                mips32_op = OPC_BLTC;
16401            }
16402            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16403        } else {
16404            /* J32 */
16405            gen_compute_branch(ctx, OPC_J, 4, rt, rs,
16406                               (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16407        }
16408        break;
16409    case JAL32: /* BLEZC, BGEZC, BGEC */
16410        if (ctx->insn_flags & ISA_MIPS_R6) {
16411            if (rs == 0 && rt != 0) {
16412                /* BLEZC */
16413                mips32_op = OPC_BLEZC;
16414            } else if (rs != 0 && rt != 0 && rs == rt) {
16415                /* BGEZC */
16416                mips32_op = OPC_BGEZC;
16417            } else {
16418                /* BGEC */
16419                mips32_op = OPC_BGEC;
16420            }
16421            gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16422        } else {
16423            /* JAL32 */
16424            gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
16425                               (int32_t)(ctx->opcode & 0x3FFFFFF) << 1, 4);
16426            ctx->hflags |= MIPS_HFLAG_BDS_STRICT;
16427        }
16428        break;
16429        /* Floating point (COP1) */
16430    case LWC132:
16431        mips32_op = OPC_LWC1;
16432        goto do_cop1;
16433    case LDC132:
16434        mips32_op = OPC_LDC1;
16435        goto do_cop1;
16436    case SWC132:
16437        mips32_op = OPC_SWC1;
16438        goto do_cop1;
16439    case SDC132:
16440        mips32_op = OPC_SDC1;
16441    do_cop1:
16442        gen_cop1_ldst(ctx, mips32_op, rt, rs, imm);
16443        break;
16444    case ADDIUPC: /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16445        if (ctx->insn_flags & ISA_MIPS_R6) {
16446            /* PCREL: ADDIUPC, AUIPC, ALUIPC, LWPC */
16447            switch ((ctx->opcode >> 16) & 0x1f) {
16448            case ADDIUPC_00:
16449            case ADDIUPC_01:
16450            case ADDIUPC_02:
16451            case ADDIUPC_03:
16452            case ADDIUPC_04:
16453            case ADDIUPC_05:
16454            case ADDIUPC_06:
16455            case ADDIUPC_07:
16456                gen_pcrel(ctx, OPC_ADDIUPC, ctx->base.pc_next & ~0x3, rt);
16457                break;
16458            case AUIPC:
16459                gen_pcrel(ctx, OPC_AUIPC, ctx->base.pc_next, rt);
16460                break;
16461            case ALUIPC:
16462                gen_pcrel(ctx, OPC_ALUIPC, ctx->base.pc_next, rt);
16463                break;
16464            case LWPC_08:
16465            case LWPC_09:
16466            case LWPC_0A:
16467            case LWPC_0B:
16468            case LWPC_0C:
16469            case LWPC_0D:
16470            case LWPC_0E:
16471            case LWPC_0F:
16472                gen_pcrel(ctx, R6_OPC_LWPC, ctx->base.pc_next & ~0x3, rt);
16473                break;
16474            default:
16475                generate_exception(ctx, EXCP_RI);
16476                break;
16477            }
16478        } else {
16479            /* ADDIUPC */
16480            int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
16481            offset = SIMM(ctx->opcode, 0, 23) << 2;
16482
16483            gen_addiupc(ctx, reg, offset, 0, 0);
16484        }
16485        break;
16486    case BNVC: /* BNEC, BNEZALC */
16487        check_insn(ctx, ISA_MIPS_R6);
16488        if (rs >= rt) {
16489            /* BNVC */
16490            mips32_op = OPC_BNVC;
16491        } else if (rs < rt && rs == 0) {
16492            /* BNEZALC */
16493            mips32_op = OPC_BNEZALC;
16494        } else {
16495            /* BNEC */
16496            mips32_op = OPC_BNEC;
16497        }
16498        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16499        break;
16500    case R6_BNEZC: /* JIALC */
16501        check_insn(ctx, ISA_MIPS_R6);
16502        if (rt != 0) {
16503            /* BNEZC */
16504            gen_compute_compact_branch(ctx, OPC_BNEZC, rt, 0,
16505                                       sextract32(ctx->opcode << 1, 0, 22));
16506        } else {
16507            /* JIALC */
16508            gen_compute_compact_branch(ctx, OPC_JIALC, 0, rs, imm);
16509        }
16510        break;
16511    case R6_BEQZC: /* JIC */
16512        check_insn(ctx, ISA_MIPS_R6);
16513        if (rt != 0) {
16514            /* BEQZC */
16515            gen_compute_compact_branch(ctx, OPC_BEQZC, rt, 0,
16516                                       sextract32(ctx->opcode << 1, 0, 22));
16517        } else {
16518            /* JIC */
16519            gen_compute_compact_branch(ctx, OPC_JIC, 0, rs, imm);
16520        }
16521        break;
16522    case BLEZALC: /* BGEZALC, BGEUC */
16523        check_insn(ctx, ISA_MIPS_R6);
16524        if (rs == 0 && rt != 0) {
16525            /* BLEZALC */
16526            mips32_op = OPC_BLEZALC;
16527        } else if (rs != 0 && rt != 0 && rs == rt) {
16528            /* BGEZALC */
16529            mips32_op = OPC_BGEZALC;
16530        } else {
16531            /* BGEUC */
16532            mips32_op = OPC_BGEUC;
16533        }
16534        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16535        break;
16536    case BGTZALC: /* BLTZALC, BLTUC */
16537        check_insn(ctx, ISA_MIPS_R6);
16538        if (rs == 0 && rt != 0) {
16539            /* BGTZALC */
16540            mips32_op = OPC_BGTZALC;
16541        } else if (rs != 0 && rt != 0 && rs == rt) {
16542            /* BLTZALC */
16543            mips32_op = OPC_BLTZALC;
16544        } else {
16545            /* BLTUC */
16546            mips32_op = OPC_BLTUC;
16547        }
16548        gen_compute_compact_branch(ctx, mips32_op, rs, rt, imm << 1);
16549        break;
16550        /* Loads and stores */
16551    case LB32:
16552        mips32_op = OPC_LB;
16553        goto do_ld;
16554    case LBU32:
16555        mips32_op = OPC_LBU;
16556        goto do_ld;
16557    case LH32:
16558        mips32_op = OPC_LH;
16559        goto do_ld;
16560    case LHU32:
16561        mips32_op = OPC_LHU;
16562        goto do_ld;
16563    case LW32:
16564        mips32_op = OPC_LW;
16565        goto do_ld;
16566#ifdef TARGET_MIPS64
16567    case LD32:
16568        check_insn(ctx, ISA_MIPS3);
16569        check_mips_64(ctx);
16570        mips32_op = OPC_LD;
16571        goto do_ld;
16572    case SD32:
16573        check_insn(ctx, ISA_MIPS3);
16574        check_mips_64(ctx);
16575        mips32_op = OPC_SD;
16576        goto do_st;
16577#endif
16578    case SB32:
16579        mips32_op = OPC_SB;
16580        goto do_st;
16581    case SH32:
16582        mips32_op = OPC_SH;
16583        goto do_st;
16584    case SW32:
16585        mips32_op = OPC_SW;
16586        goto do_st;
16587    do_ld:
16588        gen_ld(ctx, mips32_op, rt, rs, imm);
16589        break;
16590    do_st:
16591        gen_st(ctx, mips32_op, rt, rs, imm);
16592        break;
16593    default:
16594        gen_reserved_instruction(ctx);
16595        break;
16596    }
16597}
16598
16599static int decode_micromips_opc(CPUMIPSState *env, DisasContext *ctx)
16600{
16601    uint32_t op;
16602
16603    /* make sure instructions are on a halfword boundary */
16604    if (ctx->base.pc_next & 0x1) {
16605        env->CP0_BadVAddr = ctx->base.pc_next;
16606        generate_exception_end(ctx, EXCP_AdEL);
16607        return 2;
16608    }
16609
16610    op = (ctx->opcode >> 10) & 0x3f;
16611    /* Enforce properly-sized instructions in a delay slot */
16612    if (ctx->hflags & MIPS_HFLAG_BDS_STRICT) {
16613        switch (op & 0x7) { /* MSB-3..MSB-5 */
16614        case 0:
16615        /* POOL32A, POOL32B, POOL32I, POOL32C */
16616        case 4:
16617        /* ADDI32, ADDIU32, ORI32, XORI32, SLTI32, SLTIU32, ANDI32, JALX32 */
16618        case 5:
16619        /* LBU32, LHU32, POOL32F, JALS32, BEQ32, BNE32, J32, JAL32 */
16620        case 6:
16621        /* SB32, SH32, ADDIUPC, SWC132, SDC132, SW32 */
16622        case 7:
16623        /* LB32, LH32, LWC132, LDC132, LW32 */
16624            if (ctx->hflags & MIPS_HFLAG_BDS16) {
16625                gen_reserved_instruction(ctx);
16626                return 2;
16627            }
16628            break;
16629        case 1:
16630        /* POOL16A, POOL16B, POOL16C, LWGP16, POOL16F */
16631        case 2:
16632        /* LBU16, LHU16, LWSP16, LW16, SB16, SH16, SWSP16, SW16 */
16633        case 3:
16634        /* MOVE16, ANDI16, POOL16D, POOL16E, BEQZ16, BNEZ16, B16, LI16 */
16635            if (ctx->hflags & MIPS_HFLAG_BDS32) {
16636                gen_reserved_instruction(ctx);
16637                return 2;
16638            }
16639            break;
16640        }
16641    }
16642
16643    switch (op) {
16644    case POOL16A:
16645        {
16646            int rd = mmreg(uMIPS_RD(ctx->opcode));
16647            int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
16648            int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
16649            uint32_t opc = 0;
16650
16651            switch (ctx->opcode & 0x1) {
16652            case ADDU16:
16653                opc = OPC_ADDU;
16654                break;
16655            case SUBU16:
16656                opc = OPC_SUBU;
16657                break;
16658            }
16659            if (ctx->insn_flags & ISA_MIPS_R6) {
16660                /*
16661                 * In the Release 6, the register number location in
16662                 * the instruction encoding has changed.
16663                 */
16664                gen_arith(ctx, opc, rs1, rd, rs2);
16665            } else {
16666                gen_arith(ctx, opc, rd, rs1, rs2);
16667            }
16668        }
16669        break;
16670    case POOL16B:
16671        {
16672            int rd = mmreg(uMIPS_RD(ctx->opcode));
16673            int rs = mmreg(uMIPS_RS(ctx->opcode));
16674            int amount = (ctx->opcode >> 1) & 0x7;
16675            uint32_t opc = 0;
16676            amount = amount == 0 ? 8 : amount;
16677
16678            switch (ctx->opcode & 0x1) {
16679            case SLL16:
16680                opc = OPC_SLL;
16681                break;
16682            case SRL16:
16683                opc = OPC_SRL;
16684                break;
16685            }
16686
16687            gen_shift_imm(ctx, opc, rd, rs, amount);
16688        }
16689        break;
16690    case POOL16C:
16691        if (ctx->insn_flags & ISA_MIPS_R6) {
16692            gen_pool16c_r6_insn(ctx);
16693        } else {
16694            gen_pool16c_insn(ctx);
16695        }
16696        break;
16697    case LWGP16:
16698        {
16699            int rd = mmreg(uMIPS_RD(ctx->opcode));
16700            int rb = 28;            /* GP */
16701            int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
16702
16703            gen_ld(ctx, OPC_LW, rd, rb, offset);
16704        }
16705        break;
16706    case POOL16F:
16707        check_insn_opc_removed(ctx, ISA_MIPS_R6);
16708        if (ctx->opcode & 1) {
16709            gen_reserved_instruction(ctx);
16710        } else {
16711            /* MOVEP */
16712            int enc_dest = uMIPS_RD(ctx->opcode);
16713            int enc_rt = uMIPS_RS2(ctx->opcode);
16714            int enc_rs = uMIPS_RS1(ctx->opcode);
16715            gen_movep(ctx, enc_dest, enc_rt, enc_rs);
16716        }
16717        break;
16718    case LBU16:
16719        {
16720            int rd = mmreg(uMIPS_RD(ctx->opcode));
16721            int rb = mmreg(uMIPS_RS(ctx->opcode));
16722            int16_t offset = ZIMM(ctx->opcode, 0, 4);
16723            offset = (offset == 0xf ? -1 : offset);
16724
16725            gen_ld(ctx, OPC_LBU, rd, rb, offset);
16726        }
16727        break;
16728    case LHU16:
16729        {
16730            int rd = mmreg(uMIPS_RD(ctx->opcode));
16731            int rb = mmreg(uMIPS_RS(ctx->opcode));
16732            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
16733
16734            gen_ld(ctx, OPC_LHU, rd, rb, offset);
16735        }
16736        break;
16737    case LWSP16:
16738        {
16739            int rd = (ctx->opcode >> 5) & 0x1f;
16740            int rb = 29;            /* SP */
16741            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
16742
16743            gen_ld(ctx, OPC_LW, rd, rb, offset);
16744        }
16745        break;
16746    case LW16:
16747        {
16748            int rd = mmreg(uMIPS_RD(ctx->opcode));
16749            int rb = mmreg(uMIPS_RS(ctx->opcode));
16750            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
16751
16752            gen_ld(ctx, OPC_LW, rd, rb, offset);
16753        }
16754        break;
16755    case SB16:
16756        {
16757            int rd = mmreg2(uMIPS_RD(ctx->opcode));
16758            int rb = mmreg(uMIPS_RS(ctx->opcode));
16759            int16_t offset = ZIMM(ctx->opcode, 0, 4);
16760
16761            gen_st(ctx, OPC_SB, rd, rb, offset);
16762        }
16763        break;
16764    case SH16:
16765        {
16766            int rd = mmreg2(uMIPS_RD(ctx->opcode));
16767            int rb = mmreg(uMIPS_RS(ctx->opcode));
16768            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
16769
16770            gen_st(ctx, OPC_SH, rd, rb, offset);
16771        }
16772        break;
16773    case SWSP16:
16774        {
16775            int rd = (ctx->opcode >> 5) & 0x1f;
16776            int rb = 29;            /* SP */
16777            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
16778
16779            gen_st(ctx, OPC_SW, rd, rb, offset);
16780        }
16781        break;
16782    case SW16:
16783        {
16784            int rd = mmreg2(uMIPS_RD(ctx->opcode));
16785            int rb = mmreg(uMIPS_RS(ctx->opcode));
16786            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
16787
16788            gen_st(ctx, OPC_SW, rd, rb, offset);
16789        }
16790        break;
16791    case MOVE16:
16792        {
16793            int rd = uMIPS_RD5(ctx->opcode);
16794            int rs = uMIPS_RS5(ctx->opcode);
16795
16796            gen_arith(ctx, OPC_ADDU, rd, rs, 0);
16797        }
16798        break;
16799    case ANDI16:
16800        gen_andi16(ctx);
16801        break;
16802    case POOL16D:
16803        switch (ctx->opcode & 0x1) {
16804        case ADDIUS5:
16805            gen_addius5(ctx);
16806            break;
16807        case ADDIUSP:
16808            gen_addiusp(ctx);
16809            break;
16810        }
16811        break;
16812    case POOL16E:
16813        switch (ctx->opcode & 0x1) {
16814        case ADDIUR2:
16815            gen_addiur2(ctx);
16816            break;
16817        case ADDIUR1SP:
16818            gen_addiur1sp(ctx);
16819            break;
16820        }
16821        break;
16822    case B16: /* BC16 */
16823        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
16824                           sextract32(ctx->opcode, 0, 10) << 1,
16825                           (ctx->insn_flags & ISA_MIPS_R6) ? 0 : 4);
16826        break;
16827    case BNEZ16: /* BNEZC16 */
16828    case BEQZ16: /* BEQZC16 */
16829        gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
16830                           mmreg(uMIPS_RD(ctx->opcode)),
16831                           0, sextract32(ctx->opcode, 0, 7) << 1,
16832                           (ctx->insn_flags & ISA_MIPS_R6) ? 0 : 4);
16833
16834        break;
16835    case LI16:
16836        {
16837            int reg = mmreg(uMIPS_RD(ctx->opcode));
16838            int imm = ZIMM(ctx->opcode, 0, 7);
16839
16840            imm = (imm == 0x7f ? -1 : imm);
16841            tcg_gen_movi_tl(cpu_gpr[reg], imm);
16842        }
16843        break;
16844    case RES_29:
16845    case RES_31:
16846    case RES_39:
16847        gen_reserved_instruction(ctx);
16848        break;
16849    default:
16850        decode_micromips32_opc(env, ctx);
16851        return 4;
16852    }
16853
16854    return 2;
16855}
16856
16857/*
16858 *
16859 * nanoMIPS opcodes
16860 *
16861 */
16862
16863/* MAJOR, P16, and P32 pools opcodes */
16864enum {
16865    NM_P_ADDIU      = 0x00,
16866    NM_ADDIUPC      = 0x01,
16867    NM_MOVE_BALC    = 0x02,
16868    NM_P16_MV       = 0x04,
16869    NM_LW16         = 0x05,
16870    NM_BC16         = 0x06,
16871    NM_P16_SR       = 0x07,
16872
16873    NM_POOL32A      = 0x08,
16874    NM_P_BAL        = 0x0a,
16875    NM_P16_SHIFT    = 0x0c,
16876    NM_LWSP16       = 0x0d,
16877    NM_BALC16       = 0x0e,
16878    NM_P16_4X4      = 0x0f,
16879
16880    NM_P_GP_W       = 0x10,
16881    NM_P_GP_BH      = 0x11,
16882    NM_P_J          = 0x12,
16883    NM_P16C         = 0x14,
16884    NM_LWGP16       = 0x15,
16885    NM_P16_LB       = 0x17,
16886
16887    NM_P48I         = 0x18,
16888    NM_P16_A1       = 0x1c,
16889    NM_LW4X4        = 0x1d,
16890    NM_P16_LH       = 0x1f,
16891
16892    NM_P_U12        = 0x20,
16893    NM_P_LS_U12     = 0x21,
16894    NM_P_BR1        = 0x22,
16895    NM_P16_A2       = 0x24,
16896    NM_SW16         = 0x25,
16897    NM_BEQZC16      = 0x26,
16898
16899    NM_POOL32F      = 0x28,
16900    NM_P_LS_S9      = 0x29,
16901    NM_P_BR2        = 0x2a,
16902
16903    NM_P16_ADDU     = 0x2c,
16904    NM_SWSP16       = 0x2d,
16905    NM_BNEZC16      = 0x2e,
16906    NM_MOVEP        = 0x2f,
16907
16908    NM_POOL32S      = 0x30,
16909    NM_P_BRI        = 0x32,
16910    NM_LI16         = 0x34,
16911    NM_SWGP16       = 0x35,
16912    NM_P16_BR       = 0x36,
16913
16914    NM_P_LUI        = 0x38,
16915    NM_ANDI16       = 0x3c,
16916    NM_SW4X4        = 0x3d,
16917    NM_MOVEPREV     = 0x3f,
16918};
16919
16920/* POOL32A instruction pool */
16921enum {
16922    NM_POOL32A0    = 0x00,
16923    NM_SPECIAL2    = 0x01,
16924    NM_COP2_1      = 0x02,
16925    NM_UDI         = 0x03,
16926    NM_POOL32A5    = 0x05,
16927    NM_POOL32A7    = 0x07,
16928};
16929
16930/* P.GP.W instruction pool */
16931enum {
16932    NM_ADDIUGP_W = 0x00,
16933    NM_LWGP      = 0x02,
16934    NM_SWGP      = 0x03,
16935};
16936
16937/* P48I instruction pool */
16938enum {
16939    NM_LI48        = 0x00,
16940    NM_ADDIU48     = 0x01,
16941    NM_ADDIUGP48   = 0x02,
16942    NM_ADDIUPC48   = 0x03,
16943    NM_LWPC48      = 0x0b,
16944    NM_SWPC48      = 0x0f,
16945};
16946
16947/* P.U12 instruction pool */
16948enum {
16949    NM_ORI      = 0x00,
16950    NM_XORI     = 0x01,
16951    NM_ANDI     = 0x02,
16952    NM_P_SR     = 0x03,
16953    NM_SLTI     = 0x04,
16954    NM_SLTIU    = 0x05,
16955    NM_SEQI     = 0x06,
16956    NM_ADDIUNEG = 0x08,
16957    NM_P_SHIFT  = 0x0c,
16958    NM_P_ROTX   = 0x0d,
16959    NM_P_INS    = 0x0e,
16960    NM_P_EXT    = 0x0f,
16961};
16962
16963/* POOL32F instruction pool */
16964enum {
16965    NM_POOL32F_0   = 0x00,
16966    NM_POOL32F_3   = 0x03,
16967    NM_POOL32F_5   = 0x05,
16968};
16969
16970/* POOL32S instruction pool */
16971enum {
16972    NM_POOL32S_0   = 0x00,
16973    NM_POOL32S_4   = 0x04,
16974};
16975
16976/* P.LUI instruction pool */
16977enum {
16978    NM_LUI      = 0x00,
16979    NM_ALUIPC   = 0x01,
16980};
16981
16982/* P.GP.BH instruction pool */
16983enum {
16984    NM_LBGP      = 0x00,
16985    NM_SBGP      = 0x01,
16986    NM_LBUGP     = 0x02,
16987    NM_ADDIUGP_B = 0x03,
16988    NM_P_GP_LH   = 0x04,
16989    NM_P_GP_SH   = 0x05,
16990    NM_P_GP_CP1  = 0x06,
16991};
16992
16993/* P.LS.U12 instruction pool */
16994enum {
16995    NM_LB        = 0x00,
16996    NM_SB        = 0x01,
16997    NM_LBU       = 0x02,
16998    NM_P_PREFU12 = 0x03,
16999    NM_LH        = 0x04,
17000    NM_SH        = 0x05,
17001    NM_LHU       = 0x06,
17002    NM_LWU       = 0x07,
17003    NM_LW        = 0x08,
17004    NM_SW        = 0x09,
17005    NM_LWC1      = 0x0a,
17006    NM_SWC1      = 0x0b,
17007    NM_LDC1      = 0x0e,
17008    NM_SDC1      = 0x0f,
17009};
17010
17011/* P.LS.S9 instruction pool */
17012enum {
17013    NM_P_LS_S0         = 0x00,
17014    NM_P_LS_S1         = 0x01,
17015    NM_P_LS_E0         = 0x02,
17016    NM_P_LS_WM         = 0x04,
17017    NM_P_LS_UAWM       = 0x05,
17018};
17019
17020/* P.BAL instruction pool */
17021enum {
17022    NM_BC       = 0x00,
17023    NM_BALC     = 0x01,
17024};
17025
17026/* P.J instruction pool */
17027enum {
17028    NM_JALRC    = 0x00,
17029    NM_JALRC_HB = 0x01,
17030    NM_P_BALRSC = 0x08,
17031};
17032
17033/* P.BR1 instruction pool */
17034enum {
17035    NM_BEQC     = 0x00,
17036    NM_P_BR3A   = 0x01,
17037    NM_BGEC     = 0x02,
17038    NM_BGEUC    = 0x03,
17039};
17040
17041/* P.BR2 instruction pool */
17042enum {
17043    NM_BNEC     = 0x00,
17044    NM_BLTC     = 0x02,
17045    NM_BLTUC    = 0x03,
17046};
17047
17048/* P.BRI instruction pool */
17049enum {
17050    NM_BEQIC    = 0x00,
17051    NM_BBEQZC   = 0x01,
17052    NM_BGEIC    = 0x02,
17053    NM_BGEIUC   = 0x03,
17054    NM_BNEIC    = 0x04,
17055    NM_BBNEZC   = 0x05,
17056    NM_BLTIC    = 0x06,
17057    NM_BLTIUC   = 0x07,
17058};
17059
17060/* P16.SHIFT instruction pool */
17061enum {
17062    NM_SLL16    = 0x00,
17063    NM_SRL16    = 0x01,
17064};
17065
17066/* POOL16C instruction pool */
17067enum {
17068    NM_POOL16C_0  = 0x00,
17069    NM_LWXS16     = 0x01,
17070};
17071
17072/* P16.A1 instruction pool */
17073enum {
17074    NM_ADDIUR1SP = 0x01,
17075};
17076
17077/* P16.A2 instruction pool */
17078enum {
17079    NM_ADDIUR2  = 0x00,
17080    NM_P_ADDIURS5  = 0x01,
17081};
17082
17083/* P16.ADDU instruction pool */
17084enum {
17085    NM_ADDU16     = 0x00,
17086    NM_SUBU16     = 0x01,
17087};
17088
17089/* P16.SR instruction pool */
17090enum {
17091    NM_SAVE16        = 0x00,
17092    NM_RESTORE_JRC16 = 0x01,
17093};
17094
17095/* P16.4X4 instruction pool */
17096enum {
17097    NM_ADDU4X4      = 0x00,
17098    NM_MUL4X4       = 0x01,
17099};
17100
17101/* P16.LB instruction pool */
17102enum {
17103    NM_LB16       = 0x00,
17104    NM_SB16       = 0x01,
17105    NM_LBU16      = 0x02,
17106};
17107
17108/* P16.LH  instruction pool */
17109enum {
17110    NM_LH16     = 0x00,
17111    NM_SH16     = 0x01,
17112    NM_LHU16    = 0x02,
17113};
17114
17115/* P.RI instruction pool */
17116enum {
17117    NM_SIGRIE       = 0x00,
17118    NM_P_SYSCALL    = 0x01,
17119    NM_BREAK        = 0x02,
17120    NM_SDBBP        = 0x03,
17121};
17122
17123/* POOL32A0 instruction pool */
17124enum {
17125    NM_P_TRAP   = 0x00,
17126    NM_SEB      = 0x01,
17127    NM_SLLV     = 0x02,
17128    NM_MUL      = 0x03,
17129    NM_MFC0     = 0x06,
17130    NM_MFHC0    = 0x07,
17131    NM_SEH      = 0x09,
17132    NM_SRLV     = 0x0a,
17133    NM_MUH      = 0x0b,
17134    NM_MTC0     = 0x0e,
17135    NM_MTHC0    = 0x0f,
17136    NM_SRAV     = 0x12,
17137    NM_MULU     = 0x13,
17138    NM_ROTRV    = 0x1a,
17139    NM_MUHU     = 0x1b,
17140    NM_ADD      = 0x22,
17141    NM_DIV      = 0x23,
17142    NM_ADDU     = 0x2a,
17143    NM_MOD      = 0x2b,
17144    NM_SUB      = 0x32,
17145    NM_DIVU     = 0x33,
17146    NM_RDHWR    = 0x38,
17147    NM_SUBU     = 0x3a,
17148    NM_MODU     = 0x3b,
17149    NM_P_CMOVE  = 0x42,
17150    NM_FORK     = 0x45,
17151    NM_MFTR     = 0x46,
17152    NM_MFHTR    = 0x47,
17153    NM_AND      = 0x4a,
17154    NM_YIELD    = 0x4d,
17155    NM_MTTR     = 0x4e,
17156    NM_MTHTR    = 0x4f,
17157    NM_OR       = 0x52,
17158    NM_D_E_MT_VPE = 0x56,
17159    NM_NOR      = 0x5a,
17160    NM_XOR      = 0x62,
17161    NM_SLT      = 0x6a,
17162    NM_P_SLTU   = 0x72,
17163    NM_SOV      = 0x7a,
17164};
17165
17166/* CRC32 instruction pool */
17167enum {
17168    NM_CRC32B   = 0x00,
17169    NM_CRC32H   = 0x01,
17170    NM_CRC32W   = 0x02,
17171    NM_CRC32CB  = 0x04,
17172    NM_CRC32CH  = 0x05,
17173    NM_CRC32CW  = 0x06,
17174};
17175
17176/* POOL32A5 instruction pool */
17177enum {
17178    NM_CMP_EQ_PH        = 0x00,
17179    NM_CMP_LT_PH        = 0x08,
17180    NM_CMP_LE_PH        = 0x10,
17181    NM_CMPGU_EQ_QB      = 0x18,
17182    NM_CMPGU_LT_QB      = 0x20,
17183    NM_CMPGU_LE_QB      = 0x28,
17184    NM_CMPGDU_EQ_QB     = 0x30,
17185    NM_CMPGDU_LT_QB     = 0x38,
17186    NM_CMPGDU_LE_QB     = 0x40,
17187    NM_CMPU_EQ_QB       = 0x48,
17188    NM_CMPU_LT_QB       = 0x50,
17189    NM_CMPU_LE_QB       = 0x58,
17190    NM_ADDQ_S_W         = 0x60,
17191    NM_SUBQ_S_W         = 0x68,
17192    NM_ADDSC            = 0x70,
17193    NM_ADDWC            = 0x78,
17194
17195    NM_ADDQ_S_PH   = 0x01,
17196    NM_ADDQH_R_PH  = 0x09,
17197    NM_ADDQH_R_W   = 0x11,
17198    NM_ADDU_S_QB   = 0x19,
17199    NM_ADDU_S_PH   = 0x21,
17200    NM_ADDUH_R_QB  = 0x29,
17201    NM_SHRAV_R_PH  = 0x31,
17202    NM_SHRAV_R_QB  = 0x39,
17203    NM_SUBQ_S_PH   = 0x41,
17204    NM_SUBQH_R_PH  = 0x49,
17205    NM_SUBQH_R_W   = 0x51,
17206    NM_SUBU_S_QB   = 0x59,
17207    NM_SUBU_S_PH   = 0x61,
17208    NM_SUBUH_R_QB  = 0x69,
17209    NM_SHLLV_S_PH  = 0x71,
17210    NM_PRECR_SRA_R_PH_W = 0x79,
17211
17212    NM_MULEU_S_PH_QBL   = 0x12,
17213    NM_MULEU_S_PH_QBR   = 0x1a,
17214    NM_MULQ_RS_PH       = 0x22,
17215    NM_MULQ_S_PH        = 0x2a,
17216    NM_MULQ_RS_W        = 0x32,
17217    NM_MULQ_S_W         = 0x3a,
17218    NM_APPEND           = 0x42,
17219    NM_MODSUB           = 0x52,
17220    NM_SHRAV_R_W        = 0x5a,
17221    NM_SHRLV_PH         = 0x62,
17222    NM_SHRLV_QB         = 0x6a,
17223    NM_SHLLV_QB         = 0x72,
17224    NM_SHLLV_S_W        = 0x7a,
17225
17226    NM_SHILO            = 0x03,
17227
17228    NM_MULEQ_S_W_PHL    = 0x04,
17229    NM_MULEQ_S_W_PHR    = 0x0c,
17230
17231    NM_MUL_S_PH         = 0x05,
17232    NM_PRECR_QB_PH      = 0x0d,
17233    NM_PRECRQ_QB_PH     = 0x15,
17234    NM_PRECRQ_PH_W      = 0x1d,
17235    NM_PRECRQ_RS_PH_W   = 0x25,
17236    NM_PRECRQU_S_QB_PH  = 0x2d,
17237    NM_PACKRL_PH        = 0x35,
17238    NM_PICK_QB          = 0x3d,
17239    NM_PICK_PH          = 0x45,
17240
17241    NM_SHRA_R_W         = 0x5e,
17242    NM_SHRA_R_PH        = 0x66,
17243    NM_SHLL_S_PH        = 0x76,
17244    NM_SHLL_S_W         = 0x7e,
17245
17246    NM_REPL_PH          = 0x07
17247};
17248
17249/* POOL32A7 instruction pool */
17250enum {
17251    NM_P_LSX        = 0x00,
17252    NM_LSA          = 0x01,
17253    NM_EXTW         = 0x03,
17254    NM_POOL32AXF    = 0x07,
17255};
17256
17257/* P.SR instruction pool */
17258enum {
17259    NM_PP_SR           = 0x00,
17260    NM_P_SR_F          = 0x01,
17261};
17262
17263/* P.SHIFT instruction pool */
17264enum {
17265    NM_P_SLL        = 0x00,
17266    NM_SRL          = 0x02,
17267    NM_SRA          = 0x04,
17268    NM_ROTR         = 0x06,
17269};
17270
17271/* P.ROTX instruction pool */
17272enum {
17273    NM_ROTX         = 0x00,
17274};
17275
17276/* P.INS instruction pool */
17277enum {
17278    NM_INS          = 0x00,
17279};
17280
17281/* P.EXT instruction pool */
17282enum {
17283    NM_EXT          = 0x00,
17284};
17285
17286/* POOL32F_0 (fmt) instruction pool */
17287enum {
17288    NM_RINT_S              = 0x04,
17289    NM_RINT_D              = 0x44,
17290    NM_ADD_S               = 0x06,
17291    NM_SELEQZ_S            = 0x07,
17292    NM_SELEQZ_D            = 0x47,
17293    NM_CLASS_S             = 0x0c,
17294    NM_CLASS_D             = 0x4c,
17295    NM_SUB_S               = 0x0e,
17296    NM_SELNEZ_S            = 0x0f,
17297    NM_SELNEZ_D            = 0x4f,
17298    NM_MUL_S               = 0x16,
17299    NM_SEL_S               = 0x17,
17300    NM_SEL_D               = 0x57,
17301    NM_DIV_S               = 0x1e,
17302    NM_ADD_D               = 0x26,
17303    NM_SUB_D               = 0x2e,
17304    NM_MUL_D               = 0x36,
17305    NM_MADDF_S             = 0x37,
17306    NM_MADDF_D             = 0x77,
17307    NM_DIV_D               = 0x3e,
17308    NM_MSUBF_S             = 0x3f,
17309    NM_MSUBF_D             = 0x7f,
17310};
17311
17312/* POOL32F_3  instruction pool */
17313enum {
17314    NM_MIN_FMT         = 0x00,
17315    NM_MAX_FMT         = 0x01,
17316    NM_MINA_FMT        = 0x04,
17317    NM_MAXA_FMT        = 0x05,
17318    NM_POOL32FXF       = 0x07,
17319};
17320
17321/* POOL32F_5  instruction pool */
17322enum {
17323    NM_CMP_CONDN_S     = 0x00,
17324    NM_CMP_CONDN_D     = 0x02,
17325};
17326
17327/* P.GP.LH instruction pool */
17328enum {
17329    NM_LHGP    = 0x00,
17330    NM_LHUGP   = 0x01,
17331};
17332
17333/* P.GP.SH instruction pool */
17334enum {
17335    NM_SHGP    = 0x00,
17336};
17337
17338/* P.GP.CP1 instruction pool */
17339enum {
17340    NM_LWC1GP       = 0x00,
17341    NM_SWC1GP       = 0x01,
17342    NM_LDC1GP       = 0x02,
17343    NM_SDC1GP       = 0x03,
17344};
17345
17346/* P.LS.S0 instruction pool */
17347enum {
17348    NM_LBS9     = 0x00,
17349    NM_LHS9     = 0x04,
17350    NM_LWS9     = 0x08,
17351    NM_LDS9     = 0x0c,
17352
17353    NM_SBS9     = 0x01,
17354    NM_SHS9     = 0x05,
17355    NM_SWS9     = 0x09,
17356    NM_SDS9     = 0x0d,
17357
17358    NM_LBUS9    = 0x02,
17359    NM_LHUS9    = 0x06,
17360    NM_LWC1S9   = 0x0a,
17361    NM_LDC1S9   = 0x0e,
17362
17363    NM_P_PREFS9 = 0x03,
17364    NM_LWUS9    = 0x07,
17365    NM_SWC1S9   = 0x0b,
17366    NM_SDC1S9   = 0x0f,
17367};
17368
17369/* P.LS.S1 instruction pool */
17370enum {
17371    NM_ASET_ACLR = 0x02,
17372    NM_UALH      = 0x04,
17373    NM_UASH      = 0x05,
17374    NM_CACHE     = 0x07,
17375    NM_P_LL      = 0x0a,
17376    NM_P_SC      = 0x0b,
17377};
17378
17379/* P.LS.E0 instruction pool */
17380enum {
17381    NM_LBE      = 0x00,
17382    NM_SBE      = 0x01,
17383    NM_LBUE     = 0x02,
17384    NM_P_PREFE  = 0x03,
17385    NM_LHE      = 0x04,
17386    NM_SHE      = 0x05,
17387    NM_LHUE     = 0x06,
17388    NM_CACHEE   = 0x07,
17389    NM_LWE      = 0x08,
17390    NM_SWE      = 0x09,
17391    NM_P_LLE    = 0x0a,
17392    NM_P_SCE    = 0x0b,
17393};
17394
17395/* P.PREFE instruction pool */
17396enum {
17397    NM_SYNCIE   = 0x00,
17398    NM_PREFE    = 0x01,
17399};
17400
17401/* P.LLE instruction pool */
17402enum {
17403    NM_LLE      = 0x00,
17404    NM_LLWPE    = 0x01,
17405};
17406
17407/* P.SCE instruction pool */
17408enum {
17409    NM_SCE      = 0x00,
17410    NM_SCWPE    = 0x01,
17411};
17412
17413/* P.LS.WM instruction pool */
17414enum {
17415    NM_LWM       = 0x00,
17416    NM_SWM       = 0x01,
17417};
17418
17419/* P.LS.UAWM instruction pool */
17420enum {
17421    NM_UALWM       = 0x00,
17422    NM_UASWM       = 0x01,
17423};
17424
17425/* P.BR3A instruction pool */
17426enum {
17427    NM_BC1EQZC          = 0x00,
17428    NM_BC1NEZC          = 0x01,
17429    NM_BC2EQZC          = 0x02,
17430    NM_BC2NEZC          = 0x03,
17431    NM_BPOSGE32C        = 0x04,
17432};
17433
17434/* P16.RI instruction pool */
17435enum {
17436    NM_P16_SYSCALL  = 0x01,
17437    NM_BREAK16      = 0x02,
17438    NM_SDBBP16      = 0x03,
17439};
17440
17441/* POOL16C_0 instruction pool */
17442enum {
17443    NM_POOL16C_00      = 0x00,
17444};
17445
17446/* P16.JRC instruction pool */
17447enum {
17448    NM_JRC          = 0x00,
17449    NM_JALRC16      = 0x01,
17450};
17451
17452/* P.SYSCALL instruction pool */
17453enum {
17454    NM_SYSCALL      = 0x00,
17455    NM_HYPCALL      = 0x01,
17456};
17457
17458/* P.TRAP instruction pool */
17459enum {
17460    NM_TEQ          = 0x00,
17461    NM_TNE          = 0x01,
17462};
17463
17464/* P.CMOVE instruction pool */
17465enum {
17466    NM_MOVZ            = 0x00,
17467    NM_MOVN            = 0x01,
17468};
17469
17470/* POOL32Axf instruction pool */
17471enum {
17472    NM_POOL32AXF_1 = 0x01,
17473    NM_POOL32AXF_2 = 0x02,
17474    NM_POOL32AXF_4 = 0x04,
17475    NM_POOL32AXF_5 = 0x05,
17476    NM_POOL32AXF_7 = 0x07,
17477};
17478
17479/* POOL32Axf_1 instruction pool */
17480enum {
17481    NM_POOL32AXF_1_0 = 0x00,
17482    NM_POOL32AXF_1_1 = 0x01,
17483    NM_POOL32AXF_1_3 = 0x03,
17484    NM_POOL32AXF_1_4 = 0x04,
17485    NM_POOL32AXF_1_5 = 0x05,
17486    NM_POOL32AXF_1_7 = 0x07,
17487};
17488
17489/* POOL32Axf_2 instruction pool */
17490enum {
17491    NM_POOL32AXF_2_0_7     = 0x00,
17492    NM_POOL32AXF_2_8_15    = 0x01,
17493    NM_POOL32AXF_2_16_23   = 0x02,
17494    NM_POOL32AXF_2_24_31   = 0x03,
17495};
17496
17497/* POOL32Axf_7 instruction pool */
17498enum {
17499    NM_SHRA_R_QB    = 0x0,
17500    NM_SHRL_PH      = 0x1,
17501    NM_REPL_QB      = 0x2,
17502};
17503
17504/* POOL32Axf_1_0 instruction pool */
17505enum {
17506    NM_MFHI = 0x0,
17507    NM_MFLO = 0x1,
17508    NM_MTHI = 0x2,
17509    NM_MTLO = 0x3,
17510};
17511
17512/* POOL32Axf_1_1 instruction pool */
17513enum {
17514    NM_MTHLIP = 0x0,
17515    NM_SHILOV = 0x1,
17516};
17517
17518/* POOL32Axf_1_3 instruction pool */
17519enum {
17520    NM_RDDSP    = 0x0,
17521    NM_WRDSP    = 0x1,
17522    NM_EXTP     = 0x2,
17523    NM_EXTPDP   = 0x3,
17524};
17525
17526/* POOL32Axf_1_4 instruction pool */
17527enum {
17528    NM_SHLL_QB  = 0x0,
17529    NM_SHRL_QB  = 0x1,
17530};
17531
17532/* POOL32Axf_1_5 instruction pool */
17533enum {
17534    NM_MAQ_S_W_PHR   = 0x0,
17535    NM_MAQ_S_W_PHL   = 0x1,
17536    NM_MAQ_SA_W_PHR  = 0x2,
17537    NM_MAQ_SA_W_PHL  = 0x3,
17538};
17539
17540/* POOL32Axf_1_7 instruction pool */
17541enum {
17542    NM_EXTR_W       = 0x0,
17543    NM_EXTR_R_W     = 0x1,
17544    NM_EXTR_RS_W    = 0x2,
17545    NM_EXTR_S_H     = 0x3,
17546};
17547
17548/* POOL32Axf_2_0_7 instruction pool */
17549enum {
17550    NM_DPA_W_PH     = 0x0,
17551    NM_DPAQ_S_W_PH  = 0x1,
17552    NM_DPS_W_PH     = 0x2,
17553    NM_DPSQ_S_W_PH  = 0x3,
17554    NM_BALIGN       = 0x4,
17555    NM_MADD         = 0x5,
17556    NM_MULT         = 0x6,
17557    NM_EXTRV_W      = 0x7,
17558};
17559
17560/* POOL32Axf_2_8_15 instruction pool */
17561enum {
17562    NM_DPAX_W_PH    = 0x0,
17563    NM_DPAQ_SA_L_W  = 0x1,
17564    NM_DPSX_W_PH    = 0x2,
17565    NM_DPSQ_SA_L_W  = 0x3,
17566    NM_MADDU        = 0x5,
17567    NM_MULTU        = 0x6,
17568    NM_EXTRV_R_W    = 0x7,
17569};
17570
17571/* POOL32Axf_2_16_23 instruction pool */
17572enum {
17573    NM_DPAU_H_QBL       = 0x0,
17574    NM_DPAQX_S_W_PH     = 0x1,
17575    NM_DPSU_H_QBL       = 0x2,
17576    NM_DPSQX_S_W_PH     = 0x3,
17577    NM_EXTPV            = 0x4,
17578    NM_MSUB             = 0x5,
17579    NM_MULSA_W_PH       = 0x6,
17580    NM_EXTRV_RS_W       = 0x7,
17581};
17582
17583/* POOL32Axf_2_24_31 instruction pool */
17584enum {
17585    NM_DPAU_H_QBR       = 0x0,
17586    NM_DPAQX_SA_W_PH    = 0x1,
17587    NM_DPSU_H_QBR       = 0x2,
17588    NM_DPSQX_SA_W_PH    = 0x3,
17589    NM_EXTPDPV          = 0x4,
17590    NM_MSUBU            = 0x5,
17591    NM_MULSAQ_S_W_PH    = 0x6,
17592    NM_EXTRV_S_H        = 0x7,
17593};
17594
17595/* POOL32Axf_{4, 5} instruction pool */
17596enum {
17597    NM_CLO      = 0x25,
17598    NM_CLZ      = 0x2d,
17599
17600    NM_TLBP     = 0x01,
17601    NM_TLBR     = 0x09,
17602    NM_TLBWI    = 0x11,
17603    NM_TLBWR    = 0x19,
17604    NM_TLBINV   = 0x03,
17605    NM_TLBINVF  = 0x0b,
17606    NM_DI       = 0x23,
17607    NM_EI       = 0x2b,
17608    NM_RDPGPR   = 0x70,
17609    NM_WRPGPR   = 0x78,
17610    NM_WAIT     = 0x61,
17611    NM_DERET    = 0x71,
17612    NM_ERETX    = 0x79,
17613
17614    /* nanoMIPS DSP instructions */
17615    NM_ABSQ_S_QB        = 0x00,
17616    NM_ABSQ_S_PH        = 0x08,
17617    NM_ABSQ_S_W         = 0x10,
17618    NM_PRECEQ_W_PHL     = 0x28,
17619    NM_PRECEQ_W_PHR     = 0x30,
17620    NM_PRECEQU_PH_QBL   = 0x38,
17621    NM_PRECEQU_PH_QBR   = 0x48,
17622    NM_PRECEU_PH_QBL    = 0x58,
17623    NM_PRECEU_PH_QBR    = 0x68,
17624    NM_PRECEQU_PH_QBLA  = 0x39,
17625    NM_PRECEQU_PH_QBRA  = 0x49,
17626    NM_PRECEU_PH_QBLA   = 0x59,
17627    NM_PRECEU_PH_QBRA   = 0x69,
17628    NM_REPLV_PH         = 0x01,
17629    NM_REPLV_QB         = 0x09,
17630    NM_BITREV           = 0x18,
17631    NM_INSV             = 0x20,
17632    NM_RADDU_W_QB       = 0x78,
17633
17634    NM_BITSWAP          = 0x05,
17635    NM_WSBH             = 0x3d,
17636};
17637
17638/* PP.SR instruction pool */
17639enum {
17640    NM_SAVE         = 0x00,
17641    NM_RESTORE      = 0x02,
17642    NM_RESTORE_JRC  = 0x03,
17643};
17644
17645/* P.SR.F instruction pool */
17646enum {
17647    NM_SAVEF        = 0x00,
17648    NM_RESTOREF     = 0x01,
17649};
17650
17651/* P16.SYSCALL  instruction pool */
17652enum {
17653    NM_SYSCALL16     = 0x00,
17654    NM_HYPCALL16     = 0x01,
17655};
17656
17657/* POOL16C_00 instruction pool */
17658enum {
17659    NM_NOT16           = 0x00,
17660    NM_XOR16           = 0x01,
17661    NM_AND16           = 0x02,
17662    NM_OR16            = 0x03,
17663};
17664
17665/* PP.LSX and PP.LSXS instruction pool */
17666enum {
17667    NM_LBX      = 0x00,
17668    NM_LHX      = 0x04,
17669    NM_LWX      = 0x08,
17670    NM_LDX      = 0x0c,
17671
17672    NM_SBX      = 0x01,
17673    NM_SHX      = 0x05,
17674    NM_SWX      = 0x09,
17675    NM_SDX      = 0x0d,
17676
17677    NM_LBUX     = 0x02,
17678    NM_LHUX     = 0x06,
17679    NM_LWC1X    = 0x0a,
17680    NM_LDC1X    = 0x0e,
17681
17682    NM_LWUX     = 0x07,
17683    NM_SWC1X    = 0x0b,
17684    NM_SDC1X    = 0x0f,
17685
17686    NM_LHXS     = 0x04,
17687    NM_LWXS     = 0x08,
17688    NM_LDXS     = 0x0c,
17689
17690    NM_SHXS     = 0x05,
17691    NM_SWXS     = 0x09,
17692    NM_SDXS     = 0x0d,
17693
17694    NM_LHUXS    = 0x06,
17695    NM_LWC1XS   = 0x0a,
17696    NM_LDC1XS   = 0x0e,
17697
17698    NM_LWUXS    = 0x07,
17699    NM_SWC1XS   = 0x0b,
17700    NM_SDC1XS   = 0x0f,
17701};
17702
17703/* ERETx instruction pool */
17704enum {
17705    NM_ERET     = 0x00,
17706    NM_ERETNC   = 0x01,
17707};
17708
17709/* POOL32FxF_{0, 1} insturction pool */
17710enum {
17711    NM_CFC1     = 0x40,
17712    NM_CTC1     = 0x60,
17713    NM_MFC1     = 0x80,
17714    NM_MTC1     = 0xa0,
17715    NM_MFHC1    = 0xc0,
17716    NM_MTHC1    = 0xe0,
17717
17718    NM_CVT_S_PL = 0x84,
17719    NM_CVT_S_PU = 0xa4,
17720
17721    NM_CVT_L_S     = 0x004,
17722    NM_CVT_L_D     = 0x104,
17723    NM_CVT_W_S     = 0x024,
17724    NM_CVT_W_D     = 0x124,
17725
17726    NM_RSQRT_S     = 0x008,
17727    NM_RSQRT_D     = 0x108,
17728
17729    NM_SQRT_S      = 0x028,
17730    NM_SQRT_D      = 0x128,
17731
17732    NM_RECIP_S     = 0x048,
17733    NM_RECIP_D     = 0x148,
17734
17735    NM_FLOOR_L_S   = 0x00c,
17736    NM_FLOOR_L_D   = 0x10c,
17737
17738    NM_FLOOR_W_S   = 0x02c,
17739    NM_FLOOR_W_D   = 0x12c,
17740
17741    NM_CEIL_L_S    = 0x04c,
17742    NM_CEIL_L_D    = 0x14c,
17743    NM_CEIL_W_S    = 0x06c,
17744    NM_CEIL_W_D    = 0x16c,
17745    NM_TRUNC_L_S   = 0x08c,
17746    NM_TRUNC_L_D   = 0x18c,
17747    NM_TRUNC_W_S   = 0x0ac,
17748    NM_TRUNC_W_D   = 0x1ac,
17749    NM_ROUND_L_S   = 0x0cc,
17750    NM_ROUND_L_D   = 0x1cc,
17751    NM_ROUND_W_S   = 0x0ec,
17752    NM_ROUND_W_D   = 0x1ec,
17753
17754    NM_MOV_S       = 0x01,
17755    NM_MOV_D       = 0x81,
17756    NM_ABS_S       = 0x0d,
17757    NM_ABS_D       = 0x8d,
17758    NM_NEG_S       = 0x2d,
17759    NM_NEG_D       = 0xad,
17760    NM_CVT_D_S     = 0x04d,
17761    NM_CVT_D_W     = 0x0cd,
17762    NM_CVT_D_L     = 0x14d,
17763    NM_CVT_S_D     = 0x06d,
17764    NM_CVT_S_W     = 0x0ed,
17765    NM_CVT_S_L     = 0x16d,
17766};
17767
17768/* P.LL instruction pool */
17769enum {
17770    NM_LL       = 0x00,
17771    NM_LLWP     = 0x01,
17772};
17773
17774/* P.SC instruction pool */
17775enum {
17776    NM_SC       = 0x00,
17777    NM_SCWP     = 0x01,
17778};
17779
17780/* P.DVP instruction pool */
17781enum {
17782    NM_DVP      = 0x00,
17783    NM_EVP      = 0x01,
17784};
17785
17786
17787/*
17788 *
17789 * nanoMIPS decoding engine
17790 *
17791 */
17792
17793
17794/* extraction utilities */
17795
17796#define NANOMIPS_EXTRACT_RT3(op) ((op >> 7) & 0x7)
17797#define NANOMIPS_EXTRACT_RS3(op) ((op >> 4) & 0x7)
17798#define NANOMIPS_EXTRACT_RD3(op) ((op >> 1) & 0x7)
17799#define NANOMIPS_EXTRACT_RD5(op) ((op >> 5) & 0x1f)
17800#define NANOMIPS_EXTRACT_RS5(op) (op & 0x1f)
17801
17802/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3'). */
17803static inline int decode_gpr_gpr3(int r)
17804{
17805    static const int map[] = { 16, 17, 18, 19,  4,  5,  6,  7 };
17806
17807    return map[r & 0x7];
17808}
17809
17810/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr3.src.store'). */
17811static inline int decode_gpr_gpr3_src_store(int r)
17812{
17813    static const int map[] = {  0, 17, 18, 19,  4,  5,  6,  7 };
17814
17815    return map[r & 0x7];
17816}
17817
17818/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4'). */
17819static inline int decode_gpr_gpr4(int r)
17820{
17821    static const int map[] = {  8,  9, 10, 11,  4,  5,  6,  7,
17822                               16, 17, 18, 19, 20, 21, 22, 23 };
17823
17824    return map[r & 0xf];
17825}
17826
17827/* Implement nanoMIPS pseudocode decode_gpr(encoded_gpr, 'gpr4.zero'). */
17828static inline int decode_gpr_gpr4_zero(int r)
17829{
17830    static const int map[] = {  8,  9, 10,  0,  4,  5,  6,  7,
17831                               16, 17, 18, 19, 20, 21, 22, 23 };
17832
17833    return map[r & 0xf];
17834}
17835
17836
17837static void gen_adjust_sp(DisasContext *ctx, int u)
17838{
17839    gen_op_addr_addi(ctx, cpu_gpr[29], cpu_gpr[29], u);
17840}
17841
17842static void gen_save(DisasContext *ctx, uint8_t rt, uint8_t count,
17843                     uint8_t gp, uint16_t u)
17844{
17845    int counter = 0;
17846    TCGv va = tcg_temp_new();
17847    TCGv t0 = tcg_temp_new();
17848
17849    while (counter != count) {
17850        bool use_gp = gp && (counter == count - 1);
17851        int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
17852        int this_offset = -((counter + 1) << 2);
17853        gen_base_offset_addr(ctx, va, 29, this_offset);
17854        gen_load_gpr(t0, this_rt);
17855        tcg_gen_qemu_st_tl(t0, va, ctx->mem_idx,
17856                           (MO_TEUL | ctx->default_tcg_memop_mask));
17857        counter++;
17858    }
17859
17860    /* adjust stack pointer */
17861    gen_adjust_sp(ctx, -u);
17862
17863    tcg_temp_free(t0);
17864    tcg_temp_free(va);
17865}
17866
17867static void gen_restore(DisasContext *ctx, uint8_t rt, uint8_t count,
17868                        uint8_t gp, uint16_t u)
17869{
17870    int counter = 0;
17871    TCGv va = tcg_temp_new();
17872    TCGv t0 = tcg_temp_new();
17873
17874    while (counter != count) {
17875        bool use_gp = gp && (counter == count - 1);
17876        int this_rt = use_gp ? 28 : (rt & 0x10) | ((rt + counter) & 0x1f);
17877        int this_offset = u - ((counter + 1) << 2);
17878        gen_base_offset_addr(ctx, va, 29, this_offset);
17879        tcg_gen_qemu_ld_tl(t0, va, ctx->mem_idx, MO_TESL |
17880                        ctx->default_tcg_memop_mask);
17881        tcg_gen_ext32s_tl(t0, t0);
17882        gen_store_gpr(t0, this_rt);
17883        counter++;
17884    }
17885
17886    /* adjust stack pointer */
17887    gen_adjust_sp(ctx, u);
17888
17889    tcg_temp_free(t0);
17890    tcg_temp_free(va);
17891}
17892
17893static void gen_pool16c_nanomips_insn(DisasContext *ctx)
17894{
17895    int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
17896    int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
17897
17898    switch (extract32(ctx->opcode, 2, 2)) {
17899    case NM_NOT16:
17900        gen_logic(ctx, OPC_NOR, rt, rs, 0);
17901        break;
17902    case NM_AND16:
17903        gen_logic(ctx, OPC_AND, rt, rt, rs);
17904        break;
17905    case NM_XOR16:
17906        gen_logic(ctx, OPC_XOR, rt, rt, rs);
17907        break;
17908    case NM_OR16:
17909        gen_logic(ctx, OPC_OR, rt, rt, rs);
17910        break;
17911    }
17912}
17913
17914static void gen_pool32a0_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
17915{
17916    int rt = extract32(ctx->opcode, 21, 5);
17917    int rs = extract32(ctx->opcode, 16, 5);
17918    int rd = extract32(ctx->opcode, 11, 5);
17919
17920    switch (extract32(ctx->opcode, 3, 7)) {
17921    case NM_P_TRAP:
17922        switch (extract32(ctx->opcode, 10, 1)) {
17923        case NM_TEQ:
17924            check_nms(ctx);
17925            gen_trap(ctx, OPC_TEQ, rs, rt, -1);
17926            break;
17927        case NM_TNE:
17928            check_nms(ctx);
17929            gen_trap(ctx, OPC_TNE, rs, rt, -1);
17930            break;
17931        }
17932        break;
17933    case NM_RDHWR:
17934        check_nms(ctx);
17935        gen_rdhwr(ctx, rt, rs, extract32(ctx->opcode, 11, 3));
17936        break;
17937    case NM_SEB:
17938        check_nms(ctx);
17939        gen_bshfl(ctx, OPC_SEB, rs, rt);
17940        break;
17941    case NM_SEH:
17942        gen_bshfl(ctx, OPC_SEH, rs, rt);
17943        break;
17944    case NM_SLLV:
17945        gen_shift(ctx, OPC_SLLV, rd, rt, rs);
17946        break;
17947    case NM_SRLV:
17948        gen_shift(ctx, OPC_SRLV, rd, rt, rs);
17949        break;
17950    case NM_SRAV:
17951        gen_shift(ctx, OPC_SRAV, rd, rt, rs);
17952        break;
17953    case NM_ROTRV:
17954        gen_shift(ctx, OPC_ROTRV, rd, rt, rs);
17955        break;
17956    case NM_ADD:
17957        gen_arith(ctx, OPC_ADD, rd, rs, rt);
17958        break;
17959    case NM_ADDU:
17960        gen_arith(ctx, OPC_ADDU, rd, rs, rt);
17961        break;
17962    case NM_SUB:
17963        check_nms(ctx);
17964        gen_arith(ctx, OPC_SUB, rd, rs, rt);
17965        break;
17966    case NM_SUBU:
17967        gen_arith(ctx, OPC_SUBU, rd, rs, rt);
17968        break;
17969    case NM_P_CMOVE:
17970        switch (extract32(ctx->opcode, 10, 1)) {
17971        case NM_MOVZ:
17972            gen_cond_move(ctx, OPC_MOVZ, rd, rs, rt);
17973            break;
17974        case NM_MOVN:
17975            gen_cond_move(ctx, OPC_MOVN, rd, rs, rt);
17976            break;
17977        }
17978        break;
17979    case NM_AND:
17980        gen_logic(ctx, OPC_AND, rd, rs, rt);
17981        break;
17982    case NM_OR:
17983        gen_logic(ctx, OPC_OR, rd, rs, rt);
17984        break;
17985    case NM_NOR:
17986        gen_logic(ctx, OPC_NOR, rd, rs, rt);
17987        break;
17988    case NM_XOR:
17989        gen_logic(ctx, OPC_XOR, rd, rs, rt);
17990        break;
17991    case NM_SLT:
17992        gen_slt(ctx, OPC_SLT, rd, rs, rt);
17993        break;
17994    case NM_P_SLTU:
17995        if (rd == 0) {
17996            /* P_DVP */
17997#ifndef CONFIG_USER_ONLY
17998            TCGv t0 = tcg_temp_new();
17999            switch (extract32(ctx->opcode, 10, 1)) {
18000            case NM_DVP:
18001                if (ctx->vp) {
18002                    check_cp0_enabled(ctx);
18003                    gen_helper_dvp(t0, cpu_env);
18004                    gen_store_gpr(t0, rt);
18005                }
18006                break;
18007            case NM_EVP:
18008                if (ctx->vp) {
18009                    check_cp0_enabled(ctx);
18010                    gen_helper_evp(t0, cpu_env);
18011                    gen_store_gpr(t0, rt);
18012                }
18013                break;
18014            }
18015            tcg_temp_free(t0);
18016#endif
18017        } else {
18018            gen_slt(ctx, OPC_SLTU, rd, rs, rt);
18019        }
18020        break;
18021    case NM_SOV:
18022        {
18023            TCGv t0 = tcg_temp_new();
18024            TCGv t1 = tcg_temp_new();
18025            TCGv t2 = tcg_temp_new();
18026
18027            gen_load_gpr(t1, rs);
18028            gen_load_gpr(t2, rt);
18029            tcg_gen_add_tl(t0, t1, t2);
18030            tcg_gen_ext32s_tl(t0, t0);
18031            tcg_gen_xor_tl(t1, t1, t2);
18032            tcg_gen_xor_tl(t2, t0, t2);
18033            tcg_gen_andc_tl(t1, t2, t1);
18034
18035            /* operands of same sign, result different sign */
18036            tcg_gen_setcondi_tl(TCG_COND_LT, t0, t1, 0);
18037            gen_store_gpr(t0, rd);
18038
18039            tcg_temp_free(t0);
18040            tcg_temp_free(t1);
18041            tcg_temp_free(t2);
18042        }
18043        break;
18044    case NM_MUL:
18045        gen_r6_muldiv(ctx, R6_OPC_MUL, rd, rs, rt);
18046        break;
18047    case NM_MUH:
18048        gen_r6_muldiv(ctx, R6_OPC_MUH, rd, rs, rt);
18049        break;
18050    case NM_MULU:
18051        gen_r6_muldiv(ctx, R6_OPC_MULU, rd, rs, rt);
18052        break;
18053    case NM_MUHU:
18054        gen_r6_muldiv(ctx, R6_OPC_MUHU, rd, rs, rt);
18055        break;
18056    case NM_DIV:
18057        gen_r6_muldiv(ctx, R6_OPC_DIV, rd, rs, rt);
18058        break;
18059    case NM_MOD:
18060        gen_r6_muldiv(ctx, R6_OPC_MOD, rd, rs, rt);
18061        break;
18062    case NM_DIVU:
18063        gen_r6_muldiv(ctx, R6_OPC_DIVU, rd, rs, rt);
18064        break;
18065    case NM_MODU:
18066        gen_r6_muldiv(ctx, R6_OPC_MODU, rd, rs, rt);
18067        break;
18068#ifndef CONFIG_USER_ONLY
18069    case NM_MFC0:
18070        check_cp0_enabled(ctx);
18071        if (rt == 0) {
18072            /* Treat as NOP. */
18073            break;
18074        }
18075        gen_mfc0(ctx, cpu_gpr[rt], rs, extract32(ctx->opcode, 11, 3));
18076        break;
18077    case NM_MTC0:
18078        check_cp0_enabled(ctx);
18079        {
18080            TCGv t0 = tcg_temp_new();
18081
18082            gen_load_gpr(t0, rt);
18083            gen_mtc0(ctx, t0, rs, extract32(ctx->opcode, 11, 3));
18084            tcg_temp_free(t0);
18085        }
18086        break;
18087    case NM_D_E_MT_VPE:
18088        {
18089            uint8_t sc = extract32(ctx->opcode, 10, 1);
18090            TCGv t0 = tcg_temp_new();
18091
18092            switch (sc) {
18093            case 0:
18094                if (rs == 1) {
18095                    /* DMT */
18096                    check_cp0_mt(ctx);
18097                    gen_helper_dmt(t0);
18098                    gen_store_gpr(t0, rt);
18099                } else if (rs == 0) {
18100                    /* DVPE */
18101                    check_cp0_mt(ctx);
18102                    gen_helper_dvpe(t0, cpu_env);
18103                    gen_store_gpr(t0, rt);
18104                } else {
18105                    gen_reserved_instruction(ctx);
18106                }
18107                break;
18108            case 1:
18109                if (rs == 1) {
18110                    /* EMT */
18111                    check_cp0_mt(ctx);
18112                    gen_helper_emt(t0);
18113                    gen_store_gpr(t0, rt);
18114                } else if (rs == 0) {
18115                    /* EVPE */
18116                    check_cp0_mt(ctx);
18117                    gen_helper_evpe(t0, cpu_env);
18118                    gen_store_gpr(t0, rt);
18119                } else {
18120                    gen_reserved_instruction(ctx);
18121                }
18122                break;
18123            }
18124
18125            tcg_temp_free(t0);
18126        }
18127        break;
18128    case NM_FORK:
18129        check_mt(ctx);
18130        {
18131            TCGv t0 = tcg_temp_new();
18132            TCGv t1 = tcg_temp_new();
18133
18134            gen_load_gpr(t0, rt);
18135            gen_load_gpr(t1, rs);
18136            gen_helper_fork(t0, t1);
18137            tcg_temp_free(t0);
18138            tcg_temp_free(t1);
18139        }
18140        break;
18141    case NM_MFTR:
18142    case NM_MFHTR:
18143        check_cp0_enabled(ctx);
18144        if (rd == 0) {
18145            /* Treat as NOP. */
18146            return;
18147        }
18148        gen_mftr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18149                 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18150        break;
18151    case NM_MTTR:
18152    case NM_MTHTR:
18153        check_cp0_enabled(ctx);
18154        gen_mttr(env, ctx, rs, rt, extract32(ctx->opcode, 10, 1),
18155                 extract32(ctx->opcode, 11, 5), extract32(ctx->opcode, 3, 1));
18156        break;
18157    case NM_YIELD:
18158        check_mt(ctx);
18159        {
18160            TCGv t0 = tcg_temp_new();
18161
18162            gen_load_gpr(t0, rs);
18163            gen_helper_yield(t0, cpu_env, t0);
18164            gen_store_gpr(t0, rt);
18165            tcg_temp_free(t0);
18166        }
18167        break;
18168#endif
18169    default:
18170        gen_reserved_instruction(ctx);
18171        break;
18172    }
18173}
18174
18175/* dsp */
18176static void gen_pool32axf_1_5_nanomips_insn(DisasContext *ctx, uint32_t opc,
18177                                            int ret, int v1, int v2)
18178{
18179    TCGv_i32 t0;
18180    TCGv v0_t;
18181    TCGv v1_t;
18182
18183    t0 = tcg_temp_new_i32();
18184
18185    v0_t = tcg_temp_new();
18186    v1_t = tcg_temp_new();
18187
18188    tcg_gen_movi_i32(t0, v2 >> 3);
18189
18190    gen_load_gpr(v0_t, ret);
18191    gen_load_gpr(v1_t, v1);
18192
18193    switch (opc) {
18194    case NM_MAQ_S_W_PHR:
18195        check_dsp(ctx);
18196        gen_helper_maq_s_w_phr(t0, v1_t, v0_t, cpu_env);
18197        break;
18198    case NM_MAQ_S_W_PHL:
18199        check_dsp(ctx);
18200        gen_helper_maq_s_w_phl(t0, v1_t, v0_t, cpu_env);
18201        break;
18202    case NM_MAQ_SA_W_PHR:
18203        check_dsp(ctx);
18204        gen_helper_maq_sa_w_phr(t0, v1_t, v0_t, cpu_env);
18205        break;
18206    case NM_MAQ_SA_W_PHL:
18207        check_dsp(ctx);
18208        gen_helper_maq_sa_w_phl(t0, v1_t, v0_t, cpu_env);
18209        break;
18210    default:
18211        gen_reserved_instruction(ctx);
18212        break;
18213    }
18214
18215    tcg_temp_free_i32(t0);
18216
18217    tcg_temp_free(v0_t);
18218    tcg_temp_free(v1_t);
18219}
18220
18221
18222static void gen_pool32axf_1_nanomips_insn(DisasContext *ctx, uint32_t opc,
18223                                    int ret, int v1, int v2)
18224{
18225    int16_t imm;
18226    TCGv t0 = tcg_temp_new();
18227    TCGv t1 = tcg_temp_new();
18228    TCGv v0_t = tcg_temp_new();
18229
18230    gen_load_gpr(v0_t, v1);
18231
18232    switch (opc) {
18233    case NM_POOL32AXF_1_0:
18234        check_dsp(ctx);
18235        switch (extract32(ctx->opcode, 12, 2)) {
18236        case NM_MFHI:
18237            gen_HILO(ctx, OPC_MFHI, v2 >> 3, ret);
18238            break;
18239        case NM_MFLO:
18240            gen_HILO(ctx, OPC_MFLO, v2 >> 3, ret);
18241            break;
18242        case NM_MTHI:
18243            gen_HILO(ctx, OPC_MTHI, v2 >> 3, v1);
18244            break;
18245        case NM_MTLO:
18246            gen_HILO(ctx, OPC_MTLO, v2 >> 3, v1);
18247            break;
18248        }
18249        break;
18250    case NM_POOL32AXF_1_1:
18251        check_dsp(ctx);
18252        switch (extract32(ctx->opcode, 12, 2)) {
18253        case NM_MTHLIP:
18254            tcg_gen_movi_tl(t0, v2);
18255            gen_helper_mthlip(t0, v0_t, cpu_env);
18256            break;
18257        case NM_SHILOV:
18258            tcg_gen_movi_tl(t0, v2 >> 3);
18259            gen_helper_shilo(t0, v0_t, cpu_env);
18260            break;
18261        default:
18262            gen_reserved_instruction(ctx);
18263            break;
18264        }
18265        break;
18266    case NM_POOL32AXF_1_3:
18267        check_dsp(ctx);
18268        imm = extract32(ctx->opcode, 14, 7);
18269        switch (extract32(ctx->opcode, 12, 2)) {
18270        case NM_RDDSP:
18271            tcg_gen_movi_tl(t0, imm);
18272            gen_helper_rddsp(t0, t0, cpu_env);
18273            gen_store_gpr(t0, ret);
18274            break;
18275        case NM_WRDSP:
18276            gen_load_gpr(t0, ret);
18277            tcg_gen_movi_tl(t1, imm);
18278            gen_helper_wrdsp(t0, t1, cpu_env);
18279            break;
18280        case NM_EXTP:
18281            tcg_gen_movi_tl(t0, v2 >> 3);
18282            tcg_gen_movi_tl(t1, v1);
18283            gen_helper_extp(t0, t0, t1, cpu_env);
18284            gen_store_gpr(t0, ret);
18285            break;
18286        case NM_EXTPDP:
18287            tcg_gen_movi_tl(t0, v2 >> 3);
18288            tcg_gen_movi_tl(t1, v1);
18289            gen_helper_extpdp(t0, t0, t1, cpu_env);
18290            gen_store_gpr(t0, ret);
18291            break;
18292        }
18293        break;
18294    case NM_POOL32AXF_1_4:
18295        check_dsp(ctx);
18296        tcg_gen_movi_tl(t0, v2 >> 2);
18297        switch (extract32(ctx->opcode, 12, 1)) {
18298        case NM_SHLL_QB:
18299            gen_helper_shll_qb(t0, t0, v0_t, cpu_env);
18300            gen_store_gpr(t0, ret);
18301            break;
18302        case NM_SHRL_QB:
18303            gen_helper_shrl_qb(t0, t0, v0_t);
18304            gen_store_gpr(t0, ret);
18305            break;
18306        }
18307        break;
18308    case NM_POOL32AXF_1_5:
18309        opc = extract32(ctx->opcode, 12, 2);
18310        gen_pool32axf_1_5_nanomips_insn(ctx, opc, ret, v1, v2);
18311        break;
18312    case NM_POOL32AXF_1_7:
18313        check_dsp(ctx);
18314        tcg_gen_movi_tl(t0, v2 >> 3);
18315        tcg_gen_movi_tl(t1, v1);
18316        switch (extract32(ctx->opcode, 12, 2)) {
18317        case NM_EXTR_W:
18318            gen_helper_extr_w(t0, t0, t1, cpu_env);
18319            gen_store_gpr(t0, ret);
18320            break;
18321        case NM_EXTR_R_W:
18322            gen_helper_extr_r_w(t0, t0, t1, cpu_env);
18323            gen_store_gpr(t0, ret);
18324            break;
18325        case NM_EXTR_RS_W:
18326            gen_helper_extr_rs_w(t0, t0, t1, cpu_env);
18327            gen_store_gpr(t0, ret);
18328            break;
18329        case NM_EXTR_S_H:
18330            gen_helper_extr_s_h(t0, t0, t1, cpu_env);
18331            gen_store_gpr(t0, ret);
18332            break;
18333        }
18334        break;
18335    default:
18336        gen_reserved_instruction(ctx);
18337        break;
18338    }
18339
18340    tcg_temp_free(t0);
18341    tcg_temp_free(t1);
18342    tcg_temp_free(v0_t);
18343}
18344
18345static void gen_pool32axf_2_multiply(DisasContext *ctx, uint32_t opc,
18346                                    TCGv v0, TCGv v1, int rd)
18347{
18348    TCGv_i32 t0;
18349
18350    t0 = tcg_temp_new_i32();
18351
18352    tcg_gen_movi_i32(t0, rd >> 3);
18353
18354    switch (opc) {
18355    case NM_POOL32AXF_2_0_7:
18356        switch (extract32(ctx->opcode, 9, 3)) {
18357        case NM_DPA_W_PH:
18358            check_dsp_r2(ctx);
18359            gen_helper_dpa_w_ph(t0, v1, v0, cpu_env);
18360            break;
18361        case NM_DPAQ_S_W_PH:
18362            check_dsp(ctx);
18363            gen_helper_dpaq_s_w_ph(t0, v1, v0, cpu_env);
18364            break;
18365        case NM_DPS_W_PH:
18366            check_dsp_r2(ctx);
18367            gen_helper_dps_w_ph(t0, v1, v0, cpu_env);
18368            break;
18369        case NM_DPSQ_S_W_PH:
18370            check_dsp(ctx);
18371            gen_helper_dpsq_s_w_ph(t0, v1, v0, cpu_env);
18372            break;
18373        default:
18374            gen_reserved_instruction(ctx);
18375            break;
18376        }
18377        break;
18378    case NM_POOL32AXF_2_8_15:
18379        switch (extract32(ctx->opcode, 9, 3)) {
18380        case NM_DPAX_W_PH:
18381            check_dsp_r2(ctx);
18382            gen_helper_dpax_w_ph(t0, v0, v1, cpu_env);
18383            break;
18384        case NM_DPAQ_SA_L_W:
18385            check_dsp(ctx);
18386            gen_helper_dpaq_sa_l_w(t0, v0, v1, cpu_env);
18387            break;
18388        case NM_DPSX_W_PH:
18389            check_dsp_r2(ctx);
18390            gen_helper_dpsx_w_ph(t0, v0, v1, cpu_env);
18391            break;
18392        case NM_DPSQ_SA_L_W:
18393            check_dsp(ctx);
18394            gen_helper_dpsq_sa_l_w(t0, v0, v1, cpu_env);
18395            break;
18396        default:
18397            gen_reserved_instruction(ctx);
18398            break;
18399        }
18400        break;
18401    case NM_POOL32AXF_2_16_23:
18402        switch (extract32(ctx->opcode, 9, 3)) {
18403        case NM_DPAU_H_QBL:
18404            check_dsp(ctx);
18405            gen_helper_dpau_h_qbl(t0, v0, v1, cpu_env);
18406            break;
18407        case NM_DPAQX_S_W_PH:
18408            check_dsp_r2(ctx);
18409            gen_helper_dpaqx_s_w_ph(t0, v0, v1, cpu_env);
18410            break;
18411        case NM_DPSU_H_QBL:
18412            check_dsp(ctx);
18413            gen_helper_dpsu_h_qbl(t0, v0, v1, cpu_env);
18414            break;
18415        case NM_DPSQX_S_W_PH:
18416            check_dsp_r2(ctx);
18417            gen_helper_dpsqx_s_w_ph(t0, v0, v1, cpu_env);
18418            break;
18419        case NM_MULSA_W_PH:
18420            check_dsp_r2(ctx);
18421            gen_helper_mulsa_w_ph(t0, v0, v1, cpu_env);
18422            break;
18423        default:
18424            gen_reserved_instruction(ctx);
18425            break;
18426        }
18427        break;
18428    case NM_POOL32AXF_2_24_31:
18429        switch (extract32(ctx->opcode, 9, 3)) {
18430        case NM_DPAU_H_QBR:
18431            check_dsp(ctx);
18432            gen_helper_dpau_h_qbr(t0, v1, v0, cpu_env);
18433            break;
18434        case NM_DPAQX_SA_W_PH:
18435            check_dsp_r2(ctx);
18436            gen_helper_dpaqx_sa_w_ph(t0, v1, v0, cpu_env);
18437            break;
18438        case NM_DPSU_H_QBR:
18439            check_dsp(ctx);
18440            gen_helper_dpsu_h_qbr(t0, v1, v0, cpu_env);
18441            break;
18442        case NM_DPSQX_SA_W_PH:
18443            check_dsp_r2(ctx);
18444            gen_helper_dpsqx_sa_w_ph(t0, v1, v0, cpu_env);
18445            break;
18446        case NM_MULSAQ_S_W_PH:
18447            check_dsp(ctx);
18448            gen_helper_mulsaq_s_w_ph(t0, v1, v0, cpu_env);
18449            break;
18450        default:
18451            gen_reserved_instruction(ctx);
18452            break;
18453        }
18454        break;
18455    default:
18456        gen_reserved_instruction(ctx);
18457        break;
18458    }
18459
18460    tcg_temp_free_i32(t0);
18461}
18462
18463static void gen_pool32axf_2_nanomips_insn(DisasContext *ctx, uint32_t opc,
18464                                          int rt, int rs, int rd)
18465{
18466    int ret = rt;
18467    TCGv t0 = tcg_temp_new();
18468    TCGv t1 = tcg_temp_new();
18469    TCGv v0_t = tcg_temp_new();
18470    TCGv v1_t = tcg_temp_new();
18471
18472    gen_load_gpr(v0_t, rt);
18473    gen_load_gpr(v1_t, rs);
18474
18475    switch (opc) {
18476    case NM_POOL32AXF_2_0_7:
18477        switch (extract32(ctx->opcode, 9, 3)) {
18478        case NM_DPA_W_PH:
18479        case NM_DPAQ_S_W_PH:
18480        case NM_DPS_W_PH:
18481        case NM_DPSQ_S_W_PH:
18482            gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18483            break;
18484        case NM_BALIGN:
18485            check_dsp_r2(ctx);
18486            if (rt != 0) {
18487                gen_load_gpr(t0, rs);
18488                rd &= 3;
18489                if (rd != 0 && rd != 2) {
18490                    tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 8 * rd);
18491                    tcg_gen_ext32u_tl(t0, t0);
18492                    tcg_gen_shri_tl(t0, t0, 8 * (4 - rd));
18493                    tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
18494                }
18495                tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
18496            }
18497            break;
18498        case NM_MADD:
18499            check_dsp(ctx);
18500            {
18501                int acc = extract32(ctx->opcode, 14, 2);
18502                TCGv_i64 t2 = tcg_temp_new_i64();
18503                TCGv_i64 t3 = tcg_temp_new_i64();
18504
18505                gen_load_gpr(t0, rt);
18506                gen_load_gpr(t1, rs);
18507                tcg_gen_ext_tl_i64(t2, t0);
18508                tcg_gen_ext_tl_i64(t3, t1);
18509                tcg_gen_mul_i64(t2, t2, t3);
18510                tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18511                tcg_gen_add_i64(t2, t2, t3);
18512                tcg_temp_free_i64(t3);
18513                gen_move_low32(cpu_LO[acc], t2);
18514                gen_move_high32(cpu_HI[acc], t2);
18515                tcg_temp_free_i64(t2);
18516            }
18517            break;
18518        case NM_MULT:
18519            check_dsp(ctx);
18520            {
18521                int acc = extract32(ctx->opcode, 14, 2);
18522                TCGv_i32 t2 = tcg_temp_new_i32();
18523                TCGv_i32 t3 = tcg_temp_new_i32();
18524
18525                gen_load_gpr(t0, rs);
18526                gen_load_gpr(t1, rt);
18527                tcg_gen_trunc_tl_i32(t2, t0);
18528                tcg_gen_trunc_tl_i32(t3, t1);
18529                tcg_gen_muls2_i32(t2, t3, t2, t3);
18530                tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
18531                tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
18532                tcg_temp_free_i32(t2);
18533                tcg_temp_free_i32(t3);
18534            }
18535            break;
18536        case NM_EXTRV_W:
18537            check_dsp(ctx);
18538            gen_load_gpr(v1_t, rs);
18539            tcg_gen_movi_tl(t0, rd >> 3);
18540            gen_helper_extr_w(t0, t0, v1_t, cpu_env);
18541            gen_store_gpr(t0, ret);
18542            break;
18543        }
18544        break;
18545    case NM_POOL32AXF_2_8_15:
18546        switch (extract32(ctx->opcode, 9, 3)) {
18547        case NM_DPAX_W_PH:
18548        case NM_DPAQ_SA_L_W:
18549        case NM_DPSX_W_PH:
18550        case NM_DPSQ_SA_L_W:
18551            gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18552            break;
18553        case NM_MADDU:
18554            check_dsp(ctx);
18555            {
18556                int acc = extract32(ctx->opcode, 14, 2);
18557                TCGv_i64 t2 = tcg_temp_new_i64();
18558                TCGv_i64 t3 = tcg_temp_new_i64();
18559
18560                gen_load_gpr(t0, rs);
18561                gen_load_gpr(t1, rt);
18562                tcg_gen_ext32u_tl(t0, t0);
18563                tcg_gen_ext32u_tl(t1, t1);
18564                tcg_gen_extu_tl_i64(t2, t0);
18565                tcg_gen_extu_tl_i64(t3, t1);
18566                tcg_gen_mul_i64(t2, t2, t3);
18567                tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18568                tcg_gen_add_i64(t2, t2, t3);
18569                tcg_temp_free_i64(t3);
18570                gen_move_low32(cpu_LO[acc], t2);
18571                gen_move_high32(cpu_HI[acc], t2);
18572                tcg_temp_free_i64(t2);
18573            }
18574            break;
18575        case NM_MULTU:
18576            check_dsp(ctx);
18577            {
18578                int acc = extract32(ctx->opcode, 14, 2);
18579                TCGv_i32 t2 = tcg_temp_new_i32();
18580                TCGv_i32 t3 = tcg_temp_new_i32();
18581
18582                gen_load_gpr(t0, rs);
18583                gen_load_gpr(t1, rt);
18584                tcg_gen_trunc_tl_i32(t2, t0);
18585                tcg_gen_trunc_tl_i32(t3, t1);
18586                tcg_gen_mulu2_i32(t2, t3, t2, t3);
18587                tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
18588                tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
18589                tcg_temp_free_i32(t2);
18590                tcg_temp_free_i32(t3);
18591            }
18592            break;
18593        case NM_EXTRV_R_W:
18594            check_dsp(ctx);
18595            tcg_gen_movi_tl(t0, rd >> 3);
18596            gen_helper_extr_r_w(t0, t0, v1_t, cpu_env);
18597            gen_store_gpr(t0, ret);
18598            break;
18599        default:
18600            gen_reserved_instruction(ctx);
18601            break;
18602        }
18603        break;
18604    case NM_POOL32AXF_2_16_23:
18605        switch (extract32(ctx->opcode, 9, 3)) {
18606        case NM_DPAU_H_QBL:
18607        case NM_DPAQX_S_W_PH:
18608        case NM_DPSU_H_QBL:
18609        case NM_DPSQX_S_W_PH:
18610        case NM_MULSA_W_PH:
18611            gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18612            break;
18613        case NM_EXTPV:
18614            check_dsp(ctx);
18615            tcg_gen_movi_tl(t0, rd >> 3);
18616            gen_helper_extp(t0, t0, v1_t, cpu_env);
18617            gen_store_gpr(t0, ret);
18618            break;
18619        case NM_MSUB:
18620            check_dsp(ctx);
18621            {
18622                int acc = extract32(ctx->opcode, 14, 2);
18623                TCGv_i64 t2 = tcg_temp_new_i64();
18624                TCGv_i64 t3 = tcg_temp_new_i64();
18625
18626                gen_load_gpr(t0, rs);
18627                gen_load_gpr(t1, rt);
18628                tcg_gen_ext_tl_i64(t2, t0);
18629                tcg_gen_ext_tl_i64(t3, t1);
18630                tcg_gen_mul_i64(t2, t2, t3);
18631                tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18632                tcg_gen_sub_i64(t2, t3, t2);
18633                tcg_temp_free_i64(t3);
18634                gen_move_low32(cpu_LO[acc], t2);
18635                gen_move_high32(cpu_HI[acc], t2);
18636                tcg_temp_free_i64(t2);
18637            }
18638            break;
18639        case NM_EXTRV_RS_W:
18640            check_dsp(ctx);
18641            tcg_gen_movi_tl(t0, rd >> 3);
18642            gen_helper_extr_rs_w(t0, t0, v1_t, cpu_env);
18643            gen_store_gpr(t0, ret);
18644            break;
18645        }
18646        break;
18647    case NM_POOL32AXF_2_24_31:
18648        switch (extract32(ctx->opcode, 9, 3)) {
18649        case NM_DPAU_H_QBR:
18650        case NM_DPAQX_SA_W_PH:
18651        case NM_DPSU_H_QBR:
18652        case NM_DPSQX_SA_W_PH:
18653        case NM_MULSAQ_S_W_PH:
18654            gen_pool32axf_2_multiply(ctx, opc, v0_t, v1_t, rd);
18655            break;
18656        case NM_EXTPDPV:
18657            check_dsp(ctx);
18658            tcg_gen_movi_tl(t0, rd >> 3);
18659            gen_helper_extpdp(t0, t0, v1_t, cpu_env);
18660            gen_store_gpr(t0, ret);
18661            break;
18662        case NM_MSUBU:
18663            check_dsp(ctx);
18664            {
18665                int acc = extract32(ctx->opcode, 14, 2);
18666                TCGv_i64 t2 = tcg_temp_new_i64();
18667                TCGv_i64 t3 = tcg_temp_new_i64();
18668
18669                gen_load_gpr(t0, rs);
18670                gen_load_gpr(t1, rt);
18671                tcg_gen_ext32u_tl(t0, t0);
18672                tcg_gen_ext32u_tl(t1, t1);
18673                tcg_gen_extu_tl_i64(t2, t0);
18674                tcg_gen_extu_tl_i64(t3, t1);
18675                tcg_gen_mul_i64(t2, t2, t3);
18676                tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
18677                tcg_gen_sub_i64(t2, t3, t2);
18678                tcg_temp_free_i64(t3);
18679                gen_move_low32(cpu_LO[acc], t2);
18680                gen_move_high32(cpu_HI[acc], t2);
18681                tcg_temp_free_i64(t2);
18682            }
18683            break;
18684        case NM_EXTRV_S_H:
18685            check_dsp(ctx);
18686            tcg_gen_movi_tl(t0, rd >> 3);
18687            gen_helper_extr_s_h(t0, t0, v0_t, cpu_env);
18688            gen_store_gpr(t0, ret);
18689            break;
18690        }
18691        break;
18692    default:
18693        gen_reserved_instruction(ctx);
18694        break;
18695    }
18696
18697    tcg_temp_free(t0);
18698    tcg_temp_free(t1);
18699
18700    tcg_temp_free(v0_t);
18701    tcg_temp_free(v1_t);
18702}
18703
18704static void gen_pool32axf_4_nanomips_insn(DisasContext *ctx, uint32_t opc,
18705                                          int rt, int rs)
18706{
18707    int ret = rt;
18708    TCGv t0 = tcg_temp_new();
18709    TCGv v0_t = tcg_temp_new();
18710
18711    gen_load_gpr(v0_t, rs);
18712
18713    switch (opc) {
18714    case NM_ABSQ_S_QB:
18715        check_dsp_r2(ctx);
18716        gen_helper_absq_s_qb(v0_t, v0_t, cpu_env);
18717        gen_store_gpr(v0_t, ret);
18718        break;
18719    case NM_ABSQ_S_PH:
18720        check_dsp(ctx);
18721        gen_helper_absq_s_ph(v0_t, v0_t, cpu_env);
18722        gen_store_gpr(v0_t, ret);
18723        break;
18724    case NM_ABSQ_S_W:
18725        check_dsp(ctx);
18726        gen_helper_absq_s_w(v0_t, v0_t, cpu_env);
18727        gen_store_gpr(v0_t, ret);
18728        break;
18729    case NM_PRECEQ_W_PHL:
18730        check_dsp(ctx);
18731        tcg_gen_andi_tl(v0_t, v0_t, 0xFFFF0000);
18732        tcg_gen_ext32s_tl(v0_t, v0_t);
18733        gen_store_gpr(v0_t, ret);
18734        break;
18735    case NM_PRECEQ_W_PHR:
18736        check_dsp(ctx);
18737        tcg_gen_andi_tl(v0_t, v0_t, 0x0000FFFF);
18738        tcg_gen_shli_tl(v0_t, v0_t, 16);
18739        tcg_gen_ext32s_tl(v0_t, v0_t);
18740        gen_store_gpr(v0_t, ret);
18741        break;
18742    case NM_PRECEQU_PH_QBL:
18743        check_dsp(ctx);
18744        gen_helper_precequ_ph_qbl(v0_t, v0_t);
18745        gen_store_gpr(v0_t, ret);
18746        break;
18747    case NM_PRECEQU_PH_QBR:
18748        check_dsp(ctx);
18749        gen_helper_precequ_ph_qbr(v0_t, v0_t);
18750        gen_store_gpr(v0_t, ret);
18751        break;
18752    case NM_PRECEQU_PH_QBLA:
18753        check_dsp(ctx);
18754        gen_helper_precequ_ph_qbla(v0_t, v0_t);
18755        gen_store_gpr(v0_t, ret);
18756        break;
18757    case NM_PRECEQU_PH_QBRA:
18758        check_dsp(ctx);
18759        gen_helper_precequ_ph_qbra(v0_t, v0_t);
18760        gen_store_gpr(v0_t, ret);
18761        break;
18762    case NM_PRECEU_PH_QBL:
18763        check_dsp(ctx);
18764        gen_helper_preceu_ph_qbl(v0_t, v0_t);
18765        gen_store_gpr(v0_t, ret);
18766        break;
18767    case NM_PRECEU_PH_QBR:
18768        check_dsp(ctx);
18769        gen_helper_preceu_ph_qbr(v0_t, v0_t);
18770        gen_store_gpr(v0_t, ret);
18771        break;
18772    case NM_PRECEU_PH_QBLA:
18773        check_dsp(ctx);
18774        gen_helper_preceu_ph_qbla(v0_t, v0_t);
18775        gen_store_gpr(v0_t, ret);
18776        break;
18777    case NM_PRECEU_PH_QBRA:
18778        check_dsp(ctx);
18779        gen_helper_preceu_ph_qbra(v0_t, v0_t);
18780        gen_store_gpr(v0_t, ret);
18781        break;
18782    case NM_REPLV_PH:
18783        check_dsp(ctx);
18784        tcg_gen_ext16u_tl(v0_t, v0_t);
18785        tcg_gen_shli_tl(t0, v0_t, 16);
18786        tcg_gen_or_tl(v0_t, v0_t, t0);
18787        tcg_gen_ext32s_tl(v0_t, v0_t);
18788        gen_store_gpr(v0_t, ret);
18789        break;
18790    case NM_REPLV_QB:
18791        check_dsp(ctx);
18792        tcg_gen_ext8u_tl(v0_t, v0_t);
18793        tcg_gen_shli_tl(t0, v0_t, 8);
18794        tcg_gen_or_tl(v0_t, v0_t, t0);
18795        tcg_gen_shli_tl(t0, v0_t, 16);
18796        tcg_gen_or_tl(v0_t, v0_t, t0);
18797        tcg_gen_ext32s_tl(v0_t, v0_t);
18798        gen_store_gpr(v0_t, ret);
18799        break;
18800    case NM_BITREV:
18801        check_dsp(ctx);
18802        gen_helper_bitrev(v0_t, v0_t);
18803        gen_store_gpr(v0_t, ret);
18804        break;
18805    case NM_INSV:
18806        check_dsp(ctx);
18807        {
18808            TCGv tv0 = tcg_temp_new();
18809
18810            gen_load_gpr(tv0, rt);
18811            gen_helper_insv(v0_t, cpu_env, v0_t, tv0);
18812            gen_store_gpr(v0_t, ret);
18813            tcg_temp_free(tv0);
18814        }
18815        break;
18816    case NM_RADDU_W_QB:
18817        check_dsp(ctx);
18818        gen_helper_raddu_w_qb(v0_t, v0_t);
18819        gen_store_gpr(v0_t, ret);
18820        break;
18821    case NM_BITSWAP:
18822        gen_bitswap(ctx, OPC_BITSWAP, ret, rs);
18823        break;
18824    case NM_CLO:
18825        check_nms(ctx);
18826        gen_cl(ctx, OPC_CLO, ret, rs);
18827        break;
18828    case NM_CLZ:
18829        check_nms(ctx);
18830        gen_cl(ctx, OPC_CLZ, ret, rs);
18831        break;
18832    case NM_WSBH:
18833        gen_bshfl(ctx, OPC_WSBH, ret, rs);
18834        break;
18835    default:
18836        gen_reserved_instruction(ctx);
18837        break;
18838    }
18839
18840    tcg_temp_free(v0_t);
18841    tcg_temp_free(t0);
18842}
18843
18844static void gen_pool32axf_7_nanomips_insn(DisasContext *ctx, uint32_t opc,
18845                                          int rt, int rs, int rd)
18846{
18847    TCGv t0 = tcg_temp_new();
18848    TCGv rs_t = tcg_temp_new();
18849
18850    gen_load_gpr(rs_t, rs);
18851
18852    switch (opc) {
18853    case NM_SHRA_R_QB:
18854        check_dsp_r2(ctx);
18855        tcg_gen_movi_tl(t0, rd >> 2);
18856        switch (extract32(ctx->opcode, 12, 1)) {
18857        case 0:
18858            /* NM_SHRA_QB */
18859            gen_helper_shra_qb(t0, t0, rs_t);
18860            gen_store_gpr(t0, rt);
18861            break;
18862        case 1:
18863            /* NM_SHRA_R_QB */
18864            gen_helper_shra_r_qb(t0, t0, rs_t);
18865            gen_store_gpr(t0, rt);
18866            break;
18867        }
18868        break;
18869    case NM_SHRL_PH:
18870        check_dsp_r2(ctx);
18871        tcg_gen_movi_tl(t0, rd >> 1);
18872        gen_helper_shrl_ph(t0, t0, rs_t);
18873        gen_store_gpr(t0, rt);
18874        break;
18875    case NM_REPL_QB:
18876        check_dsp(ctx);
18877        {
18878            int16_t imm;
18879            target_long result;
18880            imm = extract32(ctx->opcode, 13, 8);
18881            result = (uint32_t)imm << 24 |
18882                     (uint32_t)imm << 16 |
18883                     (uint32_t)imm << 8  |
18884                     (uint32_t)imm;
18885            result = (int32_t)result;
18886            tcg_gen_movi_tl(t0, result);
18887            gen_store_gpr(t0, rt);
18888        }
18889        break;
18890    default:
18891        gen_reserved_instruction(ctx);
18892        break;
18893    }
18894    tcg_temp_free(t0);
18895    tcg_temp_free(rs_t);
18896}
18897
18898
18899static void gen_pool32axf_nanomips_insn(CPUMIPSState *env, DisasContext *ctx)
18900{
18901    int rt = extract32(ctx->opcode, 21, 5);
18902    int rs = extract32(ctx->opcode, 16, 5);
18903    int rd = extract32(ctx->opcode, 11, 5);
18904
18905    switch (extract32(ctx->opcode, 6, 3)) {
18906    case NM_POOL32AXF_1:
18907        {
18908            int32_t op1 = extract32(ctx->opcode, 9, 3);
18909            gen_pool32axf_1_nanomips_insn(ctx, op1, rt, rs, rd);
18910        }
18911        break;
18912    case NM_POOL32AXF_2:
18913        {
18914            int32_t op1 = extract32(ctx->opcode, 12, 2);
18915            gen_pool32axf_2_nanomips_insn(ctx, op1, rt, rs, rd);
18916        }
18917        break;
18918    case NM_POOL32AXF_4:
18919        {
18920            int32_t op1 = extract32(ctx->opcode, 9, 7);
18921            gen_pool32axf_4_nanomips_insn(ctx, op1, rt, rs);
18922        }
18923        break;
18924    case NM_POOL32AXF_5:
18925        switch (extract32(ctx->opcode, 9, 7)) {
18926#ifndef CONFIG_USER_ONLY
18927        case NM_TLBP:
18928            gen_cp0(env, ctx, OPC_TLBP, 0, 0);
18929            break;
18930        case NM_TLBR:
18931            gen_cp0(env, ctx, OPC_TLBR, 0, 0);
18932            break;
18933        case NM_TLBWI:
18934            gen_cp0(env, ctx, OPC_TLBWI, 0, 0);
18935            break;
18936        case NM_TLBWR:
18937            gen_cp0(env, ctx, OPC_TLBWR, 0, 0);
18938            break;
18939        case NM_TLBINV:
18940            gen_cp0(env, ctx, OPC_TLBINV, 0, 0);
18941            break;
18942        case NM_TLBINVF:
18943            gen_cp0(env, ctx, OPC_TLBINVF, 0, 0);
18944            break;
18945        case NM_DI:
18946            check_cp0_enabled(ctx);
18947            {
18948                TCGv t0 = tcg_temp_new();
18949
18950                save_cpu_state(ctx, 1);
18951                gen_helper_di(t0, cpu_env);
18952                gen_store_gpr(t0, rt);
18953            /* Stop translation as we may have switched the execution mode */
18954                ctx->base.is_jmp = DISAS_STOP;
18955                tcg_temp_free(t0);
18956            }
18957            break;
18958        case NM_EI:
18959            check_cp0_enabled(ctx);
18960            {
18961                TCGv t0 = tcg_temp_new();
18962
18963                save_cpu_state(ctx, 1);
18964                gen_helper_ei(t0, cpu_env);
18965                gen_store_gpr(t0, rt);
18966            /* Stop translation as we may have switched the execution mode */
18967                ctx->base.is_jmp = DISAS_STOP;
18968                tcg_temp_free(t0);
18969            }
18970            break;
18971        case NM_RDPGPR:
18972            gen_load_srsgpr(rs, rt);
18973            break;
18974        case NM_WRPGPR:
18975            gen_store_srsgpr(rs, rt);
18976            break;
18977        case NM_WAIT:
18978            gen_cp0(env, ctx, OPC_WAIT, 0, 0);
18979            break;
18980        case NM_DERET:
18981            gen_cp0(env, ctx, OPC_DERET, 0, 0);
18982            break;
18983        case NM_ERETX:
18984            gen_cp0(env, ctx, OPC_ERET, 0, 0);
18985            break;
18986#endif
18987        default:
18988            gen_reserved_instruction(ctx);
18989            break;
18990        }
18991        break;
18992    case NM_POOL32AXF_7:
18993        {
18994            int32_t op1 = extract32(ctx->opcode, 9, 3);
18995            gen_pool32axf_7_nanomips_insn(ctx, op1, rt, rs, rd);
18996        }
18997        break;
18998    default:
18999        gen_reserved_instruction(ctx);
19000        break;
19001    }
19002}
19003
19004/* Immediate Value Compact Branches */
19005static void gen_compute_imm_branch(DisasContext *ctx, uint32_t opc,
19006                                   int rt, int32_t imm, int32_t offset)
19007{
19008    TCGCond cond = TCG_COND_ALWAYS;
19009    TCGv t0 = tcg_temp_new();
19010    TCGv t1 = tcg_temp_new();
19011
19012    gen_load_gpr(t0, rt);
19013    tcg_gen_movi_tl(t1, imm);
19014    ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19015
19016    /* Load needed operands and calculate btarget */
19017    switch (opc) {
19018    case NM_BEQIC:
19019        if (rt == 0 && imm == 0) {
19020            /* Unconditional branch */
19021        } else if (rt == 0 && imm != 0) {
19022            /* Treat as NOP */
19023            goto out;
19024        } else {
19025            cond = TCG_COND_EQ;
19026        }
19027        break;
19028    case NM_BBEQZC:
19029    case NM_BBNEZC:
19030        check_nms(ctx);
19031        if (imm >= 32 && !(ctx->hflags & MIPS_HFLAG_64)) {
19032            gen_reserved_instruction(ctx);
19033            goto out;
19034        } else if (rt == 0 && opc == NM_BBEQZC) {
19035            /* Unconditional branch */
19036        } else if (rt == 0 && opc == NM_BBNEZC) {
19037            /* Treat as NOP */
19038            goto out;
19039        } else {
19040            tcg_gen_shri_tl(t0, t0, imm);
19041            tcg_gen_andi_tl(t0, t0, 1);
19042            tcg_gen_movi_tl(t1, 0);
19043            if (opc == NM_BBEQZC) {
19044                cond = TCG_COND_EQ;
19045            } else {
19046                cond = TCG_COND_NE;
19047            }
19048        }
19049        break;
19050    case NM_BNEIC:
19051        if (rt == 0 && imm == 0) {
19052            /* Treat as NOP */
19053            goto out;
19054        } else if (rt == 0 && imm != 0) {
19055            /* Unconditional branch */
19056        } else {
19057            cond = TCG_COND_NE;
19058        }
19059        break;
19060    case NM_BGEIC:
19061        if (rt == 0 && imm == 0) {
19062            /* Unconditional branch */
19063        } else  {
19064            cond = TCG_COND_GE;
19065        }
19066        break;
19067    case NM_BLTIC:
19068        cond = TCG_COND_LT;
19069        break;
19070    case NM_BGEIUC:
19071        if (rt == 0 && imm == 0) {
19072            /* Unconditional branch */
19073        } else  {
19074            cond = TCG_COND_GEU;
19075        }
19076        break;
19077    case NM_BLTIUC:
19078        cond = TCG_COND_LTU;
19079        break;
19080    default:
19081        MIPS_INVAL("Immediate Value Compact branch");
19082        gen_reserved_instruction(ctx);
19083        goto out;
19084    }
19085
19086    /* branch completion */
19087    clear_branch_hflags(ctx);
19088    ctx->base.is_jmp = DISAS_NORETURN;
19089
19090    if (cond == TCG_COND_ALWAYS) {
19091        /* Uncoditional compact branch */
19092        gen_goto_tb(ctx, 0, ctx->btarget);
19093    } else {
19094        /* Conditional compact branch */
19095        TCGLabel *fs = gen_new_label();
19096
19097        tcg_gen_brcond_tl(tcg_invert_cond(cond), t0, t1, fs);
19098
19099        gen_goto_tb(ctx, 1, ctx->btarget);
19100        gen_set_label(fs);
19101
19102        gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19103    }
19104
19105out:
19106    tcg_temp_free(t0);
19107    tcg_temp_free(t1);
19108}
19109
19110/* P.BALRSC type nanoMIPS R6 branches: BALRSC and BRSC */
19111static void gen_compute_nanomips_pbalrsc_branch(DisasContext *ctx, int rs,
19112                                                int rt)
19113{
19114    TCGv t0 = tcg_temp_new();
19115    TCGv t1 = tcg_temp_new();
19116
19117    /* load rs */
19118    gen_load_gpr(t0, rs);
19119
19120    /* link */
19121    if (rt != 0) {
19122        tcg_gen_movi_tl(cpu_gpr[rt], ctx->base.pc_next + 4);
19123    }
19124
19125    /* calculate btarget */
19126    tcg_gen_shli_tl(t0, t0, 1);
19127    tcg_gen_movi_tl(t1, ctx->base.pc_next + 4);
19128    gen_op_addr_add(ctx, btarget, t1, t0);
19129
19130    /* branch completion */
19131    clear_branch_hflags(ctx);
19132    ctx->base.is_jmp = DISAS_NORETURN;
19133
19134    /* unconditional branch to register */
19135    tcg_gen_mov_tl(cpu_PC, btarget);
19136    tcg_gen_lookup_and_goto_ptr();
19137
19138    tcg_temp_free(t0);
19139    tcg_temp_free(t1);
19140}
19141
19142/* nanoMIPS Branches */
19143static void gen_compute_compact_branch_nm(DisasContext *ctx, uint32_t opc,
19144                                       int rs, int rt, int32_t offset)
19145{
19146    int bcond_compute = 0;
19147    TCGv t0 = tcg_temp_new();
19148    TCGv t1 = tcg_temp_new();
19149
19150    /* Load needed operands and calculate btarget */
19151    switch (opc) {
19152    /* compact branch */
19153    case OPC_BGEC:
19154    case OPC_BLTC:
19155        gen_load_gpr(t0, rs);
19156        gen_load_gpr(t1, rt);
19157        bcond_compute = 1;
19158        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19159        break;
19160    case OPC_BGEUC:
19161    case OPC_BLTUC:
19162        if (rs == 0 || rs == rt) {
19163            /* OPC_BLEZALC, OPC_BGEZALC */
19164            /* OPC_BGTZALC, OPC_BLTZALC */
19165            tcg_gen_movi_tl(cpu_gpr[31], ctx->base.pc_next + 4);
19166        }
19167        gen_load_gpr(t0, rs);
19168        gen_load_gpr(t1, rt);
19169        bcond_compute = 1;
19170        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19171        break;
19172    case OPC_BC:
19173        ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19174        break;
19175    case OPC_BEQZC:
19176        if (rs != 0) {
19177            /* OPC_BEQZC, OPC_BNEZC */
19178            gen_load_gpr(t0, rs);
19179            bcond_compute = 1;
19180            ctx->btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19181        } else {
19182            /* OPC_JIC, OPC_JIALC */
19183            TCGv tbase = tcg_temp_new();
19184            TCGv toffset = tcg_temp_new();
19185
19186            gen_load_gpr(tbase, rt);
19187            tcg_gen_movi_tl(toffset, offset);
19188            gen_op_addr_add(ctx, btarget, tbase, toffset);
19189            tcg_temp_free(tbase);
19190            tcg_temp_free(toffset);
19191        }
19192        break;
19193    default:
19194        MIPS_INVAL("Compact branch/jump");
19195        gen_reserved_instruction(ctx);
19196        goto out;
19197    }
19198
19199    if (bcond_compute == 0) {
19200        /* Uncoditional compact branch */
19201        switch (opc) {
19202        case OPC_BC:
19203            gen_goto_tb(ctx, 0, ctx->btarget);
19204            break;
19205        default:
19206            MIPS_INVAL("Compact branch/jump");
19207            gen_reserved_instruction(ctx);
19208            goto out;
19209        }
19210    } else {
19211        /* Conditional compact branch */
19212        TCGLabel *fs = gen_new_label();
19213
19214        switch (opc) {
19215        case OPC_BGEUC:
19216            if (rs == 0 && rt != 0) {
19217                /* OPC_BLEZALC */
19218                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19219            } else if (rs != 0 && rt != 0 && rs == rt) {
19220                /* OPC_BGEZALC */
19221                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19222            } else {
19223                /* OPC_BGEUC */
19224                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GEU), t0, t1, fs);
19225            }
19226            break;
19227        case OPC_BLTUC:
19228            if (rs == 0 && rt != 0) {
19229                /* OPC_BGTZALC */
19230                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19231            } else if (rs != 0 && rt != 0 && rs == rt) {
19232                /* OPC_BLTZALC */
19233                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19234            } else {
19235                /* OPC_BLTUC */
19236                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LTU), t0, t1, fs);
19237            }
19238            break;
19239        case OPC_BGEC:
19240            if (rs == 0 && rt != 0) {
19241                /* OPC_BLEZC */
19242                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LE), t1, 0, fs);
19243            } else if (rs != 0 && rt != 0 && rs == rt) {
19244                /* OPC_BGEZC */
19245                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GE), t1, 0, fs);
19246            } else {
19247                /* OPC_BGEC */
19248                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_GE), t0, t1, fs);
19249            }
19250            break;
19251        case OPC_BLTC:
19252            if (rs == 0 && rt != 0) {
19253                /* OPC_BGTZC */
19254                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_GT), t1, 0, fs);
19255            } else if (rs != 0 && rt != 0 && rs == rt) {
19256                /* OPC_BLTZC */
19257                tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_LT), t1, 0, fs);
19258            } else {
19259                /* OPC_BLTC */
19260                tcg_gen_brcond_tl(tcg_invert_cond(TCG_COND_LT), t0, t1, fs);
19261            }
19262            break;
19263        case OPC_BEQZC:
19264            tcg_gen_brcondi_tl(tcg_invert_cond(TCG_COND_EQ), t0, 0, fs);
19265            break;
19266        default:
19267            MIPS_INVAL("Compact conditional branch/jump");
19268            gen_reserved_instruction(ctx);
19269            goto out;
19270        }
19271
19272        /* branch completion */
19273        clear_branch_hflags(ctx);
19274        ctx->base.is_jmp = DISAS_NORETURN;
19275
19276        /* Generating branch here as compact branches don't have delay slot */
19277        gen_goto_tb(ctx, 1, ctx->btarget);
19278        gen_set_label(fs);
19279
19280        gen_goto_tb(ctx, 0, ctx->base.pc_next + 4);
19281    }
19282
19283out:
19284    tcg_temp_free(t0);
19285    tcg_temp_free(t1);
19286}
19287
19288
19289/* nanoMIPS CP1 Branches */
19290static void gen_compute_branch_cp1_nm(DisasContext *ctx, uint32_t op,
19291                                   int32_t ft, int32_t offset)
19292{
19293    target_ulong btarget;
19294    TCGv_i64 t0 = tcg_temp_new_i64();
19295
19296    gen_load_fpr64(ctx, t0, ft);
19297    tcg_gen_andi_i64(t0, t0, 1);
19298
19299    btarget = addr_add(ctx, ctx->base.pc_next + 4, offset);
19300
19301    switch (op) {
19302    case NM_BC1EQZC:
19303        tcg_gen_xori_i64(t0, t0, 1);
19304        ctx->hflags |= MIPS_HFLAG_BC;
19305        break;
19306    case NM_BC1NEZC:
19307        /* t0 already set */
19308        ctx->hflags |= MIPS_HFLAG_BC;
19309        break;
19310    default:
19311        MIPS_INVAL("cp1 cond branch");
19312        gen_reserved_instruction(ctx);
19313        goto out;
19314    }
19315
19316    tcg_gen_trunc_i64_tl(bcond, t0);
19317
19318    ctx->btarget = btarget;
19319
19320out:
19321    tcg_temp_free_i64(t0);
19322}
19323
19324
19325static void gen_p_lsx(DisasContext *ctx, int rd, int rs, int rt)
19326{
19327    TCGv t0, t1;
19328    t0 = tcg_temp_new();
19329    t1 = tcg_temp_new();
19330
19331    gen_load_gpr(t0, rs);
19332    gen_load_gpr(t1, rt);
19333
19334    if ((extract32(ctx->opcode, 6, 1)) == 1) {
19335        /* PP.LSXS instructions require shifting */
19336        switch (extract32(ctx->opcode, 7, 4)) {
19337        case NM_SHXS:
19338            check_nms(ctx);
19339            /* fall through */
19340        case NM_LHXS:
19341        case NM_LHUXS:
19342            tcg_gen_shli_tl(t0, t0, 1);
19343            break;
19344        case NM_SWXS:
19345            check_nms(ctx);
19346            /* fall through */
19347        case NM_LWXS:
19348        case NM_LWC1XS:
19349        case NM_SWC1XS:
19350            tcg_gen_shli_tl(t0, t0, 2);
19351            break;
19352        case NM_LDC1XS:
19353        case NM_SDC1XS:
19354            tcg_gen_shli_tl(t0, t0, 3);
19355            break;
19356        }
19357    }
19358    gen_op_addr_add(ctx, t0, t0, t1);
19359
19360    switch (extract32(ctx->opcode, 7, 4)) {
19361    case NM_LBX:
19362        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19363                           MO_SB);
19364        gen_store_gpr(t0, rd);
19365        break;
19366    case NM_LHX:
19367    /*case NM_LHXS:*/
19368        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19369                           MO_TESW);
19370        gen_store_gpr(t0, rd);
19371        break;
19372    case NM_LWX:
19373    /*case NM_LWXS:*/
19374        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19375                           MO_TESL);
19376        gen_store_gpr(t0, rd);
19377        break;
19378    case NM_LBUX:
19379        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19380                           MO_UB);
19381        gen_store_gpr(t0, rd);
19382        break;
19383    case NM_LHUX:
19384    /*case NM_LHUXS:*/
19385        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx,
19386                           MO_TEUW);
19387        gen_store_gpr(t0, rd);
19388        break;
19389    case NM_SBX:
19390        check_nms(ctx);
19391        gen_load_gpr(t1, rd);
19392        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19393                           MO_8);
19394        break;
19395    case NM_SHX:
19396    /*case NM_SHXS:*/
19397        check_nms(ctx);
19398        gen_load_gpr(t1, rd);
19399        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19400                           MO_TEUW);
19401        break;
19402    case NM_SWX:
19403    /*case NM_SWXS:*/
19404        check_nms(ctx);
19405        gen_load_gpr(t1, rd);
19406        tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx,
19407                           MO_TEUL);
19408        break;
19409    case NM_LWC1X:
19410    /*case NM_LWC1XS:*/
19411    case NM_LDC1X:
19412    /*case NM_LDC1XS:*/
19413    case NM_SWC1X:
19414    /*case NM_SWC1XS:*/
19415    case NM_SDC1X:
19416    /*case NM_SDC1XS:*/
19417        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
19418            check_cp1_enabled(ctx);
19419            switch (extract32(ctx->opcode, 7, 4)) {
19420            case NM_LWC1X:
19421            /*case NM_LWC1XS:*/
19422                gen_flt_ldst(ctx, OPC_LWC1, rd, t0);
19423                break;
19424            case NM_LDC1X:
19425            /*case NM_LDC1XS:*/
19426                gen_flt_ldst(ctx, OPC_LDC1, rd, t0);
19427                break;
19428            case NM_SWC1X:
19429            /*case NM_SWC1XS:*/
19430                gen_flt_ldst(ctx, OPC_SWC1, rd, t0);
19431                break;
19432            case NM_SDC1X:
19433            /*case NM_SDC1XS:*/
19434                gen_flt_ldst(ctx, OPC_SDC1, rd, t0);
19435                break;
19436            }
19437        } else {
19438            generate_exception_err(ctx, EXCP_CpU, 1);
19439        }
19440        break;
19441    default:
19442        gen_reserved_instruction(ctx);
19443        break;
19444    }
19445
19446    tcg_temp_free(t0);
19447    tcg_temp_free(t1);
19448}
19449
19450static void gen_pool32f_nanomips_insn(DisasContext *ctx)
19451{
19452    int rt, rs, rd;
19453
19454    rt = extract32(ctx->opcode, 21, 5);
19455    rs = extract32(ctx->opcode, 16, 5);
19456    rd = extract32(ctx->opcode, 11, 5);
19457
19458    if (!(ctx->CP0_Config1 & (1 << CP0C1_FP))) {
19459        gen_reserved_instruction(ctx);
19460        return;
19461    }
19462    check_cp1_enabled(ctx);
19463    switch (extract32(ctx->opcode, 0, 3)) {
19464    case NM_POOL32F_0:
19465        switch (extract32(ctx->opcode, 3, 7)) {
19466        case NM_RINT_S:
19467            gen_farith(ctx, OPC_RINT_S, 0, rt, rs, 0);
19468            break;
19469        case NM_RINT_D:
19470            gen_farith(ctx, OPC_RINT_D, 0, rt, rs, 0);
19471            break;
19472        case NM_CLASS_S:
19473            gen_farith(ctx, OPC_CLASS_S, 0, rt, rs, 0);
19474            break;
19475        case NM_CLASS_D:
19476            gen_farith(ctx, OPC_CLASS_D, 0, rt, rs, 0);
19477            break;
19478        case NM_ADD_S:
19479            gen_farith(ctx, OPC_ADD_S, rt, rs, rd, 0);
19480            break;
19481        case NM_ADD_D:
19482            gen_farith(ctx, OPC_ADD_D, rt, rs, rd, 0);
19483            break;
19484        case NM_SUB_S:
19485            gen_farith(ctx, OPC_SUB_S, rt, rs, rd, 0);
19486            break;
19487        case NM_SUB_D:
19488            gen_farith(ctx, OPC_SUB_D, rt, rs, rd, 0);
19489            break;
19490        case NM_MUL_S:
19491            gen_farith(ctx, OPC_MUL_S, rt, rs, rd, 0);
19492            break;
19493        case NM_MUL_D:
19494            gen_farith(ctx, OPC_MUL_D, rt, rs, rd, 0);
19495            break;
19496        case NM_DIV_S:
19497            gen_farith(ctx, OPC_DIV_S, rt, rs, rd, 0);
19498            break;
19499        case NM_DIV_D:
19500            gen_farith(ctx, OPC_DIV_D, rt, rs, rd, 0);
19501            break;
19502        case NM_SELEQZ_S:
19503            gen_sel_s(ctx, OPC_SELEQZ_S, rd, rt, rs);
19504            break;
19505        case NM_SELEQZ_D:
19506            gen_sel_d(ctx, OPC_SELEQZ_D, rd, rt, rs);
19507            break;
19508        case NM_SELNEZ_S:
19509            gen_sel_s(ctx, OPC_SELNEZ_S, rd, rt, rs);
19510            break;
19511        case NM_SELNEZ_D:
19512            gen_sel_d(ctx, OPC_SELNEZ_D, rd, rt, rs);
19513            break;
19514        case NM_SEL_S:
19515            gen_sel_s(ctx, OPC_SEL_S, rd, rt, rs);
19516            break;
19517        case NM_SEL_D:
19518            gen_sel_d(ctx, OPC_SEL_D, rd, rt, rs);
19519            break;
19520        case NM_MADDF_S:
19521            gen_farith(ctx, OPC_MADDF_S, rt, rs, rd, 0);
19522            break;
19523        case NM_MADDF_D:
19524            gen_farith(ctx, OPC_MADDF_D, rt, rs, rd, 0);
19525            break;
19526        case NM_MSUBF_S:
19527            gen_farith(ctx, OPC_MSUBF_S, rt, rs, rd, 0);
19528            break;
19529        case NM_MSUBF_D:
19530            gen_farith(ctx, OPC_MSUBF_D, rt, rs, rd, 0);
19531            break;
19532        default:
19533            gen_reserved_instruction(ctx);
19534            break;
19535        }
19536        break;
19537    case NM_POOL32F_3:
19538        switch (extract32(ctx->opcode, 3, 3)) {
19539        case NM_MIN_FMT:
19540            switch (extract32(ctx->opcode, 9, 1)) {
19541            case FMT_SDPS_S:
19542                gen_farith(ctx, OPC_MIN_S, rt, rs, rd, 0);
19543                break;
19544            case FMT_SDPS_D:
19545                gen_farith(ctx, OPC_MIN_D, rt, rs, rd, 0);
19546                break;
19547            }
19548            break;
19549        case NM_MAX_FMT:
19550            switch (extract32(ctx->opcode, 9, 1)) {
19551            case FMT_SDPS_S:
19552                gen_farith(ctx, OPC_MAX_S, rt, rs, rd, 0);
19553                break;
19554            case FMT_SDPS_D:
19555                gen_farith(ctx, OPC_MAX_D, rt, rs, rd, 0);
19556                break;
19557            }
19558            break;
19559        case NM_MINA_FMT:
19560            switch (extract32(ctx->opcode, 9, 1)) {
19561            case FMT_SDPS_S:
19562                gen_farith(ctx, OPC_MINA_S, rt, rs, rd, 0);
19563                break;
19564            case FMT_SDPS_D:
19565                gen_farith(ctx, OPC_MINA_D, rt, rs, rd, 0);
19566                break;
19567            }
19568            break;
19569        case NM_MAXA_FMT:
19570            switch (extract32(ctx->opcode, 9, 1)) {
19571            case FMT_SDPS_S:
19572                gen_farith(ctx, OPC_MAXA_S, rt, rs, rd, 0);
19573                break;
19574            case FMT_SDPS_D:
19575                gen_farith(ctx, OPC_MAXA_D, rt, rs, rd, 0);
19576                break;
19577            }
19578            break;
19579        case NM_POOL32FXF:
19580            switch (extract32(ctx->opcode, 6, 8)) {
19581            case NM_CFC1:
19582                gen_cp1(ctx, OPC_CFC1, rt, rs);
19583                break;
19584            case NM_CTC1:
19585                gen_cp1(ctx, OPC_CTC1, rt, rs);
19586                break;
19587            case NM_MFC1:
19588                gen_cp1(ctx, OPC_MFC1, rt, rs);
19589                break;
19590            case NM_MTC1:
19591                gen_cp1(ctx, OPC_MTC1, rt, rs);
19592                break;
19593            case NM_MFHC1:
19594                gen_cp1(ctx, OPC_MFHC1, rt, rs);
19595                break;
19596            case NM_MTHC1:
19597                gen_cp1(ctx, OPC_MTHC1, rt, rs);
19598                break;
19599            case NM_CVT_S_PL:
19600                gen_farith(ctx, OPC_CVT_S_PL, -1, rs, rt, 0);
19601                break;
19602            case NM_CVT_S_PU:
19603                gen_farith(ctx, OPC_CVT_S_PU, -1, rs, rt, 0);
19604                break;
19605            default:
19606                switch (extract32(ctx->opcode, 6, 9)) {
19607                case NM_CVT_L_S:
19608                    gen_farith(ctx, OPC_CVT_L_S, -1, rs, rt, 0);
19609                    break;
19610                case NM_CVT_L_D:
19611                    gen_farith(ctx, OPC_CVT_L_D, -1, rs, rt, 0);
19612                    break;
19613                case NM_CVT_W_S:
19614                    gen_farith(ctx, OPC_CVT_W_S, -1, rs, rt, 0);
19615                    break;
19616                case NM_CVT_W_D:
19617                    gen_farith(ctx, OPC_CVT_W_D, -1, rs, rt, 0);
19618                    break;
19619                case NM_RSQRT_S:
19620                    gen_farith(ctx, OPC_RSQRT_S, -1, rs, rt, 0);
19621                    break;
19622                case NM_RSQRT_D:
19623                    gen_farith(ctx, OPC_RSQRT_D, -1, rs, rt, 0);
19624                    break;
19625                case NM_SQRT_S:
19626                    gen_farith(ctx, OPC_SQRT_S, -1, rs, rt, 0);
19627                    break;
19628                case NM_SQRT_D:
19629                    gen_farith(ctx, OPC_SQRT_D, -1, rs, rt, 0);
19630                    break;
19631                case NM_RECIP_S:
19632                    gen_farith(ctx, OPC_RECIP_S, -1, rs, rt, 0);
19633                    break;
19634                case NM_RECIP_D:
19635                    gen_farith(ctx, OPC_RECIP_D, -1, rs, rt, 0);
19636                    break;
19637                case NM_FLOOR_L_S:
19638                    gen_farith(ctx, OPC_FLOOR_L_S, -1, rs, rt, 0);
19639                    break;
19640                case NM_FLOOR_L_D:
19641                    gen_farith(ctx, OPC_FLOOR_L_D, -1, rs, rt, 0);
19642                    break;
19643                case NM_FLOOR_W_S:
19644                    gen_farith(ctx, OPC_FLOOR_W_S, -1, rs, rt, 0);
19645                    break;
19646                case NM_FLOOR_W_D:
19647                    gen_farith(ctx, OPC_FLOOR_W_D, -1, rs, rt, 0);
19648                    break;
19649                case NM_CEIL_L_S:
19650                    gen_farith(ctx, OPC_CEIL_L_S, -1, rs, rt, 0);
19651                    break;
19652                case NM_CEIL_L_D:
19653                    gen_farith(ctx, OPC_CEIL_L_D, -1, rs, rt, 0);
19654                    break;
19655                case NM_CEIL_W_S:
19656                    gen_farith(ctx, OPC_CEIL_W_S, -1, rs, rt, 0);
19657                    break;
19658                case NM_CEIL_W_D:
19659                    gen_farith(ctx, OPC_CEIL_W_D, -1, rs, rt, 0);
19660                    break;
19661                case NM_TRUNC_L_S:
19662                    gen_farith(ctx, OPC_TRUNC_L_S, -1, rs, rt, 0);
19663                    break;
19664                case NM_TRUNC_L_D:
19665                    gen_farith(ctx, OPC_TRUNC_L_D, -1, rs, rt, 0);
19666                    break;
19667                case NM_TRUNC_W_S:
19668                    gen_farith(ctx, OPC_TRUNC_W_S, -1, rs, rt, 0);
19669                    break;
19670                case NM_TRUNC_W_D:
19671                    gen_farith(ctx, OPC_TRUNC_W_D, -1, rs, rt, 0);
19672                    break;
19673                case NM_ROUND_L_S:
19674                    gen_farith(ctx, OPC_ROUND_L_S, -1, rs, rt, 0);
19675                    break;
19676                case NM_ROUND_L_D:
19677                    gen_farith(ctx, OPC_ROUND_L_D, -1, rs, rt, 0);
19678                    break;
19679                case NM_ROUND_W_S:
19680                    gen_farith(ctx, OPC_ROUND_W_S, -1, rs, rt, 0);
19681                    break;
19682                case NM_ROUND_W_D:
19683                    gen_farith(ctx, OPC_ROUND_W_D, -1, rs, rt, 0);
19684                    break;
19685                case NM_MOV_S:
19686                    gen_farith(ctx, OPC_MOV_S, -1, rs, rt, 0);
19687                    break;
19688                case NM_MOV_D:
19689                    gen_farith(ctx, OPC_MOV_D, -1, rs, rt, 0);
19690                    break;
19691                case NM_ABS_S:
19692                    gen_farith(ctx, OPC_ABS_S, -1, rs, rt, 0);
19693                    break;
19694                case NM_ABS_D:
19695                    gen_farith(ctx, OPC_ABS_D, -1, rs, rt, 0);
19696                    break;
19697                case NM_NEG_S:
19698                    gen_farith(ctx, OPC_NEG_S, -1, rs, rt, 0);
19699                    break;
19700                case NM_NEG_D:
19701                    gen_farith(ctx, OPC_NEG_D, -1, rs, rt, 0);
19702                    break;
19703                case NM_CVT_D_S:
19704                    gen_farith(ctx, OPC_CVT_D_S, -1, rs, rt, 0);
19705                    break;
19706                case NM_CVT_D_W:
19707                    gen_farith(ctx, OPC_CVT_D_W, -1, rs, rt, 0);
19708                    break;
19709                case NM_CVT_D_L:
19710                    gen_farith(ctx, OPC_CVT_D_L, -1, rs, rt, 0);
19711                    break;
19712                case NM_CVT_S_D:
19713                    gen_farith(ctx, OPC_CVT_S_D, -1, rs, rt, 0);
19714                    break;
19715                case NM_CVT_S_W:
19716                    gen_farith(ctx, OPC_CVT_S_W, -1, rs, rt, 0);
19717                    break;
19718                case NM_CVT_S_L:
19719                    gen_farith(ctx, OPC_CVT_S_L, -1, rs, rt, 0);
19720                    break;
19721                default:
19722                    gen_reserved_instruction(ctx);
19723                    break;
19724                }
19725                break;
19726            }
19727            break;
19728        }
19729        break;
19730    case NM_POOL32F_5:
19731        switch (extract32(ctx->opcode, 3, 3)) {
19732        case NM_CMP_CONDN_S:
19733            gen_r6_cmp_s(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
19734            break;
19735        case NM_CMP_CONDN_D:
19736            gen_r6_cmp_d(ctx, extract32(ctx->opcode, 6, 5), rt, rs, rd);
19737            break;
19738        default:
19739            gen_reserved_instruction(ctx);
19740            break;
19741        }
19742        break;
19743    default:
19744        gen_reserved_instruction(ctx);
19745        break;
19746    }
19747}
19748
19749static void gen_pool32a5_nanomips_insn(DisasContext *ctx, int opc,
19750                                       int rd, int rs, int rt)
19751{
19752    int ret = rd;
19753    TCGv t0 = tcg_temp_new();
19754    TCGv v1_t = tcg_temp_new();
19755    TCGv v2_t = tcg_temp_new();
19756
19757    gen_load_gpr(v1_t, rs);
19758    gen_load_gpr(v2_t, rt);
19759
19760    switch (opc) {
19761    case NM_CMP_EQ_PH:
19762        check_dsp(ctx);
19763        gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
19764        break;
19765    case NM_CMP_LT_PH:
19766        check_dsp(ctx);
19767        gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
19768        break;
19769    case NM_CMP_LE_PH:
19770        check_dsp(ctx);
19771        gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
19772        break;
19773    case NM_CMPU_EQ_QB:
19774        check_dsp(ctx);
19775        gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
19776        break;
19777    case NM_CMPU_LT_QB:
19778        check_dsp(ctx);
19779        gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
19780        break;
19781    case NM_CMPU_LE_QB:
19782        check_dsp(ctx);
19783        gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
19784        break;
19785    case NM_CMPGU_EQ_QB:
19786        check_dsp(ctx);
19787        gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
19788        gen_store_gpr(v1_t, ret);
19789        break;
19790    case NM_CMPGU_LT_QB:
19791        check_dsp(ctx);
19792        gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
19793        gen_store_gpr(v1_t, ret);
19794        break;
19795    case NM_CMPGU_LE_QB:
19796        check_dsp(ctx);
19797        gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
19798        gen_store_gpr(v1_t, ret);
19799        break;
19800    case NM_CMPGDU_EQ_QB:
19801        check_dsp_r2(ctx);
19802        gen_helper_cmpgu_eq_qb(v1_t, v1_t, v2_t);
19803        tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
19804        gen_store_gpr(v1_t, ret);
19805        break;
19806    case NM_CMPGDU_LT_QB:
19807        check_dsp_r2(ctx);
19808        gen_helper_cmpgu_lt_qb(v1_t, v1_t, v2_t);
19809        tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
19810        gen_store_gpr(v1_t, ret);
19811        break;
19812    case NM_CMPGDU_LE_QB:
19813        check_dsp_r2(ctx);
19814        gen_helper_cmpgu_le_qb(v1_t, v1_t, v2_t);
19815        tcg_gen_deposit_tl(cpu_dspctrl, cpu_dspctrl, v1_t, 24, 4);
19816        gen_store_gpr(v1_t, ret);
19817        break;
19818    case NM_PACKRL_PH:
19819        check_dsp(ctx);
19820        gen_helper_packrl_ph(v1_t, v1_t, v2_t);
19821        gen_store_gpr(v1_t, ret);
19822        break;
19823    case NM_PICK_QB:
19824        check_dsp(ctx);
19825        gen_helper_pick_qb(v1_t, v1_t, v2_t, cpu_env);
19826        gen_store_gpr(v1_t, ret);
19827        break;
19828    case NM_PICK_PH:
19829        check_dsp(ctx);
19830        gen_helper_pick_ph(v1_t, v1_t, v2_t, cpu_env);
19831        gen_store_gpr(v1_t, ret);
19832        break;
19833    case NM_ADDQ_S_W:
19834        check_dsp(ctx);
19835        gen_helper_addq_s_w(v1_t, v1_t, v2_t, cpu_env);
19836        gen_store_gpr(v1_t, ret);
19837        break;
19838    case NM_SUBQ_S_W:
19839        check_dsp(ctx);
19840        gen_helper_subq_s_w(v1_t, v1_t, v2_t, cpu_env);
19841        gen_store_gpr(v1_t, ret);
19842        break;
19843    case NM_ADDSC:
19844        check_dsp(ctx);
19845        gen_helper_addsc(v1_t, v1_t, v2_t, cpu_env);
19846        gen_store_gpr(v1_t, ret);
19847        break;
19848    case NM_ADDWC:
19849        check_dsp(ctx);
19850        gen_helper_addwc(v1_t, v1_t, v2_t, cpu_env);
19851        gen_store_gpr(v1_t, ret);
19852        break;
19853    case NM_ADDQ_S_PH:
19854        check_dsp(ctx);
19855        switch (extract32(ctx->opcode, 10, 1)) {
19856        case 0:
19857            /* ADDQ_PH */
19858            gen_helper_addq_ph(v1_t, v1_t, v2_t, cpu_env);
19859            gen_store_gpr(v1_t, ret);
19860            break;
19861        case 1:
19862            /* ADDQ_S_PH */
19863            gen_helper_addq_s_ph(v1_t, v1_t, v2_t, cpu_env);
19864            gen_store_gpr(v1_t, ret);
19865            break;
19866        }
19867        break;
19868    case NM_ADDQH_R_PH:
19869        check_dsp_r2(ctx);
19870        switch (extract32(ctx->opcode, 10, 1)) {
19871        case 0:
19872            /* ADDQH_PH */
19873            gen_helper_addqh_ph(v1_t, v1_t, v2_t);
19874            gen_store_gpr(v1_t, ret);
19875            break;
19876        case 1:
19877            /* ADDQH_R_PH */
19878            gen_helper_addqh_r_ph(v1_t, v1_t, v2_t);
19879            gen_store_gpr(v1_t, ret);
19880            break;
19881        }
19882        break;
19883    case NM_ADDQH_R_W:
19884        check_dsp_r2(ctx);
19885        switch (extract32(ctx->opcode, 10, 1)) {
19886        case 0:
19887            /* ADDQH_W */
19888            gen_helper_addqh_w(v1_t, v1_t, v2_t);
19889            gen_store_gpr(v1_t, ret);
19890            break;
19891        case 1:
19892            /* ADDQH_R_W */
19893            gen_helper_addqh_r_w(v1_t, v1_t, v2_t);
19894            gen_store_gpr(v1_t, ret);
19895            break;
19896        }
19897        break;
19898    case NM_ADDU_S_QB:
19899        check_dsp(ctx);
19900        switch (extract32(ctx->opcode, 10, 1)) {
19901        case 0:
19902            /* ADDU_QB */
19903            gen_helper_addu_qb(v1_t, v1_t, v2_t, cpu_env);
19904            gen_store_gpr(v1_t, ret);
19905            break;
19906        case 1:
19907            /* ADDU_S_QB */
19908            gen_helper_addu_s_qb(v1_t, v1_t, v2_t, cpu_env);
19909            gen_store_gpr(v1_t, ret);
19910            break;
19911        }
19912        break;
19913    case NM_ADDU_S_PH:
19914        check_dsp_r2(ctx);
19915        switch (extract32(ctx->opcode, 10, 1)) {
19916        case 0:
19917            /* ADDU_PH */
19918            gen_helper_addu_ph(v1_t, v1_t, v2_t, cpu_env);
19919            gen_store_gpr(v1_t, ret);
19920            break;
19921        case 1:
19922            /* ADDU_S_PH */
19923            gen_helper_addu_s_ph(v1_t, v1_t, v2_t, cpu_env);
19924            gen_store_gpr(v1_t, ret);
19925            break;
19926        }
19927        break;
19928    case NM_ADDUH_R_QB:
19929        check_dsp_r2(ctx);
19930        switch (extract32(ctx->opcode, 10, 1)) {
19931        case 0:
19932            /* ADDUH_QB */
19933            gen_helper_adduh_qb(v1_t, v1_t, v2_t);
19934            gen_store_gpr(v1_t, ret);
19935            break;
19936        case 1:
19937            /* ADDUH_R_QB */
19938            gen_helper_adduh_r_qb(v1_t, v1_t, v2_t);
19939            gen_store_gpr(v1_t, ret);
19940            break;
19941        }
19942        break;
19943    case NM_SHRAV_R_PH:
19944        check_dsp(ctx);
19945        switch (extract32(ctx->opcode, 10, 1)) {
19946        case 0:
19947            /* SHRAV_PH */
19948            gen_helper_shra_ph(v1_t, v1_t, v2_t);
19949            gen_store_gpr(v1_t, ret);
19950            break;
19951        case 1:
19952            /* SHRAV_R_PH */
19953            gen_helper_shra_r_ph(v1_t, v1_t, v2_t);
19954            gen_store_gpr(v1_t, ret);
19955            break;
19956        }
19957        break;
19958    case NM_SHRAV_R_QB:
19959        check_dsp_r2(ctx);
19960        switch (extract32(ctx->opcode, 10, 1)) {
19961        case 0:
19962            /* SHRAV_QB */
19963            gen_helper_shra_qb(v1_t, v1_t, v2_t);
19964            gen_store_gpr(v1_t, ret);
19965            break;
19966        case 1:
19967            /* SHRAV_R_QB */
19968            gen_helper_shra_r_qb(v1_t, v1_t, v2_t);
19969            gen_store_gpr(v1_t, ret);
19970            break;
19971        }
19972        break;
19973    case NM_SUBQ_S_PH:
19974        check_dsp(ctx);
19975        switch (extract32(ctx->opcode, 10, 1)) {
19976        case 0:
19977            /* SUBQ_PH */
19978            gen_helper_subq_ph(v1_t, v1_t, v2_t, cpu_env);
19979            gen_store_gpr(v1_t, ret);
19980            break;
19981        case 1:
19982            /* SUBQ_S_PH */
19983            gen_helper_subq_s_ph(v1_t, v1_t, v2_t, cpu_env);
19984            gen_store_gpr(v1_t, ret);
19985            break;
19986        }
19987        break;
19988    case NM_SUBQH_R_PH:
19989        check_dsp_r2(ctx);
19990        switch (extract32(ctx->opcode, 10, 1)) {
19991        case 0:
19992            /* SUBQH_PH */
19993            gen_helper_subqh_ph(v1_t, v1_t, v2_t);
19994            gen_store_gpr(v1_t, ret);
19995            break;
19996        case 1:
19997            /* SUBQH_R_PH */
19998            gen_helper_subqh_r_ph(v1_t, v1_t, v2_t);
19999            gen_store_gpr(v1_t, ret);
20000            break;
20001        }
20002        break;
20003    case NM_SUBQH_R_W:
20004        check_dsp_r2(ctx);
20005        switch (extract32(ctx->opcode, 10, 1)) {
20006        case 0:
20007            /* SUBQH_W */
20008            gen_helper_subqh_w(v1_t, v1_t, v2_t);
20009            gen_store_gpr(v1_t, ret);
20010            break;
20011        case 1:
20012            /* SUBQH_R_W */
20013            gen_helper_subqh_r_w(v1_t, v1_t, v2_t);
20014            gen_store_gpr(v1_t, ret);
20015            break;
20016        }
20017        break;
20018    case NM_SUBU_S_QB:
20019        check_dsp(ctx);
20020        switch (extract32(ctx->opcode, 10, 1)) {
20021        case 0:
20022            /* SUBU_QB */
20023            gen_helper_subu_qb(v1_t, v1_t, v2_t, cpu_env);
20024            gen_store_gpr(v1_t, ret);
20025            break;
20026        case 1:
20027            /* SUBU_S_QB */
20028            gen_helper_subu_s_qb(v1_t, v1_t, v2_t, cpu_env);
20029            gen_store_gpr(v1_t, ret);
20030            break;
20031        }
20032        break;
20033    case NM_SUBU_S_PH:
20034        check_dsp_r2(ctx);
20035        switch (extract32(ctx->opcode, 10, 1)) {
20036        case 0:
20037            /* SUBU_PH */
20038            gen_helper_subu_ph(v1_t, v1_t, v2_t, cpu_env);
20039            gen_store_gpr(v1_t, ret);
20040            break;
20041        case 1:
20042            /* SUBU_S_PH */
20043            gen_helper_subu_s_ph(v1_t, v1_t, v2_t, cpu_env);
20044            gen_store_gpr(v1_t, ret);
20045            break;
20046        }
20047        break;
20048    case NM_SUBUH_R_QB:
20049        check_dsp_r2(ctx);
20050        switch (extract32(ctx->opcode, 10, 1)) {
20051        case 0:
20052            /* SUBUH_QB */
20053            gen_helper_subuh_qb(v1_t, v1_t, v2_t);
20054            gen_store_gpr(v1_t, ret);
20055            break;
20056        case 1:
20057            /* SUBUH_R_QB */
20058            gen_helper_subuh_r_qb(v1_t, v1_t, v2_t);
20059            gen_store_gpr(v1_t, ret);
20060            break;
20061        }
20062        break;
20063    case NM_SHLLV_S_PH:
20064        check_dsp(ctx);
20065        switch (extract32(ctx->opcode, 10, 1)) {
20066        case 0:
20067            /* SHLLV_PH */
20068            gen_helper_shll_ph(v1_t, v1_t, v2_t, cpu_env);
20069            gen_store_gpr(v1_t, ret);
20070            break;
20071        case 1:
20072            /* SHLLV_S_PH */
20073            gen_helper_shll_s_ph(v1_t, v1_t, v2_t, cpu_env);
20074            gen_store_gpr(v1_t, ret);
20075            break;
20076        }
20077        break;
20078    case NM_PRECR_SRA_R_PH_W:
20079        check_dsp_r2(ctx);
20080        switch (extract32(ctx->opcode, 10, 1)) {
20081        case 0:
20082            /* PRECR_SRA_PH_W */
20083            {
20084                TCGv_i32 sa_t = tcg_const_i32(rd);
20085                gen_helper_precr_sra_ph_w(v1_t, sa_t, v1_t,
20086                                          cpu_gpr[rt]);
20087                gen_store_gpr(v1_t, rt);
20088                tcg_temp_free_i32(sa_t);
20089            }
20090            break;
20091        case 1:
20092            /* PRECR_SRA_R_PH_W */
20093            {
20094                TCGv_i32 sa_t = tcg_const_i32(rd);
20095                gen_helper_precr_sra_r_ph_w(v1_t, sa_t, v1_t,
20096                                            cpu_gpr[rt]);
20097                gen_store_gpr(v1_t, rt);
20098                tcg_temp_free_i32(sa_t);
20099            }
20100            break;
20101       }
20102        break;
20103    case NM_MULEU_S_PH_QBL:
20104        check_dsp(ctx);
20105        gen_helper_muleu_s_ph_qbl(v1_t, v1_t, v2_t, cpu_env);
20106        gen_store_gpr(v1_t, ret);
20107        break;
20108    case NM_MULEU_S_PH_QBR:
20109        check_dsp(ctx);
20110        gen_helper_muleu_s_ph_qbr(v1_t, v1_t, v2_t, cpu_env);
20111        gen_store_gpr(v1_t, ret);
20112        break;
20113    case NM_MULQ_RS_PH:
20114        check_dsp(ctx);
20115        gen_helper_mulq_rs_ph(v1_t, v1_t, v2_t, cpu_env);
20116        gen_store_gpr(v1_t, ret);
20117        break;
20118    case NM_MULQ_S_PH:
20119        check_dsp_r2(ctx);
20120        gen_helper_mulq_s_ph(v1_t, v1_t, v2_t, cpu_env);
20121        gen_store_gpr(v1_t, ret);
20122        break;
20123    case NM_MULQ_RS_W:
20124        check_dsp_r2(ctx);
20125        gen_helper_mulq_rs_w(v1_t, v1_t, v2_t, cpu_env);
20126        gen_store_gpr(v1_t, ret);
20127        break;
20128    case NM_MULQ_S_W:
20129        check_dsp_r2(ctx);
20130        gen_helper_mulq_s_w(v1_t, v1_t, v2_t, cpu_env);
20131        gen_store_gpr(v1_t, ret);
20132        break;
20133    case NM_APPEND:
20134        check_dsp_r2(ctx);
20135        gen_load_gpr(t0, rs);
20136        if (rd != 0) {
20137            tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], rd, 32 - rd);
20138        }
20139        tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20140        break;
20141    case NM_MODSUB:
20142        check_dsp(ctx);
20143        gen_helper_modsub(v1_t, v1_t, v2_t);
20144        gen_store_gpr(v1_t, ret);
20145        break;
20146    case NM_SHRAV_R_W:
20147        check_dsp(ctx);
20148        gen_helper_shra_r_w(v1_t, v1_t, v2_t);
20149        gen_store_gpr(v1_t, ret);
20150        break;
20151    case NM_SHRLV_PH:
20152        check_dsp_r2(ctx);
20153        gen_helper_shrl_ph(v1_t, v1_t, v2_t);
20154        gen_store_gpr(v1_t, ret);
20155        break;
20156    case NM_SHRLV_QB:
20157        check_dsp(ctx);
20158        gen_helper_shrl_qb(v1_t, v1_t, v2_t);
20159        gen_store_gpr(v1_t, ret);
20160        break;
20161    case NM_SHLLV_QB:
20162        check_dsp(ctx);
20163        gen_helper_shll_qb(v1_t, v1_t, v2_t, cpu_env);
20164        gen_store_gpr(v1_t, ret);
20165        break;
20166    case NM_SHLLV_S_W:
20167        check_dsp(ctx);
20168        gen_helper_shll_s_w(v1_t, v1_t, v2_t, cpu_env);
20169        gen_store_gpr(v1_t, ret);
20170        break;
20171    case NM_SHILO:
20172        check_dsp(ctx);
20173        {
20174            TCGv tv0 = tcg_temp_new();
20175            TCGv tv1 = tcg_temp_new();
20176            int16_t imm = extract32(ctx->opcode, 16, 7);
20177
20178            tcg_gen_movi_tl(tv0, rd >> 3);
20179            tcg_gen_movi_tl(tv1, imm);
20180            gen_helper_shilo(tv0, tv1, cpu_env);
20181        }
20182        break;
20183    case NM_MULEQ_S_W_PHL:
20184        check_dsp(ctx);
20185        gen_helper_muleq_s_w_phl(v1_t, v1_t, v2_t, cpu_env);
20186        gen_store_gpr(v1_t, ret);
20187        break;
20188    case NM_MULEQ_S_W_PHR:
20189        check_dsp(ctx);
20190        gen_helper_muleq_s_w_phr(v1_t, v1_t, v2_t, cpu_env);
20191        gen_store_gpr(v1_t, ret);
20192        break;
20193    case NM_MUL_S_PH:
20194        check_dsp_r2(ctx);
20195        switch (extract32(ctx->opcode, 10, 1)) {
20196        case 0:
20197            /* MUL_PH */
20198            gen_helper_mul_ph(v1_t, v1_t, v2_t, cpu_env);
20199            gen_store_gpr(v1_t, ret);
20200            break;
20201        case 1:
20202            /* MUL_S_PH */
20203            gen_helper_mul_s_ph(v1_t, v1_t, v2_t, cpu_env);
20204            gen_store_gpr(v1_t, ret);
20205            break;
20206        }
20207        break;
20208    case NM_PRECR_QB_PH:
20209        check_dsp_r2(ctx);
20210        gen_helper_precr_qb_ph(v1_t, v1_t, v2_t);
20211        gen_store_gpr(v1_t, ret);
20212        break;
20213    case NM_PRECRQ_QB_PH:
20214        check_dsp(ctx);
20215        gen_helper_precrq_qb_ph(v1_t, v1_t, v2_t);
20216        gen_store_gpr(v1_t, ret);
20217        break;
20218    case NM_PRECRQ_PH_W:
20219        check_dsp(ctx);
20220        gen_helper_precrq_ph_w(v1_t, v1_t, v2_t);
20221        gen_store_gpr(v1_t, ret);
20222        break;
20223    case NM_PRECRQ_RS_PH_W:
20224        check_dsp(ctx);
20225        gen_helper_precrq_rs_ph_w(v1_t, v1_t, v2_t, cpu_env);
20226        gen_store_gpr(v1_t, ret);
20227        break;
20228    case NM_PRECRQU_S_QB_PH:
20229        check_dsp(ctx);
20230        gen_helper_precrqu_s_qb_ph(v1_t, v1_t, v2_t, cpu_env);
20231        gen_store_gpr(v1_t, ret);
20232        break;
20233    case NM_SHRA_R_W:
20234        check_dsp(ctx);
20235        tcg_gen_movi_tl(t0, rd);
20236        gen_helper_shra_r_w(v1_t, t0, v1_t);
20237        gen_store_gpr(v1_t, rt);
20238        break;
20239    case NM_SHRA_R_PH:
20240        check_dsp(ctx);
20241        tcg_gen_movi_tl(t0, rd >> 1);
20242        switch (extract32(ctx->opcode, 10, 1)) {
20243        case 0:
20244            /* SHRA_PH */
20245            gen_helper_shra_ph(v1_t, t0, v1_t);
20246            gen_store_gpr(v1_t, rt);
20247            break;
20248        case 1:
20249            /* SHRA_R_PH */
20250            gen_helper_shra_r_ph(v1_t, t0, v1_t);
20251            gen_store_gpr(v1_t, rt);
20252            break;
20253        }
20254        break;
20255    case NM_SHLL_S_PH:
20256        check_dsp(ctx);
20257        tcg_gen_movi_tl(t0, rd >> 1);
20258        switch (extract32(ctx->opcode, 10, 2)) {
20259        case 0:
20260            /* SHLL_PH */
20261            gen_helper_shll_ph(v1_t, t0, v1_t, cpu_env);
20262            gen_store_gpr(v1_t, rt);
20263            break;
20264        case 2:
20265            /* SHLL_S_PH */
20266            gen_helper_shll_s_ph(v1_t, t0, v1_t, cpu_env);
20267            gen_store_gpr(v1_t, rt);
20268            break;
20269        default:
20270            gen_reserved_instruction(ctx);
20271            break;
20272        }
20273        break;
20274    case NM_SHLL_S_W:
20275        check_dsp(ctx);
20276        tcg_gen_movi_tl(t0, rd);
20277        gen_helper_shll_s_w(v1_t, t0, v1_t, cpu_env);
20278        gen_store_gpr(v1_t, rt);
20279        break;
20280    case NM_REPL_PH:
20281        check_dsp(ctx);
20282        {
20283            int16_t imm;
20284            imm = sextract32(ctx->opcode, 11, 11);
20285            imm = (int16_t)(imm << 6) >> 6;
20286            if (rt != 0) {
20287                tcg_gen_movi_tl(cpu_gpr[rt], dup_const(MO_16, imm));
20288            }
20289        }
20290        break;
20291    default:
20292        gen_reserved_instruction(ctx);
20293        break;
20294    }
20295}
20296
20297static int decode_nanomips_32_48_opc(CPUMIPSState *env, DisasContext *ctx)
20298{
20299    uint16_t insn;
20300    uint32_t op;
20301    int rt, rs, rd;
20302    int offset;
20303    int imm;
20304
20305    insn = translator_lduw(env, ctx->base.pc_next + 2);
20306    ctx->opcode = (ctx->opcode << 16) | insn;
20307
20308    rt = extract32(ctx->opcode, 21, 5);
20309    rs = extract32(ctx->opcode, 16, 5);
20310    rd = extract32(ctx->opcode, 11, 5);
20311
20312    op = extract32(ctx->opcode, 26, 6);
20313    switch (op) {
20314    case NM_P_ADDIU:
20315        if (rt == 0) {
20316            /* P.RI */
20317            switch (extract32(ctx->opcode, 19, 2)) {
20318            case NM_SIGRIE:
20319            default:
20320                gen_reserved_instruction(ctx);
20321                break;
20322            case NM_P_SYSCALL:
20323                if ((extract32(ctx->opcode, 18, 1)) == NM_SYSCALL) {
20324                    generate_exception_end(ctx, EXCP_SYSCALL);
20325                } else {
20326                    gen_reserved_instruction(ctx);
20327                }
20328                break;
20329            case NM_BREAK:
20330                generate_exception_end(ctx, EXCP_BREAK);
20331                break;
20332            case NM_SDBBP:
20333                if (is_uhi(extract32(ctx->opcode, 0, 19))) {
20334                    gen_helper_do_semihosting(cpu_env);
20335                } else {
20336                    if (ctx->hflags & MIPS_HFLAG_SBRI) {
20337                        gen_reserved_instruction(ctx);
20338                    } else {
20339                        generate_exception_end(ctx, EXCP_DBp);
20340                    }
20341                }
20342                break;
20343            }
20344        } else {
20345            /* NM_ADDIU */
20346            imm = extract32(ctx->opcode, 0, 16);
20347            if (rs != 0) {
20348                tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], imm);
20349            } else {
20350                tcg_gen_movi_tl(cpu_gpr[rt], imm);
20351            }
20352            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20353        }
20354        break;
20355    case NM_ADDIUPC:
20356        if (rt != 0) {
20357            offset = sextract32(ctx->opcode, 0, 1) << 21 |
20358                     extract32(ctx->opcode, 1, 20) << 1;
20359            target_long addr = addr_add(ctx, ctx->base.pc_next + 4, offset);
20360            tcg_gen_movi_tl(cpu_gpr[rt], addr);
20361        }
20362        break;
20363    case NM_POOL32A:
20364        switch (ctx->opcode & 0x07) {
20365        case NM_POOL32A0:
20366            gen_pool32a0_nanomips_insn(env, ctx);
20367            break;
20368        case NM_POOL32A5:
20369            {
20370                int32_t op1 = extract32(ctx->opcode, 3, 7);
20371                gen_pool32a5_nanomips_insn(ctx, op1, rd, rs, rt);
20372            }
20373            break;
20374        case NM_POOL32A7:
20375            switch (extract32(ctx->opcode, 3, 3)) {
20376            case NM_P_LSX:
20377                gen_p_lsx(ctx, rd, rs, rt);
20378                break;
20379            case NM_LSA:
20380                /*
20381                 * In nanoMIPS, the shift field directly encodes the shift
20382                 * amount, meaning that the supported shift values are in
20383                 * the range 0 to 3 (instead of 1 to 4 in MIPSR6).
20384                 */
20385                gen_lsa(ctx, rd, rt, rs, extract32(ctx->opcode, 9, 2) - 1);
20386                break;
20387            case NM_EXTW:
20388                gen_ext(ctx, 32, rd, rs, rt, extract32(ctx->opcode, 6, 5));
20389                break;
20390            case NM_POOL32AXF:
20391                gen_pool32axf_nanomips_insn(env, ctx);
20392                break;
20393            default:
20394                gen_reserved_instruction(ctx);
20395                break;
20396            }
20397            break;
20398        default:
20399            gen_reserved_instruction(ctx);
20400            break;
20401        }
20402        break;
20403    case NM_P_GP_W:
20404        switch (ctx->opcode & 0x03) {
20405        case NM_ADDIUGP_W:
20406            if (rt != 0) {
20407                offset = extract32(ctx->opcode, 0, 21);
20408                gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], offset);
20409            }
20410            break;
20411        case NM_LWGP:
20412            gen_ld(ctx, OPC_LW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20413            break;
20414        case NM_SWGP:
20415            gen_st(ctx, OPC_SW, rt, 28, extract32(ctx->opcode, 2, 19) << 2);
20416            break;
20417        default:
20418            gen_reserved_instruction(ctx);
20419            break;
20420        }
20421        break;
20422    case NM_P48I:
20423        {
20424            insn = translator_lduw(env, ctx->base.pc_next + 4);
20425            target_long addr_off = extract32(ctx->opcode, 0, 16) | insn << 16;
20426            switch (extract32(ctx->opcode, 16, 5)) {
20427            case NM_LI48:
20428                check_nms(ctx);
20429                if (rt != 0) {
20430                    tcg_gen_movi_tl(cpu_gpr[rt], addr_off);
20431                }
20432                break;
20433            case NM_ADDIU48:
20434                check_nms(ctx);
20435                if (rt != 0) {
20436                    tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rt], addr_off);
20437                    tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
20438                }
20439                break;
20440            case NM_ADDIUGP48:
20441                check_nms(ctx);
20442                if (rt != 0) {
20443                    gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], addr_off);
20444                }
20445                break;
20446            case NM_ADDIUPC48:
20447                check_nms(ctx);
20448                if (rt != 0) {
20449                    target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20450                                                addr_off);
20451
20452                    tcg_gen_movi_tl(cpu_gpr[rt], addr);
20453                }
20454                break;
20455            case NM_LWPC48:
20456                check_nms(ctx);
20457                if (rt != 0) {
20458                    TCGv t0;
20459                    t0 = tcg_temp_new();
20460
20461                    target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20462                                                addr_off);
20463
20464                    tcg_gen_movi_tl(t0, addr);
20465                    tcg_gen_qemu_ld_tl(cpu_gpr[rt], t0, ctx->mem_idx, MO_TESL);
20466                    tcg_temp_free(t0);
20467                }
20468                break;
20469            case NM_SWPC48:
20470                check_nms(ctx);
20471                {
20472                    TCGv t0, t1;
20473                    t0 = tcg_temp_new();
20474                    t1 = tcg_temp_new();
20475
20476                    target_long addr = addr_add(ctx, ctx->base.pc_next + 6,
20477                                                addr_off);
20478
20479                    tcg_gen_movi_tl(t0, addr);
20480                    gen_load_gpr(t1, rt);
20481
20482                    tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUL);
20483
20484                    tcg_temp_free(t0);
20485                    tcg_temp_free(t1);
20486                }
20487                break;
20488            default:
20489                gen_reserved_instruction(ctx);
20490                break;
20491            }
20492            return 6;
20493        }
20494    case NM_P_U12:
20495        switch (extract32(ctx->opcode, 12, 4)) {
20496        case NM_ORI:
20497            gen_logic_imm(ctx, OPC_ORI, rt, rs, extract32(ctx->opcode, 0, 12));
20498            break;
20499        case NM_XORI:
20500            gen_logic_imm(ctx, OPC_XORI, rt, rs, extract32(ctx->opcode, 0, 12));
20501            break;
20502        case NM_ANDI:
20503            gen_logic_imm(ctx, OPC_ANDI, rt, rs, extract32(ctx->opcode, 0, 12));
20504            break;
20505        case NM_P_SR:
20506            switch (extract32(ctx->opcode, 20, 1)) {
20507            case NM_PP_SR:
20508                switch (ctx->opcode & 3) {
20509                case NM_SAVE:
20510                    gen_save(ctx, rt, extract32(ctx->opcode, 16, 4),
20511                             extract32(ctx->opcode, 2, 1),
20512                             extract32(ctx->opcode, 3, 9) << 3);
20513                    break;
20514                case NM_RESTORE:
20515                case NM_RESTORE_JRC:
20516                    gen_restore(ctx, rt, extract32(ctx->opcode, 16, 4),
20517                                extract32(ctx->opcode, 2, 1),
20518                                extract32(ctx->opcode, 3, 9) << 3);
20519                    if ((ctx->opcode & 3) == NM_RESTORE_JRC) {
20520                        gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
20521                    }
20522                    break;
20523                default:
20524                    gen_reserved_instruction(ctx);
20525                    break;
20526                }
20527                break;
20528            case NM_P_SR_F:
20529                gen_reserved_instruction(ctx);
20530                break;
20531            }
20532            break;
20533        case NM_SLTI:
20534            gen_slt_imm(ctx, OPC_SLTI, rt, rs, extract32(ctx->opcode, 0, 12));
20535            break;
20536        case NM_SLTIU:
20537            gen_slt_imm(ctx, OPC_SLTIU, rt, rs, extract32(ctx->opcode, 0, 12));
20538            break;
20539        case NM_SEQI:
20540            {
20541                TCGv t0 = tcg_temp_new();
20542
20543                imm = extract32(ctx->opcode, 0, 12);
20544                gen_load_gpr(t0, rs);
20545                tcg_gen_setcondi_tl(TCG_COND_EQ, t0, t0, imm);
20546                gen_store_gpr(t0, rt);
20547
20548                tcg_temp_free(t0);
20549            }
20550            break;
20551        case NM_ADDIUNEG:
20552            imm = (int16_t) extract32(ctx->opcode, 0, 12);
20553            gen_arith_imm(ctx, OPC_ADDIU, rt, rs, -imm);
20554            break;
20555        case NM_P_SHIFT:
20556            {
20557                int shift = extract32(ctx->opcode, 0, 5);
20558                switch (extract32(ctx->opcode, 5, 4)) {
20559                case NM_P_SLL:
20560                    if (rt == 0 && shift == 0) {
20561                        /* NOP */
20562                    } else if (rt == 0 && shift == 3) {
20563                        /* EHB - treat as NOP */
20564                    } else if (rt == 0 && shift == 5) {
20565                        /* PAUSE - treat as NOP */
20566                    } else if (rt == 0 && shift == 6) {
20567                        /* SYNC */
20568                        gen_sync(extract32(ctx->opcode, 16, 5));
20569                    } else {
20570                        /* SLL */
20571                        gen_shift_imm(ctx, OPC_SLL, rt, rs,
20572                                      extract32(ctx->opcode, 0, 5));
20573                    }
20574                    break;
20575                case NM_SRL:
20576                    gen_shift_imm(ctx, OPC_SRL, rt, rs,
20577                                  extract32(ctx->opcode, 0, 5));
20578                    break;
20579                case NM_SRA:
20580                    gen_shift_imm(ctx, OPC_SRA, rt, rs,
20581                                  extract32(ctx->opcode, 0, 5));
20582                    break;
20583                case NM_ROTR:
20584                    gen_shift_imm(ctx, OPC_ROTR, rt, rs,
20585                                  extract32(ctx->opcode, 0, 5));
20586                    break;
20587                }
20588            }
20589            break;
20590        case NM_P_ROTX:
20591            check_nms(ctx);
20592            if (rt != 0) {
20593                TCGv t0 = tcg_temp_new();
20594                TCGv_i32 shift = tcg_const_i32(extract32(ctx->opcode, 0, 5));
20595                TCGv_i32 shiftx = tcg_const_i32(extract32(ctx->opcode, 7, 4)
20596                                                << 1);
20597                TCGv_i32 stripe = tcg_const_i32(extract32(ctx->opcode, 6, 1));
20598
20599                gen_load_gpr(t0, rs);
20600                gen_helper_rotx(cpu_gpr[rt], t0, shift, shiftx, stripe);
20601                tcg_temp_free(t0);
20602
20603                tcg_temp_free_i32(shift);
20604                tcg_temp_free_i32(shiftx);
20605                tcg_temp_free_i32(stripe);
20606            }
20607            break;
20608        case NM_P_INS:
20609            switch (((ctx->opcode >> 10) & 2) |
20610                    (extract32(ctx->opcode, 5, 1))) {
20611            case NM_INS:
20612                check_nms(ctx);
20613                gen_bitops(ctx, OPC_INS, rt, rs, extract32(ctx->opcode, 0, 5),
20614                           extract32(ctx->opcode, 6, 5));
20615                break;
20616            default:
20617                gen_reserved_instruction(ctx);
20618                break;
20619            }
20620            break;
20621        case NM_P_EXT:
20622            switch (((ctx->opcode >> 10) & 2) |
20623                    (extract32(ctx->opcode, 5, 1))) {
20624            case NM_EXT:
20625                check_nms(ctx);
20626                gen_bitops(ctx, OPC_EXT, rt, rs, extract32(ctx->opcode, 0, 5),
20627                           extract32(ctx->opcode, 6, 5));
20628                break;
20629            default:
20630                gen_reserved_instruction(ctx);
20631                break;
20632            }
20633            break;
20634        default:
20635            gen_reserved_instruction(ctx);
20636            break;
20637        }
20638        break;
20639    case NM_POOL32F:
20640        gen_pool32f_nanomips_insn(ctx);
20641        break;
20642    case NM_POOL32S:
20643        break;
20644    case NM_P_LUI:
20645        switch (extract32(ctx->opcode, 1, 1)) {
20646        case NM_LUI:
20647            if (rt != 0) {
20648                tcg_gen_movi_tl(cpu_gpr[rt],
20649                                sextract32(ctx->opcode, 0, 1) << 31 |
20650                                extract32(ctx->opcode, 2, 10) << 21 |
20651                                extract32(ctx->opcode, 12, 9) << 12);
20652            }
20653            break;
20654        case NM_ALUIPC:
20655            if (rt != 0) {
20656                offset = sextract32(ctx->opcode, 0, 1) << 31 |
20657                         extract32(ctx->opcode, 2, 10) << 21 |
20658                         extract32(ctx->opcode, 12, 9) << 12;
20659                target_long addr;
20660                addr = ~0xFFF & addr_add(ctx, ctx->base.pc_next + 4, offset);
20661                tcg_gen_movi_tl(cpu_gpr[rt], addr);
20662            }
20663            break;
20664        }
20665        break;
20666    case NM_P_GP_BH:
20667        {
20668            uint32_t u = extract32(ctx->opcode, 0, 18);
20669
20670            switch (extract32(ctx->opcode, 18, 3)) {
20671            case NM_LBGP:
20672                gen_ld(ctx, OPC_LB, rt, 28, u);
20673                break;
20674            case NM_SBGP:
20675                gen_st(ctx, OPC_SB, rt, 28, u);
20676                break;
20677            case NM_LBUGP:
20678                gen_ld(ctx, OPC_LBU, rt, 28, u);
20679                break;
20680            case NM_ADDIUGP_B:
20681                if (rt != 0) {
20682                    gen_op_addr_addi(ctx, cpu_gpr[rt], cpu_gpr[28], u);
20683                }
20684                break;
20685            case NM_P_GP_LH:
20686                u &= ~1;
20687                switch (ctx->opcode & 1) {
20688                case NM_LHGP:
20689                    gen_ld(ctx, OPC_LH, rt, 28, u);
20690                    break;
20691                case NM_LHUGP:
20692                    gen_ld(ctx, OPC_LHU, rt, 28, u);
20693                    break;
20694                }
20695                break;
20696            case NM_P_GP_SH:
20697                u &= ~1;
20698                switch (ctx->opcode & 1) {
20699                case NM_SHGP:
20700                    gen_st(ctx, OPC_SH, rt, 28, u);
20701                    break;
20702                default:
20703                    gen_reserved_instruction(ctx);
20704                    break;
20705                }
20706                break;
20707            case NM_P_GP_CP1:
20708                u &= ~0x3;
20709                switch (ctx->opcode & 0x3) {
20710                case NM_LWC1GP:
20711                    gen_cop1_ldst(ctx, OPC_LWC1, rt, 28, u);
20712                    break;
20713                case NM_LDC1GP:
20714                    gen_cop1_ldst(ctx, OPC_LDC1, rt, 28, u);
20715                    break;
20716                case NM_SWC1GP:
20717                    gen_cop1_ldst(ctx, OPC_SWC1, rt, 28, u);
20718                    break;
20719                case NM_SDC1GP:
20720                    gen_cop1_ldst(ctx, OPC_SDC1, rt, 28, u);
20721                    break;
20722                }
20723                break;
20724            default:
20725                gen_reserved_instruction(ctx);
20726                break;
20727            }
20728        }
20729        break;
20730    case NM_P_LS_U12:
20731        {
20732            uint32_t u = extract32(ctx->opcode, 0, 12);
20733
20734            switch (extract32(ctx->opcode, 12, 4)) {
20735            case NM_P_PREFU12:
20736                if (rt == 31) {
20737                    /* SYNCI */
20738                    /*
20739                     * Break the TB to be able to sync copied instructions
20740                     * immediately.
20741                     */
20742                    ctx->base.is_jmp = DISAS_STOP;
20743                } else {
20744                    /* PREF */
20745                    /* Treat as NOP. */
20746                }
20747                break;
20748            case NM_LB:
20749                gen_ld(ctx, OPC_LB, rt, rs, u);
20750                break;
20751            case NM_LH:
20752                gen_ld(ctx, OPC_LH, rt, rs, u);
20753                break;
20754            case NM_LW:
20755                gen_ld(ctx, OPC_LW, rt, rs, u);
20756                break;
20757            case NM_LBU:
20758                gen_ld(ctx, OPC_LBU, rt, rs, u);
20759                break;
20760            case NM_LHU:
20761                gen_ld(ctx, OPC_LHU, rt, rs, u);
20762                break;
20763            case NM_SB:
20764                gen_st(ctx, OPC_SB, rt, rs, u);
20765                break;
20766            case NM_SH:
20767                gen_st(ctx, OPC_SH, rt, rs, u);
20768                break;
20769            case NM_SW:
20770                gen_st(ctx, OPC_SW, rt, rs, u);
20771                break;
20772            case NM_LWC1:
20773                gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, u);
20774                break;
20775            case NM_LDC1:
20776                gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, u);
20777                break;
20778            case NM_SWC1:
20779                gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, u);
20780                break;
20781            case NM_SDC1:
20782                gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, u);
20783                break;
20784            default:
20785                gen_reserved_instruction(ctx);
20786                break;
20787            }
20788        }
20789        break;
20790    case NM_P_LS_S9:
20791        {
20792            int32_t s = (sextract32(ctx->opcode, 15, 1) << 8) |
20793                        extract32(ctx->opcode, 0, 8);
20794
20795            switch (extract32(ctx->opcode, 8, 3)) {
20796            case NM_P_LS_S0:
20797                switch (extract32(ctx->opcode, 11, 4)) {
20798                case NM_LBS9:
20799                    gen_ld(ctx, OPC_LB, rt, rs, s);
20800                    break;
20801                case NM_LHS9:
20802                    gen_ld(ctx, OPC_LH, rt, rs, s);
20803                    break;
20804                case NM_LWS9:
20805                    gen_ld(ctx, OPC_LW, rt, rs, s);
20806                    break;
20807                case NM_LBUS9:
20808                    gen_ld(ctx, OPC_LBU, rt, rs, s);
20809                    break;
20810                case NM_LHUS9:
20811                    gen_ld(ctx, OPC_LHU, rt, rs, s);
20812                    break;
20813                case NM_SBS9:
20814                    gen_st(ctx, OPC_SB, rt, rs, s);
20815                    break;
20816                case NM_SHS9:
20817                    gen_st(ctx, OPC_SH, rt, rs, s);
20818                    break;
20819                case NM_SWS9:
20820                    gen_st(ctx, OPC_SW, rt, rs, s);
20821                    break;
20822                case NM_LWC1S9:
20823                    gen_cop1_ldst(ctx, OPC_LWC1, rt, rs, s);
20824                    break;
20825                case NM_LDC1S9:
20826                    gen_cop1_ldst(ctx, OPC_LDC1, rt, rs, s);
20827                    break;
20828                case NM_SWC1S9:
20829                    gen_cop1_ldst(ctx, OPC_SWC1, rt, rs, s);
20830                    break;
20831                case NM_SDC1S9:
20832                    gen_cop1_ldst(ctx, OPC_SDC1, rt, rs, s);
20833                    break;
20834                case NM_P_PREFS9:
20835                    if (rt == 31) {
20836                        /* SYNCI */
20837                        /*
20838                         * Break the TB to be able to sync copied instructions
20839                         * immediately.
20840                         */
20841                        ctx->base.is_jmp = DISAS_STOP;
20842                    } else {
20843                        /* PREF */
20844                        /* Treat as NOP. */
20845                    }
20846                    break;
20847                default:
20848                    gen_reserved_instruction(ctx);
20849                    break;
20850                }
20851                break;
20852            case NM_P_LS_S1:
20853                switch (extract32(ctx->opcode, 11, 4)) {
20854                case NM_UALH:
20855                case NM_UASH:
20856                    check_nms(ctx);
20857                    {
20858                        TCGv t0 = tcg_temp_new();
20859                        TCGv t1 = tcg_temp_new();
20860
20861                        gen_base_offset_addr(ctx, t0, rs, s);
20862
20863                        switch (extract32(ctx->opcode, 11, 4)) {
20864                        case NM_UALH:
20865                            tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW |
20866                                               MO_UNALN);
20867                            gen_store_gpr(t0, rt);
20868                            break;
20869                        case NM_UASH:
20870                            gen_load_gpr(t1, rt);
20871                            tcg_gen_qemu_st_tl(t1, t0, ctx->mem_idx, MO_TEUW |
20872                                               MO_UNALN);
20873                            break;
20874                        }
20875                        tcg_temp_free(t0);
20876                        tcg_temp_free(t1);
20877                    }
20878                    break;
20879                case NM_P_LL:
20880                    switch (ctx->opcode & 0x03) {
20881                    case NM_LL:
20882                        gen_ld(ctx, OPC_LL, rt, rs, s);
20883                        break;
20884                    case NM_LLWP:
20885                        check_xnp(ctx);
20886                        gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
20887                        break;
20888                    }
20889                    break;
20890                case NM_P_SC:
20891                    switch (ctx->opcode & 0x03) {
20892                    case NM_SC:
20893                        gen_st_cond(ctx, rt, rs, s, MO_TESL, false);
20894                        break;
20895                    case NM_SCWP:
20896                        check_xnp(ctx);
20897                        gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
20898                                 false);
20899                        break;
20900                    }
20901                    break;
20902                case NM_CACHE:
20903                    check_cp0_enabled(ctx);
20904                    if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
20905                        gen_cache_operation(ctx, rt, rs, s);
20906                    }
20907                    break;
20908                }
20909                break;
20910            case NM_P_LS_E0:
20911                switch (extract32(ctx->opcode, 11, 4)) {
20912                case NM_LBE:
20913                    check_eva(ctx);
20914                    check_cp0_enabled(ctx);
20915                    gen_ld(ctx, OPC_LBE, rt, rs, s);
20916                    break;
20917                case NM_SBE:
20918                    check_eva(ctx);
20919                    check_cp0_enabled(ctx);
20920                    gen_st(ctx, OPC_SBE, rt, rs, s);
20921                    break;
20922                case NM_LBUE:
20923                    check_eva(ctx);
20924                    check_cp0_enabled(ctx);
20925                    gen_ld(ctx, OPC_LBUE, rt, rs, s);
20926                    break;
20927                case NM_P_PREFE:
20928                    if (rt == 31) {
20929                        /* case NM_SYNCIE */
20930                        check_eva(ctx);
20931                        check_cp0_enabled(ctx);
20932                        /*
20933                         * Break the TB to be able to sync copied instructions
20934                         * immediately.
20935                         */
20936                        ctx->base.is_jmp = DISAS_STOP;
20937                    } else {
20938                        /* case NM_PREFE */
20939                        check_eva(ctx);
20940                        check_cp0_enabled(ctx);
20941                        /* Treat as NOP. */
20942                    }
20943                    break;
20944                case NM_LHE:
20945                    check_eva(ctx);
20946                    check_cp0_enabled(ctx);
20947                    gen_ld(ctx, OPC_LHE, rt, rs, s);
20948                    break;
20949                case NM_SHE:
20950                    check_eva(ctx);
20951                    check_cp0_enabled(ctx);
20952                    gen_st(ctx, OPC_SHE, rt, rs, s);
20953                    break;
20954                case NM_LHUE:
20955                    check_eva(ctx);
20956                    check_cp0_enabled(ctx);
20957                    gen_ld(ctx, OPC_LHUE, rt, rs, s);
20958                    break;
20959                case NM_CACHEE:
20960                    check_nms_dl_il_sl_tl_l2c(ctx);
20961                    gen_cache_operation(ctx, rt, rs, s);
20962                    break;
20963                case NM_LWE:
20964                    check_eva(ctx);
20965                    check_cp0_enabled(ctx);
20966                    gen_ld(ctx, OPC_LWE, rt, rs, s);
20967                    break;
20968                case NM_SWE:
20969                    check_eva(ctx);
20970                    check_cp0_enabled(ctx);
20971                    gen_st(ctx, OPC_SWE, rt, rs, s);
20972                    break;
20973                case NM_P_LLE:
20974                    switch (extract32(ctx->opcode, 2, 2)) {
20975                    case NM_LLE:
20976                        check_xnp(ctx);
20977                        check_eva(ctx);
20978                        check_cp0_enabled(ctx);
20979                        gen_ld(ctx, OPC_LLE, rt, rs, s);
20980                        break;
20981                    case NM_LLWPE:
20982                        check_xnp(ctx);
20983                        check_eva(ctx);
20984                        check_cp0_enabled(ctx);
20985                        gen_llwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5));
20986                        break;
20987                    default:
20988                        gen_reserved_instruction(ctx);
20989                        break;
20990                    }
20991                    break;
20992                case NM_P_SCE:
20993                    switch (extract32(ctx->opcode, 2, 2)) {
20994                    case NM_SCE:
20995                        check_xnp(ctx);
20996                        check_eva(ctx);
20997                        check_cp0_enabled(ctx);
20998                        gen_st_cond(ctx, rt, rs, s, MO_TESL, true);
20999                        break;
21000                    case NM_SCWPE:
21001                        check_xnp(ctx);
21002                        check_eva(ctx);
21003                        check_cp0_enabled(ctx);
21004                        gen_scwp(ctx, rs, 0, rt, extract32(ctx->opcode, 3, 5),
21005                                 true);
21006                        break;
21007                    default:
21008                        gen_reserved_instruction(ctx);
21009                        break;
21010                    }
21011                    break;
21012                }
21013                break;
21014            case NM_P_LS_WM:
21015            case NM_P_LS_UAWM:
21016                check_nms(ctx);
21017                {
21018                    int count = extract32(ctx->opcode, 12, 3);
21019                    int counter = 0;
21020
21021                    offset = sextract32(ctx->opcode, 15, 1) << 8 |
21022                             extract32(ctx->opcode, 0, 8);
21023                    TCGv va = tcg_temp_new();
21024                    TCGv t1 = tcg_temp_new();
21025                    MemOp memop = (extract32(ctx->opcode, 8, 3)) ==
21026                                      NM_P_LS_UAWM ? MO_UNALN : 0;
21027
21028                    count = (count == 0) ? 8 : count;
21029                    while (counter != count) {
21030                        int this_rt = ((rt + counter) & 0x1f) | (rt & 0x10);
21031                        int this_offset = offset + (counter << 2);
21032
21033                        gen_base_offset_addr(ctx, va, rs, this_offset);
21034
21035                        switch (extract32(ctx->opcode, 11, 1)) {
21036                        case NM_LWM:
21037                            tcg_gen_qemu_ld_tl(t1, va, ctx->mem_idx,
21038                                               memop | MO_TESL);
21039                            gen_store_gpr(t1, this_rt);
21040                            if ((this_rt == rs) &&
21041                                (counter != (count - 1))) {
21042                                /* UNPREDICTABLE */
21043                            }
21044                            break;
21045                        case NM_SWM:
21046                            this_rt = (rt == 0) ? 0 : this_rt;
21047                            gen_load_gpr(t1, this_rt);
21048                            tcg_gen_qemu_st_tl(t1, va, ctx->mem_idx,
21049                                               memop | MO_TEUL);
21050                            break;
21051                        }
21052                        counter++;
21053                    }
21054                    tcg_temp_free(va);
21055                    tcg_temp_free(t1);
21056                }
21057                break;
21058            default:
21059                gen_reserved_instruction(ctx);
21060                break;
21061            }
21062        }
21063        break;
21064    case NM_MOVE_BALC:
21065        check_nms(ctx);
21066        {
21067            TCGv t0 = tcg_temp_new();
21068            int32_t s = sextract32(ctx->opcode, 0, 1) << 21 |
21069                        extract32(ctx->opcode, 1, 20) << 1;
21070            rd = (extract32(ctx->opcode, 24, 1)) == 0 ? 4 : 5;
21071            rt = decode_gpr_gpr4_zero(extract32(ctx->opcode, 25, 1) << 3 |
21072                            extract32(ctx->opcode, 21, 3));
21073            gen_load_gpr(t0, rt);
21074            tcg_gen_mov_tl(cpu_gpr[rd], t0);
21075            gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21076            tcg_temp_free(t0);
21077        }
21078        break;
21079    case NM_P_BAL:
21080        {
21081            int32_t s = sextract32(ctx->opcode, 0, 1) << 25 |
21082                        extract32(ctx->opcode, 1, 24) << 1;
21083
21084            if ((extract32(ctx->opcode, 25, 1)) == 0) {
21085                /* BC */
21086                gen_compute_branch_nm(ctx, OPC_BEQ, 4, 0, 0, s);
21087            } else {
21088                /* BALC */
21089                gen_compute_branch_nm(ctx, OPC_BGEZAL, 4, 0, 0, s);
21090            }
21091        }
21092        break;
21093    case NM_P_J:
21094        switch (extract32(ctx->opcode, 12, 4)) {
21095        case NM_JALRC:
21096        case NM_JALRC_HB:
21097            gen_compute_branch_nm(ctx, OPC_JALR, 4, rs, rt, 0);
21098            break;
21099        case NM_P_BALRSC:
21100            gen_compute_nanomips_pbalrsc_branch(ctx, rs, rt);
21101            break;
21102        default:
21103            gen_reserved_instruction(ctx);
21104            break;
21105        }
21106        break;
21107    case NM_P_BR1:
21108        {
21109            int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21110                        extract32(ctx->opcode, 1, 13) << 1;
21111            switch (extract32(ctx->opcode, 14, 2)) {
21112            case NM_BEQC:
21113                check_nms(ctx);
21114                gen_compute_branch_nm(ctx, OPC_BEQ, 4, rs, rt, s);
21115                break;
21116            case NM_P_BR3A:
21117                s = sextract32(ctx->opcode, 0, 1) << 14 |
21118                    extract32(ctx->opcode, 1, 13) << 1;
21119                check_cp1_enabled(ctx);
21120                switch (extract32(ctx->opcode, 16, 5)) {
21121                case NM_BC1EQZC:
21122                    gen_compute_branch_cp1_nm(ctx, OPC_BC1EQZ, rt, s);
21123                    break;
21124                case NM_BC1NEZC:
21125                    gen_compute_branch_cp1_nm(ctx, OPC_BC1NEZ, rt, s);
21126                    break;
21127                case NM_BPOSGE32C:
21128                    check_dsp_r3(ctx);
21129                    {
21130                        int32_t imm = extract32(ctx->opcode, 1, 13) |
21131                                      extract32(ctx->opcode, 0, 1) << 13;
21132
21133                        gen_compute_branch_nm(ctx, OPC_BPOSGE32, 4, -1, -2,
21134                                              imm);
21135                    }
21136                    break;
21137                default:
21138                    gen_reserved_instruction(ctx);
21139                    break;
21140                }
21141                break;
21142            case NM_BGEC:
21143                if (rs == rt) {
21144                    gen_compute_compact_branch_nm(ctx, OPC_BC, rs, rt, s);
21145                } else {
21146                    gen_compute_compact_branch_nm(ctx, OPC_BGEC, rs, rt, s);
21147                }
21148                break;
21149            case NM_BGEUC:
21150                if (rs == rt || rt == 0) {
21151                    gen_compute_compact_branch_nm(ctx, OPC_BC, 0, 0, s);
21152                } else if (rs == 0) {
21153                    gen_compute_compact_branch_nm(ctx, OPC_BEQZC, rt, 0, s);
21154                } else {
21155                    gen_compute_compact_branch_nm(ctx, OPC_BGEUC, rs, rt, s);
21156                }
21157                break;
21158            }
21159        }
21160        break;
21161    case NM_P_BR2:
21162        {
21163            int32_t s = sextract32(ctx->opcode, 0, 1) << 14 |
21164                        extract32(ctx->opcode, 1, 13) << 1;
21165            switch (extract32(ctx->opcode, 14, 2)) {
21166            case NM_BNEC:
21167                check_nms(ctx);
21168                gen_compute_branch_nm(ctx, OPC_BNE, 4, rs, rt, s);
21169                break;
21170            case NM_BLTC:
21171                if (rs != 0 && rt != 0 && rs == rt) {
21172                    /* NOP */
21173                    ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21174                } else {
21175                    gen_compute_compact_branch_nm(ctx, OPC_BLTC, rs, rt, s);
21176                }
21177                break;
21178            case NM_BLTUC:
21179                if (rs == 0 || rs == rt) {
21180                    /* NOP */
21181                    ctx->hflags |= MIPS_HFLAG_FBNSLOT;
21182                } else {
21183                    gen_compute_compact_branch_nm(ctx, OPC_BLTUC, rs, rt, s);
21184                }
21185                break;
21186            default:
21187                gen_reserved_instruction(ctx);
21188                break;
21189            }
21190        }
21191        break;
21192    case NM_P_BRI:
21193        {
21194            int32_t s = sextract32(ctx->opcode, 0, 1) << 11 |
21195                        extract32(ctx->opcode, 1, 10) << 1;
21196            uint32_t u = extract32(ctx->opcode, 11, 7);
21197
21198            gen_compute_imm_branch(ctx, extract32(ctx->opcode, 18, 3),
21199                                   rt, u, s);
21200        }
21201        break;
21202    default:
21203        gen_reserved_instruction(ctx);
21204        break;
21205    }
21206    return 4;
21207}
21208
21209static int decode_nanomips_opc(CPUMIPSState *env, DisasContext *ctx)
21210{
21211    uint32_t op;
21212    int rt = decode_gpr_gpr3(NANOMIPS_EXTRACT_RT3(ctx->opcode));
21213    int rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
21214    int rd = decode_gpr_gpr3(NANOMIPS_EXTRACT_RD3(ctx->opcode));
21215    int offset;
21216    int imm;
21217
21218    /* make sure instructions are on a halfword boundary */
21219    if (ctx->base.pc_next & 0x1) {
21220        TCGv tmp = tcg_const_tl(ctx->base.pc_next);
21221        tcg_gen_st_tl(tmp, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
21222        tcg_temp_free(tmp);
21223        generate_exception_end(ctx, EXCP_AdEL);
21224        return 2;
21225    }
21226
21227    op = extract32(ctx->opcode, 10, 6);
21228    switch (op) {
21229    case NM_P16_MV:
21230        rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21231        if (rt != 0) {
21232            /* MOVE */
21233            rs = NANOMIPS_EXTRACT_RS5(ctx->opcode);
21234            gen_arith(ctx, OPC_ADDU, rt, rs, 0);
21235        } else {
21236            /* P16.RI */
21237            switch (extract32(ctx->opcode, 3, 2)) {
21238            case NM_P16_SYSCALL:
21239                if (extract32(ctx->opcode, 2, 1) == 0) {
21240                    generate_exception_end(ctx, EXCP_SYSCALL);
21241                } else {
21242                    gen_reserved_instruction(ctx);
21243                }
21244                break;
21245            case NM_BREAK16:
21246                generate_exception_end(ctx, EXCP_BREAK);
21247                break;
21248            case NM_SDBBP16:
21249                if (is_uhi(extract32(ctx->opcode, 0, 3))) {
21250                    gen_helper_do_semihosting(cpu_env);
21251                } else {
21252                    if (ctx->hflags & MIPS_HFLAG_SBRI) {
21253                        gen_reserved_instruction(ctx);
21254                    } else {
21255                        generate_exception_end(ctx, EXCP_DBp);
21256                    }
21257                }
21258                break;
21259            default:
21260                gen_reserved_instruction(ctx);
21261                break;
21262            }
21263        }
21264        break;
21265    case NM_P16_SHIFT:
21266        {
21267            int shift = extract32(ctx->opcode, 0, 3);
21268            uint32_t opc = 0;
21269            shift = (shift == 0) ? 8 : shift;
21270
21271            switch (extract32(ctx->opcode, 3, 1)) {
21272            case NM_SLL16:
21273                opc = OPC_SLL;
21274                break;
21275            case NM_SRL16:
21276                opc = OPC_SRL;
21277                break;
21278            }
21279            gen_shift_imm(ctx, opc, rt, rs, shift);
21280        }
21281        break;
21282    case NM_P16C:
21283        switch (ctx->opcode & 1) {
21284        case NM_POOL16C_0:
21285            gen_pool16c_nanomips_insn(ctx);
21286            break;
21287        case NM_LWXS16:
21288            gen_ldxs(ctx, rt, rs, rd);
21289            break;
21290        }
21291        break;
21292    case NM_P16_A1:
21293        switch (extract32(ctx->opcode, 6, 1)) {
21294        case NM_ADDIUR1SP:
21295            imm = extract32(ctx->opcode, 0, 6) << 2;
21296            gen_arith_imm(ctx, OPC_ADDIU, rt, 29, imm);
21297            break;
21298        default:
21299            gen_reserved_instruction(ctx);
21300            break;
21301        }
21302        break;
21303    case NM_P16_A2:
21304        switch (extract32(ctx->opcode, 3, 1)) {
21305        case NM_ADDIUR2:
21306            imm = extract32(ctx->opcode, 0, 3) << 2;
21307            gen_arith_imm(ctx, OPC_ADDIU, rt, rs, imm);
21308            break;
21309        case NM_P_ADDIURS5:
21310            rt = extract32(ctx->opcode, 5, 5);
21311            if (rt != 0) {
21312                /* imm = sign_extend(s[3] . s[2:0] , from_nbits = 4) */
21313                imm = (sextract32(ctx->opcode, 4, 1) << 3) |
21314                      (extract32(ctx->opcode, 0, 3));
21315                gen_arith_imm(ctx, OPC_ADDIU, rt, rt, imm);
21316            }
21317            break;
21318        }
21319        break;
21320    case NM_P16_ADDU:
21321        switch (ctx->opcode & 0x1) {
21322        case NM_ADDU16:
21323            gen_arith(ctx, OPC_ADDU, rd, rs, rt);
21324            break;
21325        case NM_SUBU16:
21326            gen_arith(ctx, OPC_SUBU, rd, rs, rt);
21327            break;
21328        }
21329        break;
21330    case NM_P16_4X4:
21331        rt = (extract32(ctx->opcode, 9, 1) << 3) |
21332              extract32(ctx->opcode, 5, 3);
21333        rs = (extract32(ctx->opcode, 4, 1) << 3) |
21334              extract32(ctx->opcode, 0, 3);
21335        rt = decode_gpr_gpr4(rt);
21336        rs = decode_gpr_gpr4(rs);
21337        switch ((extract32(ctx->opcode, 7, 2) & 0x2) |
21338                (extract32(ctx->opcode, 3, 1))) {
21339        case NM_ADDU4X4:
21340            check_nms(ctx);
21341            gen_arith(ctx, OPC_ADDU, rt, rs, rt);
21342            break;
21343        case NM_MUL4X4:
21344            check_nms(ctx);
21345            gen_r6_muldiv(ctx, R6_OPC_MUL, rt, rs, rt);
21346            break;
21347        default:
21348            gen_reserved_instruction(ctx);
21349            break;
21350        }
21351        break;
21352    case NM_LI16:
21353        {
21354            int imm = extract32(ctx->opcode, 0, 7);
21355            imm = (imm == 0x7f ? -1 : imm);
21356            if (rt != 0) {
21357                tcg_gen_movi_tl(cpu_gpr[rt], imm);
21358            }
21359        }
21360        break;
21361    case NM_ANDI16:
21362        {
21363            uint32_t u = extract32(ctx->opcode, 0, 4);
21364            u = (u == 12) ? 0xff :
21365                (u == 13) ? 0xffff : u;
21366            gen_logic_imm(ctx, OPC_ANDI, rt, rs, u);
21367        }
21368        break;
21369    case NM_P16_LB:
21370        offset = extract32(ctx->opcode, 0, 2);
21371        switch (extract32(ctx->opcode, 2, 2)) {
21372        case NM_LB16:
21373            gen_ld(ctx, OPC_LB, rt, rs, offset);
21374            break;
21375        case NM_SB16:
21376            rt = decode_gpr_gpr3_src_store(
21377                     NANOMIPS_EXTRACT_RT3(ctx->opcode));
21378            gen_st(ctx, OPC_SB, rt, rs, offset);
21379            break;
21380        case NM_LBU16:
21381            gen_ld(ctx, OPC_LBU, rt, rs, offset);
21382            break;
21383        default:
21384            gen_reserved_instruction(ctx);
21385            break;
21386        }
21387        break;
21388    case NM_P16_LH:
21389        offset = extract32(ctx->opcode, 1, 2) << 1;
21390        switch ((extract32(ctx->opcode, 3, 1) << 1) | (ctx->opcode & 1)) {
21391        case NM_LH16:
21392            gen_ld(ctx, OPC_LH, rt, rs, offset);
21393            break;
21394        case NM_SH16:
21395            rt = decode_gpr_gpr3_src_store(
21396                     NANOMIPS_EXTRACT_RT3(ctx->opcode));
21397            gen_st(ctx, OPC_SH, rt, rs, offset);
21398            break;
21399        case NM_LHU16:
21400            gen_ld(ctx, OPC_LHU, rt, rs, offset);
21401            break;
21402        default:
21403            gen_reserved_instruction(ctx);
21404            break;
21405        }
21406        break;
21407    case NM_LW16:
21408        offset = extract32(ctx->opcode, 0, 4) << 2;
21409        gen_ld(ctx, OPC_LW, rt, rs, offset);
21410        break;
21411    case NM_LWSP16:
21412        rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21413        offset = extract32(ctx->opcode, 0, 5) << 2;
21414        gen_ld(ctx, OPC_LW, rt, 29, offset);
21415        break;
21416    case NM_LW4X4:
21417        check_nms(ctx);
21418        rt = (extract32(ctx->opcode, 9, 1) << 3) |
21419             extract32(ctx->opcode, 5, 3);
21420        rs = (extract32(ctx->opcode, 4, 1) << 3) |
21421             extract32(ctx->opcode, 0, 3);
21422        offset = (extract32(ctx->opcode, 3, 1) << 3) |
21423                 (extract32(ctx->opcode, 8, 1) << 2);
21424        rt = decode_gpr_gpr4(rt);
21425        rs = decode_gpr_gpr4(rs);
21426        gen_ld(ctx, OPC_LW, rt, rs, offset);
21427        break;
21428    case NM_SW4X4:
21429        check_nms(ctx);
21430        rt = (extract32(ctx->opcode, 9, 1) << 3) |
21431             extract32(ctx->opcode, 5, 3);
21432        rs = (extract32(ctx->opcode, 4, 1) << 3) |
21433             extract32(ctx->opcode, 0, 3);
21434        offset = (extract32(ctx->opcode, 3, 1) << 3) |
21435                 (extract32(ctx->opcode, 8, 1) << 2);
21436        rt = decode_gpr_gpr4_zero(rt);
21437        rs = decode_gpr_gpr4(rs);
21438        gen_st(ctx, OPC_SW, rt, rs, offset);
21439        break;
21440    case NM_LWGP16:
21441        offset = extract32(ctx->opcode, 0, 7) << 2;
21442        gen_ld(ctx, OPC_LW, rt, 28, offset);
21443        break;
21444    case NM_SWSP16:
21445        rt = NANOMIPS_EXTRACT_RD5(ctx->opcode);
21446        offset = extract32(ctx->opcode, 0, 5) << 2;
21447        gen_st(ctx, OPC_SW, rt, 29, offset);
21448        break;
21449    case NM_SW16:
21450        rt = decode_gpr_gpr3_src_store(
21451                 NANOMIPS_EXTRACT_RT3(ctx->opcode));
21452        rs = decode_gpr_gpr3(NANOMIPS_EXTRACT_RS3(ctx->opcode));
21453        offset = extract32(ctx->opcode, 0, 4) << 2;
21454        gen_st(ctx, OPC_SW, rt, rs, offset);
21455        break;
21456    case NM_SWGP16:
21457        rt = decode_gpr_gpr3_src_store(
21458                 NANOMIPS_EXTRACT_RT3(ctx->opcode));
21459        offset = extract32(ctx->opcode, 0, 7) << 2;
21460        gen_st(ctx, OPC_SW, rt, 28, offset);
21461        break;
21462    case NM_BC16:
21463        gen_compute_branch_nm(ctx, OPC_BEQ, 2, 0, 0,
21464                           (sextract32(ctx->opcode, 0, 1) << 10) |
21465                           (extract32(ctx->opcode, 1, 9) << 1));
21466        break;
21467    case NM_BALC16:
21468        gen_compute_branch_nm(ctx, OPC_BGEZAL, 2, 0, 0,
21469                           (sextract32(ctx->opcode, 0, 1) << 10) |
21470                           (extract32(ctx->opcode, 1, 9) << 1));
21471        break;
21472    case NM_BEQZC16:
21473        gen_compute_branch_nm(ctx, OPC_BEQ, 2, rt, 0,
21474                           (sextract32(ctx->opcode, 0, 1) << 7) |
21475                           (extract32(ctx->opcode, 1, 6) << 1));
21476        break;
21477    case NM_BNEZC16:
21478        gen_compute_branch_nm(ctx, OPC_BNE, 2, rt, 0,
21479                           (sextract32(ctx->opcode, 0, 1) << 7) |
21480                           (extract32(ctx->opcode, 1, 6) << 1));
21481        break;
21482    case NM_P16_BR:
21483        switch (ctx->opcode & 0xf) {
21484        case 0:
21485            /* P16.JRC */
21486            switch (extract32(ctx->opcode, 4, 1)) {
21487            case NM_JRC:
21488                gen_compute_branch_nm(ctx, OPC_JR, 2,
21489                                   extract32(ctx->opcode, 5, 5), 0, 0);
21490                break;
21491            case NM_JALRC16:
21492                gen_compute_branch_nm(ctx, OPC_JALR, 2,
21493                                   extract32(ctx->opcode, 5, 5), 31, 0);
21494                break;
21495            }
21496            break;
21497        default:
21498            {
21499                /* P16.BRI */
21500                uint32_t opc = extract32(ctx->opcode, 4, 3) <
21501                               extract32(ctx->opcode, 7, 3) ? OPC_BEQ : OPC_BNE;
21502                gen_compute_branch_nm(ctx, opc, 2, rs, rt,
21503                                   extract32(ctx->opcode, 0, 4) << 1);
21504            }
21505            break;
21506        }
21507        break;
21508    case NM_P16_SR:
21509        {
21510            int count = extract32(ctx->opcode, 0, 4);
21511            int u = extract32(ctx->opcode, 4, 4) << 4;
21512
21513            rt = 30 + extract32(ctx->opcode, 9, 1);
21514            switch (extract32(ctx->opcode, 8, 1)) {
21515            case NM_SAVE16:
21516                gen_save(ctx, rt, count, 0, u);
21517                break;
21518            case NM_RESTORE_JRC16:
21519                gen_restore(ctx, rt, count, 0, u);
21520                gen_compute_branch_nm(ctx, OPC_JR, 2, 31, 0, 0);
21521                break;
21522            }
21523        }
21524        break;
21525    case NM_MOVEP:
21526    case NM_MOVEPREV:
21527        check_nms(ctx);
21528        {
21529            static const int gpr2reg1[] = {4, 5, 6, 7};
21530            static const int gpr2reg2[] = {5, 6, 7, 8};
21531            int re;
21532            int rd2 = extract32(ctx->opcode, 3, 1) << 1 |
21533                      extract32(ctx->opcode, 8, 1);
21534            int r1 = gpr2reg1[rd2];
21535            int r2 = gpr2reg2[rd2];
21536            int r3 = extract32(ctx->opcode, 4, 1) << 3 |
21537                     extract32(ctx->opcode, 0, 3);
21538            int r4 = extract32(ctx->opcode, 9, 1) << 3 |
21539                     extract32(ctx->opcode, 5, 3);
21540            TCGv t0 = tcg_temp_new();
21541            TCGv t1 = tcg_temp_new();
21542            if (op == NM_MOVEP) {
21543                rd = r1;
21544                re = r2;
21545                rs = decode_gpr_gpr4_zero(r3);
21546                rt = decode_gpr_gpr4_zero(r4);
21547            } else {
21548                rd = decode_gpr_gpr4(r3);
21549                re = decode_gpr_gpr4(r4);
21550                rs = r1;
21551                rt = r2;
21552            }
21553            gen_load_gpr(t0, rs);
21554            gen_load_gpr(t1, rt);
21555            tcg_gen_mov_tl(cpu_gpr[rd], t0);
21556            tcg_gen_mov_tl(cpu_gpr[re], t1);
21557            tcg_temp_free(t0);
21558            tcg_temp_free(t1);
21559        }
21560        break;
21561    default:
21562        return decode_nanomips_32_48_opc(env, ctx);
21563    }
21564
21565    return 2;
21566}
21567
21568
21569/* SmartMIPS extension to MIPS32 */
21570
21571#if defined(TARGET_MIPS64)
21572
21573/* MDMX extension to MIPS64 */
21574
21575#endif
21576
21577/* MIPSDSP functions. */
21578static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
21579                           int rd, int base, int offset)
21580{
21581    TCGv t0;
21582
21583    check_dsp(ctx);
21584    t0 = tcg_temp_new();
21585
21586    if (base == 0) {
21587        gen_load_gpr(t0, offset);
21588    } else if (offset == 0) {
21589        gen_load_gpr(t0, base);
21590    } else {
21591        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
21592    }
21593
21594    switch (opc) {
21595    case OPC_LBUX:
21596        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_UB);
21597        gen_store_gpr(t0, rd);
21598        break;
21599    case OPC_LHX:
21600        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESW);
21601        gen_store_gpr(t0, rd);
21602        break;
21603    case OPC_LWX:
21604        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TESL);
21605        gen_store_gpr(t0, rd);
21606        break;
21607#if defined(TARGET_MIPS64)
21608    case OPC_LDX:
21609        tcg_gen_qemu_ld_tl(t0, t0, ctx->mem_idx, MO_TEQ);
21610        gen_store_gpr(t0, rd);
21611        break;
21612#endif
21613    }
21614    tcg_temp_free(t0);
21615}
21616
21617static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
21618                              int ret, int v1, int v2)
21619{
21620    TCGv v1_t;
21621    TCGv v2_t;
21622
21623    if (ret == 0) {
21624        /* Treat as NOP. */
21625        return;
21626    }
21627
21628    v1_t = tcg_temp_new();
21629    v2_t = tcg_temp_new();
21630
21631    gen_load_gpr(v1_t, v1);
21632    gen_load_gpr(v2_t, v2);
21633
21634    switch (op1) {
21635    /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
21636    case OPC_MULT_G_2E:
21637        check_dsp_r2(ctx);
21638        switch (op2) {
21639        case OPC_ADDUH_QB:
21640            gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
21641            break;
21642        case OPC_ADDUH_R_QB:
21643            gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
21644            break;
21645        case OPC_ADDQH_PH:
21646            gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
21647            break;
21648        case OPC_ADDQH_R_PH:
21649            gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
21650            break;
21651        case OPC_ADDQH_W:
21652            gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
21653            break;
21654        case OPC_ADDQH_R_W:
21655            gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
21656            break;
21657        case OPC_SUBUH_QB:
21658            gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
21659            break;
21660        case OPC_SUBUH_R_QB:
21661            gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
21662            break;
21663        case OPC_SUBQH_PH:
21664            gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
21665            break;
21666        case OPC_SUBQH_R_PH:
21667            gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
21668            break;
21669        case OPC_SUBQH_W:
21670            gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
21671            break;
21672        case OPC_SUBQH_R_W:
21673            gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
21674            break;
21675        }
21676        break;
21677    case OPC_ABSQ_S_PH_DSP:
21678        switch (op2) {
21679        case OPC_ABSQ_S_QB:
21680            check_dsp_r2(ctx);
21681            gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
21682            break;
21683        case OPC_ABSQ_S_PH:
21684            check_dsp(ctx);
21685            gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
21686            break;
21687        case OPC_ABSQ_S_W:
21688            check_dsp(ctx);
21689            gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
21690            break;
21691        case OPC_PRECEQ_W_PHL:
21692            check_dsp(ctx);
21693            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
21694            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
21695            break;
21696        case OPC_PRECEQ_W_PHR:
21697            check_dsp(ctx);
21698            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
21699            tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
21700            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
21701            break;
21702        case OPC_PRECEQU_PH_QBL:
21703            check_dsp(ctx);
21704            gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
21705            break;
21706        case OPC_PRECEQU_PH_QBR:
21707            check_dsp(ctx);
21708            gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
21709            break;
21710        case OPC_PRECEQU_PH_QBLA:
21711            check_dsp(ctx);
21712            gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
21713            break;
21714        case OPC_PRECEQU_PH_QBRA:
21715            check_dsp(ctx);
21716            gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
21717            break;
21718        case OPC_PRECEU_PH_QBL:
21719            check_dsp(ctx);
21720            gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
21721            break;
21722        case OPC_PRECEU_PH_QBR:
21723            check_dsp(ctx);
21724            gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
21725            break;
21726        case OPC_PRECEU_PH_QBLA:
21727            check_dsp(ctx);
21728            gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
21729            break;
21730        case OPC_PRECEU_PH_QBRA:
21731            check_dsp(ctx);
21732            gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
21733            break;
21734        }
21735        break;
21736    case OPC_ADDU_QB_DSP:
21737        switch (op2) {
21738        case OPC_ADDQ_PH:
21739            check_dsp(ctx);
21740            gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21741            break;
21742        case OPC_ADDQ_S_PH:
21743            check_dsp(ctx);
21744            gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21745            break;
21746        case OPC_ADDQ_S_W:
21747            check_dsp(ctx);
21748            gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21749            break;
21750        case OPC_ADDU_QB:
21751            check_dsp(ctx);
21752            gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21753            break;
21754        case OPC_ADDU_S_QB:
21755            check_dsp(ctx);
21756            gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21757            break;
21758        case OPC_ADDU_PH:
21759            check_dsp_r2(ctx);
21760            gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21761            break;
21762        case OPC_ADDU_S_PH:
21763            check_dsp_r2(ctx);
21764            gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21765            break;
21766        case OPC_SUBQ_PH:
21767            check_dsp(ctx);
21768            gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21769            break;
21770        case OPC_SUBQ_S_PH:
21771            check_dsp(ctx);
21772            gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21773            break;
21774        case OPC_SUBQ_S_W:
21775            check_dsp(ctx);
21776            gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21777            break;
21778        case OPC_SUBU_QB:
21779            check_dsp(ctx);
21780            gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21781            break;
21782        case OPC_SUBU_S_QB:
21783            check_dsp(ctx);
21784            gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21785            break;
21786        case OPC_SUBU_PH:
21787            check_dsp_r2(ctx);
21788            gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21789            break;
21790        case OPC_SUBU_S_PH:
21791            check_dsp_r2(ctx);
21792            gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21793            break;
21794        case OPC_ADDSC:
21795            check_dsp(ctx);
21796            gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21797            break;
21798        case OPC_ADDWC:
21799            check_dsp(ctx);
21800            gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21801            break;
21802        case OPC_MODSUB:
21803            check_dsp(ctx);
21804            gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
21805            break;
21806        case OPC_RADDU_W_QB:
21807            check_dsp(ctx);
21808            gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
21809            break;
21810        }
21811        break;
21812    case OPC_CMPU_EQ_QB_DSP:
21813        switch (op2) {
21814        case OPC_PRECR_QB_PH:
21815            check_dsp_r2(ctx);
21816            gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
21817            break;
21818        case OPC_PRECRQ_QB_PH:
21819            check_dsp(ctx);
21820            gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
21821            break;
21822        case OPC_PRECR_SRA_PH_W:
21823            check_dsp_r2(ctx);
21824            {
21825                TCGv_i32 sa_t = tcg_const_i32(v2);
21826                gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
21827                                          cpu_gpr[ret]);
21828                tcg_temp_free_i32(sa_t);
21829                break;
21830            }
21831        case OPC_PRECR_SRA_R_PH_W:
21832            check_dsp_r2(ctx);
21833            {
21834                TCGv_i32 sa_t = tcg_const_i32(v2);
21835                gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
21836                                            cpu_gpr[ret]);
21837                tcg_temp_free_i32(sa_t);
21838                break;
21839            }
21840        case OPC_PRECRQ_PH_W:
21841            check_dsp(ctx);
21842            gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
21843            break;
21844        case OPC_PRECRQ_RS_PH_W:
21845            check_dsp(ctx);
21846            gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21847            break;
21848        case OPC_PRECRQU_S_QB_PH:
21849            check_dsp(ctx);
21850            gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21851            break;
21852        }
21853        break;
21854#ifdef TARGET_MIPS64
21855    case OPC_ABSQ_S_QH_DSP:
21856        switch (op2) {
21857        case OPC_PRECEQ_L_PWL:
21858            check_dsp(ctx);
21859            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
21860            break;
21861        case OPC_PRECEQ_L_PWR:
21862            check_dsp(ctx);
21863            tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
21864            break;
21865        case OPC_PRECEQ_PW_QHL:
21866            check_dsp(ctx);
21867            gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
21868            break;
21869        case OPC_PRECEQ_PW_QHR:
21870            check_dsp(ctx);
21871            gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
21872            break;
21873        case OPC_PRECEQ_PW_QHLA:
21874            check_dsp(ctx);
21875            gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
21876            break;
21877        case OPC_PRECEQ_PW_QHRA:
21878            check_dsp(ctx);
21879            gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
21880            break;
21881        case OPC_PRECEQU_QH_OBL:
21882            check_dsp(ctx);
21883            gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
21884            break;
21885        case OPC_PRECEQU_QH_OBR:
21886            check_dsp(ctx);
21887            gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
21888            break;
21889        case OPC_PRECEQU_QH_OBLA:
21890            check_dsp(ctx);
21891            gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
21892            break;
21893        case OPC_PRECEQU_QH_OBRA:
21894            check_dsp(ctx);
21895            gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
21896            break;
21897        case OPC_PRECEU_QH_OBL:
21898            check_dsp(ctx);
21899            gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
21900            break;
21901        case OPC_PRECEU_QH_OBR:
21902            check_dsp(ctx);
21903            gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
21904            break;
21905        case OPC_PRECEU_QH_OBLA:
21906            check_dsp(ctx);
21907            gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
21908            break;
21909        case OPC_PRECEU_QH_OBRA:
21910            check_dsp(ctx);
21911            gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
21912            break;
21913        case OPC_ABSQ_S_OB:
21914            check_dsp_r2(ctx);
21915            gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
21916            break;
21917        case OPC_ABSQ_S_PW:
21918            check_dsp(ctx);
21919            gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
21920            break;
21921        case OPC_ABSQ_S_QH:
21922            check_dsp(ctx);
21923            gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
21924            break;
21925        }
21926        break;
21927    case OPC_ADDU_OB_DSP:
21928        switch (op2) {
21929        case OPC_RADDU_L_OB:
21930            check_dsp(ctx);
21931            gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
21932            break;
21933        case OPC_SUBQ_PW:
21934            check_dsp(ctx);
21935            gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21936            break;
21937        case OPC_SUBQ_S_PW:
21938            check_dsp(ctx);
21939            gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21940            break;
21941        case OPC_SUBQ_QH:
21942            check_dsp(ctx);
21943            gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21944            break;
21945        case OPC_SUBQ_S_QH:
21946            check_dsp(ctx);
21947            gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21948            break;
21949        case OPC_SUBU_OB:
21950            check_dsp(ctx);
21951            gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21952            break;
21953        case OPC_SUBU_S_OB:
21954            check_dsp(ctx);
21955            gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21956            break;
21957        case OPC_SUBU_QH:
21958            check_dsp_r2(ctx);
21959            gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21960            break;
21961        case OPC_SUBU_S_QH:
21962            check_dsp_r2(ctx);
21963            gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21964            break;
21965        case OPC_SUBUH_OB:
21966            check_dsp_r2(ctx);
21967            gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
21968            break;
21969        case OPC_SUBUH_R_OB:
21970            check_dsp_r2(ctx);
21971            gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
21972            break;
21973        case OPC_ADDQ_PW:
21974            check_dsp(ctx);
21975            gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21976            break;
21977        case OPC_ADDQ_S_PW:
21978            check_dsp(ctx);
21979            gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21980            break;
21981        case OPC_ADDQ_QH:
21982            check_dsp(ctx);
21983            gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21984            break;
21985        case OPC_ADDQ_S_QH:
21986            check_dsp(ctx);
21987            gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21988            break;
21989        case OPC_ADDU_OB:
21990            check_dsp(ctx);
21991            gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21992            break;
21993        case OPC_ADDU_S_OB:
21994            check_dsp(ctx);
21995            gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
21996            break;
21997        case OPC_ADDU_QH:
21998            check_dsp_r2(ctx);
21999            gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22000            break;
22001        case OPC_ADDU_S_QH:
22002            check_dsp_r2(ctx);
22003            gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22004            break;
22005        case OPC_ADDUH_OB:
22006            check_dsp_r2(ctx);
22007            gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
22008            break;
22009        case OPC_ADDUH_R_OB:
22010            check_dsp_r2(ctx);
22011            gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
22012            break;
22013        }
22014        break;
22015    case OPC_CMPU_EQ_OB_DSP:
22016        switch (op2) {
22017        case OPC_PRECR_OB_QH:
22018            check_dsp_r2(ctx);
22019            gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22020            break;
22021        case OPC_PRECR_SRA_QH_PW:
22022            check_dsp_r2(ctx);
22023            {
22024                TCGv_i32 ret_t = tcg_const_i32(ret);
22025                gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
22026                tcg_temp_free_i32(ret_t);
22027                break;
22028            }
22029        case OPC_PRECR_SRA_R_QH_PW:
22030            check_dsp_r2(ctx);
22031            {
22032                TCGv_i32 sa_v = tcg_const_i32(ret);
22033                gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
22034                tcg_temp_free_i32(sa_v);
22035                break;
22036            }
22037        case OPC_PRECRQ_OB_QH:
22038            check_dsp(ctx);
22039            gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
22040            break;
22041        case OPC_PRECRQ_PW_L:
22042            check_dsp(ctx);
22043            gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
22044            break;
22045        case OPC_PRECRQ_QH_PW:
22046            check_dsp(ctx);
22047            gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
22048            break;
22049        case OPC_PRECRQ_RS_QH_PW:
22050            check_dsp(ctx);
22051            gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22052            break;
22053        case OPC_PRECRQU_S_OB_QH:
22054            check_dsp(ctx);
22055            gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22056            break;
22057        }
22058        break;
22059#endif
22060    }
22061
22062    tcg_temp_free(v1_t);
22063    tcg_temp_free(v2_t);
22064}
22065
22066static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
22067                              int ret, int v1, int v2)
22068{
22069    uint32_t op2;
22070    TCGv t0;
22071    TCGv v1_t;
22072    TCGv v2_t;
22073
22074    if (ret == 0) {
22075        /* Treat as NOP. */
22076        return;
22077    }
22078
22079    t0 = tcg_temp_new();
22080    v1_t = tcg_temp_new();
22081    v2_t = tcg_temp_new();
22082
22083    tcg_gen_movi_tl(t0, v1);
22084    gen_load_gpr(v1_t, v1);
22085    gen_load_gpr(v2_t, v2);
22086
22087    switch (opc) {
22088    case OPC_SHLL_QB_DSP:
22089        {
22090            op2 = MASK_SHLL_QB(ctx->opcode);
22091            switch (op2) {
22092            case OPC_SHLL_QB:
22093                check_dsp(ctx);
22094                gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
22095                break;
22096            case OPC_SHLLV_QB:
22097                check_dsp(ctx);
22098                gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22099                break;
22100            case OPC_SHLL_PH:
22101                check_dsp(ctx);
22102                gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22103                break;
22104            case OPC_SHLLV_PH:
22105                check_dsp(ctx);
22106                gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22107                break;
22108            case OPC_SHLL_S_PH:
22109                check_dsp(ctx);
22110                gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
22111                break;
22112            case OPC_SHLLV_S_PH:
22113                check_dsp(ctx);
22114                gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22115                break;
22116            case OPC_SHLL_S_W:
22117                check_dsp(ctx);
22118                gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
22119                break;
22120            case OPC_SHLLV_S_W:
22121                check_dsp(ctx);
22122                gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22123                break;
22124            case OPC_SHRL_QB:
22125                check_dsp(ctx);
22126                gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
22127                break;
22128            case OPC_SHRLV_QB:
22129                check_dsp(ctx);
22130                gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
22131                break;
22132            case OPC_SHRL_PH:
22133                check_dsp_r2(ctx);
22134                gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
22135                break;
22136            case OPC_SHRLV_PH:
22137                check_dsp_r2(ctx);
22138                gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
22139                break;
22140            case OPC_SHRA_QB:
22141                check_dsp_r2(ctx);
22142                gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
22143                break;
22144            case OPC_SHRA_R_QB:
22145                check_dsp_r2(ctx);
22146                gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
22147                break;
22148            case OPC_SHRAV_QB:
22149                check_dsp_r2(ctx);
22150                gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
22151                break;
22152            case OPC_SHRAV_R_QB:
22153                check_dsp_r2(ctx);
22154                gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
22155                break;
22156            case OPC_SHRA_PH:
22157                check_dsp(ctx);
22158                gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
22159                break;
22160            case OPC_SHRA_R_PH:
22161                check_dsp(ctx);
22162                gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
22163                break;
22164            case OPC_SHRAV_PH:
22165                check_dsp(ctx);
22166                gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
22167                break;
22168            case OPC_SHRAV_R_PH:
22169                check_dsp(ctx);
22170                gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
22171                break;
22172            case OPC_SHRA_R_W:
22173                check_dsp(ctx);
22174                gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
22175                break;
22176            case OPC_SHRAV_R_W:
22177                check_dsp(ctx);
22178                gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
22179                break;
22180            default:            /* Invalid */
22181                MIPS_INVAL("MASK SHLL.QB");
22182                gen_reserved_instruction(ctx);
22183                break;
22184            }
22185            break;
22186        }
22187#ifdef TARGET_MIPS64
22188    case OPC_SHLL_OB_DSP:
22189        op2 = MASK_SHLL_OB(ctx->opcode);
22190        switch (op2) {
22191        case OPC_SHLL_PW:
22192            check_dsp(ctx);
22193            gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22194            break;
22195        case OPC_SHLLV_PW:
22196            check_dsp(ctx);
22197            gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22198            break;
22199        case OPC_SHLL_S_PW:
22200            check_dsp(ctx);
22201            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
22202            break;
22203        case OPC_SHLLV_S_PW:
22204            check_dsp(ctx);
22205            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22206            break;
22207        case OPC_SHLL_OB:
22208            check_dsp(ctx);
22209            gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
22210            break;
22211        case OPC_SHLLV_OB:
22212            check_dsp(ctx);
22213            gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22214            break;
22215        case OPC_SHLL_QH:
22216            check_dsp(ctx);
22217            gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22218            break;
22219        case OPC_SHLLV_QH:
22220            check_dsp(ctx);
22221            gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22222            break;
22223        case OPC_SHLL_S_QH:
22224            check_dsp(ctx);
22225            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
22226            break;
22227        case OPC_SHLLV_S_QH:
22228            check_dsp(ctx);
22229            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
22230            break;
22231        case OPC_SHRA_OB:
22232            check_dsp_r2(ctx);
22233            gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
22234            break;
22235        case OPC_SHRAV_OB:
22236            check_dsp_r2(ctx);
22237            gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
22238            break;
22239        case OPC_SHRA_R_OB:
22240            check_dsp_r2(ctx);
22241            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
22242            break;
22243        case OPC_SHRAV_R_OB:
22244            check_dsp_r2(ctx);
22245            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
22246            break;
22247        case OPC_SHRA_PW:
22248            check_dsp(ctx);
22249            gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
22250            break;
22251        case OPC_SHRAV_PW:
22252            check_dsp(ctx);
22253            gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
22254            break;
22255        case OPC_SHRA_R_PW:
22256            check_dsp(ctx);
22257            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
22258            break;
22259        case OPC_SHRAV_R_PW:
22260            check_dsp(ctx);
22261            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
22262            break;
22263        case OPC_SHRA_QH:
22264            check_dsp(ctx);
22265            gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
22266            break;
22267        case OPC_SHRAV_QH:
22268            check_dsp(ctx);
22269            gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
22270            break;
22271        case OPC_SHRA_R_QH:
22272            check_dsp(ctx);
22273            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
22274            break;
22275        case OPC_SHRAV_R_QH:
22276            check_dsp(ctx);
22277            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
22278            break;
22279        case OPC_SHRL_OB:
22280            check_dsp(ctx);
22281            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
22282            break;
22283        case OPC_SHRLV_OB:
22284            check_dsp(ctx);
22285            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
22286            break;
22287        case OPC_SHRL_QH:
22288            check_dsp_r2(ctx);
22289            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
22290            break;
22291        case OPC_SHRLV_QH:
22292            check_dsp_r2(ctx);
22293            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
22294            break;
22295        default:            /* Invalid */
22296            MIPS_INVAL("MASK SHLL.OB");
22297            gen_reserved_instruction(ctx);
22298            break;
22299        }
22300        break;
22301#endif
22302    }
22303
22304    tcg_temp_free(t0);
22305    tcg_temp_free(v1_t);
22306    tcg_temp_free(v2_t);
22307}
22308
22309static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
22310                                 int ret, int v1, int v2, int check_ret)
22311{
22312    TCGv_i32 t0;
22313    TCGv v1_t;
22314    TCGv v2_t;
22315
22316    if ((ret == 0) && (check_ret == 1)) {
22317        /* Treat as NOP. */
22318        return;
22319    }
22320
22321    t0 = tcg_temp_new_i32();
22322    v1_t = tcg_temp_new();
22323    v2_t = tcg_temp_new();
22324
22325    tcg_gen_movi_i32(t0, ret);
22326    gen_load_gpr(v1_t, v1);
22327    gen_load_gpr(v2_t, v2);
22328
22329    switch (op1) {
22330    /*
22331     * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
22332     * the same mask and op1.
22333     */
22334    case OPC_MULT_G_2E:
22335        check_dsp_r2(ctx);
22336        switch (op2) {
22337        case  OPC_MUL_PH:
22338            gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22339            break;
22340        case  OPC_MUL_S_PH:
22341            gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22342            break;
22343        case OPC_MULQ_S_W:
22344            gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22345            break;
22346        case OPC_MULQ_RS_W:
22347            gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22348            break;
22349        }
22350        break;
22351    case OPC_DPA_W_PH_DSP:
22352        switch (op2) {
22353        case OPC_DPAU_H_QBL:
22354            check_dsp(ctx);
22355            gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
22356            break;
22357        case OPC_DPAU_H_QBR:
22358            check_dsp(ctx);
22359            gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
22360            break;
22361        case OPC_DPSU_H_QBL:
22362            check_dsp(ctx);
22363            gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
22364            break;
22365        case OPC_DPSU_H_QBR:
22366            check_dsp(ctx);
22367            gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
22368            break;
22369        case OPC_DPA_W_PH:
22370            check_dsp_r2(ctx);
22371            gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
22372            break;
22373        case OPC_DPAX_W_PH:
22374            check_dsp_r2(ctx);
22375            gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
22376            break;
22377        case OPC_DPAQ_S_W_PH:
22378            check_dsp(ctx);
22379            gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22380            break;
22381        case OPC_DPAQX_S_W_PH:
22382            check_dsp_r2(ctx);
22383            gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
22384            break;
22385        case OPC_DPAQX_SA_W_PH:
22386            check_dsp_r2(ctx);
22387            gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
22388            break;
22389        case OPC_DPS_W_PH:
22390            check_dsp_r2(ctx);
22391            gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
22392            break;
22393        case OPC_DPSX_W_PH:
22394            check_dsp_r2(ctx);
22395            gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
22396            break;
22397        case OPC_DPSQ_S_W_PH:
22398            check_dsp(ctx);
22399            gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22400            break;
22401        case OPC_DPSQX_S_W_PH:
22402            check_dsp_r2(ctx);
22403            gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
22404            break;
22405        case OPC_DPSQX_SA_W_PH:
22406            check_dsp_r2(ctx);
22407            gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
22408            break;
22409        case OPC_MULSAQ_S_W_PH:
22410            check_dsp(ctx);
22411            gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
22412            break;
22413        case OPC_DPAQ_SA_L_W:
22414            check_dsp(ctx);
22415            gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
22416            break;
22417        case OPC_DPSQ_SA_L_W:
22418            check_dsp(ctx);
22419            gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
22420            break;
22421        case OPC_MAQ_S_W_PHL:
22422            check_dsp(ctx);
22423            gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
22424            break;
22425        case OPC_MAQ_S_W_PHR:
22426            check_dsp(ctx);
22427            gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
22428            break;
22429        case OPC_MAQ_SA_W_PHL:
22430            check_dsp(ctx);
22431            gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
22432            break;
22433        case OPC_MAQ_SA_W_PHR:
22434            check_dsp(ctx);
22435            gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
22436            break;
22437        case OPC_MULSA_W_PH:
22438            check_dsp_r2(ctx);
22439            gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
22440            break;
22441        }
22442        break;
22443#ifdef TARGET_MIPS64
22444    case OPC_DPAQ_W_QH_DSP:
22445        {
22446            int ac = ret & 0x03;
22447            tcg_gen_movi_i32(t0, ac);
22448
22449            switch (op2) {
22450            case OPC_DMADD:
22451                check_dsp(ctx);
22452                gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
22453                break;
22454            case OPC_DMADDU:
22455                check_dsp(ctx);
22456                gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
22457                break;
22458            case OPC_DMSUB:
22459                check_dsp(ctx);
22460                gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
22461                break;
22462            case OPC_DMSUBU:
22463                check_dsp(ctx);
22464                gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
22465                break;
22466            case OPC_DPA_W_QH:
22467                check_dsp_r2(ctx);
22468                gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
22469                break;
22470            case OPC_DPAQ_S_W_QH:
22471                check_dsp(ctx);
22472                gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22473                break;
22474            case OPC_DPAQ_SA_L_PW:
22475                check_dsp(ctx);
22476                gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
22477                break;
22478            case OPC_DPAU_H_OBL:
22479                check_dsp(ctx);
22480                gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
22481                break;
22482            case OPC_DPAU_H_OBR:
22483                check_dsp(ctx);
22484                gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
22485                break;
22486            case OPC_DPS_W_QH:
22487                check_dsp_r2(ctx);
22488                gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
22489                break;
22490            case OPC_DPSQ_S_W_QH:
22491                check_dsp(ctx);
22492                gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22493                break;
22494            case OPC_DPSQ_SA_L_PW:
22495                check_dsp(ctx);
22496                gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
22497                break;
22498            case OPC_DPSU_H_OBL:
22499                check_dsp(ctx);
22500                gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
22501                break;
22502            case OPC_DPSU_H_OBR:
22503                check_dsp(ctx);
22504                gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
22505                break;
22506            case OPC_MAQ_S_L_PWL:
22507                check_dsp(ctx);
22508                gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
22509                break;
22510            case OPC_MAQ_S_L_PWR:
22511                check_dsp(ctx);
22512                gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
22513                break;
22514            case OPC_MAQ_S_W_QHLL:
22515                check_dsp(ctx);
22516                gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
22517                break;
22518            case OPC_MAQ_SA_W_QHLL:
22519                check_dsp(ctx);
22520                gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
22521                break;
22522            case OPC_MAQ_S_W_QHLR:
22523                check_dsp(ctx);
22524                gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
22525                break;
22526            case OPC_MAQ_SA_W_QHLR:
22527                check_dsp(ctx);
22528                gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
22529                break;
22530            case OPC_MAQ_S_W_QHRL:
22531                check_dsp(ctx);
22532                gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
22533                break;
22534            case OPC_MAQ_SA_W_QHRL:
22535                check_dsp(ctx);
22536                gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
22537                break;
22538            case OPC_MAQ_S_W_QHRR:
22539                check_dsp(ctx);
22540                gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
22541                break;
22542            case OPC_MAQ_SA_W_QHRR:
22543                check_dsp(ctx);
22544                gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
22545                break;
22546            case OPC_MULSAQ_S_L_PW:
22547                check_dsp(ctx);
22548                gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
22549                break;
22550            case OPC_MULSAQ_S_W_QH:
22551                check_dsp(ctx);
22552                gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
22553                break;
22554            }
22555        }
22556        break;
22557#endif
22558    case OPC_ADDU_QB_DSP:
22559        switch (op2) {
22560        case OPC_MULEU_S_PH_QBL:
22561            check_dsp(ctx);
22562            gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22563            break;
22564        case OPC_MULEU_S_PH_QBR:
22565            check_dsp(ctx);
22566            gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22567            break;
22568        case OPC_MULQ_RS_PH:
22569            check_dsp(ctx);
22570            gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22571            break;
22572        case OPC_MULEQ_S_W_PHL:
22573            check_dsp(ctx);
22574            gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22575            break;
22576        case OPC_MULEQ_S_W_PHR:
22577            check_dsp(ctx);
22578            gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22579            break;
22580        case OPC_MULQ_S_PH:
22581            check_dsp_r2(ctx);
22582            gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22583            break;
22584        }
22585        break;
22586#ifdef TARGET_MIPS64
22587    case OPC_ADDU_OB_DSP:
22588        switch (op2) {
22589        case OPC_MULEQ_S_PW_QHL:
22590            check_dsp(ctx);
22591            gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22592            break;
22593        case OPC_MULEQ_S_PW_QHR:
22594            check_dsp(ctx);
22595            gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22596            break;
22597        case OPC_MULEU_S_QH_OBL:
22598            check_dsp(ctx);
22599            gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22600            break;
22601        case OPC_MULEU_S_QH_OBR:
22602            check_dsp(ctx);
22603            gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22604            break;
22605        case OPC_MULQ_RS_QH:
22606            check_dsp(ctx);
22607            gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22608            break;
22609        }
22610        break;
22611#endif
22612    }
22613
22614    tcg_temp_free_i32(t0);
22615    tcg_temp_free(v1_t);
22616    tcg_temp_free(v2_t);
22617}
22618
22619static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
22620                                int ret, int val)
22621{
22622    int16_t imm;
22623    TCGv t0;
22624    TCGv val_t;
22625
22626    if (ret == 0) {
22627        /* Treat as NOP. */
22628        return;
22629    }
22630
22631    t0 = tcg_temp_new();
22632    val_t = tcg_temp_new();
22633    gen_load_gpr(val_t, val);
22634
22635    switch (op1) {
22636    case OPC_ABSQ_S_PH_DSP:
22637        switch (op2) {
22638        case OPC_BITREV:
22639            check_dsp(ctx);
22640            gen_helper_bitrev(cpu_gpr[ret], val_t);
22641            break;
22642        case OPC_REPL_QB:
22643            check_dsp(ctx);
22644            {
22645                target_long result;
22646                imm = (ctx->opcode >> 16) & 0xFF;
22647                result = (uint32_t)imm << 24 |
22648                         (uint32_t)imm << 16 |
22649                         (uint32_t)imm << 8  |
22650                         (uint32_t)imm;
22651                result = (int32_t)result;
22652                tcg_gen_movi_tl(cpu_gpr[ret], result);
22653            }
22654            break;
22655        case OPC_REPLV_QB:
22656            check_dsp(ctx);
22657            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
22658            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
22659            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22660            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22661            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22662            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22663            break;
22664        case OPC_REPL_PH:
22665            check_dsp(ctx);
22666            {
22667                imm = (ctx->opcode >> 16) & 0x03FF;
22668                imm = (int16_t)(imm << 6) >> 6;
22669                tcg_gen_movi_tl(cpu_gpr[ret], \
22670                                (target_long)((int32_t)imm << 16 | \
22671                                (uint16_t)imm));
22672            }
22673            break;
22674        case OPC_REPLV_PH:
22675            check_dsp(ctx);
22676            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
22677            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22678            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22679            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
22680            break;
22681        }
22682        break;
22683#ifdef TARGET_MIPS64
22684    case OPC_ABSQ_S_QH_DSP:
22685        switch (op2) {
22686        case OPC_REPL_OB:
22687            check_dsp(ctx);
22688            {
22689                target_long temp;
22690
22691                imm = (ctx->opcode >> 16) & 0xFF;
22692                temp = ((uint64_t)imm << 8) | (uint64_t)imm;
22693                temp = (temp << 16) | temp;
22694                temp = (temp << 32) | temp;
22695                tcg_gen_movi_tl(cpu_gpr[ret], temp);
22696                break;
22697            }
22698        case OPC_REPL_PW:
22699            check_dsp(ctx);
22700            {
22701                target_long temp;
22702
22703                imm = (ctx->opcode >> 16) & 0x03FF;
22704                imm = (int16_t)(imm << 6) >> 6;
22705                temp = ((target_long)imm << 32) \
22706                       | ((target_long)imm & 0xFFFFFFFF);
22707                tcg_gen_movi_tl(cpu_gpr[ret], temp);
22708                break;
22709            }
22710        case OPC_REPL_QH:
22711            check_dsp(ctx);
22712            {
22713                target_long temp;
22714
22715                imm = (ctx->opcode >> 16) & 0x03FF;
22716                imm = (int16_t)(imm << 6) >> 6;
22717
22718                temp = ((uint64_t)(uint16_t)imm << 48) |
22719                       ((uint64_t)(uint16_t)imm << 32) |
22720                       ((uint64_t)(uint16_t)imm << 16) |
22721                       (uint64_t)(uint16_t)imm;
22722                tcg_gen_movi_tl(cpu_gpr[ret], temp);
22723                break;
22724            }
22725        case OPC_REPLV_OB:
22726            check_dsp(ctx);
22727            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
22728            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
22729            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22730            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22731            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22732            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
22733            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22734            break;
22735        case OPC_REPLV_PW:
22736            check_dsp(ctx);
22737            tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
22738            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
22739            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22740            break;
22741        case OPC_REPLV_QH:
22742            check_dsp(ctx);
22743            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
22744            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
22745            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22746            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
22747            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
22748            break;
22749        }
22750        break;
22751#endif
22752    }
22753    tcg_temp_free(t0);
22754    tcg_temp_free(val_t);
22755}
22756
22757static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
22758                                     uint32_t op1, uint32_t op2,
22759                                     int ret, int v1, int v2, int check_ret)
22760{
22761    TCGv t1;
22762    TCGv v1_t;
22763    TCGv v2_t;
22764
22765    if ((ret == 0) && (check_ret == 1)) {
22766        /* Treat as NOP. */
22767        return;
22768    }
22769
22770    t1 = tcg_temp_new();
22771    v1_t = tcg_temp_new();
22772    v2_t = tcg_temp_new();
22773
22774    gen_load_gpr(v1_t, v1);
22775    gen_load_gpr(v2_t, v2);
22776
22777    switch (op1) {
22778    case OPC_CMPU_EQ_QB_DSP:
22779        switch (op2) {
22780        case OPC_CMPU_EQ_QB:
22781            check_dsp(ctx);
22782            gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
22783            break;
22784        case OPC_CMPU_LT_QB:
22785            check_dsp(ctx);
22786            gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
22787            break;
22788        case OPC_CMPU_LE_QB:
22789            check_dsp(ctx);
22790            gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
22791            break;
22792        case OPC_CMPGU_EQ_QB:
22793            check_dsp(ctx);
22794            gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
22795            break;
22796        case OPC_CMPGU_LT_QB:
22797            check_dsp(ctx);
22798            gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
22799            break;
22800        case OPC_CMPGU_LE_QB:
22801            check_dsp(ctx);
22802            gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
22803            break;
22804        case OPC_CMPGDU_EQ_QB:
22805            check_dsp_r2(ctx);
22806            gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
22807            tcg_gen_mov_tl(cpu_gpr[ret], t1);
22808            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
22809            tcg_gen_shli_tl(t1, t1, 24);
22810            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
22811            break;
22812        case OPC_CMPGDU_LT_QB:
22813            check_dsp_r2(ctx);
22814            gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
22815            tcg_gen_mov_tl(cpu_gpr[ret], t1);
22816            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
22817            tcg_gen_shli_tl(t1, t1, 24);
22818            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
22819            break;
22820        case OPC_CMPGDU_LE_QB:
22821            check_dsp_r2(ctx);
22822            gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
22823            tcg_gen_mov_tl(cpu_gpr[ret], t1);
22824            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
22825            tcg_gen_shli_tl(t1, t1, 24);
22826            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
22827            break;
22828        case OPC_CMP_EQ_PH:
22829            check_dsp(ctx);
22830            gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
22831            break;
22832        case OPC_CMP_LT_PH:
22833            check_dsp(ctx);
22834            gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
22835            break;
22836        case OPC_CMP_LE_PH:
22837            check_dsp(ctx);
22838            gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
22839            break;
22840        case OPC_PICK_QB:
22841            check_dsp(ctx);
22842            gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22843            break;
22844        case OPC_PICK_PH:
22845            check_dsp(ctx);
22846            gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22847            break;
22848        case OPC_PACKRL_PH:
22849            check_dsp(ctx);
22850            gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
22851            break;
22852        }
22853        break;
22854#ifdef TARGET_MIPS64
22855    case OPC_CMPU_EQ_OB_DSP:
22856        switch (op2) {
22857        case OPC_CMP_EQ_PW:
22858            check_dsp(ctx);
22859            gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
22860            break;
22861        case OPC_CMP_LT_PW:
22862            check_dsp(ctx);
22863            gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
22864            break;
22865        case OPC_CMP_LE_PW:
22866            check_dsp(ctx);
22867            gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
22868            break;
22869        case OPC_CMP_EQ_QH:
22870            check_dsp(ctx);
22871            gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
22872            break;
22873        case OPC_CMP_LT_QH:
22874            check_dsp(ctx);
22875            gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
22876            break;
22877        case OPC_CMP_LE_QH:
22878            check_dsp(ctx);
22879            gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
22880            break;
22881        case OPC_CMPGDU_EQ_OB:
22882            check_dsp_r2(ctx);
22883            gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22884            break;
22885        case OPC_CMPGDU_LT_OB:
22886            check_dsp_r2(ctx);
22887            gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22888            break;
22889        case OPC_CMPGDU_LE_OB:
22890            check_dsp_r2(ctx);
22891            gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22892            break;
22893        case OPC_CMPGU_EQ_OB:
22894            check_dsp(ctx);
22895            gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
22896            break;
22897        case OPC_CMPGU_LT_OB:
22898            check_dsp(ctx);
22899            gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
22900            break;
22901        case OPC_CMPGU_LE_OB:
22902            check_dsp(ctx);
22903            gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
22904            break;
22905        case OPC_CMPU_EQ_OB:
22906            check_dsp(ctx);
22907            gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
22908            break;
22909        case OPC_CMPU_LT_OB:
22910            check_dsp(ctx);
22911            gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
22912            break;
22913        case OPC_CMPU_LE_OB:
22914            check_dsp(ctx);
22915            gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
22916            break;
22917        case OPC_PACKRL_PW:
22918            check_dsp(ctx);
22919            gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
22920            break;
22921        case OPC_PICK_OB:
22922            check_dsp(ctx);
22923            gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22924            break;
22925        case OPC_PICK_PW:
22926            check_dsp(ctx);
22927            gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22928            break;
22929        case OPC_PICK_QH:
22930            check_dsp(ctx);
22931            gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
22932            break;
22933        }
22934        break;
22935#endif
22936    }
22937
22938    tcg_temp_free(t1);
22939    tcg_temp_free(v1_t);
22940    tcg_temp_free(v2_t);
22941}
22942
22943static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
22944                               uint32_t op1, int rt, int rs, int sa)
22945{
22946    TCGv t0;
22947
22948    check_dsp_r2(ctx);
22949
22950    if (rt == 0) {
22951        /* Treat as NOP. */
22952        return;
22953    }
22954
22955    t0 = tcg_temp_new();
22956    gen_load_gpr(t0, rs);
22957
22958    switch (op1) {
22959    case OPC_APPEND_DSP:
22960        switch (MASK_APPEND(ctx->opcode)) {
22961        case OPC_APPEND:
22962            if (sa != 0) {
22963                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
22964            }
22965            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
22966            break;
22967        case OPC_PREPEND:
22968            if (sa != 0) {
22969                tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
22970                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
22971                tcg_gen_shli_tl(t0, t0, 32 - sa);
22972                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
22973            }
22974            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
22975            break;
22976        case OPC_BALIGN:
22977            sa &= 3;
22978            if (sa != 0 && sa != 2) {
22979                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
22980                tcg_gen_ext32u_tl(t0, t0);
22981                tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
22982                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
22983            }
22984            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
22985            break;
22986        default:            /* Invalid */
22987            MIPS_INVAL("MASK APPEND");
22988            gen_reserved_instruction(ctx);
22989            break;
22990        }
22991        break;
22992#ifdef TARGET_MIPS64
22993    case OPC_DAPPEND_DSP:
22994        switch (MASK_DAPPEND(ctx->opcode)) {
22995        case OPC_DAPPEND:
22996            if (sa != 0) {
22997                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
22998            }
22999            break;
23000        case OPC_PREPENDD:
23001            tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
23002            tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
23003            tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
23004            break;
23005        case OPC_PREPENDW:
23006            if (sa != 0) {
23007                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
23008                tcg_gen_shli_tl(t0, t0, 64 - sa);
23009                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23010            }
23011            break;
23012        case OPC_DBALIGN:
23013            sa &= 7;
23014            if (sa != 0 && sa != 2 && sa != 4) {
23015                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
23016                tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
23017                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
23018            }
23019            break;
23020        default:            /* Invalid */
23021            MIPS_INVAL("MASK DAPPEND");
23022            gen_reserved_instruction(ctx);
23023            break;
23024        }
23025        break;
23026#endif
23027    }
23028    tcg_temp_free(t0);
23029}
23030
23031static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
23032                                int ret, int v1, int v2, int check_ret)
23033
23034{
23035    TCGv t0;
23036    TCGv t1;
23037    TCGv v1_t;
23038    TCGv v2_t;
23039    int16_t imm;
23040
23041    if ((ret == 0) && (check_ret == 1)) {
23042        /* Treat as NOP. */
23043        return;
23044    }
23045
23046    t0 = tcg_temp_new();
23047    t1 = tcg_temp_new();
23048    v1_t = tcg_temp_new();
23049    v2_t = tcg_temp_new();
23050
23051    gen_load_gpr(v1_t, v1);
23052    gen_load_gpr(v2_t, v2);
23053
23054    switch (op1) {
23055    case OPC_EXTR_W_DSP:
23056        check_dsp(ctx);
23057        switch (op2) {
23058        case OPC_EXTR_W:
23059            tcg_gen_movi_tl(t0, v2);
23060            tcg_gen_movi_tl(t1, v1);
23061            gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
23062            break;
23063        case OPC_EXTR_R_W:
23064            tcg_gen_movi_tl(t0, v2);
23065            tcg_gen_movi_tl(t1, v1);
23066            gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23067            break;
23068        case OPC_EXTR_RS_W:
23069            tcg_gen_movi_tl(t0, v2);
23070            tcg_gen_movi_tl(t1, v1);
23071            gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23072            break;
23073        case OPC_EXTR_S_H:
23074            tcg_gen_movi_tl(t0, v2);
23075            tcg_gen_movi_tl(t1, v1);
23076            gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23077            break;
23078        case OPC_EXTRV_S_H:
23079            tcg_gen_movi_tl(t0, v2);
23080            gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
23081            break;
23082        case OPC_EXTRV_W:
23083            tcg_gen_movi_tl(t0, v2);
23084            gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23085            break;
23086        case OPC_EXTRV_R_W:
23087            tcg_gen_movi_tl(t0, v2);
23088            gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23089            break;
23090        case OPC_EXTRV_RS_W:
23091            tcg_gen_movi_tl(t0, v2);
23092            gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23093            break;
23094        case OPC_EXTP:
23095            tcg_gen_movi_tl(t0, v2);
23096            tcg_gen_movi_tl(t1, v1);
23097            gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
23098            break;
23099        case OPC_EXTPV:
23100            tcg_gen_movi_tl(t0, v2);
23101            gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
23102            break;
23103        case OPC_EXTPDP:
23104            tcg_gen_movi_tl(t0, v2);
23105            tcg_gen_movi_tl(t1, v1);
23106            gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
23107            break;
23108        case OPC_EXTPDPV:
23109            tcg_gen_movi_tl(t0, v2);
23110            gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23111            break;
23112        case OPC_SHILO:
23113            imm = (ctx->opcode >> 20) & 0x3F;
23114            tcg_gen_movi_tl(t0, ret);
23115            tcg_gen_movi_tl(t1, imm);
23116            gen_helper_shilo(t0, t1, cpu_env);
23117            break;
23118        case OPC_SHILOV:
23119            tcg_gen_movi_tl(t0, ret);
23120            gen_helper_shilo(t0, v1_t, cpu_env);
23121            break;
23122        case OPC_MTHLIP:
23123            tcg_gen_movi_tl(t0, ret);
23124            gen_helper_mthlip(t0, v1_t, cpu_env);
23125            break;
23126        case OPC_WRDSP:
23127            imm = (ctx->opcode >> 11) & 0x3FF;
23128            tcg_gen_movi_tl(t0, imm);
23129            gen_helper_wrdsp(v1_t, t0, cpu_env);
23130            break;
23131        case OPC_RDDSP:
23132            imm = (ctx->opcode >> 16) & 0x03FF;
23133            tcg_gen_movi_tl(t0, imm);
23134            gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
23135            break;
23136        }
23137        break;
23138#ifdef TARGET_MIPS64
23139    case OPC_DEXTR_W_DSP:
23140        check_dsp(ctx);
23141        switch (op2) {
23142        case OPC_DMTHLIP:
23143            tcg_gen_movi_tl(t0, ret);
23144            gen_helper_dmthlip(v1_t, t0, cpu_env);
23145            break;
23146        case OPC_DSHILO:
23147            {
23148                int shift = (ctx->opcode >> 19) & 0x7F;
23149                int ac = (ctx->opcode >> 11) & 0x03;
23150                tcg_gen_movi_tl(t0, shift);
23151                tcg_gen_movi_tl(t1, ac);
23152                gen_helper_dshilo(t0, t1, cpu_env);
23153                break;
23154            }
23155        case OPC_DSHILOV:
23156            {
23157                int ac = (ctx->opcode >> 11) & 0x03;
23158                tcg_gen_movi_tl(t0, ac);
23159                gen_helper_dshilo(v1_t, t0, cpu_env);
23160                break;
23161            }
23162        case OPC_DEXTP:
23163            tcg_gen_movi_tl(t0, v2);
23164            tcg_gen_movi_tl(t1, v1);
23165
23166            gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
23167            break;
23168        case OPC_DEXTPV:
23169            tcg_gen_movi_tl(t0, v2);
23170            gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
23171            break;
23172        case OPC_DEXTPDP:
23173            tcg_gen_movi_tl(t0, v2);
23174            tcg_gen_movi_tl(t1, v1);
23175            gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
23176            break;
23177        case OPC_DEXTPDPV:
23178            tcg_gen_movi_tl(t0, v2);
23179            gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
23180            break;
23181        case OPC_DEXTR_L:
23182            tcg_gen_movi_tl(t0, v2);
23183            tcg_gen_movi_tl(t1, v1);
23184            gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
23185            break;
23186        case OPC_DEXTR_R_L:
23187            tcg_gen_movi_tl(t0, v2);
23188            tcg_gen_movi_tl(t1, v1);
23189            gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
23190            break;
23191        case OPC_DEXTR_RS_L:
23192            tcg_gen_movi_tl(t0, v2);
23193            tcg_gen_movi_tl(t1, v1);
23194            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
23195            break;
23196        case OPC_DEXTR_W:
23197            tcg_gen_movi_tl(t0, v2);
23198            tcg_gen_movi_tl(t1, v1);
23199            gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
23200            break;
23201        case OPC_DEXTR_R_W:
23202            tcg_gen_movi_tl(t0, v2);
23203            tcg_gen_movi_tl(t1, v1);
23204            gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
23205            break;
23206        case OPC_DEXTR_RS_W:
23207            tcg_gen_movi_tl(t0, v2);
23208            tcg_gen_movi_tl(t1, v1);
23209            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
23210            break;
23211        case OPC_DEXTR_S_H:
23212            tcg_gen_movi_tl(t0, v2);
23213            tcg_gen_movi_tl(t1, v1);
23214            gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23215            break;
23216        case OPC_DEXTRV_S_H:
23217            tcg_gen_movi_tl(t0, v2);
23218            tcg_gen_movi_tl(t1, v1);
23219            gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
23220            break;
23221        case OPC_DEXTRV_L:
23222            tcg_gen_movi_tl(t0, v2);
23223            gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23224            break;
23225        case OPC_DEXTRV_R_L:
23226            tcg_gen_movi_tl(t0, v2);
23227            gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23228            break;
23229        case OPC_DEXTRV_RS_L:
23230            tcg_gen_movi_tl(t0, v2);
23231            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
23232            break;
23233        case OPC_DEXTRV_W:
23234            tcg_gen_movi_tl(t0, v2);
23235            gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23236            break;
23237        case OPC_DEXTRV_R_W:
23238            tcg_gen_movi_tl(t0, v2);
23239            gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23240            break;
23241        case OPC_DEXTRV_RS_W:
23242            tcg_gen_movi_tl(t0, v2);
23243            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
23244            break;
23245        }
23246        break;
23247#endif
23248    }
23249
23250    tcg_temp_free(t0);
23251    tcg_temp_free(t1);
23252    tcg_temp_free(v1_t);
23253    tcg_temp_free(v2_t);
23254}
23255
23256/* End MIPSDSP functions. */
23257
23258static void decode_opc_special_r6(CPUMIPSState *env, DisasContext *ctx)
23259{
23260    int rs, rt, rd, sa;
23261    uint32_t op1, op2;
23262
23263    rs = (ctx->opcode >> 21) & 0x1f;
23264    rt = (ctx->opcode >> 16) & 0x1f;
23265    rd = (ctx->opcode >> 11) & 0x1f;
23266    sa = (ctx->opcode >> 6) & 0x1f;
23267
23268    op1 = MASK_SPECIAL(ctx->opcode);
23269    switch (op1) {
23270    case OPC_MULT:
23271    case OPC_MULTU:
23272    case OPC_DIV:
23273    case OPC_DIVU:
23274        op2 = MASK_R6_MULDIV(ctx->opcode);
23275        switch (op2) {
23276        case R6_OPC_MUL:
23277        case R6_OPC_MUH:
23278        case R6_OPC_MULU:
23279        case R6_OPC_MUHU:
23280        case R6_OPC_DIV:
23281        case R6_OPC_MOD:
23282        case R6_OPC_DIVU:
23283        case R6_OPC_MODU:
23284            gen_r6_muldiv(ctx, op2, rd, rs, rt);
23285            break;
23286        default:
23287            MIPS_INVAL("special_r6 muldiv");
23288            gen_reserved_instruction(ctx);
23289            break;
23290        }
23291        break;
23292    case OPC_SELEQZ:
23293    case OPC_SELNEZ:
23294        gen_cond_move(ctx, op1, rd, rs, rt);
23295        break;
23296    case R6_OPC_CLO:
23297    case R6_OPC_CLZ:
23298        if (rt == 0 && sa == 1) {
23299            /*
23300             * Major opcode and function field is shared with preR6 MFHI/MTHI.
23301             * We need additionally to check other fields.
23302             */
23303            gen_cl(ctx, op1, rd, rs);
23304        } else {
23305            gen_reserved_instruction(ctx);
23306        }
23307        break;
23308    case R6_OPC_SDBBP:
23309        if (is_uhi(extract32(ctx->opcode, 6, 20))) {
23310            gen_helper_do_semihosting(cpu_env);
23311        } else {
23312            if (ctx->hflags & MIPS_HFLAG_SBRI) {
23313                gen_reserved_instruction(ctx);
23314            } else {
23315                generate_exception_end(ctx, EXCP_DBp);
23316            }
23317        }
23318        break;
23319#if defined(TARGET_MIPS64)
23320    case R6_OPC_DCLO:
23321    case R6_OPC_DCLZ:
23322        if (rt == 0 && sa == 1) {
23323            /*
23324             * Major opcode and function field is shared with preR6 MFHI/MTHI.
23325             * We need additionally to check other fields.
23326             */
23327            check_mips_64(ctx);
23328            gen_cl(ctx, op1, rd, rs);
23329        } else {
23330            gen_reserved_instruction(ctx);
23331        }
23332        break;
23333    case OPC_DMULT:
23334    case OPC_DMULTU:
23335    case OPC_DDIV:
23336    case OPC_DDIVU:
23337
23338        op2 = MASK_R6_MULDIV(ctx->opcode);
23339        switch (op2) {
23340        case R6_OPC_DMUL:
23341        case R6_OPC_DMUH:
23342        case R6_OPC_DMULU:
23343        case R6_OPC_DMUHU:
23344        case R6_OPC_DDIV:
23345        case R6_OPC_DMOD:
23346        case R6_OPC_DDIVU:
23347        case R6_OPC_DMODU:
23348            check_mips_64(ctx);
23349            gen_r6_muldiv(ctx, op2, rd, rs, rt);
23350            break;
23351        default:
23352            MIPS_INVAL("special_r6 muldiv");
23353            gen_reserved_instruction(ctx);
23354            break;
23355        }
23356        break;
23357#endif
23358    default:            /* Invalid */
23359        MIPS_INVAL("special_r6");
23360        gen_reserved_instruction(ctx);
23361        break;
23362    }
23363}
23364
23365static void decode_opc_special_tx79(CPUMIPSState *env, DisasContext *ctx)
23366{
23367    int rs = extract32(ctx->opcode, 21, 5);
23368    int rt = extract32(ctx->opcode, 16, 5);
23369    int rd = extract32(ctx->opcode, 11, 5);
23370    uint32_t op1 = MASK_SPECIAL(ctx->opcode);
23371
23372    switch (op1) {
23373    case OPC_MOVN:         /* Conditional move */
23374    case OPC_MOVZ:
23375        gen_cond_move(ctx, op1, rd, rs, rt);
23376        break;
23377    case OPC_MFHI:          /* Move from HI/LO */
23378    case OPC_MFLO:
23379        gen_HILO(ctx, op1, 0, rd);
23380        break;
23381    case OPC_MTHI:
23382    case OPC_MTLO:          /* Move to HI/LO */
23383        gen_HILO(ctx, op1, 0, rs);
23384        break;
23385    case OPC_MULT:
23386    case OPC_MULTU:
23387        gen_mul_txx9(ctx, op1, rd, rs, rt);
23388        break;
23389    case OPC_DIV:
23390    case OPC_DIVU:
23391        gen_muldiv(ctx, op1, 0, rs, rt);
23392        break;
23393#if defined(TARGET_MIPS64)
23394    case OPC_DMULT:
23395    case OPC_DMULTU:
23396    case OPC_DDIV:
23397    case OPC_DDIVU:
23398        check_insn_opc_user_only(ctx, INSN_R5900);
23399        gen_muldiv(ctx, op1, 0, rs, rt);
23400        break;
23401#endif
23402    case OPC_JR:
23403        gen_compute_branch(ctx, op1, 4, rs, 0, 0, 4);
23404        break;
23405    default:            /* Invalid */
23406        MIPS_INVAL("special_tx79");
23407        gen_reserved_instruction(ctx);
23408        break;
23409    }
23410}
23411
23412static void decode_opc_special_legacy(CPUMIPSState *env, DisasContext *ctx)
23413{
23414    int rs, rt, rd, sa;
23415    uint32_t op1;
23416
23417    rs = (ctx->opcode >> 21) & 0x1f;
23418    rt = (ctx->opcode >> 16) & 0x1f;
23419    rd = (ctx->opcode >> 11) & 0x1f;
23420    sa = (ctx->opcode >> 6) & 0x1f;
23421
23422    op1 = MASK_SPECIAL(ctx->opcode);
23423    switch (op1) {
23424    case OPC_MOVN:         /* Conditional move */
23425    case OPC_MOVZ:
23426        check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1 |
23427                   INSN_LOONGSON2E | INSN_LOONGSON2F);
23428        gen_cond_move(ctx, op1, rd, rs, rt);
23429        break;
23430    case OPC_MFHI:          /* Move from HI/LO */
23431    case OPC_MFLO:
23432        gen_HILO(ctx, op1, rs & 3, rd);
23433        break;
23434    case OPC_MTHI:
23435    case OPC_MTLO:          /* Move to HI/LO */
23436        gen_HILO(ctx, op1, rd & 3, rs);
23437        break;
23438    case OPC_MOVCI:
23439        check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
23440        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
23441            check_cp1_enabled(ctx);
23442            gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
23443                      (ctx->opcode >> 16) & 1);
23444        } else {
23445            generate_exception_err(ctx, EXCP_CpU, 1);
23446        }
23447        break;
23448    case OPC_MULT:
23449    case OPC_MULTU:
23450        if (sa) {
23451            check_insn(ctx, INSN_VR54XX);
23452            op1 = MASK_MUL_VR54XX(ctx->opcode);
23453            gen_mul_vr54xx(ctx, op1, rd, rs, rt);
23454        } else {
23455            gen_muldiv(ctx, op1, rd & 3, rs, rt);
23456        }
23457        break;
23458    case OPC_DIV:
23459    case OPC_DIVU:
23460        gen_muldiv(ctx, op1, 0, rs, rt);
23461        break;
23462#if defined(TARGET_MIPS64)
23463    case OPC_DMULT:
23464    case OPC_DMULTU:
23465    case OPC_DDIV:
23466    case OPC_DDIVU:
23467        check_insn(ctx, ISA_MIPS3);
23468        check_mips_64(ctx);
23469        gen_muldiv(ctx, op1, 0, rs, rt);
23470        break;
23471#endif
23472    case OPC_JR:
23473        gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
23474        break;
23475    case OPC_SPIM:
23476#ifdef MIPS_STRICT_STANDARD
23477        MIPS_INVAL("SPIM");
23478        gen_reserved_instruction(ctx);
23479#else
23480        /* Implemented as RI exception for now. */
23481        MIPS_INVAL("spim (unofficial)");
23482        gen_reserved_instruction(ctx);
23483#endif
23484        break;
23485    default:            /* Invalid */
23486        MIPS_INVAL("special_legacy");
23487        gen_reserved_instruction(ctx);
23488        break;
23489    }
23490}
23491
23492static void decode_opc_special(CPUMIPSState *env, DisasContext *ctx)
23493{
23494    int rs, rt, rd, sa;
23495    uint32_t op1;
23496
23497    rs = (ctx->opcode >> 21) & 0x1f;
23498    rt = (ctx->opcode >> 16) & 0x1f;
23499    rd = (ctx->opcode >> 11) & 0x1f;
23500    sa = (ctx->opcode >> 6) & 0x1f;
23501
23502    op1 = MASK_SPECIAL(ctx->opcode);
23503    switch (op1) {
23504    case OPC_SLL:          /* Shift with immediate */
23505        if (sa == 5 && rd == 0 &&
23506            rs == 0 && rt == 0) { /* PAUSE */
23507            if ((ctx->insn_flags & ISA_MIPS_R6) &&
23508                (ctx->hflags & MIPS_HFLAG_BMASK)) {
23509                gen_reserved_instruction(ctx);
23510                break;
23511            }
23512        }
23513        /* Fallthrough */
23514    case OPC_SRA:
23515        gen_shift_imm(ctx, op1, rd, rt, sa);
23516        break;
23517    case OPC_SRL:
23518        switch ((ctx->opcode >> 21) & 0x1f) {
23519        case 1:
23520            /* rotr is decoded as srl on non-R2 CPUs */
23521            if (ctx->insn_flags & ISA_MIPS_R2) {
23522                op1 = OPC_ROTR;
23523            }
23524            /* Fallthrough */
23525        case 0:
23526            gen_shift_imm(ctx, op1, rd, rt, sa);
23527            break;
23528        default:
23529            gen_reserved_instruction(ctx);
23530            break;
23531        }
23532        break;
23533    case OPC_ADD:
23534    case OPC_ADDU:
23535    case OPC_SUB:
23536    case OPC_SUBU:
23537        gen_arith(ctx, op1, rd, rs, rt);
23538        break;
23539    case OPC_SLLV:         /* Shifts */
23540    case OPC_SRAV:
23541        gen_shift(ctx, op1, rd, rs, rt);
23542        break;
23543    case OPC_SRLV:
23544        switch ((ctx->opcode >> 6) & 0x1f) {
23545        case 1:
23546            /* rotrv is decoded as srlv on non-R2 CPUs */
23547            if (ctx->insn_flags & ISA_MIPS_R2) {
23548                op1 = OPC_ROTRV;
23549            }
23550            /* Fallthrough */
23551        case 0:
23552            gen_shift(ctx, op1, rd, rs, rt);
23553            break;
23554        default:
23555            gen_reserved_instruction(ctx);
23556            break;
23557        }
23558        break;
23559    case OPC_SLT:          /* Set on less than */
23560    case OPC_SLTU:
23561        gen_slt(ctx, op1, rd, rs, rt);
23562        break;
23563    case OPC_AND:          /* Logic*/
23564    case OPC_OR:
23565    case OPC_NOR:
23566    case OPC_XOR:
23567        gen_logic(ctx, op1, rd, rs, rt);
23568        break;
23569    case OPC_JALR:
23570        gen_compute_branch(ctx, op1, 4, rs, rd, sa, 4);
23571        break;
23572    case OPC_TGE: /* Traps */
23573    case OPC_TGEU:
23574    case OPC_TLT:
23575    case OPC_TLTU:
23576    case OPC_TEQ:
23577    case OPC_TNE:
23578        check_insn(ctx, ISA_MIPS2);
23579        gen_trap(ctx, op1, rs, rt, -1);
23580        break;
23581    case OPC_PMON:
23582        /* Pmon entry point, also R4010 selsl */
23583#ifdef MIPS_STRICT_STANDARD
23584        MIPS_INVAL("PMON / selsl");
23585        gen_reserved_instruction(ctx);
23586#else
23587        gen_helper_0e0i(pmon, sa);
23588#endif
23589        break;
23590    case OPC_SYSCALL:
23591        generate_exception_end(ctx, EXCP_SYSCALL);
23592        break;
23593    case OPC_BREAK:
23594        generate_exception_end(ctx, EXCP_BREAK);
23595        break;
23596    case OPC_SYNC:
23597        check_insn(ctx, ISA_MIPS2);
23598        gen_sync(extract32(ctx->opcode, 6, 5));
23599        break;
23600
23601#if defined(TARGET_MIPS64)
23602        /* MIPS64 specific opcodes */
23603    case OPC_DSLL:
23604    case OPC_DSRA:
23605    case OPC_DSLL32:
23606    case OPC_DSRA32:
23607        check_insn(ctx, ISA_MIPS3);
23608        check_mips_64(ctx);
23609        gen_shift_imm(ctx, op1, rd, rt, sa);
23610        break;
23611    case OPC_DSRL:
23612        switch ((ctx->opcode >> 21) & 0x1f) {
23613        case 1:
23614            /* drotr is decoded as dsrl on non-R2 CPUs */
23615            if (ctx->insn_flags & ISA_MIPS_R2) {
23616                op1 = OPC_DROTR;
23617            }
23618            /* Fallthrough */
23619        case 0:
23620            check_insn(ctx, ISA_MIPS3);
23621            check_mips_64(ctx);
23622            gen_shift_imm(ctx, op1, rd, rt, sa);
23623            break;
23624        default:
23625            gen_reserved_instruction(ctx);
23626            break;
23627        }
23628        break;
23629    case OPC_DSRL32:
23630        switch ((ctx->opcode >> 21) & 0x1f) {
23631        case 1:
23632            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
23633            if (ctx->insn_flags & ISA_MIPS_R2) {
23634                op1 = OPC_DROTR32;
23635            }
23636            /* Fallthrough */
23637        case 0:
23638            check_insn(ctx, ISA_MIPS3);
23639            check_mips_64(ctx);
23640            gen_shift_imm(ctx, op1, rd, rt, sa);
23641            break;
23642        default:
23643            gen_reserved_instruction(ctx);
23644            break;
23645        }
23646        break;
23647    case OPC_DADD:
23648    case OPC_DADDU:
23649    case OPC_DSUB:
23650    case OPC_DSUBU:
23651        check_insn(ctx, ISA_MIPS3);
23652        check_mips_64(ctx);
23653        gen_arith(ctx, op1, rd, rs, rt);
23654        break;
23655    case OPC_DSLLV:
23656    case OPC_DSRAV:
23657        check_insn(ctx, ISA_MIPS3);
23658        check_mips_64(ctx);
23659        gen_shift(ctx, op1, rd, rs, rt);
23660        break;
23661    case OPC_DSRLV:
23662        switch ((ctx->opcode >> 6) & 0x1f) {
23663        case 1:
23664            /* drotrv is decoded as dsrlv on non-R2 CPUs */
23665            if (ctx->insn_flags & ISA_MIPS_R2) {
23666                op1 = OPC_DROTRV;
23667            }
23668            /* Fallthrough */
23669        case 0:
23670            check_insn(ctx, ISA_MIPS3);
23671            check_mips_64(ctx);
23672            gen_shift(ctx, op1, rd, rs, rt);
23673            break;
23674        default:
23675            gen_reserved_instruction(ctx);
23676            break;
23677        }
23678        break;
23679#endif
23680    default:
23681        if (ctx->insn_flags & ISA_MIPS_R6) {
23682            decode_opc_special_r6(env, ctx);
23683        } else if (ctx->insn_flags & INSN_R5900) {
23684            decode_opc_special_tx79(env, ctx);
23685        } else {
23686            decode_opc_special_legacy(env, ctx);
23687        }
23688    }
23689}
23690
23691
23692static void decode_opc_special2_legacy(CPUMIPSState *env, DisasContext *ctx)
23693{
23694    int rs, rt, rd;
23695    uint32_t op1;
23696
23697    rs = (ctx->opcode >> 21) & 0x1f;
23698    rt = (ctx->opcode >> 16) & 0x1f;
23699    rd = (ctx->opcode >> 11) & 0x1f;
23700
23701    op1 = MASK_SPECIAL2(ctx->opcode);
23702    switch (op1) {
23703    case OPC_MADD: /* Multiply and add/sub */
23704    case OPC_MADDU:
23705    case OPC_MSUB:
23706    case OPC_MSUBU:
23707        check_insn(ctx, ISA_MIPS_R1);
23708        gen_muldiv(ctx, op1, rd & 3, rs, rt);
23709        break;
23710    case OPC_MUL:
23711        gen_arith(ctx, op1, rd, rs, rt);
23712        break;
23713    case OPC_DIV_G_2F:
23714    case OPC_DIVU_G_2F:
23715    case OPC_MULT_G_2F:
23716    case OPC_MULTU_G_2F:
23717    case OPC_MOD_G_2F:
23718    case OPC_MODU_G_2F:
23719        check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
23720        gen_loongson_integer(ctx, op1, rd, rs, rt);
23721        break;
23722    case OPC_CLO:
23723    case OPC_CLZ:
23724        check_insn(ctx, ISA_MIPS_R1);
23725        gen_cl(ctx, op1, rd, rs);
23726        break;
23727    case OPC_SDBBP:
23728        if (is_uhi(extract32(ctx->opcode, 6, 20))) {
23729            gen_helper_do_semihosting(cpu_env);
23730        } else {
23731            /*
23732             * XXX: not clear which exception should be raised
23733             *      when in debug mode...
23734             */
23735            check_insn(ctx, ISA_MIPS_R1);
23736            generate_exception_end(ctx, EXCP_DBp);
23737        }
23738        break;
23739#if defined(TARGET_MIPS64)
23740    case OPC_DCLO:
23741    case OPC_DCLZ:
23742        check_insn(ctx, ISA_MIPS_R1);
23743        check_mips_64(ctx);
23744        gen_cl(ctx, op1, rd, rs);
23745        break;
23746    case OPC_DMULT_G_2F:
23747    case OPC_DMULTU_G_2F:
23748    case OPC_DDIV_G_2F:
23749    case OPC_DDIVU_G_2F:
23750    case OPC_DMOD_G_2F:
23751    case OPC_DMODU_G_2F:
23752        check_insn(ctx, INSN_LOONGSON2F | ASE_LEXT);
23753        gen_loongson_integer(ctx, op1, rd, rs, rt);
23754        break;
23755#endif
23756    default:            /* Invalid */
23757        MIPS_INVAL("special2_legacy");
23758        gen_reserved_instruction(ctx);
23759        break;
23760    }
23761}
23762
23763static void decode_opc_special3_r6(CPUMIPSState *env, DisasContext *ctx)
23764{
23765    int rs, rt, rd, sa;
23766    uint32_t op1, op2;
23767    int16_t imm;
23768
23769    rs = (ctx->opcode >> 21) & 0x1f;
23770    rt = (ctx->opcode >> 16) & 0x1f;
23771    rd = (ctx->opcode >> 11) & 0x1f;
23772    sa = (ctx->opcode >> 6) & 0x1f;
23773    imm = (int16_t)ctx->opcode >> 7;
23774
23775    op1 = MASK_SPECIAL3(ctx->opcode);
23776    switch (op1) {
23777    case R6_OPC_PREF:
23778        if (rt >= 24) {
23779            /* hint codes 24-31 are reserved and signal RI */
23780            gen_reserved_instruction(ctx);
23781        }
23782        /* Treat as NOP. */
23783        break;
23784    case R6_OPC_CACHE:
23785        check_cp0_enabled(ctx);
23786        if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
23787            gen_cache_operation(ctx, rt, rs, imm);
23788        }
23789        break;
23790    case R6_OPC_SC:
23791        gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
23792        break;
23793    case R6_OPC_LL:
23794        gen_ld(ctx, op1, rt, rs, imm);
23795        break;
23796    case OPC_BSHFL:
23797        {
23798            if (rd == 0) {
23799                /* Treat as NOP. */
23800                break;
23801            }
23802            op2 = MASK_BSHFL(ctx->opcode);
23803            switch (op2) {
23804            case OPC_ALIGN:
23805            case OPC_ALIGN_1:
23806            case OPC_ALIGN_2:
23807            case OPC_ALIGN_3:
23808                gen_align(ctx, 32, rd, rs, rt, sa & 3);
23809                break;
23810            case OPC_BITSWAP:
23811                gen_bitswap(ctx, op2, rd, rt);
23812                break;
23813            }
23814        }
23815        break;
23816#ifndef CONFIG_USER_ONLY
23817    case OPC_GINV:
23818        if (unlikely(ctx->gi <= 1)) {
23819            gen_reserved_instruction(ctx);
23820        }
23821        check_cp0_enabled(ctx);
23822        switch ((ctx->opcode >> 6) & 3) {
23823        case 0:    /* GINVI */
23824            /* Treat as NOP. */
23825            break;
23826        case 2:    /* GINVT */
23827            gen_helper_0e1i(ginvt, cpu_gpr[rs], extract32(ctx->opcode, 8, 2));
23828            break;
23829        default:
23830            gen_reserved_instruction(ctx);
23831            break;
23832        }
23833        break;
23834#endif
23835#if defined(TARGET_MIPS64)
23836    case R6_OPC_SCD:
23837        gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
23838        break;
23839    case R6_OPC_LLD:
23840        gen_ld(ctx, op1, rt, rs, imm);
23841        break;
23842    case OPC_DBSHFL:
23843        check_mips_64(ctx);
23844        {
23845            if (rd == 0) {
23846                /* Treat as NOP. */
23847                break;
23848            }
23849            op2 = MASK_DBSHFL(ctx->opcode);
23850            switch (op2) {
23851            case OPC_DALIGN:
23852            case OPC_DALIGN_1:
23853            case OPC_DALIGN_2:
23854            case OPC_DALIGN_3:
23855            case OPC_DALIGN_4:
23856            case OPC_DALIGN_5:
23857            case OPC_DALIGN_6:
23858            case OPC_DALIGN_7:
23859                gen_align(ctx, 64, rd, rs, rt, sa & 7);
23860                break;
23861            case OPC_DBITSWAP:
23862                gen_bitswap(ctx, op2, rd, rt);
23863                break;
23864            }
23865
23866        }
23867        break;
23868#endif
23869    default:            /* Invalid */
23870        MIPS_INVAL("special3_r6");
23871        gen_reserved_instruction(ctx);
23872        break;
23873    }
23874}
23875
23876static void decode_opc_special3_legacy(CPUMIPSState *env, DisasContext *ctx)
23877{
23878    int rs, rt, rd;
23879    uint32_t op1, op2;
23880
23881    rs = (ctx->opcode >> 21) & 0x1f;
23882    rt = (ctx->opcode >> 16) & 0x1f;
23883    rd = (ctx->opcode >> 11) & 0x1f;
23884
23885    op1 = MASK_SPECIAL3(ctx->opcode);
23886    switch (op1) {
23887    case OPC_DIV_G_2E:
23888    case OPC_DIVU_G_2E:
23889    case OPC_MOD_G_2E:
23890    case OPC_MODU_G_2E:
23891    case OPC_MULT_G_2E:
23892    case OPC_MULTU_G_2E:
23893        /*
23894         * OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
23895         * the same mask and op1.
23896         */
23897        if ((ctx->insn_flags & ASE_DSP_R2) && (op1 == OPC_MULT_G_2E)) {
23898            op2 = MASK_ADDUH_QB(ctx->opcode);
23899            switch (op2) {
23900            case OPC_ADDUH_QB:
23901            case OPC_ADDUH_R_QB:
23902            case OPC_ADDQH_PH:
23903            case OPC_ADDQH_R_PH:
23904            case OPC_ADDQH_W:
23905            case OPC_ADDQH_R_W:
23906            case OPC_SUBUH_QB:
23907            case OPC_SUBUH_R_QB:
23908            case OPC_SUBQH_PH:
23909            case OPC_SUBQH_R_PH:
23910            case OPC_SUBQH_W:
23911            case OPC_SUBQH_R_W:
23912                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23913                break;
23914            case OPC_MUL_PH:
23915            case OPC_MUL_S_PH:
23916            case OPC_MULQ_S_W:
23917            case OPC_MULQ_RS_W:
23918                gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
23919                break;
23920            default:
23921                MIPS_INVAL("MASK ADDUH.QB");
23922                gen_reserved_instruction(ctx);
23923                break;
23924            }
23925        } else if (ctx->insn_flags & INSN_LOONGSON2E) {
23926            gen_loongson_integer(ctx, op1, rd, rs, rt);
23927        } else {
23928            gen_reserved_instruction(ctx);
23929        }
23930        break;
23931    case OPC_LX_DSP:
23932        op2 = MASK_LX(ctx->opcode);
23933        switch (op2) {
23934#if defined(TARGET_MIPS64)
23935        case OPC_LDX:
23936#endif
23937        case OPC_LBUX:
23938        case OPC_LHX:
23939        case OPC_LWX:
23940            gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
23941            break;
23942        default:            /* Invalid */
23943            MIPS_INVAL("MASK LX");
23944            gen_reserved_instruction(ctx);
23945            break;
23946        }
23947        break;
23948    case OPC_ABSQ_S_PH_DSP:
23949        op2 = MASK_ABSQ_S_PH(ctx->opcode);
23950        switch (op2) {
23951        case OPC_ABSQ_S_QB:
23952        case OPC_ABSQ_S_PH:
23953        case OPC_ABSQ_S_W:
23954        case OPC_PRECEQ_W_PHL:
23955        case OPC_PRECEQ_W_PHR:
23956        case OPC_PRECEQU_PH_QBL:
23957        case OPC_PRECEQU_PH_QBR:
23958        case OPC_PRECEQU_PH_QBLA:
23959        case OPC_PRECEQU_PH_QBRA:
23960        case OPC_PRECEU_PH_QBL:
23961        case OPC_PRECEU_PH_QBR:
23962        case OPC_PRECEU_PH_QBLA:
23963        case OPC_PRECEU_PH_QBRA:
23964            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
23965            break;
23966        case OPC_BITREV:
23967        case OPC_REPL_QB:
23968        case OPC_REPLV_QB:
23969        case OPC_REPL_PH:
23970        case OPC_REPLV_PH:
23971            gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
23972            break;
23973        default:
23974            MIPS_INVAL("MASK ABSQ_S.PH");
23975            gen_reserved_instruction(ctx);
23976            break;
23977        }
23978        break;
23979    case OPC_ADDU_QB_DSP:
23980        op2 = MASK_ADDU_QB(ctx->opcode);
23981        switch (op2) {
23982        case OPC_ADDQ_PH:
23983        case OPC_ADDQ_S_PH:
23984        case OPC_ADDQ_S_W:
23985        case OPC_ADDU_QB:
23986        case OPC_ADDU_S_QB:
23987        case OPC_ADDU_PH:
23988        case OPC_ADDU_S_PH:
23989        case OPC_SUBQ_PH:
23990        case OPC_SUBQ_S_PH:
23991        case OPC_SUBQ_S_W:
23992        case OPC_SUBU_QB:
23993        case OPC_SUBU_S_QB:
23994        case OPC_SUBU_PH:
23995        case OPC_SUBU_S_PH:
23996        case OPC_ADDSC:
23997        case OPC_ADDWC:
23998        case OPC_MODSUB:
23999        case OPC_RADDU_W_QB:
24000            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
24001            break;
24002        case OPC_MULEU_S_PH_QBL:
24003        case OPC_MULEU_S_PH_QBR:
24004        case OPC_MULQ_RS_PH:
24005        case OPC_MULEQ_S_W_PHL:
24006        case OPC_MULEQ_S_W_PHR:
24007        case OPC_MULQ_S_PH:
24008            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
24009            break;
24010        default:            /* Invalid */
24011            MIPS_INVAL("MASK ADDU.QB");
24012            gen_reserved_instruction(ctx);
24013            break;
24014
24015        }
24016        break;
24017    case OPC_CMPU_EQ_QB_DSP:
24018        op2 = MASK_CMPU_EQ_QB(ctx->opcode);
24019        switch (op2) {
24020        case OPC_PRECR_SRA_PH_W:
24021        case OPC_PRECR_SRA_R_PH_W:
24022            gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
24023            break;
24024        case OPC_PRECR_QB_PH:
24025        case OPC_PRECRQ_QB_PH:
24026        case OPC_PRECRQ_PH_W:
24027        case OPC_PRECRQ_RS_PH_W:
24028        case OPC_PRECRQU_S_QB_PH:
24029            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
24030            break;
24031        case OPC_CMPU_EQ_QB:
24032        case OPC_CMPU_LT_QB:
24033        case OPC_CMPU_LE_QB:
24034        case OPC_CMP_EQ_PH:
24035        case OPC_CMP_LT_PH:
24036        case OPC_CMP_LE_PH:
24037            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
24038            break;
24039        case OPC_CMPGU_EQ_QB:
24040        case OPC_CMPGU_LT_QB:
24041        case OPC_CMPGU_LE_QB:
24042        case OPC_CMPGDU_EQ_QB:
24043        case OPC_CMPGDU_LT_QB:
24044        case OPC_CMPGDU_LE_QB:
24045        case OPC_PICK_QB:
24046        case OPC_PICK_PH:
24047        case OPC_PACKRL_PH:
24048            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
24049            break;
24050        default:            /* Invalid */
24051            MIPS_INVAL("MASK CMPU.EQ.QB");
24052            gen_reserved_instruction(ctx);
24053            break;
24054        }
24055        break;
24056    case OPC_SHLL_QB_DSP:
24057        gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
24058        break;
24059    case OPC_DPA_W_PH_DSP:
24060        op2 = MASK_DPA_W_PH(ctx->opcode);
24061        switch (op2) {
24062        case OPC_DPAU_H_QBL:
24063        case OPC_DPAU_H_QBR:
24064        case OPC_DPSU_H_QBL:
24065        case OPC_DPSU_H_QBR:
24066        case OPC_DPA_W_PH:
24067        case OPC_DPAX_W_PH:
24068        case OPC_DPAQ_S_W_PH:
24069        case OPC_DPAQX_S_W_PH:
24070        case OPC_DPAQX_SA_W_PH:
24071        case OPC_DPS_W_PH:
24072        case OPC_DPSX_W_PH:
24073        case OPC_DPSQ_S_W_PH:
24074        case OPC_DPSQX_S_W_PH:
24075        case OPC_DPSQX_SA_W_PH:
24076        case OPC_MULSAQ_S_W_PH:
24077        case OPC_DPAQ_SA_L_W:
24078        case OPC_DPSQ_SA_L_W:
24079        case OPC_MAQ_S_W_PHL:
24080        case OPC_MAQ_S_W_PHR:
24081        case OPC_MAQ_SA_W_PHL:
24082        case OPC_MAQ_SA_W_PHR:
24083        case OPC_MULSA_W_PH:
24084            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
24085            break;
24086        default:            /* Invalid */
24087            MIPS_INVAL("MASK DPAW.PH");
24088            gen_reserved_instruction(ctx);
24089            break;
24090        }
24091        break;
24092    case OPC_INSV_DSP:
24093        op2 = MASK_INSV(ctx->opcode);
24094        switch (op2) {
24095        case OPC_INSV:
24096            check_dsp(ctx);
24097            {
24098                TCGv t0, t1;
24099
24100                if (rt == 0) {
24101                    break;
24102                }
24103
24104                t0 = tcg_temp_new();
24105                t1 = tcg_temp_new();
24106
24107                gen_load_gpr(t0, rt);
24108                gen_load_gpr(t1, rs);
24109
24110                gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
24111
24112                tcg_temp_free(t0);
24113                tcg_temp_free(t1);
24114                break;
24115            }
24116        default:            /* Invalid */
24117            MIPS_INVAL("MASK INSV");
24118            gen_reserved_instruction(ctx);
24119            break;
24120        }
24121        break;
24122    case OPC_APPEND_DSP:
24123        gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
24124        break;
24125    case OPC_EXTR_W_DSP:
24126        op2 = MASK_EXTR_W(ctx->opcode);
24127        switch (op2) {
24128        case OPC_EXTR_W:
24129        case OPC_EXTR_R_W:
24130        case OPC_EXTR_RS_W:
24131        case OPC_EXTR_S_H:
24132        case OPC_EXTRV_S_H:
24133        case OPC_EXTRV_W:
24134        case OPC_EXTRV_R_W:
24135        case OPC_EXTRV_RS_W:
24136        case OPC_EXTP:
24137        case OPC_EXTPV:
24138        case OPC_EXTPDP:
24139        case OPC_EXTPDPV:
24140            gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
24141            break;
24142        case OPC_RDDSP:
24143            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
24144            break;
24145        case OPC_SHILO:
24146        case OPC_SHILOV:
24147        case OPC_MTHLIP:
24148        case OPC_WRDSP:
24149            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
24150            break;
24151        default:            /* Invalid */
24152            MIPS_INVAL("MASK EXTR.W");
24153            gen_reserved_instruction(ctx);
24154            break;
24155        }
24156        break;
24157#if defined(TARGET_MIPS64)
24158    case OPC_DDIV_G_2E:
24159    case OPC_DDIVU_G_2E:
24160    case OPC_DMULT_G_2E:
24161    case OPC_DMULTU_G_2E:
24162    case OPC_DMOD_G_2E:
24163    case OPC_DMODU_G_2E:
24164        check_insn(ctx, INSN_LOONGSON2E);
24165        gen_loongson_integer(ctx, op1, rd, rs, rt);
24166        break;
24167    case OPC_ABSQ_S_QH_DSP:
24168        op2 = MASK_ABSQ_S_QH(ctx->opcode);
24169        switch (op2) {
24170        case OPC_PRECEQ_L_PWL:
24171        case OPC_PRECEQ_L_PWR:
24172        case OPC_PRECEQ_PW_QHL:
24173        case OPC_PRECEQ_PW_QHR:
24174        case OPC_PRECEQ_PW_QHLA:
24175        case OPC_PRECEQ_PW_QHRA:
24176        case OPC_PRECEQU_QH_OBL:
24177        case OPC_PRECEQU_QH_OBR:
24178        case OPC_PRECEQU_QH_OBLA:
24179        case OPC_PRECEQU_QH_OBRA:
24180        case OPC_PRECEU_QH_OBL:
24181        case OPC_PRECEU_QH_OBR:
24182        case OPC_PRECEU_QH_OBLA:
24183        case OPC_PRECEU_QH_OBRA:
24184        case OPC_ABSQ_S_OB:
24185        case OPC_ABSQ_S_PW:
24186        case OPC_ABSQ_S_QH:
24187            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
24188            break;
24189        case OPC_REPL_OB:
24190        case OPC_REPL_PW:
24191        case OPC_REPL_QH:
24192        case OPC_REPLV_OB:
24193        case OPC_REPLV_PW:
24194        case OPC_REPLV_QH:
24195            gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
24196            break;
24197        default:            /* Invalid */
24198            MIPS_INVAL("MASK ABSQ_S.QH");
24199            gen_reserved_instruction(ctx);
24200            break;
24201        }
24202        break;
24203    case OPC_ADDU_OB_DSP:
24204        op2 = MASK_ADDU_OB(ctx->opcode);
24205        switch (op2) {
24206        case OPC_RADDU_L_OB:
24207        case OPC_SUBQ_PW:
24208        case OPC_SUBQ_S_PW:
24209        case OPC_SUBQ_QH:
24210        case OPC_SUBQ_S_QH:
24211        case OPC_SUBU_OB:
24212        case OPC_SUBU_S_OB:
24213        case OPC_SUBU_QH:
24214        case OPC_SUBU_S_QH:
24215        case OPC_SUBUH_OB:
24216        case OPC_SUBUH_R_OB:
24217        case OPC_ADDQ_PW:
24218        case OPC_ADDQ_S_PW:
24219        case OPC_ADDQ_QH:
24220        case OPC_ADDQ_S_QH:
24221        case OPC_ADDU_OB:
24222        case OPC_ADDU_S_OB:
24223        case OPC_ADDU_QH:
24224        case OPC_ADDU_S_QH:
24225        case OPC_ADDUH_OB:
24226        case OPC_ADDUH_R_OB:
24227            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
24228            break;
24229        case OPC_MULEQ_S_PW_QHL:
24230        case OPC_MULEQ_S_PW_QHR:
24231        case OPC_MULEU_S_QH_OBL:
24232        case OPC_MULEU_S_QH_OBR:
24233        case OPC_MULQ_RS_QH:
24234            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
24235            break;
24236        default:            /* Invalid */
24237            MIPS_INVAL("MASK ADDU.OB");
24238            gen_reserved_instruction(ctx);
24239            break;
24240        }
24241        break;
24242    case OPC_CMPU_EQ_OB_DSP:
24243        op2 = MASK_CMPU_EQ_OB(ctx->opcode);
24244        switch (op2) {
24245        case OPC_PRECR_SRA_QH_PW:
24246        case OPC_PRECR_SRA_R_QH_PW:
24247            /* Return value is rt. */
24248            gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
24249            break;
24250        case OPC_PRECR_OB_QH:
24251        case OPC_PRECRQ_OB_QH:
24252        case OPC_PRECRQ_PW_L:
24253        case OPC_PRECRQ_QH_PW:
24254        case OPC_PRECRQ_RS_QH_PW:
24255        case OPC_PRECRQU_S_OB_QH:
24256            gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
24257            break;
24258        case OPC_CMPU_EQ_OB:
24259        case OPC_CMPU_LT_OB:
24260        case OPC_CMPU_LE_OB:
24261        case OPC_CMP_EQ_QH:
24262        case OPC_CMP_LT_QH:
24263        case OPC_CMP_LE_QH:
24264        case OPC_CMP_EQ_PW:
24265        case OPC_CMP_LT_PW:
24266        case OPC_CMP_LE_PW:
24267            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
24268            break;
24269        case OPC_CMPGDU_EQ_OB:
24270        case OPC_CMPGDU_LT_OB:
24271        case OPC_CMPGDU_LE_OB:
24272        case OPC_CMPGU_EQ_OB:
24273        case OPC_CMPGU_LT_OB:
24274        case OPC_CMPGU_LE_OB:
24275        case OPC_PACKRL_PW:
24276        case OPC_PICK_OB:
24277        case OPC_PICK_PW:
24278        case OPC_PICK_QH:
24279            gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
24280            break;
24281        default:            /* Invalid */
24282            MIPS_INVAL("MASK CMPU_EQ.OB");
24283            gen_reserved_instruction(ctx);
24284            break;
24285        }
24286        break;
24287    case OPC_DAPPEND_DSP:
24288        gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
24289        break;
24290    case OPC_DEXTR_W_DSP:
24291        op2 = MASK_DEXTR_W(ctx->opcode);
24292        switch (op2) {
24293        case OPC_DEXTP:
24294        case OPC_DEXTPDP:
24295        case OPC_DEXTPDPV:
24296        case OPC_DEXTPV:
24297        case OPC_DEXTR_L:
24298        case OPC_DEXTR_R_L:
24299        case OPC_DEXTR_RS_L:
24300        case OPC_DEXTR_W:
24301        case OPC_DEXTR_R_W:
24302        case OPC_DEXTR_RS_W:
24303        case OPC_DEXTR_S_H:
24304        case OPC_DEXTRV_L:
24305        case OPC_DEXTRV_R_L:
24306        case OPC_DEXTRV_RS_L:
24307        case OPC_DEXTRV_S_H:
24308        case OPC_DEXTRV_W:
24309        case OPC_DEXTRV_R_W:
24310        case OPC_DEXTRV_RS_W:
24311            gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
24312            break;
24313        case OPC_DMTHLIP:
24314        case OPC_DSHILO:
24315        case OPC_DSHILOV:
24316            gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
24317            break;
24318        default:            /* Invalid */
24319            MIPS_INVAL("MASK EXTR.W");
24320            gen_reserved_instruction(ctx);
24321            break;
24322        }
24323        break;
24324    case OPC_DPAQ_W_QH_DSP:
24325        op2 = MASK_DPAQ_W_QH(ctx->opcode);
24326        switch (op2) {
24327        case OPC_DPAU_H_OBL:
24328        case OPC_DPAU_H_OBR:
24329        case OPC_DPSU_H_OBL:
24330        case OPC_DPSU_H_OBR:
24331        case OPC_DPA_W_QH:
24332        case OPC_DPAQ_S_W_QH:
24333        case OPC_DPS_W_QH:
24334        case OPC_DPSQ_S_W_QH:
24335        case OPC_MULSAQ_S_W_QH:
24336        case OPC_DPAQ_SA_L_PW:
24337        case OPC_DPSQ_SA_L_PW:
24338        case OPC_MULSAQ_S_L_PW:
24339            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
24340            break;
24341        case OPC_MAQ_S_W_QHLL:
24342        case OPC_MAQ_S_W_QHLR:
24343        case OPC_MAQ_S_W_QHRL:
24344        case OPC_MAQ_S_W_QHRR:
24345        case OPC_MAQ_SA_W_QHLL:
24346        case OPC_MAQ_SA_W_QHLR:
24347        case OPC_MAQ_SA_W_QHRL:
24348        case OPC_MAQ_SA_W_QHRR:
24349        case OPC_MAQ_S_L_PWL:
24350        case OPC_MAQ_S_L_PWR:
24351        case OPC_DMADD:
24352        case OPC_DMADDU:
24353        case OPC_DMSUB:
24354        case OPC_DMSUBU:
24355            gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
24356            break;
24357        default:            /* Invalid */
24358            MIPS_INVAL("MASK DPAQ.W.QH");
24359            gen_reserved_instruction(ctx);
24360            break;
24361        }
24362        break;
24363    case OPC_DINSV_DSP:
24364        op2 = MASK_INSV(ctx->opcode);
24365        switch (op2) {
24366        case OPC_DINSV:
24367        {
24368            TCGv t0, t1;
24369
24370            if (rt == 0) {
24371                break;
24372            }
24373            check_dsp(ctx);
24374
24375            t0 = tcg_temp_new();
24376            t1 = tcg_temp_new();
24377
24378            gen_load_gpr(t0, rt);
24379            gen_load_gpr(t1, rs);
24380
24381            gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
24382
24383            tcg_temp_free(t0);
24384            tcg_temp_free(t1);
24385            break;
24386        }
24387        default:            /* Invalid */
24388            MIPS_INVAL("MASK DINSV");
24389            gen_reserved_instruction(ctx);
24390            break;
24391        }
24392        break;
24393    case OPC_SHLL_OB_DSP:
24394        gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
24395        break;
24396#endif
24397    default:            /* Invalid */
24398        MIPS_INVAL("special3_legacy");
24399        gen_reserved_instruction(ctx);
24400        break;
24401    }
24402}
24403
24404
24405#if defined(TARGET_MIPS64)
24406
24407static void decode_mmi(CPUMIPSState *env, DisasContext *ctx)
24408{
24409    uint32_t opc = MASK_MMI(ctx->opcode);
24410    int rs = extract32(ctx->opcode, 21, 5);
24411    int rt = extract32(ctx->opcode, 16, 5);
24412    int rd = extract32(ctx->opcode, 11, 5);
24413
24414    switch (opc) {
24415    case MMI_OPC_MULT1:
24416    case MMI_OPC_MULTU1:
24417    case MMI_OPC_MADD:
24418    case MMI_OPC_MADDU:
24419    case MMI_OPC_MADD1:
24420    case MMI_OPC_MADDU1:
24421        gen_mul_txx9(ctx, opc, rd, rs, rt);
24422        break;
24423    case MMI_OPC_DIV1:
24424    case MMI_OPC_DIVU1:
24425        gen_div1_tx79(ctx, opc, rs, rt);
24426        break;
24427    default:
24428        MIPS_INVAL("TX79 MMI class");
24429        gen_reserved_instruction(ctx);
24430        break;
24431    }
24432}
24433
24434static void gen_mmi_lq(CPUMIPSState *env, DisasContext *ctx)
24435{
24436    gen_reserved_instruction(ctx);    /* TODO: MMI_OPC_LQ */
24437}
24438
24439static void gen_mmi_sq(DisasContext *ctx, int base, int rt, int offset)
24440{
24441    gen_reserved_instruction(ctx);    /* TODO: MMI_OPC_SQ */
24442}
24443
24444/*
24445 * The TX79-specific instruction Store Quadword
24446 *
24447 * +--------+-------+-------+------------------------+
24448 * | 011111 |  base |   rt  |           offset       | SQ
24449 * +--------+-------+-------+------------------------+
24450 *      6       5       5                 16
24451 *
24452 * has the same opcode as the Read Hardware Register instruction
24453 *
24454 * +--------+-------+-------+-------+-------+--------+
24455 * | 011111 | 00000 |   rt  |   rd  | 00000 | 111011 | RDHWR
24456 * +--------+-------+-------+-------+-------+--------+
24457 *      6       5       5       5       5        6
24458 *
24459 * that is required, trapped and emulated by the Linux kernel. However, all
24460 * RDHWR encodings yield address error exceptions on the TX79 since the SQ
24461 * offset is odd. Therefore all valid SQ instructions can execute normally.
24462 * In user mode, QEMU must verify the upper and lower 11 bits to distinguish
24463 * between SQ and RDHWR, as the Linux kernel does.
24464 */
24465static void decode_mmi_sq(CPUMIPSState *env, DisasContext *ctx)
24466{
24467    int base = extract32(ctx->opcode, 21, 5);
24468    int rt = extract32(ctx->opcode, 16, 5);
24469    int offset = extract32(ctx->opcode, 0, 16);
24470
24471#ifdef CONFIG_USER_ONLY
24472    uint32_t op1 = MASK_SPECIAL3(ctx->opcode);
24473    uint32_t op2 = extract32(ctx->opcode, 6, 5);
24474
24475    if (base == 0 && op2 == 0 && op1 == OPC_RDHWR) {
24476        int rd = extract32(ctx->opcode, 11, 5);
24477
24478        gen_rdhwr(ctx, rt, rd, 0);
24479        return;
24480    }
24481#endif
24482
24483    gen_mmi_sq(ctx, base, rt, offset);
24484}
24485
24486#endif
24487
24488static void decode_opc_special3(CPUMIPSState *env, DisasContext *ctx)
24489{
24490    int rs, rt, rd, sa;
24491    uint32_t op1, op2;
24492    int16_t imm;
24493
24494    rs = (ctx->opcode >> 21) & 0x1f;
24495    rt = (ctx->opcode >> 16) & 0x1f;
24496    rd = (ctx->opcode >> 11) & 0x1f;
24497    sa = (ctx->opcode >> 6) & 0x1f;
24498    imm = sextract32(ctx->opcode, 7, 9);
24499
24500    op1 = MASK_SPECIAL3(ctx->opcode);
24501
24502    /*
24503     * EVA loads and stores overlap Loongson 2E instructions decoded by
24504     * decode_opc_special3_legacy(), so be careful to allow their decoding when
24505     * EVA is absent.
24506     */
24507    if (ctx->eva) {
24508        switch (op1) {
24509        case OPC_LWLE:
24510        case OPC_LWRE:
24511        case OPC_LBUE:
24512        case OPC_LHUE:
24513        case OPC_LBE:
24514        case OPC_LHE:
24515        case OPC_LLE:
24516        case OPC_LWE:
24517            check_cp0_enabled(ctx);
24518            gen_ld(ctx, op1, rt, rs, imm);
24519            return;
24520        case OPC_SWLE:
24521        case OPC_SWRE:
24522        case OPC_SBE:
24523        case OPC_SHE:
24524        case OPC_SWE:
24525            check_cp0_enabled(ctx);
24526            gen_st(ctx, op1, rt, rs, imm);
24527            return;
24528        case OPC_SCE:
24529            check_cp0_enabled(ctx);
24530            gen_st_cond(ctx, rt, rs, imm, MO_TESL, true);
24531            return;
24532        case OPC_CACHEE:
24533            check_cp0_enabled(ctx);
24534            if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
24535                gen_cache_operation(ctx, rt, rs, imm);
24536            }
24537            /* Treat as NOP. */
24538            return;
24539        case OPC_PREFE:
24540            check_cp0_enabled(ctx);
24541            /* Treat as NOP. */
24542            return;
24543        }
24544    }
24545
24546    switch (op1) {
24547    case OPC_EXT:
24548    case OPC_INS:
24549        check_insn(ctx, ISA_MIPS_R2);
24550        gen_bitops(ctx, op1, rt, rs, sa, rd);
24551        break;
24552    case OPC_BSHFL:
24553        op2 = MASK_BSHFL(ctx->opcode);
24554        switch (op2) {
24555        case OPC_ALIGN:
24556        case OPC_ALIGN_1:
24557        case OPC_ALIGN_2:
24558        case OPC_ALIGN_3:
24559        case OPC_BITSWAP:
24560            check_insn(ctx, ISA_MIPS_R6);
24561            decode_opc_special3_r6(env, ctx);
24562            break;
24563        default:
24564            check_insn(ctx, ISA_MIPS_R2);
24565            gen_bshfl(ctx, op2, rt, rd);
24566            break;
24567        }
24568        break;
24569#if defined(TARGET_MIPS64)
24570    case OPC_DEXTM:
24571    case OPC_DEXTU:
24572    case OPC_DEXT:
24573    case OPC_DINSM:
24574    case OPC_DINSU:
24575    case OPC_DINS:
24576        check_insn(ctx, ISA_MIPS_R2);
24577        check_mips_64(ctx);
24578        gen_bitops(ctx, op1, rt, rs, sa, rd);
24579        break;
24580    case OPC_DBSHFL:
24581        op2 = MASK_DBSHFL(ctx->opcode);
24582        switch (op2) {
24583        case OPC_DALIGN:
24584        case OPC_DALIGN_1:
24585        case OPC_DALIGN_2:
24586        case OPC_DALIGN_3:
24587        case OPC_DALIGN_4:
24588        case OPC_DALIGN_5:
24589        case OPC_DALIGN_6:
24590        case OPC_DALIGN_7:
24591        case OPC_DBITSWAP:
24592            check_insn(ctx, ISA_MIPS_R6);
24593            decode_opc_special3_r6(env, ctx);
24594            break;
24595        default:
24596            check_insn(ctx, ISA_MIPS_R2);
24597            check_mips_64(ctx);
24598            op2 = MASK_DBSHFL(ctx->opcode);
24599            gen_bshfl(ctx, op2, rt, rd);
24600            break;
24601        }
24602        break;
24603#endif
24604    case OPC_RDHWR:
24605        gen_rdhwr(ctx, rt, rd, extract32(ctx->opcode, 6, 3));
24606        break;
24607    case OPC_FORK:
24608        check_mt(ctx);
24609        {
24610            TCGv t0 = tcg_temp_new();
24611            TCGv t1 = tcg_temp_new();
24612
24613            gen_load_gpr(t0, rt);
24614            gen_load_gpr(t1, rs);
24615            gen_helper_fork(t0, t1);
24616            tcg_temp_free(t0);
24617            tcg_temp_free(t1);
24618        }
24619        break;
24620    case OPC_YIELD:
24621        check_mt(ctx);
24622        {
24623            TCGv t0 = tcg_temp_new();
24624
24625            gen_load_gpr(t0, rs);
24626            gen_helper_yield(t0, cpu_env, t0);
24627            gen_store_gpr(t0, rd);
24628            tcg_temp_free(t0);
24629        }
24630        break;
24631    default:
24632        if (ctx->insn_flags & ISA_MIPS_R6) {
24633            decode_opc_special3_r6(env, ctx);
24634        } else {
24635            decode_opc_special3_legacy(env, ctx);
24636        }
24637    }
24638}
24639
24640static bool decode_opc_legacy(CPUMIPSState *env, DisasContext *ctx)
24641{
24642    int32_t offset;
24643    int rs, rt, rd, sa;
24644    uint32_t op, op1;
24645    int16_t imm;
24646
24647    op = MASK_OP_MAJOR(ctx->opcode);
24648    rs = (ctx->opcode >> 21) & 0x1f;
24649    rt = (ctx->opcode >> 16) & 0x1f;
24650    rd = (ctx->opcode >> 11) & 0x1f;
24651    sa = (ctx->opcode >> 6) & 0x1f;
24652    imm = (int16_t)ctx->opcode;
24653    switch (op) {
24654    case OPC_SPECIAL:
24655        decode_opc_special(env, ctx);
24656        break;
24657    case OPC_SPECIAL2:
24658#if defined(TARGET_MIPS64)
24659        if ((ctx->insn_flags & INSN_R5900) && (ctx->insn_flags & ASE_MMI)) {
24660            decode_mmi(env, ctx);
24661            break;
24662        }
24663#endif
24664        if (TARGET_LONG_BITS == 32 && (ctx->insn_flags & ASE_MXU)) {
24665            if (MASK_SPECIAL2(ctx->opcode) == OPC_MUL) {
24666                gen_arith(ctx, OPC_MUL, rd, rs, rt);
24667            } else {
24668                decode_ase_mxu(ctx, ctx->opcode);
24669            }
24670            break;
24671        }
24672        decode_opc_special2_legacy(env, ctx);
24673        break;
24674    case OPC_SPECIAL3:
24675#if defined(TARGET_MIPS64)
24676        if (ctx->insn_flags & INSN_R5900) {
24677            decode_mmi_sq(env, ctx);    /* MMI_OPC_SQ */
24678        } else {
24679            decode_opc_special3(env, ctx);
24680        }
24681#else
24682        decode_opc_special3(env, ctx);
24683#endif
24684        break;
24685    case OPC_REGIMM:
24686        op1 = MASK_REGIMM(ctx->opcode);
24687        switch (op1) {
24688        case OPC_BLTZL: /* REGIMM branches */
24689        case OPC_BGEZL:
24690        case OPC_BLTZALL:
24691        case OPC_BGEZALL:
24692            check_insn(ctx, ISA_MIPS2);
24693            check_insn_opc_removed(ctx, ISA_MIPS_R6);
24694            /* Fallthrough */
24695        case OPC_BLTZ:
24696        case OPC_BGEZ:
24697            gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
24698            break;
24699        case OPC_BLTZAL:
24700        case OPC_BGEZAL:
24701            if (ctx->insn_flags & ISA_MIPS_R6) {
24702                if (rs == 0) {
24703                    /* OPC_NAL, OPC_BAL */
24704                    gen_compute_branch(ctx, op1, 4, 0, -1, imm << 2, 4);
24705                } else {
24706                    gen_reserved_instruction(ctx);
24707                }
24708            } else {
24709                gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2, 4);
24710            }
24711            break;
24712        case OPC_TGEI: /* REGIMM traps */
24713        case OPC_TGEIU:
24714        case OPC_TLTI:
24715        case OPC_TLTIU:
24716        case OPC_TEQI:
24717
24718        case OPC_TNEI:
24719            check_insn(ctx, ISA_MIPS2);
24720            check_insn_opc_removed(ctx, ISA_MIPS_R6);
24721            gen_trap(ctx, op1, rs, -1, imm);
24722            break;
24723        case OPC_SIGRIE:
24724            check_insn(ctx, ISA_MIPS_R6);
24725            gen_reserved_instruction(ctx);
24726            break;
24727        case OPC_SYNCI:
24728            check_insn(ctx, ISA_MIPS_R2);
24729            /*
24730             * Break the TB to be able to sync copied instructions
24731             * immediately.
24732             */
24733            ctx->base.is_jmp = DISAS_STOP;
24734            break;
24735        case OPC_BPOSGE32:    /* MIPS DSP branch */
24736#if defined(TARGET_MIPS64)
24737        case OPC_BPOSGE64:
24738#endif
24739            check_dsp(ctx);
24740            gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2, 4);
24741            break;
24742#if defined(TARGET_MIPS64)
24743        case OPC_DAHI:
24744            check_insn(ctx, ISA_MIPS_R6);
24745            check_mips_64(ctx);
24746            if (rs != 0) {
24747                tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 32);
24748            }
24749            break;
24750        case OPC_DATI:
24751            check_insn(ctx, ISA_MIPS_R6);
24752            check_mips_64(ctx);
24753            if (rs != 0) {
24754                tcg_gen_addi_tl(cpu_gpr[rs], cpu_gpr[rs], (int64_t)imm << 48);
24755            }
24756            break;
24757#endif
24758        default:            /* Invalid */
24759            MIPS_INVAL("regimm");
24760            gen_reserved_instruction(ctx);
24761            break;
24762        }
24763        break;
24764    case OPC_CP0:
24765        check_cp0_enabled(ctx);
24766        op1 = MASK_CP0(ctx->opcode);
24767        switch (op1) {
24768        case OPC_MFC0:
24769        case OPC_MTC0:
24770        case OPC_MFTR:
24771        case OPC_MTTR:
24772        case OPC_MFHC0:
24773        case OPC_MTHC0:
24774#if defined(TARGET_MIPS64)
24775        case OPC_DMFC0:
24776        case OPC_DMTC0:
24777#endif
24778#ifndef CONFIG_USER_ONLY
24779            gen_cp0(env, ctx, op1, rt, rd);
24780#endif /* !CONFIG_USER_ONLY */
24781            break;
24782        case OPC_C0:
24783        case OPC_C0_1:
24784        case OPC_C0_2:
24785        case OPC_C0_3:
24786        case OPC_C0_4:
24787        case OPC_C0_5:
24788        case OPC_C0_6:
24789        case OPC_C0_7:
24790        case OPC_C0_8:
24791        case OPC_C0_9:
24792        case OPC_C0_A:
24793        case OPC_C0_B:
24794        case OPC_C0_C:
24795        case OPC_C0_D:
24796        case OPC_C0_E:
24797        case OPC_C0_F:
24798#ifndef CONFIG_USER_ONLY
24799            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
24800#endif /* !CONFIG_USER_ONLY */
24801            break;
24802        case OPC_MFMC0:
24803#ifndef CONFIG_USER_ONLY
24804            {
24805                uint32_t op2;
24806                TCGv t0 = tcg_temp_new();
24807
24808                op2 = MASK_MFMC0(ctx->opcode);
24809                switch (op2) {
24810                case OPC_DMT:
24811                    check_cp0_mt(ctx);
24812                    gen_helper_dmt(t0);
24813                    gen_store_gpr(t0, rt);
24814                    break;
24815                case OPC_EMT:
24816                    check_cp0_mt(ctx);
24817                    gen_helper_emt(t0);
24818                    gen_store_gpr(t0, rt);
24819                    break;
24820                case OPC_DVPE:
24821                    check_cp0_mt(ctx);
24822                    gen_helper_dvpe(t0, cpu_env);
24823                    gen_store_gpr(t0, rt);
24824                    break;
24825                case OPC_EVPE:
24826                    check_cp0_mt(ctx);
24827                    gen_helper_evpe(t0, cpu_env);
24828                    gen_store_gpr(t0, rt);
24829                    break;
24830                case OPC_DVP:
24831                    check_insn(ctx, ISA_MIPS_R6);
24832                    if (ctx->vp) {
24833                        gen_helper_dvp(t0, cpu_env);
24834                        gen_store_gpr(t0, rt);
24835                    }
24836                    break;
24837                case OPC_EVP:
24838                    check_insn(ctx, ISA_MIPS_R6);
24839                    if (ctx->vp) {
24840                        gen_helper_evp(t0, cpu_env);
24841                        gen_store_gpr(t0, rt);
24842                    }
24843                    break;
24844                case OPC_DI:
24845                    check_insn(ctx, ISA_MIPS_R2);
24846                    save_cpu_state(ctx, 1);
24847                    gen_helper_di(t0, cpu_env);
24848                    gen_store_gpr(t0, rt);
24849                    /*
24850                     * Stop translation as we may have switched
24851                     * the execution mode.
24852                     */
24853                    ctx->base.is_jmp = DISAS_STOP;
24854                    break;
24855                case OPC_EI:
24856                    check_insn(ctx, ISA_MIPS_R2);
24857                    save_cpu_state(ctx, 1);
24858                    gen_helper_ei(t0, cpu_env);
24859                    gen_store_gpr(t0, rt);
24860                    /*
24861                     * DISAS_STOP isn't sufficient, we need to ensure we break
24862                     * out of translated code to check for pending interrupts.
24863                     */
24864                    gen_save_pc(ctx->base.pc_next + 4);
24865                    ctx->base.is_jmp = DISAS_EXIT;
24866                    break;
24867                default:            /* Invalid */
24868                    MIPS_INVAL("mfmc0");
24869                    gen_reserved_instruction(ctx);
24870                    break;
24871                }
24872                tcg_temp_free(t0);
24873            }
24874#endif /* !CONFIG_USER_ONLY */
24875            break;
24876        case OPC_RDPGPR:
24877            check_insn(ctx, ISA_MIPS_R2);
24878            gen_load_srsgpr(rt, rd);
24879            break;
24880        case OPC_WRPGPR:
24881            check_insn(ctx, ISA_MIPS_R2);
24882            gen_store_srsgpr(rt, rd);
24883            break;
24884        default:
24885            MIPS_INVAL("cp0");
24886            gen_reserved_instruction(ctx);
24887            break;
24888        }
24889        break;
24890    case OPC_BOVC: /* OPC_BEQZALC, OPC_BEQC, OPC_ADDI */
24891        if (ctx->insn_flags & ISA_MIPS_R6) {
24892            /* OPC_BOVC, OPC_BEQZALC, OPC_BEQC */
24893            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
24894        } else {
24895            /* OPC_ADDI */
24896            /* Arithmetic with immediate opcode */
24897            gen_arith_imm(ctx, op, rt, rs, imm);
24898        }
24899        break;
24900    case OPC_ADDIU:
24901         gen_arith_imm(ctx, op, rt, rs, imm);
24902         break;
24903    case OPC_SLTI: /* Set on less than with immediate opcode */
24904    case OPC_SLTIU:
24905         gen_slt_imm(ctx, op, rt, rs, imm);
24906         break;
24907    case OPC_ANDI: /* Arithmetic with immediate opcode */
24908    case OPC_LUI: /* OPC_AUI */
24909    case OPC_ORI:
24910    case OPC_XORI:
24911         gen_logic_imm(ctx, op, rt, rs, imm);
24912         break;
24913    case OPC_J: /* Jump */
24914    case OPC_JAL:
24915         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
24916         gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
24917         break;
24918    /* Branch */
24919    case OPC_BLEZC: /* OPC_BGEZC, OPC_BGEC, OPC_BLEZL */
24920        if (ctx->insn_flags & ISA_MIPS_R6) {
24921            if (rt == 0) {
24922                gen_reserved_instruction(ctx);
24923                break;
24924            }
24925            /* OPC_BLEZC, OPC_BGEZC, OPC_BGEC */
24926            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
24927        } else {
24928            /* OPC_BLEZL */
24929            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
24930        }
24931        break;
24932    case OPC_BGTZC: /* OPC_BLTZC, OPC_BLTC, OPC_BGTZL */
24933        if (ctx->insn_flags & ISA_MIPS_R6) {
24934            if (rt == 0) {
24935                gen_reserved_instruction(ctx);
24936                break;
24937            }
24938            /* OPC_BGTZC, OPC_BLTZC, OPC_BLTC */
24939            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
24940        } else {
24941            /* OPC_BGTZL */
24942            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
24943        }
24944        break;
24945    case OPC_BLEZALC: /* OPC_BGEZALC, OPC_BGEUC, OPC_BLEZ */
24946        if (rt == 0) {
24947            /* OPC_BLEZ */
24948            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
24949        } else {
24950            check_insn(ctx, ISA_MIPS_R6);
24951            /* OPC_BLEZALC, OPC_BGEZALC, OPC_BGEUC */
24952            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
24953        }
24954        break;
24955    case OPC_BGTZALC: /* OPC_BLTZALC, OPC_BLTUC, OPC_BGTZ */
24956        if (rt == 0) {
24957            /* OPC_BGTZ */
24958            gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
24959        } else {
24960            check_insn(ctx, ISA_MIPS_R6);
24961            /* OPC_BGTZALC, OPC_BLTZALC, OPC_BLTUC */
24962            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
24963        }
24964        break;
24965    case OPC_BEQL:
24966    case OPC_BNEL:
24967        check_insn(ctx, ISA_MIPS2);
24968         check_insn_opc_removed(ctx, ISA_MIPS_R6);
24969        /* Fallthrough */
24970    case OPC_BEQ:
24971    case OPC_BNE:
24972         gen_compute_branch(ctx, op, 4, rs, rt, imm << 2, 4);
24973         break;
24974    case OPC_LL: /* Load and stores */
24975        check_insn(ctx, ISA_MIPS2);
24976        if (ctx->insn_flags & INSN_R5900) {
24977            check_insn_opc_user_only(ctx, INSN_R5900);
24978        }
24979        /* Fallthrough */
24980    case OPC_LWL:
24981    case OPC_LWR:
24982    case OPC_LB:
24983    case OPC_LH:
24984    case OPC_LW:
24985    case OPC_LWPC:
24986    case OPC_LBU:
24987    case OPC_LHU:
24988         gen_ld(ctx, op, rt, rs, imm);
24989         break;
24990    case OPC_SWL:
24991    case OPC_SWR:
24992    case OPC_SB:
24993    case OPC_SH:
24994    case OPC_SW:
24995         gen_st(ctx, op, rt, rs, imm);
24996         break;
24997    case OPC_SC:
24998        check_insn(ctx, ISA_MIPS2);
24999        if (ctx->insn_flags & INSN_R5900) {
25000            check_insn_opc_user_only(ctx, INSN_R5900);
25001        }
25002        gen_st_cond(ctx, rt, rs, imm, MO_TESL, false);
25003        break;
25004    case OPC_CACHE:
25005        check_cp0_enabled(ctx);
25006        check_insn(ctx, ISA_MIPS3 | ISA_MIPS_R1);
25007        if (ctx->hflags & MIPS_HFLAG_ITC_CACHE) {
25008            gen_cache_operation(ctx, rt, rs, imm);
25009        }
25010        /* Treat as NOP. */
25011        break;
25012    case OPC_PREF:
25013        if (ctx->insn_flags & INSN_R5900) {
25014            /* Treat as NOP. */
25015        } else {
25016            check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R1);
25017            /* Treat as NOP. */
25018        }
25019        break;
25020
25021    /* Floating point (COP1). */
25022    case OPC_LWC1:
25023    case OPC_LDC1:
25024    case OPC_SWC1:
25025    case OPC_SDC1:
25026        gen_cop1_ldst(ctx, op, rt, rs, imm);
25027        break;
25028
25029    case OPC_CP1:
25030        op1 = MASK_CP1(ctx->opcode);
25031
25032        switch (op1) {
25033        case OPC_MFHC1:
25034        case OPC_MTHC1:
25035            check_cp1_enabled(ctx);
25036            check_insn(ctx, ISA_MIPS_R2);
25037            /* fall through */
25038        case OPC_MFC1:
25039        case OPC_CFC1:
25040        case OPC_MTC1:
25041        case OPC_CTC1:
25042            check_cp1_enabled(ctx);
25043            gen_cp1(ctx, op1, rt, rd);
25044            break;
25045#if defined(TARGET_MIPS64)
25046        case OPC_DMFC1:
25047        case OPC_DMTC1:
25048            check_cp1_enabled(ctx);
25049            check_insn(ctx, ISA_MIPS3);
25050            check_mips_64(ctx);
25051            gen_cp1(ctx, op1, rt, rd);
25052            break;
25053#endif
25054        case OPC_BC1EQZ: /* OPC_BC1ANY2 */
25055            check_cp1_enabled(ctx);
25056            if (ctx->insn_flags & ISA_MIPS_R6) {
25057                /* OPC_BC1EQZ */
25058                gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
25059                                       rt, imm << 2, 4);
25060            } else {
25061                /* OPC_BC1ANY2 */
25062                check_cop1x(ctx);
25063                check_insn(ctx, ASE_MIPS3D);
25064                gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
25065                                    (rt >> 2) & 0x7, imm << 2);
25066            }
25067            break;
25068        case OPC_BC1NEZ:
25069            check_cp1_enabled(ctx);
25070            check_insn(ctx, ISA_MIPS_R6);
25071            gen_compute_branch1_r6(ctx, MASK_CP1(ctx->opcode),
25072                                   rt, imm << 2, 4);
25073            break;
25074        case OPC_BC1ANY4:
25075            check_cp1_enabled(ctx);
25076            check_insn_opc_removed(ctx, ISA_MIPS_R6);
25077            check_cop1x(ctx);
25078            check_insn(ctx, ASE_MIPS3D);
25079            /* fall through */
25080        case OPC_BC1:
25081            check_cp1_enabled(ctx);
25082            check_insn_opc_removed(ctx, ISA_MIPS_R6);
25083            gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
25084                                (rt >> 2) & 0x7, imm << 2);
25085            break;
25086        case OPC_PS_FMT:
25087            check_ps(ctx);
25088            /* fall through */
25089        case OPC_S_FMT:
25090        case OPC_D_FMT:
25091            check_cp1_enabled(ctx);
25092            gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
25093                       (imm >> 8) & 0x7);
25094            break;
25095        case OPC_W_FMT:
25096        case OPC_L_FMT:
25097        {
25098            int r6_op = ctx->opcode & FOP(0x3f, 0x1f);
25099            check_cp1_enabled(ctx);
25100            if (ctx->insn_flags & ISA_MIPS_R6) {
25101                switch (r6_op) {
25102                case R6_OPC_CMP_AF_S:
25103                case R6_OPC_CMP_UN_S:
25104                case R6_OPC_CMP_EQ_S:
25105                case R6_OPC_CMP_UEQ_S:
25106                case R6_OPC_CMP_LT_S:
25107                case R6_OPC_CMP_ULT_S:
25108                case R6_OPC_CMP_LE_S:
25109                case R6_OPC_CMP_ULE_S:
25110                case R6_OPC_CMP_SAF_S:
25111                case R6_OPC_CMP_SUN_S:
25112                case R6_OPC_CMP_SEQ_S:
25113                case R6_OPC_CMP_SEUQ_S:
25114                case R6_OPC_CMP_SLT_S:
25115                case R6_OPC_CMP_SULT_S:
25116                case R6_OPC_CMP_SLE_S:
25117                case R6_OPC_CMP_SULE_S:
25118                case R6_OPC_CMP_OR_S:
25119                case R6_OPC_CMP_UNE_S:
25120                case R6_OPC_CMP_NE_S:
25121                case R6_OPC_CMP_SOR_S:
25122                case R6_OPC_CMP_SUNE_S:
25123                case R6_OPC_CMP_SNE_S:
25124                    gen_r6_cmp_s(ctx, ctx->opcode & 0x1f, rt, rd, sa);
25125                    break;
25126                case R6_OPC_CMP_AF_D:
25127                case R6_OPC_CMP_UN_D:
25128                case R6_OPC_CMP_EQ_D:
25129                case R6_OPC_CMP_UEQ_D:
25130                case R6_OPC_CMP_LT_D:
25131                case R6_OPC_CMP_ULT_D:
25132                case R6_OPC_CMP_LE_D:
25133                case R6_OPC_CMP_ULE_D:
25134                case R6_OPC_CMP_SAF_D:
25135                case R6_OPC_CMP_SUN_D:
25136                case R6_OPC_CMP_SEQ_D:
25137                case R6_OPC_CMP_SEUQ_D:
25138                case R6_OPC_CMP_SLT_D:
25139                case R6_OPC_CMP_SULT_D:
25140                case R6_OPC_CMP_SLE_D:
25141                case R6_OPC_CMP_SULE_D:
25142                case R6_OPC_CMP_OR_D:
25143                case R6_OPC_CMP_UNE_D:
25144                case R6_OPC_CMP_NE_D:
25145                case R6_OPC_CMP_SOR_D:
25146                case R6_OPC_CMP_SUNE_D:
25147                case R6_OPC_CMP_SNE_D:
25148                    gen_r6_cmp_d(ctx, ctx->opcode & 0x1f, rt, rd, sa);
25149                    break;
25150                default:
25151                    gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f),
25152                               rt, rd, sa, (imm >> 8) & 0x7);
25153
25154                    break;
25155                }
25156            } else {
25157                gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
25158                           (imm >> 8) & 0x7);
25159            }
25160            break;
25161        }
25162        default:
25163            MIPS_INVAL("cp1");
25164            gen_reserved_instruction(ctx);
25165            break;
25166        }
25167        break;
25168
25169    /* Compact branches [R6] and COP2 [non-R6] */
25170    case OPC_BC: /* OPC_LWC2 */
25171    case OPC_BALC: /* OPC_SWC2 */
25172        if (ctx->insn_flags & ISA_MIPS_R6) {
25173            /* OPC_BC, OPC_BALC */
25174            gen_compute_compact_branch(ctx, op, 0, 0,
25175                                       sextract32(ctx->opcode << 2, 0, 28));
25176        } else if (ctx->insn_flags & ASE_LEXT) {
25177            gen_loongson_lswc2(ctx, rt, rs, rd);
25178        } else {
25179            /* OPC_LWC2, OPC_SWC2 */
25180            /* COP2: Not implemented. */
25181            generate_exception_err(ctx, EXCP_CpU, 2);
25182        }
25183        break;
25184    case OPC_BEQZC: /* OPC_JIC, OPC_LDC2 */
25185    case OPC_BNEZC: /* OPC_JIALC, OPC_SDC2 */
25186        if (ctx->insn_flags & ISA_MIPS_R6) {
25187            if (rs != 0) {
25188                /* OPC_BEQZC, OPC_BNEZC */
25189                gen_compute_compact_branch(ctx, op, rs, 0,
25190                                           sextract32(ctx->opcode << 2, 0, 23));
25191            } else {
25192                /* OPC_JIC, OPC_JIALC */
25193                gen_compute_compact_branch(ctx, op, 0, rt, imm);
25194            }
25195        } else if (ctx->insn_flags & ASE_LEXT) {
25196            gen_loongson_lsdc2(ctx, rt, rs, rd);
25197        } else {
25198            /* OPC_LWC2, OPC_SWC2 */
25199            /* COP2: Not implemented. */
25200            generate_exception_err(ctx, EXCP_CpU, 2);
25201        }
25202        break;
25203    case OPC_CP2:
25204        check_insn(ctx, ASE_LMMI);
25205        /* Note that these instructions use different fields.  */
25206        gen_loongson_multimedia(ctx, sa, rd, rt);
25207        break;
25208
25209    case OPC_CP3:
25210        if (ctx->CP0_Config1 & (1 << CP0C1_FP)) {
25211            check_cp1_enabled(ctx);
25212            op1 = MASK_CP3(ctx->opcode);
25213            switch (op1) {
25214            case OPC_LUXC1:
25215            case OPC_SUXC1:
25216                check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
25217                /* Fallthrough */
25218            case OPC_LWXC1:
25219            case OPC_LDXC1:
25220            case OPC_SWXC1:
25221            case OPC_SDXC1:
25222                check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
25223                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
25224                break;
25225            case OPC_PREFX:
25226                check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
25227                /* Treat as NOP. */
25228                break;
25229            case OPC_ALNV_PS:
25230                check_insn(ctx, ISA_MIPS5 | ISA_MIPS_R2);
25231                /* Fallthrough */
25232            case OPC_MADD_S:
25233            case OPC_MADD_D:
25234            case OPC_MADD_PS:
25235            case OPC_MSUB_S:
25236            case OPC_MSUB_D:
25237            case OPC_MSUB_PS:
25238            case OPC_NMADD_S:
25239            case OPC_NMADD_D:
25240            case OPC_NMADD_PS:
25241            case OPC_NMSUB_S:
25242            case OPC_NMSUB_D:
25243            case OPC_NMSUB_PS:
25244                check_insn(ctx, ISA_MIPS4 | ISA_MIPS_R2);
25245                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
25246                break;
25247            default:
25248                MIPS_INVAL("cp3");
25249                gen_reserved_instruction(ctx);
25250                break;
25251            }
25252        } else {
25253            generate_exception_err(ctx, EXCP_CpU, 1);
25254        }
25255        break;
25256
25257#if defined(TARGET_MIPS64)
25258    /* MIPS64 opcodes */
25259    case OPC_LLD:
25260        if (ctx->insn_flags & INSN_R5900) {
25261            check_insn_opc_user_only(ctx, INSN_R5900);
25262        }
25263        /* fall through */
25264    case OPC_LDL:
25265    case OPC_LDR:
25266    case OPC_LWU:
25267    case OPC_LD:
25268        check_insn(ctx, ISA_MIPS3);
25269        check_mips_64(ctx);
25270        gen_ld(ctx, op, rt, rs, imm);
25271        break;
25272    case OPC_SDL:
25273    case OPC_SDR:
25274    case OPC_SD:
25275        check_insn(ctx, ISA_MIPS3);
25276        check_mips_64(ctx);
25277        gen_st(ctx, op, rt, rs, imm);
25278        break;
25279    case OPC_SCD:
25280        check_insn(ctx, ISA_MIPS3);
25281        if (ctx->insn_flags & INSN_R5900) {
25282            check_insn_opc_user_only(ctx, INSN_R5900);
25283        }
25284        check_mips_64(ctx);
25285        gen_st_cond(ctx, rt, rs, imm, MO_TEQ, false);
25286        break;
25287    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC, OPC_DADDI */
25288        if (ctx->insn_flags & ISA_MIPS_R6) {
25289            /* OPC_BNVC, OPC_BNEZALC, OPC_BNEC */
25290            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25291        } else {
25292            /* OPC_DADDI */
25293            check_insn(ctx, ISA_MIPS3);
25294            check_mips_64(ctx);
25295            gen_arith_imm(ctx, op, rt, rs, imm);
25296        }
25297        break;
25298    case OPC_DADDIU:
25299        check_insn(ctx, ISA_MIPS3);
25300        check_mips_64(ctx);
25301        gen_arith_imm(ctx, op, rt, rs, imm);
25302        break;
25303#else
25304    case OPC_BNVC: /* OPC_BNEZALC, OPC_BNEC */
25305        if (ctx->insn_flags & ISA_MIPS_R6) {
25306            gen_compute_compact_branch(ctx, op, rs, rt, imm << 2);
25307        } else {
25308            MIPS_INVAL("major opcode");
25309            gen_reserved_instruction(ctx);
25310        }
25311        break;
25312#endif
25313    case OPC_DAUI: /* OPC_JALX */
25314        if (ctx->insn_flags & ISA_MIPS_R6) {
25315#if defined(TARGET_MIPS64)
25316            /* OPC_DAUI */
25317            check_mips_64(ctx);
25318            if (rs == 0) {
25319                generate_exception(ctx, EXCP_RI);
25320            } else if (rt != 0) {
25321                TCGv t0 = tcg_temp_new();
25322                gen_load_gpr(t0, rs);
25323                tcg_gen_addi_tl(cpu_gpr[rt], t0, imm << 16);
25324                tcg_temp_free(t0);
25325            }
25326#else
25327            gen_reserved_instruction(ctx);
25328            MIPS_INVAL("major opcode");
25329#endif
25330        } else {
25331            /* OPC_JALX */
25332            check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
25333            offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
25334            gen_compute_branch(ctx, op, 4, rs, rt, offset, 4);
25335        }
25336        break;
25337    case OPC_MDMX: /* MMI_OPC_LQ */
25338        if (ctx->insn_flags & INSN_R5900) {
25339#if defined(TARGET_MIPS64)
25340            gen_mmi_lq(env, ctx);
25341#endif
25342        } else {
25343            /* MDMX: Not implemented. */
25344        }
25345        break;
25346    case OPC_PCREL:
25347        check_insn(ctx, ISA_MIPS_R6);
25348        gen_pcrel(ctx, ctx->opcode, ctx->base.pc_next, rs);
25349        break;
25350    default:            /* Invalid */
25351        MIPS_INVAL("major opcode");
25352        return false;
25353    }
25354    return true;
25355}
25356
25357static void decode_opc(CPUMIPSState *env, DisasContext *ctx)
25358{
25359    /* make sure instructions are on a word boundary */
25360    if (ctx->base.pc_next & 0x3) {
25361        env->CP0_BadVAddr = ctx->base.pc_next;
25362        generate_exception_err(ctx, EXCP_AdEL, EXCP_INST_NOTAVAIL);
25363        return;
25364    }
25365
25366    /* Handle blikely not taken case */
25367    if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
25368        TCGLabel *l1 = gen_new_label();
25369
25370        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
25371        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
25372        gen_goto_tb(ctx, 1, ctx->base.pc_next + 4);
25373        gen_set_label(l1);
25374    }
25375
25376    /* Transition to the auto-generated decoder.  */
25377
25378    /* ISA extensions */
25379    if (ase_msa_available(env) && decode_ase_msa(ctx, ctx->opcode)) {
25380        return;
25381    }
25382
25383    /* ISA (from latest to oldest) */
25384    if (cpu_supports_isa(env, ISA_MIPS_R6) && decode_isa_rel6(ctx, ctx->opcode)) {
25385        return;
25386    }
25387    if (cpu_supports_isa(env, INSN_R5900) && decode_ext_txx9(ctx, ctx->opcode)) {
25388        return;
25389    }
25390
25391    if (decode_opc_legacy(env, ctx)) {
25392        return;
25393    }
25394
25395    gen_reserved_instruction(ctx);
25396}
25397
25398static void mips_tr_init_disas_context(DisasContextBase *dcbase, CPUState *cs)
25399{
25400    DisasContext *ctx = container_of(dcbase, DisasContext, base);
25401    CPUMIPSState *env = cs->env_ptr;
25402
25403    ctx->page_start = ctx->base.pc_first & TARGET_PAGE_MASK;
25404    ctx->saved_pc = -1;
25405    ctx->insn_flags = env->insn_flags;
25406    ctx->CP0_Config1 = env->CP0_Config1;
25407    ctx->CP0_Config2 = env->CP0_Config2;
25408    ctx->CP0_Config3 = env->CP0_Config3;
25409    ctx->CP0_Config5 = env->CP0_Config5;
25410    ctx->btarget = 0;
25411    ctx->kscrexist = (env->CP0_Config4 >> CP0C4_KScrExist) & 0xff;
25412    ctx->rxi = (env->CP0_Config3 >> CP0C3_RXI) & 1;
25413    ctx->ie = (env->CP0_Config4 >> CP0C4_IE) & 3;
25414    ctx->bi = (env->CP0_Config3 >> CP0C3_BI) & 1;
25415    ctx->bp = (env->CP0_Config3 >> CP0C3_BP) & 1;
25416    ctx->PAMask = env->PAMask;
25417    ctx->mvh = (env->CP0_Config5 >> CP0C5_MVH) & 1;
25418    ctx->eva = (env->CP0_Config5 >> CP0C5_EVA) & 1;
25419    ctx->sc = (env->CP0_Config3 >> CP0C3_SC) & 1;
25420    ctx->CP0_LLAddr_shift = env->CP0_LLAddr_shift;
25421    ctx->cmgcr = (env->CP0_Config3 >> CP0C3_CMGCR) & 1;
25422    /* Restore delay slot state from the tb context.  */
25423    ctx->hflags = (uint32_t)ctx->base.tb->flags; /* FIXME: maybe use 64 bits? */
25424    ctx->ulri = (env->CP0_Config3 >> CP0C3_ULRI) & 1;
25425    ctx->ps = ((env->active_fpu.fcr0 >> FCR0_PS) & 1) ||
25426             (env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F));
25427    ctx->vp = (env->CP0_Config5 >> CP0C5_VP) & 1;
25428    ctx->mrp = (env->CP0_Config5 >> CP0C5_MRP) & 1;
25429    ctx->nan2008 = (env->active_fpu.fcr31 >> FCR31_NAN2008) & 1;
25430    ctx->abs2008 = (env->active_fpu.fcr31 >> FCR31_ABS2008) & 1;
25431    ctx->mi = (env->CP0_Config5 >> CP0C5_MI) & 1;
25432    ctx->gi = (env->CP0_Config5 >> CP0C5_GI) & 3;
25433    restore_cpu_state(env, ctx);
25434#ifdef CONFIG_USER_ONLY
25435        ctx->mem_idx = MIPS_HFLAG_UM;
25436#else
25437        ctx->mem_idx = hflags_mmu_index(ctx->hflags);
25438#endif
25439    ctx->default_tcg_memop_mask = (ctx->insn_flags & (ISA_MIPS_R6 |
25440                                  INSN_LOONGSON3A)) ? MO_UNALN : MO_ALIGN;
25441
25442    LOG_DISAS("\ntb %p idx %d hflags %04x\n", ctx->base.tb, ctx->mem_idx,
25443              ctx->hflags);
25444}
25445
25446static void mips_tr_tb_start(DisasContextBase *dcbase, CPUState *cs)
25447{
25448}
25449
25450static void mips_tr_insn_start(DisasContextBase *dcbase, CPUState *cs)
25451{
25452    DisasContext *ctx = container_of(dcbase, DisasContext, base);
25453
25454    tcg_gen_insn_start(ctx->base.pc_next, ctx->hflags & MIPS_HFLAG_BMASK,
25455                       ctx->btarget);
25456}
25457
25458static bool mips_tr_breakpoint_check(DisasContextBase *dcbase, CPUState *cs,
25459                                     const CPUBreakpoint *bp)
25460{
25461    DisasContext *ctx = container_of(dcbase, DisasContext, base);
25462
25463    save_cpu_state(ctx, 1);
25464    ctx->base.is_jmp = DISAS_NORETURN;
25465    gen_helper_raise_exception_debug(cpu_env);
25466    /*
25467     * The address covered by the breakpoint must be included in
25468     * [tb->pc, tb->pc + tb->size) in order to for it to be
25469     * properly cleared -- thus we increment the PC here so that
25470     * the logic setting tb->size below does the right thing.
25471     */
25472    ctx->base.pc_next += 4;
25473    return true;
25474}
25475
25476static void mips_tr_translate_insn(DisasContextBase *dcbase, CPUState *cs)
25477{
25478    CPUMIPSState *env = cs->env_ptr;
25479    DisasContext *ctx = container_of(dcbase, DisasContext, base);
25480    int insn_bytes;
25481    int is_slot;
25482
25483    is_slot = ctx->hflags & MIPS_HFLAG_BMASK;
25484    if (ctx->insn_flags & ISA_NANOMIPS32) {
25485        ctx->opcode = translator_lduw(env, ctx->base.pc_next);
25486        insn_bytes = decode_nanomips_opc(env, ctx);
25487    } else if (!(ctx->hflags & MIPS_HFLAG_M16)) {
25488        ctx->opcode = translator_ldl(env, ctx->base.pc_next);
25489        insn_bytes = 4;
25490        decode_opc(env, ctx);
25491    } else if (ctx->insn_flags & ASE_MICROMIPS) {
25492        ctx->opcode = translator_lduw(env, ctx->base.pc_next);
25493        insn_bytes = decode_micromips_opc(env, ctx);
25494    } else if (ctx->insn_flags & ASE_MIPS16) {
25495        ctx->opcode = translator_lduw(env, ctx->base.pc_next);
25496        insn_bytes = decode_mips16_opc(env, ctx);
25497    } else {
25498        gen_reserved_instruction(ctx);
25499        g_assert(ctx->base.is_jmp == DISAS_NORETURN);
25500        return;
25501    }
25502
25503    if (ctx->hflags & MIPS_HFLAG_BMASK) {
25504        if (!(ctx->hflags & (MIPS_HFLAG_BDS16 | MIPS_HFLAG_BDS32 |
25505                             MIPS_HFLAG_FBNSLOT))) {
25506            /*
25507             * Force to generate branch as there is neither delay nor
25508             * forbidden slot.
25509             */
25510            is_slot = 1;
25511        }
25512        if ((ctx->hflags & MIPS_HFLAG_M16) &&
25513            (ctx->hflags & MIPS_HFLAG_FBNSLOT)) {
25514            /*
25515             * Force to generate branch as microMIPS R6 doesn't restrict
25516             * branches in the forbidden slot.
25517             */
25518            is_slot = 1;
25519        }
25520    }
25521    if (is_slot) {
25522        gen_branch(ctx, insn_bytes);
25523    }
25524    ctx->base.pc_next += insn_bytes;
25525
25526    if (ctx->base.is_jmp != DISAS_NEXT) {
25527        return;
25528    }
25529    /*
25530     * Execute a branch and its delay slot as a single instruction.
25531     * This is what GDB expects and is consistent with what the
25532     * hardware does (e.g. if a delay slot instruction faults, the
25533     * reported PC is the PC of the branch).
25534     */
25535    if (ctx->base.singlestep_enabled &&
25536        (ctx->hflags & MIPS_HFLAG_BMASK) == 0) {
25537        ctx->base.is_jmp = DISAS_TOO_MANY;
25538    }
25539    if (ctx->base.pc_next - ctx->page_start >= TARGET_PAGE_SIZE) {
25540        ctx->base.is_jmp = DISAS_TOO_MANY;
25541    }
25542}
25543
25544static void mips_tr_tb_stop(DisasContextBase *dcbase, CPUState *cs)
25545{
25546    DisasContext *ctx = container_of(dcbase, DisasContext, base);
25547
25548    if (ctx->base.singlestep_enabled && ctx->base.is_jmp != DISAS_NORETURN) {
25549        save_cpu_state(ctx, ctx->base.is_jmp != DISAS_EXIT);
25550        gen_helper_raise_exception_debug(cpu_env);
25551    } else {
25552        switch (ctx->base.is_jmp) {
25553        case DISAS_STOP:
25554            gen_save_pc(ctx->base.pc_next);
25555            tcg_gen_lookup_and_goto_ptr();
25556            break;
25557        case DISAS_NEXT:
25558        case DISAS_TOO_MANY:
25559            save_cpu_state(ctx, 0);
25560            gen_goto_tb(ctx, 0, ctx->base.pc_next);
25561            break;
25562        case DISAS_EXIT:
25563            tcg_gen_exit_tb(NULL, 0);
25564            break;
25565        case DISAS_NORETURN:
25566            break;
25567        default:
25568            g_assert_not_reached();
25569        }
25570    }
25571}
25572
25573static void mips_tr_disas_log(const DisasContextBase *dcbase, CPUState *cs)
25574{
25575    qemu_log("IN: %s\n", lookup_symbol(dcbase->pc_first));
25576    log_target_disas(cs, dcbase->pc_first, dcbase->tb->size);
25577}
25578
25579static const TranslatorOps mips_tr_ops = {
25580    .init_disas_context = mips_tr_init_disas_context,
25581    .tb_start           = mips_tr_tb_start,
25582    .insn_start         = mips_tr_insn_start,
25583    .breakpoint_check   = mips_tr_breakpoint_check,
25584    .translate_insn     = mips_tr_translate_insn,
25585    .tb_stop            = mips_tr_tb_stop,
25586    .disas_log          = mips_tr_disas_log,
25587};
25588
25589void gen_intermediate_code(CPUState *cs, TranslationBlock *tb, int max_insns)
25590{
25591    DisasContext ctx;
25592
25593    translator_loop(&mips_tr_ops, &ctx.base, cs, tb, max_insns);
25594}
25595
25596static void fpu_dump_state(CPUMIPSState *env, FILE * f, int flags)
25597{
25598    int i;
25599    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
25600
25601#define printfpr(fp)                                                    \
25602    do {                                                                \
25603        if (is_fpu64)                                                   \
25604            qemu_fprintf(f, "w:%08x d:%016" PRIx64                      \
25605                         " fd:%13g fs:%13g psu: %13g\n",                \
25606                         (fp)->w[FP_ENDIAN_IDX], (fp)->d,               \
25607                         (double)(fp)->fd,                              \
25608                         (double)(fp)->fs[FP_ENDIAN_IDX],               \
25609                         (double)(fp)->fs[!FP_ENDIAN_IDX]);             \
25610        else {                                                          \
25611            fpr_t tmp;                                                  \
25612            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
25613            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
25614            qemu_fprintf(f, "w:%08x d:%016" PRIx64                      \
25615                         " fd:%13g fs:%13g psu:%13g\n",                 \
25616                         tmp.w[FP_ENDIAN_IDX], tmp.d,                   \
25617                         (double)tmp.fd,                                \
25618                         (double)tmp.fs[FP_ENDIAN_IDX],                 \
25619                         (double)tmp.fs[!FP_ENDIAN_IDX]);               \
25620        }                                                               \
25621    } while (0)
25622
25623
25624    qemu_fprintf(f,
25625                 "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%02x\n",
25626                 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
25627                 get_float_exception_flags(&env->active_fpu.fp_status));
25628    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
25629        qemu_fprintf(f, "%3s: ", fregnames[i]);
25630        printfpr(&env->active_fpu.fpr[i]);
25631    }
25632
25633#undef printfpr
25634}
25635
25636void mips_cpu_dump_state(CPUState *cs, FILE *f, int flags)
25637{
25638    MIPSCPU *cpu = MIPS_CPU(cs);
25639    CPUMIPSState *env = &cpu->env;
25640    int i;
25641
25642    qemu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
25643                 " LO=0x" TARGET_FMT_lx " ds %04x "
25644                 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
25645                 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
25646                 env->hflags, env->btarget, env->bcond);
25647    for (i = 0; i < 32; i++) {
25648        if ((i & 3) == 0) {
25649            qemu_fprintf(f, "GPR%02d:", i);
25650        }
25651        qemu_fprintf(f, " %s " TARGET_FMT_lx,
25652                     regnames[i], env->active_tc.gpr[i]);
25653        if ((i & 3) == 3) {
25654            qemu_fprintf(f, "\n");
25655        }
25656    }
25657
25658    qemu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x"
25659                 TARGET_FMT_lx "\n",
25660                 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
25661    qemu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x%016"
25662                 PRIx64 "\n",
25663                 env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
25664    qemu_fprintf(f, "    Config2 0x%08x Config3 0x%08x\n",
25665                 env->CP0_Config2, env->CP0_Config3);
25666    qemu_fprintf(f, "    Config4 0x%08x Config5 0x%08x\n",
25667                 env->CP0_Config4, env->CP0_Config5);
25668    if ((flags & CPU_DUMP_FPU) && (env->hflags & MIPS_HFLAG_FPU)) {
25669        fpu_dump_state(env, f, flags);
25670    }
25671}
25672
25673void mips_tcg_init(void)
25674{
25675    int i;
25676
25677    cpu_gpr[0] = NULL;
25678    for (i = 1; i < 32; i++)
25679        cpu_gpr[i] = tcg_global_mem_new(cpu_env,
25680                                        offsetof(CPUMIPSState,
25681                                                 active_tc.gpr[i]),
25682                                        regnames[i]);
25683#if defined(TARGET_MIPS64)
25684    cpu_gpr_hi[0] = NULL;
25685
25686    for (unsigned i = 1; i < 32; i++) {
25687        g_autofree char *rname = g_strdup_printf("%s[hi]", regnames[i]);
25688
25689        cpu_gpr_hi[i] = tcg_global_mem_new_i64(cpu_env,
25690                                               offsetof(CPUMIPSState,
25691                                                        active_tc.gpr_hi[i]),
25692                                               rname);
25693    }
25694#endif /* !TARGET_MIPS64 */
25695    for (i = 0; i < 32; i++) {
25696        int off = offsetof(CPUMIPSState, active_fpu.fpr[i].wr.d[0]);
25697
25698        fpu_f64[i] = tcg_global_mem_new_i64(cpu_env, off, fregnames[i]);
25699    }
25700    msa_translate_init();
25701    cpu_PC = tcg_global_mem_new(cpu_env,
25702                                offsetof(CPUMIPSState, active_tc.PC), "PC");
25703    for (i = 0; i < MIPS_DSP_ACC; i++) {
25704        cpu_HI[i] = tcg_global_mem_new(cpu_env,
25705                                       offsetof(CPUMIPSState, active_tc.HI[i]),
25706                                       regnames_HI[i]);
25707        cpu_LO[i] = tcg_global_mem_new(cpu_env,
25708                                       offsetof(CPUMIPSState, active_tc.LO[i]),
25709                                       regnames_LO[i]);
25710    }
25711    cpu_dspctrl = tcg_global_mem_new(cpu_env,
25712                                     offsetof(CPUMIPSState,
25713                                              active_tc.DSPControl),
25714                                     "DSPControl");
25715    bcond = tcg_global_mem_new(cpu_env,
25716                               offsetof(CPUMIPSState, bcond), "bcond");
25717    btarget = tcg_global_mem_new(cpu_env,
25718                                 offsetof(CPUMIPSState, btarget), "btarget");
25719    hflags = tcg_global_mem_new_i32(cpu_env,
25720                                    offsetof(CPUMIPSState, hflags), "hflags");
25721
25722    fpu_fcr0 = tcg_global_mem_new_i32(cpu_env,
25723                                      offsetof(CPUMIPSState, active_fpu.fcr0),
25724                                      "fcr0");
25725    fpu_fcr31 = tcg_global_mem_new_i32(cpu_env,
25726                                       offsetof(CPUMIPSState, active_fpu.fcr31),
25727                                       "fcr31");
25728    cpu_lladdr = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, lladdr),
25729                                    "lladdr");
25730    cpu_llval = tcg_global_mem_new(cpu_env, offsetof(CPUMIPSState, llval),
25731                                   "llval");
25732
25733    if (TARGET_LONG_BITS == 32) {
25734        mxu_translate_init();
25735    }
25736}
25737
25738void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb,
25739                          target_ulong *data)
25740{
25741    env->active_tc.PC = data[0];
25742    env->hflags &= ~MIPS_HFLAG_BMASK;
25743    env->hflags |= data[1];
25744    switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
25745    case MIPS_HFLAG_BR:
25746        break;
25747    case MIPS_HFLAG_BC:
25748    case MIPS_HFLAG_BL:
25749    case MIPS_HFLAG_B:
25750        env->btarget = data[2];
25751        break;
25752    }
25753}
25754