qemu/target-mips/translate.c
<<
>>
Prefs
   1/*
   2 *  MIPS32 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 *
  10 * This library is free software; you can redistribute it and/or
  11 * modify it under the terms of the GNU Lesser General Public
  12 * License as published by the Free Software Foundation; either
  13 * version 2 of the License, or (at your option) any later version.
  14 *
  15 * This library is distributed in the hope that it will be useful,
  16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  18 * Lesser General Public License for more details.
  19 *
  20 * You should have received a copy of the GNU Lesser General Public
  21 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  22 */
  23
  24#include "cpu.h"
  25#include "disas/disas.h"
  26#include "tcg-op.h"
  27
  28#include "helper.h"
  29#define GEN_HELPER 1
  30#include "helper.h"
  31
  32#define MIPS_DEBUG_DISAS 0
  33//#define MIPS_DEBUG_SIGN_EXTENSIONS
  34
  35/* MIPS major opcodes */
  36#define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
  37
  38enum {
  39    /* indirect opcode tables */
  40    OPC_SPECIAL  = (0x00 << 26),
  41    OPC_REGIMM   = (0x01 << 26),
  42    OPC_CP0      = (0x10 << 26),
  43    OPC_CP1      = (0x11 << 26),
  44    OPC_CP2      = (0x12 << 26),
  45    OPC_CP3      = (0x13 << 26),
  46    OPC_SPECIAL2 = (0x1C << 26),
  47    OPC_SPECIAL3 = (0x1F << 26),
  48    /* arithmetic with immediate */
  49    OPC_ADDI     = (0x08 << 26),
  50    OPC_ADDIU    = (0x09 << 26),
  51    OPC_SLTI     = (0x0A << 26),
  52    OPC_SLTIU    = (0x0B << 26),
  53    /* logic with immediate */
  54    OPC_ANDI     = (0x0C << 26),
  55    OPC_ORI      = (0x0D << 26),
  56    OPC_XORI     = (0x0E << 26),
  57    OPC_LUI      = (0x0F << 26),
  58    /* arithmetic with immediate */
  59    OPC_DADDI    = (0x18 << 26),
  60    OPC_DADDIU   = (0x19 << 26),
  61    /* Jump and branches */
  62    OPC_J        = (0x02 << 26),
  63    OPC_JAL      = (0x03 << 26),
  64    OPC_JALS     = OPC_JAL | 0x5,
  65    OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
  66    OPC_BEQL     = (0x14 << 26),
  67    OPC_BNE      = (0x05 << 26),
  68    OPC_BNEL     = (0x15 << 26),
  69    OPC_BLEZ     = (0x06 << 26),
  70    OPC_BLEZL    = (0x16 << 26),
  71    OPC_BGTZ     = (0x07 << 26),
  72    OPC_BGTZL    = (0x17 << 26),
  73    OPC_JALX     = (0x1D << 26),  /* MIPS 16 only */
  74    OPC_JALXS    = OPC_JALX | 0x5,
  75    /* Load and stores */
  76    OPC_LDL      = (0x1A << 26),
  77    OPC_LDR      = (0x1B << 26),
  78    OPC_LB       = (0x20 << 26),
  79    OPC_LH       = (0x21 << 26),
  80    OPC_LWL      = (0x22 << 26),
  81    OPC_LW       = (0x23 << 26),
  82    OPC_LWPC     = OPC_LW | 0x5,
  83    OPC_LBU      = (0x24 << 26),
  84    OPC_LHU      = (0x25 << 26),
  85    OPC_LWR      = (0x26 << 26),
  86    OPC_LWU      = (0x27 << 26),
  87    OPC_SB       = (0x28 << 26),
  88    OPC_SH       = (0x29 << 26),
  89    OPC_SWL      = (0x2A << 26),
  90    OPC_SW       = (0x2B << 26),
  91    OPC_SDL      = (0x2C << 26),
  92    OPC_SDR      = (0x2D << 26),
  93    OPC_SWR      = (0x2E << 26),
  94    OPC_LL       = (0x30 << 26),
  95    OPC_LLD      = (0x34 << 26),
  96    OPC_LD       = (0x37 << 26),
  97    OPC_LDPC     = OPC_LD | 0x5,
  98    OPC_SC       = (0x38 << 26),
  99    OPC_SCD      = (0x3C << 26),
 100    OPC_SD       = (0x3F << 26),
 101    /* Floating point load/store */
 102    OPC_LWC1     = (0x31 << 26),
 103    OPC_LWC2     = (0x32 << 26),
 104    OPC_LDC1     = (0x35 << 26),
 105    OPC_LDC2     = (0x36 << 26),
 106    OPC_SWC1     = (0x39 << 26),
 107    OPC_SWC2     = (0x3A << 26),
 108    OPC_SDC1     = (0x3D << 26),
 109    OPC_SDC2     = (0x3E << 26),
 110    /* MDMX ASE specific */
 111    OPC_MDMX     = (0x1E << 26),
 112    /* Cache and prefetch */
 113    OPC_CACHE    = (0x2F << 26),
 114    OPC_PREF     = (0x33 << 26),
 115    /* Reserved major opcode */
 116    OPC_MAJOR3B_RESERVED = (0x3B << 26),
 117};
 118
 119/* MIPS special opcodes */
 120#define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
 121
 122enum {
 123    /* Shifts */
 124    OPC_SLL      = 0x00 | OPC_SPECIAL,
 125    /* NOP is SLL r0, r0, 0   */
 126    /* SSNOP is SLL r0, r0, 1 */
 127    /* EHB is SLL r0, r0, 3 */
 128    OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
 129    OPC_ROTR     = OPC_SRL | (1 << 21),
 130    OPC_SRA      = 0x03 | OPC_SPECIAL,
 131    OPC_SLLV     = 0x04 | OPC_SPECIAL,
 132    OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
 133    OPC_ROTRV    = OPC_SRLV | (1 << 6),
 134    OPC_SRAV     = 0x07 | OPC_SPECIAL,
 135    OPC_DSLLV    = 0x14 | OPC_SPECIAL,
 136    OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
 137    OPC_DROTRV   = OPC_DSRLV | (1 << 6),
 138    OPC_DSRAV    = 0x17 | OPC_SPECIAL,
 139    OPC_DSLL     = 0x38 | OPC_SPECIAL,
 140    OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
 141    OPC_DROTR    = OPC_DSRL | (1 << 21),
 142    OPC_DSRA     = 0x3B | OPC_SPECIAL,
 143    OPC_DSLL32   = 0x3C | OPC_SPECIAL,
 144    OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
 145    OPC_DROTR32  = OPC_DSRL32 | (1 << 21),
 146    OPC_DSRA32   = 0x3F | OPC_SPECIAL,
 147    /* Multiplication / division */
 148    OPC_MULT     = 0x18 | OPC_SPECIAL,
 149    OPC_MULTU    = 0x19 | OPC_SPECIAL,
 150    OPC_DIV      = 0x1A | OPC_SPECIAL,
 151    OPC_DIVU     = 0x1B | OPC_SPECIAL,
 152    OPC_DMULT    = 0x1C | OPC_SPECIAL,
 153    OPC_DMULTU   = 0x1D | OPC_SPECIAL,
 154    OPC_DDIV     = 0x1E | OPC_SPECIAL,
 155    OPC_DDIVU    = 0x1F | OPC_SPECIAL,
 156    /* 2 registers arithmetic / logic */
 157    OPC_ADD      = 0x20 | OPC_SPECIAL,
 158    OPC_ADDU     = 0x21 | OPC_SPECIAL,
 159    OPC_SUB      = 0x22 | OPC_SPECIAL,
 160    OPC_SUBU     = 0x23 | OPC_SPECIAL,
 161    OPC_AND      = 0x24 | OPC_SPECIAL,
 162    OPC_OR       = 0x25 | OPC_SPECIAL,
 163    OPC_XOR      = 0x26 | OPC_SPECIAL,
 164    OPC_NOR      = 0x27 | OPC_SPECIAL,
 165    OPC_SLT      = 0x2A | OPC_SPECIAL,
 166    OPC_SLTU     = 0x2B | OPC_SPECIAL,
 167    OPC_DADD     = 0x2C | OPC_SPECIAL,
 168    OPC_DADDU    = 0x2D | OPC_SPECIAL,
 169    OPC_DSUB     = 0x2E | OPC_SPECIAL,
 170    OPC_DSUBU    = 0x2F | OPC_SPECIAL,
 171    /* Jumps */
 172    OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
 173    OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
 174    OPC_JALRC    = OPC_JALR | (0x5 << 6),
 175    OPC_JALRS    = 0x10 | OPC_SPECIAL | (0x5 << 6),
 176    /* Traps */
 177    OPC_TGE      = 0x30 | OPC_SPECIAL,
 178    OPC_TGEU     = 0x31 | OPC_SPECIAL,
 179    OPC_TLT      = 0x32 | OPC_SPECIAL,
 180    OPC_TLTU     = 0x33 | OPC_SPECIAL,
 181    OPC_TEQ      = 0x34 | OPC_SPECIAL,
 182    OPC_TNE      = 0x36 | OPC_SPECIAL,
 183    /* HI / LO registers load & stores */
 184    OPC_MFHI     = 0x10 | OPC_SPECIAL,
 185    OPC_MTHI     = 0x11 | OPC_SPECIAL,
 186    OPC_MFLO     = 0x12 | OPC_SPECIAL,
 187    OPC_MTLO     = 0x13 | OPC_SPECIAL,
 188    /* Conditional moves */
 189    OPC_MOVZ     = 0x0A | OPC_SPECIAL,
 190    OPC_MOVN     = 0x0B | OPC_SPECIAL,
 191
 192    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
 193
 194    /* Special */
 195    OPC_PMON     = 0x05 | OPC_SPECIAL, /* unofficial */
 196    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
 197    OPC_BREAK    = 0x0D | OPC_SPECIAL,
 198    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
 199    OPC_SYNC     = 0x0F | OPC_SPECIAL,
 200
 201    OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
 202    OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
 203    OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
 204    OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
 205    OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
 206    OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
 207    OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
 208};
 209
 210/* Multiplication variants of the vr54xx. */
 211#define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
 212
 213enum {
 214    OPC_VR54XX_MULS    = (0x03 << 6) | OPC_MULT,
 215    OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,
 216    OPC_VR54XX_MACC    = (0x05 << 6) | OPC_MULT,
 217    OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,
 218    OPC_VR54XX_MSAC    = (0x07 << 6) | OPC_MULT,
 219    OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,
 220    OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,
 221    OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,
 222    OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,
 223    OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
 224    OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,
 225    OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
 226    OPC_VR54XX_MSACHI  = (0x0F << 6) | OPC_MULT,
 227    OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
 228};
 229
 230/* REGIMM (rt field) opcodes */
 231#define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
 232
 233enum {
 234    OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
 235    OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
 236    OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
 237    OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
 238    OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
 239    OPC_BLTZALS  = OPC_BLTZAL | 0x5, /* microMIPS */
 240    OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
 241    OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
 242    OPC_BGEZALS  = OPC_BGEZAL | 0x5, /* microMIPS */
 243    OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
 244    OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
 245    OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
 246    OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
 247    OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
 248    OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
 249    OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
 250    OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
 251};
 252
 253/* Special2 opcodes */
 254#define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
 255
 256enum {
 257    /* Multiply & xxx operations */
 258    OPC_MADD     = 0x00 | OPC_SPECIAL2,
 259    OPC_MADDU    = 0x01 | OPC_SPECIAL2,
 260    OPC_MUL      = 0x02 | OPC_SPECIAL2,
 261    OPC_MSUB     = 0x04 | OPC_SPECIAL2,
 262    OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
 263    /* Loongson 2F */
 264    OPC_MULT_G_2F   = 0x10 | OPC_SPECIAL2,
 265    OPC_DMULT_G_2F  = 0x11 | OPC_SPECIAL2,
 266    OPC_MULTU_G_2F  = 0x12 | OPC_SPECIAL2,
 267    OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
 268    OPC_DIV_G_2F    = 0x14 | OPC_SPECIAL2,
 269    OPC_DDIV_G_2F   = 0x15 | OPC_SPECIAL2,
 270    OPC_DIVU_G_2F   = 0x16 | OPC_SPECIAL2,
 271    OPC_DDIVU_G_2F  = 0x17 | OPC_SPECIAL2,
 272    OPC_MOD_G_2F    = 0x1c | OPC_SPECIAL2,
 273    OPC_DMOD_G_2F   = 0x1d | OPC_SPECIAL2,
 274    OPC_MODU_G_2F   = 0x1e | OPC_SPECIAL2,
 275    OPC_DMODU_G_2F  = 0x1f | OPC_SPECIAL2,
 276    /* Misc */
 277    OPC_CLZ      = 0x20 | OPC_SPECIAL2,
 278    OPC_CLO      = 0x21 | OPC_SPECIAL2,
 279    OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
 280    OPC_DCLO     = 0x25 | OPC_SPECIAL2,
 281    /* Special */
 282    OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
 283};
 284
 285/* Special3 opcodes */
 286#define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
 287
 288enum {
 289    OPC_EXT      = 0x00 | OPC_SPECIAL3,
 290    OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
 291    OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
 292    OPC_DEXT     = 0x03 | OPC_SPECIAL3,
 293    OPC_INS      = 0x04 | OPC_SPECIAL3,
 294    OPC_DINSM    = 0x05 | OPC_SPECIAL3,
 295    OPC_DINSU    = 0x06 | OPC_SPECIAL3,
 296    OPC_DINS     = 0x07 | OPC_SPECIAL3,
 297    OPC_FORK     = 0x08 | OPC_SPECIAL3,
 298    OPC_YIELD    = 0x09 | OPC_SPECIAL3,
 299    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
 300    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
 301    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
 302
 303    /* Loongson 2E */
 304    OPC_MULT_G_2E   = 0x18 | OPC_SPECIAL3,
 305    OPC_MULTU_G_2E  = 0x19 | OPC_SPECIAL3,
 306    OPC_DIV_G_2E    = 0x1A | OPC_SPECIAL3,
 307    OPC_DIVU_G_2E   = 0x1B | OPC_SPECIAL3,
 308    OPC_DMULT_G_2E  = 0x1C | OPC_SPECIAL3,
 309    OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
 310    OPC_DDIV_G_2E   = 0x1E | OPC_SPECIAL3,
 311    OPC_DDIVU_G_2E  = 0x1F | OPC_SPECIAL3,
 312    OPC_MOD_G_2E    = 0x22 | OPC_SPECIAL3,
 313    OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
 314    OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
 315    OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
 316
 317    /* MIPS DSP Load */
 318    OPC_LX_DSP         = 0x0A | OPC_SPECIAL3,
 319    /* MIPS DSP Arithmetic */
 320    OPC_ADDU_QB_DSP    = 0x10 | OPC_SPECIAL3,
 321    OPC_ADDU_OB_DSP    = 0x14 | OPC_SPECIAL3,
 322    OPC_ABSQ_S_PH_DSP  = 0x12 | OPC_SPECIAL3,
 323    OPC_ABSQ_S_QH_DSP  = 0x16 | OPC_SPECIAL3,
 324    /* OPC_ADDUH_QB_DSP is same as OPC_MULT_G_2E.  */
 325    /* OPC_ADDUH_QB_DSP   = 0x18 | OPC_SPECIAL3,  */
 326    OPC_CMPU_EQ_QB_DSP = 0x11 | OPC_SPECIAL3,
 327    OPC_CMPU_EQ_OB_DSP = 0x15 | OPC_SPECIAL3,
 328    /* MIPS DSP GPR-Based Shift Sub-class */
 329    OPC_SHLL_QB_DSP    = 0x13 | OPC_SPECIAL3,
 330    OPC_SHLL_OB_DSP    = 0x17 | OPC_SPECIAL3,
 331    /* MIPS DSP Multiply Sub-class insns */
 332    /* OPC_MUL_PH_DSP is same as OPC_ADDUH_QB_DSP.  */
 333    /* OPC_MUL_PH_DSP     = 0x18 | OPC_SPECIAL3,  */
 334    OPC_DPA_W_PH_DSP   = 0x30 | OPC_SPECIAL3,
 335    OPC_DPAQ_W_QH_DSP  = 0x34 | OPC_SPECIAL3,
 336    /* DSP Bit/Manipulation Sub-class */
 337    OPC_INSV_DSP       = 0x0C | OPC_SPECIAL3,
 338    OPC_DINSV_DSP      = 0x0D | OPC_SPECIAL3,
 339    /* MIPS DSP Append Sub-class */
 340    OPC_APPEND_DSP     = 0x31 | OPC_SPECIAL3,
 341    OPC_DAPPEND_DSP    = 0x35 | OPC_SPECIAL3,
 342    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 343    OPC_EXTR_W_DSP     = 0x38 | OPC_SPECIAL3,
 344    OPC_DEXTR_W_DSP    = 0x3C | OPC_SPECIAL3,
 345};
 346
 347/* BSHFL opcodes */
 348#define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
 349
 350enum {
 351    OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
 352    OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
 353    OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
 354};
 355
 356/* DBSHFL opcodes */
 357#define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
 358
 359enum {
 360    OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
 361    OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
 362};
 363
 364/* MIPS DSP REGIMM opcodes */
 365enum {
 366    OPC_BPOSGE32 = (0x1C << 16) | OPC_REGIMM,
 367    OPC_BPOSGE64 = (0x1D << 16) | OPC_REGIMM,
 368};
 369
 370#define MASK_LX(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 371/* MIPS DSP Load */
 372enum {
 373    OPC_LBUX = (0x06 << 6) | OPC_LX_DSP,
 374    OPC_LHX  = (0x04 << 6) | OPC_LX_DSP,
 375    OPC_LWX  = (0x00 << 6) | OPC_LX_DSP,
 376    OPC_LDX = (0x08 << 6) | OPC_LX_DSP,
 377};
 378
 379#define MASK_ADDU_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 380enum {
 381    /* MIPS DSP Arithmetic Sub-class */
 382    OPC_ADDQ_PH        = (0x0A << 6) | OPC_ADDU_QB_DSP,
 383    OPC_ADDQ_S_PH      = (0x0E << 6) | OPC_ADDU_QB_DSP,
 384    OPC_ADDQ_S_W       = (0x16 << 6) | OPC_ADDU_QB_DSP,
 385    OPC_ADDU_QB        = (0x00 << 6) | OPC_ADDU_QB_DSP,
 386    OPC_ADDU_S_QB      = (0x04 << 6) | OPC_ADDU_QB_DSP,
 387    OPC_ADDU_PH        = (0x08 << 6) | OPC_ADDU_QB_DSP,
 388    OPC_ADDU_S_PH      = (0x0C << 6) | OPC_ADDU_QB_DSP,
 389    OPC_SUBQ_PH        = (0x0B << 6) | OPC_ADDU_QB_DSP,
 390    OPC_SUBQ_S_PH      = (0x0F << 6) | OPC_ADDU_QB_DSP,
 391    OPC_SUBQ_S_W       = (0x17 << 6) | OPC_ADDU_QB_DSP,
 392    OPC_SUBU_QB        = (0x01 << 6) | OPC_ADDU_QB_DSP,
 393    OPC_SUBU_S_QB      = (0x05 << 6) | OPC_ADDU_QB_DSP,
 394    OPC_SUBU_PH        = (0x09 << 6) | OPC_ADDU_QB_DSP,
 395    OPC_SUBU_S_PH      = (0x0D << 6) | OPC_ADDU_QB_DSP,
 396    OPC_ADDSC          = (0x10 << 6) | OPC_ADDU_QB_DSP,
 397    OPC_ADDWC          = (0x11 << 6) | OPC_ADDU_QB_DSP,
 398    OPC_MODSUB         = (0x12 << 6) | OPC_ADDU_QB_DSP,
 399    OPC_RADDU_W_QB     = (0x14 << 6) | OPC_ADDU_QB_DSP,
 400    /* MIPS DSP Multiply Sub-class insns */
 401    OPC_MULEU_S_PH_QBL = (0x06 << 6) | OPC_ADDU_QB_DSP,
 402    OPC_MULEU_S_PH_QBR = (0x07 << 6) | OPC_ADDU_QB_DSP,
 403    OPC_MULQ_RS_PH     = (0x1F << 6) | OPC_ADDU_QB_DSP,
 404    OPC_MULEQ_S_W_PHL  = (0x1C << 6) | OPC_ADDU_QB_DSP,
 405    OPC_MULEQ_S_W_PHR  = (0x1D << 6) | OPC_ADDU_QB_DSP,
 406    OPC_MULQ_S_PH      = (0x1E << 6) | OPC_ADDU_QB_DSP,
 407};
 408
 409#define OPC_ADDUH_QB_DSP OPC_MULT_G_2E
 410#define MASK_ADDUH_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 411enum {
 412    /* MIPS DSP Arithmetic Sub-class */
 413    OPC_ADDUH_QB   = (0x00 << 6) | OPC_ADDUH_QB_DSP,
 414    OPC_ADDUH_R_QB = (0x02 << 6) | OPC_ADDUH_QB_DSP,
 415    OPC_ADDQH_PH   = (0x08 << 6) | OPC_ADDUH_QB_DSP,
 416    OPC_ADDQH_R_PH = (0x0A << 6) | OPC_ADDUH_QB_DSP,
 417    OPC_ADDQH_W    = (0x10 << 6) | OPC_ADDUH_QB_DSP,
 418    OPC_ADDQH_R_W  = (0x12 << 6) | OPC_ADDUH_QB_DSP,
 419    OPC_SUBUH_QB   = (0x01 << 6) | OPC_ADDUH_QB_DSP,
 420    OPC_SUBUH_R_QB = (0x03 << 6) | OPC_ADDUH_QB_DSP,
 421    OPC_SUBQH_PH   = (0x09 << 6) | OPC_ADDUH_QB_DSP,
 422    OPC_SUBQH_R_PH = (0x0B << 6) | OPC_ADDUH_QB_DSP,
 423    OPC_SUBQH_W    = (0x11 << 6) | OPC_ADDUH_QB_DSP,
 424    OPC_SUBQH_R_W  = (0x13 << 6) | OPC_ADDUH_QB_DSP,
 425    /* MIPS DSP Multiply Sub-class insns */
 426    OPC_MUL_PH     = (0x0C << 6) | OPC_ADDUH_QB_DSP,
 427    OPC_MUL_S_PH   = (0x0E << 6) | OPC_ADDUH_QB_DSP,
 428    OPC_MULQ_S_W   = (0x16 << 6) | OPC_ADDUH_QB_DSP,
 429    OPC_MULQ_RS_W  = (0x17 << 6) | OPC_ADDUH_QB_DSP,
 430};
 431
 432#define MASK_ABSQ_S_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 433enum {
 434    /* MIPS DSP Arithmetic Sub-class */
 435    OPC_ABSQ_S_QB       = (0x01 << 6) | OPC_ABSQ_S_PH_DSP,
 436    OPC_ABSQ_S_PH       = (0x09 << 6) | OPC_ABSQ_S_PH_DSP,
 437    OPC_ABSQ_S_W        = (0x11 << 6) | OPC_ABSQ_S_PH_DSP,
 438    OPC_PRECEQ_W_PHL    = (0x0C << 6) | OPC_ABSQ_S_PH_DSP,
 439    OPC_PRECEQ_W_PHR    = (0x0D << 6) | OPC_ABSQ_S_PH_DSP,
 440    OPC_PRECEQU_PH_QBL  = (0x04 << 6) | OPC_ABSQ_S_PH_DSP,
 441    OPC_PRECEQU_PH_QBR  = (0x05 << 6) | OPC_ABSQ_S_PH_DSP,
 442    OPC_PRECEQU_PH_QBLA = (0x06 << 6) | OPC_ABSQ_S_PH_DSP,
 443    OPC_PRECEQU_PH_QBRA = (0x07 << 6) | OPC_ABSQ_S_PH_DSP,
 444    OPC_PRECEU_PH_QBL   = (0x1C << 6) | OPC_ABSQ_S_PH_DSP,
 445    OPC_PRECEU_PH_QBR   = (0x1D << 6) | OPC_ABSQ_S_PH_DSP,
 446    OPC_PRECEU_PH_QBLA  = (0x1E << 6) | OPC_ABSQ_S_PH_DSP,
 447    OPC_PRECEU_PH_QBRA  = (0x1F << 6) | OPC_ABSQ_S_PH_DSP,
 448    /* DSP Bit/Manipulation Sub-class */
 449    OPC_BITREV          = (0x1B << 6) | OPC_ABSQ_S_PH_DSP,
 450    OPC_REPL_QB         = (0x02 << 6) | OPC_ABSQ_S_PH_DSP,
 451    OPC_REPLV_QB        = (0x03 << 6) | OPC_ABSQ_S_PH_DSP,
 452    OPC_REPL_PH         = (0x0A << 6) | OPC_ABSQ_S_PH_DSP,
 453    OPC_REPLV_PH        = (0x0B << 6) | OPC_ABSQ_S_PH_DSP,
 454};
 455
 456#define MASK_CMPU_EQ_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 457enum {
 458    /* MIPS DSP Arithmetic Sub-class */
 459    OPC_PRECR_QB_PH      = (0x0D << 6) | OPC_CMPU_EQ_QB_DSP,
 460    OPC_PRECRQ_QB_PH     = (0x0C << 6) | OPC_CMPU_EQ_QB_DSP,
 461    OPC_PRECR_SRA_PH_W   = (0x1E << 6) | OPC_CMPU_EQ_QB_DSP,
 462    OPC_PRECR_SRA_R_PH_W = (0x1F << 6) | OPC_CMPU_EQ_QB_DSP,
 463    OPC_PRECRQ_PH_W      = (0x14 << 6) | OPC_CMPU_EQ_QB_DSP,
 464    OPC_PRECRQ_RS_PH_W   = (0x15 << 6) | OPC_CMPU_EQ_QB_DSP,
 465    OPC_PRECRQU_S_QB_PH  = (0x0F << 6) | OPC_CMPU_EQ_QB_DSP,
 466    /* DSP Compare-Pick Sub-class */
 467    OPC_CMPU_EQ_QB       = (0x00 << 6) | OPC_CMPU_EQ_QB_DSP,
 468    OPC_CMPU_LT_QB       = (0x01 << 6) | OPC_CMPU_EQ_QB_DSP,
 469    OPC_CMPU_LE_QB       = (0x02 << 6) | OPC_CMPU_EQ_QB_DSP,
 470    OPC_CMPGU_EQ_QB      = (0x04 << 6) | OPC_CMPU_EQ_QB_DSP,
 471    OPC_CMPGU_LT_QB      = (0x05 << 6) | OPC_CMPU_EQ_QB_DSP,
 472    OPC_CMPGU_LE_QB      = (0x06 << 6) | OPC_CMPU_EQ_QB_DSP,
 473    OPC_CMPGDU_EQ_QB     = (0x18 << 6) | OPC_CMPU_EQ_QB_DSP,
 474    OPC_CMPGDU_LT_QB     = (0x19 << 6) | OPC_CMPU_EQ_QB_DSP,
 475    OPC_CMPGDU_LE_QB     = (0x1A << 6) | OPC_CMPU_EQ_QB_DSP,
 476    OPC_CMP_EQ_PH        = (0x08 << 6) | OPC_CMPU_EQ_QB_DSP,
 477    OPC_CMP_LT_PH        = (0x09 << 6) | OPC_CMPU_EQ_QB_DSP,
 478    OPC_CMP_LE_PH        = (0x0A << 6) | OPC_CMPU_EQ_QB_DSP,
 479    OPC_PICK_QB          = (0x03 << 6) | OPC_CMPU_EQ_QB_DSP,
 480    OPC_PICK_PH          = (0x0B << 6) | OPC_CMPU_EQ_QB_DSP,
 481    OPC_PACKRL_PH        = (0x0E << 6) | OPC_CMPU_EQ_QB_DSP,
 482};
 483
 484#define MASK_SHLL_QB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 485enum {
 486    /* MIPS DSP GPR-Based Shift Sub-class */
 487    OPC_SHLL_QB    = (0x00 << 6) | OPC_SHLL_QB_DSP,
 488    OPC_SHLLV_QB   = (0x02 << 6) | OPC_SHLL_QB_DSP,
 489    OPC_SHLL_PH    = (0x08 << 6) | OPC_SHLL_QB_DSP,
 490    OPC_SHLLV_PH   = (0x0A << 6) | OPC_SHLL_QB_DSP,
 491    OPC_SHLL_S_PH  = (0x0C << 6) | OPC_SHLL_QB_DSP,
 492    OPC_SHLLV_S_PH = (0x0E << 6) | OPC_SHLL_QB_DSP,
 493    OPC_SHLL_S_W   = (0x14 << 6) | OPC_SHLL_QB_DSP,
 494    OPC_SHLLV_S_W  = (0x16 << 6) | OPC_SHLL_QB_DSP,
 495    OPC_SHRL_QB    = (0x01 << 6) | OPC_SHLL_QB_DSP,
 496    OPC_SHRLV_QB   = (0x03 << 6) | OPC_SHLL_QB_DSP,
 497    OPC_SHRL_PH    = (0x19 << 6) | OPC_SHLL_QB_DSP,
 498    OPC_SHRLV_PH   = (0x1B << 6) | OPC_SHLL_QB_DSP,
 499    OPC_SHRA_QB    = (0x04 << 6) | OPC_SHLL_QB_DSP,
 500    OPC_SHRA_R_QB  = (0x05 << 6) | OPC_SHLL_QB_DSP,
 501    OPC_SHRAV_QB   = (0x06 << 6) | OPC_SHLL_QB_DSP,
 502    OPC_SHRAV_R_QB = (0x07 << 6) | OPC_SHLL_QB_DSP,
 503    OPC_SHRA_PH    = (0x09 << 6) | OPC_SHLL_QB_DSP,
 504    OPC_SHRAV_PH   = (0x0B << 6) | OPC_SHLL_QB_DSP,
 505    OPC_SHRA_R_PH  = (0x0D << 6) | OPC_SHLL_QB_DSP,
 506    OPC_SHRAV_R_PH = (0x0F << 6) | OPC_SHLL_QB_DSP,
 507    OPC_SHRA_R_W   = (0x15 << 6) | OPC_SHLL_QB_DSP,
 508    OPC_SHRAV_R_W  = (0x17 << 6) | OPC_SHLL_QB_DSP,
 509};
 510
 511#define MASK_DPA_W_PH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 512enum {
 513    /* MIPS DSP Multiply Sub-class insns */
 514    OPC_DPAU_H_QBL    = (0x03 << 6) | OPC_DPA_W_PH_DSP,
 515    OPC_DPAU_H_QBR    = (0x07 << 6) | OPC_DPA_W_PH_DSP,
 516    OPC_DPSU_H_QBL    = (0x0B << 6) | OPC_DPA_W_PH_DSP,
 517    OPC_DPSU_H_QBR    = (0x0F << 6) | OPC_DPA_W_PH_DSP,
 518    OPC_DPA_W_PH      = (0x00 << 6) | OPC_DPA_W_PH_DSP,
 519    OPC_DPAX_W_PH     = (0x08 << 6) | OPC_DPA_W_PH_DSP,
 520    OPC_DPAQ_S_W_PH   = (0x04 << 6) | OPC_DPA_W_PH_DSP,
 521    OPC_DPAQX_S_W_PH  = (0x18 << 6) | OPC_DPA_W_PH_DSP,
 522    OPC_DPAQX_SA_W_PH = (0x1A << 6) | OPC_DPA_W_PH_DSP,
 523    OPC_DPS_W_PH      = (0x01 << 6) | OPC_DPA_W_PH_DSP,
 524    OPC_DPSX_W_PH     = (0x09 << 6) | OPC_DPA_W_PH_DSP,
 525    OPC_DPSQ_S_W_PH   = (0x05 << 6) | OPC_DPA_W_PH_DSP,
 526    OPC_DPSQX_S_W_PH  = (0x19 << 6) | OPC_DPA_W_PH_DSP,
 527    OPC_DPSQX_SA_W_PH = (0x1B << 6) | OPC_DPA_W_PH_DSP,
 528    OPC_MULSAQ_S_W_PH = (0x06 << 6) | OPC_DPA_W_PH_DSP,
 529    OPC_DPAQ_SA_L_W   = (0x0C << 6) | OPC_DPA_W_PH_DSP,
 530    OPC_DPSQ_SA_L_W   = (0x0D << 6) | OPC_DPA_W_PH_DSP,
 531    OPC_MAQ_S_W_PHL   = (0x14 << 6) | OPC_DPA_W_PH_DSP,
 532    OPC_MAQ_S_W_PHR   = (0x16 << 6) | OPC_DPA_W_PH_DSP,
 533    OPC_MAQ_SA_W_PHL  = (0x10 << 6) | OPC_DPA_W_PH_DSP,
 534    OPC_MAQ_SA_W_PHR  = (0x12 << 6) | OPC_DPA_W_PH_DSP,
 535    OPC_MULSA_W_PH    = (0x02 << 6) | OPC_DPA_W_PH_DSP,
 536};
 537
 538#define MASK_INSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 539enum {
 540    /* DSP Bit/Manipulation Sub-class */
 541    OPC_INSV = (0x00 << 6) | OPC_INSV_DSP,
 542};
 543
 544#define MASK_APPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 545enum {
 546    /* MIPS DSP Append Sub-class */
 547    OPC_APPEND  = (0x00 << 6) | OPC_APPEND_DSP,
 548    OPC_PREPEND = (0x01 << 6) | OPC_APPEND_DSP,
 549    OPC_BALIGN  = (0x10 << 6) | OPC_APPEND_DSP,
 550};
 551
 552#define MASK_EXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 553enum {
 554    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 555    OPC_EXTR_W     = (0x00 << 6) | OPC_EXTR_W_DSP,
 556    OPC_EXTR_R_W   = (0x04 << 6) | OPC_EXTR_W_DSP,
 557    OPC_EXTR_RS_W  = (0x06 << 6) | OPC_EXTR_W_DSP,
 558    OPC_EXTR_S_H   = (0x0E << 6) | OPC_EXTR_W_DSP,
 559    OPC_EXTRV_S_H  = (0x0F << 6) | OPC_EXTR_W_DSP,
 560    OPC_EXTRV_W    = (0x01 << 6) | OPC_EXTR_W_DSP,
 561    OPC_EXTRV_R_W  = (0x05 << 6) | OPC_EXTR_W_DSP,
 562    OPC_EXTRV_RS_W = (0x07 << 6) | OPC_EXTR_W_DSP,
 563    OPC_EXTP       = (0x02 << 6) | OPC_EXTR_W_DSP,
 564    OPC_EXTPV      = (0x03 << 6) | OPC_EXTR_W_DSP,
 565    OPC_EXTPDP     = (0x0A << 6) | OPC_EXTR_W_DSP,
 566    OPC_EXTPDPV    = (0x0B << 6) | OPC_EXTR_W_DSP,
 567    OPC_SHILO      = (0x1A << 6) | OPC_EXTR_W_DSP,
 568    OPC_SHILOV     = (0x1B << 6) | OPC_EXTR_W_DSP,
 569    OPC_MTHLIP     = (0x1F << 6) | OPC_EXTR_W_DSP,
 570    OPC_WRDSP      = (0x13 << 6) | OPC_EXTR_W_DSP,
 571    OPC_RDDSP      = (0x12 << 6) | OPC_EXTR_W_DSP,
 572};
 573
 574#define MASK_ABSQ_S_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 575enum {
 576    /* MIPS DSP Arithmetic Sub-class */
 577    OPC_PRECEQ_L_PWL    = (0x14 << 6) | OPC_ABSQ_S_QH_DSP,
 578    OPC_PRECEQ_L_PWR    = (0x15 << 6) | OPC_ABSQ_S_QH_DSP,
 579    OPC_PRECEQ_PW_QHL   = (0x0C << 6) | OPC_ABSQ_S_QH_DSP,
 580    OPC_PRECEQ_PW_QHR   = (0x0D << 6) | OPC_ABSQ_S_QH_DSP,
 581    OPC_PRECEQ_PW_QHLA  = (0x0E << 6) | OPC_ABSQ_S_QH_DSP,
 582    OPC_PRECEQ_PW_QHRA  = (0x0F << 6) | OPC_ABSQ_S_QH_DSP,
 583    OPC_PRECEQU_QH_OBL  = (0x04 << 6) | OPC_ABSQ_S_QH_DSP,
 584    OPC_PRECEQU_QH_OBR  = (0x05 << 6) | OPC_ABSQ_S_QH_DSP,
 585    OPC_PRECEQU_QH_OBLA = (0x06 << 6) | OPC_ABSQ_S_QH_DSP,
 586    OPC_PRECEQU_QH_OBRA = (0x07 << 6) | OPC_ABSQ_S_QH_DSP,
 587    OPC_PRECEU_QH_OBL   = (0x1C << 6) | OPC_ABSQ_S_QH_DSP,
 588    OPC_PRECEU_QH_OBR   = (0x1D << 6) | OPC_ABSQ_S_QH_DSP,
 589    OPC_PRECEU_QH_OBLA  = (0x1E << 6) | OPC_ABSQ_S_QH_DSP,
 590    OPC_PRECEU_QH_OBRA  = (0x1F << 6) | OPC_ABSQ_S_QH_DSP,
 591    OPC_ABSQ_S_OB       = (0x01 << 6) | OPC_ABSQ_S_QH_DSP,
 592    OPC_ABSQ_S_PW       = (0x11 << 6) | OPC_ABSQ_S_QH_DSP,
 593    OPC_ABSQ_S_QH       = (0x09 << 6) | OPC_ABSQ_S_QH_DSP,
 594    /* DSP Bit/Manipulation Sub-class */
 595    OPC_REPL_OB         = (0x02 << 6) | OPC_ABSQ_S_QH_DSP,
 596    OPC_REPL_PW         = (0x12 << 6) | OPC_ABSQ_S_QH_DSP,
 597    OPC_REPL_QH         = (0x0A << 6) | OPC_ABSQ_S_QH_DSP,
 598    OPC_REPLV_OB        = (0x03 << 6) | OPC_ABSQ_S_QH_DSP,
 599    OPC_REPLV_PW        = (0x13 << 6) | OPC_ABSQ_S_QH_DSP,
 600    OPC_REPLV_QH        = (0x0B << 6) | OPC_ABSQ_S_QH_DSP,
 601};
 602
 603#define MASK_ADDU_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 604enum {
 605    /* MIPS DSP Multiply Sub-class insns */
 606    OPC_MULEQ_S_PW_QHL = (0x1C << 6) | OPC_ADDU_OB_DSP,
 607    OPC_MULEQ_S_PW_QHR = (0x1D << 6) | OPC_ADDU_OB_DSP,
 608    OPC_MULEU_S_QH_OBL = (0x06 << 6) | OPC_ADDU_OB_DSP,
 609    OPC_MULEU_S_QH_OBR = (0x07 << 6) | OPC_ADDU_OB_DSP,
 610    OPC_MULQ_RS_QH     = (0x1F << 6) | OPC_ADDU_OB_DSP,
 611    /* MIPS DSP Arithmetic Sub-class */
 612    OPC_RADDU_L_OB     = (0x14 << 6) | OPC_ADDU_OB_DSP,
 613    OPC_SUBQ_PW        = (0x13 << 6) | OPC_ADDU_OB_DSP,
 614    OPC_SUBQ_S_PW      = (0x17 << 6) | OPC_ADDU_OB_DSP,
 615    OPC_SUBQ_QH        = (0x0B << 6) | OPC_ADDU_OB_DSP,
 616    OPC_SUBQ_S_QH      = (0x0F << 6) | OPC_ADDU_OB_DSP,
 617    OPC_SUBU_OB        = (0x01 << 6) | OPC_ADDU_OB_DSP,
 618    OPC_SUBU_S_OB      = (0x05 << 6) | OPC_ADDU_OB_DSP,
 619    OPC_SUBU_QH        = (0x09 << 6) | OPC_ADDU_OB_DSP,
 620    OPC_SUBU_S_QH      = (0x0D << 6) | OPC_ADDU_OB_DSP,
 621    OPC_SUBUH_OB       = (0x19 << 6) | OPC_ADDU_OB_DSP,
 622    OPC_SUBUH_R_OB     = (0x1B << 6) | OPC_ADDU_OB_DSP,
 623    OPC_ADDQ_PW        = (0x12 << 6) | OPC_ADDU_OB_DSP,
 624    OPC_ADDQ_S_PW      = (0x16 << 6) | OPC_ADDU_OB_DSP,
 625    OPC_ADDQ_QH        = (0x0A << 6) | OPC_ADDU_OB_DSP,
 626    OPC_ADDQ_S_QH      = (0x0E << 6) | OPC_ADDU_OB_DSP,
 627    OPC_ADDU_OB        = (0x00 << 6) | OPC_ADDU_OB_DSP,
 628    OPC_ADDU_S_OB      = (0x04 << 6) | OPC_ADDU_OB_DSP,
 629    OPC_ADDU_QH        = (0x08 << 6) | OPC_ADDU_OB_DSP,
 630    OPC_ADDU_S_QH      = (0x0C << 6) | OPC_ADDU_OB_DSP,
 631    OPC_ADDUH_OB       = (0x18 << 6) | OPC_ADDU_OB_DSP,
 632    OPC_ADDUH_R_OB     = (0x1A << 6) | OPC_ADDU_OB_DSP,
 633};
 634
 635#define MASK_CMPU_EQ_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 636enum {
 637    /* DSP Compare-Pick Sub-class */
 638    OPC_CMP_EQ_PW         = (0x10 << 6) | OPC_CMPU_EQ_OB_DSP,
 639    OPC_CMP_LT_PW         = (0x11 << 6) | OPC_CMPU_EQ_OB_DSP,
 640    OPC_CMP_LE_PW         = (0x12 << 6) | OPC_CMPU_EQ_OB_DSP,
 641    OPC_CMP_EQ_QH         = (0x08 << 6) | OPC_CMPU_EQ_OB_DSP,
 642    OPC_CMP_LT_QH         = (0x09 << 6) | OPC_CMPU_EQ_OB_DSP,
 643    OPC_CMP_LE_QH         = (0x0A << 6) | OPC_CMPU_EQ_OB_DSP,
 644    OPC_CMPGDU_EQ_OB      = (0x18 << 6) | OPC_CMPU_EQ_OB_DSP,
 645    OPC_CMPGDU_LT_OB      = (0x19 << 6) | OPC_CMPU_EQ_OB_DSP,
 646    OPC_CMPGDU_LE_OB      = (0x1A << 6) | OPC_CMPU_EQ_OB_DSP,
 647    OPC_CMPGU_EQ_OB       = (0x04 << 6) | OPC_CMPU_EQ_OB_DSP,
 648    OPC_CMPGU_LT_OB       = (0x05 << 6) | OPC_CMPU_EQ_OB_DSP,
 649    OPC_CMPGU_LE_OB       = (0x06 << 6) | OPC_CMPU_EQ_OB_DSP,
 650    OPC_CMPU_EQ_OB        = (0x00 << 6) | OPC_CMPU_EQ_OB_DSP,
 651    OPC_CMPU_LT_OB        = (0x01 << 6) | OPC_CMPU_EQ_OB_DSP,
 652    OPC_CMPU_LE_OB        = (0x02 << 6) | OPC_CMPU_EQ_OB_DSP,
 653    OPC_PACKRL_PW         = (0x0E << 6) | OPC_CMPU_EQ_OB_DSP,
 654    OPC_PICK_OB           = (0x03 << 6) | OPC_CMPU_EQ_OB_DSP,
 655    OPC_PICK_PW           = (0x13 << 6) | OPC_CMPU_EQ_OB_DSP,
 656    OPC_PICK_QH           = (0x0B << 6) | OPC_CMPU_EQ_OB_DSP,
 657    /* MIPS DSP Arithmetic Sub-class */
 658    OPC_PRECR_OB_QH       = (0x0D << 6) | OPC_CMPU_EQ_OB_DSP,
 659    OPC_PRECR_SRA_QH_PW   = (0x1E << 6) | OPC_CMPU_EQ_OB_DSP,
 660    OPC_PRECR_SRA_R_QH_PW = (0x1F << 6) | OPC_CMPU_EQ_OB_DSP,
 661    OPC_PRECRQ_OB_QH      = (0x0C << 6) | OPC_CMPU_EQ_OB_DSP,
 662    OPC_PRECRQ_PW_L       = (0x1C << 6) | OPC_CMPU_EQ_OB_DSP,
 663    OPC_PRECRQ_QH_PW      = (0x14 << 6) | OPC_CMPU_EQ_OB_DSP,
 664    OPC_PRECRQ_RS_QH_PW   = (0x15 << 6) | OPC_CMPU_EQ_OB_DSP,
 665    OPC_PRECRQU_S_OB_QH   = (0x0F << 6) | OPC_CMPU_EQ_OB_DSP,
 666};
 667
 668#define MASK_DAPPEND(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 669enum {
 670    /* DSP Append Sub-class */
 671    OPC_DAPPEND  = (0x00 << 6) | OPC_DAPPEND_DSP,
 672    OPC_PREPENDD = (0x03 << 6) | OPC_DAPPEND_DSP,
 673    OPC_PREPENDW = (0x01 << 6) | OPC_DAPPEND_DSP,
 674    OPC_DBALIGN  = (0x10 << 6) | OPC_DAPPEND_DSP,
 675};
 676
 677#define MASK_DEXTR_W(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 678enum {
 679    /* MIPS DSP Accumulator and DSPControl Access Sub-class */
 680    OPC_DMTHLIP     = (0x1F << 6) | OPC_DEXTR_W_DSP,
 681    OPC_DSHILO      = (0x1A << 6) | OPC_DEXTR_W_DSP,
 682    OPC_DEXTP       = (0x02 << 6) | OPC_DEXTR_W_DSP,
 683    OPC_DEXTPDP     = (0x0A << 6) | OPC_DEXTR_W_DSP,
 684    OPC_DEXTPDPV    = (0x0B << 6) | OPC_DEXTR_W_DSP,
 685    OPC_DEXTPV      = (0x03 << 6) | OPC_DEXTR_W_DSP,
 686    OPC_DEXTR_L     = (0x10 << 6) | OPC_DEXTR_W_DSP,
 687    OPC_DEXTR_R_L   = (0x14 << 6) | OPC_DEXTR_W_DSP,
 688    OPC_DEXTR_RS_L  = (0x16 << 6) | OPC_DEXTR_W_DSP,
 689    OPC_DEXTR_W     = (0x00 << 6) | OPC_DEXTR_W_DSP,
 690    OPC_DEXTR_R_W   = (0x04 << 6) | OPC_DEXTR_W_DSP,
 691    OPC_DEXTR_RS_W  = (0x06 << 6) | OPC_DEXTR_W_DSP,
 692    OPC_DEXTR_S_H   = (0x0E << 6) | OPC_DEXTR_W_DSP,
 693    OPC_DEXTRV_L    = (0x11 << 6) | OPC_DEXTR_W_DSP,
 694    OPC_DEXTRV_R_L  = (0x15 << 6) | OPC_DEXTR_W_DSP,
 695    OPC_DEXTRV_RS_L = (0x17 << 6) | OPC_DEXTR_W_DSP,
 696    OPC_DEXTRV_S_H  = (0x0F << 6) | OPC_DEXTR_W_DSP,
 697    OPC_DEXTRV_W    = (0x01 << 6) | OPC_DEXTR_W_DSP,
 698    OPC_DEXTRV_R_W  = (0x05 << 6) | OPC_DEXTR_W_DSP,
 699    OPC_DEXTRV_RS_W = (0x07 << 6) | OPC_DEXTR_W_DSP,
 700    OPC_DSHILOV     = (0x1B << 6) | OPC_DEXTR_W_DSP,
 701};
 702
 703#define MASK_DINSV(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 704enum {
 705    /* DSP Bit/Manipulation Sub-class */
 706    OPC_DINSV = (0x00 << 6) | OPC_DINSV_DSP,
 707};
 708
 709#define MASK_DPAQ_W_QH(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 710enum {
 711    /* MIPS DSP Multiply Sub-class insns */
 712    OPC_DMADD         = (0x19 << 6) | OPC_DPAQ_W_QH_DSP,
 713    OPC_DMADDU        = (0x1D << 6) | OPC_DPAQ_W_QH_DSP,
 714    OPC_DMSUB         = (0x1B << 6) | OPC_DPAQ_W_QH_DSP,
 715    OPC_DMSUBU        = (0x1F << 6) | OPC_DPAQ_W_QH_DSP,
 716    OPC_DPA_W_QH      = (0x00 << 6) | OPC_DPAQ_W_QH_DSP,
 717    OPC_DPAQ_S_W_QH   = (0x04 << 6) | OPC_DPAQ_W_QH_DSP,
 718    OPC_DPAQ_SA_L_PW  = (0x0C << 6) | OPC_DPAQ_W_QH_DSP,
 719    OPC_DPAU_H_OBL    = (0x03 << 6) | OPC_DPAQ_W_QH_DSP,
 720    OPC_DPAU_H_OBR    = (0x07 << 6) | OPC_DPAQ_W_QH_DSP,
 721    OPC_DPS_W_QH      = (0x01 << 6) | OPC_DPAQ_W_QH_DSP,
 722    OPC_DPSQ_S_W_QH   = (0x05 << 6) | OPC_DPAQ_W_QH_DSP,
 723    OPC_DPSQ_SA_L_PW  = (0x0D << 6) | OPC_DPAQ_W_QH_DSP,
 724    OPC_DPSU_H_OBL    = (0x0B << 6) | OPC_DPAQ_W_QH_DSP,
 725    OPC_DPSU_H_OBR    = (0x0F << 6) | OPC_DPAQ_W_QH_DSP,
 726    OPC_MAQ_S_L_PWL   = (0x1C << 6) | OPC_DPAQ_W_QH_DSP,
 727    OPC_MAQ_S_L_PWR   = (0x1E << 6) | OPC_DPAQ_W_QH_DSP,
 728    OPC_MAQ_S_W_QHLL  = (0x14 << 6) | OPC_DPAQ_W_QH_DSP,
 729    OPC_MAQ_SA_W_QHLL = (0x10 << 6) | OPC_DPAQ_W_QH_DSP,
 730    OPC_MAQ_S_W_QHLR  = (0x15 << 6) | OPC_DPAQ_W_QH_DSP,
 731    OPC_MAQ_SA_W_QHLR = (0x11 << 6) | OPC_DPAQ_W_QH_DSP,
 732    OPC_MAQ_S_W_QHRL  = (0x16 << 6) | OPC_DPAQ_W_QH_DSP,
 733    OPC_MAQ_SA_W_QHRL = (0x12 << 6) | OPC_DPAQ_W_QH_DSP,
 734    OPC_MAQ_S_W_QHRR  = (0x17 << 6) | OPC_DPAQ_W_QH_DSP,
 735    OPC_MAQ_SA_W_QHRR = (0x13 << 6) | OPC_DPAQ_W_QH_DSP,
 736    OPC_MULSAQ_S_L_PW = (0x0E << 6) | OPC_DPAQ_W_QH_DSP,
 737    OPC_MULSAQ_S_W_QH = (0x06 << 6) | OPC_DPAQ_W_QH_DSP,
 738};
 739
 740#define MASK_SHLL_OB(op) (MASK_SPECIAL3(op) | (op & (0x1F << 6)))
 741enum {
 742    /* MIPS DSP GPR-Based Shift Sub-class */
 743    OPC_SHLL_PW    = (0x10 << 6) | OPC_SHLL_OB_DSP,
 744    OPC_SHLL_S_PW  = (0x14 << 6) | OPC_SHLL_OB_DSP,
 745    OPC_SHLLV_OB   = (0x02 << 6) | OPC_SHLL_OB_DSP,
 746    OPC_SHLLV_PW   = (0x12 << 6) | OPC_SHLL_OB_DSP,
 747    OPC_SHLLV_S_PW = (0x16 << 6) | OPC_SHLL_OB_DSP,
 748    OPC_SHLLV_QH   = (0x0A << 6) | OPC_SHLL_OB_DSP,
 749    OPC_SHLLV_S_QH = (0x0E << 6) | OPC_SHLL_OB_DSP,
 750    OPC_SHRA_PW    = (0x11 << 6) | OPC_SHLL_OB_DSP,
 751    OPC_SHRA_R_PW  = (0x15 << 6) | OPC_SHLL_OB_DSP,
 752    OPC_SHRAV_OB   = (0x06 << 6) | OPC_SHLL_OB_DSP,
 753    OPC_SHRAV_R_OB = (0x07 << 6) | OPC_SHLL_OB_DSP,
 754    OPC_SHRAV_PW   = (0x13 << 6) | OPC_SHLL_OB_DSP,
 755    OPC_SHRAV_R_PW = (0x17 << 6) | OPC_SHLL_OB_DSP,
 756    OPC_SHRAV_QH   = (0x0B << 6) | OPC_SHLL_OB_DSP,
 757    OPC_SHRAV_R_QH = (0x0F << 6) | OPC_SHLL_OB_DSP,
 758    OPC_SHRLV_OB   = (0x03 << 6) | OPC_SHLL_OB_DSP,
 759    OPC_SHRLV_QH   = (0x1B << 6) | OPC_SHLL_OB_DSP,
 760    OPC_SHLL_OB    = (0x00 << 6) | OPC_SHLL_OB_DSP,
 761    OPC_SHLL_QH    = (0x08 << 6) | OPC_SHLL_OB_DSP,
 762    OPC_SHLL_S_QH  = (0x0C << 6) | OPC_SHLL_OB_DSP,
 763    OPC_SHRA_OB    = (0x04 << 6) | OPC_SHLL_OB_DSP,
 764    OPC_SHRA_R_OB  = (0x05 << 6) | OPC_SHLL_OB_DSP,
 765    OPC_SHRA_QH    = (0x09 << 6) | OPC_SHLL_OB_DSP,
 766    OPC_SHRA_R_QH  = (0x0D << 6) | OPC_SHLL_OB_DSP,
 767    OPC_SHRL_OB    = (0x01 << 6) | OPC_SHLL_OB_DSP,
 768    OPC_SHRL_QH    = (0x19 << 6) | OPC_SHLL_OB_DSP,
 769};
 770
 771/* Coprocessor 0 (rs field) */
 772#define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
 773
 774enum {
 775    OPC_MFC0     = (0x00 << 21) | OPC_CP0,
 776    OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
 777    OPC_MTC0     = (0x04 << 21) | OPC_CP0,
 778    OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
 779    OPC_MFTR     = (0x08 << 21) | OPC_CP0,
 780    OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
 781    OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
 782    OPC_MTTR     = (0x0C << 21) | OPC_CP0,
 783    OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
 784    OPC_C0       = (0x10 << 21) | OPC_CP0,
 785    OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
 786    OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,
 787};
 788
 789/* MFMC0 opcodes */
 790#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
 791
 792enum {
 793    OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
 794    OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
 795    OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
 796    OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
 797    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
 798    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
 799};
 800
 801/* Coprocessor 0 (with rs == C0) */
 802#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
 803
 804enum {
 805    OPC_TLBR     = 0x01 | OPC_C0,
 806    OPC_TLBWI    = 0x02 | OPC_C0,
 807    OPC_TLBWR    = 0x06 | OPC_C0,
 808    OPC_TLBP     = 0x08 | OPC_C0,
 809    OPC_RFE      = 0x10 | OPC_C0,
 810    OPC_ERET     = 0x18 | OPC_C0,
 811    OPC_DERET    = 0x1F | OPC_C0,
 812    OPC_WAIT     = 0x20 | OPC_C0,
 813};
 814
 815/* Coprocessor 1 (rs field) */
 816#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
 817
 818/* Values for the fmt field in FP instructions */
 819enum {
 820    /* 0 - 15 are reserved */
 821    FMT_S = 16,          /* single fp */
 822    FMT_D = 17,          /* double fp */
 823    FMT_E = 18,          /* extended fp */
 824    FMT_Q = 19,          /* quad fp */
 825    FMT_W = 20,          /* 32-bit fixed */
 826    FMT_L = 21,          /* 64-bit fixed */
 827    FMT_PS = 22,         /* paired single fp */
 828    /* 23 - 31 are reserved */
 829};
 830
 831enum {
 832    OPC_MFC1     = (0x00 << 21) | OPC_CP1,
 833    OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
 834    OPC_CFC1     = (0x02 << 21) | OPC_CP1,
 835    OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
 836    OPC_MTC1     = (0x04 << 21) | OPC_CP1,
 837    OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
 838    OPC_CTC1     = (0x06 << 21) | OPC_CP1,
 839    OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
 840    OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
 841    OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
 842    OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
 843    OPC_S_FMT    = (FMT_S << 21) | OPC_CP1,
 844    OPC_D_FMT    = (FMT_D << 21) | OPC_CP1,
 845    OPC_E_FMT    = (FMT_E << 21) | OPC_CP1,
 846    OPC_Q_FMT    = (FMT_Q << 21) | OPC_CP1,
 847    OPC_W_FMT    = (FMT_W << 21) | OPC_CP1,
 848    OPC_L_FMT    = (FMT_L << 21) | OPC_CP1,
 849    OPC_PS_FMT   = (FMT_PS << 21) | OPC_CP1,
 850};
 851
 852#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
 853#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
 854
 855enum {
 856    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
 857    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
 858    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
 859    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
 860};
 861
 862enum {
 863    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
 864    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
 865};
 866
 867enum {
 868    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
 869    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
 870};
 871
 872#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
 873
 874enum {
 875    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
 876    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
 877    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
 878    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
 879    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
 880    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
 881    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
 882    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
 883    OPC_BC2     = (0x08 << 21) | OPC_CP2,
 884};
 885
 886#define MASK_LMI(op)  (MASK_OP_MAJOR(op) | (op & (0x1F << 21)) | (op & 0x1F))
 887
 888enum {
 889    OPC_PADDSH  = (24 << 21) | (0x00) | OPC_CP2,
 890    OPC_PADDUSH = (25 << 21) | (0x00) | OPC_CP2,
 891    OPC_PADDH   = (26 << 21) | (0x00) | OPC_CP2,
 892    OPC_PADDW   = (27 << 21) | (0x00) | OPC_CP2,
 893    OPC_PADDSB  = (28 << 21) | (0x00) | OPC_CP2,
 894    OPC_PADDUSB = (29 << 21) | (0x00) | OPC_CP2,
 895    OPC_PADDB   = (30 << 21) | (0x00) | OPC_CP2,
 896    OPC_PADDD   = (31 << 21) | (0x00) | OPC_CP2,
 897
 898    OPC_PSUBSH  = (24 << 21) | (0x01) | OPC_CP2,
 899    OPC_PSUBUSH = (25 << 21) | (0x01) | OPC_CP2,
 900    OPC_PSUBH   = (26 << 21) | (0x01) | OPC_CP2,
 901    OPC_PSUBW   = (27 << 21) | (0x01) | OPC_CP2,
 902    OPC_PSUBSB  = (28 << 21) | (0x01) | OPC_CP2,
 903    OPC_PSUBUSB = (29 << 21) | (0x01) | OPC_CP2,
 904    OPC_PSUBB   = (30 << 21) | (0x01) | OPC_CP2,
 905    OPC_PSUBD   = (31 << 21) | (0x01) | OPC_CP2,
 906
 907    OPC_PSHUFH   = (24 << 21) | (0x02) | OPC_CP2,
 908    OPC_PACKSSWH = (25 << 21) | (0x02) | OPC_CP2,
 909    OPC_PACKSSHB = (26 << 21) | (0x02) | OPC_CP2,
 910    OPC_PACKUSHB = (27 << 21) | (0x02) | OPC_CP2,
 911    OPC_XOR_CP2  = (28 << 21) | (0x02) | OPC_CP2,
 912    OPC_NOR_CP2  = (29 << 21) | (0x02) | OPC_CP2,
 913    OPC_AND_CP2  = (30 << 21) | (0x02) | OPC_CP2,
 914    OPC_PANDN    = (31 << 21) | (0x02) | OPC_CP2,
 915
 916    OPC_PUNPCKLHW = (24 << 21) | (0x03) | OPC_CP2,
 917    OPC_PUNPCKHHW = (25 << 21) | (0x03) | OPC_CP2,
 918    OPC_PUNPCKLBH = (26 << 21) | (0x03) | OPC_CP2,
 919    OPC_PUNPCKHBH = (27 << 21) | (0x03) | OPC_CP2,
 920    OPC_PINSRH_0  = (28 << 21) | (0x03) | OPC_CP2,
 921    OPC_PINSRH_1  = (29 << 21) | (0x03) | OPC_CP2,
 922    OPC_PINSRH_2  = (30 << 21) | (0x03) | OPC_CP2,
 923    OPC_PINSRH_3  = (31 << 21) | (0x03) | OPC_CP2,
 924
 925    OPC_PAVGH   = (24 << 21) | (0x08) | OPC_CP2,
 926    OPC_PAVGB   = (25 << 21) | (0x08) | OPC_CP2,
 927    OPC_PMAXSH  = (26 << 21) | (0x08) | OPC_CP2,
 928    OPC_PMINSH  = (27 << 21) | (0x08) | OPC_CP2,
 929    OPC_PMAXUB  = (28 << 21) | (0x08) | OPC_CP2,
 930    OPC_PMINUB  = (29 << 21) | (0x08) | OPC_CP2,
 931
 932    OPC_PCMPEQW = (24 << 21) | (0x09) | OPC_CP2,
 933    OPC_PCMPGTW = (25 << 21) | (0x09) | OPC_CP2,
 934    OPC_PCMPEQH = (26 << 21) | (0x09) | OPC_CP2,
 935    OPC_PCMPGTH = (27 << 21) | (0x09) | OPC_CP2,
 936    OPC_PCMPEQB = (28 << 21) | (0x09) | OPC_CP2,
 937    OPC_PCMPGTB = (29 << 21) | (0x09) | OPC_CP2,
 938
 939    OPC_PSLLW   = (24 << 21) | (0x0A) | OPC_CP2,
 940    OPC_PSLLH   = (25 << 21) | (0x0A) | OPC_CP2,
 941    OPC_PMULLH  = (26 << 21) | (0x0A) | OPC_CP2,
 942    OPC_PMULHH  = (27 << 21) | (0x0A) | OPC_CP2,
 943    OPC_PMULUW  = (28 << 21) | (0x0A) | OPC_CP2,
 944    OPC_PMULHUH = (29 << 21) | (0x0A) | OPC_CP2,
 945
 946    OPC_PSRLW     = (24 << 21) | (0x0B) | OPC_CP2,
 947    OPC_PSRLH     = (25 << 21) | (0x0B) | OPC_CP2,
 948    OPC_PSRAW     = (26 << 21) | (0x0B) | OPC_CP2,
 949    OPC_PSRAH     = (27 << 21) | (0x0B) | OPC_CP2,
 950    OPC_PUNPCKLWD = (28 << 21) | (0x0B) | OPC_CP2,
 951    OPC_PUNPCKHWD = (29 << 21) | (0x0B) | OPC_CP2,
 952
 953    OPC_ADDU_CP2 = (24 << 21) | (0x0C) | OPC_CP2,
 954    OPC_OR_CP2   = (25 << 21) | (0x0C) | OPC_CP2,
 955    OPC_ADD_CP2  = (26 << 21) | (0x0C) | OPC_CP2,
 956    OPC_DADD_CP2 = (27 << 21) | (0x0C) | OPC_CP2,
 957    OPC_SEQU_CP2 = (28 << 21) | (0x0C) | OPC_CP2,
 958    OPC_SEQ_CP2  = (29 << 21) | (0x0C) | OPC_CP2,
 959
 960    OPC_SUBU_CP2 = (24 << 21) | (0x0D) | OPC_CP2,
 961    OPC_PASUBUB  = (25 << 21) | (0x0D) | OPC_CP2,
 962    OPC_SUB_CP2  = (26 << 21) | (0x0D) | OPC_CP2,
 963    OPC_DSUB_CP2 = (27 << 21) | (0x0D) | OPC_CP2,
 964    OPC_SLTU_CP2 = (28 << 21) | (0x0D) | OPC_CP2,
 965    OPC_SLT_CP2  = (29 << 21) | (0x0D) | OPC_CP2,
 966
 967    OPC_SLL_CP2  = (24 << 21) | (0x0E) | OPC_CP2,
 968    OPC_DSLL_CP2 = (25 << 21) | (0x0E) | OPC_CP2,
 969    OPC_PEXTRH   = (26 << 21) | (0x0E) | OPC_CP2,
 970    OPC_PMADDHW  = (27 << 21) | (0x0E) | OPC_CP2,
 971    OPC_SLEU_CP2 = (28 << 21) | (0x0E) | OPC_CP2,
 972    OPC_SLE_CP2  = (29 << 21) | (0x0E) | OPC_CP2,
 973
 974    OPC_SRL_CP2  = (24 << 21) | (0x0F) | OPC_CP2,
 975    OPC_DSRL_CP2 = (25 << 21) | (0x0F) | OPC_CP2,
 976    OPC_SRA_CP2  = (26 << 21) | (0x0F) | OPC_CP2,
 977    OPC_DSRA_CP2 = (27 << 21) | (0x0F) | OPC_CP2,
 978    OPC_BIADD    = (28 << 21) | (0x0F) | OPC_CP2,
 979    OPC_PMOVMSKB = (29 << 21) | (0x0F) | OPC_CP2,
 980};
 981
 982
 983#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
 984
 985enum {
 986    OPC_LWXC1   = 0x00 | OPC_CP3,
 987    OPC_LDXC1   = 0x01 | OPC_CP3,
 988    OPC_LUXC1   = 0x05 | OPC_CP3,
 989    OPC_SWXC1   = 0x08 | OPC_CP3,
 990    OPC_SDXC1   = 0x09 | OPC_CP3,
 991    OPC_SUXC1   = 0x0D | OPC_CP3,
 992    OPC_PREFX   = 0x0F | OPC_CP3,
 993    OPC_ALNV_PS = 0x1E | OPC_CP3,
 994    OPC_MADD_S  = 0x20 | OPC_CP3,
 995    OPC_MADD_D  = 0x21 | OPC_CP3,
 996    OPC_MADD_PS = 0x26 | OPC_CP3,
 997    OPC_MSUB_S  = 0x28 | OPC_CP3,
 998    OPC_MSUB_D  = 0x29 | OPC_CP3,
 999    OPC_MSUB_PS = 0x2E | OPC_CP3,
1000    OPC_NMADD_S = 0x30 | OPC_CP3,
1001    OPC_NMADD_D = 0x31 | OPC_CP3,
1002    OPC_NMADD_PS= 0x36 | OPC_CP3,
1003    OPC_NMSUB_S = 0x38 | OPC_CP3,
1004    OPC_NMSUB_D = 0x39 | OPC_CP3,
1005    OPC_NMSUB_PS= 0x3E | OPC_CP3,
1006};
1007
1008/* global register indices */
1009static TCGv_ptr cpu_env;
1010static TCGv cpu_gpr[32], cpu_PC;
1011static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
1012static TCGv cpu_dspctrl, btarget, bcond;
1013static TCGv_i32 hflags;
1014static TCGv_i32 fpu_fcr0, fpu_fcr31;
1015static TCGv_i64 fpu_f64[32];
1016
1017static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
1018static target_ulong gen_opc_btarget[OPC_BUF_SIZE];
1019
1020#include "exec/gen-icount.h"
1021
1022#define gen_helper_0e0i(name, arg) do {                           \
1023    TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
1024    gen_helper_##name(cpu_env, helper_tmp);                       \
1025    tcg_temp_free_i32(helper_tmp);                                \
1026    } while(0)
1027
1028#define gen_helper_0e1i(name, arg1, arg2) do {                    \
1029    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
1030    gen_helper_##name(cpu_env, arg1, helper_tmp);                 \
1031    tcg_temp_free_i32(helper_tmp);                                \
1032    } while(0)
1033
1034#define gen_helper_1e0i(name, ret, arg1) do {                     \
1035    TCGv_i32 helper_tmp = tcg_const_i32(arg1);                    \
1036    gen_helper_##name(ret, cpu_env, helper_tmp);                  \
1037    tcg_temp_free_i32(helper_tmp);                                \
1038    } while(0)
1039
1040#define gen_helper_1e1i(name, ret, arg1, arg2) do {               \
1041    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
1042    gen_helper_##name(ret, cpu_env, arg1, helper_tmp);            \
1043    tcg_temp_free_i32(helper_tmp);                                \
1044    } while(0)
1045
1046#define gen_helper_0e2i(name, arg1, arg2, arg3) do {              \
1047    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
1048    gen_helper_##name(cpu_env, arg1, arg2, helper_tmp);           \
1049    tcg_temp_free_i32(helper_tmp);                                \
1050    } while(0)
1051
1052#define gen_helper_1e2i(name, ret, arg1, arg2, arg3) do {         \
1053    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
1054    gen_helper_##name(ret, cpu_env, arg1, arg2, helper_tmp);      \
1055    tcg_temp_free_i32(helper_tmp);                                \
1056    } while(0)
1057
1058#define gen_helper_0e3i(name, arg1, arg2, arg3, arg4) do {        \
1059    TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
1060    gen_helper_##name(cpu_env, arg1, arg2, arg3, helper_tmp);     \
1061    tcg_temp_free_i32(helper_tmp);                                \
1062    } while(0)
1063
1064typedef struct DisasContext {
1065    struct TranslationBlock *tb;
1066    target_ulong pc, saved_pc;
1067    uint32_t opcode;
1068    int singlestep_enabled;
1069    int insn_flags;
1070    /* Routine used to access memory */
1071    int mem_idx;
1072    uint32_t hflags, saved_hflags;
1073    int bstate;
1074    target_ulong btarget;
1075} DisasContext;
1076
1077enum {
1078    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
1079                      * exception condition */
1080    BS_STOP     = 1, /* We want to stop translation for any reason */
1081    BS_BRANCH   = 2, /* We reached a branch condition     */
1082    BS_EXCP     = 3, /* We reached an exception condition */
1083};
1084
1085static const char * const regnames[] = {
1086    "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
1087    "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
1088    "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
1089    "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra",
1090};
1091
1092static const char * const regnames_HI[] = {
1093    "HI0", "HI1", "HI2", "HI3",
1094};
1095
1096static const char * const regnames_LO[] = {
1097    "LO0", "LO1", "LO2", "LO3",
1098};
1099
1100static const char * const regnames_ACX[] = {
1101    "ACX0", "ACX1", "ACX2", "ACX3",
1102};
1103
1104static const char * const fregnames[] = {
1105    "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
1106    "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
1107    "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
1108    "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31",
1109};
1110
1111#define MIPS_DEBUG(fmt, ...)                                                  \
1112    do {                                                                      \
1113        if (MIPS_DEBUG_DISAS) {                                               \
1114            qemu_log_mask(CPU_LOG_TB_IN_ASM,                                  \
1115                          TARGET_FMT_lx ": %08x " fmt "\n",                   \
1116                          ctx->pc, ctx->opcode , ## __VA_ARGS__);             \
1117        }                                                                     \
1118    } while (0)
1119
1120#define LOG_DISAS(...)                                                        \
1121    do {                                                                      \
1122        if (MIPS_DEBUG_DISAS) {                                               \
1123            qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__);                 \
1124        }                                                                     \
1125    } while (0)
1126
1127#define MIPS_INVAL(op)                                                        \
1128    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
1129               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F))
1130
1131/* General purpose registers moves. */
1132static inline void gen_load_gpr (TCGv t, int reg)
1133{
1134    if (reg == 0)
1135        tcg_gen_movi_tl(t, 0);
1136    else
1137        tcg_gen_mov_tl(t, cpu_gpr[reg]);
1138}
1139
1140static inline void gen_store_gpr (TCGv t, int reg)
1141{
1142    if (reg != 0)
1143        tcg_gen_mov_tl(cpu_gpr[reg], t);
1144}
1145
1146/* Moves to/from ACX register.  */
1147static inline void gen_load_ACX (TCGv t, int reg)
1148{
1149    tcg_gen_mov_tl(t, cpu_ACX[reg]);
1150}
1151
1152static inline void gen_store_ACX (TCGv t, int reg)
1153{
1154    tcg_gen_mov_tl(cpu_ACX[reg], t);
1155}
1156
1157/* Moves to/from shadow registers. */
1158static inline void gen_load_srsgpr (int from, int to)
1159{
1160    TCGv t0 = tcg_temp_new();
1161
1162    if (from == 0)
1163        tcg_gen_movi_tl(t0, 0);
1164    else {
1165        TCGv_i32 t2 = tcg_temp_new_i32();
1166        TCGv_ptr addr = tcg_temp_new_ptr();
1167
1168        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1169        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1170        tcg_gen_andi_i32(t2, t2, 0xf);
1171        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1172        tcg_gen_ext_i32_ptr(addr, t2);
1173        tcg_gen_add_ptr(addr, cpu_env, addr);
1174
1175        tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1176        tcg_temp_free_ptr(addr);
1177        tcg_temp_free_i32(t2);
1178    }
1179    gen_store_gpr(t0, to);
1180    tcg_temp_free(t0);
1181}
1182
1183static inline void gen_store_srsgpr (int from, int to)
1184{
1185    if (to != 0) {
1186        TCGv t0 = tcg_temp_new();
1187        TCGv_i32 t2 = tcg_temp_new_i32();
1188        TCGv_ptr addr = tcg_temp_new_ptr();
1189
1190        gen_load_gpr(t0, from);
1191        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1192        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
1193        tcg_gen_andi_i32(t2, t2, 0xf);
1194        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
1195        tcg_gen_ext_i32_ptr(addr, t2);
1196        tcg_gen_add_ptr(addr, cpu_env, addr);
1197
1198        tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1199        tcg_temp_free_ptr(addr);
1200        tcg_temp_free_i32(t2);
1201        tcg_temp_free(t0);
1202    }
1203}
1204
1205/* Floating point register moves. */
1206static void gen_load_fpr32(TCGv_i32 t, int reg)
1207{
1208    tcg_gen_trunc_i64_i32(t, fpu_f64[reg]);
1209}
1210
1211static void gen_store_fpr32(TCGv_i32 t, int reg)
1212{
1213    TCGv_i64 t64 = tcg_temp_new_i64();
1214    tcg_gen_extu_i32_i64(t64, t);
1215    tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 0, 32);
1216    tcg_temp_free_i64(t64);
1217}
1218
1219static void gen_load_fpr32h(TCGv_i32 t, int reg)
1220{
1221    TCGv_i64 t64 = tcg_temp_new_i64();
1222    tcg_gen_shri_i64(t64, fpu_f64[reg], 32);
1223    tcg_gen_trunc_i64_i32(t, t64);
1224    tcg_temp_free_i64(t64);
1225}
1226
1227static void gen_store_fpr32h(TCGv_i32 t, int reg)
1228{
1229    TCGv_i64 t64 = tcg_temp_new_i64();
1230    tcg_gen_extu_i32_i64(t64, t);
1231    tcg_gen_deposit_i64(fpu_f64[reg], fpu_f64[reg], t64, 32, 32);
1232    tcg_temp_free_i64(t64);
1233}
1234
1235static void gen_load_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1236{
1237    if (ctx->hflags & MIPS_HFLAG_F64) {
1238        tcg_gen_mov_i64(t, fpu_f64[reg]);
1239    } else {
1240        tcg_gen_concat32_i64(t, fpu_f64[reg & ~1], fpu_f64[reg | 1]);
1241    }
1242}
1243
1244static void gen_store_fpr64(DisasContext *ctx, TCGv_i64 t, int reg)
1245{
1246    if (ctx->hflags & MIPS_HFLAG_F64) {
1247        tcg_gen_mov_i64(fpu_f64[reg], t);
1248    } else {
1249        TCGv_i64 t0;
1250        tcg_gen_deposit_i64(fpu_f64[reg & ~1], fpu_f64[reg & ~1], t, 0, 32);
1251        t0 = tcg_temp_new_i64();
1252        tcg_gen_shri_i64(t0, t, 32);
1253        tcg_gen_deposit_i64(fpu_f64[reg | 1], fpu_f64[reg | 1], t0, 0, 32);
1254        tcg_temp_free_i64(t0);
1255    }
1256}
1257
1258static inline int get_fp_bit (int cc)
1259{
1260    if (cc)
1261        return 24 + cc;
1262    else
1263        return 23;
1264}
1265
1266/* Tests */
1267static inline void gen_save_pc(target_ulong pc)
1268{
1269    tcg_gen_movi_tl(cpu_PC, pc);
1270}
1271
1272static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
1273{
1274    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1275    if (do_save_pc && ctx->pc != ctx->saved_pc) {
1276        gen_save_pc(ctx->pc);
1277        ctx->saved_pc = ctx->pc;
1278    }
1279    if (ctx->hflags != ctx->saved_hflags) {
1280        tcg_gen_movi_i32(hflags, ctx->hflags);
1281        ctx->saved_hflags = ctx->hflags;
1282        switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1283        case MIPS_HFLAG_BR:
1284            break;
1285        case MIPS_HFLAG_BC:
1286        case MIPS_HFLAG_BL:
1287        case MIPS_HFLAG_B:
1288            tcg_gen_movi_tl(btarget, ctx->btarget);
1289            break;
1290        }
1291    }
1292}
1293
1294static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
1295{
1296    ctx->saved_hflags = ctx->hflags;
1297    switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1298    case MIPS_HFLAG_BR:
1299        break;
1300    case MIPS_HFLAG_BC:
1301    case MIPS_HFLAG_BL:
1302    case MIPS_HFLAG_B:
1303        ctx->btarget = env->btarget;
1304        break;
1305    }
1306}
1307
1308static inline void
1309generate_exception_err (DisasContext *ctx, int excp, int err)
1310{
1311    TCGv_i32 texcp = tcg_const_i32(excp);
1312    TCGv_i32 terr = tcg_const_i32(err);
1313    save_cpu_state(ctx, 1);
1314    gen_helper_raise_exception_err(cpu_env, texcp, terr);
1315    tcg_temp_free_i32(terr);
1316    tcg_temp_free_i32(texcp);
1317}
1318
1319static inline void
1320generate_exception (DisasContext *ctx, int excp)
1321{
1322    save_cpu_state(ctx, 1);
1323    gen_helper_0e0i(raise_exception, excp);
1324}
1325
1326/* Addresses computation */
1327static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1328{
1329    tcg_gen_add_tl(ret, arg0, arg1);
1330
1331#if defined(TARGET_MIPS64)
1332    /* For compatibility with 32-bit code, data reference in user mode
1333       with Status_UX = 0 should be casted to 32-bit and sign extended.
1334       See the MIPS64 PRA manual, section 4.10. */
1335    if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
1336        !(ctx->hflags & MIPS_HFLAG_UX)) {
1337        tcg_gen_ext32s_i64(ret, ret);
1338    }
1339#endif
1340}
1341
1342static inline void check_cp0_enabled(DisasContext *ctx)
1343{
1344    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1345        generate_exception_err(ctx, EXCP_CpU, 0);
1346}
1347
1348static inline void check_cp1_enabled(DisasContext *ctx)
1349{
1350    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
1351        generate_exception_err(ctx, EXCP_CpU, 1);
1352}
1353
1354/* Verify that the processor is running with COP1X instructions enabled.
1355   This is associated with the nabla symbol in the MIPS32 and MIPS64
1356   opcode tables.  */
1357
1358static inline void check_cop1x(DisasContext *ctx)
1359{
1360    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
1361        generate_exception(ctx, EXCP_RI);
1362}
1363
1364/* Verify that the processor is running with 64-bit floating-point
1365   operations enabled.  */
1366
1367static inline void check_cp1_64bitmode(DisasContext *ctx)
1368{
1369    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
1370        generate_exception(ctx, EXCP_RI);
1371}
1372
1373/*
1374 * Verify if floating point register is valid; an operation is not defined
1375 * if bit 0 of any register specification is set and the FR bit in the
1376 * Status register equals zero, since the register numbers specify an
1377 * even-odd pair of adjacent coprocessor general registers. When the FR bit
1378 * in the Status register equals one, both even and odd register numbers
1379 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
1380 *
1381 * Multiple 64 bit wide registers can be checked by calling
1382 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
1383 */
1384static inline void check_cp1_registers(DisasContext *ctx, int regs)
1385{
1386    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
1387        generate_exception(ctx, EXCP_RI);
1388}
1389
1390/* Verify that the processor is running with DSP instructions enabled.
1391   This is enabled by CP0 Status register MX(24) bit.
1392 */
1393
1394static inline void check_dsp(DisasContext *ctx)
1395{
1396    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSP))) {
1397        if (ctx->insn_flags & ASE_DSP) {
1398            generate_exception(ctx, EXCP_DSPDIS);
1399        } else {
1400            generate_exception(ctx, EXCP_RI);
1401        }
1402    }
1403}
1404
1405static inline void check_dspr2(DisasContext *ctx)
1406{
1407    if (unlikely(!(ctx->hflags & MIPS_HFLAG_DSPR2))) {
1408        if (ctx->insn_flags & ASE_DSP) {
1409            generate_exception(ctx, EXCP_DSPDIS);
1410        } else {
1411            generate_exception(ctx, EXCP_RI);
1412        }
1413    }
1414}
1415
1416/* This code generates a "reserved instruction" exception if the
1417   CPU does not support the instruction set corresponding to flags. */
1418static inline void check_insn(DisasContext *ctx, int flags)
1419{
1420    if (unlikely(!(ctx->insn_flags & flags))) {
1421        generate_exception(ctx, EXCP_RI);
1422    }
1423}
1424
1425/* This code generates a "reserved instruction" exception if 64-bit
1426   instructions are not enabled. */
1427static inline void check_mips_64(DisasContext *ctx)
1428{
1429    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
1430        generate_exception(ctx, EXCP_RI);
1431}
1432
1433/* Define small wrappers for gen_load_fpr* so that we have a uniform
1434   calling interface for 32 and 64-bit FPRs.  No sense in changing
1435   all callers for gen_load_fpr32 when we need the CTX parameter for
1436   this one use.  */
1437#define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
1438#define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
1439#define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
1440static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
1441                                               int ft, int fs, int cc)        \
1442{                                                                             \
1443    TCGv_i##bits fp0 = tcg_temp_new_i##bits ();                               \
1444    TCGv_i##bits fp1 = tcg_temp_new_i##bits ();                               \
1445    switch (ifmt) {                                                           \
1446    case FMT_PS:                                                              \
1447        check_cp1_64bitmode(ctx);                                             \
1448        break;                                                                \
1449    case FMT_D:                                                               \
1450        if (abs) {                                                            \
1451            check_cop1x(ctx);                                                 \
1452        }                                                                     \
1453        check_cp1_registers(ctx, fs | ft);                                    \
1454        break;                                                                \
1455    case FMT_S:                                                               \
1456        if (abs) {                                                            \
1457            check_cop1x(ctx);                                                 \
1458        }                                                                     \
1459        break;                                                                \
1460    }                                                                         \
1461    gen_ldcmp_fpr##bits (ctx, fp0, fs);                                       \
1462    gen_ldcmp_fpr##bits (ctx, fp1, ft);                                       \
1463    switch (n) {                                                              \
1464    case  0: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);    break;\
1465    case  1: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);   break;\
1466    case  2: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);   break;\
1467    case  3: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);  break;\
1468    case  4: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);  break;\
1469    case  5: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);  break;\
1470    case  6: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);  break;\
1471    case  7: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);  break;\
1472    case  8: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);   break;\
1473    case  9: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
1474    case 10: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);  break;\
1475    case 11: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);  break;\
1476    case 12: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);   break;\
1477    case 13: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);  break;\
1478    case 14: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);   break;\
1479    case 15: gen_helper_0e2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);  break;\
1480    default: abort();                                                         \
1481    }                                                                         \
1482    tcg_temp_free_i##bits (fp0);                                              \
1483    tcg_temp_free_i##bits (fp1);                                              \
1484}
1485
1486FOP_CONDS(, 0, d, FMT_D, 64)
1487FOP_CONDS(abs, 1, d, FMT_D, 64)
1488FOP_CONDS(, 0, s, FMT_S, 32)
1489FOP_CONDS(abs, 1, s, FMT_S, 32)
1490FOP_CONDS(, 0, ps, FMT_PS, 64)
1491FOP_CONDS(abs, 1, ps, FMT_PS, 64)
1492#undef FOP_CONDS
1493#undef gen_ldcmp_fpr32
1494#undef gen_ldcmp_fpr64
1495
1496/* load/store instructions. */
1497#ifdef CONFIG_USER_ONLY
1498#define OP_LD_ATOMIC(insn,fname)                                           \
1499static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
1500{                                                                          \
1501    TCGv t0 = tcg_temp_new();                                              \
1502    tcg_gen_mov_tl(t0, arg1);                                              \
1503    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
1504    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                \
1505    tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval));                \
1506    tcg_temp_free(t0);                                                     \
1507}
1508#else
1509#define OP_LD_ATOMIC(insn,fname)                                           \
1510static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
1511{                                                                          \
1512    gen_helper_1e1i(insn, ret, arg1, ctx->mem_idx);                        \
1513}
1514#endif
1515OP_LD_ATOMIC(ll,ld32s);
1516#if defined(TARGET_MIPS64)
1517OP_LD_ATOMIC(lld,ld64);
1518#endif
1519#undef OP_LD_ATOMIC
1520
1521#ifdef CONFIG_USER_ONLY
1522#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
1523static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1524{                                                                            \
1525    TCGv t0 = tcg_temp_new();                                                \
1526    int l1 = gen_new_label();                                                \
1527    int l2 = gen_new_label();                                                \
1528                                                                             \
1529    tcg_gen_andi_tl(t0, arg2, almask);                                       \
1530    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                              \
1531    tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));          \
1532    generate_exception(ctx, EXCP_AdES);                                      \
1533    gen_set_label(l1);                                                       \
1534    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                  \
1535    tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                            \
1536    tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20));                        \
1537    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg));                   \
1538    tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval));              \
1539    gen_helper_0e0i(raise_exception, EXCP_SC);                               \
1540    gen_set_label(l2);                                                       \
1541    tcg_gen_movi_tl(t0, 0);                                                  \
1542    gen_store_gpr(t0, rt);                                                   \
1543    tcg_temp_free(t0);                                                       \
1544}
1545#else
1546#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
1547static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1548{                                                                            \
1549    TCGv t0 = tcg_temp_new();                                                \
1550    gen_helper_1e2i(insn, t0, arg1, arg2, ctx->mem_idx);                     \
1551    gen_store_gpr(t0, rt);                                                   \
1552    tcg_temp_free(t0);                                                       \
1553}
1554#endif
1555OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1556#if defined(TARGET_MIPS64)
1557OP_ST_ATOMIC(scd,st64,ld64,0x7);
1558#endif
1559#undef OP_ST_ATOMIC
1560
1561static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
1562                                  int base, int16_t offset)
1563{
1564    if (base == 0) {
1565        tcg_gen_movi_tl(addr, offset);
1566    } else if (offset == 0) {
1567        gen_load_gpr(addr, base);
1568    } else {
1569        tcg_gen_movi_tl(addr, offset);
1570        gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1571    }
1572}
1573
1574static target_ulong pc_relative_pc (DisasContext *ctx)
1575{
1576    target_ulong pc = ctx->pc;
1577
1578    if (ctx->hflags & MIPS_HFLAG_BMASK) {
1579        int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
1580
1581        pc -= branch_bytes;
1582    }
1583
1584    pc &= ~(target_ulong)3;
1585    return pc;
1586}
1587
1588/* Load */
1589static void gen_ld(DisasContext *ctx, uint32_t opc,
1590                   int rt, int base, int16_t offset)
1591{
1592    const char *opn = "ld";
1593    TCGv t0, t1, t2;
1594
1595    if (rt == 0 && ctx->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
1596        /* Loongson CPU uses a load to zero register for prefetch.
1597           We emulate it as a NOP. On other CPU we must perform the
1598           actual memory access. */
1599        MIPS_DEBUG("NOP");
1600        return;
1601    }
1602
1603    t0 = tcg_temp_new();
1604    gen_base_offset_addr(ctx, t0, base, offset);
1605
1606    switch (opc) {
1607#if defined(TARGET_MIPS64)
1608    case OPC_LWU:
1609        tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1610        gen_store_gpr(t0, rt);
1611        opn = "lwu";
1612        break;
1613    case OPC_LD:
1614        tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1615        gen_store_gpr(t0, rt);
1616        opn = "ld";
1617        break;
1618    case OPC_LLD:
1619        save_cpu_state(ctx, 1);
1620        op_ld_lld(t0, t0, ctx);
1621        gen_store_gpr(t0, rt);
1622        opn = "lld";
1623        break;
1624    case OPC_LDL:
1625        t1 = tcg_temp_new();
1626        tcg_gen_andi_tl(t1, t0, 7);
1627#ifndef TARGET_WORDS_BIGENDIAN
1628        tcg_gen_xori_tl(t1, t1, 7);
1629#endif
1630        tcg_gen_shli_tl(t1, t1, 3);
1631        tcg_gen_andi_tl(t0, t0, ~7);
1632        tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1633        tcg_gen_shl_tl(t0, t0, t1);
1634        tcg_gen_xori_tl(t1, t1, 63);
1635        t2 = tcg_const_tl(0x7fffffffffffffffull);
1636        tcg_gen_shr_tl(t2, t2, t1);
1637        gen_load_gpr(t1, rt);
1638        tcg_gen_and_tl(t1, t1, t2);
1639        tcg_temp_free(t2);
1640        tcg_gen_or_tl(t0, t0, t1);
1641        tcg_temp_free(t1);
1642        gen_store_gpr(t0, rt);
1643        opn = "ldl";
1644        break;
1645    case OPC_LDR:
1646        t1 = tcg_temp_new();
1647        tcg_gen_andi_tl(t1, t0, 7);
1648#ifdef TARGET_WORDS_BIGENDIAN
1649        tcg_gen_xori_tl(t1, t1, 7);
1650#endif
1651        tcg_gen_shli_tl(t1, t1, 3);
1652        tcg_gen_andi_tl(t0, t0, ~7);
1653        tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1654        tcg_gen_shr_tl(t0, t0, t1);
1655        tcg_gen_xori_tl(t1, t1, 63);
1656        t2 = tcg_const_tl(0xfffffffffffffffeull);
1657        tcg_gen_shl_tl(t2, t2, t1);
1658        gen_load_gpr(t1, rt);
1659        tcg_gen_and_tl(t1, t1, t2);
1660        tcg_temp_free(t2);
1661        tcg_gen_or_tl(t0, t0, t1);
1662        tcg_temp_free(t1);
1663        gen_store_gpr(t0, rt);
1664        opn = "ldr";
1665        break;
1666    case OPC_LDPC:
1667        t1 = tcg_const_tl(pc_relative_pc(ctx));
1668        gen_op_addr_add(ctx, t0, t0, t1);
1669        tcg_temp_free(t1);
1670        tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
1671        gen_store_gpr(t0, rt);
1672        opn = "ldpc";
1673        break;
1674#endif
1675    case OPC_LWPC:
1676        t1 = tcg_const_tl(pc_relative_pc(ctx));
1677        gen_op_addr_add(ctx, t0, t0, t1);
1678        tcg_temp_free(t1);
1679        tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1680        gen_store_gpr(t0, rt);
1681        opn = "lwpc";
1682        break;
1683    case OPC_LW:
1684        tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1685        gen_store_gpr(t0, rt);
1686        opn = "lw";
1687        break;
1688    case OPC_LH:
1689        tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
1690        gen_store_gpr(t0, rt);
1691        opn = "lh";
1692        break;
1693    case OPC_LHU:
1694        tcg_gen_qemu_ld16u(t0, t0, ctx->mem_idx);
1695        gen_store_gpr(t0, rt);
1696        opn = "lhu";
1697        break;
1698    case OPC_LB:
1699        tcg_gen_qemu_ld8s(t0, t0, ctx->mem_idx);
1700        gen_store_gpr(t0, rt);
1701        opn = "lb";
1702        break;
1703    case OPC_LBU:
1704        tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
1705        gen_store_gpr(t0, rt);
1706        opn = "lbu";
1707        break;
1708    case OPC_LWL:
1709        t1 = tcg_temp_new();
1710        tcg_gen_andi_tl(t1, t0, 3);
1711#ifndef TARGET_WORDS_BIGENDIAN
1712        tcg_gen_xori_tl(t1, t1, 3);
1713#endif
1714        tcg_gen_shli_tl(t1, t1, 3);
1715        tcg_gen_andi_tl(t0, t0, ~3);
1716        tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1717        tcg_gen_shl_tl(t0, t0, t1);
1718        tcg_gen_xori_tl(t1, t1, 31);
1719        t2 = tcg_const_tl(0x7fffffffull);
1720        tcg_gen_shr_tl(t2, t2, t1);
1721        gen_load_gpr(t1, rt);
1722        tcg_gen_and_tl(t1, t1, t2);
1723        tcg_temp_free(t2);
1724        tcg_gen_or_tl(t0, t0, t1);
1725        tcg_temp_free(t1);
1726        tcg_gen_ext32s_tl(t0, t0);
1727        gen_store_gpr(t0, rt);
1728        opn = "lwl";
1729        break;
1730    case OPC_LWR:
1731        t1 = tcg_temp_new();
1732        tcg_gen_andi_tl(t1, t0, 3);
1733#ifdef TARGET_WORDS_BIGENDIAN
1734        tcg_gen_xori_tl(t1, t1, 3);
1735#endif
1736        tcg_gen_shli_tl(t1, t1, 3);
1737        tcg_gen_andi_tl(t0, t0, ~3);
1738        tcg_gen_qemu_ld32u(t0, t0, ctx->mem_idx);
1739        tcg_gen_shr_tl(t0, t0, t1);
1740        tcg_gen_xori_tl(t1, t1, 31);
1741        t2 = tcg_const_tl(0xfffffffeull);
1742        tcg_gen_shl_tl(t2, t2, t1);
1743        gen_load_gpr(t1, rt);
1744        tcg_gen_and_tl(t1, t1, t2);
1745        tcg_temp_free(t2);
1746        tcg_gen_or_tl(t0, t0, t1);
1747        tcg_temp_free(t1);
1748        tcg_gen_ext32s_tl(t0, t0);
1749        gen_store_gpr(t0, rt);
1750        opn = "lwr";
1751        break;
1752    case OPC_LL:
1753        save_cpu_state(ctx, 1);
1754        op_ld_ll(t0, t0, ctx);
1755        gen_store_gpr(t0, rt);
1756        opn = "ll";
1757        break;
1758    }
1759    (void)opn; /* avoid a compiler warning */
1760    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1761    tcg_temp_free(t0);
1762}
1763
1764/* Store */
1765static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
1766                    int base, int16_t offset)
1767{
1768    const char *opn = "st";
1769    TCGv t0 = tcg_temp_new();
1770    TCGv t1 = tcg_temp_new();
1771
1772    gen_base_offset_addr(ctx, t0, base, offset);
1773    gen_load_gpr(t1, rt);
1774    switch (opc) {
1775#if defined(TARGET_MIPS64)
1776    case OPC_SD:
1777        tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
1778        opn = "sd";
1779        break;
1780    case OPC_SDL:
1781        save_cpu_state(ctx, 1);
1782        gen_helper_0e2i(sdl, t1, t0, ctx->mem_idx);
1783        opn = "sdl";
1784        break;
1785    case OPC_SDR:
1786        save_cpu_state(ctx, 1);
1787        gen_helper_0e2i(sdr, t1, t0, ctx->mem_idx);
1788        opn = "sdr";
1789        break;
1790#endif
1791    case OPC_SW:
1792        tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1793        opn = "sw";
1794        break;
1795    case OPC_SH:
1796        tcg_gen_qemu_st16(t1, t0, ctx->mem_idx);
1797        opn = "sh";
1798        break;
1799    case OPC_SB:
1800        tcg_gen_qemu_st8(t1, t0, ctx->mem_idx);
1801        opn = "sb";
1802        break;
1803    case OPC_SWL:
1804        save_cpu_state(ctx, 1);
1805        gen_helper_0e2i(swl, t1, t0, ctx->mem_idx);
1806        opn = "swl";
1807        break;
1808    case OPC_SWR:
1809        save_cpu_state(ctx, 1);
1810        gen_helper_0e2i(swr, t1, t0, ctx->mem_idx);
1811        opn = "swr";
1812        break;
1813    }
1814    (void)opn; /* avoid a compiler warning */
1815    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1816    tcg_temp_free(t0);
1817    tcg_temp_free(t1);
1818}
1819
1820
1821/* Store conditional */
1822static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1823                         int base, int16_t offset)
1824{
1825    const char *opn = "st_cond";
1826    TCGv t0, t1;
1827
1828#ifdef CONFIG_USER_ONLY
1829    t0 = tcg_temp_local_new();
1830    t1 = tcg_temp_local_new();
1831#else
1832    t0 = tcg_temp_new();
1833    t1 = tcg_temp_new();
1834#endif
1835    gen_base_offset_addr(ctx, t0, base, offset);
1836    gen_load_gpr(t1, rt);
1837    switch (opc) {
1838#if defined(TARGET_MIPS64)
1839    case OPC_SCD:
1840        save_cpu_state(ctx, 1);
1841        op_st_scd(t1, t0, rt, ctx);
1842        opn = "scd";
1843        break;
1844#endif
1845    case OPC_SC:
1846        save_cpu_state(ctx, 1);
1847        op_st_sc(t1, t0, rt, ctx);
1848        opn = "sc";
1849        break;
1850    }
1851    (void)opn; /* avoid a compiler warning */
1852    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1853    tcg_temp_free(t1);
1854    tcg_temp_free(t0);
1855}
1856
1857/* Load and store */
1858static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1859                          int base, int16_t offset)
1860{
1861    const char *opn = "flt_ldst";
1862    TCGv t0 = tcg_temp_new();
1863
1864    gen_base_offset_addr(ctx, t0, base, offset);
1865    /* Don't do NOP if destination is zero: we must perform the actual
1866       memory access. */
1867    switch (opc) {
1868    case OPC_LWC1:
1869        {
1870            TCGv_i32 fp0 = tcg_temp_new_i32();
1871
1872            tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1873            tcg_gen_trunc_tl_i32(fp0, t0);
1874            gen_store_fpr32(fp0, ft);
1875            tcg_temp_free_i32(fp0);
1876        }
1877        opn = "lwc1";
1878        break;
1879    case OPC_SWC1:
1880        {
1881            TCGv_i32 fp0 = tcg_temp_new_i32();
1882            TCGv t1 = tcg_temp_new();
1883
1884            gen_load_fpr32(fp0, ft);
1885            tcg_gen_extu_i32_tl(t1, fp0);
1886            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1887            tcg_temp_free(t1);
1888            tcg_temp_free_i32(fp0);
1889        }
1890        opn = "swc1";
1891        break;
1892    case OPC_LDC1:
1893        {
1894            TCGv_i64 fp0 = tcg_temp_new_i64();
1895
1896            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1897            gen_store_fpr64(ctx, fp0, ft);
1898            tcg_temp_free_i64(fp0);
1899        }
1900        opn = "ldc1";
1901        break;
1902    case OPC_SDC1:
1903        {
1904            TCGv_i64 fp0 = tcg_temp_new_i64();
1905
1906            gen_load_fpr64(ctx, fp0, ft);
1907            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1908            tcg_temp_free_i64(fp0);
1909        }
1910        opn = "sdc1";
1911        break;
1912    default:
1913        MIPS_INVAL(opn);
1914        generate_exception(ctx, EXCP_RI);
1915        goto out;
1916    }
1917    (void)opn; /* avoid a compiler warning */
1918    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1919 out:
1920    tcg_temp_free(t0);
1921}
1922
1923static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
1924                          uint32_t op, int rt, int rs, int16_t imm)
1925{
1926    if (env->CP0_Config1 & (1 << CP0C1_FP)) {
1927        check_cp1_enabled(ctx);
1928        gen_flt_ldst(ctx, op, rt, rs, imm);
1929    } else {
1930        generate_exception_err(ctx, EXCP_CpU, 1);
1931    }
1932}
1933
1934/* Arithmetic with immediate operand */
1935static void gen_arith_imm(DisasContext *ctx, uint32_t opc,
1936                          int rt, int rs, int16_t imm)
1937{
1938    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1939    const char *opn = "imm arith";
1940
1941    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1942        /* If no destination, treat it as a NOP.
1943           For addi, we must generate the overflow exception when needed. */
1944        MIPS_DEBUG("NOP");
1945        return;
1946    }
1947    switch (opc) {
1948    case OPC_ADDI:
1949        {
1950            TCGv t0 = tcg_temp_local_new();
1951            TCGv t1 = tcg_temp_new();
1952            TCGv t2 = tcg_temp_new();
1953            int l1 = gen_new_label();
1954
1955            gen_load_gpr(t1, rs);
1956            tcg_gen_addi_tl(t0, t1, uimm);
1957            tcg_gen_ext32s_tl(t0, t0);
1958
1959            tcg_gen_xori_tl(t1, t1, ~uimm);
1960            tcg_gen_xori_tl(t2, t0, uimm);
1961            tcg_gen_and_tl(t1, t1, t2);
1962            tcg_temp_free(t2);
1963            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1964            tcg_temp_free(t1);
1965            /* operands of same sign, result different sign */
1966            generate_exception(ctx, EXCP_OVERFLOW);
1967            gen_set_label(l1);
1968            tcg_gen_ext32s_tl(t0, t0);
1969            gen_store_gpr(t0, rt);
1970            tcg_temp_free(t0);
1971        }
1972        opn = "addi";
1973        break;
1974    case OPC_ADDIU:
1975        if (rs != 0) {
1976            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1977            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1978        } else {
1979            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1980        }
1981        opn = "addiu";
1982        break;
1983#if defined(TARGET_MIPS64)
1984    case OPC_DADDI:
1985        {
1986            TCGv t0 = tcg_temp_local_new();
1987            TCGv t1 = tcg_temp_new();
1988            TCGv t2 = tcg_temp_new();
1989            int l1 = gen_new_label();
1990
1991            gen_load_gpr(t1, rs);
1992            tcg_gen_addi_tl(t0, t1, uimm);
1993
1994            tcg_gen_xori_tl(t1, t1, ~uimm);
1995            tcg_gen_xori_tl(t2, t0, uimm);
1996            tcg_gen_and_tl(t1, t1, t2);
1997            tcg_temp_free(t2);
1998            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1999            tcg_temp_free(t1);
2000            /* operands of same sign, result different sign */
2001            generate_exception(ctx, EXCP_OVERFLOW);
2002            gen_set_label(l1);
2003            gen_store_gpr(t0, rt);
2004            tcg_temp_free(t0);
2005        }
2006        opn = "daddi";
2007        break;
2008    case OPC_DADDIU:
2009        if (rs != 0) {
2010            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2011        } else {
2012            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2013        }
2014        opn = "daddiu";
2015        break;
2016#endif
2017    }
2018    (void)opn; /* avoid a compiler warning */
2019    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2020}
2021
2022/* Logic with immediate operand */
2023static void gen_logic_imm(DisasContext *ctx, uint32_t opc,
2024                          int rt, int rs, int16_t imm)
2025{
2026    target_ulong uimm;
2027
2028    if (rt == 0) {
2029        /* If no destination, treat it as a NOP. */
2030        MIPS_DEBUG("NOP");
2031        return;
2032    }
2033    uimm = (uint16_t)imm;
2034    switch (opc) {
2035    case OPC_ANDI:
2036        if (likely(rs != 0))
2037            tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2038        else
2039            tcg_gen_movi_tl(cpu_gpr[rt], 0);
2040        MIPS_DEBUG("andi %s, %s, " TARGET_FMT_lx, regnames[rt],
2041                   regnames[rs], uimm);
2042        break;
2043    case OPC_ORI:
2044        if (rs != 0)
2045            tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2046        else
2047            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2048        MIPS_DEBUG("ori %s, %s, " TARGET_FMT_lx, regnames[rt],
2049                   regnames[rs], uimm);
2050        break;
2051    case OPC_XORI:
2052        if (likely(rs != 0))
2053            tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
2054        else
2055            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
2056        MIPS_DEBUG("xori %s, %s, " TARGET_FMT_lx, regnames[rt],
2057                   regnames[rs], uimm);
2058        break;
2059    case OPC_LUI:
2060        tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
2061        MIPS_DEBUG("lui %s, " TARGET_FMT_lx, regnames[rt], uimm);
2062        break;
2063
2064    default:
2065        MIPS_DEBUG("Unknown logical immediate opcode %08x", opc);
2066        break;
2067    }
2068}
2069
2070/* Set on less than with immediate operand */
2071static void gen_slt_imm(DisasContext *ctx, uint32_t opc,
2072                        int rt, int rs, int16_t imm)
2073{
2074    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
2075    const char *opn = "imm arith";
2076    TCGv t0;
2077
2078    if (rt == 0) {
2079        /* If no destination, treat it as a NOP. */
2080        MIPS_DEBUG("NOP");
2081        return;
2082    }
2083    t0 = tcg_temp_new();
2084    gen_load_gpr(t0, rs);
2085    switch (opc) {
2086    case OPC_SLTI:
2087        tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
2088        opn = "slti";
2089        break;
2090    case OPC_SLTIU:
2091        tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
2092        opn = "sltiu";
2093        break;
2094    }
2095    (void)opn; /* avoid a compiler warning */
2096    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2097    tcg_temp_free(t0);
2098}
2099
2100/* Shifts with immediate operand */
2101static void gen_shift_imm(DisasContext *ctx, uint32_t opc,
2102                          int rt, int rs, int16_t imm)
2103{
2104    target_ulong uimm = ((uint16_t)imm) & 0x1f;
2105    const char *opn = "imm shift";
2106    TCGv t0;
2107
2108    if (rt == 0) {
2109        /* If no destination, treat it as a NOP. */
2110        MIPS_DEBUG("NOP");
2111        return;
2112    }
2113
2114    t0 = tcg_temp_new();
2115    gen_load_gpr(t0, rs);
2116    switch (opc) {
2117    case OPC_SLL:
2118        tcg_gen_shli_tl(t0, t0, uimm);
2119        tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2120        opn = "sll";
2121        break;
2122    case OPC_SRA:
2123        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2124        opn = "sra";
2125        break;
2126    case OPC_SRL:
2127        if (uimm != 0) {
2128            tcg_gen_ext32u_tl(t0, t0);
2129            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2130        } else {
2131            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2132        }
2133        opn = "srl";
2134        break;
2135    case OPC_ROTR:
2136        if (uimm != 0) {
2137            TCGv_i32 t1 = tcg_temp_new_i32();
2138
2139            tcg_gen_trunc_tl_i32(t1, t0);
2140            tcg_gen_rotri_i32(t1, t1, uimm);
2141            tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
2142            tcg_temp_free_i32(t1);
2143        } else {
2144            tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
2145        }
2146        opn = "rotr";
2147        break;
2148#if defined(TARGET_MIPS64)
2149    case OPC_DSLL:
2150        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
2151        opn = "dsll";
2152        break;
2153    case OPC_DSRA:
2154        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
2155        opn = "dsra";
2156        break;
2157    case OPC_DSRL:
2158        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
2159        opn = "dsrl";
2160        break;
2161    case OPC_DROTR:
2162        if (uimm != 0) {
2163            tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
2164        } else {
2165            tcg_gen_mov_tl(cpu_gpr[rt], t0);
2166        }
2167        opn = "drotr";
2168        break;
2169    case OPC_DSLL32:
2170        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
2171        opn = "dsll32";
2172        break;
2173    case OPC_DSRA32:
2174        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
2175        opn = "dsra32";
2176        break;
2177    case OPC_DSRL32:
2178        tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
2179        opn = "dsrl32";
2180        break;
2181    case OPC_DROTR32:
2182        tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
2183        opn = "drotr32";
2184        break;
2185#endif
2186    }
2187    (void)opn; /* avoid a compiler warning */
2188    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
2189    tcg_temp_free(t0);
2190}
2191
2192/* Arithmetic */
2193static void gen_arith(DisasContext *ctx, uint32_t opc,
2194                      int rd, int rs, int rt)
2195{
2196    const char *opn = "arith";
2197
2198    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
2199       && opc != OPC_DADD && opc != OPC_DSUB) {
2200        /* If no destination, treat it as a NOP.
2201           For add & sub, we must generate the overflow exception when needed. */
2202        MIPS_DEBUG("NOP");
2203        return;
2204    }
2205
2206    switch (opc) {
2207    case OPC_ADD:
2208        {
2209            TCGv t0 = tcg_temp_local_new();
2210            TCGv t1 = tcg_temp_new();
2211            TCGv t2 = tcg_temp_new();
2212            int l1 = gen_new_label();
2213
2214            gen_load_gpr(t1, rs);
2215            gen_load_gpr(t2, rt);
2216            tcg_gen_add_tl(t0, t1, t2);
2217            tcg_gen_ext32s_tl(t0, t0);
2218            tcg_gen_xor_tl(t1, t1, t2);
2219            tcg_gen_xor_tl(t2, t0, t2);
2220            tcg_gen_andc_tl(t1, t2, t1);
2221            tcg_temp_free(t2);
2222            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2223            tcg_temp_free(t1);
2224            /* operands of same sign, result different sign */
2225            generate_exception(ctx, EXCP_OVERFLOW);
2226            gen_set_label(l1);
2227            gen_store_gpr(t0, rd);
2228            tcg_temp_free(t0);
2229        }
2230        opn = "add";
2231        break;
2232    case OPC_ADDU:
2233        if (rs != 0 && rt != 0) {
2234            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2235            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2236        } else if (rs == 0 && rt != 0) {
2237            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2238        } else if (rs != 0 && rt == 0) {
2239            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2240        } else {
2241            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2242        }
2243        opn = "addu";
2244        break;
2245    case OPC_SUB:
2246        {
2247            TCGv t0 = tcg_temp_local_new();
2248            TCGv t1 = tcg_temp_new();
2249            TCGv t2 = tcg_temp_new();
2250            int l1 = gen_new_label();
2251
2252            gen_load_gpr(t1, rs);
2253            gen_load_gpr(t2, rt);
2254            tcg_gen_sub_tl(t0, t1, t2);
2255            tcg_gen_ext32s_tl(t0, t0);
2256            tcg_gen_xor_tl(t2, t1, t2);
2257            tcg_gen_xor_tl(t1, t0, t1);
2258            tcg_gen_and_tl(t1, t1, t2);
2259            tcg_temp_free(t2);
2260            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2261            tcg_temp_free(t1);
2262            /* operands of different sign, first operand and result different sign */
2263            generate_exception(ctx, EXCP_OVERFLOW);
2264            gen_set_label(l1);
2265            gen_store_gpr(t0, rd);
2266            tcg_temp_free(t0);
2267        }
2268        opn = "sub";
2269        break;
2270    case OPC_SUBU:
2271        if (rs != 0 && rt != 0) {
2272            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2273            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2274        } else if (rs == 0 && rt != 0) {
2275            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2276            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2277        } else if (rs != 0 && rt == 0) {
2278            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2279        } else {
2280            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2281        }
2282        opn = "subu";
2283        break;
2284#if defined(TARGET_MIPS64)
2285    case OPC_DADD:
2286        {
2287            TCGv t0 = tcg_temp_local_new();
2288            TCGv t1 = tcg_temp_new();
2289            TCGv t2 = tcg_temp_new();
2290            int l1 = gen_new_label();
2291
2292            gen_load_gpr(t1, rs);
2293            gen_load_gpr(t2, rt);
2294            tcg_gen_add_tl(t0, t1, t2);
2295            tcg_gen_xor_tl(t1, t1, t2);
2296            tcg_gen_xor_tl(t2, t0, t2);
2297            tcg_gen_andc_tl(t1, t2, t1);
2298            tcg_temp_free(t2);
2299            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2300            tcg_temp_free(t1);
2301            /* operands of same sign, result different sign */
2302            generate_exception(ctx, EXCP_OVERFLOW);
2303            gen_set_label(l1);
2304            gen_store_gpr(t0, rd);
2305            tcg_temp_free(t0);
2306        }
2307        opn = "dadd";
2308        break;
2309    case OPC_DADDU:
2310        if (rs != 0 && rt != 0) {
2311            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2312        } else if (rs == 0 && rt != 0) {
2313            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2314        } else if (rs != 0 && rt == 0) {
2315            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2316        } else {
2317            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2318        }
2319        opn = "daddu";
2320        break;
2321    case OPC_DSUB:
2322        {
2323            TCGv t0 = tcg_temp_local_new();
2324            TCGv t1 = tcg_temp_new();
2325            TCGv t2 = tcg_temp_new();
2326            int l1 = gen_new_label();
2327
2328            gen_load_gpr(t1, rs);
2329            gen_load_gpr(t2, rt);
2330            tcg_gen_sub_tl(t0, t1, t2);
2331            tcg_gen_xor_tl(t2, t1, t2);
2332            tcg_gen_xor_tl(t1, t0, t1);
2333            tcg_gen_and_tl(t1, t1, t2);
2334            tcg_temp_free(t2);
2335            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
2336            tcg_temp_free(t1);
2337            /* operands of different sign, first operand and result different sign */
2338            generate_exception(ctx, EXCP_OVERFLOW);
2339            gen_set_label(l1);
2340            gen_store_gpr(t0, rd);
2341            tcg_temp_free(t0);
2342        }
2343        opn = "dsub";
2344        break;
2345    case OPC_DSUBU:
2346        if (rs != 0 && rt != 0) {
2347            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2348        } else if (rs == 0 && rt != 0) {
2349            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
2350        } else if (rs != 0 && rt == 0) {
2351            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2352        } else {
2353            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2354        }
2355        opn = "dsubu";
2356        break;
2357#endif
2358    case OPC_MUL:
2359        if (likely(rs != 0 && rt != 0)) {
2360            tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2361            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
2362        } else {
2363            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2364        }
2365        opn = "mul";
2366        break;
2367    }
2368    (void)opn; /* avoid a compiler warning */
2369    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2370}
2371
2372/* Conditional move */
2373static void gen_cond_move(DisasContext *ctx, uint32_t opc,
2374                          int rd, int rs, int rt)
2375{
2376    const char *opn = "cond move";
2377    TCGv t0, t1, t2;
2378
2379    if (rd == 0) {
2380        /* If no destination, treat it as a NOP. */
2381        MIPS_DEBUG("NOP");
2382        return;
2383    }
2384
2385    t0 = tcg_temp_new();
2386    gen_load_gpr(t0, rt);
2387    t1 = tcg_const_tl(0);
2388    t2 = tcg_temp_new();
2389    gen_load_gpr(t2, rs);
2390    switch (opc) {
2391    case OPC_MOVN:
2392        tcg_gen_movcond_tl(TCG_COND_NE, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2393        opn = "movn";
2394        break;
2395    case OPC_MOVZ:
2396        tcg_gen_movcond_tl(TCG_COND_EQ, cpu_gpr[rd], t0, t1, t2, cpu_gpr[rd]);
2397        opn = "movz";
2398        break;
2399    }
2400    tcg_temp_free(t2);
2401    tcg_temp_free(t1);
2402    tcg_temp_free(t0);
2403
2404    (void)opn; /* avoid a compiler warning */
2405    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2406}
2407
2408/* Logic */
2409static void gen_logic(DisasContext *ctx, uint32_t opc,
2410                      int rd, int rs, int rt)
2411{
2412    const char *opn = "logic";
2413
2414    if (rd == 0) {
2415        /* If no destination, treat it as a NOP. */
2416        MIPS_DEBUG("NOP");
2417        return;
2418    }
2419
2420    switch (opc) {
2421    case OPC_AND:
2422        if (likely(rs != 0 && rt != 0)) {
2423            tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2424        } else {
2425            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2426        }
2427        opn = "and";
2428        break;
2429    case OPC_NOR:
2430        if (rs != 0 && rt != 0) {
2431            tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2432        } else if (rs == 0 && rt != 0) {
2433            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
2434        } else if (rs != 0 && rt == 0) {
2435            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
2436        } else {
2437            tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
2438        }
2439        opn = "nor";
2440        break;
2441    case OPC_OR:
2442        if (likely(rs != 0 && rt != 0)) {
2443            tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2444        } else if (rs == 0 && rt != 0) {
2445            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2446        } else if (rs != 0 && rt == 0) {
2447            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2448        } else {
2449            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2450        }
2451        opn = "or";
2452        break;
2453    case OPC_XOR:
2454        if (likely(rs != 0 && rt != 0)) {
2455            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
2456        } else if (rs == 0 && rt != 0) {
2457            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
2458        } else if (rs != 0 && rt == 0) {
2459            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
2460        } else {
2461            tcg_gen_movi_tl(cpu_gpr[rd], 0);
2462        }
2463        opn = "xor";
2464        break;
2465    }
2466    (void)opn; /* avoid a compiler warning */
2467    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2468}
2469
2470/* Set on lower than */
2471static void gen_slt(DisasContext *ctx, uint32_t opc,
2472                    int rd, int rs, int rt)
2473{
2474    const char *opn = "slt";
2475    TCGv t0, t1;
2476
2477    if (rd == 0) {
2478        /* If no destination, treat it as a NOP. */
2479        MIPS_DEBUG("NOP");
2480        return;
2481    }
2482
2483    t0 = tcg_temp_new();
2484    t1 = tcg_temp_new();
2485    gen_load_gpr(t0, rs);
2486    gen_load_gpr(t1, rt);
2487    switch (opc) {
2488    case OPC_SLT:
2489        tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
2490        opn = "slt";
2491        break;
2492    case OPC_SLTU:
2493        tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
2494        opn = "sltu";
2495        break;
2496    }
2497    (void)opn; /* avoid a compiler warning */
2498    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2499    tcg_temp_free(t0);
2500    tcg_temp_free(t1);
2501}
2502
2503/* Shifts */
2504static void gen_shift(DisasContext *ctx, uint32_t opc,
2505                      int rd, int rs, int rt)
2506{
2507    const char *opn = "shifts";
2508    TCGv t0, t1;
2509
2510    if (rd == 0) {
2511        /* If no destination, treat it as a NOP.
2512           For add & sub, we must generate the overflow exception when needed. */
2513        MIPS_DEBUG("NOP");
2514        return;
2515    }
2516
2517    t0 = tcg_temp_new();
2518    t1 = tcg_temp_new();
2519    gen_load_gpr(t0, rs);
2520    gen_load_gpr(t1, rt);
2521    switch (opc) {
2522    case OPC_SLLV:
2523        tcg_gen_andi_tl(t0, t0, 0x1f);
2524        tcg_gen_shl_tl(t0, t1, t0);
2525        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2526        opn = "sllv";
2527        break;
2528    case OPC_SRAV:
2529        tcg_gen_andi_tl(t0, t0, 0x1f);
2530        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2531        opn = "srav";
2532        break;
2533    case OPC_SRLV:
2534        tcg_gen_ext32u_tl(t1, t1);
2535        tcg_gen_andi_tl(t0, t0, 0x1f);
2536        tcg_gen_shr_tl(t0, t1, t0);
2537        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2538        opn = "srlv";
2539        break;
2540    case OPC_ROTRV:
2541        {
2542            TCGv_i32 t2 = tcg_temp_new_i32();
2543            TCGv_i32 t3 = tcg_temp_new_i32();
2544
2545            tcg_gen_trunc_tl_i32(t2, t0);
2546            tcg_gen_trunc_tl_i32(t3, t1);
2547            tcg_gen_andi_i32(t2, t2, 0x1f);
2548            tcg_gen_rotr_i32(t2, t3, t2);
2549            tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
2550            tcg_temp_free_i32(t2);
2551            tcg_temp_free_i32(t3);
2552            opn = "rotrv";
2553        }
2554        break;
2555#if defined(TARGET_MIPS64)
2556    case OPC_DSLLV:
2557        tcg_gen_andi_tl(t0, t0, 0x3f);
2558        tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
2559        opn = "dsllv";
2560        break;
2561    case OPC_DSRAV:
2562        tcg_gen_andi_tl(t0, t0, 0x3f);
2563        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
2564        opn = "dsrav";
2565        break;
2566    case OPC_DSRLV:
2567        tcg_gen_andi_tl(t0, t0, 0x3f);
2568        tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
2569        opn = "dsrlv";
2570        break;
2571    case OPC_DROTRV:
2572        tcg_gen_andi_tl(t0, t0, 0x3f);
2573        tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
2574        opn = "drotrv";
2575        break;
2576#endif
2577    }
2578    (void)opn; /* avoid a compiler warning */
2579    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2580    tcg_temp_free(t0);
2581    tcg_temp_free(t1);
2582}
2583
2584/* Arithmetic on HI/LO registers */
2585static void gen_HILO(DisasContext *ctx, uint32_t opc, int acc, int reg)
2586{
2587    const char *opn = "hilo";
2588
2589    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
2590        /* Treat as NOP. */
2591        MIPS_DEBUG("NOP");
2592        return;
2593    }
2594
2595    if (acc != 0) {
2596        check_dsp(ctx);
2597    }
2598
2599    switch (opc) {
2600    case OPC_MFHI:
2601#if defined(TARGET_MIPS64)
2602        if (acc != 0) {
2603            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_HI[acc]);
2604        } else
2605#endif
2606        {
2607            tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[acc]);
2608        }
2609        opn = "mfhi";
2610        break;
2611    case OPC_MFLO:
2612#if defined(TARGET_MIPS64)
2613        if (acc != 0) {
2614            tcg_gen_ext32s_tl(cpu_gpr[reg], cpu_LO[acc]);
2615        } else
2616#endif
2617        {
2618            tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[acc]);
2619        }
2620        opn = "mflo";
2621        break;
2622    case OPC_MTHI:
2623        if (reg != 0) {
2624#if defined(TARGET_MIPS64)
2625            if (acc != 0) {
2626                tcg_gen_ext32s_tl(cpu_HI[acc], cpu_gpr[reg]);
2627            } else
2628#endif
2629            {
2630                tcg_gen_mov_tl(cpu_HI[acc], cpu_gpr[reg]);
2631            }
2632        } else {
2633            tcg_gen_movi_tl(cpu_HI[acc], 0);
2634        }
2635        opn = "mthi";
2636        break;
2637    case OPC_MTLO:
2638        if (reg != 0) {
2639#if defined(TARGET_MIPS64)
2640            if (acc != 0) {
2641                tcg_gen_ext32s_tl(cpu_LO[acc], cpu_gpr[reg]);
2642            } else
2643#endif
2644            {
2645                tcg_gen_mov_tl(cpu_LO[acc], cpu_gpr[reg]);
2646            }
2647        } else {
2648            tcg_gen_movi_tl(cpu_LO[acc], 0);
2649        }
2650        opn = "mtlo";
2651        break;
2652    }
2653    (void)opn; /* avoid a compiler warning */
2654    MIPS_DEBUG("%s %s", opn, regnames[reg]);
2655}
2656
2657static void gen_muldiv(DisasContext *ctx, uint32_t opc,
2658                       int acc, int rs, int rt)
2659{
2660    const char *opn = "mul/div";
2661    TCGv t0, t1;
2662
2663    t0 = tcg_temp_new();
2664    t1 = tcg_temp_new();
2665
2666    gen_load_gpr(t0, rs);
2667    gen_load_gpr(t1, rt);
2668
2669    if (acc != 0) {
2670        check_dsp(ctx);
2671    }
2672
2673    switch (opc) {
2674    case OPC_DIV:
2675        {
2676            TCGv t2 = tcg_temp_new();
2677            TCGv t3 = tcg_temp_new();
2678            tcg_gen_ext32s_tl(t0, t0);
2679            tcg_gen_ext32s_tl(t1, t1);
2680            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, INT_MIN);
2681            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1);
2682            tcg_gen_and_tl(t2, t2, t3);
2683            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2684            tcg_gen_or_tl(t2, t2, t3);
2685            tcg_gen_movi_tl(t3, 0);
2686            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2687            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
2688            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
2689            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
2690            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
2691            tcg_temp_free(t3);
2692            tcg_temp_free(t2);
2693        }
2694        opn = "div";
2695        break;
2696    case OPC_DIVU:
2697        {
2698            TCGv t2 = tcg_const_tl(0);
2699            TCGv t3 = tcg_const_tl(1);
2700            tcg_gen_ext32u_tl(t0, t0);
2701            tcg_gen_ext32u_tl(t1, t1);
2702            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2703            tcg_gen_divu_tl(cpu_LO[acc], t0, t1);
2704            tcg_gen_remu_tl(cpu_HI[acc], t0, t1);
2705            tcg_gen_ext32s_tl(cpu_LO[acc], cpu_LO[acc]);
2706            tcg_gen_ext32s_tl(cpu_HI[acc], cpu_HI[acc]);
2707            tcg_temp_free(t3);
2708            tcg_temp_free(t2);
2709        }
2710        opn = "divu";
2711        break;
2712    case OPC_MULT:
2713        {
2714            TCGv_i32 t2 = tcg_temp_new_i32();
2715            TCGv_i32 t3 = tcg_temp_new_i32();
2716            tcg_gen_trunc_tl_i32(t2, t0);
2717            tcg_gen_trunc_tl_i32(t3, t1);
2718            tcg_gen_muls2_i32(t2, t3, t2, t3);
2719            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
2720            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
2721            tcg_temp_free_i32(t2);
2722            tcg_temp_free_i32(t3);
2723        }
2724        opn = "mult";
2725        break;
2726    case OPC_MULTU:
2727        {
2728            TCGv_i32 t2 = tcg_temp_new_i32();
2729            TCGv_i32 t3 = tcg_temp_new_i32();
2730            tcg_gen_trunc_tl_i32(t2, t0);
2731            tcg_gen_trunc_tl_i32(t3, t1);
2732            tcg_gen_mulu2_i32(t2, t3, t2, t3);
2733            tcg_gen_ext_i32_tl(cpu_LO[acc], t2);
2734            tcg_gen_ext_i32_tl(cpu_HI[acc], t3);
2735            tcg_temp_free_i32(t2);
2736            tcg_temp_free_i32(t3);
2737        }
2738        opn = "multu";
2739        break;
2740#if defined(TARGET_MIPS64)
2741    case OPC_DDIV:
2742        {
2743            TCGv t2 = tcg_temp_new();
2744            TCGv t3 = tcg_temp_new();
2745            tcg_gen_setcondi_tl(TCG_COND_EQ, t2, t0, -1LL << 63);
2746            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, -1LL);
2747            tcg_gen_and_tl(t2, t2, t3);
2748            tcg_gen_setcondi_tl(TCG_COND_EQ, t3, t1, 0);
2749            tcg_gen_or_tl(t2, t2, t3);
2750            tcg_gen_movi_tl(t3, 0);
2751            tcg_gen_movcond_tl(TCG_COND_NE, t1, t2, t3, t2, t1);
2752            tcg_gen_div_tl(cpu_LO[acc], t0, t1);
2753            tcg_gen_rem_tl(cpu_HI[acc], t0, t1);
2754            tcg_temp_free(t3);
2755            tcg_temp_free(t2);
2756        }
2757        opn = "ddiv";
2758        break;
2759    case OPC_DDIVU:
2760        {
2761            TCGv t2 = tcg_const_tl(0);
2762            TCGv t3 = tcg_const_tl(1);
2763            tcg_gen_movcond_tl(TCG_COND_EQ, t1, t1, t2, t3, t1);
2764            tcg_gen_divu_i64(cpu_LO[acc], t0, t1);
2765            tcg_gen_remu_i64(cpu_HI[acc], t0, t1);
2766            tcg_temp_free(t3);
2767            tcg_temp_free(t2);
2768        }
2769        opn = "ddivu";
2770        break;
2771    case OPC_DMULT:
2772        tcg_gen_muls2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
2773        opn = "dmult";
2774        break;
2775    case OPC_DMULTU:
2776        tcg_gen_mulu2_i64(cpu_LO[acc], cpu_HI[acc], t0, t1);
2777        opn = "dmultu";
2778        break;
2779#endif
2780    case OPC_MADD:
2781        {
2782            TCGv_i64 t2 = tcg_temp_new_i64();
2783            TCGv_i64 t3 = tcg_temp_new_i64();
2784
2785            tcg_gen_ext_tl_i64(t2, t0);
2786            tcg_gen_ext_tl_i64(t3, t1);
2787            tcg_gen_mul_i64(t2, t2, t3);
2788            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2789            tcg_gen_add_i64(t2, t2, t3);
2790            tcg_temp_free_i64(t3);
2791            tcg_gen_trunc_i64_tl(t0, t2);
2792            tcg_gen_shri_i64(t2, t2, 32);
2793            tcg_gen_trunc_i64_tl(t1, t2);
2794            tcg_temp_free_i64(t2);
2795            tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2796            tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2797        }
2798        opn = "madd";
2799        break;
2800    case OPC_MADDU:
2801        {
2802            TCGv_i64 t2 = tcg_temp_new_i64();
2803            TCGv_i64 t3 = tcg_temp_new_i64();
2804
2805            tcg_gen_ext32u_tl(t0, t0);
2806            tcg_gen_ext32u_tl(t1, t1);
2807            tcg_gen_extu_tl_i64(t2, t0);
2808            tcg_gen_extu_tl_i64(t3, t1);
2809            tcg_gen_mul_i64(t2, t2, t3);
2810            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2811            tcg_gen_add_i64(t2, t2, t3);
2812            tcg_temp_free_i64(t3);
2813            tcg_gen_trunc_i64_tl(t0, t2);
2814            tcg_gen_shri_i64(t2, t2, 32);
2815            tcg_gen_trunc_i64_tl(t1, t2);
2816            tcg_temp_free_i64(t2);
2817            tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2818            tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2819        }
2820        opn = "maddu";
2821        break;
2822    case OPC_MSUB:
2823        {
2824            TCGv_i64 t2 = tcg_temp_new_i64();
2825            TCGv_i64 t3 = tcg_temp_new_i64();
2826
2827            tcg_gen_ext_tl_i64(t2, t0);
2828            tcg_gen_ext_tl_i64(t3, t1);
2829            tcg_gen_mul_i64(t2, t2, t3);
2830            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2831            tcg_gen_sub_i64(t2, t3, t2);
2832            tcg_temp_free_i64(t3);
2833            tcg_gen_trunc_i64_tl(t0, t2);
2834            tcg_gen_shri_i64(t2, t2, 32);
2835            tcg_gen_trunc_i64_tl(t1, t2);
2836            tcg_temp_free_i64(t2);
2837            tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2838            tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2839        }
2840        opn = "msub";
2841        break;
2842    case OPC_MSUBU:
2843        {
2844            TCGv_i64 t2 = tcg_temp_new_i64();
2845            TCGv_i64 t3 = tcg_temp_new_i64();
2846
2847            tcg_gen_ext32u_tl(t0, t0);
2848            tcg_gen_ext32u_tl(t1, t1);
2849            tcg_gen_extu_tl_i64(t2, t0);
2850            tcg_gen_extu_tl_i64(t3, t1);
2851            tcg_gen_mul_i64(t2, t2, t3);
2852            tcg_gen_concat_tl_i64(t3, cpu_LO[acc], cpu_HI[acc]);
2853            tcg_gen_sub_i64(t2, t3, t2);
2854            tcg_temp_free_i64(t3);
2855            tcg_gen_trunc_i64_tl(t0, t2);
2856            tcg_gen_shri_i64(t2, t2, 32);
2857            tcg_gen_trunc_i64_tl(t1, t2);
2858            tcg_temp_free_i64(t2);
2859            tcg_gen_ext32s_tl(cpu_LO[acc], t0);
2860            tcg_gen_ext32s_tl(cpu_HI[acc], t1);
2861        }
2862        opn = "msubu";
2863        break;
2864    default:
2865        MIPS_INVAL(opn);
2866        generate_exception(ctx, EXCP_RI);
2867        goto out;
2868    }
2869    (void)opn; /* avoid a compiler warning */
2870    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2871 out:
2872    tcg_temp_free(t0);
2873    tcg_temp_free(t1);
2874}
2875
2876static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2877                            int rd, int rs, int rt)
2878{
2879    const char *opn = "mul vr54xx";
2880    TCGv t0 = tcg_temp_new();
2881    TCGv t1 = tcg_temp_new();
2882
2883    gen_load_gpr(t0, rs);
2884    gen_load_gpr(t1, rt);
2885
2886    switch (opc) {
2887    case OPC_VR54XX_MULS:
2888        gen_helper_muls(t0, cpu_env, t0, t1);
2889        opn = "muls";
2890        break;
2891    case OPC_VR54XX_MULSU:
2892        gen_helper_mulsu(t0, cpu_env, t0, t1);
2893        opn = "mulsu";
2894        break;
2895    case OPC_VR54XX_MACC:
2896        gen_helper_macc(t0, cpu_env, t0, t1);
2897        opn = "macc";
2898        break;
2899    case OPC_VR54XX_MACCU:
2900        gen_helper_maccu(t0, cpu_env, t0, t1);
2901        opn = "maccu";
2902        break;
2903    case OPC_VR54XX_MSAC:
2904        gen_helper_msac(t0, cpu_env, t0, t1);
2905        opn = "msac";
2906        break;
2907    case OPC_VR54XX_MSACU:
2908        gen_helper_msacu(t0, cpu_env, t0, t1);
2909        opn = "msacu";
2910        break;
2911    case OPC_VR54XX_MULHI:
2912        gen_helper_mulhi(t0, cpu_env, t0, t1);
2913        opn = "mulhi";
2914        break;
2915    case OPC_VR54XX_MULHIU:
2916        gen_helper_mulhiu(t0, cpu_env, t0, t1);
2917        opn = "mulhiu";
2918        break;
2919    case OPC_VR54XX_MULSHI:
2920        gen_helper_mulshi(t0, cpu_env, t0, t1);
2921        opn = "mulshi";
2922        break;
2923    case OPC_VR54XX_MULSHIU:
2924        gen_helper_mulshiu(t0, cpu_env, t0, t1);
2925        opn = "mulshiu";
2926        break;
2927    case OPC_VR54XX_MACCHI:
2928        gen_helper_macchi(t0, cpu_env, t0, t1);
2929        opn = "macchi";
2930        break;
2931    case OPC_VR54XX_MACCHIU:
2932        gen_helper_macchiu(t0, cpu_env, t0, t1);
2933        opn = "macchiu";
2934        break;
2935    case OPC_VR54XX_MSACHI:
2936        gen_helper_msachi(t0, cpu_env, t0, t1);
2937        opn = "msachi";
2938        break;
2939    case OPC_VR54XX_MSACHIU:
2940        gen_helper_msachiu(t0, cpu_env, t0, t1);
2941        opn = "msachiu";
2942        break;
2943    default:
2944        MIPS_INVAL("mul vr54xx");
2945        generate_exception(ctx, EXCP_RI);
2946        goto out;
2947    }
2948    gen_store_gpr(t0, rd);
2949    (void)opn; /* avoid a compiler warning */
2950    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2951
2952 out:
2953    tcg_temp_free(t0);
2954    tcg_temp_free(t1);
2955}
2956
2957static void gen_cl (DisasContext *ctx, uint32_t opc,
2958                    int rd, int rs)
2959{
2960    const char *opn = "CLx";
2961    TCGv t0;
2962
2963    if (rd == 0) {
2964        /* Treat as NOP. */
2965        MIPS_DEBUG("NOP");
2966        return;
2967    }
2968    t0 = tcg_temp_new();
2969    gen_load_gpr(t0, rs);
2970    switch (opc) {
2971    case OPC_CLO:
2972        gen_helper_clo(cpu_gpr[rd], t0);
2973        opn = "clo";
2974        break;
2975    case OPC_CLZ:
2976        gen_helper_clz(cpu_gpr[rd], t0);
2977        opn = "clz";
2978        break;
2979#if defined(TARGET_MIPS64)
2980    case OPC_DCLO:
2981        gen_helper_dclo(cpu_gpr[rd], t0);
2982        opn = "dclo";
2983        break;
2984    case OPC_DCLZ:
2985        gen_helper_dclz(cpu_gpr[rd], t0);
2986        opn = "dclz";
2987        break;
2988#endif
2989    }
2990    (void)opn; /* avoid a compiler warning */
2991    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2992    tcg_temp_free(t0);
2993}
2994
2995/* Godson integer instructions */
2996static void gen_loongson_integer(DisasContext *ctx, uint32_t opc,
2997                                 int rd, int rs, int rt)
2998{
2999    const char *opn = "loongson";
3000    TCGv t0, t1;
3001
3002    if (rd == 0) {
3003        /* Treat as NOP. */
3004        MIPS_DEBUG("NOP");
3005        return;
3006    }
3007
3008    switch (opc) {
3009    case OPC_MULT_G_2E:
3010    case OPC_MULT_G_2F:
3011    case OPC_MULTU_G_2E:
3012    case OPC_MULTU_G_2F:
3013#if defined(TARGET_MIPS64)
3014    case OPC_DMULT_G_2E:
3015    case OPC_DMULT_G_2F:
3016    case OPC_DMULTU_G_2E:
3017    case OPC_DMULTU_G_2F:
3018#endif
3019        t0 = tcg_temp_new();
3020        t1 = tcg_temp_new();
3021        break;
3022    default:
3023        t0 = tcg_temp_local_new();
3024        t1 = tcg_temp_local_new();
3025        break;
3026    }
3027
3028    gen_load_gpr(t0, rs);
3029    gen_load_gpr(t1, rt);
3030
3031    switch (opc) {
3032    case OPC_MULT_G_2E:
3033    case OPC_MULT_G_2F:
3034        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3035        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3036        opn = "mult.g";
3037        break;
3038    case OPC_MULTU_G_2E:
3039    case OPC_MULTU_G_2F:
3040        tcg_gen_ext32u_tl(t0, t0);
3041        tcg_gen_ext32u_tl(t1, t1);
3042        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3043        tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3044        opn = "multu.g";
3045        break;
3046    case OPC_DIV_G_2E:
3047    case OPC_DIV_G_2F:
3048        {
3049            int l1 = gen_new_label();
3050            int l2 = gen_new_label();
3051            int l3 = gen_new_label();
3052            tcg_gen_ext32s_tl(t0, t0);
3053            tcg_gen_ext32s_tl(t1, t1);
3054            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3055            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3056            tcg_gen_br(l3);
3057            gen_set_label(l1);
3058            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3059            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3060            tcg_gen_mov_tl(cpu_gpr[rd], t0);
3061            tcg_gen_br(l3);
3062            gen_set_label(l2);
3063            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3064            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3065            gen_set_label(l3);
3066        }
3067        opn = "div.g";
3068        break;
3069    case OPC_DIVU_G_2E:
3070    case OPC_DIVU_G_2F:
3071        {
3072            int l1 = gen_new_label();
3073            int l2 = gen_new_label();
3074            tcg_gen_ext32u_tl(t0, t0);
3075            tcg_gen_ext32u_tl(t1, t1);
3076            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3077            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3078            tcg_gen_br(l2);
3079            gen_set_label(l1);
3080            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3081            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3082            gen_set_label(l2);
3083        }
3084        opn = "divu.g";
3085        break;
3086    case OPC_MOD_G_2E:
3087    case OPC_MOD_G_2F:
3088        {
3089            int l1 = gen_new_label();
3090            int l2 = gen_new_label();
3091            int l3 = gen_new_label();
3092            tcg_gen_ext32u_tl(t0, t0);
3093            tcg_gen_ext32u_tl(t1, t1);
3094            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3095            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
3096            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
3097            gen_set_label(l1);
3098            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3099            tcg_gen_br(l3);
3100            gen_set_label(l2);
3101            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3102            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3103            gen_set_label(l3);
3104        }
3105        opn = "mod.g";
3106        break;
3107    case OPC_MODU_G_2E:
3108    case OPC_MODU_G_2F:
3109        {
3110            int l1 = gen_new_label();
3111            int l2 = gen_new_label();
3112            tcg_gen_ext32u_tl(t0, t0);
3113            tcg_gen_ext32u_tl(t1, t1);
3114            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3115            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3116            tcg_gen_br(l2);
3117            gen_set_label(l1);
3118            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3119            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
3120            gen_set_label(l2);
3121        }
3122        opn = "modu.g";
3123        break;
3124#if defined(TARGET_MIPS64)
3125    case OPC_DMULT_G_2E:
3126    case OPC_DMULT_G_2F:
3127        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3128        opn = "dmult.g";
3129        break;
3130    case OPC_DMULTU_G_2E:
3131    case OPC_DMULTU_G_2F:
3132        tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
3133        opn = "dmultu.g";
3134        break;
3135    case OPC_DDIV_G_2E:
3136    case OPC_DDIV_G_2F:
3137        {
3138            int l1 = gen_new_label();
3139            int l2 = gen_new_label();
3140            int l3 = gen_new_label();
3141            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3142            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3143            tcg_gen_br(l3);
3144            gen_set_label(l1);
3145            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3146            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3147            tcg_gen_mov_tl(cpu_gpr[rd], t0);
3148            tcg_gen_br(l3);
3149            gen_set_label(l2);
3150            tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
3151            gen_set_label(l3);
3152        }
3153        opn = "ddiv.g";
3154        break;
3155    case OPC_DDIVU_G_2E:
3156    case OPC_DDIVU_G_2F:
3157        {
3158            int l1 = gen_new_label();
3159            int l2 = gen_new_label();
3160            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3161            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3162            tcg_gen_br(l2);
3163            gen_set_label(l1);
3164            tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
3165            gen_set_label(l2);
3166        }
3167        opn = "ddivu.g";
3168        break;
3169    case OPC_DMOD_G_2E:
3170    case OPC_DMOD_G_2F:
3171        {
3172            int l1 = gen_new_label();
3173            int l2 = gen_new_label();
3174            int l3 = gen_new_label();
3175            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
3176            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
3177            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
3178            gen_set_label(l1);
3179            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3180            tcg_gen_br(l3);
3181            gen_set_label(l2);
3182            tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
3183            gen_set_label(l3);
3184        }
3185        opn = "dmod.g";
3186        break;
3187    case OPC_DMODU_G_2E:
3188    case OPC_DMODU_G_2F:
3189        {
3190            int l1 = gen_new_label();
3191            int l2 = gen_new_label();
3192            tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
3193            tcg_gen_movi_tl(cpu_gpr[rd], 0);
3194            tcg_gen_br(l2);
3195            gen_set_label(l1);
3196            tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
3197            gen_set_label(l2);
3198        }
3199        opn = "dmodu.g";
3200        break;
3201#endif
3202    }
3203
3204    (void)opn; /* avoid a compiler warning */
3205    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
3206    tcg_temp_free(t0);
3207    tcg_temp_free(t1);
3208}
3209
3210/* Loongson multimedia instructions */
3211static void gen_loongson_multimedia(DisasContext *ctx, int rd, int rs, int rt)
3212{
3213    const char *opn = "loongson_cp2";
3214    uint32_t opc, shift_max;
3215    TCGv_i64 t0, t1;
3216
3217    opc = MASK_LMI(ctx->opcode);
3218    switch (opc) {
3219    case OPC_ADD_CP2:
3220    case OPC_SUB_CP2:
3221    case OPC_DADD_CP2:
3222    case OPC_DSUB_CP2:
3223        t0 = tcg_temp_local_new_i64();
3224        t1 = tcg_temp_local_new_i64();
3225        break;
3226    default:
3227        t0 = tcg_temp_new_i64();
3228        t1 = tcg_temp_new_i64();
3229        break;
3230    }
3231
3232    gen_load_fpr64(ctx, t0, rs);
3233    gen_load_fpr64(ctx, t1, rt);
3234
3235#define LMI_HELPER(UP, LO) \
3236    case OPC_##UP: gen_helper_##LO(t0, t0, t1); opn = #LO; break
3237#define LMI_HELPER_1(UP, LO) \
3238    case OPC_##UP: gen_helper_##LO(t0, t0); opn = #LO; break
3239#define LMI_DIRECT(UP, LO, OP) \
3240    case OPC_##UP: tcg_gen_##OP##_i64(t0, t0, t1); opn = #LO; break
3241
3242    switch (opc) {
3243    LMI_HELPER(PADDSH, paddsh);
3244    LMI_HELPER(PADDUSH, paddush);
3245    LMI_HELPER(PADDH, paddh);
3246    LMI_HELPER(PADDW, paddw);
3247    LMI_HELPER(PADDSB, paddsb);
3248    LMI_HELPER(PADDUSB, paddusb);
3249    LMI_HELPER(PADDB, paddb);
3250
3251    LMI_HELPER(PSUBSH, psubsh);
3252    LMI_HELPER(PSUBUSH, psubush);
3253    LMI_HELPER(PSUBH, psubh);
3254    LMI_HELPER(PSUBW, psubw);
3255    LMI_HELPER(PSUBSB, psubsb);
3256    LMI_HELPER(PSUBUSB, psubusb);
3257    LMI_HELPER(PSUBB, psubb);
3258
3259    LMI_HELPER(PSHUFH, pshufh);
3260    LMI_HELPER(PACKSSWH, packsswh);
3261    LMI_HELPER(PACKSSHB, packsshb);
3262    LMI_HELPER(PACKUSHB, packushb);
3263
3264    LMI_HELPER(PUNPCKLHW, punpcklhw);
3265    LMI_HELPER(PUNPCKHHW, punpckhhw);
3266    LMI_HELPER(PUNPCKLBH, punpcklbh);
3267    LMI_HELPER(PUNPCKHBH, punpckhbh);
3268    LMI_HELPER(PUNPCKLWD, punpcklwd);
3269    LMI_HELPER(PUNPCKHWD, punpckhwd);
3270
3271    LMI_HELPER(PAVGH, pavgh);
3272    LMI_HELPER(PAVGB, pavgb);
3273    LMI_HELPER(PMAXSH, pmaxsh);
3274    LMI_HELPER(PMINSH, pminsh);
3275    LMI_HELPER(PMAXUB, pmaxub);
3276    LMI_HELPER(PMINUB, pminub);
3277
3278    LMI_HELPER(PCMPEQW, pcmpeqw);
3279    LMI_HELPER(PCMPGTW, pcmpgtw);
3280    LMI_HELPER(PCMPEQH, pcmpeqh);
3281    LMI_HELPER(PCMPGTH, pcmpgth);
3282    LMI_HELPER(PCMPEQB, pcmpeqb);
3283    LMI_HELPER(PCMPGTB, pcmpgtb);
3284
3285    LMI_HELPER(PSLLW, psllw);
3286    LMI_HELPER(PSLLH, psllh);
3287    LMI_HELPER(PSRLW, psrlw);
3288    LMI_HELPER(PSRLH, psrlh);
3289    LMI_HELPER(PSRAW, psraw);
3290    LMI_HELPER(PSRAH, psrah);
3291
3292    LMI_HELPER(PMULLH, pmullh);
3293    LMI_HELPER(PMULHH, pmulhh);
3294    LMI_HELPER(PMULHUH, pmulhuh);
3295    LMI_HELPER(PMADDHW, pmaddhw);
3296
3297    LMI_HELPER(PASUBUB, pasubub);
3298    LMI_HELPER_1(BIADD, biadd);
3299    LMI_HELPER_1(PMOVMSKB, pmovmskb);
3300
3301    LMI_DIRECT(PADDD, paddd, add);
3302    LMI_DIRECT(PSUBD, psubd, sub);
3303    LMI_DIRECT(XOR_CP2, xor, xor);
3304    LMI_DIRECT(NOR_CP2, nor, nor);
3305    LMI_DIRECT(AND_CP2, and, and);
3306    LMI_DIRECT(PANDN, pandn, andc);
3307    LMI_DIRECT(OR, or, or);
3308
3309    case OPC_PINSRH_0:
3310        tcg_gen_deposit_i64(t0, t0, t1, 0, 16);
3311        opn = "pinsrh_0";
3312        break;
3313    case OPC_PINSRH_1:
3314        tcg_gen_deposit_i64(t0, t0, t1, 16, 16);
3315        opn = "pinsrh_1";
3316        break;
3317    case OPC_PINSRH_2:
3318        tcg_gen_deposit_i64(t0, t0, t1, 32, 16);
3319        opn = "pinsrh_2";
3320        break;
3321    case OPC_PINSRH_3:
3322        tcg_gen_deposit_i64(t0, t0, t1, 48, 16);
3323        opn = "pinsrh_3";
3324        break;
3325
3326    case OPC_PEXTRH:
3327        tcg_gen_andi_i64(t1, t1, 3);
3328        tcg_gen_shli_i64(t1, t1, 4);
3329        tcg_gen_shr_i64(t0, t0, t1);
3330        tcg_gen_ext16u_i64(t0, t0);
3331        opn = "pextrh";
3332        break;
3333
3334    case OPC_ADDU_CP2:
3335        tcg_gen_add_i64(t0, t0, t1);
3336        tcg_gen_ext32s_i64(t0, t0);
3337        opn = "addu";
3338        break;
3339    case OPC_SUBU_CP2:
3340        tcg_gen_sub_i64(t0, t0, t1);
3341        tcg_gen_ext32s_i64(t0, t0);
3342        opn = "addu";
3343        break;
3344
3345    case OPC_SLL_CP2:
3346        opn = "sll";
3347        shift_max = 32;
3348        goto do_shift;
3349    case OPC_SRL_CP2:
3350        opn = "srl";
3351        shift_max = 32;
3352        goto do_shift;
3353    case OPC_SRA_CP2:
3354        opn = "sra";
3355        shift_max = 32;
3356        goto do_shift;
3357    case OPC_DSLL_CP2:
3358        opn = "dsll";
3359        shift_max = 64;
3360        goto do_shift;
3361    case OPC_DSRL_CP2:
3362        opn = "dsrl";
3363        shift_max = 64;
3364        goto do_shift;
3365    case OPC_DSRA_CP2:
3366        opn = "dsra";
3367        shift_max = 64;
3368        goto do_shift;
3369    do_shift:
3370        /* Make sure shift count isn't TCG undefined behaviour.  */
3371        tcg_gen_andi_i64(t1, t1, shift_max - 1);
3372
3373        switch (opc) {
3374        case OPC_SLL_CP2:
3375        case OPC_DSLL_CP2:
3376            tcg_gen_shl_i64(t0, t0, t1);
3377            break;
3378        case OPC_SRA_CP2:
3379        case OPC_DSRA_CP2:
3380            /* Since SRA is UndefinedResult without sign-extended inputs,
3381               we can treat SRA and DSRA the same.  */
3382            tcg_gen_sar_i64(t0, t0, t1);
3383            break;
3384        case OPC_SRL_CP2:
3385            /* We want to shift in zeros for SRL; zero-extend first.  */
3386            tcg_gen_ext32u_i64(t0, t0);
3387            /* FALLTHRU */
3388        case OPC_DSRL_CP2:
3389            tcg_gen_shr_i64(t0, t0, t1);
3390            break;
3391        }
3392
3393        if (shift_max == 32) {
3394            tcg_gen_ext32s_i64(t0, t0);
3395        }
3396
3397        /* Shifts larger than MAX produce zero.  */
3398        tcg_gen_setcondi_i64(TCG_COND_LTU, t1, t1, shift_max);
3399        tcg_gen_neg_i64(t1, t1);
3400        tcg_gen_and_i64(t0, t0, t1);
3401        break;
3402
3403    case OPC_ADD_CP2:
3404    case OPC_DADD_CP2:
3405        {
3406            TCGv_i64 t2 = tcg_temp_new_i64();
3407            int lab = gen_new_label();
3408
3409            tcg_gen_mov_i64(t2, t0);
3410            tcg_gen_add_i64(t0, t1, t2);
3411            if (opc == OPC_ADD_CP2) {
3412                tcg_gen_ext32s_i64(t0, t0);
3413            }
3414            tcg_gen_xor_i64(t1, t1, t2);
3415            tcg_gen_xor_i64(t2, t2, t0);
3416            tcg_gen_andc_i64(t1, t2, t1);
3417            tcg_temp_free_i64(t2);
3418            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3419            generate_exception(ctx, EXCP_OVERFLOW);
3420            gen_set_label(lab);
3421
3422            opn = (opc == OPC_ADD_CP2 ? "add" : "dadd");
3423            break;
3424        }
3425
3426    case OPC_SUB_CP2:
3427    case OPC_DSUB_CP2:
3428        {
3429            TCGv_i64 t2 = tcg_temp_new_i64();
3430            int lab = gen_new_label();
3431
3432            tcg_gen_mov_i64(t2, t0);
3433            tcg_gen_sub_i64(t0, t1, t2);
3434            if (opc == OPC_SUB_CP2) {
3435                tcg_gen_ext32s_i64(t0, t0);
3436            }
3437            tcg_gen_xor_i64(t1, t1, t2);
3438            tcg_gen_xor_i64(t2, t2, t0);
3439            tcg_gen_and_i64(t1, t1, t2);
3440            tcg_temp_free_i64(t2);
3441            tcg_gen_brcondi_i64(TCG_COND_GE, t1, 0, lab);
3442            generate_exception(ctx, EXCP_OVERFLOW);
3443            gen_set_label(lab);
3444
3445            opn = (opc == OPC_SUB_CP2 ? "sub" : "dsub");
3446            break;
3447        }
3448
3449    case OPC_PMULUW:
3450        tcg_gen_ext32u_i64(t0, t0);
3451        tcg_gen_ext32u_i64(t1, t1);
3452        tcg_gen_mul_i64(t0, t0, t1);
3453        opn = "pmuluw";
3454        break;
3455
3456    case OPC_SEQU_CP2:
3457    case OPC_SEQ_CP2:
3458    case OPC_SLTU_CP2:
3459    case OPC_SLT_CP2:
3460    case OPC_SLEU_CP2:
3461    case OPC_SLE_CP2:
3462        /* ??? Document is unclear: Set FCC[CC].  Does that mean the
3463           FD field is the CC field?  */
3464    default:
3465        MIPS_INVAL(opn);
3466        generate_exception(ctx, EXCP_RI);
3467        return;
3468    }
3469
3470#undef LMI_HELPER
3471#undef LMI_DIRECT
3472
3473    gen_store_fpr64(ctx, t0, rd);
3474
3475    (void)opn; /* avoid a compiler warning */
3476    MIPS_DEBUG("%s %s, %s, %s", opn,
3477               fregnames[rd], fregnames[rs], fregnames[rt]);
3478    tcg_temp_free_i64(t0);
3479    tcg_temp_free_i64(t1);
3480}
3481
3482/* Traps */
3483static void gen_trap (DisasContext *ctx, uint32_t opc,
3484                      int rs, int rt, int16_t imm)
3485{
3486    int cond;
3487    TCGv t0 = tcg_temp_new();
3488    TCGv t1 = tcg_temp_new();
3489
3490    cond = 0;
3491    /* Load needed operands */
3492    switch (opc) {
3493    case OPC_TEQ:
3494    case OPC_TGE:
3495    case OPC_TGEU:
3496    case OPC_TLT:
3497    case OPC_TLTU:
3498    case OPC_TNE:
3499        /* Compare two registers */
3500        if (rs != rt) {
3501            gen_load_gpr(t0, rs);
3502            gen_load_gpr(t1, rt);
3503            cond = 1;
3504        }
3505        break;
3506    case OPC_TEQI:
3507    case OPC_TGEI:
3508    case OPC_TGEIU:
3509    case OPC_TLTI:
3510    case OPC_TLTIU:
3511    case OPC_TNEI:
3512        /* Compare register to immediate */
3513        if (rs != 0 || imm != 0) {
3514            gen_load_gpr(t0, rs);
3515            tcg_gen_movi_tl(t1, (int32_t)imm);
3516            cond = 1;
3517        }
3518        break;
3519    }
3520    if (cond == 0) {
3521        switch (opc) {
3522        case OPC_TEQ:   /* rs == rs */
3523        case OPC_TEQI:  /* r0 == 0  */
3524        case OPC_TGE:   /* rs >= rs */
3525        case OPC_TGEI:  /* r0 >= 0  */
3526        case OPC_TGEU:  /* rs >= rs unsigned */
3527        case OPC_TGEIU: /* r0 >= 0  unsigned */
3528            /* Always trap */
3529            generate_exception(ctx, EXCP_TRAP);
3530            break;
3531        case OPC_TLT:   /* rs < rs           */
3532        case OPC_TLTI:  /* r0 < 0            */
3533        case OPC_TLTU:  /* rs < rs unsigned  */
3534        case OPC_TLTIU: /* r0 < 0  unsigned  */
3535        case OPC_TNE:   /* rs != rs          */
3536        case OPC_TNEI:  /* r0 != 0           */
3537            /* Never trap: treat as NOP. */
3538            break;
3539        }
3540    } else {
3541        int l1 = gen_new_label();
3542
3543        switch (opc) {
3544        case OPC_TEQ:
3545        case OPC_TEQI:
3546            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
3547            break;
3548        case OPC_TGE:
3549        case OPC_TGEI:
3550            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
3551            break;
3552        case OPC_TGEU:
3553        case OPC_TGEIU:
3554            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
3555            break;
3556        case OPC_TLT:
3557        case OPC_TLTI:
3558            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
3559            break;
3560        case OPC_TLTU:
3561        case OPC_TLTIU:
3562            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
3563            break;
3564        case OPC_TNE:
3565        case OPC_TNEI:
3566            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
3567            break;
3568        }
3569        generate_exception(ctx, EXCP_TRAP);
3570        gen_set_label(l1);
3571    }
3572    tcg_temp_free(t0);
3573    tcg_temp_free(t1);
3574}
3575
3576static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
3577{
3578    TranslationBlock *tb;
3579    tb = ctx->tb;
3580    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
3581        likely(!ctx->singlestep_enabled)) {
3582        tcg_gen_goto_tb(n);
3583        gen_save_pc(dest);
3584        tcg_gen_exit_tb((tcg_target_long)tb + n);
3585    } else {
3586        gen_save_pc(dest);
3587        if (ctx->singlestep_enabled) {
3588            save_cpu_state(ctx, 0);
3589            gen_helper_0e0i(raise_exception, EXCP_DEBUG);
3590        }
3591        tcg_gen_exit_tb(0);
3592    }
3593}
3594
3595/* Branches (before delay slot) */
3596static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
3597                                int insn_bytes,
3598                                int rs, int rt, int32_t offset)
3599{
3600    target_ulong btgt = -1;
3601    int blink = 0;
3602    int bcond_compute = 0;
3603    TCGv t0 = tcg_temp_new();
3604    TCGv t1 = tcg_temp_new();
3605
3606    if (ctx->hflags & MIPS_HFLAG_BMASK) {
3607#ifdef MIPS_DEBUG_DISAS
3608        LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
3609#endif
3610        generate_exception(ctx, EXCP_RI);
3611        goto out;
3612    }
3613
3614    /* Load needed operands */
3615    switch (opc) {
3616    case OPC_BEQ:
3617    case OPC_BEQL:
3618    case OPC_BNE:
3619    case OPC_BNEL:
3620        /* Compare two registers */
3621        if (rs != rt) {
3622            gen_load_gpr(t0, rs);
3623            gen_load_gpr(t1, rt);
3624            bcond_compute = 1;
3625        }
3626        btgt = ctx->pc + insn_bytes + offset;
3627        break;
3628    case OPC_BGEZ:
3629    case OPC_BGEZAL:
3630    case OPC_BGEZALS:
3631    case OPC_BGEZALL:
3632    case OPC_BGEZL:
3633    case OPC_BGTZ:
3634    case OPC_BGTZL:
3635    case OPC_BLEZ:
3636    case OPC_BLEZL:
3637    case OPC_BLTZ:
3638    case OPC_BLTZAL:
3639    case OPC_BLTZALS:
3640    case OPC_BLTZALL:
3641    case OPC_BLTZL:
3642        /* Compare to zero */
3643        if (rs != 0) {
3644            gen_load_gpr(t0, rs);
3645            bcond_compute = 1;
3646        }
3647        btgt = ctx->pc + insn_bytes + offset;
3648        break;
3649    case OPC_BPOSGE32:
3650#if defined(TARGET_MIPS64)
3651    case OPC_BPOSGE64:
3652        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x7F);
3653#else
3654        tcg_gen_andi_tl(t0, cpu_dspctrl, 0x3F);
3655#endif
3656        bcond_compute = 1;
3657        btgt = ctx->pc + insn_bytes + offset;
3658        break;
3659    case OPC_J:
3660    case OPC_JAL:
3661    case OPC_JALX:
3662    case OPC_JALS:
3663    case OPC_JALXS:
3664        /* Jump to immediate */
3665        btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
3666        break;
3667    case OPC_JR:
3668    case OPC_JALR:
3669    case OPC_JALRC:
3670    case OPC_JALRS:
3671        /* Jump to register */
3672        if (offset != 0 && offset != 16) {
3673            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
3674               others are reserved. */
3675            MIPS_INVAL("jump hint");
3676            generate_exception(ctx, EXCP_RI);
3677            goto out;
3678        }
3679        gen_load_gpr(btarget, rs);
3680        break;
3681    default:
3682        MIPS_INVAL("branch/jump");
3683        generate_exception(ctx, EXCP_RI);
3684        goto out;
3685    }
3686    if (bcond_compute == 0) {
3687        /* No condition to be computed */
3688        switch (opc) {
3689        case OPC_BEQ:     /* rx == rx        */
3690        case OPC_BEQL:    /* rx == rx likely */
3691        case OPC_BGEZ:    /* 0 >= 0          */
3692        case OPC_BGEZL:   /* 0 >= 0 likely   */
3693        case OPC_BLEZ:    /* 0 <= 0          */
3694        case OPC_BLEZL:   /* 0 <= 0 likely   */
3695            /* Always take */
3696            ctx->hflags |= MIPS_HFLAG_B;
3697            MIPS_DEBUG("balways");
3698            break;
3699        case OPC_BGEZALS:
3700        case OPC_BGEZAL:  /* 0 >= 0          */
3701        case OPC_BGEZALL: /* 0 >= 0 likely   */
3702            ctx->hflags |= (opc == OPC_BGEZALS
3703                            ? MIPS_HFLAG_BDS16
3704                            : MIPS_HFLAG_BDS32);
3705            /* Always take and link */
3706            blink = 31;
3707            ctx->hflags |= MIPS_HFLAG_B;
3708            MIPS_DEBUG("balways and link");
3709            break;
3710        case OPC_BNE:     /* rx != rx        */
3711        case OPC_BGTZ:    /* 0 > 0           */
3712        case OPC_BLTZ:    /* 0 < 0           */
3713            /* Treat as NOP. */
3714            MIPS_DEBUG("bnever (NOP)");
3715            goto out;
3716        case OPC_BLTZALS:
3717        case OPC_BLTZAL:  /* 0 < 0           */
3718            ctx->hflags |= (opc == OPC_BLTZALS
3719                            ? MIPS_HFLAG_BDS16
3720                            : MIPS_HFLAG_BDS32);
3721            /* Handle as an unconditional branch to get correct delay
3722               slot checking.  */
3723            blink = 31;
3724            btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
3725            ctx->hflags |= MIPS_HFLAG_B;
3726            MIPS_DEBUG("bnever and link");
3727            break;
3728        case OPC_BLTZALL: /* 0 < 0 likely */
3729            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
3730            /* Skip the instruction in the delay slot */
3731            MIPS_DEBUG("bnever, link and skip");
3732            ctx->pc += 4;
3733            goto out;
3734        case OPC_BNEL:    /* rx != rx likely */
3735        case OPC_BGTZL:   /* 0 > 0 likely */
3736        case OPC_BLTZL:   /* 0 < 0 likely */
3737            /* Skip the instruction in the delay slot */
3738            MIPS_DEBUG("bnever and skip");
3739            ctx->pc += 4;
3740            goto out;
3741        case OPC_J:
3742            ctx->hflags |= MIPS_HFLAG_B;
3743            MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
3744            break;
3745        case OPC_JALXS:
3746        case OPC_JALX:
3747            ctx->hflags |= MIPS_HFLAG_BX;
3748            /* Fallthrough */
3749        case OPC_JALS:
3750        case OPC_JAL:
3751            blink = 31;
3752            ctx->hflags |= MIPS_HFLAG_B;
3753            ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
3754                            ? MIPS_HFLAG_BDS16
3755                            : MIPS_HFLAG_BDS32);
3756            MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
3757            break;
3758        case OPC_JR:
3759            ctx->hflags |= MIPS_HFLAG_BR;
3760            if (insn_bytes == 4)
3761                ctx->hflags |= MIPS_HFLAG_BDS32;
3762            MIPS_DEBUG("jr %s", regnames[rs]);
3763            break;
3764        case OPC_JALRS:
3765        case OPC_JALR:
3766        case OPC_JALRC:
3767            blink = rt;
3768            ctx->hflags |= MIPS_HFLAG_BR;
3769            ctx->hflags |= (opc == OPC_JALRS
3770                            ? MIPS_HFLAG_BDS16
3771                            : MIPS_HFLAG_BDS32);
3772            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
3773            break;
3774        default:
3775            MIPS_INVAL("branch/jump");
3776            generate_exception(ctx, EXCP_RI);
3777            goto out;
3778        }
3779    } else {
3780        switch (opc) {
3781        case OPC_BEQ:
3782            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3783            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
3784                       regnames[rs], regnames[rt], btgt);
3785            goto not_likely;
3786        case OPC_BEQL:
3787            tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
3788            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
3789                       regnames[rs], regnames[rt], btgt);
3790            goto likely;
3791        case OPC_BNE:
3792            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3793            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
3794                       regnames[rs], regnames[rt], btgt);
3795            goto not_likely;
3796        case OPC_BNEL:
3797            tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
3798            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
3799                       regnames[rs], regnames[rt], btgt);
3800            goto likely;
3801        case OPC_BGEZ:
3802            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3803            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3804            goto not_likely;
3805        case OPC_BGEZL:
3806            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3807            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3808            goto likely;
3809        case OPC_BGEZALS:
3810        case OPC_BGEZAL:
3811            ctx->hflags |= (opc == OPC_BGEZALS
3812                            ? MIPS_HFLAG_BDS16
3813                            : MIPS_HFLAG_BDS32);
3814            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3815            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3816            blink = 31;
3817            goto not_likely;
3818        case OPC_BGEZALL:
3819            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
3820            blink = 31;
3821            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3822            goto likely;
3823        case OPC_BGTZ:
3824            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3825            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3826            goto not_likely;
3827        case OPC_BGTZL:
3828            tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
3829            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3830            goto likely;
3831        case OPC_BLEZ:
3832            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3833            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
3834            goto not_likely;
3835        case OPC_BLEZL:
3836            tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
3837            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3838            goto likely;
3839        case OPC_BLTZ:
3840            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3841            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
3842            goto not_likely;
3843        case OPC_BLTZL:
3844            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3845            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
3846            goto likely;
3847        case OPC_BPOSGE32:
3848            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 32);
3849            MIPS_DEBUG("bposge32 " TARGET_FMT_lx, btgt);
3850            goto not_likely;
3851#if defined(TARGET_MIPS64)
3852        case OPC_BPOSGE64:
3853            tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 64);
3854            MIPS_DEBUG("bposge64 " TARGET_FMT_lx, btgt);
3855            goto not_likely;
3856#endif
3857        case OPC_BLTZALS:
3858        case OPC_BLTZAL:
3859            ctx->hflags |= (opc == OPC_BLTZALS
3860                            ? MIPS_HFLAG_BDS16
3861                            : MIPS_HFLAG_BDS32);
3862            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3863            blink = 31;
3864            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
3865        not_likely:
3866            ctx->hflags |= MIPS_HFLAG_BC;
3867            break;
3868        case OPC_BLTZALL:
3869            tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
3870            blink = 31;
3871            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
3872        likely:
3873            ctx->hflags |= MIPS_HFLAG_BL;
3874            break;
3875        default:
3876            MIPS_INVAL("conditional branch/jump");
3877            generate_exception(ctx, EXCP_RI);
3878            goto out;
3879        }
3880    }
3881    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
3882               blink, ctx->hflags, btgt);
3883
3884    ctx->btarget = btgt;
3885    if (blink > 0) {
3886        int post_delay = insn_bytes;
3887        int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
3888
3889        if (opc != OPC_JALRC)
3890            post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
3891
3892        tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
3893    }
3894
3895 out:
3896    if (insn_bytes == 2)
3897        ctx->hflags |= MIPS_HFLAG_B16;
3898    tcg_temp_free(t0);
3899    tcg_temp_free(t1);
3900}
3901
3902/* special3 bitfield operations */
3903static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
3904                        int rs, int lsb, int msb)
3905{
3906    TCGv t0 = tcg_temp_new();
3907    TCGv t1 = tcg_temp_new();
3908
3909    gen_load_gpr(t1, rs);
3910    switch (opc) {
3911    case OPC_EXT:
3912        if (lsb + msb > 31)
3913            goto fail;
3914        tcg_gen_shri_tl(t0, t1, lsb);
3915        if (msb != 31) {
3916            tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
3917        } else {
3918            tcg_gen_ext32s_tl(t0, t0);
3919        }
3920        break;
3921#if defined(TARGET_MIPS64)
3922    case OPC_DEXTM:
3923        tcg_gen_shri_tl(t0, t1, lsb);
3924        if (msb != 31) {
3925            tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
3926        }
3927        break;
3928    case OPC_DEXTU:
3929        tcg_gen_shri_tl(t0, t1, lsb + 32);
3930        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3931        break;
3932    case OPC_DEXT:
3933        tcg_gen_shri_tl(t0, t1, lsb);
3934        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
3935        break;
3936#endif
3937    case OPC_INS:
3938        if (lsb > msb)
3939            goto fail;
3940        gen_load_gpr(t0, rt);
3941        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
3942        tcg_gen_ext32s_tl(t0, t0);
3943        break;
3944#if defined(TARGET_MIPS64)
3945    case OPC_DINSM:
3946        gen_load_gpr(t0, rt);
3947        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb + 32 - lsb + 1);
3948        break;
3949    case OPC_DINSU:
3950        gen_load_gpr(t0, rt);
3951        tcg_gen_deposit_tl(t0, t0, t1, lsb + 32, msb - lsb + 1);
3952        break;
3953    case OPC_DINS:
3954        gen_load_gpr(t0, rt);
3955        tcg_gen_deposit_tl(t0, t0, t1, lsb, msb - lsb + 1);
3956        break;
3957#endif
3958    default:
3959fail:
3960        MIPS_INVAL("bitops");
3961        generate_exception(ctx, EXCP_RI);
3962        tcg_temp_free(t0);
3963        tcg_temp_free(t1);
3964        return;
3965    }
3966    gen_store_gpr(t0, rt);
3967    tcg_temp_free(t0);
3968    tcg_temp_free(t1);
3969}
3970
3971static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
3972{
3973    TCGv t0;
3974
3975    if (rd == 0) {
3976        /* If no destination, treat it as a NOP. */
3977        MIPS_DEBUG("NOP");
3978        return;
3979    }
3980
3981    t0 = tcg_temp_new();
3982    gen_load_gpr(t0, rt);
3983    switch (op2) {
3984    case OPC_WSBH:
3985        {
3986            TCGv t1 = tcg_temp_new();
3987
3988            tcg_gen_shri_tl(t1, t0, 8);
3989            tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
3990            tcg_gen_shli_tl(t0, t0, 8);
3991            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
3992            tcg_gen_or_tl(t0, t0, t1);
3993            tcg_temp_free(t1);
3994            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
3995        }
3996        break;
3997    case OPC_SEB:
3998        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
3999        break;
4000    case OPC_SEH:
4001        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
4002        break;
4003#if defined(TARGET_MIPS64)
4004    case OPC_DSBH:
4005        {
4006            TCGv t1 = tcg_temp_new();
4007
4008            tcg_gen_shri_tl(t1, t0, 8);
4009            tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
4010            tcg_gen_shli_tl(t0, t0, 8);
4011            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
4012            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4013            tcg_temp_free(t1);
4014        }
4015        break;
4016    case OPC_DSHD:
4017        {
4018            TCGv t1 = tcg_temp_new();
4019
4020            tcg_gen_shri_tl(t1, t0, 16);
4021            tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
4022            tcg_gen_shli_tl(t0, t0, 16);
4023            tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
4024            tcg_gen_or_tl(t0, t0, t1);
4025            tcg_gen_shri_tl(t1, t0, 32);
4026            tcg_gen_shli_tl(t0, t0, 32);
4027            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
4028            tcg_temp_free(t1);
4029        }
4030        break;
4031#endif
4032    default:
4033        MIPS_INVAL("bsfhl");
4034        generate_exception(ctx, EXCP_RI);
4035        tcg_temp_free(t0);
4036        return;
4037    }
4038    tcg_temp_free(t0);
4039}
4040
4041#ifndef CONFIG_USER_ONLY
4042/* CP0 (MMU and control) */
4043static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
4044{
4045    TCGv_i32 t0 = tcg_temp_new_i32();
4046
4047    tcg_gen_ld_i32(t0, cpu_env, off);
4048    tcg_gen_ext_i32_tl(arg, t0);
4049    tcg_temp_free_i32(t0);
4050}
4051
4052static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
4053{
4054    tcg_gen_ld_tl(arg, cpu_env, off);
4055    tcg_gen_ext32s_tl(arg, arg);
4056}
4057
4058static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
4059{
4060    TCGv_i32 t0 = tcg_temp_new_i32();
4061
4062    tcg_gen_trunc_tl_i32(t0, arg);
4063    tcg_gen_st_i32(t0, cpu_env, off);
4064    tcg_temp_free_i32(t0);
4065}
4066
4067static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
4068{
4069    tcg_gen_ext32s_tl(arg, arg);
4070    tcg_gen_st_tl(arg, cpu_env, off);
4071}
4072
4073static void gen_mfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4074{
4075    const char *rn = "invalid";
4076
4077    if (sel != 0)
4078        check_insn(ctx, ISA_MIPS32);
4079
4080    switch (reg) {
4081    case 0:
4082        switch (sel) {
4083        case 0:
4084            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
4085            rn = "Index";
4086            break;
4087        case 1:
4088            check_insn(ctx, ASE_MT);
4089            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
4090            rn = "MVPControl";
4091            break;
4092        case 2:
4093            check_insn(ctx, ASE_MT);
4094            gen_helper_mfc0_mvpconf0(arg, cpu_env);
4095            rn = "MVPConf0";
4096            break;
4097        case 3:
4098            check_insn(ctx, ASE_MT);
4099            gen_helper_mfc0_mvpconf1(arg, cpu_env);
4100            rn = "MVPConf1";
4101            break;
4102        default:
4103            goto die;
4104        }
4105        break;
4106    case 1:
4107        switch (sel) {
4108        case 0:
4109            gen_helper_mfc0_random(arg, cpu_env);
4110            rn = "Random";
4111            break;
4112        case 1:
4113            check_insn(ctx, ASE_MT);
4114            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
4115            rn = "VPEControl";
4116            break;
4117        case 2:
4118            check_insn(ctx, ASE_MT);
4119            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
4120            rn = "VPEConf0";
4121            break;
4122        case 3:
4123            check_insn(ctx, ASE_MT);
4124            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
4125            rn = "VPEConf1";
4126            break;
4127        case 4:
4128            check_insn(ctx, ASE_MT);
4129            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
4130            rn = "YQMask";
4131            break;
4132        case 5:
4133            check_insn(ctx, ASE_MT);
4134            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4135            rn = "VPESchedule";
4136            break;
4137        case 6:
4138            check_insn(ctx, ASE_MT);
4139            gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4140            rn = "VPEScheFBack";
4141            break;
4142        case 7:
4143            check_insn(ctx, ASE_MT);
4144            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
4145            rn = "VPEOpt";
4146            break;
4147        default:
4148            goto die;
4149        }
4150        break;
4151    case 2:
4152        switch (sel) {
4153        case 0:
4154            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
4155            tcg_gen_ext32s_tl(arg, arg);
4156            rn = "EntryLo0";
4157            break;
4158        case 1:
4159            check_insn(ctx, ASE_MT);
4160            gen_helper_mfc0_tcstatus(arg, cpu_env);
4161            rn = "TCStatus";
4162            break;
4163        case 2:
4164            check_insn(ctx, ASE_MT);
4165            gen_helper_mfc0_tcbind(arg, cpu_env);
4166            rn = "TCBind";
4167            break;
4168        case 3:
4169            check_insn(ctx, ASE_MT);
4170            gen_helper_mfc0_tcrestart(arg, cpu_env);
4171            rn = "TCRestart";
4172            break;
4173        case 4:
4174            check_insn(ctx, ASE_MT);
4175            gen_helper_mfc0_tchalt(arg, cpu_env);
4176            rn = "TCHalt";
4177            break;
4178        case 5:
4179            check_insn(ctx, ASE_MT);
4180            gen_helper_mfc0_tccontext(arg, cpu_env);
4181            rn = "TCContext";
4182            break;
4183        case 6:
4184            check_insn(ctx, ASE_MT);
4185            gen_helper_mfc0_tcschedule(arg, cpu_env);
4186            rn = "TCSchedule";
4187            break;
4188        case 7:
4189            check_insn(ctx, ASE_MT);
4190            gen_helper_mfc0_tcschefback(arg, cpu_env);
4191            rn = "TCScheFBack";
4192            break;
4193        default:
4194            goto die;
4195        }
4196        break;
4197    case 3:
4198        switch (sel) {
4199        case 0:
4200            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
4201            tcg_gen_ext32s_tl(arg, arg);
4202            rn = "EntryLo1";
4203            break;
4204        default:
4205            goto die;
4206        }
4207        break;
4208    case 4:
4209        switch (sel) {
4210        case 0:
4211            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
4212            tcg_gen_ext32s_tl(arg, arg);
4213            rn = "Context";
4214            break;
4215        case 1:
4216//            gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
4217            rn = "ContextConfig";
4218//            break;
4219        default:
4220            goto die;
4221        }
4222        break;
4223    case 5:
4224        switch (sel) {
4225        case 0:
4226            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
4227            rn = "PageMask";
4228            break;
4229        case 1:
4230            check_insn(ctx, ISA_MIPS32R2);
4231            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
4232            rn = "PageGrain";
4233            break;
4234        default:
4235            goto die;
4236        }
4237        break;
4238    case 6:
4239        switch (sel) {
4240        case 0:
4241            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
4242            rn = "Wired";
4243            break;
4244        case 1:
4245            check_insn(ctx, ISA_MIPS32R2);
4246            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
4247            rn = "SRSConf0";
4248            break;
4249        case 2:
4250            check_insn(ctx, ISA_MIPS32R2);
4251            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
4252            rn = "SRSConf1";
4253            break;
4254        case 3:
4255            check_insn(ctx, ISA_MIPS32R2);
4256            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
4257            rn = "SRSConf2";
4258            break;
4259        case 4:
4260            check_insn(ctx, ISA_MIPS32R2);
4261            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
4262            rn = "SRSConf3";
4263            break;
4264        case 5:
4265            check_insn(ctx, ISA_MIPS32R2);
4266            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
4267            rn = "SRSConf4";
4268            break;
4269        default:
4270            goto die;
4271        }
4272        break;
4273    case 7:
4274        switch (sel) {
4275        case 0:
4276            check_insn(ctx, ISA_MIPS32R2);
4277            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
4278            rn = "HWREna";
4279            break;
4280        default:
4281            goto die;
4282        }
4283        break;
4284    case 8:
4285        switch (sel) {
4286        case 0:
4287            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
4288            tcg_gen_ext32s_tl(arg, arg);
4289            rn = "BadVAddr";
4290            break;
4291        default:
4292            goto die;
4293       }
4294        break;
4295    case 9:
4296        switch (sel) {
4297        case 0:
4298            /* Mark as an IO operation because we read the time.  */
4299            if (use_icount)
4300                gen_io_start();
4301            gen_helper_mfc0_count(arg, cpu_env);
4302            if (use_icount) {
4303                gen_io_end();
4304            }
4305            /* Break the TB to be able to take timer interrupts immediately
4306               after reading count.  */
4307            ctx->bstate = BS_STOP;
4308            rn = "Count";
4309            break;
4310        /* 6,7 are implementation dependent */
4311        default:
4312            goto die;
4313        }
4314        break;
4315    case 10:
4316        switch (sel) {
4317        case 0:
4318            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
4319            tcg_gen_ext32s_tl(arg, arg);
4320            rn = "EntryHi";
4321            break;
4322        default:
4323            goto die;
4324        }
4325        break;
4326    case 11:
4327        switch (sel) {
4328        case 0:
4329            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
4330            rn = "Compare";
4331            break;
4332        /* 6,7 are implementation dependent */
4333        default:
4334            goto die;
4335        }
4336        break;
4337    case 12:
4338        switch (sel) {
4339        case 0:
4340            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
4341            rn = "Status";
4342            break;
4343        case 1:
4344            check_insn(ctx, ISA_MIPS32R2);
4345            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
4346            rn = "IntCtl";
4347            break;
4348        case 2:
4349            check_insn(ctx, ISA_MIPS32R2);
4350            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
4351            rn = "SRSCtl";
4352            break;
4353        case 3:
4354            check_insn(ctx, ISA_MIPS32R2);
4355            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4356            rn = "SRSMap";
4357            break;
4358        default:
4359            goto die;
4360       }
4361        break;
4362    case 13:
4363        switch (sel) {
4364        case 0:
4365            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
4366            rn = "Cause";
4367            break;
4368        default:
4369            goto die;
4370       }
4371        break;
4372    case 14:
4373        switch (sel) {
4374        case 0:
4375            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
4376            tcg_gen_ext32s_tl(arg, arg);
4377            rn = "EPC";
4378            break;
4379        default:
4380            goto die;
4381        }
4382        break;
4383    case 15:
4384        switch (sel) {
4385        case 0:
4386            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
4387            rn = "PRid";
4388            break;
4389        case 1:
4390            check_insn(ctx, ISA_MIPS32R2);
4391            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
4392            rn = "EBase";
4393            break;
4394        default:
4395            goto die;
4396       }
4397        break;
4398    case 16:
4399        switch (sel) {
4400        case 0:
4401            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
4402            rn = "Config";
4403            break;
4404        case 1:
4405            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
4406            rn = "Config1";
4407            break;
4408        case 2:
4409            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
4410            rn = "Config2";
4411            break;
4412        case 3:
4413            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
4414            rn = "Config3";
4415            break;
4416        /* 4,5 are reserved */
4417        /* 6,7 are implementation dependent */
4418        case 6:
4419            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
4420            rn = "Config6";
4421            break;
4422        case 7:
4423            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
4424            rn = "Config7";
4425            break;
4426        default:
4427            goto die;
4428        }
4429        break;
4430    case 17:
4431        switch (sel) {
4432        case 0:
4433            gen_helper_mfc0_lladdr(arg, cpu_env);
4434            rn = "LLAddr";
4435            break;
4436        default:
4437            goto die;
4438        }
4439        break;
4440    case 18:
4441        switch (sel) {
4442        case 0 ... 7:
4443            gen_helper_1e0i(mfc0_watchlo, arg, sel);
4444            rn = "WatchLo";
4445            break;
4446        default:
4447            goto die;
4448        }
4449        break;
4450    case 19:
4451        switch (sel) {
4452        case 0 ...7:
4453            gen_helper_1e0i(mfc0_watchhi, arg, sel);
4454            rn = "WatchHi";
4455            break;
4456        default:
4457            goto die;
4458        }
4459        break;
4460    case 20:
4461        switch (sel) {
4462        case 0:
4463#if defined(TARGET_MIPS64)
4464            check_insn(ctx, ISA_MIPS3);
4465            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
4466            tcg_gen_ext32s_tl(arg, arg);
4467            rn = "XContext";
4468            break;
4469#endif
4470        default:
4471            goto die;
4472        }
4473        break;
4474    case 21:
4475       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4476        switch (sel) {
4477        case 0:
4478            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
4479            rn = "Framemask";
4480            break;
4481        default:
4482            goto die;
4483        }
4484        break;
4485    case 22:
4486        tcg_gen_movi_tl(arg, 0); /* unimplemented */
4487        rn = "'Diagnostic"; /* implementation dependent */
4488        break;
4489    case 23:
4490        switch (sel) {
4491        case 0:
4492            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
4493            rn = "Debug";
4494            break;
4495        case 1:
4496//            gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
4497            rn = "TraceControl";
4498//            break;
4499        case 2:
4500//            gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
4501            rn = "TraceControl2";
4502//            break;
4503        case 3:
4504//            gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
4505            rn = "UserTraceData";
4506//            break;
4507        case 4:
4508//            gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
4509            rn = "TraceBPC";
4510//            break;
4511        default:
4512            goto die;
4513        }
4514        break;
4515    case 24:
4516        switch (sel) {
4517        case 0:
4518            /* EJTAG support */
4519            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
4520            tcg_gen_ext32s_tl(arg, arg);
4521            rn = "DEPC";
4522            break;
4523        default:
4524            goto die;
4525        }
4526        break;
4527    case 25:
4528        switch (sel) {
4529        case 0:
4530            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
4531            rn = "Performance0";
4532            break;
4533        case 1:
4534//            gen_helper_mfc0_performance1(arg);
4535            rn = "Performance1";
4536//            break;
4537        case 2:
4538//            gen_helper_mfc0_performance2(arg);
4539            rn = "Performance2";
4540//            break;
4541        case 3:
4542//            gen_helper_mfc0_performance3(arg);
4543            rn = "Performance3";
4544//            break;
4545        case 4:
4546//            gen_helper_mfc0_performance4(arg);
4547            rn = "Performance4";
4548//            break;
4549        case 5:
4550//            gen_helper_mfc0_performance5(arg);
4551            rn = "Performance5";
4552//            break;
4553        case 6:
4554//            gen_helper_mfc0_performance6(arg);
4555            rn = "Performance6";
4556//            break;
4557        case 7:
4558//            gen_helper_mfc0_performance7(arg);
4559            rn = "Performance7";
4560//            break;
4561        default:
4562            goto die;
4563        }
4564        break;
4565    case 26:
4566        tcg_gen_movi_tl(arg, 0); /* unimplemented */
4567        rn = "ECC";
4568        break;
4569    case 27:
4570        switch (sel) {
4571        case 0 ... 3:
4572            tcg_gen_movi_tl(arg, 0); /* unimplemented */
4573            rn = "CacheErr";
4574            break;
4575        default:
4576            goto die;
4577        }
4578        break;
4579    case 28:
4580        switch (sel) {
4581        case 0:
4582        case 2:
4583        case 4:
4584        case 6:
4585            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
4586            rn = "TagLo";
4587            break;
4588        case 1:
4589        case 3:
4590        case 5:
4591        case 7:
4592            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
4593            rn = "DataLo";
4594            break;
4595        default:
4596            goto die;
4597        }
4598        break;
4599    case 29:
4600        switch (sel) {
4601        case 0:
4602        case 2:
4603        case 4:
4604        case 6:
4605            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
4606            rn = "TagHi";
4607            break;
4608        case 1:
4609        case 3:
4610        case 5:
4611        case 7:
4612            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
4613            rn = "DataHi";
4614            break;
4615        default:
4616            goto die;
4617        }
4618        break;
4619    case 30:
4620        switch (sel) {
4621        case 0:
4622            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
4623            tcg_gen_ext32s_tl(arg, arg);
4624            rn = "ErrorEPC";
4625            break;
4626        default:
4627            goto die;
4628        }
4629        break;
4630    case 31:
4631        switch (sel) {
4632        case 0:
4633            /* EJTAG support */
4634            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
4635            rn = "DESAVE";
4636            break;
4637        default:
4638            goto die;
4639        }
4640        break;
4641    default:
4642       goto die;
4643    }
4644    (void)rn; /* avoid a compiler warning */
4645    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4646    return;
4647
4648die:
4649    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4650    generate_exception(ctx, EXCP_RI);
4651}
4652
4653static void gen_mtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
4654{
4655    const char *rn = "invalid";
4656
4657    if (sel != 0)
4658        check_insn(ctx, ISA_MIPS32);
4659
4660    if (use_icount)
4661        gen_io_start();
4662
4663    switch (reg) {
4664    case 0:
4665        switch (sel) {
4666        case 0:
4667            gen_helper_mtc0_index(cpu_env, arg);
4668            rn = "Index";
4669            break;
4670        case 1:
4671            check_insn(ctx, ASE_MT);
4672            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
4673            rn = "MVPControl";
4674            break;
4675        case 2:
4676            check_insn(ctx, ASE_MT);
4677            /* ignored */
4678            rn = "MVPConf0";
4679            break;
4680        case 3:
4681            check_insn(ctx, ASE_MT);
4682            /* ignored */
4683            rn = "MVPConf1";
4684            break;
4685        default:
4686            goto die;
4687        }
4688        break;
4689    case 1:
4690        switch (sel) {
4691        case 0:
4692            /* ignored */
4693            rn = "Random";
4694            break;
4695        case 1:
4696            check_insn(ctx, ASE_MT);
4697            gen_helper_mtc0_vpecontrol(cpu_env, arg);
4698            rn = "VPEControl";
4699            break;
4700        case 2:
4701            check_insn(ctx, ASE_MT);
4702            gen_helper_mtc0_vpeconf0(cpu_env, arg);
4703            rn = "VPEConf0";
4704            break;
4705        case 3:
4706            check_insn(ctx, ASE_MT);
4707            gen_helper_mtc0_vpeconf1(cpu_env, arg);
4708            rn = "VPEConf1";
4709            break;
4710        case 4:
4711            check_insn(ctx, ASE_MT);
4712            gen_helper_mtc0_yqmask(cpu_env, arg);
4713            rn = "YQMask";
4714            break;
4715        case 5:
4716            check_insn(ctx, ASE_MT);
4717            gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
4718            rn = "VPESchedule";
4719            break;
4720        case 6:
4721            check_insn(ctx, ASE_MT);
4722            gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
4723            rn = "VPEScheFBack";
4724            break;
4725        case 7:
4726            check_insn(ctx, ASE_MT);
4727            gen_helper_mtc0_vpeopt(cpu_env, arg);
4728            rn = "VPEOpt";
4729            break;
4730        default:
4731            goto die;
4732        }
4733        break;
4734    case 2:
4735        switch (sel) {
4736        case 0:
4737            gen_helper_mtc0_entrylo0(cpu_env, arg);
4738            rn = "EntryLo0";
4739            break;
4740        case 1:
4741            check_insn(ctx, ASE_MT);
4742            gen_helper_mtc0_tcstatus(cpu_env, arg);
4743            rn = "TCStatus";
4744            break;
4745        case 2:
4746            check_insn(ctx, ASE_MT);
4747            gen_helper_mtc0_tcbind(cpu_env, arg);
4748            rn = "TCBind";
4749            break;
4750        case 3:
4751            check_insn(ctx, ASE_MT);
4752            gen_helper_mtc0_tcrestart(cpu_env, arg);
4753            rn = "TCRestart";
4754            break;
4755        case 4:
4756            check_insn(ctx, ASE_MT);
4757            gen_helper_mtc0_tchalt(cpu_env, arg);
4758            rn = "TCHalt";
4759            break;
4760        case 5:
4761            check_insn(ctx, ASE_MT);
4762            gen_helper_mtc0_tccontext(cpu_env, arg);
4763            rn = "TCContext";
4764            break;
4765        case 6:
4766            check_insn(ctx, ASE_MT);
4767            gen_helper_mtc0_tcschedule(cpu_env, arg);
4768            rn = "TCSchedule";
4769            break;
4770        case 7:
4771            check_insn(ctx, ASE_MT);
4772            gen_helper_mtc0_tcschefback(cpu_env, arg);
4773            rn = "TCScheFBack";
4774            break;
4775        default:
4776            goto die;
4777        }
4778        break;
4779    case 3:
4780        switch (sel) {
4781        case 0:
4782            gen_helper_mtc0_entrylo1(cpu_env, arg);
4783            rn = "EntryLo1";
4784            break;
4785        default:
4786            goto die;
4787        }
4788        break;
4789    case 4:
4790        switch (sel) {
4791        case 0:
4792            gen_helper_mtc0_context(cpu_env, arg);
4793            rn = "Context";
4794            break;
4795        case 1:
4796//            gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
4797            rn = "ContextConfig";
4798//            break;
4799        default:
4800            goto die;
4801        }
4802        break;
4803    case 5:
4804        switch (sel) {
4805        case 0:
4806            gen_helper_mtc0_pagemask(cpu_env, arg);
4807            rn = "PageMask";
4808            break;
4809        case 1:
4810            check_insn(ctx, ISA_MIPS32R2);
4811            gen_helper_mtc0_pagegrain(cpu_env, arg);
4812            rn = "PageGrain";
4813            break;
4814        default:
4815            goto die;
4816        }
4817        break;
4818    case 6:
4819        switch (sel) {
4820        case 0:
4821            gen_helper_mtc0_wired(cpu_env, arg);
4822            rn = "Wired";
4823            break;
4824        case 1:
4825            check_insn(ctx, ISA_MIPS32R2);
4826            gen_helper_mtc0_srsconf0(cpu_env, arg);
4827            rn = "SRSConf0";
4828            break;
4829        case 2:
4830            check_insn(ctx, ISA_MIPS32R2);
4831            gen_helper_mtc0_srsconf1(cpu_env, arg);
4832            rn = "SRSConf1";
4833            break;
4834        case 3:
4835            check_insn(ctx, ISA_MIPS32R2);
4836            gen_helper_mtc0_srsconf2(cpu_env, arg);
4837            rn = "SRSConf2";
4838            break;
4839        case 4:
4840            check_insn(ctx, ISA_MIPS32R2);
4841            gen_helper_mtc0_srsconf3(cpu_env, arg);
4842            rn = "SRSConf3";
4843            break;
4844        case 5:
4845            check_insn(ctx, ISA_MIPS32R2);
4846            gen_helper_mtc0_srsconf4(cpu_env, arg);
4847            rn = "SRSConf4";
4848            break;
4849        default:
4850            goto die;
4851        }
4852        break;
4853    case 7:
4854        switch (sel) {
4855        case 0:
4856            check_insn(ctx, ISA_MIPS32R2);
4857            gen_helper_mtc0_hwrena(cpu_env, arg);
4858            rn = "HWREna";
4859            break;
4860        default:
4861            goto die;
4862        }
4863        break;
4864    case 8:
4865        /* ignored */
4866        rn = "BadVAddr";
4867        break;
4868    case 9:
4869        switch (sel) {
4870        case 0:
4871            gen_helper_mtc0_count(cpu_env, arg);
4872            rn = "Count";
4873            break;
4874        /* 6,7 are implementation dependent */
4875        default:
4876            goto die;
4877        }
4878        break;
4879    case 10:
4880        switch (sel) {
4881        case 0:
4882            gen_helper_mtc0_entryhi(cpu_env, arg);
4883            rn = "EntryHi";
4884            break;
4885        default:
4886            goto die;
4887        }
4888        break;
4889    case 11:
4890        switch (sel) {
4891        case 0:
4892            gen_helper_mtc0_compare(cpu_env, arg);
4893            rn = "Compare";
4894            break;
4895        /* 6,7 are implementation dependent */
4896        default:
4897            goto die;
4898        }
4899        break;
4900    case 12:
4901        switch (sel) {
4902        case 0:
4903            save_cpu_state(ctx, 1);
4904            gen_helper_mtc0_status(cpu_env, arg);
4905            /* BS_STOP isn't good enough here, hflags may have changed. */
4906            gen_save_pc(ctx->pc + 4);
4907            ctx->bstate = BS_EXCP;
4908            rn = "Status";
4909            break;
4910        case 1:
4911            check_insn(ctx, ISA_MIPS32R2);
4912            gen_helper_mtc0_intctl(cpu_env, arg);
4913            /* Stop translation as we may have switched the execution mode */
4914            ctx->bstate = BS_STOP;
4915            rn = "IntCtl";
4916            break;
4917        case 2:
4918            check_insn(ctx, ISA_MIPS32R2);
4919            gen_helper_mtc0_srsctl(cpu_env, arg);
4920            /* Stop translation as we may have switched the execution mode */
4921            ctx->bstate = BS_STOP;
4922            rn = "SRSCtl";
4923            break;
4924        case 3:
4925            check_insn(ctx, ISA_MIPS32R2);
4926            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
4927            /* Stop translation as we may have switched the execution mode */
4928            ctx->bstate = BS_STOP;
4929            rn = "SRSMap";
4930            break;
4931        default:
4932            goto die;
4933        }
4934        break;
4935    case 13:
4936        switch (sel) {
4937        case 0:
4938            save_cpu_state(ctx, 1);
4939            gen_helper_mtc0_cause(cpu_env, arg);
4940            rn = "Cause";
4941            break;
4942        default:
4943            goto die;
4944        }
4945        break;
4946    case 14:
4947        switch (sel) {
4948        case 0:
4949            gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
4950            rn = "EPC";
4951            break;
4952        default:
4953            goto die;
4954        }
4955        break;
4956    case 15:
4957        switch (sel) {
4958        case 0:
4959            /* ignored */
4960            rn = "PRid";
4961            break;
4962        case 1:
4963            check_insn(ctx, ISA_MIPS32R2);
4964            gen_helper_mtc0_ebase(cpu_env, arg);
4965            rn = "EBase";
4966            break;
4967        default:
4968            goto die;
4969        }
4970        break;
4971    case 16:
4972        switch (sel) {
4973        case 0:
4974            gen_helper_mtc0_config0(cpu_env, arg);
4975            rn = "Config";
4976            /* Stop translation as we may have switched the execution mode */
4977            ctx->bstate = BS_STOP;
4978            break;
4979        case 1:
4980            /* ignored, read only */
4981            rn = "Config1";
4982            break;
4983        case 2:
4984            gen_helper_mtc0_config2(cpu_env, arg);
4985            rn = "Config2";
4986            /* Stop translation as we may have switched the execution mode */
4987            ctx->bstate = BS_STOP;
4988            break;
4989        case 3:
4990            /* ignored, read only */
4991            rn = "Config3";
4992            break;
4993        /* 4,5 are reserved */
4994        /* 6,7 are implementation dependent */
4995        case 6:
4996            /* ignored */
4997            rn = "Config6";
4998            break;
4999        case 7:
5000            /* ignored */
5001            rn = "Config7";
5002            break;
5003        default:
5004            rn = "Invalid config selector";
5005            goto die;
5006        }
5007        break;
5008    case 17:
5009        switch (sel) {
5010        case 0:
5011            gen_helper_mtc0_lladdr(cpu_env, arg);
5012            rn = "LLAddr";
5013            break;
5014        default:
5015            goto die;
5016        }
5017        break;
5018    case 18:
5019        switch (sel) {
5020        case 0 ... 7:
5021            gen_helper_0e1i(mtc0_watchlo, arg, sel);
5022            rn = "WatchLo";
5023            break;
5024        default:
5025            goto die;
5026        }
5027        break;
5028    case 19:
5029        switch (sel) {
5030        case 0 ... 7:
5031            gen_helper_0e1i(mtc0_watchhi, arg, sel);
5032            rn = "WatchHi";
5033            break;
5034        default:
5035            goto die;
5036        }
5037        break;
5038    case 20:
5039        switch (sel) {
5040        case 0:
5041#if defined(TARGET_MIPS64)
5042            check_insn(ctx, ISA_MIPS3);
5043            gen_helper_mtc0_xcontext(cpu_env, arg);
5044            rn = "XContext";
5045            break;
5046#endif
5047        default:
5048            goto die;
5049        }
5050        break;
5051    case 21:
5052       /* Officially reserved, but sel 0 is used for R1x000 framemask */
5053        switch (sel) {
5054        case 0:
5055            gen_helper_mtc0_framemask(cpu_env, arg);
5056            rn = "Framemask";
5057            break;
5058        default:
5059            goto die;
5060        }
5061        break;
5062    case 22:
5063        /* ignored */
5064        rn = "Diagnostic"; /* implementation dependent */
5065        break;
5066    case 23:
5067        switch (sel) {
5068        case 0:
5069            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
5070            /* BS_STOP isn't good enough here, hflags may have changed. */
5071            gen_save_pc(ctx->pc + 4);
5072            ctx->bstate = BS_EXCP;
5073            rn = "Debug";
5074            break;
5075        case 1:
5076//            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
5077            rn = "TraceControl";
5078            /* Stop translation as we may have switched the execution mode */
5079            ctx->bstate = BS_STOP;
5080//            break;
5081        case 2:
5082//            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
5083            rn = "TraceControl2";
5084            /* Stop translation as we may have switched the execution mode */
5085            ctx->bstate = BS_STOP;
5086//            break;
5087        case 3:
5088            /* Stop translation as we may have switched the execution mode */
5089            ctx->bstate = BS_STOP;
5090//            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
5091            rn = "UserTraceData";
5092            /* Stop translation as we may have switched the execution mode */
5093            ctx->bstate = BS_STOP;
5094//            break;
5095        case 4:
5096//            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
5097            /* Stop translation as we may have switched the execution mode */
5098            ctx->bstate = BS_STOP;
5099            rn = "TraceBPC";
5100//            break;
5101        default:
5102            goto die;
5103        }
5104        break;
5105    case 24:
5106        switch (sel) {
5107        case 0:
5108            /* EJTAG support */
5109            gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
5110            rn = "DEPC";
5111            break;
5112        default:
5113            goto die;
5114        }
5115        break;
5116    case 25:
5117        switch (sel) {
5118        case 0:
5119            gen_helper_mtc0_performance0(cpu_env, arg);
5120            rn = "Performance0";
5121            break;
5122        case 1:
5123//            gen_helper_mtc0_performance1(arg);
5124            rn = "Performance1";
5125//            break;
5126        case 2:
5127//            gen_helper_mtc0_performance2(arg);
5128            rn = "Performance2";
5129//            break;
5130        case 3:
5131//            gen_helper_mtc0_performance3(arg);
5132            rn = "Performance3";
5133//            break;
5134        case 4:
5135//            gen_helper_mtc0_performance4(arg);
5136            rn = "Performance4";
5137//            break;
5138        case 5:
5139//            gen_helper_mtc0_performance5(arg);
5140            rn = "Performance5";
5141//            break;
5142        case 6:
5143//            gen_helper_mtc0_performance6(arg);
5144            rn = "Performance6";
5145//            break;
5146        case 7:
5147//            gen_helper_mtc0_performance7(arg);
5148            rn = "Performance7";
5149//            break;
5150        default:
5151            goto die;
5152        }
5153       break;
5154    case 26:
5155        /* ignored */
5156        rn = "ECC";
5157        break;
5158    case 27:
5159        switch (sel) {
5160        case 0 ... 3:
5161            /* ignored */
5162            rn = "CacheErr";
5163            break;
5164        default:
5165            goto die;
5166        }
5167       break;
5168    case 28:
5169        switch (sel) {
5170        case 0:
5171        case 2:
5172        case 4:
5173        case 6:
5174            gen_helper_mtc0_taglo(cpu_env, arg);
5175            rn = "TagLo";
5176            break;
5177        case 1:
5178        case 3:
5179        case 5:
5180        case 7:
5181            gen_helper_mtc0_datalo(cpu_env, arg);
5182            rn = "DataLo";
5183            break;
5184        default:
5185            goto die;
5186        }
5187        break;
5188    case 29:
5189        switch (sel) {
5190        case 0:
5191        case 2:
5192        case 4:
5193        case 6:
5194            gen_helper_mtc0_taghi(cpu_env, arg);
5195            rn = "TagHi";
5196            break;
5197        case 1:
5198        case 3:
5199        case 5:
5200        case 7:
5201            gen_helper_mtc0_datahi(cpu_env, arg);
5202            rn = "DataHi";
5203            break;
5204        default:
5205            rn = "invalid sel";
5206            goto die;
5207        }
5208       break;
5209    case 30:
5210        switch (sel) {
5211        case 0:
5212            gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
5213            rn = "ErrorEPC";
5214            break;
5215        default:
5216            goto die;
5217        }
5218        break;
5219    case 31:
5220        switch (sel) {
5221        case 0:
5222            /* EJTAG support */
5223            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5224            rn = "DESAVE";
5225            break;
5226        default:
5227            goto die;
5228        }
5229        /* Stop translation as we may have switched the execution mode */
5230        ctx->bstate = BS_STOP;
5231        break;
5232    default:
5233       goto die;
5234    }
5235    (void)rn; /* avoid a compiler warning */
5236    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5237    /* For simplicity assume that all writes can cause interrupts.  */
5238    if (use_icount) {
5239        gen_io_end();
5240        ctx->bstate = BS_STOP;
5241    }
5242    return;
5243
5244die:
5245    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5246    generate_exception(ctx, EXCP_RI);
5247}
5248
5249#if defined(TARGET_MIPS64)
5250static void gen_dmfc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5251{
5252    const char *rn = "invalid";
5253
5254    if (sel != 0)
5255        check_insn(ctx, ISA_MIPS64);
5256
5257    switch (reg) {
5258    case 0:
5259        switch (sel) {
5260        case 0:
5261            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
5262            rn = "Index";
5263            break;
5264        case 1:
5265            check_insn(ctx, ASE_MT);
5266            gen_helper_mfc0_mvpcontrol(arg, cpu_env);
5267            rn = "MVPControl";
5268            break;
5269        case 2:
5270            check_insn(ctx, ASE_MT);
5271            gen_helper_mfc0_mvpconf0(arg, cpu_env);
5272            rn = "MVPConf0";
5273            break;
5274        case 3:
5275            check_insn(ctx, ASE_MT);
5276            gen_helper_mfc0_mvpconf1(arg, cpu_env);
5277            rn = "MVPConf1";
5278            break;
5279        default:
5280            goto die;
5281        }
5282        break;
5283    case 1:
5284        switch (sel) {
5285        case 0:
5286            gen_helper_mfc0_random(arg, cpu_env);
5287            rn = "Random";
5288            break;
5289        case 1:
5290            check_insn(ctx, ASE_MT);
5291            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
5292            rn = "VPEControl";
5293            break;
5294        case 2:
5295            check_insn(ctx, ASE_MT);
5296            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
5297            rn = "VPEConf0";
5298            break;
5299        case 3:
5300            check_insn(ctx, ASE_MT);
5301            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
5302            rn = "VPEConf1";
5303            break;
5304        case 4:
5305            check_insn(ctx, ASE_MT);
5306            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
5307            rn = "YQMask";
5308            break;
5309        case 5:
5310            check_insn(ctx, ASE_MT);
5311            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5312            rn = "VPESchedule";
5313            break;
5314        case 6:
5315            check_insn(ctx, ASE_MT);
5316            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5317            rn = "VPEScheFBack";
5318            break;
5319        case 7:
5320            check_insn(ctx, ASE_MT);
5321            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
5322            rn = "VPEOpt";
5323            break;
5324        default:
5325            goto die;
5326        }
5327        break;
5328    case 2:
5329        switch (sel) {
5330        case 0:
5331            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
5332            rn = "EntryLo0";
5333            break;
5334        case 1:
5335            check_insn(ctx, ASE_MT);
5336            gen_helper_mfc0_tcstatus(arg, cpu_env);
5337            rn = "TCStatus";
5338            break;
5339        case 2:
5340            check_insn(ctx, ASE_MT);
5341            gen_helper_mfc0_tcbind(arg, cpu_env);
5342            rn = "TCBind";
5343            break;
5344        case 3:
5345            check_insn(ctx, ASE_MT);
5346            gen_helper_dmfc0_tcrestart(arg, cpu_env);
5347            rn = "TCRestart";
5348            break;
5349        case 4:
5350            check_insn(ctx, ASE_MT);
5351            gen_helper_dmfc0_tchalt(arg, cpu_env);
5352            rn = "TCHalt";
5353            break;
5354        case 5:
5355            check_insn(ctx, ASE_MT);
5356            gen_helper_dmfc0_tccontext(arg, cpu_env);
5357            rn = "TCContext";
5358            break;
5359        case 6:
5360            check_insn(ctx, ASE_MT);
5361            gen_helper_dmfc0_tcschedule(arg, cpu_env);
5362            rn = "TCSchedule";
5363            break;
5364        case 7:
5365            check_insn(ctx, ASE_MT);
5366            gen_helper_dmfc0_tcschefback(arg, cpu_env);
5367            rn = "TCScheFBack";
5368            break;
5369        default:
5370            goto die;
5371        }
5372        break;
5373    case 3:
5374        switch (sel) {
5375        case 0:
5376            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
5377            rn = "EntryLo1";
5378            break;
5379        default:
5380            goto die;
5381        }
5382        break;
5383    case 4:
5384        switch (sel) {
5385        case 0:
5386            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
5387            rn = "Context";
5388            break;
5389        case 1:
5390//            gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
5391            rn = "ContextConfig";
5392//            break;
5393        default:
5394            goto die;
5395        }
5396        break;
5397    case 5:
5398        switch (sel) {
5399        case 0:
5400            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
5401            rn = "PageMask";
5402            break;
5403        case 1:
5404            check_insn(ctx, ISA_MIPS32R2);
5405            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
5406            rn = "PageGrain";
5407            break;
5408        default:
5409            goto die;
5410        }
5411        break;
5412    case 6:
5413        switch (sel) {
5414        case 0:
5415            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
5416            rn = "Wired";
5417            break;
5418        case 1:
5419            check_insn(ctx, ISA_MIPS32R2);
5420            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
5421            rn = "SRSConf0";
5422            break;
5423        case 2:
5424            check_insn(ctx, ISA_MIPS32R2);
5425            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
5426            rn = "SRSConf1";
5427            break;
5428        case 3:
5429            check_insn(ctx, ISA_MIPS32R2);
5430            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
5431            rn = "SRSConf2";
5432            break;
5433        case 4:
5434            check_insn(ctx, ISA_MIPS32R2);
5435            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
5436            rn = "SRSConf3";
5437            break;
5438        case 5:
5439            check_insn(ctx, ISA_MIPS32R2);
5440            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
5441            rn = "SRSConf4";
5442            break;
5443        default:
5444            goto die;
5445        }
5446        break;
5447    case 7:
5448        switch (sel) {
5449        case 0:
5450            check_insn(ctx, ISA_MIPS32R2);
5451            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
5452            rn = "HWREna";
5453            break;
5454        default:
5455            goto die;
5456        }
5457        break;
5458    case 8:
5459        switch (sel) {
5460        case 0:
5461            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
5462            rn = "BadVAddr";
5463            break;
5464        default:
5465            goto die;
5466        }
5467        break;
5468    case 9:
5469        switch (sel) {
5470        case 0:
5471            /* Mark as an IO operation because we read the time.  */
5472            if (use_icount)
5473                gen_io_start();
5474            gen_helper_mfc0_count(arg, cpu_env);
5475            if (use_icount) {
5476                gen_io_end();
5477            }
5478            /* Break the TB to be able to take timer interrupts immediately
5479               after reading count.  */
5480            ctx->bstate = BS_STOP;
5481            rn = "Count";
5482            break;
5483        /* 6,7 are implementation dependent */
5484        default:
5485            goto die;
5486        }
5487        break;
5488    case 10:
5489        switch (sel) {
5490        case 0:
5491            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
5492            rn = "EntryHi";
5493            break;
5494        default:
5495            goto die;
5496        }
5497        break;
5498    case 11:
5499        switch (sel) {
5500        case 0:
5501            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
5502            rn = "Compare";
5503            break;
5504        /* 6,7 are implementation dependent */
5505        default:
5506            goto die;
5507        }
5508        break;
5509    case 12:
5510        switch (sel) {
5511        case 0:
5512            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
5513            rn = "Status";
5514            break;
5515        case 1:
5516            check_insn(ctx, ISA_MIPS32R2);
5517            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
5518            rn = "IntCtl";
5519            break;
5520        case 2:
5521            check_insn(ctx, ISA_MIPS32R2);
5522            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
5523            rn = "SRSCtl";
5524            break;
5525        case 3:
5526            check_insn(ctx, ISA_MIPS32R2);
5527            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
5528            rn = "SRSMap";
5529            break;
5530        default:
5531            goto die;
5532        }
5533        break;
5534    case 13:
5535        switch (sel) {
5536        case 0:
5537            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
5538            rn = "Cause";
5539            break;
5540        default:
5541            goto die;
5542        }
5543        break;
5544    case 14:
5545        switch (sel) {
5546        case 0:
5547            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
5548            rn = "EPC";
5549            break;
5550        default:
5551            goto die;
5552        }
5553        break;
5554    case 15:
5555        switch (sel) {
5556        case 0:
5557            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
5558            rn = "PRid";
5559            break;
5560        case 1:
5561            check_insn(ctx, ISA_MIPS32R2);
5562            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
5563            rn = "EBase";
5564            break;
5565        default:
5566            goto die;
5567        }
5568        break;
5569    case 16:
5570        switch (sel) {
5571        case 0:
5572            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
5573            rn = "Config";
5574            break;
5575        case 1:
5576            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
5577            rn = "Config1";
5578            break;
5579        case 2:
5580            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
5581            rn = "Config2";
5582            break;
5583        case 3:
5584            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
5585            rn = "Config3";
5586            break;
5587       /* 6,7 are implementation dependent */
5588        case 6:
5589            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
5590            rn = "Config6";
5591            break;
5592        case 7:
5593            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
5594            rn = "Config7";
5595            break;
5596        default:
5597            goto die;
5598        }
5599        break;
5600    case 17:
5601        switch (sel) {
5602        case 0:
5603            gen_helper_dmfc0_lladdr(arg, cpu_env);
5604            rn = "LLAddr";
5605            break;
5606        default:
5607            goto die;
5608        }
5609        break;
5610    case 18:
5611        switch (sel) {
5612        case 0 ... 7:
5613            gen_helper_1e0i(dmfc0_watchlo, arg, sel);
5614            rn = "WatchLo";
5615            break;
5616        default:
5617            goto die;
5618        }
5619        break;
5620    case 19:
5621        switch (sel) {
5622        case 0 ... 7:
5623            gen_helper_1e0i(mfc0_watchhi, arg, sel);
5624            rn = "WatchHi";
5625            break;
5626        default:
5627            goto die;
5628        }
5629        break;
5630    case 20:
5631        switch (sel) {
5632        case 0:
5633            check_insn(ctx, ISA_MIPS3);
5634            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
5635            rn = "XContext";
5636            break;
5637        default:
5638            goto die;
5639        }
5640        break;
5641    case 21:
5642       /* Officially reserved, but sel 0 is used for R1x000 framemask */
5643        switch (sel) {
5644        case 0:
5645            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
5646            rn = "Framemask";
5647            break;
5648        default:
5649            goto die;
5650        }
5651        break;
5652    case 22:
5653        tcg_gen_movi_tl(arg, 0); /* unimplemented */
5654        rn = "'Diagnostic"; /* implementation dependent */
5655        break;
5656    case 23:
5657        switch (sel) {
5658        case 0:
5659            gen_helper_mfc0_debug(arg, cpu_env); /* EJTAG support */
5660            rn = "Debug";
5661            break;
5662        case 1:
5663//            gen_helper_dmfc0_tracecontrol(arg, cpu_env); /* PDtrace support */
5664            rn = "TraceControl";
5665//            break;
5666        case 2:
5667//            gen_helper_dmfc0_tracecontrol2(arg, cpu_env); /* PDtrace support */
5668            rn = "TraceControl2";
5669//            break;
5670        case 3:
5671//            gen_helper_dmfc0_usertracedata(arg, cpu_env); /* PDtrace support */
5672            rn = "UserTraceData";
5673//            break;
5674        case 4:
5675//            gen_helper_dmfc0_tracebpc(arg, cpu_env); /* PDtrace support */
5676            rn = "TraceBPC";
5677//            break;
5678        default:
5679            goto die;
5680        }
5681        break;
5682    case 24:
5683        switch (sel) {
5684        case 0:
5685            /* EJTAG support */
5686            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
5687            rn = "DEPC";
5688            break;
5689        default:
5690            goto die;
5691        }
5692        break;
5693    case 25:
5694        switch (sel) {
5695        case 0:
5696            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
5697            rn = "Performance0";
5698            break;
5699        case 1:
5700//            gen_helper_dmfc0_performance1(arg);
5701            rn = "Performance1";
5702//            break;
5703        case 2:
5704//            gen_helper_dmfc0_performance2(arg);
5705            rn = "Performance2";
5706//            break;
5707        case 3:
5708//            gen_helper_dmfc0_performance3(arg);
5709            rn = "Performance3";
5710//            break;
5711        case 4:
5712//            gen_helper_dmfc0_performance4(arg);
5713            rn = "Performance4";
5714//            break;
5715        case 5:
5716//            gen_helper_dmfc0_performance5(arg);
5717            rn = "Performance5";
5718//            break;
5719        case 6:
5720//            gen_helper_dmfc0_performance6(arg);
5721            rn = "Performance6";
5722//            break;
5723        case 7:
5724//            gen_helper_dmfc0_performance7(arg);
5725            rn = "Performance7";
5726//            break;
5727        default:
5728            goto die;
5729        }
5730        break;
5731    case 26:
5732        tcg_gen_movi_tl(arg, 0); /* unimplemented */
5733        rn = "ECC";
5734        break;
5735    case 27:
5736        switch (sel) {
5737        /* ignored */
5738        case 0 ... 3:
5739            tcg_gen_movi_tl(arg, 0); /* unimplemented */
5740            rn = "CacheErr";
5741            break;
5742        default:
5743            goto die;
5744        }
5745        break;
5746    case 28:
5747        switch (sel) {
5748        case 0:
5749        case 2:
5750        case 4:
5751        case 6:
5752            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
5753            rn = "TagLo";
5754            break;
5755        case 1:
5756        case 3:
5757        case 5:
5758        case 7:
5759            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
5760            rn = "DataLo";
5761            break;
5762        default:
5763            goto die;
5764        }
5765        break;
5766    case 29:
5767        switch (sel) {
5768        case 0:
5769        case 2:
5770        case 4:
5771        case 6:
5772            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
5773            rn = "TagHi";
5774            break;
5775        case 1:
5776        case 3:
5777        case 5:
5778        case 7:
5779            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
5780            rn = "DataHi";
5781            break;
5782        default:
5783            goto die;
5784        }
5785        break;
5786    case 30:
5787        switch (sel) {
5788        case 0:
5789            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
5790            rn = "ErrorEPC";
5791            break;
5792        default:
5793            goto die;
5794        }
5795        break;
5796    case 31:
5797        switch (sel) {
5798        case 0:
5799            /* EJTAG support */
5800            gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
5801            rn = "DESAVE";
5802            break;
5803        default:
5804            goto die;
5805        }
5806        break;
5807    default:
5808        goto die;
5809    }
5810    (void)rn; /* avoid a compiler warning */
5811    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5812    return;
5813
5814die:
5815    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
5816    generate_exception(ctx, EXCP_RI);
5817}
5818
5819static void gen_dmtc0(DisasContext *ctx, TCGv arg, int reg, int sel)
5820{
5821    const char *rn = "invalid";
5822
5823    if (sel != 0)
5824        check_insn(ctx, ISA_MIPS64);
5825
5826    if (use_icount)
5827        gen_io_start();
5828
5829    switch (reg) {
5830    case 0:
5831        switch (sel) {
5832        case 0:
5833            gen_helper_mtc0_index(cpu_env, arg);
5834            rn = "Index";
5835            break;
5836        case 1:
5837            check_insn(ctx, ASE_MT);
5838            gen_helper_mtc0_mvpcontrol(cpu_env, arg);
5839            rn = "MVPControl";
5840            break;
5841        case 2:
5842            check_insn(ctx, ASE_MT);
5843            /* ignored */
5844            rn = "MVPConf0";
5845            break;
5846        case 3:
5847            check_insn(ctx, ASE_MT);
5848            /* ignored */
5849            rn = "MVPConf1";
5850            break;
5851        default:
5852            goto die;
5853        }
5854        break;
5855    case 1:
5856        switch (sel) {
5857        case 0:
5858            /* ignored */
5859            rn = "Random";
5860            break;
5861        case 1:
5862            check_insn(ctx, ASE_MT);
5863            gen_helper_mtc0_vpecontrol(cpu_env, arg);
5864            rn = "VPEControl";
5865            break;
5866        case 2:
5867            check_insn(ctx, ASE_MT);
5868            gen_helper_mtc0_vpeconf0(cpu_env, arg);
5869            rn = "VPEConf0";
5870            break;
5871        case 3:
5872            check_insn(ctx, ASE_MT);
5873            gen_helper_mtc0_vpeconf1(cpu_env, arg);
5874            rn = "VPEConf1";
5875            break;
5876        case 4:
5877            check_insn(ctx, ASE_MT);
5878            gen_helper_mtc0_yqmask(cpu_env, arg);
5879            rn = "YQMask";
5880            break;
5881        case 5:
5882            check_insn(ctx, ASE_MT);
5883            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
5884            rn = "VPESchedule";
5885            break;
5886        case 6:
5887            check_insn(ctx, ASE_MT);
5888            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
5889            rn = "VPEScheFBack";
5890            break;
5891        case 7:
5892            check_insn(ctx, ASE_MT);
5893            gen_helper_mtc0_vpeopt(cpu_env, arg);
5894            rn = "VPEOpt";
5895            break;
5896        default:
5897            goto die;
5898        }
5899        break;
5900    case 2:
5901        switch (sel) {
5902        case 0:
5903            gen_helper_mtc0_entrylo0(cpu_env, arg);
5904            rn = "EntryLo0";
5905            break;
5906        case 1:
5907            check_insn(ctx, ASE_MT);
5908            gen_helper_mtc0_tcstatus(cpu_env, arg);
5909            rn = "TCStatus";
5910            break;
5911        case 2:
5912            check_insn(ctx, ASE_MT);
5913            gen_helper_mtc0_tcbind(cpu_env, arg);
5914            rn = "TCBind";
5915            break;
5916        case 3:
5917            check_insn(ctx, ASE_MT);
5918            gen_helper_mtc0_tcrestart(cpu_env, arg);
5919            rn = "TCRestart";
5920            break;
5921        case 4:
5922            check_insn(ctx, ASE_MT);
5923            gen_helper_mtc0_tchalt(cpu_env, arg);
5924            rn = "TCHalt";
5925            break;
5926        case 5:
5927            check_insn(ctx, ASE_MT);
5928            gen_helper_mtc0_tccontext(cpu_env, arg);
5929            rn = "TCContext";
5930            break;
5931        case 6:
5932            check_insn(ctx, ASE_MT);
5933            gen_helper_mtc0_tcschedule(cpu_env, arg);
5934            rn = "TCSchedule";
5935            break;
5936        case 7:
5937            check_insn(ctx, ASE_MT);
5938            gen_helper_mtc0_tcschefback(cpu_env, arg);
5939            rn = "TCScheFBack";
5940            break;
5941        default:
5942            goto die;
5943        }
5944        break;
5945    case 3:
5946        switch (sel) {
5947        case 0:
5948            gen_helper_mtc0_entrylo1(cpu_env, arg);
5949            rn = "EntryLo1";
5950            break;
5951        default:
5952            goto die;
5953        }
5954        break;
5955    case 4:
5956        switch (sel) {
5957        case 0:
5958            gen_helper_mtc0_context(cpu_env, arg);
5959            rn = "Context";
5960            break;
5961        case 1:
5962//           gen_helper_mtc0_contextconfig(cpu_env, arg); /* SmartMIPS ASE */
5963            rn = "ContextConfig";
5964//           break;
5965        default:
5966            goto die;
5967        }
5968        break;
5969    case 5:
5970        switch (sel) {
5971        case 0:
5972            gen_helper_mtc0_pagemask(cpu_env, arg);
5973            rn = "PageMask";
5974            break;
5975        case 1:
5976            check_insn(ctx, ISA_MIPS32R2);
5977            gen_helper_mtc0_pagegrain(cpu_env, arg);
5978            rn = "PageGrain";
5979            break;
5980        default:
5981            goto die;
5982        }
5983        break;
5984    case 6:
5985        switch (sel) {
5986        case 0:
5987            gen_helper_mtc0_wired(cpu_env, arg);
5988            rn = "Wired";
5989            break;
5990        case 1:
5991            check_insn(ctx, ISA_MIPS32R2);
5992            gen_helper_mtc0_srsconf0(cpu_env, arg);
5993            rn = "SRSConf0";
5994            break;
5995        case 2:
5996            check_insn(ctx, ISA_MIPS32R2);
5997            gen_helper_mtc0_srsconf1(cpu_env, arg);
5998            rn = "SRSConf1";
5999            break;
6000        case 3:
6001            check_insn(ctx, ISA_MIPS32R2);
6002            gen_helper_mtc0_srsconf2(cpu_env, arg);
6003            rn = "SRSConf2";
6004            break;
6005        case 4:
6006            check_insn(ctx, ISA_MIPS32R2);
6007            gen_helper_mtc0_srsconf3(cpu_env, arg);
6008            rn = "SRSConf3";
6009            break;
6010        case 5:
6011            check_insn(ctx, ISA_MIPS32R2);
6012            gen_helper_mtc0_srsconf4(cpu_env, arg);
6013            rn = "SRSConf4";
6014            break;
6015        default:
6016            goto die;
6017        }
6018        break;
6019    case 7:
6020        switch (sel) {
6021        case 0:
6022            check_insn(ctx, ISA_MIPS32R2);
6023            gen_helper_mtc0_hwrena(cpu_env, arg);
6024            rn = "HWREna";
6025            break;
6026        default:
6027            goto die;
6028        }
6029        break;
6030    case 8:
6031        /* ignored */
6032        rn = "BadVAddr";
6033        break;
6034    case 9:
6035        switch (sel) {
6036        case 0:
6037            gen_helper_mtc0_count(cpu_env, arg);
6038            rn = "Count";
6039            break;
6040        /* 6,7 are implementation dependent */
6041        default:
6042            goto die;
6043        }
6044        /* Stop translation as we may have switched the execution mode */
6045        ctx->bstate = BS_STOP;
6046        break;
6047    case 10:
6048        switch (sel) {
6049        case 0:
6050            gen_helper_mtc0_entryhi(cpu_env, arg);
6051            rn = "EntryHi";
6052            break;
6053        default:
6054            goto die;
6055        }
6056        break;
6057    case 11:
6058        switch (sel) {
6059        case 0:
6060            gen_helper_mtc0_compare(cpu_env, arg);
6061            rn = "Compare";
6062            break;
6063        /* 6,7 are implementation dependent */
6064        default:
6065            goto die;
6066        }
6067        /* Stop translation as we may have switched the execution mode */
6068        ctx->bstate = BS_STOP;
6069        break;
6070    case 12:
6071        switch (sel) {
6072        case 0:
6073            save_cpu_state(ctx, 1);
6074            gen_helper_mtc0_status(cpu_env, arg);
6075            /* BS_STOP isn't good enough here, hflags may have changed. */
6076            gen_save_pc(ctx->pc + 4);
6077            ctx->bstate = BS_EXCP;
6078            rn = "Status";
6079            break;
6080        case 1:
6081            check_insn(ctx, ISA_MIPS32R2);
6082            gen_helper_mtc0_intctl(cpu_env, arg);
6083            /* Stop translation as we may have switched the execution mode */
6084            ctx->bstate = BS_STOP;
6085            rn = "IntCtl";
6086            break;
6087        case 2:
6088            check_insn(ctx, ISA_MIPS32R2);
6089            gen_helper_mtc0_srsctl(cpu_env, arg);
6090            /* Stop translation as we may have switched the execution mode */
6091            ctx->bstate = BS_STOP;
6092            rn = "SRSCtl";
6093            break;
6094        case 3:
6095            check_insn(ctx, ISA_MIPS32R2);
6096            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
6097            /* Stop translation as we may have switched the execution mode */
6098            ctx->bstate = BS_STOP;
6099            rn = "SRSMap";
6100            break;
6101        default:
6102            goto die;
6103        }
6104        break;
6105    case 13:
6106        switch (sel) {
6107        case 0:
6108            save_cpu_state(ctx, 1);
6109            /* Mark as an IO operation because we may trigger a software
6110               interrupt.  */
6111            if (use_icount) {
6112                gen_io_start();
6113            }
6114            gen_helper_mtc0_cause(cpu_env, arg);
6115            if (use_icount) {
6116                gen_io_end();
6117            }
6118            /* Stop translation as we may have triggered an intetrupt */
6119            ctx->bstate = BS_STOP;
6120            rn = "Cause";
6121            break;
6122        default:
6123            goto die;
6124        }
6125        break;
6126    case 14:
6127        switch (sel) {
6128        case 0:
6129            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
6130            rn = "EPC";
6131            break;
6132        default:
6133            goto die;
6134        }
6135        break;
6136    case 15:
6137        switch (sel) {
6138        case 0:
6139            /* ignored */
6140            rn = "PRid";
6141            break;
6142        case 1:
6143            check_insn(ctx, ISA_MIPS32R2);
6144            gen_helper_mtc0_ebase(cpu_env, arg);
6145            rn = "EBase";
6146            break;
6147        default:
6148            goto die;
6149        }
6150        break;
6151    case 16:
6152        switch (sel) {
6153        case 0:
6154            gen_helper_mtc0_config0(cpu_env, arg);
6155            rn = "Config";
6156            /* Stop translation as we may have switched the execution mode */
6157            ctx->bstate = BS_STOP;
6158            break;
6159        case 1:
6160            /* ignored, read only */
6161            rn = "Config1";
6162            break;
6163        case 2:
6164            gen_helper_mtc0_config2(cpu_env, arg);
6165            rn = "Config2";
6166            /* Stop translation as we may have switched the execution mode */
6167            ctx->bstate = BS_STOP;
6168            break;
6169        case 3:
6170            /* ignored */
6171            rn = "Config3";
6172            break;
6173        /* 6,7 are implementation dependent */
6174        default:
6175            rn = "Invalid config selector";
6176            goto die;
6177        }
6178        break;
6179    case 17:
6180        switch (sel) {
6181        case 0:
6182            gen_helper_mtc0_lladdr(cpu_env, arg);
6183            rn = "LLAddr";
6184            break;
6185        default:
6186            goto die;
6187        }
6188        break;
6189    case 18:
6190        switch (sel) {
6191        case 0 ... 7:
6192            gen_helper_0e1i(mtc0_watchlo, arg, sel);
6193            rn = "WatchLo";
6194            break;
6195        default:
6196            goto die;
6197        }
6198        break;
6199    case 19:
6200        switch (sel) {
6201        case 0 ... 7:
6202            gen_helper_0e1i(mtc0_watchhi, arg, sel);
6203            rn = "WatchHi";
6204            break;
6205        default:
6206            goto die;
6207        }
6208        break;
6209    case 20:
6210        switch (sel) {
6211        case 0:
6212            check_insn(ctx, ISA_MIPS3);
6213            gen_helper_mtc0_xcontext(cpu_env, arg);
6214            rn = "XContext";
6215            break;
6216        default:
6217            goto die;
6218        }
6219        break;
6220    case 21:
6221       /* Officially reserved, but sel 0 is used for R1x000 framemask */
6222        switch (sel) {
6223        case 0:
6224            gen_helper_mtc0_framemask(cpu_env, arg);
6225            rn = "Framemask";
6226            break;
6227        default:
6228            goto die;
6229        }
6230        break;
6231    case 22:
6232        /* ignored */
6233        rn = "Diagnostic"; /* implementation dependent */
6234        break;
6235    case 23:
6236        switch (sel) {
6237        case 0:
6238            gen_helper_mtc0_debug(cpu_env, arg); /* EJTAG support */
6239            /* BS_STOP isn't good enough here, hflags may have changed. */
6240            gen_save_pc(ctx->pc + 4);
6241            ctx->bstate = BS_EXCP;
6242            rn = "Debug";
6243            break;
6244        case 1:
6245//            gen_helper_mtc0_tracecontrol(cpu_env, arg); /* PDtrace support */
6246            /* Stop translation as we may have switched the execution mode */
6247            ctx->bstate = BS_STOP;
6248            rn = "TraceControl";
6249//            break;
6250        case 2:
6251//            gen_helper_mtc0_tracecontrol2(cpu_env, arg); /* PDtrace support */
6252            /* Stop translation as we may have switched the execution mode */
6253            ctx->bstate = BS_STOP;
6254            rn = "TraceControl2";
6255//            break;
6256        case 3:
6257//            gen_helper_mtc0_usertracedata(cpu_env, arg); /* PDtrace support */
6258            /* Stop translation as we may have switched the execution mode */
6259            ctx->bstate = BS_STOP;
6260            rn = "UserTraceData";
6261//            break;
6262        case 4:
6263//            gen_helper_mtc0_tracebpc(cpu_env, arg); /* PDtrace support */
6264            /* Stop translation as we may have switched the execution mode */
6265            ctx->bstate = BS_STOP;
6266            rn = "TraceBPC";
6267//            break;
6268        default:
6269            goto die;
6270        }
6271        break;
6272    case 24:
6273        switch (sel) {
6274        case 0:
6275            /* EJTAG support */
6276            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
6277            rn = "DEPC";
6278            break;
6279        default:
6280            goto die;
6281        }
6282        break;
6283    case 25:
6284        switch (sel) {
6285        case 0:
6286            gen_helper_mtc0_performance0(cpu_env, arg);
6287            rn = "Performance0";
6288            break;
6289        case 1:
6290//            gen_helper_mtc0_performance1(cpu_env, arg);
6291            rn = "Performance1";
6292//            break;
6293        case 2:
6294//            gen_helper_mtc0_performance2(cpu_env, arg);
6295            rn = "Performance2";
6296//            break;
6297        case 3:
6298//            gen_helper_mtc0_performance3(cpu_env, arg);
6299            rn = "Performance3";
6300//            break;
6301        case 4:
6302//            gen_helper_mtc0_performance4(cpu_env, arg);
6303            rn = "Performance4";
6304//            break;
6305        case 5:
6306//            gen_helper_mtc0_performance5(cpu_env, arg);
6307            rn = "Performance5";
6308//            break;
6309        case 6:
6310//            gen_helper_mtc0_performance6(cpu_env, arg);
6311            rn = "Performance6";
6312//            break;
6313        case 7:
6314//            gen_helper_mtc0_performance7(cpu_env, arg);
6315            rn = "Performance7";
6316//            break;
6317        default:
6318            goto die;
6319        }
6320        break;
6321    case 26:
6322        /* ignored */
6323        rn = "ECC";
6324        break;
6325    case 27:
6326        switch (sel) {
6327        case 0 ... 3:
6328            /* ignored */
6329            rn = "CacheErr";
6330            break;
6331        default:
6332            goto die;
6333        }
6334        break;
6335    case 28:
6336        switch (sel) {
6337        case 0:
6338        case 2:
6339        case 4:
6340        case 6:
6341            gen_helper_mtc0_taglo(cpu_env, arg);
6342            rn = "TagLo";
6343            break;
6344        case 1:
6345        case 3:
6346        case 5:
6347        case 7:
6348            gen_helper_mtc0_datalo(cpu_env, arg);
6349            rn = "DataLo";
6350            break;
6351        default:
6352            goto die;
6353        }
6354        break;
6355    case 29:
6356        switch (sel) {
6357        case 0:
6358        case 2:
6359        case 4:
6360        case 6:
6361            gen_helper_mtc0_taghi(cpu_env, arg);
6362            rn = "TagHi";
6363            break;
6364        case 1:
6365        case 3:
6366        case 5:
6367        case 7:
6368            gen_helper_mtc0_datahi(cpu_env, arg);
6369            rn = "DataHi";
6370            break;
6371        default:
6372            rn = "invalid sel";
6373            goto die;
6374        }
6375        break;
6376    case 30:
6377        switch (sel) {
6378        case 0:
6379            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
6380            rn = "ErrorEPC";
6381            break;
6382        default:
6383            goto die;
6384        }
6385        break;
6386    case 31:
6387        switch (sel) {
6388        case 0:
6389            /* EJTAG support */
6390            gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
6391            rn = "DESAVE";
6392            break;
6393        default:
6394            goto die;
6395        }
6396        /* Stop translation as we may have switched the execution mode */
6397        ctx->bstate = BS_STOP;
6398        break;
6399    default:
6400        goto die;
6401    }
6402    (void)rn; /* avoid a compiler warning */
6403    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6404    /* For simplicity assume that all writes can cause interrupts.  */
6405    if (use_icount) {
6406        gen_io_end();
6407        ctx->bstate = BS_STOP;
6408    }
6409    return;
6410
6411die:
6412    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
6413    generate_exception(ctx, EXCP_RI);
6414}
6415#endif /* TARGET_MIPS64 */
6416
6417static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
6418                     int u, int sel, int h)
6419{
6420    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6421    TCGv t0 = tcg_temp_local_new();
6422
6423    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6424        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6425         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6426        tcg_gen_movi_tl(t0, -1);
6427    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6428             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6429        tcg_gen_movi_tl(t0, -1);
6430    else if (u == 0) {
6431        switch (rt) {
6432        case 1:
6433            switch (sel) {
6434            case 1:
6435                gen_helper_mftc0_vpecontrol(t0, cpu_env);
6436                break;
6437            case 2:
6438                gen_helper_mftc0_vpeconf0(t0, cpu_env);
6439                break;
6440            default:
6441                goto die;
6442                break;
6443            }
6444            break;
6445        case 2:
6446            switch (sel) {
6447            case 1:
6448                gen_helper_mftc0_tcstatus(t0, cpu_env);
6449                break;
6450            case 2:
6451                gen_helper_mftc0_tcbind(t0, cpu_env);
6452                break;
6453            case 3:
6454                gen_helper_mftc0_tcrestart(t0, cpu_env);
6455                break;
6456            case 4:
6457                gen_helper_mftc0_tchalt(t0, cpu_env);
6458                break;
6459            case 5:
6460                gen_helper_mftc0_tccontext(t0, cpu_env);
6461                break;
6462            case 6:
6463                gen_helper_mftc0_tcschedule(t0, cpu_env);
6464                break;
6465            case 7:
6466                gen_helper_mftc0_tcschefback(t0, cpu_env);
6467                break;
6468            default:
6469                gen_mfc0(ctx, t0, rt, sel);
6470                break;
6471            }
6472            break;
6473        case 10:
6474            switch (sel) {
6475            case 0:
6476                gen_helper_mftc0_entryhi(t0, cpu_env);
6477                break;
6478            default:
6479                gen_mfc0(ctx, t0, rt, sel);
6480                break;
6481            }
6482        case 12:
6483            switch (sel) {
6484            case 0:
6485                gen_helper_mftc0_status(t0, cpu_env);
6486                break;
6487            default:
6488                gen_mfc0(ctx, t0, rt, sel);
6489                break;
6490            }
6491        case 13:
6492            switch (sel) {
6493            case 0:
6494                gen_helper_mftc0_cause(t0, cpu_env);
6495                break;
6496            default:
6497                goto die;
6498                break;
6499            }
6500            break;
6501        case 14:
6502            switch (sel) {
6503            case 0:
6504                gen_helper_mftc0_epc(t0, cpu_env);
6505                break;
6506            default:
6507                goto die;
6508                break;
6509            }
6510            break;
6511        case 15:
6512            switch (sel) {
6513            case 1:
6514                gen_helper_mftc0_ebase(t0, cpu_env);
6515                break;
6516            default:
6517                goto die;
6518                break;
6519            }
6520            break;
6521        case 16:
6522            switch (sel) {
6523            case 0 ... 7:
6524                gen_helper_mftc0_configx(t0, cpu_env, tcg_const_tl(sel));
6525                break;
6526            default:
6527                goto die;
6528                break;
6529            }
6530            break;
6531        case 23:
6532            switch (sel) {
6533            case 0:
6534                gen_helper_mftc0_debug(t0, cpu_env);
6535                break;
6536            default:
6537                gen_mfc0(ctx, t0, rt, sel);
6538                break;
6539            }
6540            break;
6541        default:
6542            gen_mfc0(ctx, t0, rt, sel);
6543        }
6544    } else switch (sel) {
6545    /* GPR registers. */
6546    case 0:
6547        gen_helper_1e0i(mftgpr, t0, rt);
6548        break;
6549    /* Auxiliary CPU registers */
6550    case 1:
6551        switch (rt) {
6552        case 0:
6553            gen_helper_1e0i(mftlo, t0, 0);
6554            break;
6555        case 1:
6556            gen_helper_1e0i(mfthi, t0, 0);
6557            break;
6558        case 2:
6559            gen_helper_1e0i(mftacx, t0, 0);
6560            break;
6561        case 4:
6562            gen_helper_1e0i(mftlo, t0, 1);
6563            break;
6564        case 5:
6565            gen_helper_1e0i(mfthi, t0, 1);
6566            break;
6567        case 6:
6568            gen_helper_1e0i(mftacx, t0, 1);
6569            break;
6570        case 8:
6571            gen_helper_1e0i(mftlo, t0, 2);
6572            break;
6573        case 9:
6574            gen_helper_1e0i(mfthi, t0, 2);
6575            break;
6576        case 10:
6577            gen_helper_1e0i(mftacx, t0, 2);
6578            break;
6579        case 12:
6580            gen_helper_1e0i(mftlo, t0, 3);
6581            break;
6582        case 13:
6583            gen_helper_1e0i(mfthi, t0, 3);
6584            break;
6585        case 14:
6586            gen_helper_1e0i(mftacx, t0, 3);
6587            break;
6588        case 16:
6589            gen_helper_mftdsp(t0, cpu_env);
6590            break;
6591        default:
6592            goto die;
6593        }
6594        break;
6595    /* Floating point (COP1). */
6596    case 2:
6597        /* XXX: For now we support only a single FPU context. */
6598        if (h == 0) {
6599            TCGv_i32 fp0 = tcg_temp_new_i32();
6600
6601            gen_load_fpr32(fp0, rt);
6602            tcg_gen_ext_i32_tl(t0, fp0);
6603            tcg_temp_free_i32(fp0);
6604        } else {
6605            TCGv_i32 fp0 = tcg_temp_new_i32();
6606
6607            gen_load_fpr32h(fp0, rt);
6608            tcg_gen_ext_i32_tl(t0, fp0);
6609            tcg_temp_free_i32(fp0);
6610        }
6611        break;
6612    case 3:
6613        /* XXX: For now we support only a single FPU context. */
6614        gen_helper_1e0i(cfc1, t0, rt);
6615        break;
6616    /* COP2: Not implemented. */
6617    case 4:
6618    case 5:
6619        /* fall through */
6620    default:
6621        goto die;
6622    }
6623    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6624    gen_store_gpr(t0, rd);
6625    tcg_temp_free(t0);
6626    return;
6627
6628die:
6629    tcg_temp_free(t0);
6630    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
6631    generate_exception(ctx, EXCP_RI);
6632}
6633
6634static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
6635                     int u, int sel, int h)
6636{
6637    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
6638    TCGv t0 = tcg_temp_local_new();
6639
6640    gen_load_gpr(t0, rt);
6641    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
6642        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
6643         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
6644        /* NOP */ ;
6645    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
6646             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
6647        /* NOP */ ;
6648    else if (u == 0) {
6649        switch (rd) {
6650        case 1:
6651            switch (sel) {
6652            case 1:
6653                gen_helper_mttc0_vpecontrol(cpu_env, t0);
6654                break;
6655            case 2:
6656                gen_helper_mttc0_vpeconf0(cpu_env, t0);
6657                break;
6658            default:
6659                goto die;
6660                break;
6661            }
6662            break;
6663        case 2:
6664            switch (sel) {
6665            case 1:
6666                gen_helper_mttc0_tcstatus(cpu_env, t0);
6667                break;
6668            case 2:
6669                gen_helper_mttc0_tcbind(cpu_env, t0);
6670                break;
6671            case 3:
6672                gen_helper_mttc0_tcrestart(cpu_env, t0);
6673                break;
6674            case 4:
6675                gen_helper_mttc0_tchalt(cpu_env, t0);
6676                break;
6677            case 5:
6678                gen_helper_mttc0_tccontext(cpu_env, t0);
6679                break;
6680            case 6:
6681                gen_helper_mttc0_tcschedule(cpu_env, t0);
6682                break;
6683            case 7:
6684                gen_helper_mttc0_tcschefback(cpu_env, t0);
6685                break;
6686            default:
6687                gen_mtc0(ctx, t0, rd, sel);
6688                break;
6689            }
6690            break;
6691        case 10:
6692            switch (sel) {
6693            case 0:
6694                gen_helper_mttc0_entryhi(cpu_env, t0);
6695                break;
6696            default:
6697                gen_mtc0(ctx, t0, rd, sel);
6698                break;
6699            }
6700        case 12:
6701            switch (sel) {
6702            case 0:
6703                gen_helper_mttc0_status(cpu_env, t0);
6704                break;
6705            default:
6706                gen_mtc0(ctx, t0, rd, sel);
6707                break;
6708            }
6709        case 13:
6710            switch (sel) {
6711            case 0:
6712                gen_helper_mttc0_cause(cpu_env, t0);
6713                break;
6714            default:
6715                goto die;
6716                break;
6717            }
6718            break;
6719        case 15:
6720            switch (sel) {
6721            case 1:
6722                gen_helper_mttc0_ebase(cpu_env, t0);
6723                break;
6724            default:
6725                goto die;
6726                break;
6727            }
6728            break;
6729        case 23:
6730            switch (sel) {
6731            case 0:
6732                gen_helper_mttc0_debug(cpu_env, t0);
6733                break;
6734            default:
6735                gen_mtc0(ctx, t0, rd, sel);
6736                break;
6737            }
6738            break;
6739        default:
6740            gen_mtc0(ctx, t0, rd, sel);
6741        }
6742    } else switch (sel) {
6743    /* GPR registers. */
6744    case 0:
6745        gen_helper_0e1i(mttgpr, t0, rd);
6746        break;
6747    /* Auxiliary CPU registers */
6748    case 1:
6749        switch (rd) {
6750        case 0:
6751            gen_helper_0e1i(mttlo, t0, 0);
6752            break;
6753        case 1:
6754            gen_helper_0e1i(mtthi, t0, 0);
6755            break;
6756        case 2:
6757            gen_helper_0e1i(mttacx, t0, 0);
6758            break;
6759        case 4:
6760            gen_helper_0e1i(mttlo, t0, 1);
6761            break;
6762        case 5:
6763            gen_helper_0e1i(mtthi, t0, 1);
6764            break;
6765        case 6:
6766            gen_helper_0e1i(mttacx, t0, 1);
6767            break;
6768        case 8:
6769            gen_helper_0e1i(mttlo, t0, 2);
6770            break;
6771        case 9:
6772            gen_helper_0e1i(mtthi, t0, 2);
6773            break;
6774        case 10:
6775            gen_helper_0e1i(mttacx, t0, 2);
6776            break;
6777        case 12:
6778            gen_helper_0e1i(mttlo, t0, 3);
6779            break;
6780        case 13:
6781            gen_helper_0e1i(mtthi, t0, 3);
6782            break;
6783        case 14:
6784            gen_helper_0e1i(mttacx, t0, 3);
6785            break;
6786        case 16:
6787            gen_helper_mttdsp(cpu_env, t0);
6788            break;
6789        default:
6790            goto die;
6791        }
6792        break;
6793    /* Floating point (COP1). */
6794    case 2:
6795        /* XXX: For now we support only a single FPU context. */
6796        if (h == 0) {
6797            TCGv_i32 fp0 = tcg_temp_new_i32();
6798
6799            tcg_gen_trunc_tl_i32(fp0, t0);
6800            gen_store_fpr32(fp0, rd);
6801            tcg_temp_free_i32(fp0);
6802        } else {
6803            TCGv_i32 fp0 = tcg_temp_new_i32();
6804
6805            tcg_gen_trunc_tl_i32(fp0, t0);
6806            gen_store_fpr32h(fp0, rd);
6807            tcg_temp_free_i32(fp0);
6808        }
6809        break;
6810    case 3:
6811        /* XXX: For now we support only a single FPU context. */
6812        gen_helper_0e1i(ctc1, t0, rd);
6813        break;
6814    /* COP2: Not implemented. */
6815    case 4:
6816    case 5:
6817        /* fall through */
6818    default:
6819        goto die;
6820    }
6821    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6822    tcg_temp_free(t0);
6823    return;
6824
6825die:
6826    tcg_temp_free(t0);
6827    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
6828    generate_exception(ctx, EXCP_RI);
6829}
6830
6831static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
6832{
6833    const char *opn = "ldst";
6834
6835    check_cp0_enabled(ctx);
6836    switch (opc) {
6837    case OPC_MFC0:
6838        if (rt == 0) {
6839            /* Treat as NOP. */
6840            return;
6841        }
6842        gen_mfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6843        opn = "mfc0";
6844        break;
6845    case OPC_MTC0:
6846        {
6847            TCGv t0 = tcg_temp_new();
6848
6849            gen_load_gpr(t0, rt);
6850            gen_mtc0(ctx, t0, rd, ctx->opcode & 0x7);
6851            tcg_temp_free(t0);
6852        }
6853        opn = "mtc0";
6854        break;
6855#if defined(TARGET_MIPS64)
6856    case OPC_DMFC0:
6857        check_insn(ctx, ISA_MIPS3);
6858        if (rt == 0) {
6859            /* Treat as NOP. */
6860            return;
6861        }
6862        gen_dmfc0(ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
6863        opn = "dmfc0";
6864        break;
6865    case OPC_DMTC0:
6866        check_insn(ctx, ISA_MIPS3);
6867        {
6868            TCGv t0 = tcg_temp_new();
6869
6870            gen_load_gpr(t0, rt);
6871            gen_dmtc0(ctx, t0, rd, ctx->opcode & 0x7);
6872            tcg_temp_free(t0);
6873        }
6874        opn = "dmtc0";
6875        break;
6876#endif
6877    case OPC_MFTR:
6878        check_insn(ctx, ASE_MT);
6879        if (rd == 0) {
6880            /* Treat as NOP. */
6881            return;
6882        }
6883        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
6884                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6885        opn = "mftr";
6886        break;
6887    case OPC_MTTR:
6888        check_insn(ctx, ASE_MT);
6889        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
6890                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
6891        opn = "mttr";
6892        break;
6893    case OPC_TLBWI:
6894        opn = "tlbwi";
6895        if (!env->tlb->helper_tlbwi)
6896            goto die;
6897        gen_helper_tlbwi(cpu_env);
6898        break;
6899    case OPC_TLBWR:
6900        opn = "tlbwr";
6901        if (!env->tlb->helper_tlbwr)
6902            goto die;
6903        gen_helper_tlbwr(cpu_env);
6904        break;
6905    case OPC_TLBP:
6906        opn = "tlbp";
6907        if (!env->tlb->helper_tlbp)
6908            goto die;
6909        gen_helper_tlbp(cpu_env);
6910        break;
6911    case OPC_TLBR:
6912        opn = "tlbr";
6913        if (!env->tlb->helper_tlbr)
6914            goto die;
6915        gen_helper_tlbr(cpu_env);
6916        break;
6917    case OPC_ERET:
6918        opn = "eret";
6919        check_insn(ctx, ISA_MIPS2);
6920        gen_helper_eret(cpu_env);
6921        ctx->bstate = BS_EXCP;
6922        break;
6923    case OPC_DERET:
6924        opn = "deret";
6925        check_insn(ctx, ISA_MIPS32);
6926        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
6927            MIPS_INVAL(opn);
6928            generate_exception(ctx, EXCP_RI);
6929        } else {
6930            gen_helper_deret(cpu_env);
6931            ctx->bstate = BS_EXCP;
6932        }
6933        break;
6934    case OPC_WAIT:
6935        opn = "wait";
6936        check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
6937        /* If we get an exception, we want to restart at next instruction */
6938        ctx->pc += 4;
6939        save_cpu_state(ctx, 1);
6940        ctx->pc -= 4;
6941        gen_helper_wait(cpu_env);
6942        ctx->bstate = BS_EXCP;
6943        break;
6944    default:
6945 die:
6946        MIPS_INVAL(opn);
6947        generate_exception(ctx, EXCP_RI);
6948        return;
6949    }
6950    (void)opn; /* avoid a compiler warning */
6951    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
6952}
6953#endif /* !CONFIG_USER_ONLY */
6954
6955/* CP1 Branches (before delay slot) */
6956static void gen_compute_branch1(DisasContext *ctx, uint32_t op,
6957                                int32_t cc, int32_t offset)
6958{
6959    target_ulong btarget;
6960    const char *opn = "cp1 cond branch";
6961    TCGv_i32 t0 = tcg_temp_new_i32();
6962
6963    if (cc != 0)
6964        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
6965
6966    btarget = ctx->pc + 4 + offset;
6967
6968    switch (op) {
6969    case OPC_BC1F:
6970        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6971        tcg_gen_not_i32(t0, t0);
6972        tcg_gen_andi_i32(t0, t0, 1);
6973        tcg_gen_extu_i32_tl(bcond, t0);
6974        opn = "bc1f";
6975        goto not_likely;
6976    case OPC_BC1FL:
6977        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6978        tcg_gen_not_i32(t0, t0);
6979        tcg_gen_andi_i32(t0, t0, 1);
6980        tcg_gen_extu_i32_tl(bcond, t0);
6981        opn = "bc1fl";
6982        goto likely;
6983    case OPC_BC1T:
6984        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6985        tcg_gen_andi_i32(t0, t0, 1);
6986        tcg_gen_extu_i32_tl(bcond, t0);
6987        opn = "bc1t";
6988        goto not_likely;
6989    case OPC_BC1TL:
6990        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
6991        tcg_gen_andi_i32(t0, t0, 1);
6992        tcg_gen_extu_i32_tl(bcond, t0);
6993        opn = "bc1tl";
6994    likely:
6995        ctx->hflags |= MIPS_HFLAG_BL;
6996        break;
6997    case OPC_BC1FANY2:
6998        {
6999            TCGv_i32 t1 = tcg_temp_new_i32();
7000            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7001            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7002            tcg_gen_nand_i32(t0, t0, t1);
7003            tcg_temp_free_i32(t1);
7004            tcg_gen_andi_i32(t0, t0, 1);
7005            tcg_gen_extu_i32_tl(bcond, t0);
7006        }
7007        opn = "bc1any2f";
7008        goto not_likely;
7009    case OPC_BC1TANY2:
7010        {
7011            TCGv_i32 t1 = tcg_temp_new_i32();
7012            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7013            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7014            tcg_gen_or_i32(t0, t0, t1);
7015            tcg_temp_free_i32(t1);
7016            tcg_gen_andi_i32(t0, t0, 1);
7017            tcg_gen_extu_i32_tl(bcond, t0);
7018        }
7019        opn = "bc1any2t";
7020        goto not_likely;
7021    case OPC_BC1FANY4:
7022        {
7023            TCGv_i32 t1 = tcg_temp_new_i32();
7024            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7025            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7026            tcg_gen_and_i32(t0, t0, t1);
7027            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7028            tcg_gen_and_i32(t0, t0, t1);
7029            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7030            tcg_gen_nand_i32(t0, t0, t1);
7031            tcg_temp_free_i32(t1);
7032            tcg_gen_andi_i32(t0, t0, 1);
7033            tcg_gen_extu_i32_tl(bcond, t0);
7034        }
7035        opn = "bc1any4f";
7036        goto not_likely;
7037    case OPC_BC1TANY4:
7038        {
7039            TCGv_i32 t1 = tcg_temp_new_i32();
7040            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
7041            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
7042            tcg_gen_or_i32(t0, t0, t1);
7043            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
7044            tcg_gen_or_i32(t0, t0, t1);
7045            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
7046            tcg_gen_or_i32(t0, t0, t1);
7047            tcg_temp_free_i32(t1);
7048            tcg_gen_andi_i32(t0, t0, 1);
7049            tcg_gen_extu_i32_tl(bcond, t0);
7050        }
7051        opn = "bc1any4t";
7052    not_likely:
7053        ctx->hflags |= MIPS_HFLAG_BC;
7054        break;
7055    default:
7056        MIPS_INVAL(opn);
7057        generate_exception (ctx, EXCP_RI);
7058        goto out;
7059    }
7060    (void)opn; /* avoid a compiler warning */
7061    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
7062               ctx->hflags, btarget);
7063    ctx->btarget = btarget;
7064
7065 out:
7066    tcg_temp_free_i32(t0);
7067}
7068
7069/* Coprocessor 1 (FPU) */
7070
7071#define FOP(func, fmt) (((fmt) << 21) | (func))
7072
7073enum fopcode {
7074    OPC_ADD_S = FOP(0, FMT_S),
7075    OPC_SUB_S = FOP(1, FMT_S),
7076    OPC_MUL_S = FOP(2, FMT_S),
7077    OPC_DIV_S = FOP(3, FMT_S),
7078    OPC_SQRT_S = FOP(4, FMT_S),
7079    OPC_ABS_S = FOP(5, FMT_S),
7080    OPC_MOV_S = FOP(6, FMT_S),
7081    OPC_NEG_S = FOP(7, FMT_S),
7082    OPC_ROUND_L_S = FOP(8, FMT_S),
7083    OPC_TRUNC_L_S = FOP(9, FMT_S),
7084    OPC_CEIL_L_S = FOP(10, FMT_S),
7085    OPC_FLOOR_L_S = FOP(11, FMT_S),
7086    OPC_ROUND_W_S = FOP(12, FMT_S),
7087    OPC_TRUNC_W_S = FOP(13, FMT_S),
7088    OPC_CEIL_W_S = FOP(14, FMT_S),
7089    OPC_FLOOR_W_S = FOP(15, FMT_S),
7090    OPC_MOVCF_S = FOP(17, FMT_S),
7091    OPC_MOVZ_S = FOP(18, FMT_S),
7092    OPC_MOVN_S = FOP(19, FMT_S),
7093    OPC_RECIP_S = FOP(21, FMT_S),
7094    OPC_RSQRT_S = FOP(22, FMT_S),
7095    OPC_RECIP2_S = FOP(28, FMT_S),
7096    OPC_RECIP1_S = FOP(29, FMT_S),
7097    OPC_RSQRT1_S = FOP(30, FMT_S),
7098    OPC_RSQRT2_S = FOP(31, FMT_S),
7099    OPC_CVT_D_S = FOP(33, FMT_S),
7100    OPC_CVT_W_S = FOP(36, FMT_S),
7101    OPC_CVT_L_S = FOP(37, FMT_S),
7102    OPC_CVT_PS_S = FOP(38, FMT_S),
7103    OPC_CMP_F_S = FOP (48, FMT_S),
7104    OPC_CMP_UN_S = FOP (49, FMT_S),
7105    OPC_CMP_EQ_S = FOP (50, FMT_S),
7106    OPC_CMP_UEQ_S = FOP (51, FMT_S),
7107    OPC_CMP_OLT_S = FOP (52, FMT_S),
7108    OPC_CMP_ULT_S = FOP (53, FMT_S),
7109    OPC_CMP_OLE_S = FOP (54, FMT_S),
7110    OPC_CMP_ULE_S = FOP (55, FMT_S),
7111    OPC_CMP_SF_S = FOP (56, FMT_S),
7112    OPC_CMP_NGLE_S = FOP (57, FMT_S),
7113    OPC_CMP_SEQ_S = FOP (58, FMT_S),
7114    OPC_CMP_NGL_S = FOP (59, FMT_S),
7115    OPC_CMP_LT_S = FOP (60, FMT_S),
7116    OPC_CMP_NGE_S = FOP (61, FMT_S),
7117    OPC_CMP_LE_S = FOP (62, FMT_S),
7118    OPC_CMP_NGT_S = FOP (63, FMT_S),
7119
7120    OPC_ADD_D = FOP(0, FMT_D),
7121    OPC_SUB_D = FOP(1, FMT_D),
7122    OPC_MUL_D = FOP(2, FMT_D),
7123    OPC_DIV_D = FOP(3, FMT_D),
7124    OPC_SQRT_D = FOP(4, FMT_D),
7125    OPC_ABS_D = FOP(5, FMT_D),
7126    OPC_MOV_D = FOP(6, FMT_D),
7127    OPC_NEG_D = FOP(7, FMT_D),
7128    OPC_ROUND_L_D = FOP(8, FMT_D),
7129    OPC_TRUNC_L_D = FOP(9, FMT_D),
7130    OPC_CEIL_L_D = FOP(10, FMT_D),
7131    OPC_FLOOR_L_D = FOP(11, FMT_D),
7132    OPC_ROUND_W_D = FOP(12, FMT_D),
7133    OPC_TRUNC_W_D = FOP(13, FMT_D),
7134    OPC_CEIL_W_D = FOP(14, FMT_D),
7135    OPC_FLOOR_W_D = FOP(15, FMT_D),
7136    OPC_MOVCF_D = FOP(17, FMT_D),
7137    OPC_MOVZ_D = FOP(18, FMT_D),
7138    OPC_MOVN_D = FOP(19, FMT_D),
7139    OPC_RECIP_D = FOP(21, FMT_D),
7140    OPC_RSQRT_D = FOP(22, FMT_D),
7141    OPC_RECIP2_D = FOP(28, FMT_D),
7142    OPC_RECIP1_D = FOP(29, FMT_D),
7143    OPC_RSQRT1_D = FOP(30, FMT_D),
7144    OPC_RSQRT2_D = FOP(31, FMT_D),
7145    OPC_CVT_S_D = FOP(32, FMT_D),
7146    OPC_CVT_W_D = FOP(36, FMT_D),
7147    OPC_CVT_L_D = FOP(37, FMT_D),
7148    OPC_CMP_F_D = FOP (48, FMT_D),
7149    OPC_CMP_UN_D = FOP (49, FMT_D),
7150    OPC_CMP_EQ_D = FOP (50, FMT_D),
7151    OPC_CMP_UEQ_D = FOP (51, FMT_D),
7152    OPC_CMP_OLT_D = FOP (52, FMT_D),
7153    OPC_CMP_ULT_D = FOP (53, FMT_D),
7154    OPC_CMP_OLE_D = FOP (54, FMT_D),
7155    OPC_CMP_ULE_D = FOP (55, FMT_D),
7156    OPC_CMP_SF_D = FOP (56, FMT_D),
7157    OPC_CMP_NGLE_D = FOP (57, FMT_D),
7158    OPC_CMP_SEQ_D = FOP (58, FMT_D),
7159    OPC_CMP_NGL_D = FOP (59, FMT_D),
7160    OPC_CMP_LT_D = FOP (60, FMT_D),
7161    OPC_CMP_NGE_D = FOP (61, FMT_D),
7162    OPC_CMP_LE_D = FOP (62, FMT_D),
7163    OPC_CMP_NGT_D = FOP (63, FMT_D),
7164
7165    OPC_CVT_S_W = FOP(32, FMT_W),
7166    OPC_CVT_D_W = FOP(33, FMT_W),
7167    OPC_CVT_S_L = FOP(32, FMT_L),
7168    OPC_CVT_D_L = FOP(33, FMT_L),
7169    OPC_CVT_PS_PW = FOP(38, FMT_W),
7170
7171    OPC_ADD_PS = FOP(0, FMT_PS),
7172    OPC_SUB_PS = FOP(1, FMT_PS),
7173    OPC_MUL_PS = FOP(2, FMT_PS),
7174    OPC_DIV_PS = FOP(3, FMT_PS),
7175    OPC_ABS_PS = FOP(5, FMT_PS),
7176    OPC_MOV_PS = FOP(6, FMT_PS),
7177    OPC_NEG_PS = FOP(7, FMT_PS),
7178    OPC_MOVCF_PS = FOP(17, FMT_PS),
7179    OPC_MOVZ_PS = FOP(18, FMT_PS),
7180    OPC_MOVN_PS = FOP(19, FMT_PS),
7181    OPC_ADDR_PS = FOP(24, FMT_PS),
7182    OPC_MULR_PS = FOP(26, FMT_PS),
7183    OPC_RECIP2_PS = FOP(28, FMT_PS),
7184    OPC_RECIP1_PS = FOP(29, FMT_PS),
7185    OPC_RSQRT1_PS = FOP(30, FMT_PS),
7186    OPC_RSQRT2_PS = FOP(31, FMT_PS),
7187
7188    OPC_CVT_S_PU = FOP(32, FMT_PS),
7189    OPC_CVT_PW_PS = FOP(36, FMT_PS),
7190    OPC_CVT_S_PL = FOP(40, FMT_PS),
7191    OPC_PLL_PS = FOP(44, FMT_PS),
7192    OPC_PLU_PS = FOP(45, FMT_PS),
7193    OPC_PUL_PS = FOP(46, FMT_PS),
7194    OPC_PUU_PS = FOP(47, FMT_PS),
7195    OPC_CMP_F_PS = FOP (48, FMT_PS),
7196    OPC_CMP_UN_PS = FOP (49, FMT_PS),
7197    OPC_CMP_EQ_PS = FOP (50, FMT_PS),
7198    OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
7199    OPC_CMP_OLT_PS = FOP (52, FMT_PS),
7200    OPC_CMP_ULT_PS = FOP (53, FMT_PS),
7201    OPC_CMP_OLE_PS = FOP (54, FMT_PS),
7202    OPC_CMP_ULE_PS = FOP (55, FMT_PS),
7203    OPC_CMP_SF_PS = FOP (56, FMT_PS),
7204    OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
7205    OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
7206    OPC_CMP_NGL_PS = FOP (59, FMT_PS),
7207    OPC_CMP_LT_PS = FOP (60, FMT_PS),
7208    OPC_CMP_NGE_PS = FOP (61, FMT_PS),
7209    OPC_CMP_LE_PS = FOP (62, FMT_PS),
7210    OPC_CMP_NGT_PS = FOP (63, FMT_PS),
7211};
7212
7213static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
7214{
7215    const char *opn = "cp1 move";
7216    TCGv t0 = tcg_temp_new();
7217
7218    switch (opc) {
7219    case OPC_MFC1:
7220        {
7221            TCGv_i32 fp0 = tcg_temp_new_i32();
7222
7223            gen_load_fpr32(fp0, fs);
7224            tcg_gen_ext_i32_tl(t0, fp0);
7225            tcg_temp_free_i32(fp0);
7226        }
7227        gen_store_gpr(t0, rt);
7228        opn = "mfc1";
7229        break;
7230    case OPC_MTC1:
7231        gen_load_gpr(t0, rt);
7232        {
7233            TCGv_i32 fp0 = tcg_temp_new_i32();
7234
7235            tcg_gen_trunc_tl_i32(fp0, t0);
7236            gen_store_fpr32(fp0, fs);
7237            tcg_temp_free_i32(fp0);
7238        }
7239        opn = "mtc1";
7240        break;
7241    case OPC_CFC1:
7242        gen_helper_1e0i(cfc1, t0, fs);
7243        gen_store_gpr(t0, rt);
7244        opn = "cfc1";
7245        break;
7246    case OPC_CTC1:
7247        gen_load_gpr(t0, rt);
7248        gen_helper_0e1i(ctc1, t0, fs);
7249        opn = "ctc1";
7250        break;
7251#if defined(TARGET_MIPS64)
7252    case OPC_DMFC1:
7253        gen_load_fpr64(ctx, t0, fs);
7254        gen_store_gpr(t0, rt);
7255        opn = "dmfc1";
7256        break;
7257    case OPC_DMTC1:
7258        gen_load_gpr(t0, rt);
7259        gen_store_fpr64(ctx, t0, fs);
7260        opn = "dmtc1";
7261        break;
7262#endif
7263    case OPC_MFHC1:
7264        {
7265            TCGv_i32 fp0 = tcg_temp_new_i32();
7266
7267            gen_load_fpr32h(fp0, fs);
7268            tcg_gen_ext_i32_tl(t0, fp0);
7269            tcg_temp_free_i32(fp0);
7270        }
7271        gen_store_gpr(t0, rt);
7272        opn = "mfhc1";
7273        break;
7274    case OPC_MTHC1:
7275        gen_load_gpr(t0, rt);
7276        {
7277            TCGv_i32 fp0 = tcg_temp_new_i32();
7278
7279            tcg_gen_trunc_tl_i32(fp0, t0);
7280            gen_store_fpr32h(fp0, fs);
7281            tcg_temp_free_i32(fp0);
7282        }
7283        opn = "mthc1";
7284        break;
7285    default:
7286        MIPS_INVAL(opn);
7287        generate_exception (ctx, EXCP_RI);
7288        goto out;
7289    }
7290    (void)opn; /* avoid a compiler warning */
7291    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
7292
7293 out:
7294    tcg_temp_free(t0);
7295}
7296
7297static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
7298{
7299    int l1;
7300    TCGCond cond;
7301    TCGv_i32 t0;
7302
7303    if (rd == 0) {
7304        /* Treat as NOP. */
7305        return;
7306    }
7307
7308    if (tf)
7309        cond = TCG_COND_EQ;
7310    else
7311        cond = TCG_COND_NE;
7312
7313    l1 = gen_new_label();
7314    t0 = tcg_temp_new_i32();
7315    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7316    tcg_gen_brcondi_i32(cond, t0, 0, l1);
7317    tcg_temp_free_i32(t0);
7318    if (rs == 0) {
7319        tcg_gen_movi_tl(cpu_gpr[rd], 0);
7320    } else {
7321        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
7322    }
7323    gen_set_label(l1);
7324}
7325
7326static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
7327{
7328    int cond;
7329    TCGv_i32 t0 = tcg_temp_new_i32();
7330    int l1 = gen_new_label();
7331
7332    if (tf)
7333        cond = TCG_COND_EQ;
7334    else
7335        cond = TCG_COND_NE;
7336
7337    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7338    tcg_gen_brcondi_i32(cond, t0, 0, l1);
7339    gen_load_fpr32(t0, fs);
7340    gen_store_fpr32(t0, fd);
7341    gen_set_label(l1);
7342    tcg_temp_free_i32(t0);
7343}
7344
7345static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
7346{
7347    int cond;
7348    TCGv_i32 t0 = tcg_temp_new_i32();
7349    TCGv_i64 fp0;
7350    int l1 = gen_new_label();
7351
7352    if (tf)
7353        cond = TCG_COND_EQ;
7354    else
7355        cond = TCG_COND_NE;
7356
7357    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7358    tcg_gen_brcondi_i32(cond, t0, 0, l1);
7359    tcg_temp_free_i32(t0);
7360    fp0 = tcg_temp_new_i64();
7361    gen_load_fpr64(ctx, fp0, fs);
7362    gen_store_fpr64(ctx, fp0, fd);
7363    tcg_temp_free_i64(fp0);
7364    gen_set_label(l1);
7365}
7366
7367static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
7368{
7369    int cond;
7370    TCGv_i32 t0 = tcg_temp_new_i32();
7371    int l1 = gen_new_label();
7372    int l2 = gen_new_label();
7373
7374    if (tf)
7375        cond = TCG_COND_EQ;
7376    else
7377        cond = TCG_COND_NE;
7378
7379    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
7380    tcg_gen_brcondi_i32(cond, t0, 0, l1);
7381    gen_load_fpr32(t0, fs);
7382    gen_store_fpr32(t0, fd);
7383    gen_set_label(l1);
7384
7385    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
7386    tcg_gen_brcondi_i32(cond, t0, 0, l2);
7387    gen_load_fpr32h(t0, fs);
7388    gen_store_fpr32h(t0, fd);
7389    tcg_temp_free_i32(t0);
7390    gen_set_label(l2);
7391}
7392
7393
7394static void gen_farith (DisasContext *ctx, enum fopcode op1,
7395                        int ft, int fs, int fd, int cc)
7396{
7397    const char *opn = "farith";
7398    const char *condnames[] = {
7399            "c.f",
7400            "c.un",
7401            "c.eq",
7402            "c.ueq",
7403            "c.olt",
7404            "c.ult",
7405            "c.ole",
7406            "c.ule",
7407            "c.sf",
7408            "c.ngle",
7409            "c.seq",
7410            "c.ngl",
7411            "c.lt",
7412            "c.nge",
7413            "c.le",
7414            "c.ngt",
7415    };
7416    const char *condnames_abs[] = {
7417            "cabs.f",
7418            "cabs.un",
7419            "cabs.eq",
7420            "cabs.ueq",
7421            "cabs.olt",
7422            "cabs.ult",
7423            "cabs.ole",
7424            "cabs.ule",
7425            "cabs.sf",
7426            "cabs.ngle",
7427            "cabs.seq",
7428            "cabs.ngl",
7429            "cabs.lt",
7430            "cabs.nge",
7431            "cabs.le",
7432            "cabs.ngt",
7433    };
7434    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
7435    uint32_t func = ctx->opcode & 0x3f;
7436
7437    switch (op1) {
7438    case OPC_ADD_S:
7439        {
7440            TCGv_i32 fp0 = tcg_temp_new_i32();
7441            TCGv_i32 fp1 = tcg_temp_new_i32();
7442
7443            gen_load_fpr32(fp0, fs);
7444            gen_load_fpr32(fp1, ft);
7445            gen_helper_float_add_s(fp0, cpu_env, fp0, fp1);
7446            tcg_temp_free_i32(fp1);
7447            gen_store_fpr32(fp0, fd);
7448            tcg_temp_free_i32(fp0);
7449        }
7450        opn = "add.s";
7451        optype = BINOP;
7452        break;
7453    case OPC_SUB_S:
7454        {
7455            TCGv_i32 fp0 = tcg_temp_new_i32();
7456            TCGv_i32 fp1 = tcg_temp_new_i32();
7457
7458            gen_load_fpr32(fp0, fs);
7459            gen_load_fpr32(fp1, ft);
7460            gen_helper_float_sub_s(fp0, cpu_env, fp0, fp1);
7461            tcg_temp_free_i32(fp1);
7462            gen_store_fpr32(fp0, fd);
7463            tcg_temp_free_i32(fp0);
7464        }
7465        opn = "sub.s";
7466        optype = BINOP;
7467        break;
7468    case OPC_MUL_S:
7469        {
7470            TCGv_i32 fp0 = tcg_temp_new_i32();
7471            TCGv_i32 fp1 = tcg_temp_new_i32();
7472
7473            gen_load_fpr32(fp0, fs);
7474            gen_load_fpr32(fp1, ft);
7475            gen_helper_float_mul_s(fp0, cpu_env, fp0, fp1);
7476            tcg_temp_free_i32(fp1);
7477            gen_store_fpr32(fp0, fd);
7478            tcg_temp_free_i32(fp0);
7479        }
7480        opn = "mul.s";
7481        optype = BINOP;
7482        break;
7483    case OPC_DIV_S:
7484        {
7485            TCGv_i32 fp0 = tcg_temp_new_i32();
7486            TCGv_i32 fp1 = tcg_temp_new_i32();
7487
7488            gen_load_fpr32(fp0, fs);
7489            gen_load_fpr32(fp1, ft);
7490            gen_helper_float_div_s(fp0, cpu_env, fp0, fp1);
7491            tcg_temp_free_i32(fp1);
7492            gen_store_fpr32(fp0, fd);
7493            tcg_temp_free_i32(fp0);
7494        }
7495        opn = "div.s";
7496        optype = BINOP;
7497        break;
7498    case OPC_SQRT_S:
7499        {
7500            TCGv_i32 fp0 = tcg_temp_new_i32();
7501
7502            gen_load_fpr32(fp0, fs);
7503            gen_helper_float_sqrt_s(fp0, cpu_env, fp0);
7504            gen_store_fpr32(fp0, fd);
7505            tcg_temp_free_i32(fp0);
7506        }
7507        opn = "sqrt.s";
7508        break;
7509    case OPC_ABS_S:
7510        {
7511            TCGv_i32 fp0 = tcg_temp_new_i32();
7512
7513            gen_load_fpr32(fp0, fs);
7514            gen_helper_float_abs_s(fp0, fp0);
7515            gen_store_fpr32(fp0, fd);
7516            tcg_temp_free_i32(fp0);
7517        }
7518        opn = "abs.s";
7519        break;
7520    case OPC_MOV_S:
7521        {
7522            TCGv_i32 fp0 = tcg_temp_new_i32();
7523
7524            gen_load_fpr32(fp0, fs);
7525            gen_store_fpr32(fp0, fd);
7526            tcg_temp_free_i32(fp0);
7527        }
7528        opn = "mov.s";
7529        break;
7530    case OPC_NEG_S:
7531        {
7532            TCGv_i32 fp0 = tcg_temp_new_i32();
7533
7534            gen_load_fpr32(fp0, fs);
7535            gen_helper_float_chs_s(fp0, fp0);
7536            gen_store_fpr32(fp0, fd);
7537            tcg_temp_free_i32(fp0);
7538        }
7539        opn = "neg.s";
7540        break;
7541    case OPC_ROUND_L_S:
7542        check_cp1_64bitmode(ctx);
7543        {
7544            TCGv_i32 fp32 = tcg_temp_new_i32();
7545            TCGv_i64 fp64 = tcg_temp_new_i64();
7546
7547            gen_load_fpr32(fp32, fs);
7548            gen_helper_float_roundl_s(fp64, cpu_env, fp32);
7549            tcg_temp_free_i32(fp32);
7550            gen_store_fpr64(ctx, fp64, fd);
7551            tcg_temp_free_i64(fp64);
7552        }
7553        opn = "round.l.s";
7554        break;
7555    case OPC_TRUNC_L_S:
7556        check_cp1_64bitmode(ctx);
7557        {
7558            TCGv_i32 fp32 = tcg_temp_new_i32();
7559            TCGv_i64 fp64 = tcg_temp_new_i64();
7560
7561            gen_load_fpr32(fp32, fs);
7562            gen_helper_float_truncl_s(fp64, cpu_env, fp32);
7563            tcg_temp_free_i32(fp32);
7564            gen_store_fpr64(ctx, fp64, fd);
7565            tcg_temp_free_i64(fp64);
7566        }
7567        opn = "trunc.l.s";
7568        break;
7569    case OPC_CEIL_L_S:
7570        check_cp1_64bitmode(ctx);
7571        {
7572            TCGv_i32 fp32 = tcg_temp_new_i32();
7573            TCGv_i64 fp64 = tcg_temp_new_i64();
7574
7575            gen_load_fpr32(fp32, fs);
7576            gen_helper_float_ceill_s(fp64, cpu_env, fp32);
7577            tcg_temp_free_i32(fp32);
7578            gen_store_fpr64(ctx, fp64, fd);
7579            tcg_temp_free_i64(fp64);
7580        }
7581        opn = "ceil.l.s";
7582        break;
7583    case OPC_FLOOR_L_S:
7584        check_cp1_64bitmode(ctx);
7585        {
7586            TCGv_i32 fp32 = tcg_temp_new_i32();
7587            TCGv_i64 fp64 = tcg_temp_new_i64();
7588
7589            gen_load_fpr32(fp32, fs);
7590            gen_helper_float_floorl_s(fp64, cpu_env, fp32);
7591            tcg_temp_free_i32(fp32);
7592            gen_store_fpr64(ctx, fp64, fd);
7593            tcg_temp_free_i64(fp64);
7594        }
7595        opn = "floor.l.s";
7596        break;
7597    case OPC_ROUND_W_S:
7598        {
7599            TCGv_i32 fp0 = tcg_temp_new_i32();
7600
7601            gen_load_fpr32(fp0, fs);
7602            gen_helper_float_roundw_s(fp0, cpu_env, fp0);
7603            gen_store_fpr32(fp0, fd);
7604            tcg_temp_free_i32(fp0);
7605        }
7606        opn = "round.w.s";
7607        break;
7608    case OPC_TRUNC_W_S:
7609        {
7610            TCGv_i32 fp0 = tcg_temp_new_i32();
7611
7612            gen_load_fpr32(fp0, fs);
7613            gen_helper_float_truncw_s(fp0, cpu_env, fp0);
7614            gen_store_fpr32(fp0, fd);
7615            tcg_temp_free_i32(fp0);
7616        }
7617        opn = "trunc.w.s";
7618        break;
7619    case OPC_CEIL_W_S:
7620        {
7621            TCGv_i32 fp0 = tcg_temp_new_i32();
7622
7623            gen_load_fpr32(fp0, fs);
7624            gen_helper_float_ceilw_s(fp0, cpu_env, fp0);
7625            gen_store_fpr32(fp0, fd);
7626            tcg_temp_free_i32(fp0);
7627        }
7628        opn = "ceil.w.s";
7629        break;
7630    case OPC_FLOOR_W_S:
7631        {
7632            TCGv_i32 fp0 = tcg_temp_new_i32();
7633
7634            gen_load_fpr32(fp0, fs);
7635            gen_helper_float_floorw_s(fp0, cpu_env, fp0);
7636            gen_store_fpr32(fp0, fd);
7637            tcg_temp_free_i32(fp0);
7638        }
7639        opn = "floor.w.s";
7640        break;
7641    case OPC_MOVCF_S:
7642        gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
7643        opn = "movcf.s";
7644        break;
7645    case OPC_MOVZ_S:
7646        {
7647            int l1 = gen_new_label();
7648            TCGv_i32 fp0;
7649
7650            if (ft != 0) {
7651                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
7652            }
7653            fp0 = tcg_temp_new_i32();
7654            gen_load_fpr32(fp0, fs);
7655            gen_store_fpr32(fp0, fd);
7656            tcg_temp_free_i32(fp0);
7657            gen_set_label(l1);
7658        }
7659        opn = "movz.s";
7660        break;
7661    case OPC_MOVN_S:
7662        {
7663            int l1 = gen_new_label();
7664            TCGv_i32 fp0;
7665
7666            if (ft != 0) {
7667                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7668                fp0 = tcg_temp_new_i32();
7669                gen_load_fpr32(fp0, fs);
7670                gen_store_fpr32(fp0, fd);
7671                tcg_temp_free_i32(fp0);
7672                gen_set_label(l1);
7673            }
7674        }
7675        opn = "movn.s";
7676        break;
7677    case OPC_RECIP_S:
7678        check_cop1x(ctx);
7679        {
7680            TCGv_i32 fp0 = tcg_temp_new_i32();
7681
7682            gen_load_fpr32(fp0, fs);
7683            gen_helper_float_recip_s(fp0, cpu_env, fp0);
7684            gen_store_fpr32(fp0, fd);
7685            tcg_temp_free_i32(fp0);
7686        }
7687        opn = "recip.s";
7688        break;
7689    case OPC_RSQRT_S:
7690        check_cop1x(ctx);
7691        {
7692            TCGv_i32 fp0 = tcg_temp_new_i32();
7693
7694            gen_load_fpr32(fp0, fs);
7695            gen_helper_float_rsqrt_s(fp0, cpu_env, fp0);
7696            gen_store_fpr32(fp0, fd);
7697            tcg_temp_free_i32(fp0);
7698        }
7699        opn = "rsqrt.s";
7700        break;
7701    case OPC_RECIP2_S:
7702        check_cp1_64bitmode(ctx);
7703        {
7704            TCGv_i32 fp0 = tcg_temp_new_i32();
7705            TCGv_i32 fp1 = tcg_temp_new_i32();
7706
7707            gen_load_fpr32(fp0, fs);
7708            gen_load_fpr32(fp1, ft);
7709            gen_helper_float_recip2_s(fp0, cpu_env, fp0, fp1);
7710            tcg_temp_free_i32(fp1);
7711            gen_store_fpr32(fp0, fd);
7712            tcg_temp_free_i32(fp0);
7713        }
7714        opn = "recip2.s";
7715        break;
7716    case OPC_RECIP1_S:
7717        check_cp1_64bitmode(ctx);
7718        {
7719            TCGv_i32 fp0 = tcg_temp_new_i32();
7720
7721            gen_load_fpr32(fp0, fs);
7722            gen_helper_float_recip1_s(fp0, cpu_env, fp0);
7723            gen_store_fpr32(fp0, fd);
7724            tcg_temp_free_i32(fp0);
7725        }
7726        opn = "recip1.s";
7727        break;
7728    case OPC_RSQRT1_S:
7729        check_cp1_64bitmode(ctx);
7730        {
7731            TCGv_i32 fp0 = tcg_temp_new_i32();
7732
7733            gen_load_fpr32(fp0, fs);
7734            gen_helper_float_rsqrt1_s(fp0, cpu_env, fp0);
7735            gen_store_fpr32(fp0, fd);
7736            tcg_temp_free_i32(fp0);
7737        }
7738        opn = "rsqrt1.s";
7739        break;
7740    case OPC_RSQRT2_S:
7741        check_cp1_64bitmode(ctx);
7742        {
7743            TCGv_i32 fp0 = tcg_temp_new_i32();
7744            TCGv_i32 fp1 = tcg_temp_new_i32();
7745
7746            gen_load_fpr32(fp0, fs);
7747            gen_load_fpr32(fp1, ft);
7748            gen_helper_float_rsqrt2_s(fp0, cpu_env, fp0, fp1);
7749            tcg_temp_free_i32(fp1);
7750            gen_store_fpr32(fp0, fd);
7751            tcg_temp_free_i32(fp0);
7752        }
7753        opn = "rsqrt2.s";
7754        break;
7755    case OPC_CVT_D_S:
7756        check_cp1_registers(ctx, fd);
7757        {
7758            TCGv_i32 fp32 = tcg_temp_new_i32();
7759            TCGv_i64 fp64 = tcg_temp_new_i64();
7760
7761            gen_load_fpr32(fp32, fs);
7762            gen_helper_float_cvtd_s(fp64, cpu_env, fp32);
7763            tcg_temp_free_i32(fp32);
7764            gen_store_fpr64(ctx, fp64, fd);
7765            tcg_temp_free_i64(fp64);
7766        }
7767        opn = "cvt.d.s";
7768        break;
7769    case OPC_CVT_W_S:
7770        {
7771            TCGv_i32 fp0 = tcg_temp_new_i32();
7772
7773            gen_load_fpr32(fp0, fs);
7774            gen_helper_float_cvtw_s(fp0, cpu_env, fp0);
7775            gen_store_fpr32(fp0, fd);
7776            tcg_temp_free_i32(fp0);
7777        }
7778        opn = "cvt.w.s";
7779        break;
7780    case OPC_CVT_L_S:
7781        check_cp1_64bitmode(ctx);
7782        {
7783            TCGv_i32 fp32 = tcg_temp_new_i32();
7784            TCGv_i64 fp64 = tcg_temp_new_i64();
7785
7786            gen_load_fpr32(fp32, fs);
7787            gen_helper_float_cvtl_s(fp64, cpu_env, fp32);
7788            tcg_temp_free_i32(fp32);
7789            gen_store_fpr64(ctx, fp64, fd);
7790            tcg_temp_free_i64(fp64);
7791        }
7792        opn = "cvt.l.s";
7793        break;
7794    case OPC_CVT_PS_S:
7795        check_cp1_64bitmode(ctx);
7796        {
7797            TCGv_i64 fp64 = tcg_temp_new_i64();
7798            TCGv_i32 fp32_0 = tcg_temp_new_i32();
7799            TCGv_i32 fp32_1 = tcg_temp_new_i32();
7800
7801            gen_load_fpr32(fp32_0, fs);
7802            gen_load_fpr32(fp32_1, ft);
7803            tcg_gen_concat_i32_i64(fp64, fp32_1, fp32_0);
7804            tcg_temp_free_i32(fp32_1);
7805            tcg_temp_free_i32(fp32_0);
7806            gen_store_fpr64(ctx, fp64, fd);
7807            tcg_temp_free_i64(fp64);
7808        }
7809        opn = "cvt.ps.s";
7810        break;
7811    case OPC_CMP_F_S:
7812    case OPC_CMP_UN_S:
7813    case OPC_CMP_EQ_S:
7814    case OPC_CMP_UEQ_S:
7815    case OPC_CMP_OLT_S:
7816    case OPC_CMP_ULT_S:
7817    case OPC_CMP_OLE_S:
7818    case OPC_CMP_ULE_S:
7819    case OPC_CMP_SF_S:
7820    case OPC_CMP_NGLE_S:
7821    case OPC_CMP_SEQ_S:
7822    case OPC_CMP_NGL_S:
7823    case OPC_CMP_LT_S:
7824    case OPC_CMP_NGE_S:
7825    case OPC_CMP_LE_S:
7826    case OPC_CMP_NGT_S:
7827        if (ctx->opcode & (1 << 6)) {
7828            gen_cmpabs_s(ctx, func-48, ft, fs, cc);
7829            opn = condnames_abs[func-48];
7830        } else {
7831            gen_cmp_s(ctx, func-48, ft, fs, cc);
7832            opn = condnames[func-48];
7833        }
7834        break;
7835    case OPC_ADD_D:
7836        check_cp1_registers(ctx, fs | ft | fd);
7837        {
7838            TCGv_i64 fp0 = tcg_temp_new_i64();
7839            TCGv_i64 fp1 = tcg_temp_new_i64();
7840
7841            gen_load_fpr64(ctx, fp0, fs);
7842            gen_load_fpr64(ctx, fp1, ft);
7843            gen_helper_float_add_d(fp0, cpu_env, fp0, fp1);
7844            tcg_temp_free_i64(fp1);
7845            gen_store_fpr64(ctx, fp0, fd);
7846            tcg_temp_free_i64(fp0);
7847        }
7848        opn = "add.d";
7849        optype = BINOP;
7850        break;
7851    case OPC_SUB_D:
7852        check_cp1_registers(ctx, fs | ft | fd);
7853        {
7854            TCGv_i64 fp0 = tcg_temp_new_i64();
7855            TCGv_i64 fp1 = tcg_temp_new_i64();
7856
7857            gen_load_fpr64(ctx, fp0, fs);
7858            gen_load_fpr64(ctx, fp1, ft);
7859            gen_helper_float_sub_d(fp0, cpu_env, fp0, fp1);
7860            tcg_temp_free_i64(fp1);
7861            gen_store_fpr64(ctx, fp0, fd);
7862            tcg_temp_free_i64(fp0);
7863        }
7864        opn = "sub.d";
7865        optype = BINOP;
7866        break;
7867    case OPC_MUL_D:
7868        check_cp1_registers(ctx, fs | ft | fd);
7869        {
7870            TCGv_i64 fp0 = tcg_temp_new_i64();
7871            TCGv_i64 fp1 = tcg_temp_new_i64();
7872
7873            gen_load_fpr64(ctx, fp0, fs);
7874            gen_load_fpr64(ctx, fp1, ft);
7875            gen_helper_float_mul_d(fp0, cpu_env, fp0, fp1);
7876            tcg_temp_free_i64(fp1);
7877            gen_store_fpr64(ctx, fp0, fd);
7878            tcg_temp_free_i64(fp0);
7879        }
7880        opn = "mul.d";
7881        optype = BINOP;
7882        break;
7883    case OPC_DIV_D:
7884        check_cp1_registers(ctx, fs | ft | fd);
7885        {
7886            TCGv_i64 fp0 = tcg_temp_new_i64();
7887            TCGv_i64 fp1 = tcg_temp_new_i64();
7888
7889            gen_load_fpr64(ctx, fp0, fs);
7890            gen_load_fpr64(ctx, fp1, ft);
7891            gen_helper_float_div_d(fp0, cpu_env, fp0, fp1);
7892            tcg_temp_free_i64(fp1);
7893            gen_store_fpr64(ctx, fp0, fd);
7894            tcg_temp_free_i64(fp0);
7895        }
7896        opn = "div.d";
7897        optype = BINOP;
7898        break;
7899    case OPC_SQRT_D:
7900        check_cp1_registers(ctx, fs | fd);
7901        {
7902            TCGv_i64 fp0 = tcg_temp_new_i64();
7903
7904            gen_load_fpr64(ctx, fp0, fs);
7905            gen_helper_float_sqrt_d(fp0, cpu_env, fp0);
7906            gen_store_fpr64(ctx, fp0, fd);
7907            tcg_temp_free_i64(fp0);
7908        }
7909        opn = "sqrt.d";
7910        break;
7911    case OPC_ABS_D:
7912        check_cp1_registers(ctx, fs | fd);
7913        {
7914            TCGv_i64 fp0 = tcg_temp_new_i64();
7915
7916            gen_load_fpr64(ctx, fp0, fs);
7917            gen_helper_float_abs_d(fp0, fp0);
7918            gen_store_fpr64(ctx, fp0, fd);
7919            tcg_temp_free_i64(fp0);
7920        }
7921        opn = "abs.d";
7922        break;
7923    case OPC_MOV_D:
7924        check_cp1_registers(ctx, fs | fd);
7925        {
7926            TCGv_i64 fp0 = tcg_temp_new_i64();
7927
7928            gen_load_fpr64(ctx, fp0, fs);
7929            gen_store_fpr64(ctx, fp0, fd);
7930            tcg_temp_free_i64(fp0);
7931        }
7932        opn = "mov.d";
7933        break;
7934    case OPC_NEG_D:
7935        check_cp1_registers(ctx, fs | fd);
7936        {
7937            TCGv_i64 fp0 = tcg_temp_new_i64();
7938
7939            gen_load_fpr64(ctx, fp0, fs);
7940            gen_helper_float_chs_d(fp0, fp0);
7941            gen_store_fpr64(ctx, fp0, fd);
7942            tcg_temp_free_i64(fp0);
7943        }
7944        opn = "neg.d";
7945        break;
7946    case OPC_ROUND_L_D:
7947        check_cp1_64bitmode(ctx);
7948        {
7949            TCGv_i64 fp0 = tcg_temp_new_i64();
7950
7951            gen_load_fpr64(ctx, fp0, fs);
7952            gen_helper_float_roundl_d(fp0, cpu_env, fp0);
7953            gen_store_fpr64(ctx, fp0, fd);
7954            tcg_temp_free_i64(fp0);
7955        }
7956        opn = "round.l.d";
7957        break;
7958    case OPC_TRUNC_L_D:
7959        check_cp1_64bitmode(ctx);
7960        {
7961            TCGv_i64 fp0 = tcg_temp_new_i64();
7962
7963            gen_load_fpr64(ctx, fp0, fs);
7964            gen_helper_float_truncl_d(fp0, cpu_env, fp0);
7965            gen_store_fpr64(ctx, fp0, fd);
7966            tcg_temp_free_i64(fp0);
7967        }
7968        opn = "trunc.l.d";
7969        break;
7970    case OPC_CEIL_L_D:
7971        check_cp1_64bitmode(ctx);
7972        {
7973            TCGv_i64 fp0 = tcg_temp_new_i64();
7974
7975            gen_load_fpr64(ctx, fp0, fs);
7976            gen_helper_float_ceill_d(fp0, cpu_env, fp0);
7977            gen_store_fpr64(ctx, fp0, fd);
7978            tcg_temp_free_i64(fp0);
7979        }
7980        opn = "ceil.l.d";
7981        break;
7982    case OPC_FLOOR_L_D:
7983        check_cp1_64bitmode(ctx);
7984        {
7985            TCGv_i64 fp0 = tcg_temp_new_i64();
7986
7987            gen_load_fpr64(ctx, fp0, fs);
7988            gen_helper_float_floorl_d(fp0, cpu_env, fp0);
7989            gen_store_fpr64(ctx, fp0, fd);
7990            tcg_temp_free_i64(fp0);
7991        }
7992        opn = "floor.l.d";
7993        break;
7994    case OPC_ROUND_W_D:
7995        check_cp1_registers(ctx, fs);
7996        {
7997            TCGv_i32 fp32 = tcg_temp_new_i32();
7998            TCGv_i64 fp64 = tcg_temp_new_i64();
7999
8000            gen_load_fpr64(ctx, fp64, fs);
8001            gen_helper_float_roundw_d(fp32, cpu_env, fp64);
8002            tcg_temp_free_i64(fp64);
8003            gen_store_fpr32(fp32, fd);
8004            tcg_temp_free_i32(fp32);
8005        }
8006        opn = "round.w.d";
8007        break;
8008    case OPC_TRUNC_W_D:
8009        check_cp1_registers(ctx, fs);
8010        {
8011            TCGv_i32 fp32 = tcg_temp_new_i32();
8012            TCGv_i64 fp64 = tcg_temp_new_i64();
8013
8014            gen_load_fpr64(ctx, fp64, fs);
8015            gen_helper_float_truncw_d(fp32, cpu_env, fp64);
8016            tcg_temp_free_i64(fp64);
8017            gen_store_fpr32(fp32, fd);
8018            tcg_temp_free_i32(fp32);
8019        }
8020        opn = "trunc.w.d";
8021        break;
8022    case OPC_CEIL_W_D:
8023        check_cp1_registers(ctx, fs);
8024        {
8025            TCGv_i32 fp32 = tcg_temp_new_i32();
8026            TCGv_i64 fp64 = tcg_temp_new_i64();
8027
8028            gen_load_fpr64(ctx, fp64, fs);
8029            gen_helper_float_ceilw_d(fp32, cpu_env, fp64);
8030            tcg_temp_free_i64(fp64);
8031            gen_store_fpr32(fp32, fd);
8032            tcg_temp_free_i32(fp32);
8033        }
8034        opn = "ceil.w.d";
8035        break;
8036    case OPC_FLOOR_W_D:
8037        check_cp1_registers(ctx, fs);
8038        {
8039            TCGv_i32 fp32 = tcg_temp_new_i32();
8040            TCGv_i64 fp64 = tcg_temp_new_i64();
8041
8042            gen_load_fpr64(ctx, fp64, fs);
8043            gen_helper_float_floorw_d(fp32, cpu_env, fp64);
8044            tcg_temp_free_i64(fp64);
8045            gen_store_fpr32(fp32, fd);
8046            tcg_temp_free_i32(fp32);
8047        }
8048        opn = "floor.w.d";
8049        break;
8050    case OPC_MOVCF_D:
8051        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8052        opn = "movcf.d";
8053        break;
8054    case OPC_MOVZ_D:
8055        {
8056            int l1 = gen_new_label();
8057            TCGv_i64 fp0;
8058
8059            if (ft != 0) {
8060                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8061            }
8062            fp0 = tcg_temp_new_i64();
8063            gen_load_fpr64(ctx, fp0, fs);
8064            gen_store_fpr64(ctx, fp0, fd);
8065            tcg_temp_free_i64(fp0);
8066            gen_set_label(l1);
8067        }
8068        opn = "movz.d";
8069        break;
8070    case OPC_MOVN_D:
8071        {
8072            int l1 = gen_new_label();
8073            TCGv_i64 fp0;
8074
8075            if (ft != 0) {
8076                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8077                fp0 = tcg_temp_new_i64();
8078                gen_load_fpr64(ctx, fp0, fs);
8079                gen_store_fpr64(ctx, fp0, fd);
8080                tcg_temp_free_i64(fp0);
8081                gen_set_label(l1);
8082            }
8083        }
8084        opn = "movn.d";
8085        break;
8086    case OPC_RECIP_D:
8087        check_cp1_64bitmode(ctx);
8088        {
8089            TCGv_i64 fp0 = tcg_temp_new_i64();
8090
8091            gen_load_fpr64(ctx, fp0, fs);
8092            gen_helper_float_recip_d(fp0, cpu_env, fp0);
8093            gen_store_fpr64(ctx, fp0, fd);
8094            tcg_temp_free_i64(fp0);
8095        }
8096        opn = "recip.d";
8097        break;
8098    case OPC_RSQRT_D:
8099        check_cp1_64bitmode(ctx);
8100        {
8101            TCGv_i64 fp0 = tcg_temp_new_i64();
8102
8103            gen_load_fpr64(ctx, fp0, fs);
8104            gen_helper_float_rsqrt_d(fp0, cpu_env, fp0);
8105            gen_store_fpr64(ctx, fp0, fd);
8106            tcg_temp_free_i64(fp0);
8107        }
8108        opn = "rsqrt.d";
8109        break;
8110    case OPC_RECIP2_D:
8111        check_cp1_64bitmode(ctx);
8112        {
8113            TCGv_i64 fp0 = tcg_temp_new_i64();
8114            TCGv_i64 fp1 = tcg_temp_new_i64();
8115
8116            gen_load_fpr64(ctx, fp0, fs);
8117            gen_load_fpr64(ctx, fp1, ft);
8118            gen_helper_float_recip2_d(fp0, cpu_env, fp0, fp1);
8119            tcg_temp_free_i64(fp1);
8120            gen_store_fpr64(ctx, fp0, fd);
8121            tcg_temp_free_i64(fp0);
8122        }
8123        opn = "recip2.d";
8124        break;
8125    case OPC_RECIP1_D:
8126        check_cp1_64bitmode(ctx);
8127        {
8128            TCGv_i64 fp0 = tcg_temp_new_i64();
8129
8130            gen_load_fpr64(ctx, fp0, fs);
8131            gen_helper_float_recip1_d(fp0, cpu_env, fp0);
8132            gen_store_fpr64(ctx, fp0, fd);
8133            tcg_temp_free_i64(fp0);
8134        }
8135        opn = "recip1.d";
8136        break;
8137    case OPC_RSQRT1_D:
8138        check_cp1_64bitmode(ctx);
8139        {
8140            TCGv_i64 fp0 = tcg_temp_new_i64();
8141
8142            gen_load_fpr64(ctx, fp0, fs);
8143            gen_helper_float_rsqrt1_d(fp0, cpu_env, fp0);
8144            gen_store_fpr64(ctx, fp0, fd);
8145            tcg_temp_free_i64(fp0);
8146        }
8147        opn = "rsqrt1.d";
8148        break;
8149    case OPC_RSQRT2_D:
8150        check_cp1_64bitmode(ctx);
8151        {
8152            TCGv_i64 fp0 = tcg_temp_new_i64();
8153            TCGv_i64 fp1 = tcg_temp_new_i64();
8154
8155            gen_load_fpr64(ctx, fp0, fs);
8156            gen_load_fpr64(ctx, fp1, ft);
8157            gen_helper_float_rsqrt2_d(fp0, cpu_env, fp0, fp1);
8158            tcg_temp_free_i64(fp1);
8159            gen_store_fpr64(ctx, fp0, fd);
8160            tcg_temp_free_i64(fp0);
8161        }
8162        opn = "rsqrt2.d";
8163        break;
8164    case OPC_CMP_F_D:
8165    case OPC_CMP_UN_D:
8166    case OPC_CMP_EQ_D:
8167    case OPC_CMP_UEQ_D:
8168    case OPC_CMP_OLT_D:
8169    case OPC_CMP_ULT_D:
8170    case OPC_CMP_OLE_D:
8171    case OPC_CMP_ULE_D:
8172    case OPC_CMP_SF_D:
8173    case OPC_CMP_NGLE_D:
8174    case OPC_CMP_SEQ_D:
8175    case OPC_CMP_NGL_D:
8176    case OPC_CMP_LT_D:
8177    case OPC_CMP_NGE_D:
8178    case OPC_CMP_LE_D:
8179    case OPC_CMP_NGT_D:
8180        if (ctx->opcode & (1 << 6)) {
8181            gen_cmpabs_d(ctx, func-48, ft, fs, cc);
8182            opn = condnames_abs[func-48];
8183        } else {
8184            gen_cmp_d(ctx, func-48, ft, fs, cc);
8185            opn = condnames[func-48];
8186        }
8187        break;
8188    case OPC_CVT_S_D:
8189        check_cp1_registers(ctx, fs);
8190        {
8191            TCGv_i32 fp32 = tcg_temp_new_i32();
8192            TCGv_i64 fp64 = tcg_temp_new_i64();
8193
8194            gen_load_fpr64(ctx, fp64, fs);
8195            gen_helper_float_cvts_d(fp32, cpu_env, fp64);
8196            tcg_temp_free_i64(fp64);
8197            gen_store_fpr32(fp32, fd);
8198            tcg_temp_free_i32(fp32);
8199        }
8200        opn = "cvt.s.d";
8201        break;
8202    case OPC_CVT_W_D:
8203        check_cp1_registers(ctx, fs);
8204        {
8205            TCGv_i32 fp32 = tcg_temp_new_i32();
8206            TCGv_i64 fp64 = tcg_temp_new_i64();
8207
8208            gen_load_fpr64(ctx, fp64, fs);
8209            gen_helper_float_cvtw_d(fp32, cpu_env, fp64);
8210            tcg_temp_free_i64(fp64);
8211            gen_store_fpr32(fp32, fd);
8212            tcg_temp_free_i32(fp32);
8213        }
8214        opn = "cvt.w.d";
8215        break;
8216    case OPC_CVT_L_D:
8217        check_cp1_64bitmode(ctx);
8218        {
8219            TCGv_i64 fp0 = tcg_temp_new_i64();
8220
8221            gen_load_fpr64(ctx, fp0, fs);
8222            gen_helper_float_cvtl_d(fp0, cpu_env, fp0);
8223            gen_store_fpr64(ctx, fp0, fd);
8224            tcg_temp_free_i64(fp0);
8225        }
8226        opn = "cvt.l.d";
8227        break;
8228    case OPC_CVT_S_W:
8229        {
8230            TCGv_i32 fp0 = tcg_temp_new_i32();
8231
8232            gen_load_fpr32(fp0, fs);
8233            gen_helper_float_cvts_w(fp0, cpu_env, fp0);
8234            gen_store_fpr32(fp0, fd);
8235            tcg_temp_free_i32(fp0);
8236        }
8237        opn = "cvt.s.w";
8238        break;
8239    case OPC_CVT_D_W:
8240        check_cp1_registers(ctx, fd);
8241        {
8242            TCGv_i32 fp32 = tcg_temp_new_i32();
8243            TCGv_i64 fp64 = tcg_temp_new_i64();
8244
8245            gen_load_fpr32(fp32, fs);
8246            gen_helper_float_cvtd_w(fp64, cpu_env, fp32);
8247            tcg_temp_free_i32(fp32);
8248            gen_store_fpr64(ctx, fp64, fd);
8249            tcg_temp_free_i64(fp64);
8250        }
8251        opn = "cvt.d.w";
8252        break;
8253    case OPC_CVT_S_L:
8254        check_cp1_64bitmode(ctx);
8255        {
8256            TCGv_i32 fp32 = tcg_temp_new_i32();
8257            TCGv_i64 fp64 = tcg_temp_new_i64();
8258
8259            gen_load_fpr64(ctx, fp64, fs);
8260            gen_helper_float_cvts_l(fp32, cpu_env, fp64);
8261            tcg_temp_free_i64(fp64);
8262            gen_store_fpr32(fp32, fd);
8263            tcg_temp_free_i32(fp32);
8264        }
8265        opn = "cvt.s.l";
8266        break;
8267    case OPC_CVT_D_L:
8268        check_cp1_64bitmode(ctx);
8269        {
8270            TCGv_i64 fp0 = tcg_temp_new_i64();
8271
8272            gen_load_fpr64(ctx, fp0, fs);
8273            gen_helper_float_cvtd_l(fp0, cpu_env, fp0);
8274            gen_store_fpr64(ctx, fp0, fd);
8275            tcg_temp_free_i64(fp0);
8276        }
8277        opn = "cvt.d.l";
8278        break;
8279    case OPC_CVT_PS_PW:
8280        check_cp1_64bitmode(ctx);
8281        {
8282            TCGv_i64 fp0 = tcg_temp_new_i64();
8283
8284            gen_load_fpr64(ctx, fp0, fs);
8285            gen_helper_float_cvtps_pw(fp0, cpu_env, fp0);
8286            gen_store_fpr64(ctx, fp0, fd);
8287            tcg_temp_free_i64(fp0);
8288        }
8289        opn = "cvt.ps.pw";
8290        break;
8291    case OPC_ADD_PS:
8292        check_cp1_64bitmode(ctx);
8293        {
8294            TCGv_i64 fp0 = tcg_temp_new_i64();
8295            TCGv_i64 fp1 = tcg_temp_new_i64();
8296
8297            gen_load_fpr64(ctx, fp0, fs);
8298            gen_load_fpr64(ctx, fp1, ft);
8299            gen_helper_float_add_ps(fp0, cpu_env, fp0, fp1);
8300            tcg_temp_free_i64(fp1);
8301            gen_store_fpr64(ctx, fp0, fd);
8302            tcg_temp_free_i64(fp0);
8303        }
8304        opn = "add.ps";
8305        break;
8306    case OPC_SUB_PS:
8307        check_cp1_64bitmode(ctx);
8308        {
8309            TCGv_i64 fp0 = tcg_temp_new_i64();
8310            TCGv_i64 fp1 = tcg_temp_new_i64();
8311
8312            gen_load_fpr64(ctx, fp0, fs);
8313            gen_load_fpr64(ctx, fp1, ft);
8314            gen_helper_float_sub_ps(fp0, cpu_env, fp0, fp1);
8315            tcg_temp_free_i64(fp1);
8316            gen_store_fpr64(ctx, fp0, fd);
8317            tcg_temp_free_i64(fp0);
8318        }
8319        opn = "sub.ps";
8320        break;
8321    case OPC_MUL_PS:
8322        check_cp1_64bitmode(ctx);
8323        {
8324            TCGv_i64 fp0 = tcg_temp_new_i64();
8325            TCGv_i64 fp1 = tcg_temp_new_i64();
8326
8327            gen_load_fpr64(ctx, fp0, fs);
8328            gen_load_fpr64(ctx, fp1, ft);
8329            gen_helper_float_mul_ps(fp0, cpu_env, fp0, fp1);
8330            tcg_temp_free_i64(fp1);
8331            gen_store_fpr64(ctx, fp0, fd);
8332            tcg_temp_free_i64(fp0);
8333        }
8334        opn = "mul.ps";
8335        break;
8336    case OPC_ABS_PS:
8337        check_cp1_64bitmode(ctx);
8338        {
8339            TCGv_i64 fp0 = tcg_temp_new_i64();
8340
8341            gen_load_fpr64(ctx, fp0, fs);
8342            gen_helper_float_abs_ps(fp0, fp0);
8343            gen_store_fpr64(ctx, fp0, fd);
8344            tcg_temp_free_i64(fp0);
8345        }
8346        opn = "abs.ps";
8347        break;
8348    case OPC_MOV_PS:
8349        check_cp1_64bitmode(ctx);
8350        {
8351            TCGv_i64 fp0 = tcg_temp_new_i64();
8352
8353            gen_load_fpr64(ctx, fp0, fs);
8354            gen_store_fpr64(ctx, fp0, fd);
8355            tcg_temp_free_i64(fp0);
8356        }
8357        opn = "mov.ps";
8358        break;
8359    case OPC_NEG_PS:
8360        check_cp1_64bitmode(ctx);
8361        {
8362            TCGv_i64 fp0 = tcg_temp_new_i64();
8363
8364            gen_load_fpr64(ctx, fp0, fs);
8365            gen_helper_float_chs_ps(fp0, fp0);
8366            gen_store_fpr64(ctx, fp0, fd);
8367            tcg_temp_free_i64(fp0);
8368        }
8369        opn = "neg.ps";
8370        break;
8371    case OPC_MOVCF_PS:
8372        check_cp1_64bitmode(ctx);
8373        gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
8374        opn = "movcf.ps";
8375        break;
8376    case OPC_MOVZ_PS:
8377        check_cp1_64bitmode(ctx);
8378        {
8379            int l1 = gen_new_label();
8380            TCGv_i64 fp0;
8381
8382            if (ft != 0)
8383                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
8384            fp0 = tcg_temp_new_i64();
8385            gen_load_fpr64(ctx, fp0, fs);
8386            gen_store_fpr64(ctx, fp0, fd);
8387            tcg_temp_free_i64(fp0);
8388            gen_set_label(l1);
8389        }
8390        opn = "movz.ps";
8391        break;
8392    case OPC_MOVN_PS:
8393        check_cp1_64bitmode(ctx);
8394        {
8395            int l1 = gen_new_label();
8396            TCGv_i64 fp0;
8397
8398            if (ft != 0) {
8399                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
8400                fp0 = tcg_temp_new_i64();
8401                gen_load_fpr64(ctx, fp0, fs);
8402                gen_store_fpr64(ctx, fp0, fd);
8403                tcg_temp_free_i64(fp0);
8404                gen_set_label(l1);
8405            }
8406        }
8407        opn = "movn.ps";
8408        break;
8409    case OPC_ADDR_PS:
8410        check_cp1_64bitmode(ctx);
8411        {
8412            TCGv_i64 fp0 = tcg_temp_new_i64();
8413            TCGv_i64 fp1 = tcg_temp_new_i64();
8414
8415            gen_load_fpr64(ctx, fp0, ft);
8416            gen_load_fpr64(ctx, fp1, fs);
8417            gen_helper_float_addr_ps(fp0, cpu_env, fp0, fp1);
8418            tcg_temp_free_i64(fp1);
8419            gen_store_fpr64(ctx, fp0, fd);
8420            tcg_temp_free_i64(fp0);
8421        }
8422        opn = "addr.ps";
8423        break;
8424    case OPC_MULR_PS:
8425        check_cp1_64bitmode(ctx);
8426        {
8427            TCGv_i64 fp0 = tcg_temp_new_i64();
8428            TCGv_i64 fp1 = tcg_temp_new_i64();
8429
8430            gen_load_fpr64(ctx, fp0, ft);
8431            gen_load_fpr64(ctx, fp1, fs);
8432            gen_helper_float_mulr_ps(fp0, cpu_env, fp0, fp1);
8433            tcg_temp_free_i64(fp1);
8434            gen_store_fpr64(ctx, fp0, fd);
8435            tcg_temp_free_i64(fp0);
8436        }
8437        opn = "mulr.ps";
8438        break;
8439    case OPC_RECIP2_PS:
8440        check_cp1_64bitmode(ctx);
8441        {
8442            TCGv_i64 fp0 = tcg_temp_new_i64();
8443            TCGv_i64 fp1 = tcg_temp_new_i64();
8444
8445            gen_load_fpr64(ctx, fp0, fs);
8446            gen_load_fpr64(ctx, fp1, ft);
8447            gen_helper_float_recip2_ps(fp0, cpu_env, fp0, fp1);
8448            tcg_temp_free_i64(fp1);
8449            gen_store_fpr64(ctx, fp0, fd);
8450            tcg_temp_free_i64(fp0);
8451        }
8452        opn = "recip2.ps";
8453        break;
8454    case OPC_RECIP1_PS:
8455        check_cp1_64bitmode(ctx);
8456        {
8457            TCGv_i64 fp0 = tcg_temp_new_i64();
8458
8459            gen_load_fpr64(ctx, fp0, fs);
8460            gen_helper_float_recip1_ps(fp0, cpu_env, fp0);
8461            gen_store_fpr64(ctx, fp0, fd);
8462            tcg_temp_free_i64(fp0);
8463        }
8464        opn = "recip1.ps";
8465        break;
8466    case OPC_RSQRT1_PS:
8467        check_cp1_64bitmode(ctx);
8468        {
8469            TCGv_i64 fp0 = tcg_temp_new_i64();
8470
8471            gen_load_fpr64(ctx, fp0, fs);
8472            gen_helper_float_rsqrt1_ps(fp0, cpu_env, fp0);
8473            gen_store_fpr64(ctx, fp0, fd);
8474            tcg_temp_free_i64(fp0);
8475        }
8476        opn = "rsqrt1.ps";
8477        break;
8478    case OPC_RSQRT2_PS:
8479        check_cp1_64bitmode(ctx);
8480        {
8481            TCGv_i64 fp0 = tcg_temp_new_i64();
8482            TCGv_i64 fp1 = tcg_temp_new_i64();
8483
8484            gen_load_fpr64(ctx, fp0, fs);
8485            gen_load_fpr64(ctx, fp1, ft);
8486            gen_helper_float_rsqrt2_ps(fp0, cpu_env, fp0, fp1);
8487            tcg_temp_free_i64(fp1);
8488            gen_store_fpr64(ctx, fp0, fd);
8489            tcg_temp_free_i64(fp0);
8490        }
8491        opn = "rsqrt2.ps";
8492        break;
8493    case OPC_CVT_S_PU:
8494        check_cp1_64bitmode(ctx);
8495        {
8496            TCGv_i32 fp0 = tcg_temp_new_i32();
8497
8498            gen_load_fpr32h(fp0, fs);
8499            gen_helper_float_cvts_pu(fp0, cpu_env, fp0);
8500            gen_store_fpr32(fp0, fd);
8501            tcg_temp_free_i32(fp0);
8502        }
8503        opn = "cvt.s.pu";
8504        break;
8505    case OPC_CVT_PW_PS:
8506        check_cp1_64bitmode(ctx);
8507        {
8508            TCGv_i64 fp0 = tcg_temp_new_i64();
8509
8510            gen_load_fpr64(ctx, fp0, fs);
8511            gen_helper_float_cvtpw_ps(fp0, cpu_env, fp0);
8512            gen_store_fpr64(ctx, fp0, fd);
8513            tcg_temp_free_i64(fp0);
8514        }
8515        opn = "cvt.pw.ps";
8516        break;
8517    case OPC_CVT_S_PL:
8518        check_cp1_64bitmode(ctx);
8519        {
8520            TCGv_i32 fp0 = tcg_temp_new_i32();
8521
8522            gen_load_fpr32(fp0, fs);
8523            gen_helper_float_cvts_pl(fp0, cpu_env, fp0);
8524            gen_store_fpr32(fp0, fd);
8525            tcg_temp_free_i32(fp0);
8526        }
8527        opn = "cvt.s.pl";
8528        break;
8529    case OPC_PLL_PS:
8530        check_cp1_64bitmode(ctx);
8531        {
8532            TCGv_i32 fp0 = tcg_temp_new_i32();
8533            TCGv_i32 fp1 = tcg_temp_new_i32();
8534
8535            gen_load_fpr32(fp0, fs);
8536            gen_load_fpr32(fp1, ft);
8537            gen_store_fpr32h(fp0, fd);
8538            gen_store_fpr32(fp1, fd);
8539            tcg_temp_free_i32(fp0);
8540            tcg_temp_free_i32(fp1);
8541        }
8542        opn = "pll.ps";
8543        break;
8544    case OPC_PLU_PS:
8545        check_cp1_64bitmode(ctx);
8546        {
8547            TCGv_i32 fp0 = tcg_temp_new_i32();
8548            TCGv_i32 fp1 = tcg_temp_new_i32();
8549
8550            gen_load_fpr32(fp0, fs);
8551            gen_load_fpr32h(fp1, ft);
8552            gen_store_fpr32(fp1, fd);
8553            gen_store_fpr32h(fp0, fd);
8554            tcg_temp_free_i32(fp0);
8555            tcg_temp_free_i32(fp1);
8556        }
8557        opn = "plu.ps";
8558        break;
8559    case OPC_PUL_PS:
8560        check_cp1_64bitmode(ctx);
8561        {
8562            TCGv_i32 fp0 = tcg_temp_new_i32();
8563            TCGv_i32 fp1 = tcg_temp_new_i32();
8564
8565            gen_load_fpr32h(fp0, fs);
8566            gen_load_fpr32(fp1, ft);
8567            gen_store_fpr32(fp1, fd);
8568            gen_store_fpr32h(fp0, fd);
8569            tcg_temp_free_i32(fp0);
8570            tcg_temp_free_i32(fp1);
8571        }
8572        opn = "pul.ps";
8573        break;
8574    case OPC_PUU_PS:
8575        check_cp1_64bitmode(ctx);
8576        {
8577            TCGv_i32 fp0 = tcg_temp_new_i32();
8578            TCGv_i32 fp1 = tcg_temp_new_i32();
8579
8580            gen_load_fpr32h(fp0, fs);
8581            gen_load_fpr32h(fp1, ft);
8582            gen_store_fpr32(fp1, fd);
8583            gen_store_fpr32h(fp0, fd);
8584            tcg_temp_free_i32(fp0);
8585            tcg_temp_free_i32(fp1);
8586        }
8587        opn = "puu.ps";
8588        break;
8589    case OPC_CMP_F_PS:
8590    case OPC_CMP_UN_PS:
8591    case OPC_CMP_EQ_PS:
8592    case OPC_CMP_UEQ_PS:
8593    case OPC_CMP_OLT_PS:
8594    case OPC_CMP_ULT_PS:
8595    case OPC_CMP_OLE_PS:
8596    case OPC_CMP_ULE_PS:
8597    case OPC_CMP_SF_PS:
8598    case OPC_CMP_NGLE_PS:
8599    case OPC_CMP_SEQ_PS:
8600    case OPC_CMP_NGL_PS:
8601    case OPC_CMP_LT_PS:
8602    case OPC_CMP_NGE_PS:
8603    case OPC_CMP_LE_PS:
8604    case OPC_CMP_NGT_PS:
8605        if (ctx->opcode & (1 << 6)) {
8606            gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
8607            opn = condnames_abs[func-48];
8608        } else {
8609            gen_cmp_ps(ctx, func-48, ft, fs, cc);
8610            opn = condnames[func-48];
8611        }
8612        break;
8613    default:
8614        MIPS_INVAL(opn);
8615        generate_exception (ctx, EXCP_RI);
8616        return;
8617    }
8618    (void)opn; /* avoid a compiler warning */
8619    switch (optype) {
8620    case BINOP:
8621        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
8622        break;
8623    case CMPOP:
8624        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
8625        break;
8626    default:
8627        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
8628        break;
8629    }
8630}
8631
8632/* Coprocessor 3 (FPU) */
8633static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
8634                           int fd, int fs, int base, int index)
8635{
8636    const char *opn = "extended float load/store";
8637    int store = 0;
8638    TCGv t0 = tcg_temp_new();
8639
8640    if (base == 0) {
8641        gen_load_gpr(t0, index);
8642    } else if (index == 0) {
8643        gen_load_gpr(t0, base);
8644    } else {
8645        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[index]);
8646    }
8647    /* Don't do NOP if destination is zero: we must perform the actual
8648       memory access. */
8649    switch (opc) {
8650    case OPC_LWXC1:
8651        check_cop1x(ctx);
8652        {
8653            TCGv_i32 fp0 = tcg_temp_new_i32();
8654
8655            tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
8656            tcg_gen_trunc_tl_i32(fp0, t0);
8657            gen_store_fpr32(fp0, fd);
8658            tcg_temp_free_i32(fp0);
8659        }
8660        opn = "lwxc1";
8661        break;
8662    case OPC_LDXC1:
8663        check_cop1x(ctx);
8664        check_cp1_registers(ctx, fd);
8665        {
8666            TCGv_i64 fp0 = tcg_temp_new_i64();
8667
8668            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8669            gen_store_fpr64(ctx, fp0, fd);
8670            tcg_temp_free_i64(fp0);
8671        }
8672        opn = "ldxc1";
8673        break;
8674    case OPC_LUXC1:
8675        check_cp1_64bitmode(ctx);
8676        tcg_gen_andi_tl(t0, t0, ~0x7);
8677        {
8678            TCGv_i64 fp0 = tcg_temp_new_i64();
8679
8680            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
8681            gen_store_fpr64(ctx, fp0, fd);
8682            tcg_temp_free_i64(fp0);
8683        }
8684        opn = "luxc1";
8685        break;
8686    case OPC_SWXC1:
8687        check_cop1x(ctx);
8688        {
8689            TCGv_i32 fp0 = tcg_temp_new_i32();
8690            TCGv t1 = tcg_temp_new();
8691
8692            gen_load_fpr32(fp0, fs);
8693            tcg_gen_extu_i32_tl(t1, fp0);
8694            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
8695            tcg_temp_free_i32(fp0);
8696            tcg_temp_free(t1);
8697        }
8698        opn = "swxc1";
8699        store = 1;
8700        break;
8701    case OPC_SDXC1:
8702        check_cop1x(ctx);
8703        check_cp1_registers(ctx, fs);
8704        {
8705            TCGv_i64 fp0 = tcg_temp_new_i64();
8706
8707            gen_load_fpr64(ctx, fp0, fs);
8708            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8709            tcg_temp_free_i64(fp0);
8710        }
8711        opn = "sdxc1";
8712        store = 1;
8713        break;
8714    case OPC_SUXC1:
8715        check_cp1_64bitmode(ctx);
8716        tcg_gen_andi_tl(t0, t0, ~0x7);
8717        {
8718            TCGv_i64 fp0 = tcg_temp_new_i64();
8719
8720            gen_load_fpr64(ctx, fp0, fs);
8721            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
8722            tcg_temp_free_i64(fp0);
8723        }
8724        opn = "suxc1";
8725        store = 1;
8726        break;
8727    }
8728    tcg_temp_free(t0);
8729    (void)opn; (void)store; /* avoid compiler warnings */
8730    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
8731               regnames[index], regnames[base]);
8732}
8733
8734static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
8735                            int fd, int fr, int fs, int ft)
8736{
8737    const char *opn = "flt3_arith";
8738
8739    switch (opc) {
8740    case OPC_ALNV_PS:
8741        check_cp1_64bitmode(ctx);
8742        {
8743            TCGv t0 = tcg_temp_local_new();
8744            TCGv_i32 fp = tcg_temp_new_i32();
8745            TCGv_i32 fph = tcg_temp_new_i32();
8746            int l1 = gen_new_label();
8747            int l2 = gen_new_label();
8748
8749            gen_load_gpr(t0, fr);
8750            tcg_gen_andi_tl(t0, t0, 0x7);
8751
8752            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
8753            gen_load_fpr32(fp, fs);
8754            gen_load_fpr32h(fph, fs);
8755            gen_store_fpr32(fp, fd);
8756            gen_store_fpr32h(fph, fd);
8757            tcg_gen_br(l2);
8758            gen_set_label(l1);
8759            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
8760            tcg_temp_free(t0);
8761#ifdef TARGET_WORDS_BIGENDIAN
8762            gen_load_fpr32(fp, fs);
8763            gen_load_fpr32h(fph, ft);
8764            gen_store_fpr32h(fp, fd);
8765            gen_store_fpr32(fph, fd);
8766#else
8767            gen_load_fpr32h(fph, fs);
8768            gen_load_fpr32(fp, ft);
8769            gen_store_fpr32(fph, fd);
8770            gen_store_fpr32h(fp, fd);
8771#endif
8772            gen_set_label(l2);
8773            tcg_temp_free_i32(fp);
8774            tcg_temp_free_i32(fph);
8775        }
8776        opn = "alnv.ps";
8777        break;
8778    case OPC_MADD_S:
8779        check_cop1x(ctx);
8780        {
8781            TCGv_i32 fp0 = tcg_temp_new_i32();
8782            TCGv_i32 fp1 = tcg_temp_new_i32();
8783            TCGv_i32 fp2 = tcg_temp_new_i32();
8784
8785            gen_load_fpr32(fp0, fs);
8786            gen_load_fpr32(fp1, ft);
8787            gen_load_fpr32(fp2, fr);
8788            gen_helper_float_madd_s(fp2, cpu_env, fp0, fp1, fp2);
8789            tcg_temp_free_i32(fp0);
8790            tcg_temp_free_i32(fp1);
8791            gen_store_fpr32(fp2, fd);
8792            tcg_temp_free_i32(fp2);
8793        }
8794        opn = "madd.s";
8795        break;
8796    case OPC_MADD_D:
8797        check_cop1x(ctx);
8798        check_cp1_registers(ctx, fd | fs | ft | fr);
8799        {
8800            TCGv_i64 fp0 = tcg_temp_new_i64();
8801            TCGv_i64 fp1 = tcg_temp_new_i64();
8802            TCGv_i64 fp2 = tcg_temp_new_i64();
8803
8804            gen_load_fpr64(ctx, fp0, fs);
8805            gen_load_fpr64(ctx, fp1, ft);
8806            gen_load_fpr64(ctx, fp2, fr);
8807            gen_helper_float_madd_d(fp2, cpu_env, fp0, fp1, fp2);
8808            tcg_temp_free_i64(fp0);
8809            tcg_temp_free_i64(fp1);
8810            gen_store_fpr64(ctx, fp2, fd);
8811            tcg_temp_free_i64(fp2);
8812        }
8813        opn = "madd.d";
8814        break;
8815    case OPC_MADD_PS:
8816        check_cp1_64bitmode(ctx);
8817        {
8818            TCGv_i64 fp0 = tcg_temp_new_i64();
8819            TCGv_i64 fp1 = tcg_temp_new_i64();
8820            TCGv_i64 fp2 = tcg_temp_new_i64();
8821
8822            gen_load_fpr64(ctx, fp0, fs);
8823            gen_load_fpr64(ctx, fp1, ft);
8824            gen_load_fpr64(ctx, fp2, fr);
8825            gen_helper_float_madd_ps(fp2, cpu_env, fp0, fp1, fp2);
8826            tcg_temp_free_i64(fp0);
8827            tcg_temp_free_i64(fp1);
8828            gen_store_fpr64(ctx, fp2, fd);
8829            tcg_temp_free_i64(fp2);
8830        }
8831        opn = "madd.ps";
8832        break;
8833    case OPC_MSUB_S:
8834        check_cop1x(ctx);
8835        {
8836            TCGv_i32 fp0 = tcg_temp_new_i32();
8837            TCGv_i32 fp1 = tcg_temp_new_i32();
8838            TCGv_i32 fp2 = tcg_temp_new_i32();
8839
8840            gen_load_fpr32(fp0, fs);
8841            gen_load_fpr32(fp1, ft);
8842            gen_load_fpr32(fp2, fr);
8843            gen_helper_float_msub_s(fp2, cpu_env, fp0, fp1, fp2);
8844            tcg_temp_free_i32(fp0);
8845            tcg_temp_free_i32(fp1);
8846            gen_store_fpr32(fp2, fd);
8847            tcg_temp_free_i32(fp2);
8848        }
8849        opn = "msub.s";
8850        break;
8851    case OPC_MSUB_D:
8852        check_cop1x(ctx);
8853        check_cp1_registers(ctx, fd | fs | ft | fr);
8854        {
8855            TCGv_i64 fp0 = tcg_temp_new_i64();
8856            TCGv_i64 fp1 = tcg_temp_new_i64();
8857            TCGv_i64 fp2 = tcg_temp_new_i64();
8858
8859            gen_load_fpr64(ctx, fp0, fs);
8860            gen_load_fpr64(ctx, fp1, ft);
8861            gen_load_fpr64(ctx, fp2, fr);
8862            gen_helper_float_msub_d(fp2, cpu_env, fp0, fp1, fp2);
8863            tcg_temp_free_i64(fp0);
8864            tcg_temp_free_i64(fp1);
8865            gen_store_fpr64(ctx, fp2, fd);
8866            tcg_temp_free_i64(fp2);
8867        }
8868        opn = "msub.d";
8869        break;
8870    case OPC_MSUB_PS:
8871        check_cp1_64bitmode(ctx);
8872        {
8873            TCGv_i64 fp0 = tcg_temp_new_i64();
8874            TCGv_i64 fp1 = tcg_temp_new_i64();
8875            TCGv_i64 fp2 = tcg_temp_new_i64();
8876
8877            gen_load_fpr64(ctx, fp0, fs);
8878            gen_load_fpr64(ctx, fp1, ft);
8879            gen_load_fpr64(ctx, fp2, fr);
8880            gen_helper_float_msub_ps(fp2, cpu_env, fp0, fp1, fp2);
8881            tcg_temp_free_i64(fp0);
8882            tcg_temp_free_i64(fp1);
8883            gen_store_fpr64(ctx, fp2, fd);
8884            tcg_temp_free_i64(fp2);
8885        }
8886        opn = "msub.ps";
8887        break;
8888    case OPC_NMADD_S:
8889        check_cop1x(ctx);
8890        {
8891            TCGv_i32 fp0 = tcg_temp_new_i32();
8892            TCGv_i32 fp1 = tcg_temp_new_i32();
8893            TCGv_i32 fp2 = tcg_temp_new_i32();
8894
8895            gen_load_fpr32(fp0, fs);
8896            gen_load_fpr32(fp1, ft);
8897            gen_load_fpr32(fp2, fr);
8898            gen_helper_float_nmadd_s(fp2, cpu_env, fp0, fp1, fp2);
8899            tcg_temp_free_i32(fp0);
8900            tcg_temp_free_i32(fp1);
8901            gen_store_fpr32(fp2, fd);
8902            tcg_temp_free_i32(fp2);
8903        }
8904        opn = "nmadd.s";
8905        break;
8906    case OPC_NMADD_D:
8907        check_cop1x(ctx);
8908        check_cp1_registers(ctx, fd | fs | ft | fr);
8909        {
8910            TCGv_i64 fp0 = tcg_temp_new_i64();
8911            TCGv_i64 fp1 = tcg_temp_new_i64();
8912            TCGv_i64 fp2 = tcg_temp_new_i64();
8913
8914            gen_load_fpr64(ctx, fp0, fs);
8915            gen_load_fpr64(ctx, fp1, ft);
8916            gen_load_fpr64(ctx, fp2, fr);
8917            gen_helper_float_nmadd_d(fp2, cpu_env, fp0, fp1, fp2);
8918            tcg_temp_free_i64(fp0);
8919            tcg_temp_free_i64(fp1);
8920            gen_store_fpr64(ctx, fp2, fd);
8921            tcg_temp_free_i64(fp2);
8922        }
8923        opn = "nmadd.d";
8924        break;
8925    case OPC_NMADD_PS:
8926        check_cp1_64bitmode(ctx);
8927        {
8928            TCGv_i64 fp0 = tcg_temp_new_i64();
8929            TCGv_i64 fp1 = tcg_temp_new_i64();
8930            TCGv_i64 fp2 = tcg_temp_new_i64();
8931
8932            gen_load_fpr64(ctx, fp0, fs);
8933            gen_load_fpr64(ctx, fp1, ft);
8934            gen_load_fpr64(ctx, fp2, fr);
8935            gen_helper_float_nmadd_ps(fp2, cpu_env, fp0, fp1, fp2);
8936            tcg_temp_free_i64(fp0);
8937            tcg_temp_free_i64(fp1);
8938            gen_store_fpr64(ctx, fp2, fd);
8939            tcg_temp_free_i64(fp2);
8940        }
8941        opn = "nmadd.ps";
8942        break;
8943    case OPC_NMSUB_S:
8944        check_cop1x(ctx);
8945        {
8946            TCGv_i32 fp0 = tcg_temp_new_i32();
8947            TCGv_i32 fp1 = tcg_temp_new_i32();
8948            TCGv_i32 fp2 = tcg_temp_new_i32();
8949
8950            gen_load_fpr32(fp0, fs);
8951            gen_load_fpr32(fp1, ft);
8952            gen_load_fpr32(fp2, fr);
8953            gen_helper_float_nmsub_s(fp2, cpu_env, fp0, fp1, fp2);
8954            tcg_temp_free_i32(fp0);
8955            tcg_temp_free_i32(fp1);
8956            gen_store_fpr32(fp2, fd);
8957            tcg_temp_free_i32(fp2);
8958        }
8959        opn = "nmsub.s";
8960        break;
8961    case OPC_NMSUB_D:
8962        check_cop1x(ctx);
8963        check_cp1_registers(ctx, fd | fs | ft | fr);
8964        {
8965            TCGv_i64 fp0 = tcg_temp_new_i64();
8966            TCGv_i64 fp1 = tcg_temp_new_i64();
8967            TCGv_i64 fp2 = tcg_temp_new_i64();
8968
8969            gen_load_fpr64(ctx, fp0, fs);
8970            gen_load_fpr64(ctx, fp1, ft);
8971            gen_load_fpr64(ctx, fp2, fr);
8972            gen_helper_float_nmsub_d(fp2, cpu_env, fp0, fp1, fp2);
8973            tcg_temp_free_i64(fp0);
8974            tcg_temp_free_i64(fp1);
8975            gen_store_fpr64(ctx, fp2, fd);
8976            tcg_temp_free_i64(fp2);
8977        }
8978        opn = "nmsub.d";
8979        break;
8980    case OPC_NMSUB_PS:
8981        check_cp1_64bitmode(ctx);
8982        {
8983            TCGv_i64 fp0 = tcg_temp_new_i64();
8984            TCGv_i64 fp1 = tcg_temp_new_i64();
8985            TCGv_i64 fp2 = tcg_temp_new_i64();
8986
8987            gen_load_fpr64(ctx, fp0, fs);
8988            gen_load_fpr64(ctx, fp1, ft);
8989            gen_load_fpr64(ctx, fp2, fr);
8990            gen_helper_float_nmsub_ps(fp2, cpu_env, fp0, fp1, fp2);
8991            tcg_temp_free_i64(fp0);
8992            tcg_temp_free_i64(fp1);
8993            gen_store_fpr64(ctx, fp2, fd);
8994            tcg_temp_free_i64(fp2);
8995        }
8996        opn = "nmsub.ps";
8997        break;
8998    default:
8999        MIPS_INVAL(opn);
9000        generate_exception (ctx, EXCP_RI);
9001        return;
9002    }
9003    (void)opn; /* avoid a compiler warning */
9004    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
9005               fregnames[fs], fregnames[ft]);
9006}
9007
9008static void gen_rdhwr(DisasContext *ctx, int rt, int rd)
9009{
9010    TCGv t0;
9011
9012#if !defined(CONFIG_USER_ONLY)
9013    /* The Linux kernel will emulate rdhwr if it's not supported natively.
9014       Therefore only check the ISA in system mode.  */
9015    check_insn(ctx, ISA_MIPS32R2);
9016#endif
9017    t0 = tcg_temp_new();
9018
9019    switch (rd) {
9020    case 0:
9021        save_cpu_state(ctx, 1);
9022        gen_helper_rdhwr_cpunum(t0, cpu_env);
9023        gen_store_gpr(t0, rt);
9024        break;
9025    case 1:
9026        save_cpu_state(ctx, 1);
9027        gen_helper_rdhwr_synci_step(t0, cpu_env);
9028        gen_store_gpr(t0, rt);
9029        break;
9030    case 2:
9031        save_cpu_state(ctx, 1);
9032        gen_helper_rdhwr_cc(t0, cpu_env);
9033        gen_store_gpr(t0, rt);
9034        break;
9035    case 3:
9036        save_cpu_state(ctx, 1);
9037        gen_helper_rdhwr_ccres(t0, cpu_env);
9038        gen_store_gpr(t0, rt);
9039        break;
9040    case 29:
9041#if defined(CONFIG_USER_ONLY)
9042        tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
9043        gen_store_gpr(t0, rt);
9044        break;
9045#else
9046        /* XXX: Some CPUs implement this in hardware.
9047           Not supported yet. */
9048#endif
9049    default:            /* Invalid */
9050        MIPS_INVAL("rdhwr");
9051        generate_exception(ctx, EXCP_RI);
9052        break;
9053    }
9054    tcg_temp_free(t0);
9055}
9056
9057static void handle_delay_slot(DisasContext *ctx, int insn_bytes)
9058{
9059    if (ctx->hflags & MIPS_HFLAG_BMASK) {
9060        int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
9061        /* Branches completion */
9062        ctx->hflags &= ~MIPS_HFLAG_BMASK;
9063        ctx->bstate = BS_BRANCH;
9064        save_cpu_state(ctx, 0);
9065        /* FIXME: Need to clear can_do_io.  */
9066        switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
9067        case MIPS_HFLAG_B:
9068            /* unconditional branch */
9069            MIPS_DEBUG("unconditional branch");
9070            if (proc_hflags & MIPS_HFLAG_BX) {
9071                tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
9072            }
9073            gen_goto_tb(ctx, 0, ctx->btarget);
9074            break;
9075        case MIPS_HFLAG_BL:
9076            /* blikely taken case */
9077            MIPS_DEBUG("blikely branch taken");
9078            gen_goto_tb(ctx, 0, ctx->btarget);
9079            break;
9080        case MIPS_HFLAG_BC:
9081            /* Conditional branch */
9082            MIPS_DEBUG("conditional branch");
9083            {
9084                int l1 = gen_new_label();
9085
9086                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
9087                gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
9088                gen_set_label(l1);
9089                gen_goto_tb(ctx, 0, ctx->btarget);
9090            }
9091            break;
9092        case MIPS_HFLAG_BR:
9093            /* unconditional branch to register */
9094            MIPS_DEBUG("branch to register");
9095            if (ctx->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
9096                TCGv t0 = tcg_temp_new();
9097                TCGv_i32 t1 = tcg_temp_new_i32();
9098
9099                tcg_gen_andi_tl(t0, btarget, 0x1);
9100                tcg_gen_trunc_tl_i32(t1, t0);
9101                tcg_temp_free(t0);
9102                tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
9103                tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
9104                tcg_gen_or_i32(hflags, hflags, t1);
9105                tcg_temp_free_i32(t1);
9106
9107                tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
9108            } else {
9109                tcg_gen_mov_tl(cpu_PC, btarget);
9110            }
9111            if (ctx->singlestep_enabled) {
9112                save_cpu_state(ctx, 0);
9113                gen_helper_0e0i(raise_exception, EXCP_DEBUG);
9114            }
9115            tcg_gen_exit_tb(0);
9116            break;
9117        default:
9118            MIPS_DEBUG("unknown branch");
9119            break;
9120        }
9121    }
9122}
9123
9124/* ISA extensions (ASEs) */
9125/* MIPS16 extension to MIPS32 */
9126
9127/* MIPS16 major opcodes */
9128enum {
9129  M16_OPC_ADDIUSP = 0x00,
9130  M16_OPC_ADDIUPC = 0x01,
9131  M16_OPC_B = 0x02,
9132  M16_OPC_JAL = 0x03,
9133  M16_OPC_BEQZ = 0x04,
9134  M16_OPC_BNEQZ = 0x05,
9135  M16_OPC_SHIFT = 0x06,
9136  M16_OPC_LD = 0x07,
9137  M16_OPC_RRIA = 0x08,
9138  M16_OPC_ADDIU8 = 0x09,
9139  M16_OPC_SLTI = 0x0a,
9140  M16_OPC_SLTIU = 0x0b,
9141  M16_OPC_I8 = 0x0c,
9142  M16_OPC_LI = 0x0d,
9143  M16_OPC_CMPI = 0x0e,
9144  M16_OPC_SD = 0x0f,
9145  M16_OPC_LB = 0x10,
9146  M16_OPC_LH = 0x11,
9147  M16_OPC_LWSP = 0x12,
9148  M16_OPC_LW = 0x13,
9149  M16_OPC_LBU = 0x14,
9150  M16_OPC_LHU = 0x15,
9151  M16_OPC_LWPC = 0x16,
9152  M16_OPC_LWU = 0x17,
9153  M16_OPC_SB = 0x18,
9154  M16_OPC_SH = 0x19,
9155  M16_OPC_SWSP = 0x1a,
9156  M16_OPC_SW = 0x1b,
9157  M16_OPC_RRR = 0x1c,
9158  M16_OPC_RR = 0x1d,
9159  M16_OPC_EXTEND = 0x1e,
9160  M16_OPC_I64 = 0x1f
9161};
9162
9163/* I8 funct field */
9164enum {
9165  I8_BTEQZ = 0x0,
9166  I8_BTNEZ = 0x1,
9167  I8_SWRASP = 0x2,
9168  I8_ADJSP = 0x3,
9169  I8_SVRS = 0x4,
9170  I8_MOV32R = 0x5,
9171  I8_MOVR32 = 0x7
9172};
9173
9174/* RRR f field */
9175enum {
9176  RRR_DADDU = 0x0,
9177  RRR_ADDU = 0x1,
9178  RRR_DSUBU = 0x2,
9179  RRR_SUBU = 0x3
9180};
9181
9182/* RR funct field */
9183enum {
9184  RR_JR = 0x00,
9185  RR_SDBBP = 0x01,
9186  RR_SLT = 0x02,
9187  RR_SLTU = 0x03,
9188  RR_SLLV = 0x04,
9189  RR_BREAK = 0x05,
9190  RR_SRLV = 0x06,
9191  RR_SRAV = 0x07,
9192  RR_DSRL = 0x08,
9193  RR_CMP = 0x0a,
9194  RR_NEG = 0x0b,
9195  RR_AND = 0x0c,
9196  RR_OR = 0x0d,
9197  RR_XOR = 0x0e,
9198  RR_NOT = 0x0f,
9199  RR_MFHI = 0x10,
9200  RR_CNVT = 0x11,
9201  RR_MFLO = 0x12,
9202  RR_DSRA = 0x13,
9203  RR_DSLLV = 0x14,
9204  RR_DSRLV = 0x16,
9205  RR_DSRAV = 0x17,
9206  RR_MULT = 0x18,
9207  RR_MULTU = 0x19,
9208  RR_DIV = 0x1a,
9209  RR_DIVU = 0x1b,
9210  RR_DMULT = 0x1c,
9211  RR_DMULTU = 0x1d,
9212  RR_DDIV = 0x1e,
9213  RR_DDIVU = 0x1f
9214};
9215
9216/* I64 funct field */
9217enum {
9218  I64_LDSP = 0x0,
9219  I64_SDSP = 0x1,
9220  I64_SDRASP = 0x2,
9221  I64_DADJSP = 0x3,
9222  I64_LDPC = 0x4,
9223  I64_DADDIU5 = 0x5,
9224  I64_DADDIUPC = 0x6,
9225  I64_DADDIUSP = 0x7
9226};
9227
9228/* RR ry field for CNVT */
9229enum {
9230  RR_RY_CNVT_ZEB = 0x0,
9231  RR_RY_CNVT_ZEH = 0x1,
9232  RR_RY_CNVT_ZEW = 0x2,
9233  RR_RY_CNVT_SEB = 0x4,
9234  RR_RY_CNVT_SEH = 0x5,
9235  RR_RY_CNVT_SEW = 0x6,
9236};
9237
9238static int xlat (int r)
9239{
9240  static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
9241
9242  return map[r];
9243}
9244
9245static void gen_mips16_save (DisasContext *ctx,
9246                             int xsregs, int aregs,
9247                             int do_ra, int do_s0, int do_s1,
9248                             int framesize)
9249{
9250    TCGv t0 = tcg_temp_new();
9251    TCGv t1 = tcg_temp_new();
9252    int args, astatic;
9253
9254    switch (aregs) {
9255    case 0:
9256    case 1:
9257    case 2:
9258    case 3:
9259    case 11:
9260        args = 0;
9261        break;
9262    case 4:
9263    case 5:
9264    case 6:
9265    case 7:
9266        args = 1;
9267        break;
9268    case 8:
9269    case 9:
9270    case 10:
9271        args = 2;
9272        break;
9273    case 12:
9274    case 13:
9275        args = 3;
9276        break;
9277    case 14:
9278        args = 4;
9279        break;
9280    default:
9281        generate_exception(ctx, EXCP_RI);
9282        return;
9283    }
9284
9285    switch (args) {
9286    case 4:
9287        gen_base_offset_addr(ctx, t0, 29, 12);
9288        gen_load_gpr(t1, 7);
9289        tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9290        /* Fall through */
9291    case 3:
9292        gen_base_offset_addr(ctx, t0, 29, 8);
9293        gen_load_gpr(t1, 6);
9294        tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9295        /* Fall through */
9296    case 2:
9297        gen_base_offset_addr(ctx, t0, 29, 4);
9298        gen_load_gpr(t1, 5);
9299        tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9300        /* Fall through */
9301    case 1:
9302        gen_base_offset_addr(ctx, t0, 29, 0);
9303        gen_load_gpr(t1, 4);
9304        tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
9305    }
9306
9307    gen_load_gpr(t0, 29);
9308
9309#define DECR_AND_STORE(reg) do {                \
9310        tcg_gen_subi_tl(t0, t0, 4);             \
9311        gen_load_gpr(t1, reg);                  \
9312        tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);                  \
9313    } while (0)
9314
9315    if (do_ra) {
9316        DECR_AND_STORE(31);
9317    }
9318
9319    switch (xsregs) {
9320    case 7:
9321        DECR_AND_STORE(30);
9322        /* Fall through */
9323    case 6:
9324        DECR_AND_STORE(23);
9325        /* Fall through */
9326    case 5:
9327        DECR_AND_STORE(22);
9328        /* Fall through */
9329    case 4:
9330        DECR_AND_STORE(21);
9331        /* Fall through */
9332    case 3:
9333        DECR_AND_STORE(20);
9334        /* Fall through */
9335    case 2:
9336        DECR_AND_STORE(19);
9337        /* Fall through */
9338    case 1:
9339        DECR_AND_STORE(18);
9340    }
9341
9342    if (do_s1) {
9343        DECR_AND_STORE(17);
9344    }
9345    if (do_s0) {
9346        DECR_AND_STORE(16);
9347    }
9348
9349    switch (aregs) {
9350    case 0:
9351    case 4:
9352    case 8:
9353    case 12:
9354    case 14:
9355        astatic = 0;
9356        break;
9357    case 1:
9358    case 5:
9359    case 9:
9360    case 13:
9361        astatic = 1;
9362        break;
9363    case 2:
9364    case 6:
9365    case 10:
9366        astatic = 2;
9367        break;
9368    case 3:
9369    case 7:
9370        astatic = 3;
9371        break;
9372    case 11:
9373        astatic = 4;
9374        break;
9375    default:
9376        generate_exception(ctx, EXCP_RI);
9377        return;
9378    }
9379
9380    if (astatic > 0) {
9381        DECR_AND_STORE(7);
9382        if (astatic > 1) {
9383            DECR_AND_STORE(6);
9384            if (astatic > 2) {
9385                DECR_AND_STORE(5);
9386                if (astatic > 3) {
9387                    DECR_AND_STORE(4);
9388                }
9389            }
9390        }
9391    }
9392#undef DECR_AND_STORE
9393
9394    tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9395    tcg_temp_free(t0);
9396    tcg_temp_free(t1);
9397}
9398
9399static void gen_mips16_restore (DisasContext *ctx,
9400                                int xsregs, int aregs,
9401                                int do_ra, int do_s0, int do_s1,
9402                                int framesize)
9403{
9404    int astatic;
9405    TCGv t0 = tcg_temp_new();
9406    TCGv t1 = tcg_temp_new();
9407
9408    tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
9409
9410#define DECR_AND_LOAD(reg) do {                   \
9411        tcg_gen_subi_tl(t0, t0, 4);               \
9412        tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx); \
9413        gen_store_gpr(t1, reg);                   \
9414    } while (0)
9415
9416    if (do_ra) {
9417        DECR_AND_LOAD(31);
9418    }
9419
9420    switch (xsregs) {
9421    case 7:
9422        DECR_AND_LOAD(30);
9423        /* Fall through */
9424    case 6:
9425        DECR_AND_LOAD(23);
9426        /* Fall through */
9427    case 5:
9428        DECR_AND_LOAD(22);
9429        /* Fall through */
9430    case 4:
9431        DECR_AND_LOAD(21);
9432        /* Fall through */
9433    case 3:
9434        DECR_AND_LOAD(20);
9435        /* Fall through */
9436    case 2:
9437        DECR_AND_LOAD(19);
9438        /* Fall through */
9439    case 1:
9440        DECR_AND_LOAD(18);
9441    }
9442
9443    if (do_s1) {
9444        DECR_AND_LOAD(17);
9445    }
9446    if (do_s0) {
9447        DECR_AND_LOAD(16);
9448    }
9449
9450    switch (aregs) {
9451    case 0:
9452    case 4:
9453    case 8:
9454    case 12:
9455    case 14:
9456        astatic = 0;
9457        break;
9458    case 1:
9459    case 5:
9460    case 9:
9461    case 13:
9462        astatic = 1;
9463        break;
9464    case 2:
9465    case 6:
9466    case 10:
9467        astatic = 2;
9468        break;
9469    case 3:
9470    case 7:
9471        astatic = 3;
9472        break;
9473    case 11:
9474        astatic = 4;
9475        break;
9476    default:
9477        generate_exception(ctx, EXCP_RI);
9478        return;
9479    }
9480
9481    if (astatic > 0) {
9482        DECR_AND_LOAD(7);
9483        if (astatic > 1) {
9484            DECR_AND_LOAD(6);
9485            if (astatic > 2) {
9486                DECR_AND_LOAD(5);
9487                if (astatic > 3) {
9488                    DECR_AND_LOAD(4);
9489                }
9490            }
9491        }
9492    }
9493#undef DECR_AND_LOAD
9494
9495    tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
9496    tcg_temp_free(t0);
9497    tcg_temp_free(t1);
9498}
9499
9500static void gen_addiupc (DisasContext *ctx, int rx, int imm,
9501                         int is_64_bit, int extended)
9502{
9503    TCGv t0;
9504
9505    if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9506        generate_exception(ctx, EXCP_RI);
9507        return;
9508    }
9509
9510    t0 = tcg_temp_new();
9511
9512    tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
9513    tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
9514    if (!is_64_bit) {
9515        tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
9516    }
9517
9518    tcg_temp_free(t0);
9519}
9520
9521#if defined(TARGET_MIPS64)
9522static void decode_i64_mips16 (DisasContext *ctx,
9523                               int ry, int funct, int16_t offset,
9524                               int extended)
9525{
9526    switch (funct) {
9527    case I64_LDSP:
9528        check_mips_64(ctx);
9529        offset = extended ? offset : offset << 3;
9530        gen_ld(ctx, OPC_LD, ry, 29, offset);
9531        break;
9532    case I64_SDSP:
9533        check_mips_64(ctx);
9534        offset = extended ? offset : offset << 3;
9535        gen_st(ctx, OPC_SD, ry, 29, offset);
9536        break;
9537    case I64_SDRASP:
9538        check_mips_64(ctx);
9539        offset = extended ? offset : (ctx->opcode & 0xff) << 3;
9540        gen_st(ctx, OPC_SD, 31, 29, offset);
9541        break;
9542    case I64_DADJSP:
9543        check_mips_64(ctx);
9544        offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
9545        gen_arith_imm(ctx, OPC_DADDIU, 29, 29, offset);
9546        break;
9547    case I64_LDPC:
9548        if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
9549            generate_exception(ctx, EXCP_RI);
9550        } else {
9551            offset = extended ? offset : offset << 3;
9552            gen_ld(ctx, OPC_LDPC, ry, 0, offset);
9553        }
9554        break;
9555    case I64_DADDIU5:
9556        check_mips_64(ctx);
9557        offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
9558        gen_arith_imm(ctx, OPC_DADDIU, ry, ry, offset);
9559        break;
9560    case I64_DADDIUPC:
9561        check_mips_64(ctx);
9562        offset = extended ? offset : offset << 2;
9563        gen_addiupc(ctx, ry, offset, 1, extended);
9564        break;
9565    case I64_DADDIUSP:
9566        check_mips_64(ctx);
9567        offset = extended ? offset : offset << 2;
9568        gen_arith_imm(ctx, OPC_DADDIU, ry, 29, offset);
9569        break;
9570    }
9571}
9572#endif
9573
9574static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
9575{
9576    int extend = cpu_lduw_code(env, ctx->pc + 2);
9577    int op, rx, ry, funct, sa;
9578    int16_t imm, offset;
9579
9580    ctx->opcode = (ctx->opcode << 16) | extend;
9581    op = (ctx->opcode >> 11) & 0x1f;
9582    sa = (ctx->opcode >> 22) & 0x1f;
9583    funct = (ctx->opcode >> 8) & 0x7;
9584    rx = xlat((ctx->opcode >> 8) & 0x7);
9585    ry = xlat((ctx->opcode >> 5) & 0x7);
9586    offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
9587                              | ((ctx->opcode >> 21) & 0x3f) << 5
9588                              | (ctx->opcode & 0x1f));
9589
9590    /* The extended opcodes cleverly reuse the opcodes from their 16-bit
9591       counterparts.  */
9592    switch (op) {
9593    case M16_OPC_ADDIUSP:
9594        gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
9595        break;
9596    case M16_OPC_ADDIUPC:
9597        gen_addiupc(ctx, rx, imm, 0, 1);
9598        break;
9599    case M16_OPC_B:
9600        gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
9601        /* No delay slot, so just process as a normal instruction */
9602        break;
9603    case M16_OPC_BEQZ:
9604        gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
9605        /* No delay slot, so just process as a normal instruction */
9606        break;
9607    case M16_OPC_BNEQZ:
9608        gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
9609        /* No delay slot, so just process as a normal instruction */
9610        break;
9611    case M16_OPC_SHIFT:
9612        switch (ctx->opcode & 0x3) {
9613        case 0x0:
9614            gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
9615            break;
9616        case 0x1:
9617#if defined(TARGET_MIPS64)
9618            check_mips_64(ctx);
9619            gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
9620#else
9621            generate_exception(ctx, EXCP_RI);
9622#endif
9623            break;
9624        case 0x2:
9625            gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
9626            break;
9627        case 0x3:
9628            gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
9629            break;
9630        }
9631        break;
9632#if defined(TARGET_MIPS64)
9633    case M16_OPC_LD:
9634            check_mips_64(ctx);
9635        gen_ld(ctx, OPC_LD, ry, rx, offset);
9636        break;
9637#endif
9638    case M16_OPC_RRIA:
9639        imm = ctx->opcode & 0xf;
9640        imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
9641        imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
9642        imm = (int16_t) (imm << 1) >> 1;
9643        if ((ctx->opcode >> 4) & 0x1) {
9644#if defined(TARGET_MIPS64)
9645            check_mips_64(ctx);
9646            gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
9647#else
9648            generate_exception(ctx, EXCP_RI);
9649#endif
9650        } else {
9651            gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
9652        }
9653        break;
9654    case M16_OPC_ADDIU8:
9655        gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
9656        break;
9657    case M16_OPC_SLTI:
9658        gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
9659        break;
9660    case M16_OPC_SLTIU:
9661        gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
9662        break;
9663    case M16_OPC_I8:
9664        switch (funct) {
9665        case I8_BTEQZ:
9666            gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
9667            break;
9668        case I8_BTNEZ:
9669            gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
9670            break;
9671        case I8_SWRASP:
9672            gen_st(ctx, OPC_SW, 31, 29, imm);
9673            break;
9674        case I8_ADJSP:
9675            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm);
9676            break;
9677        case I8_SVRS:
9678            {
9679                int xsregs = (ctx->opcode >> 24) & 0x7;
9680                int aregs = (ctx->opcode >> 16) & 0xf;
9681                int do_ra = (ctx->opcode >> 6) & 0x1;
9682                int do_s0 = (ctx->opcode >> 5) & 0x1;
9683                int do_s1 = (ctx->opcode >> 4) & 0x1;
9684                int framesize = (((ctx->opcode >> 20) & 0xf) << 4
9685                                 | (ctx->opcode & 0xf)) << 3;
9686
9687                if (ctx->opcode & (1 << 7)) {
9688                    gen_mips16_save(ctx, xsregs, aregs,
9689                                    do_ra, do_s0, do_s1,
9690                                    framesize);
9691                } else {
9692                    gen_mips16_restore(ctx, xsregs, aregs,
9693                                       do_ra, do_s0, do_s1,
9694                                       framesize);
9695                }
9696            }
9697            break;
9698        default:
9699            generate_exception(ctx, EXCP_RI);
9700            break;
9701        }
9702        break;
9703    case M16_OPC_LI:
9704        tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
9705        break;
9706    case M16_OPC_CMPI:
9707        tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
9708        break;
9709#if defined(TARGET_MIPS64)
9710    case M16_OPC_SD:
9711        gen_st(ctx, OPC_SD, ry, rx, offset);
9712        break;
9713#endif
9714    case M16_OPC_LB:
9715        gen_ld(ctx, OPC_LB, ry, rx, offset);
9716        break;
9717    case M16_OPC_LH:
9718        gen_ld(ctx, OPC_LH, ry, rx, offset);
9719        break;
9720    case M16_OPC_LWSP:
9721        gen_ld(ctx, OPC_LW, rx, 29, offset);
9722        break;
9723    case M16_OPC_LW:
9724        gen_ld(ctx, OPC_LW, ry, rx, offset);
9725        break;
9726    case M16_OPC_LBU:
9727        gen_ld(ctx, OPC_LBU, ry, rx, offset);
9728        break;
9729    case M16_OPC_LHU:
9730        gen_ld(ctx, OPC_LHU, ry, rx, offset);
9731        break;
9732    case M16_OPC_LWPC:
9733        gen_ld(ctx, OPC_LWPC, rx, 0, offset);
9734        break;
9735#if defined(TARGET_MIPS64)
9736    case M16_OPC_LWU:
9737        gen_ld(ctx, OPC_LWU, ry, rx, offset);
9738        break;
9739#endif
9740    case M16_OPC_SB:
9741        gen_st(ctx, OPC_SB, ry, rx, offset);
9742        break;
9743    case M16_OPC_SH:
9744        gen_st(ctx, OPC_SH, ry, rx, offset);
9745        break;
9746    case M16_OPC_SWSP:
9747        gen_st(ctx, OPC_SW, rx, 29, offset);
9748        break;
9749    case M16_OPC_SW:
9750        gen_st(ctx, OPC_SW, ry, rx, offset);
9751        break;
9752#if defined(TARGET_MIPS64)
9753    case M16_OPC_I64:
9754        decode_i64_mips16(ctx, ry, funct, offset, 1);
9755        break;
9756#endif
9757    default:
9758        generate_exception(ctx, EXCP_RI);
9759        break;
9760    }
9761
9762    return 4;
9763}
9764
9765static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx)
9766{
9767    int rx, ry;
9768    int sa;
9769    int op, cnvt_op, op1, offset;
9770    int funct;
9771    int n_bytes;
9772
9773    op = (ctx->opcode >> 11) & 0x1f;
9774    sa = (ctx->opcode >> 2) & 0x7;
9775    sa = sa == 0 ? 8 : sa;
9776    rx = xlat((ctx->opcode >> 8) & 0x7);
9777    cnvt_op = (ctx->opcode >> 5) & 0x7;
9778    ry = xlat((ctx->opcode >> 5) & 0x7);
9779    op1 = offset = ctx->opcode & 0x1f;
9780
9781    n_bytes = 2;
9782
9783    switch (op) {
9784    case M16_OPC_ADDIUSP:
9785        {
9786            int16_t imm = ((uint8_t) ctx->opcode) << 2;
9787
9788            gen_arith_imm(ctx, OPC_ADDIU, rx, 29, imm);
9789        }
9790        break;
9791    case M16_OPC_ADDIUPC:
9792        gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
9793        break;
9794    case M16_OPC_B:
9795        offset = (ctx->opcode & 0x7ff) << 1;
9796        offset = (int16_t)(offset << 4) >> 4;
9797        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
9798        /* No delay slot, so just process as a normal instruction */
9799        break;
9800    case M16_OPC_JAL:
9801        offset = cpu_lduw_code(env, ctx->pc + 2);
9802        offset = (((ctx->opcode & 0x1f) << 21)
9803                  | ((ctx->opcode >> 5) & 0x1f) << 16
9804                  | offset) << 2;
9805        op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
9806        gen_compute_branch(ctx, op, 4, rx, ry, offset);
9807        n_bytes = 4;
9808        break;
9809    case M16_OPC_BEQZ:
9810        gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9811        /* No delay slot, so just process as a normal instruction */
9812        break;
9813    case M16_OPC_BNEQZ:
9814        gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
9815        /* No delay slot, so just process as a normal instruction */
9816        break;
9817    case M16_OPC_SHIFT:
9818        switch (ctx->opcode & 0x3) {
9819        case 0x0:
9820            gen_shift_imm(ctx, OPC_SLL, rx, ry, sa);
9821            break;
9822        case 0x1:
9823#if defined(TARGET_MIPS64)
9824            check_mips_64(ctx);
9825            gen_shift_imm(ctx, OPC_DSLL, rx, ry, sa);
9826#else
9827            generate_exception(ctx, EXCP_RI);
9828#endif
9829            break;
9830        case 0x2:
9831            gen_shift_imm(ctx, OPC_SRL, rx, ry, sa);
9832            break;
9833        case 0x3:
9834            gen_shift_imm(ctx, OPC_SRA, rx, ry, sa);
9835            break;
9836        }
9837        break;
9838#if defined(TARGET_MIPS64)
9839    case M16_OPC_LD:
9840        check_mips_64(ctx);
9841        gen_ld(ctx, OPC_LD, ry, rx, offset << 3);
9842        break;
9843#endif
9844    case M16_OPC_RRIA:
9845        {
9846            int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
9847
9848            if ((ctx->opcode >> 4) & 1) {
9849#if defined(TARGET_MIPS64)
9850                check_mips_64(ctx);
9851                gen_arith_imm(ctx, OPC_DADDIU, ry, rx, imm);
9852#else
9853                generate_exception(ctx, EXCP_RI);
9854#endif
9855            } else {
9856                gen_arith_imm(ctx, OPC_ADDIU, ry, rx, imm);
9857            }
9858        }
9859        break;
9860    case M16_OPC_ADDIU8:
9861        {
9862            int16_t imm = (int8_t) ctx->opcode;
9863
9864            gen_arith_imm(ctx, OPC_ADDIU, rx, rx, imm);
9865        }
9866        break;
9867    case M16_OPC_SLTI:
9868        {
9869            int16_t imm = (uint8_t) ctx->opcode;
9870            gen_slt_imm(ctx, OPC_SLTI, 24, rx, imm);
9871        }
9872        break;
9873    case M16_OPC_SLTIU:
9874        {
9875            int16_t imm = (uint8_t) ctx->opcode;
9876            gen_slt_imm(ctx, OPC_SLTIU, 24, rx, imm);
9877        }
9878        break;
9879    case M16_OPC_I8:
9880        {
9881            int reg32;
9882
9883            funct = (ctx->opcode >> 8) & 0x7;
9884            switch (funct) {
9885            case I8_BTEQZ:
9886                gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
9887                                   ((int8_t)ctx->opcode) << 1);
9888                break;
9889            case I8_BTNEZ:
9890                gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
9891                                   ((int8_t)ctx->opcode) << 1);
9892                break;
9893            case I8_SWRASP:
9894                gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
9895                break;
9896            case I8_ADJSP:
9897                gen_arith_imm(ctx, OPC_ADDIU, 29, 29,
9898                              ((int8_t)ctx->opcode) << 3);
9899                break;
9900            case I8_SVRS:
9901                {
9902                    int do_ra = ctx->opcode & (1 << 6);
9903                    int do_s0 = ctx->opcode & (1 << 5);
9904                    int do_s1 = ctx->opcode & (1 << 4);
9905                    int framesize = ctx->opcode & 0xf;
9906
9907                    if (framesize == 0) {
9908                        framesize = 128;
9909                    } else {
9910                        framesize = framesize << 3;
9911                    }
9912
9913                    if (ctx->opcode & (1 << 7)) {
9914                        gen_mips16_save(ctx, 0, 0,
9915                                        do_ra, do_s0, do_s1, framesize);
9916                    } else {
9917                        gen_mips16_restore(ctx, 0, 0,
9918                                           do_ra, do_s0, do_s1, framesize);
9919                    }
9920                }
9921                break;
9922            case I8_MOV32R:
9923                {
9924                    int rz = xlat(ctx->opcode & 0x7);
9925
9926                    reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
9927                        ((ctx->opcode >> 5) & 0x7);
9928                    gen_arith(ctx, OPC_ADDU, reg32, rz, 0);
9929                }
9930                break;
9931            case I8_MOVR32:
9932                reg32 = ctx->opcode & 0x1f;
9933                gen_arith(ctx, OPC_ADDU, ry, reg32, 0);
9934                break;
9935            default:
9936                generate_exception(ctx, EXCP_RI);
9937                break;
9938            }
9939        }
9940        break;
9941    case M16_OPC_LI:
9942        {
9943            int16_t imm = (uint8_t) ctx->opcode;
9944
9945            gen_arith_imm(ctx, OPC_ADDIU, rx, 0, imm);
9946        }
9947        break;
9948    case M16_OPC_CMPI:
9949        {
9950            int16_t imm = (uint8_t) ctx->opcode;
9951            gen_logic_imm(ctx, OPC_XORI, 24, rx, imm);
9952        }
9953        break;
9954#if defined(TARGET_MIPS64)
9955    case M16_OPC_SD:
9956        check_mips_64(ctx);
9957        gen_st(ctx, OPC_SD, ry, rx, offset << 3);
9958        break;
9959#endif
9960    case M16_OPC_LB:
9961        gen_ld(ctx, OPC_LB, ry, rx, offset);
9962        break;
9963    case M16_OPC_LH:
9964        gen_ld(ctx, OPC_LH, ry, rx, offset << 1);
9965        break;
9966    case M16_OPC_LWSP:
9967        gen_ld(ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
9968        break;
9969    case M16_OPC_LW:
9970        gen_ld(ctx, OPC_LW, ry, rx, offset << 2);
9971        break;
9972    case M16_OPC_LBU:
9973        gen_ld(ctx, OPC_LBU, ry, rx, offset);
9974        break;
9975    case M16_OPC_LHU:
9976        gen_ld(ctx, OPC_LHU, ry, rx, offset << 1);
9977        break;
9978    case M16_OPC_LWPC:
9979        gen_ld(ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
9980        break;
9981#if defined (TARGET_MIPS64)
9982    case M16_OPC_LWU:
9983        check_mips_64(ctx);
9984        gen_ld(ctx, OPC_LWU, ry, rx, offset << 2);
9985        break;
9986#endif
9987    case M16_OPC_SB:
9988        gen_st(ctx, OPC_SB, ry, rx, offset);
9989        break;
9990    case M16_OPC_SH:
9991        gen_st(ctx, OPC_SH, ry, rx, offset << 1);
9992        break;
9993    case M16_OPC_SWSP:
9994        gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
9995        break;
9996    case M16_OPC_SW:
9997        gen_st(ctx, OPC_SW, ry, rx, offset << 2);
9998        break;
9999    case M16_OPC_RRR:
10000        {
10001            int rz = xlat((ctx->opcode >> 2) & 0x7);
10002            int mips32_op;
10003
10004            switch (ctx->opcode & 0x3) {
10005            case RRR_ADDU:
10006                mips32_op = OPC_ADDU;
10007                break;
10008            case RRR_SUBU:
10009                mips32_op = OPC_SUBU;
10010                break;
10011#if defined(TARGET_MIPS64)
10012            case RRR_DADDU:
10013                mips32_op = OPC_DADDU;
10014                check_mips_64(ctx);
10015                break;
10016            case RRR_DSUBU:
10017                mips32_op = OPC_DSUBU;
10018                check_mips_64(ctx);
10019                break;
10020#endif
10021            default:
10022                generate_exception(ctx, EXCP_RI);
10023                goto done;
10024            }
10025
10026            gen_arith(ctx, mips32_op, rz, rx, ry);
10027        done:
10028            ;
10029        }
10030        break;
10031    case M16_OPC_RR:
10032        switch (op1) {
10033        case RR_JR:
10034            {
10035                int nd = (ctx->opcode >> 7) & 0x1;
10036                int link = (ctx->opcode >> 6) & 0x1;
10037                int ra = (ctx->opcode >> 5) & 0x1;
10038
10039                if (link) {
10040                    op = nd ? OPC_JALRC : OPC_JALRS;
10041                } else {
10042                    op = OPC_JR;
10043                }
10044
10045                gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
10046            }
10047            break;
10048        case RR_SDBBP:
10049            /* XXX: not clear which exception should be raised
10050             *      when in debug mode...
10051             */
10052            check_insn(ctx, ISA_MIPS32);
10053            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10054                generate_exception(ctx, EXCP_DBp);
10055            } else {
10056                generate_exception(ctx, EXCP_DBp);
10057            }
10058            break;
10059        case RR_SLT:
10060            gen_slt(ctx, OPC_SLT, 24, rx, ry);
10061            break;
10062        case RR_SLTU:
10063            gen_slt(ctx, OPC_SLTU, 24, rx, ry);
10064            break;
10065        case RR_BREAK:
10066            generate_exception(ctx, EXCP_BREAK);
10067            break;
10068        case RR_SLLV:
10069            gen_shift(ctx, OPC_SLLV, ry, rx, ry);
10070            break;
10071        case RR_SRLV:
10072            gen_shift(ctx, OPC_SRLV, ry, rx, ry);
10073            break;
10074        case RR_SRAV:
10075            gen_shift(ctx, OPC_SRAV, ry, rx, ry);
10076            break;
10077#if defined (TARGET_MIPS64)
10078        case RR_DSRL:
10079            check_mips_64(ctx);
10080            gen_shift_imm(ctx, OPC_DSRL, ry, ry, sa);
10081            break;
10082#endif
10083        case RR_CMP:
10084            gen_logic(ctx, OPC_XOR, 24, rx, ry);
10085            break;
10086        case RR_NEG:
10087            gen_arith(ctx, OPC_SUBU, rx, 0, ry);
10088            break;
10089        case RR_AND:
10090            gen_logic(ctx, OPC_AND, rx, rx, ry);
10091            break;
10092        case RR_OR:
10093            gen_logic(ctx, OPC_OR, rx, rx, ry);
10094            break;
10095        case RR_XOR:
10096            gen_logic(ctx, OPC_XOR, rx, rx, ry);
10097            break;
10098        case RR_NOT:
10099            gen_logic(ctx, OPC_NOR, rx, ry, 0);
10100            break;
10101        case RR_MFHI:
10102            gen_HILO(ctx, OPC_MFHI, 0, rx);
10103            break;
10104        case RR_CNVT:
10105            switch (cnvt_op) {
10106            case RR_RY_CNVT_ZEB:
10107                tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10108                break;
10109            case RR_RY_CNVT_ZEH:
10110                tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10111                break;
10112            case RR_RY_CNVT_SEB:
10113                tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10114                break;
10115            case RR_RY_CNVT_SEH:
10116                tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10117                break;
10118#if defined (TARGET_MIPS64)
10119            case RR_RY_CNVT_ZEW:
10120                check_mips_64(ctx);
10121                tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
10122                break;
10123            case RR_RY_CNVT_SEW:
10124                check_mips_64(ctx);
10125                tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
10126                break;
10127#endif
10128            default:
10129                generate_exception(ctx, EXCP_RI);
10130                break;
10131            }
10132            break;
10133        case RR_MFLO:
10134            gen_HILO(ctx, OPC_MFLO, 0, rx);
10135            break;
10136#if defined (TARGET_MIPS64)
10137        case RR_DSRA:
10138            check_mips_64(ctx);
10139            gen_shift_imm(ctx, OPC_DSRA, ry, ry, sa);
10140            break;
10141        case RR_DSLLV:
10142            check_mips_64(ctx);
10143            gen_shift(ctx, OPC_DSLLV, ry, rx, ry);
10144            break;
10145        case RR_DSRLV:
10146            check_mips_64(ctx);
10147            gen_shift(ctx, OPC_DSRLV, ry, rx, ry);
10148            break;
10149        case RR_DSRAV:
10150            check_mips_64(ctx);
10151            gen_shift(ctx, OPC_DSRAV, ry, rx, ry);
10152            break;
10153#endif
10154        case RR_MULT:
10155            gen_muldiv(ctx, OPC_MULT, 0, rx, ry);
10156            break;
10157        case RR_MULTU:
10158            gen_muldiv(ctx, OPC_MULTU, 0, rx, ry);
10159            break;
10160        case RR_DIV:
10161            gen_muldiv(ctx, OPC_DIV, 0, rx, ry);
10162            break;
10163        case RR_DIVU:
10164            gen_muldiv(ctx, OPC_DIVU, 0, rx, ry);
10165            break;
10166#if defined (TARGET_MIPS64)
10167        case RR_DMULT:
10168            check_mips_64(ctx);
10169            gen_muldiv(ctx, OPC_DMULT, 0, rx, ry);
10170            break;
10171        case RR_DMULTU:
10172            check_mips_64(ctx);
10173            gen_muldiv(ctx, OPC_DMULTU, 0, rx, ry);
10174            break;
10175        case RR_DDIV:
10176            check_mips_64(ctx);
10177            gen_muldiv(ctx, OPC_DDIV, 0, rx, ry);
10178            break;
10179        case RR_DDIVU:
10180            check_mips_64(ctx);
10181            gen_muldiv(ctx, OPC_DDIVU, 0, rx, ry);
10182            break;
10183#endif
10184        default:
10185            generate_exception(ctx, EXCP_RI);
10186            break;
10187        }
10188        break;
10189    case M16_OPC_EXTEND:
10190        decode_extended_mips16_opc(env, ctx);
10191        n_bytes = 4;
10192        break;
10193#if defined(TARGET_MIPS64)
10194    case M16_OPC_I64:
10195        funct = (ctx->opcode >> 8) & 0x7;
10196        decode_i64_mips16(ctx, ry, funct, offset, 0);
10197        break;
10198#endif
10199    default:
10200        generate_exception(ctx, EXCP_RI);
10201        break;
10202    }
10203
10204    return n_bytes;
10205}
10206
10207/* microMIPS extension to MIPS32/MIPS64 */
10208
10209/*
10210 * microMIPS32/microMIPS64 major opcodes
10211 *
10212 * 1. MIPS Architecture for Programmers Volume II-B:
10213 *      The microMIPS32 Instruction Set (Revision 3.05)
10214 *
10215 *    Table 6.2 microMIPS32 Encoding of Major Opcode Field
10216 *
10217 * 2. MIPS Architecture For Programmers Volume II-A:
10218 *      The MIPS64 Instruction Set (Revision 3.51)
10219 */
10220
10221enum {
10222    POOL32A = 0x00,
10223    POOL16A = 0x01,
10224    LBU16 = 0x02,
10225    MOVE16 = 0x03,
10226    ADDI32 = 0x04,
10227    LBU32 = 0x05,
10228    SB32 = 0x06,
10229    LB32 = 0x07,
10230
10231    POOL32B = 0x08,
10232    POOL16B = 0x09,
10233    LHU16 = 0x0a,
10234    ANDI16 = 0x0b,
10235    ADDIU32 = 0x0c,
10236    LHU32 = 0x0d,
10237    SH32 = 0x0e,
10238    LH32 = 0x0f,
10239
10240    POOL32I = 0x10,
10241    POOL16C = 0x11,
10242    LWSP16 = 0x12,
10243    POOL16D = 0x13,
10244    ORI32 = 0x14,
10245    POOL32F = 0x15,
10246    POOL32S = 0x16,  /* MIPS64 */
10247    DADDIU32 = 0x17, /* MIPS64 */
10248
10249    /* 0x1f is reserved */
10250    POOL32C = 0x18,
10251    LWGP16 = 0x19,
10252    LW16 = 0x1a,
10253    POOL16E = 0x1b,
10254    XORI32 = 0x1c,
10255    JALS32 = 0x1d,
10256    ADDIUPC = 0x1e,
10257
10258    /* 0x20 is reserved */
10259    RES_20 = 0x20,
10260    POOL16F = 0x21,
10261    SB16 = 0x22,
10262    BEQZ16 = 0x23,
10263    SLTI32 = 0x24,
10264    BEQ32 = 0x25,
10265    SWC132 = 0x26,
10266    LWC132 = 0x27,
10267
10268    /* 0x28 and 0x29 are reserved */
10269    RES_28 = 0x28,
10270    RES_29 = 0x29,
10271    SH16 = 0x2a,
10272    BNEZ16 = 0x2b,
10273    SLTIU32 = 0x2c,
10274    BNE32 = 0x2d,
10275    SDC132 = 0x2e,
10276    LDC132 = 0x2f,
10277
10278    /* 0x30 and 0x31 are reserved */
10279    RES_30 = 0x30,
10280    RES_31 = 0x31,
10281    SWSP16 = 0x32,
10282    B16 = 0x33,
10283    ANDI32 = 0x34,
10284    J32 = 0x35,
10285    SD32 = 0x36, /* MIPS64 */
10286    LD32 = 0x37, /* MIPS64 */
10287
10288    /* 0x38 and 0x39 are reserved */
10289    RES_38 = 0x38,
10290    RES_39 = 0x39,
10291    SW16 = 0x3a,
10292    LI16 = 0x3b,
10293    JALX32 = 0x3c,
10294    JAL32 = 0x3d,
10295    SW32 = 0x3e,
10296    LW32 = 0x3f
10297};
10298
10299/* POOL32A encoding of minor opcode field */
10300
10301enum {
10302    /* These opcodes are distinguished only by bits 9..6; those bits are
10303     * what are recorded below. */
10304    SLL32 = 0x0,
10305    SRL32 = 0x1,
10306    SRA = 0x2,
10307    ROTR = 0x3,
10308
10309    SLLV = 0x0,
10310    SRLV = 0x1,
10311    SRAV = 0x2,
10312    ROTRV = 0x3,
10313    ADD = 0x4,
10314    ADDU32 = 0x5,
10315    SUB = 0x6,
10316    SUBU32 = 0x7,
10317    MUL = 0x8,
10318    AND = 0x9,
10319    OR32 = 0xa,
10320    NOR = 0xb,
10321    XOR32 = 0xc,
10322    SLT = 0xd,
10323    SLTU = 0xe,
10324
10325    MOVN = 0x0,
10326    MOVZ = 0x1,
10327    LWXS = 0x4,
10328
10329    /* The following can be distinguished by their lower 6 bits. */
10330    INS = 0x0c,
10331    EXT = 0x2c,
10332    POOL32AXF = 0x3c
10333};
10334
10335/* POOL32AXF encoding of minor opcode field extension */
10336
10337/*
10338 * 1. MIPS Architecture for Programmers Volume II-B:
10339 *      The microMIPS32 Instruction Set (Revision 3.05)
10340 *
10341 *    Table 6.5 POOL32Axf Encoding of Minor Opcode Extension Field
10342 *
10343 * 2. MIPS Architecture for Programmers VolumeIV-e:
10344 *      The MIPS DSP Application-Specific Extension
10345 *        to the microMIPS32 Architecture (Revision 2.34)
10346 *
10347 *    Table 5.5 POOL32Axf Encoding of Minor Opcode Extension Field
10348 */
10349
10350enum {
10351    /* bits 11..6 */
10352    TEQ = 0x00,
10353    TGE = 0x08,
10354    TGEU = 0x10,
10355    TLT = 0x20,
10356    TLTU = 0x28,
10357    TNE = 0x30,
10358
10359    MFC0 = 0x03,
10360    MTC0 = 0x0b,
10361
10362    /* begin of microMIPS32 DSP */
10363
10364    /* bits 13..12 for 0x01 */
10365    MFHI_ACC = 0x0,
10366    MFLO_ACC = 0x1,
10367    MTHI_ACC = 0x2,
10368    MTLO_ACC = 0x3,
10369
10370    /* bits 13..12 for 0x2a */
10371    MADD_ACC = 0x0,
10372    MADDU_ACC = 0x1,
10373    MSUB_ACC = 0x2,
10374    MSUBU_ACC = 0x3,
10375
10376    /* bits 13..12 for 0x32 */
10377    MULT_ACC = 0x0,
10378    MULTU_ACC = 0x1,
10379
10380    /* end of microMIPS32 DSP */
10381
10382    /* bits 15..12 for 0x2c */
10383    SEB = 0x2,
10384    SEH = 0x3,
10385    CLO = 0x4,
10386    CLZ = 0x5,
10387    RDHWR = 0x6,
10388    WSBH = 0x7,
10389    MULT = 0x8,
10390    MULTU = 0x9,
10391    DIV = 0xa,
10392    DIVU = 0xb,
10393    MADD = 0xc,
10394    MADDU = 0xd,
10395    MSUB = 0xe,
10396    MSUBU = 0xf,
10397
10398    /* bits 15..12 for 0x34 */
10399    MFC2 = 0x4,
10400    MTC2 = 0x5,
10401    MFHC2 = 0x8,
10402    MTHC2 = 0x9,
10403    CFC2 = 0xc,
10404    CTC2 = 0xd,
10405
10406    /* bits 15..12 for 0x3c */
10407    JALR = 0x0,
10408    JR = 0x0,                   /* alias */
10409    JALR_HB = 0x1,
10410    JALRS = 0x4,
10411    JALRS_HB = 0x5,
10412
10413    /* bits 15..12 for 0x05 */
10414    RDPGPR = 0xe,
10415    WRPGPR = 0xf,
10416
10417    /* bits 15..12 for 0x0d */
10418    TLBP = 0x0,
10419    TLBR = 0x1,
10420    TLBWI = 0x2,
10421    TLBWR = 0x3,
10422    WAIT = 0x9,
10423    IRET = 0xd,
10424    DERET = 0xe,
10425    ERET = 0xf,
10426
10427    /* bits 15..12 for 0x15 */
10428    DMT = 0x0,
10429    DVPE = 0x1,
10430    EMT = 0x2,
10431    EVPE = 0x3,
10432
10433    /* bits 15..12 for 0x1d */
10434    DI = 0x4,
10435    EI = 0x5,
10436
10437    /* bits 15..12 for 0x2d */
10438    SYNC = 0x6,
10439    SYSCALL = 0x8,
10440    SDBBP = 0xd,
10441
10442    /* bits 15..12 for 0x35 */
10443    MFHI32 = 0x0,
10444    MFLO32 = 0x1,
10445    MTHI32 = 0x2,
10446    MTLO32 = 0x3,
10447};
10448
10449/* POOL32B encoding of minor opcode field (bits 15..12) */
10450
10451enum {
10452    LWC2 = 0x0,
10453    LWP = 0x1,
10454    LDP = 0x4,
10455    LWM32 = 0x5,
10456    CACHE = 0x6,
10457    LDM = 0x7,
10458    SWC2 = 0x8,
10459    SWP = 0x9,
10460    SDP = 0xc,
10461    SWM32 = 0xd,
10462    SDM = 0xf
10463};
10464
10465/* POOL32C encoding of minor opcode field (bits 15..12) */
10466
10467enum {
10468    LWL = 0x0,
10469    SWL = 0x8,
10470    LWR = 0x1,
10471    SWR = 0x9,
10472    PREF = 0x2,
10473    /* 0xa is reserved */
10474    LL = 0x3,
10475    SC = 0xb,
10476    LDL = 0x4,
10477    SDL = 0xc,
10478    LDR = 0x5,
10479    SDR = 0xd,
10480    /* 0x6 is reserved */
10481    LWU = 0xe,
10482    LLD = 0x7,
10483    SCD = 0xf
10484};
10485
10486/* POOL32F encoding of minor opcode field (bits 5..0) */
10487
10488enum {
10489    /* These are the bit 7..6 values */
10490    ADD_FMT = 0x0,
10491    MOVN_FMT = 0x0,
10492
10493    SUB_FMT = 0x1,
10494    MOVZ_FMT = 0x1,
10495
10496    MUL_FMT = 0x2,
10497
10498    DIV_FMT = 0x3,
10499
10500    /* These are the bit 8..6 values */
10501    RSQRT2_FMT = 0x0,
10502    MOVF_FMT = 0x0,
10503
10504    LWXC1 = 0x1,
10505    MOVT_FMT = 0x1,
10506
10507    PLL_PS = 0x2,
10508    SWXC1 = 0x2,
10509
10510    PLU_PS = 0x3,
10511    LDXC1 = 0x3,
10512
10513    PUL_PS = 0x4,
10514    SDXC1 = 0x4,
10515    RECIP2_FMT = 0x4,
10516
10517    PUU_PS = 0x5,
10518    LUXC1 = 0x5,
10519
10520    CVT_PS_S = 0x6,
10521    SUXC1 = 0x6,
10522    ADDR_PS = 0x6,
10523    PREFX = 0x6,
10524
10525    MULR_PS = 0x7,
10526
10527    MADD_S = 0x01,
10528    MADD_D = 0x09,
10529    MADD_PS = 0x11,
10530    ALNV_PS = 0x19,
10531    MSUB_S = 0x21,
10532    MSUB_D = 0x29,
10533    MSUB_PS = 0x31,
10534
10535    NMADD_S = 0x02,
10536    NMADD_D = 0x0a,
10537    NMADD_PS = 0x12,
10538    NMSUB_S = 0x22,
10539    NMSUB_D = 0x2a,
10540    NMSUB_PS = 0x32,
10541
10542    POOL32FXF = 0x3b,
10543
10544    CABS_COND_FMT = 0x1c,              /* MIPS3D */
10545    C_COND_FMT = 0x3c
10546};
10547
10548/* POOL32Fxf encoding of minor opcode extension field */
10549
10550enum {
10551    CVT_L = 0x04,
10552    RSQRT_FMT = 0x08,
10553    FLOOR_L = 0x0c,
10554    CVT_PW_PS = 0x1c,
10555    CVT_W = 0x24,
10556    SQRT_FMT = 0x28,
10557    FLOOR_W = 0x2c,
10558    CVT_PS_PW = 0x3c,
10559    CFC1 = 0x40,
10560    RECIP_FMT = 0x48,
10561    CEIL_L = 0x4c,
10562    CTC1 = 0x60,
10563    CEIL_W = 0x6c,
10564    MFC1 = 0x80,
10565    CVT_S_PL = 0x84,
10566    TRUNC_L = 0x8c,
10567    MTC1 = 0xa0,
10568    CVT_S_PU = 0xa4,
10569    TRUNC_W = 0xac,
10570    MFHC1 = 0xc0,
10571    ROUND_L = 0xcc,
10572    MTHC1 = 0xe0,
10573    ROUND_W = 0xec,
10574
10575    MOV_FMT = 0x01,
10576    MOVF = 0x05,
10577    ABS_FMT = 0x0d,
10578    RSQRT1_FMT = 0x1d,
10579    MOVT = 0x25,
10580    NEG_FMT = 0x2d,
10581    CVT_D = 0x4d,
10582    RECIP1_FMT = 0x5d,
10583    CVT_S = 0x6d
10584};
10585
10586/* POOL32I encoding of minor opcode field (bits 25..21) */
10587
10588enum {
10589    BLTZ = 0x00,
10590    BLTZAL = 0x01,
10591    BGEZ = 0x02,
10592    BGEZAL = 0x03,
10593    BLEZ = 0x04,
10594    BNEZC = 0x05,
10595    BGTZ = 0x06,
10596    BEQZC = 0x07,
10597    TLTI = 0x08,
10598    TGEI = 0x09,
10599    TLTIU = 0x0a,
10600    TGEIU = 0x0b,
10601    TNEI = 0x0c,
10602    LUI = 0x0d,
10603    TEQI = 0x0e,
10604    SYNCI = 0x10,
10605    BLTZALS = 0x11,
10606    BGEZALS = 0x13,
10607    BC2F = 0x14,
10608    BC2T = 0x15,
10609    BPOSGE64 = 0x1a,
10610    BPOSGE32 = 0x1b,
10611    /* These overlap and are distinguished by bit16 of the instruction */
10612    BC1F = 0x1c,
10613    BC1T = 0x1d,
10614    BC1ANY2F = 0x1c,
10615    BC1ANY2T = 0x1d,
10616    BC1ANY4F = 0x1e,
10617    BC1ANY4T = 0x1f
10618};
10619
10620/* POOL16A encoding of minor opcode field */
10621
10622enum {
10623    ADDU16 = 0x0,
10624    SUBU16 = 0x1
10625};
10626
10627/* POOL16B encoding of minor opcode field */
10628
10629enum {
10630    SLL16 = 0x0,
10631    SRL16 = 0x1
10632};
10633
10634/* POOL16C encoding of minor opcode field */
10635
10636enum {
10637    NOT16 = 0x00,
10638    XOR16 = 0x04,
10639    AND16 = 0x08,
10640    OR16 = 0x0c,
10641    LWM16 = 0x10,
10642    SWM16 = 0x14,
10643    JR16 = 0x18,
10644    JRC16 = 0x1a,
10645    JALR16 = 0x1c,
10646    JALR16S = 0x1e,
10647    MFHI16 = 0x20,
10648    MFLO16 = 0x24,
10649    BREAK16 = 0x28,
10650    SDBBP16 = 0x2c,
10651    JRADDIUSP = 0x30
10652};
10653
10654/* POOL16D encoding of minor opcode field */
10655
10656enum {
10657    ADDIUS5 = 0x0,
10658    ADDIUSP = 0x1
10659};
10660
10661/* POOL16E encoding of minor opcode field */
10662
10663enum {
10664    ADDIUR2 = 0x0,
10665    ADDIUR1SP = 0x1
10666};
10667
10668static int mmreg (int r)
10669{
10670    static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
10671
10672    return map[r];
10673}
10674
10675/* Used for 16-bit store instructions.  */
10676static int mmreg2 (int r)
10677{
10678    static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
10679
10680    return map[r];
10681}
10682
10683#define uMIPS_RD(op) ((op >> 7) & 0x7)
10684#define uMIPS_RS(op) ((op >> 4) & 0x7)
10685#define uMIPS_RS2(op) uMIPS_RS(op)
10686#define uMIPS_RS1(op) ((op >> 1) & 0x7)
10687#define uMIPS_RD5(op) ((op >> 5) & 0x1f)
10688#define uMIPS_RS5(op) (op & 0x1f)
10689
10690/* Signed immediate */
10691#define SIMM(op, start, width)                                          \
10692    ((int32_t)(((op >> start) & ((~0U) >> (32-width)))                 \
10693               << (32-width))                                           \
10694     >> (32-width))
10695/* Zero-extended immediate */
10696#define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
10697
10698static void gen_addiur1sp(DisasContext *ctx)
10699{
10700    int rd = mmreg(uMIPS_RD(ctx->opcode));
10701
10702    gen_arith_imm(ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
10703}
10704
10705static void gen_addiur2(DisasContext *ctx)
10706{
10707    static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
10708    int rd = mmreg(uMIPS_RD(ctx->opcode));
10709    int rs = mmreg(uMIPS_RS(ctx->opcode));
10710
10711    gen_arith_imm(ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
10712}
10713
10714static void gen_addiusp(DisasContext *ctx)
10715{
10716    int encoded = ZIMM(ctx->opcode, 1, 9);
10717    int decoded;
10718
10719    if (encoded <= 1) {
10720        decoded = 256 + encoded;
10721    } else if (encoded <= 255) {
10722        decoded = encoded;
10723    } else if (encoded <= 509) {
10724        decoded = encoded - 512;
10725    } else {
10726        decoded = encoded - 768;
10727    }
10728
10729    gen_arith_imm(ctx, OPC_ADDIU, 29, 29, decoded << 2);
10730}
10731
10732static void gen_addius5(DisasContext *ctx)
10733{
10734    int imm = SIMM(ctx->opcode, 1, 4);
10735    int rd = (ctx->opcode >> 5) & 0x1f;
10736
10737    gen_arith_imm(ctx, OPC_ADDIU, rd, rd, imm);
10738}
10739
10740static void gen_andi16(DisasContext *ctx)
10741{
10742    static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
10743                                 31, 32, 63, 64, 255, 32768, 65535 };
10744    int rd = mmreg(uMIPS_RD(ctx->opcode));
10745    int rs = mmreg(uMIPS_RS(ctx->opcode));
10746    int encoded = ZIMM(ctx->opcode, 0, 4);
10747
10748    gen_logic_imm(ctx, OPC_ANDI, rd, rs, decoded_imm[encoded]);
10749}
10750
10751static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
10752                               int base, int16_t offset)
10753{
10754    const char *opn = "ldst_multiple";
10755    TCGv t0, t1;
10756    TCGv_i32 t2;
10757
10758    if (ctx->hflags & MIPS_HFLAG_BMASK) {
10759        generate_exception(ctx, EXCP_RI);
10760        return;
10761    }
10762
10763    t0 = tcg_temp_new();
10764
10765    gen_base_offset_addr(ctx, t0, base, offset);
10766
10767    t1 = tcg_const_tl(reglist);
10768    t2 = tcg_const_i32(ctx->mem_idx);
10769
10770    save_cpu_state(ctx, 1);
10771    switch (opc) {
10772    case LWM32:
10773        gen_helper_lwm(cpu_env, t0, t1, t2);
10774        opn = "lwm";
10775        break;
10776    case SWM32:
10777        gen_helper_swm(cpu_env, t0, t1, t2);
10778        opn = "swm";
10779        break;
10780#ifdef TARGET_MIPS64
10781    case LDM:
10782        gen_helper_ldm(cpu_env, t0, t1, t2);
10783        opn = "ldm";
10784        break;
10785    case SDM:
10786        gen_helper_sdm(cpu_env, t0, t1, t2);
10787        opn = "sdm";
10788        break;
10789#endif
10790    }
10791    (void)opn;
10792    MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
10793    tcg_temp_free(t0);
10794    tcg_temp_free(t1);
10795    tcg_temp_free_i32(t2);
10796}
10797
10798
10799static void gen_pool16c_insn(DisasContext *ctx)
10800{
10801    int rd = mmreg((ctx->opcode >> 3) & 0x7);
10802    int rs = mmreg(ctx->opcode & 0x7);
10803    int opc;
10804
10805    switch (((ctx->opcode) >> 4) & 0x3f) {
10806    case NOT16 + 0:
10807    case NOT16 + 1:
10808    case NOT16 + 2:
10809    case NOT16 + 3:
10810        gen_logic(ctx, OPC_NOR, rd, rs, 0);
10811        break;
10812    case XOR16 + 0:
10813    case XOR16 + 1:
10814    case XOR16 + 2:
10815    case XOR16 + 3:
10816        gen_logic(ctx, OPC_XOR, rd, rd, rs);
10817        break;
10818    case AND16 + 0:
10819    case AND16 + 1:
10820    case AND16 + 2:
10821    case AND16 + 3:
10822        gen_logic(ctx, OPC_AND, rd, rd, rs);
10823        break;
10824    case OR16 + 0:
10825    case OR16 + 1:
10826    case OR16 + 2:
10827    case OR16 + 3:
10828        gen_logic(ctx, OPC_OR, rd, rd, rs);
10829        break;
10830    case LWM16 + 0:
10831    case LWM16 + 1:
10832    case LWM16 + 2:
10833    case LWM16 + 3:
10834        {
10835            static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10836            int offset = ZIMM(ctx->opcode, 0, 4);
10837
10838            gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
10839                              29, offset << 2);
10840        }
10841        break;
10842    case SWM16 + 0:
10843    case SWM16 + 1:
10844    case SWM16 + 2:
10845    case SWM16 + 3:
10846        {
10847            static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
10848            int offset = ZIMM(ctx->opcode, 0, 4);
10849
10850            gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
10851                              29, offset << 2);
10852        }
10853        break;
10854    case JR16 + 0:
10855    case JR16 + 1:
10856        {
10857            int reg = ctx->opcode & 0x1f;
10858
10859            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10860        }
10861        break;
10862    case JRC16 + 0:
10863    case JRC16 + 1:
10864        {
10865            int reg = ctx->opcode & 0x1f;
10866
10867            gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
10868            /* Let normal delay slot handling in our caller take us
10869               to the branch target.  */
10870        }
10871        break;
10872    case JALR16 + 0:
10873    case JALR16 + 1:
10874        opc = OPC_JALR;
10875        goto do_jalr;
10876    case JALR16S + 0:
10877    case JALR16S + 1:
10878        opc = OPC_JALRS;
10879    do_jalr:
10880        {
10881            int reg = ctx->opcode & 0x1f;
10882
10883            gen_compute_branch(ctx, opc, 2, reg, 31, 0);
10884        }
10885        break;
10886    case MFHI16 + 0:
10887    case MFHI16 + 1:
10888        gen_HILO(ctx, OPC_MFHI, 0, uMIPS_RS5(ctx->opcode));
10889        break;
10890    case MFLO16 + 0:
10891    case MFLO16 + 1:
10892        gen_HILO(ctx, OPC_MFLO, 0, uMIPS_RS5(ctx->opcode));
10893        break;
10894    case BREAK16:
10895        generate_exception(ctx, EXCP_BREAK);
10896        break;
10897    case SDBBP16:
10898        /* XXX: not clear which exception should be raised
10899         *      when in debug mode...
10900         */
10901        check_insn(ctx, ISA_MIPS32);
10902        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
10903            generate_exception(ctx, EXCP_DBp);
10904        } else {
10905            generate_exception(ctx, EXCP_DBp);
10906        }
10907        break;
10908    case JRADDIUSP + 0:
10909    case JRADDIUSP + 1:
10910        {
10911            int imm = ZIMM(ctx->opcode, 0, 5);
10912
10913            gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
10914            gen_arith_imm(ctx, OPC_ADDIU, 29, 29, imm << 2);
10915            /* Let normal delay slot handling in our caller take us
10916               to the branch target.  */
10917        }
10918        break;
10919    default:
10920        generate_exception(ctx, EXCP_RI);
10921        break;
10922    }
10923}
10924
10925static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
10926{
10927    TCGv t0 = tcg_temp_new();
10928    TCGv t1 = tcg_temp_new();
10929
10930    gen_load_gpr(t0, base);
10931
10932    if (index != 0) {
10933        gen_load_gpr(t1, index);
10934        tcg_gen_shli_tl(t1, t1, 2);
10935        gen_op_addr_add(ctx, t0, t1, t0);
10936    }
10937
10938    tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
10939    gen_store_gpr(t1, rd);
10940
10941    tcg_temp_free(t0);
10942    tcg_temp_free(t1);
10943}
10944
10945static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
10946                           int base, int16_t offset)
10947{
10948    const char *opn = "ldst_pair";
10949    TCGv t0, t1;
10950
10951    if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31) {
10952        generate_exception(ctx, EXCP_RI);
10953        return;
10954    }
10955
10956    t0 = tcg_temp_new();
10957    t1 = tcg_temp_new();
10958
10959    gen_base_offset_addr(ctx, t0, base, offset);
10960
10961    switch (opc) {
10962    case LWP:
10963        if (rd == base) {
10964            generate_exception(ctx, EXCP_RI);
10965            return;
10966        }
10967        tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
10968        gen_store_gpr(t1, rd);
10969        tcg_gen_movi_tl(t1, 4);
10970        gen_op_addr_add(ctx, t0, t0, t1);
10971        tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
10972        gen_store_gpr(t1, rd+1);
10973        opn = "lwp";
10974        break;
10975    case SWP:
10976        gen_load_gpr(t1, rd);
10977        tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
10978        tcg_gen_movi_tl(t1, 4);
10979        gen_op_addr_add(ctx, t0, t0, t1);
10980        gen_load_gpr(t1, rd+1);
10981        tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
10982        opn = "swp";
10983        break;
10984#ifdef TARGET_MIPS64
10985    case LDP:
10986        if (rd == base) {
10987            generate_exception(ctx, EXCP_RI);
10988            return;
10989        }
10990        tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
10991        gen_store_gpr(t1, rd);
10992        tcg_gen_movi_tl(t1, 8);
10993        gen_op_addr_add(ctx, t0, t0, t1);
10994        tcg_gen_qemu_ld64(t1, t0, ctx->mem_idx);
10995        gen_store_gpr(t1, rd+1);
10996        opn = "ldp";
10997        break;
10998    case SDP:
10999        gen_load_gpr(t1, rd);
11000        tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
11001        tcg_gen_movi_tl(t1, 8);
11002        gen_op_addr_add(ctx, t0, t0, t1);
11003        gen_load_gpr(t1, rd+1);
11004        tcg_gen_qemu_st64(t1, t0, ctx->mem_idx);
11005        opn = "sdp";
11006        break;
11007#endif
11008    }
11009    (void)opn; /* avoid a compiler warning */
11010    MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
11011    tcg_temp_free(t0);
11012    tcg_temp_free(t1);
11013}
11014
11015static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
11016{
11017    int extension = (ctx->opcode >> 6) & 0x3f;
11018    int minor = (ctx->opcode >> 12) & 0xf;
11019    uint32_t mips32_op;
11020
11021    switch (extension) {
11022    case TEQ:
11023        mips32_op = OPC_TEQ;
11024        goto do_trap;
11025    case TGE:
11026        mips32_op = OPC_TGE;
11027        goto do_trap;
11028    case TGEU:
11029        mips32_op = OPC_TGEU;
11030        goto do_trap;
11031    case TLT:
11032        mips32_op = OPC_TLT;
11033        goto do_trap;
11034    case TLTU:
11035        mips32_op = OPC_TLTU;
11036        goto do_trap;
11037    case TNE:
11038        mips32_op = OPC_TNE;
11039    do_trap:
11040        gen_trap(ctx, mips32_op, rs, rt, -1);
11041        break;
11042#ifndef CONFIG_USER_ONLY
11043    case MFC0:
11044    case MFC0 + 32:
11045        check_cp0_enabled(ctx);
11046        if (rt == 0) {
11047            /* Treat as NOP. */
11048            break;
11049        }
11050        gen_mfc0(ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
11051        break;
11052    case MTC0:
11053    case MTC0 + 32:
11054        check_cp0_enabled(ctx);
11055        {
11056            TCGv t0 = tcg_temp_new();
11057
11058            gen_load_gpr(t0, rt);
11059            gen_mtc0(ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
11060            tcg_temp_free(t0);
11061        }
11062        break;
11063#endif
11064    case 0x2a:
11065        switch (minor & 3) {
11066        case MADD_ACC:
11067            gen_muldiv(ctx, OPC_MADD, (ctx->opcode >> 14) & 3, rs, rt);
11068            break;
11069        case MADDU_ACC:
11070            gen_muldiv(ctx, OPC_MADDU, (ctx->opcode >> 14) & 3, rs, rt);
11071            break;
11072        case MSUB_ACC:
11073            gen_muldiv(ctx, OPC_MSUB, (ctx->opcode >> 14) & 3, rs, rt);
11074            break;
11075        case MSUBU_ACC:
11076            gen_muldiv(ctx, OPC_MSUBU, (ctx->opcode >> 14) & 3, rs, rt);
11077            break;
11078        default:
11079            goto pool32axf_invalid;
11080        }
11081        break;
11082    case 0x32:
11083        switch (minor & 3) {
11084        case MULT_ACC:
11085            gen_muldiv(ctx, OPC_MULT, (ctx->opcode >> 14) & 3, rs, rt);
11086            break;
11087        case MULTU_ACC:
11088            gen_muldiv(ctx, OPC_MULTU, (ctx->opcode >> 14) & 3, rs, rt);
11089            break;
11090        default:
11091            goto pool32axf_invalid;
11092        }
11093        break;
11094    case 0x2c:
11095        switch (minor) {
11096        case SEB:
11097            gen_bshfl(ctx, OPC_SEB, rs, rt);
11098            break;
11099        case SEH:
11100            gen_bshfl(ctx, OPC_SEH, rs, rt);
11101            break;
11102        case CLO:
11103            mips32_op = OPC_CLO;
11104            goto do_cl;
11105        case CLZ:
11106            mips32_op = OPC_CLZ;
11107        do_cl:
11108            check_insn(ctx, ISA_MIPS32);
11109            gen_cl(ctx, mips32_op, rt, rs);
11110            break;
11111        case RDHWR:
11112            gen_rdhwr(ctx, rt, rs);
11113            break;
11114        case WSBH:
11115            gen_bshfl(ctx, OPC_WSBH, rs, rt);
11116            break;
11117        case MULT:
11118            mips32_op = OPC_MULT;
11119            goto do_mul;
11120        case MULTU:
11121            mips32_op = OPC_MULTU;
11122            goto do_mul;
11123        case DIV:
11124            mips32_op = OPC_DIV;
11125            goto do_div;
11126        case DIVU:
11127            mips32_op = OPC_DIVU;
11128            goto do_div;
11129        do_div:
11130            check_insn(ctx, ISA_MIPS32);
11131            gen_muldiv(ctx, mips32_op, 0, rs, rt);
11132            break;
11133        case MADD:
11134            mips32_op = OPC_MADD;
11135            goto do_mul;
11136        case MADDU:
11137            mips32_op = OPC_MADDU;
11138            goto do_mul;
11139        case MSUB:
11140            mips32_op = OPC_MSUB;
11141            goto do_mul;
11142        case MSUBU:
11143            mips32_op = OPC_MSUBU;
11144        do_mul:
11145            check_insn(ctx, ISA_MIPS32);
11146            gen_muldiv(ctx, mips32_op, 0, rs, rt);
11147            break;
11148        default:
11149            goto pool32axf_invalid;
11150        }
11151        break;
11152    case 0x34:
11153        switch (minor) {
11154        case MFC2:
11155        case MTC2:
11156        case MFHC2:
11157        case MTHC2:
11158        case CFC2:
11159        case CTC2:
11160            generate_exception_err(ctx, EXCP_CpU, 2);
11161            break;
11162        default:
11163            goto pool32axf_invalid;
11164        }
11165        break;
11166    case 0x3c:
11167        switch (minor) {
11168        case JALR:
11169        case JALR_HB:
11170            gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
11171            break;
11172        case JALRS:
11173        case JALRS_HB:
11174            gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
11175            break;
11176        default:
11177            goto pool32axf_invalid;
11178        }
11179        break;
11180    case 0x05:
11181        switch (minor) {
11182        case RDPGPR:
11183            check_cp0_enabled(ctx);
11184            check_insn(ctx, ISA_MIPS32R2);
11185            gen_load_srsgpr(rt, rs);
11186            break;
11187        case WRPGPR:
11188            check_cp0_enabled(ctx);
11189            check_insn(ctx, ISA_MIPS32R2);
11190            gen_store_srsgpr(rt, rs);
11191            break;
11192        default:
11193            goto pool32axf_invalid;
11194        }
11195        break;
11196#ifndef CONFIG_USER_ONLY
11197    case 0x0d:
11198        switch (minor) {
11199        case TLBP:
11200            mips32_op = OPC_TLBP;
11201            goto do_cp0;
11202        case TLBR:
11203            mips32_op = OPC_TLBR;
11204            goto do_cp0;
11205        case TLBWI:
11206            mips32_op = OPC_TLBWI;
11207            goto do_cp0;
11208        case TLBWR:
11209            mips32_op = OPC_TLBWR;
11210            goto do_cp0;
11211        case WAIT:
11212            mips32_op = OPC_WAIT;
11213            goto do_cp0;
11214        case DERET:
11215            mips32_op = OPC_DERET;
11216            goto do_cp0;
11217        case ERET:
11218            mips32_op = OPC_ERET;
11219        do_cp0:
11220            gen_cp0(env, ctx, mips32_op, rt, rs);
11221            break;
11222        default:
11223            goto pool32axf_invalid;
11224        }
11225        break;
11226    case 0x1d:
11227        switch (minor) {
11228        case DI:
11229            check_cp0_enabled(ctx);
11230            {
11231                TCGv t0 = tcg_temp_new();
11232
11233                save_cpu_state(ctx, 1);
11234                gen_helper_di(t0, cpu_env);
11235                gen_store_gpr(t0, rs);
11236                /* Stop translation as we may have switched the execution mode */
11237                ctx->bstate = BS_STOP;
11238                tcg_temp_free(t0);
11239            }
11240            break;
11241        case EI:
11242            check_cp0_enabled(ctx);
11243            {
11244                TCGv t0 = tcg_temp_new();
11245
11246                save_cpu_state(ctx, 1);
11247                gen_helper_ei(t0, cpu_env);
11248                gen_store_gpr(t0, rs);
11249                /* Stop translation as we may have switched the execution mode */
11250                ctx->bstate = BS_STOP;
11251                tcg_temp_free(t0);
11252            }
11253            break;
11254        default:
11255            goto pool32axf_invalid;
11256        }
11257        break;
11258#endif
11259    case 0x2d:
11260        switch (minor) {
11261        case SYNC:
11262            /* NOP */
11263            break;
11264        case SYSCALL:
11265            generate_exception(ctx, EXCP_SYSCALL);
11266            ctx->bstate = BS_STOP;
11267            break;
11268        case SDBBP:
11269            check_insn(ctx, ISA_MIPS32);
11270            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
11271                generate_exception(ctx, EXCP_DBp);
11272            } else {
11273                generate_exception(ctx, EXCP_DBp);
11274            }
11275            break;
11276        default:
11277            goto pool32axf_invalid;
11278        }
11279        break;
11280    case 0x01:
11281        switch (minor & 3) {
11282        case MFHI_ACC:
11283            gen_HILO(ctx, OPC_MFHI, minor >> 2, rs);
11284            break;
11285        case MFLO_ACC:
11286            gen_HILO(ctx, OPC_MFLO, minor >> 2, rs);
11287            break;
11288        case MTHI_ACC:
11289            gen_HILO(ctx, OPC_MTHI, minor >> 2, rs);
11290            break;
11291        case MTLO_ACC:
11292            gen_HILO(ctx, OPC_MTLO, minor >> 2, rs);
11293            break;
11294        default:
11295            goto pool32axf_invalid;
11296        }
11297        break;
11298    case 0x35:
11299        switch (minor) {
11300        case MFHI32:
11301            gen_HILO(ctx, OPC_MFHI, 0, rs);
11302            break;
11303        case MFLO32:
11304            gen_HILO(ctx, OPC_MFLO, 0, rs);
11305            break;
11306        case MTHI32:
11307            gen_HILO(ctx, OPC_MTHI, 0, rs);
11308            break;
11309        case MTLO32:
11310            gen_HILO(ctx, OPC_MTLO, 0, rs);
11311            break;
11312        default:
11313            goto pool32axf_invalid;
11314        }
11315        break;
11316    default:
11317    pool32axf_invalid:
11318        MIPS_INVAL("pool32axf");
11319        generate_exception(ctx, EXCP_RI);
11320        break;
11321    }
11322}
11323
11324/* Values for microMIPS fmt field.  Variable-width, depending on which
11325   formats the instruction supports.  */
11326
11327enum {
11328    FMT_SD_S = 0,
11329    FMT_SD_D = 1,
11330
11331    FMT_SDPS_S = 0,
11332    FMT_SDPS_D = 1,
11333    FMT_SDPS_PS = 2,
11334
11335    FMT_SWL_S = 0,
11336    FMT_SWL_W = 1,
11337    FMT_SWL_L = 2,
11338
11339    FMT_DWL_D = 0,
11340    FMT_DWL_W = 1,
11341    FMT_DWL_L = 2
11342};
11343
11344static void gen_pool32fxf(DisasContext *ctx, int rt, int rs)
11345{
11346    int extension = (ctx->opcode >> 6) & 0x3ff;
11347    uint32_t mips32_op;
11348
11349#define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
11350#define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
11351#define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
11352
11353    switch (extension) {
11354    case FLOAT_1BIT_FMT(CFC1, 0):
11355        mips32_op = OPC_CFC1;
11356        goto do_cp1;
11357    case FLOAT_1BIT_FMT(CTC1, 0):
11358        mips32_op = OPC_CTC1;
11359        goto do_cp1;
11360    case FLOAT_1BIT_FMT(MFC1, 0):
11361        mips32_op = OPC_MFC1;
11362        goto do_cp1;
11363    case FLOAT_1BIT_FMT(MTC1, 0):
11364        mips32_op = OPC_MTC1;
11365        goto do_cp1;
11366    case FLOAT_1BIT_FMT(MFHC1, 0):
11367        mips32_op = OPC_MFHC1;
11368        goto do_cp1;
11369    case FLOAT_1BIT_FMT(MTHC1, 0):
11370        mips32_op = OPC_MTHC1;
11371    do_cp1:
11372        gen_cp1(ctx, mips32_op, rt, rs);
11373        break;
11374
11375        /* Reciprocal square root */
11376    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
11377        mips32_op = OPC_RSQRT_S;
11378        goto do_unaryfp;
11379    case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
11380        mips32_op = OPC_RSQRT_D;
11381        goto do_unaryfp;
11382
11383        /* Square root */
11384    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
11385        mips32_op = OPC_SQRT_S;
11386        goto do_unaryfp;
11387    case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
11388        mips32_op = OPC_SQRT_D;
11389        goto do_unaryfp;
11390
11391        /* Reciprocal */
11392    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
11393        mips32_op = OPC_RECIP_S;
11394        goto do_unaryfp;
11395    case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
11396        mips32_op = OPC_RECIP_D;
11397        goto do_unaryfp;
11398
11399        /* Floor */
11400    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
11401        mips32_op = OPC_FLOOR_L_S;
11402        goto do_unaryfp;
11403    case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
11404        mips32_op = OPC_FLOOR_L_D;
11405        goto do_unaryfp;
11406    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
11407        mips32_op = OPC_FLOOR_W_S;
11408        goto do_unaryfp;
11409    case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
11410        mips32_op = OPC_FLOOR_W_D;
11411        goto do_unaryfp;
11412
11413        /* Ceiling */
11414    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
11415        mips32_op = OPC_CEIL_L_S;
11416        goto do_unaryfp;
11417    case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
11418        mips32_op = OPC_CEIL_L_D;
11419        goto do_unaryfp;
11420    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
11421        mips32_op = OPC_CEIL_W_S;
11422        goto do_unaryfp;
11423    case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
11424        mips32_op = OPC_CEIL_W_D;
11425        goto do_unaryfp;
11426
11427        /* Truncation */
11428    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
11429        mips32_op = OPC_TRUNC_L_S;
11430        goto do_unaryfp;
11431    case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
11432        mips32_op = OPC_TRUNC_L_D;
11433        goto do_unaryfp;
11434    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
11435        mips32_op = OPC_TRUNC_W_S;
11436        goto do_unaryfp;
11437    case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
11438        mips32_op = OPC_TRUNC_W_D;
11439        goto do_unaryfp;
11440
11441        /* Round */
11442    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
11443        mips32_op = OPC_ROUND_L_S;
11444        goto do_unaryfp;
11445    case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
11446        mips32_op = OPC_ROUND_L_D;
11447        goto do_unaryfp;
11448    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
11449        mips32_op = OPC_ROUND_W_S;
11450        goto do_unaryfp;
11451    case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
11452        mips32_op = OPC_ROUND_W_D;
11453        goto do_unaryfp;
11454
11455        /* Integer to floating-point conversion */
11456    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
11457        mips32_op = OPC_CVT_L_S;
11458        goto do_unaryfp;
11459    case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
11460        mips32_op = OPC_CVT_L_D;
11461        goto do_unaryfp;
11462    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
11463        mips32_op = OPC_CVT_W_S;
11464        goto do_unaryfp;
11465    case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
11466        mips32_op = OPC_CVT_W_D;
11467        goto do_unaryfp;
11468
11469        /* Paired-foo conversions */
11470    case FLOAT_1BIT_FMT(CVT_S_PL, 0):
11471        mips32_op = OPC_CVT_S_PL;
11472        goto do_unaryfp;
11473    case FLOAT_1BIT_FMT(CVT_S_PU, 0):
11474        mips32_op = OPC_CVT_S_PU;
11475        goto do_unaryfp;
11476    case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
11477        mips32_op = OPC_CVT_PW_PS;
11478        goto do_unaryfp;
11479    case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
11480        mips32_op = OPC_CVT_PS_PW;
11481        goto do_unaryfp;
11482
11483        /* Floating-point moves */
11484    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
11485        mips32_op = OPC_MOV_S;
11486        goto do_unaryfp;
11487    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
11488        mips32_op = OPC_MOV_D;
11489        goto do_unaryfp;
11490    case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
11491        mips32_op = OPC_MOV_PS;
11492        goto do_unaryfp;
11493
11494        /* Absolute value */
11495    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
11496        mips32_op = OPC_ABS_S;
11497        goto do_unaryfp;
11498    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
11499        mips32_op = OPC_ABS_D;
11500        goto do_unaryfp;
11501    case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
11502        mips32_op = OPC_ABS_PS;
11503        goto do_unaryfp;
11504
11505        /* Negation */
11506    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
11507        mips32_op = OPC_NEG_S;
11508        goto do_unaryfp;
11509    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
11510        mips32_op = OPC_NEG_D;
11511        goto do_unaryfp;
11512    case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
11513        mips32_op = OPC_NEG_PS;
11514        goto do_unaryfp;
11515
11516        /* Reciprocal square root step */
11517    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
11518        mips32_op = OPC_RSQRT1_S;
11519        goto do_unaryfp;
11520    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
11521        mips32_op = OPC_RSQRT1_D;
11522        goto do_unaryfp;
11523    case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
11524        mips32_op = OPC_RSQRT1_PS;
11525        goto do_unaryfp;
11526
11527        /* Reciprocal step */
11528    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
11529        mips32_op = OPC_RECIP1_S;
11530        goto do_unaryfp;
11531    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
11532        mips32_op = OPC_RECIP1_S;
11533        goto do_unaryfp;
11534    case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
11535        mips32_op = OPC_RECIP1_PS;
11536        goto do_unaryfp;
11537
11538        /* Conversions from double */
11539    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
11540        mips32_op = OPC_CVT_D_S;
11541        goto do_unaryfp;
11542    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
11543        mips32_op = OPC_CVT_D_W;
11544        goto do_unaryfp;
11545    case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
11546        mips32_op = OPC_CVT_D_L;
11547        goto do_unaryfp;
11548
11549        /* Conversions from single */
11550    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
11551        mips32_op = OPC_CVT_S_D;
11552        goto do_unaryfp;
11553    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
11554        mips32_op = OPC_CVT_S_W;
11555        goto do_unaryfp;
11556    case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
11557        mips32_op = OPC_CVT_S_L;
11558    do_unaryfp:
11559        gen_farith(ctx, mips32_op, -1, rs, rt, 0);
11560        break;
11561
11562        /* Conditional moves on floating-point codes */
11563    case COND_FLOAT_MOV(MOVT, 0):
11564    case COND_FLOAT_MOV(MOVT, 1):
11565    case COND_FLOAT_MOV(MOVT, 2):
11566    case COND_FLOAT_MOV(MOVT, 3):
11567    case COND_FLOAT_MOV(MOVT, 4):
11568    case COND_FLOAT_MOV(MOVT, 5):
11569    case COND_FLOAT_MOV(MOVT, 6):
11570    case COND_FLOAT_MOV(MOVT, 7):
11571        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
11572        break;
11573    case COND_FLOAT_MOV(MOVF, 0):
11574    case COND_FLOAT_MOV(MOVF, 1):
11575    case COND_FLOAT_MOV(MOVF, 2):
11576    case COND_FLOAT_MOV(MOVF, 3):
11577    case COND_FLOAT_MOV(MOVF, 4):
11578    case COND_FLOAT_MOV(MOVF, 5):
11579    case COND_FLOAT_MOV(MOVF, 6):
11580    case COND_FLOAT_MOV(MOVF, 7):
11581        gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
11582        break;
11583    default:
11584        MIPS_INVAL("pool32fxf");
11585        generate_exception(ctx, EXCP_RI);
11586        break;
11587    }
11588}
11589
11590static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
11591                                    uint16_t insn_hw1)
11592{
11593    int32_t offset;
11594    uint16_t insn;
11595    int rt, rs, rd, rr;
11596    int16_t imm;
11597    uint32_t op, minor, mips32_op;
11598    uint32_t cond, fmt, cc;
11599
11600    insn = cpu_lduw_code(env, ctx->pc + 2);
11601    ctx->opcode = (ctx->opcode << 16) | insn;
11602
11603    rt = (ctx->opcode >> 21) & 0x1f;
11604    rs = (ctx->opcode >> 16) & 0x1f;
11605    rd = (ctx->opcode >> 11) & 0x1f;
11606    rr = (ctx->opcode >> 6) & 0x1f;
11607    imm = (int16_t) ctx->opcode;
11608
11609    op = (ctx->opcode >> 26) & 0x3f;
11610    switch (op) {
11611    case POOL32A:
11612        minor = ctx->opcode & 0x3f;
11613        switch (minor) {
11614        case 0x00:
11615            minor = (ctx->opcode >> 6) & 0xf;
11616            switch (minor) {
11617            case SLL32:
11618                mips32_op = OPC_SLL;
11619                goto do_shifti;
11620            case SRA:
11621                mips32_op = OPC_SRA;
11622                goto do_shifti;
11623            case SRL32:
11624                mips32_op = OPC_SRL;
11625                goto do_shifti;
11626            case ROTR:
11627                mips32_op = OPC_ROTR;
11628            do_shifti:
11629                gen_shift_imm(ctx, mips32_op, rt, rs, rd);
11630                break;
11631            default:
11632                goto pool32a_invalid;
11633            }
11634            break;
11635        case 0x10:
11636            minor = (ctx->opcode >> 6) & 0xf;
11637            switch (minor) {
11638                /* Arithmetic */
11639            case ADD:
11640                mips32_op = OPC_ADD;
11641                goto do_arith;
11642            case ADDU32:
11643                mips32_op = OPC_ADDU;
11644                goto do_arith;
11645            case SUB:
11646                mips32_op = OPC_SUB;
11647                goto do_arith;
11648            case SUBU32:
11649                mips32_op = OPC_SUBU;
11650                goto do_arith;
11651            case MUL:
11652                mips32_op = OPC_MUL;
11653            do_arith:
11654                gen_arith(ctx, mips32_op, rd, rs, rt);
11655                break;
11656                /* Shifts */
11657            case SLLV:
11658                mips32_op = OPC_SLLV;
11659                goto do_shift;
11660            case SRLV:
11661                mips32_op = OPC_SRLV;
11662                goto do_shift;
11663            case SRAV:
11664                mips32_op = OPC_SRAV;
11665                goto do_shift;
11666            case ROTRV:
11667                mips32_op = OPC_ROTRV;
11668            do_shift:
11669                gen_shift(ctx, mips32_op, rd, rs, rt);
11670                break;
11671                /* Logical operations */
11672            case AND:
11673                mips32_op = OPC_AND;
11674                goto do_logic;
11675            case OR32:
11676                mips32_op = OPC_OR;
11677                goto do_logic;
11678            case NOR:
11679                mips32_op = OPC_NOR;
11680                goto do_logic;
11681            case XOR32:
11682                mips32_op = OPC_XOR;
11683            do_logic:
11684                gen_logic(ctx, mips32_op, rd, rs, rt);
11685                break;
11686                /* Set less than */
11687            case SLT:
11688                mips32_op = OPC_SLT;
11689                goto do_slt;
11690            case SLTU:
11691                mips32_op = OPC_SLTU;
11692            do_slt:
11693                gen_slt(ctx, mips32_op, rd, rs, rt);
11694                break;
11695            default:
11696                goto pool32a_invalid;
11697            }
11698            break;
11699        case 0x18:
11700            minor = (ctx->opcode >> 6) & 0xf;
11701            switch (minor) {
11702                /* Conditional moves */
11703            case MOVN:
11704                mips32_op = OPC_MOVN;
11705                goto do_cmov;
11706            case MOVZ:
11707                mips32_op = OPC_MOVZ;
11708            do_cmov:
11709                gen_cond_move(ctx, mips32_op, rd, rs, rt);
11710                break;
11711            case LWXS:
11712                gen_ldxs(ctx, rs, rt, rd);
11713                break;
11714            default:
11715                goto pool32a_invalid;
11716            }
11717            break;
11718        case INS:
11719            gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
11720            return;
11721        case EXT:
11722            gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
11723            return;
11724        case POOL32AXF:
11725            gen_pool32axf(env, ctx, rt, rs);
11726            break;
11727        case 0x07:
11728            generate_exception(ctx, EXCP_BREAK);
11729            break;
11730        default:
11731        pool32a_invalid:
11732                MIPS_INVAL("pool32a");
11733                generate_exception(ctx, EXCP_RI);
11734                break;
11735        }
11736        break;
11737    case POOL32B:
11738        minor = (ctx->opcode >> 12) & 0xf;
11739        switch (minor) {
11740        case CACHE:
11741            check_cp0_enabled(ctx);
11742            /* Treat as no-op. */
11743            break;
11744        case LWC2:
11745        case SWC2:
11746            /* COP2: Not implemented. */
11747            generate_exception_err(ctx, EXCP_CpU, 2);
11748            break;
11749        case LWP:
11750        case SWP:
11751#ifdef TARGET_MIPS64
11752        case LDP:
11753        case SDP:
11754#endif
11755            gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11756            break;
11757        case LWM32:
11758        case SWM32:
11759#ifdef TARGET_MIPS64
11760        case LDM:
11761        case SDM:
11762#endif
11763            gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
11764            break;
11765        default:
11766            MIPS_INVAL("pool32b");
11767            generate_exception(ctx, EXCP_RI);
11768            break;
11769        }
11770        break;
11771    case POOL32F:
11772        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
11773            minor = ctx->opcode & 0x3f;
11774            check_cp1_enabled(ctx);
11775            switch (minor) {
11776            case ALNV_PS:
11777                mips32_op = OPC_ALNV_PS;
11778                goto do_madd;
11779            case MADD_S:
11780                mips32_op = OPC_MADD_S;
11781                goto do_madd;
11782            case MADD_D:
11783                mips32_op = OPC_MADD_D;
11784                goto do_madd;
11785            case MADD_PS:
11786                mips32_op = OPC_MADD_PS;
11787                goto do_madd;
11788            case MSUB_S:
11789                mips32_op = OPC_MSUB_S;
11790                goto do_madd;
11791            case MSUB_D:
11792                mips32_op = OPC_MSUB_D;
11793                goto do_madd;
11794            case MSUB_PS:
11795                mips32_op = OPC_MSUB_PS;
11796                goto do_madd;
11797            case NMADD_S:
11798                mips32_op = OPC_NMADD_S;
11799                goto do_madd;
11800            case NMADD_D:
11801                mips32_op = OPC_NMADD_D;
11802                goto do_madd;
11803            case NMADD_PS:
11804                mips32_op = OPC_NMADD_PS;
11805                goto do_madd;
11806            case NMSUB_S:
11807                mips32_op = OPC_NMSUB_S;
11808                goto do_madd;
11809            case NMSUB_D:
11810                mips32_op = OPC_NMSUB_D;
11811                goto do_madd;
11812            case NMSUB_PS:
11813                mips32_op = OPC_NMSUB_PS;
11814            do_madd:
11815                gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
11816                break;
11817            case CABS_COND_FMT:
11818                cond = (ctx->opcode >> 6) & 0xf;
11819                cc = (ctx->opcode >> 13) & 0x7;
11820                fmt = (ctx->opcode >> 10) & 0x3;
11821                switch (fmt) {
11822                case 0x0:
11823                    gen_cmpabs_s(ctx, cond, rt, rs, cc);
11824                    break;
11825                case 0x1:
11826                    gen_cmpabs_d(ctx, cond, rt, rs, cc);
11827                    break;
11828                case 0x2:
11829                    gen_cmpabs_ps(ctx, cond, rt, rs, cc);
11830                    break;
11831                default:
11832                    goto pool32f_invalid;
11833                }
11834                break;
11835            case C_COND_FMT:
11836                cond = (ctx->opcode >> 6) & 0xf;
11837                cc = (ctx->opcode >> 13) & 0x7;
11838                fmt = (ctx->opcode >> 10) & 0x3;
11839                switch (fmt) {
11840                case 0x0:
11841                    gen_cmp_s(ctx, cond, rt, rs, cc);
11842                    break;
11843                case 0x1:
11844                    gen_cmp_d(ctx, cond, rt, rs, cc);
11845                    break;
11846                case 0x2:
11847                    gen_cmp_ps(ctx, cond, rt, rs, cc);
11848                    break;
11849                default:
11850                    goto pool32f_invalid;
11851                }
11852                break;
11853            case POOL32FXF:
11854                gen_pool32fxf(ctx, rt, rs);
11855                break;
11856            case 0x00:
11857                /* PLL foo */
11858                switch ((ctx->opcode >> 6) & 0x7) {
11859                case PLL_PS:
11860                    mips32_op = OPC_PLL_PS;
11861                    goto do_ps;
11862                case PLU_PS:
11863                    mips32_op = OPC_PLU_PS;
11864                    goto do_ps;
11865                case PUL_PS:
11866                    mips32_op = OPC_PUL_PS;
11867                    goto do_ps;
11868                case PUU_PS:
11869                    mips32_op = OPC_PUU_PS;
11870                    goto do_ps;
11871                case CVT_PS_S:
11872                    mips32_op = OPC_CVT_PS_S;
11873                do_ps:
11874                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11875                    break;
11876                default:
11877                    goto pool32f_invalid;
11878                }
11879                break;
11880            case 0x08:
11881                /* [LS][WDU]XC1 */
11882                switch ((ctx->opcode >> 6) & 0x7) {
11883                case LWXC1:
11884                    mips32_op = OPC_LWXC1;
11885                    goto do_ldst_cp1;
11886                case SWXC1:
11887                    mips32_op = OPC_SWXC1;
11888                    goto do_ldst_cp1;
11889                case LDXC1:
11890                    mips32_op = OPC_LDXC1;
11891                    goto do_ldst_cp1;
11892                case SDXC1:
11893                    mips32_op = OPC_SDXC1;
11894                    goto do_ldst_cp1;
11895                case LUXC1:
11896                    mips32_op = OPC_LUXC1;
11897                    goto do_ldst_cp1;
11898                case SUXC1:
11899                    mips32_op = OPC_SUXC1;
11900                do_ldst_cp1:
11901                    gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
11902                    break;
11903                default:
11904                    goto pool32f_invalid;
11905                }
11906                break;
11907            case 0x18:
11908                /* 3D insns */
11909                fmt = (ctx->opcode >> 9) & 0x3;
11910                switch ((ctx->opcode >> 6) & 0x7) {
11911                case RSQRT2_FMT:
11912                    switch (fmt) {
11913                    case FMT_SDPS_S:
11914                        mips32_op = OPC_RSQRT2_S;
11915                        goto do_3d;
11916                    case FMT_SDPS_D:
11917                        mips32_op = OPC_RSQRT2_D;
11918                        goto do_3d;
11919                    case FMT_SDPS_PS:
11920                        mips32_op = OPC_RSQRT2_PS;
11921                        goto do_3d;
11922                    default:
11923                        goto pool32f_invalid;
11924                    }
11925                    break;
11926                case RECIP2_FMT:
11927                    switch (fmt) {
11928                    case FMT_SDPS_S:
11929                        mips32_op = OPC_RECIP2_S;
11930                        goto do_3d;
11931                    case FMT_SDPS_D:
11932                        mips32_op = OPC_RECIP2_D;
11933                        goto do_3d;
11934                    case FMT_SDPS_PS:
11935                        mips32_op = OPC_RECIP2_PS;
11936                        goto do_3d;
11937                    default:
11938                        goto pool32f_invalid;
11939                    }
11940                    break;
11941                case ADDR_PS:
11942                    mips32_op = OPC_ADDR_PS;
11943                    goto do_3d;
11944                case MULR_PS:
11945                    mips32_op = OPC_MULR_PS;
11946                do_3d:
11947                    gen_farith(ctx, mips32_op, rt, rs, rd, 0);
11948                    break;
11949                default:
11950                    goto pool32f_invalid;
11951                }
11952                break;
11953            case 0x20:
11954                /* MOV[FT].fmt and PREFX */
11955                cc = (ctx->opcode >> 13) & 0x7;
11956                fmt = (ctx->opcode >> 9) & 0x3;
11957                switch ((ctx->opcode >> 6) & 0x7) {
11958                case MOVF_FMT:
11959                    switch (fmt) {
11960                    case FMT_SDPS_S:
11961                        gen_movcf_s(rs, rt, cc, 0);
11962                        break;
11963                    case FMT_SDPS_D:
11964                        gen_movcf_d(ctx, rs, rt, cc, 0);
11965                        break;
11966                    case FMT_SDPS_PS:
11967                        gen_movcf_ps(rs, rt, cc, 0);
11968                        break;
11969                    default:
11970                        goto pool32f_invalid;
11971                    }
11972                    break;
11973                case MOVT_FMT:
11974                    switch (fmt) {
11975                    case FMT_SDPS_S:
11976                        gen_movcf_s(rs, rt, cc, 1);
11977                        break;
11978                    case FMT_SDPS_D:
11979                        gen_movcf_d(ctx, rs, rt, cc, 1);
11980                        break;
11981                    case FMT_SDPS_PS:
11982                        gen_movcf_ps(rs, rt, cc, 1);
11983                        break;
11984                    default:
11985                        goto pool32f_invalid;
11986                    }
11987                    break;
11988                case PREFX:
11989                    break;
11990                default:
11991                    goto pool32f_invalid;
11992                }
11993                break;
11994#define FINSN_3ARG_SDPS(prfx)                           \
11995                switch ((ctx->opcode >> 8) & 0x3) {     \
11996                case FMT_SDPS_S:                        \
11997                    mips32_op = OPC_##prfx##_S;         \
11998                    goto do_fpop;                       \
11999                case FMT_SDPS_D:                        \
12000                    mips32_op = OPC_##prfx##_D;         \
12001                    goto do_fpop;                       \
12002                case FMT_SDPS_PS:                       \
12003                    mips32_op = OPC_##prfx##_PS;        \
12004                    goto do_fpop;                       \
12005                default:                                \
12006                    goto pool32f_invalid;               \
12007                }
12008            case 0x30:
12009                /* regular FP ops */
12010                switch ((ctx->opcode >> 6) & 0x3) {
12011                case ADD_FMT:
12012                    FINSN_3ARG_SDPS(ADD);
12013                    break;
12014                case SUB_FMT:
12015                    FINSN_3ARG_SDPS(SUB);
12016                    break;
12017                case MUL_FMT:
12018                    FINSN_3ARG_SDPS(MUL);
12019                    break;
12020                case DIV_FMT:
12021                    fmt = (ctx->opcode >> 8) & 0x3;
12022                    if (fmt == 1) {
12023                        mips32_op = OPC_DIV_D;
12024                    } else if (fmt == 0) {
12025                        mips32_op = OPC_DIV_S;
12026                    } else {
12027                        goto pool32f_invalid;
12028                    }
12029                    goto do_fpop;
12030                default:
12031                    goto pool32f_invalid;
12032                }
12033                break;
12034            case 0x38:
12035                /* cmovs */
12036                switch ((ctx->opcode >> 6) & 0x3) {
12037                case MOVN_FMT:
12038                    FINSN_3ARG_SDPS(MOVN);
12039                    break;
12040                case MOVZ_FMT:
12041                    FINSN_3ARG_SDPS(MOVZ);
12042                    break;
12043                default:
12044                    goto pool32f_invalid;
12045                }
12046                break;
12047            do_fpop:
12048                gen_farith(ctx, mips32_op, rt, rs, rd, 0);
12049                break;
12050            default:
12051            pool32f_invalid:
12052                MIPS_INVAL("pool32f");
12053                generate_exception(ctx, EXCP_RI);
12054                break;
12055            }
12056        } else {
12057            generate_exception_err(ctx, EXCP_CpU, 1);
12058        }
12059        break;
12060    case POOL32I:
12061        minor = (ctx->opcode >> 21) & 0x1f;
12062        switch (minor) {
12063        case BLTZ:
12064            mips32_op = OPC_BLTZ;
12065            goto do_branch;
12066        case BLTZAL:
12067            mips32_op = OPC_BLTZAL;
12068            goto do_branch;
12069        case BLTZALS:
12070            mips32_op = OPC_BLTZALS;
12071            goto do_branch;
12072        case BGEZ:
12073            mips32_op = OPC_BGEZ;
12074            goto do_branch;
12075        case BGEZAL:
12076            mips32_op = OPC_BGEZAL;
12077            goto do_branch;
12078        case BGEZALS:
12079            mips32_op = OPC_BGEZALS;
12080            goto do_branch;
12081        case BLEZ:
12082            mips32_op = OPC_BLEZ;
12083            goto do_branch;
12084        case BGTZ:
12085            mips32_op = OPC_BGTZ;
12086        do_branch:
12087            gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
12088            break;
12089
12090            /* Traps */
12091        case TLTI:
12092            mips32_op = OPC_TLTI;
12093            goto do_trapi;
12094        case TGEI:
12095            mips32_op = OPC_TGEI;
12096            goto do_trapi;
12097        case TLTIU:
12098            mips32_op = OPC_TLTIU;
12099            goto do_trapi;
12100        case TGEIU:
12101            mips32_op = OPC_TGEIU;
12102            goto do_trapi;
12103        case TNEI:
12104            mips32_op = OPC_TNEI;
12105            goto do_trapi;
12106        case TEQI:
12107            mips32_op = OPC_TEQI;
12108        do_trapi:
12109            gen_trap(ctx, mips32_op, rs, -1, imm);
12110            break;
12111
12112        case BNEZC:
12113        case BEQZC:
12114            gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
12115                               4, rs, 0, imm << 1);
12116            /* Compact branches don't have a delay slot, so just let
12117               the normal delay slot handling take us to the branch
12118               target. */
12119            break;
12120        case LUI:
12121            gen_logic_imm(ctx, OPC_LUI, rs, -1, imm);
12122            break;
12123        case SYNCI:
12124            break;
12125        case BC2F:
12126        case BC2T:
12127            /* COP2: Not implemented. */
12128            generate_exception_err(ctx, EXCP_CpU, 2);
12129            break;
12130        case BC1F:
12131            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
12132            goto do_cp1branch;
12133        case BC1T:
12134            mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
12135            goto do_cp1branch;
12136        case BC1ANY4F:
12137            mips32_op = OPC_BC1FANY4;
12138            goto do_cp1mips3d;
12139        case BC1ANY4T:
12140            mips32_op = OPC_BC1TANY4;
12141        do_cp1mips3d:
12142            check_cop1x(ctx);
12143            check_insn(ctx, ASE_MIPS3D);
12144            /* Fall through */
12145        do_cp1branch:
12146            gen_compute_branch1(ctx, mips32_op,
12147                                (ctx->opcode >> 18) & 0x7, imm << 1);
12148            break;
12149        case BPOSGE64:
12150        case BPOSGE32:
12151            /* MIPS DSP: not implemented */
12152            /* Fall through */
12153        default:
12154            MIPS_INVAL("pool32i");
12155            generate_exception(ctx, EXCP_RI);
12156            break;
12157        }
12158        break;
12159    case POOL32C:
12160        minor = (ctx->opcode >> 12) & 0xf;
12161        switch (minor) {
12162        case LWL:
12163            mips32_op = OPC_LWL;
12164            goto do_ld_lr;
12165        case SWL:
12166            mips32_op = OPC_SWL;
12167            goto do_st_lr;
12168        case LWR:
12169            mips32_op = OPC_LWR;
12170            goto do_ld_lr;
12171        case SWR:
12172            mips32_op = OPC_SWR;
12173            goto do_st_lr;
12174#if defined(TARGET_MIPS64)
12175        case LDL:
12176            mips32_op = OPC_LDL;
12177            goto do_ld_lr;
12178        case SDL:
12179            mips32_op = OPC_SDL;
12180            goto do_st_lr;
12181        case LDR:
12182            mips32_op = OPC_LDR;
12183            goto do_ld_lr;
12184        case SDR:
12185            mips32_op = OPC_SDR;
12186            goto do_st_lr;
12187        case LWU:
12188            mips32_op = OPC_LWU;
12189            goto do_ld_lr;
12190        case LLD:
12191            mips32_op = OPC_LLD;
12192            goto do_ld_lr;
12193#endif
12194        case LL:
12195            mips32_op = OPC_LL;
12196            goto do_ld_lr;
12197        do_ld_lr:
12198            gen_ld(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12199            break;
12200        do_st_lr:
12201            gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
12202            break;
12203        case SC:
12204            gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
12205            break;
12206#if defined(TARGET_MIPS64)
12207        case SCD:
12208            gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
12209            break;
12210#endif
12211        case PREF:
12212            /* Treat as no-op */
12213            break;
12214        default:
12215            MIPS_INVAL("pool32c");
12216            generate_exception(ctx, EXCP_RI);
12217            break;
12218        }
12219        break;
12220    case ADDI32:
12221        mips32_op = OPC_ADDI;
12222        goto do_addi;
12223    case ADDIU32:
12224        mips32_op = OPC_ADDIU;
12225    do_addi:
12226        gen_arith_imm(ctx, mips32_op, rt, rs, imm);
12227        break;
12228
12229        /* Logical operations */
12230    case ORI32:
12231        mips32_op = OPC_ORI;
12232        goto do_logici;
12233    case XORI32:
12234        mips32_op = OPC_XORI;
12235        goto do_logici;
12236    case ANDI32:
12237        mips32_op = OPC_ANDI;
12238    do_logici:
12239        gen_logic_imm(ctx, mips32_op, rt, rs, imm);
12240        break;
12241
12242        /* Set less than immediate */
12243    case SLTI32:
12244        mips32_op = OPC_SLTI;
12245        goto do_slti;
12246    case SLTIU32:
12247        mips32_op = OPC_SLTIU;
12248    do_slti:
12249        gen_slt_imm(ctx, mips32_op, rt, rs, imm);
12250        break;
12251    case JALX32:
12252        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
12253        gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
12254        break;
12255    case JALS32:
12256        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
12257        gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
12258        break;
12259    case BEQ32:
12260        gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
12261        break;
12262    case BNE32:
12263        gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
12264        break;
12265    case J32:
12266        gen_compute_branch(ctx, OPC_J, 4, rt, rs,
12267                           (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12268        break;
12269    case JAL32:
12270        gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
12271                           (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
12272        break;
12273        /* Floating point (COP1) */
12274    case LWC132:
12275        mips32_op = OPC_LWC1;
12276        goto do_cop1;
12277    case LDC132:
12278        mips32_op = OPC_LDC1;
12279        goto do_cop1;
12280    case SWC132:
12281        mips32_op = OPC_SWC1;
12282        goto do_cop1;
12283    case SDC132:
12284        mips32_op = OPC_SDC1;
12285    do_cop1:
12286        gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
12287        break;
12288    case ADDIUPC:
12289        {
12290            int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
12291            int offset = SIMM(ctx->opcode, 0, 23) << 2;
12292
12293            gen_addiupc(ctx, reg, offset, 0, 0);
12294        }
12295        break;
12296        /* Loads and stores */
12297    case LB32:
12298        mips32_op = OPC_LB;
12299        goto do_ld;
12300    case LBU32:
12301        mips32_op = OPC_LBU;
12302        goto do_ld;
12303    case LH32:
12304        mips32_op = OPC_LH;
12305        goto do_ld;
12306    case LHU32:
12307        mips32_op = OPC_LHU;
12308        goto do_ld;
12309    case LW32:
12310        mips32_op = OPC_LW;
12311        goto do_ld;
12312#ifdef TARGET_MIPS64
12313    case LD32:
12314        mips32_op = OPC_LD;
12315        goto do_ld;
12316    case SD32:
12317        mips32_op = OPC_SD;
12318        goto do_st;
12319#endif
12320    case SB32:
12321        mips32_op = OPC_SB;
12322        goto do_st;
12323    case SH32:
12324        mips32_op = OPC_SH;
12325        goto do_st;
12326    case SW32:
12327        mips32_op = OPC_SW;
12328        goto do_st;
12329    do_ld:
12330        gen_ld(ctx, mips32_op, rt, rs, imm);
12331        break;
12332    do_st:
12333        gen_st(ctx, mips32_op, rt, rs, imm);
12334        break;
12335    default:
12336        generate_exception(ctx, EXCP_RI);
12337        break;
12338    }
12339}
12340
12341static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx)
12342{
12343    uint32_t op;
12344
12345    /* make sure instructions are on a halfword boundary */
12346    if (ctx->pc & 0x1) {
12347        env->CP0_BadVAddr = ctx->pc;
12348        generate_exception(ctx, EXCP_AdEL);
12349        ctx->bstate = BS_STOP;
12350        return 2;
12351    }
12352
12353    op = (ctx->opcode >> 10) & 0x3f;
12354    /* Enforce properly-sized instructions in a delay slot */
12355    if (ctx->hflags & MIPS_HFLAG_BMASK) {
12356        int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
12357
12358        switch (op) {
12359        case POOL32A:
12360        case POOL32B:
12361        case POOL32I:
12362        case POOL32C:
12363        case ADDI32:
12364        case ADDIU32:
12365        case ORI32:
12366        case XORI32:
12367        case SLTI32:
12368        case SLTIU32:
12369        case ANDI32:
12370        case JALX32:
12371        case LBU32:
12372        case LHU32:
12373        case POOL32F:
12374        case JALS32:
12375        case BEQ32:
12376        case BNE32:
12377        case J32:
12378        case JAL32:
12379        case SB32:
12380        case SH32:
12381        case POOL32S:
12382        case ADDIUPC:
12383        case SWC132:
12384        case SDC132:
12385        case SD32:
12386        case SW32:
12387        case LB32:
12388        case LH32:
12389        case DADDIU32:
12390        case LWC132:
12391        case LDC132:
12392        case LD32:
12393        case LW32:
12394            if (bits & MIPS_HFLAG_BDS16) {
12395                generate_exception(ctx, EXCP_RI);
12396                /* Just stop translation; the user is confused.  */
12397                ctx->bstate = BS_STOP;
12398                return 2;
12399            }
12400            break;
12401        case POOL16A:
12402        case POOL16B:
12403        case POOL16C:
12404        case LWGP16:
12405        case POOL16F:
12406        case LBU16:
12407        case LHU16:
12408        case LWSP16:
12409        case LW16:
12410        case SB16:
12411        case SH16:
12412        case SWSP16:
12413        case SW16:
12414        case MOVE16:
12415        case ANDI16:
12416        case POOL16D:
12417        case POOL16E:
12418        case BEQZ16:
12419        case BNEZ16:
12420        case B16:
12421        case LI16:
12422            if (bits & MIPS_HFLAG_BDS32) {
12423                generate_exception(ctx, EXCP_RI);
12424                /* Just stop translation; the user is confused.  */
12425                ctx->bstate = BS_STOP;
12426                return 2;
12427            }
12428            break;
12429        default:
12430            break;
12431        }
12432    }
12433    switch (op) {
12434    case POOL16A:
12435        {
12436            int rd = mmreg(uMIPS_RD(ctx->opcode));
12437            int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
12438            int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
12439            uint32_t opc = 0;
12440
12441            switch (ctx->opcode & 0x1) {
12442            case ADDU16:
12443                opc = OPC_ADDU;
12444                break;
12445            case SUBU16:
12446                opc = OPC_SUBU;
12447                break;
12448            }
12449
12450            gen_arith(ctx, opc, rd, rs1, rs2);
12451        }
12452        break;
12453    case POOL16B:
12454        {
12455            int rd = mmreg(uMIPS_RD(ctx->opcode));
12456            int rs = mmreg(uMIPS_RS(ctx->opcode));
12457            int amount = (ctx->opcode >> 1) & 0x7;
12458            uint32_t opc = 0;
12459            amount = amount == 0 ? 8 : amount;
12460
12461            switch (ctx->opcode & 0x1) {
12462            case SLL16:
12463                opc = OPC_SLL;
12464                break;
12465            case SRL16:
12466                opc = OPC_SRL;
12467                break;
12468            }
12469
12470            gen_shift_imm(ctx, opc, rd, rs, amount);
12471        }
12472        break;
12473    case POOL16C:
12474        gen_pool16c_insn(ctx);
12475        break;
12476    case LWGP16:
12477        {
12478            int rd = mmreg(uMIPS_RD(ctx->opcode));
12479            int rb = 28;            /* GP */
12480            int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
12481
12482            gen_ld(ctx, OPC_LW, rd, rb, offset);
12483        }
12484        break;
12485    case POOL16F:
12486        if (ctx->opcode & 1) {
12487            generate_exception(ctx, EXCP_RI);
12488        } else {
12489            /* MOVEP */
12490            int enc_dest = uMIPS_RD(ctx->opcode);
12491            int enc_rt = uMIPS_RS2(ctx->opcode);
12492            int enc_rs = uMIPS_RS1(ctx->opcode);
12493            int rd, rs, re, rt;
12494            static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
12495            static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
12496            static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
12497
12498            rd = rd_enc[enc_dest];
12499            re = re_enc[enc_dest];
12500            rs = rs_rt_enc[enc_rs];
12501            rt = rs_rt_enc[enc_rt];
12502
12503            gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
12504            gen_arith_imm(ctx, OPC_ADDIU, re, rt, 0);
12505        }
12506        break;
12507    case LBU16:
12508        {
12509            int rd = mmreg(uMIPS_RD(ctx->opcode));
12510            int rb = mmreg(uMIPS_RS(ctx->opcode));
12511            int16_t offset = ZIMM(ctx->opcode, 0, 4);
12512            offset = (offset == 0xf ? -1 : offset);
12513
12514            gen_ld(ctx, OPC_LBU, rd, rb, offset);
12515        }
12516        break;
12517    case LHU16:
12518        {
12519            int rd = mmreg(uMIPS_RD(ctx->opcode));
12520            int rb = mmreg(uMIPS_RS(ctx->opcode));
12521            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12522
12523            gen_ld(ctx, OPC_LHU, rd, rb, offset);
12524        }
12525        break;
12526    case LWSP16:
12527        {
12528            int rd = (ctx->opcode >> 5) & 0x1f;
12529            int rb = 29;            /* SP */
12530            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12531
12532            gen_ld(ctx, OPC_LW, rd, rb, offset);
12533        }
12534        break;
12535    case LW16:
12536        {
12537            int rd = mmreg(uMIPS_RD(ctx->opcode));
12538            int rb = mmreg(uMIPS_RS(ctx->opcode));
12539            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12540
12541            gen_ld(ctx, OPC_LW, rd, rb, offset);
12542        }
12543        break;
12544    case SB16:
12545        {
12546            int rd = mmreg2(uMIPS_RD(ctx->opcode));
12547            int rb = mmreg(uMIPS_RS(ctx->opcode));
12548            int16_t offset = ZIMM(ctx->opcode, 0, 4);
12549
12550            gen_st(ctx, OPC_SB, rd, rb, offset);
12551        }
12552        break;
12553    case SH16:
12554        {
12555            int rd = mmreg2(uMIPS_RD(ctx->opcode));
12556            int rb = mmreg(uMIPS_RS(ctx->opcode));
12557            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
12558
12559            gen_st(ctx, OPC_SH, rd, rb, offset);
12560        }
12561        break;
12562    case SWSP16:
12563        {
12564            int rd = (ctx->opcode >> 5) & 0x1f;
12565            int rb = 29;            /* SP */
12566            int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
12567
12568            gen_st(ctx, OPC_SW, rd, rb, offset);
12569        }
12570        break;
12571    case SW16:
12572        {
12573            int rd = mmreg2(uMIPS_RD(ctx->opcode));
12574            int rb = mmreg(uMIPS_RS(ctx->opcode));
12575            int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
12576
12577            gen_st(ctx, OPC_SW, rd, rb, offset);
12578        }
12579        break;
12580    case MOVE16:
12581        {
12582            int rd = uMIPS_RD5(ctx->opcode);
12583            int rs = uMIPS_RS5(ctx->opcode);
12584
12585            gen_arith_imm(ctx, OPC_ADDIU, rd, rs, 0);
12586        }
12587        break;
12588    case ANDI16:
12589        gen_andi16(ctx);
12590        break;
12591    case POOL16D:
12592        switch (ctx->opcode & 0x1) {
12593        case ADDIUS5:
12594            gen_addius5(ctx);
12595            break;
12596        case ADDIUSP:
12597            gen_addiusp(ctx);
12598            break;
12599        }
12600        break;
12601    case POOL16E:
12602        switch (ctx->opcode & 0x1) {
12603        case ADDIUR2:
12604            gen_addiur2(ctx);
12605            break;
12606        case ADDIUR1SP:
12607            gen_addiur1sp(ctx);
12608            break;
12609        }
12610        break;
12611    case B16:
12612        gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
12613                           SIMM(ctx->opcode, 0, 10) << 1);
12614        break;
12615    case BNEZ16:
12616    case BEQZ16:
12617        gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
12618                           mmreg(uMIPS_RD(ctx->opcode)),
12619                           0, SIMM(ctx->opcode, 0, 7) << 1);
12620        break;
12621    case LI16:
12622        {
12623            int reg = mmreg(uMIPS_RD(ctx->opcode));
12624            int imm = ZIMM(ctx->opcode, 0, 7);
12625
12626            imm = (imm == 0x7f ? -1 : imm);
12627            tcg_gen_movi_tl(cpu_gpr[reg], imm);
12628        }
12629        break;
12630    case RES_20:
12631    case RES_28:
12632    case RES_29:
12633    case RES_30:
12634    case RES_31:
12635    case RES_38:
12636    case RES_39:
12637        generate_exception(ctx, EXCP_RI);
12638        break;
12639    default:
12640        decode_micromips32_opc (env, ctx, op);
12641        return 4;
12642    }
12643
12644    return 2;
12645}
12646
12647/* SmartMIPS extension to MIPS32 */
12648
12649#if defined(TARGET_MIPS64)
12650
12651/* MDMX extension to MIPS64 */
12652
12653#endif
12654
12655/* MIPSDSP functions. */
12656static void gen_mipsdsp_ld(DisasContext *ctx, uint32_t opc,
12657                           int rd, int base, int offset)
12658{
12659    const char *opn = "ldx";
12660    TCGv t0;
12661
12662    check_dsp(ctx);
12663    t0 = tcg_temp_new();
12664
12665    if (base == 0) {
12666        gen_load_gpr(t0, offset);
12667    } else if (offset == 0) {
12668        gen_load_gpr(t0, base);
12669    } else {
12670        gen_op_addr_add(ctx, t0, cpu_gpr[base], cpu_gpr[offset]);
12671    }
12672
12673    switch (opc) {
12674    case OPC_LBUX:
12675        tcg_gen_qemu_ld8u(t0, t0, ctx->mem_idx);
12676        gen_store_gpr(t0, rd);
12677        opn = "lbux";
12678        break;
12679    case OPC_LHX:
12680        tcg_gen_qemu_ld16s(t0, t0, ctx->mem_idx);
12681        gen_store_gpr(t0, rd);
12682        opn = "lhx";
12683        break;
12684    case OPC_LWX:
12685        tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
12686        gen_store_gpr(t0, rd);
12687        opn = "lwx";
12688        break;
12689#if defined(TARGET_MIPS64)
12690    case OPC_LDX:
12691        tcg_gen_qemu_ld64(t0, t0, ctx->mem_idx);
12692        gen_store_gpr(t0, rd);
12693        opn = "ldx";
12694        break;
12695#endif
12696    }
12697    (void)opn; /* avoid a compiler warning */
12698    MIPS_DEBUG("%s %s, %s(%s)", opn,
12699               regnames[rd], regnames[offset], regnames[base]);
12700    tcg_temp_free(t0);
12701}
12702
12703static void gen_mipsdsp_arith(DisasContext *ctx, uint32_t op1, uint32_t op2,
12704                              int ret, int v1, int v2)
12705{
12706    const char *opn = "mipsdsp arith";
12707    TCGv v1_t;
12708    TCGv v2_t;
12709
12710    if (ret == 0) {
12711        /* Treat as NOP. */
12712        MIPS_DEBUG("NOP");
12713        return;
12714    }
12715
12716    v1_t = tcg_temp_new();
12717    v2_t = tcg_temp_new();
12718
12719    gen_load_gpr(v1_t, v1);
12720    gen_load_gpr(v2_t, v2);
12721
12722    switch (op1) {
12723    /* OPC_MULT_G_2E is equal OPC_ADDUH_QB_DSP */
12724    case OPC_MULT_G_2E:
12725        check_dspr2(ctx);
12726        switch (op2) {
12727        case OPC_ADDUH_QB:
12728            gen_helper_adduh_qb(cpu_gpr[ret], v1_t, v2_t);
12729            break;
12730        case OPC_ADDUH_R_QB:
12731            gen_helper_adduh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12732            break;
12733        case OPC_ADDQH_PH:
12734            gen_helper_addqh_ph(cpu_gpr[ret], v1_t, v2_t);
12735            break;
12736        case OPC_ADDQH_R_PH:
12737            gen_helper_addqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12738            break;
12739        case OPC_ADDQH_W:
12740            gen_helper_addqh_w(cpu_gpr[ret], v1_t, v2_t);
12741            break;
12742        case OPC_ADDQH_R_W:
12743            gen_helper_addqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12744            break;
12745        case OPC_SUBUH_QB:
12746            gen_helper_subuh_qb(cpu_gpr[ret], v1_t, v2_t);
12747            break;
12748        case OPC_SUBUH_R_QB:
12749            gen_helper_subuh_r_qb(cpu_gpr[ret], v1_t, v2_t);
12750            break;
12751        case OPC_SUBQH_PH:
12752            gen_helper_subqh_ph(cpu_gpr[ret], v1_t, v2_t);
12753            break;
12754        case OPC_SUBQH_R_PH:
12755            gen_helper_subqh_r_ph(cpu_gpr[ret], v1_t, v2_t);
12756            break;
12757        case OPC_SUBQH_W:
12758            gen_helper_subqh_w(cpu_gpr[ret], v1_t, v2_t);
12759            break;
12760        case OPC_SUBQH_R_W:
12761            gen_helper_subqh_r_w(cpu_gpr[ret], v1_t, v2_t);
12762            break;
12763        }
12764        break;
12765    case OPC_ABSQ_S_PH_DSP:
12766        switch (op2) {
12767        case OPC_ABSQ_S_QB:
12768            check_dspr2(ctx);
12769            gen_helper_absq_s_qb(cpu_gpr[ret], v2_t, cpu_env);
12770            break;
12771        case OPC_ABSQ_S_PH:
12772            check_dsp(ctx);
12773            gen_helper_absq_s_ph(cpu_gpr[ret], v2_t, cpu_env);
12774            break;
12775        case OPC_ABSQ_S_W:
12776            check_dsp(ctx);
12777            gen_helper_absq_s_w(cpu_gpr[ret], v2_t, cpu_env);
12778            break;
12779        case OPC_PRECEQ_W_PHL:
12780            check_dsp(ctx);
12781            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFF0000);
12782            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12783            break;
12784        case OPC_PRECEQ_W_PHR:
12785            check_dsp(ctx);
12786            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0x0000FFFF);
12787            tcg_gen_shli_tl(cpu_gpr[ret], cpu_gpr[ret], 16);
12788            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
12789            break;
12790        case OPC_PRECEQU_PH_QBL:
12791            check_dsp(ctx);
12792            gen_helper_precequ_ph_qbl(cpu_gpr[ret], v2_t);
12793            break;
12794        case OPC_PRECEQU_PH_QBR:
12795            check_dsp(ctx);
12796            gen_helper_precequ_ph_qbr(cpu_gpr[ret], v2_t);
12797            break;
12798        case OPC_PRECEQU_PH_QBLA:
12799            check_dsp(ctx);
12800            gen_helper_precequ_ph_qbla(cpu_gpr[ret], v2_t);
12801            break;
12802        case OPC_PRECEQU_PH_QBRA:
12803            check_dsp(ctx);
12804            gen_helper_precequ_ph_qbra(cpu_gpr[ret], v2_t);
12805            break;
12806        case OPC_PRECEU_PH_QBL:
12807            check_dsp(ctx);
12808            gen_helper_preceu_ph_qbl(cpu_gpr[ret], v2_t);
12809            break;
12810        case OPC_PRECEU_PH_QBR:
12811            check_dsp(ctx);
12812            gen_helper_preceu_ph_qbr(cpu_gpr[ret], v2_t);
12813            break;
12814        case OPC_PRECEU_PH_QBLA:
12815            check_dsp(ctx);
12816            gen_helper_preceu_ph_qbla(cpu_gpr[ret], v2_t);
12817            break;
12818        case OPC_PRECEU_PH_QBRA:
12819            check_dsp(ctx);
12820            gen_helper_preceu_ph_qbra(cpu_gpr[ret], v2_t);
12821            break;
12822        }
12823        break;
12824    case OPC_ADDU_QB_DSP:
12825        switch (op2) {
12826        case OPC_ADDQ_PH:
12827            check_dsp(ctx);
12828            gen_helper_addq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12829            break;
12830        case OPC_ADDQ_S_PH:
12831            check_dsp(ctx);
12832            gen_helper_addq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12833            break;
12834        case OPC_ADDQ_S_W:
12835            check_dsp(ctx);
12836            gen_helper_addq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12837            break;
12838        case OPC_ADDU_QB:
12839            check_dsp(ctx);
12840            gen_helper_addu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12841            break;
12842        case OPC_ADDU_S_QB:
12843            check_dsp(ctx);
12844            gen_helper_addu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12845            break;
12846        case OPC_ADDU_PH:
12847            check_dspr2(ctx);
12848            gen_helper_addu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12849            break;
12850        case OPC_ADDU_S_PH:
12851            check_dspr2(ctx);
12852            gen_helper_addu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12853            break;
12854        case OPC_SUBQ_PH:
12855            check_dsp(ctx);
12856            gen_helper_subq_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12857            break;
12858        case OPC_SUBQ_S_PH:
12859            check_dsp(ctx);
12860            gen_helper_subq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12861            break;
12862        case OPC_SUBQ_S_W:
12863            check_dsp(ctx);
12864            gen_helper_subq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12865            break;
12866        case OPC_SUBU_QB:
12867            check_dsp(ctx);
12868            gen_helper_subu_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12869            break;
12870        case OPC_SUBU_S_QB:
12871            check_dsp(ctx);
12872            gen_helper_subu_s_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12873            break;
12874        case OPC_SUBU_PH:
12875            check_dspr2(ctx);
12876            gen_helper_subu_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12877            break;
12878        case OPC_SUBU_S_PH:
12879            check_dspr2(ctx);
12880            gen_helper_subu_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12881            break;
12882        case OPC_ADDSC:
12883            check_dsp(ctx);
12884            gen_helper_addsc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12885            break;
12886        case OPC_ADDWC:
12887            check_dsp(ctx);
12888            gen_helper_addwc(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12889            break;
12890        case OPC_MODSUB:
12891            check_dsp(ctx);
12892            gen_helper_modsub(cpu_gpr[ret], v1_t, v2_t);
12893            break;
12894        case OPC_RADDU_W_QB:
12895            check_dsp(ctx);
12896            gen_helper_raddu_w_qb(cpu_gpr[ret], v1_t);
12897            break;
12898        }
12899        break;
12900    case OPC_CMPU_EQ_QB_DSP:
12901        switch (op2) {
12902        case OPC_PRECR_QB_PH:
12903            check_dspr2(ctx);
12904            gen_helper_precr_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12905            break;
12906        case OPC_PRECRQ_QB_PH:
12907            check_dsp(ctx);
12908            gen_helper_precrq_qb_ph(cpu_gpr[ret], v1_t, v2_t);
12909            break;
12910        case OPC_PRECR_SRA_PH_W:
12911            check_dspr2(ctx);
12912            {
12913                TCGv_i32 sa_t = tcg_const_i32(v2);
12914                gen_helper_precr_sra_ph_w(cpu_gpr[ret], sa_t, v1_t,
12915                                          cpu_gpr[ret]);
12916                tcg_temp_free_i32(sa_t);
12917                break;
12918            }
12919        case OPC_PRECR_SRA_R_PH_W:
12920            check_dspr2(ctx);
12921            {
12922                TCGv_i32 sa_t = tcg_const_i32(v2);
12923                gen_helper_precr_sra_r_ph_w(cpu_gpr[ret], sa_t, v1_t,
12924                                            cpu_gpr[ret]);
12925                tcg_temp_free_i32(sa_t);
12926                break;
12927            }
12928        case OPC_PRECRQ_PH_W:
12929            check_dsp(ctx);
12930            gen_helper_precrq_ph_w(cpu_gpr[ret], v1_t, v2_t);
12931            break;
12932        case OPC_PRECRQ_RS_PH_W:
12933            check_dsp(ctx);
12934            gen_helper_precrq_rs_ph_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12935            break;
12936        case OPC_PRECRQU_S_QB_PH:
12937            check_dsp(ctx);
12938            gen_helper_precrqu_s_qb_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
12939            break;
12940        }
12941        break;
12942#ifdef TARGET_MIPS64
12943    case OPC_ABSQ_S_QH_DSP:
12944        switch (op2) {
12945        case OPC_PRECEQ_L_PWL:
12946            check_dsp(ctx);
12947            tcg_gen_andi_tl(cpu_gpr[ret], v2_t, 0xFFFFFFFF00000000ull);
12948            break;
12949        case OPC_PRECEQ_L_PWR:
12950            check_dsp(ctx);
12951            tcg_gen_shli_tl(cpu_gpr[ret], v2_t, 32);
12952            break;
12953        case OPC_PRECEQ_PW_QHL:
12954            check_dsp(ctx);
12955            gen_helper_preceq_pw_qhl(cpu_gpr[ret], v2_t);
12956            break;
12957        case OPC_PRECEQ_PW_QHR:
12958            check_dsp(ctx);
12959            gen_helper_preceq_pw_qhr(cpu_gpr[ret], v2_t);
12960            break;
12961        case OPC_PRECEQ_PW_QHLA:
12962            check_dsp(ctx);
12963            gen_helper_preceq_pw_qhla(cpu_gpr[ret], v2_t);
12964            break;
12965        case OPC_PRECEQ_PW_QHRA:
12966            check_dsp(ctx);
12967            gen_helper_preceq_pw_qhra(cpu_gpr[ret], v2_t);
12968            break;
12969        case OPC_PRECEQU_QH_OBL:
12970            check_dsp(ctx);
12971            gen_helper_precequ_qh_obl(cpu_gpr[ret], v2_t);
12972            break;
12973        case OPC_PRECEQU_QH_OBR:
12974            check_dsp(ctx);
12975            gen_helper_precequ_qh_obr(cpu_gpr[ret], v2_t);
12976            break;
12977        case OPC_PRECEQU_QH_OBLA:
12978            check_dsp(ctx);
12979            gen_helper_precequ_qh_obla(cpu_gpr[ret], v2_t);
12980            break;
12981        case OPC_PRECEQU_QH_OBRA:
12982            check_dsp(ctx);
12983            gen_helper_precequ_qh_obra(cpu_gpr[ret], v2_t);
12984            break;
12985        case OPC_PRECEU_QH_OBL:
12986            check_dsp(ctx);
12987            gen_helper_preceu_qh_obl(cpu_gpr[ret], v2_t);
12988            break;
12989        case OPC_PRECEU_QH_OBR:
12990            check_dsp(ctx);
12991            gen_helper_preceu_qh_obr(cpu_gpr[ret], v2_t);
12992            break;
12993        case OPC_PRECEU_QH_OBLA:
12994            check_dsp(ctx);
12995            gen_helper_preceu_qh_obla(cpu_gpr[ret], v2_t);
12996            break;
12997        case OPC_PRECEU_QH_OBRA:
12998            check_dsp(ctx);
12999            gen_helper_preceu_qh_obra(cpu_gpr[ret], v2_t);
13000            break;
13001        case OPC_ABSQ_S_OB:
13002            check_dspr2(ctx);
13003            gen_helper_absq_s_ob(cpu_gpr[ret], v2_t, cpu_env);
13004            break;
13005        case OPC_ABSQ_S_PW:
13006            check_dsp(ctx);
13007            gen_helper_absq_s_pw(cpu_gpr[ret], v2_t, cpu_env);
13008            break;
13009        case OPC_ABSQ_S_QH:
13010            check_dsp(ctx);
13011            gen_helper_absq_s_qh(cpu_gpr[ret], v2_t, cpu_env);
13012            break;
13013        }
13014        break;
13015    case OPC_ADDU_OB_DSP:
13016        switch (op2) {
13017        case OPC_RADDU_L_OB:
13018            check_dsp(ctx);
13019            gen_helper_raddu_l_ob(cpu_gpr[ret], v1_t);
13020            break;
13021        case OPC_SUBQ_PW:
13022            check_dsp(ctx);
13023            gen_helper_subq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13024            break;
13025        case OPC_SUBQ_S_PW:
13026            check_dsp(ctx);
13027            gen_helper_subq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13028            break;
13029        case OPC_SUBQ_QH:
13030            check_dsp(ctx);
13031            gen_helper_subq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13032            break;
13033        case OPC_SUBQ_S_QH:
13034            check_dsp(ctx);
13035            gen_helper_subq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13036            break;
13037        case OPC_SUBU_OB:
13038            check_dsp(ctx);
13039            gen_helper_subu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13040            break;
13041        case OPC_SUBU_S_OB:
13042            check_dsp(ctx);
13043            gen_helper_subu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13044            break;
13045        case OPC_SUBU_QH:
13046            check_dspr2(ctx);
13047            gen_helper_subu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13048            break;
13049        case OPC_SUBU_S_QH:
13050            check_dspr2(ctx);
13051            gen_helper_subu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13052            break;
13053        case OPC_SUBUH_OB:
13054            check_dspr2(ctx);
13055            gen_helper_subuh_ob(cpu_gpr[ret], v1_t, v2_t);
13056            break;
13057        case OPC_SUBUH_R_OB:
13058            check_dspr2(ctx);
13059            gen_helper_subuh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13060            break;
13061        case OPC_ADDQ_PW:
13062            check_dsp(ctx);
13063            gen_helper_addq_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13064            break;
13065        case OPC_ADDQ_S_PW:
13066            check_dsp(ctx);
13067            gen_helper_addq_s_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13068            break;
13069        case OPC_ADDQ_QH:
13070            check_dsp(ctx);
13071            gen_helper_addq_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13072            break;
13073        case OPC_ADDQ_S_QH:
13074            check_dsp(ctx);
13075            gen_helper_addq_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13076            break;
13077        case OPC_ADDU_OB:
13078            check_dsp(ctx);
13079            gen_helper_addu_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13080            break;
13081        case OPC_ADDU_S_OB:
13082            check_dsp(ctx);
13083            gen_helper_addu_s_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13084            break;
13085        case OPC_ADDU_QH:
13086            check_dspr2(ctx);
13087            gen_helper_addu_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13088            break;
13089        case OPC_ADDU_S_QH:
13090            check_dspr2(ctx);
13091            gen_helper_addu_s_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13092            break;
13093        case OPC_ADDUH_OB:
13094            check_dspr2(ctx);
13095            gen_helper_adduh_ob(cpu_gpr[ret], v1_t, v2_t);
13096            break;
13097        case OPC_ADDUH_R_OB:
13098            check_dspr2(ctx);
13099            gen_helper_adduh_r_ob(cpu_gpr[ret], v1_t, v2_t);
13100            break;
13101        }
13102        break;
13103    case OPC_CMPU_EQ_OB_DSP:
13104        switch (op2) {
13105        case OPC_PRECR_OB_QH:
13106            check_dspr2(ctx);
13107            gen_helper_precr_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13108            break;
13109        case OPC_PRECR_SRA_QH_PW:
13110            check_dspr2(ctx);
13111            {
13112                TCGv_i32 ret_t = tcg_const_i32(ret);
13113                gen_helper_precr_sra_qh_pw(v2_t, v1_t, v2_t, ret_t);
13114                tcg_temp_free_i32(ret_t);
13115                break;
13116            }
13117        case OPC_PRECR_SRA_R_QH_PW:
13118            check_dspr2(ctx);
13119            {
13120                TCGv_i32 sa_v = tcg_const_i32(ret);
13121                gen_helper_precr_sra_r_qh_pw(v2_t, v1_t, v2_t, sa_v);
13122                tcg_temp_free_i32(sa_v);
13123                break;
13124            }
13125        case OPC_PRECRQ_OB_QH:
13126            check_dsp(ctx);
13127            gen_helper_precrq_ob_qh(cpu_gpr[ret], v1_t, v2_t);
13128            break;
13129        case OPC_PRECRQ_PW_L:
13130            check_dsp(ctx);
13131            gen_helper_precrq_pw_l(cpu_gpr[ret], v1_t, v2_t);
13132            break;
13133        case OPC_PRECRQ_QH_PW:
13134            check_dsp(ctx);
13135            gen_helper_precrq_qh_pw(cpu_gpr[ret], v1_t, v2_t);
13136            break;
13137        case OPC_PRECRQ_RS_QH_PW:
13138            check_dsp(ctx);
13139            gen_helper_precrq_rs_qh_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13140            break;
13141        case OPC_PRECRQU_S_OB_QH:
13142            check_dsp(ctx);
13143            gen_helper_precrqu_s_ob_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13144            break;
13145        }
13146        break;
13147#endif
13148    }
13149
13150    tcg_temp_free(v1_t);
13151    tcg_temp_free(v2_t);
13152
13153    (void)opn; /* avoid a compiler warning */
13154    MIPS_DEBUG("%s", opn);
13155}
13156
13157static void gen_mipsdsp_shift(DisasContext *ctx, uint32_t opc,
13158                              int ret, int v1, int v2)
13159{
13160    uint32_t op2;
13161    const char *opn = "mipsdsp shift";
13162    TCGv t0;
13163    TCGv v1_t;
13164    TCGv v2_t;
13165
13166    if (ret == 0) {
13167        /* Treat as NOP. */
13168        MIPS_DEBUG("NOP");
13169        return;
13170    }
13171
13172    t0 = tcg_temp_new();
13173    v1_t = tcg_temp_new();
13174    v2_t = tcg_temp_new();
13175
13176    tcg_gen_movi_tl(t0, v1);
13177    gen_load_gpr(v1_t, v1);
13178    gen_load_gpr(v2_t, v2);
13179
13180    switch (opc) {
13181    case OPC_SHLL_QB_DSP:
13182        {
13183            op2 = MASK_SHLL_QB(ctx->opcode);
13184            switch (op2) {
13185            case OPC_SHLL_QB:
13186                check_dsp(ctx);
13187                gen_helper_shll_qb(cpu_gpr[ret], t0, v2_t, cpu_env);
13188                break;
13189            case OPC_SHLLV_QB:
13190                check_dsp(ctx);
13191                gen_helper_shll_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13192                break;
13193            case OPC_SHLL_PH:
13194                check_dsp(ctx);
13195                gen_helper_shll_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13196                break;
13197            case OPC_SHLLV_PH:
13198                check_dsp(ctx);
13199                gen_helper_shll_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13200                break;
13201            case OPC_SHLL_S_PH:
13202                check_dsp(ctx);
13203                gen_helper_shll_s_ph(cpu_gpr[ret], t0, v2_t, cpu_env);
13204                break;
13205            case OPC_SHLLV_S_PH:
13206                check_dsp(ctx);
13207                gen_helper_shll_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13208                break;
13209            case OPC_SHLL_S_W:
13210                check_dsp(ctx);
13211                gen_helper_shll_s_w(cpu_gpr[ret], t0, v2_t, cpu_env);
13212                break;
13213            case OPC_SHLLV_S_W:
13214                check_dsp(ctx);
13215                gen_helper_shll_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13216                break;
13217            case OPC_SHRL_QB:
13218                check_dsp(ctx);
13219                gen_helper_shrl_qb(cpu_gpr[ret], t0, v2_t);
13220                break;
13221            case OPC_SHRLV_QB:
13222                check_dsp(ctx);
13223                gen_helper_shrl_qb(cpu_gpr[ret], v1_t, v2_t);
13224                break;
13225            case OPC_SHRL_PH:
13226                check_dspr2(ctx);
13227                gen_helper_shrl_ph(cpu_gpr[ret], t0, v2_t);
13228                break;
13229            case OPC_SHRLV_PH:
13230                check_dspr2(ctx);
13231                gen_helper_shrl_ph(cpu_gpr[ret], v1_t, v2_t);
13232                break;
13233            case OPC_SHRA_QB:
13234                check_dspr2(ctx);
13235                gen_helper_shra_qb(cpu_gpr[ret], t0, v2_t);
13236                break;
13237            case OPC_SHRA_R_QB:
13238                check_dspr2(ctx);
13239                gen_helper_shra_r_qb(cpu_gpr[ret], t0, v2_t);
13240                break;
13241            case OPC_SHRAV_QB:
13242                check_dspr2(ctx);
13243                gen_helper_shra_qb(cpu_gpr[ret], v1_t, v2_t);
13244                break;
13245            case OPC_SHRAV_R_QB:
13246                check_dspr2(ctx);
13247                gen_helper_shra_r_qb(cpu_gpr[ret], v1_t, v2_t);
13248                break;
13249            case OPC_SHRA_PH:
13250                check_dsp(ctx);
13251                gen_helper_shra_ph(cpu_gpr[ret], t0, v2_t);
13252                break;
13253            case OPC_SHRA_R_PH:
13254                check_dsp(ctx);
13255                gen_helper_shra_r_ph(cpu_gpr[ret], t0, v2_t);
13256                break;
13257            case OPC_SHRAV_PH:
13258                check_dsp(ctx);
13259                gen_helper_shra_ph(cpu_gpr[ret], v1_t, v2_t);
13260                break;
13261            case OPC_SHRAV_R_PH:
13262                check_dsp(ctx);
13263                gen_helper_shra_r_ph(cpu_gpr[ret], v1_t, v2_t);
13264                break;
13265            case OPC_SHRA_R_W:
13266                check_dsp(ctx);
13267                gen_helper_shra_r_w(cpu_gpr[ret], t0, v2_t);
13268                break;
13269            case OPC_SHRAV_R_W:
13270                check_dsp(ctx);
13271                gen_helper_shra_r_w(cpu_gpr[ret], v1_t, v2_t);
13272                break;
13273            default:            /* Invalid */
13274                MIPS_INVAL("MASK SHLL.QB");
13275                generate_exception(ctx, EXCP_RI);
13276                break;
13277            }
13278            break;
13279        }
13280#ifdef TARGET_MIPS64
13281    case OPC_SHLL_OB_DSP:
13282        op2 = MASK_SHLL_OB(ctx->opcode);
13283        switch (op2) {
13284        case OPC_SHLL_PW:
13285            check_dsp(ctx);
13286            gen_helper_shll_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13287            break;
13288        case OPC_SHLLV_PW:
13289            check_dsp(ctx);
13290            gen_helper_shll_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13291            break;
13292        case OPC_SHLL_S_PW:
13293            check_dsp(ctx);
13294            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, t0, cpu_env);
13295            break;
13296        case OPC_SHLLV_S_PW:
13297            check_dsp(ctx);
13298            gen_helper_shll_s_pw(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13299            break;
13300        case OPC_SHLL_OB:
13301            check_dsp(ctx);
13302            gen_helper_shll_ob(cpu_gpr[ret], v2_t, t0, cpu_env);
13303            break;
13304        case OPC_SHLLV_OB:
13305            check_dsp(ctx);
13306            gen_helper_shll_ob(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13307            break;
13308        case OPC_SHLL_QH:
13309            check_dsp(ctx);
13310            gen_helper_shll_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13311            break;
13312        case OPC_SHLLV_QH:
13313            check_dsp(ctx);
13314            gen_helper_shll_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13315            break;
13316        case OPC_SHLL_S_QH:
13317            check_dsp(ctx);
13318            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, t0, cpu_env);
13319            break;
13320        case OPC_SHLLV_S_QH:
13321            check_dsp(ctx);
13322            gen_helper_shll_s_qh(cpu_gpr[ret], v2_t, v1_t, cpu_env);
13323            break;
13324        case OPC_SHRA_OB:
13325            check_dspr2(ctx);
13326            gen_helper_shra_ob(cpu_gpr[ret], v2_t, t0);
13327            break;
13328        case OPC_SHRAV_OB:
13329            check_dspr2(ctx);
13330            gen_helper_shra_ob(cpu_gpr[ret], v2_t, v1_t);
13331            break;
13332        case OPC_SHRA_R_OB:
13333            check_dspr2(ctx);
13334            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, t0);
13335            break;
13336        case OPC_SHRAV_R_OB:
13337            check_dspr2(ctx);
13338            gen_helper_shra_r_ob(cpu_gpr[ret], v2_t, v1_t);
13339            break;
13340        case OPC_SHRA_PW:
13341            check_dsp(ctx);
13342            gen_helper_shra_pw(cpu_gpr[ret], v2_t, t0);
13343            break;
13344        case OPC_SHRAV_PW:
13345            check_dsp(ctx);
13346            gen_helper_shra_pw(cpu_gpr[ret], v2_t, v1_t);
13347            break;
13348        case OPC_SHRA_R_PW:
13349            check_dsp(ctx);
13350            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, t0);
13351            break;
13352        case OPC_SHRAV_R_PW:
13353            check_dsp(ctx);
13354            gen_helper_shra_r_pw(cpu_gpr[ret], v2_t, v1_t);
13355            break;
13356        case OPC_SHRA_QH:
13357            check_dsp(ctx);
13358            gen_helper_shra_qh(cpu_gpr[ret], v2_t, t0);
13359            break;
13360        case OPC_SHRAV_QH:
13361            check_dsp(ctx);
13362            gen_helper_shra_qh(cpu_gpr[ret], v2_t, v1_t);
13363            break;
13364        case OPC_SHRA_R_QH:
13365            check_dsp(ctx);
13366            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, t0);
13367            break;
13368        case OPC_SHRAV_R_QH:
13369            check_dsp(ctx);
13370            gen_helper_shra_r_qh(cpu_gpr[ret], v2_t, v1_t);
13371            break;
13372        case OPC_SHRL_OB:
13373            check_dsp(ctx);
13374            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, t0);
13375            break;
13376        case OPC_SHRLV_OB:
13377            check_dsp(ctx);
13378            gen_helper_shrl_ob(cpu_gpr[ret], v2_t, v1_t);
13379            break;
13380        case OPC_SHRL_QH:
13381            check_dspr2(ctx);
13382            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, t0);
13383            break;
13384        case OPC_SHRLV_QH:
13385            check_dspr2(ctx);
13386            gen_helper_shrl_qh(cpu_gpr[ret], v2_t, v1_t);
13387            break;
13388        default:            /* Invalid */
13389            MIPS_INVAL("MASK SHLL.OB");
13390            generate_exception(ctx, EXCP_RI);
13391            break;
13392        }
13393        break;
13394#endif
13395    }
13396
13397    tcg_temp_free(t0);
13398    tcg_temp_free(v1_t);
13399    tcg_temp_free(v2_t);
13400    (void)opn; /* avoid a compiler warning */
13401    MIPS_DEBUG("%s", opn);
13402}
13403
13404static void gen_mipsdsp_multiply(DisasContext *ctx, uint32_t op1, uint32_t op2,
13405                                 int ret, int v1, int v2, int check_ret)
13406{
13407    const char *opn = "mipsdsp multiply";
13408    TCGv_i32 t0;
13409    TCGv v1_t;
13410    TCGv v2_t;
13411
13412    if ((ret == 0) && (check_ret == 1)) {
13413        /* Treat as NOP. */
13414        MIPS_DEBUG("NOP");
13415        return;
13416    }
13417
13418    t0 = tcg_temp_new_i32();
13419    v1_t = tcg_temp_new();
13420    v2_t = tcg_temp_new();
13421
13422    tcg_gen_movi_i32(t0, ret);
13423    gen_load_gpr(v1_t, v1);
13424    gen_load_gpr(v2_t, v2);
13425
13426    switch (op1) {
13427    /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
13428     * the same mask and op1. */
13429    case OPC_MULT_G_2E:
13430        check_dspr2(ctx);
13431        switch (op2) {
13432        case  OPC_MUL_PH:
13433            gen_helper_mul_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13434            break;
13435        case  OPC_MUL_S_PH:
13436            gen_helper_mul_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13437            break;
13438        case OPC_MULQ_S_W:
13439            gen_helper_mulq_s_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13440            break;
13441        case OPC_MULQ_RS_W:
13442            gen_helper_mulq_rs_w(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13443            break;
13444        }
13445        break;
13446    case OPC_DPA_W_PH_DSP:
13447        switch (op2) {
13448        case OPC_DPAU_H_QBL:
13449            check_dsp(ctx);
13450            gen_helper_dpau_h_qbl(t0, v1_t, v2_t, cpu_env);
13451            break;
13452        case OPC_DPAU_H_QBR:
13453            check_dsp(ctx);
13454            gen_helper_dpau_h_qbr(t0, v1_t, v2_t, cpu_env);
13455            break;
13456        case OPC_DPSU_H_QBL:
13457            check_dsp(ctx);
13458            gen_helper_dpsu_h_qbl(t0, v1_t, v2_t, cpu_env);
13459            break;
13460        case OPC_DPSU_H_QBR:
13461            check_dsp(ctx);
13462            gen_helper_dpsu_h_qbr(t0, v1_t, v2_t, cpu_env);
13463            break;
13464        case OPC_DPA_W_PH:
13465            check_dspr2(ctx);
13466            gen_helper_dpa_w_ph(t0, v1_t, v2_t, cpu_env);
13467            break;
13468        case OPC_DPAX_W_PH:
13469            check_dspr2(ctx);
13470            gen_helper_dpax_w_ph(t0, v1_t, v2_t, cpu_env);
13471            break;
13472        case OPC_DPAQ_S_W_PH:
13473            check_dsp(ctx);
13474            gen_helper_dpaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13475            break;
13476        case OPC_DPAQX_S_W_PH:
13477            check_dspr2(ctx);
13478            gen_helper_dpaqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13479            break;
13480        case OPC_DPAQX_SA_W_PH:
13481            check_dspr2(ctx);
13482            gen_helper_dpaqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13483            break;
13484        case OPC_DPS_W_PH:
13485            check_dspr2(ctx);
13486            gen_helper_dps_w_ph(t0, v1_t, v2_t, cpu_env);
13487            break;
13488        case OPC_DPSX_W_PH:
13489            check_dspr2(ctx);
13490            gen_helper_dpsx_w_ph(t0, v1_t, v2_t, cpu_env);
13491            break;
13492        case OPC_DPSQ_S_W_PH:
13493            check_dsp(ctx);
13494            gen_helper_dpsq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13495            break;
13496        case OPC_DPSQX_S_W_PH:
13497            check_dspr2(ctx);
13498            gen_helper_dpsqx_s_w_ph(t0, v1_t, v2_t, cpu_env);
13499            break;
13500        case OPC_DPSQX_SA_W_PH:
13501            check_dspr2(ctx);
13502            gen_helper_dpsqx_sa_w_ph(t0, v1_t, v2_t, cpu_env);
13503            break;
13504        case OPC_MULSAQ_S_W_PH:
13505            check_dsp(ctx);
13506            gen_helper_mulsaq_s_w_ph(t0, v1_t, v2_t, cpu_env);
13507            break;
13508        case OPC_DPAQ_SA_L_W:
13509            check_dsp(ctx);
13510            gen_helper_dpaq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13511            break;
13512        case OPC_DPSQ_SA_L_W:
13513            check_dsp(ctx);
13514            gen_helper_dpsq_sa_l_w(t0, v1_t, v2_t, cpu_env);
13515            break;
13516        case OPC_MAQ_S_W_PHL:
13517            check_dsp(ctx);
13518            gen_helper_maq_s_w_phl(t0, v1_t, v2_t, cpu_env);
13519            break;
13520        case OPC_MAQ_S_W_PHR:
13521            check_dsp(ctx);
13522            gen_helper_maq_s_w_phr(t0, v1_t, v2_t, cpu_env);
13523            break;
13524        case OPC_MAQ_SA_W_PHL:
13525            check_dsp(ctx);
13526            gen_helper_maq_sa_w_phl(t0, v1_t, v2_t, cpu_env);
13527            break;
13528        case OPC_MAQ_SA_W_PHR:
13529            check_dsp(ctx);
13530            gen_helper_maq_sa_w_phr(t0, v1_t, v2_t, cpu_env);
13531            break;
13532        case OPC_MULSA_W_PH:
13533            check_dspr2(ctx);
13534            gen_helper_mulsa_w_ph(t0, v1_t, v2_t, cpu_env);
13535            break;
13536        }
13537        break;
13538#ifdef TARGET_MIPS64
13539    case OPC_DPAQ_W_QH_DSP:
13540        {
13541            int ac = ret & 0x03;
13542            tcg_gen_movi_i32(t0, ac);
13543
13544            switch (op2) {
13545            case OPC_DMADD:
13546                check_dsp(ctx);
13547                gen_helper_dmadd(v1_t, v2_t, t0, cpu_env);
13548                break;
13549            case OPC_DMADDU:
13550                check_dsp(ctx);
13551                gen_helper_dmaddu(v1_t, v2_t, t0, cpu_env);
13552                break;
13553            case OPC_DMSUB:
13554                check_dsp(ctx);
13555                gen_helper_dmsub(v1_t, v2_t, t0, cpu_env);
13556                break;
13557            case OPC_DMSUBU:
13558                check_dsp(ctx);
13559                gen_helper_dmsubu(v1_t, v2_t, t0, cpu_env);
13560                break;
13561            case OPC_DPA_W_QH:
13562                check_dspr2(ctx);
13563                gen_helper_dpa_w_qh(v1_t, v2_t, t0, cpu_env);
13564                break;
13565            case OPC_DPAQ_S_W_QH:
13566                check_dsp(ctx);
13567                gen_helper_dpaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13568                break;
13569            case OPC_DPAQ_SA_L_PW:
13570                check_dsp(ctx);
13571                gen_helper_dpaq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13572                break;
13573            case OPC_DPAU_H_OBL:
13574                check_dsp(ctx);
13575                gen_helper_dpau_h_obl(v1_t, v2_t, t0, cpu_env);
13576                break;
13577            case OPC_DPAU_H_OBR:
13578                check_dsp(ctx);
13579                gen_helper_dpau_h_obr(v1_t, v2_t, t0, cpu_env);
13580                break;
13581            case OPC_DPS_W_QH:
13582                check_dspr2(ctx);
13583                gen_helper_dps_w_qh(v1_t, v2_t, t0, cpu_env);
13584                break;
13585            case OPC_DPSQ_S_W_QH:
13586                check_dsp(ctx);
13587                gen_helper_dpsq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13588                break;
13589            case OPC_DPSQ_SA_L_PW:
13590                check_dsp(ctx);
13591                gen_helper_dpsq_sa_l_pw(v1_t, v2_t, t0, cpu_env);
13592                break;
13593            case OPC_DPSU_H_OBL:
13594                check_dsp(ctx);
13595                gen_helper_dpsu_h_obl(v1_t, v2_t, t0, cpu_env);
13596                break;
13597            case OPC_DPSU_H_OBR:
13598                check_dsp(ctx);
13599                gen_helper_dpsu_h_obr(v1_t, v2_t, t0, cpu_env);
13600                break;
13601            case OPC_MAQ_S_L_PWL:
13602                check_dsp(ctx);
13603                gen_helper_maq_s_l_pwl(v1_t, v2_t, t0, cpu_env);
13604                break;
13605            case OPC_MAQ_S_L_PWR:
13606                check_dsp(ctx);
13607                gen_helper_maq_s_l_pwr(v1_t, v2_t, t0, cpu_env);
13608                break;
13609            case OPC_MAQ_S_W_QHLL:
13610                check_dsp(ctx);
13611                gen_helper_maq_s_w_qhll(v1_t, v2_t, t0, cpu_env);
13612                break;
13613            case OPC_MAQ_SA_W_QHLL:
13614                check_dsp(ctx);
13615                gen_helper_maq_sa_w_qhll(v1_t, v2_t, t0, cpu_env);
13616                break;
13617            case OPC_MAQ_S_W_QHLR:
13618                check_dsp(ctx);
13619                gen_helper_maq_s_w_qhlr(v1_t, v2_t, t0, cpu_env);
13620                break;
13621            case OPC_MAQ_SA_W_QHLR:
13622                check_dsp(ctx);
13623                gen_helper_maq_sa_w_qhlr(v1_t, v2_t, t0, cpu_env);
13624                break;
13625            case OPC_MAQ_S_W_QHRL:
13626                check_dsp(ctx);
13627                gen_helper_maq_s_w_qhrl(v1_t, v2_t, t0, cpu_env);
13628                break;
13629            case OPC_MAQ_SA_W_QHRL:
13630                check_dsp(ctx);
13631                gen_helper_maq_sa_w_qhrl(v1_t, v2_t, t0, cpu_env);
13632                break;
13633            case OPC_MAQ_S_W_QHRR:
13634                check_dsp(ctx);
13635                gen_helper_maq_s_w_qhrr(v1_t, v2_t, t0, cpu_env);
13636                break;
13637            case OPC_MAQ_SA_W_QHRR:
13638                check_dsp(ctx);
13639                gen_helper_maq_sa_w_qhrr(v1_t, v2_t, t0, cpu_env);
13640                break;
13641            case OPC_MULSAQ_S_L_PW:
13642                check_dsp(ctx);
13643                gen_helper_mulsaq_s_l_pw(v1_t, v2_t, t0, cpu_env);
13644                break;
13645            case OPC_MULSAQ_S_W_QH:
13646                check_dsp(ctx);
13647                gen_helper_mulsaq_s_w_qh(v1_t, v2_t, t0, cpu_env);
13648                break;
13649            }
13650        }
13651        break;
13652#endif
13653    case OPC_ADDU_QB_DSP:
13654        switch (op2) {
13655        case OPC_MULEU_S_PH_QBL:
13656            check_dsp(ctx);
13657            gen_helper_muleu_s_ph_qbl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13658            break;
13659        case OPC_MULEU_S_PH_QBR:
13660            check_dsp(ctx);
13661            gen_helper_muleu_s_ph_qbr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13662            break;
13663        case OPC_MULQ_RS_PH:
13664            check_dsp(ctx);
13665            gen_helper_mulq_rs_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13666            break;
13667        case OPC_MULEQ_S_W_PHL:
13668            check_dsp(ctx);
13669            gen_helper_muleq_s_w_phl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13670            break;
13671        case OPC_MULEQ_S_W_PHR:
13672            check_dsp(ctx);
13673            gen_helper_muleq_s_w_phr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13674            break;
13675        case OPC_MULQ_S_PH:
13676            check_dspr2(ctx);
13677            gen_helper_mulq_s_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13678            break;
13679        }
13680        break;
13681#ifdef TARGET_MIPS64
13682    case OPC_ADDU_OB_DSP:
13683        switch (op2) {
13684        case OPC_MULEQ_S_PW_QHL:
13685            check_dsp(ctx);
13686            gen_helper_muleq_s_pw_qhl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13687            break;
13688        case OPC_MULEQ_S_PW_QHR:
13689            check_dsp(ctx);
13690            gen_helper_muleq_s_pw_qhr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13691            break;
13692        case OPC_MULEU_S_QH_OBL:
13693            check_dsp(ctx);
13694            gen_helper_muleu_s_qh_obl(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13695            break;
13696        case OPC_MULEU_S_QH_OBR:
13697            check_dsp(ctx);
13698            gen_helper_muleu_s_qh_obr(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13699            break;
13700        case OPC_MULQ_RS_QH:
13701            check_dsp(ctx);
13702            gen_helper_mulq_rs_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13703            break;
13704        }
13705        break;
13706#endif
13707    }
13708
13709    tcg_temp_free_i32(t0);
13710    tcg_temp_free(v1_t);
13711    tcg_temp_free(v2_t);
13712
13713    (void)opn; /* avoid a compiler warning */
13714    MIPS_DEBUG("%s", opn);
13715
13716}
13717
13718static void gen_mipsdsp_bitinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
13719                                int ret, int val)
13720{
13721    const char *opn = "mipsdsp Bit/ Manipulation";
13722    int16_t imm;
13723    TCGv t0;
13724    TCGv val_t;
13725
13726    if (ret == 0) {
13727        /* Treat as NOP. */
13728        MIPS_DEBUG("NOP");
13729        return;
13730    }
13731
13732    t0 = tcg_temp_new();
13733    val_t = tcg_temp_new();
13734    gen_load_gpr(val_t, val);
13735
13736    switch (op1) {
13737    case OPC_ABSQ_S_PH_DSP:
13738        switch (op2) {
13739        case OPC_BITREV:
13740            check_dsp(ctx);
13741            gen_helper_bitrev(cpu_gpr[ret], val_t);
13742            break;
13743        case OPC_REPL_QB:
13744            check_dsp(ctx);
13745            {
13746                target_long result;
13747                imm = (ctx->opcode >> 16) & 0xFF;
13748                result = (uint32_t)imm << 24 |
13749                         (uint32_t)imm << 16 |
13750                         (uint32_t)imm << 8  |
13751                         (uint32_t)imm;
13752                result = (int32_t)result;
13753                tcg_gen_movi_tl(cpu_gpr[ret], result);
13754            }
13755            break;
13756        case OPC_REPLV_QB:
13757            check_dsp(ctx);
13758            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13759            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13760            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13761            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13762            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13763            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13764            break;
13765        case OPC_REPL_PH:
13766            check_dsp(ctx);
13767            {
13768                imm = (ctx->opcode >> 16) & 0x03FF;
13769                imm = (int16_t)(imm << 6) >> 6;
13770                tcg_gen_movi_tl(cpu_gpr[ret], \
13771                                (target_long)((int32_t)imm << 16 | \
13772                                (uint16_t)imm));
13773            }
13774            break;
13775        case OPC_REPLV_PH:
13776            check_dsp(ctx);
13777            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13778            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13779            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13780            tcg_gen_ext32s_tl(cpu_gpr[ret], cpu_gpr[ret]);
13781            break;
13782        }
13783        break;
13784#ifdef TARGET_MIPS64
13785    case OPC_ABSQ_S_QH_DSP:
13786        switch (op2) {
13787        case OPC_REPL_OB:
13788            check_dsp(ctx);
13789            {
13790                target_long temp;
13791
13792                imm = (ctx->opcode >> 16) & 0xFF;
13793                temp = ((uint64_t)imm << 8) | (uint64_t)imm;
13794                temp = (temp << 16) | temp;
13795                temp = (temp << 32) | temp;
13796                tcg_gen_movi_tl(cpu_gpr[ret], temp);
13797                break;
13798            }
13799        case OPC_REPL_PW:
13800            check_dsp(ctx);
13801            {
13802                target_long temp;
13803
13804                imm = (ctx->opcode >> 16) & 0x03FF;
13805                imm = (int16_t)(imm << 6) >> 6;
13806                temp = ((target_long)imm << 32) \
13807                       | ((target_long)imm & 0xFFFFFFFF);
13808                tcg_gen_movi_tl(cpu_gpr[ret], temp);
13809                break;
13810            }
13811        case OPC_REPL_QH:
13812            check_dsp(ctx);
13813            {
13814                target_long temp;
13815
13816                imm = (ctx->opcode >> 16) & 0x03FF;
13817                imm = (int16_t)(imm << 6) >> 6;
13818
13819                temp = ((uint64_t)(uint16_t)imm << 48) |
13820                       ((uint64_t)(uint16_t)imm << 32) |
13821                       ((uint64_t)(uint16_t)imm << 16) |
13822                       (uint64_t)(uint16_t)imm;
13823                tcg_gen_movi_tl(cpu_gpr[ret], temp);
13824                break;
13825            }
13826        case OPC_REPLV_OB:
13827            check_dsp(ctx);
13828            tcg_gen_ext8u_tl(cpu_gpr[ret], val_t);
13829            tcg_gen_shli_tl(t0, cpu_gpr[ret], 8);
13830            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13831            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13832            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13833            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13834            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13835            break;
13836        case OPC_REPLV_PW:
13837            check_dsp(ctx);
13838            tcg_gen_ext32u_i64(cpu_gpr[ret], val_t);
13839            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13840            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13841            break;
13842        case OPC_REPLV_QH:
13843            check_dsp(ctx);
13844            tcg_gen_ext16u_tl(cpu_gpr[ret], val_t);
13845            tcg_gen_shli_tl(t0, cpu_gpr[ret], 16);
13846            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13847            tcg_gen_shli_tl(t0, cpu_gpr[ret], 32);
13848            tcg_gen_or_tl(cpu_gpr[ret], cpu_gpr[ret], t0);
13849            break;
13850        }
13851        break;
13852#endif
13853    }
13854    tcg_temp_free(t0);
13855    tcg_temp_free(val_t);
13856
13857    (void)opn; /* avoid a compiler warning */
13858    MIPS_DEBUG("%s", opn);
13859}
13860
13861static void gen_mipsdsp_add_cmp_pick(DisasContext *ctx,
13862                                     uint32_t op1, uint32_t op2,
13863                                     int ret, int v1, int v2, int check_ret)
13864{
13865    const char *opn = "mipsdsp add compare pick";
13866    TCGv t1;
13867    TCGv v1_t;
13868    TCGv v2_t;
13869
13870    if ((ret == 0) && (check_ret == 1)) {
13871        /* Treat as NOP. */
13872        MIPS_DEBUG("NOP");
13873        return;
13874    }
13875
13876    t1 = tcg_temp_new();
13877    v1_t = tcg_temp_new();
13878    v2_t = tcg_temp_new();
13879
13880    gen_load_gpr(v1_t, v1);
13881    gen_load_gpr(v2_t, v2);
13882
13883    switch (op1) {
13884    case OPC_CMPU_EQ_QB_DSP:
13885        switch (op2) {
13886        case OPC_CMPU_EQ_QB:
13887            check_dsp(ctx);
13888            gen_helper_cmpu_eq_qb(v1_t, v2_t, cpu_env);
13889            break;
13890        case OPC_CMPU_LT_QB:
13891            check_dsp(ctx);
13892            gen_helper_cmpu_lt_qb(v1_t, v2_t, cpu_env);
13893            break;
13894        case OPC_CMPU_LE_QB:
13895            check_dsp(ctx);
13896            gen_helper_cmpu_le_qb(v1_t, v2_t, cpu_env);
13897            break;
13898        case OPC_CMPGU_EQ_QB:
13899            check_dsp(ctx);
13900            gen_helper_cmpgu_eq_qb(cpu_gpr[ret], v1_t, v2_t);
13901            break;
13902        case OPC_CMPGU_LT_QB:
13903            check_dsp(ctx);
13904            gen_helper_cmpgu_lt_qb(cpu_gpr[ret], v1_t, v2_t);
13905            break;
13906        case OPC_CMPGU_LE_QB:
13907            check_dsp(ctx);
13908            gen_helper_cmpgu_le_qb(cpu_gpr[ret], v1_t, v2_t);
13909            break;
13910        case OPC_CMPGDU_EQ_QB:
13911            check_dspr2(ctx);
13912            gen_helper_cmpgu_eq_qb(t1, v1_t, v2_t);
13913            tcg_gen_mov_tl(cpu_gpr[ret], t1);
13914            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13915            tcg_gen_shli_tl(t1, t1, 24);
13916            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13917            break;
13918        case OPC_CMPGDU_LT_QB:
13919            check_dspr2(ctx);
13920            gen_helper_cmpgu_lt_qb(t1, v1_t, v2_t);
13921            tcg_gen_mov_tl(cpu_gpr[ret], t1);
13922            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13923            tcg_gen_shli_tl(t1, t1, 24);
13924            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13925            break;
13926        case OPC_CMPGDU_LE_QB:
13927            check_dspr2(ctx);
13928            gen_helper_cmpgu_le_qb(t1, v1_t, v2_t);
13929            tcg_gen_mov_tl(cpu_gpr[ret], t1);
13930            tcg_gen_andi_tl(cpu_dspctrl, cpu_dspctrl, 0xF0FFFFFF);
13931            tcg_gen_shli_tl(t1, t1, 24);
13932            tcg_gen_or_tl(cpu_dspctrl, cpu_dspctrl, t1);
13933            break;
13934        case OPC_CMP_EQ_PH:
13935            check_dsp(ctx);
13936            gen_helper_cmp_eq_ph(v1_t, v2_t, cpu_env);
13937            break;
13938        case OPC_CMP_LT_PH:
13939            check_dsp(ctx);
13940            gen_helper_cmp_lt_ph(v1_t, v2_t, cpu_env);
13941            break;
13942        case OPC_CMP_LE_PH:
13943            check_dsp(ctx);
13944            gen_helper_cmp_le_ph(v1_t, v2_t, cpu_env);
13945            break;
13946        case OPC_PICK_QB:
13947            check_dsp(ctx);
13948            gen_helper_pick_qb(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13949            break;
13950        case OPC_PICK_PH:
13951            check_dsp(ctx);
13952            gen_helper_pick_ph(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13953            break;
13954        case OPC_PACKRL_PH:
13955            check_dsp(ctx);
13956            gen_helper_packrl_ph(cpu_gpr[ret], v1_t, v2_t);
13957            break;
13958        }
13959        break;
13960#ifdef TARGET_MIPS64
13961    case OPC_CMPU_EQ_OB_DSP:
13962        switch (op2) {
13963        case OPC_CMP_EQ_PW:
13964            check_dsp(ctx);
13965            gen_helper_cmp_eq_pw(v1_t, v2_t, cpu_env);
13966            break;
13967        case OPC_CMP_LT_PW:
13968            check_dsp(ctx);
13969            gen_helper_cmp_lt_pw(v1_t, v2_t, cpu_env);
13970            break;
13971        case OPC_CMP_LE_PW:
13972            check_dsp(ctx);
13973            gen_helper_cmp_le_pw(v1_t, v2_t, cpu_env);
13974            break;
13975        case OPC_CMP_EQ_QH:
13976            check_dsp(ctx);
13977            gen_helper_cmp_eq_qh(v1_t, v2_t, cpu_env);
13978            break;
13979        case OPC_CMP_LT_QH:
13980            check_dsp(ctx);
13981            gen_helper_cmp_lt_qh(v1_t, v2_t, cpu_env);
13982            break;
13983        case OPC_CMP_LE_QH:
13984            check_dsp(ctx);
13985            gen_helper_cmp_le_qh(v1_t, v2_t, cpu_env);
13986            break;
13987        case OPC_CMPGDU_EQ_OB:
13988            check_dspr2(ctx);
13989            gen_helper_cmpgdu_eq_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13990            break;
13991        case OPC_CMPGDU_LT_OB:
13992            check_dspr2(ctx);
13993            gen_helper_cmpgdu_lt_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13994            break;
13995        case OPC_CMPGDU_LE_OB:
13996            check_dspr2(ctx);
13997            gen_helper_cmpgdu_le_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
13998            break;
13999        case OPC_CMPGU_EQ_OB:
14000            check_dsp(ctx);
14001            gen_helper_cmpgu_eq_ob(cpu_gpr[ret], v1_t, v2_t);
14002            break;
14003        case OPC_CMPGU_LT_OB:
14004            check_dsp(ctx);
14005            gen_helper_cmpgu_lt_ob(cpu_gpr[ret], v1_t, v2_t);
14006            break;
14007        case OPC_CMPGU_LE_OB:
14008            check_dsp(ctx);
14009            gen_helper_cmpgu_le_ob(cpu_gpr[ret], v1_t, v2_t);
14010            break;
14011        case OPC_CMPU_EQ_OB:
14012            check_dsp(ctx);
14013            gen_helper_cmpu_eq_ob(v1_t, v2_t, cpu_env);
14014            break;
14015        case OPC_CMPU_LT_OB:
14016            check_dsp(ctx);
14017            gen_helper_cmpu_lt_ob(v1_t, v2_t, cpu_env);
14018            break;
14019        case OPC_CMPU_LE_OB:
14020            check_dsp(ctx);
14021            gen_helper_cmpu_le_ob(v1_t, v2_t, cpu_env);
14022            break;
14023        case OPC_PACKRL_PW:
14024            check_dsp(ctx);
14025            gen_helper_packrl_pw(cpu_gpr[ret], v1_t, v2_t);
14026            break;
14027        case OPC_PICK_OB:
14028            check_dsp(ctx);
14029            gen_helper_pick_ob(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14030            break;
14031        case OPC_PICK_PW:
14032            check_dsp(ctx);
14033            gen_helper_pick_pw(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14034            break;
14035        case OPC_PICK_QH:
14036            check_dsp(ctx);
14037            gen_helper_pick_qh(cpu_gpr[ret], v1_t, v2_t, cpu_env);
14038            break;
14039        }
14040        break;
14041#endif
14042    }
14043
14044    tcg_temp_free(t1);
14045    tcg_temp_free(v1_t);
14046    tcg_temp_free(v2_t);
14047
14048    (void)opn; /* avoid a compiler warning */
14049    MIPS_DEBUG("%s", opn);
14050}
14051
14052static void gen_mipsdsp_append(CPUMIPSState *env, DisasContext *ctx,
14053                               uint32_t op1, int rt, int rs, int sa)
14054{
14055    const char *opn = "mipsdsp append/dappend";
14056    TCGv t0;
14057
14058    check_dspr2(ctx);
14059
14060    if (rt == 0) {
14061        /* Treat as NOP. */
14062        MIPS_DEBUG("NOP");
14063        return;
14064    }
14065
14066    t0 = tcg_temp_new();
14067    gen_load_gpr(t0, rs);
14068
14069    switch (op1) {
14070    case OPC_APPEND_DSP:
14071        switch (MASK_APPEND(ctx->opcode)) {
14072        case OPC_APPEND:
14073            if (sa != 0) {
14074                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 32 - sa);
14075            }
14076            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14077            break;
14078        case OPC_PREPEND:
14079            if (sa != 0) {
14080                tcg_gen_ext32u_tl(cpu_gpr[rt], cpu_gpr[rt]);
14081                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14082                tcg_gen_shli_tl(t0, t0, 32 - sa);
14083                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14084            }
14085            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14086            break;
14087        case OPC_BALIGN:
14088            sa &= 3;
14089            if (sa != 0 && sa != 2) {
14090                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14091                tcg_gen_ext32u_tl(t0, t0);
14092                tcg_gen_shri_tl(t0, t0, 8 * (4 - sa));
14093                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14094            }
14095            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
14096            break;
14097        default:            /* Invalid */
14098            MIPS_INVAL("MASK APPEND");
14099            generate_exception(ctx, EXCP_RI);
14100            break;
14101        }
14102        break;
14103#ifdef TARGET_MIPS64
14104    case OPC_DAPPEND_DSP:
14105        switch (MASK_DAPPEND(ctx->opcode)) {
14106        case OPC_DAPPEND:
14107            if (sa != 0) {
14108                tcg_gen_deposit_tl(cpu_gpr[rt], t0, cpu_gpr[rt], sa, 64 - sa);
14109            }
14110            break;
14111        case OPC_PREPENDD:
14112            tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], 0x20 | sa);
14113            tcg_gen_shli_tl(t0, t0, 64 - (0x20 | sa));
14114            tcg_gen_or_tl(cpu_gpr[rt], t0, t0);
14115            break;
14116        case OPC_PREPENDW:
14117            if (sa != 0) {
14118                tcg_gen_shri_tl(cpu_gpr[rt], cpu_gpr[rt], sa);
14119                tcg_gen_shli_tl(t0, t0, 64 - sa);
14120                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14121            }
14122            break;
14123        case OPC_DBALIGN:
14124            sa &= 7;
14125            if (sa != 0 && sa != 2 && sa != 4) {
14126                tcg_gen_shli_tl(cpu_gpr[rt], cpu_gpr[rt], 8 * sa);
14127                tcg_gen_shri_tl(t0, t0, 8 * (8 - sa));
14128                tcg_gen_or_tl(cpu_gpr[rt], cpu_gpr[rt], t0);
14129            }
14130            break;
14131        default:            /* Invalid */
14132            MIPS_INVAL("MASK DAPPEND");
14133            generate_exception(ctx, EXCP_RI);
14134            break;
14135        }
14136        break;
14137#endif
14138    }
14139    tcg_temp_free(t0);
14140    (void)opn; /* avoid a compiler warning */
14141    MIPS_DEBUG("%s", opn);
14142}
14143
14144static void gen_mipsdsp_accinsn(DisasContext *ctx, uint32_t op1, uint32_t op2,
14145                                int ret, int v1, int v2, int check_ret)
14146
14147{
14148    const char *opn = "mipsdsp accumulator";
14149    TCGv t0;
14150    TCGv t1;
14151    TCGv v1_t;
14152    TCGv v2_t;
14153    int16_t imm;
14154
14155    if ((ret == 0) && (check_ret == 1)) {
14156        /* Treat as NOP. */
14157        MIPS_DEBUG("NOP");
14158        return;
14159    }
14160
14161    t0 = tcg_temp_new();
14162    t1 = tcg_temp_new();
14163    v1_t = tcg_temp_new();
14164    v2_t = tcg_temp_new();
14165
14166    gen_load_gpr(v1_t, v1);
14167    gen_load_gpr(v2_t, v2);
14168
14169    switch (op1) {
14170    case OPC_EXTR_W_DSP:
14171        check_dsp(ctx);
14172        switch (op2) {
14173        case OPC_EXTR_W:
14174            tcg_gen_movi_tl(t0, v2);
14175            tcg_gen_movi_tl(t1, v1);
14176            gen_helper_extr_w(cpu_gpr[ret], t0, t1, cpu_env);
14177            break;
14178        case OPC_EXTR_R_W:
14179            tcg_gen_movi_tl(t0, v2);
14180            tcg_gen_movi_tl(t1, v1);
14181            gen_helper_extr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14182            break;
14183        case OPC_EXTR_RS_W:
14184            tcg_gen_movi_tl(t0, v2);
14185            tcg_gen_movi_tl(t1, v1);
14186            gen_helper_extr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14187            break;
14188        case OPC_EXTR_S_H:
14189            tcg_gen_movi_tl(t0, v2);
14190            tcg_gen_movi_tl(t1, v1);
14191            gen_helper_extr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14192            break;
14193        case OPC_EXTRV_S_H:
14194            tcg_gen_movi_tl(t0, v2);
14195            gen_helper_extr_s_h(cpu_gpr[ret], t0, v1_t, cpu_env);
14196            break;
14197        case OPC_EXTRV_W:
14198            tcg_gen_movi_tl(t0, v2);
14199            gen_helper_extr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14200            break;
14201        case OPC_EXTRV_R_W:
14202            tcg_gen_movi_tl(t0, v2);
14203            gen_helper_extr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14204            break;
14205        case OPC_EXTRV_RS_W:
14206            tcg_gen_movi_tl(t0, v2);
14207            gen_helper_extr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14208            break;
14209        case OPC_EXTP:
14210            tcg_gen_movi_tl(t0, v2);
14211            tcg_gen_movi_tl(t1, v1);
14212            gen_helper_extp(cpu_gpr[ret], t0, t1, cpu_env);
14213            break;
14214        case OPC_EXTPV:
14215            tcg_gen_movi_tl(t0, v2);
14216            gen_helper_extp(cpu_gpr[ret], t0, v1_t, cpu_env);
14217            break;
14218        case OPC_EXTPDP:
14219            tcg_gen_movi_tl(t0, v2);
14220            tcg_gen_movi_tl(t1, v1);
14221            gen_helper_extpdp(cpu_gpr[ret], t0, t1, cpu_env);
14222            break;
14223        case OPC_EXTPDPV:
14224            tcg_gen_movi_tl(t0, v2);
14225            gen_helper_extpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14226            break;
14227        case OPC_SHILO:
14228            imm = (ctx->opcode >> 20) & 0x3F;
14229            tcg_gen_movi_tl(t0, ret);
14230            tcg_gen_movi_tl(t1, imm);
14231            gen_helper_shilo(t0, t1, cpu_env);
14232            break;
14233        case OPC_SHILOV:
14234            tcg_gen_movi_tl(t0, ret);
14235            gen_helper_shilo(t0, v1_t, cpu_env);
14236            break;
14237        case OPC_MTHLIP:
14238            tcg_gen_movi_tl(t0, ret);
14239            gen_helper_mthlip(t0, v1_t, cpu_env);
14240            break;
14241        case OPC_WRDSP:
14242            imm = (ctx->opcode >> 11) & 0x3FF;
14243            tcg_gen_movi_tl(t0, imm);
14244            gen_helper_wrdsp(v1_t, t0, cpu_env);
14245            break;
14246        case OPC_RDDSP:
14247            imm = (ctx->opcode >> 16) & 0x03FF;
14248            tcg_gen_movi_tl(t0, imm);
14249            gen_helper_rddsp(cpu_gpr[ret], t0, cpu_env);
14250            break;
14251        }
14252        break;
14253#ifdef TARGET_MIPS64
14254    case OPC_DEXTR_W_DSP:
14255        check_dsp(ctx);
14256        switch (op2) {
14257        case OPC_DMTHLIP:
14258            tcg_gen_movi_tl(t0, ret);
14259            gen_helper_dmthlip(v1_t, t0, cpu_env);
14260            break;
14261        case OPC_DSHILO:
14262            {
14263                int shift = (ctx->opcode >> 19) & 0x7F;
14264                int ac = (ctx->opcode >> 11) & 0x03;
14265                tcg_gen_movi_tl(t0, shift);
14266                tcg_gen_movi_tl(t1, ac);
14267                gen_helper_dshilo(t0, t1, cpu_env);
14268                break;
14269            }
14270        case OPC_DSHILOV:
14271            {
14272                int ac = (ctx->opcode >> 11) & 0x03;
14273                tcg_gen_movi_tl(t0, ac);
14274                gen_helper_dshilo(v1_t, t0, cpu_env);
14275                break;
14276            }
14277        case OPC_DEXTP:
14278            tcg_gen_movi_tl(t0, v2);
14279            tcg_gen_movi_tl(t1, v1);
14280
14281            gen_helper_dextp(cpu_gpr[ret], t0, t1, cpu_env);
14282            break;
14283        case OPC_DEXTPV:
14284            tcg_gen_movi_tl(t0, v2);
14285            gen_helper_dextp(cpu_gpr[ret], t0, v1_t, cpu_env);
14286            break;
14287        case OPC_DEXTPDP:
14288            tcg_gen_movi_tl(t0, v2);
14289            tcg_gen_movi_tl(t1, v1);
14290            gen_helper_dextpdp(cpu_gpr[ret], t0, t1, cpu_env);
14291            break;
14292        case OPC_DEXTPDPV:
14293            tcg_gen_movi_tl(t0, v2);
14294            gen_helper_dextpdp(cpu_gpr[ret], t0, v1_t, cpu_env);
14295            break;
14296        case OPC_DEXTR_L:
14297            tcg_gen_movi_tl(t0, v2);
14298            tcg_gen_movi_tl(t1, v1);
14299            gen_helper_dextr_l(cpu_gpr[ret], t0, t1, cpu_env);
14300            break;
14301        case OPC_DEXTR_R_L:
14302            tcg_gen_movi_tl(t0, v2);
14303            tcg_gen_movi_tl(t1, v1);
14304            gen_helper_dextr_r_l(cpu_gpr[ret], t0, t1, cpu_env);
14305            break;
14306        case OPC_DEXTR_RS_L:
14307            tcg_gen_movi_tl(t0, v2);
14308            tcg_gen_movi_tl(t1, v1);
14309            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, t1, cpu_env);
14310            break;
14311        case OPC_DEXTR_W:
14312            tcg_gen_movi_tl(t0, v2);
14313            tcg_gen_movi_tl(t1, v1);
14314            gen_helper_dextr_w(cpu_gpr[ret], t0, t1, cpu_env);
14315            break;
14316        case OPC_DEXTR_R_W:
14317            tcg_gen_movi_tl(t0, v2);
14318            tcg_gen_movi_tl(t1, v1);
14319            gen_helper_dextr_r_w(cpu_gpr[ret], t0, t1, cpu_env);
14320            break;
14321        case OPC_DEXTR_RS_W:
14322            tcg_gen_movi_tl(t0, v2);
14323            tcg_gen_movi_tl(t1, v1);
14324            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, t1, cpu_env);
14325            break;
14326        case OPC_DEXTR_S_H:
14327            tcg_gen_movi_tl(t0, v2);
14328            tcg_gen_movi_tl(t1, v1);
14329            gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14330            break;
14331        case OPC_DEXTRV_S_H:
14332            tcg_gen_movi_tl(t0, v2);
14333            tcg_gen_movi_tl(t1, v1);
14334            gen_helper_dextr_s_h(cpu_gpr[ret], t0, t1, cpu_env);
14335            break;
14336        case OPC_DEXTRV_L:
14337            tcg_gen_movi_tl(t0, v2);
14338            gen_helper_dextr_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14339            break;
14340        case OPC_DEXTRV_R_L:
14341            tcg_gen_movi_tl(t0, v2);
14342            gen_helper_dextr_r_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14343            break;
14344        case OPC_DEXTRV_RS_L:
14345            tcg_gen_movi_tl(t0, v2);
14346            gen_helper_dextr_rs_l(cpu_gpr[ret], t0, v1_t, cpu_env);
14347            break;
14348        case OPC_DEXTRV_W:
14349            tcg_gen_movi_tl(t0, v2);
14350            gen_helper_dextr_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14351            break;
14352        case OPC_DEXTRV_R_W:
14353            tcg_gen_movi_tl(t0, v2);
14354            gen_helper_dextr_r_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14355            break;
14356        case OPC_DEXTRV_RS_W:
14357            tcg_gen_movi_tl(t0, v2);
14358            gen_helper_dextr_rs_w(cpu_gpr[ret], t0, v1_t, cpu_env);
14359            break;
14360        }
14361        break;
14362#endif
14363    }
14364
14365    tcg_temp_free(t0);
14366    tcg_temp_free(t1);
14367    tcg_temp_free(v1_t);
14368    tcg_temp_free(v2_t);
14369
14370    (void)opn; /* avoid a compiler warning */
14371    MIPS_DEBUG("%s", opn);
14372}
14373
14374/* End MIPSDSP functions. */
14375
14376static void decode_opc (CPUMIPSState *env, DisasContext *ctx)
14377{
14378    int32_t offset;
14379    int rs, rt, rd, sa;
14380    uint32_t op, op1, op2;
14381    int16_t imm;
14382
14383    /* make sure instructions are on a word boundary */
14384    if (ctx->pc & 0x3) {
14385        env->CP0_BadVAddr = ctx->pc;
14386        generate_exception(ctx, EXCP_AdEL);
14387        return;
14388    }
14389
14390    /* Handle blikely not taken case */
14391    if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
14392        int l1 = gen_new_label();
14393
14394        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
14395        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
14396        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
14397        gen_goto_tb(ctx, 1, ctx->pc + 4);
14398        gen_set_label(l1);
14399    }
14400
14401    if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP | CPU_LOG_TB_OP_OPT))) {
14402        tcg_gen_debug_insn_start(ctx->pc);
14403    }
14404
14405    op = MASK_OP_MAJOR(ctx->opcode);
14406    rs = (ctx->opcode >> 21) & 0x1f;
14407    rt = (ctx->opcode >> 16) & 0x1f;
14408    rd = (ctx->opcode >> 11) & 0x1f;
14409    sa = (ctx->opcode >> 6) & 0x1f;
14410    imm = (int16_t)ctx->opcode;
14411    switch (op) {
14412    case OPC_SPECIAL:
14413        op1 = MASK_SPECIAL(ctx->opcode);
14414        switch (op1) {
14415        case OPC_SLL:          /* Shift with immediate */
14416        case OPC_SRA:
14417            gen_shift_imm(ctx, op1, rd, rt, sa);
14418            break;
14419        case OPC_SRL:
14420            switch ((ctx->opcode >> 21) & 0x1f) {
14421            case 1:
14422                /* rotr is decoded as srl on non-R2 CPUs */
14423                if (ctx->insn_flags & ISA_MIPS32R2) {
14424                    op1 = OPC_ROTR;
14425                }
14426                /* Fallthrough */
14427            case 0:
14428                gen_shift_imm(ctx, op1, rd, rt, sa);
14429                break;
14430            default:
14431                generate_exception(ctx, EXCP_RI);
14432                break;
14433            }
14434            break;
14435        case OPC_MOVN:         /* Conditional move */
14436        case OPC_MOVZ:
14437            check_insn(ctx, ISA_MIPS4 | ISA_MIPS32 |
14438                                 INSN_LOONGSON2E | INSN_LOONGSON2F);
14439            gen_cond_move(ctx, op1, rd, rs, rt);
14440            break;
14441        case OPC_ADD ... OPC_SUBU:
14442            gen_arith(ctx, op1, rd, rs, rt);
14443            break;
14444        case OPC_SLLV:         /* Shifts */
14445        case OPC_SRAV:
14446            gen_shift(ctx, op1, rd, rs, rt);
14447            break;
14448        case OPC_SRLV:
14449            switch ((ctx->opcode >> 6) & 0x1f) {
14450            case 1:
14451                /* rotrv is decoded as srlv on non-R2 CPUs */
14452                if (ctx->insn_flags & ISA_MIPS32R2) {
14453                    op1 = OPC_ROTRV;
14454                }
14455                /* Fallthrough */
14456            case 0:
14457                gen_shift(ctx, op1, rd, rs, rt);
14458                break;
14459            default:
14460                generate_exception(ctx, EXCP_RI);
14461                break;
14462            }
14463            break;
14464        case OPC_SLT:          /* Set on less than */
14465        case OPC_SLTU:
14466            gen_slt(ctx, op1, rd, rs, rt);
14467            break;
14468        case OPC_AND:          /* Logic*/
14469        case OPC_OR:
14470        case OPC_NOR:
14471        case OPC_XOR:
14472            gen_logic(ctx, op1, rd, rs, rt);
14473            break;
14474        case OPC_MULT:
14475        case OPC_MULTU:
14476            if (sa) {
14477                check_insn(ctx, INSN_VR54XX);
14478                op1 = MASK_MUL_VR54XX(ctx->opcode);
14479                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
14480            } else {
14481                gen_muldiv(ctx, op1, rd & 3, rs, rt);
14482            }
14483            break;
14484        case OPC_DIV:
14485        case OPC_DIVU:
14486            gen_muldiv(ctx, op1, 0, rs, rt);
14487            break;
14488        case OPC_JR ... OPC_JALR:
14489            gen_compute_branch(ctx, op1, 4, rs, rd, sa);
14490            break;
14491        case OPC_TGE ... OPC_TEQ: /* Traps */
14492        case OPC_TNE:
14493            gen_trap(ctx, op1, rs, rt, -1);
14494            break;
14495        case OPC_MFHI:          /* Move from HI/LO */
14496        case OPC_MFLO:
14497            gen_HILO(ctx, op1, rs & 3, rd);
14498            break;
14499        case OPC_MTHI:
14500        case OPC_MTLO:          /* Move to HI/LO */
14501            gen_HILO(ctx, op1, rd & 3, rs);
14502            break;
14503        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
14504#ifdef MIPS_STRICT_STANDARD
14505            MIPS_INVAL("PMON / selsl");
14506            generate_exception(ctx, EXCP_RI);
14507#else
14508            gen_helper_0e0i(pmon, sa);
14509#endif
14510            break;
14511        case OPC_SYSCALL:
14512            generate_exception(ctx, EXCP_SYSCALL);
14513            ctx->bstate = BS_STOP;
14514            break;
14515        case OPC_BREAK:
14516            generate_exception(ctx, EXCP_BREAK);
14517            break;
14518        case OPC_SPIM:
14519#ifdef MIPS_STRICT_STANDARD
14520            MIPS_INVAL("SPIM");
14521            generate_exception(ctx, EXCP_RI);
14522#else
14523           /* Implemented as RI exception for now. */
14524            MIPS_INVAL("spim (unofficial)");
14525            generate_exception(ctx, EXCP_RI);
14526#endif
14527            break;
14528        case OPC_SYNC:
14529            /* Treat as NOP. */
14530            break;
14531
14532        case OPC_MOVCI:
14533            check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
14534            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
14535                check_cp1_enabled(ctx);
14536                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
14537                          (ctx->opcode >> 16) & 1);
14538            } else {
14539                generate_exception_err(ctx, EXCP_CpU, 1);
14540            }
14541            break;
14542
14543#if defined(TARGET_MIPS64)
14544       /* MIPS64 specific opcodes */
14545        case OPC_DSLL:
14546        case OPC_DSRA:
14547        case OPC_DSLL32:
14548        case OPC_DSRA32:
14549            check_insn(ctx, ISA_MIPS3);
14550            check_mips_64(ctx);
14551            gen_shift_imm(ctx, op1, rd, rt, sa);
14552            break;
14553        case OPC_DSRL:
14554            switch ((ctx->opcode >> 21) & 0x1f) {
14555            case 1:
14556                /* drotr is decoded as dsrl on non-R2 CPUs */
14557                if (ctx->insn_flags & ISA_MIPS32R2) {
14558                    op1 = OPC_DROTR;
14559                }
14560                /* Fallthrough */
14561            case 0:
14562                check_insn(ctx, ISA_MIPS3);
14563                check_mips_64(ctx);
14564                gen_shift_imm(ctx, op1, rd, rt, sa);
14565                break;
14566            default:
14567                generate_exception(ctx, EXCP_RI);
14568                break;
14569            }
14570            break;
14571        case OPC_DSRL32:
14572            switch ((ctx->opcode >> 21) & 0x1f) {
14573            case 1:
14574                /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
14575                if (ctx->insn_flags & ISA_MIPS32R2) {
14576                    op1 = OPC_DROTR32;
14577                }
14578                /* Fallthrough */
14579            case 0:
14580                check_insn(ctx, ISA_MIPS3);
14581                check_mips_64(ctx);
14582                gen_shift_imm(ctx, op1, rd, rt, sa);
14583                break;
14584            default:
14585                generate_exception(ctx, EXCP_RI);
14586                break;
14587            }
14588            break;
14589        case OPC_DADD ... OPC_DSUBU:
14590            check_insn(ctx, ISA_MIPS3);
14591            check_mips_64(ctx);
14592            gen_arith(ctx, op1, rd, rs, rt);
14593            break;
14594        case OPC_DSLLV:
14595        case OPC_DSRAV:
14596            check_insn(ctx, ISA_MIPS3);
14597            check_mips_64(ctx);
14598            gen_shift(ctx, op1, rd, rs, rt);
14599            break;
14600        case OPC_DSRLV:
14601            switch ((ctx->opcode >> 6) & 0x1f) {
14602            case 1:
14603                /* drotrv is decoded as dsrlv on non-R2 CPUs */
14604                if (ctx->insn_flags & ISA_MIPS32R2) {
14605                    op1 = OPC_DROTRV;
14606                }
14607                /* Fallthrough */
14608            case 0:
14609                check_insn(ctx, ISA_MIPS3);
14610                check_mips_64(ctx);
14611                gen_shift(ctx, op1, rd, rs, rt);
14612                break;
14613            default:
14614                generate_exception(ctx, EXCP_RI);
14615                break;
14616            }
14617            break;
14618        case OPC_DMULT ... OPC_DDIVU:
14619            check_insn(ctx, ISA_MIPS3);
14620            check_mips_64(ctx);
14621            gen_muldiv(ctx, op1, 0, rs, rt);
14622            break;
14623#endif
14624        default:            /* Invalid */
14625            MIPS_INVAL("special");
14626            generate_exception(ctx, EXCP_RI);
14627            break;
14628        }
14629        break;
14630    case OPC_SPECIAL2:
14631        op1 = MASK_SPECIAL2(ctx->opcode);
14632        switch (op1) {
14633        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
14634        case OPC_MSUB ... OPC_MSUBU:
14635            check_insn(ctx, ISA_MIPS32);
14636            gen_muldiv(ctx, op1, rd & 3, rs, rt);
14637            break;
14638        case OPC_MUL:
14639            gen_arith(ctx, op1, rd, rs, rt);
14640            break;
14641        case OPC_CLO:
14642        case OPC_CLZ:
14643            check_insn(ctx, ISA_MIPS32);
14644            gen_cl(ctx, op1, rd, rs);
14645            break;
14646        case OPC_SDBBP:
14647            /* XXX: not clear which exception should be raised
14648             *      when in debug mode...
14649             */
14650            check_insn(ctx, ISA_MIPS32);
14651            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
14652                generate_exception(ctx, EXCP_DBp);
14653            } else {
14654                generate_exception(ctx, EXCP_DBp);
14655            }
14656            /* Treat as NOP. */
14657            break;
14658        case OPC_DIV_G_2F:
14659        case OPC_DIVU_G_2F:
14660        case OPC_MULT_G_2F:
14661        case OPC_MULTU_G_2F:
14662        case OPC_MOD_G_2F:
14663        case OPC_MODU_G_2F:
14664            check_insn(ctx, INSN_LOONGSON2F);
14665            gen_loongson_integer(ctx, op1, rd, rs, rt);
14666            break;
14667#if defined(TARGET_MIPS64)
14668        case OPC_DCLO:
14669        case OPC_DCLZ:
14670            check_insn(ctx, ISA_MIPS64);
14671            check_mips_64(ctx);
14672            gen_cl(ctx, op1, rd, rs);
14673            break;
14674        case OPC_DMULT_G_2F:
14675        case OPC_DMULTU_G_2F:
14676        case OPC_DDIV_G_2F:
14677        case OPC_DDIVU_G_2F:
14678        case OPC_DMOD_G_2F:
14679        case OPC_DMODU_G_2F:
14680            check_insn(ctx, INSN_LOONGSON2F);
14681            gen_loongson_integer(ctx, op1, rd, rs, rt);
14682            break;
14683#endif
14684        default:            /* Invalid */
14685            MIPS_INVAL("special2");
14686            generate_exception(ctx, EXCP_RI);
14687            break;
14688        }
14689        break;
14690    case OPC_SPECIAL3:
14691        op1 = MASK_SPECIAL3(ctx->opcode);
14692        switch (op1) {
14693        case OPC_EXT:
14694        case OPC_INS:
14695            check_insn(ctx, ISA_MIPS32R2);
14696            gen_bitops(ctx, op1, rt, rs, sa, rd);
14697            break;
14698        case OPC_BSHFL:
14699            check_insn(ctx, ISA_MIPS32R2);
14700            op2 = MASK_BSHFL(ctx->opcode);
14701            gen_bshfl(ctx, op2, rt, rd);
14702            break;
14703        case OPC_RDHWR:
14704            gen_rdhwr(ctx, rt, rd);
14705            break;
14706        case OPC_FORK:
14707            check_insn(ctx, ASE_MT);
14708            {
14709                TCGv t0 = tcg_temp_new();
14710                TCGv t1 = tcg_temp_new();
14711
14712                gen_load_gpr(t0, rt);
14713                gen_load_gpr(t1, rs);
14714                gen_helper_fork(t0, t1);
14715                tcg_temp_free(t0);
14716                tcg_temp_free(t1);
14717            }
14718            break;
14719        case OPC_YIELD:
14720            check_insn(ctx, ASE_MT);
14721            {
14722                TCGv t0 = tcg_temp_new();
14723
14724                save_cpu_state(ctx, 1);
14725                gen_load_gpr(t0, rs);
14726                gen_helper_yield(t0, cpu_env, t0);
14727                gen_store_gpr(t0, rd);
14728                tcg_temp_free(t0);
14729            }
14730            break;
14731        case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
14732        case OPC_MOD_G_2E ... OPC_MODU_G_2E:
14733        case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
14734        /* OPC_MULT_G_2E, OPC_ADDUH_QB_DSP, OPC_MUL_PH_DSP have
14735         * the same mask and op1. */
14736            if ((ctx->insn_flags & ASE_DSPR2) && (op1 == OPC_MULT_G_2E)) {
14737                op2 = MASK_ADDUH_QB(ctx->opcode);
14738                switch (op2) {
14739                case OPC_ADDUH_QB:
14740                case OPC_ADDUH_R_QB:
14741                case OPC_ADDQH_PH:
14742                case OPC_ADDQH_R_PH:
14743                case OPC_ADDQH_W:
14744                case OPC_ADDQH_R_W:
14745                case OPC_SUBUH_QB:
14746                case OPC_SUBUH_R_QB:
14747                case OPC_SUBQH_PH:
14748                case OPC_SUBQH_R_PH:
14749                case OPC_SUBQH_W:
14750                case OPC_SUBQH_R_W:
14751                    gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14752                    break;
14753                case OPC_MUL_PH:
14754                case OPC_MUL_S_PH:
14755                case OPC_MULQ_S_W:
14756                case OPC_MULQ_RS_W:
14757                    gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14758                    break;
14759                default:
14760                    MIPS_INVAL("MASK ADDUH.QB");
14761                    generate_exception(ctx, EXCP_RI);
14762                    break;
14763                }
14764            } else if (ctx->insn_flags & INSN_LOONGSON2E) {
14765                gen_loongson_integer(ctx, op1, rd, rs, rt);
14766            } else {
14767                generate_exception(ctx, EXCP_RI);
14768            }
14769            break;
14770        case OPC_LX_DSP:
14771            op2 = MASK_LX(ctx->opcode);
14772            switch (op2) {
14773#if defined(TARGET_MIPS64)
14774            case OPC_LDX:
14775#endif
14776            case OPC_LBUX:
14777            case OPC_LHX:
14778            case OPC_LWX:
14779                gen_mipsdsp_ld(ctx, op2, rd, rs, rt);
14780                break;
14781            default:            /* Invalid */
14782                MIPS_INVAL("MASK LX");
14783                generate_exception(ctx, EXCP_RI);
14784                break;
14785            }
14786            break;
14787        case OPC_ABSQ_S_PH_DSP:
14788            op2 = MASK_ABSQ_S_PH(ctx->opcode);
14789            switch (op2) {
14790            case OPC_ABSQ_S_QB:
14791            case OPC_ABSQ_S_PH:
14792            case OPC_ABSQ_S_W:
14793            case OPC_PRECEQ_W_PHL:
14794            case OPC_PRECEQ_W_PHR:
14795            case OPC_PRECEQU_PH_QBL:
14796            case OPC_PRECEQU_PH_QBR:
14797            case OPC_PRECEQU_PH_QBLA:
14798            case OPC_PRECEQU_PH_QBRA:
14799            case OPC_PRECEU_PH_QBL:
14800            case OPC_PRECEU_PH_QBR:
14801            case OPC_PRECEU_PH_QBLA:
14802            case OPC_PRECEU_PH_QBRA:
14803                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14804                break;
14805            case OPC_BITREV:
14806            case OPC_REPL_QB:
14807            case OPC_REPLV_QB:
14808            case OPC_REPL_PH:
14809            case OPC_REPLV_PH:
14810                gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
14811                break;
14812            default:
14813                MIPS_INVAL("MASK ABSQ_S.PH");
14814                generate_exception(ctx, EXCP_RI);
14815                break;
14816            }
14817            break;
14818        case OPC_ADDU_QB_DSP:
14819            op2 = MASK_ADDU_QB(ctx->opcode);
14820            switch (op2) {
14821            case OPC_ADDQ_PH:
14822            case OPC_ADDQ_S_PH:
14823            case OPC_ADDQ_S_W:
14824            case OPC_ADDU_QB:
14825            case OPC_ADDU_S_QB:
14826            case OPC_ADDU_PH:
14827            case OPC_ADDU_S_PH:
14828            case OPC_SUBQ_PH:
14829            case OPC_SUBQ_S_PH:
14830            case OPC_SUBQ_S_W:
14831            case OPC_SUBU_QB:
14832            case OPC_SUBU_S_QB:
14833            case OPC_SUBU_PH:
14834            case OPC_SUBU_S_PH:
14835            case OPC_ADDSC:
14836            case OPC_ADDWC:
14837            case OPC_MODSUB:
14838            case OPC_RADDU_W_QB:
14839                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14840                break;
14841            case OPC_MULEU_S_PH_QBL:
14842            case OPC_MULEU_S_PH_QBR:
14843            case OPC_MULQ_RS_PH:
14844            case OPC_MULEQ_S_W_PHL:
14845            case OPC_MULEQ_S_W_PHR:
14846            case OPC_MULQ_S_PH:
14847                gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
14848                break;
14849            default:            /* Invalid */
14850                MIPS_INVAL("MASK ADDU.QB");
14851                generate_exception(ctx, EXCP_RI);
14852                break;
14853
14854            }
14855            break;
14856        case OPC_CMPU_EQ_QB_DSP:
14857            op2 = MASK_CMPU_EQ_QB(ctx->opcode);
14858            switch (op2) {
14859            case OPC_PRECR_SRA_PH_W:
14860            case OPC_PRECR_SRA_R_PH_W:
14861                gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
14862                break;
14863            case OPC_PRECR_QB_PH:
14864            case OPC_PRECRQ_QB_PH:
14865            case OPC_PRECRQ_PH_W:
14866            case OPC_PRECRQ_RS_PH_W:
14867            case OPC_PRECRQU_S_QB_PH:
14868                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
14869                break;
14870            case OPC_CMPU_EQ_QB:
14871            case OPC_CMPU_LT_QB:
14872            case OPC_CMPU_LE_QB:
14873            case OPC_CMP_EQ_PH:
14874            case OPC_CMP_LT_PH:
14875            case OPC_CMP_LE_PH:
14876                gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
14877                break;
14878            case OPC_CMPGU_EQ_QB:
14879            case OPC_CMPGU_LT_QB:
14880            case OPC_CMPGU_LE_QB:
14881            case OPC_CMPGDU_EQ_QB:
14882            case OPC_CMPGDU_LT_QB:
14883            case OPC_CMPGDU_LE_QB:
14884            case OPC_PICK_QB:
14885            case OPC_PICK_PH:
14886            case OPC_PACKRL_PH:
14887                gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
14888                break;
14889            default:            /* Invalid */
14890                MIPS_INVAL("MASK CMPU.EQ.QB");
14891                generate_exception(ctx, EXCP_RI);
14892                break;
14893            }
14894            break;
14895        case OPC_SHLL_QB_DSP:
14896            gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
14897            break;
14898        case OPC_DPA_W_PH_DSP:
14899            op2 = MASK_DPA_W_PH(ctx->opcode);
14900            switch (op2) {
14901            case OPC_DPAU_H_QBL:
14902            case OPC_DPAU_H_QBR:
14903            case OPC_DPSU_H_QBL:
14904            case OPC_DPSU_H_QBR:
14905            case OPC_DPA_W_PH:
14906            case OPC_DPAX_W_PH:
14907            case OPC_DPAQ_S_W_PH:
14908            case OPC_DPAQX_S_W_PH:
14909            case OPC_DPAQX_SA_W_PH:
14910            case OPC_DPS_W_PH:
14911            case OPC_DPSX_W_PH:
14912            case OPC_DPSQ_S_W_PH:
14913            case OPC_DPSQX_S_W_PH:
14914            case OPC_DPSQX_SA_W_PH:
14915            case OPC_MULSAQ_S_W_PH:
14916            case OPC_DPAQ_SA_L_W:
14917            case OPC_DPSQ_SA_L_W:
14918            case OPC_MAQ_S_W_PHL:
14919            case OPC_MAQ_S_W_PHR:
14920            case OPC_MAQ_SA_W_PHL:
14921            case OPC_MAQ_SA_W_PHR:
14922            case OPC_MULSA_W_PH:
14923                gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
14924                break;
14925            default:            /* Invalid */
14926                MIPS_INVAL("MASK DPAW.PH");
14927                generate_exception(ctx, EXCP_RI);
14928                break;
14929            }
14930            break;
14931        case OPC_INSV_DSP:
14932            op2 = MASK_INSV(ctx->opcode);
14933            switch (op2) {
14934            case OPC_INSV:
14935                check_dsp(ctx);
14936                {
14937                    TCGv t0, t1;
14938
14939                    if (rt == 0) {
14940                        MIPS_DEBUG("NOP");
14941                        break;
14942                    }
14943
14944                    t0 = tcg_temp_new();
14945                    t1 = tcg_temp_new();
14946
14947                    gen_load_gpr(t0, rt);
14948                    gen_load_gpr(t1, rs);
14949
14950                    gen_helper_insv(cpu_gpr[rt], cpu_env, t1, t0);
14951
14952                    tcg_temp_free(t0);
14953                    tcg_temp_free(t1);
14954                    break;
14955                }
14956            default:            /* Invalid */
14957                MIPS_INVAL("MASK INSV");
14958                generate_exception(ctx, EXCP_RI);
14959                break;
14960            }
14961            break;
14962        case OPC_APPEND_DSP:
14963            gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
14964            break;
14965        case OPC_EXTR_W_DSP:
14966            op2 = MASK_EXTR_W(ctx->opcode);
14967            switch (op2) {
14968            case OPC_EXTR_W:
14969            case OPC_EXTR_R_W:
14970            case OPC_EXTR_RS_W:
14971            case OPC_EXTR_S_H:
14972            case OPC_EXTRV_S_H:
14973            case OPC_EXTRV_W:
14974            case OPC_EXTRV_R_W:
14975            case OPC_EXTRV_RS_W:
14976            case OPC_EXTP:
14977            case OPC_EXTPV:
14978            case OPC_EXTPDP:
14979            case OPC_EXTPDPV:
14980                gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
14981                break;
14982            case OPC_RDDSP:
14983                gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 1);
14984                break;
14985            case OPC_SHILO:
14986            case OPC_SHILOV:
14987            case OPC_MTHLIP:
14988            case OPC_WRDSP:
14989                gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
14990                break;
14991            default:            /* Invalid */
14992                MIPS_INVAL("MASK EXTR.W");
14993                generate_exception(ctx, EXCP_RI);
14994                break;
14995            }
14996            break;
14997#if defined(TARGET_MIPS64)
14998        case OPC_DEXTM ... OPC_DEXT:
14999        case OPC_DINSM ... OPC_DINS:
15000            check_insn(ctx, ISA_MIPS64R2);
15001            check_mips_64(ctx);
15002            gen_bitops(ctx, op1, rt, rs, sa, rd);
15003            break;
15004        case OPC_DBSHFL:
15005            check_insn(ctx, ISA_MIPS64R2);
15006            check_mips_64(ctx);
15007            op2 = MASK_DBSHFL(ctx->opcode);
15008            gen_bshfl(ctx, op2, rt, rd);
15009            break;
15010        case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
15011        case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
15012        case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
15013            check_insn(ctx, INSN_LOONGSON2E);
15014            gen_loongson_integer(ctx, op1, rd, rs, rt);
15015            break;
15016        case OPC_ABSQ_S_QH_DSP:
15017            op2 = MASK_ABSQ_S_QH(ctx->opcode);
15018            switch (op2) {
15019            case OPC_PRECEQ_L_PWL:
15020            case OPC_PRECEQ_L_PWR:
15021            case OPC_PRECEQ_PW_QHL:
15022            case OPC_PRECEQ_PW_QHR:
15023            case OPC_PRECEQ_PW_QHLA:
15024            case OPC_PRECEQ_PW_QHRA:
15025            case OPC_PRECEQU_QH_OBL:
15026            case OPC_PRECEQU_QH_OBR:
15027            case OPC_PRECEQU_QH_OBLA:
15028            case OPC_PRECEQU_QH_OBRA:
15029            case OPC_PRECEU_QH_OBL:
15030            case OPC_PRECEU_QH_OBR:
15031            case OPC_PRECEU_QH_OBLA:
15032            case OPC_PRECEU_QH_OBRA:
15033            case OPC_ABSQ_S_OB:
15034            case OPC_ABSQ_S_PW:
15035            case OPC_ABSQ_S_QH:
15036                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15037                break;
15038            case OPC_REPL_OB:
15039            case OPC_REPL_PW:
15040            case OPC_REPL_QH:
15041            case OPC_REPLV_OB:
15042            case OPC_REPLV_PW:
15043            case OPC_REPLV_QH:
15044                gen_mipsdsp_bitinsn(ctx, op1, op2, rd, rt);
15045                break;
15046            default:            /* Invalid */
15047                MIPS_INVAL("MASK ABSQ_S.QH");
15048                generate_exception(ctx, EXCP_RI);
15049                break;
15050            }
15051            break;
15052        case OPC_ADDU_OB_DSP:
15053            op2 = MASK_ADDU_OB(ctx->opcode);
15054            switch (op2) {
15055            case OPC_RADDU_L_OB:
15056            case OPC_SUBQ_PW:
15057            case OPC_SUBQ_S_PW:
15058            case OPC_SUBQ_QH:
15059            case OPC_SUBQ_S_QH:
15060            case OPC_SUBU_OB:
15061            case OPC_SUBU_S_OB:
15062            case OPC_SUBU_QH:
15063            case OPC_SUBU_S_QH:
15064            case OPC_SUBUH_OB:
15065            case OPC_SUBUH_R_OB:
15066            case OPC_ADDQ_PW:
15067            case OPC_ADDQ_S_PW:
15068            case OPC_ADDQ_QH:
15069            case OPC_ADDQ_S_QH:
15070            case OPC_ADDU_OB:
15071            case OPC_ADDU_S_OB:
15072            case OPC_ADDU_QH:
15073            case OPC_ADDU_S_QH:
15074            case OPC_ADDUH_OB:
15075            case OPC_ADDUH_R_OB:
15076                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15077                break;
15078            case OPC_MULEQ_S_PW_QHL:
15079            case OPC_MULEQ_S_PW_QHR:
15080            case OPC_MULEU_S_QH_OBL:
15081            case OPC_MULEU_S_QH_OBR:
15082            case OPC_MULQ_RS_QH:
15083                gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 1);
15084                break;
15085            default:            /* Invalid */
15086                MIPS_INVAL("MASK ADDU.OB");
15087                generate_exception(ctx, EXCP_RI);
15088                break;
15089            }
15090            break;
15091        case OPC_CMPU_EQ_OB_DSP:
15092            op2 = MASK_CMPU_EQ_OB(ctx->opcode);
15093            switch (op2) {
15094            case OPC_PRECR_SRA_QH_PW:
15095            case OPC_PRECR_SRA_R_QH_PW:
15096                /* Return value is rt. */
15097                gen_mipsdsp_arith(ctx, op1, op2, rt, rs, rd);
15098                break;
15099            case OPC_PRECR_OB_QH:
15100            case OPC_PRECRQ_OB_QH:
15101            case OPC_PRECRQ_PW_L:
15102            case OPC_PRECRQ_QH_PW:
15103            case OPC_PRECRQ_RS_QH_PW:
15104            case OPC_PRECRQU_S_OB_QH:
15105                gen_mipsdsp_arith(ctx, op1, op2, rd, rs, rt);
15106                break;
15107            case OPC_CMPU_EQ_OB:
15108            case OPC_CMPU_LT_OB:
15109            case OPC_CMPU_LE_OB:
15110            case OPC_CMP_EQ_QH:
15111            case OPC_CMP_LT_QH:
15112            case OPC_CMP_LE_QH:
15113            case OPC_CMP_EQ_PW:
15114            case OPC_CMP_LT_PW:
15115            case OPC_CMP_LE_PW:
15116                gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 0);
15117                break;
15118            case OPC_CMPGDU_EQ_OB:
15119            case OPC_CMPGDU_LT_OB:
15120            case OPC_CMPGDU_LE_OB:
15121            case OPC_CMPGU_EQ_OB:
15122            case OPC_CMPGU_LT_OB:
15123            case OPC_CMPGU_LE_OB:
15124            case OPC_PACKRL_PW:
15125            case OPC_PICK_OB:
15126            case OPC_PICK_PW:
15127            case OPC_PICK_QH:
15128                gen_mipsdsp_add_cmp_pick(ctx, op1, op2, rd, rs, rt, 1);
15129                break;
15130            default:            /* Invalid */
15131                MIPS_INVAL("MASK CMPU_EQ.OB");
15132                generate_exception(ctx, EXCP_RI);
15133                break;
15134            }
15135            break;
15136        case OPC_DAPPEND_DSP:
15137            gen_mipsdsp_append(env, ctx, op1, rt, rs, rd);
15138            break;
15139        case OPC_DEXTR_W_DSP:
15140            op2 = MASK_DEXTR_W(ctx->opcode);
15141            switch (op2) {
15142            case OPC_DEXTP:
15143            case OPC_DEXTPDP:
15144            case OPC_DEXTPDPV:
15145            case OPC_DEXTPV:
15146            case OPC_DEXTR_L:
15147            case OPC_DEXTR_R_L:
15148            case OPC_DEXTR_RS_L:
15149            case OPC_DEXTR_W:
15150            case OPC_DEXTR_R_W:
15151            case OPC_DEXTR_RS_W:
15152            case OPC_DEXTR_S_H:
15153            case OPC_DEXTRV_L:
15154            case OPC_DEXTRV_R_L:
15155            case OPC_DEXTRV_RS_L:
15156            case OPC_DEXTRV_S_H:
15157            case OPC_DEXTRV_W:
15158            case OPC_DEXTRV_R_W:
15159            case OPC_DEXTRV_RS_W:
15160                gen_mipsdsp_accinsn(ctx, op1, op2, rt, rs, rd, 1);
15161                break;
15162            case OPC_DMTHLIP:
15163            case OPC_DSHILO:
15164            case OPC_DSHILOV:
15165                gen_mipsdsp_accinsn(ctx, op1, op2, rd, rs, rt, 0);
15166                break;
15167            default:            /* Invalid */
15168                MIPS_INVAL("MASK EXTR.W");
15169                generate_exception(ctx, EXCP_RI);
15170                break;
15171            }
15172            break;
15173        case OPC_DPAQ_W_QH_DSP:
15174            op2 = MASK_DPAQ_W_QH(ctx->opcode);
15175            switch (op2) {
15176            case OPC_DPAU_H_OBL:
15177            case OPC_DPAU_H_OBR:
15178            case OPC_DPSU_H_OBL:
15179            case OPC_DPSU_H_OBR:
15180            case OPC_DPA_W_QH:
15181            case OPC_DPAQ_S_W_QH:
15182            case OPC_DPS_W_QH:
15183            case OPC_DPSQ_S_W_QH:
15184            case OPC_MULSAQ_S_W_QH:
15185            case OPC_DPAQ_SA_L_PW:
15186            case OPC_DPSQ_SA_L_PW:
15187            case OPC_MULSAQ_S_L_PW:
15188                gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15189                break;
15190            case OPC_MAQ_S_W_QHLL:
15191            case OPC_MAQ_S_W_QHLR:
15192            case OPC_MAQ_S_W_QHRL:
15193            case OPC_MAQ_S_W_QHRR:
15194            case OPC_MAQ_SA_W_QHLL:
15195            case OPC_MAQ_SA_W_QHLR:
15196            case OPC_MAQ_SA_W_QHRL:
15197            case OPC_MAQ_SA_W_QHRR:
15198            case OPC_MAQ_S_L_PWL:
15199            case OPC_MAQ_S_L_PWR:
15200            case OPC_DMADD:
15201            case OPC_DMADDU:
15202            case OPC_DMSUB:
15203            case OPC_DMSUBU:
15204                gen_mipsdsp_multiply(ctx, op1, op2, rd, rs, rt, 0);
15205                break;
15206            default:            /* Invalid */
15207                MIPS_INVAL("MASK DPAQ.W.QH");
15208                generate_exception(ctx, EXCP_RI);
15209                break;
15210            }
15211            break;
15212        case OPC_DINSV_DSP:
15213            op2 = MASK_INSV(ctx->opcode);
15214            switch (op2) {
15215            case OPC_DINSV:
15216                {
15217                    TCGv t0, t1;
15218
15219                    if (rt == 0) {
15220                        MIPS_DEBUG("NOP");
15221                        break;
15222                    }
15223                    check_dsp(ctx);
15224
15225                    t0 = tcg_temp_new();
15226                    t1 = tcg_temp_new();
15227
15228                    gen_load_gpr(t0, rt);
15229                    gen_load_gpr(t1, rs);
15230
15231                    gen_helper_dinsv(cpu_gpr[rt], cpu_env, t1, t0);
15232                    break;
15233                }
15234            default:            /* Invalid */
15235                MIPS_INVAL("MASK DINSV");
15236                generate_exception(ctx, EXCP_RI);
15237                break;
15238            }
15239            break;
15240        case OPC_SHLL_OB_DSP:
15241            gen_mipsdsp_shift(ctx, op1, rd, rs, rt);
15242            break;
15243#endif
15244        default:            /* Invalid */
15245            MIPS_INVAL("special3");
15246            generate_exception(ctx, EXCP_RI);
15247            break;
15248        }
15249        break;
15250    case OPC_REGIMM:
15251        op1 = MASK_REGIMM(ctx->opcode);
15252        switch (op1) {
15253        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
15254        case OPC_BLTZAL ... OPC_BGEZALL:
15255            gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
15256            break;
15257        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
15258        case OPC_TNEI:
15259            gen_trap(ctx, op1, rs, -1, imm);
15260            break;
15261        case OPC_SYNCI:
15262            check_insn(ctx, ISA_MIPS32R2);
15263            /* Treat as NOP. */
15264            break;
15265        case OPC_BPOSGE32:    /* MIPS DSP branch */
15266#if defined(TARGET_MIPS64)
15267        case OPC_BPOSGE64:
15268#endif
15269            check_dsp(ctx);
15270            gen_compute_branch(ctx, op1, 4, -1, -2, (int32_t)imm << 2);
15271            break;
15272        default:            /* Invalid */
15273            MIPS_INVAL("regimm");
15274            generate_exception(ctx, EXCP_RI);
15275            break;
15276        }
15277        break;
15278    case OPC_CP0:
15279        check_cp0_enabled(ctx);
15280        op1 = MASK_CP0(ctx->opcode);
15281        switch (op1) {
15282        case OPC_MFC0:
15283        case OPC_MTC0:
15284        case OPC_MFTR:
15285        case OPC_MTTR:
15286#if defined(TARGET_MIPS64)
15287        case OPC_DMFC0:
15288        case OPC_DMTC0:
15289#endif
15290#ifndef CONFIG_USER_ONLY
15291            gen_cp0(env, ctx, op1, rt, rd);
15292#endif /* !CONFIG_USER_ONLY */
15293            break;
15294        case OPC_C0_FIRST ... OPC_C0_LAST:
15295#ifndef CONFIG_USER_ONLY
15296            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
15297#endif /* !CONFIG_USER_ONLY */
15298            break;
15299        case OPC_MFMC0:
15300#ifndef CONFIG_USER_ONLY
15301            {
15302                TCGv t0 = tcg_temp_new();
15303
15304                op2 = MASK_MFMC0(ctx->opcode);
15305                switch (op2) {
15306                case OPC_DMT:
15307                    check_insn(ctx, ASE_MT);
15308                    gen_helper_dmt(t0);
15309                    gen_store_gpr(t0, rt);
15310                    break;
15311                case OPC_EMT:
15312                    check_insn(ctx, ASE_MT);
15313                    gen_helper_emt(t0);
15314                    gen_store_gpr(t0, rt);
15315                    break;
15316                case OPC_DVPE:
15317                    check_insn(ctx, ASE_MT);
15318                    gen_helper_dvpe(t0, cpu_env);
15319                    gen_store_gpr(t0, rt);
15320                    break;
15321                case OPC_EVPE:
15322                    check_insn(ctx, ASE_MT);
15323                    gen_helper_evpe(t0, cpu_env);
15324                    gen_store_gpr(t0, rt);
15325                    break;
15326                case OPC_DI:
15327                    check_insn(ctx, ISA_MIPS32R2);
15328                    save_cpu_state(ctx, 1);
15329                    gen_helper_di(t0, cpu_env);
15330                    gen_store_gpr(t0, rt);
15331                    /* Stop translation as we may have switched the execution mode */
15332                    ctx->bstate = BS_STOP;
15333                    break;
15334                case OPC_EI:
15335                    check_insn(ctx, ISA_MIPS32R2);
15336                    save_cpu_state(ctx, 1);
15337                    gen_helper_ei(t0, cpu_env);
15338                    gen_store_gpr(t0, rt);
15339                    /* Stop translation as we may have switched the execution mode */
15340                    ctx->bstate = BS_STOP;
15341                    break;
15342                default:            /* Invalid */
15343                    MIPS_INVAL("mfmc0");
15344                    generate_exception(ctx, EXCP_RI);
15345                    break;
15346                }
15347                tcg_temp_free(t0);
15348            }
15349#endif /* !CONFIG_USER_ONLY */
15350            break;
15351        case OPC_RDPGPR:
15352            check_insn(ctx, ISA_MIPS32R2);
15353            gen_load_srsgpr(rt, rd);
15354            break;
15355        case OPC_WRPGPR:
15356            check_insn(ctx, ISA_MIPS32R2);
15357            gen_store_srsgpr(rt, rd);
15358            break;
15359        default:
15360            MIPS_INVAL("cp0");
15361            generate_exception(ctx, EXCP_RI);
15362            break;
15363        }
15364        break;
15365    case OPC_ADDI: /* Arithmetic with immediate opcode */
15366    case OPC_ADDIU:
15367         gen_arith_imm(ctx, op, rt, rs, imm);
15368         break;
15369    case OPC_SLTI: /* Set on less than with immediate opcode */
15370    case OPC_SLTIU:
15371         gen_slt_imm(ctx, op, rt, rs, imm);
15372         break;
15373    case OPC_ANDI: /* Arithmetic with immediate opcode */
15374    case OPC_LUI:
15375    case OPC_ORI:
15376    case OPC_XORI:
15377         gen_logic_imm(ctx, op, rt, rs, imm);
15378         break;
15379    case OPC_J ... OPC_JAL: /* Jump */
15380         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15381         gen_compute_branch(ctx, op, 4, rs, rt, offset);
15382         break;
15383    case OPC_BEQ ... OPC_BGTZ: /* Branch */
15384    case OPC_BEQL ... OPC_BGTZL:
15385         gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
15386         break;
15387    case OPC_LB ... OPC_LWR: /* Load and stores */
15388    case OPC_LL:
15389         gen_ld(ctx, op, rt, rs, imm);
15390         break;
15391    case OPC_SB ... OPC_SW:
15392    case OPC_SWR:
15393         gen_st(ctx, op, rt, rs, imm);
15394         break;
15395    case OPC_SC:
15396         gen_st_cond(ctx, op, rt, rs, imm);
15397         break;
15398    case OPC_CACHE:
15399        check_cp0_enabled(ctx);
15400        check_insn(ctx, ISA_MIPS3 | ISA_MIPS32);
15401        /* Treat as NOP. */
15402        break;
15403    case OPC_PREF:
15404        check_insn(ctx, ISA_MIPS4 | ISA_MIPS32);
15405        /* Treat as NOP. */
15406        break;
15407
15408    /* Floating point (COP1). */
15409    case OPC_LWC1:
15410    case OPC_LDC1:
15411    case OPC_SWC1:
15412    case OPC_SDC1:
15413        gen_cop1_ldst(env, ctx, op, rt, rs, imm);
15414        break;
15415
15416    case OPC_CP1:
15417        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15418            check_cp1_enabled(ctx);
15419            op1 = MASK_CP1(ctx->opcode);
15420            switch (op1) {
15421            case OPC_MFHC1:
15422            case OPC_MTHC1:
15423                check_insn(ctx, ISA_MIPS32R2);
15424            case OPC_MFC1:
15425            case OPC_CFC1:
15426            case OPC_MTC1:
15427            case OPC_CTC1:
15428                gen_cp1(ctx, op1, rt, rd);
15429                break;
15430#if defined(TARGET_MIPS64)
15431            case OPC_DMFC1:
15432            case OPC_DMTC1:
15433                check_insn(ctx, ISA_MIPS3);
15434                gen_cp1(ctx, op1, rt, rd);
15435                break;
15436#endif
15437            case OPC_BC1ANY2:
15438            case OPC_BC1ANY4:
15439                check_cop1x(ctx);
15440                check_insn(ctx, ASE_MIPS3D);
15441                /* fall through */
15442            case OPC_BC1:
15443                gen_compute_branch1(ctx, MASK_BC1(ctx->opcode),
15444                                    (rt >> 2) & 0x7, imm << 2);
15445                break;
15446            case OPC_S_FMT:
15447            case OPC_D_FMT:
15448            case OPC_W_FMT:
15449            case OPC_L_FMT:
15450            case OPC_PS_FMT:
15451                gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
15452                           (imm >> 8) & 0x7);
15453                break;
15454            default:
15455                MIPS_INVAL("cp1");
15456                generate_exception (ctx, EXCP_RI);
15457                break;
15458            }
15459        } else {
15460            generate_exception_err(ctx, EXCP_CpU, 1);
15461        }
15462        break;
15463
15464    /* COP2.  */
15465    case OPC_LWC2:
15466    case OPC_LDC2:
15467    case OPC_SWC2:
15468    case OPC_SDC2:
15469        /* COP2: Not implemented. */
15470        generate_exception_err(ctx, EXCP_CpU, 2);
15471        break;
15472    case OPC_CP2:
15473        check_insn(ctx, INSN_LOONGSON2F);
15474        /* Note that these instructions use different fields.  */
15475        gen_loongson_multimedia(ctx, sa, rd, rt);
15476        break;
15477
15478    case OPC_CP3:
15479        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15480            check_cp1_enabled(ctx);
15481            op1 = MASK_CP3(ctx->opcode);
15482            switch (op1) {
15483            case OPC_LWXC1:
15484            case OPC_LDXC1:
15485            case OPC_LUXC1:
15486            case OPC_SWXC1:
15487            case OPC_SDXC1:
15488            case OPC_SUXC1:
15489                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
15490                break;
15491            case OPC_PREFX:
15492                /* Treat as NOP. */
15493                break;
15494            case OPC_ALNV_PS:
15495            case OPC_MADD_S:
15496            case OPC_MADD_D:
15497            case OPC_MADD_PS:
15498            case OPC_MSUB_S:
15499            case OPC_MSUB_D:
15500            case OPC_MSUB_PS:
15501            case OPC_NMADD_S:
15502            case OPC_NMADD_D:
15503            case OPC_NMADD_PS:
15504            case OPC_NMSUB_S:
15505            case OPC_NMSUB_D:
15506            case OPC_NMSUB_PS:
15507                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
15508                break;
15509            default:
15510                MIPS_INVAL("cp3");
15511                generate_exception (ctx, EXCP_RI);
15512                break;
15513            }
15514        } else {
15515            generate_exception_err(ctx, EXCP_CpU, 1);
15516        }
15517        break;
15518
15519#if defined(TARGET_MIPS64)
15520    /* MIPS64 opcodes */
15521    case OPC_LWU:
15522    case OPC_LDL ... OPC_LDR:
15523    case OPC_LLD:
15524    case OPC_LD:
15525        check_insn(ctx, ISA_MIPS3);
15526        check_mips_64(ctx);
15527        gen_ld(ctx, op, rt, rs, imm);
15528        break;
15529    case OPC_SDL ... OPC_SDR:
15530    case OPC_SD:
15531        check_insn(ctx, ISA_MIPS3);
15532        check_mips_64(ctx);
15533        gen_st(ctx, op, rt, rs, imm);
15534        break;
15535    case OPC_SCD:
15536        check_insn(ctx, ISA_MIPS3);
15537        check_mips_64(ctx);
15538        gen_st_cond(ctx, op, rt, rs, imm);
15539        break;
15540    case OPC_DADDI:
15541    case OPC_DADDIU:
15542        check_insn(ctx, ISA_MIPS3);
15543        check_mips_64(ctx);
15544        gen_arith_imm(ctx, op, rt, rs, imm);
15545        break;
15546#endif
15547    case OPC_JALX:
15548        check_insn(ctx, ASE_MIPS16 | ASE_MICROMIPS);
15549        offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
15550        gen_compute_branch(ctx, op, 4, rs, rt, offset);
15551        break;
15552    case OPC_MDMX:
15553        check_insn(ctx, ASE_MDMX);
15554        /* MDMX: Not implemented. */
15555    default:            /* Invalid */
15556        MIPS_INVAL("major opcode");
15557        generate_exception(ctx, EXCP_RI);
15558        break;
15559    }
15560}
15561
15562static inline void
15563gen_intermediate_code_internal(MIPSCPU *cpu, TranslationBlock *tb,
15564                               bool search_pc)
15565{
15566    CPUState *cs = CPU(cpu);
15567    CPUMIPSState *env = &cpu->env;
15568    DisasContext ctx;
15569    target_ulong pc_start;
15570    uint16_t *gen_opc_end;
15571    CPUBreakpoint *bp;
15572    int j, lj = -1;
15573    int num_insns;
15574    int max_insns;
15575    int insn_bytes;
15576    int is_delay;
15577
15578    if (search_pc)
15579        qemu_log("search pc %d\n", search_pc);
15580
15581    pc_start = tb->pc;
15582    gen_opc_end = tcg_ctx.gen_opc_buf + OPC_MAX_SIZE;
15583    ctx.pc = pc_start;
15584    ctx.saved_pc = -1;
15585    ctx.singlestep_enabled = cs->singlestep_enabled;
15586    ctx.insn_flags = env->insn_flags;
15587    ctx.tb = tb;
15588    ctx.bstate = BS_NONE;
15589    /* Restore delay slot state from the tb context.  */
15590    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
15591    restore_cpu_state(env, &ctx);
15592#ifdef CONFIG_USER_ONLY
15593        ctx.mem_idx = MIPS_HFLAG_UM;
15594#else
15595        ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
15596#endif
15597    num_insns = 0;
15598    max_insns = tb->cflags & CF_COUNT_MASK;
15599    if (max_insns == 0)
15600        max_insns = CF_COUNT_MASK;
15601    LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
15602    gen_tb_start();
15603    while (ctx.bstate == BS_NONE) {
15604        if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
15605            QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
15606                if (bp->pc == ctx.pc) {
15607                    save_cpu_state(&ctx, 1);
15608                    ctx.bstate = BS_BRANCH;
15609                    gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15610                    /* Include the breakpoint location or the tb won't
15611                     * be flushed when it must be.  */
15612                    ctx.pc += 4;
15613                    goto done_generating;
15614                }
15615            }
15616        }
15617
15618        if (search_pc) {
15619            j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
15620            if (lj < j) {
15621                lj++;
15622                while (lj < j)
15623                    tcg_ctx.gen_opc_instr_start[lj++] = 0;
15624            }
15625            tcg_ctx.gen_opc_pc[lj] = ctx.pc;
15626            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
15627            gen_opc_btarget[lj] = ctx.btarget;
15628            tcg_ctx.gen_opc_instr_start[lj] = 1;
15629            tcg_ctx.gen_opc_icount[lj] = num_insns;
15630        }
15631        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
15632            gen_io_start();
15633
15634        is_delay = ctx.hflags & MIPS_HFLAG_BMASK;
15635        if (!(ctx.hflags & MIPS_HFLAG_M16)) {
15636            ctx.opcode = cpu_ldl_code(env, ctx.pc);
15637            insn_bytes = 4;
15638            decode_opc(env, &ctx);
15639        } else if (ctx.insn_flags & ASE_MICROMIPS) {
15640            ctx.opcode = cpu_lduw_code(env, ctx.pc);
15641            insn_bytes = decode_micromips_opc(env, &ctx);
15642        } else if (ctx.insn_flags & ASE_MIPS16) {
15643            ctx.opcode = cpu_lduw_code(env, ctx.pc);
15644            insn_bytes = decode_mips16_opc(env, &ctx);
15645        } else {
15646            generate_exception(&ctx, EXCP_RI);
15647            ctx.bstate = BS_STOP;
15648            break;
15649        }
15650        if (is_delay) {
15651            handle_delay_slot(&ctx, insn_bytes);
15652        }
15653        ctx.pc += insn_bytes;
15654
15655        num_insns++;
15656
15657        /* Execute a branch and its delay slot as a single instruction.
15658           This is what GDB expects and is consistent with what the
15659           hardware does (e.g. if a delay slot instruction faults, the
15660           reported PC is the PC of the branch).  */
15661        if (cs->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0) {
15662            break;
15663        }
15664
15665        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
15666            break;
15667
15668        if (tcg_ctx.gen_opc_ptr >= gen_opc_end) {
15669            break;
15670        }
15671
15672        if (num_insns >= max_insns)
15673            break;
15674
15675        if (singlestep)
15676            break;
15677    }
15678    if (tb->cflags & CF_LAST_IO) {
15679        gen_io_end();
15680    }
15681    if (cs->singlestep_enabled && ctx.bstate != BS_BRANCH) {
15682        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
15683        gen_helper_0e0i(raise_exception, EXCP_DEBUG);
15684    } else {
15685        switch (ctx.bstate) {
15686        case BS_STOP:
15687            gen_goto_tb(&ctx, 0, ctx.pc);
15688            break;
15689        case BS_NONE:
15690            save_cpu_state(&ctx, 0);
15691            gen_goto_tb(&ctx, 0, ctx.pc);
15692            break;
15693        case BS_EXCP:
15694            tcg_gen_exit_tb(0);
15695            break;
15696        case BS_BRANCH:
15697        default:
15698            break;
15699        }
15700    }
15701done_generating:
15702    gen_tb_end(tb, num_insns);
15703    *tcg_ctx.gen_opc_ptr = INDEX_op_end;
15704    if (search_pc) {
15705        j = tcg_ctx.gen_opc_ptr - tcg_ctx.gen_opc_buf;
15706        lj++;
15707        while (lj <= j)
15708            tcg_ctx.gen_opc_instr_start[lj++] = 0;
15709    } else {
15710        tb->size = ctx.pc - pc_start;
15711        tb->icount = num_insns;
15712    }
15713#ifdef DEBUG_DISAS
15714    LOG_DISAS("\n");
15715    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
15716        qemu_log("IN: %s\n", lookup_symbol(pc_start));
15717        log_target_disas(env, pc_start, ctx.pc - pc_start, 0);
15718        qemu_log("\n");
15719    }
15720#endif
15721}
15722
15723void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
15724{
15725    gen_intermediate_code_internal(mips_env_get_cpu(env), tb, false);
15726}
15727
15728void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
15729{
15730    gen_intermediate_code_internal(mips_env_get_cpu(env), tb, true);
15731}
15732
15733static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
15734                           int flags)
15735{
15736    int i;
15737    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
15738
15739#define printfpr(fp)                                                    \
15740    do {                                                                \
15741        if (is_fpu64)                                                   \
15742            fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
15743                        " fd:%13g fs:%13g psu: %13g\n",                 \
15744                        (fp)->w[FP_ENDIAN_IDX], (fp)->d,                \
15745                        (double)(fp)->fd,                               \
15746                        (double)(fp)->fs[FP_ENDIAN_IDX],                \
15747                        (double)(fp)->fs[!FP_ENDIAN_IDX]);              \
15748        else {                                                          \
15749            fpr_t tmp;                                                  \
15750            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
15751            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
15752            fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
15753                        " fd:%13g fs:%13g psu:%13g\n",                  \
15754                        tmp.w[FP_ENDIAN_IDX], tmp.d,                    \
15755                        (double)tmp.fd,                                 \
15756                        (double)tmp.fs[FP_ENDIAN_IDX],                  \
15757                        (double)tmp.fs[!FP_ENDIAN_IDX]);                \
15758        }                                                               \
15759    } while(0)
15760
15761
15762    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%02x\n",
15763                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
15764                get_float_exception_flags(&env->active_fpu.fp_status));
15765    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
15766        fpu_fprintf(f, "%3s: ", fregnames[i]);
15767        printfpr(&env->active_fpu.fpr[i]);
15768    }
15769
15770#undef printfpr
15771}
15772
15773#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15774/* Debug help: The architecture requires 32bit code to maintain proper
15775   sign-extended values on 64bit machines.  */
15776
15777#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
15778
15779static void
15780cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
15781                                fprintf_function cpu_fprintf,
15782                                int flags)
15783{
15784    int i;
15785
15786    if (!SIGN_EXT_P(env->active_tc.PC))
15787        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
15788    if (!SIGN_EXT_P(env->active_tc.HI[0]))
15789        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
15790    if (!SIGN_EXT_P(env->active_tc.LO[0]))
15791        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
15792    if (!SIGN_EXT_P(env->btarget))
15793        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
15794
15795    for (i = 0; i < 32; i++) {
15796        if (!SIGN_EXT_P(env->active_tc.gpr[i]))
15797            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
15798    }
15799
15800    if (!SIGN_EXT_P(env->CP0_EPC))
15801        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
15802    if (!SIGN_EXT_P(env->lladdr))
15803        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
15804}
15805#endif
15806
15807void mips_cpu_dump_state(CPUState *cs, FILE *f, fprintf_function cpu_fprintf,
15808                         int flags)
15809{
15810    MIPSCPU *cpu = MIPS_CPU(cs);
15811    CPUMIPSState *env = &cpu->env;
15812    int i;
15813
15814    cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
15815                " LO=0x" TARGET_FMT_lx " ds %04x "
15816                TARGET_FMT_lx " " TARGET_FMT_ld "\n",
15817                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
15818                env->hflags, env->btarget, env->bcond);
15819    for (i = 0; i < 32; i++) {
15820        if ((i & 3) == 0)
15821            cpu_fprintf(f, "GPR%02d:", i);
15822        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
15823        if ((i & 3) == 3)
15824            cpu_fprintf(f, "\n");
15825    }
15826
15827    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
15828                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
15829    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
15830                env->CP0_Config0, env->CP0_Config1, env->lladdr);
15831    if (env->hflags & MIPS_HFLAG_FPU)
15832        fpu_dump_state(env, f, cpu_fprintf, flags);
15833#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
15834    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
15835#endif
15836}
15837
15838void mips_tcg_init(void)
15839{
15840    int i;
15841    static int inited;
15842
15843    /* Initialize various static tables. */
15844    if (inited)
15845        return;
15846
15847    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
15848    TCGV_UNUSED(cpu_gpr[0]);
15849    for (i = 1; i < 32; i++)
15850        cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
15851                                        offsetof(CPUMIPSState, active_tc.gpr[i]),
15852                                        regnames[i]);
15853
15854    for (i = 0; i < 32; i++) {
15855        int off = offsetof(CPUMIPSState, active_fpu.fpr[i]);
15856        fpu_f64[i] = tcg_global_mem_new_i64(TCG_AREG0, off, fregnames[i]);
15857    }
15858
15859    cpu_PC = tcg_global_mem_new(TCG_AREG0,
15860                                offsetof(CPUMIPSState, active_tc.PC), "PC");
15861    for (i = 0; i < MIPS_DSP_ACC; i++) {
15862        cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
15863                                       offsetof(CPUMIPSState, active_tc.HI[i]),
15864                                       regnames_HI[i]);
15865        cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
15866                                       offsetof(CPUMIPSState, active_tc.LO[i]),
15867                                       regnames_LO[i]);
15868        cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
15869                                        offsetof(CPUMIPSState, active_tc.ACX[i]),
15870                                        regnames_ACX[i]);
15871    }
15872    cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
15873                                     offsetof(CPUMIPSState, active_tc.DSPControl),
15874                                     "DSPControl");
15875    bcond = tcg_global_mem_new(TCG_AREG0,
15876                               offsetof(CPUMIPSState, bcond), "bcond");
15877    btarget = tcg_global_mem_new(TCG_AREG0,
15878                                 offsetof(CPUMIPSState, btarget), "btarget");
15879    hflags = tcg_global_mem_new_i32(TCG_AREG0,
15880                                    offsetof(CPUMIPSState, hflags), "hflags");
15881
15882    fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
15883                                      offsetof(CPUMIPSState, active_fpu.fcr0),
15884                                      "fcr0");
15885    fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
15886                                       offsetof(CPUMIPSState, active_fpu.fcr31),
15887                                       "fcr31");
15888
15889    /* register helpers */
15890#define GEN_HELPER 2
15891#include "helper.h"
15892
15893    inited = 1;
15894}
15895
15896#include "translate_init.c"
15897
15898MIPSCPU *cpu_mips_init(const char *cpu_model)
15899{
15900    MIPSCPU *cpu;
15901    CPUMIPSState *env;
15902    const mips_def_t *def;
15903
15904    def = cpu_mips_find_by_name(cpu_model);
15905    if (!def)
15906        return NULL;
15907    cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
15908    env = &cpu->env;
15909    env->cpu_model = def;
15910    env->cpu_model_str = cpu_model;
15911
15912#ifndef CONFIG_USER_ONLY
15913    mmu_init(env, def);
15914#endif
15915    fpu_init(env, def);
15916    mvp_init(env, def);
15917
15918    object_property_set_bool(OBJECT(cpu), true, "realized", NULL);
15919
15920    return cpu;
15921}
15922
15923void cpu_state_reset(CPUMIPSState *env)
15924{
15925#ifndef CONFIG_USER_ONLY
15926    MIPSCPU *cpu = mips_env_get_cpu(env);
15927    CPUState *cs = CPU(cpu);
15928#endif
15929
15930    /* Reset registers to their default values */
15931    env->CP0_PRid = env->cpu_model->CP0_PRid;
15932    env->CP0_Config0 = env->cpu_model->CP0_Config0;
15933#ifdef TARGET_WORDS_BIGENDIAN
15934    env->CP0_Config0 |= (1 << CP0C0_BE);
15935#endif
15936    env->CP0_Config1 = env->cpu_model->CP0_Config1;
15937    env->CP0_Config2 = env->cpu_model->CP0_Config2;
15938    env->CP0_Config3 = env->cpu_model->CP0_Config3;
15939    env->CP0_Config6 = env->cpu_model->CP0_Config6;
15940    env->CP0_Config7 = env->cpu_model->CP0_Config7;
15941    env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
15942                                 << env->cpu_model->CP0_LLAddr_shift;
15943    env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
15944    env->SYNCI_Step = env->cpu_model->SYNCI_Step;
15945    env->CCRes = env->cpu_model->CCRes;
15946    env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
15947    env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
15948    env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
15949    env->current_tc = 0;
15950    env->SEGBITS = env->cpu_model->SEGBITS;
15951    env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
15952#if defined(TARGET_MIPS64)
15953    if (env->cpu_model->insn_flags & ISA_MIPS3) {
15954        env->SEGMask |= 3ULL << 62;
15955    }
15956#endif
15957    env->PABITS = env->cpu_model->PABITS;
15958    env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
15959    env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
15960    env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
15961    env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
15962    env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
15963    env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
15964    env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
15965    env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
15966    env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
15967    env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
15968    env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
15969    env->active_fpu.fcr0 = env->cpu_model->CP1_fcr0;
15970    env->insn_flags = env->cpu_model->insn_flags;
15971
15972#if defined(CONFIG_USER_ONLY)
15973    env->CP0_Status = (MIPS_HFLAG_UM << CP0St_KSU);
15974# ifdef TARGET_MIPS64
15975    /* Enable 64-bit register mode.  */
15976    env->CP0_Status |= (1 << CP0St_PX);
15977# endif
15978# ifdef TARGET_ABI_MIPSN64
15979    /* Enable 64-bit address mode.  */
15980    env->CP0_Status |= (1 << CP0St_UX);
15981# endif
15982    /* Enable access to the CPUNum, SYNCI_Step, CC, and CCRes RDHWR
15983       hardware registers.  */
15984    env->CP0_HWREna |= 0x0000000F;
15985    if (env->CP0_Config1 & (1 << CP0C1_FP)) {
15986        env->CP0_Status |= (1 << CP0St_CU1);
15987    }
15988    if (env->CP0_Config3 & (1 << CP0C3_DSPP)) {
15989        env->CP0_Status |= (1 << CP0St_MX);
15990    }
15991    /* Enable 64-bit FPU if the target cpu supports it.  */
15992    if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
15993        env->CP0_Status |= (1 << CP0St_FR);
15994    }
15995#else
15996    if (env->hflags & MIPS_HFLAG_BMASK) {
15997        /* If the exception was raised from a delay slot,
15998           come back to the jump.  */
15999        env->CP0_ErrorEPC = env->active_tc.PC - 4;
16000    } else {
16001        env->CP0_ErrorEPC = env->active_tc.PC;
16002    }
16003    env->active_tc.PC = (int32_t)0xBFC00000;
16004    env->CP0_Random = env->tlb->nb_tlb - 1;
16005    env->tlb->tlb_in_use = env->tlb->nb_tlb;
16006    env->CP0_Wired = 0;
16007    env->CP0_EBase = 0x80000000 | (cs->cpu_index & 0x3FF);
16008    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
16009    /* vectored interrupts not implemented, timer on int 7,
16010       no performance counters. */
16011    env->CP0_IntCtl = 0xe0000000;
16012    {
16013        int i;
16014
16015        for (i = 0; i < 7; i++) {
16016            env->CP0_WatchLo[i] = 0;
16017            env->CP0_WatchHi[i] = 0x80000000;
16018        }
16019        env->CP0_WatchLo[7] = 0;
16020        env->CP0_WatchHi[7] = 0;
16021    }
16022    /* Count register increments in debug mode, EJTAG version 1 */
16023    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
16024
16025    if (env->CP0_Config3 & (1 << CP0C3_MT)) {
16026        int i;
16027
16028        /* Only TC0 on VPE 0 starts as active.  */
16029        for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
16030            env->tcs[i].CP0_TCBind = cs->cpu_index << CP0TCBd_CurVPE;
16031            env->tcs[i].CP0_TCHalt = 1;
16032        }
16033        env->active_tc.CP0_TCHalt = 1;
16034        cs->halted = 1;
16035
16036        if (cs->cpu_index == 0) {
16037            /* VPE0 starts up enabled.  */
16038            env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
16039            env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
16040
16041            /* TC0 starts up unhalted.  */
16042            cs->halted = 0;
16043            env->active_tc.CP0_TCHalt = 0;
16044            env->tcs[0].CP0_TCHalt = 0;
16045            /* With thread 0 active.  */
16046            env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
16047            env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
16048        }
16049    }
16050#endif
16051    compute_hflags(env);
16052    env->exception_index = EXCP_NONE;
16053}
16054
16055void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
16056{
16057    env->active_tc.PC = tcg_ctx.gen_opc_pc[pc_pos];
16058    env->hflags &= ~MIPS_HFLAG_BMASK;
16059    env->hflags |= gen_opc_hflags[pc_pos];
16060    switch (env->hflags & MIPS_HFLAG_BMASK_BASE) {
16061    case MIPS_HFLAG_BR:
16062        break;
16063    case MIPS_HFLAG_BC:
16064    case MIPS_HFLAG_BL:
16065    case MIPS_HFLAG_B:
16066        env->btarget = gen_opc_btarget[pc_pos];
16067        break;
16068    }
16069}
16070