Annotation of qemu/target-mips/translate.c, revision 1.1.1.6

1.1       root        1: /*
                      2:  *  MIPS32 emulation for qemu: main translation routines.
1.1.1.6 ! root        3:  *
1.1       root        4:  *  Copyright (c) 2004-2005 Jocelyn Mayer
1.1.1.4   root        5:  *  Copyright (c) 2006 Marius Groeger (FPU operations)
1.1.1.5   root        6:  *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
1.1       root        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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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: 
1.1.1.2   root       33: //#define MIPS_DEBUG_DISAS
1.1.1.5   root       34: //#define MIPS_DEBUG_SIGN_EXTENSIONS
1.1       root       35: //#define MIPS_SINGLE_STEP
                     36: 
1.1.1.2   root       37: #ifdef USE_DIRECT_JUMP
                     38: #define TBPARAM(x)
                     39: #else
                     40: #define TBPARAM(x) (long)(x)
                     41: #endif
                     42: 
1.1       root       43: enum {
                     44: #define DEF(s, n, copy_size) INDEX_op_ ## s,
                     45: #include "opc.h"
                     46: #undef DEF
                     47:     NB_OPS,
                     48: };
                     49: 
                     50: static uint16_t *gen_opc_ptr;
                     51: static uint32_t *gen_opparam_ptr;
                     52: 
                     53: #include "gen-op.h"
                     54: 
1.1.1.5   root       55: /* MIPS major opcodes */
                     56: #define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
1.1       root       57: 
                     58: enum {
                     59:     /* indirect opcode tables */
1.1.1.5   root       60:     OPC_SPECIAL  = (0x00 << 26),
                     61:     OPC_REGIMM   = (0x01 << 26),
                     62:     OPC_CP0      = (0x10 << 26),
                     63:     OPC_CP1      = (0x11 << 26),
                     64:     OPC_CP2      = (0x12 << 26),
                     65:     OPC_CP3      = (0x13 << 26),
                     66:     OPC_SPECIAL2 = (0x1C << 26),
                     67:     OPC_SPECIAL3 = (0x1F << 26),
1.1       root       68:     /* arithmetic with immediate */
1.1.1.5   root       69:     OPC_ADDI     = (0x08 << 26),
                     70:     OPC_ADDIU    = (0x09 << 26),
                     71:     OPC_SLTI     = (0x0A << 26),
                     72:     OPC_SLTIU    = (0x0B << 26),
                     73:     OPC_ANDI     = (0x0C << 26),
                     74:     OPC_ORI      = (0x0D << 26),
                     75:     OPC_XORI     = (0x0E << 26),
                     76:     OPC_LUI      = (0x0F << 26),
                     77:     OPC_DADDI    = (0x18 << 26),
                     78:     OPC_DADDIU   = (0x19 << 26),
1.1       root       79:     /* Jump and branches */
1.1.1.5   root       80:     OPC_J        = (0x02 << 26),
                     81:     OPC_JAL      = (0x03 << 26),
                     82:     OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
                     83:     OPC_BEQL     = (0x14 << 26),
                     84:     OPC_BNE      = (0x05 << 26),
                     85:     OPC_BNEL     = (0x15 << 26),
                     86:     OPC_BLEZ     = (0x06 << 26),
                     87:     OPC_BLEZL    = (0x16 << 26),
                     88:     OPC_BGTZ     = (0x07 << 26),
                     89:     OPC_BGTZL    = (0x17 << 26),
                     90:     OPC_JALX     = (0x1D << 26),  /* MIPS 16 only */
1.1       root       91:     /* Load and stores */
1.1.1.5   root       92:     OPC_LDL      = (0x1A << 26),
                     93:     OPC_LDR      = (0x1B << 26),
                     94:     OPC_LB       = (0x20 << 26),
                     95:     OPC_LH       = (0x21 << 26),
                     96:     OPC_LWL      = (0x22 << 26),
                     97:     OPC_LW       = (0x23 << 26),
                     98:     OPC_LBU      = (0x24 << 26),
                     99:     OPC_LHU      = (0x25 << 26),
                    100:     OPC_LWR      = (0x26 << 26),
                    101:     OPC_LWU      = (0x27 << 26),
                    102:     OPC_SB       = (0x28 << 26),
                    103:     OPC_SH       = (0x29 << 26),
                    104:     OPC_SWL      = (0x2A << 26),
                    105:     OPC_SW       = (0x2B << 26),
                    106:     OPC_SDL      = (0x2C << 26),
                    107:     OPC_SDR      = (0x2D << 26),
                    108:     OPC_SWR      = (0x2E << 26),
                    109:     OPC_LL       = (0x30 << 26),
                    110:     OPC_LLD      = (0x34 << 26),
                    111:     OPC_LD       = (0x37 << 26),
                    112:     OPC_SC       = (0x38 << 26),
                    113:     OPC_SCD      = (0x3C << 26),
                    114:     OPC_SD       = (0x3F << 26),
1.1       root      115:     /* Floating point load/store */
1.1.1.5   root      116:     OPC_LWC1     = (0x31 << 26),
                    117:     OPC_LWC2     = (0x32 << 26),
                    118:     OPC_LDC1     = (0x35 << 26),
                    119:     OPC_LDC2     = (0x36 << 26),
                    120:     OPC_SWC1     = (0x39 << 26),
                    121:     OPC_SWC2     = (0x3A << 26),
                    122:     OPC_SDC1     = (0x3D << 26),
                    123:     OPC_SDC2     = (0x3E << 26),
                    124:     /* MDMX ASE specific */
                    125:     OPC_MDMX     = (0x1E << 26),
1.1       root      126:     /* Cache and prefetch */
1.1.1.5   root      127:     OPC_CACHE    = (0x2F << 26),
                    128:     OPC_PREF     = (0x33 << 26),
                    129:     /* Reserved major opcode */
                    130:     OPC_MAJOR3B_RESERVED = (0x3B << 26),
1.1       root      131: };
                    132: 
                    133: /* MIPS special opcodes */
1.1.1.5   root      134: #define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
                    135: 
1.1       root      136: enum {
                    137:     /* Shifts */
1.1.1.5   root      138:     OPC_SLL      = 0x00 | OPC_SPECIAL,
1.1       root      139:     /* NOP is SLL r0, r0, 0   */
                    140:     /* SSNOP is SLL r0, r0, 1 */
1.1.1.5   root      141:     /* EHB is SLL r0, r0, 3 */
                    142:     OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
                    143:     OPC_SRA      = 0x03 | OPC_SPECIAL,
                    144:     OPC_SLLV     = 0x04 | OPC_SPECIAL,
1.1.1.6 ! root      145:     OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
1.1.1.5   root      146:     OPC_SRAV     = 0x07 | OPC_SPECIAL,
                    147:     OPC_DSLLV    = 0x14 | OPC_SPECIAL,
                    148:     OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
                    149:     OPC_DSRAV    = 0x17 | OPC_SPECIAL,
                    150:     OPC_DSLL     = 0x38 | OPC_SPECIAL,
                    151:     OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
                    152:     OPC_DSRA     = 0x3B | OPC_SPECIAL,
                    153:     OPC_DSLL32   = 0x3C | OPC_SPECIAL,
                    154:     OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
                    155:     OPC_DSRA32   = 0x3F | OPC_SPECIAL,
1.1       root      156:     /* Multiplication / division */
1.1.1.5   root      157:     OPC_MULT     = 0x18 | OPC_SPECIAL,
                    158:     OPC_MULTU    = 0x19 | OPC_SPECIAL,
                    159:     OPC_DIV      = 0x1A | OPC_SPECIAL,
                    160:     OPC_DIVU     = 0x1B | OPC_SPECIAL,
                    161:     OPC_DMULT    = 0x1C | OPC_SPECIAL,
                    162:     OPC_DMULTU   = 0x1D | OPC_SPECIAL,
                    163:     OPC_DDIV     = 0x1E | OPC_SPECIAL,
                    164:     OPC_DDIVU    = 0x1F | OPC_SPECIAL,
1.1       root      165:     /* 2 registers arithmetic / logic */
1.1.1.5   root      166:     OPC_ADD      = 0x20 | OPC_SPECIAL,
                    167:     OPC_ADDU     = 0x21 | OPC_SPECIAL,
                    168:     OPC_SUB      = 0x22 | OPC_SPECIAL,
                    169:     OPC_SUBU     = 0x23 | OPC_SPECIAL,
                    170:     OPC_AND      = 0x24 | OPC_SPECIAL,
                    171:     OPC_OR       = 0x25 | OPC_SPECIAL,
                    172:     OPC_XOR      = 0x26 | OPC_SPECIAL,
                    173:     OPC_NOR      = 0x27 | OPC_SPECIAL,
                    174:     OPC_SLT      = 0x2A | OPC_SPECIAL,
                    175:     OPC_SLTU     = 0x2B | OPC_SPECIAL,
                    176:     OPC_DADD     = 0x2C | OPC_SPECIAL,
                    177:     OPC_DADDU    = 0x2D | OPC_SPECIAL,
                    178:     OPC_DSUB     = 0x2E | OPC_SPECIAL,
                    179:     OPC_DSUBU    = 0x2F | OPC_SPECIAL,
1.1       root      180:     /* Jumps */
1.1.1.5   root      181:     OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
                    182:     OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
1.1       root      183:     /* Traps */
1.1.1.5   root      184:     OPC_TGE      = 0x30 | OPC_SPECIAL,
                    185:     OPC_TGEU     = 0x31 | OPC_SPECIAL,
                    186:     OPC_TLT      = 0x32 | OPC_SPECIAL,
                    187:     OPC_TLTU     = 0x33 | OPC_SPECIAL,
                    188:     OPC_TEQ      = 0x34 | OPC_SPECIAL,
                    189:     OPC_TNE      = 0x36 | OPC_SPECIAL,
1.1       root      190:     /* HI / LO registers load & stores */
1.1.1.5   root      191:     OPC_MFHI     = 0x10 | OPC_SPECIAL,
                    192:     OPC_MTHI     = 0x11 | OPC_SPECIAL,
                    193:     OPC_MFLO     = 0x12 | OPC_SPECIAL,
                    194:     OPC_MTLO     = 0x13 | OPC_SPECIAL,
1.1       root      195:     /* Conditional moves */
1.1.1.5   root      196:     OPC_MOVZ     = 0x0A | OPC_SPECIAL,
                    197:     OPC_MOVN     = 0x0B | OPC_SPECIAL,
1.1       root      198: 
1.1.1.5   root      199:     OPC_MOVCI    = 0x01 | OPC_SPECIAL,
1.1       root      200: 
                    201:     /* Special */
1.1.1.5   root      202:     OPC_PMON     = 0x05 | OPC_SPECIAL, /* inofficial */
                    203:     OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
                    204:     OPC_BREAK    = 0x0D | OPC_SPECIAL,
                    205:     OPC_SPIM     = 0x0E | OPC_SPECIAL, /* inofficial */
                    206:     OPC_SYNC     = 0x0F | OPC_SPECIAL,
                    207: 
                    208:     OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
                    209:     OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
                    210:     OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
                    211:     OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
                    212:     OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
                    213:     OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
                    214:     OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
                    215: };
                    216: 
1.1.1.6 ! root      217: /* Multiplication variants of the vr54xx. */
        !           218: #define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
        !           219: 
        !           220: enum {
        !           221:     OPC_VR54XX_MULS    = (0x03 << 6) | OPC_MULT,
        !           222:     OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,
        !           223:     OPC_VR54XX_MACC    = (0x05 << 6) | OPC_MULT,
        !           224:     OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,
        !           225:     OPC_VR54XX_MSAC    = (0x07 << 6) | OPC_MULT,
        !           226:     OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,
        !           227:     OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,
        !           228:     OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,
        !           229:     OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,
        !           230:     OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
        !           231:     OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,
        !           232:     OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
        !           233:     OPC_VR54XX_MSACHI  = (0x0F << 6) | OPC_MULT,
        !           234:     OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
        !           235: };
        !           236: 
1.1.1.5   root      237: /* REGIMM (rt field) opcodes */
                    238: #define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
                    239: 
                    240: enum {
                    241:     OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
                    242:     OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
                    243:     OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
                    244:     OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
                    245:     OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
                    246:     OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
                    247:     OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
                    248:     OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
                    249:     OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
                    250:     OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
                    251:     OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
                    252:     OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
                    253:     OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
                    254:     OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
                    255:     OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
1.1       root      256: };
                    257: 
1.1.1.5   root      258: /* Special2 opcodes */
                    259: #define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
                    260: 
1.1       root      261: enum {
1.1.1.5   root      262:     /* Multiply & xxx operations */
                    263:     OPC_MADD     = 0x00 | OPC_SPECIAL2,
                    264:     OPC_MADDU    = 0x01 | OPC_SPECIAL2,
                    265:     OPC_MUL      = 0x02 | OPC_SPECIAL2,
                    266:     OPC_MSUB     = 0x04 | OPC_SPECIAL2,
                    267:     OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
1.1       root      268:     /* Misc */
1.1.1.5   root      269:     OPC_CLZ      = 0x20 | OPC_SPECIAL2,
                    270:     OPC_CLO      = 0x21 | OPC_SPECIAL2,
                    271:     OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
                    272:     OPC_DCLO     = 0x25 | OPC_SPECIAL2,
1.1       root      273:     /* Special */
1.1.1.5   root      274:     OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
                    275: };
                    276: 
                    277: /* Special3 opcodes */
                    278: #define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
                    279: 
                    280: enum {
                    281:     OPC_EXT      = 0x00 | OPC_SPECIAL3,
                    282:     OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
                    283:     OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
                    284:     OPC_DEXT     = 0x03 | OPC_SPECIAL3,
                    285:     OPC_INS      = 0x04 | OPC_SPECIAL3,
                    286:     OPC_DINSM    = 0x05 | OPC_SPECIAL3,
                    287:     OPC_DINSU    = 0x06 | OPC_SPECIAL3,
                    288:     OPC_DINS     = 0x07 | OPC_SPECIAL3,
1.1.1.6 ! root      289:     OPC_FORK     = 0x08 | OPC_SPECIAL3,
        !           290:     OPC_YIELD    = 0x09 | OPC_SPECIAL3,
1.1.1.5   root      291:     OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
                    292:     OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
                    293:     OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
1.1       root      294: };
                    295: 
1.1.1.5   root      296: /* BSHFL opcodes */
                    297: #define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
                    298: 
1.1       root      299: enum {
1.1.1.5   root      300:     OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
                    301:     OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
                    302:     OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
1.1       root      303: };
                    304: 
1.1.1.5   root      305: /* DBSHFL opcodes */
                    306: #define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
                    307: 
1.1       root      308: enum {
1.1.1.5   root      309:     OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
                    310:     OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
1.1       root      311: };
                    312: 
1.1.1.5   root      313: /* Coprocessor 0 (rs field) */
                    314: #define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
                    315: 
1.1.1.4   root      316: enum {
1.1.1.5   root      317:     OPC_MFC0     = (0x00 << 21) | OPC_CP0,
                    318:     OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
                    319:     OPC_MTC0     = (0x04 << 21) | OPC_CP0,
                    320:     OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
1.1.1.6 ! root      321:     OPC_MFTR     = (0x08 << 21) | OPC_CP0,
1.1.1.5   root      322:     OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
                    323:     OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
1.1.1.6 ! root      324:     OPC_MTTR     = (0x0C << 21) | OPC_CP0,
1.1.1.5   root      325:     OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
                    326:     OPC_C0       = (0x10 << 21) | OPC_CP0,
                    327:     OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
                    328:     OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,
1.1.1.4   root      329: };
1.1.1.5   root      330: 
                    331: /* MFMC0 opcodes */
1.1.1.6 ! root      332: #define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
1.1.1.5   root      333: 
                    334: enum {
1.1.1.6 ! root      335:     OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
        !           336:     OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
        !           337:     OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
        !           338:     OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
1.1.1.5   root      339:     OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
                    340:     OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
                    341: };
                    342: 
                    343: /* Coprocessor 0 (with rs == C0) */
                    344: #define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
                    345: 
                    346: enum {
                    347:     OPC_TLBR     = 0x01 | OPC_C0,
                    348:     OPC_TLBWI    = 0x02 | OPC_C0,
                    349:     OPC_TLBWR    = 0x06 | OPC_C0,
                    350:     OPC_TLBP     = 0x08 | OPC_C0,
                    351:     OPC_RFE      = 0x10 | OPC_C0,
                    352:     OPC_ERET     = 0x18 | OPC_C0,
                    353:     OPC_DERET    = 0x1F | OPC_C0,
                    354:     OPC_WAIT     = 0x20 | OPC_C0,
                    355: };
                    356: 
                    357: /* Coprocessor 1 (rs field) */
                    358: #define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
                    359: 
                    360: enum {
                    361:     OPC_MFC1     = (0x00 << 21) | OPC_CP1,
                    362:     OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
                    363:     OPC_CFC1     = (0x02 << 21) | OPC_CP1,
1.1.1.6 ! root      364:     OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
1.1.1.5   root      365:     OPC_MTC1     = (0x04 << 21) | OPC_CP1,
                    366:     OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
                    367:     OPC_CTC1     = (0x06 << 21) | OPC_CP1,
1.1.1.6 ! root      368:     OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
1.1.1.5   root      369:     OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
1.1.1.6 ! root      370:     OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
        !           371:     OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
1.1.1.5   root      372:     OPC_S_FMT    = (0x10 << 21) | OPC_CP1, /* 16: fmt=single fp */
                    373:     OPC_D_FMT    = (0x11 << 21) | OPC_CP1, /* 17: fmt=double fp */
                    374:     OPC_E_FMT    = (0x12 << 21) | OPC_CP1, /* 18: fmt=extended fp */
                    375:     OPC_Q_FMT    = (0x13 << 21) | OPC_CP1, /* 19: fmt=quad fp */
                    376:     OPC_W_FMT    = (0x14 << 21) | OPC_CP1, /* 20: fmt=32bit fixed */
                    377:     OPC_L_FMT    = (0x15 << 21) | OPC_CP1, /* 21: fmt=64bit fixed */
1.1.1.6 ! root      378:     OPC_PS_FMT   = (0x16 << 21) | OPC_CP1, /* 22: fmt=paired single fp */
1.1.1.5   root      379: };
                    380: 
1.1.1.6 ! root      381: #define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
        !           382: #define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
        !           383: 
1.1.1.5   root      384: enum {
                    385:     OPC_BC1F     = (0x00 << 16) | OPC_BC1,
                    386:     OPC_BC1T     = (0x01 << 16) | OPC_BC1,
                    387:     OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
                    388:     OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
                    389: };
                    390: 
1.1.1.6 ! root      391: enum {
        !           392:     OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
        !           393:     OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
        !           394: };
        !           395: 
        !           396: enum {
        !           397:     OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
        !           398:     OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
        !           399: };
1.1.1.5   root      400: 
                    401: #define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
1.1.1.6 ! root      402: 
        !           403: enum {
        !           404:     OPC_MFC2    = (0x00 << 21) | OPC_CP2,
        !           405:     OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
        !           406:     OPC_CFC2    = (0x02 << 21) | OPC_CP2,
        !           407:     OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
        !           408:     OPC_MTC2    = (0x04 << 21) | OPC_CP2,
        !           409:     OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
        !           410:     OPC_CTC2    = (0x06 << 21) | OPC_CP2,
        !           411:     OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
        !           412:     OPC_BC2     = (0x08 << 21) | OPC_CP2,
        !           413: };
        !           414: 
        !           415: #define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
        !           416: 
        !           417: enum {
        !           418:     OPC_LWXC1   = 0x00 | OPC_CP3,
        !           419:     OPC_LDXC1   = 0x01 | OPC_CP3,
        !           420:     OPC_LUXC1   = 0x05 | OPC_CP3,
        !           421:     OPC_SWXC1   = 0x08 | OPC_CP3,
        !           422:     OPC_SDXC1   = 0x09 | OPC_CP3,
        !           423:     OPC_SUXC1   = 0x0D | OPC_CP3,
        !           424:     OPC_PREFX   = 0x0F | OPC_CP3,
        !           425:     OPC_ALNV_PS = 0x1E | OPC_CP3,
        !           426:     OPC_MADD_S  = 0x20 | OPC_CP3,
        !           427:     OPC_MADD_D  = 0x21 | OPC_CP3,
        !           428:     OPC_MADD_PS = 0x26 | OPC_CP3,
        !           429:     OPC_MSUB_S  = 0x28 | OPC_CP3,
        !           430:     OPC_MSUB_D  = 0x29 | OPC_CP3,
        !           431:     OPC_MSUB_PS = 0x2E | OPC_CP3,
        !           432:     OPC_NMADD_S = 0x30 | OPC_CP3,
        !           433:     OPC_NMADD_D = 0x31 | OPC_CP3,
        !           434:     OPC_NMADD_PS= 0x36 | OPC_CP3,
        !           435:     OPC_NMSUB_S = 0x38 | OPC_CP3,
        !           436:     OPC_NMSUB_D = 0x39 | OPC_CP3,
        !           437:     OPC_NMSUB_PS= 0x3E | OPC_CP3,
        !           438: };
        !           439: 
1.1.1.4   root      440: 
1.1       root      441: const unsigned char *regnames[] =
                    442:     { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
                    443:       "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
                    444:       "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
                    445:       "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
                    446: 
                    447: /* Warning: no function for r0 register (hard wired to zero) */
1.1.1.6 ! root      448: #define GEN32(func, NAME)                        \
        !           449: static GenOpFunc *NAME ## _table [32] = {        \
        !           450: NULL,       NAME ## 1, NAME ## 2, NAME ## 3,     \
        !           451: NAME ## 4,  NAME ## 5, NAME ## 6, NAME ## 7,     \
        !           452: NAME ## 8,  NAME ## 9, NAME ## 10, NAME ## 11,   \
        !           453: NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,  \
        !           454: NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,  \
        !           455: NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,  \
        !           456: NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,  \
        !           457: NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,  \
        !           458: };                                               \
        !           459: static always_inline void func(int n)            \
        !           460: {                                                \
        !           461:     NAME ## _table[n]();                         \
1.1       root      462: }
                    463: 
                    464: /* General purpose registers moves */
                    465: GEN32(gen_op_load_gpr_T0, gen_op_load_gpr_T0_gpr);
                    466: GEN32(gen_op_load_gpr_T1, gen_op_load_gpr_T1_gpr);
                    467: GEN32(gen_op_load_gpr_T2, gen_op_load_gpr_T2_gpr);
                    468: 
                    469: GEN32(gen_op_store_T0_gpr, gen_op_store_T0_gpr_gpr);
                    470: GEN32(gen_op_store_T1_gpr, gen_op_store_T1_gpr_gpr);
                    471: 
1.1.1.6 ! root      472: /* Moves to/from shadow registers */
        !           473: GEN32(gen_op_load_srsgpr_T0, gen_op_load_srsgpr_T0_gpr);
        !           474: GEN32(gen_op_store_T0_srsgpr, gen_op_store_T0_srsgpr_gpr);
1.1.1.5   root      475: 
                    476: static const char *fregnames[] =
1.1.1.4   root      477:     { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
                    478:       "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
                    479:       "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
                    480:       "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
                    481: 
1.1.1.6 ! root      482: #define FGEN32(func, NAME)                       \
        !           483: static GenOpFunc *NAME ## _table [32] = {        \
        !           484: NAME ## 0,  NAME ## 1,  NAME ## 2,  NAME ## 3,   \
        !           485: NAME ## 4,  NAME ## 5,  NAME ## 6,  NAME ## 7,   \
        !           486: NAME ## 8,  NAME ## 9,  NAME ## 10, NAME ## 11,  \
        !           487: NAME ## 12, NAME ## 13, NAME ## 14, NAME ## 15,  \
        !           488: NAME ## 16, NAME ## 17, NAME ## 18, NAME ## 19,  \
        !           489: NAME ## 20, NAME ## 21, NAME ## 22, NAME ## 23,  \
        !           490: NAME ## 24, NAME ## 25, NAME ## 26, NAME ## 27,  \
        !           491: NAME ## 28, NAME ## 29, NAME ## 30, NAME ## 31,  \
        !           492: };                                               \
        !           493: static always_inline void func(int n)            \
        !           494: {                                                \
        !           495:     NAME ## _table[n]();                         \
        !           496: }
        !           497: 
        !           498: FGEN32(gen_op_load_fpr_WT0,  gen_op_load_fpr_WT0_fpr);
        !           499: FGEN32(gen_op_store_fpr_WT0, gen_op_store_fpr_WT0_fpr);
        !           500: 
        !           501: FGEN32(gen_op_load_fpr_WT1,  gen_op_load_fpr_WT1_fpr);
        !           502: FGEN32(gen_op_store_fpr_WT1, gen_op_store_fpr_WT1_fpr);
        !           503: 
        !           504: FGEN32(gen_op_load_fpr_WT2,  gen_op_load_fpr_WT2_fpr);
        !           505: FGEN32(gen_op_store_fpr_WT2, gen_op_store_fpr_WT2_fpr);
        !           506: 
        !           507: FGEN32(gen_op_load_fpr_DT0,  gen_op_load_fpr_DT0_fpr);
        !           508: FGEN32(gen_op_store_fpr_DT0, gen_op_store_fpr_DT0_fpr);
        !           509: 
        !           510: FGEN32(gen_op_load_fpr_DT1,  gen_op_load_fpr_DT1_fpr);
        !           511: FGEN32(gen_op_store_fpr_DT1, gen_op_store_fpr_DT1_fpr);
        !           512: 
        !           513: FGEN32(gen_op_load_fpr_DT2,  gen_op_load_fpr_DT2_fpr);
        !           514: FGEN32(gen_op_store_fpr_DT2, gen_op_store_fpr_DT2_fpr);
        !           515: 
        !           516: FGEN32(gen_op_load_fpr_WTH0,  gen_op_load_fpr_WTH0_fpr);
        !           517: FGEN32(gen_op_store_fpr_WTH0, gen_op_store_fpr_WTH0_fpr);
        !           518: 
        !           519: FGEN32(gen_op_load_fpr_WTH1,  gen_op_load_fpr_WTH1_fpr);
        !           520: FGEN32(gen_op_store_fpr_WTH1, gen_op_store_fpr_WTH1_fpr);
        !           521: 
        !           522: FGEN32(gen_op_load_fpr_WTH2,  gen_op_load_fpr_WTH2_fpr);
        !           523: FGEN32(gen_op_store_fpr_WTH2, gen_op_store_fpr_WTH2_fpr);
        !           524: 
        !           525: #define FOP_CONDS(type, fmt)                                            \
        !           526: static GenOpFunc1 * gen_op_cmp ## type ## _ ## fmt ## _table[16] = {    \
        !           527:     gen_op_cmp ## type ## _ ## fmt ## _f,                               \
        !           528:     gen_op_cmp ## type ## _ ## fmt ## _un,                              \
        !           529:     gen_op_cmp ## type ## _ ## fmt ## _eq,                              \
        !           530:     gen_op_cmp ## type ## _ ## fmt ## _ueq,                             \
        !           531:     gen_op_cmp ## type ## _ ## fmt ## _olt,                             \
        !           532:     gen_op_cmp ## type ## _ ## fmt ## _ult,                             \
        !           533:     gen_op_cmp ## type ## _ ## fmt ## _ole,                             \
        !           534:     gen_op_cmp ## type ## _ ## fmt ## _ule,                             \
        !           535:     gen_op_cmp ## type ## _ ## fmt ## _sf,                              \
        !           536:     gen_op_cmp ## type ## _ ## fmt ## _ngle,                            \
        !           537:     gen_op_cmp ## type ## _ ## fmt ## _seq,                             \
        !           538:     gen_op_cmp ## type ## _ ## fmt ## _ngl,                             \
        !           539:     gen_op_cmp ## type ## _ ## fmt ## _lt,                              \
        !           540:     gen_op_cmp ## type ## _ ## fmt ## _nge,                             \
        !           541:     gen_op_cmp ## type ## _ ## fmt ## _le,                              \
        !           542:     gen_op_cmp ## type ## _ ## fmt ## _ngt,                             \
1.1.1.4   root      543: };                                                                      \
1.1.1.6 ! root      544: static always_inline void gen_cmp ## type ## _ ## fmt(int n, long cc)   \
1.1.1.4   root      545: {                                                                       \
1.1.1.6 ! root      546:     gen_op_cmp ## type ## _ ## fmt ## _table[n](cc);                    \
1.1.1.4   root      547: }
                    548: 
1.1.1.6 ! root      549: FOP_CONDS(, d)
        !           550: FOP_CONDS(abs, d)
        !           551: FOP_CONDS(, s)
        !           552: FOP_CONDS(abs, s)
        !           553: FOP_CONDS(, ps)
        !           554: FOP_CONDS(abs, ps)
1.1.1.4   root      555: 
1.1       root      556: typedef struct DisasContext {
                    557:     struct TranslationBlock *tb;
                    558:     target_ulong pc, saved_pc;
                    559:     uint32_t opcode;
1.1.1.6 ! root      560:     uint32_t fp_status;
1.1       root      561:     /* Routine used to access memory */
                    562:     int mem_idx;
                    563:     uint32_t hflags, saved_hflags;
                    564:     int bstate;
                    565:     target_ulong btarget;
1.1.1.6 ! root      566:     void *last_T0_store;
        !           567:     int last_T0_gpr;
1.1       root      568: } DisasContext;
                    569: 
                    570: enum {
                    571:     BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
                    572:                       * exception condition
                    573:                       */
                    574:     BS_STOP     = 1, /* We want to stop translation for any reason */
                    575:     BS_BRANCH   = 2, /* We reached a branch condition     */
                    576:     BS_EXCP     = 3, /* We reached an exception condition */
                    577: };
                    578: 
1.1.1.6 ! root      579: #ifdef MIPS_DEBUG_DISAS
1.1       root      580: #define MIPS_DEBUG(fmt, args...)                                              \
                    581: do {                                                                          \
                    582:     if (loglevel & CPU_LOG_TB_IN_ASM) {                                       \
1.1.1.6 ! root      583:         fprintf(logfile, TARGET_FMT_lx ": %08x " fmt "\n",                    \
1.1       root      584:                 ctx->pc, ctx->opcode , ##args);                               \
                    585:     }                                                                         \
                    586: } while (0)
                    587: #else
                    588: #define MIPS_DEBUG(fmt, args...) do { } while(0)
                    589: #endif
                    590: 
                    591: #define MIPS_INVAL(op)                                                        \
                    592: do {                                                                          \
                    593:     MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
                    594:                ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
                    595: } while (0)
                    596: 
1.1.1.6 ! root      597: #define GEN_LOAD_REG_T0(Rn)                                                   \
        !           598: do {                                                                          \
        !           599:     if (Rn == 0) {                                                            \
        !           600:         gen_op_reset_T0();                                                    \
        !           601:     } else {                                                                  \
        !           602:         if (ctx->glue(last_T0, _store) != gen_opc_ptr                         \
        !           603:             || ctx->glue(last_T0, _gpr) != Rn) {                              \
        !           604:                 gen_op_load_gpr_T0(Rn);                                       \
        !           605:         }                                                                     \
        !           606:     }                                                                         \
        !           607: } while (0)
        !           608: 
        !           609: #define GEN_LOAD_REG_T1(Rn)                                                   \
        !           610: do {                                                                          \
        !           611:     if (Rn == 0) {                                                            \
        !           612:         gen_op_reset_T1();                                                    \
        !           613:     } else {                                                                  \
        !           614:         gen_op_load_gpr_T1(Rn);                                               \
        !           615:     }                                                                         \
        !           616: } while (0)
        !           617: 
        !           618: #define GEN_LOAD_REG_T2(Rn)                                                   \
        !           619: do {                                                                          \
        !           620:     if (Rn == 0) {                                                            \
        !           621:         gen_op_reset_T2();                                                    \
        !           622:     } else {                                                                  \
        !           623:         gen_op_load_gpr_T2(Rn);                                               \
        !           624:     }                                                                         \
        !           625: } while (0)
        !           626: 
        !           627: #define GEN_LOAD_SRSREG_TN(Tn, Rn)                                            \
1.1       root      628: do {                                                                          \
                    629:     if (Rn == 0) {                                                            \
                    630:         glue(gen_op_reset_, Tn)();                                            \
                    631:     } else {                                                                  \
1.1.1.6 ! root      632:         glue(gen_op_load_srsgpr_, Tn)(Rn);                                    \
1.1       root      633:     }                                                                         \
                    634: } while (0)
                    635: 
1.1.1.6 ! root      636: #if defined(TARGET_MIPS64)
        !           637: #define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
        !           638: do {                                                                          \
        !           639:     if (Imm == 0) {                                                           \
        !           640:         glue(gen_op_reset_, Tn)();                                            \
        !           641:     } else if ((int32_t)Imm == Imm) {                                         \
        !           642:         glue(gen_op_set_, Tn)(Imm);                                           \
        !           643:     } else {                                                                  \
        !           644:         glue(gen_op_set64_, Tn)(((uint64_t)Imm) >> 32, (uint32_t)Imm);        \
        !           645:     }                                                                         \
        !           646: } while (0)
        !           647: #else
1.1       root      648: #define GEN_LOAD_IMM_TN(Tn, Imm)                                              \
                    649: do {                                                                          \
                    650:     if (Imm == 0) {                                                           \
                    651:         glue(gen_op_reset_, Tn)();                                            \
                    652:     } else {                                                                  \
                    653:         glue(gen_op_set_, Tn)(Imm);                                           \
                    654:     }                                                                         \
                    655: } while (0)
1.1.1.6 ! root      656: #endif
        !           657: 
        !           658: #define GEN_STORE_T0_REG(Rn)                                                  \
        !           659: do {                                                                          \
        !           660:     if (Rn != 0) {                                                            \
        !           661:         glue(gen_op_store_T0,_gpr)(Rn);                                       \
        !           662:         ctx->glue(last_T0,_store) = gen_opc_ptr;                              \
        !           663:         ctx->glue(last_T0,_gpr) = Rn;                                         \
        !           664:     }                                                                         \
        !           665: } while (0)
        !           666: 
        !           667: #define GEN_STORE_T1_REG(Rn)                                                  \
        !           668: do {                                                                          \
        !           669:     if (Rn != 0)                                                              \
        !           670:         glue(gen_op_store_T1,_gpr)(Rn);                                       \
        !           671: } while (0)
1.1       root      672: 
1.1.1.6 ! root      673: #define GEN_STORE_TN_SRSREG(Rn, Tn)                                           \
1.1       root      674: do {                                                                          \
                    675:     if (Rn != 0) {                                                            \
1.1.1.6 ! root      676:         glue(glue(gen_op_store_, Tn),_srsgpr)(Rn);                            \
1.1       root      677:     }                                                                         \
                    678: } while (0)
                    679: 
1.1.1.5   root      680: #define GEN_LOAD_FREG_FTN(FTn, Fn)                                            \
1.1.1.4   root      681: do {                                                                          \
                    682:     glue(gen_op_load_fpr_, FTn)(Fn);                                          \
                    683: } while (0)
                    684: 
                    685: #define GEN_STORE_FTN_FREG(Fn, FTn)                                           \
                    686: do {                                                                          \
                    687:     glue(gen_op_store_fpr_, FTn)(Fn);                                         \
                    688: } while (0)
                    689: 
1.1.1.6 ! root      690: static always_inline void gen_save_pc(target_ulong pc)
        !           691: {
        !           692: #if defined(TARGET_MIPS64)
        !           693:     if (pc == (int32_t)pc) {
        !           694:         gen_op_save_pc(pc);
        !           695:     } else {
        !           696:         gen_op_save_pc64(pc >> 32, (uint32_t)pc);
        !           697:     }
        !           698: #else
        !           699:     gen_op_save_pc(pc);
        !           700: #endif
        !           701: }
        !           702: 
        !           703: static always_inline void gen_save_btarget(target_ulong btarget)
        !           704: {
        !           705: #if defined(TARGET_MIPS64)
        !           706:     if (btarget == (int32_t)btarget) {
        !           707:         gen_op_save_btarget(btarget);
        !           708:     } else {
        !           709:         gen_op_save_btarget64(btarget >> 32, (uint32_t)btarget);
        !           710:     }
        !           711: #else
        !           712:     gen_op_save_btarget(btarget);
        !           713: #endif
        !           714: }
        !           715: 
        !           716: static always_inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
1.1       root      717: {
                    718: #if defined MIPS_DEBUG_DISAS
                    719:     if (loglevel & CPU_LOG_TB_IN_ASM) {
                    720:             fprintf(logfile, "hflags %08x saved %08x\n",
                    721:                     ctx->hflags, ctx->saved_hflags);
                    722:     }
                    723: #endif
                    724:     if (do_save_pc && ctx->pc != ctx->saved_pc) {
1.1.1.6 ! root      725:         gen_save_pc(ctx->pc);
1.1       root      726:         ctx->saved_pc = ctx->pc;
                    727:     }
                    728:     if (ctx->hflags != ctx->saved_hflags) {
                    729:         gen_op_save_state(ctx->hflags);
                    730:         ctx->saved_hflags = ctx->hflags;
1.1.1.6 ! root      731:         switch (ctx->hflags & MIPS_HFLAG_BMASK) {
        !           732:         case MIPS_HFLAG_BR:
1.1       root      733:             gen_op_save_breg_target();
1.1.1.6 ! root      734:             break;
        !           735:         case MIPS_HFLAG_BC:
1.1       root      736:             gen_op_save_bcond();
1.1.1.6 ! root      737:             /* fall through */
        !           738:         case MIPS_HFLAG_BL:
        !           739:             /* bcond was already saved by the BL insn */
        !           740:             /* fall through */
        !           741:         case MIPS_HFLAG_B:
        !           742:             gen_save_btarget(ctx->btarget);
        !           743:             break;
1.1       root      744:         }
                    745:     }
                    746: }
                    747: 
1.1.1.6 ! root      748: static always_inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
        !           749: {
        !           750:     ctx->saved_hflags = ctx->hflags;
        !           751:     switch (ctx->hflags & MIPS_HFLAG_BMASK) {
        !           752:     case MIPS_HFLAG_BR:
        !           753:         gen_op_restore_breg_target();
        !           754:         break;
        !           755:     case MIPS_HFLAG_B:
        !           756:         ctx->btarget = env->btarget;
        !           757:         break;
        !           758:     case MIPS_HFLAG_BC:
        !           759:     case MIPS_HFLAG_BL:
        !           760:         ctx->btarget = env->btarget;
        !           761:         gen_op_restore_bcond();
        !           762:         break;
        !           763:     }
        !           764: }
        !           765: 
        !           766: static always_inline void generate_exception_err (DisasContext *ctx, int excp, int err)
1.1       root      767: {
                    768: #if defined MIPS_DEBUG_DISAS
                    769:     if (loglevel & CPU_LOG_TB_IN_ASM)
                    770:             fprintf(logfile, "%s: raise exception %d\n", __func__, excp);
                    771: #endif
                    772:     save_cpu_state(ctx, 1);
1.1.1.2   root      773:     if (err == 0)
                    774:         gen_op_raise_exception(excp);
                    775:     else
                    776:         gen_op_raise_exception_err(excp, err);
1.1       root      777:     ctx->bstate = BS_EXCP;
                    778: }
                    779: 
1.1.1.6 ! root      780: static always_inline void generate_exception (DisasContext *ctx, int excp)
1.1.1.2   root      781: {
                    782:     generate_exception_err (ctx, excp, 0);
                    783: }
                    784: 
1.1.1.6 ! root      785: static always_inline void check_cp0_enabled(DisasContext *ctx)
        !           786: {
        !           787:     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
        !           788:         generate_exception_err(ctx, EXCP_CpU, 1);
        !           789: }
        !           790: 
        !           791: static always_inline void check_cp1_enabled(DisasContext *ctx)
        !           792: {
        !           793:     if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
        !           794:         generate_exception_err(ctx, EXCP_CpU, 1);
        !           795: }
        !           796: 
        !           797: /* Verify that the processor is running with COP1X instructions enabled.
        !           798:    This is associated with the nabla symbol in the MIPS32 and MIPS64
        !           799:    opcode tables.  */
        !           800: 
        !           801: static always_inline void check_cop1x(DisasContext *ctx)
        !           802: {
        !           803:     if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
        !           804:         generate_exception(ctx, EXCP_RI);
        !           805: }
        !           806: 
        !           807: /* Verify that the processor is running with 64-bit floating-point
        !           808:    operations enabled.  */
        !           809: 
        !           810: static always_inline void check_cp1_64bitmode(DisasContext *ctx)
        !           811: {
        !           812:     if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
        !           813:         generate_exception(ctx, EXCP_RI);
        !           814: }
        !           815: 
        !           816: /*
        !           817:  * Verify if floating point register is valid; an operation is not defined
        !           818:  * if bit 0 of any register specification is set and the FR bit in the
        !           819:  * Status register equals zero, since the register numbers specify an
        !           820:  * even-odd pair of adjacent coprocessor general registers. When the FR bit
        !           821:  * in the Status register equals one, both even and odd register numbers
        !           822:  * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
        !           823:  *
        !           824:  * Multiple 64 bit wide registers can be checked by calling
        !           825:  * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
        !           826:  */
        !           827: void check_cp1_registers(DisasContext *ctx, int regs)
        !           828: {
        !           829:     if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
        !           830:         generate_exception(ctx, EXCP_RI);
        !           831: }
        !           832: 
        !           833: /* This code generates a "reserved instruction" exception if the
        !           834:    CPU does not support the instruction set corresponding to flags. */
        !           835: static always_inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
        !           836: {
        !           837:     if (unlikely(!(env->insn_flags & flags)))
        !           838:         generate_exception(ctx, EXCP_RI);
        !           839: }
        !           840: 
        !           841: /* This code generates a "reserved instruction" exception if 64-bit
        !           842:    instructions are not enabled. */
        !           843: static always_inline void check_mips_64(DisasContext *ctx)
        !           844: {
        !           845:     if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
        !           846:         generate_exception(ctx, EXCP_RI);
        !           847: }
        !           848: 
1.1       root      849: #if defined(CONFIG_USER_ONLY)
                    850: #define op_ldst(name)        gen_op_##name##_raw()
                    851: #define OP_LD_TABLE(width)
                    852: #define OP_ST_TABLE(width)
                    853: #else
                    854: #define op_ldst(name)        (*gen_op_##name[ctx->mem_idx])()
                    855: #define OP_LD_TABLE(width)                                                    \
                    856: static GenOpFunc *gen_op_l##width[] = {                                       \
                    857:     &gen_op_l##width##_kernel,                                                \
1.1.1.6 ! root      858:     &gen_op_l##width##_super,                                                 \
        !           859:     &gen_op_l##width##_user,                                                  \
1.1       root      860: }
                    861: #define OP_ST_TABLE(width)                                                    \
                    862: static GenOpFunc *gen_op_s##width[] = {                                       \
                    863:     &gen_op_s##width##_kernel,                                                \
1.1.1.6 ! root      864:     &gen_op_s##width##_super,                                                 \
        !           865:     &gen_op_s##width##_user,                                                  \
1.1       root      866: }
                    867: #endif
                    868: 
1.1.1.6 ! root      869: #if defined(TARGET_MIPS64)
1.1       root      870: OP_LD_TABLE(d);
                    871: OP_LD_TABLE(dl);
                    872: OP_LD_TABLE(dr);
                    873: OP_ST_TABLE(d);
                    874: OP_ST_TABLE(dl);
                    875: OP_ST_TABLE(dr);
1.1.1.5   root      876: OP_LD_TABLE(ld);
                    877: OP_ST_TABLE(cd);
1.1.1.6 ! root      878: OP_LD_TABLE(wu);
1.1       root      879: #endif
                    880: OP_LD_TABLE(w);
                    881: OP_LD_TABLE(wl);
                    882: OP_LD_TABLE(wr);
                    883: OP_ST_TABLE(w);
                    884: OP_ST_TABLE(wl);
                    885: OP_ST_TABLE(wr);
                    886: OP_LD_TABLE(h);
                    887: OP_LD_TABLE(hu);
                    888: OP_ST_TABLE(h);
                    889: OP_LD_TABLE(b);
                    890: OP_LD_TABLE(bu);
                    891: OP_ST_TABLE(b);
                    892: OP_LD_TABLE(l);
                    893: OP_ST_TABLE(c);
1.1.1.4   root      894: OP_LD_TABLE(wc1);
                    895: OP_ST_TABLE(wc1);
                    896: OP_LD_TABLE(dc1);
                    897: OP_ST_TABLE(dc1);
1.1.1.6 ! root      898: OP_LD_TABLE(uxc1);
        !           899: OP_ST_TABLE(uxc1);
1.1       root      900: 
                    901: /* Load and store */
1.1.1.5   root      902: static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
1.1       root      903:                       int base, int16_t offset)
                    904: {
1.1.1.6 ! root      905:     const char *opn = "ldst";
1.1       root      906: 
                    907:     if (base == 0) {
                    908:         GEN_LOAD_IMM_TN(T0, offset);
                    909:     } else if (offset == 0) {
                    910:         gen_op_load_gpr_T0(base);
                    911:     } else {
                    912:         gen_op_load_gpr_T0(base);
                    913:         gen_op_set_T1(offset);
1.1.1.6 ! root      914:         gen_op_addr_add();
1.1       root      915:     }
                    916:     /* Don't do NOP if destination is zero: we must perform the actual
1.1.1.6 ! root      917:        memory access. */
1.1       root      918:     switch (opc) {
1.1.1.6 ! root      919: #if defined(TARGET_MIPS64)
        !           920:     case OPC_LWU:
        !           921:         op_ldst(lwu);
        !           922:         GEN_STORE_T0_REG(rt);
        !           923:         opn = "lwu";
        !           924:         break;
1.1       root      925:     case OPC_LD:
                    926:         op_ldst(ld);
1.1.1.6 ! root      927:         GEN_STORE_T0_REG(rt);
1.1       root      928:         opn = "ld";
                    929:         break;
1.1.1.5   root      930:     case OPC_LLD:
                    931:         op_ldst(lld);
1.1.1.6 ! root      932:         GEN_STORE_T0_REG(rt);
1.1.1.5   root      933:         opn = "lld";
                    934:         break;
1.1       root      935:     case OPC_SD:
1.1.1.6 ! root      936:         GEN_LOAD_REG_T1(rt);
1.1       root      937:         op_ldst(sd);
                    938:         opn = "sd";
                    939:         break;
1.1.1.5   root      940:     case OPC_SCD:
1.1.1.6 ! root      941:         save_cpu_state(ctx, 1);
        !           942:         GEN_LOAD_REG_T1(rt);
1.1.1.5   root      943:         op_ldst(scd);
1.1.1.6 ! root      944:         GEN_STORE_T0_REG(rt);
1.1.1.5   root      945:         opn = "scd";
                    946:         break;
1.1       root      947:     case OPC_LDL:
1.1.1.6 ! root      948:         GEN_LOAD_REG_T1(rt);
1.1       root      949:         op_ldst(ldl);
1.1.1.6 ! root      950:         GEN_STORE_T1_REG(rt);
1.1       root      951:         opn = "ldl";
                    952:         break;
                    953:     case OPC_SDL:
1.1.1.6 ! root      954:         GEN_LOAD_REG_T1(rt);
1.1       root      955:         op_ldst(sdl);
                    956:         opn = "sdl";
                    957:         break;
                    958:     case OPC_LDR:
1.1.1.6 ! root      959:         GEN_LOAD_REG_T1(rt);
1.1       root      960:         op_ldst(ldr);
1.1.1.6 ! root      961:         GEN_STORE_T1_REG(rt);
1.1       root      962:         opn = "ldr";
                    963:         break;
                    964:     case OPC_SDR:
1.1.1.6 ! root      965:         GEN_LOAD_REG_T1(rt);
1.1       root      966:         op_ldst(sdr);
                    967:         opn = "sdr";
                    968:         break;
                    969: #endif
                    970:     case OPC_LW:
                    971:         op_ldst(lw);
1.1.1.6 ! root      972:         GEN_STORE_T0_REG(rt);
1.1       root      973:         opn = "lw";
                    974:         break;
                    975:     case OPC_SW:
1.1.1.6 ! root      976:         GEN_LOAD_REG_T1(rt);
1.1       root      977:         op_ldst(sw);
                    978:         opn = "sw";
                    979:         break;
                    980:     case OPC_LH:
                    981:         op_ldst(lh);
1.1.1.6 ! root      982:         GEN_STORE_T0_REG(rt);
1.1       root      983:         opn = "lh";
                    984:         break;
                    985:     case OPC_SH:
1.1.1.6 ! root      986:         GEN_LOAD_REG_T1(rt);
1.1       root      987:         op_ldst(sh);
                    988:         opn = "sh";
                    989:         break;
                    990:     case OPC_LHU:
                    991:         op_ldst(lhu);
1.1.1.6 ! root      992:         GEN_STORE_T0_REG(rt);
1.1       root      993:         opn = "lhu";
                    994:         break;
                    995:     case OPC_LB:
                    996:         op_ldst(lb);
1.1.1.6 ! root      997:         GEN_STORE_T0_REG(rt);
1.1       root      998:         opn = "lb";
                    999:         break;
                   1000:     case OPC_SB:
1.1.1.6 ! root     1001:         GEN_LOAD_REG_T1(rt);
1.1       root     1002:         op_ldst(sb);
                   1003:         opn = "sb";
                   1004:         break;
                   1005:     case OPC_LBU:
                   1006:         op_ldst(lbu);
1.1.1.6 ! root     1007:         GEN_STORE_T0_REG(rt);
1.1       root     1008:         opn = "lbu";
                   1009:         break;
                   1010:     case OPC_LWL:
1.1.1.6 ! root     1011:        GEN_LOAD_REG_T1(rt);
1.1       root     1012:         op_ldst(lwl);
1.1.1.6 ! root     1013:         GEN_STORE_T1_REG(rt);
1.1       root     1014:         opn = "lwl";
                   1015:         break;
                   1016:     case OPC_SWL:
1.1.1.6 ! root     1017:         GEN_LOAD_REG_T1(rt);
1.1       root     1018:         op_ldst(swl);
                   1019:         opn = "swr";
                   1020:         break;
                   1021:     case OPC_LWR:
1.1.1.6 ! root     1022:        GEN_LOAD_REG_T1(rt);
1.1       root     1023:         op_ldst(lwr);
1.1.1.6 ! root     1024:         GEN_STORE_T1_REG(rt);
1.1       root     1025:         opn = "lwr";
                   1026:         break;
                   1027:     case OPC_SWR:
1.1.1.6 ! root     1028:         GEN_LOAD_REG_T1(rt);
1.1       root     1029:         op_ldst(swr);
                   1030:         opn = "swr";
                   1031:         break;
                   1032:     case OPC_LL:
                   1033:         op_ldst(ll);
1.1.1.6 ! root     1034:         GEN_STORE_T0_REG(rt);
1.1       root     1035:         opn = "ll";
                   1036:         break;
                   1037:     case OPC_SC:
1.1.1.6 ! root     1038:         save_cpu_state(ctx, 1);
        !          1039:         GEN_LOAD_REG_T1(rt);
1.1       root     1040:         op_ldst(sc);
1.1.1.6 ! root     1041:         GEN_STORE_T0_REG(rt);
1.1       root     1042:         opn = "sc";
                   1043:         break;
                   1044:     default:
1.1.1.6 ! root     1045:         MIPS_INVAL(opn);
1.1       root     1046:         generate_exception(ctx, EXCP_RI);
                   1047:         return;
                   1048:     }
                   1049:     MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
                   1050: }
                   1051: 
1.1.1.4   root     1052: /* Load and store */
1.1.1.5   root     1053: static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1.1.1.4   root     1054:                       int base, int16_t offset)
                   1055: {
1.1.1.6 ! root     1056:     const char *opn = "flt_ldst";
1.1.1.4   root     1057: 
                   1058:     if (base == 0) {
                   1059:         GEN_LOAD_IMM_TN(T0, offset);
                   1060:     } else if (offset == 0) {
                   1061:         gen_op_load_gpr_T0(base);
                   1062:     } else {
                   1063:         gen_op_load_gpr_T0(base);
                   1064:         gen_op_set_T1(offset);
1.1.1.6 ! root     1065:         gen_op_addr_add();
1.1.1.4   root     1066:     }
                   1067:     /* Don't do NOP if destination is zero: we must perform the actual
1.1.1.6 ! root     1068:        memory access. */
1.1.1.4   root     1069:     switch (opc) {
                   1070:     case OPC_LWC1:
                   1071:         op_ldst(lwc1);
                   1072:         GEN_STORE_FTN_FREG(ft, WT0);
                   1073:         opn = "lwc1";
                   1074:         break;
                   1075:     case OPC_SWC1:
                   1076:         GEN_LOAD_FREG_FTN(WT0, ft);
                   1077:         op_ldst(swc1);
                   1078:         opn = "swc1";
                   1079:         break;
                   1080:     case OPC_LDC1:
                   1081:         op_ldst(ldc1);
                   1082:         GEN_STORE_FTN_FREG(ft, DT0);
                   1083:         opn = "ldc1";
                   1084:         break;
                   1085:     case OPC_SDC1:
                   1086:         GEN_LOAD_FREG_FTN(DT0, ft);
                   1087:         op_ldst(sdc1);
                   1088:         opn = "sdc1";
                   1089:         break;
                   1090:     default:
1.1.1.6 ! root     1091:         MIPS_INVAL(opn);
        !          1092:         generate_exception(ctx, EXCP_RI);
1.1.1.4   root     1093:         return;
                   1094:     }
                   1095:     MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
                   1096: }
1.1.1.5   root     1097: 
1.1       root     1098: /* Arithmetic with immediate operand */
1.1.1.6 ! root     1099: static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
        !          1100:                            int rt, int rs, int16_t imm)
1.1       root     1101: {
1.1.1.6 ! root     1102:     target_ulong uimm;
        !          1103:     const char *opn = "imm arith";
1.1       root     1104: 
1.1.1.5   root     1105:     if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1.1.1.6 ! root     1106:         /* If no destination, treat it as a NOP.
        !          1107:            For addi, we must generate the overflow exception when needed. */
1.1       root     1108:         MIPS_DEBUG("NOP");
                   1109:         return;
                   1110:     }
1.1.1.6 ! root     1111:     uimm = (uint16_t)imm;
        !          1112:     switch (opc) {
        !          1113:     case OPC_ADDI:
        !          1114:     case OPC_ADDIU:
        !          1115: #if defined(TARGET_MIPS64)
        !          1116:     case OPC_DADDI:
        !          1117:     case OPC_DADDIU:
        !          1118: #endif
        !          1119:     case OPC_SLTI:
        !          1120:     case OPC_SLTIU:
        !          1121:         uimm = (target_long)imm; /* Sign extend to 32/64 bits */
        !          1122:         /* Fall through. */
        !          1123:     case OPC_ANDI:
        !          1124:     case OPC_ORI:
        !          1125:     case OPC_XORI:
        !          1126:         GEN_LOAD_REG_T0(rs);
1.1       root     1127:         GEN_LOAD_IMM_TN(T1, uimm);
1.1.1.6 ! root     1128:         break;
        !          1129:     case OPC_LUI:
        !          1130:         GEN_LOAD_IMM_TN(T0, imm << 16);
        !          1131:         break;
        !          1132:     case OPC_SLL:
        !          1133:     case OPC_SRA:
        !          1134:     case OPC_SRL:
        !          1135: #if defined(TARGET_MIPS64)
        !          1136:     case OPC_DSLL:
        !          1137:     case OPC_DSRA:
        !          1138:     case OPC_DSRL:
        !          1139:     case OPC_DSLL32:
        !          1140:     case OPC_DSRA32:
        !          1141:     case OPC_DSRL32:
        !          1142: #endif
        !          1143:         uimm &= 0x1f;
        !          1144:         GEN_LOAD_REG_T0(rs);
        !          1145:         GEN_LOAD_IMM_TN(T1, uimm);
        !          1146:         break;
1.1       root     1147:     }
                   1148:     switch (opc) {
                   1149:     case OPC_ADDI:
                   1150:         save_cpu_state(ctx, 1);
                   1151:         gen_op_addo();
                   1152:         opn = "addi";
                   1153:         break;
                   1154:     case OPC_ADDIU:
                   1155:         gen_op_add();
                   1156:         opn = "addiu";
                   1157:         break;
1.1.1.6 ! root     1158: #if defined(TARGET_MIPS64)
1.1.1.5   root     1159:     case OPC_DADDI:
                   1160:         save_cpu_state(ctx, 1);
                   1161:         gen_op_daddo();
                   1162:         opn = "daddi";
                   1163:         break;
                   1164:     case OPC_DADDIU:
                   1165:         gen_op_dadd();
                   1166:         opn = "daddiu";
                   1167:         break;
                   1168: #endif
1.1       root     1169:     case OPC_SLTI:
                   1170:         gen_op_lt();
                   1171:         opn = "slti";
                   1172:         break;
                   1173:     case OPC_SLTIU:
                   1174:         gen_op_ltu();
                   1175:         opn = "sltiu";
                   1176:         break;
                   1177:     case OPC_ANDI:
                   1178:         gen_op_and();
                   1179:         opn = "andi";
                   1180:         break;
                   1181:     case OPC_ORI:
                   1182:         gen_op_or();
                   1183:         opn = "ori";
                   1184:         break;
                   1185:     case OPC_XORI:
                   1186:         gen_op_xor();
                   1187:         opn = "xori";
                   1188:         break;
                   1189:     case OPC_LUI:
                   1190:         opn = "lui";
                   1191:         break;
                   1192:     case OPC_SLL:
                   1193:         gen_op_sll();
                   1194:         opn = "sll";
                   1195:         break;
                   1196:     case OPC_SRA:
                   1197:         gen_op_sra();
                   1198:         opn = "sra";
                   1199:         break;
                   1200:     case OPC_SRL:
1.1.1.6 ! root     1201:         switch ((ctx->opcode >> 21) & 0x1f) {
        !          1202:         case 0:
1.1.1.5   root     1203:             gen_op_srl();
                   1204:             opn = "srl";
1.1.1.6 ! root     1205:             break;
        !          1206:         case 1:
        !          1207:             /* rotr is decoded as srl on non-R2 CPUs */
        !          1208:             if (env->insn_flags & ISA_MIPS32R2) {
        !          1209:                 gen_op_rotr();
        !          1210:                 opn = "rotr";
        !          1211:             } else {
        !          1212:                 gen_op_srl();
        !          1213:                 opn = "srl";
        !          1214:             }
        !          1215:             break;
        !          1216:         default:
        !          1217:             MIPS_INVAL("invalid srl flag");
        !          1218:             generate_exception(ctx, EXCP_RI);
        !          1219:             break;
        !          1220:         }
1.1.1.5   root     1221:         break;
1.1.1.6 ! root     1222: #if defined(TARGET_MIPS64)
1.1.1.5   root     1223:     case OPC_DSLL:
                   1224:         gen_op_dsll();
                   1225:         opn = "dsll";
                   1226:         break;
                   1227:     case OPC_DSRA:
                   1228:         gen_op_dsra();
                   1229:         opn = "dsra";
                   1230:         break;
                   1231:     case OPC_DSRL:
1.1.1.6 ! root     1232:         switch ((ctx->opcode >> 21) & 0x1f) {
        !          1233:         case 0:
1.1.1.5   root     1234:             gen_op_dsrl();
                   1235:             opn = "dsrl";
1.1.1.6 ! root     1236:             break;
        !          1237:         case 1:
        !          1238:             /* drotr is decoded as dsrl on non-R2 CPUs */
        !          1239:             if (env->insn_flags & ISA_MIPS32R2) {
        !          1240:                 gen_op_drotr();
        !          1241:                 opn = "drotr";
        !          1242:             } else {
        !          1243:                 gen_op_dsrl();
        !          1244:                 opn = "dsrl";
        !          1245:             }
        !          1246:             break;
        !          1247:         default:
        !          1248:             MIPS_INVAL("invalid dsrl flag");
        !          1249:             generate_exception(ctx, EXCP_RI);
        !          1250:             break;
        !          1251:         }
1.1.1.5   root     1252:         break;
                   1253:     case OPC_DSLL32:
                   1254:         gen_op_dsll32();
                   1255:         opn = "dsll32";
                   1256:         break;
                   1257:     case OPC_DSRA32:
                   1258:         gen_op_dsra32();
                   1259:         opn = "dsra32";
                   1260:         break;
                   1261:     case OPC_DSRL32:
1.1.1.6 ! root     1262:         switch ((ctx->opcode >> 21) & 0x1f) {
        !          1263:         case 0:
1.1.1.5   root     1264:             gen_op_dsrl32();
                   1265:             opn = "dsrl32";
1.1.1.6 ! root     1266:             break;
        !          1267:         case 1:
        !          1268:             /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
        !          1269:             if (env->insn_flags & ISA_MIPS32R2) {
        !          1270:                 gen_op_drotr32();
        !          1271:                 opn = "drotr32";
        !          1272:             } else {
        !          1273:                 gen_op_dsrl32();
        !          1274:                 opn = "dsrl32";
        !          1275:             }
        !          1276:             break;
        !          1277:         default:
        !          1278:             MIPS_INVAL("invalid dsrl32 flag");
        !          1279:             generate_exception(ctx, EXCP_RI);
        !          1280:             break;
        !          1281:         }
1.1       root     1282:         break;
1.1.1.5   root     1283: #endif
1.1       root     1284:     default:
1.1.1.6 ! root     1285:         MIPS_INVAL(opn);
1.1       root     1286:         generate_exception(ctx, EXCP_RI);
                   1287:         return;
                   1288:     }
1.1.1.6 ! root     1289:     GEN_STORE_T0_REG(rt);
        !          1290:     MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1.1       root     1291: }
                   1292: 
                   1293: /* Arithmetic */
1.1.1.6 ! root     1294: static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1.1       root     1295:                        int rd, int rs, int rt)
                   1296: {
1.1.1.6 ! root     1297:     const char *opn = "arith";
1.1       root     1298: 
1.1.1.5   root     1299:     if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
                   1300:        && opc != OPC_DADD && opc != OPC_DSUB) {
1.1.1.6 ! root     1301:         /* If no destination, treat it as a NOP.
        !          1302:            For add & sub, we must generate the overflow exception when needed. */
1.1       root     1303:         MIPS_DEBUG("NOP");
                   1304:         return;
                   1305:     }
1.1.1.6 ! root     1306:     GEN_LOAD_REG_T0(rs);
        !          1307:     /* Specialcase the conventional move operation. */
        !          1308:     if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
        !          1309:                     || opc == OPC_SUBU || opc == OPC_DSUBU)) {
        !          1310:         GEN_STORE_T0_REG(rd);
        !          1311:         return;
        !          1312:     }
        !          1313:     GEN_LOAD_REG_T1(rt);
1.1       root     1314:     switch (opc) {
                   1315:     case OPC_ADD:
                   1316:         save_cpu_state(ctx, 1);
                   1317:         gen_op_addo();
                   1318:         opn = "add";
                   1319:         break;
                   1320:     case OPC_ADDU:
                   1321:         gen_op_add();
                   1322:         opn = "addu";
                   1323:         break;
                   1324:     case OPC_SUB:
                   1325:         save_cpu_state(ctx, 1);
                   1326:         gen_op_subo();
                   1327:         opn = "sub";
                   1328:         break;
                   1329:     case OPC_SUBU:
                   1330:         gen_op_sub();
                   1331:         opn = "subu";
                   1332:         break;
1.1.1.6 ! root     1333: #if defined(TARGET_MIPS64)
1.1.1.5   root     1334:     case OPC_DADD:
                   1335:         save_cpu_state(ctx, 1);
                   1336:         gen_op_daddo();
                   1337:         opn = "dadd";
                   1338:         break;
                   1339:     case OPC_DADDU:
                   1340:         gen_op_dadd();
                   1341:         opn = "daddu";
                   1342:         break;
                   1343:     case OPC_DSUB:
                   1344:         save_cpu_state(ctx, 1);
                   1345:         gen_op_dsubo();
                   1346:         opn = "dsub";
                   1347:         break;
                   1348:     case OPC_DSUBU:
                   1349:         gen_op_dsub();
                   1350:         opn = "dsubu";
                   1351:         break;
                   1352: #endif
1.1       root     1353:     case OPC_SLT:
                   1354:         gen_op_lt();
                   1355:         opn = "slt";
                   1356:         break;
                   1357:     case OPC_SLTU:
                   1358:         gen_op_ltu();
                   1359:         opn = "sltu";
                   1360:         break;
                   1361:     case OPC_AND:
                   1362:         gen_op_and();
                   1363:         opn = "and";
                   1364:         break;
                   1365:     case OPC_NOR:
                   1366:         gen_op_nor();
                   1367:         opn = "nor";
                   1368:         break;
                   1369:     case OPC_OR:
                   1370:         gen_op_or();
                   1371:         opn = "or";
                   1372:         break;
                   1373:     case OPC_XOR:
                   1374:         gen_op_xor();
                   1375:         opn = "xor";
                   1376:         break;
                   1377:     case OPC_MUL:
                   1378:         gen_op_mul();
                   1379:         opn = "mul";
                   1380:         break;
                   1381:     case OPC_MOVN:
                   1382:         gen_op_movn(rd);
                   1383:         opn = "movn";
                   1384:         goto print;
                   1385:     case OPC_MOVZ:
                   1386:         gen_op_movz(rd);
                   1387:         opn = "movz";
                   1388:         goto print;
                   1389:     case OPC_SLLV:
                   1390:         gen_op_sllv();
                   1391:         opn = "sllv";
                   1392:         break;
                   1393:     case OPC_SRAV:
                   1394:         gen_op_srav();
                   1395:         opn = "srav";
                   1396:         break;
                   1397:     case OPC_SRLV:
1.1.1.6 ! root     1398:         switch ((ctx->opcode >> 6) & 0x1f) {
        !          1399:         case 0:
1.1.1.5   root     1400:             gen_op_srlv();
                   1401:             opn = "srlv";
1.1.1.6 ! root     1402:             break;
        !          1403:         case 1:
        !          1404:             /* rotrv is decoded as srlv on non-R2 CPUs */
        !          1405:             if (env->insn_flags & ISA_MIPS32R2) {
        !          1406:                 gen_op_rotrv();
        !          1407:                 opn = "rotrv";
        !          1408:             } else {
        !          1409:                 gen_op_srlv();
        !          1410:                 opn = "srlv";
        !          1411:             }
        !          1412:             break;
        !          1413:         default:
        !          1414:             MIPS_INVAL("invalid srlv flag");
        !          1415:             generate_exception(ctx, EXCP_RI);
        !          1416:             break;
        !          1417:         }
1.1.1.5   root     1418:         break;
1.1.1.6 ! root     1419: #if defined(TARGET_MIPS64)
1.1.1.5   root     1420:     case OPC_DSLLV:
                   1421:         gen_op_dsllv();
                   1422:         opn = "dsllv";
                   1423:         break;
                   1424:     case OPC_DSRAV:
                   1425:         gen_op_dsrav();
                   1426:         opn = "dsrav";
                   1427:         break;
                   1428:     case OPC_DSRLV:
1.1.1.6 ! root     1429:         switch ((ctx->opcode >> 6) & 0x1f) {
        !          1430:         case 0:
1.1.1.5   root     1431:             gen_op_dsrlv();
                   1432:             opn = "dsrlv";
1.1.1.6 ! root     1433:             break;
        !          1434:         case 1:
        !          1435:             /* drotrv is decoded as dsrlv on non-R2 CPUs */
        !          1436:             if (env->insn_flags & ISA_MIPS32R2) {
        !          1437:                 gen_op_drotrv();
        !          1438:                 opn = "drotrv";
        !          1439:             } else {
        !          1440:                 gen_op_dsrlv();
        !          1441:                 opn = "dsrlv";
        !          1442:             }
        !          1443:             break;
        !          1444:         default:
        !          1445:             MIPS_INVAL("invalid dsrlv flag");
        !          1446:             generate_exception(ctx, EXCP_RI);
        !          1447:             break;
        !          1448:         }
1.1       root     1449:         break;
1.1.1.5   root     1450: #endif
1.1       root     1451:     default:
1.1.1.6 ! root     1452:         MIPS_INVAL(opn);
1.1       root     1453:         generate_exception(ctx, EXCP_RI);
                   1454:         return;
                   1455:     }
1.1.1.6 ! root     1456:     GEN_STORE_T0_REG(rd);
1.1       root     1457:  print:
                   1458:     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
                   1459: }
                   1460: 
                   1461: /* Arithmetic on HI/LO registers */
1.1.1.5   root     1462: static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1.1       root     1463: {
1.1.1.6 ! root     1464:     const char *opn = "hilo";
1.1       root     1465: 
                   1466:     if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1.1.1.6 ! root     1467:         /* Treat as NOP. */
1.1       root     1468:         MIPS_DEBUG("NOP");
                   1469:         return;
                   1470:     }
                   1471:     switch (opc) {
                   1472:     case OPC_MFHI:
1.1.1.6 ! root     1473:         gen_op_load_HI(0);
        !          1474:         GEN_STORE_T0_REG(reg);
1.1       root     1475:         opn = "mfhi";
                   1476:         break;
                   1477:     case OPC_MFLO:
1.1.1.6 ! root     1478:         gen_op_load_LO(0);
        !          1479:         GEN_STORE_T0_REG(reg);
1.1       root     1480:         opn = "mflo";
                   1481:         break;
                   1482:     case OPC_MTHI:
1.1.1.6 ! root     1483:         GEN_LOAD_REG_T0(reg);
        !          1484:         gen_op_store_HI(0);
1.1       root     1485:         opn = "mthi";
                   1486:         break;
                   1487:     case OPC_MTLO:
1.1.1.6 ! root     1488:         GEN_LOAD_REG_T0(reg);
        !          1489:         gen_op_store_LO(0);
1.1       root     1490:         opn = "mtlo";
                   1491:         break;
                   1492:     default:
1.1.1.6 ! root     1493:         MIPS_INVAL(opn);
1.1       root     1494:         generate_exception(ctx, EXCP_RI);
                   1495:         return;
                   1496:     }
                   1497:     MIPS_DEBUG("%s %s", opn, regnames[reg]);
                   1498: }
                   1499: 
1.1.1.5   root     1500: static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1.1       root     1501:                         int rs, int rt)
                   1502: {
1.1.1.6 ! root     1503:     const char *opn = "mul/div";
1.1       root     1504: 
1.1.1.6 ! root     1505:     GEN_LOAD_REG_T0(rs);
        !          1506:     GEN_LOAD_REG_T1(rt);
1.1       root     1507:     switch (opc) {
                   1508:     case OPC_DIV:
                   1509:         gen_op_div();
                   1510:         opn = "div";
                   1511:         break;
                   1512:     case OPC_DIVU:
                   1513:         gen_op_divu();
                   1514:         opn = "divu";
                   1515:         break;
                   1516:     case OPC_MULT:
                   1517:         gen_op_mult();
                   1518:         opn = "mult";
                   1519:         break;
                   1520:     case OPC_MULTU:
                   1521:         gen_op_multu();
                   1522:         opn = "multu";
                   1523:         break;
1.1.1.6 ! root     1524: #if defined(TARGET_MIPS64)
1.1.1.5   root     1525:     case OPC_DDIV:
                   1526:         gen_op_ddiv();
                   1527:         opn = "ddiv";
                   1528:         break;
                   1529:     case OPC_DDIVU:
                   1530:         gen_op_ddivu();
                   1531:         opn = "ddivu";
                   1532:         break;
                   1533:     case OPC_DMULT:
                   1534:         gen_op_dmult();
                   1535:         opn = "dmult";
                   1536:         break;
                   1537:     case OPC_DMULTU:
                   1538:         gen_op_dmultu();
                   1539:         opn = "dmultu";
                   1540:         break;
                   1541: #endif
1.1       root     1542:     case OPC_MADD:
                   1543:         gen_op_madd();
                   1544:         opn = "madd";
                   1545:         break;
                   1546:     case OPC_MADDU:
                   1547:         gen_op_maddu();
                   1548:         opn = "maddu";
                   1549:         break;
                   1550:     case OPC_MSUB:
                   1551:         gen_op_msub();
                   1552:         opn = "msub";
                   1553:         break;
                   1554:     case OPC_MSUBU:
                   1555:         gen_op_msubu();
                   1556:         opn = "msubu";
                   1557:         break;
                   1558:     default:
1.1.1.6 ! root     1559:         MIPS_INVAL(opn);
1.1       root     1560:         generate_exception(ctx, EXCP_RI);
                   1561:         return;
                   1562:     }
                   1563:     MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
                   1564: }
                   1565: 
1.1.1.6 ! root     1566: static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
        !          1567:                             int rd, int rs, int rt)
        !          1568: {
        !          1569:     const char *opn = "mul vr54xx";
        !          1570: 
        !          1571:     GEN_LOAD_REG_T0(rs);
        !          1572:     GEN_LOAD_REG_T1(rt);
        !          1573: 
        !          1574:     switch (opc) {
        !          1575:     case OPC_VR54XX_MULS:
        !          1576:         gen_op_muls();
        !          1577:         opn = "muls";
        !          1578:        break;
        !          1579:     case OPC_VR54XX_MULSU:
        !          1580:         gen_op_mulsu();
        !          1581:         opn = "mulsu";
        !          1582:        break;
        !          1583:     case OPC_VR54XX_MACC:
        !          1584:         gen_op_macc();
        !          1585:         opn = "macc";
        !          1586:        break;
        !          1587:     case OPC_VR54XX_MACCU:
        !          1588:         gen_op_maccu();
        !          1589:         opn = "maccu";
        !          1590:        break;
        !          1591:     case OPC_VR54XX_MSAC:
        !          1592:         gen_op_msac();
        !          1593:         opn = "msac";
        !          1594:        break;
        !          1595:     case OPC_VR54XX_MSACU:
        !          1596:         gen_op_msacu();
        !          1597:         opn = "msacu";
        !          1598:        break;
        !          1599:     case OPC_VR54XX_MULHI:
        !          1600:         gen_op_mulhi();
        !          1601:         opn = "mulhi";
        !          1602:        break;
        !          1603:     case OPC_VR54XX_MULHIU:
        !          1604:         gen_op_mulhiu();
        !          1605:         opn = "mulhiu";
        !          1606:        break;
        !          1607:     case OPC_VR54XX_MULSHI:
        !          1608:         gen_op_mulshi();
        !          1609:         opn = "mulshi";
        !          1610:        break;
        !          1611:     case OPC_VR54XX_MULSHIU:
        !          1612:         gen_op_mulshiu();
        !          1613:         opn = "mulshiu";
        !          1614:        break;
        !          1615:     case OPC_VR54XX_MACCHI:
        !          1616:         gen_op_macchi();
        !          1617:         opn = "macchi";
        !          1618:        break;
        !          1619:     case OPC_VR54XX_MACCHIU:
        !          1620:         gen_op_macchiu();
        !          1621:         opn = "macchiu";
        !          1622:        break;
        !          1623:     case OPC_VR54XX_MSACHI:
        !          1624:         gen_op_msachi();
        !          1625:         opn = "msachi";
        !          1626:        break;
        !          1627:     case OPC_VR54XX_MSACHIU:
        !          1628:         gen_op_msachiu();
        !          1629:         opn = "msachiu";
        !          1630:        break;
        !          1631:     default:
        !          1632:         MIPS_INVAL("mul vr54xx");
        !          1633:         generate_exception(ctx, EXCP_RI);
        !          1634:         return;
        !          1635:     }
        !          1636:     GEN_STORE_T0_REG(rd);
        !          1637:     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
        !          1638: }
        !          1639: 
1.1.1.5   root     1640: static void gen_cl (DisasContext *ctx, uint32_t opc,
1.1       root     1641:                     int rd, int rs)
                   1642: {
1.1.1.6 ! root     1643:     const char *opn = "CLx";
1.1       root     1644:     if (rd == 0) {
1.1.1.6 ! root     1645:         /* Treat as NOP. */
1.1       root     1646:         MIPS_DEBUG("NOP");
                   1647:         return;
                   1648:     }
1.1.1.6 ! root     1649:     GEN_LOAD_REG_T0(rs);
1.1       root     1650:     switch (opc) {
                   1651:     case OPC_CLO:
                   1652:         gen_op_clo();
                   1653:         opn = "clo";
                   1654:         break;
                   1655:     case OPC_CLZ:
                   1656:         gen_op_clz();
                   1657:         opn = "clz";
                   1658:         break;
1.1.1.6 ! root     1659: #if defined(TARGET_MIPS64)
1.1.1.5   root     1660:     case OPC_DCLO:
                   1661:         gen_op_dclo();
                   1662:         opn = "dclo";
                   1663:         break;
                   1664:     case OPC_DCLZ:
                   1665:         gen_op_dclz();
                   1666:         opn = "dclz";
                   1667:         break;
                   1668: #endif
1.1       root     1669:     default:
1.1.1.6 ! root     1670:         MIPS_INVAL(opn);
1.1       root     1671:         generate_exception(ctx, EXCP_RI);
                   1672:         return;
                   1673:     }
                   1674:     gen_op_store_T0_gpr(rd);
                   1675:     MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
                   1676: }
                   1677: 
                   1678: /* Traps */
1.1.1.5   root     1679: static void gen_trap (DisasContext *ctx, uint32_t opc,
1.1       root     1680:                       int rs, int rt, int16_t imm)
                   1681: {
                   1682:     int cond;
                   1683: 
                   1684:     cond = 0;
                   1685:     /* Load needed operands */
                   1686:     switch (opc) {
                   1687:     case OPC_TEQ:
                   1688:     case OPC_TGE:
                   1689:     case OPC_TGEU:
                   1690:     case OPC_TLT:
                   1691:     case OPC_TLTU:
                   1692:     case OPC_TNE:
                   1693:         /* Compare two registers */
                   1694:         if (rs != rt) {
1.1.1.6 ! root     1695:             GEN_LOAD_REG_T0(rs);
        !          1696:             GEN_LOAD_REG_T1(rt);
1.1       root     1697:             cond = 1;
                   1698:         }
1.1.1.5   root     1699:         break;
1.1       root     1700:     case OPC_TEQI:
                   1701:     case OPC_TGEI:
                   1702:     case OPC_TGEIU:
                   1703:     case OPC_TLTI:
                   1704:     case OPC_TLTIU:
                   1705:     case OPC_TNEI:
                   1706:         /* Compare register to immediate */
                   1707:         if (rs != 0 || imm != 0) {
1.1.1.6 ! root     1708:             GEN_LOAD_REG_T0(rs);
1.1       root     1709:             GEN_LOAD_IMM_TN(T1, (int32_t)imm);
                   1710:             cond = 1;
                   1711:         }
                   1712:         break;
                   1713:     }
                   1714:     if (cond == 0) {
                   1715:         switch (opc) {
                   1716:         case OPC_TEQ:   /* rs == rs */
                   1717:         case OPC_TEQI:  /* r0 == 0  */
                   1718:         case OPC_TGE:   /* rs >= rs */
                   1719:         case OPC_TGEI:  /* r0 >= 0  */
                   1720:         case OPC_TGEU:  /* rs >= rs unsigned */
                   1721:         case OPC_TGEIU: /* r0 >= 0  unsigned */
                   1722:             /* Always trap */
                   1723:             gen_op_set_T0(1);
                   1724:             break;
                   1725:         case OPC_TLT:   /* rs < rs           */
                   1726:         case OPC_TLTI:  /* r0 < 0            */
                   1727:         case OPC_TLTU:  /* rs < rs unsigned  */
                   1728:         case OPC_TLTIU: /* r0 < 0  unsigned  */
                   1729:         case OPC_TNE:   /* rs != rs          */
                   1730:         case OPC_TNEI:  /* r0 != 0           */
1.1.1.6 ! root     1731:             /* Never trap: treat as NOP. */
1.1       root     1732:             return;
                   1733:         default:
1.1.1.6 ! root     1734:             MIPS_INVAL("trap");
1.1       root     1735:             generate_exception(ctx, EXCP_RI);
                   1736:             return;
                   1737:         }
                   1738:     } else {
                   1739:         switch (opc) {
                   1740:         case OPC_TEQ:
                   1741:         case OPC_TEQI:
                   1742:             gen_op_eq();
                   1743:             break;
                   1744:         case OPC_TGE:
                   1745:         case OPC_TGEI:
                   1746:             gen_op_ge();
                   1747:             break;
                   1748:         case OPC_TGEU:
                   1749:         case OPC_TGEIU:
                   1750:             gen_op_geu();
                   1751:             break;
                   1752:         case OPC_TLT:
                   1753:         case OPC_TLTI:
                   1754:             gen_op_lt();
                   1755:             break;
                   1756:         case OPC_TLTU:
                   1757:         case OPC_TLTIU:
                   1758:             gen_op_ltu();
                   1759:             break;
                   1760:         case OPC_TNE:
                   1761:         case OPC_TNEI:
                   1762:             gen_op_ne();
                   1763:             break;
                   1764:         default:
1.1.1.6 ! root     1765:             MIPS_INVAL("trap");
1.1       root     1766:             generate_exception(ctx, EXCP_RI);
                   1767:             return;
                   1768:         }
                   1769:     }
                   1770:     save_cpu_state(ctx, 1);
                   1771:     gen_op_trap();
                   1772:     ctx->bstate = BS_STOP;
                   1773: }
                   1774: 
1.1.1.6 ! root     1775: static always_inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1.1.1.2   root     1776: {
                   1777:     TranslationBlock *tb;
                   1778:     tb = ctx->tb;
                   1779:     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
                   1780:         if (n == 0)
                   1781:             gen_op_goto_tb0(TBPARAM(tb));
                   1782:         else
                   1783:             gen_op_goto_tb1(TBPARAM(tb));
1.1.1.6 ! root     1784:         gen_save_pc(dest);
1.1.1.2   root     1785:         gen_op_set_T0((long)tb + n);
                   1786:     } else {
1.1.1.6 ! root     1787:         gen_save_pc(dest);
        !          1788:         gen_op_reset_T0();
1.1.1.2   root     1789:     }
1.1.1.6 ! root     1790:     gen_op_exit_tb();
1.1.1.2   root     1791: }
                   1792: 
1.1       root     1793: /* Branches (before delay slot) */
1.1.1.5   root     1794: static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1.1       root     1795:                                 int rs, int rt, int32_t offset)
                   1796: {
1.1.1.6 ! root     1797:     target_ulong btarget = -1;
        !          1798:     int blink = 0;
        !          1799:     int bcond = 0;
1.1       root     1800: 
1.1.1.6 ! root     1801:     if (ctx->hflags & MIPS_HFLAG_BMASK) {
        !          1802: #ifdef MIPS_DEBUG_DISAS
        !          1803:         if (loglevel & CPU_LOG_TB_IN_ASM) {
        !          1804:             fprintf(logfile,
        !          1805:                     "Branch in delay slot at PC 0x" TARGET_FMT_lx "\n",
        !          1806:                     ctx->pc);
        !          1807:        }
        !          1808: #endif
        !          1809:         generate_exception(ctx, EXCP_RI);
        !          1810:         return;
        !          1811:     }
        !          1812: 
        !          1813:     /* Load needed operands */
        !          1814:     switch (opc) {
        !          1815:     case OPC_BEQ:
        !          1816:     case OPC_BEQL:
        !          1817:     case OPC_BNE:
        !          1818:     case OPC_BNEL:
1.1       root     1819:         /* Compare two registers */
                   1820:         if (rs != rt) {
1.1.1.6 ! root     1821:             GEN_LOAD_REG_T0(rs);
        !          1822:             GEN_LOAD_REG_T1(rt);
1.1       root     1823:             bcond = 1;
                   1824:         }
                   1825:         btarget = ctx->pc + 4 + offset;
                   1826:         break;
                   1827:     case OPC_BGEZ:
                   1828:     case OPC_BGEZAL:
                   1829:     case OPC_BGEZALL:
                   1830:     case OPC_BGEZL:
                   1831:     case OPC_BGTZ:
                   1832:     case OPC_BGTZL:
                   1833:     case OPC_BLEZ:
                   1834:     case OPC_BLEZL:
                   1835:     case OPC_BLTZ:
                   1836:     case OPC_BLTZAL:
                   1837:     case OPC_BLTZALL:
                   1838:     case OPC_BLTZL:
                   1839:         /* Compare to zero */
                   1840:         if (rs != 0) {
                   1841:             gen_op_load_gpr_T0(rs);
                   1842:             bcond = 1;
                   1843:         }
                   1844:         btarget = ctx->pc + 4 + offset;
                   1845:         break;
                   1846:     case OPC_J:
                   1847:     case OPC_JAL:
                   1848:         /* Jump to immediate */
1.1.1.6 ! root     1849:         btarget = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
1.1       root     1850:         break;
                   1851:     case OPC_JR:
                   1852:     case OPC_JALR:
                   1853:         /* Jump to register */
1.1.1.5   root     1854:         if (offset != 0 && offset != 16) {
                   1855:             /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
1.1.1.6 ! root     1856:                others are reserved. */
        !          1857:             MIPS_INVAL("jump hint");
1.1       root     1858:             generate_exception(ctx, EXCP_RI);
                   1859:             return;
                   1860:         }
1.1.1.6 ! root     1861:         GEN_LOAD_REG_T2(rs);
1.1       root     1862:         break;
                   1863:     default:
                   1864:         MIPS_INVAL("branch/jump");
                   1865:         generate_exception(ctx, EXCP_RI);
                   1866:         return;
                   1867:     }
                   1868:     if (bcond == 0) {
                   1869:         /* No condition to be computed */
                   1870:         switch (opc) {
                   1871:         case OPC_BEQ:     /* rx == rx        */
                   1872:         case OPC_BEQL:    /* rx == rx likely */
                   1873:         case OPC_BGEZ:    /* 0 >= 0          */
                   1874:         case OPC_BGEZL:   /* 0 >= 0 likely   */
                   1875:         case OPC_BLEZ:    /* 0 <= 0          */
                   1876:         case OPC_BLEZL:   /* 0 <= 0 likely   */
                   1877:             /* Always take */
1.1.1.2   root     1878:             ctx->hflags |= MIPS_HFLAG_B;
1.1       root     1879:             MIPS_DEBUG("balways");
                   1880:             break;
                   1881:         case OPC_BGEZAL:  /* 0 >= 0          */
                   1882:         case OPC_BGEZALL: /* 0 >= 0 likely   */
                   1883:             /* Always take and link */
                   1884:             blink = 31;
1.1.1.2   root     1885:             ctx->hflags |= MIPS_HFLAG_B;
1.1       root     1886:             MIPS_DEBUG("balways and link");
                   1887:             break;
                   1888:         case OPC_BNE:     /* rx != rx        */
                   1889:         case OPC_BGTZ:    /* 0 > 0           */
                   1890:         case OPC_BLTZ:    /* 0 < 0           */
1.1.1.6 ! root     1891:             /* Treat as NOP. */
1.1       root     1892:             MIPS_DEBUG("bnever (NOP)");
                   1893:             return;
1.1.1.2   root     1894:         case OPC_BLTZAL:  /* 0 < 0           */
1.1.1.6 ! root     1895:             GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
1.1.1.2   root     1896:             gen_op_store_T0_gpr(31);
1.1.1.6 ! root     1897:             MIPS_DEBUG("bnever and link");
1.1.1.2   root     1898:             return;
                   1899:         case OPC_BLTZALL: /* 0 < 0 likely */
1.1.1.6 ! root     1900:             GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
1.1.1.2   root     1901:             gen_op_store_T0_gpr(31);
1.1.1.6 ! root     1902:             /* Skip the instruction in the delay slot */
        !          1903:             MIPS_DEBUG("bnever, link and skip");
        !          1904:             ctx->pc += 4;
1.1.1.2   root     1905:             return;
1.1       root     1906:         case OPC_BNEL:    /* rx != rx likely */
                   1907:         case OPC_BGTZL:   /* 0 > 0 likely */
                   1908:         case OPC_BLTZL:   /* 0 < 0 likely */
                   1909:             /* Skip the instruction in the delay slot */
                   1910:             MIPS_DEBUG("bnever and skip");
1.1.1.6 ! root     1911:             ctx->pc += 4;
1.1       root     1912:             return;
                   1913:         case OPC_J:
1.1.1.2   root     1914:             ctx->hflags |= MIPS_HFLAG_B;
1.1.1.6 ! root     1915:             MIPS_DEBUG("j " TARGET_FMT_lx, btarget);
1.1       root     1916:             break;
                   1917:         case OPC_JAL:
                   1918:             blink = 31;
1.1.1.2   root     1919:             ctx->hflags |= MIPS_HFLAG_B;
1.1.1.6 ! root     1920:             MIPS_DEBUG("jal " TARGET_FMT_lx, btarget);
1.1       root     1921:             break;
                   1922:         case OPC_JR:
1.1.1.2   root     1923:             ctx->hflags |= MIPS_HFLAG_BR;
1.1       root     1924:             MIPS_DEBUG("jr %s", regnames[rs]);
                   1925:             break;
                   1926:         case OPC_JALR:
                   1927:             blink = rt;
1.1.1.2   root     1928:             ctx->hflags |= MIPS_HFLAG_BR;
1.1       root     1929:             MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
                   1930:             break;
                   1931:         default:
                   1932:             MIPS_INVAL("branch/jump");
                   1933:             generate_exception(ctx, EXCP_RI);
                   1934:             return;
                   1935:         }
                   1936:     } else {
                   1937:         switch (opc) {
                   1938:         case OPC_BEQ:
                   1939:             gen_op_eq();
1.1.1.6 ! root     1940:             MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
1.1       root     1941:                        regnames[rs], regnames[rt], btarget);
                   1942:             goto not_likely;
                   1943:         case OPC_BEQL:
                   1944:             gen_op_eq();
1.1.1.6 ! root     1945:             MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
1.1       root     1946:                        regnames[rs], regnames[rt], btarget);
                   1947:             goto likely;
                   1948:         case OPC_BNE:
                   1949:             gen_op_ne();
1.1.1.6 ! root     1950:             MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
1.1       root     1951:                        regnames[rs], regnames[rt], btarget);
                   1952:             goto not_likely;
                   1953:         case OPC_BNEL:
                   1954:             gen_op_ne();
1.1.1.6 ! root     1955:             MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
1.1       root     1956:                        regnames[rs], regnames[rt], btarget);
                   1957:             goto likely;
                   1958:         case OPC_BGEZ:
                   1959:             gen_op_gez();
1.1.1.6 ! root     1960:             MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btarget);
1.1       root     1961:             goto not_likely;
                   1962:         case OPC_BGEZL:
                   1963:             gen_op_gez();
1.1.1.6 ! root     1964:             MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1.1       root     1965:             goto likely;
                   1966:         case OPC_BGEZAL:
                   1967:             gen_op_gez();
1.1.1.6 ! root     1968:             MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btarget);
1.1       root     1969:             blink = 31;
                   1970:             goto not_likely;
                   1971:         case OPC_BGEZALL:
                   1972:             gen_op_gez();
                   1973:             blink = 31;
1.1.1.6 ! root     1974:             MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btarget);
1.1       root     1975:             goto likely;
                   1976:         case OPC_BGTZ:
                   1977:             gen_op_gtz();
1.1.1.6 ! root     1978:             MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btarget);
1.1       root     1979:             goto not_likely;
                   1980:         case OPC_BGTZL:
                   1981:             gen_op_gtz();
1.1.1.6 ! root     1982:             MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1.1       root     1983:             goto likely;
                   1984:         case OPC_BLEZ:
                   1985:             gen_op_lez();
1.1.1.6 ! root     1986:             MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btarget);
1.1       root     1987:             goto not_likely;
                   1988:         case OPC_BLEZL:
                   1989:             gen_op_lez();
1.1.1.6 ! root     1990:             MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1.1       root     1991:             goto likely;
                   1992:         case OPC_BLTZ:
                   1993:             gen_op_ltz();
1.1.1.6 ! root     1994:             MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btarget);
1.1       root     1995:             goto not_likely;
                   1996:         case OPC_BLTZL:
                   1997:             gen_op_ltz();
1.1.1.6 ! root     1998:             MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btarget);
1.1       root     1999:             goto likely;
                   2000:         case OPC_BLTZAL:
                   2001:             gen_op_ltz();
                   2002:             blink = 31;
1.1.1.6 ! root     2003:             MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btarget);
1.1       root     2004:         not_likely:
1.1.1.2   root     2005:             ctx->hflags |= MIPS_HFLAG_BC;
1.1.1.6 ! root     2006:             gen_op_set_bcond();
1.1       root     2007:             break;
                   2008:         case OPC_BLTZALL:
                   2009:             gen_op_ltz();
                   2010:             blink = 31;
1.1.1.6 ! root     2011:             MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btarget);
1.1       root     2012:         likely:
1.1.1.2   root     2013:             ctx->hflags |= MIPS_HFLAG_BL;
1.1.1.6 ! root     2014:             gen_op_set_bcond();
        !          2015:             gen_op_save_bcond();
1.1       root     2016:             break;
1.1.1.6 ! root     2017:         default:
        !          2018:             MIPS_INVAL("conditional branch/jump");
        !          2019:             generate_exception(ctx, EXCP_RI);
        !          2020:             return;
1.1       root     2021:         }
                   2022:     }
1.1.1.6 ! root     2023:     MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
1.1       root     2024:                blink, ctx->hflags, btarget);
1.1.1.6 ! root     2025: 
1.1       root     2026:     ctx->btarget = btarget;
                   2027:     if (blink > 0) {
1.1.1.6 ! root     2028:         GEN_LOAD_IMM_TN(T0, ctx->pc + 8);
1.1       root     2029:         gen_op_store_T0_gpr(blink);
                   2030:     }
                   2031: }
                   2032: 
1.1.1.5   root     2033: /* special3 bitfield operations */
                   2034: static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
                   2035:                        int rs, int lsb, int msb)
1.1       root     2036: {
1.1.1.6 ! root     2037:     GEN_LOAD_REG_T1(rs);
1.1.1.5   root     2038:     switch (opc) {
                   2039:     case OPC_EXT:
                   2040:         if (lsb + msb > 31)
                   2041:             goto fail;
                   2042:         gen_op_ext(lsb, msb + 1);
                   2043:         break;
1.1.1.6 ! root     2044: #if defined(TARGET_MIPS64)
1.1.1.5   root     2045:     case OPC_DEXTM:
                   2046:         if (lsb + msb > 63)
                   2047:             goto fail;
1.1.1.6 ! root     2048:         gen_op_dext(lsb, msb + 1 + 32);
1.1.1.5   root     2049:         break;
                   2050:     case OPC_DEXTU:
                   2051:         if (lsb + msb > 63)
                   2052:             goto fail;
1.1.1.6 ! root     2053:         gen_op_dext(lsb + 32, msb + 1);
1.1.1.5   root     2054:         break;
                   2055:     case OPC_DEXT:
1.1.1.6 ! root     2056:         if (lsb + msb > 63)
        !          2057:             goto fail;
        !          2058:         gen_op_dext(lsb, msb + 1);
1.1.1.5   root     2059:         break;
1.1.1.6 ! root     2060: #endif
1.1.1.5   root     2061:     case OPC_INS:
                   2062:         if (lsb > msb)
                   2063:             goto fail;
1.1.1.6 ! root     2064:         GEN_LOAD_REG_T0(rt);
1.1.1.5   root     2065:         gen_op_ins(lsb, msb - lsb + 1);
                   2066:         break;
1.1.1.6 ! root     2067: #if defined(TARGET_MIPS64)
1.1.1.5   root     2068:     case OPC_DINSM:
                   2069:         if (lsb > msb)
                   2070:             goto fail;
1.1.1.6 ! root     2071:         GEN_LOAD_REG_T0(rt);
        !          2072:         gen_op_dins(lsb, msb - lsb + 1 + 32);
1.1.1.5   root     2073:         break;
                   2074:     case OPC_DINSU:
                   2075:         if (lsb > msb)
                   2076:             goto fail;
1.1.1.6 ! root     2077:         GEN_LOAD_REG_T0(rt);
        !          2078:         gen_op_dins(lsb + 32, msb - lsb + 1);
1.1.1.5   root     2079:         break;
                   2080:     case OPC_DINS:
                   2081:         if (lsb > msb)
                   2082:             goto fail;
1.1.1.6 ! root     2083:         GEN_LOAD_REG_T0(rt);
        !          2084:         gen_op_dins(lsb, msb - lsb + 1);
1.1.1.5   root     2085:         break;
1.1.1.6 ! root     2086: #endif
1.1.1.5   root     2087:     default:
                   2088: fail:
                   2089:         MIPS_INVAL("bitops");
                   2090:         generate_exception(ctx, EXCP_RI);
1.1       root     2091:         return;
                   2092:     }
1.1.1.6 ! root     2093:     GEN_STORE_T0_REG(rt);
1.1.1.5   root     2094: }
1.1.1.4   root     2095: 
1.1.1.5   root     2096: /* CP0 (MMU and control) */
1.1.1.6 ! root     2097: static void gen_mfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
1.1.1.5   root     2098: {
                   2099:     const char *rn = "invalid";
                   2100: 
1.1.1.6 ! root     2101:     if (sel != 0)
        !          2102:         check_insn(env, ctx, ISA_MIPS32);
        !          2103: 
1.1.1.5   root     2104:     switch (reg) {
                   2105:     case 0:
                   2106:         switch (sel) {
                   2107:         case 0:
1.1.1.6 ! root     2108:             gen_op_mfc0_index();
1.1.1.5   root     2109:             rn = "Index";
                   2110:             break;
                   2111:         case 1:
1.1.1.6 ! root     2112:             check_insn(env, ctx, ASE_MT);
        !          2113:             gen_op_mfc0_mvpcontrol();
1.1.1.5   root     2114:             rn = "MVPControl";
1.1.1.6 ! root     2115:             break;
1.1.1.5   root     2116:         case 2:
1.1.1.6 ! root     2117:             check_insn(env, ctx, ASE_MT);
        !          2118:             gen_op_mfc0_mvpconf0();
1.1.1.5   root     2119:             rn = "MVPConf0";
1.1.1.6 ! root     2120:             break;
1.1.1.5   root     2121:         case 3:
1.1.1.6 ! root     2122:             check_insn(env, ctx, ASE_MT);
        !          2123:             gen_op_mfc0_mvpconf1();
1.1.1.5   root     2124:             rn = "MVPConf1";
1.1.1.6 ! root     2125:             break;
1.1.1.5   root     2126:         default:
                   2127:             goto die;
1.1       root     2128:         }
                   2129:         break;
1.1.1.5   root     2130:     case 1:
                   2131:         switch (sel) {
                   2132:         case 0:
                   2133:             gen_op_mfc0_random();
                   2134:             rn = "Random";
1.1.1.6 ! root     2135:             break;
1.1.1.5   root     2136:         case 1:
1.1.1.6 ! root     2137:             check_insn(env, ctx, ASE_MT);
        !          2138:             gen_op_mfc0_vpecontrol();
1.1.1.5   root     2139:             rn = "VPEControl";
1.1.1.6 ! root     2140:             break;
1.1.1.5   root     2141:         case 2:
1.1.1.6 ! root     2142:             check_insn(env, ctx, ASE_MT);
        !          2143:             gen_op_mfc0_vpeconf0();
1.1.1.5   root     2144:             rn = "VPEConf0";
1.1.1.6 ! root     2145:             break;
1.1.1.5   root     2146:         case 3:
1.1.1.6 ! root     2147:             check_insn(env, ctx, ASE_MT);
        !          2148:             gen_op_mfc0_vpeconf1();
1.1.1.5   root     2149:             rn = "VPEConf1";
1.1.1.6 ! root     2150:             break;
1.1.1.5   root     2151:         case 4:
1.1.1.6 ! root     2152:             check_insn(env, ctx, ASE_MT);
        !          2153:             gen_op_mfc0_yqmask();
1.1.1.5   root     2154:             rn = "YQMask";
1.1.1.6 ! root     2155:             break;
1.1.1.5   root     2156:         case 5:
1.1.1.6 ! root     2157:             check_insn(env, ctx, ASE_MT);
        !          2158:             gen_op_mfc0_vpeschedule();
1.1.1.5   root     2159:             rn = "VPESchedule";
1.1.1.6 ! root     2160:             break;
1.1.1.5   root     2161:         case 6:
1.1.1.6 ! root     2162:             check_insn(env, ctx, ASE_MT);
        !          2163:             gen_op_mfc0_vpeschefback();
1.1.1.5   root     2164:             rn = "VPEScheFBack";
1.1.1.6 ! root     2165:             break;
1.1.1.5   root     2166:         case 7:
1.1.1.6 ! root     2167:             check_insn(env, ctx, ASE_MT);
        !          2168:             gen_op_mfc0_vpeopt();
1.1.1.5   root     2169:             rn = "VPEOpt";
1.1.1.6 ! root     2170:             break;
1.1.1.5   root     2171:         default:
                   2172:             goto die;
                   2173:         }
1.1       root     2174:         break;
1.1.1.5   root     2175:     case 2:
                   2176:         switch (sel) {
                   2177:         case 0:
1.1.1.6 ! root     2178:             gen_op_mfc0_entrylo0();
        !          2179:             rn = "EntryLo0";
        !          2180:             break;
        !          2181:         case 1:
        !          2182:             check_insn(env, ctx, ASE_MT);
        !          2183:             gen_op_mfc0_tcstatus();
        !          2184:             rn = "TCStatus";
        !          2185:             break;
        !          2186:         case 2:
        !          2187:             check_insn(env, ctx, ASE_MT);
        !          2188:             gen_op_mfc0_tcbind();
        !          2189:             rn = "TCBind";
        !          2190:             break;
1.1.1.5   root     2191:         case 3:
1.1.1.6 ! root     2192:             check_insn(env, ctx, ASE_MT);
        !          2193:             gen_op_mfc0_tcrestart();
        !          2194:             rn = "TCRestart";
        !          2195:             break;
1.1.1.5   root     2196:         case 4:
1.1.1.6 ! root     2197:             check_insn(env, ctx, ASE_MT);
        !          2198:             gen_op_mfc0_tchalt();
        !          2199:             rn = "TCHalt";
        !          2200:             break;
1.1.1.5   root     2201:         case 5:
1.1.1.6 ! root     2202:             check_insn(env, ctx, ASE_MT);
        !          2203:             gen_op_mfc0_tccontext();
        !          2204:             rn = "TCContext";
        !          2205:             break;
1.1.1.5   root     2206:         case 6:
1.1.1.6 ! root     2207:             check_insn(env, ctx, ASE_MT);
        !          2208:             gen_op_mfc0_tcschedule();
        !          2209:             rn = "TCSchedule";
        !          2210:             break;
1.1.1.5   root     2211:         case 7:
1.1.1.6 ! root     2212:             check_insn(env, ctx, ASE_MT);
        !          2213:             gen_op_mfc0_tcschefback();
        !          2214:             rn = "TCScheFBack";
        !          2215:             break;
1.1.1.5   root     2216:         default:
                   2217:             goto die;
                   2218:         }
1.1       root     2219:         break;
1.1.1.5   root     2220:     case 3:
                   2221:         switch (sel) {
                   2222:         case 0:
1.1.1.6 ! root     2223:             gen_op_mfc0_entrylo1();
        !          2224:             rn = "EntryLo1";
        !          2225:             break;
1.1.1.5   root     2226:         default:
                   2227:             goto die;
1.1.1.6 ! root     2228:         }
1.1       root     2229:         break;
1.1.1.5   root     2230:     case 4:
                   2231:         switch (sel) {
                   2232:         case 0:
1.1.1.6 ! root     2233:             gen_op_mfc0_context();
        !          2234:             rn = "Context";
        !          2235:             break;
        !          2236:         case 1:
        !          2237: //            gen_op_mfc0_contextconfig(); /* SmartMIPS ASE */
        !          2238:             rn = "ContextConfig";
        !          2239: //            break;
1.1.1.5   root     2240:         default:
                   2241:             goto die;
1.1.1.6 ! root     2242:         }
1.1       root     2243:         break;
1.1.1.5   root     2244:     case 5:
                   2245:         switch (sel) {
                   2246:         case 0:
1.1.1.6 ! root     2247:             gen_op_mfc0_pagemask();
        !          2248:             rn = "PageMask";
        !          2249:             break;
        !          2250:         case 1:
        !          2251:             check_insn(env, ctx, ISA_MIPS32R2);
        !          2252:             gen_op_mfc0_pagegrain();
        !          2253:             rn = "PageGrain";
        !          2254:             break;
1.1.1.5   root     2255:         default:
                   2256:             goto die;
1.1.1.6 ! root     2257:         }
1.1       root     2258:         break;
1.1.1.5   root     2259:     case 6:
                   2260:         switch (sel) {
                   2261:         case 0:
1.1.1.6 ! root     2262:             gen_op_mfc0_wired();
        !          2263:             rn = "Wired";
        !          2264:             break;
        !          2265:         case 1:
        !          2266:             check_insn(env, ctx, ISA_MIPS32R2);
        !          2267:             gen_op_mfc0_srsconf0();
        !          2268:             rn = "SRSConf0";
        !          2269:             break;
        !          2270:         case 2:
        !          2271:             check_insn(env, ctx, ISA_MIPS32R2);
        !          2272:             gen_op_mfc0_srsconf1();
        !          2273:             rn = "SRSConf1";
        !          2274:             break;
1.1.1.5   root     2275:         case 3:
1.1.1.6 ! root     2276:             check_insn(env, ctx, ISA_MIPS32R2);
        !          2277:             gen_op_mfc0_srsconf2();
        !          2278:             rn = "SRSConf2";
        !          2279:             break;
1.1.1.5   root     2280:         case 4:
1.1.1.6 ! root     2281:             check_insn(env, ctx, ISA_MIPS32R2);
        !          2282:             gen_op_mfc0_srsconf3();
        !          2283:             rn = "SRSConf3";
        !          2284:             break;
1.1.1.5   root     2285:         case 5:
1.1.1.6 ! root     2286:             check_insn(env, ctx, ISA_MIPS32R2);
        !          2287:             gen_op_mfc0_srsconf4();
        !          2288:             rn = "SRSConf4";
        !          2289:             break;
1.1.1.5   root     2290:         default:
                   2291:             goto die;
1.1.1.6 ! root     2292:         }
1.1       root     2293:         break;
1.1.1.5   root     2294:     case 7:
                   2295:         switch (sel) {
                   2296:         case 0:
1.1.1.6 ! root     2297:             check_insn(env, ctx, ISA_MIPS32R2);
        !          2298:             gen_op_mfc0_hwrena();
        !          2299:             rn = "HWREna";
        !          2300:             break;
1.1.1.5   root     2301:         default:
                   2302:             goto die;
1.1.1.6 ! root     2303:         }
1.1       root     2304:         break;
1.1.1.5   root     2305:     case 8:
                   2306:         switch (sel) {
                   2307:         case 0:
1.1.1.6 ! root     2308:             gen_op_mfc0_badvaddr();
        !          2309:             rn = "BadVaddr";
        !          2310:             break;
1.1.1.5   root     2311:         default:
                   2312:             goto die;
                   2313:        }
1.1.1.2   root     2314:         break;
1.1.1.5   root     2315:     case 9:
                   2316:         switch (sel) {
                   2317:         case 0:
1.1.1.6 ! root     2318:             gen_op_mfc0_count();
        !          2319:             rn = "Count";
        !          2320:             break;
        !          2321:         /* 6,7 are implementation dependent */
1.1.1.5   root     2322:         default:
                   2323:             goto die;
1.1.1.6 ! root     2324:         }
1.1.1.5   root     2325:         break;
                   2326:     case 10:
                   2327:         switch (sel) {
                   2328:         case 0:
1.1.1.6 ! root     2329:             gen_op_mfc0_entryhi();
        !          2330:             rn = "EntryHi";
        !          2331:             break;
1.1.1.5   root     2332:         default:
                   2333:             goto die;
1.1.1.6 ! root     2334:         }
1.1.1.5   root     2335:         break;
                   2336:     case 11:
                   2337:         switch (sel) {
                   2338:         case 0:
1.1.1.6 ! root     2339:             gen_op_mfc0_compare();
        !          2340:             rn = "Compare";
        !          2341:             break;
        !          2342:         /* 6,7 are implementation dependent */
1.1.1.5   root     2343:         default:
                   2344:             goto die;
1.1.1.6 ! root     2345:         }
1.1.1.5   root     2346:         break;
                   2347:     case 12:
                   2348:         switch (sel) {
                   2349:         case 0:
1.1.1.6 ! root     2350:             gen_op_mfc0_status();
        !          2351:             rn = "Status";
        !          2352:             break;
        !          2353:         case 1:
        !          2354:             check_insn(env, ctx, ISA_MIPS32R2);
        !          2355:             gen_op_mfc0_intctl();
        !          2356:             rn = "IntCtl";
        !          2357:             break;
        !          2358:         case 2:
        !          2359:             check_insn(env, ctx, ISA_MIPS32R2);
        !          2360:             gen_op_mfc0_srsctl();
        !          2361:             rn = "SRSCtl";
        !          2362:             break;
1.1.1.5   root     2363:         case 3:
1.1.1.6 ! root     2364:             check_insn(env, ctx, ISA_MIPS32R2);
        !          2365:             gen_op_mfc0_srsmap();
        !          2366:             rn = "SRSMap";
        !          2367:             break;
1.1.1.5   root     2368:         default:
                   2369:             goto die;
                   2370:        }
                   2371:         break;
                   2372:     case 13:
                   2373:         switch (sel) {
                   2374:         case 0:
1.1.1.6 ! root     2375:             gen_op_mfc0_cause();
        !          2376:             rn = "Cause";
        !          2377:             break;
1.1.1.5   root     2378:         default:
                   2379:             goto die;
                   2380:        }
                   2381:         break;
                   2382:     case 14:
                   2383:         switch (sel) {
                   2384:         case 0:
1.1.1.6 ! root     2385:             gen_op_mfc0_epc();
        !          2386:             rn = "EPC";
        !          2387:             break;
1.1.1.5   root     2388:         default:
                   2389:             goto die;
1.1.1.6 ! root     2390:         }
1.1.1.5   root     2391:         break;
                   2392:     case 15:
                   2393:         switch (sel) {
                   2394:         case 0:
1.1.1.6 ! root     2395:             gen_op_mfc0_prid();
        !          2396:             rn = "PRid";
        !          2397:             break;
        !          2398:         case 1:
        !          2399:             check_insn(env, ctx, ISA_MIPS32R2);
        !          2400:             gen_op_mfc0_ebase();
        !          2401:             rn = "EBase";
        !          2402:             break;
1.1.1.5   root     2403:         default:
                   2404:             goto die;
                   2405:        }
                   2406:         break;
                   2407:     case 16:
                   2408:         switch (sel) {
                   2409:         case 0:
1.1.1.6 ! root     2410:             gen_op_mfc0_config0();
1.1.1.5   root     2411:             rn = "Config";
                   2412:             break;
                   2413:         case 1:
1.1.1.6 ! root     2414:             gen_op_mfc0_config1();
1.1.1.5   root     2415:             rn = "Config1";
                   2416:             break;
                   2417:         case 2:
1.1.1.6 ! root     2418:             gen_op_mfc0_config2();
1.1.1.5   root     2419:             rn = "Config2";
                   2420:             break;
                   2421:         case 3:
1.1.1.6 ! root     2422:             gen_op_mfc0_config3();
1.1.1.5   root     2423:             rn = "Config3";
                   2424:             break;
1.1.1.6 ! root     2425:         /* 4,5 are reserved */
        !          2426:         /* 6,7 are implementation dependent */
        !          2427:         case 6:
        !          2428:             gen_op_mfc0_config6();
        !          2429:             rn = "Config6";
        !          2430:             break;
        !          2431:         case 7:
        !          2432:             gen_op_mfc0_config7();
        !          2433:             rn = "Config7";
        !          2434:             break;
1.1.1.5   root     2435:         default:
                   2436:             goto die;
1.1       root     2437:         }
1.1.1.4   root     2438:         break;
1.1.1.5   root     2439:     case 17:
                   2440:         switch (sel) {
                   2441:         case 0:
1.1.1.6 ! root     2442:             gen_op_mfc0_lladdr();
        !          2443:             rn = "LLAddr";
        !          2444:             break;
1.1.1.5   root     2445:         default:
                   2446:             goto die;
                   2447:         }
1.1.1.4   root     2448:         break;
1.1.1.5   root     2449:     case 18:
                   2450:         switch (sel) {
1.1.1.6 ! root     2451:         case 0 ... 7:
        !          2452:             gen_op_mfc0_watchlo(sel);
        !          2453:             rn = "WatchLo";
        !          2454:             break;
1.1.1.5   root     2455:         default:
                   2456:             goto die;
                   2457:         }
1.1.1.4   root     2458:         break;
1.1.1.5   root     2459:     case 19:
                   2460:         switch (sel) {
1.1.1.6 ! root     2461:         case 0 ...7:
        !          2462:             gen_op_mfc0_watchhi(sel);
        !          2463:             rn = "WatchHi";
        !          2464:             break;
1.1.1.5   root     2465:         default:
                   2466:             goto die;
                   2467:         }
1.1.1.4   root     2468:         break;
1.1.1.5   root     2469:     case 20:
                   2470:         switch (sel) {
                   2471:         case 0:
1.1.1.6 ! root     2472: #if defined(TARGET_MIPS64)
        !          2473:             check_insn(env, ctx, ISA_MIPS3);
        !          2474:             gen_op_mfc0_xcontext();
        !          2475:             rn = "XContext";
        !          2476:             break;
        !          2477: #endif
1.1.1.5   root     2478:         default:
                   2479:             goto die;
1.1.1.4   root     2480:         }
                   2481:         break;
1.1.1.5   root     2482:     case 21:
                   2483:        /* Officially reserved, but sel 0 is used for R1x000 framemask */
                   2484:         switch (sel) {
                   2485:         case 0:
1.1.1.6 ! root     2486:             gen_op_mfc0_framemask();
        !          2487:             rn = "Framemask";
        !          2488:             break;
1.1.1.5   root     2489:         default:
                   2490:             goto die;
1.1.1.4   root     2491:         }
                   2492:         break;
1.1.1.5   root     2493:     case 22:
1.1.1.6 ! root     2494:         /* ignored */
        !          2495:         rn = "'Diagnostic"; /* implementation dependent */
        !          2496:         break;
1.1.1.5   root     2497:     case 23:
                   2498:         switch (sel) {
                   2499:         case 0:
1.1.1.6 ! root     2500:             gen_op_mfc0_debug(); /* EJTAG support */
        !          2501:             rn = "Debug";
        !          2502:             break;
        !          2503:         case 1:
        !          2504: //            gen_op_mfc0_tracecontrol(); /* PDtrace support */
        !          2505:             rn = "TraceControl";
        !          2506: //            break;
        !          2507:         case 2:
        !          2508: //            gen_op_mfc0_tracecontrol2(); /* PDtrace support */
        !          2509:             rn = "TraceControl2";
        !          2510: //            break;
1.1.1.5   root     2511:         case 3:
1.1.1.6 ! root     2512: //            gen_op_mfc0_usertracedata(); /* PDtrace support */
        !          2513:             rn = "UserTraceData";
        !          2514: //            break;
1.1.1.5   root     2515:         case 4:
1.1.1.6 ! root     2516: //            gen_op_mfc0_debug(); /* PDtrace support */
        !          2517:             rn = "TraceBPC";
        !          2518: //            break;
1.1.1.5   root     2519:         default:
                   2520:             goto die;
1.1.1.4   root     2521:         }
1.1.1.5   root     2522:         break;
                   2523:     case 24:
                   2524:         switch (sel) {
                   2525:         case 0:
1.1.1.6 ! root     2526:             gen_op_mfc0_depc(); /* EJTAG support */
        !          2527:             rn = "DEPC";
        !          2528:             break;
1.1.1.5   root     2529:         default:
                   2530:             goto die;
                   2531:         }
                   2532:         break;
                   2533:     case 25:
                   2534:         switch (sel) {
                   2535:         case 0:
1.1.1.6 ! root     2536:             gen_op_mfc0_performance0();
        !          2537:             rn = "Performance0";
1.1.1.5   root     2538:             break;
                   2539:         case 1:
1.1.1.6 ! root     2540: //            gen_op_mfc0_performance1();
        !          2541:             rn = "Performance1";
        !          2542: //            break;
1.1.1.5   root     2543:         case 2:
1.1.1.6 ! root     2544: //            gen_op_mfc0_performance2();
        !          2545:             rn = "Performance2";
        !          2546: //            break;
1.1.1.5   root     2547:         case 3:
1.1.1.6 ! root     2548: //            gen_op_mfc0_performance3();
        !          2549:             rn = "Performance3";
        !          2550: //            break;
1.1.1.5   root     2551:         case 4:
1.1.1.6 ! root     2552: //            gen_op_mfc0_performance4();
        !          2553:             rn = "Performance4";
        !          2554: //            break;
1.1.1.5   root     2555:         case 5:
1.1.1.6 ! root     2556: //            gen_op_mfc0_performance5();
        !          2557:             rn = "Performance5";
        !          2558: //            break;
1.1.1.5   root     2559:         case 6:
1.1.1.6 ! root     2560: //            gen_op_mfc0_performance6();
        !          2561:             rn = "Performance6";
        !          2562: //            break;
1.1.1.5   root     2563:         case 7:
1.1.1.6 ! root     2564: //            gen_op_mfc0_performance7();
        !          2565:             rn = "Performance7";
        !          2566: //            break;
1.1.1.5   root     2567:         default:
                   2568:             goto die;
                   2569:         }
                   2570:         break;
                   2571:     case 26:
                   2572:        rn = "ECC";
                   2573:        break;
                   2574:     case 27:
                   2575:         switch (sel) {
                   2576:         /* ignored */
                   2577:         case 0 ... 3:
1.1.1.6 ! root     2578:             rn = "CacheErr";
        !          2579:             break;
1.1.1.5   root     2580:         default:
                   2581:             goto die;
                   2582:         }
                   2583:         break;
                   2584:     case 28:
                   2585:         switch (sel) {
                   2586:         case 0:
                   2587:         case 2:
                   2588:         case 4:
                   2589:         case 6:
                   2590:             gen_op_mfc0_taglo();
                   2591:             rn = "TagLo";
                   2592:             break;
                   2593:         case 1:
                   2594:         case 3:
                   2595:         case 5:
                   2596:         case 7:
                   2597:             gen_op_mfc0_datalo();
                   2598:             rn = "DataLo";
                   2599:             break;
                   2600:         default:
                   2601:             goto die;
                   2602:         }
                   2603:         break;
                   2604:     case 29:
                   2605:         switch (sel) {
                   2606:         case 0:
                   2607:         case 2:
                   2608:         case 4:
                   2609:         case 6:
                   2610:             gen_op_mfc0_taghi();
                   2611:             rn = "TagHi";
                   2612:             break;
                   2613:         case 1:
                   2614:         case 3:
                   2615:         case 5:
                   2616:         case 7:
                   2617:             gen_op_mfc0_datahi();
                   2618:             rn = "DataHi";
                   2619:             break;
                   2620:         default:
                   2621:             goto die;
                   2622:         }
                   2623:         break;
                   2624:     case 30:
                   2625:         switch (sel) {
                   2626:         case 0:
1.1.1.6 ! root     2627:             gen_op_mfc0_errorepc();
        !          2628:             rn = "ErrorEPC";
        !          2629:             break;
1.1.1.5   root     2630:         default:
                   2631:             goto die;
                   2632:         }
                   2633:         break;
                   2634:     case 31:
                   2635:         switch (sel) {
                   2636:         case 0:
1.1.1.6 ! root     2637:             gen_op_mfc0_desave(); /* EJTAG support */
        !          2638:             rn = "DESAVE";
        !          2639:             break;
1.1.1.5   root     2640:         default:
                   2641:             goto die;
                   2642:         }
                   2643:         break;
                   2644:     default:
                   2645:        goto die;
                   2646:     }
                   2647: #if defined MIPS_DEBUG_DISAS
                   2648:     if (loglevel & CPU_LOG_TB_IN_ASM) {
                   2649:         fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
                   2650:                 rn, reg, sel);
                   2651:     }
                   2652: #endif
                   2653:     return;
                   2654: 
                   2655: die:
                   2656: #if defined MIPS_DEBUG_DISAS
                   2657:     if (loglevel & CPU_LOG_TB_IN_ASM) {
                   2658:         fprintf(logfile, "mfc0 %s (reg %d sel %d)\n",
                   2659:                 rn, reg, sel);
                   2660:     }
                   2661: #endif
                   2662:     generate_exception(ctx, EXCP_RI);
                   2663: }
                   2664: 
1.1.1.6 ! root     2665: static void gen_mtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
1.1.1.5   root     2666: {
                   2667:     const char *rn = "invalid";
                   2668: 
1.1.1.6 ! root     2669:     if (sel != 0)
        !          2670:         check_insn(env, ctx, ISA_MIPS32);
        !          2671: 
1.1.1.5   root     2672:     switch (reg) {
                   2673:     case 0:
                   2674:         switch (sel) {
                   2675:         case 0:
1.1.1.6 ! root     2676:             gen_op_mtc0_index();
1.1.1.5   root     2677:             rn = "Index";
                   2678:             break;
                   2679:         case 1:
1.1.1.6 ! root     2680:             check_insn(env, ctx, ASE_MT);
        !          2681:             gen_op_mtc0_mvpcontrol();
1.1.1.5   root     2682:             rn = "MVPControl";
1.1.1.6 ! root     2683:             break;
1.1.1.5   root     2684:         case 2:
1.1.1.6 ! root     2685:             check_insn(env, ctx, ASE_MT);
        !          2686:             /* ignored */
1.1.1.5   root     2687:             rn = "MVPConf0";
1.1.1.6 ! root     2688:             break;
1.1.1.5   root     2689:         case 3:
1.1.1.6 ! root     2690:             check_insn(env, ctx, ASE_MT);
        !          2691:             /* ignored */
1.1.1.5   root     2692:             rn = "MVPConf1";
1.1.1.6 ! root     2693:             break;
1.1.1.5   root     2694:         default:
                   2695:             goto die;
                   2696:         }
                   2697:         break;
                   2698:     case 1:
                   2699:         switch (sel) {
                   2700:         case 0:
1.1.1.6 ! root     2701:             /* ignored */
1.1.1.5   root     2702:             rn = "Random";
1.1.1.6 ! root     2703:             break;
1.1.1.5   root     2704:         case 1:
1.1.1.6 ! root     2705:             check_insn(env, ctx, ASE_MT);
        !          2706:             gen_op_mtc0_vpecontrol();
1.1.1.5   root     2707:             rn = "VPEControl";
1.1.1.6 ! root     2708:             break;
1.1.1.5   root     2709:         case 2:
1.1.1.6 ! root     2710:             check_insn(env, ctx, ASE_MT);
        !          2711:             gen_op_mtc0_vpeconf0();
1.1.1.5   root     2712:             rn = "VPEConf0";
1.1.1.6 ! root     2713:             break;
1.1.1.5   root     2714:         case 3:
1.1.1.6 ! root     2715:             check_insn(env, ctx, ASE_MT);
        !          2716:             gen_op_mtc0_vpeconf1();
1.1.1.5   root     2717:             rn = "VPEConf1";
1.1.1.6 ! root     2718:             break;
1.1.1.5   root     2719:         case 4:
1.1.1.6 ! root     2720:             check_insn(env, ctx, ASE_MT);
        !          2721:             gen_op_mtc0_yqmask();
1.1.1.5   root     2722:             rn = "YQMask";
1.1.1.6 ! root     2723:             break;
1.1.1.5   root     2724:         case 5:
1.1.1.6 ! root     2725:             check_insn(env, ctx, ASE_MT);
        !          2726:             gen_op_mtc0_vpeschedule();
1.1.1.5   root     2727:             rn = "VPESchedule";
1.1.1.6 ! root     2728:             break;
1.1.1.5   root     2729:         case 6:
1.1.1.6 ! root     2730:             check_insn(env, ctx, ASE_MT);
        !          2731:             gen_op_mtc0_vpeschefback();
1.1.1.5   root     2732:             rn = "VPEScheFBack";
1.1.1.6 ! root     2733:             break;
1.1.1.5   root     2734:         case 7:
1.1.1.6 ! root     2735:             check_insn(env, ctx, ASE_MT);
        !          2736:             gen_op_mtc0_vpeopt();
1.1.1.5   root     2737:             rn = "VPEOpt";
1.1.1.6 ! root     2738:             break;
1.1.1.5   root     2739:         default:
                   2740:             goto die;
                   2741:         }
                   2742:         break;
                   2743:     case 2:
                   2744:         switch (sel) {
                   2745:         case 0:
1.1.1.6 ! root     2746:             gen_op_mtc0_entrylo0();
        !          2747:             rn = "EntryLo0";
        !          2748:             break;
        !          2749:         case 1:
        !          2750:             check_insn(env, ctx, ASE_MT);
        !          2751:             gen_op_mtc0_tcstatus();
        !          2752:             rn = "TCStatus";
        !          2753:             break;
        !          2754:         case 2:
        !          2755:             check_insn(env, ctx, ASE_MT);
        !          2756:             gen_op_mtc0_tcbind();
        !          2757:             rn = "TCBind";
        !          2758:             break;
1.1.1.5   root     2759:         case 3:
1.1.1.6 ! root     2760:             check_insn(env, ctx, ASE_MT);
        !          2761:             gen_op_mtc0_tcrestart();
        !          2762:             rn = "TCRestart";
        !          2763:             break;
1.1.1.5   root     2764:         case 4:
1.1.1.6 ! root     2765:             check_insn(env, ctx, ASE_MT);
        !          2766:             gen_op_mtc0_tchalt();
        !          2767:             rn = "TCHalt";
        !          2768:             break;
1.1.1.5   root     2769:         case 5:
1.1.1.6 ! root     2770:             check_insn(env, ctx, ASE_MT);
        !          2771:             gen_op_mtc0_tccontext();
        !          2772:             rn = "TCContext";
        !          2773:             break;
1.1.1.5   root     2774:         case 6:
1.1.1.6 ! root     2775:             check_insn(env, ctx, ASE_MT);
        !          2776:             gen_op_mtc0_tcschedule();
        !          2777:             rn = "TCSchedule";
        !          2778:             break;
1.1.1.5   root     2779:         case 7:
1.1.1.6 ! root     2780:             check_insn(env, ctx, ASE_MT);
        !          2781:             gen_op_mtc0_tcschefback();
        !          2782:             rn = "TCScheFBack";
        !          2783:             break;
1.1.1.5   root     2784:         default:
                   2785:             goto die;
                   2786:         }
                   2787:         break;
                   2788:     case 3:
                   2789:         switch (sel) {
                   2790:         case 0:
1.1.1.6 ! root     2791:             gen_op_mtc0_entrylo1();
        !          2792:             rn = "EntryLo1";
        !          2793:             break;
1.1.1.5   root     2794:         default:
                   2795:             goto die;
1.1.1.6 ! root     2796:         }
1.1.1.5   root     2797:         break;
                   2798:     case 4:
                   2799:         switch (sel) {
                   2800:         case 0:
1.1.1.6 ! root     2801:             gen_op_mtc0_context();
        !          2802:             rn = "Context";
        !          2803:             break;
        !          2804:         case 1:
        !          2805: //            gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
        !          2806:             rn = "ContextConfig";
        !          2807: //            break;
1.1.1.5   root     2808:         default:
                   2809:             goto die;
1.1.1.6 ! root     2810:         }
1.1.1.5   root     2811:         break;
                   2812:     case 5:
                   2813:         switch (sel) {
                   2814:         case 0:
1.1.1.6 ! root     2815:             gen_op_mtc0_pagemask();
        !          2816:             rn = "PageMask";
        !          2817:             break;
        !          2818:         case 1:
        !          2819:             check_insn(env, ctx, ISA_MIPS32R2);
        !          2820:             gen_op_mtc0_pagegrain();
        !          2821:             rn = "PageGrain";
        !          2822:             break;
1.1.1.5   root     2823:         default:
                   2824:             goto die;
1.1.1.6 ! root     2825:         }
1.1.1.5   root     2826:         break;
                   2827:     case 6:
                   2828:         switch (sel) {
                   2829:         case 0:
1.1.1.6 ! root     2830:             gen_op_mtc0_wired();
        !          2831:             rn = "Wired";
        !          2832:             break;
        !          2833:         case 1:
        !          2834:             check_insn(env, ctx, ISA_MIPS32R2);
        !          2835:             gen_op_mtc0_srsconf0();
        !          2836:             rn = "SRSConf0";
        !          2837:             break;
        !          2838:         case 2:
        !          2839:             check_insn(env, ctx, ISA_MIPS32R2);
        !          2840:             gen_op_mtc0_srsconf1();
        !          2841:             rn = "SRSConf1";
        !          2842:             break;
1.1.1.5   root     2843:         case 3:
1.1.1.6 ! root     2844:             check_insn(env, ctx, ISA_MIPS32R2);
        !          2845:             gen_op_mtc0_srsconf2();
        !          2846:             rn = "SRSConf2";
        !          2847:             break;
1.1.1.5   root     2848:         case 4:
1.1.1.6 ! root     2849:             check_insn(env, ctx, ISA_MIPS32R2);
        !          2850:             gen_op_mtc0_srsconf3();
        !          2851:             rn = "SRSConf3";
        !          2852:             break;
1.1.1.5   root     2853:         case 5:
1.1.1.6 ! root     2854:             check_insn(env, ctx, ISA_MIPS32R2);
        !          2855:             gen_op_mtc0_srsconf4();
        !          2856:             rn = "SRSConf4";
        !          2857:             break;
1.1.1.5   root     2858:         default:
                   2859:             goto die;
1.1.1.6 ! root     2860:         }
1.1.1.5   root     2861:         break;
                   2862:     case 7:
                   2863:         switch (sel) {
                   2864:         case 0:
1.1.1.6 ! root     2865:             check_insn(env, ctx, ISA_MIPS32R2);
        !          2866:             gen_op_mtc0_hwrena();
        !          2867:             rn = "HWREna";
        !          2868:             break;
1.1.1.5   root     2869:         default:
                   2870:             goto die;
1.1.1.6 ! root     2871:         }
1.1.1.5   root     2872:         break;
                   2873:     case 8:
                   2874:         /* ignored */
                   2875:         rn = "BadVaddr";
                   2876:         break;
                   2877:     case 9:
                   2878:         switch (sel) {
                   2879:         case 0:
1.1.1.6 ! root     2880:             gen_op_mtc0_count();
        !          2881:             rn = "Count";
        !          2882:             break;
        !          2883:         /* 6,7 are implementation dependent */
1.1.1.5   root     2884:         default:
                   2885:             goto die;
1.1.1.6 ! root     2886:         }
        !          2887:         /* Stop translation as we may have switched the execution mode */
        !          2888:         ctx->bstate = BS_STOP;
1.1.1.5   root     2889:         break;
                   2890:     case 10:
                   2891:         switch (sel) {
                   2892:         case 0:
1.1.1.6 ! root     2893:             gen_op_mtc0_entryhi();
        !          2894:             rn = "EntryHi";
        !          2895:             break;
1.1.1.5   root     2896:         default:
                   2897:             goto die;
1.1.1.6 ! root     2898:         }
1.1.1.5   root     2899:         break;
                   2900:     case 11:
                   2901:         switch (sel) {
                   2902:         case 0:
1.1.1.6 ! root     2903:             gen_op_mtc0_compare();
        !          2904:             rn = "Compare";
        !          2905:             break;
        !          2906:         /* 6,7 are implementation dependent */
1.1.1.5   root     2907:         default:
                   2908:             goto die;
1.1.1.6 ! root     2909:         }
        !          2910:         /* Stop translation as we may have switched the execution mode */
        !          2911:         ctx->bstate = BS_STOP;
1.1.1.5   root     2912:         break;
                   2913:     case 12:
                   2914:         switch (sel) {
                   2915:         case 0:
1.1.1.6 ! root     2916:             gen_op_mtc0_status();
        !          2917:             /* BS_STOP isn't good enough here, hflags may have changed. */
        !          2918:             gen_save_pc(ctx->pc + 4);
        !          2919:             ctx->bstate = BS_EXCP;
        !          2920:             rn = "Status";
        !          2921:             break;
        !          2922:         case 1:
        !          2923:             check_insn(env, ctx, ISA_MIPS32R2);
        !          2924:             gen_op_mtc0_intctl();
        !          2925:             /* Stop translation as we may have switched the execution mode */
        !          2926:             ctx->bstate = BS_STOP;
        !          2927:             rn = "IntCtl";
        !          2928:             break;
        !          2929:         case 2:
        !          2930:             check_insn(env, ctx, ISA_MIPS32R2);
        !          2931:             gen_op_mtc0_srsctl();
        !          2932:             /* Stop translation as we may have switched the execution mode */
        !          2933:             ctx->bstate = BS_STOP;
        !          2934:             rn = "SRSCtl";
        !          2935:             break;
1.1.1.5   root     2936:         case 3:
1.1.1.6 ! root     2937:             check_insn(env, ctx, ISA_MIPS32R2);
        !          2938:             gen_op_mtc0_srsmap();
        !          2939:             /* Stop translation as we may have switched the execution mode */
        !          2940:             ctx->bstate = BS_STOP;
        !          2941:             rn = "SRSMap";
        !          2942:             break;
1.1.1.5   root     2943:         default:
                   2944:             goto die;
1.1.1.6 ! root     2945:         }
1.1.1.5   root     2946:         break;
                   2947:     case 13:
                   2948:         switch (sel) {
                   2949:         case 0:
1.1.1.6 ! root     2950:             gen_op_mtc0_cause();
        !          2951:             rn = "Cause";
        !          2952:             break;
1.1.1.5   root     2953:         default:
                   2954:             goto die;
1.1.1.6 ! root     2955:         }
        !          2956:         /* Stop translation as we may have switched the execution mode */
        !          2957:         ctx->bstate = BS_STOP;
1.1.1.5   root     2958:         break;
                   2959:     case 14:
                   2960:         switch (sel) {
                   2961:         case 0:
1.1.1.6 ! root     2962:             gen_op_mtc0_epc();
        !          2963:             rn = "EPC";
        !          2964:             break;
1.1.1.5   root     2965:         default:
                   2966:             goto die;
1.1.1.6 ! root     2967:         }
1.1.1.5   root     2968:         break;
                   2969:     case 15:
                   2970:         switch (sel) {
                   2971:         case 0:
1.1.1.6 ! root     2972:             /* ignored */
        !          2973:             rn = "PRid";
        !          2974:             break;
        !          2975:         case 1:
        !          2976:             check_insn(env, ctx, ISA_MIPS32R2);
        !          2977:             gen_op_mtc0_ebase();
        !          2978:             rn = "EBase";
        !          2979:             break;
1.1.1.5   root     2980:         default:
                   2981:             goto die;
1.1.1.6 ! root     2982:         }
1.1.1.5   root     2983:         break;
                   2984:     case 16:
                   2985:         switch (sel) {
                   2986:         case 0:
1.1.1.6 ! root     2987:             gen_op_mtc0_config0();
1.1.1.5   root     2988:             rn = "Config";
1.1.1.6 ! root     2989:             /* Stop translation as we may have switched the execution mode */
        !          2990:             ctx->bstate = BS_STOP;
1.1.1.5   root     2991:             break;
                   2992:         case 1:
1.1.1.6 ! root     2993:             /* ignored, read only */
1.1.1.5   root     2994:             rn = "Config1";
                   2995:             break;
                   2996:         case 2:
1.1.1.6 ! root     2997:             gen_op_mtc0_config2();
1.1.1.5   root     2998:             rn = "Config2";
1.1.1.6 ! root     2999:             /* Stop translation as we may have switched the execution mode */
        !          3000:             ctx->bstate = BS_STOP;
1.1.1.5   root     3001:             break;
                   3002:         case 3:
1.1.1.6 ! root     3003:             /* ignored, read only */
1.1.1.5   root     3004:             rn = "Config3";
                   3005:             break;
1.1.1.6 ! root     3006:         /* 4,5 are reserved */
        !          3007:         /* 6,7 are implementation dependent */
        !          3008:         case 6:
        !          3009:             /* ignored */
        !          3010:             rn = "Config6";
        !          3011:             break;
        !          3012:         case 7:
        !          3013:             /* ignored */
        !          3014:             rn = "Config7";
        !          3015:             break;
1.1.1.5   root     3016:         default:
                   3017:             rn = "Invalid config selector";
                   3018:             goto die;
                   3019:         }
                   3020:         break;
                   3021:     case 17:
                   3022:         switch (sel) {
                   3023:         case 0:
1.1.1.6 ! root     3024:             /* ignored */
        !          3025:             rn = "LLAddr";
        !          3026:             break;
1.1.1.5   root     3027:         default:
                   3028:             goto die;
                   3029:         }
                   3030:         break;
                   3031:     case 18:
                   3032:         switch (sel) {
1.1.1.6 ! root     3033:         case 0 ... 7:
        !          3034:             gen_op_mtc0_watchlo(sel);
        !          3035:             rn = "WatchLo";
        !          3036:             break;
1.1.1.5   root     3037:         default:
                   3038:             goto die;
                   3039:         }
                   3040:         break;
                   3041:     case 19:
                   3042:         switch (sel) {
1.1.1.6 ! root     3043:         case 0 ... 7:
        !          3044:             gen_op_mtc0_watchhi(sel);
        !          3045:             rn = "WatchHi";
        !          3046:             break;
1.1.1.5   root     3047:         default:
                   3048:             goto die;
                   3049:         }
                   3050:         break;
                   3051:     case 20:
                   3052:         switch (sel) {
                   3053:         case 0:
1.1.1.6 ! root     3054: #if defined(TARGET_MIPS64)
        !          3055:             check_insn(env, ctx, ISA_MIPS3);
        !          3056:             gen_op_mtc0_xcontext();
        !          3057:             rn = "XContext";
        !          3058:             break;
        !          3059: #endif
1.1.1.5   root     3060:         default:
                   3061:             goto die;
                   3062:         }
                   3063:         break;
                   3064:     case 21:
                   3065:        /* Officially reserved, but sel 0 is used for R1x000 framemask */
                   3066:         switch (sel) {
                   3067:         case 0:
1.1.1.6 ! root     3068:             gen_op_mtc0_framemask();
        !          3069:             rn = "Framemask";
        !          3070:             break;
1.1.1.5   root     3071:         default:
                   3072:             goto die;
                   3073:         }
                   3074:         break;
                   3075:     case 22:
                   3076:         /* ignored */
                   3077:         rn = "Diagnostic"; /* implementation dependent */
1.1.1.6 ! root     3078:         break;
1.1.1.5   root     3079:     case 23:
                   3080:         switch (sel) {
                   3081:         case 0:
1.1.1.6 ! root     3082:             gen_op_mtc0_debug(); /* EJTAG support */
        !          3083:             /* BS_STOP isn't good enough here, hflags may have changed. */
        !          3084:             gen_save_pc(ctx->pc + 4);
        !          3085:             ctx->bstate = BS_EXCP;
        !          3086:             rn = "Debug";
        !          3087:             break;
        !          3088:         case 1:
        !          3089: //            gen_op_mtc0_tracecontrol(); /* PDtrace support */
        !          3090:             rn = "TraceControl";
        !          3091:             /* Stop translation as we may have switched the execution mode */
        !          3092:             ctx->bstate = BS_STOP;
        !          3093: //            break;
        !          3094:         case 2:
        !          3095: //            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
        !          3096:             rn = "TraceControl2";
        !          3097:             /* Stop translation as we may have switched the execution mode */
        !          3098:             ctx->bstate = BS_STOP;
        !          3099: //            break;
        !          3100:         case 3:
        !          3101:             /* Stop translation as we may have switched the execution mode */
        !          3102:             ctx->bstate = BS_STOP;
        !          3103: //            gen_op_mtc0_usertracedata(); /* PDtrace support */
        !          3104:             rn = "UserTraceData";
        !          3105:             /* Stop translation as we may have switched the execution mode */
        !          3106:             ctx->bstate = BS_STOP;
        !          3107: //            break;
1.1.1.5   root     3108:         case 4:
1.1.1.6 ! root     3109: //            gen_op_mtc0_debug(); /* PDtrace support */
        !          3110:             /* Stop translation as we may have switched the execution mode */
        !          3111:             ctx->bstate = BS_STOP;
        !          3112:             rn = "TraceBPC";
        !          3113: //            break;
1.1.1.5   root     3114:         default:
                   3115:             goto die;
                   3116:         }
                   3117:         break;
                   3118:     case 24:
                   3119:         switch (sel) {
                   3120:         case 0:
1.1.1.6 ! root     3121:             gen_op_mtc0_depc(); /* EJTAG support */
        !          3122:             rn = "DEPC";
        !          3123:             break;
1.1.1.5   root     3124:         default:
                   3125:             goto die;
                   3126:         }
                   3127:         break;
                   3128:     case 25:
                   3129:         switch (sel) {
                   3130:         case 0:
1.1.1.6 ! root     3131:             gen_op_mtc0_performance0();
        !          3132:             rn = "Performance0";
        !          3133:             break;
        !          3134:         case 1:
        !          3135: //            gen_op_mtc0_performance1();
        !          3136:             rn = "Performance1";
        !          3137: //            break;
        !          3138:         case 2:
        !          3139: //            gen_op_mtc0_performance2();
        !          3140:             rn = "Performance2";
        !          3141: //            break;
        !          3142:         case 3:
        !          3143: //            gen_op_mtc0_performance3();
        !          3144:             rn = "Performance3";
        !          3145: //            break;
1.1.1.5   root     3146:         case 4:
1.1.1.6 ! root     3147: //            gen_op_mtc0_performance4();
        !          3148:             rn = "Performance4";
        !          3149: //            break;
1.1.1.5   root     3150:         case 5:
1.1.1.6 ! root     3151: //            gen_op_mtc0_performance5();
        !          3152:             rn = "Performance5";
        !          3153: //            break;
1.1.1.5   root     3154:         case 6:
1.1.1.6 ! root     3155: //            gen_op_mtc0_performance6();
        !          3156:             rn = "Performance6";
        !          3157: //            break;
1.1.1.5   root     3158:         case 7:
1.1.1.6 ! root     3159: //            gen_op_mtc0_performance7();
        !          3160:             rn = "Performance7";
        !          3161: //            break;
1.1.1.5   root     3162:         default:
                   3163:             goto die;
                   3164:         }
                   3165:        break;
                   3166:     case 26:
1.1.1.6 ! root     3167:         /* ignored */
1.1.1.5   root     3168:         rn = "ECC";
1.1.1.6 ! root     3169:         break;
1.1.1.5   root     3170:     case 27:
                   3171:         switch (sel) {
                   3172:         case 0 ... 3:
1.1.1.6 ! root     3173:             /* ignored */
        !          3174:             rn = "CacheErr";
        !          3175:             break;
1.1.1.5   root     3176:         default:
                   3177:             goto die;
                   3178:         }
                   3179:        break;
                   3180:     case 28:
                   3181:         switch (sel) {
                   3182:         case 0:
                   3183:         case 2:
                   3184:         case 4:
                   3185:         case 6:
                   3186:             gen_op_mtc0_taglo();
                   3187:             rn = "TagLo";
                   3188:             break;
                   3189:         case 1:
                   3190:         case 3:
                   3191:         case 5:
                   3192:         case 7:
1.1.1.6 ! root     3193:             gen_op_mtc0_datalo();
1.1.1.5   root     3194:             rn = "DataLo";
                   3195:             break;
                   3196:         default:
                   3197:             goto die;
                   3198:         }
                   3199:         break;
                   3200:     case 29:
                   3201:         switch (sel) {
                   3202:         case 0:
                   3203:         case 2:
                   3204:         case 4:
                   3205:         case 6:
                   3206:             gen_op_mtc0_taghi();
                   3207:             rn = "TagHi";
                   3208:             break;
                   3209:         case 1:
                   3210:         case 3:
                   3211:         case 5:
                   3212:         case 7:
1.1.1.6 ! root     3213:             gen_op_mtc0_datahi();
1.1.1.5   root     3214:             rn = "DataHi";
                   3215:             break;
                   3216:         default:
                   3217:             rn = "invalid sel";
                   3218:             goto die;
                   3219:         }
                   3220:        break;
                   3221:     case 30:
                   3222:         switch (sel) {
                   3223:         case 0:
1.1.1.6 ! root     3224:             gen_op_mtc0_errorepc();
        !          3225:             rn = "ErrorEPC";
        !          3226:             break;
1.1.1.5   root     3227:         default:
                   3228:             goto die;
                   3229:         }
                   3230:         break;
                   3231:     case 31:
                   3232:         switch (sel) {
                   3233:         case 0:
1.1.1.6 ! root     3234:             gen_op_mtc0_desave(); /* EJTAG support */
        !          3235:             rn = "DESAVE";
        !          3236:             break;
1.1.1.5   root     3237:         default:
                   3238:             goto die;
                   3239:         }
1.1.1.6 ! root     3240:         /* Stop translation as we may have switched the execution mode */
        !          3241:         ctx->bstate = BS_STOP;
1.1.1.5   root     3242:         break;
                   3243:     default:
                   3244:        goto die;
                   3245:     }
                   3246: #if defined MIPS_DEBUG_DISAS
                   3247:     if (loglevel & CPU_LOG_TB_IN_ASM) {
                   3248:         fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
                   3249:                 rn, reg, sel);
                   3250:     }
                   3251: #endif
                   3252:     return;
                   3253: 
                   3254: die:
                   3255: #if defined MIPS_DEBUG_DISAS
                   3256:     if (loglevel & CPU_LOG_TB_IN_ASM) {
                   3257:         fprintf(logfile, "mtc0 %s (reg %d sel %d)\n",
                   3258:                 rn, reg, sel);
                   3259:     }
                   3260: #endif
                   3261:     generate_exception(ctx, EXCP_RI);
                   3262: }
                   3263: 
1.1.1.6 ! root     3264: #if defined(TARGET_MIPS64)
        !          3265: static void gen_dmfc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
1.1.1.5   root     3266: {
                   3267:     const char *rn = "invalid";
                   3268: 
1.1.1.6 ! root     3269:     if (sel != 0)
        !          3270:         check_insn(env, ctx, ISA_MIPS64);
        !          3271: 
1.1.1.5   root     3272:     switch (reg) {
                   3273:     case 0:
                   3274:         switch (sel) {
                   3275:         case 0:
1.1.1.6 ! root     3276:             gen_op_mfc0_index();
1.1.1.5   root     3277:             rn = "Index";
                   3278:             break;
                   3279:         case 1:
1.1.1.6 ! root     3280:             check_insn(env, ctx, ASE_MT);
        !          3281:             gen_op_mfc0_mvpcontrol();
1.1.1.5   root     3282:             rn = "MVPControl";
1.1.1.6 ! root     3283:             break;
1.1.1.5   root     3284:         case 2:
1.1.1.6 ! root     3285:             check_insn(env, ctx, ASE_MT);
        !          3286:             gen_op_mfc0_mvpconf0();
1.1.1.5   root     3287:             rn = "MVPConf0";
1.1.1.6 ! root     3288:             break;
1.1.1.5   root     3289:         case 3:
1.1.1.6 ! root     3290:             check_insn(env, ctx, ASE_MT);
        !          3291:             gen_op_mfc0_mvpconf1();
1.1.1.5   root     3292:             rn = "MVPConf1";
1.1.1.6 ! root     3293:             break;
1.1.1.5   root     3294:         default:
                   3295:             goto die;
                   3296:         }
                   3297:         break;
                   3298:     case 1:
                   3299:         switch (sel) {
                   3300:         case 0:
                   3301:             gen_op_mfc0_random();
                   3302:             rn = "Random";
1.1.1.6 ! root     3303:             break;
1.1.1.5   root     3304:         case 1:
1.1.1.6 ! root     3305:             check_insn(env, ctx, ASE_MT);
        !          3306:             gen_op_mfc0_vpecontrol();
1.1.1.5   root     3307:             rn = "VPEControl";
1.1.1.6 ! root     3308:             break;
1.1.1.5   root     3309:         case 2:
1.1.1.6 ! root     3310:             check_insn(env, ctx, ASE_MT);
        !          3311:             gen_op_mfc0_vpeconf0();
1.1.1.5   root     3312:             rn = "VPEConf0";
1.1.1.6 ! root     3313:             break;
1.1.1.5   root     3314:         case 3:
1.1.1.6 ! root     3315:             check_insn(env, ctx, ASE_MT);
        !          3316:             gen_op_mfc0_vpeconf1();
1.1.1.5   root     3317:             rn = "VPEConf1";
1.1.1.6 ! root     3318:             break;
1.1.1.5   root     3319:         case 4:
1.1.1.6 ! root     3320:             check_insn(env, ctx, ASE_MT);
        !          3321:             gen_op_dmfc0_yqmask();
1.1.1.5   root     3322:             rn = "YQMask";
1.1.1.6 ! root     3323:             break;
1.1.1.5   root     3324:         case 5:
1.1.1.6 ! root     3325:             check_insn(env, ctx, ASE_MT);
        !          3326:             gen_op_dmfc0_vpeschedule();
1.1.1.5   root     3327:             rn = "VPESchedule";
1.1.1.6 ! root     3328:             break;
1.1.1.5   root     3329:         case 6:
1.1.1.6 ! root     3330:             check_insn(env, ctx, ASE_MT);
        !          3331:             gen_op_dmfc0_vpeschefback();
1.1.1.5   root     3332:             rn = "VPEScheFBack";
1.1.1.6 ! root     3333:             break;
1.1.1.5   root     3334:         case 7:
1.1.1.6 ! root     3335:             check_insn(env, ctx, ASE_MT);
        !          3336:             gen_op_mfc0_vpeopt();
1.1.1.5   root     3337:             rn = "VPEOpt";
1.1.1.6 ! root     3338:             break;
1.1.1.5   root     3339:         default:
                   3340:             goto die;
                   3341:         }
                   3342:         break;
                   3343:     case 2:
                   3344:         switch (sel) {
                   3345:         case 0:
1.1.1.6 ! root     3346:             gen_op_dmfc0_entrylo0();
        !          3347:             rn = "EntryLo0";
        !          3348:             break;
        !          3349:         case 1:
        !          3350:             check_insn(env, ctx, ASE_MT);
        !          3351:             gen_op_mfc0_tcstatus();
        !          3352:             rn = "TCStatus";
        !          3353:             break;
        !          3354:         case 2:
        !          3355:             check_insn(env, ctx, ASE_MT);
        !          3356:             gen_op_mfc0_tcbind();
        !          3357:             rn = "TCBind";
        !          3358:             break;
1.1.1.5   root     3359:         case 3:
1.1.1.6 ! root     3360:             check_insn(env, ctx, ASE_MT);
        !          3361:             gen_op_dmfc0_tcrestart();
        !          3362:             rn = "TCRestart";
        !          3363:             break;
1.1.1.5   root     3364:         case 4:
1.1.1.6 ! root     3365:             check_insn(env, ctx, ASE_MT);
        !          3366:             gen_op_dmfc0_tchalt();
        !          3367:             rn = "TCHalt";
        !          3368:             break;
1.1.1.5   root     3369:         case 5:
1.1.1.6 ! root     3370:             check_insn(env, ctx, ASE_MT);
        !          3371:             gen_op_dmfc0_tccontext();
        !          3372:             rn = "TCContext";
        !          3373:             break;
1.1.1.5   root     3374:         case 6:
1.1.1.6 ! root     3375:             check_insn(env, ctx, ASE_MT);
        !          3376:             gen_op_dmfc0_tcschedule();
        !          3377:             rn = "TCSchedule";
        !          3378:             break;
1.1.1.5   root     3379:         case 7:
1.1.1.6 ! root     3380:             check_insn(env, ctx, ASE_MT);
        !          3381:             gen_op_dmfc0_tcschefback();
        !          3382:             rn = "TCScheFBack";
        !          3383:             break;
1.1.1.5   root     3384:         default:
                   3385:             goto die;
                   3386:         }
                   3387:         break;
                   3388:     case 3:
                   3389:         switch (sel) {
                   3390:         case 0:
1.1.1.6 ! root     3391:             gen_op_dmfc0_entrylo1();
        !          3392:             rn = "EntryLo1";
        !          3393:             break;
1.1.1.5   root     3394:         default:
                   3395:             goto die;
1.1.1.6 ! root     3396:         }
1.1.1.5   root     3397:         break;
                   3398:     case 4:
                   3399:         switch (sel) {
                   3400:         case 0:
1.1.1.6 ! root     3401:             gen_op_dmfc0_context();
        !          3402:             rn = "Context";
        !          3403:             break;
        !          3404:         case 1:
        !          3405: //            gen_op_dmfc0_contextconfig(); /* SmartMIPS ASE */
        !          3406:             rn = "ContextConfig";
        !          3407: //            break;
1.1.1.5   root     3408:         default:
                   3409:             goto die;
1.1.1.6 ! root     3410:         }
1.1.1.5   root     3411:         break;
                   3412:     case 5:
                   3413:         switch (sel) {
                   3414:         case 0:
1.1.1.6 ! root     3415:             gen_op_mfc0_pagemask();
        !          3416:             rn = "PageMask";
        !          3417:             break;
        !          3418:         case 1:
        !          3419:             check_insn(env, ctx, ISA_MIPS32R2);
        !          3420:             gen_op_mfc0_pagegrain();
        !          3421:             rn = "PageGrain";
        !          3422:             break;
1.1.1.5   root     3423:         default:
                   3424:             goto die;
1.1.1.6 ! root     3425:         }
1.1.1.5   root     3426:         break;
                   3427:     case 6:
                   3428:         switch (sel) {
                   3429:         case 0:
1.1.1.6 ! root     3430:             gen_op_mfc0_wired();
        !          3431:             rn = "Wired";
        !          3432:             break;
        !          3433:         case 1:
        !          3434:             check_insn(env, ctx, ISA_MIPS32R2);
        !          3435:             gen_op_mfc0_srsconf0();
        !          3436:             rn = "SRSConf0";
        !          3437:             break;
        !          3438:         case 2:
        !          3439:             check_insn(env, ctx, ISA_MIPS32R2);
        !          3440:             gen_op_mfc0_srsconf1();
        !          3441:             rn = "SRSConf1";
        !          3442:             break;
1.1.1.5   root     3443:         case 3:
1.1.1.6 ! root     3444:             check_insn(env, ctx, ISA_MIPS32R2);
        !          3445:             gen_op_mfc0_srsconf2();
        !          3446:             rn = "SRSConf2";
        !          3447:             break;
1.1.1.5   root     3448:         case 4:
1.1.1.6 ! root     3449:             check_insn(env, ctx, ISA_MIPS32R2);
        !          3450:             gen_op_mfc0_srsconf3();
        !          3451:             rn = "SRSConf3";
        !          3452:             break;
1.1.1.5   root     3453:         case 5:
1.1.1.6 ! root     3454:             check_insn(env, ctx, ISA_MIPS32R2);
        !          3455:             gen_op_mfc0_srsconf4();
        !          3456:             rn = "SRSConf4";
        !          3457:             break;
1.1.1.5   root     3458:         default:
                   3459:             goto die;
1.1.1.6 ! root     3460:         }
1.1.1.5   root     3461:         break;
                   3462:     case 7:
                   3463:         switch (sel) {
                   3464:         case 0:
1.1.1.6 ! root     3465:             check_insn(env, ctx, ISA_MIPS32R2);
        !          3466:             gen_op_mfc0_hwrena();
        !          3467:             rn = "HWREna";
        !          3468:             break;
1.1.1.5   root     3469:         default:
                   3470:             goto die;
1.1.1.6 ! root     3471:         }
1.1.1.5   root     3472:         break;
                   3473:     case 8:
                   3474:         switch (sel) {
                   3475:         case 0:
1.1.1.6 ! root     3476:             gen_op_dmfc0_badvaddr();
        !          3477:             rn = "BadVaddr";
        !          3478:             break;
1.1.1.5   root     3479:         default:
                   3480:             goto die;
1.1.1.6 ! root     3481:         }
1.1.1.5   root     3482:         break;
                   3483:     case 9:
                   3484:         switch (sel) {
                   3485:         case 0:
1.1.1.6 ! root     3486:             gen_op_mfc0_count();
        !          3487:             rn = "Count";
        !          3488:             break;
        !          3489:         /* 6,7 are implementation dependent */
1.1.1.5   root     3490:         default:
                   3491:             goto die;
1.1.1.6 ! root     3492:         }
1.1.1.5   root     3493:         break;
                   3494:     case 10:
                   3495:         switch (sel) {
                   3496:         case 0:
1.1.1.6 ! root     3497:             gen_op_dmfc0_entryhi();
        !          3498:             rn = "EntryHi";
        !          3499:             break;
1.1.1.5   root     3500:         default:
                   3501:             goto die;
1.1.1.6 ! root     3502:         }
1.1.1.5   root     3503:         break;
                   3504:     case 11:
                   3505:         switch (sel) {
                   3506:         case 0:
1.1.1.6 ! root     3507:             gen_op_mfc0_compare();
        !          3508:             rn = "Compare";
        !          3509:             break;
        !          3510:         /* 6,7 are implementation dependent */
1.1.1.5   root     3511:         default:
                   3512:             goto die;
1.1.1.6 ! root     3513:         }
1.1.1.5   root     3514:         break;
                   3515:     case 12:
                   3516:         switch (sel) {
                   3517:         case 0:
1.1.1.6 ! root     3518:             gen_op_mfc0_status();
        !          3519:             rn = "Status";
        !          3520:             break;
        !          3521:         case 1:
        !          3522:             check_insn(env, ctx, ISA_MIPS32R2);
        !          3523:             gen_op_mfc0_intctl();
        !          3524:             rn = "IntCtl";
        !          3525:             break;
        !          3526:         case 2:
        !          3527:             check_insn(env, ctx, ISA_MIPS32R2);
        !          3528:             gen_op_mfc0_srsctl();
        !          3529:             rn = "SRSCtl";
        !          3530:             break;
1.1.1.5   root     3531:         case 3:
1.1.1.6 ! root     3532:             check_insn(env, ctx, ISA_MIPS32R2);
        !          3533:             gen_op_mfc0_srsmap();
        !          3534:             rn = "SRSMap";
        !          3535:             break;
1.1.1.5   root     3536:         default:
                   3537:             goto die;
1.1.1.6 ! root     3538:         }
1.1.1.5   root     3539:         break;
                   3540:     case 13:
                   3541:         switch (sel) {
                   3542:         case 0:
1.1.1.6 ! root     3543:             gen_op_mfc0_cause();
        !          3544:             rn = "Cause";
        !          3545:             break;
1.1.1.5   root     3546:         default:
                   3547:             goto die;
1.1.1.6 ! root     3548:         }
1.1.1.5   root     3549:         break;
                   3550:     case 14:
                   3551:         switch (sel) {
                   3552:         case 0:
1.1.1.6 ! root     3553:             gen_op_dmfc0_epc();
        !          3554:             rn = "EPC";
        !          3555:             break;
1.1.1.5   root     3556:         default:
                   3557:             goto die;
1.1.1.6 ! root     3558:         }
1.1.1.5   root     3559:         break;
                   3560:     case 15:
                   3561:         switch (sel) {
                   3562:         case 0:
1.1.1.6 ! root     3563:             gen_op_mfc0_prid();
        !          3564:             rn = "PRid";
        !          3565:             break;
        !          3566:         case 1:
        !          3567:             check_insn(env, ctx, ISA_MIPS32R2);
        !          3568:             gen_op_mfc0_ebase();
        !          3569:             rn = "EBase";
        !          3570:             break;
1.1.1.5   root     3571:         default:
                   3572:             goto die;
1.1.1.6 ! root     3573:         }
1.1.1.5   root     3574:         break;
                   3575:     case 16:
                   3576:         switch (sel) {
                   3577:         case 0:
1.1.1.6 ! root     3578:             gen_op_mfc0_config0();
1.1.1.5   root     3579:             rn = "Config";
                   3580:             break;
                   3581:         case 1:
1.1.1.6 ! root     3582:             gen_op_mfc0_config1();
1.1.1.5   root     3583:             rn = "Config1";
                   3584:             break;
                   3585:         case 2:
1.1.1.6 ! root     3586:             gen_op_mfc0_config2();
1.1.1.5   root     3587:             rn = "Config2";
                   3588:             break;
                   3589:         case 3:
1.1.1.6 ! root     3590:             gen_op_mfc0_config3();
1.1.1.5   root     3591:             rn = "Config3";
                   3592:             break;
                   3593:        /* 6,7 are implementation dependent */
                   3594:         default:
                   3595:             goto die;
                   3596:         }
                   3597:         break;
                   3598:     case 17:
                   3599:         switch (sel) {
                   3600:         case 0:
1.1.1.6 ! root     3601:             gen_op_dmfc0_lladdr();
        !          3602:             rn = "LLAddr";
        !          3603:             break;
1.1.1.5   root     3604:         default:
                   3605:             goto die;
                   3606:         }
                   3607:         break;
                   3608:     case 18:
                   3609:         switch (sel) {
1.1.1.6 ! root     3610:         case 0 ... 7:
        !          3611:             gen_op_dmfc0_watchlo(sel);
        !          3612:             rn = "WatchLo";
        !          3613:             break;
1.1.1.5   root     3614:         default:
                   3615:             goto die;
                   3616:         }
                   3617:         break;
                   3618:     case 19:
                   3619:         switch (sel) {
1.1.1.6 ! root     3620:         case 0 ... 7:
        !          3621:             gen_op_mfc0_watchhi(sel);
        !          3622:             rn = "WatchHi";
        !          3623:             break;
1.1.1.5   root     3624:         default:
                   3625:             goto die;
                   3626:         }
                   3627:         break;
                   3628:     case 20:
                   3629:         switch (sel) {
                   3630:         case 0:
1.1.1.6 ! root     3631:             check_insn(env, ctx, ISA_MIPS3);
        !          3632:             gen_op_dmfc0_xcontext();
        !          3633:             rn = "XContext";
        !          3634:             break;
1.1.1.5   root     3635:         default:
                   3636:             goto die;
                   3637:         }
                   3638:         break;
                   3639:     case 21:
                   3640:        /* Officially reserved, but sel 0 is used for R1x000 framemask */
                   3641:         switch (sel) {
                   3642:         case 0:
1.1.1.6 ! root     3643:             gen_op_mfc0_framemask();
        !          3644:             rn = "Framemask";
        !          3645:             break;
1.1.1.5   root     3646:         default:
                   3647:             goto die;
                   3648:         }
                   3649:         break;
                   3650:     case 22:
1.1.1.6 ! root     3651:         /* ignored */
        !          3652:         rn = "'Diagnostic"; /* implementation dependent */
        !          3653:         break;
1.1.1.5   root     3654:     case 23:
                   3655:         switch (sel) {
                   3656:         case 0:
1.1.1.6 ! root     3657:             gen_op_mfc0_debug(); /* EJTAG support */
        !          3658:             rn = "Debug";
        !          3659:             break;
        !          3660:         case 1:
        !          3661: //            gen_op_dmfc0_tracecontrol(); /* PDtrace support */
        !          3662:             rn = "TraceControl";
        !          3663: //            break;
        !          3664:         case 2:
        !          3665: //            gen_op_dmfc0_tracecontrol2(); /* PDtrace support */
        !          3666:             rn = "TraceControl2";
        !          3667: //            break;
1.1.1.5   root     3668:         case 3:
1.1.1.6 ! root     3669: //            gen_op_dmfc0_usertracedata(); /* PDtrace support */
        !          3670:             rn = "UserTraceData";
        !          3671: //            break;
1.1.1.5   root     3672:         case 4:
1.1.1.6 ! root     3673: //            gen_op_dmfc0_debug(); /* PDtrace support */
        !          3674:             rn = "TraceBPC";
        !          3675: //            break;
1.1.1.5   root     3676:         default:
                   3677:             goto die;
                   3678:         }
                   3679:         break;
                   3680:     case 24:
                   3681:         switch (sel) {
                   3682:         case 0:
1.1.1.6 ! root     3683:             gen_op_dmfc0_depc(); /* EJTAG support */
        !          3684:             rn = "DEPC";
        !          3685:             break;
1.1.1.5   root     3686:         default:
                   3687:             goto die;
                   3688:         }
                   3689:         break;
                   3690:     case 25:
                   3691:         switch (sel) {
                   3692:         case 0:
1.1.1.6 ! root     3693:             gen_op_mfc0_performance0();
        !          3694:             rn = "Performance0";
1.1.1.5   root     3695:             break;
                   3696:         case 1:
1.1.1.6 ! root     3697: //            gen_op_dmfc0_performance1();
        !          3698:             rn = "Performance1";
        !          3699: //            break;
1.1.1.5   root     3700:         case 2:
1.1.1.6 ! root     3701: //            gen_op_dmfc0_performance2();
        !          3702:             rn = "Performance2";
        !          3703: //            break;
1.1.1.5   root     3704:         case 3:
1.1.1.6 ! root     3705: //            gen_op_dmfc0_performance3();
        !          3706:             rn = "Performance3";
        !          3707: //            break;
1.1.1.5   root     3708:         case 4:
1.1.1.6 ! root     3709: //            gen_op_dmfc0_performance4();
        !          3710:             rn = "Performance4";
        !          3711: //            break;
1.1.1.5   root     3712:         case 5:
1.1.1.6 ! root     3713: //            gen_op_dmfc0_performance5();
        !          3714:             rn = "Performance5";
        !          3715: //            break;
1.1.1.5   root     3716:         case 6:
1.1.1.6 ! root     3717: //            gen_op_dmfc0_performance6();
        !          3718:             rn = "Performance6";
        !          3719: //            break;
1.1.1.5   root     3720:         case 7:
1.1.1.6 ! root     3721: //            gen_op_dmfc0_performance7();
        !          3722:             rn = "Performance7";
        !          3723: //            break;
1.1.1.5   root     3724:         default:
                   3725:             goto die;
                   3726:         }
                   3727:         break;
                   3728:     case 26:
                   3729:        rn = "ECC";
                   3730:        break;
                   3731:     case 27:
                   3732:         switch (sel) {
                   3733:         /* ignored */
                   3734:         case 0 ... 3:
1.1.1.6 ! root     3735:             rn = "CacheErr";
        !          3736:             break;
1.1.1.5   root     3737:         default:
                   3738:             goto die;
                   3739:         }
                   3740:         break;
                   3741:     case 28:
                   3742:         switch (sel) {
                   3743:         case 0:
                   3744:         case 2:
                   3745:         case 4:
                   3746:         case 6:
                   3747:             gen_op_mfc0_taglo();
                   3748:             rn = "TagLo";
                   3749:             break;
                   3750:         case 1:
                   3751:         case 3:
                   3752:         case 5:
                   3753:         case 7:
                   3754:             gen_op_mfc0_datalo();
                   3755:             rn = "DataLo";
                   3756:             break;
                   3757:         default:
                   3758:             goto die;
                   3759:         }
                   3760:         break;
                   3761:     case 29:
                   3762:         switch (sel) {
                   3763:         case 0:
                   3764:         case 2:
                   3765:         case 4:
                   3766:         case 6:
                   3767:             gen_op_mfc0_taghi();
                   3768:             rn = "TagHi";
                   3769:             break;
                   3770:         case 1:
                   3771:         case 3:
                   3772:         case 5:
                   3773:         case 7:
                   3774:             gen_op_mfc0_datahi();
                   3775:             rn = "DataHi";
                   3776:             break;
                   3777:         default:
                   3778:             goto die;
                   3779:         }
                   3780:         break;
                   3781:     case 30:
                   3782:         switch (sel) {
                   3783:         case 0:
1.1.1.6 ! root     3784:             gen_op_dmfc0_errorepc();
        !          3785:             rn = "ErrorEPC";
        !          3786:             break;
1.1.1.5   root     3787:         default:
                   3788:             goto die;
                   3789:         }
                   3790:         break;
                   3791:     case 31:
                   3792:         switch (sel) {
                   3793:         case 0:
1.1.1.6 ! root     3794:             gen_op_mfc0_desave(); /* EJTAG support */
        !          3795:             rn = "DESAVE";
        !          3796:             break;
1.1.1.5   root     3797:         default:
                   3798:             goto die;
                   3799:         }
                   3800:         break;
                   3801:     default:
1.1.1.6 ! root     3802:         goto die;
1.1.1.5   root     3803:     }
                   3804: #if defined MIPS_DEBUG_DISAS
                   3805:     if (loglevel & CPU_LOG_TB_IN_ASM) {
                   3806:         fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
                   3807:                 rn, reg, sel);
                   3808:     }
                   3809: #endif
                   3810:     return;
                   3811: 
                   3812: die:
                   3813: #if defined MIPS_DEBUG_DISAS
                   3814:     if (loglevel & CPU_LOG_TB_IN_ASM) {
                   3815:         fprintf(logfile, "dmfc0 %s (reg %d sel %d)\n",
                   3816:                 rn, reg, sel);
                   3817:     }
                   3818: #endif
                   3819:     generate_exception(ctx, EXCP_RI);
                   3820: }
                   3821: 
1.1.1.6 ! root     3822: static void gen_dmtc0 (CPUState *env, DisasContext *ctx, int reg, int sel)
1.1.1.5   root     3823: {
                   3824:     const char *rn = "invalid";
                   3825: 
1.1.1.6 ! root     3826:     if (sel != 0)
        !          3827:         check_insn(env, ctx, ISA_MIPS64);
        !          3828: 
1.1.1.5   root     3829:     switch (reg) {
                   3830:     case 0:
                   3831:         switch (sel) {
                   3832:         case 0:
                   3833:             gen_op_mtc0_index();
                   3834:             rn = "Index";
                   3835:             break;
                   3836:         case 1:
1.1.1.6 ! root     3837:             check_insn(env, ctx, ASE_MT);
        !          3838:             gen_op_mtc0_mvpcontrol();
1.1.1.5   root     3839:             rn = "MVPControl";
1.1.1.6 ! root     3840:             break;
1.1.1.5   root     3841:         case 2:
1.1.1.6 ! root     3842:             check_insn(env, ctx, ASE_MT);
        !          3843:             /* ignored */
1.1.1.5   root     3844:             rn = "MVPConf0";
1.1.1.6 ! root     3845:             break;
1.1.1.5   root     3846:         case 3:
1.1.1.6 ! root     3847:             check_insn(env, ctx, ASE_MT);
        !          3848:             /* ignored */
1.1.1.5   root     3849:             rn = "MVPConf1";
1.1.1.6 ! root     3850:             break;
1.1.1.5   root     3851:         default:
                   3852:             goto die;
                   3853:         }
                   3854:         break;
                   3855:     case 1:
                   3856:         switch (sel) {
                   3857:         case 0:
1.1.1.6 ! root     3858:             /* ignored */
1.1.1.5   root     3859:             rn = "Random";
1.1.1.6 ! root     3860:             break;
1.1.1.5   root     3861:         case 1:
1.1.1.6 ! root     3862:             check_insn(env, ctx, ASE_MT);
        !          3863:             gen_op_mtc0_vpecontrol();
1.1.1.5   root     3864:             rn = "VPEControl";
1.1.1.6 ! root     3865:             break;
1.1.1.5   root     3866:         case 2:
1.1.1.6 ! root     3867:             check_insn(env, ctx, ASE_MT);
        !          3868:             gen_op_mtc0_vpeconf0();
1.1.1.5   root     3869:             rn = "VPEConf0";
1.1.1.6 ! root     3870:             break;
1.1.1.5   root     3871:         case 3:
1.1.1.6 ! root     3872:             check_insn(env, ctx, ASE_MT);
        !          3873:             gen_op_mtc0_vpeconf1();
1.1.1.5   root     3874:             rn = "VPEConf1";
1.1.1.6 ! root     3875:             break;
1.1.1.5   root     3876:         case 4:
1.1.1.6 ! root     3877:             check_insn(env, ctx, ASE_MT);
        !          3878:             gen_op_mtc0_yqmask();
1.1.1.5   root     3879:             rn = "YQMask";
1.1.1.6 ! root     3880:             break;
1.1.1.5   root     3881:         case 5:
1.1.1.6 ! root     3882:             check_insn(env, ctx, ASE_MT);
        !          3883:             gen_op_mtc0_vpeschedule();
1.1.1.5   root     3884:             rn = "VPESchedule";
1.1.1.6 ! root     3885:             break;
1.1.1.5   root     3886:         case 6:
1.1.1.6 ! root     3887:             check_insn(env, ctx, ASE_MT);
        !          3888:             gen_op_mtc0_vpeschefback();
1.1.1.5   root     3889:             rn = "VPEScheFBack";
1.1.1.6 ! root     3890:             break;
1.1.1.5   root     3891:         case 7:
1.1.1.6 ! root     3892:             check_insn(env, ctx, ASE_MT);
        !          3893:             gen_op_mtc0_vpeopt();
1.1.1.5   root     3894:             rn = "VPEOpt";
1.1.1.6 ! root     3895:             break;
1.1.1.5   root     3896:         default:
                   3897:             goto die;
                   3898:         }
                   3899:         break;
                   3900:     case 2:
                   3901:         switch (sel) {
                   3902:         case 0:
1.1.1.6 ! root     3903:             gen_op_mtc0_entrylo0();
        !          3904:             rn = "EntryLo0";
        !          3905:             break;
        !          3906:         case 1:
        !          3907:             check_insn(env, ctx, ASE_MT);
        !          3908:             gen_op_mtc0_tcstatus();
        !          3909:             rn = "TCStatus";
        !          3910:             break;
        !          3911:         case 2:
        !          3912:             check_insn(env, ctx, ASE_MT);
        !          3913:             gen_op_mtc0_tcbind();
        !          3914:             rn = "TCBind";
        !          3915:             break;
1.1.1.5   root     3916:         case 3:
1.1.1.6 ! root     3917:             check_insn(env, ctx, ASE_MT);
        !          3918:             gen_op_mtc0_tcrestart();
        !          3919:             rn = "TCRestart";
        !          3920:             break;
1.1.1.5   root     3921:         case 4:
1.1.1.6 ! root     3922:             check_insn(env, ctx, ASE_MT);
        !          3923:             gen_op_mtc0_tchalt();
        !          3924:             rn = "TCHalt";
        !          3925:             break;
1.1.1.5   root     3926:         case 5:
1.1.1.6 ! root     3927:             check_insn(env, ctx, ASE_MT);
        !          3928:             gen_op_mtc0_tccontext();
        !          3929:             rn = "TCContext";
        !          3930:             break;
1.1.1.5   root     3931:         case 6:
1.1.1.6 ! root     3932:             check_insn(env, ctx, ASE_MT);
        !          3933:             gen_op_mtc0_tcschedule();
        !          3934:             rn = "TCSchedule";
        !          3935:             break;
1.1.1.5   root     3936:         case 7:
1.1.1.6 ! root     3937:             check_insn(env, ctx, ASE_MT);
        !          3938:             gen_op_mtc0_tcschefback();
        !          3939:             rn = "TCScheFBack";
        !          3940:             break;
1.1.1.5   root     3941:         default:
                   3942:             goto die;
                   3943:         }
                   3944:         break;
                   3945:     case 3:
                   3946:         switch (sel) {
                   3947:         case 0:
1.1.1.6 ! root     3948:             gen_op_mtc0_entrylo1();
        !          3949:             rn = "EntryLo1";
        !          3950:             break;
1.1.1.5   root     3951:         default:
                   3952:             goto die;
1.1.1.6 ! root     3953:         }
1.1.1.5   root     3954:         break;
                   3955:     case 4:
                   3956:         switch (sel) {
                   3957:         case 0:
1.1.1.6 ! root     3958:             gen_op_mtc0_context();
        !          3959:             rn = "Context";
        !          3960:             break;
        !          3961:         case 1:
        !          3962: //           gen_op_mtc0_contextconfig(); /* SmartMIPS ASE */
        !          3963:             rn = "ContextConfig";
        !          3964: //           break;
1.1.1.5   root     3965:         default:
                   3966:             goto die;
1.1.1.6 ! root     3967:         }
1.1.1.5   root     3968:         break;
                   3969:     case 5:
                   3970:         switch (sel) {
                   3971:         case 0:
1.1.1.6 ! root     3972:             gen_op_mtc0_pagemask();
        !          3973:             rn = "PageMask";
        !          3974:             break;
        !          3975:         case 1:
        !          3976:             check_insn(env, ctx, ISA_MIPS32R2);
        !          3977:             gen_op_mtc0_pagegrain();
        !          3978:             rn = "PageGrain";
        !          3979:             break;
1.1.1.5   root     3980:         default:
                   3981:             goto die;
1.1.1.6 ! root     3982:         }
1.1.1.5   root     3983:         break;
                   3984:     case 6:
                   3985:         switch (sel) {
                   3986:         case 0:
1.1.1.6 ! root     3987:             gen_op_mtc0_wired();
        !          3988:             rn = "Wired";
        !          3989:             break;
        !          3990:         case 1:
        !          3991:             check_insn(env, ctx, ISA_MIPS32R2);
        !          3992:             gen_op_mtc0_srsconf0();
        !          3993:             rn = "SRSConf0";
        !          3994:             break;
        !          3995:         case 2:
        !          3996:             check_insn(env, ctx, ISA_MIPS32R2);
        !          3997:             gen_op_mtc0_srsconf1();
        !          3998:             rn = "SRSConf1";
        !          3999:             break;
1.1.1.5   root     4000:         case 3:
1.1.1.6 ! root     4001:             check_insn(env, ctx, ISA_MIPS32R2);
        !          4002:             gen_op_mtc0_srsconf2();
        !          4003:             rn = "SRSConf2";
        !          4004:             break;
1.1.1.5   root     4005:         case 4:
1.1.1.6 ! root     4006:             check_insn(env, ctx, ISA_MIPS32R2);
        !          4007:             gen_op_mtc0_srsconf3();
        !          4008:             rn = "SRSConf3";
        !          4009:             break;
1.1.1.5   root     4010:         case 5:
1.1.1.6 ! root     4011:             check_insn(env, ctx, ISA_MIPS32R2);
        !          4012:             gen_op_mtc0_srsconf4();
        !          4013:             rn = "SRSConf4";
        !          4014:             break;
1.1.1.5   root     4015:         default:
                   4016:             goto die;
1.1.1.6 ! root     4017:         }
1.1.1.5   root     4018:         break;
                   4019:     case 7:
                   4020:         switch (sel) {
                   4021:         case 0:
1.1.1.6 ! root     4022:             check_insn(env, ctx, ISA_MIPS32R2);
        !          4023:             gen_op_mtc0_hwrena();
        !          4024:             rn = "HWREna";
        !          4025:             break;
1.1.1.5   root     4026:         default:
                   4027:             goto die;
1.1.1.6 ! root     4028:         }
1.1.1.5   root     4029:         break;
                   4030:     case 8:
                   4031:         /* ignored */
                   4032:         rn = "BadVaddr";
                   4033:         break;
                   4034:     case 9:
                   4035:         switch (sel) {
                   4036:         case 0:
1.1.1.6 ! root     4037:             gen_op_mtc0_count();
        !          4038:             rn = "Count";
        !          4039:             break;
        !          4040:         /* 6,7 are implementation dependent */
1.1.1.5   root     4041:         default:
                   4042:             goto die;
1.1.1.6 ! root     4043:         }
        !          4044:         /* Stop translation as we may have switched the execution mode */
        !          4045:         ctx->bstate = BS_STOP;
1.1.1.5   root     4046:         break;
                   4047:     case 10:
                   4048:         switch (sel) {
                   4049:         case 0:
1.1.1.6 ! root     4050:             gen_op_mtc0_entryhi();
        !          4051:             rn = "EntryHi";
        !          4052:             break;
1.1.1.5   root     4053:         default:
                   4054:             goto die;
1.1.1.6 ! root     4055:         }
1.1.1.5   root     4056:         break;
                   4057:     case 11:
                   4058:         switch (sel) {
                   4059:         case 0:
1.1.1.6 ! root     4060:             gen_op_mtc0_compare();
        !          4061:             rn = "Compare";
        !          4062:             break;
        !          4063:         /* 6,7 are implementation dependent */
1.1.1.5   root     4064:         default:
                   4065:             goto die;
1.1.1.6 ! root     4066:         }
        !          4067:         /* Stop translation as we may have switched the execution mode */
        !          4068:         ctx->bstate = BS_STOP;
1.1.1.5   root     4069:         break;
                   4070:     case 12:
                   4071:         switch (sel) {
                   4072:         case 0:
1.1.1.6 ! root     4073:             gen_op_mtc0_status();
        !          4074:             /* BS_STOP isn't good enough here, hflags may have changed. */
        !          4075:             gen_save_pc(ctx->pc + 4);
        !          4076:             ctx->bstate = BS_EXCP;
        !          4077:             rn = "Status";
        !          4078:             break;
        !          4079:         case 1:
        !          4080:             check_insn(env, ctx, ISA_MIPS32R2);
        !          4081:             gen_op_mtc0_intctl();
        !          4082:             /* Stop translation as we may have switched the execution mode */
        !          4083:             ctx->bstate = BS_STOP;
        !          4084:             rn = "IntCtl";
        !          4085:             break;
        !          4086:         case 2:
        !          4087:             check_insn(env, ctx, ISA_MIPS32R2);
        !          4088:             gen_op_mtc0_srsctl();
        !          4089:             /* Stop translation as we may have switched the execution mode */
        !          4090:             ctx->bstate = BS_STOP;
        !          4091:             rn = "SRSCtl";
        !          4092:             break;
1.1.1.5   root     4093:         case 3:
1.1.1.6 ! root     4094:             check_insn(env, ctx, ISA_MIPS32R2);
        !          4095:             gen_op_mtc0_srsmap();
        !          4096:             /* Stop translation as we may have switched the execution mode */
        !          4097:             ctx->bstate = BS_STOP;
        !          4098:             rn = "SRSMap";
        !          4099:             break;
1.1.1.5   root     4100:         default:
                   4101:             goto die;
1.1.1.6 ! root     4102:         }
1.1.1.5   root     4103:         break;
                   4104:     case 13:
                   4105:         switch (sel) {
                   4106:         case 0:
1.1.1.6 ! root     4107:             gen_op_mtc0_cause();
        !          4108:             rn = "Cause";
        !          4109:             break;
1.1.1.5   root     4110:         default:
                   4111:             goto die;
1.1.1.6 ! root     4112:         }
        !          4113:         /* Stop translation as we may have switched the execution mode */
        !          4114:         ctx->bstate = BS_STOP;
1.1.1.5   root     4115:         break;
                   4116:     case 14:
                   4117:         switch (sel) {
                   4118:         case 0:
1.1.1.6 ! root     4119:             gen_op_mtc0_epc();
        !          4120:             rn = "EPC";
        !          4121:             break;
1.1.1.5   root     4122:         default:
                   4123:             goto die;
1.1.1.6 ! root     4124:         }
1.1.1.5   root     4125:         break;
                   4126:     case 15:
                   4127:         switch (sel) {
                   4128:         case 0:
1.1.1.6 ! root     4129:             /* ignored */
        !          4130:             rn = "PRid";
        !          4131:             break;
        !          4132:         case 1:
        !          4133:             check_insn(env, ctx, ISA_MIPS32R2);
        !          4134:             gen_op_mtc0_ebase();
        !          4135:             rn = "EBase";
        !          4136:             break;
1.1.1.5   root     4137:         default:
                   4138:             goto die;
1.1.1.6 ! root     4139:         }
1.1.1.5   root     4140:         break;
                   4141:     case 16:
                   4142:         switch (sel) {
                   4143:         case 0:
                   4144:             gen_op_mtc0_config0();
                   4145:             rn = "Config";
1.1.1.6 ! root     4146:             /* Stop translation as we may have switched the execution mode */
        !          4147:             ctx->bstate = BS_STOP;
1.1.1.5   root     4148:             break;
                   4149:         case 1:
1.1.1.6 ! root     4150:             /* ignored */
1.1.1.5   root     4151:             rn = "Config1";
                   4152:             break;
                   4153:         case 2:
                   4154:             gen_op_mtc0_config2();
                   4155:             rn = "Config2";
1.1.1.6 ! root     4156:             /* Stop translation as we may have switched the execution mode */
        !          4157:             ctx->bstate = BS_STOP;
1.1.1.5   root     4158:             break;
                   4159:         case 3:
1.1.1.6 ! root     4160:             /* ignored */
1.1.1.5   root     4161:             rn = "Config3";
                   4162:             break;
                   4163:         /* 6,7 are implementation dependent */
                   4164:         default:
                   4165:             rn = "Invalid config selector";
                   4166:             goto die;
                   4167:         }
                   4168:         break;
                   4169:     case 17:
                   4170:         switch (sel) {
                   4171:         case 0:
1.1.1.6 ! root     4172:             /* ignored */
        !          4173:             rn = "LLAddr";
        !          4174:             break;
1.1.1.5   root     4175:         default:
                   4176:             goto die;
                   4177:         }
                   4178:         break;
                   4179:     case 18:
                   4180:         switch (sel) {
1.1.1.6 ! root     4181:         case 0 ... 7:
        !          4182:             gen_op_mtc0_watchlo(sel);
        !          4183:             rn = "WatchLo";
        !          4184:             break;
1.1.1.5   root     4185:         default:
                   4186:             goto die;
                   4187:         }
                   4188:         break;
                   4189:     case 19:
                   4190:         switch (sel) {
1.1.1.6 ! root     4191:         case 0 ... 7:
        !          4192:             gen_op_mtc0_watchhi(sel);
        !          4193:             rn = "WatchHi";
        !          4194:             break;
1.1.1.5   root     4195:         default:
                   4196:             goto die;
                   4197:         }
                   4198:         break;
                   4199:     case 20:
                   4200:         switch (sel) {
                   4201:         case 0:
1.1.1.6 ! root     4202:             check_insn(env, ctx, ISA_MIPS3);
        !          4203:             gen_op_mtc0_xcontext();
        !          4204:             rn = "XContext";
        !          4205:             break;
1.1.1.5   root     4206:         default:
                   4207:             goto die;
                   4208:         }
                   4209:         break;
                   4210:     case 21:
                   4211:        /* Officially reserved, but sel 0 is used for R1x000 framemask */
                   4212:         switch (sel) {
                   4213:         case 0:
1.1.1.6 ! root     4214:             gen_op_mtc0_framemask();
        !          4215:             rn = "Framemask";
        !          4216:             break;
1.1.1.5   root     4217:         default:
                   4218:             goto die;
                   4219:         }
                   4220:         break;
                   4221:     case 22:
                   4222:         /* ignored */
                   4223:         rn = "Diagnostic"; /* implementation dependent */
1.1.1.6 ! root     4224:         break;
1.1.1.5   root     4225:     case 23:
                   4226:         switch (sel) {
                   4227:         case 0:
1.1.1.6 ! root     4228:             gen_op_mtc0_debug(); /* EJTAG support */
        !          4229:             /* BS_STOP isn't good enough here, hflags may have changed. */
        !          4230:             gen_save_pc(ctx->pc + 4);
        !          4231:             ctx->bstate = BS_EXCP;
        !          4232:             rn = "Debug";
        !          4233:             break;
        !          4234:         case 1:
        !          4235: //            gen_op_mtc0_tracecontrol(); /* PDtrace support */
        !          4236:             /* Stop translation as we may have switched the execution mode */
        !          4237:             ctx->bstate = BS_STOP;
        !          4238:             rn = "TraceControl";
        !          4239: //            break;
        !          4240:         case 2:
        !          4241: //            gen_op_mtc0_tracecontrol2(); /* PDtrace support */
        !          4242:             /* Stop translation as we may have switched the execution mode */
        !          4243:             ctx->bstate = BS_STOP;
        !          4244:             rn = "TraceControl2";
        !          4245: //            break;
        !          4246:         case 3:
        !          4247: //            gen_op_mtc0_usertracedata(); /* PDtrace support */
        !          4248:             /* Stop translation as we may have switched the execution mode */
        !          4249:             ctx->bstate = BS_STOP;
        !          4250:             rn = "UserTraceData";
        !          4251: //            break;
1.1.1.5   root     4252:         case 4:
1.1.1.6 ! root     4253: //            gen_op_mtc0_debug(); /* PDtrace support */
        !          4254:             /* Stop translation as we may have switched the execution mode */
        !          4255:             ctx->bstate = BS_STOP;
        !          4256:             rn = "TraceBPC";
        !          4257: //            break;
1.1.1.5   root     4258:         default:
                   4259:             goto die;
                   4260:         }
                   4261:         break;
                   4262:     case 24:
                   4263:         switch (sel) {
                   4264:         case 0:
1.1.1.6 ! root     4265:             gen_op_mtc0_depc(); /* EJTAG support */
        !          4266:             rn = "DEPC";
        !          4267:             break;
1.1.1.5   root     4268:         default:
                   4269:             goto die;
                   4270:         }
                   4271:         break;
                   4272:     case 25:
                   4273:         switch (sel) {
                   4274:         case 0:
1.1.1.6 ! root     4275:             gen_op_mtc0_performance0();
        !          4276:             rn = "Performance0";
        !          4277:             break;
        !          4278:         case 1:
        !          4279: //            gen_op_mtc0_performance1();
        !          4280:             rn = "Performance1";
        !          4281: //            break;
        !          4282:         case 2:
        !          4283: //            gen_op_mtc0_performance2();
        !          4284:             rn = "Performance2";
        !          4285: //            break;
1.1.1.5   root     4286:         case 3:
1.1.1.6 ! root     4287: //            gen_op_mtc0_performance3();
        !          4288:             rn = "Performance3";
        !          4289: //            break;
1.1.1.5   root     4290:         case 4:
1.1.1.6 ! root     4291: //            gen_op_mtc0_performance4();
        !          4292:             rn = "Performance4";
        !          4293: //            break;
1.1.1.5   root     4294:         case 5:
1.1.1.6 ! root     4295: //            gen_op_mtc0_performance5();
        !          4296:             rn = "Performance5";
        !          4297: //            break;
1.1.1.5   root     4298:         case 6:
1.1.1.6 ! root     4299: //            gen_op_mtc0_performance6();
        !          4300:             rn = "Performance6";
        !          4301: //            break;
1.1.1.5   root     4302:         case 7:
1.1.1.6 ! root     4303: //            gen_op_mtc0_performance7();
        !          4304:             rn = "Performance7";
        !          4305: //            break;
1.1.1.5   root     4306:         default:
                   4307:             goto die;
                   4308:         }
1.1.1.6 ! root     4309:         break;
1.1.1.5   root     4310:     case 26:
1.1.1.6 ! root     4311:         /* ignored */
1.1.1.5   root     4312:         rn = "ECC";
1.1.1.6 ! root     4313:         break;
1.1.1.5   root     4314:     case 27:
                   4315:         switch (sel) {
                   4316:         case 0 ... 3:
1.1.1.6 ! root     4317:             /* ignored */
        !          4318:             rn = "CacheErr";
        !          4319:             break;
1.1.1.5   root     4320:         default:
                   4321:             goto die;
                   4322:         }
1.1.1.6 ! root     4323:         break;
1.1.1.5   root     4324:     case 28:
                   4325:         switch (sel) {
                   4326:         case 0:
                   4327:         case 2:
                   4328:         case 4:
                   4329:         case 6:
                   4330:             gen_op_mtc0_taglo();
                   4331:             rn = "TagLo";
                   4332:             break;
                   4333:         case 1:
                   4334:         case 3:
                   4335:         case 5:
                   4336:         case 7:
1.1.1.6 ! root     4337:             gen_op_mtc0_datalo();
1.1.1.5   root     4338:             rn = "DataLo";
                   4339:             break;
                   4340:         default:
                   4341:             goto die;
                   4342:         }
                   4343:         break;
                   4344:     case 29:
                   4345:         switch (sel) {
                   4346:         case 0:
                   4347:         case 2:
                   4348:         case 4:
                   4349:         case 6:
                   4350:             gen_op_mtc0_taghi();
                   4351:             rn = "TagHi";
                   4352:             break;
                   4353:         case 1:
                   4354:         case 3:
                   4355:         case 5:
                   4356:         case 7:
1.1.1.6 ! root     4357:             gen_op_mtc0_datahi();
1.1.1.5   root     4358:             rn = "DataHi";
                   4359:             break;
                   4360:         default:
                   4361:             rn = "invalid sel";
                   4362:             goto die;
                   4363:         }
1.1.1.6 ! root     4364:         break;
1.1.1.5   root     4365:     case 30:
                   4366:         switch (sel) {
                   4367:         case 0:
1.1.1.6 ! root     4368:             gen_op_mtc0_errorepc();
        !          4369:             rn = "ErrorEPC";
        !          4370:             break;
1.1.1.5   root     4371:         default:
                   4372:             goto die;
                   4373:         }
                   4374:         break;
                   4375:     case 31:
                   4376:         switch (sel) {
                   4377:         case 0:
1.1.1.6 ! root     4378:             gen_op_mtc0_desave(); /* EJTAG support */
        !          4379:             rn = "DESAVE";
        !          4380:             break;
1.1.1.5   root     4381:         default:
                   4382:             goto die;
                   4383:         }
1.1.1.6 ! root     4384:         /* Stop translation as we may have switched the execution mode */
        !          4385:         ctx->bstate = BS_STOP;
1.1.1.5   root     4386:         break;
                   4387:     default:
1.1.1.6 ! root     4388:         goto die;
1.1.1.5   root     4389:     }
                   4390: #if defined MIPS_DEBUG_DISAS
                   4391:     if (loglevel & CPU_LOG_TB_IN_ASM) {
                   4392:         fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
                   4393:                 rn, reg, sel);
                   4394:     }
                   4395: #endif
                   4396:     return;
                   4397: 
                   4398: die:
                   4399: #if defined MIPS_DEBUG_DISAS
                   4400:     if (loglevel & CPU_LOG_TB_IN_ASM) {
                   4401:         fprintf(logfile, "dmtc0 %s (reg %d sel %d)\n",
                   4402:                 rn, reg, sel);
                   4403:     }
                   4404: #endif
                   4405:     generate_exception(ctx, EXCP_RI);
                   4406: }
1.1.1.6 ! root     4407: #endif /* TARGET_MIPS64 */
1.1.1.5   root     4408: 
1.1.1.6 ! root     4409: static void gen_mftr(CPUState *env, DisasContext *ctx, int rt,
        !          4410:                      int u, int sel, int h)
1.1.1.5   root     4411: {
1.1.1.6 ! root     4412:     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1.1.1.5   root     4413: 
1.1.1.6 ! root     4414:     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
        !          4415:         ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
        !          4416:          (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
        !          4417:         gen_op_set_T0(-1);
        !          4418:     else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
        !          4419:              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
        !          4420:         gen_op_set_T0(-1);
        !          4421:     else if (u == 0) {
        !          4422:         switch (rt) {
        !          4423:         case 2:
        !          4424:             switch (sel) {
        !          4425:             case 1:
        !          4426:                 gen_op_mftc0_tcstatus();
        !          4427:                 break;
        !          4428:             case 2:
        !          4429:                 gen_op_mftc0_tcbind();
        !          4430:                 break;
        !          4431:             case 3:
        !          4432:                 gen_op_mftc0_tcrestart();
        !          4433:                 break;
        !          4434:             case 4:
        !          4435:                 gen_op_mftc0_tchalt();
        !          4436:                 break;
        !          4437:             case 5:
        !          4438:                 gen_op_mftc0_tccontext();
        !          4439:                 break;
        !          4440:             case 6:
        !          4441:                 gen_op_mftc0_tcschedule();
        !          4442:                 break;
        !          4443:             case 7:
        !          4444:                 gen_op_mftc0_tcschefback();
        !          4445:                 break;
        !          4446:             default:
        !          4447:                 gen_mfc0(env, ctx, rt, sel);
        !          4448:                 break;
        !          4449:             }
        !          4450:             break;
        !          4451:         case 10:
        !          4452:             switch (sel) {
        !          4453:             case 0:
        !          4454:                 gen_op_mftc0_entryhi();
        !          4455:                 break;
        !          4456:             default:
        !          4457:                 gen_mfc0(env, ctx, rt, sel);
        !          4458:                 break;
        !          4459:             }
        !          4460:         case 12:
        !          4461:             switch (sel) {
        !          4462:             case 0:
        !          4463:                 gen_op_mftc0_status();
        !          4464:                 break;
        !          4465:             default:
        !          4466:                 gen_mfc0(env, ctx, rt, sel);
        !          4467:                 break;
        !          4468:             }
        !          4469:         case 23:
        !          4470:             switch (sel) {
        !          4471:             case 0:
        !          4472:                 gen_op_mftc0_debug();
        !          4473:                 break;
        !          4474:             default:
        !          4475:                 gen_mfc0(env, ctx, rt, sel);
        !          4476:                 break;
        !          4477:             }
        !          4478:             break;
        !          4479:         default:
        !          4480:             gen_mfc0(env, ctx, rt, sel);
        !          4481:         }
        !          4482:     } else switch (sel) {
        !          4483:     /* GPR registers. */
        !          4484:     case 0:
        !          4485:         gen_op_mftgpr(rt);
        !          4486:         break;
        !          4487:     /* Auxiliary CPU registers */
        !          4488:     case 1:
        !          4489:         switch (rt) {
        !          4490:         case 0:
        !          4491:             gen_op_mftlo(0);
        !          4492:             break;
        !          4493:         case 1:
        !          4494:             gen_op_mfthi(0);
        !          4495:             break;
        !          4496:         case 2:
        !          4497:             gen_op_mftacx(0);
        !          4498:             break;
        !          4499:         case 4:
        !          4500:             gen_op_mftlo(1);
        !          4501:             break;
        !          4502:         case 5:
        !          4503:             gen_op_mfthi(1);
        !          4504:             break;
        !          4505:         case 6:
        !          4506:             gen_op_mftacx(1);
        !          4507:             break;
        !          4508:         case 8:
        !          4509:             gen_op_mftlo(2);
        !          4510:             break;
        !          4511:         case 9:
        !          4512:             gen_op_mfthi(2);
        !          4513:             break;
        !          4514:         case 10:
        !          4515:             gen_op_mftacx(2);
        !          4516:             break;
        !          4517:         case 12:
        !          4518:             gen_op_mftlo(3);
        !          4519:             break;
        !          4520:         case 13:
        !          4521:             gen_op_mfthi(3);
        !          4522:             break;
        !          4523:         case 14:
        !          4524:             gen_op_mftacx(3);
        !          4525:             break;
        !          4526:         case 16:
        !          4527:             gen_op_mftdsp();
        !          4528:             break;
        !          4529:         default:
        !          4530:             goto die;
        !          4531:         }
        !          4532:         break;
        !          4533:     /* Floating point (COP1). */
        !          4534:     case 2:
        !          4535:         /* XXX: For now we support only a single FPU context. */
        !          4536:         if (h == 0) {
        !          4537:             GEN_LOAD_FREG_FTN(WT0, rt);
        !          4538:             gen_op_mfc1();
        !          4539:         } else {
        !          4540:             GEN_LOAD_FREG_FTN(WTH0, rt);
        !          4541:             gen_op_mfhc1();
        !          4542:         }
        !          4543:         break;
        !          4544:     case 3:
        !          4545:         /* XXX: For now we support only a single FPU context. */
        !          4546:         gen_op_cfc1(rt);
        !          4547:         break;
        !          4548:     /* COP2: Not implemented. */
        !          4549:     case 4:
        !          4550:     case 5:
        !          4551:         /* fall through */
        !          4552:     default:
        !          4553:         goto die;
        !          4554:     }
        !          4555: #if defined MIPS_DEBUG_DISAS
        !          4556:     if (loglevel & CPU_LOG_TB_IN_ASM) {
        !          4557:         fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
        !          4558:                 rt, u, sel, h);
        !          4559:     }
        !          4560: #endif
        !          4561:     return;
        !          4562: 
        !          4563: die:
        !          4564: #if defined MIPS_DEBUG_DISAS
        !          4565:     if (loglevel & CPU_LOG_TB_IN_ASM) {
        !          4566:         fprintf(logfile, "mftr (reg %d u %d sel %d h %d)\n",
        !          4567:                 rt, u, sel, h);
        !          4568:     }
        !          4569: #endif
        !          4570:     generate_exception(ctx, EXCP_RI);
        !          4571: }
        !          4572: 
        !          4573: static void gen_mttr(CPUState *env, DisasContext *ctx, int rd,
        !          4574:                      int u, int sel, int h)
        !          4575: {
        !          4576:     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
        !          4577: 
        !          4578:     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
        !          4579:         ((env->CP0_TCBind[other_tc] & (0xf << CP0TCBd_CurVPE)) !=
        !          4580:          (env->CP0_TCBind[env->current_tc] & (0xf << CP0TCBd_CurVPE))))
        !          4581:         /* NOP */ ;
        !          4582:     else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
        !          4583:              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
        !          4584:         /* NOP */ ;
        !          4585:     else if (u == 0) {
        !          4586:         switch (rd) {
        !          4587:         case 2:
        !          4588:             switch (sel) {
        !          4589:             case 1:
        !          4590:                 gen_op_mttc0_tcstatus();
        !          4591:                 break;
        !          4592:             case 2:
        !          4593:                 gen_op_mttc0_tcbind();
        !          4594:                 break;
        !          4595:             case 3:
        !          4596:                 gen_op_mttc0_tcrestart();
        !          4597:                 break;
        !          4598:             case 4:
        !          4599:                 gen_op_mttc0_tchalt();
        !          4600:                 break;
        !          4601:             case 5:
        !          4602:                 gen_op_mttc0_tccontext();
        !          4603:                 break;
        !          4604:             case 6:
        !          4605:                 gen_op_mttc0_tcschedule();
        !          4606:                 break;
        !          4607:             case 7:
        !          4608:                 gen_op_mttc0_tcschefback();
        !          4609:                 break;
        !          4610:             default:
        !          4611:                 gen_mtc0(env, ctx, rd, sel);
        !          4612:                 break;
        !          4613:             }
        !          4614:             break;
        !          4615:         case 10:
        !          4616:             switch (sel) {
        !          4617:             case 0:
        !          4618:                 gen_op_mttc0_entryhi();
        !          4619:                 break;
        !          4620:             default:
        !          4621:                 gen_mtc0(env, ctx, rd, sel);
        !          4622:                 break;
        !          4623:             }
        !          4624:         case 12:
        !          4625:             switch (sel) {
        !          4626:             case 0:
        !          4627:                 gen_op_mttc0_status();
        !          4628:                 break;
        !          4629:             default:
        !          4630:                 gen_mtc0(env, ctx, rd, sel);
        !          4631:                 break;
        !          4632:             }
        !          4633:         case 23:
        !          4634:             switch (sel) {
        !          4635:             case 0:
        !          4636:                 gen_op_mttc0_debug();
        !          4637:                 break;
        !          4638:             default:
        !          4639:                 gen_mtc0(env, ctx, rd, sel);
        !          4640:                 break;
        !          4641:             }
        !          4642:             break;
        !          4643:         default:
        !          4644:             gen_mtc0(env, ctx, rd, sel);
        !          4645:         }
        !          4646:     } else switch (sel) {
        !          4647:     /* GPR registers. */
        !          4648:     case 0:
        !          4649:         gen_op_mttgpr(rd);
        !          4650:         break;
        !          4651:     /* Auxiliary CPU registers */
        !          4652:     case 1:
        !          4653:         switch (rd) {
        !          4654:         case 0:
        !          4655:             gen_op_mttlo(0);
        !          4656:             break;
        !          4657:         case 1:
        !          4658:             gen_op_mtthi(0);
        !          4659:             break;
        !          4660:         case 2:
        !          4661:             gen_op_mttacx(0);
        !          4662:             break;
        !          4663:         case 4:
        !          4664:             gen_op_mttlo(1);
        !          4665:             break;
        !          4666:         case 5:
        !          4667:             gen_op_mtthi(1);
        !          4668:             break;
        !          4669:         case 6:
        !          4670:             gen_op_mttacx(1);
        !          4671:             break;
        !          4672:         case 8:
        !          4673:             gen_op_mttlo(2);
        !          4674:             break;
        !          4675:         case 9:
        !          4676:             gen_op_mtthi(2);
        !          4677:             break;
        !          4678:         case 10:
        !          4679:             gen_op_mttacx(2);
        !          4680:             break;
        !          4681:         case 12:
        !          4682:             gen_op_mttlo(3);
        !          4683:             break;
        !          4684:         case 13:
        !          4685:             gen_op_mtthi(3);
        !          4686:             break;
        !          4687:         case 14:
        !          4688:             gen_op_mttacx(3);
        !          4689:             break;
        !          4690:         case 16:
        !          4691:             gen_op_mttdsp();
        !          4692:             break;
        !          4693:         default:
        !          4694:             goto die;
        !          4695:         }
        !          4696:         break;
        !          4697:     /* Floating point (COP1). */
        !          4698:     case 2:
        !          4699:         /* XXX: For now we support only a single FPU context. */
        !          4700:         if (h == 0) {
        !          4701:             gen_op_mtc1();
        !          4702:             GEN_STORE_FTN_FREG(rd, WT0);
        !          4703:         } else {
        !          4704:             gen_op_mthc1();
        !          4705:             GEN_STORE_FTN_FREG(rd, WTH0);
        !          4706:         }
        !          4707:         break;
        !          4708:     case 3:
        !          4709:         /* XXX: For now we support only a single FPU context. */
        !          4710:         gen_op_ctc1(rd);
        !          4711:         break;
        !          4712:     /* COP2: Not implemented. */
        !          4713:     case 4:
        !          4714:     case 5:
        !          4715:         /* fall through */
        !          4716:     default:
        !          4717:         goto die;
        !          4718:     }
        !          4719: #if defined MIPS_DEBUG_DISAS
        !          4720:     if (loglevel & CPU_LOG_TB_IN_ASM) {
        !          4721:         fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
        !          4722:                 rd, u, sel, h);
1.1.1.5   root     4723:     }
1.1.1.6 ! root     4724: #endif
        !          4725:     return;
        !          4726: 
        !          4727: die:
        !          4728: #if defined MIPS_DEBUG_DISAS
        !          4729:     if (loglevel & CPU_LOG_TB_IN_ASM) {
        !          4730:         fprintf(logfile, "mttr (reg %d u %d sel %d h %d)\n",
        !          4731:                 rd, u, sel, h);
        !          4732:     }
        !          4733: #endif
        !          4734:     generate_exception(ctx, EXCP_RI);
        !          4735: }
        !          4736: 
        !          4737: static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
        !          4738: {
        !          4739:     const char *opn = "ldst";
1.1.1.5   root     4740: 
                   4741:     switch (opc) {
                   4742:     case OPC_MFC0:
                   4743:         if (rt == 0) {
1.1.1.6 ! root     4744:             /* Treat as NOP. */
1.1.1.5   root     4745:             return;
                   4746:         }
1.1.1.6 ! root     4747:         gen_mfc0(env, ctx, rd, ctx->opcode & 0x7);
1.1.1.5   root     4748:         gen_op_store_T0_gpr(rt);
                   4749:         opn = "mfc0";
                   4750:         break;
                   4751:     case OPC_MTC0:
1.1.1.6 ! root     4752:         GEN_LOAD_REG_T0(rt);
1.1.1.5   root     4753:         save_cpu_state(ctx, 1);
1.1.1.6 ! root     4754:         gen_mtc0(env, ctx, rd, ctx->opcode & 0x7);
1.1.1.5   root     4755:         opn = "mtc0";
                   4756:         break;
1.1.1.6 ! root     4757: #if defined(TARGET_MIPS64)
1.1.1.5   root     4758:     case OPC_DMFC0:
1.1.1.6 ! root     4759:         check_insn(env, ctx, ISA_MIPS3);
1.1.1.5   root     4760:         if (rt == 0) {
1.1.1.6 ! root     4761:             /* Treat as NOP. */
1.1.1.5   root     4762:             return;
                   4763:         }
1.1.1.6 ! root     4764:         gen_dmfc0(env, ctx, rd, ctx->opcode & 0x7);
1.1.1.5   root     4765:         gen_op_store_T0_gpr(rt);
                   4766:         opn = "dmfc0";
                   4767:         break;
                   4768:     case OPC_DMTC0:
1.1.1.6 ! root     4769:         check_insn(env, ctx, ISA_MIPS3);
        !          4770:         GEN_LOAD_REG_T0(rt);
1.1.1.5   root     4771:         save_cpu_state(ctx, 1);
1.1.1.6 ! root     4772:         gen_dmtc0(env, ctx, rd, ctx->opcode & 0x7);
1.1.1.5   root     4773:         opn = "dmtc0";
                   4774:         break;
1.1.1.6 ! root     4775: #endif
        !          4776:     case OPC_MFTR:
        !          4777:         check_insn(env, ctx, ASE_MT);
        !          4778:         if (rd == 0) {
        !          4779:             /* Treat as NOP. */
        !          4780:             return;
        !          4781:         }
        !          4782:         gen_mftr(env, ctx, rt, (ctx->opcode >> 5) & 1,
        !          4783:                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
        !          4784:         gen_op_store_T0_gpr(rd);
        !          4785:         opn = "mftr";
        !          4786:         break;
        !          4787:     case OPC_MTTR:
        !          4788:         check_insn(env, ctx, ASE_MT);
        !          4789:         GEN_LOAD_REG_T0(rt);
        !          4790:         gen_mttr(env, ctx, rd, (ctx->opcode >> 5) & 1,
        !          4791:                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
        !          4792:         opn = "mttr";
        !          4793:         break;
1.1.1.5   root     4794:     case OPC_TLBWI:
                   4795:         opn = "tlbwi";
1.1.1.6 ! root     4796:         if (!env->tlb->do_tlbwi)
        !          4797:             goto die;
        !          4798:         gen_op_tlbwi();
1.1.1.5   root     4799:         break;
                   4800:     case OPC_TLBWR:
                   4801:         opn = "tlbwr";
1.1.1.6 ! root     4802:         if (!env->tlb->do_tlbwr)
        !          4803:             goto die;
        !          4804:         gen_op_tlbwr();
1.1.1.5   root     4805:         break;
                   4806:     case OPC_TLBP:
                   4807:         opn = "tlbp";
1.1.1.6 ! root     4808:         if (!env->tlb->do_tlbp)
        !          4809:             goto die;
        !          4810:         gen_op_tlbp();
1.1.1.5   root     4811:         break;
                   4812:     case OPC_TLBR:
                   4813:         opn = "tlbr";
1.1.1.6 ! root     4814:         if (!env->tlb->do_tlbr)
        !          4815:             goto die;
        !          4816:         gen_op_tlbr();
1.1.1.5   root     4817:         break;
                   4818:     case OPC_ERET:
                   4819:         opn = "eret";
1.1.1.6 ! root     4820:         check_insn(env, ctx, ISA_MIPS2);
        !          4821:         save_cpu_state(ctx, 1);
1.1.1.5   root     4822:         gen_op_eret();
                   4823:         ctx->bstate = BS_EXCP;
                   4824:         break;
                   4825:     case OPC_DERET:
                   4826:         opn = "deret";
1.1.1.6 ! root     4827:         check_insn(env, ctx, ISA_MIPS32);
1.1.1.5   root     4828:         if (!(ctx->hflags & MIPS_HFLAG_DM)) {
1.1.1.6 ! root     4829:             MIPS_INVAL(opn);
1.1.1.5   root     4830:             generate_exception(ctx, EXCP_RI);
                   4831:         } else {
1.1.1.6 ! root     4832:             save_cpu_state(ctx, 1);
1.1.1.5   root     4833:             gen_op_deret();
                   4834:             ctx->bstate = BS_EXCP;
                   4835:         }
                   4836:         break;
                   4837:     case OPC_WAIT:
                   4838:         opn = "wait";
1.1.1.6 ! root     4839:         check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
1.1.1.5   root     4840:         /* If we get an exception, we want to restart at next instruction */
                   4841:         ctx->pc += 4;
                   4842:         save_cpu_state(ctx, 1);
                   4843:         ctx->pc -= 4;
                   4844:         gen_op_wait();
                   4845:         ctx->bstate = BS_EXCP;
                   4846:         break;
                   4847:     default:
1.1.1.6 ! root     4848:  die:
        !          4849:         MIPS_INVAL(opn);
1.1.1.5   root     4850:         generate_exception(ctx, EXCP_RI);
                   4851:         return;
                   4852:     }
                   4853:     MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
                   4854: }
                   4855: 
                   4856: /* CP1 Branches (before delay slot) */
1.1.1.6 ! root     4857: static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
        !          4858:                                  int32_t cc, int32_t offset)
1.1.1.5   root     4859: {
                   4860:     target_ulong btarget;
1.1.1.6 ! root     4861:     const char *opn = "cp1 cond branch";
        !          4862: 
        !          4863:     if (cc != 0)
        !          4864:         check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
1.1.1.5   root     4865: 
                   4866:     btarget = ctx->pc + 4 + offset;
                   4867: 
                   4868:     switch (op) {
                   4869:     case OPC_BC1F:
1.1.1.6 ! root     4870:         gen_op_bc1f(cc);
        !          4871:         opn = "bc1f";
1.1.1.5   root     4872:         goto not_likely;
                   4873:     case OPC_BC1FL:
1.1.1.6 ! root     4874:         gen_op_bc1f(cc);
        !          4875:         opn = "bc1fl";
1.1.1.5   root     4876:         goto likely;
                   4877:     case OPC_BC1T:
1.1.1.6 ! root     4878:         gen_op_bc1t(cc);
        !          4879:         opn = "bc1t";
        !          4880:         goto not_likely;
1.1.1.5   root     4881:     case OPC_BC1TL:
1.1.1.6 ! root     4882:         gen_op_bc1t(cc);
        !          4883:         opn = "bc1tl";
1.1.1.5   root     4884:     likely:
                   4885:         ctx->hflags |= MIPS_HFLAG_BL;
1.1.1.6 ! root     4886:         gen_op_set_bcond();
        !          4887:         gen_op_save_bcond();
        !          4888:         break;
        !          4889:     case OPC_BC1FANY2:
        !          4890:         gen_op_bc1any2f(cc);
        !          4891:         opn = "bc1any2f";
        !          4892:         goto not_likely;
        !          4893:     case OPC_BC1TANY2:
        !          4894:         gen_op_bc1any2t(cc);
        !          4895:         opn = "bc1any2t";
        !          4896:         goto not_likely;
        !          4897:     case OPC_BC1FANY4:
        !          4898:         gen_op_bc1any4f(cc);
        !          4899:         opn = "bc1any4f";
        !          4900:         goto not_likely;
        !          4901:     case OPC_BC1TANY4:
        !          4902:         gen_op_bc1any4t(cc);
        !          4903:         opn = "bc1any4t";
        !          4904:     not_likely:
        !          4905:         ctx->hflags |= MIPS_HFLAG_BC;
        !          4906:         gen_op_set_bcond();
1.1.1.5   root     4907:         break;
1.1.1.6 ! root     4908:     default:
        !          4909:         MIPS_INVAL(opn);
        !          4910:         generate_exception (ctx, EXCP_RI);
1.1.1.5   root     4911:         return;
                   4912:     }
1.1.1.6 ! root     4913:     MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
1.1.1.5   root     4914:                ctx->hflags, btarget);
                   4915:     ctx->btarget = btarget;
                   4916: }
                   4917: 
                   4918: /* Coprocessor 1 (FPU) */
1.1.1.6 ! root     4919: 
        !          4920: #define FOP(func, fmt) (((fmt) << 21) | (func))
        !          4921: 
1.1.1.5   root     4922: static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
                   4923: {
1.1.1.6 ! root     4924:     const char *opn = "cp1 move";
1.1.1.5   root     4925: 
                   4926:     switch (opc) {
                   4927:     case OPC_MFC1:
                   4928:         GEN_LOAD_FREG_FTN(WT0, fs);
                   4929:         gen_op_mfc1();
1.1.1.6 ! root     4930:         GEN_STORE_T0_REG(rt);
1.1.1.5   root     4931:         opn = "mfc1";
                   4932:         break;
                   4933:     case OPC_MTC1:
1.1.1.6 ! root     4934:         GEN_LOAD_REG_T0(rt);
1.1.1.5   root     4935:         gen_op_mtc1();
                   4936:         GEN_STORE_FTN_FREG(fs, WT0);
                   4937:         opn = "mtc1";
                   4938:         break;
                   4939:     case OPC_CFC1:
1.1.1.6 ! root     4940:         gen_op_cfc1(fs);
        !          4941:         GEN_STORE_T0_REG(rt);
1.1.1.5   root     4942:         opn = "cfc1";
                   4943:         break;
                   4944:     case OPC_CTC1:
1.1.1.6 ! root     4945:         GEN_LOAD_REG_T0(rt);
        !          4946:         gen_op_ctc1(fs);
1.1.1.5   root     4947:         opn = "ctc1";
                   4948:         break;
                   4949:     case OPC_DMFC1:
1.1.1.6 ! root     4950:         GEN_LOAD_FREG_FTN(DT0, fs);
        !          4951:         gen_op_dmfc1();
        !          4952:         GEN_STORE_T0_REG(rt);
        !          4953:         opn = "dmfc1";
        !          4954:         break;
1.1.1.5   root     4955:     case OPC_DMTC1:
1.1.1.6 ! root     4956:         GEN_LOAD_REG_T0(rt);
        !          4957:         gen_op_dmtc1();
        !          4958:         GEN_STORE_FTN_FREG(fs, DT0);
        !          4959:         opn = "dmtc1";
        !          4960:         break;
        !          4961:     case OPC_MFHC1:
        !          4962:         GEN_LOAD_FREG_FTN(WTH0, fs);
        !          4963:         gen_op_mfhc1();
        !          4964:         GEN_STORE_T0_REG(rt);
        !          4965:         opn = "mfhc1";
        !          4966:         break;
        !          4967:     case OPC_MTHC1:
        !          4968:         GEN_LOAD_REG_T0(rt);
        !          4969:         gen_op_mthc1();
        !          4970:         GEN_STORE_FTN_FREG(fs, WTH0);
        !          4971:         opn = "mthc1";
        !          4972:         break;
1.1.1.5   root     4973:     default:
1.1.1.6 ! root     4974:         MIPS_INVAL(opn);
        !          4975:         generate_exception (ctx, EXCP_RI);
1.1.1.4   root     4976:         return;
                   4977:     }
                   4978:     MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
                   4979: }
                   4980: 
1.1.1.6 ! root     4981: static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
        !          4982: {
        !          4983:     uint32_t ccbit;
1.1.1.4   root     4984: 
1.1.1.6 ! root     4985:     GEN_LOAD_REG_T0(rd);
        !          4986:     GEN_LOAD_REG_T1(rs);
        !          4987:     if (cc) {
        !          4988:         ccbit = 1 << (24 + cc);
        !          4989:     } else
        !          4990:         ccbit = 1 << 23;
        !          4991:     if (!tf)
        !          4992:         gen_op_movf(ccbit);
        !          4993:     else
        !          4994:         gen_op_movt(ccbit);
        !          4995:     GEN_STORE_T0_REG(rd);
        !          4996: }
        !          4997: 
        !          4998: #define GEN_MOVCF(fmt)                                                \
        !          4999: static void glue(gen_movcf_, fmt) (DisasContext *ctx, int cc, int tf) \
        !          5000: {                                                                     \
        !          5001:     uint32_t ccbit;                                                   \
        !          5002:                                                                       \
        !          5003:     if (cc) {                                                         \
        !          5004:         ccbit = 1 << (24 + cc);                                       \
        !          5005:     } else                                                            \
        !          5006:         ccbit = 1 << 23;                                              \
        !          5007:     if (!tf)                                                          \
        !          5008:         glue(gen_op_float_movf_, fmt)(ccbit);                         \
        !          5009:     else                                                              \
        !          5010:         glue(gen_op_float_movt_, fmt)(ccbit);                         \
        !          5011: }
        !          5012: GEN_MOVCF(d);
        !          5013: GEN_MOVCF(s);
        !          5014: GEN_MOVCF(ps);
        !          5015: #undef GEN_MOVCF
1.1.1.4   root     5016: 
1.1.1.6 ! root     5017: static void gen_farith (DisasContext *ctx, uint32_t op1,
        !          5018:                         int ft, int fs, int fd, int cc)
1.1.1.4   root     5019: {
1.1.1.6 ! root     5020:     const char *opn = "farith";
1.1.1.4   root     5021:     const char *condnames[] = {
                   5022:             "c.f",
                   5023:             "c.un",
                   5024:             "c.eq",
                   5025:             "c.ueq",
                   5026:             "c.olt",
                   5027:             "c.ult",
                   5028:             "c.ole",
                   5029:             "c.ule",
                   5030:             "c.sf",
                   5031:             "c.ngle",
                   5032:             "c.seq",
                   5033:             "c.ngl",
                   5034:             "c.lt",
                   5035:             "c.nge",
                   5036:             "c.le",
                   5037:             "c.ngt",
                   5038:     };
1.1.1.6 ! root     5039:     const char *condnames_abs[] = {
        !          5040:             "cabs.f",
        !          5041:             "cabs.un",
        !          5042:             "cabs.eq",
        !          5043:             "cabs.ueq",
        !          5044:             "cabs.olt",
        !          5045:             "cabs.ult",
        !          5046:             "cabs.ole",
        !          5047:             "cabs.ule",
        !          5048:             "cabs.sf",
        !          5049:             "cabs.ngle",
        !          5050:             "cabs.seq",
        !          5051:             "cabs.ngl",
        !          5052:             "cabs.lt",
        !          5053:             "cabs.nge",
        !          5054:             "cabs.le",
        !          5055:             "cabs.ngt",
        !          5056:     };
        !          5057:     enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
1.1.1.5   root     5058:     uint32_t func = ctx->opcode & 0x3f;
                   5059: 
1.1.1.4   root     5060:     switch (ctx->opcode & FOP(0x3f, 0x1f)) {
1.1.1.6 ! root     5061:     case FOP(0, 16):
        !          5062:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5063:         GEN_LOAD_FREG_FTN(WT1, ft);
        !          5064:         gen_op_float_add_s();
        !          5065:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5066:         opn = "add.s";
        !          5067:         optype = BINOP;
        !          5068:         break;
        !          5069:     case FOP(1, 16):
        !          5070:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5071:         GEN_LOAD_FREG_FTN(WT1, ft);
        !          5072:         gen_op_float_sub_s();
        !          5073:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5074:         opn = "sub.s";
        !          5075:         optype = BINOP;
        !          5076:         break;
        !          5077:     case FOP(2, 16):
        !          5078:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5079:         GEN_LOAD_FREG_FTN(WT1, ft);
        !          5080:         gen_op_float_mul_s();
        !          5081:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5082:         opn = "mul.s";
        !          5083:         optype = BINOP;
        !          5084:         break;
        !          5085:     case FOP(3, 16):
        !          5086:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5087:         GEN_LOAD_FREG_FTN(WT1, ft);
        !          5088:         gen_op_float_div_s();
        !          5089:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5090:         opn = "div.s";
        !          5091:         optype = BINOP;
        !          5092:         break;
        !          5093:     case FOP(4, 16):
        !          5094:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5095:         gen_op_float_sqrt_s();
        !          5096:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5097:         opn = "sqrt.s";
        !          5098:         break;
        !          5099:     case FOP(5, 16):
        !          5100:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5101:         gen_op_float_abs_s();
        !          5102:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5103:         opn = "abs.s";
        !          5104:         break;
        !          5105:     case FOP(6, 16):
        !          5106:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5107:         gen_op_float_mov_s();
        !          5108:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5109:         opn = "mov.s";
        !          5110:         break;
        !          5111:     case FOP(7, 16):
        !          5112:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5113:         gen_op_float_chs_s();
        !          5114:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5115:         opn = "neg.s";
        !          5116:         break;
        !          5117:     case FOP(8, 16):
        !          5118:         check_cp1_64bitmode(ctx);
        !          5119:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5120:         gen_op_float_roundl_s();
        !          5121:         GEN_STORE_FTN_FREG(fd, DT2);
        !          5122:         opn = "round.l.s";
        !          5123:         break;
        !          5124:     case FOP(9, 16):
        !          5125:         check_cp1_64bitmode(ctx);
        !          5126:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5127:         gen_op_float_truncl_s();
        !          5128:         GEN_STORE_FTN_FREG(fd, DT2);
        !          5129:         opn = "trunc.l.s";
        !          5130:         break;
        !          5131:     case FOP(10, 16):
        !          5132:         check_cp1_64bitmode(ctx);
        !          5133:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5134:         gen_op_float_ceill_s();
        !          5135:         GEN_STORE_FTN_FREG(fd, DT2);
        !          5136:         opn = "ceil.l.s";
        !          5137:         break;
        !          5138:     case FOP(11, 16):
        !          5139:         check_cp1_64bitmode(ctx);
        !          5140:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5141:         gen_op_float_floorl_s();
        !          5142:         GEN_STORE_FTN_FREG(fd, DT2);
        !          5143:         opn = "floor.l.s";
        !          5144:         break;
        !          5145:     case FOP(12, 16):
        !          5146:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5147:         gen_op_float_roundw_s();
        !          5148:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5149:         opn = "round.w.s";
        !          5150:         break;
        !          5151:     case FOP(13, 16):
        !          5152:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5153:         gen_op_float_truncw_s();
        !          5154:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5155:         opn = "trunc.w.s";
        !          5156:         break;
        !          5157:     case FOP(14, 16):
        !          5158:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5159:         gen_op_float_ceilw_s();
        !          5160:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5161:         opn = "ceil.w.s";
        !          5162:         break;
        !          5163:     case FOP(15, 16):
        !          5164:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5165:         gen_op_float_floorw_s();
        !          5166:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5167:         opn = "floor.w.s";
        !          5168:         break;
        !          5169:     case FOP(17, 16):
        !          5170:         GEN_LOAD_REG_T0(ft);
        !          5171:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5172:         GEN_LOAD_FREG_FTN(WT2, fd);
        !          5173:         gen_movcf_s(ctx, (ft >> 2) & 0x7, ft & 0x1);
        !          5174:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5175:         opn = "movcf.s";
        !          5176:         break;
        !          5177:     case FOP(18, 16):
        !          5178:         GEN_LOAD_REG_T0(ft);
        !          5179:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5180:         GEN_LOAD_FREG_FTN(WT2, fd);
        !          5181:         gen_op_float_movz_s();
        !          5182:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5183:         opn = "movz.s";
        !          5184:         break;
        !          5185:     case FOP(19, 16):
        !          5186:         GEN_LOAD_REG_T0(ft);
        !          5187:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5188:         GEN_LOAD_FREG_FTN(WT2, fd);
        !          5189:         gen_op_float_movn_s();
        !          5190:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5191:         opn = "movn.s";
        !          5192:         break;
        !          5193:     case FOP(21, 16):
        !          5194:         check_cop1x(ctx);
        !          5195:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5196:         gen_op_float_recip_s();
        !          5197:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5198:         opn = "recip.s";
        !          5199:         break;
        !          5200:     case FOP(22, 16):
        !          5201:         check_cop1x(ctx);
        !          5202:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5203:         gen_op_float_rsqrt_s();
        !          5204:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5205:         opn = "rsqrt.s";
        !          5206:         break;
        !          5207:     case FOP(28, 16):
        !          5208:         check_cp1_64bitmode(ctx);
        !          5209:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5210:         GEN_LOAD_FREG_FTN(WT2, fd);
        !          5211:         gen_op_float_recip2_s();
        !          5212:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5213:         opn = "recip2.s";
        !          5214:         break;
        !          5215:     case FOP(29, 16):
        !          5216:         check_cp1_64bitmode(ctx);
        !          5217:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5218:         gen_op_float_recip1_s();
        !          5219:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5220:         opn = "recip1.s";
        !          5221:         break;
        !          5222:     case FOP(30, 16):
        !          5223:         check_cp1_64bitmode(ctx);
        !          5224:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5225:         gen_op_float_rsqrt1_s();
        !          5226:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5227:         opn = "rsqrt1.s";
        !          5228:         break;
        !          5229:     case FOP(31, 16):
        !          5230:         check_cp1_64bitmode(ctx);
        !          5231:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5232:         GEN_LOAD_FREG_FTN(WT2, ft);
        !          5233:         gen_op_float_rsqrt2_s();
        !          5234:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5235:         opn = "rsqrt2.s";
        !          5236:         break;
        !          5237:     case FOP(33, 16):
        !          5238:         check_cp1_registers(ctx, fd);
        !          5239:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5240:         gen_op_float_cvtd_s();
        !          5241:         GEN_STORE_FTN_FREG(fd, DT2);
        !          5242:         opn = "cvt.d.s";
        !          5243:         break;
        !          5244:     case FOP(36, 16):
        !          5245:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5246:         gen_op_float_cvtw_s();
        !          5247:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5248:         opn = "cvt.w.s";
        !          5249:         break;
        !          5250:     case FOP(37, 16):
        !          5251:         check_cp1_64bitmode(ctx);
        !          5252:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5253:         gen_op_float_cvtl_s();
        !          5254:         GEN_STORE_FTN_FREG(fd, DT2);
        !          5255:         opn = "cvt.l.s";
        !          5256:         break;
        !          5257:     case FOP(38, 16):
        !          5258:         check_cp1_64bitmode(ctx);
        !          5259:         GEN_LOAD_FREG_FTN(WT1, fs);
        !          5260:         GEN_LOAD_FREG_FTN(WT0, ft);
        !          5261:         gen_op_float_cvtps_s();
        !          5262:         GEN_STORE_FTN_FREG(fd, DT2);
        !          5263:         opn = "cvt.ps.s";
        !          5264:         break;
        !          5265:     case FOP(48, 16):
        !          5266:     case FOP(49, 16):
        !          5267:     case FOP(50, 16):
        !          5268:     case FOP(51, 16):
        !          5269:     case FOP(52, 16):
        !          5270:     case FOP(53, 16):
        !          5271:     case FOP(54, 16):
        !          5272:     case FOP(55, 16):
        !          5273:     case FOP(56, 16):
        !          5274:     case FOP(57, 16):
        !          5275:     case FOP(58, 16):
        !          5276:     case FOP(59, 16):
        !          5277:     case FOP(60, 16):
        !          5278:     case FOP(61, 16):
        !          5279:     case FOP(62, 16):
        !          5280:     case FOP(63, 16):
        !          5281:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5282:         GEN_LOAD_FREG_FTN(WT1, ft);
        !          5283:         if (ctx->opcode & (1 << 6)) {
        !          5284:             check_cop1x(ctx);
        !          5285:             gen_cmpabs_s(func-48, cc);
        !          5286:             opn = condnames_abs[func-48];
        !          5287:         } else {
        !          5288:             gen_cmp_s(func-48, cc);
        !          5289:             opn = condnames[func-48];
        !          5290:         }
        !          5291:         break;
1.1.1.4   root     5292:     case FOP(0, 17):
1.1.1.6 ! root     5293:         check_cp1_registers(ctx, fs | ft | fd);
1.1.1.4   root     5294:         GEN_LOAD_FREG_FTN(DT0, fs);
                   5295:         GEN_LOAD_FREG_FTN(DT1, ft);
                   5296:         gen_op_float_add_d();
                   5297:         GEN_STORE_FTN_FREG(fd, DT2);
                   5298:         opn = "add.d";
1.1.1.6 ! root     5299:         optype = BINOP;
1.1.1.4   root     5300:         break;
                   5301:     case FOP(1, 17):
1.1.1.6 ! root     5302:         check_cp1_registers(ctx, fs | ft | fd);
1.1.1.4   root     5303:         GEN_LOAD_FREG_FTN(DT0, fs);
                   5304:         GEN_LOAD_FREG_FTN(DT1, ft);
                   5305:         gen_op_float_sub_d();
                   5306:         GEN_STORE_FTN_FREG(fd, DT2);
                   5307:         opn = "sub.d";
1.1.1.6 ! root     5308:         optype = BINOP;
1.1.1.4   root     5309:         break;
                   5310:     case FOP(2, 17):
1.1.1.6 ! root     5311:         check_cp1_registers(ctx, fs | ft | fd);
1.1.1.4   root     5312:         GEN_LOAD_FREG_FTN(DT0, fs);
                   5313:         GEN_LOAD_FREG_FTN(DT1, ft);
                   5314:         gen_op_float_mul_d();
                   5315:         GEN_STORE_FTN_FREG(fd, DT2);
                   5316:         opn = "mul.d";
1.1.1.6 ! root     5317:         optype = BINOP;
1.1.1.4   root     5318:         break;
                   5319:     case FOP(3, 17):
1.1.1.6 ! root     5320:         check_cp1_registers(ctx, fs | ft | fd);
1.1.1.4   root     5321:         GEN_LOAD_FREG_FTN(DT0, fs);
                   5322:         GEN_LOAD_FREG_FTN(DT1, ft);
                   5323:         gen_op_float_div_d();
                   5324:         GEN_STORE_FTN_FREG(fd, DT2);
                   5325:         opn = "div.d";
1.1.1.6 ! root     5326:         optype = BINOP;
1.1.1.4   root     5327:         break;
                   5328:     case FOP(4, 17):
1.1.1.6 ! root     5329:         check_cp1_registers(ctx, fs | fd);
1.1.1.4   root     5330:         GEN_LOAD_FREG_FTN(DT0, fs);
                   5331:         gen_op_float_sqrt_d();
                   5332:         GEN_STORE_FTN_FREG(fd, DT2);
                   5333:         opn = "sqrt.d";
                   5334:         break;
                   5335:     case FOP(5, 17):
1.1.1.6 ! root     5336:         check_cp1_registers(ctx, fs | fd);
1.1.1.4   root     5337:         GEN_LOAD_FREG_FTN(DT0, fs);
                   5338:         gen_op_float_abs_d();
                   5339:         GEN_STORE_FTN_FREG(fd, DT2);
                   5340:         opn = "abs.d";
                   5341:         break;
                   5342:     case FOP(6, 17):
1.1.1.6 ! root     5343:         check_cp1_registers(ctx, fs | fd);
1.1.1.4   root     5344:         GEN_LOAD_FREG_FTN(DT0, fs);
                   5345:         gen_op_float_mov_d();
                   5346:         GEN_STORE_FTN_FREG(fd, DT2);
                   5347:         opn = "mov.d";
                   5348:         break;
                   5349:     case FOP(7, 17):
1.1.1.6 ! root     5350:         check_cp1_registers(ctx, fs | fd);
1.1.1.4   root     5351:         GEN_LOAD_FREG_FTN(DT0, fs);
                   5352:         gen_op_float_chs_d();
                   5353:         GEN_STORE_FTN_FREG(fd, DT2);
                   5354:         opn = "neg.d";
                   5355:         break;
1.1.1.6 ! root     5356:     case FOP(8, 17):
        !          5357:         check_cp1_64bitmode(ctx);
        !          5358:         GEN_LOAD_FREG_FTN(DT0, fs);
        !          5359:         gen_op_float_roundl_d();
        !          5360:         GEN_STORE_FTN_FREG(fd, DT2);
        !          5361:         opn = "round.l.d";
        !          5362:         break;
        !          5363:     case FOP(9, 17):
        !          5364:         check_cp1_64bitmode(ctx);
        !          5365:         GEN_LOAD_FREG_FTN(DT0, fs);
        !          5366:         gen_op_float_truncl_d();
        !          5367:         GEN_STORE_FTN_FREG(fd, DT2);
        !          5368:         opn = "trunc.l.d";
        !          5369:         break;
        !          5370:     case FOP(10, 17):
        !          5371:         check_cp1_64bitmode(ctx);
        !          5372:         GEN_LOAD_FREG_FTN(DT0, fs);
        !          5373:         gen_op_float_ceill_d();
        !          5374:         GEN_STORE_FTN_FREG(fd, DT2);
        !          5375:         opn = "ceil.l.d";
        !          5376:         break;
        !          5377:     case FOP(11, 17):
        !          5378:         check_cp1_64bitmode(ctx);
        !          5379:         GEN_LOAD_FREG_FTN(DT0, fs);
        !          5380:         gen_op_float_floorl_d();
        !          5381:         GEN_STORE_FTN_FREG(fd, DT2);
        !          5382:         opn = "floor.l.d";
        !          5383:         break;
1.1.1.4   root     5384:     case FOP(12, 17):
1.1.1.6 ! root     5385:         check_cp1_registers(ctx, fs);
1.1.1.4   root     5386:         GEN_LOAD_FREG_FTN(DT0, fs);
                   5387:         gen_op_float_roundw_d();
                   5388:         GEN_STORE_FTN_FREG(fd, WT2);
                   5389:         opn = "round.w.d";
                   5390:         break;
                   5391:     case FOP(13, 17):
1.1.1.6 ! root     5392:         check_cp1_registers(ctx, fs);
1.1.1.4   root     5393:         GEN_LOAD_FREG_FTN(DT0, fs);
                   5394:         gen_op_float_truncw_d();
                   5395:         GEN_STORE_FTN_FREG(fd, WT2);
                   5396:         opn = "trunc.w.d";
                   5397:         break;
                   5398:     case FOP(14, 17):
1.1.1.6 ! root     5399:         check_cp1_registers(ctx, fs);
1.1.1.4   root     5400:         GEN_LOAD_FREG_FTN(DT0, fs);
                   5401:         gen_op_float_ceilw_d();
                   5402:         GEN_STORE_FTN_FREG(fd, WT2);
                   5403:         opn = "ceil.w.d";
                   5404:         break;
                   5405:     case FOP(15, 17):
1.1.1.6 ! root     5406:         check_cp1_registers(ctx, fs);
1.1.1.4   root     5407:         GEN_LOAD_FREG_FTN(DT0, fs);
                   5408:         gen_op_float_floorw_d();
                   5409:         GEN_STORE_FTN_FREG(fd, WT2);
1.1.1.5   root     5410:         opn = "floor.w.d";
                   5411:         break;
1.1.1.6 ! root     5412:     case FOP(17, 17):
        !          5413:         GEN_LOAD_REG_T0(ft);
        !          5414:         GEN_LOAD_FREG_FTN(DT0, fs);
        !          5415:         GEN_LOAD_FREG_FTN(DT2, fd);
        !          5416:         gen_movcf_d(ctx, (ft >> 2) & 0x7, ft & 0x1);
1.1.1.5   root     5417:         GEN_STORE_FTN_FREG(fd, DT2);
1.1.1.6 ! root     5418:         opn = "movcf.d";
1.1.1.4   root     5419:         break;
1.1.1.6 ! root     5420:     case FOP(18, 17):
        !          5421:         GEN_LOAD_REG_T0(ft);
        !          5422:         GEN_LOAD_FREG_FTN(DT0, fs);
        !          5423:         GEN_LOAD_FREG_FTN(DT2, fd);
        !          5424:         gen_op_float_movz_d();
1.1.1.4   root     5425:         GEN_STORE_FTN_FREG(fd, DT2);
1.1.1.6 ! root     5426:         opn = "movz.d";
        !          5427:         break;
        !          5428:     case FOP(19, 17):
        !          5429:         GEN_LOAD_REG_T0(ft);
        !          5430:         GEN_LOAD_FREG_FTN(DT0, fs);
        !          5431:         GEN_LOAD_FREG_FTN(DT2, fd);
        !          5432:         gen_op_float_movn_d();
        !          5433:         GEN_STORE_FTN_FREG(fd, DT2);
        !          5434:         opn = "movn.d";
        !          5435:         break;
        !          5436:     case FOP(21, 17):
        !          5437:         check_cp1_64bitmode(ctx);
        !          5438:         GEN_LOAD_FREG_FTN(DT0, fs);
        !          5439:         gen_op_float_recip_d();
        !          5440:         GEN_STORE_FTN_FREG(fd, DT2);
        !          5441:         opn = "recip.d";
        !          5442:         break;
        !          5443:     case FOP(22, 17):
        !          5444:         check_cp1_64bitmode(ctx);
        !          5445:         GEN_LOAD_FREG_FTN(DT0, fs);
        !          5446:         gen_op_float_rsqrt_d();
        !          5447:         GEN_STORE_FTN_FREG(fd, DT2);
        !          5448:         opn = "rsqrt.d";
        !          5449:         break;
        !          5450:     case FOP(28, 17):
        !          5451:         check_cp1_64bitmode(ctx);
        !          5452:         GEN_LOAD_FREG_FTN(DT0, fs);
        !          5453:         GEN_LOAD_FREG_FTN(DT2, ft);
        !          5454:         gen_op_float_recip2_d();
        !          5455:         GEN_STORE_FTN_FREG(fd, DT2);
        !          5456:         opn = "recip2.d";
        !          5457:         break;
        !          5458:     case FOP(29, 17):
        !          5459:         check_cp1_64bitmode(ctx);
        !          5460:         GEN_LOAD_FREG_FTN(DT0, fs);
        !          5461:         gen_op_float_recip1_d();
        !          5462:         GEN_STORE_FTN_FREG(fd, DT2);
        !          5463:         opn = "recip1.d";
        !          5464:         break;
        !          5465:     case FOP(30, 17):
        !          5466:         check_cp1_64bitmode(ctx);
        !          5467:         GEN_LOAD_FREG_FTN(DT0, fs);
        !          5468:         gen_op_float_rsqrt1_d();
        !          5469:         GEN_STORE_FTN_FREG(fd, DT2);
        !          5470:         opn = "rsqrt1.d";
        !          5471:         break;
        !          5472:     case FOP(31, 17):
        !          5473:         check_cp1_64bitmode(ctx);
        !          5474:         GEN_LOAD_FREG_FTN(DT0, fs);
        !          5475:         GEN_LOAD_FREG_FTN(DT2, ft);
        !          5476:         gen_op_float_rsqrt2_d();
        !          5477:         GEN_STORE_FTN_FREG(fd, DT2);
        !          5478:         opn = "rsqrt2.d";
1.1.1.4   root     5479:         break;
                   5480:     case FOP(48, 17):
                   5481:     case FOP(49, 17):
                   5482:     case FOP(50, 17):
                   5483:     case FOP(51, 17):
                   5484:     case FOP(52, 17):
                   5485:     case FOP(53, 17):
                   5486:     case FOP(54, 17):
                   5487:     case FOP(55, 17):
                   5488:     case FOP(56, 17):
                   5489:     case FOP(57, 17):
                   5490:     case FOP(58, 17):
                   5491:     case FOP(59, 17):
                   5492:     case FOP(60, 17):
                   5493:     case FOP(61, 17):
                   5494:     case FOP(62, 17):
                   5495:     case FOP(63, 17):
                   5496:         GEN_LOAD_FREG_FTN(DT0, fs);
                   5497:         GEN_LOAD_FREG_FTN(DT1, ft);
1.1.1.6 ! root     5498:         if (ctx->opcode & (1 << 6)) {
        !          5499:             check_cop1x(ctx);
        !          5500:             check_cp1_registers(ctx, fs | ft);
        !          5501:             gen_cmpabs_d(func-48, cc);
        !          5502:             opn = condnames_abs[func-48];
        !          5503:         } else {
        !          5504:             check_cp1_registers(ctx, fs | ft);
        !          5505:             gen_cmp_d(func-48, cc);
        !          5506:             opn = condnames[func-48];
        !          5507:         }
        !          5508:         break;
        !          5509:     case FOP(32, 17):
        !          5510:         check_cp1_registers(ctx, fs);
        !          5511:         GEN_LOAD_FREG_FTN(DT0, fs);
        !          5512:         gen_op_float_cvts_d();
        !          5513:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5514:         opn = "cvt.s.d";
        !          5515:         break;
        !          5516:     case FOP(36, 17):
        !          5517:         check_cp1_registers(ctx, fs);
        !          5518:         GEN_LOAD_FREG_FTN(DT0, fs);
        !          5519:         gen_op_float_cvtw_d();
        !          5520:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5521:         opn = "cvt.w.d";
        !          5522:         break;
        !          5523:     case FOP(37, 17):
        !          5524:         check_cp1_64bitmode(ctx);
        !          5525:         GEN_LOAD_FREG_FTN(DT0, fs);
        !          5526:         gen_op_float_cvtl_d();
        !          5527:         GEN_STORE_FTN_FREG(fd, DT2);
        !          5528:         opn = "cvt.l.d";
        !          5529:         break;
        !          5530:     case FOP(32, 20):
        !          5531:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5532:         gen_op_float_cvts_w();
        !          5533:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5534:         opn = "cvt.s.w";
        !          5535:         break;
        !          5536:     case FOP(33, 20):
        !          5537:         check_cp1_registers(ctx, fd);
        !          5538:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5539:         gen_op_float_cvtd_w();
        !          5540:         GEN_STORE_FTN_FREG(fd, DT2);
        !          5541:         opn = "cvt.d.w";
        !          5542:         break;
        !          5543:     case FOP(32, 21):
        !          5544:         check_cp1_64bitmode(ctx);
        !          5545:         GEN_LOAD_FREG_FTN(DT0, fs);
        !          5546:         gen_op_float_cvts_l();
        !          5547:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5548:         opn = "cvt.s.l";
        !          5549:         break;
        !          5550:     case FOP(33, 21):
        !          5551:         check_cp1_64bitmode(ctx);
        !          5552:         GEN_LOAD_FREG_FTN(DT0, fs);
        !          5553:         gen_op_float_cvtd_l();
        !          5554:         GEN_STORE_FTN_FREG(fd, DT2);
        !          5555:         opn = "cvt.d.l";
        !          5556:         break;
        !          5557:     case FOP(38, 20):
        !          5558:         check_cp1_64bitmode(ctx);
        !          5559:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5560:         GEN_LOAD_FREG_FTN(WTH0, fs);
        !          5561:         gen_op_float_cvtps_pw();
        !          5562:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5563:         GEN_STORE_FTN_FREG(fd, WTH2);
        !          5564:         opn = "cvt.ps.pw";
        !          5565:         break;
        !          5566:     case FOP(0, 22):
        !          5567:         check_cp1_64bitmode(ctx);
        !          5568:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5569:         GEN_LOAD_FREG_FTN(WTH0, fs);
        !          5570:         GEN_LOAD_FREG_FTN(WT1, ft);
        !          5571:         GEN_LOAD_FREG_FTN(WTH1, ft);
        !          5572:         gen_op_float_add_ps();
        !          5573:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5574:         GEN_STORE_FTN_FREG(fd, WTH2);
        !          5575:         opn = "add.ps";
        !          5576:         break;
        !          5577:     case FOP(1, 22):
        !          5578:         check_cp1_64bitmode(ctx);
        !          5579:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5580:         GEN_LOAD_FREG_FTN(WTH0, fs);
        !          5581:         GEN_LOAD_FREG_FTN(WT1, ft);
        !          5582:         GEN_LOAD_FREG_FTN(WTH1, ft);
        !          5583:         gen_op_float_sub_ps();
        !          5584:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5585:         GEN_STORE_FTN_FREG(fd, WTH2);
        !          5586:         opn = "sub.ps";
        !          5587:         break;
        !          5588:     case FOP(2, 22):
        !          5589:         check_cp1_64bitmode(ctx);
        !          5590:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5591:         GEN_LOAD_FREG_FTN(WTH0, fs);
        !          5592:         GEN_LOAD_FREG_FTN(WT1, ft);
        !          5593:         GEN_LOAD_FREG_FTN(WTH1, ft);
        !          5594:         gen_op_float_mul_ps();
        !          5595:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5596:         GEN_STORE_FTN_FREG(fd, WTH2);
        !          5597:         opn = "mul.ps";
        !          5598:         break;
        !          5599:     case FOP(5, 22):
        !          5600:         check_cp1_64bitmode(ctx);
        !          5601:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5602:         GEN_LOAD_FREG_FTN(WTH0, fs);
        !          5603:         gen_op_float_abs_ps();
        !          5604:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5605:         GEN_STORE_FTN_FREG(fd, WTH2);
        !          5606:         opn = "abs.ps";
        !          5607:         break;
        !          5608:     case FOP(6, 22):
        !          5609:         check_cp1_64bitmode(ctx);
        !          5610:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5611:         GEN_LOAD_FREG_FTN(WTH0, fs);
        !          5612:         gen_op_float_mov_ps();
        !          5613:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5614:         GEN_STORE_FTN_FREG(fd, WTH2);
        !          5615:         opn = "mov.ps";
        !          5616:         break;
        !          5617:     case FOP(7, 22):
        !          5618:         check_cp1_64bitmode(ctx);
        !          5619:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5620:         GEN_LOAD_FREG_FTN(WTH0, fs);
        !          5621:         gen_op_float_chs_ps();
        !          5622:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5623:         GEN_STORE_FTN_FREG(fd, WTH2);
        !          5624:         opn = "neg.ps";
        !          5625:         break;
        !          5626:     case FOP(17, 22):
        !          5627:         check_cp1_64bitmode(ctx);
        !          5628:         GEN_LOAD_REG_T0(ft);
        !          5629:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5630:         GEN_LOAD_FREG_FTN(WTH0, fs);
        !          5631:         GEN_LOAD_FREG_FTN(WT2, fd);
        !          5632:         GEN_LOAD_FREG_FTN(WTH2, fd);
        !          5633:         gen_movcf_ps(ctx, (ft >> 2) & 0x7, ft & 0x1);
        !          5634:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5635:         GEN_STORE_FTN_FREG(fd, WTH2);
        !          5636:         opn = "movcf.ps";
        !          5637:         break;
        !          5638:     case FOP(18, 22):
        !          5639:         check_cp1_64bitmode(ctx);
        !          5640:         GEN_LOAD_REG_T0(ft);
        !          5641:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5642:         GEN_LOAD_FREG_FTN(WTH0, fs);
        !          5643:         GEN_LOAD_FREG_FTN(WT2, fd);
        !          5644:         GEN_LOAD_FREG_FTN(WTH2, fd);
        !          5645:         gen_op_float_movz_ps();
        !          5646:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5647:         GEN_STORE_FTN_FREG(fd, WTH2);
        !          5648:         opn = "movz.ps";
        !          5649:         break;
        !          5650:     case FOP(19, 22):
        !          5651:         check_cp1_64bitmode(ctx);
        !          5652:         GEN_LOAD_REG_T0(ft);
        !          5653:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5654:         GEN_LOAD_FREG_FTN(WTH0, fs);
        !          5655:         GEN_LOAD_FREG_FTN(WT2, fd);
        !          5656:         GEN_LOAD_FREG_FTN(WTH2, fd);
        !          5657:         gen_op_float_movn_ps();
        !          5658:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5659:         GEN_STORE_FTN_FREG(fd, WTH2);
        !          5660:         opn = "movn.ps";
        !          5661:         break;
        !          5662:     case FOP(24, 22):
        !          5663:         check_cp1_64bitmode(ctx);
        !          5664:         GEN_LOAD_FREG_FTN(WT0, ft);
        !          5665:         GEN_LOAD_FREG_FTN(WTH0, ft);
        !          5666:         GEN_LOAD_FREG_FTN(WT1, fs);
        !          5667:         GEN_LOAD_FREG_FTN(WTH1, fs);
        !          5668:         gen_op_float_addr_ps();
        !          5669:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5670:         GEN_STORE_FTN_FREG(fd, WTH2);
        !          5671:         opn = "addr.ps";
        !          5672:         break;
        !          5673:     case FOP(26, 22):
        !          5674:         check_cp1_64bitmode(ctx);
        !          5675:         GEN_LOAD_FREG_FTN(WT0, ft);
        !          5676:         GEN_LOAD_FREG_FTN(WTH0, ft);
        !          5677:         GEN_LOAD_FREG_FTN(WT1, fs);
        !          5678:         GEN_LOAD_FREG_FTN(WTH1, fs);
        !          5679:         gen_op_float_mulr_ps();
        !          5680:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5681:         GEN_STORE_FTN_FREG(fd, WTH2);
        !          5682:         opn = "mulr.ps";
        !          5683:         break;
        !          5684:     case FOP(28, 22):
        !          5685:         check_cp1_64bitmode(ctx);
        !          5686:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5687:         GEN_LOAD_FREG_FTN(WTH0, fs);
        !          5688:         GEN_LOAD_FREG_FTN(WT2, fd);
        !          5689:         GEN_LOAD_FREG_FTN(WTH2, fd);
        !          5690:         gen_op_float_recip2_ps();
        !          5691:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5692:         GEN_STORE_FTN_FREG(fd, WTH2);
        !          5693:         opn = "recip2.ps";
        !          5694:         break;
        !          5695:     case FOP(29, 22):
        !          5696:         check_cp1_64bitmode(ctx);
        !          5697:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5698:         GEN_LOAD_FREG_FTN(WTH0, fs);
        !          5699:         gen_op_float_recip1_ps();
        !          5700:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5701:         GEN_STORE_FTN_FREG(fd, WTH2);
        !          5702:         opn = "recip1.ps";
        !          5703:         break;
        !          5704:     case FOP(30, 22):
        !          5705:         check_cp1_64bitmode(ctx);
        !          5706:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5707:         GEN_LOAD_FREG_FTN(WTH0, fs);
        !          5708:         gen_op_float_rsqrt1_ps();
        !          5709:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5710:         GEN_STORE_FTN_FREG(fd, WTH2);
        !          5711:         opn = "rsqrt1.ps";
        !          5712:         break;
        !          5713:     case FOP(31, 22):
        !          5714:         check_cp1_64bitmode(ctx);
        !          5715:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5716:         GEN_LOAD_FREG_FTN(WTH0, fs);
        !          5717:         GEN_LOAD_FREG_FTN(WT2, ft);
        !          5718:         GEN_LOAD_FREG_FTN(WTH2, ft);
        !          5719:         gen_op_float_rsqrt2_ps();
        !          5720:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5721:         GEN_STORE_FTN_FREG(fd, WTH2);
        !          5722:         opn = "rsqrt2.ps";
        !          5723:         break;
        !          5724:     case FOP(32, 22):
        !          5725:         check_cp1_64bitmode(ctx);
        !          5726:         GEN_LOAD_FREG_FTN(WTH0, fs);
        !          5727:         gen_op_float_cvts_pu();
        !          5728:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5729:         opn = "cvt.s.pu";
        !          5730:         break;
        !          5731:     case FOP(36, 22):
        !          5732:         check_cp1_64bitmode(ctx);
        !          5733:         GEN_LOAD_FREG_FTN(WT0, fs);
        !          5734:         GEN_LOAD_FREG_FTN(WTH0, fs);
        !          5735:         gen_op_float_cvtpw_ps();
        !          5736:         GEN_STORE_FTN_FREG(fd, WT2);
        !          5737:         GEN_STORE_FTN_FREG(fd, WTH2);
        !          5738:         opn = "cvt.pw.ps";
1.1.1.4   root     5739:         break;
1.1.1.6 ! root     5740:     case FOP(40, 22):
        !          5741:         check_cp1_64bitmode(ctx);
1.1.1.4   root     5742:         GEN_LOAD_FREG_FTN(WT0, fs);
1.1.1.6 ! root     5743:         gen_op_float_cvts_pl();
1.1.1.4   root     5744:         GEN_STORE_FTN_FREG(fd, WT2);
1.1.1.6 ! root     5745:         opn = "cvt.s.pl";
1.1.1.4   root     5746:         break;
1.1.1.6 ! root     5747:     case FOP(44, 22):
        !          5748:         check_cp1_64bitmode(ctx);
1.1.1.4   root     5749:         GEN_LOAD_FREG_FTN(WT0, fs);
                   5750:         GEN_LOAD_FREG_FTN(WT1, ft);
1.1.1.6 ! root     5751:         gen_op_float_pll_ps();
        !          5752:         GEN_STORE_FTN_FREG(fd, DT2);
        !          5753:         opn = "pll.ps";
1.1.1.4   root     5754:         break;
1.1.1.6 ! root     5755:     case FOP(45, 22):
        !          5756:         check_cp1_64bitmode(ctx);
1.1.1.4   root     5757:         GEN_LOAD_FREG_FTN(WT0, fs);
1.1.1.6 ! root     5758:         GEN_LOAD_FREG_FTN(WTH1, ft);
        !          5759:         gen_op_float_plu_ps();
        !          5760:         GEN_STORE_FTN_FREG(fd, DT2);
        !          5761:         opn = "plu.ps";
        !          5762:         break;
        !          5763:     case FOP(46, 22):
        !          5764:         check_cp1_64bitmode(ctx);
        !          5765:         GEN_LOAD_FREG_FTN(WTH0, fs);
1.1.1.4   root     5766:         GEN_LOAD_FREG_FTN(WT1, ft);
1.1.1.6 ! root     5767:         gen_op_float_pul_ps();
        !          5768:         GEN_STORE_FTN_FREG(fd, DT2);
        !          5769:         opn = "pul.ps";
1.1.1.4   root     5770:         break;
1.1.1.6 ! root     5771:     case FOP(47, 22):
        !          5772:         check_cp1_64bitmode(ctx);
        !          5773:         GEN_LOAD_FREG_FTN(WTH0, fs);
        !          5774:         GEN_LOAD_FREG_FTN(WTH1, ft);
        !          5775:         gen_op_float_puu_ps();
        !          5776:         GEN_STORE_FTN_FREG(fd, DT2);
        !          5777:         opn = "puu.ps";
        !          5778:         break;
        !          5779:     case FOP(48, 22):
        !          5780:     case FOP(49, 22):
        !          5781:     case FOP(50, 22):
        !          5782:     case FOP(51, 22):
        !          5783:     case FOP(52, 22):
        !          5784:     case FOP(53, 22):
        !          5785:     case FOP(54, 22):
        !          5786:     case FOP(55, 22):
        !          5787:     case FOP(56, 22):
        !          5788:     case FOP(57, 22):
        !          5789:     case FOP(58, 22):
        !          5790:     case FOP(59, 22):
        !          5791:     case FOP(60, 22):
        !          5792:     case FOP(61, 22):
        !          5793:     case FOP(62, 22):
        !          5794:     case FOP(63, 22):
        !          5795:         check_cp1_64bitmode(ctx);
1.1.1.4   root     5796:         GEN_LOAD_FREG_FTN(WT0, fs);
1.1.1.6 ! root     5797:         GEN_LOAD_FREG_FTN(WTH0, fs);
1.1.1.4   root     5798:         GEN_LOAD_FREG_FTN(WT1, ft);
1.1.1.6 ! root     5799:         GEN_LOAD_FREG_FTN(WTH1, ft);
        !          5800:         if (ctx->opcode & (1 << 6)) {
        !          5801:             gen_cmpabs_ps(func-48, cc);
        !          5802:             opn = condnames_abs[func-48];
        !          5803:         } else {
        !          5804:             gen_cmp_ps(func-48, cc);
        !          5805:             opn = condnames[func-48];
        !          5806:         }
1.1.1.4   root     5807:         break;
1.1.1.6 ! root     5808:     default:
        !          5809:         MIPS_INVAL(opn);
        !          5810:         generate_exception (ctx, EXCP_RI);
        !          5811:         return;
        !          5812:     }
        !          5813:     switch (optype) {
        !          5814:     case BINOP:
        !          5815:         MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
        !          5816:         break;
        !          5817:     case CMPOP:
        !          5818:         MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
        !          5819:         break;
        !          5820:     default:
        !          5821:         MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
        !          5822:         break;
        !          5823:     }
        !          5824: }
        !          5825: 
        !          5826: /* Coprocessor 3 (FPU) */
        !          5827: static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
        !          5828:                            int fd, int fs, int base, int index)
        !          5829: {
        !          5830:     const char *opn = "extended float load/store";
        !          5831:     int store = 0;
        !          5832: 
        !          5833:     if (base == 0) {
        !          5834:         if (index == 0)
        !          5835:             gen_op_reset_T0();
        !          5836:         else
        !          5837:             GEN_LOAD_REG_T0(index);
        !          5838:     } else if (index == 0) {
        !          5839:         GEN_LOAD_REG_T0(base);
        !          5840:     } else {
        !          5841:         GEN_LOAD_REG_T0(base);
        !          5842:         GEN_LOAD_REG_T1(index);
        !          5843:         gen_op_addr_add();
        !          5844:     }
        !          5845:     /* Don't do NOP if destination is zero: we must perform the actual
        !          5846:        memory access. */
        !          5847:     switch (opc) {
        !          5848:     case OPC_LWXC1:
        !          5849:         check_cop1x(ctx);
        !          5850:         op_ldst(lwc1);
        !          5851:         GEN_STORE_FTN_FREG(fd, WT0);
        !          5852:         opn = "lwxc1";
        !          5853:         break;
        !          5854:     case OPC_LDXC1:
        !          5855:         check_cop1x(ctx);
        !          5856:         check_cp1_registers(ctx, fd);
        !          5857:         op_ldst(ldc1);
        !          5858:         GEN_STORE_FTN_FREG(fd, DT0);
        !          5859:         opn = "ldxc1";
        !          5860:         break;
        !          5861:     case OPC_LUXC1:
        !          5862:         check_cp1_64bitmode(ctx);
        !          5863:         op_ldst(luxc1);
        !          5864:         GEN_STORE_FTN_FREG(fd, DT0);
        !          5865:         opn = "luxc1";
        !          5866:         break;
        !          5867:     case OPC_SWXC1:
        !          5868:         check_cop1x(ctx);
1.1.1.4   root     5869:         GEN_LOAD_FREG_FTN(WT0, fs);
1.1.1.6 ! root     5870:         op_ldst(swc1);
        !          5871:         opn = "swxc1";
        !          5872:         store = 1;
1.1.1.4   root     5873:         break;
1.1.1.6 ! root     5874:     case OPC_SDXC1:
        !          5875:         check_cop1x(ctx);
        !          5876:         check_cp1_registers(ctx, fs);
        !          5877:         GEN_LOAD_FREG_FTN(DT0, fs);
        !          5878:         op_ldst(sdc1);
        !          5879:         opn = "sdxc1";
        !          5880:         store = 1;
        !          5881:         break;
        !          5882:     case OPC_SUXC1:
        !          5883:         check_cp1_64bitmode(ctx);
        !          5884:         GEN_LOAD_FREG_FTN(DT0, fs);
        !          5885:         op_ldst(suxc1);
        !          5886:         opn = "suxc1";
        !          5887:         store = 1;
        !          5888:         break;
        !          5889:     default:
        !          5890:         MIPS_INVAL(opn);
        !          5891:         generate_exception(ctx, EXCP_RI);
        !          5892:         return;
        !          5893:     }
        !          5894:     MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
        !          5895:                regnames[index], regnames[base]);
        !          5896: }
        !          5897: 
        !          5898: static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
        !          5899:                             int fd, int fr, int fs, int ft)
        !          5900: {
        !          5901:     const char *opn = "flt3_arith";
        !          5902: 
        !          5903:     switch (opc) {
        !          5904:     case OPC_ALNV_PS:
        !          5905:         check_cp1_64bitmode(ctx);
        !          5906:         GEN_LOAD_REG_T0(fr);
        !          5907:         GEN_LOAD_FREG_FTN(DT0, fs);
        !          5908:         GEN_LOAD_FREG_FTN(DT1, ft);
        !          5909:         gen_op_float_alnv_ps();
        !          5910:         GEN_STORE_FTN_FREG(fd, DT2);
        !          5911:         opn = "alnv.ps";
        !          5912:         break;
        !          5913:     case OPC_MADD_S:
        !          5914:         check_cop1x(ctx);
1.1.1.4   root     5915:         GEN_LOAD_FREG_FTN(WT0, fs);
1.1.1.6 ! root     5916:         GEN_LOAD_FREG_FTN(WT1, ft);
        !          5917:         GEN_LOAD_FREG_FTN(WT2, fr);
        !          5918:         gen_op_float_muladd_s();
1.1.1.4   root     5919:         GEN_STORE_FTN_FREG(fd, WT2);
1.1.1.6 ! root     5920:         opn = "madd.s";
1.1.1.4   root     5921:         break;
1.1.1.6 ! root     5922:     case OPC_MADD_D:
        !          5923:         check_cop1x(ctx);
        !          5924:         check_cp1_registers(ctx, fd | fs | ft | fr);
        !          5925:         GEN_LOAD_FREG_FTN(DT0, fs);
        !          5926:         GEN_LOAD_FREG_FTN(DT1, ft);
        !          5927:         GEN_LOAD_FREG_FTN(DT2, fr);
        !          5928:         gen_op_float_muladd_d();
        !          5929:         GEN_STORE_FTN_FREG(fd, DT2);
        !          5930:         opn = "madd.d";
        !          5931:         break;
        !          5932:     case OPC_MADD_PS:
        !          5933:         check_cp1_64bitmode(ctx);
1.1.1.4   root     5934:         GEN_LOAD_FREG_FTN(WT0, fs);
1.1.1.6 ! root     5935:         GEN_LOAD_FREG_FTN(WTH0, fs);
        !          5936:         GEN_LOAD_FREG_FTN(WT1, ft);
        !          5937:         GEN_LOAD_FREG_FTN(WTH1, ft);
        !          5938:         GEN_LOAD_FREG_FTN(WT2, fr);
        !          5939:         GEN_LOAD_FREG_FTN(WTH2, fr);
        !          5940:         gen_op_float_muladd_ps();
1.1.1.4   root     5941:         GEN_STORE_FTN_FREG(fd, WT2);
1.1.1.6 ! root     5942:         GEN_STORE_FTN_FREG(fd, WTH2);
        !          5943:         opn = "madd.ps";
1.1.1.4   root     5944:         break;
1.1.1.6 ! root     5945:     case OPC_MSUB_S:
        !          5946:         check_cop1x(ctx);
1.1.1.4   root     5947:         GEN_LOAD_FREG_FTN(WT0, fs);
1.1.1.6 ! root     5948:         GEN_LOAD_FREG_FTN(WT1, ft);
        !          5949:         GEN_LOAD_FREG_FTN(WT2, fr);
        !          5950:         gen_op_float_mulsub_s();
1.1.1.4   root     5951:         GEN_STORE_FTN_FREG(fd, WT2);
1.1.1.6 ! root     5952:         opn = "msub.s";
1.1.1.4   root     5953:         break;
1.1.1.6 ! root     5954:     case OPC_MSUB_D:
        !          5955:         check_cop1x(ctx);
        !          5956:         check_cp1_registers(ctx, fd | fs | ft | fr);
        !          5957:         GEN_LOAD_FREG_FTN(DT0, fs);
        !          5958:         GEN_LOAD_FREG_FTN(DT1, ft);
        !          5959:         GEN_LOAD_FREG_FTN(DT2, fr);
        !          5960:         gen_op_float_mulsub_d();
        !          5961:         GEN_STORE_FTN_FREG(fd, DT2);
        !          5962:         opn = "msub.d";
        !          5963:         break;
        !          5964:     case OPC_MSUB_PS:
        !          5965:         check_cp1_64bitmode(ctx);
1.1.1.4   root     5966:         GEN_LOAD_FREG_FTN(WT0, fs);
1.1.1.6 ! root     5967:         GEN_LOAD_FREG_FTN(WTH0, fs);
        !          5968:         GEN_LOAD_FREG_FTN(WT1, ft);
        !          5969:         GEN_LOAD_FREG_FTN(WTH1, ft);
        !          5970:         GEN_LOAD_FREG_FTN(WT2, fr);
        !          5971:         GEN_LOAD_FREG_FTN(WTH2, fr);
        !          5972:         gen_op_float_mulsub_ps();
1.1.1.4   root     5973:         GEN_STORE_FTN_FREG(fd, WT2);
1.1.1.6 ! root     5974:         GEN_STORE_FTN_FREG(fd, WTH2);
        !          5975:         opn = "msub.ps";
1.1.1.4   root     5976:         break;
1.1.1.6 ! root     5977:     case OPC_NMADD_S:
        !          5978:         check_cop1x(ctx);
1.1.1.4   root     5979:         GEN_LOAD_FREG_FTN(WT0, fs);
1.1.1.6 ! root     5980:         GEN_LOAD_FREG_FTN(WT1, ft);
        !          5981:         GEN_LOAD_FREG_FTN(WT2, fr);
        !          5982:         gen_op_float_nmuladd_s();
1.1.1.4   root     5983:         GEN_STORE_FTN_FREG(fd, WT2);
1.1.1.6 ! root     5984:         opn = "nmadd.s";
1.1.1.4   root     5985:         break;
1.1.1.6 ! root     5986:     case OPC_NMADD_D:
        !          5987:         check_cop1x(ctx);
        !          5988:         check_cp1_registers(ctx, fd | fs | ft | fr);
1.1.1.5   root     5989:         GEN_LOAD_FREG_FTN(DT0, fs);
1.1.1.6 ! root     5990:         GEN_LOAD_FREG_FTN(DT1, ft);
        !          5991:         GEN_LOAD_FREG_FTN(DT2, fr);
        !          5992:         gen_op_float_nmuladd_d();
        !          5993:         GEN_STORE_FTN_FREG(fd, DT2);
        !          5994:         opn = "nmadd.d";
1.1.1.5   root     5995:         break;
1.1.1.6 ! root     5996:     case OPC_NMADD_PS:
        !          5997:         check_cp1_64bitmode(ctx);
1.1.1.4   root     5998:         GEN_LOAD_FREG_FTN(WT0, fs);
1.1.1.6 ! root     5999:         GEN_LOAD_FREG_FTN(WTH0, fs);
        !          6000:         GEN_LOAD_FREG_FTN(WT1, ft);
        !          6001:         GEN_LOAD_FREG_FTN(WTH1, ft);
        !          6002:         GEN_LOAD_FREG_FTN(WT2, fr);
        !          6003:         GEN_LOAD_FREG_FTN(WTH2, fr);
        !          6004:         gen_op_float_nmuladd_ps();
1.1.1.4   root     6005:         GEN_STORE_FTN_FREG(fd, WT2);
1.1.1.6 ! root     6006:         GEN_STORE_FTN_FREG(fd, WTH2);
        !          6007:         opn = "nmadd.ps";
1.1.1.4   root     6008:         break;
1.1.1.6 ! root     6009:     case OPC_NMSUB_S:
        !          6010:         check_cop1x(ctx);
1.1.1.4   root     6011:         GEN_LOAD_FREG_FTN(WT0, fs);
1.1.1.6 ! root     6012:         GEN_LOAD_FREG_FTN(WT1, ft);
        !          6013:         GEN_LOAD_FREG_FTN(WT2, fr);
        !          6014:         gen_op_float_nmulsub_s();
1.1.1.4   root     6015:         GEN_STORE_FTN_FREG(fd, WT2);
1.1.1.6 ! root     6016:         opn = "nmsub.s";
1.1.1.4   root     6017:         break;
1.1.1.6 ! root     6018:     case OPC_NMSUB_D:
        !          6019:         check_cop1x(ctx);
        !          6020:         check_cp1_registers(ctx, fd | fs | ft | fr);
1.1.1.5   root     6021:         GEN_LOAD_FREG_FTN(DT0, fs);
1.1.1.6 ! root     6022:         GEN_LOAD_FREG_FTN(DT1, ft);
        !          6023:         GEN_LOAD_FREG_FTN(DT2, fr);
        !          6024:         gen_op_float_nmulsub_d();
        !          6025:         GEN_STORE_FTN_FREG(fd, DT2);
        !          6026:         opn = "nmsub.d";
1.1.1.4   root     6027:         break;
1.1.1.6 ! root     6028:     case OPC_NMSUB_PS:
        !          6029:         check_cp1_64bitmode(ctx);
1.1.1.4   root     6030:         GEN_LOAD_FREG_FTN(WT0, fs);
1.1.1.6 ! root     6031:         GEN_LOAD_FREG_FTN(WTH0, fs);
1.1.1.4   root     6032:         GEN_LOAD_FREG_FTN(WT1, ft);
1.1.1.6 ! root     6033:         GEN_LOAD_FREG_FTN(WTH1, ft);
        !          6034:         GEN_LOAD_FREG_FTN(WT2, fr);
        !          6035:         GEN_LOAD_FREG_FTN(WTH2, fr);
        !          6036:         gen_op_float_nmulsub_ps();
        !          6037:         GEN_STORE_FTN_FREG(fd, WT2);
        !          6038:         GEN_STORE_FTN_FREG(fd, WTH2);
        !          6039:         opn = "nmsub.ps";
1.1.1.4   root     6040:         break;
1.1.1.6 ! root     6041:     default:
        !          6042:         MIPS_INVAL(opn);
        !          6043:         generate_exception (ctx, EXCP_RI);
1.1.1.4   root     6044:         return;
                   6045:     }
1.1.1.6 ! root     6046:     MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
        !          6047:                fregnames[fs], fregnames[ft]);
1.1       root     6048: }
                   6049: 
1.1.1.5   root     6050: /* ISA extensions (ASEs) */
                   6051: /* MIPS16 extension to MIPS32 */
                   6052: /* SmartMIPS extension to MIPS32 */
                   6053: 
1.1.1.6 ! root     6054: #if defined(TARGET_MIPS64)
1.1       root     6055: 
                   6056: /* MDMX extension to MIPS64 */
                   6057: 
                   6058: #endif
                   6059: 
1.1.1.6 ! root     6060: static void decode_opc (CPUState *env, DisasContext *ctx)
1.1       root     6061: {
                   6062:     int32_t offset;
                   6063:     int rs, rt, rd, sa;
1.1.1.5   root     6064:     uint32_t op, op1, op2;
1.1       root     6065:     int16_t imm;
                   6066: 
1.1.1.4   root     6067:     /* make sure instructions are on a word boundary */
                   6068:     if (ctx->pc & 0x3) {
1.1.1.6 ! root     6069:         env->CP0_BadVAddr = ctx->pc;
1.1.1.4   root     6070:         generate_exception(ctx, EXCP_AdEL);
                   6071:         return;
                   6072:     }
                   6073: 
1.1.1.2   root     6074:     if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
1.1.1.6 ! root     6075:         int l1;
1.1       root     6076:         /* Handle blikely not taken case */
1.1.1.6 ! root     6077:         MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
        !          6078:         l1 = gen_new_label();
        !          6079:         gen_op_jnz_T2(l1);
        !          6080:         gen_op_save_state(ctx->hflags & ~MIPS_HFLAG_BMASK);
        !          6081:         gen_goto_tb(ctx, 1, ctx->pc + 4);
        !          6082:         gen_set_label(l1);
1.1       root     6083:     }
1.1.1.5   root     6084:     op = MASK_OP_MAJOR(ctx->opcode);
                   6085:     rs = (ctx->opcode >> 21) & 0x1f;
                   6086:     rt = (ctx->opcode >> 16) & 0x1f;
                   6087:     rd = (ctx->opcode >> 11) & 0x1f;
                   6088:     sa = (ctx->opcode >> 6) & 0x1f;
1.1       root     6089:     imm = (int16_t)ctx->opcode;
                   6090:     switch (op) {
1.1.1.5   root     6091:     case OPC_SPECIAL:
                   6092:         op1 = MASK_SPECIAL(ctx->opcode);
1.1       root     6093:         switch (op1) {
1.1.1.5   root     6094:         case OPC_SLL:          /* Arithmetic with immediate */
                   6095:         case OPC_SRL ... OPC_SRA:
1.1.1.6 ! root     6096:             gen_arith_imm(env, ctx, op1, rd, rt, sa);
1.1.1.5   root     6097:             break;
1.1.1.6 ! root     6098:         case OPC_MOVZ ... OPC_MOVN:
        !          6099:             check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
1.1.1.5   root     6100:         case OPC_SLLV:         /* Arithmetic */
                   6101:         case OPC_SRLV ... OPC_SRAV:
                   6102:         case OPC_ADD ... OPC_NOR:
                   6103:         case OPC_SLT ... OPC_SLTU:
1.1.1.6 ! root     6104:             gen_arith(env, ctx, op1, rd, rs, rt);
1.1       root     6105:             break;
1.1.1.5   root     6106:         case OPC_MULT ... OPC_DIVU:
1.1.1.6 ! root     6107:             if (sa) {
        !          6108:                 check_insn(env, ctx, INSN_VR54XX);
        !          6109:                 op1 = MASK_MUL_VR54XX(ctx->opcode);
        !          6110:                 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
        !          6111:             } else
        !          6112:                 gen_muldiv(ctx, op1, rs, rt);
1.1       root     6113:             break;
1.1.1.5   root     6114:         case OPC_JR ... OPC_JALR:
                   6115:             gen_compute_branch(ctx, op1, rs, rd, sa);
1.1       root     6116:             return;
1.1.1.5   root     6117:         case OPC_TGE ... OPC_TEQ: /* Traps */
                   6118:         case OPC_TNE:
                   6119:             gen_trap(ctx, op1, rs, rt, -1);
                   6120:             break;
                   6121:         case OPC_MFHI:          /* Move from HI/LO */
                   6122:         case OPC_MFLO:
                   6123:             gen_HILO(ctx, op1, rd);
1.1       root     6124:             break;
1.1.1.5   root     6125:         case OPC_MTHI:
                   6126:         case OPC_MTLO:          /* Move to HI/LO */
                   6127:             gen_HILO(ctx, op1, rs);
                   6128:             break;
1.1.1.6 ! root     6129:         case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
        !          6130: #ifdef MIPS_STRICT_STANDARD
        !          6131:             MIPS_INVAL("PMON / selsl");
        !          6132:             generate_exception(ctx, EXCP_RI);
        !          6133: #else
1.1.1.5   root     6134:             gen_op_pmon(sa);
1.1.1.6 ! root     6135: #endif
1.1.1.5   root     6136:             break;
                   6137:         case OPC_SYSCALL:
1.1       root     6138:             generate_exception(ctx, EXCP_SYSCALL);
                   6139:             break;
1.1.1.5   root     6140:         case OPC_BREAK:
1.1       root     6141:             generate_exception(ctx, EXCP_BREAK);
                   6142:             break;
1.1.1.6 ! root     6143:         case OPC_SPIM:
        !          6144: #ifdef MIPS_STRICT_STANDARD
        !          6145:             MIPS_INVAL("SPIM");
        !          6146:             generate_exception(ctx, EXCP_RI);
        !          6147: #else
1.1.1.5   root     6148:            /* Implemented as RI exception for now. */
                   6149:             MIPS_INVAL("spim (unofficial)");
                   6150:             generate_exception(ctx, EXCP_RI);
1.1.1.6 ! root     6151: #endif
1.1       root     6152:             break;
1.1.1.5   root     6153:         case OPC_SYNC:
1.1.1.6 ! root     6154:             /* Treat as NOP. */
1.1       root     6155:             break;
1.1.1.2   root     6156: 
1.1.1.5   root     6157:         case OPC_MOVCI:
1.1.1.6 ! root     6158:             check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
        !          6159:             if (env->CP0_Config1 & (1 << CP0C1_FP)) {
        !          6160:                 save_cpu_state(ctx, 1);
        !          6161:                 check_cp1_enabled(ctx);
        !          6162:                 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
        !          6163:                           (ctx->opcode >> 16) & 1);
        !          6164:             } else {
        !          6165:                 generate_exception_err(ctx, EXCP_CpU, 1);
        !          6166:             }
1.1.1.2   root     6167:             break;
                   6168: 
1.1.1.6 ! root     6169: #if defined(TARGET_MIPS64)
1.1.1.5   root     6170:        /* MIPS64 specific opcodes */
                   6171:         case OPC_DSLL:
                   6172:         case OPC_DSRL ... OPC_DSRA:
                   6173:         case OPC_DSLL32:
                   6174:         case OPC_DSRL32 ... OPC_DSRA32:
1.1.1.6 ! root     6175:             check_insn(env, ctx, ISA_MIPS3);
        !          6176:             check_mips_64(ctx);
        !          6177:             gen_arith_imm(env, ctx, op1, rd, rt, sa);
1.1.1.5   root     6178:             break;
                   6179:         case OPC_DSLLV:
                   6180:         case OPC_DSRLV ... OPC_DSRAV:
                   6181:         case OPC_DADD ... OPC_DSUBU:
1.1.1.6 ! root     6182:             check_insn(env, ctx, ISA_MIPS3);
        !          6183:             check_mips_64(ctx);
        !          6184:             gen_arith(env, ctx, op1, rd, rs, rt);
1.1.1.5   root     6185:             break;
                   6186:         case OPC_DMULT ... OPC_DDIVU:
1.1.1.6 ! root     6187:             check_insn(env, ctx, ISA_MIPS3);
        !          6188:             check_mips_64(ctx);
1.1.1.5   root     6189:             gen_muldiv(ctx, op1, rs, rt);
                   6190:             break;
1.1       root     6191: #endif
                   6192:         default:            /* Invalid */
                   6193:             MIPS_INVAL("special");
                   6194:             generate_exception(ctx, EXCP_RI);
                   6195:             break;
                   6196:         }
                   6197:         break;
1.1.1.5   root     6198:     case OPC_SPECIAL2:
                   6199:         op1 = MASK_SPECIAL2(ctx->opcode);
1.1       root     6200:         switch (op1) {
1.1.1.5   root     6201:         case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
                   6202:         case OPC_MSUB ... OPC_MSUBU:
1.1.1.6 ! root     6203:             check_insn(env, ctx, ISA_MIPS32);
1.1.1.5   root     6204:             gen_muldiv(ctx, op1, rs, rt);
1.1       root     6205:             break;
1.1.1.5   root     6206:         case OPC_MUL:
1.1.1.6 ! root     6207:             gen_arith(env, ctx, op1, rd, rs, rt);
1.1       root     6208:             break;
1.1.1.5   root     6209:         case OPC_CLZ ... OPC_CLO:
1.1.1.6 ! root     6210:             check_insn(env, ctx, ISA_MIPS32);
1.1.1.5   root     6211:             gen_cl(ctx, op1, rd, rs);
1.1       root     6212:             break;
1.1.1.5   root     6213:         case OPC_SDBBP:
1.1       root     6214:             /* XXX: not clear which exception should be raised
                   6215:              *      when in debug mode...
                   6216:              */
1.1.1.6 ! root     6217:             check_insn(env, ctx, ISA_MIPS32);
1.1       root     6218:             if (!(ctx->hflags & MIPS_HFLAG_DM)) {
                   6219:                 generate_exception(ctx, EXCP_DBp);
                   6220:             } else {
                   6221:                 generate_exception(ctx, EXCP_DBp);
                   6222:             }
1.1.1.6 ! root     6223:             /* Treat as NOP. */
1.1       root     6224:             break;
1.1.1.6 ! root     6225: #if defined(TARGET_MIPS64)
1.1.1.5   root     6226:         case OPC_DCLZ ... OPC_DCLO:
1.1.1.6 ! root     6227:             check_insn(env, ctx, ISA_MIPS64);
        !          6228:             check_mips_64(ctx);
1.1.1.5   root     6229:             gen_cl(ctx, op1, rd, rs);
                   6230:             break;
                   6231: #endif
1.1       root     6232:         default:            /* Invalid */
                   6233:             MIPS_INVAL("special2");
                   6234:             generate_exception(ctx, EXCP_RI);
                   6235:             break;
                   6236:         }
                   6237:         break;
1.1.1.5   root     6238:     case OPC_SPECIAL3:
1.1.1.6 ! root     6239:          op1 = MASK_SPECIAL3(ctx->opcode);
        !          6240:          switch (op1) {
        !          6241:          case OPC_EXT:
        !          6242:          case OPC_INS:
        !          6243:              check_insn(env, ctx, ISA_MIPS32R2);
        !          6244:              gen_bitops(ctx, op1, rt, rs, sa, rd);
        !          6245:              break;
        !          6246:          case OPC_BSHFL:
        !          6247:              check_insn(env, ctx, ISA_MIPS32R2);
        !          6248:              op2 = MASK_BSHFL(ctx->opcode);
        !          6249:              switch (op2) {
        !          6250:              case OPC_WSBH:
        !          6251:                  GEN_LOAD_REG_T1(rt);
        !          6252:                  gen_op_wsbh();
        !          6253:                  break;
        !          6254:              case OPC_SEB:
        !          6255:                  GEN_LOAD_REG_T1(rt);
        !          6256:                  gen_op_seb();
        !          6257:                  break;
        !          6258:              case OPC_SEH:
        !          6259:                  GEN_LOAD_REG_T1(rt);
        !          6260:                  gen_op_seh();
        !          6261:                  break;
        !          6262:              default:            /* Invalid */
        !          6263:                  MIPS_INVAL("bshfl");
        !          6264:                  generate_exception(ctx, EXCP_RI);
        !          6265:                  break;
        !          6266:             }
        !          6267:             GEN_STORE_T0_REG(rd);
        !          6268:             break;
        !          6269:         case OPC_RDHWR:
        !          6270:             check_insn(env, ctx, ISA_MIPS32R2);
        !          6271:             switch (rd) {
        !          6272:             case 0:
        !          6273:                 save_cpu_state(ctx, 1);
        !          6274:                 gen_op_rdhwr_cpunum();
        !          6275:                 break;
        !          6276:             case 1:
        !          6277:                 save_cpu_state(ctx, 1);
        !          6278:                 gen_op_rdhwr_synci_step();
        !          6279:                 break;
        !          6280:             case 2:
        !          6281:                 save_cpu_state(ctx, 1);
        !          6282:                 gen_op_rdhwr_cc();
        !          6283:                 break;
        !          6284:             case 3:
        !          6285:                 save_cpu_state(ctx, 1);
        !          6286:                 gen_op_rdhwr_ccres();
        !          6287:                 break;
        !          6288:             case 29:
        !          6289: #if defined (CONFIG_USER_ONLY)
        !          6290:                 gen_op_tls_value();
        !          6291:                 break;
        !          6292: #endif
        !          6293:             default:            /* Invalid */
        !          6294:                 MIPS_INVAL("rdhwr");
        !          6295:                 generate_exception(ctx, EXCP_RI);
        !          6296:                 break;
        !          6297:             }
        !          6298:             GEN_STORE_T0_REG(rt);
        !          6299:             break;
        !          6300:         case OPC_FORK:
        !          6301:             check_insn(env, ctx, ASE_MT);
        !          6302:             GEN_LOAD_REG_T0(rt);
        !          6303:             GEN_LOAD_REG_T1(rs);
        !          6304:             gen_op_fork();
        !          6305:             break;
        !          6306:         case OPC_YIELD:
        !          6307:             check_insn(env, ctx, ASE_MT);
        !          6308:             GEN_LOAD_REG_T0(rs);
        !          6309:             gen_op_yield();
        !          6310:             GEN_STORE_T0_REG(rd);
        !          6311:             break;
        !          6312: #if defined(TARGET_MIPS64)
        !          6313:         case OPC_DEXTM ... OPC_DEXT:
        !          6314:         case OPC_DINSM ... OPC_DINS:
        !          6315:             check_insn(env, ctx, ISA_MIPS64R2);
        !          6316:             check_mips_64(ctx);
1.1.1.5   root     6317:             gen_bitops(ctx, op1, rt, rs, sa, rd);
                   6318:             break;
1.1.1.6 ! root     6319:         case OPC_DBSHFL:
        !          6320:             check_insn(env, ctx, ISA_MIPS64R2);
        !          6321:             check_mips_64(ctx);
        !          6322:             op2 = MASK_DBSHFL(ctx->opcode);
1.1.1.5   root     6323:             switch (op2) {
1.1.1.6 ! root     6324:             case OPC_DSBH:
        !          6325:                 GEN_LOAD_REG_T1(rt);
        !          6326:                 gen_op_dsbh();
1.1.1.5   root     6327:                 break;
1.1.1.6 ! root     6328:             case OPC_DSHD:
        !          6329:                 GEN_LOAD_REG_T1(rt);
        !          6330:                 gen_op_dshd();
1.1.1.5   root     6331:                 break;
                   6332:             default:            /* Invalid */
                   6333:                 MIPS_INVAL("dbshfl");
                   6334:                 generate_exception(ctx, EXCP_RI);
                   6335:                 break;
1.1.1.6 ! root     6336:             }
        !          6337:             GEN_STORE_T0_REG(rd);
        !          6338:             break;
1.1.1.5   root     6339: #endif
                   6340:         default:            /* Invalid */
                   6341:             MIPS_INVAL("special3");
                   6342:             generate_exception(ctx, EXCP_RI);
                   6343:             break;
                   6344:         }
                   6345:         break;
                   6346:     case OPC_REGIMM:
                   6347:         op1 = MASK_REGIMM(ctx->opcode);
1.1       root     6348:         switch (op1) {
1.1.1.5   root     6349:         case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
                   6350:         case OPC_BLTZAL ... OPC_BGEZALL:
                   6351:             gen_compute_branch(ctx, op1, rs, -1, imm << 2);
1.1       root     6352:             return;
1.1.1.5   root     6353:         case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
                   6354:         case OPC_TNEI:
                   6355:             gen_trap(ctx, op1, rs, -1, imm);
                   6356:             break;
                   6357:         case OPC_SYNCI:
1.1.1.6 ! root     6358:             check_insn(env, ctx, ISA_MIPS32R2);
        !          6359:             /* Treat as NOP. */
1.1       root     6360:             break;
                   6361:         default:            /* Invalid */
1.1.1.6 ! root     6362:             MIPS_INVAL("regimm");
1.1       root     6363:             generate_exception(ctx, EXCP_RI);
                   6364:             break;
                   6365:         }
                   6366:         break;
1.1.1.5   root     6367:     case OPC_CP0:
1.1.1.6 ! root     6368:         check_cp0_enabled(ctx);
1.1.1.5   root     6369:         op1 = MASK_CP0(ctx->opcode);
1.1       root     6370:         switch (op1) {
1.1.1.5   root     6371:         case OPC_MFC0:
                   6372:         case OPC_MTC0:
1.1.1.6 ! root     6373:         case OPC_MFTR:
        !          6374:         case OPC_MTTR:
        !          6375: #if defined(TARGET_MIPS64)
1.1.1.5   root     6376:         case OPC_DMFC0:
                   6377:         case OPC_DMTC0:
                   6378: #endif
1.1.1.6 ! root     6379:             gen_cp0(env, ctx, op1, rt, rd);
1.1.1.5   root     6380:             break;
                   6381:         case OPC_C0_FIRST ... OPC_C0_LAST:
1.1.1.6 ! root     6382:             gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
1.1.1.5   root     6383:             break;
                   6384:         case OPC_MFMC0:
                   6385:             op2 = MASK_MFMC0(ctx->opcode);
                   6386:             switch (op2) {
1.1.1.6 ! root     6387:             case OPC_DMT:
        !          6388:                 check_insn(env, ctx, ASE_MT);
        !          6389:                 gen_op_dmt();
        !          6390:                 break;
        !          6391:             case OPC_EMT:
        !          6392:                 check_insn(env, ctx, ASE_MT);
        !          6393:                 gen_op_emt();
        !          6394:                 break;
        !          6395:             case OPC_DVPE:
        !          6396:                 check_insn(env, ctx, ASE_MT);
        !          6397:                 gen_op_dvpe();
        !          6398:                 break;
        !          6399:             case OPC_EVPE:
        !          6400:                 check_insn(env, ctx, ASE_MT);
        !          6401:                 gen_op_evpe();
        !          6402:                 break;
1.1.1.5   root     6403:             case OPC_DI:
1.1.1.6 ! root     6404:                 check_insn(env, ctx, ISA_MIPS32R2);
        !          6405:                 save_cpu_state(ctx, 1);
1.1.1.5   root     6406:                 gen_op_di();
                   6407:                 /* Stop translation as we may have switched the execution mode */
                   6408:                 ctx->bstate = BS_STOP;
                   6409:                 break;
                   6410:             case OPC_EI:
1.1.1.6 ! root     6411:                 check_insn(env, ctx, ISA_MIPS32R2);
        !          6412:                 save_cpu_state(ctx, 1);
1.1.1.5   root     6413:                 gen_op_ei();
                   6414:                 /* Stop translation as we may have switched the execution mode */
                   6415:                 ctx->bstate = BS_STOP;
                   6416:                 break;
                   6417:             default:            /* Invalid */
1.1.1.6 ! root     6418:                 MIPS_INVAL("mfmc0");
1.1.1.5   root     6419:                 generate_exception(ctx, EXCP_RI);
                   6420:                 break;
                   6421:             }
1.1.1.6 ! root     6422:             GEN_STORE_T0_REG(rt);
1.1       root     6423:             break;
1.1.1.5   root     6424:         case OPC_RDPGPR:
1.1.1.6 ! root     6425:             check_insn(env, ctx, ISA_MIPS32R2);
        !          6426:             GEN_LOAD_SRSREG_TN(T0, rt);
        !          6427:             GEN_STORE_T0_REG(rd);
        !          6428:             break;
1.1.1.5   root     6429:         case OPC_WRPGPR:
1.1.1.6 ! root     6430:             check_insn(env, ctx, ISA_MIPS32R2);
        !          6431:             GEN_LOAD_REG_T0(rt);
        !          6432:             GEN_STORE_TN_SRSREG(rd, T0);
        !          6433:             break;
1.1       root     6434:         default:
1.1.1.6 ! root     6435:             MIPS_INVAL("cp0");
1.1.1.5   root     6436:             generate_exception(ctx, EXCP_RI);
1.1       root     6437:             break;
                   6438:         }
                   6439:         break;
1.1.1.5   root     6440:     case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
1.1.1.6 ! root     6441:          gen_arith_imm(env, ctx, op, rt, rs, imm);
1.1.1.5   root     6442:          break;
                   6443:     case OPC_J ... OPC_JAL: /* Jump */
                   6444:          offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
                   6445:          gen_compute_branch(ctx, op, rs, rt, offset);
                   6446:          return;
                   6447:     case OPC_BEQ ... OPC_BGTZ: /* Branch */
                   6448:     case OPC_BEQL ... OPC_BGTZL:
                   6449:          gen_compute_branch(ctx, op, rs, rt, imm << 2);
                   6450:          return;
                   6451:     case OPC_LB ... OPC_LWR: /* Load and stores */
                   6452:     case OPC_SB ... OPC_SW:
                   6453:     case OPC_SWR:
                   6454:     case OPC_LL:
                   6455:     case OPC_SC:
                   6456:          gen_ldst(ctx, op, rt, rs, imm);
                   6457:          break;
                   6458:     case OPC_CACHE:
1.1.1.6 ! root     6459:         check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
        !          6460:         /* Treat as NOP. */
        !          6461:         break;
1.1.1.5   root     6462:     case OPC_PREF:
1.1.1.6 ! root     6463:         check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
        !          6464:         /* Treat as NOP. */
1.1       root     6465:         break;
1.1.1.2   root     6466: 
1.1.1.6 ! root     6467:     /* Floating point (COP1). */
1.1.1.5   root     6468:     case OPC_LWC1:
                   6469:     case OPC_LDC1:
                   6470:     case OPC_SWC1:
                   6471:     case OPC_SDC1:
1.1.1.6 ! root     6472:         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
        !          6473:             save_cpu_state(ctx, 1);
        !          6474:             check_cp1_enabled(ctx);
        !          6475:             gen_flt_ldst(ctx, op, rt, rs, imm);
        !          6476:         } else {
        !          6477:             generate_exception_err(ctx, EXCP_CpU, 1);
        !          6478:         }
1.1.1.4   root     6479:         break;
                   6480: 
1.1.1.5   root     6481:     case OPC_CP1:
1.1.1.6 ! root     6482:         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
        !          6483:             save_cpu_state(ctx, 1);
        !          6484:             check_cp1_enabled(ctx);
        !          6485:             op1 = MASK_CP1(ctx->opcode);
        !          6486:             switch (op1) {
        !          6487:             case OPC_MFHC1:
        !          6488:             case OPC_MTHC1:
        !          6489:                 check_insn(env, ctx, ISA_MIPS32R2);
        !          6490:             case OPC_MFC1:
        !          6491:             case OPC_CFC1:
        !          6492:             case OPC_MTC1:
        !          6493:             case OPC_CTC1:
        !          6494:                 gen_cp1(ctx, op1, rt, rd);
        !          6495:                 break;
        !          6496: #if defined(TARGET_MIPS64)
        !          6497:             case OPC_DMFC1:
        !          6498:             case OPC_DMTC1:
        !          6499:                 check_insn(env, ctx, ISA_MIPS3);
        !          6500:                 gen_cp1(ctx, op1, rt, rd);
        !          6501:                 break;
1.1.1.5   root     6502: #endif
1.1.1.6 ! root     6503:             case OPC_BC1ANY2:
        !          6504:             case OPC_BC1ANY4:
        !          6505:                 check_cop1x(ctx);
        !          6506:                 check_insn(env, ctx, ASE_MIPS3D);
        !          6507:                 /* fall through */
        !          6508:             case OPC_BC1:
        !          6509:                 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
        !          6510:                                     (rt >> 2) & 0x7, imm << 2);
        !          6511:                 return;
        !          6512:             case OPC_S_FMT:
        !          6513:             case OPC_D_FMT:
        !          6514:             case OPC_W_FMT:
        !          6515:             case OPC_L_FMT:
        !          6516:             case OPC_PS_FMT:
        !          6517:                 gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
        !          6518:                            (imm >> 8) & 0x7);
        !          6519:                 break;
        !          6520:             default:
        !          6521:                 MIPS_INVAL("cp1");
        !          6522:                 generate_exception (ctx, EXCP_RI);
        !          6523:                 break;
        !          6524:             }
        !          6525:         } else {
        !          6526:             generate_exception_err(ctx, EXCP_CpU, 1);
1.1.1.4   root     6527:         }
1.1.1.2   root     6528:         break;
                   6529: 
                   6530:     /* COP2.  */
1.1.1.5   root     6531:     case OPC_LWC2:
                   6532:     case OPC_LDC2:
                   6533:     case OPC_SWC2:
                   6534:     case OPC_SDC2:
                   6535:     case OPC_CP2:
                   6536:         /* COP2: Not implemented. */
1.1.1.2   root     6537:         generate_exception_err(ctx, EXCP_CpU, 2);
                   6538:         break;
                   6539: 
1.1.1.5   root     6540:     case OPC_CP3:
1.1.1.6 ! root     6541:         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
        !          6542:             save_cpu_state(ctx, 1);
        !          6543:             check_cp1_enabled(ctx);
        !          6544:             op1 = MASK_CP3(ctx->opcode);
        !          6545:             switch (op1) {
        !          6546:             case OPC_LWXC1:
        !          6547:             case OPC_LDXC1:
        !          6548:             case OPC_LUXC1:
        !          6549:             case OPC_SWXC1:
        !          6550:             case OPC_SDXC1:
        !          6551:             case OPC_SUXC1:
        !          6552:                 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
        !          6553:                 break;
        !          6554:             case OPC_PREFX:
        !          6555:                 /* Treat as NOP. */
        !          6556:                 break;
        !          6557:             case OPC_ALNV_PS:
        !          6558:             case OPC_MADD_S:
        !          6559:             case OPC_MADD_D:
        !          6560:             case OPC_MADD_PS:
        !          6561:             case OPC_MSUB_S:
        !          6562:             case OPC_MSUB_D:
        !          6563:             case OPC_MSUB_PS:
        !          6564:             case OPC_NMADD_S:
        !          6565:             case OPC_NMADD_D:
        !          6566:             case OPC_NMADD_PS:
        !          6567:             case OPC_NMSUB_S:
        !          6568:             case OPC_NMSUB_D:
        !          6569:             case OPC_NMSUB_PS:
        !          6570:                 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
        !          6571:                 break;
        !          6572:             default:
        !          6573:                 MIPS_INVAL("cp3");
        !          6574:                 generate_exception (ctx, EXCP_RI);
        !          6575:                 break;
        !          6576:             }
        !          6577:         } else {
        !          6578:             generate_exception_err(ctx, EXCP_CpU, 1);
1.1.1.5   root     6579:         }
1.1.1.2   root     6580:         break;
                   6581: 
1.1.1.6 ! root     6582: #if defined(TARGET_MIPS64)
1.1.1.5   root     6583:     /* MIPS64 opcodes */
                   6584:     case OPC_LWU:
                   6585:     case OPC_LDL ... OPC_LDR:
                   6586:     case OPC_SDL ... OPC_SDR:
                   6587:     case OPC_LLD:
                   6588:     case OPC_LD:
                   6589:     case OPC_SCD:
                   6590:     case OPC_SD:
1.1.1.6 ! root     6591:         check_insn(env, ctx, ISA_MIPS3);
        !          6592:         check_mips_64(ctx);
1.1.1.5   root     6593:         gen_ldst(ctx, op, rt, rs, imm);
                   6594:         break;
                   6595:     case OPC_DADDI ... OPC_DADDIU:
1.1.1.6 ! root     6596:         check_insn(env, ctx, ISA_MIPS3);
        !          6597:         check_mips_64(ctx);
        !          6598:         gen_arith_imm(env, ctx, op, rt, rs, imm);
1.1.1.5   root     6599:         break;
                   6600: #endif
                   6601:     case OPC_JALX:
1.1.1.6 ! root     6602:         check_insn(env, ctx, ASE_MIPS16);
1.1.1.5   root     6603:         /* MIPS16: Not implemented. */
                   6604:     case OPC_MDMX:
1.1.1.6 ! root     6605:         check_insn(env, ctx, ASE_MDMX);
1.1.1.5   root     6606:         /* MDMX: Not implemented. */
1.1       root     6607:     default:            /* Invalid */
1.1.1.6 ! root     6608:         MIPS_INVAL("major opcode");
1.1       root     6609:         generate_exception(ctx, EXCP_RI);
                   6610:         break;
                   6611:     }
1.1.1.2   root     6612:     if (ctx->hflags & MIPS_HFLAG_BMASK) {
1.1.1.6 ! root     6613:         int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
1.1       root     6614:         /* Branches completion */
1.1.1.2   root     6615:         ctx->hflags &= ~MIPS_HFLAG_BMASK;
1.1       root     6616:         ctx->bstate = BS_BRANCH;
                   6617:         save_cpu_state(ctx, 0);
1.1.1.6 ! root     6618:         switch (hflags) {
1.1       root     6619:         case MIPS_HFLAG_B:
                   6620:             /* unconditional branch */
                   6621:             MIPS_DEBUG("unconditional branch");
1.1.1.2   root     6622:             gen_goto_tb(ctx, 0, ctx->btarget);
1.1       root     6623:             break;
                   6624:         case MIPS_HFLAG_BL:
                   6625:             /* blikely taken case */
                   6626:             MIPS_DEBUG("blikely branch taken");
1.1.1.2   root     6627:             gen_goto_tb(ctx, 0, ctx->btarget);
1.1       root     6628:             break;
                   6629:         case MIPS_HFLAG_BC:
                   6630:             /* Conditional branch */
                   6631:             MIPS_DEBUG("conditional branch");
1.1.1.2   root     6632:             {
                   6633:               int l1;
                   6634:               l1 = gen_new_label();
                   6635:               gen_op_jnz_T2(l1);
                   6636:               gen_goto_tb(ctx, 1, ctx->pc + 4);
                   6637:               gen_set_label(l1);
                   6638:               gen_goto_tb(ctx, 0, ctx->btarget);
                   6639:             }
1.1       root     6640:             break;
                   6641:         case MIPS_HFLAG_BR:
                   6642:             /* unconditional branch to register */
                   6643:             MIPS_DEBUG("branch to register");
                   6644:             gen_op_breg();
1.1.1.6 ! root     6645:             gen_op_reset_T0();
        !          6646:             gen_op_exit_tb();
1.1       root     6647:             break;
                   6648:         default:
                   6649:             MIPS_DEBUG("unknown branch");
                   6650:             break;
                   6651:         }
                   6652:     }
                   6653: }
                   6654: 
1.1.1.6 ! root     6655: static always_inline int
        !          6656: gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
        !          6657:                                 int search_pc)
1.1       root     6658: {
1.1.1.6 ! root     6659:     DisasContext ctx;
1.1       root     6660:     target_ulong pc_start;
                   6661:     uint16_t *gen_opc_end;
                   6662:     int j, lj = -1;
                   6663: 
1.1.1.2   root     6664:     if (search_pc && loglevel)
1.1.1.4   root     6665:         fprintf (logfile, "search pc %d\n", search_pc);
1.1.1.2   root     6666: 
1.1       root     6667:     pc_start = tb->pc;
                   6668:     gen_opc_ptr = gen_opc_buf;
                   6669:     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
                   6670:     gen_opparam_ptr = gen_opparam_buf;
1.1.1.2   root     6671:     nb_gen_labels = 0;
1.1       root     6672:     ctx.pc = pc_start;
1.1.1.2   root     6673:     ctx.saved_pc = -1;
1.1       root     6674:     ctx.tb = tb;
                   6675:     ctx.bstate = BS_NONE;
1.1.1.2   root     6676:     /* Restore delay slot state from the tb context.  */
1.1.1.6 ! root     6677:     ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
        !          6678:     restore_cpu_state(env, &ctx);
1.1       root     6679: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     6680:     ctx.mem_idx = MIPS_HFLAG_UM;
1.1       root     6681: #else
1.1.1.6 ! root     6682:     ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
1.1       root     6683: #endif
                   6684: #ifdef DEBUG_DISAS
                   6685:     if (loglevel & CPU_LOG_TB_CPU) {
                   6686:         fprintf(logfile, "------------------------------------------------\n");
1.1.1.2   root     6687:         /* FIXME: This may print out stale hflags from env... */
1.1       root     6688:         cpu_dump_state(env, logfile, fprintf, 0);
                   6689:     }
                   6690: #endif
1.1.1.6 ! root     6691: #ifdef MIPS_DEBUG_DISAS
1.1       root     6692:     if (loglevel & CPU_LOG_TB_IN_ASM)
1.1.1.6 ! root     6693:         fprintf(logfile, "\ntb %p idx %d hflags %04x\n",
1.1.1.2   root     6694:                 tb, ctx.mem_idx, ctx.hflags);
1.1       root     6695: #endif
                   6696:     while (ctx.bstate == BS_NONE && gen_opc_ptr < gen_opc_end) {
1.1.1.2   root     6697:         if (env->nb_breakpoints > 0) {
                   6698:             for(j = 0; j < env->nb_breakpoints; j++) {
                   6699:                 if (env->breakpoints[j] == ctx.pc) {
1.1.1.6 ! root     6700:                     save_cpu_state(&ctx, 1);
1.1.1.2   root     6701:                     ctx.bstate = BS_BRANCH;
                   6702:                     gen_op_debug();
1.1.1.6 ! root     6703:                     /* Include the breakpoint location or the tb won't
        !          6704:                      * be flushed when it must be.  */
        !          6705:                     ctx.pc += 4;
1.1.1.2   root     6706:                     goto done_generating;
                   6707:                 }
                   6708:             }
                   6709:         }
                   6710: 
1.1       root     6711:         if (search_pc) {
                   6712:             j = gen_opc_ptr - gen_opc_buf;
                   6713:             if (lj < j) {
                   6714:                 lj++;
                   6715:                 while (lj < j)
                   6716:                     gen_opc_instr_start[lj++] = 0;
                   6717:             }
1.1.1.2   root     6718:             gen_opc_pc[lj] = ctx.pc;
                   6719:             gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
                   6720:             gen_opc_instr_start[lj] = 1;
1.1       root     6721:         }
                   6722:         ctx.opcode = ldl_code(ctx.pc);
1.1.1.6 ! root     6723:         decode_opc(env, &ctx);
1.1       root     6724:         ctx.pc += 4;
1.1.1.2   root     6725: 
                   6726:         if (env->singlestep_enabled)
                   6727:             break;
                   6728: 
1.1       root     6729:         if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
                   6730:             break;
1.1.1.2   root     6731: 
1.1       root     6732: #if defined (MIPS_SINGLE_STEP)
                   6733:         break;
                   6734: #endif
                   6735:     }
1.1.1.2   root     6736:     if (env->singlestep_enabled) {
1.1.1.6 ! root     6737:         save_cpu_state(&ctx, ctx.bstate == BS_NONE);
1.1.1.2   root     6738:         gen_op_debug();
1.1.1.6 ! root     6739:     } else {
        !          6740:        switch (ctx.bstate) {
        !          6741:         case BS_STOP:
        !          6742:             gen_op_interrupt_restart();
        !          6743:             gen_goto_tb(&ctx, 0, ctx.pc);
        !          6744:             break;
        !          6745:         case BS_NONE:
        !          6746:             save_cpu_state(&ctx, 0);
        !          6747:             gen_goto_tb(&ctx, 0, ctx.pc);
        !          6748:             break;
        !          6749:         case BS_EXCP:
        !          6750:             gen_op_interrupt_restart();
        !          6751:             gen_op_reset_T0();
        !          6752:             gen_op_exit_tb();
        !          6753:             break;
        !          6754:         case BS_BRANCH:
        !          6755:         default:
        !          6756:             break;
        !          6757:        }
1.1       root     6758:     }
1.1.1.2   root     6759: done_generating:
1.1.1.6 ! root     6760:     ctx.last_T0_store = NULL;
1.1       root     6761:     *gen_opc_ptr = INDEX_op_end;
                   6762:     if (search_pc) {
                   6763:         j = gen_opc_ptr - gen_opc_buf;
                   6764:         lj++;
                   6765:         while (lj <= j)
                   6766:             gen_opc_instr_start[lj++] = 0;
                   6767:     } else {
                   6768:         tb->size = ctx.pc - pc_start;
                   6769:     }
                   6770: #ifdef DEBUG_DISAS
                   6771: #if defined MIPS_DEBUG_DISAS
                   6772:     if (loglevel & CPU_LOG_TB_IN_ASM)
                   6773:         fprintf(logfile, "\n");
                   6774: #endif
                   6775:     if (loglevel & CPU_LOG_TB_IN_ASM) {
                   6776:         fprintf(logfile, "IN: %s\n", lookup_symbol(pc_start));
1.1.1.6 ! root     6777:         target_disas(logfile, pc_start, ctx.pc - pc_start, 0);
1.1       root     6778:         fprintf(logfile, "\n");
                   6779:     }
                   6780:     if (loglevel & CPU_LOG_TB_OP) {
                   6781:         fprintf(logfile, "OP:\n");
                   6782:         dump_ops(gen_opc_buf, gen_opparam_buf);
                   6783:         fprintf(logfile, "\n");
                   6784:     }
                   6785:     if (loglevel & CPU_LOG_TB_CPU) {
                   6786:         fprintf(logfile, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
                   6787:     }
                   6788: #endif
1.1.1.6 ! root     6789: 
1.1       root     6790:     return 0;
                   6791: }
                   6792: 
                   6793: int gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
                   6794: {
                   6795:     return gen_intermediate_code_internal(env, tb, 0);
                   6796: }
                   6797: 
                   6798: int gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
                   6799: {
                   6800:     return gen_intermediate_code_internal(env, tb, 1);
                   6801: }
                   6802: 
1.1.1.6 ! root     6803: void fpu_dump_state(CPUState *env, FILE *f,
1.1.1.4   root     6804:                     int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
                   6805:                     int flags)
                   6806: {
                   6807:     int i;
1.1.1.6 ! root     6808:     int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
1.1.1.4   root     6809: 
1.1.1.6 ! root     6810: #define printfpr(fp)                                                        \
        !          6811:     do {                                                                    \
        !          6812:         if (is_fpu64)                                                       \
        !          6813:             fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
        !          6814:                         (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
        !          6815:                         (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
        !          6816:         else {                                                              \
        !          6817:             fpr_t tmp;                                                      \
        !          6818:             tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
        !          6819:             tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
        !          6820:             fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
        !          6821:                         tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
        !          6822:                         tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
        !          6823:         }                                                                   \
1.1.1.4   root     6824:     } while(0)
                   6825: 
1.1.1.6 ! root     6826: 
        !          6827:     fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
        !          6828:                 env->fpu->fcr0, env->fpu->fcr31, is_fpu64, env->fpu->fp_status,
        !          6829:                 get_float_exception_flags(&env->fpu->fp_status));
        !          6830:     fpu_fprintf(f, "FT0: "); printfpr(&env->fpu->ft0);
        !          6831:     fpu_fprintf(f, "FT1: "); printfpr(&env->fpu->ft1);
        !          6832:     fpu_fprintf(f, "FT2: "); printfpr(&env->fpu->ft2);
        !          6833:     for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
        !          6834:         fpu_fprintf(f, "%3s: ", fregnames[i]);
        !          6835:         printfpr(&env->fpu->fpr[i]);
1.1.1.4   root     6836:     }
                   6837: 
                   6838: #undef printfpr
                   6839: }
                   6840: 
1.1.1.5   root     6841: void dump_fpu (CPUState *env)
1.1.1.4   root     6842: {
1.1.1.6 ! root     6843:     if (loglevel) {
        !          6844:        fprintf(logfile, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
        !          6845:                env->PC[env->current_tc], env->HI[0][env->current_tc], env->LO[0][env->current_tc], env->hflags, env->btarget, env->bcond);
1.1.1.4   root     6846:        fpu_dump_state(env, logfile, fprintf, 0);
                   6847:     }
                   6848: }
1.1.1.5   root     6849: 
1.1.1.6 ! root     6850: #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
1.1.1.5   root     6851: /* Debug help: The architecture requires 32bit code to maintain proper
                   6852:    sign-extened values on 64bit machines.  */
                   6853: 
                   6854: #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
                   6855: 
                   6856: void cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
                   6857:                      int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
                   6858:                      int flags)
                   6859: {
                   6860:     int i;
                   6861: 
1.1.1.6 ! root     6862:     if (!SIGN_EXT_P(env->PC[env->current_tc]))
        !          6863:         cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->PC[env->current_tc]);
        !          6864:     if (!SIGN_EXT_P(env->HI[0][env->current_tc]))
        !          6865:         cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->HI[0][env->current_tc]);
        !          6866:     if (!SIGN_EXT_P(env->LO[0][env->current_tc]))
        !          6867:         cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->LO[0][env->current_tc]);
1.1.1.5   root     6868:     if (!SIGN_EXT_P(env->btarget))
1.1.1.6 ! root     6869:         cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
1.1.1.5   root     6870: 
                   6871:     for (i = 0; i < 32; i++) {
1.1.1.6 ! root     6872:         if (!SIGN_EXT_P(env->gpr[i][env->current_tc]))
        !          6873:             cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->gpr[i][env->current_tc]);
1.1.1.5   root     6874:     }
                   6875: 
                   6876:     if (!SIGN_EXT_P(env->CP0_EPC))
1.1.1.6 ! root     6877:         cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
1.1.1.5   root     6878:     if (!SIGN_EXT_P(env->CP0_LLAddr))
1.1.1.6 ! root     6879:         cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
1.1.1.5   root     6880: }
                   6881: #endif
                   6882: 
1.1.1.6 ! root     6883: void cpu_dump_state (CPUState *env, FILE *f,
1.1       root     6884:                      int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
                   6885:                      int flags)
                   6886: {
                   6887:     int i;
1.1.1.6 ! root     6888: 
        !          6889:     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",
        !          6890:                 env->PC[env->current_tc], env->HI[env->current_tc], env->LO[env->current_tc], env->hflags, env->btarget, env->bcond);
1.1       root     6891:     for (i = 0; i < 32; i++) {
                   6892:         if ((i & 3) == 0)
                   6893:             cpu_fprintf(f, "GPR%02d:", i);
1.1.1.6 ! root     6894:         cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->gpr[i][env->current_tc]);
1.1       root     6895:         if ((i & 3) == 3)
                   6896:             cpu_fprintf(f, "\n");
                   6897:     }
                   6898: 
1.1.1.6 ! root     6899:     cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
        !          6900:                 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
        !          6901:     cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
1.1       root     6902:                 env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
1.1.1.6 ! root     6903:     if (env->hflags & MIPS_HFLAG_FPU)
1.1.1.5   root     6904:         fpu_dump_state(env, f, cpu_fprintf, flags);
1.1.1.6 ! root     6905: #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
1.1.1.5   root     6906:     cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
1.1.1.4   root     6907: #endif
1.1       root     6908: }
                   6909: 
1.1.1.6 ! root     6910: #include "translate_init.c"
        !          6911: 
        !          6912: CPUMIPSState *cpu_mips_init (const char *cpu_model)
1.1       root     6913: {
                   6914:     CPUMIPSState *env;
1.1.1.6 ! root     6915:     const mips_def_t *def;
1.1       root     6916: 
1.1.1.6 ! root     6917:     def = cpu_mips_find_by_name(cpu_model);
        !          6918:     if (!def)
        !          6919:         return NULL;
1.1       root     6920:     env = qemu_mallocz(sizeof(CPUMIPSState));
                   6921:     if (!env)
                   6922:         return NULL;
1.1.1.6 ! root     6923:     env->cpu_model = def;
        !          6924: 
1.1.1.2   root     6925:     cpu_exec_init(env);
1.1.1.6 ! root     6926:     env->cpu_model_str = cpu_model;
1.1.1.5   root     6927:     cpu_reset(env);
                   6928:     return env;
                   6929: }
                   6930: 
                   6931: void cpu_reset (CPUMIPSState *env)
                   6932: {
                   6933:     memset(env, 0, offsetof(CPUMIPSState, breakpoints));
                   6934: 
1.1       root     6935:     tlb_flush(env, 1);
1.1.1.5   root     6936: 
1.1       root     6937:     /* Minimal init */
1.1.1.5   root     6938: #if !defined(CONFIG_USER_ONLY)
                   6939:     if (env->hflags & MIPS_HFLAG_BMASK) {
                   6940:         /* If the exception was raised from a delay slot,
                   6941:          * come back to the jump.  */
1.1.1.6 ! root     6942:         env->CP0_ErrorEPC = env->PC[env->current_tc] - 4;
1.1.1.5   root     6943:     } else {
1.1.1.6 ! root     6944:         env->CP0_ErrorEPC = env->PC[env->current_tc];
1.1.1.5   root     6945:     }
1.1.1.6 ! root     6946:     env->PC[env->current_tc] = (int32_t)0xBFC00000;
1.1       root     6947:     env->CP0_Wired = 0;
1.1.1.5   root     6948:     /* SMP not implemented */
                   6949:     env->CP0_EBase = 0x80000000;
                   6950:     env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
1.1.1.6 ! root     6951:     /* vectored interrupts not implemented, timer on int 7,
        !          6952:        no performance counters. */
        !          6953:     env->CP0_IntCtl = 0xe0000000;
        !          6954:     {
        !          6955:         int i;
        !          6956: 
        !          6957:         for (i = 0; i < 7; i++) {
        !          6958:             env->CP0_WatchLo[i] = 0;
        !          6959:             env->CP0_WatchHi[i] = 0x80000000;
        !          6960:         }
        !          6961:         env->CP0_WatchLo[7] = 0;
        !          6962:         env->CP0_WatchHi[7] = 0;
        !          6963:     }
1.1       root     6964:     /* Count register increments in debug mode, EJTAG version 1 */
                   6965:     env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
1.1.1.5   root     6966: #endif
1.1       root     6967:     env->exception_index = EXCP_NONE;
1.1.1.2   root     6968: #if defined(CONFIG_USER_ONLY)
1.1.1.6 ! root     6969:     env->hflags = MIPS_HFLAG_UM;
1.1.1.5   root     6970:     env->user_mode_only = 1;
1.1.1.6 ! root     6971: #else
        !          6972:     env->hflags = MIPS_HFLAG_CP0;
1.1.1.2   root     6973: #endif
1.1.1.6 ! root     6974:     cpu_mips_register(env, env->cpu_model);
1.1       root     6975: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.