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 *
   8 * This library is free software; you can redistribute it and/or
   9 * modify it under the terms of the GNU Lesser General Public
  10 * License as published by the Free Software Foundation; either
  11 * version 2 of the License, or (at your option) any later version.
  12 *
  13 * This library is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16 * Lesser General Public License for more details.
  17 *
  18 * You should have received a copy of the GNU Lesser General Public
  19 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
  20 */
  21
  22#include <stdarg.h>
  23#include <stdlib.h>
  24#include <stdio.h>
  25#include <string.h>
  26#include <inttypes.h>
  27
  28#include "cpu.h"
  29#include "exec-all.h"
  30#include "disas.h"
  31#include "tcg-op.h"
  32#include "qemu-common.h"
  33
  34#include "helper.h"
  35#define GEN_HELPER 1
  36#include "helper.h"
  37
  38//#define MIPS_DEBUG_DISAS
  39//#define MIPS_DEBUG_SIGN_EXTENSIONS
  40
  41/* MIPS major opcodes */
  42#define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
  43
  44enum {
  45    /* indirect opcode tables */
  46    OPC_SPECIAL  = (0x00 << 26),
  47    OPC_REGIMM   = (0x01 << 26),
  48    OPC_CP0      = (0x10 << 26),
  49    OPC_CP1      = (0x11 << 26),
  50    OPC_CP2      = (0x12 << 26),
  51    OPC_CP3      = (0x13 << 26),
  52    OPC_SPECIAL2 = (0x1C << 26),
  53    OPC_SPECIAL3 = (0x1F << 26),
  54    /* arithmetic with immediate */
  55    OPC_ADDI     = (0x08 << 26),
  56    OPC_ADDIU    = (0x09 << 26),
  57    OPC_SLTI     = (0x0A << 26),
  58    OPC_SLTIU    = (0x0B << 26),
  59    /* logic with immediate */
  60    OPC_ANDI     = (0x0C << 26),
  61    OPC_ORI      = (0x0D << 26),
  62    OPC_XORI     = (0x0E << 26),
  63    OPC_LUI      = (0x0F << 26),
  64    /* arithmetic with immediate */
  65    OPC_DADDI    = (0x18 << 26),
  66    OPC_DADDIU   = (0x19 << 26),
  67    /* Jump and branches */
  68    OPC_J        = (0x02 << 26),
  69    OPC_JAL      = (0x03 << 26),
  70    OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
  71    OPC_BEQL     = (0x14 << 26),
  72    OPC_BNE      = (0x05 << 26),
  73    OPC_BNEL     = (0x15 << 26),
  74    OPC_BLEZ     = (0x06 << 26),
  75    OPC_BLEZL    = (0x16 << 26),
  76    OPC_BGTZ     = (0x07 << 26),
  77    OPC_BGTZL    = (0x17 << 26),
  78    OPC_JALX     = (0x1D << 26),  /* MIPS 16 only */
  79    /* Load and stores */
  80    OPC_LDL      = (0x1A << 26),
  81    OPC_LDR      = (0x1B << 26),
  82    OPC_LB       = (0x20 << 26),
  83    OPC_LH       = (0x21 << 26),
  84    OPC_LWL      = (0x22 << 26),
  85    OPC_LW       = (0x23 << 26),
  86    OPC_LBU      = (0x24 << 26),
  87    OPC_LHU      = (0x25 << 26),
  88    OPC_LWR      = (0x26 << 26),
  89    OPC_LWU      = (0x27 << 26),
  90    OPC_SB       = (0x28 << 26),
  91    OPC_SH       = (0x29 << 26),
  92    OPC_SWL      = (0x2A << 26),
  93    OPC_SW       = (0x2B << 26),
  94    OPC_SDL      = (0x2C << 26),
  95    OPC_SDR      = (0x2D << 26),
  96    OPC_SWR      = (0x2E << 26),
  97    OPC_LL       = (0x30 << 26),
  98    OPC_LLD      = (0x34 << 26),
  99    OPC_LD       = (0x37 << 26),
 100    OPC_SC       = (0x38 << 26),
 101    OPC_SCD      = (0x3C << 26),
 102    OPC_SD       = (0x3F << 26),
 103    /* Floating point load/store */
 104    OPC_LWC1     = (0x31 << 26),
 105    OPC_LWC2     = (0x32 << 26),
 106    OPC_LDC1     = (0x35 << 26),
 107    OPC_LDC2     = (0x36 << 26),
 108    OPC_SWC1     = (0x39 << 26),
 109    OPC_SWC2     = (0x3A << 26),
 110    OPC_SDC1     = (0x3D << 26),
 111    OPC_SDC2     = (0x3E << 26),
 112    /* MDMX ASE specific */
 113    OPC_MDMX     = (0x1E << 26),
 114    /* Cache and prefetch */
 115    OPC_CACHE    = (0x2F << 26),
 116    OPC_PREF     = (0x33 << 26),
 117    /* Reserved major opcode */
 118    OPC_MAJOR3B_RESERVED = (0x3B << 26),
 119};
 120
 121/* MIPS special opcodes */
 122#define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
 123
 124enum {
 125    /* Shifts */
 126    OPC_SLL      = 0x00 | OPC_SPECIAL,
 127    /* NOP is SLL r0, r0, 0   */
 128    /* SSNOP is SLL r0, r0, 1 */
 129    /* EHB is SLL r0, r0, 3 */
 130    OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
 131    OPC_SRA      = 0x03 | OPC_SPECIAL,
 132    OPC_SLLV     = 0x04 | OPC_SPECIAL,
 133    OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
 134    OPC_SRAV     = 0x07 | OPC_SPECIAL,
 135    OPC_DSLLV    = 0x14 | OPC_SPECIAL,
 136    OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
 137    OPC_DSRAV    = 0x17 | OPC_SPECIAL,
 138    OPC_DSLL     = 0x38 | OPC_SPECIAL,
 139    OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
 140    OPC_DSRA     = 0x3B | OPC_SPECIAL,
 141    OPC_DSLL32   = 0x3C | OPC_SPECIAL,
 142    OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
 143    OPC_DSRA32   = 0x3F | OPC_SPECIAL,
 144    /* Multiplication / division */
 145    OPC_MULT     = 0x18 | OPC_SPECIAL,
 146    OPC_MULTU    = 0x19 | OPC_SPECIAL,
 147    OPC_DIV      = 0x1A | OPC_SPECIAL,
 148    OPC_DIVU     = 0x1B | OPC_SPECIAL,
 149    OPC_DMULT    = 0x1C | OPC_SPECIAL,
 150    OPC_DMULTU   = 0x1D | OPC_SPECIAL,
 151    OPC_DDIV     = 0x1E | OPC_SPECIAL,
 152    OPC_DDIVU    = 0x1F | OPC_SPECIAL,
 153    /* 2 registers arithmetic / logic */
 154    OPC_ADD      = 0x20 | OPC_SPECIAL,
 155    OPC_ADDU     = 0x21 | OPC_SPECIAL,
 156    OPC_SUB      = 0x22 | OPC_SPECIAL,
 157    OPC_SUBU     = 0x23 | OPC_SPECIAL,
 158    OPC_AND      = 0x24 | OPC_SPECIAL,
 159    OPC_OR       = 0x25 | OPC_SPECIAL,
 160    OPC_XOR      = 0x26 | OPC_SPECIAL,
 161    OPC_NOR      = 0x27 | OPC_SPECIAL,
 162    OPC_SLT      = 0x2A | OPC_SPECIAL,
 163    OPC_SLTU     = 0x2B | OPC_SPECIAL,
 164    OPC_DADD     = 0x2C | OPC_SPECIAL,
 165    OPC_DADDU    = 0x2D | OPC_SPECIAL,
 166    OPC_DSUB     = 0x2E | OPC_SPECIAL,
 167    OPC_DSUBU    = 0x2F | OPC_SPECIAL,
 168    /* Jumps */
 169    OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
 170    OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
 171    /* Traps */
 172    OPC_TGE      = 0x30 | OPC_SPECIAL,
 173    OPC_TGEU     = 0x31 | OPC_SPECIAL,
 174    OPC_TLT      = 0x32 | OPC_SPECIAL,
 175    OPC_TLTU     = 0x33 | OPC_SPECIAL,
 176    OPC_TEQ      = 0x34 | OPC_SPECIAL,
 177    OPC_TNE      = 0x36 | OPC_SPECIAL,
 178    /* HI / LO registers load & stores */
 179    OPC_MFHI     = 0x10 | OPC_SPECIAL,
 180    OPC_MTHI     = 0x11 | OPC_SPECIAL,
 181    OPC_MFLO     = 0x12 | OPC_SPECIAL,
 182    OPC_MTLO     = 0x13 | OPC_SPECIAL,
 183    /* Conditional moves */
 184    OPC_MOVZ     = 0x0A | OPC_SPECIAL,
 185    OPC_MOVN     = 0x0B | OPC_SPECIAL,
 186
 187    OPC_MOVCI    = 0x01 | OPC_SPECIAL,
 188
 189    /* Special */
 190    OPC_PMON     = 0x05 | OPC_SPECIAL, /* inofficial */
 191    OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
 192    OPC_BREAK    = 0x0D | OPC_SPECIAL,
 193    OPC_SPIM     = 0x0E | OPC_SPECIAL, /* inofficial */
 194    OPC_SYNC     = 0x0F | OPC_SPECIAL,
 195
 196    OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
 197    OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
 198    OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
 199    OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
 200    OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
 201    OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
 202    OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
 203};
 204
 205/* Multiplication variants of the vr54xx. */
 206#define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
 207
 208enum {
 209    OPC_VR54XX_MULS    = (0x03 << 6) | OPC_MULT,
 210    OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,
 211    OPC_VR54XX_MACC    = (0x05 << 6) | OPC_MULT,
 212    OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,
 213    OPC_VR54XX_MSAC    = (0x07 << 6) | OPC_MULT,
 214    OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,
 215    OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,
 216    OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,
 217    OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,
 218    OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
 219    OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,
 220    OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
 221    OPC_VR54XX_MSACHI  = (0x0F << 6) | OPC_MULT,
 222    OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
 223};
 224
 225/* REGIMM (rt field) opcodes */
 226#define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
 227
 228enum {
 229    OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
 230    OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
 231    OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
 232    OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
 233    OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
 234    OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
 235    OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
 236    OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
 237    OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
 238    OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
 239    OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
 240    OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
 241    OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
 242    OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
 243    OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
 244};
 245
 246/* Special2 opcodes */
 247#define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
 248
 249enum {
 250    /* Multiply & xxx operations */
 251    OPC_MADD     = 0x00 | OPC_SPECIAL2,
 252    OPC_MADDU    = 0x01 | OPC_SPECIAL2,
 253    OPC_MUL      = 0x02 | OPC_SPECIAL2,
 254    OPC_MSUB     = 0x04 | OPC_SPECIAL2,
 255    OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
 256    /* Misc */
 257    OPC_CLZ      = 0x20 | OPC_SPECIAL2,
 258    OPC_CLO      = 0x21 | OPC_SPECIAL2,
 259    OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
 260    OPC_DCLO     = 0x25 | OPC_SPECIAL2,
 261    /* Special */
 262    OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
 263};
 264
 265/* Special3 opcodes */
 266#define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
 267
 268enum {
 269    OPC_EXT      = 0x00 | OPC_SPECIAL3,
 270    OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
 271    OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
 272    OPC_DEXT     = 0x03 | OPC_SPECIAL3,
 273    OPC_INS      = 0x04 | OPC_SPECIAL3,
 274    OPC_DINSM    = 0x05 | OPC_SPECIAL3,
 275    OPC_DINSU    = 0x06 | OPC_SPECIAL3,
 276    OPC_DINS     = 0x07 | OPC_SPECIAL3,
 277    OPC_FORK     = 0x08 | OPC_SPECIAL3,
 278    OPC_YIELD    = 0x09 | OPC_SPECIAL3,
 279    OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
 280    OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
 281    OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
 282};
 283
 284/* BSHFL opcodes */
 285#define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
 286
 287enum {
 288    OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
 289    OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
 290    OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
 291};
 292
 293/* DBSHFL opcodes */
 294#define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
 295
 296enum {
 297    OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
 298    OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
 299};
 300
 301/* Coprocessor 0 (rs field) */
 302#define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
 303
 304enum {
 305    OPC_MFC0     = (0x00 << 21) | OPC_CP0,
 306    OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
 307    OPC_MTC0     = (0x04 << 21) | OPC_CP0,
 308    OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
 309    OPC_MFTR     = (0x08 << 21) | OPC_CP0,
 310    OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
 311    OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
 312    OPC_MTTR     = (0x0C << 21) | OPC_CP0,
 313    OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
 314    OPC_C0       = (0x10 << 21) | OPC_CP0,
 315    OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
 316    OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,
 317};
 318
 319/* MFMC0 opcodes */
 320#define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
 321
 322enum {
 323    OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
 324    OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
 325    OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
 326    OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
 327    OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
 328    OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
 329};
 330
 331/* Coprocessor 0 (with rs == C0) */
 332#define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
 333
 334enum {
 335    OPC_TLBR     = 0x01 | OPC_C0,
 336    OPC_TLBWI    = 0x02 | OPC_C0,
 337    OPC_TLBWR    = 0x06 | OPC_C0,
 338    OPC_TLBP     = 0x08 | OPC_C0,
 339    OPC_RFE      = 0x10 | OPC_C0,
 340    OPC_ERET     = 0x18 | OPC_C0,
 341    OPC_DERET    = 0x1F | OPC_C0,
 342    OPC_WAIT     = 0x20 | OPC_C0,
 343};
 344
 345/* Coprocessor 1 (rs field) */
 346#define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
 347
 348enum {
 349    OPC_MFC1     = (0x00 << 21) | OPC_CP1,
 350    OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
 351    OPC_CFC1     = (0x02 << 21) | OPC_CP1,
 352    OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
 353    OPC_MTC1     = (0x04 << 21) | OPC_CP1,
 354    OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
 355    OPC_CTC1     = (0x06 << 21) | OPC_CP1,
 356    OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
 357    OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
 358    OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
 359    OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
 360    OPC_S_FMT    = (0x10 << 21) | OPC_CP1, /* 16: fmt=single fp */
 361    OPC_D_FMT    = (0x11 << 21) | OPC_CP1, /* 17: fmt=double fp */
 362    OPC_E_FMT    = (0x12 << 21) | OPC_CP1, /* 18: fmt=extended fp */
 363    OPC_Q_FMT    = (0x13 << 21) | OPC_CP1, /* 19: fmt=quad fp */
 364    OPC_W_FMT    = (0x14 << 21) | OPC_CP1, /* 20: fmt=32bit fixed */
 365    OPC_L_FMT    = (0x15 << 21) | OPC_CP1, /* 21: fmt=64bit fixed */
 366    OPC_PS_FMT   = (0x16 << 21) | OPC_CP1, /* 22: fmt=paired single fp */
 367};
 368
 369#define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
 370#define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
 371
 372enum {
 373    OPC_BC1F     = (0x00 << 16) | OPC_BC1,
 374    OPC_BC1T     = (0x01 << 16) | OPC_BC1,
 375    OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
 376    OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
 377};
 378
 379enum {
 380    OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
 381    OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
 382};
 383
 384enum {
 385    OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
 386    OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
 387};
 388
 389#define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
 390
 391enum {
 392    OPC_MFC2    = (0x00 << 21) | OPC_CP2,
 393    OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
 394    OPC_CFC2    = (0x02 << 21) | OPC_CP2,
 395    OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
 396    OPC_MTC2    = (0x04 << 21) | OPC_CP2,
 397    OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
 398    OPC_CTC2    = (0x06 << 21) | OPC_CP2,
 399    OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
 400    OPC_BC2     = (0x08 << 21) | OPC_CP2,
 401};
 402
 403#define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
 404
 405enum {
 406    OPC_LWXC1   = 0x00 | OPC_CP3,
 407    OPC_LDXC1   = 0x01 | OPC_CP3,
 408    OPC_LUXC1   = 0x05 | OPC_CP3,
 409    OPC_SWXC1   = 0x08 | OPC_CP3,
 410    OPC_SDXC1   = 0x09 | OPC_CP3,
 411    OPC_SUXC1   = 0x0D | OPC_CP3,
 412    OPC_PREFX   = 0x0F | OPC_CP3,
 413    OPC_ALNV_PS = 0x1E | OPC_CP3,
 414    OPC_MADD_S  = 0x20 | OPC_CP3,
 415    OPC_MADD_D  = 0x21 | OPC_CP3,
 416    OPC_MADD_PS = 0x26 | OPC_CP3,
 417    OPC_MSUB_S  = 0x28 | OPC_CP3,
 418    OPC_MSUB_D  = 0x29 | OPC_CP3,
 419    OPC_MSUB_PS = 0x2E | OPC_CP3,
 420    OPC_NMADD_S = 0x30 | OPC_CP3,
 421    OPC_NMADD_D = 0x31 | OPC_CP3,
 422    OPC_NMADD_PS= 0x36 | OPC_CP3,
 423    OPC_NMSUB_S = 0x38 | OPC_CP3,
 424    OPC_NMSUB_D = 0x39 | OPC_CP3,
 425    OPC_NMSUB_PS= 0x3E | OPC_CP3,
 426};
 427
 428/* global register indices */
 429static TCGv_ptr cpu_env;
 430static TCGv cpu_gpr[32], cpu_PC;
 431static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
 432static TCGv cpu_dspctrl, btarget, bcond;
 433static TCGv_i32 hflags;
 434static TCGv_i32 fpu_fcr0, fpu_fcr31;
 435
 436#include "gen-icount.h"
 437
 438#define gen_helper_0i(name, arg) do {                             \
 439    TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
 440    gen_helper_##name(helper_tmp);                                \
 441    tcg_temp_free_i32(helper_tmp);                                \
 442    } while(0)
 443
 444#define gen_helper_1i(name, arg1, arg2) do {                      \
 445    TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
 446    gen_helper_##name(arg1, helper_tmp);                          \
 447    tcg_temp_free_i32(helper_tmp);                                \
 448    } while(0)
 449
 450#define gen_helper_2i(name, arg1, arg2, arg3) do {                \
 451    TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
 452    gen_helper_##name(arg1, arg2, helper_tmp);                    \
 453    tcg_temp_free_i32(helper_tmp);                                \
 454    } while(0)
 455
 456#define gen_helper_3i(name, arg1, arg2, arg3, arg4) do {          \
 457    TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
 458    gen_helper_##name(arg1, arg2, arg3, helper_tmp);              \
 459    tcg_temp_free_i32(helper_tmp);                                \
 460    } while(0)
 461
 462typedef struct DisasContext {
 463    struct TranslationBlock *tb;
 464    target_ulong pc, saved_pc;
 465    uint32_t opcode;
 466    /* Routine used to access memory */
 467    int mem_idx;
 468    uint32_t hflags, saved_hflags;
 469    int bstate;
 470    target_ulong btarget;
 471} DisasContext;
 472
 473enum {
 474    BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
 475                      * exception condition */
 476    BS_STOP     = 1, /* We want to stop translation for any reason */
 477    BS_BRANCH   = 2, /* We reached a branch condition     */
 478    BS_EXCP     = 3, /* We reached an exception condition */
 479};
 480
 481static const char *regnames[] =
 482    { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
 483      "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
 484      "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
 485      "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
 486
 487static const char *regnames_HI[] =
 488    { "HI0", "HI1", "HI2", "HI3", };
 489
 490static const char *regnames_LO[] =
 491    { "LO0", "LO1", "LO2", "LO3", };
 492
 493static const char *regnames_ACX[] =
 494    { "ACX0", "ACX1", "ACX2", "ACX3", };
 495
 496static const char *fregnames[] =
 497    { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
 498      "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
 499      "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
 500      "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
 501
 502#ifdef MIPS_DEBUG_DISAS
 503#define MIPS_DEBUG(fmt, ...)                         \
 504        qemu_log_mask(CPU_LOG_TB_IN_ASM,                \
 505                       TARGET_FMT_lx ": %08x " fmt "\n", \
 506                       ctx->pc, ctx->opcode , ## __VA_ARGS__)
 507#define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
 508#else
 509#define MIPS_DEBUG(fmt, ...) do { } while(0)
 510#define LOG_DISAS(...) do { } while (0)
 511#endif
 512
 513#define MIPS_INVAL(op)                                                        \
 514do {                                                                          \
 515    MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
 516               ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
 517} while (0)
 518
 519/* General purpose registers moves. */
 520static inline void gen_load_gpr (TCGv t, int reg)
 521{
 522    if (reg == 0)
 523        tcg_gen_movi_tl(t, 0);
 524    else
 525        tcg_gen_mov_tl(t, cpu_gpr[reg]);
 526}
 527
 528static inline void gen_store_gpr (TCGv t, int reg)
 529{
 530    if (reg != 0)
 531        tcg_gen_mov_tl(cpu_gpr[reg], t);
 532}
 533
 534/* Moves to/from ACX register.  */
 535static inline void gen_load_ACX (TCGv t, int reg)
 536{
 537    tcg_gen_mov_tl(t, cpu_ACX[reg]);
 538}
 539
 540static inline void gen_store_ACX (TCGv t, int reg)
 541{
 542    tcg_gen_mov_tl(cpu_ACX[reg], t);
 543}
 544
 545/* Moves to/from shadow registers. */
 546static inline void gen_load_srsgpr (int from, int to)
 547{
 548    TCGv t0 = tcg_temp_new();
 549
 550    if (from == 0)
 551        tcg_gen_movi_tl(t0, 0);
 552    else {
 553        TCGv_i32 t2 = tcg_temp_new_i32();
 554        TCGv_ptr addr = tcg_temp_new_ptr();
 555
 556        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
 557        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
 558        tcg_gen_andi_i32(t2, t2, 0xf);
 559        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
 560        tcg_gen_ext_i32_ptr(addr, t2);
 561        tcg_gen_add_ptr(addr, cpu_env, addr);
 562
 563        tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
 564        tcg_temp_free_ptr(addr);
 565        tcg_temp_free_i32(t2);
 566    }
 567    gen_store_gpr(t0, to);
 568    tcg_temp_free(t0);
 569}
 570
 571static inline void gen_store_srsgpr (int from, int to)
 572{
 573    if (to != 0) {
 574        TCGv t0 = tcg_temp_new();
 575        TCGv_i32 t2 = tcg_temp_new_i32();
 576        TCGv_ptr addr = tcg_temp_new_ptr();
 577
 578        gen_load_gpr(t0, from);
 579        tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
 580        tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
 581        tcg_gen_andi_i32(t2, t2, 0xf);
 582        tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
 583        tcg_gen_ext_i32_ptr(addr, t2);
 584        tcg_gen_add_ptr(addr, cpu_env, addr);
 585
 586        tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
 587        tcg_temp_free_ptr(addr);
 588        tcg_temp_free_i32(t2);
 589        tcg_temp_free(t0);
 590    }
 591}
 592
 593/* Floating point register moves. */
 594static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
 595{
 596    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
 597}
 598
 599static inline void gen_store_fpr32 (TCGv_i32 t, int reg)
 600{
 601    tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
 602}
 603
 604static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
 605{
 606    tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
 607}
 608
 609static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
 610{
 611    tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
 612}
 613
 614static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
 615{
 616    if (ctx->hflags & MIPS_HFLAG_F64) {
 617        tcg_gen_ld_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
 618    } else {
 619        TCGv_i32 t0 = tcg_temp_new_i32();
 620        TCGv_i32 t1 = tcg_temp_new_i32();
 621        gen_load_fpr32(t0, reg & ~1);
 622        gen_load_fpr32(t1, reg | 1);
 623        tcg_gen_concat_i32_i64(t, t0, t1);
 624        tcg_temp_free_i32(t0);
 625        tcg_temp_free_i32(t1);
 626    }
 627}
 628
 629static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
 630{
 631    if (ctx->hflags & MIPS_HFLAG_F64) {
 632        tcg_gen_st_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
 633    } else {
 634        TCGv_i64 t0 = tcg_temp_new_i64();
 635        TCGv_i32 t1 = tcg_temp_new_i32();
 636        tcg_gen_trunc_i64_i32(t1, t);
 637        gen_store_fpr32(t1, reg & ~1);
 638        tcg_gen_shri_i64(t0, t, 32);
 639        tcg_gen_trunc_i64_i32(t1, t0);
 640        gen_store_fpr32(t1, reg | 1);
 641        tcg_temp_free_i32(t1);
 642        tcg_temp_free_i64(t0);
 643    }
 644}
 645
 646static inline int get_fp_bit (int cc)
 647{
 648    if (cc)
 649        return 24 + cc;
 650    else
 651        return 23;
 652}
 653
 654#define FOP_CONDS(type, fmt, bits)                                            \
 655static inline void gen_cmp ## type ## _ ## fmt(int n, TCGv_i##bits a,         \
 656                                               TCGv_i##bits b, int cc)        \
 657{                                                                             \
 658    switch (n) {                                                              \
 659    case  0: gen_helper_2i(cmp ## type ## _ ## fmt ## _f, a, b, cc);    break;\
 660    case  1: gen_helper_2i(cmp ## type ## _ ## fmt ## _un, a, b, cc);   break;\
 661    case  2: gen_helper_2i(cmp ## type ## _ ## fmt ## _eq, a, b, cc);   break;\
 662    case  3: gen_helper_2i(cmp ## type ## _ ## fmt ## _ueq, a, b, cc);  break;\
 663    case  4: gen_helper_2i(cmp ## type ## _ ## fmt ## _olt, a, b, cc);  break;\
 664    case  5: gen_helper_2i(cmp ## type ## _ ## fmt ## _ult, a, b, cc);  break;\
 665    case  6: gen_helper_2i(cmp ## type ## _ ## fmt ## _ole, a, b, cc);  break;\
 666    case  7: gen_helper_2i(cmp ## type ## _ ## fmt ## _ule, a, b, cc);  break;\
 667    case  8: gen_helper_2i(cmp ## type ## _ ## fmt ## _sf, a, b, cc);   break;\
 668    case  9: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngle, a, b, cc); break;\
 669    case 10: gen_helper_2i(cmp ## type ## _ ## fmt ## _seq, a, b, cc);  break;\
 670    case 11: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngl, a, b, cc);  break;\
 671    case 12: gen_helper_2i(cmp ## type ## _ ## fmt ## _lt, a, b, cc);   break;\
 672    case 13: gen_helper_2i(cmp ## type ## _ ## fmt ## _nge, a, b, cc);  break;\
 673    case 14: gen_helper_2i(cmp ## type ## _ ## fmt ## _le, a, b, cc);   break;\
 674    case 15: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngt, a, b, cc);  break;\
 675    default: abort();                                                         \
 676    }                                                                         \
 677}
 678
 679FOP_CONDS(, d, 64)
 680FOP_CONDS(abs, d, 64)
 681FOP_CONDS(, s, 32)
 682FOP_CONDS(abs, s, 32)
 683FOP_CONDS(, ps, 64)
 684FOP_CONDS(abs, ps, 64)
 685#undef FOP_CONDS
 686
 687/* Tests */
 688#define OP_COND(name, cond)                                         \
 689static inline void glue(gen_op_, name) (TCGv ret, TCGv t0, TCGv t1) \
 690{                                                                   \
 691    int l1 = gen_new_label();                                       \
 692    int l2 = gen_new_label();                                       \
 693                                                                    \
 694    tcg_gen_brcond_tl(cond, t0, t1, l1);                            \
 695    tcg_gen_movi_tl(ret, 0);                                        \
 696    tcg_gen_br(l2);                                                 \
 697    gen_set_label(l1);                                              \
 698    tcg_gen_movi_tl(ret, 1);                                        \
 699    gen_set_label(l2);                                              \
 700}
 701OP_COND(eq, TCG_COND_EQ);
 702OP_COND(ne, TCG_COND_NE);
 703OP_COND(ge, TCG_COND_GE);
 704OP_COND(geu, TCG_COND_GEU);
 705OP_COND(lt, TCG_COND_LT);
 706OP_COND(ltu, TCG_COND_LTU);
 707#undef OP_COND
 708
 709#define OP_CONDI(name, cond)                                                 \
 710static inline void glue(gen_op_, name) (TCGv ret, TCGv t0, target_ulong val) \
 711{                                                                            \
 712    int l1 = gen_new_label();                                                \
 713    int l2 = gen_new_label();                                                \
 714                                                                             \
 715    tcg_gen_brcondi_tl(cond, t0, val, l1);                                   \
 716    tcg_gen_movi_tl(ret, 0);                                                 \
 717    tcg_gen_br(l2);                                                          \
 718    gen_set_label(l1);                                                       \
 719    tcg_gen_movi_tl(ret, 1);                                                 \
 720    gen_set_label(l2);                                                       \
 721}
 722OP_CONDI(lti, TCG_COND_LT);
 723OP_CONDI(ltiu, TCG_COND_LTU);
 724#undef OP_CONDI
 725
 726#define OP_CONDZ(name, cond)                                  \
 727static inline void glue(gen_op_, name) (TCGv ret, TCGv t0)    \
 728{                                                             \
 729    int l1 = gen_new_label();                                 \
 730    int l2 = gen_new_label();                                 \
 731                                                              \
 732    tcg_gen_brcondi_tl(cond, t0, 0, l1);                      \
 733    tcg_gen_movi_tl(ret, 0);                                  \
 734    tcg_gen_br(l2);                                           \
 735    gen_set_label(l1);                                        \
 736    tcg_gen_movi_tl(ret, 1);                                  \
 737    gen_set_label(l2);                                        \
 738}
 739OP_CONDZ(gez, TCG_COND_GE);
 740OP_CONDZ(gtz, TCG_COND_GT);
 741OP_CONDZ(lez, TCG_COND_LE);
 742OP_CONDZ(ltz, TCG_COND_LT);
 743#undef OP_CONDZ
 744
 745static inline void gen_save_pc(target_ulong pc)
 746{
 747    tcg_gen_movi_tl(cpu_PC, pc);
 748}
 749
 750static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
 751{
 752    LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
 753    if (do_save_pc && ctx->pc != ctx->saved_pc) {
 754        gen_save_pc(ctx->pc);
 755        ctx->saved_pc = ctx->pc;
 756    }
 757    if (ctx->hflags != ctx->saved_hflags) {
 758        tcg_gen_movi_i32(hflags, ctx->hflags);
 759        ctx->saved_hflags = ctx->hflags;
 760        switch (ctx->hflags & MIPS_HFLAG_BMASK) {
 761        case MIPS_HFLAG_BR:
 762            break;
 763        case MIPS_HFLAG_BC:
 764        case MIPS_HFLAG_BL:
 765        case MIPS_HFLAG_B:
 766            tcg_gen_movi_tl(btarget, ctx->btarget);
 767            break;
 768        }
 769    }
 770}
 771
 772static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
 773{
 774    ctx->saved_hflags = ctx->hflags;
 775    switch (ctx->hflags & MIPS_HFLAG_BMASK) {
 776    case MIPS_HFLAG_BR:
 777        break;
 778    case MIPS_HFLAG_BC:
 779    case MIPS_HFLAG_BL:
 780    case MIPS_HFLAG_B:
 781        ctx->btarget = env->btarget;
 782        break;
 783    }
 784}
 785
 786static inline void
 787generate_exception_err (DisasContext *ctx, int excp, int err)
 788{
 789    TCGv_i32 texcp = tcg_const_i32(excp);
 790    TCGv_i32 terr = tcg_const_i32(err);
 791    save_cpu_state(ctx, 1);
 792    gen_helper_raise_exception_err(texcp, terr);
 793    tcg_temp_free_i32(terr);
 794    tcg_temp_free_i32(texcp);
 795}
 796
 797static inline void
 798generate_exception (DisasContext *ctx, int excp)
 799{
 800    save_cpu_state(ctx, 1);
 801    gen_helper_0i(raise_exception, excp);
 802}
 803
 804/* Addresses computation */
 805static inline void gen_op_addr_add (DisasContext *ctx, TCGv t0, TCGv t1)
 806{
 807    tcg_gen_add_tl(t0, t0, t1);
 808
 809#if defined(TARGET_MIPS64)
 810    /* For compatibility with 32-bit code, data reference in user mode
 811       with Status_UX = 0 should be casted to 32-bit and sign extended.
 812       See the MIPS64 PRA manual, section 4.10. */
 813    if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
 814        !(ctx->hflags & MIPS_HFLAG_UX)) {
 815        tcg_gen_ext32s_i64(t0, t0);
 816    }
 817#endif
 818}
 819
 820static inline void check_cp0_enabled(DisasContext *ctx)
 821{
 822    if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
 823        generate_exception_err(ctx, EXCP_CpU, 1);
 824}
 825
 826static inline void check_cp1_enabled(DisasContext *ctx)
 827{
 828    if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
 829        generate_exception_err(ctx, EXCP_CpU, 1);
 830}
 831
 832/* Verify that the processor is running with COP1X instructions enabled.
 833   This is associated with the nabla symbol in the MIPS32 and MIPS64
 834   opcode tables.  */
 835
 836static inline void check_cop1x(DisasContext *ctx)
 837{
 838    if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
 839        generate_exception(ctx, EXCP_RI);
 840}
 841
 842/* Verify that the processor is running with 64-bit floating-point
 843   operations enabled.  */
 844
 845static inline void check_cp1_64bitmode(DisasContext *ctx)
 846{
 847    if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
 848        generate_exception(ctx, EXCP_RI);
 849}
 850
 851/*
 852 * Verify if floating point register is valid; an operation is not defined
 853 * if bit 0 of any register specification is set and the FR bit in the
 854 * Status register equals zero, since the register numbers specify an
 855 * even-odd pair of adjacent coprocessor general registers. When the FR bit
 856 * in the Status register equals one, both even and odd register numbers
 857 * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
 858 *
 859 * Multiple 64 bit wide registers can be checked by calling
 860 * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
 861 */
 862static inline void check_cp1_registers(DisasContext *ctx, int regs)
 863{
 864    if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
 865        generate_exception(ctx, EXCP_RI);
 866}
 867
 868/* This code generates a "reserved instruction" exception if the
 869   CPU does not support the instruction set corresponding to flags. */
 870static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
 871{
 872    if (unlikely(!(env->insn_flags & flags)))
 873        generate_exception(ctx, EXCP_RI);
 874}
 875
 876/* This code generates a "reserved instruction" exception if 64-bit
 877   instructions are not enabled. */
 878static inline void check_mips_64(DisasContext *ctx)
 879{
 880    if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
 881        generate_exception(ctx, EXCP_RI);
 882}
 883
 884/* load/store instructions. */
 885#define OP_LD(insn,fname)                                                 \
 886static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx) \
 887{                                                                         \
 888    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                        \
 889}
 890OP_LD(lb,ld8s);
 891OP_LD(lbu,ld8u);
 892OP_LD(lh,ld16s);
 893OP_LD(lhu,ld16u);
 894OP_LD(lw,ld32s);
 895#if defined(TARGET_MIPS64)
 896OP_LD(lwu,ld32u);
 897OP_LD(ld,ld64);
 898#endif
 899#undef OP_LD
 900
 901#define OP_ST(insn,fname)                                                  \
 902static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx) \
 903{                                                                          \
 904    tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx);                        \
 905}
 906OP_ST(sb,st8);
 907OP_ST(sh,st16);
 908OP_ST(sw,st32);
 909#if defined(TARGET_MIPS64)
 910OP_ST(sd,st64);
 911#endif
 912#undef OP_ST
 913
 914#define OP_LD_ATOMIC(insn,fname)                                           \
 915static inline void op_ldst_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)  \
 916{                                                                          \
 917    TCGv t0 = tcg_temp_new();                                              \
 918    tcg_gen_mov_tl(t0, arg1);                                              \
 919    tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
 920    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_LLAddr));            \
 921    tcg_gen_st_tl(ret, cpu_env, offsetof(CPUState, llval));                \
 922    tcg_temp_free(t0);                                                     \
 923}
 924OP_LD_ATOMIC(ll,ld32s);
 925#if defined(TARGET_MIPS64)
 926OP_LD_ATOMIC(lld,ld64);
 927#endif
 928#undef OP_LD_ATOMIC
 929
 930#ifdef CONFIG_USER_ONLY
 931#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
 932static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
 933{                                                                            \
 934    TCGv t0 = tcg_temp_new();                                                \
 935    int l1 = gen_new_label();                                                \
 936    int l2 = gen_new_label();                                                \
 937                                                                             \
 938    tcg_gen_andi_tl(t0, arg2, almask);                                       \
 939    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                              \
 940    tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUState, CP0_BadVAddr));          \
 941    generate_exception(ctx, EXCP_AdES);                                      \
 942    gen_set_label(l1);                                                       \
 943    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_LLAddr));              \
 944    tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                            \
 945    tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20));                        \
 946    tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, llreg));                   \
 947    tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUState, llnewval));              \
 948    gen_helper_0i(raise_exception, EXCP_SC);                                 \
 949    gen_set_label(l2);                                                       \
 950    tcg_gen_movi_tl(t0, 0);                                                  \
 951    gen_store_gpr(t0, rt);                                                   \
 952    tcg_temp_free(t0);                                                       \
 953}
 954#else
 955#define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
 956static inline void op_ldst_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
 957{                                                                            \
 958    TCGv t0 = tcg_temp_new();                                                \
 959    TCGv t1 = tcg_temp_new();                                                \
 960    int l1 = gen_new_label();                                                \
 961    int l2 = gen_new_label();                                                \
 962    int l3 = gen_new_label();                                                \
 963                                                                             \
 964    tcg_gen_andi_tl(t0, arg2, almask);                                       \
 965    tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                              \
 966    tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUState, CP0_BadVAddr));          \
 967    generate_exception(ctx, EXCP_AdES);                                      \
 968    gen_set_label(l1);                                                       \
 969    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_LLAddr));              \
 970    tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                            \
 971    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, llval));                   \
 972    tcg_gen_qemu_##ldname(t1, arg2, ctx->mem_idx);                           \
 973    tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l2);                              \
 974    tcg_temp_free(t1);                                                       \
 975    tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx);                          \
 976    tcg_gen_movi_tl(t0, 1);                                                  \
 977    gen_store_gpr(t0, rt);                                                   \
 978    tcg_gen_br(l3);                                                          \
 979    gen_set_label(l2);                                                       \
 980    tcg_gen_movi_tl(t0, 0);                                                  \
 981    gen_store_gpr(t0, rt);                                                   \
 982    gen_set_label(l3);                                                       \
 983    tcg_temp_free(t0);                                                       \
 984}
 985#endif
 986
 987OP_ST_ATOMIC(sc,st32,ld32s,0x3);
 988#if defined(TARGET_MIPS64)
 989OP_ST_ATOMIC(scd,st64,ld64,0x7);
 990#endif
 991#undef OP_ST_ATOMIC
 992
 993/* Load and store */
 994static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
 995                      int base, int16_t offset)
 996{
 997    const char *opn = "ldst";
 998    TCGv t0 = tcg_temp_new();
 999    TCGv t1 = tcg_temp_new();
1000
1001    if (base == 0) {
1002        tcg_gen_movi_tl(t0, offset);
1003    } else if (offset == 0) {
1004        gen_load_gpr(t0, base);
1005    } else {
1006        tcg_gen_movi_tl(t0, offset);
1007        gen_op_addr_add(ctx, t0, cpu_gpr[base]);
1008    }
1009    /* Don't do NOP if destination is zero: we must perform the actual
1010       memory access. */
1011    switch (opc) {
1012#if defined(TARGET_MIPS64)
1013    case OPC_LWU:
1014        save_cpu_state(ctx, 0);
1015        op_ldst_lwu(t0, t0, ctx);
1016        gen_store_gpr(t0, rt);
1017        opn = "lwu";
1018        break;
1019    case OPC_LD:
1020        save_cpu_state(ctx, 0);
1021        op_ldst_ld(t0, t0, ctx);
1022        gen_store_gpr(t0, rt);
1023        opn = "ld";
1024        break;
1025    case OPC_LLD:
1026        save_cpu_state(ctx, 0);
1027        op_ldst_lld(t0, t0, ctx);
1028        gen_store_gpr(t0, rt);
1029        opn = "lld";
1030        break;
1031    case OPC_SD:
1032        save_cpu_state(ctx, 0);
1033        gen_load_gpr(t1, rt);
1034        op_ldst_sd(t1, t0, ctx);
1035        opn = "sd";
1036        break;
1037    case OPC_LDL:
1038        save_cpu_state(ctx, 1);
1039        gen_load_gpr(t1, rt);
1040        gen_helper_3i(ldl, t1, t1, t0, ctx->mem_idx);
1041        gen_store_gpr(t1, rt);
1042        opn = "ldl";
1043        break;
1044    case OPC_SDL:
1045        save_cpu_state(ctx, 1);
1046        gen_load_gpr(t1, rt);
1047        gen_helper_2i(sdl, t1, t0, ctx->mem_idx);
1048        opn = "sdl";
1049        break;
1050    case OPC_LDR:
1051        save_cpu_state(ctx, 1);
1052        gen_load_gpr(t1, rt);
1053        gen_helper_3i(ldr, t1, t1, t0, ctx->mem_idx);
1054        gen_store_gpr(t1, rt);
1055        opn = "ldr";
1056        break;
1057    case OPC_SDR:
1058        save_cpu_state(ctx, 1);
1059        gen_load_gpr(t1, rt);
1060        gen_helper_2i(sdr, t1, t0, ctx->mem_idx);
1061        opn = "sdr";
1062        break;
1063#endif
1064    case OPC_LW:
1065        save_cpu_state(ctx, 0);
1066        op_ldst_lw(t0, t0, ctx);
1067        gen_store_gpr(t0, rt);
1068        opn = "lw";
1069        break;
1070    case OPC_SW:
1071        save_cpu_state(ctx, 0);
1072        gen_load_gpr(t1, rt);
1073        op_ldst_sw(t1, t0, ctx);
1074        opn = "sw";
1075        break;
1076    case OPC_LH:
1077        save_cpu_state(ctx, 0);
1078        op_ldst_lh(t0, t0, ctx);
1079        gen_store_gpr(t0, rt);
1080        opn = "lh";
1081        break;
1082    case OPC_SH:
1083        save_cpu_state(ctx, 0);
1084        gen_load_gpr(t1, rt);
1085        op_ldst_sh(t1, t0, ctx);
1086        opn = "sh";
1087        break;
1088    case OPC_LHU:
1089        save_cpu_state(ctx, 0);
1090        op_ldst_lhu(t0, t0, ctx);
1091        gen_store_gpr(t0, rt);
1092        opn = "lhu";
1093        break;
1094    case OPC_LB:
1095        save_cpu_state(ctx, 0);
1096        op_ldst_lb(t0, t0, ctx);
1097        gen_store_gpr(t0, rt);
1098        opn = "lb";
1099        break;
1100    case OPC_SB:
1101        save_cpu_state(ctx, 0);
1102        gen_load_gpr(t1, rt);
1103        op_ldst_sb(t1, t0, ctx);
1104        opn = "sb";
1105        break;
1106    case OPC_LBU:
1107        save_cpu_state(ctx, 0);
1108        op_ldst_lbu(t0, t0, ctx);
1109        gen_store_gpr(t0, rt);
1110        opn = "lbu";
1111        break;
1112    case OPC_LWL:
1113        save_cpu_state(ctx, 1);
1114        gen_load_gpr(t1, rt);
1115        gen_helper_3i(lwl, t1, t1, t0, ctx->mem_idx);
1116        gen_store_gpr(t1, rt);
1117        opn = "lwl";
1118        break;
1119    case OPC_SWL:
1120        save_cpu_state(ctx, 1);
1121        gen_load_gpr(t1, rt);
1122        gen_helper_2i(swl, t1, t0, ctx->mem_idx);
1123        opn = "swr";
1124        break;
1125    case OPC_LWR:
1126        save_cpu_state(ctx, 1);
1127        gen_load_gpr(t1, rt);
1128        gen_helper_3i(lwr, t1, t1, t0, ctx->mem_idx);
1129        gen_store_gpr(t1, rt);
1130        opn = "lwr";
1131        break;
1132    case OPC_SWR:
1133        save_cpu_state(ctx, 1);
1134        gen_load_gpr(t1, rt);
1135        gen_helper_2i(swr, t1, t0, ctx->mem_idx);
1136        opn = "swr";
1137        break;
1138    case OPC_LL:
1139        save_cpu_state(ctx, 0);
1140        op_ldst_ll(t0, t0, ctx);
1141        gen_store_gpr(t0, rt);
1142        opn = "ll";
1143        break;
1144    }
1145    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1146    tcg_temp_free(t0);
1147    tcg_temp_free(t1);
1148}
1149
1150/* Store conditional */
1151static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
1152                         int base, int16_t offset)
1153{
1154    const char *opn = "st_cond";
1155    TCGv t0, t1;
1156
1157    t0 = tcg_temp_local_new();
1158
1159    if (base == 0) {
1160        tcg_gen_movi_tl(t0, offset);
1161    } else if (offset == 0) {
1162        gen_load_gpr(t0, base);
1163    } else {
1164        tcg_gen_movi_tl(t0, offset);
1165        gen_op_addr_add(ctx, t0, cpu_gpr[base]);
1166    }
1167    /* Don't do NOP if destination is zero: we must perform the actual
1168       memory access. */
1169
1170    t1 = tcg_temp_local_new();
1171    gen_load_gpr(t1, rt);
1172    switch (opc) {
1173#if defined(TARGET_MIPS64)
1174    case OPC_SCD:
1175        save_cpu_state(ctx, 0);
1176        op_ldst_scd(t1, t0, rt, ctx);
1177        opn = "scd";
1178        break;
1179#endif
1180    case OPC_SC:
1181        save_cpu_state(ctx, 0);
1182        op_ldst_sc(t1, t0, rt, ctx);
1183        opn = "sc";
1184        break;
1185    }
1186    MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1187    tcg_temp_free(t1);
1188    tcg_temp_free(t0);
1189}
1190
1191/* Load and store */
1192static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1193                          int base, int16_t offset)
1194{
1195    const char *opn = "flt_ldst";
1196    TCGv t0 = tcg_temp_new();
1197
1198    if (base == 0) {
1199        tcg_gen_movi_tl(t0, offset);
1200    } else if (offset == 0) {
1201        gen_load_gpr(t0, base);
1202    } else {
1203        tcg_gen_movi_tl(t0, offset);
1204        gen_op_addr_add(ctx, t0, cpu_gpr[base]);
1205    }
1206    /* Don't do NOP if destination is zero: we must perform the actual
1207       memory access. */
1208    switch (opc) {
1209    case OPC_LWC1:
1210        {
1211            TCGv_i32 fp0 = tcg_temp_new_i32();
1212
1213            tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
1214            tcg_gen_trunc_tl_i32(fp0, t0);
1215            gen_store_fpr32(fp0, ft);
1216            tcg_temp_free_i32(fp0);
1217        }
1218        opn = "lwc1";
1219        break;
1220    case OPC_SWC1:
1221        {
1222            TCGv_i32 fp0 = tcg_temp_new_i32();
1223            TCGv t1 = tcg_temp_new();
1224
1225            gen_load_fpr32(fp0, ft);
1226            tcg_gen_extu_i32_tl(t1, fp0);
1227            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
1228            tcg_temp_free(t1);
1229            tcg_temp_free_i32(fp0);
1230        }
1231        opn = "swc1";
1232        break;
1233    case OPC_LDC1:
1234        {
1235            TCGv_i64 fp0 = tcg_temp_new_i64();
1236
1237            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
1238            gen_store_fpr64(ctx, fp0, ft);
1239            tcg_temp_free_i64(fp0);
1240        }
1241        opn = "ldc1";
1242        break;
1243    case OPC_SDC1:
1244        {
1245            TCGv_i64 fp0 = tcg_temp_new_i64();
1246
1247            gen_load_fpr64(ctx, fp0, ft);
1248            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
1249            tcg_temp_free_i64(fp0);
1250        }
1251        opn = "sdc1";
1252        break;
1253    default:
1254        MIPS_INVAL(opn);
1255        generate_exception(ctx, EXCP_RI);
1256        goto out;
1257    }
1258    MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1259 out:
1260    tcg_temp_free(t0);
1261}
1262
1263/* Arithmetic with immediate operand */
1264static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
1265                           int rt, int rs, int16_t imm)
1266{
1267    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1268    const char *opn = "imm arith";
1269
1270    if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1271        /* If no destination, treat it as a NOP.
1272           For addi, we must generate the overflow exception when needed. */
1273        MIPS_DEBUG("NOP");
1274        return;
1275    }
1276    switch (opc) {
1277    case OPC_ADDI:
1278        {
1279            TCGv t0 = tcg_temp_local_new();
1280            TCGv t1 = tcg_temp_new();
1281            TCGv t2 = tcg_temp_new();
1282            int l1 = gen_new_label();
1283
1284            gen_load_gpr(t1, rs);
1285            tcg_gen_addi_tl(t0, t1, uimm);
1286            tcg_gen_ext32s_tl(t0, t0);
1287
1288            tcg_gen_xori_tl(t1, t1, ~uimm);
1289            tcg_gen_xori_tl(t2, t0, uimm);
1290            tcg_gen_and_tl(t1, t1, t2);
1291            tcg_temp_free(t2);
1292            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1293            tcg_temp_free(t1);
1294            /* operands of same sign, result different sign */
1295            generate_exception(ctx, EXCP_OVERFLOW);
1296            gen_set_label(l1);
1297            tcg_gen_ext32s_tl(t0, t0);
1298            gen_store_gpr(t0, rt);
1299            tcg_temp_free(t0);
1300        }
1301        opn = "addi";
1302        break;
1303    case OPC_ADDIU:
1304        if (rs != 0) {
1305            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1306            tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
1307        } else {
1308            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1309        }
1310        opn = "addiu";
1311        break;
1312#if defined(TARGET_MIPS64)
1313    case OPC_DADDI:
1314        {
1315            TCGv t0 = tcg_temp_local_new();
1316            TCGv t1 = tcg_temp_new();
1317            TCGv t2 = tcg_temp_new();
1318            int l1 = gen_new_label();
1319
1320            gen_load_gpr(t1, rs);
1321            tcg_gen_addi_tl(t0, t1, uimm);
1322
1323            tcg_gen_xori_tl(t1, t1, ~uimm);
1324            tcg_gen_xori_tl(t2, t0, uimm);
1325            tcg_gen_and_tl(t1, t1, t2);
1326            tcg_temp_free(t2);
1327            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1328            tcg_temp_free(t1);
1329            /* operands of same sign, result different sign */
1330            generate_exception(ctx, EXCP_OVERFLOW);
1331            gen_set_label(l1);
1332            gen_store_gpr(t0, rt);
1333            tcg_temp_free(t0);
1334        }
1335        opn = "daddi";
1336        break;
1337    case OPC_DADDIU:
1338        if (rs != 0) {
1339            tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1340        } else {
1341            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1342        }
1343        opn = "daddiu";
1344        break;
1345#endif
1346    }
1347    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1348}
1349
1350/* Logic with immediate operand */
1351static void gen_logic_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1352{
1353    target_ulong uimm;
1354    const char *opn = "imm logic";
1355
1356    if (rt == 0) {
1357        /* If no destination, treat it as a NOP. */
1358        MIPS_DEBUG("NOP");
1359        return;
1360    }
1361    uimm = (uint16_t)imm;
1362    switch (opc) {
1363    case OPC_ANDI:
1364        if (likely(rs != 0))
1365            tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1366        else
1367            tcg_gen_movi_tl(cpu_gpr[rt], 0);
1368        opn = "andi";
1369        break;
1370    case OPC_ORI:
1371        if (rs != 0)
1372            tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1373        else
1374            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1375        opn = "ori";
1376        break;
1377    case OPC_XORI:
1378        if (likely(rs != 0))
1379            tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
1380        else
1381            tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1382        opn = "xori";
1383        break;
1384    case OPC_LUI:
1385        tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
1386        opn = "lui";
1387        break;
1388    }
1389    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1390}
1391
1392/* Set on less than with immediate operand */
1393static void gen_slt_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
1394{
1395    target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1396    const char *opn = "imm arith";
1397    TCGv t0;
1398
1399    if (rt == 0) {
1400        /* If no destination, treat it as a NOP. */
1401        MIPS_DEBUG("NOP");
1402        return;
1403    }
1404    t0 = tcg_temp_new();
1405    gen_load_gpr(t0, rs);
1406    switch (opc) {
1407    case OPC_SLTI:
1408        gen_op_lti(cpu_gpr[rt], t0, uimm);
1409        opn = "slti";
1410        break;
1411    case OPC_SLTIU:
1412        gen_op_ltiu(cpu_gpr[rt], t0, uimm);
1413        opn = "sltiu";
1414        break;
1415    }
1416    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1417    tcg_temp_free(t0);
1418}
1419
1420/* Shifts with immediate operand */
1421static void gen_shift_imm(CPUState *env, DisasContext *ctx, uint32_t opc,
1422                          int rt, int rs, int16_t imm)
1423{
1424    target_ulong uimm = ((uint16_t)imm) & 0x1f;
1425    const char *opn = "imm shift";
1426    TCGv t0;
1427
1428    if (rt == 0) {
1429        /* If no destination, treat it as a NOP. */
1430        MIPS_DEBUG("NOP");
1431        return;
1432    }
1433
1434    t0 = tcg_temp_new();
1435    gen_load_gpr(t0, rs);
1436    switch (opc) {
1437    case OPC_SLL:
1438        tcg_gen_shli_tl(t0, t0, uimm);
1439        tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1440        opn = "sll";
1441        break;
1442    case OPC_SRA:
1443        tcg_gen_ext32s_tl(t0, t0);
1444        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1445        opn = "sra";
1446        break;
1447    case OPC_SRL:
1448        switch ((ctx->opcode >> 21) & 0x1f) {
1449        case 0:
1450            if (uimm != 0) {
1451                tcg_gen_ext32u_tl(t0, t0);
1452                tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1453            } else {
1454                tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1455            }
1456            opn = "srl";
1457            break;
1458        case 1:
1459            /* rotr is decoded as srl on non-R2 CPUs */
1460            if (env->insn_flags & ISA_MIPS32R2) {
1461                if (uimm != 0) {
1462                    TCGv_i32 t1 = tcg_temp_new_i32();
1463
1464                    tcg_gen_trunc_tl_i32(t1, t0);
1465                    tcg_gen_rotri_i32(t1, t1, uimm);
1466                    tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
1467                    tcg_temp_free_i32(t1);
1468                }
1469                opn = "rotr";
1470            } else {
1471                if (uimm != 0) {
1472                    tcg_gen_ext32u_tl(t0, t0);
1473                    tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1474                } else {
1475                    tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1476                }
1477                opn = "srl";
1478            }
1479            break;
1480        default:
1481            MIPS_INVAL("invalid srl flag");
1482            generate_exception(ctx, EXCP_RI);
1483            break;
1484        }
1485        break;
1486#if defined(TARGET_MIPS64)
1487    case OPC_DSLL:
1488        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
1489        opn = "dsll";
1490        break;
1491    case OPC_DSRA:
1492        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1493        opn = "dsra";
1494        break;
1495    case OPC_DSRL:
1496        switch ((ctx->opcode >> 21) & 0x1f) {
1497        case 0:
1498            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1499            opn = "dsrl";
1500            break;
1501        case 1:
1502            /* drotr is decoded as dsrl on non-R2 CPUs */
1503            if (env->insn_flags & ISA_MIPS32R2) {
1504                if (uimm != 0) {
1505                    tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
1506                }
1507                opn = "drotr";
1508            } else {
1509                tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
1510                opn = "dsrl";
1511            }
1512            break;
1513        default:
1514            MIPS_INVAL("invalid dsrl flag");
1515            generate_exception(ctx, EXCP_RI);
1516            break;
1517        }
1518        break;
1519    case OPC_DSLL32:
1520        tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
1521        opn = "dsll32";
1522        break;
1523    case OPC_DSRA32:
1524        tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
1525        opn = "dsra32";
1526        break;
1527    case OPC_DSRL32:
1528        switch ((ctx->opcode >> 21) & 0x1f) {
1529        case 0:
1530            tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
1531            opn = "dsrl32";
1532            break;
1533        case 1:
1534            /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
1535            if (env->insn_flags & ISA_MIPS32R2) {
1536                tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
1537                opn = "drotr32";
1538            } else {
1539                tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
1540                opn = "dsrl32";
1541            }
1542            break;
1543        default:
1544            MIPS_INVAL("invalid dsrl32 flag");
1545            generate_exception(ctx, EXCP_RI);
1546            break;
1547        }
1548        break;
1549#endif
1550    }
1551    MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1552    tcg_temp_free(t0);
1553}
1554
1555/* Arithmetic */
1556static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1557                       int rd, int rs, int rt)
1558{
1559    const char *opn = "arith";
1560
1561    if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
1562       && opc != OPC_DADD && opc != OPC_DSUB) {
1563        /* If no destination, treat it as a NOP.
1564           For add & sub, we must generate the overflow exception when needed. */
1565        MIPS_DEBUG("NOP");
1566        return;
1567    }
1568
1569    switch (opc) {
1570    case OPC_ADD:
1571        {
1572            TCGv t0 = tcg_temp_local_new();
1573            TCGv t1 = tcg_temp_new();
1574            TCGv t2 = tcg_temp_new();
1575            int l1 = gen_new_label();
1576
1577            gen_load_gpr(t1, rs);
1578            gen_load_gpr(t2, rt);
1579            tcg_gen_add_tl(t0, t1, t2);
1580            tcg_gen_ext32s_tl(t0, t0);
1581            tcg_gen_xor_tl(t1, t1, t2);
1582            tcg_gen_not_tl(t1, t1);
1583            tcg_gen_xor_tl(t2, t0, t2);
1584            tcg_gen_and_tl(t1, t1, t2);
1585            tcg_temp_free(t2);
1586            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1587            tcg_temp_free(t1);
1588            /* operands of same sign, result different sign */
1589            generate_exception(ctx, EXCP_OVERFLOW);
1590            gen_set_label(l1);
1591            gen_store_gpr(t0, rd);
1592            tcg_temp_free(t0);
1593        }
1594        opn = "add";
1595        break;
1596    case OPC_ADDU:
1597        if (rs != 0 && rt != 0) {
1598            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1599            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1600        } else if (rs == 0 && rt != 0) {
1601            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1602        } else if (rs != 0 && rt == 0) {
1603            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1604        } else {
1605            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1606        }
1607        opn = "addu";
1608        break;
1609    case OPC_SUB:
1610        {
1611            TCGv t0 = tcg_temp_local_new();
1612            TCGv t1 = tcg_temp_new();
1613            TCGv t2 = tcg_temp_new();
1614            int l1 = gen_new_label();
1615
1616            gen_load_gpr(t1, rs);
1617            gen_load_gpr(t2, rt);
1618            tcg_gen_sub_tl(t0, t1, t2);
1619            tcg_gen_ext32s_tl(t0, t0);
1620            tcg_gen_xor_tl(t2, t1, t2);
1621            tcg_gen_xor_tl(t1, t0, t1);
1622            tcg_gen_and_tl(t1, t1, t2);
1623            tcg_temp_free(t2);
1624            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1625            tcg_temp_free(t1);
1626            /* operands of different sign, first operand and result different sign */
1627            generate_exception(ctx, EXCP_OVERFLOW);
1628            gen_set_label(l1);
1629            gen_store_gpr(t0, rd);
1630            tcg_temp_free(t0);
1631        }
1632        opn = "sub";
1633        break;
1634    case OPC_SUBU:
1635        if (rs != 0 && rt != 0) {
1636            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1637            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1638        } else if (rs == 0 && rt != 0) {
1639            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1640            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1641        } else if (rs != 0 && rt == 0) {
1642            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1643        } else {
1644            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1645        }
1646        opn = "subu";
1647        break;
1648#if defined(TARGET_MIPS64)
1649    case OPC_DADD:
1650        {
1651            TCGv t0 = tcg_temp_local_new();
1652            TCGv t1 = tcg_temp_new();
1653            TCGv t2 = tcg_temp_new();
1654            int l1 = gen_new_label();
1655
1656            gen_load_gpr(t1, rs);
1657            gen_load_gpr(t2, rt);
1658            tcg_gen_add_tl(t0, t1, t2);
1659            tcg_gen_xor_tl(t1, t1, t2);
1660            tcg_gen_not_tl(t1, t1);
1661            tcg_gen_xor_tl(t2, t0, t2);
1662            tcg_gen_and_tl(t1, t1, t2);
1663            tcg_temp_free(t2);
1664            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1665            tcg_temp_free(t1);
1666            /* operands of same sign, result different sign */
1667            generate_exception(ctx, EXCP_OVERFLOW);
1668            gen_set_label(l1);
1669            gen_store_gpr(t0, rd);
1670            tcg_temp_free(t0);
1671        }
1672        opn = "dadd";
1673        break;
1674    case OPC_DADDU:
1675        if (rs != 0 && rt != 0) {
1676            tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1677        } else if (rs == 0 && rt != 0) {
1678            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1679        } else if (rs != 0 && rt == 0) {
1680            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1681        } else {
1682            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1683        }
1684        opn = "daddu";
1685        break;
1686    case OPC_DSUB:
1687        {
1688            TCGv t0 = tcg_temp_local_new();
1689            TCGv t1 = tcg_temp_new();
1690            TCGv t2 = tcg_temp_new();
1691            int l1 = gen_new_label();
1692
1693            gen_load_gpr(t1, rs);
1694            gen_load_gpr(t2, rt);
1695            tcg_gen_sub_tl(t0, t1, t2);
1696            tcg_gen_xor_tl(t2, t1, t2);
1697            tcg_gen_xor_tl(t1, t0, t1);
1698            tcg_gen_and_tl(t1, t1, t2);
1699            tcg_temp_free(t2);
1700            tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
1701            tcg_temp_free(t1);
1702            /* operands of different sign, first operand and result different sign */
1703            generate_exception(ctx, EXCP_OVERFLOW);
1704            gen_set_label(l1);
1705            gen_store_gpr(t0, rd);
1706            tcg_temp_free(t0);
1707        }
1708        opn = "dsub";
1709        break;
1710    case OPC_DSUBU:
1711        if (rs != 0 && rt != 0) {
1712            tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1713        } else if (rs == 0 && rt != 0) {
1714            tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
1715        } else if (rs != 0 && rt == 0) {
1716            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1717        } else {
1718            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1719        }
1720        opn = "dsubu";
1721        break;
1722#endif
1723    case OPC_MUL:
1724        if (likely(rs != 0 && rt != 0)) {
1725            tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1726            tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
1727        } else {
1728            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1729        }
1730        opn = "mul";
1731        break;
1732    }
1733    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1734}
1735
1736/* Conditional move */
1737static void gen_cond_move (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1738{
1739    const char *opn = "cond move";
1740    int l1;
1741
1742    if (rd == 0) {
1743        /* If no destination, treat it as a NOP.
1744           For add & sub, we must generate the overflow exception when needed. */
1745        MIPS_DEBUG("NOP");
1746        return;
1747    }
1748
1749    l1 = gen_new_label();
1750    switch (opc) {
1751    case OPC_MOVN:
1752        if (likely(rt != 0))
1753            tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
1754        else
1755            tcg_gen_br(l1);
1756        opn = "movn";
1757        break;
1758    case OPC_MOVZ:
1759        if (likely(rt != 0))
1760            tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
1761        opn = "movz";
1762        break;
1763    }
1764    if (rs != 0)
1765        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1766    else
1767        tcg_gen_movi_tl(cpu_gpr[rd], 0);
1768    gen_set_label(l1);
1769
1770    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1771}
1772
1773/* Logic */
1774static void gen_logic (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1775{
1776    const char *opn = "logic";
1777
1778    if (rd == 0) {
1779        /* If no destination, treat it as a NOP. */
1780        MIPS_DEBUG("NOP");
1781        return;
1782    }
1783
1784    switch (opc) {
1785    case OPC_AND:
1786        if (likely(rs != 0 && rt != 0)) {
1787            tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1788        } else {
1789            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1790        }
1791        opn = "and";
1792        break;
1793    case OPC_NOR:
1794        if (rs != 0 && rt != 0) {
1795            tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1796        } else if (rs == 0 && rt != 0) {
1797            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
1798        } else if (rs != 0 && rt == 0) {
1799            tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
1800        } else {
1801            tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
1802        }
1803        opn = "nor";
1804        break;
1805    case OPC_OR:
1806        if (likely(rs != 0 && rt != 0)) {
1807            tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1808        } else if (rs == 0 && rt != 0) {
1809            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1810        } else if (rs != 0 && rt == 0) {
1811            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1812        } else {
1813            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1814        }
1815        opn = "or";
1816        break;
1817    case OPC_XOR:
1818        if (likely(rs != 0 && rt != 0)) {
1819            tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
1820        } else if (rs == 0 && rt != 0) {
1821            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
1822        } else if (rs != 0 && rt == 0) {
1823            tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
1824        } else {
1825            tcg_gen_movi_tl(cpu_gpr[rd], 0);
1826        }
1827        opn = "xor";
1828        break;
1829    }
1830    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1831}
1832
1833/* Set on lower than */
1834static void gen_slt (CPUState *env, uint32_t opc, int rd, int rs, int rt)
1835{
1836    const char *opn = "slt";
1837    TCGv t0, t1;
1838
1839    if (rd == 0) {
1840        /* If no destination, treat it as a NOP. */
1841        MIPS_DEBUG("NOP");
1842        return;
1843    }
1844
1845    t0 = tcg_temp_new();
1846    t1 = tcg_temp_new();
1847    gen_load_gpr(t0, rs);
1848    gen_load_gpr(t1, rt);
1849    switch (opc) {
1850    case OPC_SLT:
1851        gen_op_lt(cpu_gpr[rd], t0, t1);
1852        opn = "slt";
1853        break;
1854    case OPC_SLTU:
1855        gen_op_ltu(cpu_gpr[rd], t0, t1);
1856        opn = "sltu";
1857        break;
1858    }
1859    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1860    tcg_temp_free(t0);
1861    tcg_temp_free(t1);
1862}
1863
1864/* Shifts */
1865static void gen_shift (CPUState *env, DisasContext *ctx, uint32_t opc,
1866                       int rd, int rs, int rt)
1867{
1868    const char *opn = "shifts";
1869    TCGv t0, t1;
1870
1871    if (rd == 0) {
1872        /* If no destination, treat it as a NOP.
1873           For add & sub, we must generate the overflow exception when needed. */
1874        MIPS_DEBUG("NOP");
1875        return;
1876    }
1877
1878    t0 = tcg_temp_new();
1879    t1 = tcg_temp_new();
1880    gen_load_gpr(t0, rs);
1881    gen_load_gpr(t1, rt);
1882    switch (opc) {
1883    case OPC_SLLV:
1884        tcg_gen_andi_tl(t0, t0, 0x1f);
1885        tcg_gen_shl_tl(t0, t1, t0);
1886        tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1887        opn = "sllv";
1888        break;
1889    case OPC_SRAV:
1890        tcg_gen_ext32s_tl(t1, t1);
1891        tcg_gen_andi_tl(t0, t0, 0x1f);
1892        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1893        opn = "srav";
1894        break;
1895    case OPC_SRLV:
1896        switch ((ctx->opcode >> 6) & 0x1f) {
1897        case 0:
1898            tcg_gen_ext32u_tl(t1, t1);
1899            tcg_gen_andi_tl(t0, t0, 0x1f);
1900            tcg_gen_shr_tl(t0, t1, t0);
1901            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1902            opn = "srlv";
1903            break;
1904        case 1:
1905            /* rotrv is decoded as srlv on non-R2 CPUs */
1906            if (env->insn_flags & ISA_MIPS32R2) {
1907                TCGv_i32 t2 = tcg_temp_new_i32();
1908                TCGv_i32 t3 = tcg_temp_new_i32();
1909
1910                tcg_gen_trunc_tl_i32(t2, t0);
1911                tcg_gen_trunc_tl_i32(t3, t1);
1912                tcg_gen_andi_i32(t2, t2, 0x1f);
1913                tcg_gen_rotr_i32(t2, t3, t2);
1914                tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
1915                tcg_temp_free_i32(t2);
1916                tcg_temp_free_i32(t3);
1917                opn = "rotrv";
1918            } else {
1919                tcg_gen_ext32u_tl(t1, t1);
1920                tcg_gen_andi_tl(t0, t0, 0x1f);
1921                tcg_gen_shr_tl(t0, t1, t0);
1922                tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1923                opn = "srlv";
1924            }
1925            break;
1926        default:
1927            MIPS_INVAL("invalid srlv flag");
1928            generate_exception(ctx, EXCP_RI);
1929            break;
1930        }
1931        break;
1932#if defined(TARGET_MIPS64)
1933    case OPC_DSLLV:
1934        tcg_gen_andi_tl(t0, t0, 0x3f);
1935        tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
1936        opn = "dsllv";
1937        break;
1938    case OPC_DSRAV:
1939        tcg_gen_andi_tl(t0, t0, 0x3f);
1940        tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1941        opn = "dsrav";
1942        break;
1943    case OPC_DSRLV:
1944        switch ((ctx->opcode >> 6) & 0x1f) {
1945        case 0:
1946            tcg_gen_andi_tl(t0, t0, 0x3f);
1947            tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
1948            opn = "dsrlv";
1949            break;
1950        case 1:
1951            /* drotrv is decoded as dsrlv on non-R2 CPUs */
1952            if (env->insn_flags & ISA_MIPS32R2) {
1953                tcg_gen_andi_tl(t0, t0, 0x3f);
1954                tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
1955                opn = "drotrv";
1956            } else {
1957                tcg_gen_andi_tl(t0, t0, 0x3f);
1958                tcg_gen_shr_tl(t0, t1, t0);
1959                opn = "dsrlv";
1960            }
1961            break;
1962        default:
1963            MIPS_INVAL("invalid dsrlv flag");
1964            generate_exception(ctx, EXCP_RI);
1965            break;
1966        }
1967        break;
1968#endif
1969    }
1970    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1971    tcg_temp_free(t0);
1972    tcg_temp_free(t1);
1973}
1974
1975/* Arithmetic on HI/LO registers */
1976static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1977{
1978    const char *opn = "hilo";
1979
1980    if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1981        /* Treat as NOP. */
1982        MIPS_DEBUG("NOP");
1983        return;
1984    }
1985    switch (opc) {
1986    case OPC_MFHI:
1987        tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1988        opn = "mfhi";
1989        break;
1990    case OPC_MFLO:
1991        tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1992        opn = "mflo";
1993        break;
1994    case OPC_MTHI:
1995        if (reg != 0)
1996            tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
1997        else
1998            tcg_gen_movi_tl(cpu_HI[0], 0);
1999        opn = "mthi";
2000        break;
2001    case OPC_MTLO:
2002        if (reg != 0)
2003            tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
2004        else
2005            tcg_gen_movi_tl(cpu_LO[0], 0);
2006        opn = "mtlo";
2007        break;
2008    }
2009    MIPS_DEBUG("%s %s", opn, regnames[reg]);
2010}
2011
2012static void gen_muldiv (DisasContext *ctx, uint32_t opc,
2013                        int rs, int rt)
2014{
2015    const char *opn = "mul/div";
2016    TCGv t0, t1;
2017
2018    switch (opc) {
2019    case OPC_DIV:
2020    case OPC_DIVU:
2021#if defined(TARGET_MIPS64)
2022    case OPC_DDIV:
2023    case OPC_DDIVU:
2024#endif
2025        t0 = tcg_temp_local_new();
2026        t1 = tcg_temp_local_new();
2027        break;
2028    default:
2029        t0 = tcg_temp_new();
2030        t1 = tcg_temp_new();
2031        break;
2032    }
2033
2034    gen_load_gpr(t0, rs);
2035    gen_load_gpr(t1, rt);
2036    switch (opc) {
2037    case OPC_DIV:
2038        {
2039            int l1 = gen_new_label();
2040            int l2 = gen_new_label();
2041
2042            tcg_gen_ext32s_tl(t0, t0);
2043            tcg_gen_ext32s_tl(t1, t1);
2044            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2045            tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
2046            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
2047
2048            tcg_gen_mov_tl(cpu_LO[0], t0);
2049            tcg_gen_movi_tl(cpu_HI[0], 0);
2050            tcg_gen_br(l1);
2051            gen_set_label(l2);
2052            tcg_gen_div_tl(cpu_LO[0], t0, t1);
2053            tcg_gen_rem_tl(cpu_HI[0], t0, t1);
2054            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2055            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2056            gen_set_label(l1);
2057        }
2058        opn = "div";
2059        break;
2060    case OPC_DIVU:
2061        {
2062            int l1 = gen_new_label();
2063
2064            tcg_gen_ext32u_tl(t0, t0);
2065            tcg_gen_ext32u_tl(t1, t1);
2066            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2067            tcg_gen_divu_tl(cpu_LO[0], t0, t1);
2068            tcg_gen_remu_tl(cpu_HI[0], t0, t1);
2069            tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
2070            tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
2071            gen_set_label(l1);
2072        }
2073        opn = "divu";
2074        break;
2075    case OPC_MULT:
2076        {
2077            TCGv_i64 t2 = tcg_temp_new_i64();
2078            TCGv_i64 t3 = tcg_temp_new_i64();
2079
2080            tcg_gen_ext_tl_i64(t2, t0);
2081            tcg_gen_ext_tl_i64(t3, t1);
2082            tcg_gen_mul_i64(t2, t2, t3);
2083            tcg_temp_free_i64(t3);
2084            tcg_gen_trunc_i64_tl(t0, t2);
2085            tcg_gen_shri_i64(t2, t2, 32);
2086            tcg_gen_trunc_i64_tl(t1, t2);
2087            tcg_temp_free_i64(t2);
2088            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2089            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2090        }
2091        opn = "mult";
2092        break;
2093    case OPC_MULTU:
2094        {
2095            TCGv_i64 t2 = tcg_temp_new_i64();
2096            TCGv_i64 t3 = tcg_temp_new_i64();
2097
2098            tcg_gen_ext32u_tl(t0, t0);
2099            tcg_gen_ext32u_tl(t1, t1);
2100            tcg_gen_extu_tl_i64(t2, t0);
2101            tcg_gen_extu_tl_i64(t3, t1);
2102            tcg_gen_mul_i64(t2, t2, t3);
2103            tcg_temp_free_i64(t3);
2104            tcg_gen_trunc_i64_tl(t0, t2);
2105            tcg_gen_shri_i64(t2, t2, 32);
2106            tcg_gen_trunc_i64_tl(t1, t2);
2107            tcg_temp_free_i64(t2);
2108            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2109            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2110        }
2111        opn = "multu";
2112        break;
2113#if defined(TARGET_MIPS64)
2114    case OPC_DDIV:
2115        {
2116            int l1 = gen_new_label();
2117            int l2 = gen_new_label();
2118
2119            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2120            tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
2121            tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
2122            tcg_gen_mov_tl(cpu_LO[0], t0);
2123            tcg_gen_movi_tl(cpu_HI[0], 0);
2124            tcg_gen_br(l1);
2125            gen_set_label(l2);
2126            tcg_gen_div_i64(cpu_LO[0], t0, t1);
2127            tcg_gen_rem_i64(cpu_HI[0], t0, t1);
2128            gen_set_label(l1);
2129        }
2130        opn = "ddiv";
2131        break;
2132    case OPC_DDIVU:
2133        {
2134            int l1 = gen_new_label();
2135
2136            tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
2137            tcg_gen_divu_i64(cpu_LO[0], t0, t1);
2138            tcg_gen_remu_i64(cpu_HI[0], t0, t1);
2139            gen_set_label(l1);
2140        }
2141        opn = "ddivu";
2142        break;
2143    case OPC_DMULT:
2144        gen_helper_dmult(t0, t1);
2145        opn = "dmult";
2146        break;
2147    case OPC_DMULTU:
2148        gen_helper_dmultu(t0, t1);
2149        opn = "dmultu";
2150        break;
2151#endif
2152    case OPC_MADD:
2153        {
2154            TCGv_i64 t2 = tcg_temp_new_i64();
2155            TCGv_i64 t3 = tcg_temp_new_i64();
2156
2157            tcg_gen_ext_tl_i64(t2, t0);
2158            tcg_gen_ext_tl_i64(t3, t1);
2159            tcg_gen_mul_i64(t2, t2, t3);
2160            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2161            tcg_gen_add_i64(t2, t2, t3);
2162            tcg_temp_free_i64(t3);
2163            tcg_gen_trunc_i64_tl(t0, t2);
2164            tcg_gen_shri_i64(t2, t2, 32);
2165            tcg_gen_trunc_i64_tl(t1, t2);
2166            tcg_temp_free_i64(t2);
2167            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2168            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2169        }
2170        opn = "madd";
2171        break;
2172    case OPC_MADDU:
2173       {
2174            TCGv_i64 t2 = tcg_temp_new_i64();
2175            TCGv_i64 t3 = tcg_temp_new_i64();
2176
2177            tcg_gen_ext32u_tl(t0, t0);
2178            tcg_gen_ext32u_tl(t1, t1);
2179            tcg_gen_extu_tl_i64(t2, t0);
2180            tcg_gen_extu_tl_i64(t3, t1);
2181            tcg_gen_mul_i64(t2, t2, t3);
2182            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2183            tcg_gen_add_i64(t2, t2, t3);
2184            tcg_temp_free_i64(t3);
2185            tcg_gen_trunc_i64_tl(t0, t2);
2186            tcg_gen_shri_i64(t2, t2, 32);
2187            tcg_gen_trunc_i64_tl(t1, t2);
2188            tcg_temp_free_i64(t2);
2189            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2190            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2191        }
2192        opn = "maddu";
2193        break;
2194    case OPC_MSUB:
2195        {
2196            TCGv_i64 t2 = tcg_temp_new_i64();
2197            TCGv_i64 t3 = tcg_temp_new_i64();
2198
2199            tcg_gen_ext_tl_i64(t2, t0);
2200            tcg_gen_ext_tl_i64(t3, t1);
2201            tcg_gen_mul_i64(t2, t2, t3);
2202            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2203            tcg_gen_sub_i64(t2, t3, t2);
2204            tcg_temp_free_i64(t3);
2205            tcg_gen_trunc_i64_tl(t0, t2);
2206            tcg_gen_shri_i64(t2, t2, 32);
2207            tcg_gen_trunc_i64_tl(t1, t2);
2208            tcg_temp_free_i64(t2);
2209            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2210            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2211        }
2212        opn = "msub";
2213        break;
2214    case OPC_MSUBU:
2215        {
2216            TCGv_i64 t2 = tcg_temp_new_i64();
2217            TCGv_i64 t3 = tcg_temp_new_i64();
2218
2219            tcg_gen_ext32u_tl(t0, t0);
2220            tcg_gen_ext32u_tl(t1, t1);
2221            tcg_gen_extu_tl_i64(t2, t0);
2222            tcg_gen_extu_tl_i64(t3, t1);
2223            tcg_gen_mul_i64(t2, t2, t3);
2224            tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
2225            tcg_gen_sub_i64(t2, t3, t2);
2226            tcg_temp_free_i64(t3);
2227            tcg_gen_trunc_i64_tl(t0, t2);
2228            tcg_gen_shri_i64(t2, t2, 32);
2229            tcg_gen_trunc_i64_tl(t1, t2);
2230            tcg_temp_free_i64(t2);
2231            tcg_gen_ext32s_tl(cpu_LO[0], t0);
2232            tcg_gen_ext32s_tl(cpu_HI[0], t1);
2233        }
2234        opn = "msubu";
2235        break;
2236    default:
2237        MIPS_INVAL(opn);
2238        generate_exception(ctx, EXCP_RI);
2239        goto out;
2240    }
2241    MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
2242 out:
2243    tcg_temp_free(t0);
2244    tcg_temp_free(t1);
2245}
2246
2247static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
2248                            int rd, int rs, int rt)
2249{
2250    const char *opn = "mul vr54xx";
2251    TCGv t0 = tcg_temp_new();
2252    TCGv t1 = tcg_temp_new();
2253
2254    gen_load_gpr(t0, rs);
2255    gen_load_gpr(t1, rt);
2256
2257    switch (opc) {
2258    case OPC_VR54XX_MULS:
2259        gen_helper_muls(t0, t0, t1);
2260        opn = "muls";
2261        break;
2262    case OPC_VR54XX_MULSU:
2263        gen_helper_mulsu(t0, t0, t1);
2264        opn = "mulsu";
2265        break;
2266    case OPC_VR54XX_MACC:
2267        gen_helper_macc(t0, t0, t1);
2268        opn = "macc";
2269        break;
2270    case OPC_VR54XX_MACCU:
2271        gen_helper_maccu(t0, t0, t1);
2272        opn = "maccu";
2273        break;
2274    case OPC_VR54XX_MSAC:
2275        gen_helper_msac(t0, t0, t1);
2276        opn = "msac";
2277        break;
2278    case OPC_VR54XX_MSACU:
2279        gen_helper_msacu(t0, t0, t1);
2280        opn = "msacu";
2281        break;
2282    case OPC_VR54XX_MULHI:
2283        gen_helper_mulhi(t0, t0, t1);
2284        opn = "mulhi";
2285        break;
2286    case OPC_VR54XX_MULHIU:
2287        gen_helper_mulhiu(t0, t0, t1);
2288        opn = "mulhiu";
2289        break;
2290    case OPC_VR54XX_MULSHI:
2291        gen_helper_mulshi(t0, t0, t1);
2292        opn = "mulshi";
2293        break;
2294    case OPC_VR54XX_MULSHIU:
2295        gen_helper_mulshiu(t0, t0, t1);
2296        opn = "mulshiu";
2297        break;
2298    case OPC_VR54XX_MACCHI:
2299        gen_helper_macchi(t0, t0, t1);
2300        opn = "macchi";
2301        break;
2302    case OPC_VR54XX_MACCHIU:
2303        gen_helper_macchiu(t0, t0, t1);
2304        opn = "macchiu";
2305        break;
2306    case OPC_VR54XX_MSACHI:
2307        gen_helper_msachi(t0, t0, t1);
2308        opn = "msachi";
2309        break;
2310    case OPC_VR54XX_MSACHIU:
2311        gen_helper_msachiu(t0, t0, t1);
2312        opn = "msachiu";
2313        break;
2314    default:
2315        MIPS_INVAL("mul vr54xx");
2316        generate_exception(ctx, EXCP_RI);
2317        goto out;
2318    }
2319    gen_store_gpr(t0, rd);
2320    MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
2321
2322 out:
2323    tcg_temp_free(t0);
2324    tcg_temp_free(t1);
2325}
2326
2327static void gen_cl (DisasContext *ctx, uint32_t opc,
2328                    int rd, int rs)
2329{
2330    const char *opn = "CLx";
2331    TCGv t0;
2332
2333    if (rd == 0) {
2334        /* Treat as NOP. */
2335        MIPS_DEBUG("NOP");
2336        return;
2337    }
2338    t0 = tcg_temp_new();
2339    gen_load_gpr(t0, rs);
2340    switch (opc) {
2341    case OPC_CLO:
2342        gen_helper_clo(cpu_gpr[rd], t0);
2343        opn = "clo";
2344        break;
2345    case OPC_CLZ:
2346        gen_helper_clz(cpu_gpr[rd], t0);
2347        opn = "clz";
2348        break;
2349#if defined(TARGET_MIPS64)
2350    case OPC_DCLO:
2351        gen_helper_dclo(cpu_gpr[rd], t0);
2352        opn = "dclo";
2353        break;
2354    case OPC_DCLZ:
2355        gen_helper_dclz(cpu_gpr[rd], t0);
2356        opn = "dclz";
2357        break;
2358#endif
2359    }
2360    MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
2361    tcg_temp_free(t0);
2362}
2363
2364/* Traps */
2365static void gen_trap (DisasContext *ctx, uint32_t opc,
2366                      int rs, int rt, int16_t imm)
2367{
2368    int cond;
2369    TCGv t0 = tcg_temp_new();
2370    TCGv t1 = tcg_temp_new();
2371
2372    cond = 0;
2373    /* Load needed operands */
2374    switch (opc) {
2375    case OPC_TEQ:
2376    case OPC_TGE:
2377    case OPC_TGEU:
2378    case OPC_TLT:
2379    case OPC_TLTU:
2380    case OPC_TNE:
2381        /* Compare two registers */
2382        if (rs != rt) {
2383            gen_load_gpr(t0, rs);
2384            gen_load_gpr(t1, rt);
2385            cond = 1;
2386        }
2387        break;
2388    case OPC_TEQI:
2389    case OPC_TGEI:
2390    case OPC_TGEIU:
2391    case OPC_TLTI:
2392    case OPC_TLTIU:
2393    case OPC_TNEI:
2394        /* Compare register to immediate */
2395        if (rs != 0 || imm != 0) {
2396            gen_load_gpr(t0, rs);
2397            tcg_gen_movi_tl(t1, (int32_t)imm);
2398            cond = 1;
2399        }
2400        break;
2401    }
2402    if (cond == 0) {
2403        switch (opc) {
2404        case OPC_TEQ:   /* rs == rs */
2405        case OPC_TEQI:  /* r0 == 0  */
2406        case OPC_TGE:   /* rs >= rs */
2407        case OPC_TGEI:  /* r0 >= 0  */
2408        case OPC_TGEU:  /* rs >= rs unsigned */
2409        case OPC_TGEIU: /* r0 >= 0  unsigned */
2410            /* Always trap */
2411            generate_exception(ctx, EXCP_TRAP);
2412            break;
2413        case OPC_TLT:   /* rs < rs           */
2414        case OPC_TLTI:  /* r0 < 0            */
2415        case OPC_TLTU:  /* rs < rs unsigned  */
2416        case OPC_TLTIU: /* r0 < 0  unsigned  */
2417        case OPC_TNE:   /* rs != rs          */
2418        case OPC_TNEI:  /* r0 != 0           */
2419            /* Never trap: treat as NOP. */
2420            break;
2421        }
2422    } else {
2423        int l1 = gen_new_label();
2424
2425        switch (opc) {
2426        case OPC_TEQ:
2427        case OPC_TEQI:
2428            tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
2429            break;
2430        case OPC_TGE:
2431        case OPC_TGEI:
2432            tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
2433            break;
2434        case OPC_TGEU:
2435        case OPC_TGEIU:
2436            tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
2437            break;
2438        case OPC_TLT:
2439        case OPC_TLTI:
2440            tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
2441            break;
2442        case OPC_TLTU:
2443        case OPC_TLTIU:
2444            tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
2445            break;
2446        case OPC_TNE:
2447        case OPC_TNEI:
2448            tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
2449            break;
2450        }
2451        generate_exception(ctx, EXCP_TRAP);
2452        gen_set_label(l1);
2453    }
2454    tcg_temp_free(t0);
2455    tcg_temp_free(t1);
2456}
2457
2458static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
2459{
2460    TranslationBlock *tb;
2461    tb = ctx->tb;
2462    if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
2463        tcg_gen_goto_tb(n);
2464        gen_save_pc(dest);
2465        tcg_gen_exit_tb((long)tb + n);
2466    } else {
2467        gen_save_pc(dest);
2468        tcg_gen_exit_tb(0);
2469    }
2470}
2471
2472/* Branches (before delay slot) */
2473static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
2474                                int rs, int rt, int32_t offset)
2475{
2476    target_ulong btgt = -1;
2477    int blink = 0;
2478    int bcond_compute = 0;
2479    TCGv t0 = tcg_temp_new();
2480    TCGv t1 = tcg_temp_new();
2481
2482    if (ctx->hflags & MIPS_HFLAG_BMASK) {
2483#ifdef MIPS_DEBUG_DISAS
2484        LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
2485#endif
2486        generate_exception(ctx, EXCP_RI);
2487        goto out;
2488    }
2489
2490    /* Load needed operands */
2491    switch (opc) {
2492    case OPC_BEQ:
2493    case OPC_BEQL:
2494    case OPC_BNE:
2495    case OPC_BNEL:
2496        /* Compare two registers */
2497        if (rs != rt) {
2498            gen_load_gpr(t0, rs);
2499            gen_load_gpr(t1, rt);
2500            bcond_compute = 1;
2501        }
2502        btgt = ctx->pc + 4 + offset;
2503        break;
2504    case OPC_BGEZ:
2505    case OPC_BGEZAL:
2506    case OPC_BGEZALL:
2507    case OPC_BGEZL:
2508    case OPC_BGTZ:
2509    case OPC_BGTZL:
2510    case OPC_BLEZ:
2511    case OPC_BLEZL:
2512    case OPC_BLTZ:
2513    case OPC_BLTZAL:
2514    case OPC_BLTZALL:
2515    case OPC_BLTZL:
2516        /* Compare to zero */
2517        if (rs != 0) {
2518            gen_load_gpr(t0, rs);
2519            bcond_compute = 1;
2520        }
2521        btgt = ctx->pc + 4 + offset;
2522        break;
2523    case OPC_J:
2524    case OPC_JAL:
2525        /* Jump to immediate */
2526        btgt = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
2527        break;
2528    case OPC_JR:
2529    case OPC_JALR:
2530        /* Jump to register */
2531        if (offset != 0 && offset != 16) {
2532            /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
2533               others are reserved. */
2534            MIPS_INVAL("jump hint");
2535            generate_exception(ctx, EXCP_RI);
2536            goto out;
2537        }
2538        gen_load_gpr(btarget, rs);
2539        break;
2540    default:
2541        MIPS_INVAL("branch/jump");
2542        generate_exception(ctx, EXCP_RI);
2543        goto out;
2544    }
2545    if (bcond_compute == 0) {
2546        /* No condition to be computed */
2547        switch (opc) {
2548        case OPC_BEQ:     /* rx == rx        */
2549        case OPC_BEQL:    /* rx == rx likely */
2550        case OPC_BGEZ:    /* 0 >= 0          */
2551        case OPC_BGEZL:   /* 0 >= 0 likely   */
2552        case OPC_BLEZ:    /* 0 <= 0          */
2553        case OPC_BLEZL:   /* 0 <= 0 likely   */
2554            /* Always take */
2555            ctx->hflags |= MIPS_HFLAG_B;
2556            MIPS_DEBUG("balways");
2557            break;
2558        case OPC_BGEZAL:  /* 0 >= 0          */
2559        case OPC_BGEZALL: /* 0 >= 0 likely   */
2560            /* Always take and link */
2561            blink = 31;
2562            ctx->hflags |= MIPS_HFLAG_B;
2563            MIPS_DEBUG("balways and link");
2564            break;
2565        case OPC_BNE:     /* rx != rx        */
2566        case OPC_BGTZ:    /* 0 > 0           */
2567        case OPC_BLTZ:    /* 0 < 0           */
2568            /* Treat as NOP. */
2569            MIPS_DEBUG("bnever (NOP)");
2570            goto out;
2571        case OPC_BLTZAL:  /* 0 < 0           */
2572            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
2573            MIPS_DEBUG("bnever and link");
2574            goto out;
2575        case OPC_BLTZALL: /* 0 < 0 likely */
2576            tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
2577            /* Skip the instruction in the delay slot */
2578            MIPS_DEBUG("bnever, link and skip");
2579            ctx->pc += 4;
2580            goto out;
2581        case OPC_BNEL:    /* rx != rx likely */
2582        case OPC_BGTZL:   /* 0 > 0 likely */
2583        case OPC_BLTZL:   /* 0 < 0 likely */
2584            /* Skip the instruction in the delay slot */
2585            MIPS_DEBUG("bnever and skip");
2586            ctx->pc += 4;
2587            goto out;
2588        case OPC_J:
2589            ctx->hflags |= MIPS_HFLAG_B;
2590            MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
2591            break;
2592        case OPC_JAL:
2593            blink = 31;
2594            ctx->hflags |= MIPS_HFLAG_B;
2595            MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
2596            break;
2597        case OPC_JR:
2598            ctx->hflags |= MIPS_HFLAG_BR;
2599            MIPS_DEBUG("jr %s", regnames[rs]);
2600            break;
2601        case OPC_JALR:
2602            blink = rt;
2603            ctx->hflags |= MIPS_HFLAG_BR;
2604            MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
2605            break;
2606        default:
2607            MIPS_INVAL("branch/jump");
2608            generate_exception(ctx, EXCP_RI);
2609            goto out;
2610        }
2611    } else {
2612        switch (opc) {
2613        case OPC_BEQ:
2614            gen_op_eq(bcond, t0, t1);
2615            MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
2616                       regnames[rs], regnames[rt], btgt);
2617            goto not_likely;
2618        case OPC_BEQL:
2619            gen_op_eq(bcond, t0, t1);
2620            MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
2621                       regnames[rs], regnames[rt], btgt);
2622            goto likely;
2623        case OPC_BNE:
2624            gen_op_ne(bcond, t0, t1);
2625            MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
2626                       regnames[rs], regnames[rt], btgt);
2627            goto not_likely;
2628        case OPC_BNEL:
2629            gen_op_ne(bcond, t0, t1);
2630            MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
2631                       regnames[rs], regnames[rt], btgt);
2632            goto likely;
2633        case OPC_BGEZ:
2634            gen_op_gez(bcond, t0);
2635            MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2636            goto not_likely;
2637        case OPC_BGEZL:
2638            gen_op_gez(bcond, t0);
2639            MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2640            goto likely;
2641        case OPC_BGEZAL:
2642            gen_op_gez(bcond, t0);
2643            MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2644            blink = 31;
2645            goto not_likely;
2646        case OPC_BGEZALL:
2647            gen_op_gez(bcond, t0);
2648            blink = 31;
2649            MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2650            goto likely;
2651        case OPC_BGTZ:
2652            gen_op_gtz(bcond, t0);
2653            MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2654            goto not_likely;
2655        case OPC_BGTZL:
2656            gen_op_gtz(bcond, t0);
2657            MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2658            goto likely;
2659        case OPC_BLEZ:
2660            gen_op_lez(bcond, t0);
2661            MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
2662            goto not_likely;
2663        case OPC_BLEZL:
2664            gen_op_lez(bcond, t0);
2665            MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2666            goto likely;
2667        case OPC_BLTZ:
2668            gen_op_ltz(bcond, t0);
2669            MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
2670            goto not_likely;
2671        case OPC_BLTZL:
2672            gen_op_ltz(bcond, t0);
2673            MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
2674            goto likely;
2675        case OPC_BLTZAL:
2676            gen_op_ltz(bcond, t0);
2677            blink = 31;
2678            MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
2679        not_likely:
2680            ctx->hflags |= MIPS_HFLAG_BC;
2681            break;
2682        case OPC_BLTZALL:
2683            gen_op_ltz(bcond, t0);
2684            blink = 31;
2685            MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
2686        likely:
2687            ctx->hflags |= MIPS_HFLAG_BL;
2688            break;
2689        default:
2690            MIPS_INVAL("conditional branch/jump");
2691            generate_exception(ctx, EXCP_RI);
2692            goto out;
2693        }
2694    }
2695    MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
2696               blink, ctx->hflags, btgt);
2697
2698    ctx->btarget = btgt;
2699    if (blink > 0) {
2700        tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + 8);
2701    }
2702
2703 out:
2704    tcg_temp_free(t0);
2705    tcg_temp_free(t1);
2706}
2707
2708/* special3 bitfield operations */
2709static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
2710                        int rs, int lsb, int msb)
2711{
2712    TCGv t0 = tcg_temp_new();
2713    TCGv t1 = tcg_temp_new();
2714    target_ulong mask;
2715
2716    gen_load_gpr(t1, rs);
2717    switch (opc) {
2718    case OPC_EXT:
2719        if (lsb + msb > 31)
2720            goto fail;
2721        tcg_gen_shri_tl(t0, t1, lsb);
2722        if (msb != 31) {
2723            tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
2724        } else {
2725            tcg_gen_ext32s_tl(t0, t0);
2726        }
2727        break;
2728#if defined(TARGET_MIPS64)
2729    case OPC_DEXTM:
2730        tcg_gen_shri_tl(t0, t1, lsb);
2731        if (msb != 31) {
2732            tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
2733        }
2734        break;
2735    case OPC_DEXTU:
2736        tcg_gen_shri_tl(t0, t1, lsb + 32);
2737        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2738        break;
2739    case OPC_DEXT:
2740        tcg_gen_shri_tl(t0, t1, lsb);
2741        tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
2742        break;
2743#endif
2744    case OPC_INS:
2745        if (lsb > msb)
2746            goto fail;
2747        mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
2748        gen_load_gpr(t0, rt);
2749        tcg_gen_andi_tl(t0, t0, ~mask);
2750        tcg_gen_shli_tl(t1, t1, lsb);
2751        tcg_gen_andi_tl(t1, t1, mask);
2752        tcg_gen_or_tl(t0, t0, t1);
2753        tcg_gen_ext32s_tl(t0, t0);
2754        break;
2755#if defined(TARGET_MIPS64)
2756    case OPC_DINSM:
2757        if (lsb > msb)
2758            goto fail;
2759        mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
2760        gen_load_gpr(t0, rt);
2761        tcg_gen_andi_tl(t0, t0, ~mask);
2762        tcg_gen_shli_tl(t1, t1, lsb);
2763        tcg_gen_andi_tl(t1, t1, mask);
2764        tcg_gen_or_tl(t0, t0, t1);
2765        break;
2766    case OPC_DINSU:
2767        if (lsb > msb)
2768            goto fail;
2769        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2770        gen_load_gpr(t0, rt);
2771        tcg_gen_andi_tl(t0, t0, ~mask);
2772        tcg_gen_shli_tl(t1, t1, lsb + 32);
2773        tcg_gen_andi_tl(t1, t1, mask);
2774        tcg_gen_or_tl(t0, t0, t1);
2775        break;
2776    case OPC_DINS:
2777        if (lsb > msb)
2778            goto fail;
2779        gen_load_gpr(t0, rt);
2780        mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
2781        gen_load_gpr(t0, rt);
2782        tcg_gen_andi_tl(t0, t0, ~mask);
2783        tcg_gen_shli_tl(t1, t1, lsb);
2784        tcg_gen_andi_tl(t1, t1, mask);
2785        tcg_gen_or_tl(t0, t0, t1);
2786        break;
2787#endif
2788    default:
2789fail:
2790        MIPS_INVAL("bitops");
2791        generate_exception(ctx, EXCP_RI);
2792        tcg_temp_free(t0);
2793        tcg_temp_free(t1);
2794        return;
2795    }
2796    gen_store_gpr(t0, rt);
2797    tcg_temp_free(t0);
2798    tcg_temp_free(t1);
2799}
2800
2801static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
2802{
2803    TCGv t0;
2804
2805    if (rd == 0) {
2806        /* If no destination, treat it as a NOP. */
2807        MIPS_DEBUG("NOP");
2808        return;
2809    }
2810
2811    t0 = tcg_temp_new();
2812    gen_load_gpr(t0, rt);
2813    switch (op2) {
2814    case OPC_WSBH:
2815        {
2816            TCGv t1 = tcg_temp_new();
2817
2818            tcg_gen_shri_tl(t1, t0, 8);
2819            tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
2820            tcg_gen_shli_tl(t0, t0, 8);
2821            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
2822            tcg_gen_or_tl(t0, t0, t1);
2823            tcg_temp_free(t1);
2824            tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
2825        }
2826        break;
2827    case OPC_SEB:
2828        tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
2829        break;
2830    case OPC_SEH:
2831        tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
2832        break;
2833#if defined(TARGET_MIPS64)
2834    case OPC_DSBH:
2835        {
2836            TCGv t1 = tcg_temp_new();
2837
2838            tcg_gen_shri_tl(t1, t0, 8);
2839            tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
2840            tcg_gen_shli_tl(t0, t0, 8);
2841            tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
2842            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2843            tcg_temp_free(t1);
2844        }
2845        break;
2846    case OPC_DSHD:
2847        {
2848            TCGv t1 = tcg_temp_new();
2849
2850            tcg_gen_shri_tl(t1, t0, 16);
2851            tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
2852            tcg_gen_shli_tl(t0, t0, 16);
2853            tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
2854            tcg_gen_or_tl(t0, t0, t1);
2855            tcg_gen_shri_tl(t1, t0, 32);
2856            tcg_gen_shli_tl(t0, t0, 32);
2857            tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
2858            tcg_temp_free(t1);
2859        }
2860        break;
2861#endif
2862    default:
2863        MIPS_INVAL("bsfhl");
2864        generate_exception(ctx, EXCP_RI);
2865        tcg_temp_free(t0);
2866        return;
2867    }
2868    tcg_temp_free(t0);
2869}
2870
2871#ifndef CONFIG_USER_ONLY
2872/* CP0 (MMU and control) */
2873static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
2874{
2875    TCGv_i32 t0 = tcg_temp_new_i32();
2876
2877    tcg_gen_ld_i32(t0, cpu_env, off);
2878    tcg_gen_ext_i32_tl(arg, t0);
2879    tcg_temp_free_i32(t0);
2880}
2881
2882static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
2883{
2884    tcg_gen_ld_tl(arg, cpu_env, off);
2885    tcg_gen_ext32s_tl(arg, arg);
2886}
2887
2888static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
2889{
2890    TCGv_i32 t0 = tcg_temp_new_i32();
2891
2892    tcg_gen_trunc_tl_i32(t0, arg);
2893    tcg_gen_st_i32(t0, cpu_env, off);
2894    tcg_temp_free_i32(t0);
2895}
2896
2897static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
2898{
2899    tcg_gen_ext32s_tl(arg, arg);
2900    tcg_gen_st_tl(arg, cpu_env, off);
2901}
2902
2903static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
2904{
2905    const char *rn = "invalid";
2906
2907    if (sel != 0)
2908        check_insn(env, ctx, ISA_MIPS32);
2909
2910    switch (reg) {
2911    case 0:
2912        switch (sel) {
2913        case 0:
2914            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Index));
2915            rn = "Index";
2916            break;
2917        case 1:
2918            check_insn(env, ctx, ASE_MT);
2919            gen_helper_mfc0_mvpcontrol(arg);
2920            rn = "MVPControl";
2921            break;
2922        case 2:
2923            check_insn(env, ctx, ASE_MT);
2924            gen_helper_mfc0_mvpconf0(arg);
2925            rn = "MVPConf0";
2926            break;
2927        case 3:
2928            check_insn(env, ctx, ASE_MT);
2929            gen_helper_mfc0_mvpconf1(arg);
2930            rn = "MVPConf1";
2931            break;
2932        default:
2933            goto die;
2934        }
2935        break;
2936    case 1:
2937        switch (sel) {
2938        case 0:
2939            gen_helper_mfc0_random(arg);
2940            rn = "Random";
2941            break;
2942        case 1:
2943            check_insn(env, ctx, ASE_MT);
2944            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEControl));
2945            rn = "VPEControl";
2946            break;
2947        case 2:
2948            check_insn(env, ctx, ASE_MT);
2949            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf0));
2950            rn = "VPEConf0";
2951            break;
2952        case 3:
2953            check_insn(env, ctx, ASE_MT);
2954            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf1));
2955            rn = "VPEConf1";
2956            break;
2957        case 4:
2958            check_insn(env, ctx, ASE_MT);
2959            gen_mfc0_load64(arg, offsetof(CPUState, CP0_YQMask));
2960            rn = "YQMask";
2961            break;
2962        case 5:
2963            check_insn(env, ctx, ASE_MT);
2964            gen_mfc0_load64(arg, offsetof(CPUState, CP0_VPESchedule));
2965            rn = "VPESchedule";
2966            break;
2967        case 6:
2968            check_insn(env, ctx, ASE_MT);
2969            gen_mfc0_load64(arg, offsetof(CPUState, CP0_VPEScheFBack));
2970            rn = "VPEScheFBack";
2971            break;
2972        case 7:
2973            check_insn(env, ctx, ASE_MT);
2974            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEOpt));
2975            rn = "VPEOpt";
2976            break;
2977        default:
2978            goto die;
2979        }
2980        break;
2981    case 2:
2982        switch (sel) {
2983        case 0:
2984            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo0));
2985            tcg_gen_ext32s_tl(arg, arg);
2986            rn = "EntryLo0";
2987            break;
2988        case 1:
2989            check_insn(env, ctx, ASE_MT);
2990            gen_helper_mfc0_tcstatus(arg);
2991            rn = "TCStatus";
2992            break;
2993        case 2:
2994            check_insn(env, ctx, ASE_MT);
2995            gen_helper_mfc0_tcbind(arg);
2996            rn = "TCBind";
2997            break;
2998        case 3:
2999            check_insn(env, ctx, ASE_MT);
3000            gen_helper_mfc0_tcrestart(arg);
3001            rn = "TCRestart";
3002            break;
3003        case 4:
3004            check_insn(env, ctx, ASE_MT);
3005            gen_helper_mfc0_tchalt(arg);
3006            rn = "TCHalt";
3007            break;
3008        case 5:
3009            check_insn(env, ctx, ASE_MT);
3010            gen_helper_mfc0_tccontext(arg);
3011            rn = "TCContext";
3012            break;
3013        case 6:
3014            check_insn(env, ctx, ASE_MT);
3015            gen_helper_mfc0_tcschedule(arg);
3016            rn = "TCSchedule";
3017            break;
3018        case 7:
3019            check_insn(env, ctx, ASE_MT);
3020            gen_helper_mfc0_tcschefback(arg);
3021            rn = "TCScheFBack";
3022            break;
3023        default:
3024            goto die;
3025        }
3026        break;
3027    case 3:
3028        switch (sel) {
3029        case 0:
3030            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo1));
3031            tcg_gen_ext32s_tl(arg, arg);
3032            rn = "EntryLo1";
3033            break;
3034        default:
3035            goto die;
3036        }
3037        break;
3038    case 4:
3039        switch (sel) {
3040        case 0:
3041            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_Context));
3042            tcg_gen_ext32s_tl(arg, arg);
3043            rn = "Context";
3044            break;
3045        case 1:
3046//            gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
3047            rn = "ContextConfig";
3048//            break;
3049        default:
3050            goto die;
3051        }
3052        break;
3053    case 5:
3054        switch (sel) {
3055        case 0:
3056            gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageMask));
3057            rn = "PageMask";
3058            break;
3059        case 1:
3060            check_insn(env, ctx, ISA_MIPS32R2);
3061            gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageGrain));
3062            rn = "PageGrain";
3063            break;
3064        default:
3065            goto die;
3066        }
3067        break;
3068    case 6:
3069        switch (sel) {
3070        case 0:
3071            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Wired));
3072            rn = "Wired";
3073            break;
3074        case 1:
3075            check_insn(env, ctx, ISA_MIPS32R2);
3076            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf0));
3077            rn = "SRSConf0";
3078            break;
3079        case 2:
3080            check_insn(env, ctx, ISA_MIPS32R2);
3081            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf1));
3082            rn = "SRSConf1";
3083            break;
3084        case 3:
3085            check_insn(env, ctx, ISA_MIPS32R2);
3086            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf2));
3087            rn = "SRSConf2";
3088            break;
3089        case 4:
3090            check_insn(env, ctx, ISA_MIPS32R2);
3091            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf3));
3092            rn = "SRSConf3";
3093            break;
3094        case 5:
3095            check_insn(env, ctx, ISA_MIPS32R2);
3096            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf4));
3097            rn = "SRSConf4";
3098            break;
3099        default:
3100            goto die;
3101        }
3102        break;
3103    case 7:
3104        switch (sel) {
3105        case 0:
3106            check_insn(env, ctx, ISA_MIPS32R2);
3107            gen_mfc0_load32(arg, offsetof(CPUState, CP0_HWREna));
3108            rn = "HWREna";
3109            break;
3110        default:
3111            goto die;
3112        }
3113        break;
3114    case 8:
3115        switch (sel) {
3116        case 0:
3117            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_BadVAddr));
3118            tcg_gen_ext32s_tl(arg, arg);
3119            rn = "BadVAddr";
3120            break;
3121        default:
3122            goto die;
3123       }
3124        break;
3125    case 9:
3126        switch (sel) {
3127        case 0:
3128            /* Mark as an IO operation because we read the time.  */
3129            if (use_icount)
3130                gen_io_start();
3131            gen_helper_mfc0_count(arg);
3132            if (use_icount) {
3133                gen_io_end();
3134                ctx->bstate = BS_STOP;
3135            }
3136            rn = "Count";
3137            break;
3138        /* 6,7 are implementation dependent */
3139        default:
3140            goto die;
3141        }
3142        break;
3143    case 10:
3144        switch (sel) {
3145        case 0:
3146            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryHi));
3147            tcg_gen_ext32s_tl(arg, arg);
3148            rn = "EntryHi";
3149            break;
3150        default:
3151            goto die;
3152        }
3153        break;
3154    case 11:
3155        switch (sel) {
3156        case 0:
3157            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Compare));
3158            rn = "Compare";
3159            break;
3160        /* 6,7 are implementation dependent */
3161        default:
3162            goto die;
3163        }
3164        break;
3165    case 12:
3166        switch (sel) {
3167        case 0:
3168            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Status));
3169            rn = "Status";
3170            break;
3171        case 1:
3172            check_insn(env, ctx, ISA_MIPS32R2);
3173            gen_mfc0_load32(arg, offsetof(CPUState, CP0_IntCtl));
3174            rn = "IntCtl";
3175            break;
3176        case 2:
3177            check_insn(env, ctx, ISA_MIPS32R2);
3178            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSCtl));
3179            rn = "SRSCtl";
3180            break;
3181        case 3:
3182            check_insn(env, ctx, ISA_MIPS32R2);
3183            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSMap));
3184            rn = "SRSMap";
3185            break;
3186        default:
3187            goto die;
3188       }
3189        break;
3190    case 13:
3191        switch (sel) {
3192        case 0:
3193            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Cause));
3194            rn = "Cause";
3195            break;
3196        default:
3197            goto die;
3198       }
3199        break;
3200    case 14:
3201        switch (sel) {
3202        case 0:
3203            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
3204            tcg_gen_ext32s_tl(arg, arg);
3205            rn = "EPC";
3206            break;
3207        default:
3208            goto die;
3209        }
3210        break;
3211    case 15:
3212        switch (sel) {
3213        case 0:
3214            gen_mfc0_load32(arg, offsetof(CPUState, CP0_PRid));
3215            rn = "PRid";
3216            break;
3217        case 1:
3218            check_insn(env, ctx, ISA_MIPS32R2);
3219            gen_mfc0_load32(arg, offsetof(CPUState, CP0_EBase));
3220            rn = "EBase";
3221            break;
3222        default:
3223            goto die;
3224       }
3225        break;
3226    case 16:
3227        switch (sel) {
3228        case 0:
3229            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config0));
3230            rn = "Config";
3231            break;
3232        case 1:
3233            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config1));
3234            rn = "Config1";
3235            break;
3236        case 2:
3237            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config2));
3238            rn = "Config2";
3239            break;
3240        case 3:
3241            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config3));
3242            rn = "Config3";
3243            break;
3244        /* 4,5 are reserved */
3245        /* 6,7 are implementation dependent */
3246        case 6:
3247            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config6));
3248            rn = "Config6";
3249            break;
3250        case 7:
3251            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config7));
3252            rn = "Config7";
3253            break;
3254        default:
3255            goto die;
3256        }
3257        break;
3258    case 17:
3259        switch (sel) {
3260        case 0:
3261            gen_helper_mfc0_lladdr(arg);
3262            rn = "LLAddr";
3263            break;
3264        default:
3265            goto die;
3266        }
3267        break;
3268    case 18:
3269        switch (sel) {
3270        case 0 ... 7:
3271            gen_helper_1i(mfc0_watchlo, arg, sel);
3272            rn = "WatchLo";
3273            break;
3274        default:
3275            goto die;
3276        }
3277        break;
3278    case 19:
3279        switch (sel) {
3280        case 0 ...7:
3281            gen_helper_1i(mfc0_watchhi, arg, sel);
3282            rn = "WatchHi";
3283            break;
3284        default:
3285            goto die;
3286        }
3287        break;
3288    case 20:
3289        switch (sel) {
3290        case 0:
3291#if defined(TARGET_MIPS64)
3292            check_insn(env, ctx, ISA_MIPS3);
3293            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_XContext));
3294            tcg_gen_ext32s_tl(arg, arg);
3295            rn = "XContext";
3296            break;
3297#endif
3298        default:
3299            goto die;
3300        }
3301        break;
3302    case 21:
3303       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3304        switch (sel) {
3305        case 0:
3306            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Framemask));
3307            rn = "Framemask";
3308            break;
3309        default:
3310            goto die;
3311        }
3312        break;
3313    case 22:
3314        tcg_gen_movi_tl(arg, 0); /* unimplemented */
3315        rn = "'Diagnostic"; /* implementation dependent */
3316        break;
3317    case 23:
3318        switch (sel) {
3319        case 0:
3320            gen_helper_mfc0_debug(arg); /* EJTAG support */
3321            rn = "Debug";
3322            break;
3323        case 1:
3324//            gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
3325            rn = "TraceControl";
3326//            break;
3327        case 2:
3328//            gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
3329            rn = "TraceControl2";
3330//            break;
3331        case 3:
3332//            gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
3333            rn = "UserTraceData";
3334//            break;
3335        case 4:
3336//            gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
3337            rn = "TraceBPC";
3338//            break;
3339        default:
3340            goto die;
3341        }
3342        break;
3343    case 24:
3344        switch (sel) {
3345        case 0:
3346            /* EJTAG support */
3347            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
3348            tcg_gen_ext32s_tl(arg, arg);
3349            rn = "DEPC";
3350            break;
3351        default:
3352            goto die;
3353        }
3354        break;
3355    case 25:
3356        switch (sel) {
3357        case 0:
3358            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Performance0));
3359            rn = "Performance0";
3360            break;
3361        case 1:
3362//            gen_helper_mfc0_performance1(arg);
3363            rn = "Performance1";
3364//            break;
3365        case 2:
3366//            gen_helper_mfc0_performance2(arg);
3367            rn = "Performance2";
3368//            break;
3369        case 3:
3370//            gen_helper_mfc0_performance3(arg);
3371            rn = "Performance3";
3372//            break;
3373        case 4:
3374//            gen_helper_mfc0_performance4(arg);
3375            rn = "Performance4";
3376//            break;
3377        case 5:
3378//            gen_helper_mfc0_performance5(arg);
3379            rn = "Performance5";
3380//            break;
3381        case 6:
3382//            gen_helper_mfc0_performance6(arg);
3383            rn = "Performance6";
3384//            break;
3385        case 7:
3386//            gen_helper_mfc0_performance7(arg);
3387            rn = "Performance7";
3388//            break;
3389        default:
3390            goto die;
3391        }
3392        break;
3393    case 26:
3394        tcg_gen_movi_tl(arg, 0); /* unimplemented */
3395        rn = "ECC";
3396        break;
3397    case 27:
3398        switch (sel) {
3399        case 0 ... 3:
3400            tcg_gen_movi_tl(arg, 0); /* unimplemented */
3401            rn = "CacheErr";
3402            break;
3403        default:
3404            goto die;
3405        }
3406        break;
3407    case 28:
3408        switch (sel) {
3409        case 0:
3410        case 2:
3411        case 4:
3412        case 6:
3413            gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagLo));
3414            rn = "TagLo";
3415            break;
3416        case 1:
3417        case 3:
3418        case 5:
3419        case 7:
3420            gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataLo));
3421            rn = "DataLo";
3422            break;
3423        default:
3424            goto die;
3425        }
3426        break;
3427    case 29:
3428        switch (sel) {
3429        case 0:
3430        case 2:
3431        case 4:
3432        case 6:
3433            gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagHi));
3434            rn = "TagHi";
3435            break;
3436        case 1:
3437        case 3:
3438        case 5:
3439        case 7:
3440            gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataHi));
3441            rn = "DataHi";
3442            break;
3443        default:
3444            goto die;
3445        }
3446        break;
3447    case 30:
3448        switch (sel) {
3449        case 0:
3450            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
3451            tcg_gen_ext32s_tl(arg, arg);
3452            rn = "ErrorEPC";
3453            break;
3454        default:
3455            goto die;
3456        }
3457        break;
3458    case 31:
3459        switch (sel) {
3460        case 0:
3461            /* EJTAG support */
3462            gen_mfc0_load32(arg, offsetof(CPUState, CP0_DESAVE));
3463            rn = "DESAVE";
3464            break;
3465        default:
3466            goto die;
3467        }
3468        break;
3469    default:
3470       goto die;
3471    }
3472    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3473    return;
3474
3475die:
3476    LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
3477    generate_exception(ctx, EXCP_RI);
3478}
3479
3480static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
3481{
3482    const char *rn = "invalid";
3483
3484    if (sel != 0)
3485        check_insn(env, ctx, ISA_MIPS32);
3486
3487    if (use_icount)
3488        gen_io_start();
3489
3490    switch (reg) {
3491    case 0:
3492        switch (sel) {
3493        case 0:
3494            gen_helper_mtc0_index(arg);
3495            rn = "Index";
3496            break;
3497        case 1:
3498            check_insn(env, ctx, ASE_MT);
3499            gen_helper_mtc0_mvpcontrol(arg);
3500            rn = "MVPControl";
3501            break;
3502        case 2:
3503            check_insn(env, ctx, ASE_MT);
3504            /* ignored */
3505            rn = "MVPConf0";
3506            break;
3507        case 3:
3508            check_insn(env, ctx, ASE_MT);
3509            /* ignored */
3510            rn = "MVPConf1";
3511            break;
3512        default:
3513            goto die;
3514        }
3515        break;
3516    case 1:
3517        switch (sel) {
3518        case 0:
3519            /* ignored */
3520            rn = "Random";
3521            break;
3522        case 1:
3523            check_insn(env, ctx, ASE_MT);
3524            gen_helper_mtc0_vpecontrol(arg);
3525            rn = "VPEControl";
3526            break;
3527        case 2:
3528            check_insn(env, ctx, ASE_MT);
3529            gen_helper_mtc0_vpeconf0(arg);
3530            rn = "VPEConf0";
3531            break;
3532        case 3:
3533            check_insn(env, ctx, ASE_MT);
3534            gen_helper_mtc0_vpeconf1(arg);
3535            rn = "VPEConf1";
3536            break;
3537        case 4:
3538            check_insn(env, ctx, ASE_MT);
3539            gen_helper_mtc0_yqmask(arg);
3540            rn = "YQMask";
3541            break;
3542        case 5:
3543            check_insn(env, ctx, ASE_MT);
3544            gen_mtc0_store64(arg, offsetof(CPUState, CP0_VPESchedule));
3545            rn = "VPESchedule";
3546            break;
3547        case 6:
3548            check_insn(env, ctx, ASE_MT);
3549            gen_mtc0_store64(arg, offsetof(CPUState, CP0_VPEScheFBack));
3550            rn = "VPEScheFBack";
3551            break;
3552        case 7:
3553            check_insn(env, ctx, ASE_MT);
3554            gen_helper_mtc0_vpeopt(arg);
3555            rn = "VPEOpt";
3556            break;
3557        default:
3558            goto die;
3559        }
3560        break;
3561    case 2:
3562        switch (sel) {
3563        case 0:
3564            gen_helper_mtc0_entrylo0(arg);
3565            rn = "EntryLo0";
3566            break;
3567        case 1:
3568            check_insn(env, ctx, ASE_MT);
3569            gen_helper_mtc0_tcstatus(arg);
3570            rn = "TCStatus";
3571            break;
3572        case 2:
3573            check_insn(env, ctx, ASE_MT);
3574            gen_helper_mtc0_tcbind(arg);
3575            rn = "TCBind";
3576            break;
3577        case 3:
3578            check_insn(env, ctx, ASE_MT);
3579            gen_helper_mtc0_tcrestart(arg);
3580            rn = "TCRestart";
3581            break;
3582        case 4:
3583            check_insn(env, ctx, ASE_MT);
3584            gen_helper_mtc0_tchalt(arg);
3585            rn = "TCHalt";
3586            break;
3587        case 5:
3588            check_insn(env, ctx, ASE_MT);
3589            gen_helper_mtc0_tccontext(arg);
3590            rn = "TCContext";
3591            break;
3592        case 6:
3593            check_insn(env, ctx, ASE_MT);
3594            gen_helper_mtc0_tcschedule(arg);
3595            rn = "TCSchedule";
3596            break;
3597        case 7:
3598            check_insn(env, ctx, ASE_MT);
3599            gen_helper_mtc0_tcschefback(arg);
3600            rn = "TCScheFBack";
3601            break;
3602        default:
3603            goto die;
3604        }
3605        break;
3606    case 3:
3607        switch (sel) {
3608        case 0:
3609            gen_helper_mtc0_entrylo1(arg);
3610            rn = "EntryLo1";
3611            break;
3612        default:
3613            goto die;
3614        }
3615        break;
3616    case 4:
3617        switch (sel) {
3618        case 0:
3619            gen_helper_mtc0_context(arg);
3620            rn = "Context";
3621            break;
3622        case 1:
3623//            gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
3624            rn = "ContextConfig";
3625//            break;
3626        default:
3627            goto die;
3628        }
3629        break;
3630    case 5:
3631        switch (sel) {
3632        case 0:
3633            gen_helper_mtc0_pagemask(arg);
3634            rn = "PageMask";
3635            break;
3636        case 1:
3637            check_insn(env, ctx, ISA_MIPS32R2);
3638            gen_helper_mtc0_pagegrain(arg);
3639            rn = "PageGrain";
3640            break;
3641        default:
3642            goto die;
3643        }
3644        break;
3645    case 6:
3646        switch (sel) {
3647        case 0:
3648            gen_helper_mtc0_wired(arg);
3649            rn = "Wired";
3650            break;
3651        case 1:
3652            check_insn(env, ctx, ISA_MIPS32R2);
3653            gen_helper_mtc0_srsconf0(arg);
3654            rn = "SRSConf0";
3655            break;
3656        case 2:
3657            check_insn(env, ctx, ISA_MIPS32R2);
3658            gen_helper_mtc0_srsconf1(arg);
3659            rn = "SRSConf1";
3660            break;
3661        case 3:
3662            check_insn(env, ctx, ISA_MIPS32R2);
3663            gen_helper_mtc0_srsconf2(arg);
3664            rn = "SRSConf2";
3665            break;
3666        case 4:
3667            check_insn(env, ctx, ISA_MIPS32R2);
3668            gen_helper_mtc0_srsconf3(arg);
3669            rn = "SRSConf3";
3670            break;
3671        case 5:
3672            check_insn(env, ctx, ISA_MIPS32R2);
3673            gen_helper_mtc0_srsconf4(arg);
3674            rn = "SRSConf4";
3675            break;
3676        default:
3677            goto die;
3678        }
3679        break;
3680    case 7:
3681        switch (sel) {
3682        case 0:
3683            check_insn(env, ctx, ISA_MIPS32R2);
3684            gen_helper_mtc0_hwrena(arg);
3685            rn = "HWREna";
3686            break;
3687        default:
3688            goto die;
3689        }
3690        break;
3691    case 8:
3692        /* ignored */
3693        rn = "BadVAddr";
3694        break;
3695    case 9:
3696        switch (sel) {
3697        case 0:
3698            gen_helper_mtc0_count(arg);
3699            rn = "Count";
3700            break;
3701        /* 6,7 are implementation dependent */
3702        default:
3703            goto die;
3704        }
3705        break;
3706    case 10:
3707        switch (sel) {
3708        case 0:
3709            gen_helper_mtc0_entryhi(arg);
3710            rn = "EntryHi";
3711            break;
3712        default:
3713            goto die;
3714        }
3715        break;
3716    case 11:
3717        switch (sel) {
3718        case 0:
3719            gen_helper_mtc0_compare(arg);
3720            rn = "Compare";
3721            break;
3722        /* 6,7 are implementation dependent */
3723        default:
3724            goto die;
3725        }
3726        break;
3727    case 12:
3728        switch (sel) {
3729        case 0:
3730            save_cpu_state(ctx, 1);
3731            gen_helper_mtc0_status(arg);
3732            /* BS_STOP isn't good enough here, hflags may have changed. */
3733            gen_save_pc(ctx->pc + 4);
3734            ctx->bstate = BS_EXCP;
3735            rn = "Status";
3736            break;
3737        case 1:
3738            check_insn(env, ctx, ISA_MIPS32R2);
3739            gen_helper_mtc0_intctl(arg);
3740            /* Stop translation as we may have switched the execution mode */
3741            ctx->bstate = BS_STOP;
3742            rn = "IntCtl";
3743            break;
3744        case 2:
3745            check_insn(env, ctx, ISA_MIPS32R2);
3746            gen_helper_mtc0_srsctl(arg);
3747            /* Stop translation as we may have switched the execution mode */
3748            ctx->bstate = BS_STOP;
3749            rn = "SRSCtl";
3750            break;
3751        case 3:
3752            check_insn(env, ctx, ISA_MIPS32R2);
3753            gen_mtc0_store32(arg, offsetof(CPUState, CP0_SRSMap));
3754            /* Stop translation as we may have switched the execution mode */
3755            ctx->bstate = BS_STOP;
3756            rn = "SRSMap";
3757            break;
3758        default:
3759            goto die;
3760        }
3761        break;
3762    case 13:
3763        switch (sel) {
3764        case 0:
3765            save_cpu_state(ctx, 1);
3766            gen_helper_mtc0_cause(arg);
3767            rn = "Cause";
3768            break;
3769        default:
3770            goto die;
3771        }
3772        break;
3773    case 14:
3774        switch (sel) {
3775        case 0:
3776            gen_mtc0_store64(arg, offsetof(CPUState, CP0_EPC));
3777            rn = "EPC";
3778            break;
3779        default:
3780            goto die;
3781        }
3782        break;
3783    case 15:
3784        switch (sel) {
3785        case 0:
3786            /* ignored */
3787            rn = "PRid";
3788            break;
3789        case 1:
3790            check_insn(env, ctx, ISA_MIPS32R2);
3791            gen_helper_mtc0_ebase(arg);
3792            rn = "EBase";
3793            break;
3794        default:
3795            goto die;
3796        }
3797        break;
3798    case 16:
3799        switch (sel) {
3800        case 0:
3801            gen_helper_mtc0_config0(arg);
3802            rn = "Config";
3803            /* Stop translation as we may have switched the execution mode */
3804            ctx->bstate = BS_STOP;
3805            break;
3806        case 1:
3807            /* ignored, read only */
3808            rn = "Config1";
3809            break;
3810        case 2:
3811            gen_helper_mtc0_config2(arg);
3812            rn = "Config2";
3813            /* Stop translation as we may have switched the execution mode */
3814            ctx->bstate = BS_STOP;
3815            break;
3816        case 3:
3817            /* ignored, read only */
3818            rn = "Config3";
3819            break;
3820        /* 4,5 are reserved */
3821        /* 6,7 are implementation dependent */
3822        case 6:
3823            /* ignored */
3824            rn = "Config6";
3825            break;
3826        case 7:
3827            /* ignored */
3828            rn = "Config7";
3829            break;
3830        default:
3831            rn = "Invalid config selector";
3832            goto die;
3833        }
3834        break;
3835    case 17:
3836        switch (sel) {
3837        case 0:
3838            /* ignored */
3839            rn = "LLAddr";
3840            break;
3841        default:
3842            goto die;
3843        }
3844        break;
3845    case 18:
3846        switch (sel) {
3847        case 0 ... 7:
3848            gen_helper_1i(mtc0_watchlo, arg, sel);
3849            rn = "WatchLo";
3850            break;
3851        default:
3852            goto die;
3853        }
3854        break;
3855    case 19:
3856        switch (sel) {
3857        case 0 ... 7:
3858            gen_helper_1i(mtc0_watchhi, arg, sel);
3859            rn = "WatchHi";
3860            break;
3861        default:
3862            goto die;
3863        }
3864        break;
3865    case 20:
3866        switch (sel) {
3867        case 0:
3868#if defined(TARGET_MIPS64)
3869            check_insn(env, ctx, ISA_MIPS3);
3870            gen_helper_mtc0_xcontext(arg);
3871            rn = "XContext";
3872            break;
3873#endif
3874        default:
3875            goto die;
3876        }
3877        break;
3878    case 21:
3879       /* Officially reserved, but sel 0 is used for R1x000 framemask */
3880        switch (sel) {
3881        case 0:
3882            gen_helper_mtc0_framemask(arg);
3883            rn = "Framemask";
3884            break;
3885        default:
3886            goto die;
3887        }
3888        break;
3889    case 22:
3890        /* ignored */
3891        rn = "Diagnostic"; /* implementation dependent */
3892        break;
3893    case 23:
3894        switch (sel) {
3895        case 0:
3896            gen_helper_mtc0_debug(arg); /* EJTAG support */
3897            /* BS_STOP isn't good enough here, hflags may have changed. */
3898            gen_save_pc(ctx->pc + 4);
3899            ctx->bstate = BS_EXCP;
3900            rn = "Debug";
3901            break;
3902        case 1:
3903//            gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
3904            rn = "TraceControl";
3905            /* Stop translation as we may have switched the execution mode */
3906            ctx->bstate = BS_STOP;
3907//            break;
3908        case 2:
3909//            gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
3910            rn = "TraceControl2";
3911            /* Stop translation as we may have switched the execution mode */
3912            ctx->bstate = BS_STOP;
3913//            break;
3914        case 3:
3915            /* Stop translation as we may have switched the execution mode */
3916            ctx->bstate = BS_STOP;
3917//            gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
3918            rn = "UserTraceData";
3919            /* Stop translation as we may have switched the execution mode */
3920            ctx->bstate = BS_STOP;
3921//            break;
3922        case 4:
3923//            gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
3924            /* Stop translation as we may have switched the execution mode */
3925            ctx->bstate = BS_STOP;
3926            rn = "TraceBPC";
3927//            break;
3928        default:
3929            goto die;
3930        }
3931        break;
3932    case 24:
3933        switch (sel) {
3934        case 0:
3935            /* EJTAG support */
3936            gen_mtc0_store64(arg, offsetof(CPUState, CP0_DEPC));
3937            rn = "DEPC";
3938            break;
3939        default:
3940            goto die;
3941        }
3942        break;
3943    case 25:
3944        switch (sel) {
3945        case 0:
3946            gen_helper_mtc0_performance0(arg);
3947            rn = "Performance0";
3948            break;
3949        case 1:
3950//            gen_helper_mtc0_performance1(arg);
3951            rn = "Performance1";
3952//            break;
3953        case 2:
3954//            gen_helper_mtc0_performance2(arg);
3955            rn = "Performance2";
3956//            break;
3957        case 3:
3958//            gen_helper_mtc0_performance3(arg);
3959            rn = "Performance3";
3960//            break;
3961        case 4:
3962//            gen_helper_mtc0_performance4(arg);
3963            rn = "Performance4";
3964//            break;
3965        case 5:
3966//            gen_helper_mtc0_performance5(arg);
3967            rn = "Performance5";
3968//            break;
3969        case 6:
3970//            gen_helper_mtc0_performance6(arg);
3971            rn = "Performance6";
3972//            break;
3973        case 7:
3974//            gen_helper_mtc0_performance7(arg);
3975            rn = "Performance7";
3976//            break;
3977        default:
3978            goto die;
3979        }
3980       break;
3981    case 26:
3982        /* ignored */
3983        rn = "ECC";
3984        break;
3985    case 27:
3986        switch (sel) {
3987        case 0 ... 3:
3988            /* ignored */
3989            rn = "CacheErr";
3990            break;
3991        default:
3992            goto die;
3993        }
3994       break;
3995    case 28:
3996        switch (sel) {
3997        case 0:
3998        case 2:
3999        case 4:
4000        case 6:
4001            gen_helper_mtc0_taglo(arg);
4002            rn = "TagLo";
4003            break;
4004        case 1:
4005        case 3:
4006        case 5:
4007        case 7:
4008            gen_helper_mtc0_datalo(arg);
4009            rn = "DataLo";
4010            break;
4011        default:
4012            goto die;
4013        }
4014        break;
4015    case 29:
4016        switch (sel) {
4017        case 0:
4018        case 2:
4019        case 4:
4020        case 6:
4021            gen_helper_mtc0_taghi(arg);
4022            rn = "TagHi";
4023            break;
4024        case 1:
4025        case 3:
4026        case 5:
4027        case 7:
4028            gen_helper_mtc0_datahi(arg);
4029            rn = "DataHi";
4030            break;
4031        default:
4032            rn = "invalid sel";
4033            goto die;
4034        }
4035       break;
4036    case 30:
4037        switch (sel) {
4038        case 0:
4039            gen_mtc0_store64(arg, offsetof(CPUState, CP0_ErrorEPC));
4040            rn = "ErrorEPC";
4041            break;
4042        default:
4043            goto die;
4044        }
4045        break;
4046    case 31:
4047        switch (sel) {
4048        case 0:
4049            /* EJTAG support */
4050            gen_mtc0_store32(arg, offsetof(CPUState, CP0_DESAVE));
4051            rn = "DESAVE";
4052            break;
4053        default:
4054            goto die;
4055        }
4056        /* Stop translation as we may have switched the execution mode */
4057        ctx->bstate = BS_STOP;
4058        break;
4059    default:
4060       goto die;
4061    }
4062    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4063    /* For simplicity assume that all writes can cause interrupts.  */
4064    if (use_icount) {
4065        gen_io_end();
4066        ctx->bstate = BS_STOP;
4067    }
4068    return;
4069
4070die:
4071    LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
4072    generate_exception(ctx, EXCP_RI);
4073}
4074
4075#if defined(TARGET_MIPS64)
4076static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4077{
4078    const char *rn = "invalid";
4079
4080    if (sel != 0)
4081        check_insn(env, ctx, ISA_MIPS64);
4082
4083    switch (reg) {
4084    case 0:
4085        switch (sel) {
4086        case 0:
4087            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Index));
4088            rn = "Index";
4089            break;
4090        case 1:
4091            check_insn(env, ctx, ASE_MT);
4092            gen_helper_mfc0_mvpcontrol(arg);
4093            rn = "MVPControl";
4094            break;
4095        case 2:
4096            check_insn(env, ctx, ASE_MT);
4097            gen_helper_mfc0_mvpconf0(arg);
4098            rn = "MVPConf0";
4099            break;
4100        case 3:
4101            check_insn(env, ctx, ASE_MT);
4102            gen_helper_mfc0_mvpconf1(arg);
4103            rn = "MVPConf1";
4104            break;
4105        default:
4106            goto die;
4107        }
4108        break;
4109    case 1:
4110        switch (sel) {
4111        case 0:
4112            gen_helper_mfc0_random(arg);
4113            rn = "Random";
4114            break;
4115        case 1:
4116            check_insn(env, ctx, ASE_MT);
4117            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEControl));
4118            rn = "VPEControl";
4119            break;
4120        case 2:
4121            check_insn(env, ctx, ASE_MT);
4122            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf0));
4123            rn = "VPEConf0";
4124            break;
4125        case 3:
4126            check_insn(env, ctx, ASE_MT);
4127            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf1));
4128            rn = "VPEConf1";
4129            break;
4130        case 4:
4131            check_insn(env, ctx, ASE_MT);
4132            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_YQMask));
4133            rn = "YQMask";
4134            break;
4135        case 5:
4136            check_insn(env, ctx, ASE_MT);
4137            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4138            rn = "VPESchedule";
4139            break;
4140        case 6:
4141            check_insn(env, ctx, ASE_MT);
4142            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4143            rn = "VPEScheFBack";
4144            break;
4145        case 7:
4146            check_insn(env, ctx, ASE_MT);
4147            gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEOpt));
4148            rn = "VPEOpt";
4149            break;
4150        default:
4151            goto die;
4152        }
4153        break;
4154    case 2:
4155        switch (sel) {
4156        case 0:
4157            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo0));
4158            rn = "EntryLo0";
4159            break;
4160        case 1:
4161            check_insn(env, ctx, ASE_MT);
4162            gen_helper_mfc0_tcstatus(arg);
4163            rn = "TCStatus";
4164            break;
4165        case 2:
4166            check_insn(env, ctx, ASE_MT);
4167            gen_helper_mfc0_tcbind(arg);
4168            rn = "TCBind";
4169            break;
4170        case 3:
4171            check_insn(env, ctx, ASE_MT);
4172            gen_helper_dmfc0_tcrestart(arg);
4173            rn = "TCRestart";
4174            break;
4175        case 4:
4176            check_insn(env, ctx, ASE_MT);
4177            gen_helper_dmfc0_tchalt(arg);
4178            rn = "TCHalt";
4179            break;
4180        case 5:
4181            check_insn(env, ctx, ASE_MT);
4182            gen_helper_dmfc0_tccontext(arg);
4183            rn = "TCContext";
4184            break;
4185        case 6:
4186            check_insn(env, ctx, ASE_MT);
4187            gen_helper_dmfc0_tcschedule(arg);
4188            rn = "TCSchedule";
4189            break;
4190        case 7:
4191            check_insn(env, ctx, ASE_MT);
4192            gen_helper_dmfc0_tcschefback(arg);
4193            rn = "TCScheFBack";
4194            break;
4195        default:
4196            goto die;
4197        }
4198        break;
4199    case 3:
4200        switch (sel) {
4201        case 0:
4202            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo1));
4203            rn = "EntryLo1";
4204            break;
4205        default:
4206            goto die;
4207        }
4208        break;
4209    case 4:
4210        switch (sel) {
4211        case 0:
4212            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_Context));
4213            rn = "Context";
4214            break;
4215        case 1:
4216//            gen_helper_dmfc0_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(CPUState, CP0_PageMask));
4227            rn = "PageMask";
4228            break;
4229        case 1:
4230            check_insn(env, ctx, ISA_MIPS32R2);
4231            gen_mfc0_load32(arg, offsetof(CPUState, 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(CPUState, CP0_Wired));
4242            rn = "Wired";
4243            break;
4244        case 1:
4245            check_insn(env, ctx, ISA_MIPS32R2);
4246            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf0));
4247            rn = "SRSConf0";
4248            break;
4249        case 2:
4250            check_insn(env, ctx, ISA_MIPS32R2);
4251            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf1));
4252            rn = "SRSConf1";
4253            break;
4254        case 3:
4255            check_insn(env, ctx, ISA_MIPS32R2);
4256            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf2));
4257            rn = "SRSConf2";
4258            break;
4259        case 4:
4260            check_insn(env, ctx, ISA_MIPS32R2);
4261            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf3));
4262            rn = "SRSConf3";
4263            break;
4264        case 5:
4265            check_insn(env, ctx, ISA_MIPS32R2);
4266            gen_mfc0_load32(arg, offsetof(CPUState, 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(env, ctx, ISA_MIPS32R2);
4277            gen_mfc0_load32(arg, offsetof(CPUState, 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(CPUState, CP0_BadVAddr));
4288            rn = "BadVAddr";
4289            break;
4290        default:
4291            goto die;
4292        }
4293        break;
4294    case 9:
4295        switch (sel) {
4296        case 0:
4297            /* Mark as an IO operation because we read the time.  */
4298            if (use_icount)
4299                gen_io_start();
4300            gen_helper_mfc0_count(arg);
4301            if (use_icount) {
4302                gen_io_end();
4303                ctx->bstate = BS_STOP;
4304            }
4305            rn = "Count";
4306            break;
4307        /* 6,7 are implementation dependent */
4308        default:
4309            goto die;
4310        }
4311        break;
4312    case 10:
4313        switch (sel) {
4314        case 0:
4315            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryHi));
4316            rn = "EntryHi";
4317            break;
4318        default:
4319            goto die;
4320        }
4321        break;
4322    case 11:
4323        switch (sel) {
4324        case 0:
4325            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Compare));
4326            rn = "Compare";
4327            break;
4328        /* 6,7 are implementation dependent */
4329        default:
4330            goto die;
4331        }
4332        break;
4333    case 12:
4334        switch (sel) {
4335        case 0:
4336            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Status));
4337            rn = "Status";
4338            break;
4339        case 1:
4340            check_insn(env, ctx, ISA_MIPS32R2);
4341            gen_mfc0_load32(arg, offsetof(CPUState, CP0_IntCtl));
4342            rn = "IntCtl";
4343            break;
4344        case 2:
4345            check_insn(env, ctx, ISA_MIPS32R2);
4346            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSCtl));
4347            rn = "SRSCtl";
4348            break;
4349        case 3:
4350            check_insn(env, ctx, ISA_MIPS32R2);
4351            gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSMap));
4352            rn = "SRSMap";
4353            break;
4354        default:
4355            goto die;
4356        }
4357        break;
4358    case 13:
4359        switch (sel) {
4360        case 0:
4361            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Cause));
4362            rn = "Cause";
4363            break;
4364        default:
4365            goto die;
4366        }
4367        break;
4368    case 14:
4369        switch (sel) {
4370        case 0:
4371            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
4372            rn = "EPC";
4373            break;
4374        default:
4375            goto die;
4376        }
4377        break;
4378    case 15:
4379        switch (sel) {
4380        case 0:
4381            gen_mfc0_load32(arg, offsetof(CPUState, CP0_PRid));
4382            rn = "PRid";
4383            break;
4384        case 1:
4385            check_insn(env, ctx, ISA_MIPS32R2);
4386            gen_mfc0_load32(arg, offsetof(CPUState, CP0_EBase));
4387            rn = "EBase";
4388            break;
4389        default:
4390            goto die;
4391        }
4392        break;
4393    case 16:
4394        switch (sel) {
4395        case 0:
4396            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config0));
4397            rn = "Config";
4398            break;
4399        case 1:
4400            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config1));
4401            rn = "Config1";
4402            break;
4403        case 2:
4404            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config2));
4405            rn = "Config2";
4406            break;
4407        case 3:
4408            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config3));
4409            rn = "Config3";
4410            break;
4411       /* 6,7 are implementation dependent */
4412        case 6:
4413            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config6));
4414            rn = "Config6";
4415            break;
4416        case 7:
4417            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config7));
4418            rn = "Config7";
4419            break;
4420        default:
4421            goto die;
4422        }
4423        break;
4424    case 17:
4425        switch (sel) {
4426        case 0:
4427            gen_helper_dmfc0_lladdr(arg);
4428            rn = "LLAddr";
4429            break;
4430        default:
4431            goto die;
4432        }
4433        break;
4434    case 18:
4435        switch (sel) {
4436        case 0 ... 7:
4437            gen_helper_1i(dmfc0_watchlo, arg, sel);
4438            rn = "WatchLo";
4439            break;
4440        default:
4441            goto die;
4442        }
4443        break;
4444    case 19:
4445        switch (sel) {
4446        case 0 ... 7:
4447            gen_helper_1i(mfc0_watchhi, arg, sel);
4448            rn = "WatchHi";
4449            break;
4450        default:
4451            goto die;
4452        }
4453        break;
4454    case 20:
4455        switch (sel) {
4456        case 0:
4457            check_insn(env, ctx, ISA_MIPS3);
4458            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_XContext));
4459            rn = "XContext";
4460            break;
4461        default:
4462            goto die;
4463        }
4464        break;
4465    case 21:
4466       /* Officially reserved, but sel 0 is used for R1x000 framemask */
4467        switch (sel) {
4468        case 0:
4469            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Framemask));
4470            rn = "Framemask";
4471            break;
4472        default:
4473            goto die;
4474        }
4475        break;
4476    case 22:
4477        tcg_gen_movi_tl(arg, 0); /* unimplemented */
4478        rn = "'Diagnostic"; /* implementation dependent */
4479        break;
4480    case 23:
4481        switch (sel) {
4482        case 0:
4483            gen_helper_mfc0_debug(arg); /* EJTAG support */
4484            rn = "Debug";
4485            break;
4486        case 1:
4487//            gen_helper_dmfc0_tracecontrol(arg); /* PDtrace support */
4488            rn = "TraceControl";
4489//            break;
4490        case 2:
4491//            gen_helper_dmfc0_tracecontrol2(arg); /* PDtrace support */
4492            rn = "TraceControl2";
4493//            break;
4494        case 3:
4495//            gen_helper_dmfc0_usertracedata(arg); /* PDtrace support */
4496            rn = "UserTraceData";
4497//            break;
4498        case 4:
4499//            gen_helper_dmfc0_tracebpc(arg); /* PDtrace support */
4500            rn = "TraceBPC";
4501//            break;
4502        default:
4503            goto die;
4504        }
4505        break;
4506    case 24:
4507        switch (sel) {
4508        case 0:
4509            /* EJTAG support */
4510            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
4511            rn = "DEPC";
4512            break;
4513        default:
4514            goto die;
4515        }
4516        break;
4517    case 25:
4518        switch (sel) {
4519        case 0:
4520            gen_mfc0_load32(arg, offsetof(CPUState, CP0_Performance0));
4521            rn = "Performance0";
4522            break;
4523        case 1:
4524//            gen_helper_dmfc0_performance1(arg);
4525            rn = "Performance1";
4526//            break;
4527        case 2:
4528//            gen_helper_dmfc0_performance2(arg);
4529            rn = "Performance2";
4530//            break;
4531        case 3:
4532//            gen_helper_dmfc0_performance3(arg);
4533            rn = "Performance3";
4534//            break;
4535        case 4:
4536//            gen_helper_dmfc0_performance4(arg);
4537            rn = "Performance4";
4538//            break;
4539        case 5:
4540//            gen_helper_dmfc0_performance5(arg);
4541            rn = "Performance5";
4542//            break;
4543        case 6:
4544//            gen_helper_dmfc0_performance6(arg);
4545            rn = "Performance6";
4546//            break;
4547        case 7:
4548//            gen_helper_dmfc0_performance7(arg);
4549            rn = "Performance7";
4550//            break;
4551        default:
4552            goto die;
4553        }
4554        break;
4555    case 26:
4556        tcg_gen_movi_tl(arg, 0); /* unimplemented */
4557        rn = "ECC";
4558        break;
4559    case 27:
4560        switch (sel) {
4561        /* ignored */
4562        case 0 ... 3:
4563            tcg_gen_movi_tl(arg, 0); /* unimplemented */
4564            rn = "CacheErr";
4565            break;
4566        default:
4567            goto die;
4568        }
4569        break;
4570    case 28:
4571        switch (sel) {
4572        case 0:
4573        case 2:
4574        case 4:
4575        case 6:
4576            gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagLo));
4577            rn = "TagLo";
4578            break;
4579        case 1:
4580        case 3:
4581        case 5:
4582        case 7:
4583            gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataLo));
4584            rn = "DataLo";
4585            break;
4586        default:
4587            goto die;
4588        }
4589        break;
4590    case 29:
4591        switch (sel) {
4592        case 0:
4593        case 2:
4594        case 4:
4595        case 6:
4596            gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagHi));
4597            rn = "TagHi";
4598            break;
4599        case 1:
4600        case 3:
4601        case 5:
4602        case 7:
4603            gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataHi));
4604            rn = "DataHi";
4605            break;
4606        default:
4607            goto die;
4608        }
4609        break;
4610    case 30:
4611        switch (sel) {
4612        case 0:
4613            tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
4614            rn = "ErrorEPC";
4615            break;
4616        default:
4617            goto die;
4618        }
4619        break;
4620    case 31:
4621        switch (sel) {
4622        case 0:
4623            /* EJTAG support */
4624            gen_mfc0_load32(arg, offsetof(CPUState, CP0_DESAVE));
4625            rn = "DESAVE";
4626            break;
4627        default:
4628            goto die;
4629        }
4630        break;
4631    default:
4632        goto die;
4633    }
4634    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4635    return;
4636
4637die:
4638    LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
4639    generate_exception(ctx, EXCP_RI);
4640}
4641
4642static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
4643{
4644    const char *rn = "invalid";
4645
4646    if (sel != 0)
4647        check_insn(env, ctx, ISA_MIPS64);
4648
4649    if (use_icount)
4650        gen_io_start();
4651
4652    switch (reg) {
4653    case 0:
4654        switch (sel) {
4655        case 0:
4656            gen_helper_mtc0_index(arg);
4657            rn = "Index";
4658            break;
4659        case 1:
4660            check_insn(env, ctx, ASE_MT);
4661            gen_helper_mtc0_mvpcontrol(arg);
4662            rn = "MVPControl";
4663            break;
4664        case 2:
4665            check_insn(env, ctx, ASE_MT);
4666            /* ignored */
4667            rn = "MVPConf0";
4668            break;
4669        case 3:
4670            check_insn(env, ctx, ASE_MT);
4671            /* ignored */
4672            rn = "MVPConf1";
4673            break;
4674        default:
4675            goto die;
4676        }
4677        break;
4678    case 1:
4679        switch (sel) {
4680        case 0:
4681            /* ignored */
4682            rn = "Random";
4683            break;
4684        case 1:
4685            check_insn(env, ctx, ASE_MT);
4686            gen_helper_mtc0_vpecontrol(arg);
4687            rn = "VPEControl";
4688            break;
4689        case 2:
4690            check_insn(env, ctx, ASE_MT);
4691            gen_helper_mtc0_vpeconf0(arg);
4692            rn = "VPEConf0";
4693            break;
4694        case 3:
4695            check_insn(env, ctx, ASE_MT);
4696            gen_helper_mtc0_vpeconf1(arg);
4697            rn = "VPEConf1";
4698            break;
4699        case 4:
4700            check_insn(env, ctx, ASE_MT);
4701            gen_helper_mtc0_yqmask(arg);
4702            rn = "YQMask";
4703            break;
4704        case 5:
4705            check_insn(env, ctx, ASE_MT);
4706            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_VPESchedule));
4707            rn = "VPESchedule";
4708            break;
4709        case 6:
4710            check_insn(env, ctx, ASE_MT);
4711            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
4712            rn = "VPEScheFBack";
4713            break;
4714        case 7:
4715            check_insn(env, ctx, ASE_MT);
4716            gen_helper_mtc0_vpeopt(arg);
4717            rn = "VPEOpt";
4718            break;
4719        default:
4720            goto die;
4721        }
4722        break;
4723    case 2:
4724        switch (sel) {
4725        case 0:
4726            gen_helper_mtc0_entrylo0(arg);
4727            rn = "EntryLo0";
4728            break;
4729        case 1:
4730            check_insn(env, ctx, ASE_MT);
4731            gen_helper_mtc0_tcstatus(arg);
4732            rn = "TCStatus";
4733            break;
4734        case 2:
4735            check_insn(env, ctx, ASE_MT);
4736            gen_helper_mtc0_tcbind(arg);
4737            rn = "TCBind";
4738            break;
4739        case 3:
4740            check_insn(env, ctx, ASE_MT);
4741            gen_helper_mtc0_tcrestart(arg);
4742            rn = "TCRestart";
4743            break;
4744        case 4:
4745            check_insn(env, ctx, ASE_MT);
4746            gen_helper_mtc0_tchalt(arg);
4747            rn = "TCHalt";
4748            break;
4749        case 5:
4750            check_insn(env, ctx, ASE_MT);
4751            gen_helper_mtc0_tccontext(arg);
4752            rn = "TCContext";
4753            break;
4754        case 6:
4755            check_insn(env, ctx, ASE_MT);
4756            gen_helper_mtc0_tcschedule(arg);
4757            rn = "TCSchedule";
4758            break;
4759        case 7:
4760            check_insn(env, ctx, ASE_MT);
4761            gen_helper_mtc0_tcschefback(arg);
4762            rn = "TCScheFBack";
4763            break;
4764        default:
4765            goto die;
4766        }
4767        break;
4768    case 3:
4769        switch (sel) {
4770        case 0:
4771            gen_helper_mtc0_entrylo1(arg);
4772            rn = "EntryLo1";
4773            break;
4774        default:
4775            goto die;
4776        }
4777        break;
4778    case 4:
4779        switch (sel) {
4780        case 0:
4781            gen_helper_mtc0_context(arg);
4782            rn = "Context";
4783            break;
4784        case 1:
4785//           gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
4786            rn = "ContextConfig";
4787//           break;
4788        default:
4789            goto die;
4790        }
4791        break;
4792    case 5:
4793        switch (sel) {
4794        case 0:
4795            gen_helper_mtc0_pagemask(arg);
4796            rn = "PageMask";
4797            break;
4798        case 1:
4799            check_insn(env, ctx, ISA_MIPS32R2);
4800            gen_helper_mtc0_pagegrain(arg);
4801            rn = "PageGrain";
4802            break;
4803        default:
4804            goto die;
4805        }
4806        break;
4807    case 6:
4808        switch (sel) {
4809        case 0:
4810            gen_helper_mtc0_wired(arg);
4811            rn = "Wired";
4812            break;
4813        case 1:
4814            check_insn(env, ctx, ISA_MIPS32R2);
4815            gen_helper_mtc0_srsconf0(arg);
4816            rn = "SRSConf0";
4817            break;
4818        case 2:
4819            check_insn(env, ctx, ISA_MIPS32R2);
4820            gen_helper_mtc0_srsconf1(arg);
4821            rn = "SRSConf1";
4822            break;
4823        case 3:
4824            check_insn(env, ctx, ISA_MIPS32R2);
4825            gen_helper_mtc0_srsconf2(arg);
4826            rn = "SRSConf2";
4827            break;
4828        case 4:
4829            check_insn(env, ctx, ISA_MIPS32R2);
4830            gen_helper_mtc0_srsconf3(arg);
4831            rn = "SRSConf3";
4832            break;
4833        case 5:
4834            check_insn(env, ctx, ISA_MIPS32R2);
4835            gen_helper_mtc0_srsconf4(arg);
4836            rn = "SRSConf4";
4837            break;
4838        default:
4839            goto die;
4840        }
4841        break;
4842    case 7:
4843        switch (sel) {
4844        case 0:
4845            check_insn(env, ctx, ISA_MIPS32R2);
4846            gen_helper_mtc0_hwrena(arg);
4847            rn = "HWREna";
4848            break;
4849        default:
4850            goto die;
4851        }
4852        break;
4853    case 8:
4854        /* ignored */
4855        rn = "BadVAddr";
4856        break;
4857    case 9:
4858        switch (sel) {
4859        case 0:
4860            gen_helper_mtc0_count(arg);
4861            rn = "Count";
4862            break;
4863        /* 6,7 are implementation dependent */
4864        default:
4865            goto die;
4866        }
4867        /* Stop translation as we may have switched the execution mode */
4868        ctx->bstate = BS_STOP;
4869        break;
4870    case 10:
4871        switch (sel) {
4872        case 0:
4873            gen_helper_mtc0_entryhi(arg);
4874            rn = "EntryHi";
4875            break;
4876        default:
4877            goto die;
4878        }
4879        break;
4880    case 11:
4881        switch (sel) {
4882        case 0:
4883            gen_helper_mtc0_compare(arg);
4884            rn = "Compare";
4885            break;
4886        /* 6,7 are implementation dependent */
4887        default:
4888            goto die;
4889        }
4890        /* Stop translation as we may have switched the execution mode */
4891        ctx->bstate = BS_STOP;
4892        break;
4893    case 12:
4894        switch (sel) {
4895        case 0:
4896            save_cpu_state(ctx, 1);
4897            gen_helper_mtc0_status(arg);
4898            /* BS_STOP isn't good enough here, hflags may have changed. */
4899            gen_save_pc(ctx->pc + 4);
4900            ctx->bstate = BS_EXCP;
4901            rn = "Status";
4902            break;
4903        case 1:
4904            check_insn(env, ctx, ISA_MIPS32R2);
4905            gen_helper_mtc0_intctl(arg);
4906            /* Stop translation as we may have switched the execution mode */
4907            ctx->bstate = BS_STOP;
4908            rn = "IntCtl";
4909            break;
4910        case 2:
4911            check_insn(env, ctx, ISA_MIPS32R2);
4912            gen_helper_mtc0_srsctl(arg);
4913            /* Stop translation as we may have switched the execution mode */
4914            ctx->bstate = BS_STOP;
4915            rn = "SRSCtl";
4916            break;
4917        case 3:
4918            check_insn(env, ctx, ISA_MIPS32R2);
4919            gen_mtc0_store32(arg, offsetof(CPUState, CP0_SRSMap));
4920            /* Stop translation as we may have switched the execution mode */
4921            ctx->bstate = BS_STOP;
4922            rn = "SRSMap";
4923            break;
4924        default:
4925            goto die;
4926        }
4927        break;
4928    case 13:
4929        switch (sel) {
4930        case 0:
4931            save_cpu_state(ctx, 1);
4932            gen_helper_mtc0_cause(arg);
4933            rn = "Cause";
4934            break;
4935        default:
4936            goto die;
4937        }
4938        break;
4939    case 14:
4940        switch (sel) {
4941        case 0:
4942            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
4943            rn = "EPC";
4944            break;
4945        default:
4946            goto die;
4947        }
4948        break;
4949    case 15:
4950        switch (sel) {
4951        case 0:
4952            /* ignored */
4953            rn = "PRid";
4954            break;
4955        case 1:
4956            check_insn(env, ctx, ISA_MIPS32R2);
4957            gen_helper_mtc0_ebase(arg);
4958            rn = "EBase";
4959            break;
4960        default:
4961            goto die;
4962        }
4963        break;
4964    case 16:
4965        switch (sel) {
4966        case 0:
4967            gen_helper_mtc0_config0(arg);
4968            rn = "Config";
4969            /* Stop translation as we may have switched the execution mode */
4970            ctx->bstate = BS_STOP;
4971            break;
4972        case 1:
4973            /* ignored, read only */
4974            rn = "Config1";
4975            break;
4976        case 2:
4977            gen_helper_mtc0_config2(arg);
4978            rn = "Config2";
4979            /* Stop translation as we may have switched the execution mode */
4980            ctx->bstate = BS_STOP;
4981            break;
4982        case 3:
4983            /* ignored */
4984            rn = "Config3";
4985            break;
4986        /* 6,7 are implementation dependent */
4987        default:
4988            rn = "Invalid config selector";
4989            goto die;
4990        }
4991        break;
4992    case 17:
4993        switch (sel) {
4994        case 0:
4995            /* ignored */
4996            rn = "LLAddr";
4997            break;
4998        default:
4999            goto die;
5000        }
5001        break;
5002    case 18:
5003        switch (sel) {
5004        case 0 ... 7:
5005            gen_helper_1i(mtc0_watchlo, arg, sel);
5006            rn = "WatchLo";
5007            break;
5008        default:
5009            goto die;
5010        }
5011        break;
5012    case 19:
5013        switch (sel) {
5014        case 0 ... 7:
5015            gen_helper_1i(mtc0_watchhi, arg, sel);
5016            rn = "WatchHi";
5017            break;
5018        default:
5019            goto die;
5020        }
5021        break;
5022    case 20:
5023        switch (sel) {
5024        case 0:
5025            check_insn(env, ctx, ISA_MIPS3);
5026            gen_helper_mtc0_xcontext(arg);
5027            rn = "XContext";
5028            break;
5029        default:
5030            goto die;
5031        }
5032        break;
5033    case 21:
5034       /* Officially reserved, but sel 0 is used for R1x000 framemask */
5035        switch (sel) {
5036        case 0:
5037            gen_helper_mtc0_framemask(arg);
5038            rn = "Framemask";
5039            break;
5040        default:
5041            goto die;
5042        }
5043        break;
5044    case 22:
5045        /* ignored */
5046        rn = "Diagnostic"; /* implementation dependent */
5047        break;
5048    case 23:
5049        switch (sel) {
5050        case 0:
5051            gen_helper_mtc0_debug(arg); /* EJTAG support */
5052            /* BS_STOP isn't good enough here, hflags may have changed. */
5053            gen_save_pc(ctx->pc + 4);
5054            ctx->bstate = BS_EXCP;
5055            rn = "Debug";
5056            break;
5057        case 1:
5058//            gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
5059            /* Stop translation as we may have switched the execution mode */
5060            ctx->bstate = BS_STOP;
5061            rn = "TraceControl";
5062//            break;
5063        case 2:
5064//            gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
5065            /* Stop translation as we may have switched the execution mode */
5066            ctx->bstate = BS_STOP;
5067            rn = "TraceControl2";
5068//            break;
5069        case 3:
5070//            gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
5071            /* Stop translation as we may have switched the execution mode */
5072            ctx->bstate = BS_STOP;
5073            rn = "UserTraceData";
5074//            break;
5075        case 4:
5076//            gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
5077            /* Stop translation as we may have switched the execution mode */
5078            ctx->bstate = BS_STOP;
5079            rn = "TraceBPC";
5080//            break;
5081        default:
5082            goto die;
5083        }
5084        break;
5085    case 24:
5086        switch (sel) {
5087        case 0:
5088            /* EJTAG support */
5089            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
5090            rn = "DEPC";
5091            break;
5092        default:
5093            goto die;
5094        }
5095        break;
5096    case 25:
5097        switch (sel) {
5098        case 0:
5099            gen_helper_mtc0_performance0(arg);
5100            rn = "Performance0";
5101            break;
5102        case 1:
5103//            gen_helper_mtc0_performance1(arg);
5104            rn = "Performance1";
5105//            break;
5106        case 2:
5107//            gen_helper_mtc0_performance2(arg);
5108            rn = "Performance2";
5109//            break;
5110        case 3:
5111//            gen_helper_mtc0_performance3(arg);
5112            rn = "Performance3";
5113//            break;
5114        case 4:
5115//            gen_helper_mtc0_performance4(arg);
5116            rn = "Performance4";
5117//            break;
5118        case 5:
5119//            gen_helper_mtc0_performance5(arg);
5120            rn = "Performance5";
5121//            break;
5122        case 6:
5123//            gen_helper_mtc0_performance6(arg);
5124            rn = "Performance6";
5125//            break;
5126        case 7:
5127//            gen_helper_mtc0_performance7(arg);
5128            rn = "Performance7";
5129//            break;
5130        default:
5131            goto die;
5132        }
5133        break;
5134    case 26:
5135        /* ignored */
5136        rn = "ECC";
5137        break;
5138    case 27:
5139        switch (sel) {
5140        case 0 ... 3:
5141            /* ignored */
5142            rn = "CacheErr";
5143            break;
5144        default:
5145            goto die;
5146        }
5147        break;
5148    case 28:
5149        switch (sel) {
5150        case 0:
5151        case 2:
5152        case 4:
5153        case 6:
5154            gen_helper_mtc0_taglo(arg);
5155            rn = "TagLo";
5156            break;
5157        case 1:
5158        case 3:
5159        case 5:
5160        case 7:
5161            gen_helper_mtc0_datalo(arg);
5162            rn = "DataLo";
5163            break;
5164        default:
5165            goto die;
5166        }
5167        break;
5168    case 29:
5169        switch (sel) {
5170        case 0:
5171        case 2:
5172        case 4:
5173        case 6:
5174            gen_helper_mtc0_taghi(arg);
5175            rn = "TagHi";
5176            break;
5177        case 1:
5178        case 3:
5179        case 5:
5180        case 7:
5181            gen_helper_mtc0_datahi(arg);
5182            rn = "DataHi";
5183            break;
5184        default:
5185            rn = "invalid sel";
5186            goto die;
5187        }
5188        break;
5189    case 30:
5190        switch (sel) {
5191        case 0:
5192            tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
5193            rn = "ErrorEPC";
5194            break;
5195        default:
5196            goto die;
5197        }
5198        break;
5199    case 31:
5200        switch (sel) {
5201        case 0:
5202            /* EJTAG support */
5203            gen_mtc0_store32(arg, offsetof(CPUState, CP0_DESAVE));
5204            rn = "DESAVE";
5205            break;
5206        default:
5207            goto die;
5208        }
5209        /* Stop translation as we may have switched the execution mode */
5210        ctx->bstate = BS_STOP;
5211        break;
5212    default:
5213        goto die;
5214    }
5215    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5216    /* For simplicity assume that all writes can cause interrupts.  */
5217    if (use_icount) {
5218        gen_io_end();
5219        ctx->bstate = BS_STOP;
5220    }
5221    return;
5222
5223die:
5224    LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
5225    generate_exception(ctx, EXCP_RI);
5226}
5227#endif /* TARGET_MIPS64 */
5228
5229static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
5230                     int u, int sel, int h)
5231{
5232    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5233    TCGv t0 = tcg_temp_local_new();
5234
5235    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5236        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5237         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5238        tcg_gen_movi_tl(t0, -1);
5239    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5240             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5241        tcg_gen_movi_tl(t0, -1);
5242    else if (u == 0) {
5243        switch (rt) {
5244        case 2:
5245            switch (sel) {
5246            case 1:
5247                gen_helper_mftc0_tcstatus(t0);
5248                break;
5249            case 2:
5250                gen_helper_mftc0_tcbind(t0);
5251                break;
5252            case 3:
5253                gen_helper_mftc0_tcrestart(t0);
5254                break;
5255            case 4:
5256                gen_helper_mftc0_tchalt(t0);
5257                break;
5258            case 5:
5259                gen_helper_mftc0_tccontext(t0);
5260                break;
5261            case 6:
5262                gen_helper_mftc0_tcschedule(t0);
5263                break;
5264            case 7:
5265                gen_helper_mftc0_tcschefback(t0);
5266                break;
5267            default:
5268                gen_mfc0(env, ctx, t0, rt, sel);
5269                break;
5270            }
5271            break;
5272        case 10:
5273            switch (sel) {
5274            case 0:
5275                gen_helper_mftc0_entryhi(t0);
5276                break;
5277            default:
5278                gen_mfc0(env, ctx, t0, rt, sel);
5279                break;
5280            }
5281        case 12:
5282            switch (sel) {
5283            case 0:
5284                gen_helper_mftc0_status(t0);
5285                break;
5286            default:
5287                gen_mfc0(env, ctx, t0, rt, sel);
5288                break;
5289            }
5290        case 23:
5291            switch (sel) {
5292            case 0:
5293                gen_helper_mftc0_debug(t0);
5294                break;
5295            default:
5296                gen_mfc0(env, ctx, t0, rt, sel);
5297                break;
5298            }
5299            break;
5300        default:
5301            gen_mfc0(env, ctx, t0, rt, sel);
5302        }
5303    } else switch (sel) {
5304    /* GPR registers. */
5305    case 0:
5306        gen_helper_1i(mftgpr, t0, rt);
5307        break;
5308    /* Auxiliary CPU registers */
5309    case 1:
5310        switch (rt) {
5311        case 0:
5312            gen_helper_1i(mftlo, t0, 0);
5313            break;
5314        case 1:
5315            gen_helper_1i(mfthi, t0, 0);
5316            break;
5317        case 2:
5318            gen_helper_1i(mftacx, t0, 0);
5319            break;
5320        case 4:
5321            gen_helper_1i(mftlo, t0, 1);
5322            break;
5323        case 5:
5324            gen_helper_1i(mfthi, t0, 1);
5325            break;
5326        case 6:
5327            gen_helper_1i(mftacx, t0, 1);
5328            break;
5329        case 8:
5330            gen_helper_1i(mftlo, t0, 2);
5331            break;
5332        case 9:
5333            gen_helper_1i(mfthi, t0, 2);
5334            break;
5335        case 10:
5336            gen_helper_1i(mftacx, t0, 2);
5337            break;
5338        case 12:
5339            gen_helper_1i(mftlo, t0, 3);
5340            break;
5341        case 13:
5342            gen_helper_1i(mfthi, t0, 3);
5343            break;
5344        case 14:
5345            gen_helper_1i(mftacx, t0, 3);
5346            break;
5347        case 16:
5348            gen_helper_mftdsp(t0);
5349            break;
5350        default:
5351            goto die;
5352        }
5353        break;
5354    /* Floating point (COP1). */
5355    case 2:
5356        /* XXX: For now we support only a single FPU context. */
5357        if (h == 0) {
5358            TCGv_i32 fp0 = tcg_temp_new_i32();
5359
5360            gen_load_fpr32(fp0, rt);
5361            tcg_gen_ext_i32_tl(t0, fp0);
5362            tcg_temp_free_i32(fp0);
5363        } else {
5364            TCGv_i32 fp0 = tcg_temp_new_i32();
5365
5366            gen_load_fpr32h(fp0, rt);
5367            tcg_gen_ext_i32_tl(t0, fp0);
5368            tcg_temp_free_i32(fp0);
5369        }
5370        break;
5371    case 3:
5372        /* XXX: For now we support only a single FPU context. */
5373        gen_helper_1i(cfc1, t0, rt);
5374        break;
5375    /* COP2: Not implemented. */
5376    case 4:
5377    case 5:
5378        /* fall through */
5379    default:
5380        goto die;
5381    }
5382    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5383    gen_store_gpr(t0, rd);
5384    tcg_temp_free(t0);
5385    return;
5386
5387die:
5388    tcg_temp_free(t0);
5389    LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
5390    generate_exception(ctx, EXCP_RI);
5391}
5392
5393static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
5394                     int u, int sel, int h)
5395{
5396    int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
5397    TCGv t0 = tcg_temp_local_new();
5398
5399    gen_load_gpr(t0, rt);
5400    if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
5401        ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
5402         (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
5403        /* NOP */ ;
5404    else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
5405             (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
5406        /* NOP */ ;
5407    else if (u == 0) {
5408        switch (rd) {
5409        case 2:
5410            switch (sel) {
5411            case 1:
5412                gen_helper_mttc0_tcstatus(t0);
5413                break;
5414            case 2:
5415                gen_helper_mttc0_tcbind(t0);
5416                break;
5417            case 3:
5418                gen_helper_mttc0_tcrestart(t0);
5419                break;
5420            case 4:
5421                gen_helper_mttc0_tchalt(t0);
5422                break;
5423            case 5:
5424                gen_helper_mttc0_tccontext(t0);
5425                break;
5426            case 6:
5427                gen_helper_mttc0_tcschedule(t0);
5428                break;
5429            case 7:
5430                gen_helper_mttc0_tcschefback(t0);
5431                break;
5432            default:
5433                gen_mtc0(env, ctx, t0, rd, sel);
5434                break;
5435            }
5436            break;
5437        case 10:
5438            switch (sel) {
5439            case 0:
5440                gen_helper_mttc0_entryhi(t0);
5441                break;
5442            default:
5443                gen_mtc0(env, ctx, t0, rd, sel);
5444                break;
5445            }
5446        case 12:
5447            switch (sel) {
5448            case 0:
5449                gen_helper_mttc0_status(t0);
5450                break;
5451            default:
5452                gen_mtc0(env, ctx, t0, rd, sel);
5453                break;
5454            }
5455        case 23:
5456            switch (sel) {
5457            case 0:
5458                gen_helper_mttc0_debug(t0);
5459                break;
5460            default:
5461                gen_mtc0(env, ctx, t0, rd, sel);
5462                break;
5463            }
5464            break;
5465        default:
5466            gen_mtc0(env, ctx, t0, rd, sel);
5467        }
5468    } else switch (sel) {
5469    /* GPR registers. */
5470    case 0:
5471        gen_helper_1i(mttgpr, t0, rd);
5472        break;
5473    /* Auxiliary CPU registers */
5474    case 1:
5475        switch (rd) {
5476        case 0:
5477            gen_helper_1i(mttlo, t0, 0);
5478            break;
5479        case 1:
5480            gen_helper_1i(mtthi, t0, 0);
5481            break;
5482        case 2:
5483            gen_helper_1i(mttacx, t0, 0);
5484            break;
5485        case 4:
5486            gen_helper_1i(mttlo, t0, 1);
5487            break;
5488        case 5:
5489            gen_helper_1i(mtthi, t0, 1);
5490            break;
5491        case 6:
5492            gen_helper_1i(mttacx, t0, 1);
5493            break;
5494        case 8:
5495            gen_helper_1i(mttlo, t0, 2);
5496            break;
5497        case 9:
5498            gen_helper_1i(mtthi, t0, 2);
5499            break;
5500        case 10:
5501            gen_helper_1i(mttacx, t0, 2);
5502            break;
5503        case 12:
5504            gen_helper_1i(mttlo, t0, 3);
5505            break;
5506        case 13:
5507            gen_helper_1i(mtthi, t0, 3);
5508            break;
5509        case 14:
5510            gen_helper_1i(mttacx, t0, 3);
5511            break;
5512        case 16:
5513            gen_helper_mttdsp(t0);
5514            break;
5515        default:
5516            goto die;
5517        }
5518        break;
5519    /* Floating point (COP1). */
5520    case 2:
5521        /* XXX: For now we support only a single FPU context. */
5522        if (h == 0) {
5523            TCGv_i32 fp0 = tcg_temp_new_i32();
5524
5525            tcg_gen_trunc_tl_i32(fp0, t0);
5526            gen_store_fpr32(fp0, rd);
5527            tcg_temp_free_i32(fp0);
5528        } else {
5529            TCGv_i32 fp0 = tcg_temp_new_i32();
5530
5531            tcg_gen_trunc_tl_i32(fp0, t0);
5532            gen_store_fpr32h(fp0, rd);
5533            tcg_temp_free_i32(fp0);
5534        }
5535        break;
5536    case 3:
5537        /* XXX: For now we support only a single FPU context. */
5538        gen_helper_1i(ctc1, t0, rd);
5539        break;
5540    /* COP2: Not implemented. */
5541    case 4:
5542    case 5:
5543        /* fall through */
5544    default:
5545        goto die;
5546    }
5547    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5548    tcg_temp_free(t0);
5549    return;
5550
5551die:
5552    tcg_temp_free(t0);
5553    LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
5554    generate_exception(ctx, EXCP_RI);
5555}
5556
5557static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
5558{
5559    const char *opn = "ldst";
5560
5561    switch (opc) {
5562    case OPC_MFC0:
5563        if (rt == 0) {
5564            /* Treat as NOP. */
5565            return;
5566        }
5567        gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5568        opn = "mfc0";
5569        break;
5570    case OPC_MTC0:
5571        {
5572            TCGv t0 = tcg_temp_new();
5573
5574            gen_load_gpr(t0, rt);
5575            gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5576            tcg_temp_free(t0);
5577        }
5578        opn = "mtc0";
5579        break;
5580#if defined(TARGET_MIPS64)
5581    case OPC_DMFC0:
5582        check_insn(env, ctx, ISA_MIPS3);
5583        if (rt == 0) {
5584            /* Treat as NOP. */
5585            return;
5586        }
5587        gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
5588        opn = "dmfc0";
5589        break;
5590    case OPC_DMTC0:
5591        check_insn(env, ctx, ISA_MIPS3);
5592        {
5593            TCGv t0 = tcg_temp_new();
5594
5595            gen_load_gpr(t0, rt);
5596            gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
5597            tcg_temp_free(t0);
5598        }
5599        opn = "dmtc0";
5600        break;
5601#endif
5602    case OPC_MFTR:
5603        check_insn(env, ctx, ASE_MT);
5604        if (rd == 0) {
5605            /* Treat as NOP. */
5606            return;
5607        }
5608        gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
5609                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5610        opn = "mftr";
5611        break;
5612    case OPC_MTTR:
5613        check_insn(env, ctx, ASE_MT);
5614        gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
5615                 ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
5616        opn = "mttr";
5617        break;
5618    case OPC_TLBWI:
5619        opn = "tlbwi";
5620        if (!env->tlb->helper_tlbwi)
5621            goto die;
5622        gen_helper_tlbwi();
5623        break;
5624    case OPC_TLBWR:
5625        opn = "tlbwr";
5626        if (!env->tlb->helper_tlbwr)
5627            goto die;
5628        gen_helper_tlbwr();
5629        break;
5630    case OPC_TLBP:
5631        opn = "tlbp";
5632        if (!env->tlb->helper_tlbp)
5633            goto die;
5634        gen_helper_tlbp();
5635        break;
5636    case OPC_TLBR:
5637        opn = "tlbr";
5638        if (!env->tlb->helper_tlbr)
5639            goto die;
5640        gen_helper_tlbr();
5641        break;
5642    case OPC_ERET:
5643        opn = "eret";
5644        check_insn(env, ctx, ISA_MIPS2);
5645        gen_helper_eret();
5646        ctx->bstate = BS_EXCP;
5647        break;
5648    case OPC_DERET:
5649        opn = "deret";
5650        check_insn(env, ctx, ISA_MIPS32);
5651        if (!(ctx->hflags & MIPS_HFLAG_DM)) {
5652            MIPS_INVAL(opn);
5653            generate_exception(ctx, EXCP_RI);
5654        } else {
5655            gen_helper_deret();
5656            ctx->bstate = BS_EXCP;
5657        }
5658        break;
5659    case OPC_WAIT:
5660        opn = "wait";
5661        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
5662        /* If we get an exception, we want to restart at next instruction */
5663        ctx->pc += 4;
5664        save_cpu_state(ctx, 1);
5665        ctx->pc -= 4;
5666        gen_helper_wait();
5667        ctx->bstate = BS_EXCP;
5668        break;
5669    default:
5670 die:
5671        MIPS_INVAL(opn);
5672        generate_exception(ctx, EXCP_RI);
5673        return;
5674    }
5675    MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
5676}
5677#endif /* !CONFIG_USER_ONLY */
5678
5679/* CP1 Branches (before delay slot) */
5680static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
5681                                 int32_t cc, int32_t offset)
5682{
5683    target_ulong btarget;
5684    const char *opn = "cp1 cond branch";
5685    TCGv_i32 t0 = tcg_temp_new_i32();
5686
5687    if (cc != 0)
5688        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
5689
5690    btarget = ctx->pc + 4 + offset;
5691
5692    switch (op) {
5693    case OPC_BC1F:
5694        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5695        tcg_gen_not_i32(t0, t0);
5696        tcg_gen_andi_i32(t0, t0, 1);
5697        tcg_gen_extu_i32_tl(bcond, t0);
5698        opn = "bc1f";
5699        goto not_likely;
5700    case OPC_BC1FL:
5701        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5702        tcg_gen_not_i32(t0, t0);
5703        tcg_gen_andi_i32(t0, t0, 1);
5704        tcg_gen_extu_i32_tl(bcond, t0);
5705        opn = "bc1fl";
5706        goto likely;
5707    case OPC_BC1T:
5708        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5709        tcg_gen_andi_i32(t0, t0, 1);
5710        tcg_gen_extu_i32_tl(bcond, t0);
5711        opn = "bc1t";
5712        goto not_likely;
5713    case OPC_BC1TL:
5714        tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5715        tcg_gen_andi_i32(t0, t0, 1);
5716        tcg_gen_extu_i32_tl(bcond, t0);
5717        opn = "bc1tl";
5718    likely:
5719        ctx->hflags |= MIPS_HFLAG_BL;
5720        break;
5721    case OPC_BC1FANY2:
5722        {
5723            TCGv_i32 t1 = tcg_temp_new_i32();
5724            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5725            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5726            tcg_gen_or_i32(t0, t0, t1);
5727            tcg_temp_free_i32(t1);
5728            tcg_gen_not_i32(t0, t0);
5729            tcg_gen_andi_i32(t0, t0, 1);
5730            tcg_gen_extu_i32_tl(bcond, t0);
5731        }
5732        opn = "bc1any2f";
5733        goto not_likely;
5734    case OPC_BC1TANY2:
5735        {
5736            TCGv_i32 t1 = tcg_temp_new_i32();
5737            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5738            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5739            tcg_gen_or_i32(t0, t0, t1);
5740            tcg_temp_free_i32(t1);
5741            tcg_gen_andi_i32(t0, t0, 1);
5742            tcg_gen_extu_i32_tl(bcond, t0);
5743        }
5744        opn = "bc1any2t";
5745        goto not_likely;
5746    case OPC_BC1FANY4:
5747        {
5748            TCGv_i32 t1 = tcg_temp_new_i32();
5749            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5750            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5751            tcg_gen_or_i32(t0, t0, t1);
5752            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
5753            tcg_gen_or_i32(t0, t0, t1);
5754            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
5755            tcg_gen_or_i32(t0, t0, t1);
5756            tcg_temp_free_i32(t1);
5757            tcg_gen_not_i32(t0, t0);
5758            tcg_gen_andi_i32(t0, t0, 1);
5759            tcg_gen_extu_i32_tl(bcond, t0);
5760        }
5761        opn = "bc1any4f";
5762        goto not_likely;
5763    case OPC_BC1TANY4:
5764        {
5765            TCGv_i32 t1 = tcg_temp_new_i32();
5766            tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
5767            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
5768            tcg_gen_or_i32(t0, t0, t1);
5769            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
5770            tcg_gen_or_i32(t0, t0, t1);
5771            tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
5772            tcg_gen_or_i32(t0, t0, t1);
5773            tcg_temp_free_i32(t1);
5774            tcg_gen_andi_i32(t0, t0, 1);
5775            tcg_gen_extu_i32_tl(bcond, t0);
5776        }
5777        opn = "bc1any4t";
5778    not_likely:
5779        ctx->hflags |= MIPS_HFLAG_BC;
5780        break;
5781    default:
5782        MIPS_INVAL(opn);
5783        generate_exception (ctx, EXCP_RI);
5784        goto out;
5785    }
5786    MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
5787               ctx->hflags, btarget);
5788    ctx->btarget = btarget;
5789
5790 out:
5791    tcg_temp_free_i32(t0);
5792}
5793
5794/* Coprocessor 1 (FPU) */
5795
5796#define FOP(func, fmt) (((fmt) << 21) | (func))
5797
5798static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
5799{
5800    const char *opn = "cp1 move";
5801    TCGv t0 = tcg_temp_new();
5802
5803    switch (opc) {
5804    case OPC_MFC1:
5805        {
5806            TCGv_i32 fp0 = tcg_temp_new_i32();
5807
5808            gen_load_fpr32(fp0, fs);
5809            tcg_gen_ext_i32_tl(t0, fp0);
5810            tcg_temp_free_i32(fp0);
5811        }
5812        gen_store_gpr(t0, rt);
5813        opn = "mfc1";
5814        break;
5815    case OPC_MTC1:
5816        gen_load_gpr(t0, rt);
5817        {
5818            TCGv_i32 fp0 = tcg_temp_new_i32();
5819
5820            tcg_gen_trunc_tl_i32(fp0, t0);
5821            gen_store_fpr32(fp0, fs);
5822            tcg_temp_free_i32(fp0);
5823        }
5824        opn = "mtc1";
5825        break;
5826    case OPC_CFC1:
5827        gen_helper_1i(cfc1, t0, fs);
5828        gen_store_gpr(t0, rt);
5829        opn = "cfc1";
5830        break;
5831    case OPC_CTC1:
5832        gen_load_gpr(t0, rt);
5833        gen_helper_1i(ctc1, t0, fs);
5834        opn = "ctc1";
5835        break;
5836#if defined(TARGET_MIPS64)
5837    case OPC_DMFC1:
5838        gen_load_fpr64(ctx, t0, fs);
5839        gen_store_gpr(t0, rt);
5840        opn = "dmfc1";
5841        break;
5842    case OPC_DMTC1:
5843        gen_load_gpr(t0, rt);
5844        gen_store_fpr64(ctx, t0, fs);
5845        opn = "dmtc1";
5846        break;
5847#endif
5848    case OPC_MFHC1:
5849        {
5850            TCGv_i32 fp0 = tcg_temp_new_i32();
5851
5852            gen_load_fpr32h(fp0, fs);
5853            tcg_gen_ext_i32_tl(t0, fp0);
5854            tcg_temp_free_i32(fp0);
5855        }
5856        gen_store_gpr(t0, rt);
5857        opn = "mfhc1";
5858        break;
5859    case OPC_MTHC1:
5860        gen_load_gpr(t0, rt);
5861        {
5862            TCGv_i32 fp0 = tcg_temp_new_i32();
5863
5864            tcg_gen_trunc_tl_i32(fp0, t0);
5865            gen_store_fpr32h(fp0, fs);
5866            tcg_temp_free_i32(fp0);
5867        }
5868        opn = "mthc1";
5869        break;
5870    default:
5871        MIPS_INVAL(opn);
5872        generate_exception (ctx, EXCP_RI);
5873        goto out;
5874    }
5875    MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
5876
5877 out:
5878    tcg_temp_free(t0);
5879}
5880
5881static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
5882{
5883    int l1;
5884    TCGCond cond;
5885    TCGv_i32 t0;
5886
5887    if (rd == 0) {
5888        /* Treat as NOP. */
5889        return;
5890    }
5891
5892    if (tf)
5893        cond = TCG_COND_EQ;
5894    else
5895        cond = TCG_COND_NE;
5896
5897    l1 = gen_new_label();
5898    t0 = tcg_temp_new_i32();
5899    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
5900    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5901    tcg_temp_free_i32(t0);
5902    if (rs == 0) {
5903        tcg_gen_movi_tl(cpu_gpr[rd], 0);
5904    } else {
5905        tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
5906    }
5907    gen_set_label(l1);
5908}
5909
5910static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
5911{
5912    int cond;
5913    TCGv_i32 t0 = tcg_temp_new_i32();
5914    int l1 = gen_new_label();
5915
5916    if (tf)
5917        cond = TCG_COND_EQ;
5918    else
5919        cond = TCG_COND_NE;
5920
5921    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
5922    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5923    gen_load_fpr32(t0, fs);
5924    gen_store_fpr32(t0, fd);
5925    gen_set_label(l1);
5926    tcg_temp_free_i32(t0);
5927}
5928
5929static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
5930{
5931    int cond;
5932    TCGv_i32 t0 = tcg_temp_new_i32();
5933    TCGv_i64 fp0;
5934    int l1 = gen_new_label();
5935
5936    if (tf)
5937        cond = TCG_COND_EQ;
5938    else
5939        cond = TCG_COND_NE;
5940
5941    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
5942    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5943    tcg_temp_free_i32(t0);
5944    fp0 = tcg_temp_new_i64();
5945    gen_load_fpr64(ctx, fp0, fs);
5946    gen_store_fpr64(ctx, fp0, fd);
5947    tcg_temp_free_i64(fp0);
5948    gen_set_label(l1);
5949}
5950
5951static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
5952{
5953    int cond;
5954    TCGv_i32 t0 = tcg_temp_new_i32();
5955    int l1 = gen_new_label();
5956    int l2 = gen_new_label();
5957
5958    if (tf)
5959        cond = TCG_COND_EQ;
5960    else
5961        cond = TCG_COND_NE;
5962
5963    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
5964    tcg_gen_brcondi_i32(cond, t0, 0, l1);
5965    gen_load_fpr32(t0, fs);
5966    gen_store_fpr32(t0, fd);
5967    gen_set_label(l1);
5968
5969    tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
5970    tcg_gen_brcondi_i32(cond, t0, 0, l2);
5971    gen_load_fpr32h(t0, fs);
5972    gen_store_fpr32h(t0, fd);
5973    tcg_temp_free_i32(t0);
5974    gen_set_label(l2);
5975}
5976
5977
5978static void gen_farith (DisasContext *ctx, uint32_t op1,
5979                        int ft, int fs, int fd, int cc)
5980{
5981    const char *opn = "farith";
5982    const char *condnames[] = {
5983            "c.f",
5984            "c.un",
5985            "c.eq",
5986            "c.ueq",
5987            "c.olt",
5988            "c.ult",
5989            "c.ole",
5990            "c.ule",
5991            "c.sf",
5992            "c.ngle",
5993            "c.seq",
5994            "c.ngl",
5995            "c.lt",
5996            "c.nge",
5997            "c.le",
5998            "c.ngt",
5999    };
6000    const char *condnames_abs[] = {
6001            "cabs.f",
6002            "cabs.un",
6003            "cabs.eq",
6004            "cabs.ueq",
6005            "cabs.olt",
6006            "cabs.ult",
6007            "cabs.ole",
6008            "cabs.ule",
6009            "cabs.sf",
6010            "cabs.ngle",
6011            "cabs.seq",
6012            "cabs.ngl",
6013            "cabs.lt",
6014            "cabs.nge",
6015            "cabs.le",
6016            "cabs.ngt",
6017    };
6018    enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
6019    uint32_t func = ctx->opcode & 0x3f;
6020
6021    switch (ctx->opcode & FOP(0x3f, 0x1f)) {
6022    case FOP(0, 16):
6023        {
6024            TCGv_i32 fp0 = tcg_temp_new_i32();
6025            TCGv_i32 fp1 = tcg_temp_new_i32();
6026
6027            gen_load_fpr32(fp0, fs);
6028            gen_load_fpr32(fp1, ft);
6029            gen_helper_float_add_s(fp0, fp0, fp1);
6030            tcg_temp_free_i32(fp1);
6031            gen_store_fpr32(fp0, fd);
6032            tcg_temp_free_i32(fp0);
6033        }
6034        opn = "add.s";
6035        optype = BINOP;
6036        break;
6037    case FOP(1, 16):
6038        {
6039            TCGv_i32 fp0 = tcg_temp_new_i32();
6040            TCGv_i32 fp1 = tcg_temp_new_i32();
6041
6042            gen_load_fpr32(fp0, fs);
6043            gen_load_fpr32(fp1, ft);
6044            gen_helper_float_sub_s(fp0, fp0, fp1);
6045            tcg_temp_free_i32(fp1);
6046            gen_store_fpr32(fp0, fd);
6047            tcg_temp_free_i32(fp0);
6048        }
6049        opn = "sub.s";
6050        optype = BINOP;
6051        break;
6052    case FOP(2, 16):
6053        {
6054            TCGv_i32 fp0 = tcg_temp_new_i32();
6055            TCGv_i32 fp1 = tcg_temp_new_i32();
6056
6057            gen_load_fpr32(fp0, fs);
6058            gen_load_fpr32(fp1, ft);
6059            gen_helper_float_mul_s(fp0, fp0, fp1);
6060            tcg_temp_free_i32(fp1);
6061            gen_store_fpr32(fp0, fd);
6062            tcg_temp_free_i32(fp0);
6063        }
6064        opn = "mul.s";
6065        optype = BINOP;
6066        break;
6067    case FOP(3, 16):
6068        {
6069            TCGv_i32 fp0 = tcg_temp_new_i32();
6070            TCGv_i32 fp1 = tcg_temp_new_i32();
6071
6072            gen_load_fpr32(fp0, fs);
6073            gen_load_fpr32(fp1, ft);
6074            gen_helper_float_div_s(fp0, fp0, fp1);
6075            tcg_temp_free_i32(fp1);
6076            gen_store_fpr32(fp0, fd);
6077            tcg_temp_free_i32(fp0);
6078        }
6079        opn = "div.s";
6080        optype = BINOP;
6081        break;
6082    case FOP(4, 16):
6083        {
6084            TCGv_i32 fp0 = tcg_temp_new_i32();
6085
6086            gen_load_fpr32(fp0, fs);
6087            gen_helper_float_sqrt_s(fp0, fp0);
6088            gen_store_fpr32(fp0, fd);
6089            tcg_temp_free_i32(fp0);
6090        }
6091        opn = "sqrt.s";
6092        break;
6093    case FOP(5, 16):
6094        {
6095            TCGv_i32 fp0 = tcg_temp_new_i32();
6096
6097            gen_load_fpr32(fp0, fs);
6098            gen_helper_float_abs_s(fp0, fp0);
6099            gen_store_fpr32(fp0, fd);
6100            tcg_temp_free_i32(fp0);
6101        }
6102        opn = "abs.s";
6103        break;
6104    case FOP(6, 16):
6105        {
6106            TCGv_i32 fp0 = tcg_temp_new_i32();
6107
6108            gen_load_fpr32(fp0, fs);
6109            gen_store_fpr32(fp0, fd);
6110            tcg_temp_free_i32(fp0);
6111        }
6112        opn = "mov.s";
6113        break;
6114    case FOP(7, 16):
6115        {
6116            TCGv_i32 fp0 = tcg_temp_new_i32();
6117
6118            gen_load_fpr32(fp0, fs);
6119            gen_helper_float_chs_s(fp0, fp0);
6120            gen_store_fpr32(fp0, fd);
6121            tcg_temp_free_i32(fp0);
6122        }
6123        opn = "neg.s";
6124        break;
6125    case FOP(8, 16):
6126        check_cp1_64bitmode(ctx);
6127        {
6128            TCGv_i32 fp32 = tcg_temp_new_i32();
6129            TCGv_i64 fp64 = tcg_temp_new_i64();
6130
6131            gen_load_fpr32(fp32, fs);
6132            gen_helper_float_roundl_s(fp64, fp32);
6133            tcg_temp_free_i32(fp32);
6134            gen_store_fpr64(ctx, fp64, fd);
6135            tcg_temp_free_i64(fp64);
6136        }
6137        opn = "round.l.s";
6138        break;
6139    case FOP(9, 16):
6140        check_cp1_64bitmode(ctx);
6141        {
6142            TCGv_i32 fp32 = tcg_temp_new_i32();
6143            TCGv_i64 fp64 = tcg_temp_new_i64();
6144
6145            gen_load_fpr32(fp32, fs);
6146            gen_helper_float_truncl_s(fp64, fp32);
6147            tcg_temp_free_i32(fp32);
6148            gen_store_fpr64(ctx, fp64, fd);
6149            tcg_temp_free_i64(fp64);
6150        }
6151        opn = "trunc.l.s";
6152        break;
6153    case FOP(10, 16):
6154        check_cp1_64bitmode(ctx);
6155        {
6156            TCGv_i32 fp32 = tcg_temp_new_i32();
6157            TCGv_i64 fp64 = tcg_temp_new_i64();
6158
6159            gen_load_fpr32(fp32, fs);
6160            gen_helper_float_ceill_s(fp64, fp32);
6161            tcg_temp_free_i32(fp32);
6162            gen_store_fpr64(ctx, fp64, fd);
6163            tcg_temp_free_i64(fp64);
6164        }
6165        opn = "ceil.l.s";
6166        break;
6167    case FOP(11, 16):
6168        check_cp1_64bitmode(ctx);
6169        {
6170            TCGv_i32 fp32 = tcg_temp_new_i32();
6171            TCGv_i64 fp64 = tcg_temp_new_i64();
6172
6173            gen_load_fpr32(fp32, fs);
6174            gen_helper_float_floorl_s(fp64, fp32);
6175            tcg_temp_free_i32(fp32);
6176            gen_store_fpr64(ctx, fp64, fd);
6177            tcg_temp_free_i64(fp64);
6178        }
6179        opn = "floor.l.s";
6180        break;
6181    case FOP(12, 16):
6182        {
6183            TCGv_i32 fp0 = tcg_temp_new_i32();
6184
6185            gen_load_fpr32(fp0, fs);
6186            gen_helper_float_roundw_s(fp0, fp0);
6187            gen_store_fpr32(fp0, fd);
6188            tcg_temp_free_i32(fp0);
6189        }
6190        opn = "round.w.s";
6191        break;
6192    case FOP(13, 16):
6193        {
6194            TCGv_i32 fp0 = tcg_temp_new_i32();
6195
6196            gen_load_fpr32(fp0, fs);
6197            gen_helper_float_truncw_s(fp0, fp0);
6198            gen_store_fpr32(fp0, fd);
6199            tcg_temp_free_i32(fp0);
6200        }
6201        opn = "trunc.w.s";
6202        break;
6203    case FOP(14, 16):
6204        {
6205            TCGv_i32 fp0 = tcg_temp_new_i32();
6206
6207            gen_load_fpr32(fp0, fs);
6208            gen_helper_float_ceilw_s(fp0, fp0);
6209            gen_store_fpr32(fp0, fd);
6210            tcg_temp_free_i32(fp0);
6211        }
6212        opn = "ceil.w.s";
6213        break;
6214    case FOP(15, 16):
6215        {
6216            TCGv_i32 fp0 = tcg_temp_new_i32();
6217
6218            gen_load_fpr32(fp0, fs);
6219            gen_helper_float_floorw_s(fp0, fp0);
6220            gen_store_fpr32(fp0, fd);
6221            tcg_temp_free_i32(fp0);
6222        }
6223        opn = "floor.w.s";
6224        break;
6225    case FOP(17, 16):
6226        gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6227        opn = "movcf.s";
6228        break;
6229    case FOP(18, 16):
6230        {
6231            int l1 = gen_new_label();
6232            TCGv_i32 fp0;
6233
6234            if (ft != 0) {
6235                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6236            }
6237            fp0 = tcg_temp_new_i32();
6238            gen_load_fpr32(fp0, fs);
6239            gen_store_fpr32(fp0, fd);
6240            tcg_temp_free_i32(fp0);
6241            gen_set_label(l1);
6242        }
6243        opn = "movz.s";
6244        break;
6245    case FOP(19, 16):
6246        {
6247            int l1 = gen_new_label();
6248            TCGv_i32 fp0;
6249
6250            if (ft != 0) {
6251                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6252                fp0 = tcg_temp_new_i32();
6253                gen_load_fpr32(fp0, fs);
6254                gen_store_fpr32(fp0, fd);
6255                tcg_temp_free_i32(fp0);
6256                gen_set_label(l1);
6257            }
6258        }
6259        opn = "movn.s";
6260        break;
6261    case FOP(21, 16):
6262        check_cop1x(ctx);
6263        {
6264            TCGv_i32 fp0 = tcg_temp_new_i32();
6265
6266            gen_load_fpr32(fp0, fs);
6267            gen_helper_float_recip_s(fp0, fp0);
6268            gen_store_fpr32(fp0, fd);
6269            tcg_temp_free_i32(fp0);
6270        }
6271        opn = "recip.s";
6272        break;
6273    case FOP(22, 16):
6274        check_cop1x(ctx);
6275        {
6276            TCGv_i32 fp0 = tcg_temp_new_i32();
6277
6278            gen_load_fpr32(fp0, fs);
6279            gen_helper_float_rsqrt_s(fp0, fp0);
6280            gen_store_fpr32(fp0, fd);
6281            tcg_temp_free_i32(fp0);
6282        }
6283        opn = "rsqrt.s";
6284        break;
6285    case FOP(28, 16):
6286        check_cp1_64bitmode(ctx);
6287        {
6288            TCGv_i32 fp0 = tcg_temp_new_i32();
6289            TCGv_i32 fp1 = tcg_temp_new_i32();
6290
6291            gen_load_fpr32(fp0, fs);
6292            gen_load_fpr32(fp1, fd);
6293            gen_helper_float_recip2_s(fp0, fp0, fp1);
6294            tcg_temp_free_i32(fp1);
6295            gen_store_fpr32(fp0, fd);
6296            tcg_temp_free_i32(fp0);
6297        }
6298        opn = "recip2.s";
6299        break;
6300    case FOP(29, 16):
6301        check_cp1_64bitmode(ctx);
6302        {
6303            TCGv_i32 fp0 = tcg_temp_new_i32();
6304
6305            gen_load_fpr32(fp0, fs);
6306            gen_helper_float_recip1_s(fp0, fp0);
6307            gen_store_fpr32(fp0, fd);
6308            tcg_temp_free_i32(fp0);
6309        }
6310        opn = "recip1.s";
6311        break;
6312    case FOP(30, 16):
6313        check_cp1_64bitmode(ctx);
6314        {
6315            TCGv_i32 fp0 = tcg_temp_new_i32();
6316
6317            gen_load_fpr32(fp0, fs);
6318            gen_helper_float_rsqrt1_s(fp0, fp0);
6319            gen_store_fpr32(fp0, fd);
6320            tcg_temp_free_i32(fp0);
6321        }
6322        opn = "rsqrt1.s";
6323        break;
6324    case FOP(31, 16):
6325        check_cp1_64bitmode(ctx);
6326        {
6327            TCGv_i32 fp0 = tcg_temp_new_i32();
6328            TCGv_i32 fp1 = tcg_temp_new_i32();
6329
6330            gen_load_fpr32(fp0, fs);
6331            gen_load_fpr32(fp1, ft);
6332            gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
6333            tcg_temp_free_i32(fp1);
6334            gen_store_fpr32(fp0, fd);
6335            tcg_temp_free_i32(fp0);
6336        }
6337        opn = "rsqrt2.s";
6338        break;
6339    case FOP(33, 16):
6340        check_cp1_registers(ctx, fd);
6341        {
6342            TCGv_i32 fp32 = tcg_temp_new_i32();
6343            TCGv_i64 fp64 = tcg_temp_new_i64();
6344
6345            gen_load_fpr32(fp32, fs);
6346            gen_helper_float_cvtd_s(fp64, fp32);
6347            tcg_temp_free_i32(fp32);
6348            gen_store_fpr64(ctx, fp64, fd);
6349            tcg_temp_free_i64(fp64);
6350        }
6351        opn = "cvt.d.s";
6352        break;
6353    case FOP(36, 16):
6354        {
6355            TCGv_i32 fp0 = tcg_temp_new_i32();
6356
6357            gen_load_fpr32(fp0, fs);
6358            gen_helper_float_cvtw_s(fp0, fp0);
6359            gen_store_fpr32(fp0, fd);
6360            tcg_temp_free_i32(fp0);
6361        }
6362        opn = "cvt.w.s";
6363        break;
6364    case FOP(37, 16):
6365        check_cp1_64bitmode(ctx);
6366        {
6367            TCGv_i32 fp32 = tcg_temp_new_i32();
6368            TCGv_i64 fp64 = tcg_temp_new_i64();
6369
6370            gen_load_fpr32(fp32, fs);
6371            gen_helper_float_cvtl_s(fp64, fp32);
6372            tcg_temp_free_i32(fp32);
6373            gen_store_fpr64(ctx, fp64, fd);
6374            tcg_temp_free_i64(fp64);
6375        }
6376        opn = "cvt.l.s";
6377        break;
6378    case FOP(38, 16):
6379        check_cp1_64bitmode(ctx);
6380        {
6381            TCGv_i64 fp64 = tcg_temp_new_i64();
6382            TCGv_i32 fp32_0 = tcg_temp_new_i32();
6383            TCGv_i32 fp32_1 = tcg_temp_new_i32();
6384
6385            gen_load_fpr32(fp32_0, fs);
6386            gen_load_fpr32(fp32_1, ft);
6387            tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
6388            tcg_temp_free_i32(fp32_1);
6389            tcg_temp_free_i32(fp32_0);
6390            gen_store_fpr64(ctx, fp64, fd);
6391            tcg_temp_free_i64(fp64);
6392        }
6393        opn = "cvt.ps.s";
6394        break;
6395    case FOP(48, 16):
6396    case FOP(49, 16):
6397    case FOP(50, 16):
6398    case FOP(51, 16):
6399    case FOP(52, 16):
6400    case FOP(53, 16):
6401    case FOP(54, 16):
6402    case FOP(55, 16):
6403    case FOP(56, 16):
6404    case FOP(57, 16):
6405    case FOP(58, 16):
6406    case FOP(59, 16):
6407    case FOP(60, 16):
6408    case FOP(61, 16):
6409    case FOP(62, 16):
6410    case FOP(63, 16):
6411        {
6412            TCGv_i32 fp0 = tcg_temp_new_i32();
6413            TCGv_i32 fp1 = tcg_temp_new_i32();
6414
6415            gen_load_fpr32(fp0, fs);
6416            gen_load_fpr32(fp1, ft);
6417            if (ctx->opcode & (1 << 6)) {
6418                check_cop1x(ctx);
6419                gen_cmpabs_s(func-48, fp0, fp1, cc);
6420                opn = condnames_abs[func-48];
6421            } else {
6422                gen_cmp_s(func-48, fp0, fp1, cc);
6423                opn = condnames[func-48];
6424            }
6425            tcg_temp_free_i32(fp0);
6426            tcg_temp_free_i32(fp1);
6427        }
6428        break;
6429    case FOP(0, 17):
6430        check_cp1_registers(ctx, fs | ft | fd);
6431        {
6432            TCGv_i64 fp0 = tcg_temp_new_i64();
6433            TCGv_i64 fp1 = tcg_temp_new_i64();
6434
6435            gen_load_fpr64(ctx, fp0, fs);
6436            gen_load_fpr64(ctx, fp1, ft);
6437            gen_helper_float_add_d(fp0, fp0, fp1);
6438            tcg_temp_free_i64(fp1);
6439            gen_store_fpr64(ctx, fp0, fd);
6440            tcg_temp_free_i64(fp0);
6441        }
6442        opn = "add.d";
6443        optype = BINOP;
6444        break;
6445    case FOP(1, 17):
6446        check_cp1_registers(ctx, fs | ft | fd);
6447        {
6448            TCGv_i64 fp0 = tcg_temp_new_i64();
6449            TCGv_i64 fp1 = tcg_temp_new_i64();
6450
6451            gen_load_fpr64(ctx, fp0, fs);
6452            gen_load_fpr64(ctx, fp1, ft);
6453            gen_helper_float_sub_d(fp0, fp0, fp1);
6454            tcg_temp_free_i64(fp1);
6455            gen_store_fpr64(ctx, fp0, fd);
6456            tcg_temp_free_i64(fp0);
6457        }
6458        opn = "sub.d";
6459        optype = BINOP;
6460        break;
6461    case FOP(2, 17):
6462        check_cp1_registers(ctx, fs | ft | fd);
6463        {
6464            TCGv_i64 fp0 = tcg_temp_new_i64();
6465            TCGv_i64 fp1 = tcg_temp_new_i64();
6466
6467            gen_load_fpr64(ctx, fp0, fs);
6468            gen_load_fpr64(ctx, fp1, ft);
6469            gen_helper_float_mul_d(fp0, fp0, fp1);
6470            tcg_temp_free_i64(fp1);
6471            gen_store_fpr64(ctx, fp0, fd);
6472            tcg_temp_free_i64(fp0);
6473        }
6474        opn = "mul.d";
6475        optype = BINOP;
6476        break;
6477    case FOP(3, 17):
6478        check_cp1_registers(ctx, fs | ft | fd);
6479        {
6480            TCGv_i64 fp0 = tcg_temp_new_i64();
6481            TCGv_i64 fp1 = tcg_temp_new_i64();
6482
6483            gen_load_fpr64(ctx, fp0, fs);
6484            gen_load_fpr64(ctx, fp1, ft);
6485            gen_helper_float_div_d(fp0, fp0, fp1);
6486            tcg_temp_free_i64(fp1);
6487            gen_store_fpr64(ctx, fp0, fd);
6488            tcg_temp_free_i64(fp0);
6489        }
6490        opn = "div.d";
6491        optype = BINOP;
6492        break;
6493    case FOP(4, 17):
6494        check_cp1_registers(ctx, fs | fd);
6495        {
6496            TCGv_i64 fp0 = tcg_temp_new_i64();
6497
6498            gen_load_fpr64(ctx, fp0, fs);
6499            gen_helper_float_sqrt_d(fp0, fp0);
6500            gen_store_fpr64(ctx, fp0, fd);
6501            tcg_temp_free_i64(fp0);
6502        }
6503        opn = "sqrt.d";
6504        break;
6505    case FOP(5, 17):
6506        check_cp1_registers(ctx, fs | fd);
6507        {
6508            TCGv_i64 fp0 = tcg_temp_new_i64();
6509
6510            gen_load_fpr64(ctx, fp0, fs);
6511            gen_helper_float_abs_d(fp0, fp0);
6512            gen_store_fpr64(ctx, fp0, fd);
6513            tcg_temp_free_i64(fp0);
6514        }
6515        opn = "abs.d";
6516        break;
6517    case FOP(6, 17):
6518        check_cp1_registers(ctx, fs | fd);
6519        {
6520            TCGv_i64 fp0 = tcg_temp_new_i64();
6521
6522            gen_load_fpr64(ctx, fp0, fs);
6523            gen_store_fpr64(ctx, fp0, fd);
6524            tcg_temp_free_i64(fp0);
6525        }
6526        opn = "mov.d";
6527        break;
6528    case FOP(7, 17):
6529        check_cp1_registers(ctx, fs | fd);
6530        {
6531            TCGv_i64 fp0 = tcg_temp_new_i64();
6532
6533            gen_load_fpr64(ctx, fp0, fs);
6534            gen_helper_float_chs_d(fp0, fp0);
6535            gen_store_fpr64(ctx, fp0, fd);
6536            tcg_temp_free_i64(fp0);
6537        }
6538        opn = "neg.d";
6539        break;
6540    case FOP(8, 17):
6541        check_cp1_64bitmode(ctx);
6542        {
6543            TCGv_i64 fp0 = tcg_temp_new_i64();
6544
6545            gen_load_fpr64(ctx, fp0, fs);
6546            gen_helper_float_roundl_d(fp0, fp0);
6547            gen_store_fpr64(ctx, fp0, fd);
6548            tcg_temp_free_i64(fp0);
6549        }
6550        opn = "round.l.d";
6551        break;
6552    case FOP(9, 17):
6553        check_cp1_64bitmode(ctx);
6554        {
6555            TCGv_i64 fp0 = tcg_temp_new_i64();
6556
6557            gen_load_fpr64(ctx, fp0, fs);
6558            gen_helper_float_truncl_d(fp0, fp0);
6559            gen_store_fpr64(ctx, fp0, fd);
6560            tcg_temp_free_i64(fp0);
6561        }
6562        opn = "trunc.l.d";
6563        break;
6564    case FOP(10, 17):
6565        check_cp1_64bitmode(ctx);
6566        {
6567            TCGv_i64 fp0 = tcg_temp_new_i64();
6568
6569            gen_load_fpr64(ctx, fp0, fs);
6570            gen_helper_float_ceill_d(fp0, fp0);
6571            gen_store_fpr64(ctx, fp0, fd);
6572            tcg_temp_free_i64(fp0);
6573        }
6574        opn = "ceil.l.d";
6575        break;
6576    case FOP(11, 17):
6577        check_cp1_64bitmode(ctx);
6578        {
6579            TCGv_i64 fp0 = tcg_temp_new_i64();
6580
6581            gen_load_fpr64(ctx, fp0, fs);
6582            gen_helper_float_floorl_d(fp0, fp0);
6583            gen_store_fpr64(ctx, fp0, fd);
6584            tcg_temp_free_i64(fp0);
6585        }
6586        opn = "floor.l.d";
6587        break;
6588    case FOP(12, 17):
6589        check_cp1_registers(ctx, fs);
6590        {
6591            TCGv_i32 fp32 = tcg_temp_new_i32();
6592            TCGv_i64 fp64 = tcg_temp_new_i64();
6593
6594            gen_load_fpr64(ctx, fp64, fs);
6595            gen_helper_float_roundw_d(fp32, fp64);
6596            tcg_temp_free_i64(fp64);
6597            gen_store_fpr32(fp32, fd);
6598            tcg_temp_free_i32(fp32);
6599        }
6600        opn = "round.w.d";
6601        break;
6602    case FOP(13, 17):
6603        check_cp1_registers(ctx, fs);
6604        {
6605            TCGv_i32 fp32 = tcg_temp_new_i32();
6606            TCGv_i64 fp64 = tcg_temp_new_i64();
6607
6608            gen_load_fpr64(ctx, fp64, fs);
6609            gen_helper_float_truncw_d(fp32, fp64);
6610            tcg_temp_free_i64(fp64);
6611            gen_store_fpr32(fp32, fd);
6612            tcg_temp_free_i32(fp32);
6613        }
6614        opn = "trunc.w.d";
6615        break;
6616    case FOP(14, 17):
6617        check_cp1_registers(ctx, fs);
6618        {
6619            TCGv_i32 fp32 = tcg_temp_new_i32();
6620            TCGv_i64 fp64 = tcg_temp_new_i64();
6621
6622            gen_load_fpr64(ctx, fp64, fs);
6623            gen_helper_float_ceilw_d(fp32, fp64);
6624            tcg_temp_free_i64(fp64);
6625            gen_store_fpr32(fp32, fd);
6626            tcg_temp_free_i32(fp32);
6627        }
6628        opn = "ceil.w.d";
6629        break;
6630    case FOP(15, 17):
6631        check_cp1_registers(ctx, fs);
6632        {
6633            TCGv_i32 fp32 = tcg_temp_new_i32();
6634            TCGv_i64 fp64 = tcg_temp_new_i64();
6635
6636            gen_load_fpr64(ctx, fp64, fs);
6637            gen_helper_float_floorw_d(fp32, fp64);
6638            tcg_temp_free_i64(fp64);
6639            gen_store_fpr32(fp32, fd);
6640            tcg_temp_free_i32(fp32);
6641        }
6642        opn = "floor.w.d";
6643        break;
6644    case FOP(17, 17):
6645        gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6646        opn = "movcf.d";
6647        break;
6648    case FOP(18, 17):
6649        {
6650            int l1 = gen_new_label();
6651            TCGv_i64 fp0;
6652
6653            if (ft != 0) {
6654                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6655            }
6656            fp0 = tcg_temp_new_i64();
6657            gen_load_fpr64(ctx, fp0, fs);
6658            gen_store_fpr64(ctx, fp0, fd);
6659            tcg_temp_free_i64(fp0);
6660            gen_set_label(l1);
6661        }
6662        opn = "movz.d";
6663        break;
6664    case FOP(19, 17):
6665        {
6666            int l1 = gen_new_label();
6667            TCGv_i64 fp0;
6668
6669            if (ft != 0) {
6670                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
6671                fp0 = tcg_temp_new_i64();
6672                gen_load_fpr64(ctx, fp0, fs);
6673                gen_store_fpr64(ctx, fp0, fd);
6674                tcg_temp_free_i64(fp0);
6675                gen_set_label(l1);
6676            }
6677        }
6678        opn = "movn.d";
6679        break;
6680    case FOP(21, 17):
6681        check_cp1_64bitmode(ctx);
6682        {
6683            TCGv_i64 fp0 = tcg_temp_new_i64();
6684
6685            gen_load_fpr64(ctx, fp0, fs);
6686            gen_helper_float_recip_d(fp0, fp0);
6687            gen_store_fpr64(ctx, fp0, fd);
6688            tcg_temp_free_i64(fp0);
6689        }
6690        opn = "recip.d";
6691        break;
6692    case FOP(22, 17):
6693        check_cp1_64bitmode(ctx);
6694        {
6695            TCGv_i64 fp0 = tcg_temp_new_i64();
6696
6697            gen_load_fpr64(ctx, fp0, fs);
6698            gen_helper_float_rsqrt_d(fp0, fp0);
6699            gen_store_fpr64(ctx, fp0, fd);
6700            tcg_temp_free_i64(fp0);
6701        }
6702        opn = "rsqrt.d";
6703        break;
6704    case FOP(28, 17):
6705        check_cp1_64bitmode(ctx);
6706        {
6707            TCGv_i64 fp0 = tcg_temp_new_i64();
6708            TCGv_i64 fp1 = tcg_temp_new_i64();
6709
6710            gen_load_fpr64(ctx, fp0, fs);
6711            gen_load_fpr64(ctx, fp1, ft);
6712            gen_helper_float_recip2_d(fp0, fp0, fp1);
6713            tcg_temp_free_i64(fp1);
6714            gen_store_fpr64(ctx, fp0, fd);
6715            tcg_temp_free_i64(fp0);
6716        }
6717        opn = "recip2.d";
6718        break;
6719    case FOP(29, 17):
6720        check_cp1_64bitmode(ctx);
6721        {
6722            TCGv_i64 fp0 = tcg_temp_new_i64();
6723
6724            gen_load_fpr64(ctx, fp0, fs);
6725            gen_helper_float_recip1_d(fp0, fp0);
6726            gen_store_fpr64(ctx, fp0, fd);
6727            tcg_temp_free_i64(fp0);
6728        }
6729        opn = "recip1.d";
6730        break;
6731    case FOP(30, 17):
6732        check_cp1_64bitmode(ctx);
6733        {
6734            TCGv_i64 fp0 = tcg_temp_new_i64();
6735
6736            gen_load_fpr64(ctx, fp0, fs);
6737            gen_helper_float_rsqrt1_d(fp0, fp0);
6738            gen_store_fpr64(ctx, fp0, fd);
6739            tcg_temp_free_i64(fp0);
6740        }
6741        opn = "rsqrt1.d";
6742        break;
6743    case FOP(31, 17):
6744        check_cp1_64bitmode(ctx);
6745        {
6746            TCGv_i64 fp0 = tcg_temp_new_i64();
6747            TCGv_i64 fp1 = tcg_temp_new_i64();
6748
6749            gen_load_fpr64(ctx, fp0, fs);
6750            gen_load_fpr64(ctx, fp1, ft);
6751            gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
6752            tcg_temp_free_i64(fp1);
6753            gen_store_fpr64(ctx, fp0, fd);
6754            tcg_temp_free_i64(fp0);
6755        }
6756        opn = "rsqrt2.d";
6757        break;
6758    case FOP(48, 17):
6759    case FOP(49, 17):
6760    case FOP(50, 17):
6761    case FOP(51, 17):
6762    case FOP(52, 17):
6763    case FOP(53, 17):
6764    case FOP(54, 17):
6765    case FOP(55, 17):
6766    case FOP(56, 17):
6767    case FOP(57, 17):
6768    case FOP(58, 17):
6769    case FOP(59, 17):
6770    case FOP(60, 17):
6771    case FOP(61, 17):
6772    case FOP(62, 17):
6773    case FOP(63, 17):
6774        {
6775            TCGv_i64 fp0 = tcg_temp_new_i64();
6776            TCGv_i64 fp1 = tcg_temp_new_i64();
6777
6778            gen_load_fpr64(ctx, fp0, fs);
6779            gen_load_fpr64(ctx, fp1, ft);
6780            if (ctx->opcode & (1 << 6)) {
6781                check_cop1x(ctx);
6782                check_cp1_registers(ctx, fs | ft);
6783                gen_cmpabs_d(func-48, fp0, fp1, cc);
6784                opn = condnames_abs[func-48];
6785            } else {
6786                check_cp1_registers(ctx, fs | ft);
6787                gen_cmp_d(func-48, fp0, fp1, cc);
6788                opn = condnames[func-48];
6789            }
6790            tcg_temp_free_i64(fp0);
6791            tcg_temp_free_i64(fp1);
6792        }
6793        break;
6794    case FOP(32, 17):
6795        check_cp1_registers(ctx, fs);
6796        {
6797            TCGv_i32 fp32 = tcg_temp_new_i32();
6798            TCGv_i64 fp64 = tcg_temp_new_i64();
6799
6800            gen_load_fpr64(ctx, fp64, fs);
6801            gen_helper_float_cvts_d(fp32, fp64);
6802            tcg_temp_free_i64(fp64);
6803            gen_store_fpr32(fp32, fd);
6804            tcg_temp_free_i32(fp32);
6805        }
6806        opn = "cvt.s.d";
6807        break;
6808    case FOP(36, 17):
6809        check_cp1_registers(ctx, fs);
6810        {
6811            TCGv_i32 fp32 = tcg_temp_new_i32();
6812            TCGv_i64 fp64 = tcg_temp_new_i64();
6813
6814            gen_load_fpr64(ctx, fp64, fs);
6815            gen_helper_float_cvtw_d(fp32, fp64);
6816            tcg_temp_free_i64(fp64);
6817            gen_store_fpr32(fp32, fd);
6818            tcg_temp_free_i32(fp32);
6819        }
6820        opn = "cvt.w.d";
6821        break;
6822    case FOP(37, 17):
6823        check_cp1_64bitmode(ctx);
6824        {
6825            TCGv_i64 fp0 = tcg_temp_new_i64();
6826
6827            gen_load_fpr64(ctx, fp0, fs);
6828            gen_helper_float_cvtl_d(fp0, fp0);
6829            gen_store_fpr64(ctx, fp0, fd);
6830            tcg_temp_free_i64(fp0);
6831        }
6832        opn = "cvt.l.d";
6833        break;
6834    case FOP(32, 20):
6835        {
6836            TCGv_i32 fp0 = tcg_temp_new_i32();
6837
6838            gen_load_fpr32(fp0, fs);
6839            gen_helper_float_cvts_w(fp0, fp0);
6840            gen_store_fpr32(fp0, fd);
6841            tcg_temp_free_i32(fp0);
6842        }
6843        opn = "cvt.s.w";
6844        break;
6845    case FOP(33, 20):
6846        check_cp1_registers(ctx, fd);
6847        {
6848            TCGv_i32 fp32 = tcg_temp_new_i32();
6849            TCGv_i64 fp64 = tcg_temp_new_i64();
6850
6851            gen_load_fpr32(fp32, fs);
6852            gen_helper_float_cvtd_w(fp64, fp32);
6853            tcg_temp_free_i32(fp32);
6854            gen_store_fpr64(ctx, fp64, fd);
6855            tcg_temp_free_i64(fp64);
6856        }
6857        opn = "cvt.d.w";
6858        break;
6859    case FOP(32, 21):
6860        check_cp1_64bitmode(ctx);
6861        {
6862            TCGv_i32 fp32 = tcg_temp_new_i32();
6863            TCGv_i64 fp64 = tcg_temp_new_i64();
6864
6865            gen_load_fpr64(ctx, fp64, fs);
6866            gen_helper_float_cvts_l(fp32, fp64);
6867            tcg_temp_free_i64(fp64);
6868            gen_store_fpr32(fp32, fd);
6869            tcg_temp_free_i32(fp32);
6870        }
6871        opn = "cvt.s.l";
6872        break;
6873    case FOP(33, 21):
6874        check_cp1_64bitmode(ctx);
6875        {
6876            TCGv_i64 fp0 = tcg_temp_new_i64();
6877
6878            gen_load_fpr64(ctx, fp0, fs);
6879            gen_helper_float_cvtd_l(fp0, fp0);
6880            gen_store_fpr64(ctx, fp0, fd);
6881            tcg_temp_free_i64(fp0);
6882        }
6883        opn = "cvt.d.l";
6884        break;
6885    case FOP(38, 20):
6886        check_cp1_64bitmode(ctx);
6887        {
6888            TCGv_i64 fp0 = tcg_temp_new_i64();
6889
6890            gen_load_fpr64(ctx, fp0, fs);
6891            gen_helper_float_cvtps_pw(fp0, fp0);
6892            gen_store_fpr64(ctx, fp0, fd);
6893            tcg_temp_free_i64(fp0);
6894        }
6895        opn = "cvt.ps.pw";
6896        break;
6897    case FOP(0, 22):
6898        check_cp1_64bitmode(ctx);
6899        {
6900            TCGv_i64 fp0 = tcg_temp_new_i64();
6901            TCGv_i64 fp1 = tcg_temp_new_i64();
6902
6903            gen_load_fpr64(ctx, fp0, fs);
6904            gen_load_fpr64(ctx, fp1, ft);
6905            gen_helper_float_add_ps(fp0, fp0, fp1);
6906            tcg_temp_free_i64(fp1);
6907            gen_store_fpr64(ctx, fp0, fd);
6908            tcg_temp_free_i64(fp0);
6909        }
6910        opn = "add.ps";
6911        break;
6912    case FOP(1, 22):
6913        check_cp1_64bitmode(ctx);
6914        {
6915            TCGv_i64 fp0 = tcg_temp_new_i64();
6916            TCGv_i64 fp1 = tcg_temp_new_i64();
6917
6918            gen_load_fpr64(ctx, fp0, fs);
6919            gen_load_fpr64(ctx, fp1, ft);
6920            gen_helper_float_sub_ps(fp0, fp0, fp1);
6921            tcg_temp_free_i64(fp1);
6922            gen_store_fpr64(ctx, fp0, fd);
6923            tcg_temp_free_i64(fp0);
6924        }
6925        opn = "sub.ps";
6926        break;
6927    case FOP(2, 22):
6928        check_cp1_64bitmode(ctx);
6929        {
6930            TCGv_i64 fp0 = tcg_temp_new_i64();
6931            TCGv_i64 fp1 = tcg_temp_new_i64();
6932
6933            gen_load_fpr64(ctx, fp0, fs);
6934            gen_load_fpr64(ctx, fp1, ft);
6935            gen_helper_float_mul_ps(fp0, fp0, fp1);
6936            tcg_temp_free_i64(fp1);
6937            gen_store_fpr64(ctx, fp0, fd);
6938            tcg_temp_free_i64(fp0);
6939        }
6940        opn = "mul.ps";
6941        break;
6942    case FOP(5, 22):
6943        check_cp1_64bitmode(ctx);
6944        {
6945            TCGv_i64 fp0 = tcg_temp_new_i64();
6946
6947            gen_load_fpr64(ctx, fp0, fs);
6948            gen_helper_float_abs_ps(fp0, fp0);
6949            gen_store_fpr64(ctx, fp0, fd);
6950            tcg_temp_free_i64(fp0);
6951        }
6952        opn = "abs.ps";
6953        break;
6954    case FOP(6, 22):
6955        check_cp1_64bitmode(ctx);
6956        {
6957            TCGv_i64 fp0 = tcg_temp_new_i64();
6958
6959            gen_load_fpr64(ctx, fp0, fs);
6960            gen_store_fpr64(ctx, fp0, fd);
6961            tcg_temp_free_i64(fp0);
6962        }
6963        opn = "mov.ps";
6964        break;
6965    case FOP(7, 22):
6966        check_cp1_64bitmode(ctx);
6967        {
6968            TCGv_i64 fp0 = tcg_temp_new_i64();
6969
6970            gen_load_fpr64(ctx, fp0, fs);
6971            gen_helper_float_chs_ps(fp0, fp0);
6972            gen_store_fpr64(ctx, fp0, fd);
6973            tcg_temp_free_i64(fp0);
6974        }
6975        opn = "neg.ps";
6976        break;
6977    case FOP(17, 22):
6978        check_cp1_64bitmode(ctx);
6979        gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
6980        opn = "movcf.ps";
6981        break;
6982    case FOP(18, 22):
6983        check_cp1_64bitmode(ctx);
6984        {
6985            int l1 = gen_new_label();
6986            TCGv_i64 fp0;
6987
6988            if (ft != 0)
6989                tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
6990            fp0 = tcg_temp_new_i64();
6991            gen_load_fpr64(ctx, fp0, fs);
6992            gen_store_fpr64(ctx, fp0, fd);
6993            tcg_temp_free_i64(fp0);
6994            gen_set_label(l1);
6995        }
6996        opn = "movz.ps";
6997        break;
6998    case FOP(19, 22):
6999        check_cp1_64bitmode(ctx);
7000        {
7001            int l1 = gen_new_label();
7002            TCGv_i64 fp0;
7003
7004            if (ft != 0) {
7005                tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
7006                fp0 = tcg_temp_new_i64();
7007                gen_load_fpr64(ctx, fp0, fs);
7008                gen_store_fpr64(ctx, fp0, fd);
7009                tcg_temp_free_i64(fp0);
7010                gen_set_label(l1);
7011            }
7012        }
7013        opn = "movn.ps";
7014        break;
7015    case FOP(24, 22):
7016        check_cp1_64bitmode(ctx);
7017        {
7018            TCGv_i64 fp0 = tcg_temp_new_i64();
7019            TCGv_i64 fp1 = tcg_temp_new_i64();
7020
7021            gen_load_fpr64(ctx, fp0, ft);
7022            gen_load_fpr64(ctx, fp1, fs);
7023            gen_helper_float_addr_ps(fp0, fp0, fp1);
7024            tcg_temp_free_i64(fp1);
7025            gen_store_fpr64(ctx, fp0, fd);
7026            tcg_temp_free_i64(fp0);
7027        }
7028        opn = "addr.ps";
7029        break;
7030    case FOP(26, 22):
7031        check_cp1_64bitmode(ctx);
7032        {
7033            TCGv_i64 fp0 = tcg_temp_new_i64();
7034            TCGv_i64 fp1 = tcg_temp_new_i64();
7035
7036            gen_load_fpr64(ctx, fp0, ft);
7037            gen_load_fpr64(ctx, fp1, fs);
7038            gen_helper_float_mulr_ps(fp0, fp0, fp1);
7039            tcg_temp_free_i64(fp1);
7040            gen_store_fpr64(ctx, fp0, fd);
7041            tcg_temp_free_i64(fp0);
7042        }
7043        opn = "mulr.ps";
7044        break;
7045    case FOP(28, 22):
7046        check_cp1_64bitmode(ctx);
7047        {
7048            TCGv_i64 fp0 = tcg_temp_new_i64();
7049            TCGv_i64 fp1 = tcg_temp_new_i64();
7050
7051            gen_load_fpr64(ctx, fp0, fs);
7052            gen_load_fpr64(ctx, fp1, fd);
7053            gen_helper_float_recip2_ps(fp0, fp0, fp1);
7054            tcg_temp_free_i64(fp1);
7055            gen_store_fpr64(ctx, fp0, fd);
7056            tcg_temp_free_i64(fp0);
7057        }
7058        opn = "recip2.ps";
7059        break;
7060    case FOP(29, 22):
7061        check_cp1_64bitmode(ctx);
7062        {
7063            TCGv_i64 fp0 = tcg_temp_new_i64();
7064
7065            gen_load_fpr64(ctx, fp0, fs);
7066            gen_helper_float_recip1_ps(fp0, fp0);
7067            gen_store_fpr64(ctx, fp0, fd);
7068            tcg_temp_free_i64(fp0);
7069        }
7070        opn = "recip1.ps";
7071        break;
7072    case FOP(30, 22):
7073        check_cp1_64bitmode(ctx);
7074        {
7075            TCGv_i64 fp0 = tcg_temp_new_i64();
7076
7077            gen_load_fpr64(ctx, fp0, fs);
7078            gen_helper_float_rsqrt1_ps(fp0, fp0);
7079            gen_store_fpr64(ctx, fp0, fd);
7080            tcg_temp_free_i64(fp0);
7081        }
7082        opn = "rsqrt1.ps";
7083        break;
7084    case FOP(31, 22):
7085        check_cp1_64bitmode(ctx);
7086        {
7087            TCGv_i64 fp0 = tcg_temp_new_i64();
7088            TCGv_i64 fp1 = tcg_temp_new_i64();
7089
7090            gen_load_fpr64(ctx, fp0, fs);
7091            gen_load_fpr64(ctx, fp1, ft);
7092            gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
7093            tcg_temp_free_i64(fp1);
7094            gen_store_fpr64(ctx, fp0, fd);
7095            tcg_temp_free_i64(fp0);
7096        }
7097        opn = "rsqrt2.ps";
7098        break;
7099    case FOP(32, 22):
7100        check_cp1_64bitmode(ctx);
7101        {
7102            TCGv_i32 fp0 = tcg_temp_new_i32();
7103
7104            gen_load_fpr32h(fp0, fs);
7105            gen_helper_float_cvts_pu(fp0, fp0);
7106            gen_store_fpr32(fp0, fd);
7107            tcg_temp_free_i32(fp0);
7108        }
7109        opn = "cvt.s.pu";
7110        break;
7111    case FOP(36, 22):
7112        check_cp1_64bitmode(ctx);
7113        {
7114            TCGv_i64 fp0 = tcg_temp_new_i64();
7115
7116            gen_load_fpr64(ctx, fp0, fs);
7117            gen_helper_float_cvtpw_ps(fp0, fp0);
7118            gen_store_fpr64(ctx, fp0, fd);
7119            tcg_temp_free_i64(fp0);
7120        }
7121        opn = "cvt.pw.ps";
7122        break;
7123    case FOP(40, 22):
7124        check_cp1_64bitmode(ctx);
7125        {
7126            TCGv_i32 fp0 = tcg_temp_new_i32();
7127
7128            gen_load_fpr32(fp0, fs);
7129            gen_helper_float_cvts_pl(fp0, fp0);
7130            gen_store_fpr32(fp0, fd);
7131            tcg_temp_free_i32(fp0);
7132        }
7133        opn = "cvt.s.pl";
7134        break;
7135    case FOP(44, 22):
7136        check_cp1_64bitmode(ctx);
7137        {
7138            TCGv_i32 fp0 = tcg_temp_new_i32();
7139            TCGv_i32 fp1 = tcg_temp_new_i32();
7140
7141            gen_load_fpr32(fp0, fs);
7142            gen_load_fpr32(fp1, ft);
7143            gen_store_fpr32h(fp0, fd);
7144            gen_store_fpr32(fp1, fd);
7145            tcg_temp_free_i32(fp0);
7146            tcg_temp_free_i32(fp1);
7147        }
7148        opn = "pll.ps";
7149        break;
7150    case FOP(45, 22):
7151        check_cp1_64bitmode(ctx);
7152        {
7153            TCGv_i32 fp0 = tcg_temp_new_i32();
7154            TCGv_i32 fp1 = tcg_temp_new_i32();
7155
7156            gen_load_fpr32(fp0, fs);
7157            gen_load_fpr32h(fp1, ft);
7158            gen_store_fpr32(fp1, fd);
7159            gen_store_fpr32h(fp0, fd);
7160            tcg_temp_free_i32(fp0);
7161            tcg_temp_free_i32(fp1);
7162        }
7163        opn = "plu.ps";
7164        break;
7165    case FOP(46, 22):
7166        check_cp1_64bitmode(ctx);
7167        {
7168            TCGv_i32 fp0 = tcg_temp_new_i32();
7169            TCGv_i32 fp1 = tcg_temp_new_i32();
7170
7171            gen_load_fpr32h(fp0, fs);
7172            gen_load_fpr32(fp1, ft);
7173            gen_store_fpr32(fp1, fd);
7174            gen_store_fpr32h(fp0, fd);
7175            tcg_temp_free_i32(fp0);
7176            tcg_temp_free_i32(fp1);
7177        }
7178        opn = "pul.ps";
7179        break;
7180    case FOP(47, 22):
7181        check_cp1_64bitmode(ctx);
7182        {
7183            TCGv_i32 fp0 = tcg_temp_new_i32();
7184            TCGv_i32 fp1 = tcg_temp_new_i32();
7185
7186            gen_load_fpr32h(fp0, fs);
7187            gen_load_fpr32h(fp1, ft);
7188            gen_store_fpr32(fp1, fd);
7189            gen_store_fpr32h(fp0, fd);
7190            tcg_temp_free_i32(fp0);
7191            tcg_temp_free_i32(fp1);
7192        }
7193        opn = "puu.ps";
7194        break;
7195    case FOP(48, 22):
7196    case FOP(49, 22):
7197    case FOP(50, 22):
7198    case FOP(51, 22):
7199    case FOP(52, 22):
7200    case FOP(53, 22):
7201    case FOP(54, 22):
7202    case FOP(55, 22):
7203    case FOP(56, 22):
7204    case FOP(57, 22):
7205    case FOP(58, 22):
7206    case FOP(59, 22):
7207    case FOP(60, 22):
7208    case FOP(61, 22):
7209    case FOP(62, 22):
7210    case FOP(63, 22):
7211        check_cp1_64bitmode(ctx);
7212        {
7213            TCGv_i64 fp0 = tcg_temp_new_i64();
7214            TCGv_i64 fp1 = tcg_temp_new_i64();
7215
7216            gen_load_fpr64(ctx, fp0, fs);
7217            gen_load_fpr64(ctx, fp1, ft);
7218            if (ctx->opcode & (1 << 6)) {
7219                gen_cmpabs_ps(func-48, fp0, fp1, cc);
7220                opn = condnames_abs[func-48];
7221            } else {
7222                gen_cmp_ps(func-48, fp0, fp1, cc);
7223                opn = condnames[func-48];
7224            }
7225            tcg_temp_free_i64(fp0);
7226            tcg_temp_free_i64(fp1);
7227        }
7228        break;
7229    default:
7230        MIPS_INVAL(opn);
7231        generate_exception (ctx, EXCP_RI);
7232        return;
7233    }
7234    switch (optype) {
7235    case BINOP:
7236        MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
7237        break;
7238    case CMPOP:
7239        MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
7240        break;
7241    default:
7242        MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
7243        break;
7244    }
7245}
7246
7247/* Coprocessor 3 (FPU) */
7248static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
7249                           int fd, int fs, int base, int index)
7250{
7251    const char *opn = "extended float load/store";
7252    int store = 0;
7253    TCGv t0 = tcg_temp_new();
7254
7255    if (base == 0) {
7256        gen_load_gpr(t0, index);
7257    } else if (index == 0) {
7258        gen_load_gpr(t0, base);
7259    } else {
7260        gen_load_gpr(t0, index);
7261        gen_op_addr_add(ctx, t0, cpu_gpr[base]);
7262    }
7263    /* Don't do NOP if destination is zero: we must perform the actual
7264       memory access. */
7265    save_cpu_state(ctx, 0);
7266    switch (opc) {
7267    case OPC_LWXC1:
7268        check_cop1x(ctx);
7269        {
7270            TCGv_i32 fp0 = tcg_temp_new_i32();
7271
7272            tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
7273            tcg_gen_trunc_tl_i32(fp0, t0);
7274            gen_store_fpr32(fp0, fd);
7275            tcg_temp_free_i32(fp0);
7276        }
7277        opn = "lwxc1";
7278        break;
7279    case OPC_LDXC1:
7280        check_cop1x(ctx);
7281        check_cp1_registers(ctx, fd);
7282        {
7283            TCGv_i64 fp0 = tcg_temp_new_i64();
7284
7285            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7286            gen_store_fpr64(ctx, fp0, fd);
7287            tcg_temp_free_i64(fp0);
7288        }
7289        opn = "ldxc1";
7290        break;
7291    case OPC_LUXC1:
7292        check_cp1_64bitmode(ctx);
7293        tcg_gen_andi_tl(t0, t0, ~0x7);
7294        {
7295            TCGv_i64 fp0 = tcg_temp_new_i64();
7296
7297            tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
7298            gen_store_fpr64(ctx, fp0, fd);
7299            tcg_temp_free_i64(fp0);
7300        }
7301        opn = "luxc1";
7302        break;
7303    case OPC_SWXC1:
7304        check_cop1x(ctx);
7305        {
7306            TCGv_i32 fp0 = tcg_temp_new_i32();
7307            TCGv t1 = tcg_temp_new();
7308
7309            gen_load_fpr32(fp0, fs);
7310            tcg_gen_extu_i32_tl(t1, fp0);
7311            tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
7312            tcg_temp_free_i32(fp0);
7313            tcg_temp_free(t1);
7314        }
7315        opn = "swxc1";
7316        store = 1;
7317        break;
7318    case OPC_SDXC1:
7319        check_cop1x(ctx);
7320        check_cp1_registers(ctx, fs);
7321        {
7322            TCGv_i64 fp0 = tcg_temp_new_i64();
7323
7324            gen_load_fpr64(ctx, fp0, fs);
7325            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7326            tcg_temp_free_i64(fp0);
7327        }
7328        opn = "sdxc1";
7329        store = 1;
7330        break;
7331    case OPC_SUXC1:
7332        check_cp1_64bitmode(ctx);
7333        tcg_gen_andi_tl(t0, t0, ~0x7);
7334        {
7335            TCGv_i64 fp0 = tcg_temp_new_i64();
7336
7337            gen_load_fpr64(ctx, fp0, fs);
7338            tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
7339            tcg_temp_free_i64(fp0);
7340        }
7341        opn = "suxc1";
7342        store = 1;
7343        break;
7344    }
7345    tcg_temp_free(t0);
7346    MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
7347               regnames[index], regnames[base]);
7348}
7349
7350static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
7351                            int fd, int fr, int fs, int ft)
7352{
7353    const char *opn = "flt3_arith";
7354
7355    switch (opc) {
7356    case OPC_ALNV_PS:
7357        check_cp1_64bitmode(ctx);
7358        {
7359            TCGv t0 = tcg_temp_local_new();
7360            TCGv_i32 fp = tcg_temp_new_i32();
7361            TCGv_i32 fph = tcg_temp_new_i32();
7362            int l1 = gen_new_label();
7363            int l2 = gen_new_label();
7364
7365            gen_load_gpr(t0, fr);
7366            tcg_gen_andi_tl(t0, t0, 0x7);
7367
7368            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
7369            gen_load_fpr32(fp, fs);
7370            gen_load_fpr32h(fph, fs);
7371            gen_store_fpr32(fp, fd);
7372            gen_store_fpr32h(fph, fd);
7373            tcg_gen_br(l2);
7374            gen_set_label(l1);
7375            tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
7376            tcg_temp_free(t0);
7377#ifdef TARGET_WORDS_BIGENDIAN
7378            gen_load_fpr32(fp, fs);
7379            gen_load_fpr32h(fph, ft);
7380            gen_store_fpr32h(fp, fd);
7381            gen_store_fpr32(fph, fd);
7382#else
7383            gen_load_fpr32h(fph, fs);
7384            gen_load_fpr32(fp, ft);
7385            gen_store_fpr32(fph, fd);
7386            gen_store_fpr32h(fp, fd);
7387#endif
7388            gen_set_label(l2);
7389            tcg_temp_free_i32(fp);
7390            tcg_temp_free_i32(fph);
7391        }
7392        opn = "alnv.ps";
7393        break;
7394    case OPC_MADD_S:
7395        check_cop1x(ctx);
7396        {
7397            TCGv_i32 fp0 = tcg_temp_new_i32();
7398            TCGv_i32 fp1 = tcg_temp_new_i32();
7399            TCGv_i32 fp2 = tcg_temp_new_i32();
7400
7401            gen_load_fpr32(fp0, fs);
7402            gen_load_fpr32(fp1, ft);
7403            gen_load_fpr32(fp2, fr);
7404            gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
7405            tcg_temp_free_i32(fp0);
7406            tcg_temp_free_i32(fp1);
7407            gen_store_fpr32(fp2, fd);
7408            tcg_temp_free_i32(fp2);
7409        }
7410        opn = "madd.s";
7411        break;
7412    case OPC_MADD_D:
7413        check_cop1x(ctx);
7414        check_cp1_registers(ctx, fd | fs | ft | fr);
7415        {
7416            TCGv_i64 fp0 = tcg_temp_new_i64();
7417            TCGv_i64 fp1 = tcg_temp_new_i64();
7418            TCGv_i64 fp2 = tcg_temp_new_i64();
7419
7420            gen_load_fpr64(ctx, fp0, fs);
7421            gen_load_fpr64(ctx, fp1, ft);
7422            gen_load_fpr64(ctx, fp2, fr);
7423            gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
7424            tcg_temp_free_i64(fp0);
7425            tcg_temp_free_i64(fp1);
7426            gen_store_fpr64(ctx, fp2, fd);
7427            tcg_temp_free_i64(fp2);
7428        }
7429        opn = "madd.d";
7430        break;
7431    case OPC_MADD_PS:
7432        check_cp1_64bitmode(ctx);
7433        {
7434            TCGv_i64 fp0 = tcg_temp_new_i64();
7435            TCGv_i64 fp1 = tcg_temp_new_i64();
7436            TCGv_i64 fp2 = tcg_temp_new_i64();
7437
7438            gen_load_fpr64(ctx, fp0, fs);
7439            gen_load_fpr64(ctx, fp1, ft);
7440            gen_load_fpr64(ctx, fp2, fr);
7441            gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
7442            tcg_temp_free_i64(fp0);
7443            tcg_temp_free_i64(fp1);
7444            gen_store_fpr64(ctx, fp2, fd);
7445            tcg_temp_free_i64(fp2);
7446        }
7447        opn = "madd.ps";
7448        break;
7449    case OPC_MSUB_S:
7450        check_cop1x(ctx);
7451        {
7452            TCGv_i32 fp0 = tcg_temp_new_i32();
7453            TCGv_i32 fp1 = tcg_temp_new_i32();
7454            TCGv_i32 fp2 = tcg_temp_new_i32();
7455
7456            gen_load_fpr32(fp0, fs);
7457            gen_load_fpr32(fp1, ft);
7458            gen_load_fpr32(fp2, fr);
7459            gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
7460            tcg_temp_free_i32(fp0);
7461            tcg_temp_free_i32(fp1);
7462            gen_store_fpr32(fp2, fd);
7463            tcg_temp_free_i32(fp2);
7464        }
7465        opn = "msub.s";
7466        break;
7467    case OPC_MSUB_D:
7468        check_cop1x(ctx);
7469        check_cp1_registers(ctx, fd | fs | ft | fr);
7470        {
7471            TCGv_i64 fp0 = tcg_temp_new_i64();
7472            TCGv_i64 fp1 = tcg_temp_new_i64();
7473            TCGv_i64 fp2 = tcg_temp_new_i64();
7474
7475            gen_load_fpr64(ctx, fp0, fs);
7476            gen_load_fpr64(ctx, fp1, ft);
7477            gen_load_fpr64(ctx, fp2, fr);
7478            gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
7479            tcg_temp_free_i64(fp0);
7480            tcg_temp_free_i64(fp1);
7481            gen_store_fpr64(ctx, fp2, fd);
7482            tcg_temp_free_i64(fp2);
7483        }
7484        opn = "msub.d";
7485        break;
7486    case OPC_MSUB_PS:
7487        check_cp1_64bitmode(ctx);
7488        {
7489            TCGv_i64 fp0 = tcg_temp_new_i64();
7490            TCGv_i64 fp1 = tcg_temp_new_i64();
7491            TCGv_i64 fp2 = tcg_temp_new_i64();
7492
7493            gen_load_fpr64(ctx, fp0, fs);
7494            gen_load_fpr64(ctx, fp1, ft);
7495            gen_load_fpr64(ctx, fp2, fr);
7496            gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
7497            tcg_temp_free_i64(fp0);
7498            tcg_temp_free_i64(fp1);
7499            gen_store_fpr64(ctx, fp2, fd);
7500            tcg_temp_free_i64(fp2);
7501        }
7502        opn = "msub.ps";
7503        break;
7504    case OPC_NMADD_S:
7505        check_cop1x(ctx);
7506        {
7507            TCGv_i32 fp0 = tcg_temp_new_i32();
7508            TCGv_i32 fp1 = tcg_temp_new_i32();
7509            TCGv_i32 fp2 = tcg_temp_new_i32();
7510
7511            gen_load_fpr32(fp0, fs);
7512            gen_load_fpr32(fp1, ft);
7513            gen_load_fpr32(fp2, fr);
7514            gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
7515            tcg_temp_free_i32(fp0);
7516            tcg_temp_free_i32(fp1);
7517            gen_store_fpr32(fp2, fd);
7518            tcg_temp_free_i32(fp2);
7519        }
7520        opn = "nmadd.s";
7521        break;
7522    case OPC_NMADD_D:
7523        check_cop1x(ctx);
7524        check_cp1_registers(ctx, fd | fs | ft | fr);
7525        {
7526            TCGv_i64 fp0 = tcg_temp_new_i64();
7527            TCGv_i64 fp1 = tcg_temp_new_i64();
7528            TCGv_i64 fp2 = tcg_temp_new_i64();
7529
7530            gen_load_fpr64(ctx, fp0, fs);
7531            gen_load_fpr64(ctx, fp1, ft);
7532            gen_load_fpr64(ctx, fp2, fr);
7533            gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
7534            tcg_temp_free_i64(fp0);
7535            tcg_temp_free_i64(fp1);
7536            gen_store_fpr64(ctx, fp2, fd);
7537            tcg_temp_free_i64(fp2);
7538        }
7539        opn = "nmadd.d";
7540        break;
7541    case OPC_NMADD_PS:
7542        check_cp1_64bitmode(ctx);
7543        {
7544            TCGv_i64 fp0 = tcg_temp_new_i64();
7545            TCGv_i64 fp1 = tcg_temp_new_i64();
7546            TCGv_i64 fp2 = tcg_temp_new_i64();
7547
7548            gen_load_fpr64(ctx, fp0, fs);
7549            gen_load_fpr64(ctx, fp1, ft);
7550            gen_load_fpr64(ctx, fp2, fr);
7551            gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
7552            tcg_temp_free_i64(fp0);
7553            tcg_temp_free_i64(fp1);
7554            gen_store_fpr64(ctx, fp2, fd);
7555            tcg_temp_free_i64(fp2);
7556        }
7557        opn = "nmadd.ps";
7558        break;
7559    case OPC_NMSUB_S:
7560        check_cop1x(ctx);
7561        {
7562            TCGv_i32 fp0 = tcg_temp_new_i32();
7563            TCGv_i32 fp1 = tcg_temp_new_i32();
7564            TCGv_i32 fp2 = tcg_temp_new_i32();
7565
7566            gen_load_fpr32(fp0, fs);
7567            gen_load_fpr32(fp1, ft);
7568            gen_load_fpr32(fp2, fr);
7569            gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
7570            tcg_temp_free_i32(fp0);
7571            tcg_temp_free_i32(fp1);
7572            gen_store_fpr32(fp2, fd);
7573            tcg_temp_free_i32(fp2);
7574        }
7575        opn = "nmsub.s";
7576        break;
7577    case OPC_NMSUB_D:
7578        check_cop1x(ctx);
7579        check_cp1_registers(ctx, fd | fs | ft | fr);
7580        {
7581            TCGv_i64 fp0 = tcg_temp_new_i64();
7582            TCGv_i64 fp1 = tcg_temp_new_i64();
7583            TCGv_i64 fp2 = tcg_temp_new_i64();
7584
7585            gen_load_fpr64(ctx, fp0, fs);
7586            gen_load_fpr64(ctx, fp1, ft);
7587            gen_load_fpr64(ctx, fp2, fr);
7588            gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
7589            tcg_temp_free_i64(fp0);
7590            tcg_temp_free_i64(fp1);
7591            gen_store_fpr64(ctx, fp2, fd);
7592            tcg_temp_free_i64(fp2);
7593        }
7594        opn = "nmsub.d";
7595        break;
7596    case OPC_NMSUB_PS:
7597        check_cp1_64bitmode(ctx);
7598        {
7599            TCGv_i64 fp0 = tcg_temp_new_i64();
7600            TCGv_i64 fp1 = tcg_temp_new_i64();
7601            TCGv_i64 fp2 = tcg_temp_new_i64();
7602
7603            gen_load_fpr64(ctx, fp0, fs);
7604            gen_load_fpr64(ctx, fp1, ft);
7605            gen_load_fpr64(ctx, fp2, fr);
7606            gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
7607            tcg_temp_free_i64(fp0);
7608            tcg_temp_free_i64(fp1);
7609            gen_store_fpr64(ctx, fp2, fd);
7610            tcg_temp_free_i64(fp2);
7611        }
7612        opn = "nmsub.ps";
7613        break;
7614    default:
7615        MIPS_INVAL(opn);
7616        generate_exception (ctx, EXCP_RI);
7617        return;
7618    }
7619    MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
7620               fregnames[fs], fregnames[ft]);
7621}
7622
7623/* ISA extensions (ASEs) */
7624/* MIPS16 extension to MIPS32 */
7625/* SmartMIPS extension to MIPS32 */
7626
7627#if defined(TARGET_MIPS64)
7628
7629/* MDMX extension to MIPS64 */
7630
7631#endif
7632
7633static void decode_opc (CPUState *env, DisasContext *ctx)
7634{
7635    int32_t offset;
7636    int rs, rt, rd, sa;
7637    uint32_t op, op1, op2;
7638    int16_t imm;
7639
7640    /* make sure instructions are on a word boundary */
7641    if (ctx->pc & 0x3) {
7642        env->CP0_BadVAddr = ctx->pc;
7643        generate_exception(ctx, EXCP_AdEL);
7644        return;
7645    }
7646
7647    /* Handle blikely not taken case */
7648    if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
7649        int l1 = gen_new_label();
7650
7651        MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
7652        tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
7653        tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
7654        gen_goto_tb(ctx, 1, ctx->pc + 4);
7655        gen_set_label(l1);
7656    }
7657    op = MASK_OP_MAJOR(ctx->opcode);
7658    rs = (ctx->opcode >> 21) & 0x1f;
7659    rt = (ctx->opcode >> 16) & 0x1f;
7660    rd = (ctx->opcode >> 11) & 0x1f;
7661    sa = (ctx->opcode >> 6) & 0x1f;
7662    imm = (int16_t)ctx->opcode;
7663    switch (op) {
7664    case OPC_SPECIAL:
7665        op1 = MASK_SPECIAL(ctx->opcode);
7666        switch (op1) {
7667        case OPC_SLL:          /* Shift with immediate */
7668        case OPC_SRA:
7669        case OPC_SRL:
7670            gen_shift_imm(env, ctx, op1, rd, rt, sa);
7671            break;
7672        case OPC_MOVN:         /* Conditional move */
7673        case OPC_MOVZ:
7674            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7675            gen_cond_move(env, op1, rd, rs, rt);
7676            break;
7677        case OPC_ADD ... OPC_SUBU:
7678            gen_arith(env, ctx, op1, rd, rs, rt);
7679            break;
7680        case OPC_SLLV:         /* Shifts */
7681        case OPC_SRLV:
7682        case OPC_SRAV:
7683            gen_shift(env, ctx, op1, rd, rs, rt);
7684            break;
7685        case OPC_SLT:          /* Set on less than */
7686        case OPC_SLTU:
7687            gen_slt(env, op1, rd, rs, rt);
7688            break;
7689        case OPC_AND:          /* Logic*/
7690        case OPC_OR:
7691        case OPC_NOR:
7692        case OPC_XOR:
7693            gen_logic(env, op1, rd, rs, rt);
7694            break;
7695        case OPC_MULT ... OPC_DIVU:
7696            if (sa) {
7697                check_insn(env, ctx, INSN_VR54XX);
7698                op1 = MASK_MUL_VR54XX(ctx->opcode);
7699                gen_mul_vr54xx(ctx, op1, rd, rs, rt);
7700            } else
7701                gen_muldiv(ctx, op1, rs, rt);
7702            break;
7703        case OPC_JR ... OPC_JALR:
7704            gen_compute_branch(ctx, op1, rs, rd, sa);
7705            return;
7706        case OPC_TGE ... OPC_TEQ: /* Traps */
7707        case OPC_TNE:
7708            gen_trap(ctx, op1, rs, rt, -1);
7709            break;
7710        case OPC_MFHI:          /* Move from HI/LO */
7711        case OPC_MFLO:
7712            gen_HILO(ctx, op1, rd);
7713            break;
7714        case OPC_MTHI:
7715        case OPC_MTLO:          /* Move to HI/LO */
7716            gen_HILO(ctx, op1, rs);
7717            break;
7718        case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
7719#ifdef MIPS_STRICT_STANDARD
7720            MIPS_INVAL("PMON / selsl");
7721            generate_exception(ctx, EXCP_RI);
7722#else
7723            gen_helper_0i(pmon, sa);
7724#endif
7725            break;
7726        case OPC_SYSCALL:
7727            generate_exception(ctx, EXCP_SYSCALL);
7728            ctx->bstate = BS_STOP;
7729            break;
7730        case OPC_BREAK:
7731            generate_exception(ctx, EXCP_BREAK);
7732            break;
7733        case OPC_SPIM:
7734#ifdef MIPS_STRICT_STANDARD
7735            MIPS_INVAL("SPIM");
7736            generate_exception(ctx, EXCP_RI);
7737#else
7738           /* Implemented as RI exception for now. */
7739            MIPS_INVAL("spim (unofficial)");
7740            generate_exception(ctx, EXCP_RI);
7741#endif
7742            break;
7743        case OPC_SYNC:
7744            /* Treat as NOP. */
7745            break;
7746
7747        case OPC_MOVCI:
7748            check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
7749            if (env->CP0_Config1 & (1 << CP0C1_FP)) {
7750                check_cp1_enabled(ctx);
7751                gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
7752                          (ctx->opcode >> 16) & 1);
7753            } else {
7754                generate_exception_err(ctx, EXCP_CpU, 1);
7755            }
7756            break;
7757
7758#if defined(TARGET_MIPS64)
7759       /* MIPS64 specific opcodes */
7760        case OPC_DSLL:
7761        case OPC_DSRA:
7762        case OPC_DSRL:
7763        case OPC_DSLL32:
7764        case OPC_DSRA32:
7765        case OPC_DSRL32:
7766            check_insn(env, ctx, ISA_MIPS3);
7767            check_mips_64(ctx);
7768            gen_shift_imm(env, ctx, op1, rd, rt, sa);
7769            break;
7770        case OPC_DADD ... OPC_DSUBU:
7771            check_insn(env, ctx, ISA_MIPS3);
7772            check_mips_64(ctx);
7773            gen_arith(env, ctx, op1, rd, rs, rt);
7774            break;
7775        case OPC_DSLLV:
7776        case OPC_DSRAV:
7777        case OPC_DSRLV:
7778            check_insn(env, ctx, ISA_MIPS3);
7779            check_mips_64(ctx);
7780            gen_shift(env, ctx, op1, rd, rs, rt);
7781            break;
7782        case OPC_DMULT ... OPC_DDIVU:
7783            check_insn(env, ctx, ISA_MIPS3);
7784            check_mips_64(ctx);
7785            gen_muldiv(ctx, op1, rs, rt);
7786            break;
7787#endif
7788        default:            /* Invalid */
7789            MIPS_INVAL("special");
7790            generate_exception(ctx, EXCP_RI);
7791            break;
7792        }
7793        break;
7794    case OPC_SPECIAL2:
7795        op1 = MASK_SPECIAL2(ctx->opcode);
7796        switch (op1) {
7797        case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
7798        case OPC_MSUB ... OPC_MSUBU:
7799            check_insn(env, ctx, ISA_MIPS32);
7800            gen_muldiv(ctx, op1, rs, rt);
7801            break;
7802        case OPC_MUL:
7803            gen_arith(env, ctx, op1, rd, rs, rt);
7804            break;
7805        case OPC_CLO:
7806        case OPC_CLZ:
7807            check_insn(env, ctx, ISA_MIPS32);
7808            gen_cl(ctx, op1, rd, rs);
7809            break;
7810        case OPC_SDBBP:
7811            /* XXX: not clear which exception should be raised
7812             *      when in debug mode...
7813             */
7814            check_insn(env, ctx, ISA_MIPS32);
7815            if (!(ctx->hflags & MIPS_HFLAG_DM)) {
7816                generate_exception(ctx, EXCP_DBp);
7817            } else {
7818                generate_exception(ctx, EXCP_DBp);
7819            }
7820            /* Treat as NOP. */
7821            break;
7822#if defined(TARGET_MIPS64)
7823        case OPC_DCLO:
7824        case OPC_DCLZ:
7825            check_insn(env, ctx, ISA_MIPS64);
7826            check_mips_64(ctx);
7827            gen_cl(ctx, op1, rd, rs);
7828            break;
7829#endif
7830        default:            /* Invalid */
7831            MIPS_INVAL("special2");
7832            generate_exception(ctx, EXCP_RI);
7833            break;
7834        }
7835        break;
7836    case OPC_SPECIAL3:
7837        op1 = MASK_SPECIAL3(ctx->opcode);
7838        switch (op1) {
7839        case OPC_EXT:
7840        case OPC_INS:
7841            check_insn(env, ctx, ISA_MIPS32R2);
7842            gen_bitops(ctx, op1, rt, rs, sa, rd);
7843            break;
7844        case OPC_BSHFL:
7845            check_insn(env, ctx, ISA_MIPS32R2);
7846            op2 = MASK_BSHFL(ctx->opcode);
7847            gen_bshfl(ctx, op2, rt, rd);
7848            break;
7849        case OPC_RDHWR:
7850            check_insn(env, ctx, ISA_MIPS32R2);
7851            {
7852                TCGv t0 = tcg_temp_new();
7853
7854                switch (rd) {
7855                case 0:
7856                    save_cpu_state(ctx, 1);
7857                    gen_helper_rdhwr_cpunum(t0);
7858                    gen_store_gpr(t0, rt);
7859                    break;
7860                case 1:
7861                    save_cpu_state(ctx, 1);
7862                    gen_helper_rdhwr_synci_step(t0);
7863                    gen_store_gpr(t0, rt);
7864                    break;
7865                case 2:
7866                    save_cpu_state(ctx, 1);
7867                    gen_helper_rdhwr_cc(t0);
7868                    gen_store_gpr(t0, rt);
7869                    break;
7870                case 3:
7871                    save_cpu_state(ctx, 1);
7872                    gen_helper_rdhwr_ccres(t0);
7873                    gen_store_gpr(t0, rt);
7874                    break;
7875                case 29:
7876#if defined(CONFIG_USER_ONLY)
7877                    tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
7878                    gen_store_gpr(t0, rt);
7879                    break;
7880#else
7881                    /* XXX: Some CPUs implement this in hardware.
7882                       Not supported yet. */
7883#endif
7884                default:            /* Invalid */
7885                    MIPS_INVAL("rdhwr");
7886                    generate_exception(ctx, EXCP_RI);
7887                    break;
7888                }
7889                tcg_temp_free(t0);
7890            }
7891            break;
7892        case OPC_FORK:
7893            check_insn(env, ctx, ASE_MT);
7894            {
7895                TCGv t0 = tcg_temp_new();
7896                TCGv t1 = tcg_temp_new();
7897
7898                gen_load_gpr(t0, rt);
7899                gen_load_gpr(t1, rs);
7900                gen_helper_fork(t0, t1);
7901                tcg_temp_free(t0);
7902                tcg_temp_free(t1);
7903            }
7904            break;
7905        case OPC_YIELD:
7906            check_insn(env, ctx, ASE_MT);
7907            {
7908                TCGv t0 = tcg_temp_new();
7909
7910                save_cpu_state(ctx, 1);
7911                gen_load_gpr(t0, rs);
7912                gen_helper_yield(t0, t0);
7913                gen_store_gpr(t0, rd);
7914                tcg_temp_free(t0);
7915            }
7916            break;
7917#if defined(TARGET_MIPS64)
7918        case OPC_DEXTM ... OPC_DEXT:
7919        case OPC_DINSM ... OPC_DINS:
7920            check_insn(env, ctx, ISA_MIPS64R2);
7921            check_mips_64(ctx);
7922            gen_bitops(ctx, op1, rt, rs, sa, rd);
7923            break;
7924        case OPC_DBSHFL:
7925            check_insn(env, ctx, ISA_MIPS64R2);
7926            check_mips_64(ctx);
7927            op2 = MASK_DBSHFL(ctx->opcode);
7928            gen_bshfl(ctx, op2, rt, rd);
7929            break;
7930#endif
7931        default:            /* Invalid */
7932            MIPS_INVAL("special3");
7933            generate_exception(ctx, EXCP_RI);
7934            break;
7935        }
7936        break;
7937    case OPC_REGIMM:
7938        op1 = MASK_REGIMM(ctx->opcode);
7939        switch (op1) {
7940        case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
7941        case OPC_BLTZAL ... OPC_BGEZALL:
7942            gen_compute_branch(ctx, op1, rs, -1, imm << 2);
7943            return;
7944        case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
7945        case OPC_TNEI:
7946            gen_trap(ctx, op1, rs, -1, imm);
7947            break;
7948        case OPC_SYNCI:
7949            check_insn(env, ctx, ISA_MIPS32R2);
7950            /* Treat as NOP. */
7951            break;
7952        default:            /* Invalid */
7953            MIPS_INVAL("regimm");
7954            generate_exception(ctx, EXCP_RI);
7955            break;
7956        }
7957        break;
7958    case OPC_CP0:
7959        check_cp0_enabled(ctx);
7960        op1 = MASK_CP0(ctx->opcode);
7961        switch (op1) {
7962        case OPC_MFC0:
7963        case OPC_MTC0:
7964        case OPC_MFTR:
7965        case OPC_MTTR:
7966#if defined(TARGET_MIPS64)
7967        case OPC_DMFC0:
7968        case OPC_DMTC0:
7969#endif
7970#ifndef CONFIG_USER_ONLY
7971            gen_cp0(env, ctx, op1, rt, rd);
7972#endif /* !CONFIG_USER_ONLY */
7973            break;
7974        case OPC_C0_FIRST ... OPC_C0_LAST:
7975#ifndef CONFIG_USER_ONLY
7976            gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
7977#endif /* !CONFIG_USER_ONLY */
7978            break;
7979        case OPC_MFMC0:
7980#ifndef CONFIG_USER_ONLY
7981            {
7982                TCGv t0 = tcg_temp_new();
7983
7984                op2 = MASK_MFMC0(ctx->opcode);
7985                switch (op2) {
7986                case OPC_DMT:
7987                    check_insn(env, ctx, ASE_MT);
7988                    gen_helper_dmt(t0, t0);
7989                    gen_store_gpr(t0, rt);
7990                    break;
7991                case OPC_EMT:
7992                    check_insn(env, ctx, ASE_MT);
7993                    gen_helper_emt(t0, t0);
7994                    gen_store_gpr(t0, rt);
7995                    break;
7996                case OPC_DVPE:
7997                    check_insn(env, ctx, ASE_MT);
7998                    gen_helper_dvpe(t0, t0);
7999                    gen_store_gpr(t0, rt);
8000                    break;
8001                case OPC_EVPE:
8002                    check_insn(env, ctx, ASE_MT);
8003                    gen_helper_evpe(t0, t0);
8004                    gen_store_gpr(t0, rt);
8005                    break;
8006                case OPC_DI:
8007                    check_insn(env, ctx, ISA_MIPS32R2);
8008                    save_cpu_state(ctx, 1);
8009                    gen_helper_di(t0);
8010                    gen_store_gpr(t0, rt);
8011                    /* Stop translation as we may have switched the execution mode */
8012                    ctx->bstate = BS_STOP;
8013                    break;
8014                case OPC_EI:
8015                    check_insn(env, ctx, ISA_MIPS32R2);
8016                    save_cpu_state(ctx, 1);
8017                    gen_helper_ei(t0);
8018                    gen_store_gpr(t0, rt);
8019                    /* Stop translation as we may have switched the execution mode */
8020                    ctx->bstate = BS_STOP;
8021                    break;
8022                default:            /* Invalid */
8023                    MIPS_INVAL("mfmc0");
8024                    generate_exception(ctx, EXCP_RI);
8025                    break;
8026                }
8027                tcg_temp_free(t0);
8028            }
8029#endif /* !CONFIG_USER_ONLY */
8030            break;
8031        case OPC_RDPGPR:
8032            check_insn(env, ctx, ISA_MIPS32R2);
8033            gen_load_srsgpr(rt, rd);
8034            break;
8035        case OPC_WRPGPR:
8036            check_insn(env, ctx, ISA_MIPS32R2);
8037            gen_store_srsgpr(rt, rd);
8038            break;
8039        default:
8040            MIPS_INVAL("cp0");
8041            generate_exception(ctx, EXCP_RI);
8042            break;
8043        }
8044        break;
8045    case OPC_ADDI: /* Arithmetic with immediate opcode */
8046    case OPC_ADDIU:
8047         gen_arith_imm(env, ctx, op, rt, rs, imm);
8048         break;
8049    case OPC_SLTI: /* Set on less than with immediate opcode */
8050    case OPC_SLTIU:
8051         gen_slt_imm(env, op, rt, rs, imm);
8052         break;
8053    case OPC_ANDI: /* Arithmetic with immediate opcode */
8054    case OPC_LUI:
8055    case OPC_ORI:
8056    case OPC_XORI:
8057         gen_logic_imm(env, op, rt, rs, imm);
8058         break;
8059    case OPC_J ... OPC_JAL: /* Jump */
8060         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
8061         gen_compute_branch(ctx, op, rs, rt, offset);
8062         return;
8063    case OPC_BEQ ... OPC_BGTZ: /* Branch */
8064    case OPC_BEQL ... OPC_BGTZL:
8065         gen_compute_branch(ctx, op, rs, rt, imm << 2);
8066         return;
8067    case OPC_LB ... OPC_LWR: /* Load and stores */
8068    case OPC_SB ... OPC_SW:
8069    case OPC_SWR:
8070    case OPC_LL:
8071         gen_ldst(ctx, op, rt, rs, imm);
8072         break;
8073    case OPC_SC:
8074         gen_st_cond(ctx, op, rt, rs, imm);
8075         break;
8076    case OPC_CACHE:
8077        check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
8078        /* Treat as NOP. */
8079        break;
8080    case OPC_PREF:
8081        check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
8082        /* Treat as NOP. */
8083        break;
8084
8085    /* Floating point (COP1). */
8086    case OPC_LWC1:
8087    case OPC_LDC1:
8088    case OPC_SWC1:
8089    case OPC_SDC1:
8090        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8091            check_cp1_enabled(ctx);
8092            gen_flt_ldst(ctx, op, rt, rs, imm);
8093        } else {
8094            generate_exception_err(ctx, EXCP_CpU, 1);
8095        }
8096        break;
8097
8098    case OPC_CP1:
8099        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8100            check_cp1_enabled(ctx);
8101            op1 = MASK_CP1(ctx->opcode);
8102            switch (op1) {
8103            case OPC_MFHC1:
8104            case OPC_MTHC1:
8105                check_insn(env, ctx, ISA_MIPS32R2);
8106            case OPC_MFC1:
8107            case OPC_CFC1:
8108            case OPC_MTC1:
8109            case OPC_CTC1:
8110                gen_cp1(ctx, op1, rt, rd);
8111                break;
8112#if defined(TARGET_MIPS64)
8113            case OPC_DMFC1:
8114            case OPC_DMTC1:
8115                check_insn(env, ctx, ISA_MIPS3);
8116                gen_cp1(ctx, op1, rt, rd);
8117                break;
8118#endif
8119            case OPC_BC1ANY2:
8120            case OPC_BC1ANY4:
8121                check_cop1x(ctx);
8122                check_insn(env, ctx, ASE_MIPS3D);
8123                /* fall through */
8124            case OPC_BC1:
8125                gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
8126                                    (rt >> 2) & 0x7, imm << 2);
8127                return;
8128            case OPC_S_FMT:
8129            case OPC_D_FMT:
8130            case OPC_W_FMT:
8131            case OPC_L_FMT:
8132            case OPC_PS_FMT:
8133                gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
8134                           (imm >> 8) & 0x7);
8135                break;
8136            default:
8137                MIPS_INVAL("cp1");
8138                generate_exception (ctx, EXCP_RI);
8139                break;
8140            }
8141        } else {
8142            generate_exception_err(ctx, EXCP_CpU, 1);
8143        }
8144        break;
8145
8146    /* COP2.  */
8147    case OPC_LWC2:
8148    case OPC_LDC2:
8149    case OPC_SWC2:
8150    case OPC_SDC2:
8151    case OPC_CP2:
8152        /* COP2: Not implemented. */
8153        generate_exception_err(ctx, EXCP_CpU, 2);
8154        break;
8155
8156    case OPC_CP3:
8157        if (env->CP0_Config1 & (1 << CP0C1_FP)) {
8158            check_cp1_enabled(ctx);
8159            op1 = MASK_CP3(ctx->opcode);
8160            switch (op1) {
8161            case OPC_LWXC1:
8162            case OPC_LDXC1:
8163            case OPC_LUXC1:
8164            case OPC_SWXC1:
8165            case OPC_SDXC1:
8166            case OPC_SUXC1:
8167                gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
8168                break;
8169            case OPC_PREFX:
8170                /* Treat as NOP. */
8171                break;
8172            case OPC_ALNV_PS:
8173            case OPC_MADD_S:
8174            case OPC_MADD_D:
8175            case OPC_MADD_PS:
8176            case OPC_MSUB_S:
8177            case OPC_MSUB_D:
8178            case OPC_MSUB_PS:
8179            case OPC_NMADD_S:
8180            case OPC_NMADD_D:
8181            case OPC_NMADD_PS:
8182            case OPC_NMSUB_S:
8183            case OPC_NMSUB_D:
8184            case OPC_NMSUB_PS:
8185                gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
8186                break;
8187            default:
8188                MIPS_INVAL("cp3");
8189                generate_exception (ctx, EXCP_RI);
8190                break;
8191            }
8192        } else {
8193            generate_exception_err(ctx, EXCP_CpU, 1);
8194        }
8195        break;
8196
8197#if defined(TARGET_MIPS64)
8198    /* MIPS64 opcodes */
8199    case OPC_LWU:
8200    case OPC_LDL ... OPC_LDR:
8201    case OPC_SDL ... OPC_SDR:
8202    case OPC_LLD:
8203    case OPC_LD:
8204    case OPC_SD:
8205        check_insn(env, ctx, ISA_MIPS3);
8206        check_mips_64(ctx);
8207        gen_ldst(ctx, op, rt, rs, imm);
8208        break;
8209    case OPC_SCD:
8210        check_insn(env, ctx, ISA_MIPS3);
8211        check_mips_64(ctx);
8212        gen_st_cond(ctx, op, rt, rs, imm);
8213        break;
8214    case OPC_DADDI:
8215    case OPC_DADDIU:
8216        check_insn(env, ctx, ISA_MIPS3);
8217        check_mips_64(ctx);
8218        gen_arith_imm(env, ctx, op, rt, rs, imm);
8219        break;
8220#endif
8221    case OPC_JALX:
8222        check_insn(env, ctx, ASE_MIPS16);
8223        /* MIPS16: Not implemented. */
8224    case OPC_MDMX:
8225        check_insn(env, ctx, ASE_MDMX);
8226        /* MDMX: Not implemented. */
8227    default:            /* Invalid */
8228        MIPS_INVAL("major opcode");
8229        generate_exception(ctx, EXCP_RI);
8230        break;
8231    }
8232    if (ctx->hflags & MIPS_HFLAG_BMASK) {
8233        int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
8234        /* Branches completion */
8235        ctx->hflags &= ~MIPS_HFLAG_BMASK;
8236        ctx->bstate = BS_BRANCH;
8237        save_cpu_state(ctx, 0);
8238        /* FIXME: Need to clear can_do_io.  */
8239        switch (hflags) {
8240        case MIPS_HFLAG_B:
8241            /* unconditional branch */
8242            MIPS_DEBUG("unconditional branch");
8243            gen_goto_tb(ctx, 0, ctx->btarget);
8244            break;
8245        case MIPS_HFLAG_BL:
8246            /* blikely taken case */
8247            MIPS_DEBUG("blikely branch taken");
8248            gen_goto_tb(ctx, 0, ctx->btarget);
8249            break;
8250        case MIPS_HFLAG_BC:
8251            /* Conditional branch */
8252            MIPS_DEBUG("conditional branch");
8253            {
8254                int l1 = gen_new_label();
8255
8256                tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
8257                gen_goto_tb(ctx, 1, ctx->pc + 4);
8258                gen_set_label(l1);
8259                gen_goto_tb(ctx, 0, ctx->btarget);
8260            }
8261            break;
8262        case MIPS_HFLAG_BR:
8263            /* unconditional branch to register */
8264            MIPS_DEBUG("branch to register");
8265            tcg_gen_mov_tl(cpu_PC, btarget);
8266            tcg_gen_exit_tb(0);
8267            break;
8268        default:
8269            MIPS_DEBUG("unknown branch");
8270            break;
8271        }
8272    }
8273}
8274
8275static inline void
8276gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
8277                                int search_pc)
8278{
8279    DisasContext ctx;
8280    target_ulong pc_start;
8281    uint16_t *gen_opc_end;
8282    CPUBreakpoint *bp;
8283    int j, lj = -1;
8284    int num_insns;
8285    int max_insns;
8286
8287    if (search_pc)
8288        qemu_log("search pc %d\n", search_pc);
8289
8290    pc_start = tb->pc;
8291    /* Leave some spare opc slots for branch handling. */
8292    gen_opc_end = gen_opc_buf + OPC_MAX_SIZE - 16;
8293    ctx.pc = pc_start;
8294    ctx.saved_pc = -1;
8295    ctx.tb = tb;
8296    ctx.bstate = BS_NONE;
8297    /* Restore delay slot state from the tb context.  */
8298    ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
8299    restore_cpu_state(env, &ctx);
8300#ifdef CONFIG_USER_ONLY
8301        ctx.mem_idx = MIPS_HFLAG_UM;
8302#else
8303        ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
8304#endif
8305    num_insns = 0;
8306    max_insns = tb->cflags & CF_COUNT_MASK;
8307    if (max_insns == 0)
8308        max_insns = CF_COUNT_MASK;
8309#ifdef DEBUG_DISAS
8310    qemu_log_mask(CPU_LOG_TB_CPU, "------------------------------------------------\n");
8311    /* FIXME: This may print out stale hflags from env... */
8312    log_cpu_state_mask(CPU_LOG_TB_CPU, env, 0);
8313#endif
8314    LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
8315    gen_icount_start();
8316    while (ctx.bstate == BS_NONE) {
8317        if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
8318            TAILQ_FOREACH(bp, &env->breakpoints, entry) {
8319                if (bp->pc == ctx.pc) {
8320                    save_cpu_state(&ctx, 1);
8321                    ctx.bstate = BS_BRANCH;
8322                    gen_helper_0i(raise_exception, EXCP_DEBUG);
8323                    /* Include the breakpoint location or the tb won't
8324                     * be flushed when it must be.  */
8325                    ctx.pc += 4;
8326                    goto done_generating;
8327                }
8328            }
8329        }
8330
8331        if (search_pc) {
8332            j = gen_opc_ptr - gen_opc_buf;
8333            if (lj < j) {
8334                lj++;
8335                while (lj < j)
8336                    gen_opc_instr_start[lj++] = 0;
8337            }
8338            gen_opc_pc[lj] = ctx.pc;
8339            gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
8340            gen_opc_instr_start[lj] = 1;
8341            gen_opc_icount[lj] = num_insns;
8342        }
8343        if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
8344            gen_io_start();
8345        ctx.opcode = ldl_code(ctx.pc);
8346        decode_opc(env, &ctx);
8347        ctx.pc += 4;
8348        num_insns++;
8349
8350        if (env->singlestep_enabled)
8351            break;
8352
8353        if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
8354            break;
8355
8356        if (gen_opc_ptr >= gen_opc_end)
8357            break;
8358
8359        if (num_insns >= max_insns)
8360            break;
8361
8362        if (singlestep)
8363            break;
8364    }
8365    if (tb->cflags & CF_LAST_IO)
8366        gen_io_end();
8367    if (env->singlestep_enabled) {
8368        save_cpu_state(&ctx, ctx.bstate == BS_NONE);
8369        gen_helper_0i(raise_exception, EXCP_DEBUG);
8370    } else {
8371        switch (ctx.bstate) {
8372        case BS_STOP:
8373            gen_helper_interrupt_restart();
8374            gen_goto_tb(&ctx, 0, ctx.pc);
8375            break;
8376        case BS_NONE:
8377            save_cpu_state(&ctx, 0);
8378            gen_goto_tb(&ctx, 0, ctx.pc);
8379            break;
8380        case BS_EXCP:
8381            gen_helper_interrupt_restart();
8382            tcg_gen_exit_tb(0);
8383            break;
8384        case BS_BRANCH:
8385        default:
8386            break;
8387        }
8388    }
8389done_generating:
8390    gen_icount_end(tb, num_insns);
8391    *gen_opc_ptr = INDEX_op_end;
8392    if (search_pc) {
8393        j = gen_opc_ptr - gen_opc_buf;
8394        lj++;
8395        while (lj <= j)
8396            gen_opc_instr_start[lj++] = 0;
8397    } else {
8398        tb->size = ctx.pc - pc_start;
8399        tb->icount = num_insns;
8400    }
8401#ifdef DEBUG_DISAS
8402    LOG_DISAS("\n");
8403    if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
8404        qemu_log("IN: %s\n", lookup_symbol(pc_start));
8405        log_target_disas(pc_start, ctx.pc - pc_start, 0);
8406        qemu_log("\n");
8407    }
8408    qemu_log_mask(CPU_LOG_TB_CPU, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
8409#endif
8410}
8411
8412void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
8413{
8414    gen_intermediate_code_internal(env, tb, 0);
8415}
8416
8417void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
8418{
8419    gen_intermediate_code_internal(env, tb, 1);
8420}
8421
8422static void fpu_dump_state(CPUState *env, FILE *f,
8423                           int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
8424                           int flags)
8425{
8426    int i;
8427    int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
8428
8429#define printfpr(fp)                                                        \
8430    do {                                                                    \
8431        if (is_fpu64)                                                       \
8432            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
8433                        (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
8434                        (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
8435        else {                                                              \
8436            fpr_t tmp;                                                      \
8437            tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
8438            tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
8439            fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
8440                        tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
8441                        tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
8442        }                                                                   \
8443    } while(0)
8444
8445
8446    fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
8447                env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
8448                get_float_exception_flags(&env->active_fpu.fp_status));
8449    for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
8450        fpu_fprintf(f, "%3s: ", fregnames[i]);
8451        printfpr(&env->active_fpu.fpr[i]);
8452    }
8453
8454#undef printfpr
8455}
8456
8457#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8458/* Debug help: The architecture requires 32bit code to maintain proper
8459   sign-extended values on 64bit machines.  */
8460
8461#define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
8462
8463static void
8464cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
8465                                int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8466                                int flags)
8467{
8468    int i;
8469
8470    if (!SIGN_EXT_P(env->active_tc.PC))
8471        cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
8472    if (!SIGN_EXT_P(env->active_tc.HI[0]))
8473        cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
8474    if (!SIGN_EXT_P(env->active_tc.LO[0]))
8475        cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
8476    if (!SIGN_EXT_P(env->btarget))
8477        cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
8478
8479    for (i = 0; i < 32; i++) {
8480        if (!SIGN_EXT_P(env->active_tc.gpr[i]))
8481            cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
8482    }
8483
8484    if (!SIGN_EXT_P(env->CP0_EPC))
8485        cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
8486    if (!SIGN_EXT_P(env->CP0_LLAddr))
8487        cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
8488}
8489#endif
8490
8491void cpu_dump_state (CPUState *env, FILE *f,
8492                     int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
8493                     int flags)
8494{
8495    int i;
8496
8497    cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
8498                env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
8499                env->hflags, env->btarget, env->bcond);
8500    for (i = 0; i < 32; i++) {
8501        if ((i & 3) == 0)
8502            cpu_fprintf(f, "GPR%02d:", i);
8503        cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
8504        if ((i & 3) == 3)
8505            cpu_fprintf(f, "\n");
8506    }
8507
8508    cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
8509                env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
8510    cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
8511                env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
8512    if (env->hflags & MIPS_HFLAG_FPU)
8513        fpu_dump_state(env, f, cpu_fprintf, flags);
8514#if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
8515    cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
8516#endif
8517}
8518
8519static void mips_tcg_init(void)
8520{
8521    int i;
8522    static int inited;
8523
8524    /* Initialize various static tables. */
8525    if (inited)
8526        return;
8527
8528    cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
8529    TCGV_UNUSED(cpu_gpr[0]);
8530    for (i = 1; i < 32; i++)
8531        cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
8532                                        offsetof(CPUState, active_tc.gpr[i]),
8533                                        regnames[i]);
8534    cpu_PC = tcg_global_mem_new(TCG_AREG0,
8535                                offsetof(CPUState, active_tc.PC), "PC");
8536    for (i = 0; i < MIPS_DSP_ACC; i++) {
8537        cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
8538                                       offsetof(CPUState, active_tc.HI[i]),
8539                                       regnames_HI[i]);
8540        cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
8541                                       offsetof(CPUState, active_tc.LO[i]),
8542                                       regnames_LO[i]);
8543        cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
8544                                        offsetof(CPUState, active_tc.ACX[i]),
8545                                        regnames_ACX[i]);
8546    }
8547    cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
8548                                     offsetof(CPUState, active_tc.DSPControl),
8549                                     "DSPControl");
8550    bcond = tcg_global_mem_new(TCG_AREG0,
8551                               offsetof(CPUState, bcond), "bcond");
8552    btarget = tcg_global_mem_new(TCG_AREG0,
8553                                 offsetof(CPUState, btarget), "btarget");
8554    hflags = tcg_global_mem_new_i32(TCG_AREG0,
8555                                    offsetof(CPUState, hflags), "hflags");
8556
8557    fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
8558                                      offsetof(CPUState, active_fpu.fcr0),
8559                                      "fcr0");
8560    fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
8561                                       offsetof(CPUState, active_fpu.fcr31),
8562                                       "fcr31");
8563
8564    /* register helpers */
8565#define GEN_HELPER 2
8566#include "helper.h"
8567
8568    inited = 1;
8569}
8570
8571#include "translate_init.c"
8572
8573CPUMIPSState *cpu_mips_init (const char *cpu_model)
8574{
8575    CPUMIPSState *env;
8576    const mips_def_t *def;
8577
8578    def = cpu_mips_find_by_name(cpu_model);
8579    if (!def)
8580        return NULL;
8581    env = qemu_mallocz(sizeof(CPUMIPSState));
8582    env->cpu_model = def;
8583
8584    cpu_exec_init(env);
8585    env->cpu_model_str = cpu_model;
8586    mips_tcg_init();
8587    cpu_reset(env);
8588    qemu_init_vcpu(env);
8589    return env;
8590}
8591
8592void cpu_reset (CPUMIPSState *env)
8593{
8594    if (qemu_loglevel_mask(CPU_LOG_RESET)) {
8595        qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
8596        log_cpu_state(env, 0);
8597    }
8598
8599    memset(env, 0, offsetof(CPUMIPSState, breakpoints));
8600
8601    tlb_flush(env, 1);
8602
8603    /* Minimal init */
8604#if defined(CONFIG_USER_ONLY)
8605    env->hflags = MIPS_HFLAG_UM;
8606    /* Enable access to the SYNCI_Step register.  */
8607    env->CP0_HWREna |= (1 << 1);
8608#else
8609    if (env->hflags & MIPS_HFLAG_BMASK) {
8610        /* If the exception was raised from a delay slot,
8611           come back to the jump.  */
8612        env->CP0_ErrorEPC = env->active_tc.PC - 4;
8613    } else {
8614        env->CP0_ErrorEPC = env->active_tc.PC;
8615    }
8616    env->active_tc.PC = (int32_t)0xBFC00000;
8617    env->CP0_Wired = 0;
8618    /* SMP not implemented */
8619    env->CP0_EBase = 0x80000000;
8620    env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
8621    /* vectored interrupts not implemented, timer on int 7,
8622       no performance counters. */
8623    env->CP0_IntCtl = 0xe0000000;
8624    {
8625        int i;
8626
8627        for (i = 0; i < 7; i++) {
8628            env->CP0_WatchLo[i] = 0;
8629            env->CP0_WatchHi[i] = 0x80000000;
8630        }
8631        env->CP0_WatchLo[7] = 0;
8632        env->CP0_WatchHi[7] = 0;
8633    }
8634    /* Count register increments in debug mode, EJTAG version 1 */
8635    env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
8636    env->hflags = MIPS_HFLAG_CP0;
8637#endif
8638    env->exception_index = EXCP_NONE;
8639    cpu_mips_register(env, env->cpu_model);
8640}
8641
8642void gen_pc_load(CPUState *env, TranslationBlock *tb,
8643                unsigned long searched_pc, int pc_pos, void *puc)
8644{
8645    env->active_tc.PC = gen_opc_pc[pc_pos];
8646    env->hflags &= ~MIPS_HFLAG_BMASK;
8647    env->hflags |= gen_opc_hflags[pc_pos];
8648}
8649