File:  [Qemu by Fabrice Bellard] / qemu / target-mips / translate.c
Revision 1.1.1.7 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 16:55:03 2018 UTC (3 years, 3 months ago) by root
Branches: qemu, MAIN
CVS tags: qemu0105, qemu0104, qemu0103, qemu0102, qemu0101, qemu0100, HEAD
qemu 0.10.0

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

unix.superglobalmegacorp.com