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

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.1.12! root        7:  *  Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
1.1       root        8:  *
                      9:  * This library is free software; you can redistribute it and/or
                     10:  * modify it under the terms of the GNU Lesser General Public
                     11:  * License as published by the Free Software Foundation; either
                     12:  * version 2 of the License, or (at your option) any later version.
                     13:  *
                     14:  * This library is distributed in the hope that it will be useful,
                     15:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     16:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     17:  * Lesser General Public License for more details.
                     18:  *
                     19:  * You should have received a copy of the GNU Lesser General Public
1.1.1.8   root       20:  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
1.1       root       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"
1.1.1.7   root       32: #include "tcg-op.h"
                     33: #include "qemu-common.h"
                     34: 
                     35: #include "helper.h"
                     36: #define GEN_HELPER 1
                     37: #include "helper.h"
1.1       root       38: 
1.1.1.2   root       39: //#define MIPS_DEBUG_DISAS
1.1.1.5   root       40: //#define MIPS_DEBUG_SIGN_EXTENSIONS
1.1       root       41: 
1.1.1.5   root       42: /* MIPS major opcodes */
                     43: #define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
1.1       root       44: 
                     45: enum {
                     46:     /* indirect opcode tables */
1.1.1.5   root       47:     OPC_SPECIAL  = (0x00 << 26),
                     48:     OPC_REGIMM   = (0x01 << 26),
                     49:     OPC_CP0      = (0x10 << 26),
                     50:     OPC_CP1      = (0x11 << 26),
                     51:     OPC_CP2      = (0x12 << 26),
                     52:     OPC_CP3      = (0x13 << 26),
                     53:     OPC_SPECIAL2 = (0x1C << 26),
                     54:     OPC_SPECIAL3 = (0x1F << 26),
1.1       root       55:     /* arithmetic with immediate */
1.1.1.5   root       56:     OPC_ADDI     = (0x08 << 26),
                     57:     OPC_ADDIU    = (0x09 << 26),
                     58:     OPC_SLTI     = (0x0A << 26),
                     59:     OPC_SLTIU    = (0x0B << 26),
1.1.1.8   root       60:     /* logic with immediate */
1.1.1.5   root       61:     OPC_ANDI     = (0x0C << 26),
                     62:     OPC_ORI      = (0x0D << 26),
                     63:     OPC_XORI     = (0x0E << 26),
                     64:     OPC_LUI      = (0x0F << 26),
1.1.1.8   root       65:     /* arithmetic with immediate */
1.1.1.5   root       66:     OPC_DADDI    = (0x18 << 26),
                     67:     OPC_DADDIU   = (0x19 << 26),
1.1       root       68:     /* Jump and branches */
1.1.1.5   root       69:     OPC_J        = (0x02 << 26),
                     70:     OPC_JAL      = (0x03 << 26),
1.1.1.12! root       71:     OPC_JALS     = OPC_JAL | 0x5,
1.1.1.5   root       72:     OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
                     73:     OPC_BEQL     = (0x14 << 26),
                     74:     OPC_BNE      = (0x05 << 26),
                     75:     OPC_BNEL     = (0x15 << 26),
                     76:     OPC_BLEZ     = (0x06 << 26),
                     77:     OPC_BLEZL    = (0x16 << 26),
                     78:     OPC_BGTZ     = (0x07 << 26),
                     79:     OPC_BGTZL    = (0x17 << 26),
                     80:     OPC_JALX     = (0x1D << 26),  /* MIPS 16 only */
1.1.1.12! root       81:     OPC_JALXS    = OPC_JALX | 0x5,
1.1       root       82:     /* Load and stores */
1.1.1.5   root       83:     OPC_LDL      = (0x1A << 26),
                     84:     OPC_LDR      = (0x1B << 26),
                     85:     OPC_LB       = (0x20 << 26),
                     86:     OPC_LH       = (0x21 << 26),
                     87:     OPC_LWL      = (0x22 << 26),
                     88:     OPC_LW       = (0x23 << 26),
1.1.1.12! root       89:     OPC_LWPC     = OPC_LW | 0x5,
1.1.1.5   root       90:     OPC_LBU      = (0x24 << 26),
                     91:     OPC_LHU      = (0x25 << 26),
                     92:     OPC_LWR      = (0x26 << 26),
                     93:     OPC_LWU      = (0x27 << 26),
                     94:     OPC_SB       = (0x28 << 26),
                     95:     OPC_SH       = (0x29 << 26),
                     96:     OPC_SWL      = (0x2A << 26),
                     97:     OPC_SW       = (0x2B << 26),
                     98:     OPC_SDL      = (0x2C << 26),
                     99:     OPC_SDR      = (0x2D << 26),
                    100:     OPC_SWR      = (0x2E << 26),
                    101:     OPC_LL       = (0x30 << 26),
                    102:     OPC_LLD      = (0x34 << 26),
                    103:     OPC_LD       = (0x37 << 26),
1.1.1.12! root      104:     OPC_LDPC     = OPC_LD | 0x5,
1.1.1.5   root      105:     OPC_SC       = (0x38 << 26),
                    106:     OPC_SCD      = (0x3C << 26),
                    107:     OPC_SD       = (0x3F << 26),
1.1       root      108:     /* Floating point load/store */
1.1.1.5   root      109:     OPC_LWC1     = (0x31 << 26),
                    110:     OPC_LWC2     = (0x32 << 26),
                    111:     OPC_LDC1     = (0x35 << 26),
                    112:     OPC_LDC2     = (0x36 << 26),
                    113:     OPC_SWC1     = (0x39 << 26),
                    114:     OPC_SWC2     = (0x3A << 26),
                    115:     OPC_SDC1     = (0x3D << 26),
                    116:     OPC_SDC2     = (0x3E << 26),
                    117:     /* MDMX ASE specific */
                    118:     OPC_MDMX     = (0x1E << 26),
1.1       root      119:     /* Cache and prefetch */
1.1.1.5   root      120:     OPC_CACHE    = (0x2F << 26),
                    121:     OPC_PREF     = (0x33 << 26),
                    122:     /* Reserved major opcode */
                    123:     OPC_MAJOR3B_RESERVED = (0x3B << 26),
1.1       root      124: };
                    125: 
                    126: /* MIPS special opcodes */
1.1.1.5   root      127: #define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
                    128: 
1.1       root      129: enum {
                    130:     /* Shifts */
1.1.1.5   root      131:     OPC_SLL      = 0x00 | OPC_SPECIAL,
1.1       root      132:     /* NOP is SLL r0, r0, 0   */
                    133:     /* SSNOP is SLL r0, r0, 1 */
1.1.1.5   root      134:     /* EHB is SLL r0, r0, 3 */
                    135:     OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
1.1.1.12! root      136:     OPC_ROTR     = OPC_SRL | (1 << 21),
1.1.1.5   root      137:     OPC_SRA      = 0x03 | OPC_SPECIAL,
                    138:     OPC_SLLV     = 0x04 | OPC_SPECIAL,
1.1.1.6   root      139:     OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
1.1.1.12! root      140:     OPC_ROTRV    = OPC_SRLV | (1 << 6),
1.1.1.5   root      141:     OPC_SRAV     = 0x07 | OPC_SPECIAL,
                    142:     OPC_DSLLV    = 0x14 | OPC_SPECIAL,
                    143:     OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
1.1.1.12! root      144:     OPC_DROTRV   = OPC_DSRLV | (1 << 6),
1.1.1.5   root      145:     OPC_DSRAV    = 0x17 | OPC_SPECIAL,
                    146:     OPC_DSLL     = 0x38 | OPC_SPECIAL,
                    147:     OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
1.1.1.12! root      148:     OPC_DROTR    = OPC_DSRL | (1 << 21),
1.1.1.5   root      149:     OPC_DSRA     = 0x3B | OPC_SPECIAL,
                    150:     OPC_DSLL32   = 0x3C | OPC_SPECIAL,
                    151:     OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
1.1.1.12! root      152:     OPC_DROTR32  = OPC_DSRL32 | (1 << 21),
1.1.1.5   root      153:     OPC_DSRA32   = 0x3F | OPC_SPECIAL,
1.1       root      154:     /* Multiplication / division */
1.1.1.5   root      155:     OPC_MULT     = 0x18 | OPC_SPECIAL,
                    156:     OPC_MULTU    = 0x19 | OPC_SPECIAL,
                    157:     OPC_DIV      = 0x1A | OPC_SPECIAL,
                    158:     OPC_DIVU     = 0x1B | OPC_SPECIAL,
                    159:     OPC_DMULT    = 0x1C | OPC_SPECIAL,
                    160:     OPC_DMULTU   = 0x1D | OPC_SPECIAL,
                    161:     OPC_DDIV     = 0x1E | OPC_SPECIAL,
                    162:     OPC_DDIVU    = 0x1F | OPC_SPECIAL,
1.1       root      163:     /* 2 registers arithmetic / logic */
1.1.1.5   root      164:     OPC_ADD      = 0x20 | OPC_SPECIAL,
                    165:     OPC_ADDU     = 0x21 | OPC_SPECIAL,
                    166:     OPC_SUB      = 0x22 | OPC_SPECIAL,
                    167:     OPC_SUBU     = 0x23 | OPC_SPECIAL,
                    168:     OPC_AND      = 0x24 | OPC_SPECIAL,
                    169:     OPC_OR       = 0x25 | OPC_SPECIAL,
                    170:     OPC_XOR      = 0x26 | OPC_SPECIAL,
                    171:     OPC_NOR      = 0x27 | OPC_SPECIAL,
                    172:     OPC_SLT      = 0x2A | OPC_SPECIAL,
                    173:     OPC_SLTU     = 0x2B | OPC_SPECIAL,
                    174:     OPC_DADD     = 0x2C | OPC_SPECIAL,
                    175:     OPC_DADDU    = 0x2D | OPC_SPECIAL,
                    176:     OPC_DSUB     = 0x2E | OPC_SPECIAL,
                    177:     OPC_DSUBU    = 0x2F | OPC_SPECIAL,
1.1       root      178:     /* Jumps */
1.1.1.5   root      179:     OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
                    180:     OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
1.1.1.12! root      181:     OPC_JALRC    = OPC_JALR | (0x5 << 6),
        !           182:     OPC_JALRS    = 0x10 | OPC_SPECIAL | (0x5 << 6),
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.9   root      202:     OPC_PMON     = 0x05 | OPC_SPECIAL, /* unofficial */
1.1.1.5   root      203:     OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
                    204:     OPC_BREAK    = 0x0D | OPC_SPECIAL,
1.1.1.9   root      205:     OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
1.1.1.5   root      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,
1.1.1.12! root      246:     OPC_BLTZALS  = OPC_BLTZAL | 0x5, /* microMIPS */
1.1.1.5   root      247:     OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
                    248:     OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
1.1.1.12! root      249:     OPC_BGEZALS  = OPC_BGEZAL | 0x5, /* microMIPS */
1.1.1.5   root      250:     OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
                    251:     OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
                    252:     OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
                    253:     OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
                    254:     OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
                    255:     OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
                    256:     OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
                    257:     OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
1.1       root      258: };
                    259: 
1.1.1.5   root      260: /* Special2 opcodes */
                    261: #define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
                    262: 
1.1       root      263: enum {
1.1.1.5   root      264:     /* Multiply & xxx operations */
                    265:     OPC_MADD     = 0x00 | OPC_SPECIAL2,
                    266:     OPC_MADDU    = 0x01 | OPC_SPECIAL2,
                    267:     OPC_MUL      = 0x02 | OPC_SPECIAL2,
                    268:     OPC_MSUB     = 0x04 | OPC_SPECIAL2,
                    269:     OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
1.1.1.12! root      270:     /* Loongson 2F */
        !           271:     OPC_MULT_G_2F   = 0x10 | OPC_SPECIAL2,
        !           272:     OPC_DMULT_G_2F  = 0x11 | OPC_SPECIAL2,
        !           273:     OPC_MULTU_G_2F  = 0x12 | OPC_SPECIAL2,
        !           274:     OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
        !           275:     OPC_DIV_G_2F    = 0x14 | OPC_SPECIAL2,
        !           276:     OPC_DDIV_G_2F   = 0x15 | OPC_SPECIAL2,
        !           277:     OPC_DIVU_G_2F   = 0x16 | OPC_SPECIAL2,
        !           278:     OPC_DDIVU_G_2F  = 0x17 | OPC_SPECIAL2,
        !           279:     OPC_MOD_G_2F    = 0x1c | OPC_SPECIAL2,
        !           280:     OPC_DMOD_G_2F   = 0x1d | OPC_SPECIAL2,
        !           281:     OPC_MODU_G_2F   = 0x1e | OPC_SPECIAL2,
        !           282:     OPC_DMODU_G_2F  = 0x1f | OPC_SPECIAL2,
1.1       root      283:     /* Misc */
1.1.1.5   root      284:     OPC_CLZ      = 0x20 | OPC_SPECIAL2,
                    285:     OPC_CLO      = 0x21 | OPC_SPECIAL2,
                    286:     OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
                    287:     OPC_DCLO     = 0x25 | OPC_SPECIAL2,
1.1       root      288:     /* Special */
1.1.1.5   root      289:     OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
                    290: };
                    291: 
                    292: /* Special3 opcodes */
                    293: #define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
                    294: 
                    295: enum {
                    296:     OPC_EXT      = 0x00 | OPC_SPECIAL3,
                    297:     OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
                    298:     OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
                    299:     OPC_DEXT     = 0x03 | OPC_SPECIAL3,
                    300:     OPC_INS      = 0x04 | OPC_SPECIAL3,
                    301:     OPC_DINSM    = 0x05 | OPC_SPECIAL3,
                    302:     OPC_DINSU    = 0x06 | OPC_SPECIAL3,
                    303:     OPC_DINS     = 0x07 | OPC_SPECIAL3,
1.1.1.6   root      304:     OPC_FORK     = 0x08 | OPC_SPECIAL3,
                    305:     OPC_YIELD    = 0x09 | OPC_SPECIAL3,
1.1.1.5   root      306:     OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
                    307:     OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
                    308:     OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
1.1.1.12! root      309: 
        !           310:     /* Loongson 2E */
        !           311:     OPC_MULT_G_2E   = 0x18 | OPC_SPECIAL3,
        !           312:     OPC_MULTU_G_2E  = 0x19 | OPC_SPECIAL3,
        !           313:     OPC_DIV_G_2E    = 0x1A | OPC_SPECIAL3,
        !           314:     OPC_DIVU_G_2E   = 0x1B | OPC_SPECIAL3,
        !           315:     OPC_DMULT_G_2E  = 0x1C | OPC_SPECIAL3,
        !           316:     OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
        !           317:     OPC_DDIV_G_2E   = 0x1E | OPC_SPECIAL3,
        !           318:     OPC_DDIVU_G_2E  = 0x1F | OPC_SPECIAL3,
        !           319:     OPC_MOD_G_2E    = 0x22 | OPC_SPECIAL3,
        !           320:     OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
        !           321:     OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
        !           322:     OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
1.1       root      323: };
                    324: 
1.1.1.5   root      325: /* BSHFL opcodes */
                    326: #define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
                    327: 
1.1       root      328: enum {
1.1.1.5   root      329:     OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
                    330:     OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
                    331:     OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
1.1       root      332: };
                    333: 
1.1.1.5   root      334: /* DBSHFL opcodes */
                    335: #define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
                    336: 
1.1       root      337: enum {
1.1.1.5   root      338:     OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
                    339:     OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
1.1       root      340: };
                    341: 
1.1.1.5   root      342: /* Coprocessor 0 (rs field) */
                    343: #define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
                    344: 
1.1.1.4   root      345: enum {
1.1.1.5   root      346:     OPC_MFC0     = (0x00 << 21) | OPC_CP0,
                    347:     OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
                    348:     OPC_MTC0     = (0x04 << 21) | OPC_CP0,
                    349:     OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
1.1.1.6   root      350:     OPC_MFTR     = (0x08 << 21) | OPC_CP0,
1.1.1.5   root      351:     OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
                    352:     OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
1.1.1.6   root      353:     OPC_MTTR     = (0x0C << 21) | OPC_CP0,
1.1.1.5   root      354:     OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
                    355:     OPC_C0       = (0x10 << 21) | OPC_CP0,
                    356:     OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
                    357:     OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,
1.1.1.4   root      358: };
1.1.1.5   root      359: 
                    360: /* MFMC0 opcodes */
1.1.1.6   root      361: #define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
1.1.1.5   root      362: 
                    363: enum {
1.1.1.6   root      364:     OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
                    365:     OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
                    366:     OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
                    367:     OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
1.1.1.5   root      368:     OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
                    369:     OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
                    370: };
                    371: 
                    372: /* Coprocessor 0 (with rs == C0) */
                    373: #define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
                    374: 
                    375: enum {
                    376:     OPC_TLBR     = 0x01 | OPC_C0,
                    377:     OPC_TLBWI    = 0x02 | OPC_C0,
                    378:     OPC_TLBWR    = 0x06 | OPC_C0,
                    379:     OPC_TLBP     = 0x08 | OPC_C0,
                    380:     OPC_RFE      = 0x10 | OPC_C0,
                    381:     OPC_ERET     = 0x18 | OPC_C0,
                    382:     OPC_DERET    = 0x1F | OPC_C0,
                    383:     OPC_WAIT     = 0x20 | OPC_C0,
                    384: };
                    385: 
                    386: /* Coprocessor 1 (rs field) */
                    387: #define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
                    388: 
1.1.1.12! root      389: /* Values for the fmt field in FP instructions */
        !           390: enum {
        !           391:     /* 0 - 15 are reserved */
        !           392:     FMT_S = 16,          /* single fp */
        !           393:     FMT_D = 17,          /* double fp */
        !           394:     FMT_E = 18,          /* extended fp */
        !           395:     FMT_Q = 19,          /* quad fp */
        !           396:     FMT_W = 20,          /* 32-bit fixed */
        !           397:     FMT_L = 21,          /* 64-bit fixed */
        !           398:     FMT_PS = 22,         /* paired single fp */
        !           399:     /* 23 - 31 are reserved */
        !           400: };
        !           401: 
1.1.1.5   root      402: enum {
                    403:     OPC_MFC1     = (0x00 << 21) | OPC_CP1,
                    404:     OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
                    405:     OPC_CFC1     = (0x02 << 21) | OPC_CP1,
1.1.1.6   root      406:     OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
1.1.1.5   root      407:     OPC_MTC1     = (0x04 << 21) | OPC_CP1,
                    408:     OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
                    409:     OPC_CTC1     = (0x06 << 21) | OPC_CP1,
1.1.1.6   root      410:     OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
1.1.1.5   root      411:     OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
1.1.1.6   root      412:     OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
                    413:     OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
1.1.1.12! root      414:     OPC_S_FMT    = (FMT_S << 21) | OPC_CP1,
        !           415:     OPC_D_FMT    = (FMT_D << 21) | OPC_CP1,
        !           416:     OPC_E_FMT    = (FMT_E << 21) | OPC_CP1,
        !           417:     OPC_Q_FMT    = (FMT_Q << 21) | OPC_CP1,
        !           418:     OPC_W_FMT    = (FMT_W << 21) | OPC_CP1,
        !           419:     OPC_L_FMT    = (FMT_L << 21) | OPC_CP1,
        !           420:     OPC_PS_FMT   = (FMT_PS << 21) | OPC_CP1,
1.1.1.5   root      421: };
                    422: 
1.1.1.6   root      423: #define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
                    424: #define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
                    425: 
1.1.1.5   root      426: enum {
                    427:     OPC_BC1F     = (0x00 << 16) | OPC_BC1,
                    428:     OPC_BC1T     = (0x01 << 16) | OPC_BC1,
                    429:     OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
                    430:     OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
                    431: };
                    432: 
1.1.1.6   root      433: enum {
                    434:     OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
                    435:     OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
                    436: };
                    437: 
                    438: enum {
                    439:     OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
                    440:     OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
                    441: };
1.1.1.5   root      442: 
                    443: #define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
1.1.1.6   root      444: 
                    445: enum {
                    446:     OPC_MFC2    = (0x00 << 21) | OPC_CP2,
                    447:     OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
                    448:     OPC_CFC2    = (0x02 << 21) | OPC_CP2,
                    449:     OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
                    450:     OPC_MTC2    = (0x04 << 21) | OPC_CP2,
                    451:     OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
                    452:     OPC_CTC2    = (0x06 << 21) | OPC_CP2,
                    453:     OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
                    454:     OPC_BC2     = (0x08 << 21) | OPC_CP2,
                    455: };
                    456: 
                    457: #define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
                    458: 
                    459: enum {
                    460:     OPC_LWXC1   = 0x00 | OPC_CP3,
                    461:     OPC_LDXC1   = 0x01 | OPC_CP3,
                    462:     OPC_LUXC1   = 0x05 | OPC_CP3,
                    463:     OPC_SWXC1   = 0x08 | OPC_CP3,
                    464:     OPC_SDXC1   = 0x09 | OPC_CP3,
                    465:     OPC_SUXC1   = 0x0D | OPC_CP3,
                    466:     OPC_PREFX   = 0x0F | OPC_CP3,
                    467:     OPC_ALNV_PS = 0x1E | OPC_CP3,
                    468:     OPC_MADD_S  = 0x20 | OPC_CP3,
                    469:     OPC_MADD_D  = 0x21 | OPC_CP3,
                    470:     OPC_MADD_PS = 0x26 | OPC_CP3,
                    471:     OPC_MSUB_S  = 0x28 | OPC_CP3,
                    472:     OPC_MSUB_D  = 0x29 | OPC_CP3,
                    473:     OPC_MSUB_PS = 0x2E | OPC_CP3,
                    474:     OPC_NMADD_S = 0x30 | OPC_CP3,
                    475:     OPC_NMADD_D = 0x31 | OPC_CP3,
                    476:     OPC_NMADD_PS= 0x36 | OPC_CP3,
                    477:     OPC_NMSUB_S = 0x38 | OPC_CP3,
                    478:     OPC_NMSUB_D = 0x39 | OPC_CP3,
                    479:     OPC_NMSUB_PS= 0x3E | OPC_CP3,
                    480: };
                    481: 
1.1.1.7   root      482: /* global register indices */
                    483: static TCGv_ptr cpu_env;
                    484: static TCGv cpu_gpr[32], cpu_PC;
                    485: static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
1.1.1.8   root      486: static TCGv cpu_dspctrl, btarget, bcond;
                    487: static TCGv_i32 hflags;
1.1.1.7   root      488: static TCGv_i32 fpu_fcr0, fpu_fcr31;
                    489: 
1.1.1.12! root      490: static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
        !           491: 
1.1.1.7   root      492: #include "gen-icount.h"
                    493: 
                    494: #define gen_helper_0i(name, arg) do {                             \
                    495:     TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
                    496:     gen_helper_##name(helper_tmp);                                \
                    497:     tcg_temp_free_i32(helper_tmp);                                \
                    498:     } while(0)
1.1.1.4   root      499: 
1.1.1.7   root      500: #define gen_helper_1i(name, arg1, arg2) do {                      \
                    501:     TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
                    502:     gen_helper_##name(arg1, helper_tmp);                          \
                    503:     tcg_temp_free_i32(helper_tmp);                                \
                    504:     } while(0)
1.1.1.4   root      505: 
1.1.1.7   root      506: #define gen_helper_2i(name, arg1, arg2, arg3) do {                \
                    507:     TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
                    508:     gen_helper_##name(arg1, arg2, helper_tmp);                    \
                    509:     tcg_temp_free_i32(helper_tmp);                                \
                    510:     } while(0)
1.1.1.4   root      511: 
1.1.1.7   root      512: #define gen_helper_3i(name, arg1, arg2, arg3, arg4) do {          \
                    513:     TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
                    514:     gen_helper_##name(arg1, arg2, arg3, helper_tmp);              \
                    515:     tcg_temp_free_i32(helper_tmp);                                \
                    516:     } while(0)
1.1.1.4   root      517: 
1.1       root      518: typedef struct DisasContext {
                    519:     struct TranslationBlock *tb;
                    520:     target_ulong pc, saved_pc;
                    521:     uint32_t opcode;
1.1.1.9   root      522:     int singlestep_enabled;
1.1       root      523:     /* Routine used to access memory */
                    524:     int mem_idx;
                    525:     uint32_t hflags, saved_hflags;
                    526:     int bstate;
                    527:     target_ulong btarget;
                    528: } DisasContext;
                    529: 
                    530: enum {
                    531:     BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
1.1.1.7   root      532:                       * exception condition */
1.1       root      533:     BS_STOP     = 1, /* We want to stop translation for any reason */
                    534:     BS_BRANCH   = 2, /* We reached a branch condition     */
                    535:     BS_EXCP     = 3, /* We reached an exception condition */
                    536: };
                    537: 
1.1.1.7   root      538: static const char *regnames[] =
                    539:     { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
                    540:       "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
                    541:       "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
                    542:       "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
                    543: 
                    544: static const char *regnames_HI[] =
                    545:     { "HI0", "HI1", "HI2", "HI3", };
                    546: 
                    547: static const char *regnames_LO[] =
                    548:     { "LO0", "LO1", "LO2", "LO3", };
                    549: 
                    550: static const char *regnames_ACX[] =
                    551:     { "ACX0", "ACX1", "ACX2", "ACX3", };
                    552: 
                    553: static const char *fregnames[] =
                    554:     { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
                    555:       "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
                    556:       "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
                    557:       "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
                    558: 
1.1.1.6   root      559: #ifdef MIPS_DEBUG_DISAS
1.1.1.8   root      560: #define MIPS_DEBUG(fmt, ...)                         \
1.1.1.7   root      561:         qemu_log_mask(CPU_LOG_TB_IN_ASM,                \
                    562:                        TARGET_FMT_lx ": %08x " fmt "\n", \
1.1.1.8   root      563:                        ctx->pc, ctx->opcode , ## __VA_ARGS__)
1.1.1.7   root      564: #define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
1.1       root      565: #else
1.1.1.8   root      566: #define MIPS_DEBUG(fmt, ...) do { } while(0)
1.1.1.7   root      567: #define LOG_DISAS(...) do { } while (0)
1.1       root      568: #endif
                    569: 
                    570: #define MIPS_INVAL(op)                                                        \
                    571: do {                                                                          \
                    572:     MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
                    573:                ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
                    574: } while (0)
                    575: 
1.1.1.7   root      576: /* General purpose registers moves. */
                    577: static inline void gen_load_gpr (TCGv t, int reg)
                    578: {
                    579:     if (reg == 0)
                    580:         tcg_gen_movi_tl(t, 0);
                    581:     else
                    582:         tcg_gen_mov_tl(t, cpu_gpr[reg]);
                    583: }
1.1.1.6   root      584: 
1.1.1.7   root      585: static inline void gen_store_gpr (TCGv t, int reg)
                    586: {
                    587:     if (reg != 0)
                    588:         tcg_gen_mov_tl(cpu_gpr[reg], t);
                    589: }
1.1.1.6   root      590: 
1.1.1.7   root      591: /* Moves to/from ACX register.  */
                    592: static inline void gen_load_ACX (TCGv t, int reg)
                    593: {
                    594:     tcg_gen_mov_tl(t, cpu_ACX[reg]);
                    595: }
1.1.1.6   root      596: 
1.1.1.7   root      597: static inline void gen_store_ACX (TCGv t, int reg)
                    598: {
                    599:     tcg_gen_mov_tl(cpu_ACX[reg], t);
                    600: }
1.1       root      601: 
1.1.1.7   root      602: /* Moves to/from shadow registers. */
                    603: static inline void gen_load_srsgpr (int from, int to)
                    604: {
1.1.1.8   root      605:     TCGv t0 = tcg_temp_new();
1.1.1.6   root      606: 
1.1.1.7   root      607:     if (from == 0)
1.1.1.8   root      608:         tcg_gen_movi_tl(t0, 0);
1.1.1.7   root      609:     else {
1.1.1.8   root      610:         TCGv_i32 t2 = tcg_temp_new_i32();
1.1.1.7   root      611:         TCGv_ptr addr = tcg_temp_new_ptr();
1.1.1.6   root      612: 
1.1.1.8   root      613:         tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
                    614:         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
                    615:         tcg_gen_andi_i32(t2, t2, 0xf);
                    616:         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
                    617:         tcg_gen_ext_i32_ptr(addr, t2);
1.1.1.7   root      618:         tcg_gen_add_ptr(addr, cpu_env, addr);
1.1       root      619: 
1.1.1.8   root      620:         tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1.1.1.7   root      621:         tcg_temp_free_ptr(addr);
1.1.1.8   root      622:         tcg_temp_free_i32(t2);
1.1.1.7   root      623:     }
1.1.1.8   root      624:     gen_store_gpr(t0, to);
                    625:     tcg_temp_free(t0);
1.1.1.7   root      626: }
1.1       root      627: 
1.1.1.7   root      628: static inline void gen_store_srsgpr (int from, int to)
                    629: {
                    630:     if (to != 0) {
1.1.1.8   root      631:         TCGv t0 = tcg_temp_new();
                    632:         TCGv_i32 t2 = tcg_temp_new_i32();
1.1.1.7   root      633:         TCGv_ptr addr = tcg_temp_new_ptr();
1.1.1.4   root      634: 
1.1.1.8   root      635:         gen_load_gpr(t0, from);
                    636:         tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
                    637:         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
                    638:         tcg_gen_andi_i32(t2, t2, 0xf);
                    639:         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
                    640:         tcg_gen_ext_i32_ptr(addr, t2);
1.1.1.7   root      641:         tcg_gen_add_ptr(addr, cpu_env, addr);
1.1.1.4   root      642: 
1.1.1.8   root      643:         tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1.1.1.7   root      644:         tcg_temp_free_ptr(addr);
1.1.1.8   root      645:         tcg_temp_free_i32(t2);
                    646:         tcg_temp_free(t0);
1.1.1.6   root      647:     }
                    648: }
                    649: 
1.1.1.7   root      650: /* Floating point register moves. */
                    651: static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
1.1.1.6   root      652: {
1.1.1.8   root      653:     tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
1.1.1.7   root      654: }
                    655: 
                    656: static inline void gen_store_fpr32 (TCGv_i32 t, int reg)
                    657: {
1.1.1.8   root      658:     tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
1.1.1.7   root      659: }
                    660: 
1.1.1.8   root      661: static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
1.1.1.7   root      662: {
1.1.1.8   root      663:     tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
1.1.1.6   root      664: }
                    665: 
1.1.1.8   root      666: static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
1.1       root      667: {
1.1.1.8   root      668:     tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
1.1.1.7   root      669: }
                    670: 
1.1.1.8   root      671: static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
1.1.1.7   root      672: {
1.1.1.8   root      673:     if (ctx->hflags & MIPS_HFLAG_F64) {
                    674:         tcg_gen_ld_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
                    675:     } else {
                    676:         TCGv_i32 t0 = tcg_temp_new_i32();
                    677:         TCGv_i32 t1 = tcg_temp_new_i32();
                    678:         gen_load_fpr32(t0, reg & ~1);
                    679:         gen_load_fpr32(t1, reg | 1);
                    680:         tcg_gen_concat_i32_i64(t, t0, t1);
                    681:         tcg_temp_free_i32(t0);
                    682:         tcg_temp_free_i32(t1);
                    683:     }
1.1.1.7   root      684: }
                    685: 
1.1.1.8   root      686: static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
1.1.1.7   root      687: {
1.1.1.8   root      688:     if (ctx->hflags & MIPS_HFLAG_F64) {
                    689:         tcg_gen_st_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
                    690:     } else {
                    691:         TCGv_i64 t0 = tcg_temp_new_i64();
                    692:         TCGv_i32 t1 = tcg_temp_new_i32();
                    693:         tcg_gen_trunc_i64_i32(t1, t);
                    694:         gen_store_fpr32(t1, reg & ~1);
                    695:         tcg_gen_shri_i64(t0, t, 32);
                    696:         tcg_gen_trunc_i64_i32(t1, t0);
                    697:         gen_store_fpr32(t1, reg | 1);
                    698:         tcg_temp_free_i32(t1);
                    699:         tcg_temp_free_i64(t0);
                    700:     }
1.1.1.7   root      701: }
                    702: 
1.1.1.8   root      703: static inline int get_fp_bit (int cc)
1.1.1.7   root      704: {
1.1.1.8   root      705:     if (cc)
                    706:         return 24 + cc;
                    707:     else
                    708:         return 23;
1.1.1.7   root      709: }
                    710: 
                    711: /* Tests */
                    712: static inline void gen_save_pc(target_ulong pc)
                    713: {
                    714:     tcg_gen_movi_tl(cpu_PC, pc);
                    715: }
                    716: 
                    717: static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
                    718: {
                    719:     LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1.1       root      720:     if (do_save_pc && ctx->pc != ctx->saved_pc) {
1.1.1.6   root      721:         gen_save_pc(ctx->pc);
1.1       root      722:         ctx->saved_pc = ctx->pc;
                    723:     }
                    724:     if (ctx->hflags != ctx->saved_hflags) {
1.1.1.8   root      725:         tcg_gen_movi_i32(hflags, ctx->hflags);
1.1       root      726:         ctx->saved_hflags = ctx->hflags;
1.1.1.12! root      727:         switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1.1.1.6   root      728:         case MIPS_HFLAG_BR:
                    729:             break;
                    730:         case MIPS_HFLAG_BC:
                    731:         case MIPS_HFLAG_BL:
                    732:         case MIPS_HFLAG_B:
1.1.1.7   root      733:             tcg_gen_movi_tl(btarget, ctx->btarget);
1.1.1.6   root      734:             break;
1.1       root      735:         }
                    736:     }
                    737: }
                    738: 
1.1.1.7   root      739: static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
1.1.1.6   root      740: {
                    741:     ctx->saved_hflags = ctx->hflags;
1.1.1.12! root      742:     switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1.1.1.6   root      743:     case MIPS_HFLAG_BR:
                    744:         break;
                    745:     case MIPS_HFLAG_BC:
                    746:     case MIPS_HFLAG_BL:
1.1.1.7   root      747:     case MIPS_HFLAG_B:
1.1.1.6   root      748:         ctx->btarget = env->btarget;
                    749:         break;
                    750:     }
                    751: }
                    752: 
1.1.1.7   root      753: static inline void
                    754: generate_exception_err (DisasContext *ctx, int excp, int err)
1.1       root      755: {
1.1.1.7   root      756:     TCGv_i32 texcp = tcg_const_i32(excp);
                    757:     TCGv_i32 terr = tcg_const_i32(err);
1.1       root      758:     save_cpu_state(ctx, 1);
1.1.1.7   root      759:     gen_helper_raise_exception_err(texcp, terr);
                    760:     tcg_temp_free_i32(terr);
                    761:     tcg_temp_free_i32(texcp);
                    762: }
                    763: 
                    764: static inline void
                    765: generate_exception (DisasContext *ctx, int excp)
                    766: {
                    767:     save_cpu_state(ctx, 1);
                    768:     gen_helper_0i(raise_exception, excp);
1.1       root      769: }
                    770: 
1.1.1.7   root      771: /* Addresses computation */
1.1.1.9   root      772: static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1.1.1.2   root      773: {
1.1.1.9   root      774:     tcg_gen_add_tl(ret, arg0, arg1);
1.1.1.7   root      775: 
                    776: #if defined(TARGET_MIPS64)
                    777:     /* For compatibility with 32-bit code, data reference in user mode
                    778:        with Status_UX = 0 should be casted to 32-bit and sign extended.
                    779:        See the MIPS64 PRA manual, section 4.10. */
                    780:     if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
                    781:         !(ctx->hflags & MIPS_HFLAG_UX)) {
1.1.1.9   root      782:         tcg_gen_ext32s_i64(ret, ret);
1.1.1.7   root      783:     }
                    784: #endif
1.1.1.2   root      785: }
                    786: 
1.1.1.7   root      787: static inline void check_cp0_enabled(DisasContext *ctx)
1.1.1.6   root      788: {
                    789:     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1.1.1.10  root      790:         generate_exception_err(ctx, EXCP_CpU, 0);
1.1.1.6   root      791: }
                    792: 
1.1.1.7   root      793: static inline void check_cp1_enabled(DisasContext *ctx)
1.1.1.6   root      794: {
                    795:     if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
                    796:         generate_exception_err(ctx, EXCP_CpU, 1);
                    797: }
                    798: 
                    799: /* Verify that the processor is running with COP1X instructions enabled.
                    800:    This is associated with the nabla symbol in the MIPS32 and MIPS64
                    801:    opcode tables.  */
                    802: 
1.1.1.7   root      803: static inline void check_cop1x(DisasContext *ctx)
1.1.1.6   root      804: {
                    805:     if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
                    806:         generate_exception(ctx, EXCP_RI);
                    807: }
                    808: 
                    809: /* Verify that the processor is running with 64-bit floating-point
                    810:    operations enabled.  */
                    811: 
1.1.1.7   root      812: static inline void check_cp1_64bitmode(DisasContext *ctx)
1.1.1.6   root      813: {
                    814:     if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
                    815:         generate_exception(ctx, EXCP_RI);
                    816: }
                    817: 
                    818: /*
                    819:  * Verify if floating point register is valid; an operation is not defined
                    820:  * if bit 0 of any register specification is set and the FR bit in the
                    821:  * Status register equals zero, since the register numbers specify an
                    822:  * even-odd pair of adjacent coprocessor general registers. When the FR bit
                    823:  * in the Status register equals one, both even and odd register numbers
                    824:  * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
                    825:  *
                    826:  * Multiple 64 bit wide registers can be checked by calling
                    827:  * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
                    828:  */
1.1.1.7   root      829: static inline void check_cp1_registers(DisasContext *ctx, int regs)
1.1.1.6   root      830: {
                    831:     if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
                    832:         generate_exception(ctx, EXCP_RI);
                    833: }
                    834: 
                    835: /* This code generates a "reserved instruction" exception if the
                    836:    CPU does not support the instruction set corresponding to flags. */
1.1.1.7   root      837: static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
1.1.1.6   root      838: {
                    839:     if (unlikely(!(env->insn_flags & flags)))
                    840:         generate_exception(ctx, EXCP_RI);
                    841: }
                    842: 
                    843: /* This code generates a "reserved instruction" exception if 64-bit
                    844:    instructions are not enabled. */
1.1.1.7   root      845: static inline void check_mips_64(DisasContext *ctx)
1.1.1.6   root      846: {
                    847:     if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
                    848:         generate_exception(ctx, EXCP_RI);
                    849: }
                    850: 
1.1.1.12! root      851: /* Define small wrappers for gen_load_fpr* so that we have a uniform
        !           852:    calling interface for 32 and 64-bit FPRs.  No sense in changing
        !           853:    all callers for gen_load_fpr32 when we need the CTX parameter for
        !           854:    this one use.  */
        !           855: #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
        !           856: #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
        !           857: #define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
        !           858: static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
        !           859:                                                int ft, int fs, int cc)        \
        !           860: {                                                                             \
        !           861:     TCGv_i##bits fp0 = tcg_temp_new_i##bits ();                               \
        !           862:     TCGv_i##bits fp1 = tcg_temp_new_i##bits ();                               \
        !           863:     switch (ifmt) {                                                           \
        !           864:     case FMT_PS:                                                              \
        !           865:         check_cp1_64bitmode(ctx);                                             \
        !           866:         break;                                                                \
        !           867:     case FMT_D:                                                               \
        !           868:         if (abs) {                                                            \
        !           869:             check_cop1x(ctx);                                                 \
        !           870:         }                                                                     \
        !           871:         check_cp1_registers(ctx, fs | ft);                                    \
        !           872:         break;                                                                \
        !           873:     case FMT_S:                                                               \
        !           874:         if (abs) {                                                            \
        !           875:             check_cop1x(ctx);                                                 \
        !           876:         }                                                                     \
        !           877:         break;                                                                \
        !           878:     }                                                                         \
        !           879:     gen_ldcmp_fpr##bits (ctx, fp0, fs);                                       \
        !           880:     gen_ldcmp_fpr##bits (ctx, fp1, ft);                                       \
        !           881:     switch (n) {                                                              \
        !           882:     case  0: gen_helper_2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);    break;\
        !           883:     case  1: gen_helper_2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);   break;\
        !           884:     case  2: gen_helper_2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);   break;\
        !           885:     case  3: gen_helper_2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);  break;\
        !           886:     case  4: gen_helper_2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);  break;\
        !           887:     case  5: gen_helper_2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);  break;\
        !           888:     case  6: gen_helper_2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);  break;\
        !           889:     case  7: gen_helper_2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);  break;\
        !           890:     case  8: gen_helper_2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);   break;\
        !           891:     case  9: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
        !           892:     case 10: gen_helper_2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);  break;\
        !           893:     case 11: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);  break;\
        !           894:     case 12: gen_helper_2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);   break;\
        !           895:     case 13: gen_helper_2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);  break;\
        !           896:     case 14: gen_helper_2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);   break;\
        !           897:     case 15: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);  break;\
        !           898:     default: abort();                                                         \
        !           899:     }                                                                         \
        !           900:     tcg_temp_free_i##bits (fp0);                                              \
        !           901:     tcg_temp_free_i##bits (fp1);                                              \
        !           902: }
        !           903: 
        !           904: FOP_CONDS(, 0, d, FMT_D, 64)
        !           905: FOP_CONDS(abs, 1, d, FMT_D, 64)
        !           906: FOP_CONDS(, 0, s, FMT_S, 32)
        !           907: FOP_CONDS(abs, 1, s, FMT_S, 32)
        !           908: FOP_CONDS(, 0, ps, FMT_PS, 64)
        !           909: FOP_CONDS(abs, 1, ps, FMT_PS, 64)
        !           910: #undef FOP_CONDS
        !           911: #undef gen_ldcmp_fpr32
        !           912: #undef gen_ldcmp_fpr64
        !           913: 
1.1.1.7   root      914: /* load/store instructions. */
1.1.1.8   root      915: #define OP_LD(insn,fname)                                                 \
1.1.1.12! root      916: static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)   \
1.1.1.8   root      917: {                                                                         \
                    918:     tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                        \
1.1.1.7   root      919: }
                    920: OP_LD(lb,ld8s);
                    921: OP_LD(lbu,ld8u);
                    922: OP_LD(lh,ld16s);
                    923: OP_LD(lhu,ld16u);
                    924: OP_LD(lw,ld32s);
                    925: #if defined(TARGET_MIPS64)
                    926: OP_LD(lwu,ld32u);
                    927: OP_LD(ld,ld64);
                    928: #endif
                    929: #undef OP_LD
                    930: 
1.1.1.8   root      931: #define OP_ST(insn,fname)                                                  \
1.1.1.12! root      932: static inline void op_st_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx)   \
1.1.1.8   root      933: {                                                                          \
                    934:     tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx);                        \
1.1.1.7   root      935: }
                    936: OP_ST(sb,st8);
                    937: OP_ST(sh,st16);
                    938: OP_ST(sw,st32);
                    939: #if defined(TARGET_MIPS64)
                    940: OP_ST(sd,st64);
                    941: #endif
                    942: #undef OP_ST
                    943: 
1.1.1.9   root      944: #ifdef CONFIG_USER_ONLY
1.1.1.8   root      945: #define OP_LD_ATOMIC(insn,fname)                                           \
1.1.1.12! root      946: static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
1.1.1.8   root      947: {                                                                          \
                    948:     TCGv t0 = tcg_temp_new();                                              \
                    949:     tcg_gen_mov_tl(t0, arg1);                                              \
                    950:     tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
1.1.1.9   root      951:     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, lladdr));                \
1.1.1.8   root      952:     tcg_gen_st_tl(ret, cpu_env, offsetof(CPUState, llval));                \
                    953:     tcg_temp_free(t0);                                                     \
1.1       root      954: }
1.1.1.9   root      955: #else
                    956: #define OP_LD_ATOMIC(insn,fname)                                           \
1.1.1.12! root      957: static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
1.1.1.9   root      958: {                                                                          \
                    959:     gen_helper_2i(insn, ret, arg1, ctx->mem_idx);                          \
                    960: }
                    961: #endif
1.1.1.7   root      962: OP_LD_ATOMIC(ll,ld32s);
                    963: #if defined(TARGET_MIPS64)
                    964: OP_LD_ATOMIC(lld,ld64);
1.1       root      965: #endif
1.1.1.7   root      966: #undef OP_LD_ATOMIC
1.1       root      967: 
1.1.1.8   root      968: #ifdef CONFIG_USER_ONLY
                    969: #define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
1.1.1.12! root      970: static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1.1.1.8   root      971: {                                                                            \
                    972:     TCGv t0 = tcg_temp_new();                                                \
                    973:     int l1 = gen_new_label();                                                \
                    974:     int l2 = gen_new_label();                                                \
                    975:                                                                              \
                    976:     tcg_gen_andi_tl(t0, arg2, almask);                                       \
                    977:     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                              \
                    978:     tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUState, CP0_BadVAddr));          \
                    979:     generate_exception(ctx, EXCP_AdES);                                      \
                    980:     gen_set_label(l1);                                                       \
1.1.1.9   root      981:     tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, lladdr));                  \
1.1.1.8   root      982:     tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                            \
                    983:     tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20));                        \
                    984:     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, llreg));                   \
                    985:     tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUState, llnewval));              \
                    986:     gen_helper_0i(raise_exception, EXCP_SC);                                 \
                    987:     gen_set_label(l2);                                                       \
                    988:     tcg_gen_movi_tl(t0, 0);                                                  \
                    989:     gen_store_gpr(t0, rt);                                                   \
                    990:     tcg_temp_free(t0);                                                       \
                    991: }
                    992: #else
                    993: #define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
1.1.1.12! root      994: static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1.1.1.8   root      995: {                                                                            \
                    996:     TCGv t0 = tcg_temp_new();                                                \
1.1.1.9   root      997:     gen_helper_3i(insn, t0, arg1, arg2, ctx->mem_idx);                       \
1.1.1.8   root      998:     gen_store_gpr(t0, rt);                                                   \
                    999:     tcg_temp_free(t0);                                                       \
1.1.1.7   root     1000: }
1.1.1.8   root     1001: #endif
                   1002: OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1.1.1.6   root     1003: #if defined(TARGET_MIPS64)
1.1.1.8   root     1004: OP_ST_ATOMIC(scd,st64,ld64,0x7);
1.1       root     1005: #endif
1.1.1.7   root     1006: #undef OP_ST_ATOMIC
1.1       root     1007: 
1.1.1.12! root     1008: static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
        !          1009:                                   int base, int16_t offset)
1.1       root     1010: {
                   1011:     if (base == 0) {
1.1.1.12! root     1012:         tcg_gen_movi_tl(addr, offset);
1.1       root     1013:     } else if (offset == 0) {
1.1.1.12! root     1014:         gen_load_gpr(addr, base);
1.1       root     1015:     } else {
1.1.1.12! root     1016:         tcg_gen_movi_tl(addr, offset);
        !          1017:         gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1.1       root     1018:     }
1.1.1.12! root     1019: }
        !          1020: 
        !          1021: static target_ulong pc_relative_pc (DisasContext *ctx)
        !          1022: {
        !          1023:     target_ulong pc = ctx->pc;
        !          1024: 
        !          1025:     if (ctx->hflags & MIPS_HFLAG_BMASK) {
        !          1026:         int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
        !          1027: 
        !          1028:         pc -= branch_bytes;
        !          1029:     }
        !          1030: 
        !          1031:     pc &= ~(target_ulong)3;
        !          1032:     return pc;
        !          1033: }
        !          1034: 
        !          1035: /* Load */
        !          1036: static void gen_ld (CPUState *env, DisasContext *ctx, uint32_t opc,
        !          1037:                     int rt, int base, int16_t offset)
        !          1038: {
        !          1039:     const char *opn = "ld";
        !          1040:     TCGv t0, t1;
        !          1041: 
        !          1042:     if (rt == 0 && env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
        !          1043:         /* Loongson CPU uses a load to zero register for prefetch.
        !          1044:            We emulate it as a NOP. On other CPU we must perform the
        !          1045:            actual memory access. */
        !          1046:         MIPS_DEBUG("NOP");
        !          1047:         return;
        !          1048:     }
        !          1049: 
        !          1050:     t0 = tcg_temp_new();
        !          1051:     t1 = tcg_temp_new();
        !          1052:     gen_base_offset_addr(ctx, t0, base, offset);
        !          1053: 
1.1       root     1054:     switch (opc) {
1.1.1.6   root     1055: #if defined(TARGET_MIPS64)
                   1056:     case OPC_LWU:
1.1.1.8   root     1057:         save_cpu_state(ctx, 0);
1.1.1.12! root     1058:         op_ld_lwu(t0, t0, ctx);
1.1.1.7   root     1059:         gen_store_gpr(t0, rt);
1.1.1.6   root     1060:         opn = "lwu";
                   1061:         break;
1.1       root     1062:     case OPC_LD:
1.1.1.8   root     1063:         save_cpu_state(ctx, 0);
1.1.1.12! root     1064:         op_ld_ld(t0, t0, ctx);
1.1.1.7   root     1065:         gen_store_gpr(t0, rt);
1.1       root     1066:         opn = "ld";
                   1067:         break;
1.1.1.5   root     1068:     case OPC_LLD:
1.1.1.8   root     1069:         save_cpu_state(ctx, 0);
1.1.1.12! root     1070:         op_ld_lld(t0, t0, ctx);
1.1.1.7   root     1071:         gen_store_gpr(t0, rt);
1.1.1.5   root     1072:         opn = "lld";
                   1073:         break;
1.1       root     1074:     case OPC_LDL:
1.1.1.7   root     1075:         save_cpu_state(ctx, 1);
                   1076:         gen_load_gpr(t1, rt);
1.1.1.8   root     1077:         gen_helper_3i(ldl, t1, t1, t0, ctx->mem_idx);
1.1.1.7   root     1078:         gen_store_gpr(t1, rt);
1.1       root     1079:         opn = "ldl";
                   1080:         break;
                   1081:     case OPC_LDR:
1.1.1.7   root     1082:         save_cpu_state(ctx, 1);
                   1083:         gen_load_gpr(t1, rt);
1.1.1.8   root     1084:         gen_helper_3i(ldr, t1, t1, t0, ctx->mem_idx);
1.1.1.7   root     1085:         gen_store_gpr(t1, rt);
1.1       root     1086:         opn = "ldr";
                   1087:         break;
1.1.1.12! root     1088:     case OPC_LDPC:
1.1.1.7   root     1089:         save_cpu_state(ctx, 1);
1.1.1.12! root     1090:         tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
        !          1091:         gen_op_addr_add(ctx, t0, t0, t1);
        !          1092:         op_ld_ld(t0, t0, ctx);
        !          1093:         gen_store_gpr(t0, rt);
        !          1094:         opn = "ldpc";
1.1       root     1095:         break;
                   1096: #endif
1.1.1.12! root     1097:     case OPC_LWPC:
        !          1098:         save_cpu_state(ctx, 1);
        !          1099:         tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
        !          1100:         gen_op_addr_add(ctx, t0, t0, t1);
        !          1101:         op_ld_lw(t0, t0, ctx);
        !          1102:         gen_store_gpr(t0, rt);
        !          1103:         opn = "lwpc";
        !          1104:         break;
1.1       root     1105:     case OPC_LW:
1.1.1.8   root     1106:         save_cpu_state(ctx, 0);
1.1.1.12! root     1107:         op_ld_lw(t0, t0, ctx);
1.1.1.7   root     1108:         gen_store_gpr(t0, rt);
1.1       root     1109:         opn = "lw";
                   1110:         break;
                   1111:     case OPC_LH:
1.1.1.8   root     1112:         save_cpu_state(ctx, 0);
1.1.1.12! root     1113:         op_ld_lh(t0, t0, ctx);
1.1.1.7   root     1114:         gen_store_gpr(t0, rt);
1.1       root     1115:         opn = "lh";
                   1116:         break;
                   1117:     case OPC_LHU:
1.1.1.8   root     1118:         save_cpu_state(ctx, 0);
1.1.1.12! root     1119:         op_ld_lhu(t0, t0, ctx);
1.1.1.7   root     1120:         gen_store_gpr(t0, rt);
1.1       root     1121:         opn = "lhu";
                   1122:         break;
                   1123:     case OPC_LB:
1.1.1.8   root     1124:         save_cpu_state(ctx, 0);
1.1.1.12! root     1125:         op_ld_lb(t0, t0, ctx);
1.1.1.7   root     1126:         gen_store_gpr(t0, rt);
1.1       root     1127:         opn = "lb";
                   1128:         break;
                   1129:     case OPC_LBU:
1.1.1.8   root     1130:         save_cpu_state(ctx, 0);
1.1.1.12! root     1131:         op_ld_lbu(t0, t0, ctx);
1.1.1.7   root     1132:         gen_store_gpr(t0, rt);
1.1       root     1133:         opn = "lbu";
                   1134:         break;
                   1135:     case OPC_LWL:
1.1.1.7   root     1136:         save_cpu_state(ctx, 1);
                   1137:         gen_load_gpr(t1, rt);
1.1.1.8   root     1138:         gen_helper_3i(lwl, t1, t1, t0, ctx->mem_idx);
1.1.1.7   root     1139:         gen_store_gpr(t1, rt);
1.1       root     1140:         opn = "lwl";
                   1141:         break;
                   1142:     case OPC_LWR:
1.1.1.7   root     1143:         save_cpu_state(ctx, 1);
                   1144:         gen_load_gpr(t1, rt);
1.1.1.8   root     1145:         gen_helper_3i(lwr, t1, t1, t0, ctx->mem_idx);
1.1.1.7   root     1146:         gen_store_gpr(t1, rt);
1.1       root     1147:         opn = "lwr";
                   1148:         break;
                   1149:     case OPC_LL:
1.1.1.9   root     1150:         save_cpu_state(ctx, 1);
1.1.1.12! root     1151:         op_ld_ll(t0, t0, ctx);
1.1.1.7   root     1152:         gen_store_gpr(t0, rt);
1.1       root     1153:         opn = "ll";
                   1154:         break;
1.1.1.8   root     1155:     }
                   1156:     MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
                   1157:     tcg_temp_free(t0);
                   1158:     tcg_temp_free(t1);
                   1159: }
                   1160: 
1.1.1.12! root     1161: /* Store */
        !          1162: static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
        !          1163:                     int base, int16_t offset)
        !          1164: {
        !          1165:     const char *opn = "st";
        !          1166:     TCGv t0 = tcg_temp_new();
        !          1167:     TCGv t1 = tcg_temp_new();
        !          1168: 
        !          1169:     gen_base_offset_addr(ctx, t0, base, offset);
        !          1170:     gen_load_gpr(t1, rt);
        !          1171:     switch (opc) {
        !          1172: #if defined(TARGET_MIPS64)
        !          1173:     case OPC_SD:
        !          1174:         save_cpu_state(ctx, 0);
        !          1175:         op_st_sd(t1, t0, ctx);
        !          1176:         opn = "sd";
        !          1177:         break;
        !          1178:     case OPC_SDL:
        !          1179:         save_cpu_state(ctx, 1);
        !          1180:         gen_helper_2i(sdl, t1, t0, ctx->mem_idx);
        !          1181:         opn = "sdl";
        !          1182:         break;
        !          1183:     case OPC_SDR:
        !          1184:         save_cpu_state(ctx, 1);
        !          1185:         gen_helper_2i(sdr, t1, t0, ctx->mem_idx);
        !          1186:         opn = "sdr";
        !          1187:         break;
        !          1188: #endif
        !          1189:     case OPC_SW:
        !          1190:         save_cpu_state(ctx, 0);
        !          1191:         op_st_sw(t1, t0, ctx);
        !          1192:         opn = "sw";
        !          1193:         break;
        !          1194:     case OPC_SH:
        !          1195:         save_cpu_state(ctx, 0);
        !          1196:         op_st_sh(t1, t0, ctx);
        !          1197:         opn = "sh";
        !          1198:         break;
        !          1199:     case OPC_SB:
        !          1200:         save_cpu_state(ctx, 0);
        !          1201:         op_st_sb(t1, t0, ctx);
        !          1202:         opn = "sb";
        !          1203:         break;
        !          1204:     case OPC_SWL:
        !          1205:         save_cpu_state(ctx, 1);
        !          1206:         gen_helper_2i(swl, t1, t0, ctx->mem_idx);
        !          1207:         opn = "swl";
        !          1208:         break;
        !          1209:     case OPC_SWR:
        !          1210:         save_cpu_state(ctx, 1);
        !          1211:         gen_helper_2i(swr, t1, t0, ctx->mem_idx);
        !          1212:         opn = "swr";
        !          1213:         break;
        !          1214:     }
        !          1215:     MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
        !          1216:     tcg_temp_free(t0);
        !          1217:     tcg_temp_free(t1);
        !          1218: }
        !          1219: 
        !          1220: 
1.1.1.8   root     1221: /* Store conditional */
                   1222: static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
                   1223:                          int base, int16_t offset)
                   1224: {
                   1225:     const char *opn = "st_cond";
                   1226:     TCGv t0, t1;
                   1227: 
                   1228:     t0 = tcg_temp_local_new();
                   1229: 
1.1.1.12! root     1230:     gen_base_offset_addr(ctx, t0, base, offset);
1.1.1.8   root     1231:     /* Don't do NOP if destination is zero: we must perform the actual
                   1232:        memory access. */
                   1233: 
                   1234:     t1 = tcg_temp_local_new();
                   1235:     gen_load_gpr(t1, rt);
                   1236:     switch (opc) {
                   1237: #if defined(TARGET_MIPS64)
                   1238:     case OPC_SCD:
                   1239:         save_cpu_state(ctx, 0);
1.1.1.12! root     1240:         op_st_scd(t1, t0, rt, ctx);
1.1.1.8   root     1241:         opn = "scd";
                   1242:         break;
                   1243: #endif
1.1       root     1244:     case OPC_SC:
1.1.1.9   root     1245:         save_cpu_state(ctx, 1);
1.1.1.12! root     1246:         op_st_sc(t1, t0, rt, ctx);
1.1       root     1247:         opn = "sc";
                   1248:         break;
                   1249:     }
                   1250:     MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1.1.1.7   root     1251:     tcg_temp_free(t1);
1.1.1.8   root     1252:     tcg_temp_free(t0);
1.1       root     1253: }
                   1254: 
1.1.1.4   root     1255: /* Load and store */
1.1.1.5   root     1256: static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1.1.1.7   root     1257:                           int base, int16_t offset)
1.1.1.4   root     1258: {
1.1.1.6   root     1259:     const char *opn = "flt_ldst";
1.1.1.8   root     1260:     TCGv t0 = tcg_temp_new();
1.1.1.4   root     1261: 
1.1.1.12! root     1262:     gen_base_offset_addr(ctx, t0, base, offset);
1.1.1.4   root     1263:     /* Don't do NOP if destination is zero: we must perform the actual
1.1.1.6   root     1264:        memory access. */
1.1.1.4   root     1265:     switch (opc) {
                   1266:     case OPC_LWC1:
1.1.1.7   root     1267:         {
                   1268:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   1269: 
1.1.1.8   root     1270:             tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
                   1271:             tcg_gen_trunc_tl_i32(fp0, t0);
1.1.1.7   root     1272:             gen_store_fpr32(fp0, ft);
                   1273:             tcg_temp_free_i32(fp0);
                   1274:         }
1.1.1.4   root     1275:         opn = "lwc1";
                   1276:         break;
                   1277:     case OPC_SWC1:
1.1.1.7   root     1278:         {
                   1279:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   1280:             TCGv t1 = tcg_temp_new();
                   1281: 
                   1282:             gen_load_fpr32(fp0, ft);
                   1283:             tcg_gen_extu_i32_tl(t1, fp0);
                   1284:             tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
                   1285:             tcg_temp_free(t1);
                   1286:             tcg_temp_free_i32(fp0);
                   1287:         }
1.1.1.4   root     1288:         opn = "swc1";
                   1289:         break;
                   1290:     case OPC_LDC1:
1.1.1.7   root     1291:         {
                   1292:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   1293: 
                   1294:             tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
                   1295:             gen_store_fpr64(ctx, fp0, ft);
                   1296:             tcg_temp_free_i64(fp0);
                   1297:         }
1.1.1.4   root     1298:         opn = "ldc1";
                   1299:         break;
                   1300:     case OPC_SDC1:
1.1.1.7   root     1301:         {
                   1302:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   1303: 
                   1304:             gen_load_fpr64(ctx, fp0, ft);
                   1305:             tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
                   1306:             tcg_temp_free_i64(fp0);
                   1307:         }
1.1.1.4   root     1308:         opn = "sdc1";
                   1309:         break;
                   1310:     default:
1.1.1.6   root     1311:         MIPS_INVAL(opn);
                   1312:         generate_exception(ctx, EXCP_RI);
1.1.1.7   root     1313:         goto out;
1.1.1.4   root     1314:     }
                   1315:     MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1.1.1.7   root     1316:  out:
                   1317:     tcg_temp_free(t0);
1.1.1.4   root     1318: }
1.1.1.5   root     1319: 
1.1.1.12! root     1320: static void gen_cop1_ldst(CPUState *env, DisasContext *ctx,
        !          1321:                           uint32_t op, int rt, int rs, int16_t imm)
        !          1322: {
        !          1323:     if (env->CP0_Config1 & (1 << CP0C1_FP)) {
        !          1324:         check_cp1_enabled(ctx);
        !          1325:         gen_flt_ldst(ctx, op, rt, rs, imm);
        !          1326:     } else {
        !          1327:         generate_exception_err(ctx, EXCP_CpU, 1);
        !          1328:     }
        !          1329: }
        !          1330: 
1.1       root     1331: /* Arithmetic with immediate operand */
1.1.1.6   root     1332: static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
                   1333:                            int rt, int rs, int16_t imm)
1.1       root     1334: {
1.1.1.8   root     1335:     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1.1.1.6   root     1336:     const char *opn = "imm arith";
1.1       root     1337: 
1.1.1.5   root     1338:     if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1.1.1.6   root     1339:         /* If no destination, treat it as a NOP.
                   1340:            For addi, we must generate the overflow exception when needed. */
1.1       root     1341:         MIPS_DEBUG("NOP");
1.1.1.8   root     1342:         return;
1.1       root     1343:     }
                   1344:     switch (opc) {
                   1345:     case OPC_ADDI:
1.1.1.7   root     1346:         {
1.1.1.8   root     1347:             TCGv t0 = tcg_temp_local_new();
                   1348:             TCGv t1 = tcg_temp_new();
                   1349:             TCGv t2 = tcg_temp_new();
1.1.1.7   root     1350:             int l1 = gen_new_label();
                   1351: 
1.1.1.8   root     1352:             gen_load_gpr(t1, rs);
                   1353:             tcg_gen_addi_tl(t0, t1, uimm);
                   1354:             tcg_gen_ext32s_tl(t0, t0);
1.1.1.7   root     1355: 
1.1.1.8   root     1356:             tcg_gen_xori_tl(t1, t1, ~uimm);
                   1357:             tcg_gen_xori_tl(t2, t0, uimm);
                   1358:             tcg_gen_and_tl(t1, t1, t2);
                   1359:             tcg_temp_free(t2);
                   1360:             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
                   1361:             tcg_temp_free(t1);
1.1.1.7   root     1362:             /* operands of same sign, result different sign */
                   1363:             generate_exception(ctx, EXCP_OVERFLOW);
                   1364:             gen_set_label(l1);
                   1365:             tcg_gen_ext32s_tl(t0, t0);
1.1.1.8   root     1366:             gen_store_gpr(t0, rt);
                   1367:             tcg_temp_free(t0);
1.1.1.7   root     1368:         }
1.1       root     1369:         opn = "addi";
                   1370:         break;
                   1371:     case OPC_ADDIU:
1.1.1.8   root     1372:         if (rs != 0) {
                   1373:             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
                   1374:             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
                   1375:         } else {
                   1376:             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
                   1377:         }
1.1       root     1378:         opn = "addiu";
                   1379:         break;
1.1.1.6   root     1380: #if defined(TARGET_MIPS64)
1.1.1.5   root     1381:     case OPC_DADDI:
1.1.1.7   root     1382:         {
1.1.1.8   root     1383:             TCGv t0 = tcg_temp_local_new();
                   1384:             TCGv t1 = tcg_temp_new();
                   1385:             TCGv t2 = tcg_temp_new();
1.1.1.7   root     1386:             int l1 = gen_new_label();
                   1387: 
1.1.1.8   root     1388:             gen_load_gpr(t1, rs);
                   1389:             tcg_gen_addi_tl(t0, t1, uimm);
1.1.1.7   root     1390: 
1.1.1.8   root     1391:             tcg_gen_xori_tl(t1, t1, ~uimm);
                   1392:             tcg_gen_xori_tl(t2, t0, uimm);
                   1393:             tcg_gen_and_tl(t1, t1, t2);
                   1394:             tcg_temp_free(t2);
                   1395:             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
                   1396:             tcg_temp_free(t1);
1.1.1.7   root     1397:             /* operands of same sign, result different sign */
                   1398:             generate_exception(ctx, EXCP_OVERFLOW);
                   1399:             gen_set_label(l1);
1.1.1.8   root     1400:             gen_store_gpr(t0, rt);
                   1401:             tcg_temp_free(t0);
1.1.1.7   root     1402:         }
1.1.1.5   root     1403:         opn = "daddi";
                   1404:         break;
                   1405:     case OPC_DADDIU:
1.1.1.8   root     1406:         if (rs != 0) {
                   1407:             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
                   1408:         } else {
                   1409:             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
                   1410:         }
1.1.1.5   root     1411:         opn = "daddiu";
                   1412:         break;
                   1413: #endif
1.1.1.8   root     1414:     }
                   1415:     MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
                   1416: }
                   1417: 
                   1418: /* Logic with immediate operand */
                   1419: static void gen_logic_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
                   1420: {
                   1421:     target_ulong uimm;
                   1422:     const char *opn = "imm logic";
                   1423: 
                   1424:     if (rt == 0) {
                   1425:         /* If no destination, treat it as a NOP. */
                   1426:         MIPS_DEBUG("NOP");
                   1427:         return;
                   1428:     }
                   1429:     uimm = (uint16_t)imm;
                   1430:     switch (opc) {
1.1       root     1431:     case OPC_ANDI:
1.1.1.8   root     1432:         if (likely(rs != 0))
                   1433:             tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
                   1434:         else
                   1435:             tcg_gen_movi_tl(cpu_gpr[rt], 0);
1.1       root     1436:         opn = "andi";
                   1437:         break;
                   1438:     case OPC_ORI:
1.1.1.8   root     1439:         if (rs != 0)
                   1440:             tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
                   1441:         else
                   1442:             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1.1       root     1443:         opn = "ori";
                   1444:         break;
                   1445:     case OPC_XORI:
1.1.1.8   root     1446:         if (likely(rs != 0))
                   1447:             tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
                   1448:         else
                   1449:             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1.1       root     1450:         opn = "xori";
                   1451:         break;
                   1452:     case OPC_LUI:
1.1.1.8   root     1453:         tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
1.1       root     1454:         opn = "lui";
                   1455:         break;
1.1.1.8   root     1456:     }
                   1457:     MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
                   1458: }
                   1459: 
                   1460: /* Set on less than with immediate operand */
                   1461: static void gen_slt_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
                   1462: {
                   1463:     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
                   1464:     const char *opn = "imm arith";
                   1465:     TCGv t0;
                   1466: 
                   1467:     if (rt == 0) {
                   1468:         /* If no destination, treat it as a NOP. */
                   1469:         MIPS_DEBUG("NOP");
                   1470:         return;
                   1471:     }
                   1472:     t0 = tcg_temp_new();
                   1473:     gen_load_gpr(t0, rs);
                   1474:     switch (opc) {
                   1475:     case OPC_SLTI:
1.1.1.12! root     1476:         tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
1.1.1.8   root     1477:         opn = "slti";
                   1478:         break;
                   1479:     case OPC_SLTIU:
1.1.1.12! root     1480:         tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
1.1.1.8   root     1481:         opn = "sltiu";
                   1482:         break;
                   1483:     }
                   1484:     MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
                   1485:     tcg_temp_free(t0);
                   1486: }
                   1487: 
                   1488: /* Shifts with immediate operand */
                   1489: static void gen_shift_imm(CPUState *env, DisasContext *ctx, uint32_t opc,
                   1490:                           int rt, int rs, int16_t imm)
                   1491: {
                   1492:     target_ulong uimm = ((uint16_t)imm) & 0x1f;
                   1493:     const char *opn = "imm shift";
                   1494:     TCGv t0;
                   1495: 
                   1496:     if (rt == 0) {
                   1497:         /* If no destination, treat it as a NOP. */
                   1498:         MIPS_DEBUG("NOP");
                   1499:         return;
                   1500:     }
                   1501: 
                   1502:     t0 = tcg_temp_new();
                   1503:     gen_load_gpr(t0, rs);
                   1504:     switch (opc) {
1.1       root     1505:     case OPC_SLL:
1.1.1.7   root     1506:         tcg_gen_shli_tl(t0, t0, uimm);
1.1.1.8   root     1507:         tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1.1       root     1508:         opn = "sll";
                   1509:         break;
                   1510:     case OPC_SRA:
1.1.1.8   root     1511:         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1.1       root     1512:         opn = "sra";
                   1513:         break;
                   1514:     case OPC_SRL:
1.1.1.12! root     1515:         if (uimm != 0) {
        !          1516:             tcg_gen_ext32u_tl(t0, t0);
        !          1517:             tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
        !          1518:         } else {
        !          1519:             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
        !          1520:         }
        !          1521:         opn = "srl";
        !          1522:         break;
        !          1523:     case OPC_ROTR:
        !          1524:         if (uimm != 0) {
        !          1525:             TCGv_i32 t1 = tcg_temp_new_i32();
1.1.1.7   root     1526: 
1.1.1.12! root     1527:             tcg_gen_trunc_tl_i32(t1, t0);
        !          1528:             tcg_gen_rotri_i32(t1, t1, uimm);
        !          1529:             tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
        !          1530:             tcg_temp_free_i32(t1);
        !          1531:         } else {
        !          1532:             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1.1.1.6   root     1533:         }
1.1.1.12! root     1534:         opn = "rotr";
1.1.1.5   root     1535:         break;
1.1.1.6   root     1536: #if defined(TARGET_MIPS64)
1.1.1.5   root     1537:     case OPC_DSLL:
1.1.1.8   root     1538:         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
1.1.1.5   root     1539:         opn = "dsll";
                   1540:         break;
                   1541:     case OPC_DSRA:
1.1.1.8   root     1542:         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1.1.1.5   root     1543:         opn = "dsra";
                   1544:         break;
                   1545:     case OPC_DSRL:
1.1.1.12! root     1546:         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
        !          1547:         opn = "dsrl";
        !          1548:         break;
        !          1549:     case OPC_DROTR:
        !          1550:         if (uimm != 0) {
        !          1551:             tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
        !          1552:         } else {
        !          1553:             tcg_gen_mov_tl(cpu_gpr[rt], t0);
1.1.1.6   root     1554:         }
1.1.1.12! root     1555:         opn = "drotr";
1.1.1.5   root     1556:         break;
                   1557:     case OPC_DSLL32:
1.1.1.8   root     1558:         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
1.1.1.5   root     1559:         opn = "dsll32";
                   1560:         break;
                   1561:     case OPC_DSRA32:
1.1.1.8   root     1562:         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
1.1.1.5   root     1563:         opn = "dsra32";
                   1564:         break;
                   1565:     case OPC_DSRL32:
1.1.1.12! root     1566:         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
        !          1567:         opn = "dsrl32";
        !          1568:         break;
        !          1569:     case OPC_DROTR32:
        !          1570:         tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
        !          1571:         opn = "drotr32";
1.1       root     1572:         break;
1.1.1.5   root     1573: #endif
1.1       root     1574:     }
1.1.1.6   root     1575:     MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1.1.1.7   root     1576:     tcg_temp_free(t0);
1.1       root     1577: }
                   1578: 
                   1579: /* Arithmetic */
1.1.1.6   root     1580: static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1.1       root     1581:                        int rd, int rs, int rt)
                   1582: {
1.1.1.6   root     1583:     const char *opn = "arith";
1.1       root     1584: 
1.1.1.5   root     1585:     if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
                   1586:        && opc != OPC_DADD && opc != OPC_DSUB) {
1.1.1.6   root     1587:         /* If no destination, treat it as a NOP.
                   1588:            For add & sub, we must generate the overflow exception when needed. */
1.1       root     1589:         MIPS_DEBUG("NOP");
1.1.1.8   root     1590:         return;
1.1.1.6   root     1591:     }
1.1.1.8   root     1592: 
1.1       root     1593:     switch (opc) {
                   1594:     case OPC_ADD:
1.1.1.7   root     1595:         {
1.1.1.8   root     1596:             TCGv t0 = tcg_temp_local_new();
                   1597:             TCGv t1 = tcg_temp_new();
                   1598:             TCGv t2 = tcg_temp_new();
1.1.1.7   root     1599:             int l1 = gen_new_label();
                   1600: 
1.1.1.8   root     1601:             gen_load_gpr(t1, rs);
                   1602:             gen_load_gpr(t2, rt);
                   1603:             tcg_gen_add_tl(t0, t1, t2);
                   1604:             tcg_gen_ext32s_tl(t0, t0);
                   1605:             tcg_gen_xor_tl(t1, t1, t2);
                   1606:             tcg_gen_xor_tl(t2, t0, t2);
1.1.1.12! root     1607:             tcg_gen_andc_tl(t1, t2, t1);
1.1.1.8   root     1608:             tcg_temp_free(t2);
                   1609:             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
                   1610:             tcg_temp_free(t1);
1.1.1.7   root     1611:             /* operands of same sign, result different sign */
                   1612:             generate_exception(ctx, EXCP_OVERFLOW);
                   1613:             gen_set_label(l1);
1.1.1.8   root     1614:             gen_store_gpr(t0, rd);
                   1615:             tcg_temp_free(t0);
1.1.1.7   root     1616:         }
1.1       root     1617:         opn = "add";
                   1618:         break;
                   1619:     case OPC_ADDU:
1.1.1.8   root     1620:         if (rs != 0 && rt != 0) {
                   1621:             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
                   1622:             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
                   1623:         } else if (rs == 0 && rt != 0) {
                   1624:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
                   1625:         } else if (rs != 0 && rt == 0) {
                   1626:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   1627:         } else {
                   1628:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   1629:         }
1.1       root     1630:         opn = "addu";
                   1631:         break;
                   1632:     case OPC_SUB:
1.1.1.7   root     1633:         {
1.1.1.8   root     1634:             TCGv t0 = tcg_temp_local_new();
                   1635:             TCGv t1 = tcg_temp_new();
                   1636:             TCGv t2 = tcg_temp_new();
1.1.1.7   root     1637:             int l1 = gen_new_label();
                   1638: 
1.1.1.8   root     1639:             gen_load_gpr(t1, rs);
                   1640:             gen_load_gpr(t2, rt);
                   1641:             tcg_gen_sub_tl(t0, t1, t2);
                   1642:             tcg_gen_ext32s_tl(t0, t0);
                   1643:             tcg_gen_xor_tl(t2, t1, t2);
                   1644:             tcg_gen_xor_tl(t1, t0, t1);
                   1645:             tcg_gen_and_tl(t1, t1, t2);
                   1646:             tcg_temp_free(t2);
                   1647:             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
                   1648:             tcg_temp_free(t1);
1.1.1.9   root     1649:             /* operands of different sign, first operand and result different sign */
1.1.1.7   root     1650:             generate_exception(ctx, EXCP_OVERFLOW);
                   1651:             gen_set_label(l1);
1.1.1.8   root     1652:             gen_store_gpr(t0, rd);
                   1653:             tcg_temp_free(t0);
1.1.1.7   root     1654:         }
1.1       root     1655:         opn = "sub";
                   1656:         break;
                   1657:     case OPC_SUBU:
1.1.1.8   root     1658:         if (rs != 0 && rt != 0) {
                   1659:             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
                   1660:             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
                   1661:         } else if (rs == 0 && rt != 0) {
                   1662:             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
                   1663:             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
                   1664:         } else if (rs != 0 && rt == 0) {
                   1665:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   1666:         } else {
                   1667:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   1668:         }
1.1       root     1669:         opn = "subu";
                   1670:         break;
1.1.1.6   root     1671: #if defined(TARGET_MIPS64)
1.1.1.5   root     1672:     case OPC_DADD:
1.1.1.7   root     1673:         {
1.1.1.8   root     1674:             TCGv t0 = tcg_temp_local_new();
                   1675:             TCGv t1 = tcg_temp_new();
                   1676:             TCGv t2 = tcg_temp_new();
1.1.1.7   root     1677:             int l1 = gen_new_label();
                   1678: 
1.1.1.8   root     1679:             gen_load_gpr(t1, rs);
                   1680:             gen_load_gpr(t2, rt);
                   1681:             tcg_gen_add_tl(t0, t1, t2);
                   1682:             tcg_gen_xor_tl(t1, t1, t2);
                   1683:             tcg_gen_xor_tl(t2, t0, t2);
1.1.1.12! root     1684:             tcg_gen_andc_tl(t1, t2, t1);
1.1.1.8   root     1685:             tcg_temp_free(t2);
                   1686:             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
                   1687:             tcg_temp_free(t1);
1.1.1.7   root     1688:             /* operands of same sign, result different sign */
                   1689:             generate_exception(ctx, EXCP_OVERFLOW);
                   1690:             gen_set_label(l1);
1.1.1.8   root     1691:             gen_store_gpr(t0, rd);
                   1692:             tcg_temp_free(t0);
1.1.1.7   root     1693:         }
1.1.1.5   root     1694:         opn = "dadd";
                   1695:         break;
                   1696:     case OPC_DADDU:
1.1.1.8   root     1697:         if (rs != 0 && rt != 0) {
                   1698:             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
                   1699:         } else if (rs == 0 && rt != 0) {
                   1700:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
                   1701:         } else if (rs != 0 && rt == 0) {
                   1702:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   1703:         } else {
                   1704:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   1705:         }
1.1.1.5   root     1706:         opn = "daddu";
                   1707:         break;
                   1708:     case OPC_DSUB:
1.1.1.7   root     1709:         {
1.1.1.8   root     1710:             TCGv t0 = tcg_temp_local_new();
                   1711:             TCGv t1 = tcg_temp_new();
                   1712:             TCGv t2 = tcg_temp_new();
1.1.1.7   root     1713:             int l1 = gen_new_label();
                   1714: 
1.1.1.8   root     1715:             gen_load_gpr(t1, rs);
                   1716:             gen_load_gpr(t2, rt);
                   1717:             tcg_gen_sub_tl(t0, t1, t2);
                   1718:             tcg_gen_xor_tl(t2, t1, t2);
                   1719:             tcg_gen_xor_tl(t1, t0, t1);
                   1720:             tcg_gen_and_tl(t1, t1, t2);
                   1721:             tcg_temp_free(t2);
                   1722:             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
                   1723:             tcg_temp_free(t1);
1.1.1.9   root     1724:             /* operands of different sign, first operand and result different sign */
1.1.1.7   root     1725:             generate_exception(ctx, EXCP_OVERFLOW);
                   1726:             gen_set_label(l1);
1.1.1.8   root     1727:             gen_store_gpr(t0, rd);
                   1728:             tcg_temp_free(t0);
1.1.1.7   root     1729:         }
1.1.1.5   root     1730:         opn = "dsub";
                   1731:         break;
                   1732:     case OPC_DSUBU:
1.1.1.8   root     1733:         if (rs != 0 && rt != 0) {
                   1734:             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
                   1735:         } else if (rs == 0 && rt != 0) {
                   1736:             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
                   1737:         } else if (rs != 0 && rt == 0) {
                   1738:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   1739:         } else {
                   1740:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   1741:         }
1.1.1.5   root     1742:         opn = "dsubu";
                   1743:         break;
                   1744: #endif
1.1.1.8   root     1745:     case OPC_MUL:
                   1746:         if (likely(rs != 0 && rt != 0)) {
                   1747:             tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
                   1748:             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
                   1749:         } else {
                   1750:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   1751:         }
                   1752:         opn = "mul";
1.1       root     1753:         break;
1.1.1.8   root     1754:     }
                   1755:     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
                   1756: }
                   1757: 
                   1758: /* Conditional move */
                   1759: static void gen_cond_move (CPUState *env, uint32_t opc, int rd, int rs, int rt)
                   1760: {
                   1761:     const char *opn = "cond move";
                   1762:     int l1;
                   1763: 
                   1764:     if (rd == 0) {
                   1765:         /* If no destination, treat it as a NOP.
                   1766:            For add & sub, we must generate the overflow exception when needed. */
                   1767:         MIPS_DEBUG("NOP");
                   1768:         return;
                   1769:     }
                   1770: 
                   1771:     l1 = gen_new_label();
                   1772:     switch (opc) {
                   1773:     case OPC_MOVN:
                   1774:         if (likely(rt != 0))
                   1775:             tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
                   1776:         else
                   1777:             tcg_gen_br(l1);
                   1778:         opn = "movn";
1.1       root     1779:         break;
1.1.1.8   root     1780:     case OPC_MOVZ:
                   1781:         if (likely(rt != 0))
                   1782:             tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
                   1783:         opn = "movz";
                   1784:         break;
                   1785:     }
                   1786:     if (rs != 0)
                   1787:         tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   1788:     else
                   1789:         tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   1790:     gen_set_label(l1);
                   1791: 
                   1792:     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
                   1793: }
                   1794: 
                   1795: /* Logic */
                   1796: static void gen_logic (CPUState *env, uint32_t opc, int rd, int rs, int rt)
                   1797: {
                   1798:     const char *opn = "logic";
                   1799: 
                   1800:     if (rd == 0) {
                   1801:         /* If no destination, treat it as a NOP. */
                   1802:         MIPS_DEBUG("NOP");
                   1803:         return;
                   1804:     }
                   1805: 
                   1806:     switch (opc) {
1.1       root     1807:     case OPC_AND:
1.1.1.8   root     1808:         if (likely(rs != 0 && rt != 0)) {
                   1809:             tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
                   1810:         } else {
                   1811:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   1812:         }
1.1       root     1813:         opn = "and";
                   1814:         break;
                   1815:     case OPC_NOR:
1.1.1.8   root     1816:         if (rs != 0 && rt != 0) {
                   1817:             tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
                   1818:         } else if (rs == 0 && rt != 0) {
                   1819:             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
                   1820:         } else if (rs != 0 && rt == 0) {
                   1821:             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   1822:         } else {
                   1823:             tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
                   1824:         }
1.1       root     1825:         opn = "nor";
                   1826:         break;
                   1827:     case OPC_OR:
1.1.1.8   root     1828:         if (likely(rs != 0 && rt != 0)) {
                   1829:             tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
                   1830:         } else if (rs == 0 && rt != 0) {
                   1831:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
                   1832:         } else if (rs != 0 && rt == 0) {
                   1833:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   1834:         } else {
                   1835:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   1836:         }
1.1       root     1837:         opn = "or";
                   1838:         break;
                   1839:     case OPC_XOR:
1.1.1.8   root     1840:         if (likely(rs != 0 && rt != 0)) {
                   1841:             tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
                   1842:         } else if (rs == 0 && rt != 0) {
                   1843:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
                   1844:         } else if (rs != 0 && rt == 0) {
                   1845:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   1846:         } else {
                   1847:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   1848:         }
1.1       root     1849:         opn = "xor";
                   1850:         break;
1.1.1.8   root     1851:     }
                   1852:     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
                   1853: }
                   1854: 
                   1855: /* Set on lower than */
                   1856: static void gen_slt (CPUState *env, uint32_t opc, int rd, int rs, int rt)
                   1857: {
                   1858:     const char *opn = "slt";
                   1859:     TCGv t0, t1;
                   1860: 
                   1861:     if (rd == 0) {
                   1862:         /* If no destination, treat it as a NOP. */
                   1863:         MIPS_DEBUG("NOP");
                   1864:         return;
                   1865:     }
                   1866: 
                   1867:     t0 = tcg_temp_new();
                   1868:     t1 = tcg_temp_new();
                   1869:     gen_load_gpr(t0, rs);
                   1870:     gen_load_gpr(t1, rt);
                   1871:     switch (opc) {
                   1872:     case OPC_SLT:
1.1.1.12! root     1873:         tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
1.1.1.8   root     1874:         opn = "slt";
1.1       root     1875:         break;
1.1.1.8   root     1876:     case OPC_SLTU:
1.1.1.12! root     1877:         tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
1.1.1.8   root     1878:         opn = "sltu";
                   1879:         break;
                   1880:     }
                   1881:     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
                   1882:     tcg_temp_free(t0);
                   1883:     tcg_temp_free(t1);
                   1884: }
1.1.1.7   root     1885: 
1.1.1.8   root     1886: /* Shifts */
                   1887: static void gen_shift (CPUState *env, DisasContext *ctx, uint32_t opc,
                   1888:                        int rd, int rs, int rt)
                   1889: {
                   1890:     const char *opn = "shifts";
                   1891:     TCGv t0, t1;
1.1.1.7   root     1892: 
1.1.1.8   root     1893:     if (rd == 0) {
                   1894:         /* If no destination, treat it as a NOP.
                   1895:            For add & sub, we must generate the overflow exception when needed. */
                   1896:         MIPS_DEBUG("NOP");
                   1897:         return;
                   1898:     }
                   1899: 
                   1900:     t0 = tcg_temp_new();
                   1901:     t1 = tcg_temp_new();
                   1902:     gen_load_gpr(t0, rs);
                   1903:     gen_load_gpr(t1, rt);
                   1904:     switch (opc) {
1.1       root     1905:     case OPC_SLLV:
1.1.1.7   root     1906:         tcg_gen_andi_tl(t0, t0, 0x1f);
                   1907:         tcg_gen_shl_tl(t0, t1, t0);
1.1.1.8   root     1908:         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1.1       root     1909:         opn = "sllv";
                   1910:         break;
                   1911:     case OPC_SRAV:
1.1.1.7   root     1912:         tcg_gen_andi_tl(t0, t0, 0x1f);
1.1.1.8   root     1913:         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1.1       root     1914:         opn = "srav";
                   1915:         break;
                   1916:     case OPC_SRLV:
1.1.1.12! root     1917:         tcg_gen_ext32u_tl(t1, t1);
        !          1918:         tcg_gen_andi_tl(t0, t0, 0x1f);
        !          1919:         tcg_gen_shr_tl(t0, t1, t0);
        !          1920:         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
        !          1921:         opn = "srlv";
        !          1922:         break;
        !          1923:     case OPC_ROTRV:
        !          1924:         {
        !          1925:             TCGv_i32 t2 = tcg_temp_new_i32();
        !          1926:             TCGv_i32 t3 = tcg_temp_new_i32();
        !          1927: 
        !          1928:             tcg_gen_trunc_tl_i32(t2, t0);
        !          1929:             tcg_gen_trunc_tl_i32(t3, t1);
        !          1930:             tcg_gen_andi_i32(t2, t2, 0x1f);
        !          1931:             tcg_gen_rotr_i32(t2, t3, t2);
        !          1932:             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
        !          1933:             tcg_temp_free_i32(t2);
        !          1934:             tcg_temp_free_i32(t3);
        !          1935:             opn = "rotrv";
1.1.1.6   root     1936:         }
1.1.1.5   root     1937:         break;
1.1.1.6   root     1938: #if defined(TARGET_MIPS64)
1.1.1.5   root     1939:     case OPC_DSLLV:
1.1.1.7   root     1940:         tcg_gen_andi_tl(t0, t0, 0x3f);
1.1.1.8   root     1941:         tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
1.1.1.5   root     1942:         opn = "dsllv";
                   1943:         break;
                   1944:     case OPC_DSRAV:
1.1.1.7   root     1945:         tcg_gen_andi_tl(t0, t0, 0x3f);
1.1.1.8   root     1946:         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1.1.1.5   root     1947:         opn = "dsrav";
                   1948:         break;
                   1949:     case OPC_DSRLV:
1.1.1.12! root     1950:         tcg_gen_andi_tl(t0, t0, 0x3f);
        !          1951:         tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
        !          1952:         opn = "dsrlv";
        !          1953:         break;
        !          1954:     case OPC_DROTRV:
        !          1955:         tcg_gen_andi_tl(t0, t0, 0x3f);
        !          1956:         tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
        !          1957:         opn = "drotrv";
1.1       root     1958:         break;
1.1.1.5   root     1959: #endif
1.1       root     1960:     }
                   1961:     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1.1.1.7   root     1962:     tcg_temp_free(t0);
                   1963:     tcg_temp_free(t1);
1.1       root     1964: }
                   1965: 
                   1966: /* Arithmetic on HI/LO registers */
1.1.1.5   root     1967: static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1.1       root     1968: {
1.1.1.6   root     1969:     const char *opn = "hilo";
1.1       root     1970: 
                   1971:     if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1.1.1.6   root     1972:         /* Treat as NOP. */
1.1       root     1973:         MIPS_DEBUG("NOP");
1.1.1.8   root     1974:         return;
1.1       root     1975:     }
                   1976:     switch (opc) {
                   1977:     case OPC_MFHI:
1.1.1.8   root     1978:         tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1.1       root     1979:         opn = "mfhi";
                   1980:         break;
                   1981:     case OPC_MFLO:
1.1.1.8   root     1982:         tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1.1       root     1983:         opn = "mflo";
                   1984:         break;
                   1985:     case OPC_MTHI:
1.1.1.8   root     1986:         if (reg != 0)
                   1987:             tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
                   1988:         else
                   1989:             tcg_gen_movi_tl(cpu_HI[0], 0);
1.1       root     1990:         opn = "mthi";
                   1991:         break;
                   1992:     case OPC_MTLO:
1.1.1.8   root     1993:         if (reg != 0)
                   1994:             tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
                   1995:         else
                   1996:             tcg_gen_movi_tl(cpu_LO[0], 0);
1.1       root     1997:         opn = "mtlo";
                   1998:         break;
                   1999:     }
                   2000:     MIPS_DEBUG("%s %s", opn, regnames[reg]);
                   2001: }
                   2002: 
1.1.1.5   root     2003: static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1.1       root     2004:                         int rs, int rt)
                   2005: {
1.1.1.6   root     2006:     const char *opn = "mul/div";
1.1.1.8   root     2007:     TCGv t0, t1;
                   2008: 
                   2009:     switch (opc) {
                   2010:     case OPC_DIV:
                   2011:     case OPC_DIVU:
                   2012: #if defined(TARGET_MIPS64)
                   2013:     case OPC_DDIV:
                   2014:     case OPC_DDIVU:
                   2015: #endif
                   2016:         t0 = tcg_temp_local_new();
                   2017:         t1 = tcg_temp_local_new();
                   2018:         break;
                   2019:     default:
                   2020:         t0 = tcg_temp_new();
                   2021:         t1 = tcg_temp_new();
                   2022:         break;
                   2023:     }
1.1       root     2024: 
1.1.1.7   root     2025:     gen_load_gpr(t0, rs);
                   2026:     gen_load_gpr(t1, rt);
1.1       root     2027:     switch (opc) {
                   2028:     case OPC_DIV:
1.1.1.7   root     2029:         {
                   2030:             int l1 = gen_new_label();
1.1.1.8   root     2031:             int l2 = gen_new_label();
1.1.1.7   root     2032: 
1.1.1.8   root     2033:             tcg_gen_ext32s_tl(t0, t0);
                   2034:             tcg_gen_ext32s_tl(t1, t1);
1.1.1.7   root     2035:             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1.1.1.8   root     2036:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
                   2037:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
                   2038: 
                   2039:             tcg_gen_mov_tl(cpu_LO[0], t0);
                   2040:             tcg_gen_movi_tl(cpu_HI[0], 0);
                   2041:             tcg_gen_br(l1);
                   2042:             gen_set_label(l2);
                   2043:             tcg_gen_div_tl(cpu_LO[0], t0, t1);
                   2044:             tcg_gen_rem_tl(cpu_HI[0], t0, t1);
                   2045:             tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
                   2046:             tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
1.1.1.7   root     2047:             gen_set_label(l1);
                   2048:         }
1.1       root     2049:         opn = "div";
                   2050:         break;
                   2051:     case OPC_DIVU:
1.1.1.7   root     2052:         {
                   2053:             int l1 = gen_new_label();
                   2054: 
1.1.1.8   root     2055:             tcg_gen_ext32u_tl(t0, t0);
                   2056:             tcg_gen_ext32u_tl(t1, t1);
1.1.1.7   root     2057:             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1.1.1.8   root     2058:             tcg_gen_divu_tl(cpu_LO[0], t0, t1);
                   2059:             tcg_gen_remu_tl(cpu_HI[0], t0, t1);
                   2060:             tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
                   2061:             tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
1.1.1.7   root     2062:             gen_set_label(l1);
                   2063:         }
1.1       root     2064:         opn = "divu";
                   2065:         break;
                   2066:     case OPC_MULT:
1.1.1.7   root     2067:         {
1.1.1.8   root     2068:             TCGv_i64 t2 = tcg_temp_new_i64();
                   2069:             TCGv_i64 t3 = tcg_temp_new_i64();
1.1.1.7   root     2070: 
1.1.1.8   root     2071:             tcg_gen_ext_tl_i64(t2, t0);
                   2072:             tcg_gen_ext_tl_i64(t3, t1);
                   2073:             tcg_gen_mul_i64(t2, t2, t3);
                   2074:             tcg_temp_free_i64(t3);
                   2075:             tcg_gen_trunc_i64_tl(t0, t2);
                   2076:             tcg_gen_shri_i64(t2, t2, 32);
                   2077:             tcg_gen_trunc_i64_tl(t1, t2);
                   2078:             tcg_temp_free_i64(t2);
1.1.1.7   root     2079:             tcg_gen_ext32s_tl(cpu_LO[0], t0);
                   2080:             tcg_gen_ext32s_tl(cpu_HI[0], t1);
                   2081:         }
1.1       root     2082:         opn = "mult";
                   2083:         break;
                   2084:     case OPC_MULTU:
1.1.1.7   root     2085:         {
1.1.1.8   root     2086:             TCGv_i64 t2 = tcg_temp_new_i64();
                   2087:             TCGv_i64 t3 = tcg_temp_new_i64();
1.1.1.7   root     2088: 
                   2089:             tcg_gen_ext32u_tl(t0, t0);
                   2090:             tcg_gen_ext32u_tl(t1, t1);
1.1.1.8   root     2091:             tcg_gen_extu_tl_i64(t2, t0);
                   2092:             tcg_gen_extu_tl_i64(t3, t1);
                   2093:             tcg_gen_mul_i64(t2, t2, t3);
                   2094:             tcg_temp_free_i64(t3);
                   2095:             tcg_gen_trunc_i64_tl(t0, t2);
                   2096:             tcg_gen_shri_i64(t2, t2, 32);
                   2097:             tcg_gen_trunc_i64_tl(t1, t2);
                   2098:             tcg_temp_free_i64(t2);
1.1.1.7   root     2099:             tcg_gen_ext32s_tl(cpu_LO[0], t0);
                   2100:             tcg_gen_ext32s_tl(cpu_HI[0], t1);
                   2101:         }
1.1       root     2102:         opn = "multu";
                   2103:         break;
1.1.1.6   root     2104: #if defined(TARGET_MIPS64)
1.1.1.5   root     2105:     case OPC_DDIV:
1.1.1.7   root     2106:         {
                   2107:             int l1 = gen_new_label();
1.1.1.8   root     2108:             int l2 = gen_new_label();
1.1.1.7   root     2109: 
                   2110:             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1.1.1.8   root     2111:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
                   2112:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
                   2113:             tcg_gen_mov_tl(cpu_LO[0], t0);
                   2114:             tcg_gen_movi_tl(cpu_HI[0], 0);
                   2115:             tcg_gen_br(l1);
                   2116:             gen_set_label(l2);
                   2117:             tcg_gen_div_i64(cpu_LO[0], t0, t1);
                   2118:             tcg_gen_rem_i64(cpu_HI[0], t0, t1);
1.1.1.7   root     2119:             gen_set_label(l1);
                   2120:         }
1.1.1.5   root     2121:         opn = "ddiv";
                   2122:         break;
                   2123:     case OPC_DDIVU:
1.1.1.7   root     2124:         {
                   2125:             int l1 = gen_new_label();
                   2126: 
                   2127:             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
                   2128:             tcg_gen_divu_i64(cpu_LO[0], t0, t1);
                   2129:             tcg_gen_remu_i64(cpu_HI[0], t0, t1);
                   2130:             gen_set_label(l1);
                   2131:         }
1.1.1.5   root     2132:         opn = "ddivu";
                   2133:         break;
                   2134:     case OPC_DMULT:
1.1.1.7   root     2135:         gen_helper_dmult(t0, t1);
1.1.1.5   root     2136:         opn = "dmult";
                   2137:         break;
                   2138:     case OPC_DMULTU:
1.1.1.7   root     2139:         gen_helper_dmultu(t0, t1);
1.1.1.5   root     2140:         opn = "dmultu";
                   2141:         break;
                   2142: #endif
1.1       root     2143:     case OPC_MADD:
1.1.1.7   root     2144:         {
1.1.1.8   root     2145:             TCGv_i64 t2 = tcg_temp_new_i64();
                   2146:             TCGv_i64 t3 = tcg_temp_new_i64();
1.1.1.7   root     2147: 
1.1.1.8   root     2148:             tcg_gen_ext_tl_i64(t2, t0);
                   2149:             tcg_gen_ext_tl_i64(t3, t1);
                   2150:             tcg_gen_mul_i64(t2, t2, t3);
                   2151:             tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
                   2152:             tcg_gen_add_i64(t2, t2, t3);
                   2153:             tcg_temp_free_i64(t3);
                   2154:             tcg_gen_trunc_i64_tl(t0, t2);
                   2155:             tcg_gen_shri_i64(t2, t2, 32);
                   2156:             tcg_gen_trunc_i64_tl(t1, t2);
                   2157:             tcg_temp_free_i64(t2);
1.1.1.7   root     2158:             tcg_gen_ext32s_tl(cpu_LO[0], t0);
1.1.1.8   root     2159:             tcg_gen_ext32s_tl(cpu_HI[0], t1);
1.1.1.7   root     2160:         }
1.1       root     2161:         opn = "madd";
                   2162:         break;
                   2163:     case OPC_MADDU:
1.1.1.7   root     2164:        {
1.1.1.8   root     2165:             TCGv_i64 t2 = tcg_temp_new_i64();
                   2166:             TCGv_i64 t3 = tcg_temp_new_i64();
1.1.1.7   root     2167: 
                   2168:             tcg_gen_ext32u_tl(t0, t0);
                   2169:             tcg_gen_ext32u_tl(t1, t1);
1.1.1.8   root     2170:             tcg_gen_extu_tl_i64(t2, t0);
                   2171:             tcg_gen_extu_tl_i64(t3, t1);
                   2172:             tcg_gen_mul_i64(t2, t2, t3);
                   2173:             tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
                   2174:             tcg_gen_add_i64(t2, t2, t3);
                   2175:             tcg_temp_free_i64(t3);
                   2176:             tcg_gen_trunc_i64_tl(t0, t2);
                   2177:             tcg_gen_shri_i64(t2, t2, 32);
                   2178:             tcg_gen_trunc_i64_tl(t1, t2);
                   2179:             tcg_temp_free_i64(t2);
1.1.1.7   root     2180:             tcg_gen_ext32s_tl(cpu_LO[0], t0);
                   2181:             tcg_gen_ext32s_tl(cpu_HI[0], t1);
                   2182:         }
1.1       root     2183:         opn = "maddu";
                   2184:         break;
                   2185:     case OPC_MSUB:
1.1.1.7   root     2186:         {
1.1.1.8   root     2187:             TCGv_i64 t2 = tcg_temp_new_i64();
                   2188:             TCGv_i64 t3 = tcg_temp_new_i64();
1.1.1.7   root     2189: 
1.1.1.8   root     2190:             tcg_gen_ext_tl_i64(t2, t0);
                   2191:             tcg_gen_ext_tl_i64(t3, t1);
                   2192:             tcg_gen_mul_i64(t2, t2, t3);
                   2193:             tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
                   2194:             tcg_gen_sub_i64(t2, t3, t2);
                   2195:             tcg_temp_free_i64(t3);
                   2196:             tcg_gen_trunc_i64_tl(t0, t2);
                   2197:             tcg_gen_shri_i64(t2, t2, 32);
                   2198:             tcg_gen_trunc_i64_tl(t1, t2);
                   2199:             tcg_temp_free_i64(t2);
1.1.1.7   root     2200:             tcg_gen_ext32s_tl(cpu_LO[0], t0);
                   2201:             tcg_gen_ext32s_tl(cpu_HI[0], t1);
                   2202:         }
1.1       root     2203:         opn = "msub";
                   2204:         break;
                   2205:     case OPC_MSUBU:
1.1.1.7   root     2206:         {
1.1.1.8   root     2207:             TCGv_i64 t2 = tcg_temp_new_i64();
                   2208:             TCGv_i64 t3 = tcg_temp_new_i64();
1.1.1.7   root     2209: 
                   2210:             tcg_gen_ext32u_tl(t0, t0);
                   2211:             tcg_gen_ext32u_tl(t1, t1);
1.1.1.8   root     2212:             tcg_gen_extu_tl_i64(t2, t0);
                   2213:             tcg_gen_extu_tl_i64(t3, t1);
                   2214:             tcg_gen_mul_i64(t2, t2, t3);
                   2215:             tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
                   2216:             tcg_gen_sub_i64(t2, t3, t2);
                   2217:             tcg_temp_free_i64(t3);
                   2218:             tcg_gen_trunc_i64_tl(t0, t2);
                   2219:             tcg_gen_shri_i64(t2, t2, 32);
                   2220:             tcg_gen_trunc_i64_tl(t1, t2);
                   2221:             tcg_temp_free_i64(t2);
1.1.1.7   root     2222:             tcg_gen_ext32s_tl(cpu_LO[0], t0);
                   2223:             tcg_gen_ext32s_tl(cpu_HI[0], t1);
                   2224:         }
1.1       root     2225:         opn = "msubu";
                   2226:         break;
                   2227:     default:
1.1.1.6   root     2228:         MIPS_INVAL(opn);
1.1       root     2229:         generate_exception(ctx, EXCP_RI);
1.1.1.7   root     2230:         goto out;
1.1       root     2231:     }
                   2232:     MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
1.1.1.7   root     2233:  out:
                   2234:     tcg_temp_free(t0);
                   2235:     tcg_temp_free(t1);
1.1       root     2236: }
                   2237: 
1.1.1.6   root     2238: static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
                   2239:                             int rd, int rs, int rt)
                   2240: {
                   2241:     const char *opn = "mul vr54xx";
1.1.1.8   root     2242:     TCGv t0 = tcg_temp_new();
                   2243:     TCGv t1 = tcg_temp_new();
1.1.1.6   root     2244: 
1.1.1.7   root     2245:     gen_load_gpr(t0, rs);
                   2246:     gen_load_gpr(t1, rt);
1.1.1.6   root     2247: 
                   2248:     switch (opc) {
                   2249:     case OPC_VR54XX_MULS:
1.1.1.7   root     2250:         gen_helper_muls(t0, t0, t1);
1.1.1.6   root     2251:         opn = "muls";
1.1.1.7   root     2252:         break;
1.1.1.6   root     2253:     case OPC_VR54XX_MULSU:
1.1.1.7   root     2254:         gen_helper_mulsu(t0, t0, t1);
1.1.1.6   root     2255:         opn = "mulsu";
1.1.1.7   root     2256:         break;
1.1.1.6   root     2257:     case OPC_VR54XX_MACC:
1.1.1.7   root     2258:         gen_helper_macc(t0, t0, t1);
1.1.1.6   root     2259:         opn = "macc";
1.1.1.7   root     2260:         break;
1.1.1.6   root     2261:     case OPC_VR54XX_MACCU:
1.1.1.7   root     2262:         gen_helper_maccu(t0, t0, t1);
1.1.1.6   root     2263:         opn = "maccu";
1.1.1.7   root     2264:         break;
1.1.1.6   root     2265:     case OPC_VR54XX_MSAC:
1.1.1.7   root     2266:         gen_helper_msac(t0, t0, t1);
1.1.1.6   root     2267:         opn = "msac";
1.1.1.7   root     2268:         break;
1.1.1.6   root     2269:     case OPC_VR54XX_MSACU:
1.1.1.7   root     2270:         gen_helper_msacu(t0, t0, t1);
1.1.1.6   root     2271:         opn = "msacu";
1.1.1.7   root     2272:         break;
1.1.1.6   root     2273:     case OPC_VR54XX_MULHI:
1.1.1.7   root     2274:         gen_helper_mulhi(t0, t0, t1);
1.1.1.6   root     2275:         opn = "mulhi";
1.1.1.7   root     2276:         break;
1.1.1.6   root     2277:     case OPC_VR54XX_MULHIU:
1.1.1.7   root     2278:         gen_helper_mulhiu(t0, t0, t1);
1.1.1.6   root     2279:         opn = "mulhiu";
1.1.1.7   root     2280:         break;
1.1.1.6   root     2281:     case OPC_VR54XX_MULSHI:
1.1.1.7   root     2282:         gen_helper_mulshi(t0, t0, t1);
1.1.1.6   root     2283:         opn = "mulshi";
1.1.1.7   root     2284:         break;
1.1.1.6   root     2285:     case OPC_VR54XX_MULSHIU:
1.1.1.7   root     2286:         gen_helper_mulshiu(t0, t0, t1);
1.1.1.6   root     2287:         opn = "mulshiu";
1.1.1.7   root     2288:         break;
1.1.1.6   root     2289:     case OPC_VR54XX_MACCHI:
1.1.1.7   root     2290:         gen_helper_macchi(t0, t0, t1);
1.1.1.6   root     2291:         opn = "macchi";
1.1.1.7   root     2292:         break;
1.1.1.6   root     2293:     case OPC_VR54XX_MACCHIU:
1.1.1.7   root     2294:         gen_helper_macchiu(t0, t0, t1);
1.1.1.6   root     2295:         opn = "macchiu";
1.1.1.7   root     2296:         break;
1.1.1.6   root     2297:     case OPC_VR54XX_MSACHI:
1.1.1.7   root     2298:         gen_helper_msachi(t0, t0, t1);
1.1.1.6   root     2299:         opn = "msachi";
1.1.1.7   root     2300:         break;
1.1.1.6   root     2301:     case OPC_VR54XX_MSACHIU:
1.1.1.7   root     2302:         gen_helper_msachiu(t0, t0, t1);
1.1.1.6   root     2303:         opn = "msachiu";
1.1.1.7   root     2304:         break;
1.1.1.6   root     2305:     default:
                   2306:         MIPS_INVAL("mul vr54xx");
                   2307:         generate_exception(ctx, EXCP_RI);
1.1.1.7   root     2308:         goto out;
1.1.1.6   root     2309:     }
1.1.1.7   root     2310:     gen_store_gpr(t0, rd);
1.1.1.6   root     2311:     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1.1.1.7   root     2312: 
                   2313:  out:
                   2314:     tcg_temp_free(t0);
                   2315:     tcg_temp_free(t1);
1.1.1.6   root     2316: }
                   2317: 
1.1.1.5   root     2318: static void gen_cl (DisasContext *ctx, uint32_t opc,
1.1       root     2319:                     int rd, int rs)
                   2320: {
1.1.1.6   root     2321:     const char *opn = "CLx";
1.1.1.8   root     2322:     TCGv t0;
1.1.1.7   root     2323: 
1.1       root     2324:     if (rd == 0) {
1.1.1.6   root     2325:         /* Treat as NOP. */
1.1       root     2326:         MIPS_DEBUG("NOP");
1.1.1.8   root     2327:         return;
1.1       root     2328:     }
1.1.1.8   root     2329:     t0 = tcg_temp_new();
1.1.1.7   root     2330:     gen_load_gpr(t0, rs);
1.1       root     2331:     switch (opc) {
                   2332:     case OPC_CLO:
1.1.1.8   root     2333:         gen_helper_clo(cpu_gpr[rd], t0);
1.1       root     2334:         opn = "clo";
                   2335:         break;
                   2336:     case OPC_CLZ:
1.1.1.8   root     2337:         gen_helper_clz(cpu_gpr[rd], t0);
1.1       root     2338:         opn = "clz";
                   2339:         break;
1.1.1.6   root     2340: #if defined(TARGET_MIPS64)
1.1.1.5   root     2341:     case OPC_DCLO:
1.1.1.8   root     2342:         gen_helper_dclo(cpu_gpr[rd], t0);
1.1.1.5   root     2343:         opn = "dclo";
                   2344:         break;
                   2345:     case OPC_DCLZ:
1.1.1.8   root     2346:         gen_helper_dclz(cpu_gpr[rd], t0);
1.1.1.5   root     2347:         opn = "dclz";
                   2348:         break;
                   2349: #endif
1.1       root     2350:     }
                   2351:     MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
1.1.1.7   root     2352:     tcg_temp_free(t0);
1.1       root     2353: }
                   2354: 
1.1.1.12! root     2355: /* Godson integer instructions */
        !          2356: static void gen_loongson_integer (DisasContext *ctx, uint32_t opc,
        !          2357:                                 int rd, int rs, int rt)
        !          2358: {
        !          2359:     const char *opn = "loongson";
        !          2360:     TCGv t0, t1;
        !          2361: 
        !          2362:     if (rd == 0) {
        !          2363:         /* Treat as NOP. */
        !          2364:         MIPS_DEBUG("NOP");
        !          2365:         return;
        !          2366:     }
        !          2367: 
        !          2368:     switch (opc) {
        !          2369:     case OPC_MULT_G_2E:
        !          2370:     case OPC_MULT_G_2F:
        !          2371:     case OPC_MULTU_G_2E:
        !          2372:     case OPC_MULTU_G_2F:
        !          2373: #if defined(TARGET_MIPS64)
        !          2374:     case OPC_DMULT_G_2E:
        !          2375:     case OPC_DMULT_G_2F:
        !          2376:     case OPC_DMULTU_G_2E:
        !          2377:     case OPC_DMULTU_G_2F:
        !          2378: #endif
        !          2379:         t0 = tcg_temp_new();
        !          2380:         t1 = tcg_temp_new();
        !          2381:         break;
        !          2382:     default:
        !          2383:         t0 = tcg_temp_local_new();
        !          2384:         t1 = tcg_temp_local_new();
        !          2385:         break;
        !          2386:     }
        !          2387: 
        !          2388:     gen_load_gpr(t0, rs);
        !          2389:     gen_load_gpr(t1, rt);
        !          2390: 
        !          2391:     switch (opc) {
        !          2392:     case OPC_MULT_G_2E:
        !          2393:     case OPC_MULT_G_2F:
        !          2394:         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
        !          2395:         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
        !          2396:         opn = "mult.g";
        !          2397:         break;
        !          2398:     case OPC_MULTU_G_2E:
        !          2399:     case OPC_MULTU_G_2F:
        !          2400:         tcg_gen_ext32u_tl(t0, t0);
        !          2401:         tcg_gen_ext32u_tl(t1, t1);
        !          2402:         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
        !          2403:         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
        !          2404:         opn = "multu.g";
        !          2405:         break;
        !          2406:     case OPC_DIV_G_2E:
        !          2407:     case OPC_DIV_G_2F:
        !          2408:         {
        !          2409:             int l1 = gen_new_label();
        !          2410:             int l2 = gen_new_label();
        !          2411:             int l3 = gen_new_label();
        !          2412:             tcg_gen_ext32s_tl(t0, t0);
        !          2413:             tcg_gen_ext32s_tl(t1, t1);
        !          2414:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
        !          2415:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
        !          2416:             tcg_gen_br(l3);
        !          2417:             gen_set_label(l1);
        !          2418:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
        !          2419:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
        !          2420:             tcg_gen_mov_tl(cpu_gpr[rd], t0);
        !          2421:             tcg_gen_br(l3);
        !          2422:             gen_set_label(l2);
        !          2423:             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
        !          2424:             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
        !          2425:             gen_set_label(l3);
        !          2426:         }
        !          2427:         opn = "div.g";
        !          2428:         break;
        !          2429:     case OPC_DIVU_G_2E:
        !          2430:     case OPC_DIVU_G_2F:
        !          2431:         {
        !          2432:             int l1 = gen_new_label();
        !          2433:             int l2 = gen_new_label();
        !          2434:             tcg_gen_ext32u_tl(t0, t0);
        !          2435:             tcg_gen_ext32u_tl(t1, t1);
        !          2436:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
        !          2437:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
        !          2438:             tcg_gen_br(l2);
        !          2439:             gen_set_label(l1);
        !          2440:             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
        !          2441:             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
        !          2442:             gen_set_label(l2);
        !          2443:         }
        !          2444:         opn = "divu.g";
        !          2445:         break;
        !          2446:     case OPC_MOD_G_2E:
        !          2447:     case OPC_MOD_G_2F:
        !          2448:         {
        !          2449:             int l1 = gen_new_label();
        !          2450:             int l2 = gen_new_label();
        !          2451:             int l3 = gen_new_label();
        !          2452:             tcg_gen_ext32u_tl(t0, t0);
        !          2453:             tcg_gen_ext32u_tl(t1, t1);
        !          2454:             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
        !          2455:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
        !          2456:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
        !          2457:             gen_set_label(l1);
        !          2458:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
        !          2459:             tcg_gen_br(l3);
        !          2460:             gen_set_label(l2);
        !          2461:             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
        !          2462:             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
        !          2463:             gen_set_label(l3);
        !          2464:         }
        !          2465:         opn = "mod.g";
        !          2466:         break;
        !          2467:     case OPC_MODU_G_2E:
        !          2468:     case OPC_MODU_G_2F:
        !          2469:         {
        !          2470:             int l1 = gen_new_label();
        !          2471:             int l2 = gen_new_label();
        !          2472:             tcg_gen_ext32u_tl(t0, t0);
        !          2473:             tcg_gen_ext32u_tl(t1, t1);
        !          2474:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
        !          2475:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
        !          2476:             tcg_gen_br(l2);
        !          2477:             gen_set_label(l1);
        !          2478:             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
        !          2479:             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
        !          2480:             gen_set_label(l2);
        !          2481:         }
        !          2482:         opn = "modu.g";
        !          2483:         break;
        !          2484: #if defined(TARGET_MIPS64)
        !          2485:     case OPC_DMULT_G_2E:
        !          2486:     case OPC_DMULT_G_2F:
        !          2487:         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
        !          2488:         opn = "dmult.g";
        !          2489:         break;
        !          2490:     case OPC_DMULTU_G_2E:
        !          2491:     case OPC_DMULTU_G_2F:
        !          2492:         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
        !          2493:         opn = "dmultu.g";
        !          2494:         break;
        !          2495:     case OPC_DDIV_G_2E:
        !          2496:     case OPC_DDIV_G_2F:
        !          2497:         {
        !          2498:             int l1 = gen_new_label();
        !          2499:             int l2 = gen_new_label();
        !          2500:             int l3 = gen_new_label();
        !          2501:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
        !          2502:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
        !          2503:             tcg_gen_br(l3);
        !          2504:             gen_set_label(l1);
        !          2505:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
        !          2506:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
        !          2507:             tcg_gen_mov_tl(cpu_gpr[rd], t0);
        !          2508:             tcg_gen_br(l3);
        !          2509:             gen_set_label(l2);
        !          2510:             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
        !          2511:             gen_set_label(l3);
        !          2512:         }
        !          2513:         opn = "ddiv.g";
        !          2514:         break;
        !          2515:     case OPC_DDIVU_G_2E:
        !          2516:     case OPC_DDIVU_G_2F:
        !          2517:         {
        !          2518:             int l1 = gen_new_label();
        !          2519:             int l2 = gen_new_label();
        !          2520:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
        !          2521:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
        !          2522:             tcg_gen_br(l2);
        !          2523:             gen_set_label(l1);
        !          2524:             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
        !          2525:             gen_set_label(l2);
        !          2526:         }
        !          2527:         opn = "ddivu.g";
        !          2528:         break;
        !          2529:     case OPC_DMOD_G_2E:
        !          2530:     case OPC_DMOD_G_2F:
        !          2531:         {
        !          2532:             int l1 = gen_new_label();
        !          2533:             int l2 = gen_new_label();
        !          2534:             int l3 = gen_new_label();
        !          2535:             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
        !          2536:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
        !          2537:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
        !          2538:             gen_set_label(l1);
        !          2539:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
        !          2540:             tcg_gen_br(l3);
        !          2541:             gen_set_label(l2);
        !          2542:             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
        !          2543:             gen_set_label(l3);
        !          2544:         }
        !          2545:         opn = "dmod.g";
        !          2546:         break;
        !          2547:     case OPC_DMODU_G_2E:
        !          2548:     case OPC_DMODU_G_2F:
        !          2549:         {
        !          2550:             int l1 = gen_new_label();
        !          2551:             int l2 = gen_new_label();
        !          2552:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
        !          2553:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
        !          2554:             tcg_gen_br(l2);
        !          2555:             gen_set_label(l1);
        !          2556:             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
        !          2557:             gen_set_label(l2);
        !          2558:         }
        !          2559:         opn = "dmodu.g";
        !          2560:         break;
        !          2561: #endif
        !          2562:     }
        !          2563: 
        !          2564:     MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
        !          2565:     tcg_temp_free(t0);
        !          2566:     tcg_temp_free(t1);
        !          2567: }
        !          2568: 
        !          2569: /* Traps */
1.1.1.5   root     2570: static void gen_trap (DisasContext *ctx, uint32_t opc,
1.1       root     2571:                       int rs, int rt, int16_t imm)
                   2572: {
                   2573:     int cond;
1.1.1.8   root     2574:     TCGv t0 = tcg_temp_new();
                   2575:     TCGv t1 = tcg_temp_new();
1.1       root     2576: 
                   2577:     cond = 0;
                   2578:     /* Load needed operands */
                   2579:     switch (opc) {
                   2580:     case OPC_TEQ:
                   2581:     case OPC_TGE:
                   2582:     case OPC_TGEU:
                   2583:     case OPC_TLT:
                   2584:     case OPC_TLTU:
                   2585:     case OPC_TNE:
                   2586:         /* Compare two registers */
                   2587:         if (rs != rt) {
1.1.1.7   root     2588:             gen_load_gpr(t0, rs);
                   2589:             gen_load_gpr(t1, rt);
1.1       root     2590:             cond = 1;
                   2591:         }
1.1.1.5   root     2592:         break;
1.1       root     2593:     case OPC_TEQI:
                   2594:     case OPC_TGEI:
                   2595:     case OPC_TGEIU:
                   2596:     case OPC_TLTI:
                   2597:     case OPC_TLTIU:
                   2598:     case OPC_TNEI:
                   2599:         /* Compare register to immediate */
                   2600:         if (rs != 0 || imm != 0) {
1.1.1.7   root     2601:             gen_load_gpr(t0, rs);
                   2602:             tcg_gen_movi_tl(t1, (int32_t)imm);
1.1       root     2603:             cond = 1;
                   2604:         }
                   2605:         break;
                   2606:     }
                   2607:     if (cond == 0) {
                   2608:         switch (opc) {
                   2609:         case OPC_TEQ:   /* rs == rs */
                   2610:         case OPC_TEQI:  /* r0 == 0  */
                   2611:         case OPC_TGE:   /* rs >= rs */
                   2612:         case OPC_TGEI:  /* r0 >= 0  */
                   2613:         case OPC_TGEU:  /* rs >= rs unsigned */
                   2614:         case OPC_TGEIU: /* r0 >= 0  unsigned */
                   2615:             /* Always trap */
1.1.1.8   root     2616:             generate_exception(ctx, EXCP_TRAP);
1.1       root     2617:             break;
                   2618:         case OPC_TLT:   /* rs < rs           */
                   2619:         case OPC_TLTI:  /* r0 < 0            */
                   2620:         case OPC_TLTU:  /* rs < rs unsigned  */
                   2621:         case OPC_TLTIU: /* r0 < 0  unsigned  */
                   2622:         case OPC_TNE:   /* rs != rs          */
                   2623:         case OPC_TNEI:  /* r0 != 0           */
1.1.1.6   root     2624:             /* Never trap: treat as NOP. */
1.1.1.8   root     2625:             break;
1.1       root     2626:         }
                   2627:     } else {
1.1.1.8   root     2628:         int l1 = gen_new_label();
                   2629: 
1.1       root     2630:         switch (opc) {
                   2631:         case OPC_TEQ:
                   2632:         case OPC_TEQI:
1.1.1.8   root     2633:             tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
1.1       root     2634:             break;
                   2635:         case OPC_TGE:
                   2636:         case OPC_TGEI:
1.1.1.8   root     2637:             tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
1.1       root     2638:             break;
                   2639:         case OPC_TGEU:
                   2640:         case OPC_TGEIU:
1.1.1.8   root     2641:             tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
1.1       root     2642:             break;
                   2643:         case OPC_TLT:
                   2644:         case OPC_TLTI:
1.1.1.8   root     2645:             tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
1.1       root     2646:             break;
                   2647:         case OPC_TLTU:
                   2648:         case OPC_TLTIU:
1.1.1.8   root     2649:             tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
1.1       root     2650:             break;
                   2651:         case OPC_TNE:
                   2652:         case OPC_TNEI:
1.1.1.8   root     2653:             tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
1.1       root     2654:             break;
                   2655:         }
1.1.1.8   root     2656:         generate_exception(ctx, EXCP_TRAP);
1.1.1.7   root     2657:         gen_set_label(l1);
                   2658:     }
                   2659:     tcg_temp_free(t0);
                   2660:     tcg_temp_free(t1);
1.1       root     2661: }
                   2662: 
1.1.1.7   root     2663: static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1.1.1.2   root     2664: {
                   2665:     TranslationBlock *tb;
                   2666:     tb = ctx->tb;
1.1.1.9   root     2667:     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
                   2668:         likely(!ctx->singlestep_enabled)) {
1.1.1.7   root     2669:         tcg_gen_goto_tb(n);
1.1.1.6   root     2670:         gen_save_pc(dest);
1.1.1.7   root     2671:         tcg_gen_exit_tb((long)tb + n);
1.1.1.2   root     2672:     } else {
1.1.1.6   root     2673:         gen_save_pc(dest);
1.1.1.9   root     2674:         if (ctx->singlestep_enabled) {
                   2675:             save_cpu_state(ctx, 0);
                   2676:             gen_helper_0i(raise_exception, EXCP_DEBUG);
                   2677:         }
1.1.1.7   root     2678:         tcg_gen_exit_tb(0);
1.1.1.2   root     2679:     }
                   2680: }
                   2681: 
1.1       root     2682: /* Branches (before delay slot) */
1.1.1.5   root     2683: static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1.1.1.12! root     2684:                                 int insn_bytes,
1.1       root     2685:                                 int rs, int rt, int32_t offset)
                   2686: {
1.1.1.7   root     2687:     target_ulong btgt = -1;
1.1.1.6   root     2688:     int blink = 0;
1.1.1.7   root     2689:     int bcond_compute = 0;
1.1.1.8   root     2690:     TCGv t0 = tcg_temp_new();
                   2691:     TCGv t1 = tcg_temp_new();
1.1       root     2692: 
1.1.1.6   root     2693:     if (ctx->hflags & MIPS_HFLAG_BMASK) {
                   2694: #ifdef MIPS_DEBUG_DISAS
1.1.1.7   root     2695:         LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
1.1.1.6   root     2696: #endif
                   2697:         generate_exception(ctx, EXCP_RI);
1.1.1.7   root     2698:         goto out;
1.1.1.6   root     2699:     }
                   2700: 
                   2701:     /* Load needed operands */
                   2702:     switch (opc) {
                   2703:     case OPC_BEQ:
                   2704:     case OPC_BEQL:
                   2705:     case OPC_BNE:
                   2706:     case OPC_BNEL:
1.1       root     2707:         /* Compare two registers */
                   2708:         if (rs != rt) {
1.1.1.7   root     2709:             gen_load_gpr(t0, rs);
                   2710:             gen_load_gpr(t1, rt);
                   2711:             bcond_compute = 1;
1.1       root     2712:         }
1.1.1.12! root     2713:         btgt = ctx->pc + insn_bytes + offset;
1.1       root     2714:         break;
                   2715:     case OPC_BGEZ:
                   2716:     case OPC_BGEZAL:
1.1.1.12! root     2717:     case OPC_BGEZALS:
1.1       root     2718:     case OPC_BGEZALL:
                   2719:     case OPC_BGEZL:
                   2720:     case OPC_BGTZ:
                   2721:     case OPC_BGTZL:
                   2722:     case OPC_BLEZ:
                   2723:     case OPC_BLEZL:
                   2724:     case OPC_BLTZ:
                   2725:     case OPC_BLTZAL:
1.1.1.12! root     2726:     case OPC_BLTZALS:
1.1       root     2727:     case OPC_BLTZALL:
                   2728:     case OPC_BLTZL:
                   2729:         /* Compare to zero */
                   2730:         if (rs != 0) {
1.1.1.7   root     2731:             gen_load_gpr(t0, rs);
                   2732:             bcond_compute = 1;
1.1       root     2733:         }
1.1.1.12! root     2734:         btgt = ctx->pc + insn_bytes + offset;
1.1       root     2735:         break;
                   2736:     case OPC_J:
                   2737:     case OPC_JAL:
1.1.1.12! root     2738:     case OPC_JALX:
        !          2739:     case OPC_JALS:
        !          2740:     case OPC_JALXS:
1.1       root     2741:         /* Jump to immediate */
1.1.1.12! root     2742:         btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
1.1       root     2743:         break;
                   2744:     case OPC_JR:
                   2745:     case OPC_JALR:
1.1.1.12! root     2746:     case OPC_JALRC:
        !          2747:     case OPC_JALRS:
1.1       root     2748:         /* Jump to register */
1.1.1.5   root     2749:         if (offset != 0 && offset != 16) {
                   2750:             /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
1.1.1.6   root     2751:                others are reserved. */
                   2752:             MIPS_INVAL("jump hint");
1.1       root     2753:             generate_exception(ctx, EXCP_RI);
1.1.1.7   root     2754:             goto out;
1.1       root     2755:         }
1.1.1.7   root     2756:         gen_load_gpr(btarget, rs);
1.1       root     2757:         break;
                   2758:     default:
                   2759:         MIPS_INVAL("branch/jump");
                   2760:         generate_exception(ctx, EXCP_RI);
1.1.1.7   root     2761:         goto out;
1.1       root     2762:     }
1.1.1.7   root     2763:     if (bcond_compute == 0) {
1.1       root     2764:         /* No condition to be computed */
                   2765:         switch (opc) {
                   2766:         case OPC_BEQ:     /* rx == rx        */
                   2767:         case OPC_BEQL:    /* rx == rx likely */
                   2768:         case OPC_BGEZ:    /* 0 >= 0          */
                   2769:         case OPC_BGEZL:   /* 0 >= 0 likely   */
                   2770:         case OPC_BLEZ:    /* 0 <= 0          */
                   2771:         case OPC_BLEZL:   /* 0 <= 0 likely   */
                   2772:             /* Always take */
1.1.1.2   root     2773:             ctx->hflags |= MIPS_HFLAG_B;
1.1       root     2774:             MIPS_DEBUG("balways");
                   2775:             break;
1.1.1.12! root     2776:         case OPC_BGEZALS:
1.1       root     2777:         case OPC_BGEZAL:  /* 0 >= 0          */
                   2778:         case OPC_BGEZALL: /* 0 >= 0 likely   */
1.1.1.12! root     2779:             ctx->hflags |= (opc == OPC_BGEZALS
        !          2780:                             ? MIPS_HFLAG_BDS16
        !          2781:                             : MIPS_HFLAG_BDS32);
1.1       root     2782:             /* Always take and link */
                   2783:             blink = 31;
1.1.1.2   root     2784:             ctx->hflags |= MIPS_HFLAG_B;
1.1       root     2785:             MIPS_DEBUG("balways and link");
                   2786:             break;
                   2787:         case OPC_BNE:     /* rx != rx        */
                   2788:         case OPC_BGTZ:    /* 0 > 0           */
                   2789:         case OPC_BLTZ:    /* 0 < 0           */
1.1.1.6   root     2790:             /* Treat as NOP. */
1.1       root     2791:             MIPS_DEBUG("bnever (NOP)");
1.1.1.7   root     2792:             goto out;
1.1.1.12! root     2793:         case OPC_BLTZALS:
1.1.1.2   root     2794:         case OPC_BLTZAL:  /* 0 < 0           */
1.1.1.12! root     2795:             ctx->hflags |= (opc == OPC_BLTZALS
        !          2796:                             ? MIPS_HFLAG_BDS16
        !          2797:                             : MIPS_HFLAG_BDS32);
        !          2798:             /* Handle as an unconditional branch to get correct delay
        !          2799:                slot checking.  */
        !          2800:             blink = 31;
        !          2801:             btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
        !          2802:             ctx->hflags |= MIPS_HFLAG_B;
1.1.1.6   root     2803:             MIPS_DEBUG("bnever and link");
1.1.1.12! root     2804:             break;
1.1.1.2   root     2805:         case OPC_BLTZALL: /* 0 < 0 likely */
1.1.1.8   root     2806:             tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
1.1.1.6   root     2807:             /* Skip the instruction in the delay slot */
                   2808:             MIPS_DEBUG("bnever, link and skip");
                   2809:             ctx->pc += 4;
1.1.1.7   root     2810:             goto out;
1.1       root     2811:         case OPC_BNEL:    /* rx != rx likely */
                   2812:         case OPC_BGTZL:   /* 0 > 0 likely */
                   2813:         case OPC_BLTZL:   /* 0 < 0 likely */
                   2814:             /* Skip the instruction in the delay slot */
                   2815:             MIPS_DEBUG("bnever and skip");
1.1.1.6   root     2816:             ctx->pc += 4;
1.1.1.7   root     2817:             goto out;
1.1       root     2818:         case OPC_J:
1.1.1.2   root     2819:             ctx->hflags |= MIPS_HFLAG_B;
1.1.1.7   root     2820:             MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
1.1       root     2821:             break;
1.1.1.12! root     2822:         case OPC_JALXS:
        !          2823:         case OPC_JALX:
        !          2824:             ctx->hflags |= MIPS_HFLAG_BX;
        !          2825:             /* Fallthrough */
        !          2826:         case OPC_JALS:
1.1       root     2827:         case OPC_JAL:
                   2828:             blink = 31;
1.1.1.2   root     2829:             ctx->hflags |= MIPS_HFLAG_B;
1.1.1.12! root     2830:             ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
        !          2831:                             ? MIPS_HFLAG_BDS16
        !          2832:                             : MIPS_HFLAG_BDS32);
1.1.1.7   root     2833:             MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
1.1       root     2834:             break;
                   2835:         case OPC_JR:
1.1.1.2   root     2836:             ctx->hflags |= MIPS_HFLAG_BR;
1.1.1.12! root     2837:             if (insn_bytes == 4)
        !          2838:                 ctx->hflags |= MIPS_HFLAG_BDS32;
1.1       root     2839:             MIPS_DEBUG("jr %s", regnames[rs]);
                   2840:             break;
1.1.1.12! root     2841:         case OPC_JALRS:
1.1       root     2842:         case OPC_JALR:
1.1.1.12! root     2843:         case OPC_JALRC:
1.1       root     2844:             blink = rt;
1.1.1.2   root     2845:             ctx->hflags |= MIPS_HFLAG_BR;
1.1.1.12! root     2846:             ctx->hflags |= (opc == OPC_JALRS
        !          2847:                             ? MIPS_HFLAG_BDS16
        !          2848:                             : MIPS_HFLAG_BDS32);
1.1       root     2849:             MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
                   2850:             break;
                   2851:         default:
                   2852:             MIPS_INVAL("branch/jump");
                   2853:             generate_exception(ctx, EXCP_RI);
1.1.1.7   root     2854:             goto out;
1.1       root     2855:         }
                   2856:     } else {
                   2857:         switch (opc) {
                   2858:         case OPC_BEQ:
1.1.1.12! root     2859:             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
1.1.1.6   root     2860:             MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
1.1.1.7   root     2861:                        regnames[rs], regnames[rt], btgt);
1.1       root     2862:             goto not_likely;
                   2863:         case OPC_BEQL:
1.1.1.12! root     2864:             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
1.1.1.6   root     2865:             MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
1.1.1.7   root     2866:                        regnames[rs], regnames[rt], btgt);
1.1       root     2867:             goto likely;
                   2868:         case OPC_BNE:
1.1.1.12! root     2869:             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
1.1.1.6   root     2870:             MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
1.1.1.7   root     2871:                        regnames[rs], regnames[rt], btgt);
1.1       root     2872:             goto not_likely;
                   2873:         case OPC_BNEL:
1.1.1.12! root     2874:             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
1.1.1.6   root     2875:             MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
1.1.1.7   root     2876:                        regnames[rs], regnames[rt], btgt);
1.1       root     2877:             goto likely;
                   2878:         case OPC_BGEZ:
1.1.1.12! root     2879:             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
1.1.1.7   root     2880:             MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2881:             goto not_likely;
                   2882:         case OPC_BGEZL:
1.1.1.12! root     2883:             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
1.1.1.7   root     2884:             MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2885:             goto likely;
1.1.1.12! root     2886:         case OPC_BGEZALS:
1.1       root     2887:         case OPC_BGEZAL:
1.1.1.12! root     2888:             ctx->hflags |= (opc == OPC_BGEZALS
        !          2889:                             ? MIPS_HFLAG_BDS16
        !          2890:                             : MIPS_HFLAG_BDS32);
        !          2891:             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
1.1.1.7   root     2892:             MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2893:             blink = 31;
                   2894:             goto not_likely;
                   2895:         case OPC_BGEZALL:
1.1.1.12! root     2896:             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
1.1       root     2897:             blink = 31;
1.1.1.7   root     2898:             MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2899:             goto likely;
                   2900:         case OPC_BGTZ:
1.1.1.12! root     2901:             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
1.1.1.7   root     2902:             MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2903:             goto not_likely;
                   2904:         case OPC_BGTZL:
1.1.1.12! root     2905:             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
1.1.1.7   root     2906:             MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2907:             goto likely;
                   2908:         case OPC_BLEZ:
1.1.1.12! root     2909:             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
1.1.1.7   root     2910:             MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2911:             goto not_likely;
                   2912:         case OPC_BLEZL:
1.1.1.12! root     2913:             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
1.1.1.7   root     2914:             MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2915:             goto likely;
                   2916:         case OPC_BLTZ:
1.1.1.12! root     2917:             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
1.1.1.7   root     2918:             MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2919:             goto not_likely;
                   2920:         case OPC_BLTZL:
1.1.1.12! root     2921:             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
1.1.1.7   root     2922:             MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2923:             goto likely;
1.1.1.12! root     2924:         case OPC_BLTZALS:
1.1       root     2925:         case OPC_BLTZAL:
1.1.1.12! root     2926:             ctx->hflags |= (opc == OPC_BLTZALS
        !          2927:                             ? MIPS_HFLAG_BDS16
        !          2928:                             : MIPS_HFLAG_BDS32);
        !          2929:             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
1.1       root     2930:             blink = 31;
1.1.1.7   root     2931:             MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2932:         not_likely:
1.1.1.2   root     2933:             ctx->hflags |= MIPS_HFLAG_BC;
1.1       root     2934:             break;
                   2935:         case OPC_BLTZALL:
1.1.1.12! root     2936:             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
1.1       root     2937:             blink = 31;
1.1.1.7   root     2938:             MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2939:         likely:
1.1.1.2   root     2940:             ctx->hflags |= MIPS_HFLAG_BL;
1.1       root     2941:             break;
1.1.1.6   root     2942:         default:
                   2943:             MIPS_INVAL("conditional branch/jump");
                   2944:             generate_exception(ctx, EXCP_RI);
1.1.1.7   root     2945:             goto out;
1.1       root     2946:         }
                   2947:     }
1.1.1.6   root     2948:     MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
1.1.1.7   root     2949:                blink, ctx->hflags, btgt);
1.1.1.6   root     2950: 
1.1.1.7   root     2951:     ctx->btarget = btgt;
1.1       root     2952:     if (blink > 0) {
1.1.1.12! root     2953:         int post_delay = insn_bytes;
        !          2954:         int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
        !          2955: 
        !          2956:         if (opc != OPC_JALRC)
        !          2957:             post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
        !          2958: 
        !          2959:         tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
1.1       root     2960:     }
1.1.1.7   root     2961: 
                   2962:  out:
1.1.1.12! root     2963:     if (insn_bytes == 2)
        !          2964:         ctx->hflags |= MIPS_HFLAG_B16;
1.1.1.7   root     2965:     tcg_temp_free(t0);
                   2966:     tcg_temp_free(t1);
1.1       root     2967: }
                   2968: 
1.1.1.5   root     2969: /* special3 bitfield operations */
                   2970: static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
1.1.1.7   root     2971:                         int rs, int lsb, int msb)
1.1       root     2972: {
1.1.1.7   root     2973:     TCGv t0 = tcg_temp_new();
                   2974:     TCGv t1 = tcg_temp_new();
                   2975:     target_ulong mask;
                   2976: 
                   2977:     gen_load_gpr(t1, rs);
1.1.1.5   root     2978:     switch (opc) {
                   2979:     case OPC_EXT:
                   2980:         if (lsb + msb > 31)
                   2981:             goto fail;
1.1.1.7   root     2982:         tcg_gen_shri_tl(t0, t1, lsb);
                   2983:         if (msb != 31) {
                   2984:             tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
                   2985:         } else {
                   2986:             tcg_gen_ext32s_tl(t0, t0);
                   2987:         }
1.1.1.5   root     2988:         break;
1.1.1.6   root     2989: #if defined(TARGET_MIPS64)
1.1.1.5   root     2990:     case OPC_DEXTM:
1.1.1.7   root     2991:         tcg_gen_shri_tl(t0, t1, lsb);
                   2992:         if (msb != 31) {
                   2993:             tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
                   2994:         }
1.1.1.5   root     2995:         break;
                   2996:     case OPC_DEXTU:
1.1.1.7   root     2997:         tcg_gen_shri_tl(t0, t1, lsb + 32);
                   2998:         tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
1.1.1.5   root     2999:         break;
                   3000:     case OPC_DEXT:
1.1.1.7   root     3001:         tcg_gen_shri_tl(t0, t1, lsb);
                   3002:         tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
1.1.1.5   root     3003:         break;
1.1.1.6   root     3004: #endif
1.1.1.5   root     3005:     case OPC_INS:
                   3006:         if (lsb > msb)
                   3007:             goto fail;
1.1.1.7   root     3008:         mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
                   3009:         gen_load_gpr(t0, rt);
                   3010:         tcg_gen_andi_tl(t0, t0, ~mask);
                   3011:         tcg_gen_shli_tl(t1, t1, lsb);
                   3012:         tcg_gen_andi_tl(t1, t1, mask);
                   3013:         tcg_gen_or_tl(t0, t0, t1);
                   3014:         tcg_gen_ext32s_tl(t0, t0);
1.1.1.5   root     3015:         break;
1.1.1.6   root     3016: #if defined(TARGET_MIPS64)
1.1.1.5   root     3017:     case OPC_DINSM:
                   3018:         if (lsb > msb)
                   3019:             goto fail;
1.1.1.7   root     3020:         mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
                   3021:         gen_load_gpr(t0, rt);
                   3022:         tcg_gen_andi_tl(t0, t0, ~mask);
                   3023:         tcg_gen_shli_tl(t1, t1, lsb);
                   3024:         tcg_gen_andi_tl(t1, t1, mask);
                   3025:         tcg_gen_or_tl(t0, t0, t1);
1.1.1.5   root     3026:         break;
                   3027:     case OPC_DINSU:
                   3028:         if (lsb > msb)
                   3029:             goto fail;
1.1.1.11  root     3030:         mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
1.1.1.7   root     3031:         gen_load_gpr(t0, rt);
                   3032:         tcg_gen_andi_tl(t0, t0, ~mask);
                   3033:         tcg_gen_shli_tl(t1, t1, lsb + 32);
                   3034:         tcg_gen_andi_tl(t1, t1, mask);
                   3035:         tcg_gen_or_tl(t0, t0, t1);
1.1.1.5   root     3036:         break;
                   3037:     case OPC_DINS:
                   3038:         if (lsb > msb)
                   3039:             goto fail;
1.1.1.7   root     3040:         gen_load_gpr(t0, rt);
                   3041:         mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
                   3042:         gen_load_gpr(t0, rt);
                   3043:         tcg_gen_andi_tl(t0, t0, ~mask);
                   3044:         tcg_gen_shli_tl(t1, t1, lsb);
                   3045:         tcg_gen_andi_tl(t1, t1, mask);
                   3046:         tcg_gen_or_tl(t0, t0, t1);
1.1.1.5   root     3047:         break;
1.1.1.6   root     3048: #endif
1.1.1.5   root     3049:     default:
                   3050: fail:
                   3051:         MIPS_INVAL("bitops");
                   3052:         generate_exception(ctx, EXCP_RI);
1.1.1.7   root     3053:         tcg_temp_free(t0);
                   3054:         tcg_temp_free(t1);
1.1       root     3055:         return;
                   3056:     }
1.1.1.7   root     3057:     gen_store_gpr(t0, rt);
                   3058:     tcg_temp_free(t0);
                   3059:     tcg_temp_free(t1);
                   3060: }
                   3061: 
                   3062: static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
                   3063: {
1.1.1.8   root     3064:     TCGv t0;
1.1.1.7   root     3065: 
1.1.1.8   root     3066:     if (rd == 0) {
                   3067:         /* If no destination, treat it as a NOP. */
                   3068:         MIPS_DEBUG("NOP");
                   3069:         return;
                   3070:     }
                   3071: 
                   3072:     t0 = tcg_temp_new();
                   3073:     gen_load_gpr(t0, rt);
1.1.1.7   root     3074:     switch (op2) {
                   3075:     case OPC_WSBH:
1.1.1.8   root     3076:         {
                   3077:             TCGv t1 = tcg_temp_new();
                   3078: 
                   3079:             tcg_gen_shri_tl(t1, t0, 8);
                   3080:             tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
                   3081:             tcg_gen_shli_tl(t0, t0, 8);
                   3082:             tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
                   3083:             tcg_gen_or_tl(t0, t0, t1);
                   3084:             tcg_temp_free(t1);
                   3085:             tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
                   3086:         }
1.1.1.7   root     3087:         break;
                   3088:     case OPC_SEB:
1.1.1.8   root     3089:         tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
1.1.1.7   root     3090:         break;
                   3091:     case OPC_SEH:
1.1.1.8   root     3092:         tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
1.1.1.7   root     3093:         break;
                   3094: #if defined(TARGET_MIPS64)
                   3095:     case OPC_DSBH:
1.1.1.8   root     3096:         {
                   3097:             TCGv t1 = tcg_temp_new();
                   3098: 
                   3099:             tcg_gen_shri_tl(t1, t0, 8);
                   3100:             tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
                   3101:             tcg_gen_shli_tl(t0, t0, 8);
                   3102:             tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
                   3103:             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
                   3104:             tcg_temp_free(t1);
                   3105:         }
1.1.1.7   root     3106:         break;
                   3107:     case OPC_DSHD:
1.1.1.8   root     3108:         {
                   3109:             TCGv t1 = tcg_temp_new();
                   3110: 
                   3111:             tcg_gen_shri_tl(t1, t0, 16);
                   3112:             tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
                   3113:             tcg_gen_shli_tl(t0, t0, 16);
                   3114:             tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
                   3115:             tcg_gen_or_tl(t0, t0, t1);
                   3116:             tcg_gen_shri_tl(t1, t0, 32);
                   3117:             tcg_gen_shli_tl(t0, t0, 32);
                   3118:             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
                   3119:             tcg_temp_free(t1);
                   3120:         }
1.1.1.7   root     3121:         break;
                   3122: #endif
                   3123:     default:
                   3124:         MIPS_INVAL("bsfhl");
                   3125:         generate_exception(ctx, EXCP_RI);
                   3126:         tcg_temp_free(t0);
                   3127:         return;
                   3128:     }
                   3129:     tcg_temp_free(t0);
1.1.1.5   root     3130: }
1.1.1.4   root     3131: 
1.1.1.7   root     3132: #ifndef CONFIG_USER_ONLY
1.1.1.5   root     3133: /* CP0 (MMU and control) */
1.1.1.8   root     3134: static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
1.1.1.7   root     3135: {
1.1.1.8   root     3136:     TCGv_i32 t0 = tcg_temp_new_i32();
1.1.1.7   root     3137: 
1.1.1.8   root     3138:     tcg_gen_ld_i32(t0, cpu_env, off);
                   3139:     tcg_gen_ext_i32_tl(arg, t0);
                   3140:     tcg_temp_free_i32(t0);
1.1.1.7   root     3141: }
                   3142: 
1.1.1.8   root     3143: static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
1.1.1.7   root     3144: {
1.1.1.8   root     3145:     tcg_gen_ld_tl(arg, cpu_env, off);
                   3146:     tcg_gen_ext32s_tl(arg, arg);
1.1.1.7   root     3147: }
                   3148: 
1.1.1.8   root     3149: static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
1.1.1.7   root     3150: {
1.1.1.8   root     3151:     TCGv_i32 t0 = tcg_temp_new_i32();
1.1.1.7   root     3152: 
1.1.1.8   root     3153:     tcg_gen_trunc_tl_i32(t0, arg);
                   3154:     tcg_gen_st_i32(t0, cpu_env, off);
                   3155:     tcg_temp_free_i32(t0);
1.1.1.7   root     3156: }
                   3157: 
1.1.1.8   root     3158: static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
1.1.1.7   root     3159: {
1.1.1.8   root     3160:     tcg_gen_ext32s_tl(arg, arg);
                   3161:     tcg_gen_st_tl(arg, cpu_env, off);
1.1.1.7   root     3162: }
                   3163: 
1.1.1.8   root     3164: static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
1.1.1.5   root     3165: {
                   3166:     const char *rn = "invalid";
                   3167: 
1.1.1.6   root     3168:     if (sel != 0)
                   3169:         check_insn(env, ctx, ISA_MIPS32);
                   3170: 
1.1.1.5   root     3171:     switch (reg) {
                   3172:     case 0:
                   3173:         switch (sel) {
                   3174:         case 0:
1.1.1.8   root     3175:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Index));
1.1.1.5   root     3176:             rn = "Index";
                   3177:             break;
                   3178:         case 1:
1.1.1.6   root     3179:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3180:             gen_helper_mfc0_mvpcontrol(arg);
1.1.1.5   root     3181:             rn = "MVPControl";
1.1.1.6   root     3182:             break;
1.1.1.5   root     3183:         case 2:
1.1.1.6   root     3184:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3185:             gen_helper_mfc0_mvpconf0(arg);
1.1.1.5   root     3186:             rn = "MVPConf0";
1.1.1.6   root     3187:             break;
1.1.1.5   root     3188:         case 3:
1.1.1.6   root     3189:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3190:             gen_helper_mfc0_mvpconf1(arg);
1.1.1.5   root     3191:             rn = "MVPConf1";
1.1.1.6   root     3192:             break;
1.1.1.5   root     3193:         default:
                   3194:             goto die;
1.1       root     3195:         }
                   3196:         break;
1.1.1.5   root     3197:     case 1:
                   3198:         switch (sel) {
                   3199:         case 0:
1.1.1.8   root     3200:             gen_helper_mfc0_random(arg);
1.1.1.5   root     3201:             rn = "Random";
1.1.1.6   root     3202:             break;
1.1.1.5   root     3203:         case 1:
1.1.1.6   root     3204:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3205:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEControl));
1.1.1.5   root     3206:             rn = "VPEControl";
1.1.1.6   root     3207:             break;
1.1.1.5   root     3208:         case 2:
1.1.1.6   root     3209:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3210:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf0));
1.1.1.5   root     3211:             rn = "VPEConf0";
1.1.1.6   root     3212:             break;
1.1.1.5   root     3213:         case 3:
1.1.1.6   root     3214:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3215:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf1));
1.1.1.5   root     3216:             rn = "VPEConf1";
1.1.1.6   root     3217:             break;
1.1.1.5   root     3218:         case 4:
1.1.1.6   root     3219:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3220:             gen_mfc0_load64(arg, offsetof(CPUState, CP0_YQMask));
1.1.1.5   root     3221:             rn = "YQMask";
1.1.1.6   root     3222:             break;
1.1.1.5   root     3223:         case 5:
1.1.1.6   root     3224:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3225:             gen_mfc0_load64(arg, offsetof(CPUState, CP0_VPESchedule));
1.1.1.5   root     3226:             rn = "VPESchedule";
1.1.1.6   root     3227:             break;
1.1.1.5   root     3228:         case 6:
1.1.1.6   root     3229:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3230:             gen_mfc0_load64(arg, offsetof(CPUState, CP0_VPEScheFBack));
1.1.1.5   root     3231:             rn = "VPEScheFBack";
1.1.1.6   root     3232:             break;
1.1.1.5   root     3233:         case 7:
1.1.1.6   root     3234:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3235:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEOpt));
1.1.1.5   root     3236:             rn = "VPEOpt";
1.1.1.6   root     3237:             break;
1.1.1.5   root     3238:         default:
                   3239:             goto die;
                   3240:         }
1.1       root     3241:         break;
1.1.1.5   root     3242:     case 2:
                   3243:         switch (sel) {
                   3244:         case 0:
1.1.1.8   root     3245:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo0));
                   3246:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3247:             rn = "EntryLo0";
                   3248:             break;
                   3249:         case 1:
                   3250:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3251:             gen_helper_mfc0_tcstatus(arg);
1.1.1.6   root     3252:             rn = "TCStatus";
                   3253:             break;
                   3254:         case 2:
                   3255:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3256:             gen_helper_mfc0_tcbind(arg);
1.1.1.6   root     3257:             rn = "TCBind";
                   3258:             break;
1.1.1.5   root     3259:         case 3:
1.1.1.6   root     3260:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3261:             gen_helper_mfc0_tcrestart(arg);
1.1.1.6   root     3262:             rn = "TCRestart";
                   3263:             break;
1.1.1.5   root     3264:         case 4:
1.1.1.6   root     3265:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3266:             gen_helper_mfc0_tchalt(arg);
1.1.1.6   root     3267:             rn = "TCHalt";
                   3268:             break;
1.1.1.5   root     3269:         case 5:
1.1.1.6   root     3270:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3271:             gen_helper_mfc0_tccontext(arg);
1.1.1.6   root     3272:             rn = "TCContext";
                   3273:             break;
1.1.1.5   root     3274:         case 6:
1.1.1.6   root     3275:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3276:             gen_helper_mfc0_tcschedule(arg);
1.1.1.6   root     3277:             rn = "TCSchedule";
                   3278:             break;
1.1.1.5   root     3279:         case 7:
1.1.1.6   root     3280:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3281:             gen_helper_mfc0_tcschefback(arg);
1.1.1.6   root     3282:             rn = "TCScheFBack";
                   3283:             break;
1.1.1.5   root     3284:         default:
                   3285:             goto die;
                   3286:         }
1.1       root     3287:         break;
1.1.1.5   root     3288:     case 3:
                   3289:         switch (sel) {
                   3290:         case 0:
1.1.1.8   root     3291:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo1));
                   3292:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3293:             rn = "EntryLo1";
                   3294:             break;
1.1.1.5   root     3295:         default:
                   3296:             goto die;
1.1.1.6   root     3297:         }
1.1       root     3298:         break;
1.1.1.5   root     3299:     case 4:
                   3300:         switch (sel) {
                   3301:         case 0:
1.1.1.8   root     3302:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_Context));
                   3303:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3304:             rn = "Context";
                   3305:             break;
                   3306:         case 1:
1.1.1.8   root     3307: //            gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
1.1.1.6   root     3308:             rn = "ContextConfig";
                   3309: //            break;
1.1.1.5   root     3310:         default:
                   3311:             goto die;
1.1.1.6   root     3312:         }
1.1       root     3313:         break;
1.1.1.5   root     3314:     case 5:
                   3315:         switch (sel) {
                   3316:         case 0:
1.1.1.8   root     3317:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageMask));
1.1.1.6   root     3318:             rn = "PageMask";
                   3319:             break;
                   3320:         case 1:
                   3321:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3322:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageGrain));
1.1.1.6   root     3323:             rn = "PageGrain";
                   3324:             break;
1.1.1.5   root     3325:         default:
                   3326:             goto die;
1.1.1.6   root     3327:         }
1.1       root     3328:         break;
1.1.1.5   root     3329:     case 6:
                   3330:         switch (sel) {
                   3331:         case 0:
1.1.1.8   root     3332:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Wired));
1.1.1.6   root     3333:             rn = "Wired";
                   3334:             break;
                   3335:         case 1:
                   3336:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3337:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf0));
1.1.1.6   root     3338:             rn = "SRSConf0";
                   3339:             break;
                   3340:         case 2:
                   3341:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3342:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf1));
1.1.1.6   root     3343:             rn = "SRSConf1";
                   3344:             break;
1.1.1.5   root     3345:         case 3:
1.1.1.6   root     3346:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3347:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf2));
1.1.1.6   root     3348:             rn = "SRSConf2";
                   3349:             break;
1.1.1.5   root     3350:         case 4:
1.1.1.6   root     3351:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3352:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf3));
1.1.1.6   root     3353:             rn = "SRSConf3";
                   3354:             break;
1.1.1.5   root     3355:         case 5:
1.1.1.6   root     3356:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3357:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf4));
1.1.1.6   root     3358:             rn = "SRSConf4";
                   3359:             break;
1.1.1.5   root     3360:         default:
                   3361:             goto die;
1.1.1.6   root     3362:         }
1.1       root     3363:         break;
1.1.1.5   root     3364:     case 7:
                   3365:         switch (sel) {
                   3366:         case 0:
1.1.1.6   root     3367:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3368:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_HWREna));
1.1.1.6   root     3369:             rn = "HWREna";
                   3370:             break;
1.1.1.5   root     3371:         default:
                   3372:             goto die;
1.1.1.6   root     3373:         }
1.1       root     3374:         break;
1.1.1.5   root     3375:     case 8:
                   3376:         switch (sel) {
                   3377:         case 0:
1.1.1.8   root     3378:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_BadVAddr));
                   3379:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.7   root     3380:             rn = "BadVAddr";
1.1.1.6   root     3381:             break;
1.1.1.5   root     3382:         default:
                   3383:             goto die;
                   3384:        }
1.1.1.2   root     3385:         break;
1.1.1.5   root     3386:     case 9:
                   3387:         switch (sel) {
                   3388:         case 0:
1.1.1.7   root     3389:             /* Mark as an IO operation because we read the time.  */
                   3390:             if (use_icount)
                   3391:                 gen_io_start();
1.1.1.8   root     3392:             gen_helper_mfc0_count(arg);
1.1.1.7   root     3393:             if (use_icount) {
                   3394:                 gen_io_end();
                   3395:                 ctx->bstate = BS_STOP;
                   3396:             }
1.1.1.6   root     3397:             rn = "Count";
                   3398:             break;
                   3399:         /* 6,7 are implementation dependent */
1.1.1.5   root     3400:         default:
                   3401:             goto die;
1.1.1.6   root     3402:         }
1.1.1.5   root     3403:         break;
                   3404:     case 10:
                   3405:         switch (sel) {
                   3406:         case 0:
1.1.1.8   root     3407:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryHi));
                   3408:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3409:             rn = "EntryHi";
                   3410:             break;
1.1.1.5   root     3411:         default:
                   3412:             goto die;
1.1.1.6   root     3413:         }
1.1.1.5   root     3414:         break;
                   3415:     case 11:
                   3416:         switch (sel) {
                   3417:         case 0:
1.1.1.8   root     3418:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Compare));
1.1.1.6   root     3419:             rn = "Compare";
                   3420:             break;
                   3421:         /* 6,7 are implementation dependent */
1.1.1.5   root     3422:         default:
                   3423:             goto die;
1.1.1.6   root     3424:         }
1.1.1.5   root     3425:         break;
                   3426:     case 12:
                   3427:         switch (sel) {
                   3428:         case 0:
1.1.1.8   root     3429:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Status));
1.1.1.6   root     3430:             rn = "Status";
                   3431:             break;
                   3432:         case 1:
                   3433:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3434:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_IntCtl));
1.1.1.6   root     3435:             rn = "IntCtl";
                   3436:             break;
                   3437:         case 2:
                   3438:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3439:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSCtl));
1.1.1.6   root     3440:             rn = "SRSCtl";
                   3441:             break;
1.1.1.5   root     3442:         case 3:
1.1.1.6   root     3443:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3444:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSMap));
1.1.1.6   root     3445:             rn = "SRSMap";
                   3446:             break;
1.1.1.5   root     3447:         default:
                   3448:             goto die;
                   3449:        }
                   3450:         break;
                   3451:     case 13:
                   3452:         switch (sel) {
                   3453:         case 0:
1.1.1.8   root     3454:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Cause));
1.1.1.6   root     3455:             rn = "Cause";
                   3456:             break;
1.1.1.5   root     3457:         default:
                   3458:             goto die;
                   3459:        }
                   3460:         break;
                   3461:     case 14:
                   3462:         switch (sel) {
                   3463:         case 0:
1.1.1.8   root     3464:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
                   3465:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3466:             rn = "EPC";
                   3467:             break;
1.1.1.5   root     3468:         default:
                   3469:             goto die;
1.1.1.6   root     3470:         }
1.1.1.5   root     3471:         break;
                   3472:     case 15:
                   3473:         switch (sel) {
                   3474:         case 0:
1.1.1.8   root     3475:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_PRid));
1.1.1.6   root     3476:             rn = "PRid";
                   3477:             break;
                   3478:         case 1:
                   3479:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3480:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_EBase));
1.1.1.6   root     3481:             rn = "EBase";
                   3482:             break;
1.1.1.5   root     3483:         default:
                   3484:             goto die;
                   3485:        }
                   3486:         break;
                   3487:     case 16:
                   3488:         switch (sel) {
                   3489:         case 0:
1.1.1.8   root     3490:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config0));
1.1.1.5   root     3491:             rn = "Config";
                   3492:             break;
                   3493:         case 1:
1.1.1.8   root     3494:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config1));
1.1.1.5   root     3495:             rn = "Config1";
                   3496:             break;
                   3497:         case 2:
1.1.1.8   root     3498:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config2));
1.1.1.5   root     3499:             rn = "Config2";
                   3500:             break;
                   3501:         case 3:
1.1.1.8   root     3502:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config3));
1.1.1.5   root     3503:             rn = "Config3";
                   3504:             break;
1.1.1.6   root     3505:         /* 4,5 are reserved */
                   3506:         /* 6,7 are implementation dependent */
                   3507:         case 6:
1.1.1.8   root     3508:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config6));
1.1.1.6   root     3509:             rn = "Config6";
                   3510:             break;
                   3511:         case 7:
1.1.1.8   root     3512:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config7));
1.1.1.6   root     3513:             rn = "Config7";
                   3514:             break;
1.1.1.5   root     3515:         default:
                   3516:             goto die;
1.1       root     3517:         }
1.1.1.4   root     3518:         break;
1.1.1.5   root     3519:     case 17:
                   3520:         switch (sel) {
                   3521:         case 0:
1.1.1.8   root     3522:             gen_helper_mfc0_lladdr(arg);
1.1.1.6   root     3523:             rn = "LLAddr";
                   3524:             break;
1.1.1.5   root     3525:         default:
                   3526:             goto die;
                   3527:         }
1.1.1.4   root     3528:         break;
1.1.1.5   root     3529:     case 18:
                   3530:         switch (sel) {
1.1.1.6   root     3531:         case 0 ... 7:
1.1.1.8   root     3532:             gen_helper_1i(mfc0_watchlo, arg, sel);
1.1.1.6   root     3533:             rn = "WatchLo";
                   3534:             break;
1.1.1.5   root     3535:         default:
                   3536:             goto die;
                   3537:         }
1.1.1.4   root     3538:         break;
1.1.1.5   root     3539:     case 19:
                   3540:         switch (sel) {
1.1.1.6   root     3541:         case 0 ...7:
1.1.1.8   root     3542:             gen_helper_1i(mfc0_watchhi, arg, sel);
1.1.1.6   root     3543:             rn = "WatchHi";
                   3544:             break;
1.1.1.5   root     3545:         default:
                   3546:             goto die;
                   3547:         }
1.1.1.4   root     3548:         break;
1.1.1.5   root     3549:     case 20:
                   3550:         switch (sel) {
                   3551:         case 0:
1.1.1.6   root     3552: #if defined(TARGET_MIPS64)
                   3553:             check_insn(env, ctx, ISA_MIPS3);
1.1.1.8   root     3554:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_XContext));
                   3555:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3556:             rn = "XContext";
                   3557:             break;
                   3558: #endif
1.1.1.5   root     3559:         default:
                   3560:             goto die;
1.1.1.4   root     3561:         }
                   3562:         break;
1.1.1.5   root     3563:     case 21:
                   3564:        /* Officially reserved, but sel 0 is used for R1x000 framemask */
                   3565:         switch (sel) {
                   3566:         case 0:
1.1.1.8   root     3567:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Framemask));
1.1.1.6   root     3568:             rn = "Framemask";
                   3569:             break;
1.1.1.5   root     3570:         default:
                   3571:             goto die;
1.1.1.4   root     3572:         }
                   3573:         break;
1.1.1.5   root     3574:     case 22:
1.1.1.8   root     3575:         tcg_gen_movi_tl(arg, 0); /* unimplemented */
1.1.1.6   root     3576:         rn = "'Diagnostic"; /* implementation dependent */
                   3577:         break;
1.1.1.5   root     3578:     case 23:
                   3579:         switch (sel) {
                   3580:         case 0:
1.1.1.8   root     3581:             gen_helper_mfc0_debug(arg); /* EJTAG support */
1.1.1.6   root     3582:             rn = "Debug";
                   3583:             break;
                   3584:         case 1:
1.1.1.8   root     3585: //            gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
1.1.1.6   root     3586:             rn = "TraceControl";
                   3587: //            break;
                   3588:         case 2:
1.1.1.8   root     3589: //            gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
1.1.1.6   root     3590:             rn = "TraceControl2";
                   3591: //            break;
1.1.1.5   root     3592:         case 3:
1.1.1.8   root     3593: //            gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
1.1.1.6   root     3594:             rn = "UserTraceData";
                   3595: //            break;
1.1.1.5   root     3596:         case 4:
1.1.1.8   root     3597: //            gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
1.1.1.6   root     3598:             rn = "TraceBPC";
                   3599: //            break;
1.1.1.5   root     3600:         default:
                   3601:             goto die;
1.1.1.4   root     3602:         }
1.1.1.5   root     3603:         break;
                   3604:     case 24:
                   3605:         switch (sel) {
                   3606:         case 0:
1.1.1.7   root     3607:             /* EJTAG support */
1.1.1.8   root     3608:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
                   3609:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3610:             rn = "DEPC";
                   3611:             break;
1.1.1.5   root     3612:         default:
                   3613:             goto die;
                   3614:         }
                   3615:         break;
                   3616:     case 25:
                   3617:         switch (sel) {
                   3618:         case 0:
1.1.1.8   root     3619:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Performance0));
1.1.1.6   root     3620:             rn = "Performance0";
1.1.1.5   root     3621:             break;
                   3622:         case 1:
1.1.1.8   root     3623: //            gen_helper_mfc0_performance1(arg);
1.1.1.6   root     3624:             rn = "Performance1";
                   3625: //            break;
1.1.1.5   root     3626:         case 2:
1.1.1.8   root     3627: //            gen_helper_mfc0_performance2(arg);
1.1.1.6   root     3628:             rn = "Performance2";
                   3629: //            break;
1.1.1.5   root     3630:         case 3:
1.1.1.8   root     3631: //            gen_helper_mfc0_performance3(arg);
1.1.1.6   root     3632:             rn = "Performance3";
                   3633: //            break;
1.1.1.5   root     3634:         case 4:
1.1.1.8   root     3635: //            gen_helper_mfc0_performance4(arg);
1.1.1.6   root     3636:             rn = "Performance4";
                   3637: //            break;
1.1.1.5   root     3638:         case 5:
1.1.1.8   root     3639: //            gen_helper_mfc0_performance5(arg);
1.1.1.6   root     3640:             rn = "Performance5";
                   3641: //            break;
1.1.1.5   root     3642:         case 6:
1.1.1.8   root     3643: //            gen_helper_mfc0_performance6(arg);
1.1.1.6   root     3644:             rn = "Performance6";
                   3645: //            break;
1.1.1.5   root     3646:         case 7:
1.1.1.8   root     3647: //            gen_helper_mfc0_performance7(arg);
1.1.1.6   root     3648:             rn = "Performance7";
                   3649: //            break;
1.1.1.5   root     3650:         default:
                   3651:             goto die;
                   3652:         }
                   3653:         break;
                   3654:     case 26:
1.1.1.8   root     3655:         tcg_gen_movi_tl(arg, 0); /* unimplemented */
1.1.1.7   root     3656:         rn = "ECC";
                   3657:         break;
1.1.1.5   root     3658:     case 27:
                   3659:         switch (sel) {
                   3660:         case 0 ... 3:
1.1.1.8   root     3661:             tcg_gen_movi_tl(arg, 0); /* unimplemented */
1.1.1.6   root     3662:             rn = "CacheErr";
                   3663:             break;
1.1.1.5   root     3664:         default:
                   3665:             goto die;
                   3666:         }
                   3667:         break;
                   3668:     case 28:
                   3669:         switch (sel) {
                   3670:         case 0:
                   3671:         case 2:
                   3672:         case 4:
                   3673:         case 6:
1.1.1.8   root     3674:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagLo));
1.1.1.5   root     3675:             rn = "TagLo";
                   3676:             break;
                   3677:         case 1:
                   3678:         case 3:
                   3679:         case 5:
                   3680:         case 7:
1.1.1.8   root     3681:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataLo));
1.1.1.5   root     3682:             rn = "DataLo";
                   3683:             break;
                   3684:         default:
                   3685:             goto die;
                   3686:         }
                   3687:         break;
                   3688:     case 29:
                   3689:         switch (sel) {
                   3690:         case 0:
                   3691:         case 2:
                   3692:         case 4:
                   3693:         case 6:
1.1.1.8   root     3694:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagHi));
1.1.1.5   root     3695:             rn = "TagHi";
                   3696:             break;
                   3697:         case 1:
                   3698:         case 3:
                   3699:         case 5:
                   3700:         case 7:
1.1.1.8   root     3701:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataHi));
1.1.1.5   root     3702:             rn = "DataHi";
                   3703:             break;
                   3704:         default:
                   3705:             goto die;
                   3706:         }
                   3707:         break;
                   3708:     case 30:
                   3709:         switch (sel) {
                   3710:         case 0:
1.1.1.8   root     3711:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
                   3712:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3713:             rn = "ErrorEPC";
                   3714:             break;
1.1.1.5   root     3715:         default:
                   3716:             goto die;
                   3717:         }
                   3718:         break;
                   3719:     case 31:
                   3720:         switch (sel) {
                   3721:         case 0:
1.1.1.7   root     3722:             /* EJTAG support */
1.1.1.8   root     3723:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_DESAVE));
1.1.1.6   root     3724:             rn = "DESAVE";
                   3725:             break;
1.1.1.5   root     3726:         default:
                   3727:             goto die;
                   3728:         }
                   3729:         break;
                   3730:     default:
                   3731:        goto die;
                   3732:     }
1.1.1.7   root     3733:     LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
1.1.1.5   root     3734:     return;
                   3735: 
                   3736: die:
1.1.1.7   root     3737:     LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
1.1.1.5   root     3738:     generate_exception(ctx, EXCP_RI);
                   3739: }
                   3740: 
1.1.1.8   root     3741: static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
1.1.1.5   root     3742: {
                   3743:     const char *rn = "invalid";
                   3744: 
1.1.1.6   root     3745:     if (sel != 0)
                   3746:         check_insn(env, ctx, ISA_MIPS32);
                   3747: 
1.1.1.7   root     3748:     if (use_icount)
                   3749:         gen_io_start();
                   3750: 
1.1.1.5   root     3751:     switch (reg) {
                   3752:     case 0:
                   3753:         switch (sel) {
                   3754:         case 0:
1.1.1.8   root     3755:             gen_helper_mtc0_index(arg);
1.1.1.5   root     3756:             rn = "Index";
                   3757:             break;
                   3758:         case 1:
1.1.1.6   root     3759:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3760:             gen_helper_mtc0_mvpcontrol(arg);
1.1.1.5   root     3761:             rn = "MVPControl";
1.1.1.6   root     3762:             break;
1.1.1.5   root     3763:         case 2:
1.1.1.6   root     3764:             check_insn(env, ctx, ASE_MT);
                   3765:             /* ignored */
1.1.1.5   root     3766:             rn = "MVPConf0";
1.1.1.6   root     3767:             break;
1.1.1.5   root     3768:         case 3:
1.1.1.6   root     3769:             check_insn(env, ctx, ASE_MT);
                   3770:             /* ignored */
1.1.1.5   root     3771:             rn = "MVPConf1";
1.1.1.6   root     3772:             break;
1.1.1.5   root     3773:         default:
                   3774:             goto die;
                   3775:         }
                   3776:         break;
                   3777:     case 1:
                   3778:         switch (sel) {
                   3779:         case 0:
1.1.1.6   root     3780:             /* ignored */
1.1.1.5   root     3781:             rn = "Random";
1.1.1.6   root     3782:             break;
1.1.1.5   root     3783:         case 1:
1.1.1.6   root     3784:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3785:             gen_helper_mtc0_vpecontrol(arg);
1.1.1.5   root     3786:             rn = "VPEControl";
1.1.1.6   root     3787:             break;
1.1.1.5   root     3788:         case 2:
1.1.1.6   root     3789:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3790:             gen_helper_mtc0_vpeconf0(arg);
1.1.1.5   root     3791:             rn = "VPEConf0";
1.1.1.6   root     3792:             break;
1.1.1.5   root     3793:         case 3:
1.1.1.6   root     3794:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3795:             gen_helper_mtc0_vpeconf1(arg);
1.1.1.5   root     3796:             rn = "VPEConf1";
1.1.1.6   root     3797:             break;
1.1.1.5   root     3798:         case 4:
1.1.1.6   root     3799:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3800:             gen_helper_mtc0_yqmask(arg);
1.1.1.5   root     3801:             rn = "YQMask";
1.1.1.6   root     3802:             break;
1.1.1.5   root     3803:         case 5:
1.1.1.6   root     3804:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3805:             gen_mtc0_store64(arg, offsetof(CPUState, CP0_VPESchedule));
1.1.1.5   root     3806:             rn = "VPESchedule";
1.1.1.6   root     3807:             break;
1.1.1.5   root     3808:         case 6:
1.1.1.6   root     3809:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3810:             gen_mtc0_store64(arg, offsetof(CPUState, CP0_VPEScheFBack));
1.1.1.5   root     3811:             rn = "VPEScheFBack";
1.1.1.6   root     3812:             break;
1.1.1.5   root     3813:         case 7:
1.1.1.6   root     3814:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3815:             gen_helper_mtc0_vpeopt(arg);
1.1.1.5   root     3816:             rn = "VPEOpt";
1.1.1.6   root     3817:             break;
1.1.1.5   root     3818:         default:
                   3819:             goto die;
                   3820:         }
                   3821:         break;
                   3822:     case 2:
                   3823:         switch (sel) {
                   3824:         case 0:
1.1.1.8   root     3825:             gen_helper_mtc0_entrylo0(arg);
1.1.1.6   root     3826:             rn = "EntryLo0";
                   3827:             break;
                   3828:         case 1:
                   3829:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3830:             gen_helper_mtc0_tcstatus(arg);
1.1.1.6   root     3831:             rn = "TCStatus";
                   3832:             break;
                   3833:         case 2:
                   3834:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3835:             gen_helper_mtc0_tcbind(arg);
1.1.1.6   root     3836:             rn = "TCBind";
                   3837:             break;
1.1.1.5   root     3838:         case 3:
1.1.1.6   root     3839:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3840:             gen_helper_mtc0_tcrestart(arg);
1.1.1.6   root     3841:             rn = "TCRestart";
                   3842:             break;
1.1.1.5   root     3843:         case 4:
1.1.1.6   root     3844:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3845:             gen_helper_mtc0_tchalt(arg);
1.1.1.6   root     3846:             rn = "TCHalt";
                   3847:             break;
1.1.1.5   root     3848:         case 5:
1.1.1.6   root     3849:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3850:             gen_helper_mtc0_tccontext(arg);
1.1.1.6   root     3851:             rn = "TCContext";
                   3852:             break;
1.1.1.5   root     3853:         case 6:
1.1.1.6   root     3854:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3855:             gen_helper_mtc0_tcschedule(arg);
1.1.1.6   root     3856:             rn = "TCSchedule";
                   3857:             break;
1.1.1.5   root     3858:         case 7:
1.1.1.6   root     3859:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3860:             gen_helper_mtc0_tcschefback(arg);
1.1.1.6   root     3861:             rn = "TCScheFBack";
                   3862:             break;
1.1.1.5   root     3863:         default:
                   3864:             goto die;
                   3865:         }
                   3866:         break;
                   3867:     case 3:
                   3868:         switch (sel) {
                   3869:         case 0:
1.1.1.8   root     3870:             gen_helper_mtc0_entrylo1(arg);
1.1.1.6   root     3871:             rn = "EntryLo1";
                   3872:             break;
1.1.1.5   root     3873:         default:
                   3874:             goto die;
1.1.1.6   root     3875:         }
1.1.1.5   root     3876:         break;
                   3877:     case 4:
                   3878:         switch (sel) {
                   3879:         case 0:
1.1.1.8   root     3880:             gen_helper_mtc0_context(arg);
1.1.1.6   root     3881:             rn = "Context";
                   3882:             break;
                   3883:         case 1:
1.1.1.8   root     3884: //            gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
1.1.1.6   root     3885:             rn = "ContextConfig";
                   3886: //            break;
1.1.1.5   root     3887:         default:
                   3888:             goto die;
1.1.1.6   root     3889:         }
1.1.1.5   root     3890:         break;
                   3891:     case 5:
                   3892:         switch (sel) {
                   3893:         case 0:
1.1.1.8   root     3894:             gen_helper_mtc0_pagemask(arg);
1.1.1.6   root     3895:             rn = "PageMask";
                   3896:             break;
                   3897:         case 1:
                   3898:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3899:             gen_helper_mtc0_pagegrain(arg);
1.1.1.6   root     3900:             rn = "PageGrain";
                   3901:             break;
1.1.1.5   root     3902:         default:
                   3903:             goto die;
1.1.1.6   root     3904:         }
1.1.1.5   root     3905:         break;
                   3906:     case 6:
                   3907:         switch (sel) {
                   3908:         case 0:
1.1.1.8   root     3909:             gen_helper_mtc0_wired(arg);
1.1.1.6   root     3910:             rn = "Wired";
                   3911:             break;
                   3912:         case 1:
                   3913:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3914:             gen_helper_mtc0_srsconf0(arg);
1.1.1.6   root     3915:             rn = "SRSConf0";
                   3916:             break;
                   3917:         case 2:
                   3918:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3919:             gen_helper_mtc0_srsconf1(arg);
1.1.1.6   root     3920:             rn = "SRSConf1";
                   3921:             break;
1.1.1.5   root     3922:         case 3:
1.1.1.6   root     3923:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3924:             gen_helper_mtc0_srsconf2(arg);
1.1.1.6   root     3925:             rn = "SRSConf2";
                   3926:             break;
1.1.1.5   root     3927:         case 4:
1.1.1.6   root     3928:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3929:             gen_helper_mtc0_srsconf3(arg);
1.1.1.6   root     3930:             rn = "SRSConf3";
                   3931:             break;
1.1.1.5   root     3932:         case 5:
1.1.1.6   root     3933:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3934:             gen_helper_mtc0_srsconf4(arg);
1.1.1.6   root     3935:             rn = "SRSConf4";
                   3936:             break;
1.1.1.5   root     3937:         default:
                   3938:             goto die;
1.1.1.6   root     3939:         }
1.1.1.5   root     3940:         break;
                   3941:     case 7:
                   3942:         switch (sel) {
                   3943:         case 0:
1.1.1.6   root     3944:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3945:             gen_helper_mtc0_hwrena(arg);
1.1.1.6   root     3946:             rn = "HWREna";
                   3947:             break;
1.1.1.5   root     3948:         default:
                   3949:             goto die;
1.1.1.6   root     3950:         }
1.1.1.5   root     3951:         break;
                   3952:     case 8:
                   3953:         /* ignored */
1.1.1.7   root     3954:         rn = "BadVAddr";
1.1.1.5   root     3955:         break;
                   3956:     case 9:
                   3957:         switch (sel) {
                   3958:         case 0:
1.1.1.8   root     3959:             gen_helper_mtc0_count(arg);
1.1.1.6   root     3960:             rn = "Count";
                   3961:             break;
                   3962:         /* 6,7 are implementation dependent */
1.1.1.5   root     3963:         default:
                   3964:             goto die;
1.1.1.6   root     3965:         }
1.1.1.5   root     3966:         break;
                   3967:     case 10:
                   3968:         switch (sel) {
                   3969:         case 0:
1.1.1.8   root     3970:             gen_helper_mtc0_entryhi(arg);
1.1.1.6   root     3971:             rn = "EntryHi";
                   3972:             break;
1.1.1.5   root     3973:         default:
                   3974:             goto die;
1.1.1.6   root     3975:         }
1.1.1.5   root     3976:         break;
                   3977:     case 11:
                   3978:         switch (sel) {
                   3979:         case 0:
1.1.1.8   root     3980:             gen_helper_mtc0_compare(arg);
1.1.1.6   root     3981:             rn = "Compare";
                   3982:             break;
                   3983:         /* 6,7 are implementation dependent */
1.1.1.5   root     3984:         default:
                   3985:             goto die;
1.1.1.6   root     3986:         }
1.1.1.5   root     3987:         break;
                   3988:     case 12:
                   3989:         switch (sel) {
                   3990:         case 0:
1.1.1.8   root     3991:             save_cpu_state(ctx, 1);
                   3992:             gen_helper_mtc0_status(arg);
1.1.1.6   root     3993:             /* BS_STOP isn't good enough here, hflags may have changed. */
                   3994:             gen_save_pc(ctx->pc + 4);
                   3995:             ctx->bstate = BS_EXCP;
                   3996:             rn = "Status";
                   3997:             break;
                   3998:         case 1:
                   3999:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4000:             gen_helper_mtc0_intctl(arg);
1.1.1.6   root     4001:             /* Stop translation as we may have switched the execution mode */
                   4002:             ctx->bstate = BS_STOP;
                   4003:             rn = "IntCtl";
                   4004:             break;
                   4005:         case 2:
                   4006:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4007:             gen_helper_mtc0_srsctl(arg);
1.1.1.6   root     4008:             /* Stop translation as we may have switched the execution mode */
                   4009:             ctx->bstate = BS_STOP;
                   4010:             rn = "SRSCtl";
                   4011:             break;
1.1.1.5   root     4012:         case 3:
1.1.1.6   root     4013:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4014:             gen_mtc0_store32(arg, offsetof(CPUState, CP0_SRSMap));
1.1.1.6   root     4015:             /* Stop translation as we may have switched the execution mode */
                   4016:             ctx->bstate = BS_STOP;
                   4017:             rn = "SRSMap";
                   4018:             break;
1.1.1.5   root     4019:         default:
                   4020:             goto die;
1.1.1.6   root     4021:         }
1.1.1.5   root     4022:         break;
                   4023:     case 13:
                   4024:         switch (sel) {
                   4025:         case 0:
1.1.1.8   root     4026:             save_cpu_state(ctx, 1);
                   4027:             gen_helper_mtc0_cause(arg);
1.1.1.6   root     4028:             rn = "Cause";
                   4029:             break;
1.1.1.5   root     4030:         default:
                   4031:             goto die;
1.1.1.6   root     4032:         }
1.1.1.5   root     4033:         break;
                   4034:     case 14:
                   4035:         switch (sel) {
                   4036:         case 0:
1.1.1.8   root     4037:             gen_mtc0_store64(arg, offsetof(CPUState, CP0_EPC));
1.1.1.6   root     4038:             rn = "EPC";
                   4039:             break;
1.1.1.5   root     4040:         default:
                   4041:             goto die;
1.1.1.6   root     4042:         }
1.1.1.5   root     4043:         break;
                   4044:     case 15:
                   4045:         switch (sel) {
                   4046:         case 0:
1.1.1.6   root     4047:             /* ignored */
                   4048:             rn = "PRid";
                   4049:             break;
                   4050:         case 1:
                   4051:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4052:             gen_helper_mtc0_ebase(arg);
1.1.1.6   root     4053:             rn = "EBase";
                   4054:             break;
1.1.1.5   root     4055:         default:
                   4056:             goto die;
1.1.1.6   root     4057:         }
1.1.1.5   root     4058:         break;
                   4059:     case 16:
                   4060:         switch (sel) {
                   4061:         case 0:
1.1.1.8   root     4062:             gen_helper_mtc0_config0(arg);
1.1.1.5   root     4063:             rn = "Config";
1.1.1.6   root     4064:             /* Stop translation as we may have switched the execution mode */
                   4065:             ctx->bstate = BS_STOP;
1.1.1.5   root     4066:             break;
                   4067:         case 1:
1.1.1.6   root     4068:             /* ignored, read only */
1.1.1.5   root     4069:             rn = "Config1";
                   4070:             break;
                   4071:         case 2:
1.1.1.8   root     4072:             gen_helper_mtc0_config2(arg);
1.1.1.5   root     4073:             rn = "Config2";
1.1.1.6   root     4074:             /* Stop translation as we may have switched the execution mode */
                   4075:             ctx->bstate = BS_STOP;
1.1.1.5   root     4076:             break;
                   4077:         case 3:
1.1.1.6   root     4078:             /* ignored, read only */
1.1.1.5   root     4079:             rn = "Config3";
                   4080:             break;
1.1.1.6   root     4081:         /* 4,5 are reserved */
                   4082:         /* 6,7 are implementation dependent */
                   4083:         case 6:
                   4084:             /* ignored */
                   4085:             rn = "Config6";
                   4086:             break;
                   4087:         case 7:
                   4088:             /* ignored */
                   4089:             rn = "Config7";
                   4090:             break;
1.1.1.5   root     4091:         default:
                   4092:             rn = "Invalid config selector";
                   4093:             goto die;
                   4094:         }
                   4095:         break;
                   4096:     case 17:
                   4097:         switch (sel) {
                   4098:         case 0:
1.1.1.9   root     4099:             gen_helper_mtc0_lladdr(arg);
1.1.1.6   root     4100:             rn = "LLAddr";
                   4101:             break;
1.1.1.5   root     4102:         default:
                   4103:             goto die;
                   4104:         }
                   4105:         break;
                   4106:     case 18:
                   4107:         switch (sel) {
1.1.1.6   root     4108:         case 0 ... 7:
1.1.1.8   root     4109:             gen_helper_1i(mtc0_watchlo, arg, sel);
1.1.1.6   root     4110:             rn = "WatchLo";
                   4111:             break;
1.1.1.5   root     4112:         default:
                   4113:             goto die;
                   4114:         }
                   4115:         break;
                   4116:     case 19:
                   4117:         switch (sel) {
1.1.1.6   root     4118:         case 0 ... 7:
1.1.1.8   root     4119:             gen_helper_1i(mtc0_watchhi, arg, sel);
1.1.1.6   root     4120:             rn = "WatchHi";
                   4121:             break;
1.1.1.5   root     4122:         default:
                   4123:             goto die;
                   4124:         }
                   4125:         break;
                   4126:     case 20:
                   4127:         switch (sel) {
                   4128:         case 0:
1.1.1.6   root     4129: #if defined(TARGET_MIPS64)
                   4130:             check_insn(env, ctx, ISA_MIPS3);
1.1.1.8   root     4131:             gen_helper_mtc0_xcontext(arg);
1.1.1.6   root     4132:             rn = "XContext";
                   4133:             break;
                   4134: #endif
1.1.1.5   root     4135:         default:
                   4136:             goto die;
                   4137:         }
                   4138:         break;
                   4139:     case 21:
                   4140:        /* Officially reserved, but sel 0 is used for R1x000 framemask */
                   4141:         switch (sel) {
                   4142:         case 0:
1.1.1.8   root     4143:             gen_helper_mtc0_framemask(arg);
1.1.1.6   root     4144:             rn = "Framemask";
                   4145:             break;
1.1.1.5   root     4146:         default:
                   4147:             goto die;
                   4148:         }
                   4149:         break;
                   4150:     case 22:
                   4151:         /* ignored */
                   4152:         rn = "Diagnostic"; /* implementation dependent */
1.1.1.6   root     4153:         break;
1.1.1.5   root     4154:     case 23:
                   4155:         switch (sel) {
                   4156:         case 0:
1.1.1.8   root     4157:             gen_helper_mtc0_debug(arg); /* EJTAG support */
1.1.1.6   root     4158:             /* BS_STOP isn't good enough here, hflags may have changed. */
                   4159:             gen_save_pc(ctx->pc + 4);
                   4160:             ctx->bstate = BS_EXCP;
                   4161:             rn = "Debug";
                   4162:             break;
                   4163:         case 1:
1.1.1.8   root     4164: //            gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
1.1.1.6   root     4165:             rn = "TraceControl";
                   4166:             /* Stop translation as we may have switched the execution mode */
                   4167:             ctx->bstate = BS_STOP;
                   4168: //            break;
                   4169:         case 2:
1.1.1.8   root     4170: //            gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
1.1.1.6   root     4171:             rn = "TraceControl2";
                   4172:             /* Stop translation as we may have switched the execution mode */
                   4173:             ctx->bstate = BS_STOP;
                   4174: //            break;
                   4175:         case 3:
                   4176:             /* Stop translation as we may have switched the execution mode */
                   4177:             ctx->bstate = BS_STOP;
1.1.1.8   root     4178: //            gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
1.1.1.6   root     4179:             rn = "UserTraceData";
                   4180:             /* Stop translation as we may have switched the execution mode */
                   4181:             ctx->bstate = BS_STOP;
                   4182: //            break;
1.1.1.5   root     4183:         case 4:
1.1.1.8   root     4184: //            gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
1.1.1.6   root     4185:             /* Stop translation as we may have switched the execution mode */
                   4186:             ctx->bstate = BS_STOP;
                   4187:             rn = "TraceBPC";
                   4188: //            break;
1.1.1.5   root     4189:         default:
                   4190:             goto die;
                   4191:         }
                   4192:         break;
                   4193:     case 24:
                   4194:         switch (sel) {
                   4195:         case 0:
1.1.1.7   root     4196:             /* EJTAG support */
1.1.1.8   root     4197:             gen_mtc0_store64(arg, offsetof(CPUState, CP0_DEPC));
1.1.1.6   root     4198:             rn = "DEPC";
                   4199:             break;
1.1.1.5   root     4200:         default:
                   4201:             goto die;
                   4202:         }
                   4203:         break;
                   4204:     case 25:
                   4205:         switch (sel) {
                   4206:         case 0:
1.1.1.8   root     4207:             gen_helper_mtc0_performance0(arg);
1.1.1.6   root     4208:             rn = "Performance0";
                   4209:             break;
                   4210:         case 1:
1.1.1.8   root     4211: //            gen_helper_mtc0_performance1(arg);
1.1.1.6   root     4212:             rn = "Performance1";
                   4213: //            break;
                   4214:         case 2:
1.1.1.8   root     4215: //            gen_helper_mtc0_performance2(arg);
1.1.1.6   root     4216:             rn = "Performance2";
                   4217: //            break;
                   4218:         case 3:
1.1.1.8   root     4219: //            gen_helper_mtc0_performance3(arg);
1.1.1.6   root     4220:             rn = "Performance3";
                   4221: //            break;
1.1.1.5   root     4222:         case 4:
1.1.1.8   root     4223: //            gen_helper_mtc0_performance4(arg);
1.1.1.6   root     4224:             rn = "Performance4";
                   4225: //            break;
1.1.1.5   root     4226:         case 5:
1.1.1.8   root     4227: //            gen_helper_mtc0_performance5(arg);
1.1.1.6   root     4228:             rn = "Performance5";
                   4229: //            break;
1.1.1.5   root     4230:         case 6:
1.1.1.8   root     4231: //            gen_helper_mtc0_performance6(arg);
1.1.1.6   root     4232:             rn = "Performance6";
                   4233: //            break;
1.1.1.5   root     4234:         case 7:
1.1.1.8   root     4235: //            gen_helper_mtc0_performance7(arg);
1.1.1.6   root     4236:             rn = "Performance7";
                   4237: //            break;
1.1.1.5   root     4238:         default:
                   4239:             goto die;
                   4240:         }
                   4241:        break;
                   4242:     case 26:
1.1.1.6   root     4243:         /* ignored */
1.1.1.5   root     4244:         rn = "ECC";
1.1.1.6   root     4245:         break;
1.1.1.5   root     4246:     case 27:
                   4247:         switch (sel) {
                   4248:         case 0 ... 3:
1.1.1.6   root     4249:             /* ignored */
                   4250:             rn = "CacheErr";
                   4251:             break;
1.1.1.5   root     4252:         default:
                   4253:             goto die;
                   4254:         }
                   4255:        break;
                   4256:     case 28:
                   4257:         switch (sel) {
                   4258:         case 0:
                   4259:         case 2:
                   4260:         case 4:
                   4261:         case 6:
1.1.1.8   root     4262:             gen_helper_mtc0_taglo(arg);
1.1.1.5   root     4263:             rn = "TagLo";
                   4264:             break;
                   4265:         case 1:
                   4266:         case 3:
                   4267:         case 5:
                   4268:         case 7:
1.1.1.8   root     4269:             gen_helper_mtc0_datalo(arg);
1.1.1.5   root     4270:             rn = "DataLo";
                   4271:             break;
                   4272:         default:
                   4273:             goto die;
                   4274:         }
                   4275:         break;
                   4276:     case 29:
                   4277:         switch (sel) {
                   4278:         case 0:
                   4279:         case 2:
                   4280:         case 4:
                   4281:         case 6:
1.1.1.8   root     4282:             gen_helper_mtc0_taghi(arg);
1.1.1.5   root     4283:             rn = "TagHi";
                   4284:             break;
                   4285:         case 1:
                   4286:         case 3:
                   4287:         case 5:
                   4288:         case 7:
1.1.1.8   root     4289:             gen_helper_mtc0_datahi(arg);
1.1.1.5   root     4290:             rn = "DataHi";
                   4291:             break;
                   4292:         default:
                   4293:             rn = "invalid sel";
                   4294:             goto die;
                   4295:         }
                   4296:        break;
                   4297:     case 30:
                   4298:         switch (sel) {
                   4299:         case 0:
1.1.1.8   root     4300:             gen_mtc0_store64(arg, offsetof(CPUState, CP0_ErrorEPC));
1.1.1.6   root     4301:             rn = "ErrorEPC";
                   4302:             break;
1.1.1.5   root     4303:         default:
                   4304:             goto die;
                   4305:         }
                   4306:         break;
                   4307:     case 31:
                   4308:         switch (sel) {
                   4309:         case 0:
1.1.1.7   root     4310:             /* EJTAG support */
1.1.1.8   root     4311:             gen_mtc0_store32(arg, offsetof(CPUState, CP0_DESAVE));
1.1.1.6   root     4312:             rn = "DESAVE";
                   4313:             break;
1.1.1.5   root     4314:         default:
                   4315:             goto die;
                   4316:         }
1.1.1.6   root     4317:         /* Stop translation as we may have switched the execution mode */
                   4318:         ctx->bstate = BS_STOP;
1.1.1.5   root     4319:         break;
                   4320:     default:
                   4321:        goto die;
                   4322:     }
1.1.1.7   root     4323:     LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
                   4324:     /* For simplicity assume that all writes can cause interrupts.  */
                   4325:     if (use_icount) {
                   4326:         gen_io_end();
                   4327:         ctx->bstate = BS_STOP;
1.1.1.5   root     4328:     }
                   4329:     return;
                   4330: 
                   4331: die:
1.1.1.7   root     4332:     LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
1.1.1.5   root     4333:     generate_exception(ctx, EXCP_RI);
                   4334: }
                   4335: 
1.1.1.6   root     4336: #if defined(TARGET_MIPS64)
1.1.1.8   root     4337: static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
1.1.1.5   root     4338: {
                   4339:     const char *rn = "invalid";
                   4340: 
1.1.1.6   root     4341:     if (sel != 0)
                   4342:         check_insn(env, ctx, ISA_MIPS64);
                   4343: 
1.1.1.5   root     4344:     switch (reg) {
                   4345:     case 0:
                   4346:         switch (sel) {
                   4347:         case 0:
1.1.1.8   root     4348:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Index));
1.1.1.5   root     4349:             rn = "Index";
                   4350:             break;
                   4351:         case 1:
1.1.1.6   root     4352:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4353:             gen_helper_mfc0_mvpcontrol(arg);
1.1.1.5   root     4354:             rn = "MVPControl";
1.1.1.6   root     4355:             break;
1.1.1.5   root     4356:         case 2:
1.1.1.6   root     4357:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4358:             gen_helper_mfc0_mvpconf0(arg);
1.1.1.5   root     4359:             rn = "MVPConf0";
1.1.1.6   root     4360:             break;
1.1.1.5   root     4361:         case 3:
1.1.1.6   root     4362:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4363:             gen_helper_mfc0_mvpconf1(arg);
1.1.1.5   root     4364:             rn = "MVPConf1";
1.1.1.6   root     4365:             break;
1.1.1.5   root     4366:         default:
                   4367:             goto die;
                   4368:         }
                   4369:         break;
                   4370:     case 1:
                   4371:         switch (sel) {
                   4372:         case 0:
1.1.1.8   root     4373:             gen_helper_mfc0_random(arg);
1.1.1.5   root     4374:             rn = "Random";
1.1.1.6   root     4375:             break;
1.1.1.5   root     4376:         case 1:
1.1.1.6   root     4377:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4378:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEControl));
1.1.1.5   root     4379:             rn = "VPEControl";
1.1.1.6   root     4380:             break;
1.1.1.5   root     4381:         case 2:
1.1.1.6   root     4382:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4383:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf0));
1.1.1.5   root     4384:             rn = "VPEConf0";
1.1.1.6   root     4385:             break;
1.1.1.5   root     4386:         case 3:
1.1.1.6   root     4387:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4388:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf1));
1.1.1.5   root     4389:             rn = "VPEConf1";
1.1.1.6   root     4390:             break;
1.1.1.5   root     4391:         case 4:
1.1.1.6   root     4392:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4393:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_YQMask));
1.1.1.5   root     4394:             rn = "YQMask";
1.1.1.6   root     4395:             break;
1.1.1.5   root     4396:         case 5:
1.1.1.6   root     4397:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4398:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPESchedule));
1.1.1.5   root     4399:             rn = "VPESchedule";
1.1.1.6   root     4400:             break;
1.1.1.5   root     4401:         case 6:
1.1.1.6   root     4402:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4403:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
1.1.1.5   root     4404:             rn = "VPEScheFBack";
1.1.1.6   root     4405:             break;
1.1.1.5   root     4406:         case 7:
1.1.1.6   root     4407:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4408:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEOpt));
1.1.1.5   root     4409:             rn = "VPEOpt";
1.1.1.6   root     4410:             break;
1.1.1.5   root     4411:         default:
                   4412:             goto die;
                   4413:         }
                   4414:         break;
                   4415:     case 2:
                   4416:         switch (sel) {
                   4417:         case 0:
1.1.1.8   root     4418:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo0));
1.1.1.6   root     4419:             rn = "EntryLo0";
                   4420:             break;
                   4421:         case 1:
                   4422:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4423:             gen_helper_mfc0_tcstatus(arg);
1.1.1.6   root     4424:             rn = "TCStatus";
                   4425:             break;
                   4426:         case 2:
                   4427:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4428:             gen_helper_mfc0_tcbind(arg);
1.1.1.6   root     4429:             rn = "TCBind";
                   4430:             break;
1.1.1.5   root     4431:         case 3:
1.1.1.6   root     4432:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4433:             gen_helper_dmfc0_tcrestart(arg);
1.1.1.6   root     4434:             rn = "TCRestart";
                   4435:             break;
1.1.1.5   root     4436:         case 4:
1.1.1.6   root     4437:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4438:             gen_helper_dmfc0_tchalt(arg);
1.1.1.6   root     4439:             rn = "TCHalt";
                   4440:             break;
1.1.1.5   root     4441:         case 5:
1.1.1.6   root     4442:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4443:             gen_helper_dmfc0_tccontext(arg);
1.1.1.6   root     4444:             rn = "TCContext";
                   4445:             break;
1.1.1.5   root     4446:         case 6:
1.1.1.6   root     4447:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4448:             gen_helper_dmfc0_tcschedule(arg);
1.1.1.6   root     4449:             rn = "TCSchedule";
                   4450:             break;
1.1.1.5   root     4451:         case 7:
1.1.1.6   root     4452:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4453:             gen_helper_dmfc0_tcschefback(arg);
1.1.1.6   root     4454:             rn = "TCScheFBack";
                   4455:             break;
1.1.1.5   root     4456:         default:
                   4457:             goto die;
                   4458:         }
                   4459:         break;
                   4460:     case 3:
                   4461:         switch (sel) {
                   4462:         case 0:
1.1.1.8   root     4463:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo1));
1.1.1.6   root     4464:             rn = "EntryLo1";
                   4465:             break;
1.1.1.5   root     4466:         default:
                   4467:             goto die;
1.1.1.6   root     4468:         }
1.1.1.5   root     4469:         break;
                   4470:     case 4:
                   4471:         switch (sel) {
                   4472:         case 0:
1.1.1.8   root     4473:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_Context));
1.1.1.6   root     4474:             rn = "Context";
                   4475:             break;
                   4476:         case 1:
1.1.1.8   root     4477: //            gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
1.1.1.6   root     4478:             rn = "ContextConfig";
                   4479: //            break;
1.1.1.5   root     4480:         default:
                   4481:             goto die;
1.1.1.6   root     4482:         }
1.1.1.5   root     4483:         break;
                   4484:     case 5:
                   4485:         switch (sel) {
                   4486:         case 0:
1.1.1.8   root     4487:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageMask));
1.1.1.6   root     4488:             rn = "PageMask";
                   4489:             break;
                   4490:         case 1:
                   4491:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4492:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageGrain));
1.1.1.6   root     4493:             rn = "PageGrain";
                   4494:             break;
1.1.1.5   root     4495:         default:
                   4496:             goto die;
1.1.1.6   root     4497:         }
1.1.1.5   root     4498:         break;
                   4499:     case 6:
                   4500:         switch (sel) {
                   4501:         case 0:
1.1.1.8   root     4502:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Wired));
1.1.1.6   root     4503:             rn = "Wired";
                   4504:             break;
                   4505:         case 1:
                   4506:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4507:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf0));
1.1.1.6   root     4508:             rn = "SRSConf0";
                   4509:             break;
                   4510:         case 2:
                   4511:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4512:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf1));
1.1.1.6   root     4513:             rn = "SRSConf1";
                   4514:             break;
1.1.1.5   root     4515:         case 3:
1.1.1.6   root     4516:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4517:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf2));
1.1.1.6   root     4518:             rn = "SRSConf2";
                   4519:             break;
1.1.1.5   root     4520:         case 4:
1.1.1.6   root     4521:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4522:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf3));
1.1.1.6   root     4523:             rn = "SRSConf3";
                   4524:             break;
1.1.1.5   root     4525:         case 5:
1.1.1.6   root     4526:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4527:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf4));
1.1.1.6   root     4528:             rn = "SRSConf4";
                   4529:             break;
1.1.1.5   root     4530:         default:
                   4531:             goto die;
1.1.1.6   root     4532:         }
1.1.1.5   root     4533:         break;
                   4534:     case 7:
                   4535:         switch (sel) {
                   4536:         case 0:
1.1.1.6   root     4537:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4538:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_HWREna));
1.1.1.6   root     4539:             rn = "HWREna";
                   4540:             break;
1.1.1.5   root     4541:         default:
                   4542:             goto die;
1.1.1.6   root     4543:         }
1.1.1.5   root     4544:         break;
                   4545:     case 8:
                   4546:         switch (sel) {
                   4547:         case 0:
1.1.1.8   root     4548:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_BadVAddr));
1.1.1.7   root     4549:             rn = "BadVAddr";
1.1.1.6   root     4550:             break;
1.1.1.5   root     4551:         default:
                   4552:             goto die;
1.1.1.6   root     4553:         }
1.1.1.5   root     4554:         break;
                   4555:     case 9:
                   4556:         switch (sel) {
                   4557:         case 0:
1.1.1.7   root     4558:             /* Mark as an IO operation because we read the time.  */
                   4559:             if (use_icount)
                   4560:                 gen_io_start();
1.1.1.8   root     4561:             gen_helper_mfc0_count(arg);
1.1.1.7   root     4562:             if (use_icount) {
                   4563:                 gen_io_end();
                   4564:                 ctx->bstate = BS_STOP;
                   4565:             }
1.1.1.6   root     4566:             rn = "Count";
                   4567:             break;
                   4568:         /* 6,7 are implementation dependent */
1.1.1.5   root     4569:         default:
                   4570:             goto die;
1.1.1.6   root     4571:         }
1.1.1.5   root     4572:         break;
                   4573:     case 10:
                   4574:         switch (sel) {
                   4575:         case 0:
1.1.1.8   root     4576:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryHi));
1.1.1.6   root     4577:             rn = "EntryHi";
                   4578:             break;
1.1.1.5   root     4579:         default:
                   4580:             goto die;
1.1.1.6   root     4581:         }
1.1.1.5   root     4582:         break;
                   4583:     case 11:
                   4584:         switch (sel) {
                   4585:         case 0:
1.1.1.8   root     4586:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Compare));
1.1.1.6   root     4587:             rn = "Compare";
                   4588:             break;
                   4589:         /* 6,7 are implementation dependent */
1.1.1.5   root     4590:         default:
                   4591:             goto die;
1.1.1.6   root     4592:         }
1.1.1.5   root     4593:         break;
                   4594:     case 12:
                   4595:         switch (sel) {
                   4596:         case 0:
1.1.1.8   root     4597:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Status));
1.1.1.6   root     4598:             rn = "Status";
                   4599:             break;
                   4600:         case 1:
                   4601:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4602:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_IntCtl));
1.1.1.6   root     4603:             rn = "IntCtl";
                   4604:             break;
                   4605:         case 2:
                   4606:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4607:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSCtl));
1.1.1.6   root     4608:             rn = "SRSCtl";
                   4609:             break;
1.1.1.5   root     4610:         case 3:
1.1.1.6   root     4611:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4612:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSMap));
1.1.1.6   root     4613:             rn = "SRSMap";
                   4614:             break;
1.1.1.5   root     4615:         default:
                   4616:             goto die;
1.1.1.6   root     4617:         }
1.1.1.5   root     4618:         break;
                   4619:     case 13:
                   4620:         switch (sel) {
                   4621:         case 0:
1.1.1.8   root     4622:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Cause));
1.1.1.6   root     4623:             rn = "Cause";
                   4624:             break;
1.1.1.5   root     4625:         default:
                   4626:             goto die;
1.1.1.6   root     4627:         }
1.1.1.5   root     4628:         break;
                   4629:     case 14:
                   4630:         switch (sel) {
                   4631:         case 0:
1.1.1.8   root     4632:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
1.1.1.6   root     4633:             rn = "EPC";
                   4634:             break;
1.1.1.5   root     4635:         default:
                   4636:             goto die;
1.1.1.6   root     4637:         }
1.1.1.5   root     4638:         break;
                   4639:     case 15:
                   4640:         switch (sel) {
                   4641:         case 0:
1.1.1.8   root     4642:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_PRid));
1.1.1.6   root     4643:             rn = "PRid";
                   4644:             break;
                   4645:         case 1:
                   4646:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4647:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_EBase));
1.1.1.6   root     4648:             rn = "EBase";
                   4649:             break;
1.1.1.5   root     4650:         default:
                   4651:             goto die;
1.1.1.6   root     4652:         }
1.1.1.5   root     4653:         break;
                   4654:     case 16:
                   4655:         switch (sel) {
                   4656:         case 0:
1.1.1.8   root     4657:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config0));
1.1.1.5   root     4658:             rn = "Config";
                   4659:             break;
                   4660:         case 1:
1.1.1.8   root     4661:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config1));
1.1.1.5   root     4662:             rn = "Config1";
                   4663:             break;
                   4664:         case 2:
1.1.1.8   root     4665:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config2));
1.1.1.5   root     4666:             rn = "Config2";
                   4667:             break;
                   4668:         case 3:
1.1.1.8   root     4669:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config3));
1.1.1.5   root     4670:             rn = "Config3";
                   4671:             break;
                   4672:        /* 6,7 are implementation dependent */
1.1.1.7   root     4673:         case 6:
1.1.1.8   root     4674:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config6));
1.1.1.7   root     4675:             rn = "Config6";
                   4676:             break;
                   4677:         case 7:
1.1.1.8   root     4678:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config7));
1.1.1.7   root     4679:             rn = "Config7";
                   4680:             break;
1.1.1.5   root     4681:         default:
                   4682:             goto die;
                   4683:         }
                   4684:         break;
                   4685:     case 17:
                   4686:         switch (sel) {
                   4687:         case 0:
1.1.1.8   root     4688:             gen_helper_dmfc0_lladdr(arg);
1.1.1.6   root     4689:             rn = "LLAddr";
                   4690:             break;
1.1.1.5   root     4691:         default:
                   4692:             goto die;
                   4693:         }
                   4694:         break;
                   4695:     case 18:
                   4696:         switch (sel) {
1.1.1.6   root     4697:         case 0 ... 7:
1.1.1.8   root     4698:             gen_helper_1i(dmfc0_watchlo, arg, sel);
1.1.1.6   root     4699:             rn = "WatchLo";
                   4700:             break;
1.1.1.5   root     4701:         default:
                   4702:             goto die;
                   4703:         }
                   4704:         break;
                   4705:     case 19:
                   4706:         switch (sel) {
1.1.1.6   root     4707:         case 0 ... 7:
1.1.1.8   root     4708:             gen_helper_1i(mfc0_watchhi, arg, sel);
1.1.1.6   root     4709:             rn = "WatchHi";
                   4710:             break;
1.1.1.5   root     4711:         default:
                   4712:             goto die;
                   4713:         }
                   4714:         break;
                   4715:     case 20:
                   4716:         switch (sel) {
                   4717:         case 0:
1.1.1.6   root     4718:             check_insn(env, ctx, ISA_MIPS3);
1.1.1.8   root     4719:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_XContext));
1.1.1.6   root     4720:             rn = "XContext";
                   4721:             break;
1.1.1.5   root     4722:         default:
                   4723:             goto die;
                   4724:         }
                   4725:         break;
                   4726:     case 21:
                   4727:        /* Officially reserved, but sel 0 is used for R1x000 framemask */
                   4728:         switch (sel) {
                   4729:         case 0:
1.1.1.8   root     4730:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Framemask));
1.1.1.6   root     4731:             rn = "Framemask";
                   4732:             break;
1.1.1.5   root     4733:         default:
                   4734:             goto die;
                   4735:         }
                   4736:         break;
                   4737:     case 22:
1.1.1.8   root     4738:         tcg_gen_movi_tl(arg, 0); /* unimplemented */
1.1.1.6   root     4739:         rn = "'Diagnostic"; /* implementation dependent */
                   4740:         break;
1.1.1.5   root     4741:     case 23:
                   4742:         switch (sel) {
                   4743:         case 0:
1.1.1.8   root     4744:             gen_helper_mfc0_debug(arg); /* EJTAG support */
1.1.1.6   root     4745:             rn = "Debug";
                   4746:             break;
                   4747:         case 1:
1.1.1.8   root     4748: //            gen_helper_dmfc0_tracecontrol(arg); /* PDtrace support */
1.1.1.6   root     4749:             rn = "TraceControl";
                   4750: //            break;
                   4751:         case 2:
1.1.1.8   root     4752: //            gen_helper_dmfc0_tracecontrol2(arg); /* PDtrace support */
1.1.1.6   root     4753:             rn = "TraceControl2";
                   4754: //            break;
1.1.1.5   root     4755:         case 3:
1.1.1.8   root     4756: //            gen_helper_dmfc0_usertracedata(arg); /* PDtrace support */
1.1.1.6   root     4757:             rn = "UserTraceData";
                   4758: //            break;
1.1.1.5   root     4759:         case 4:
1.1.1.8   root     4760: //            gen_helper_dmfc0_tracebpc(arg); /* PDtrace support */
1.1.1.6   root     4761:             rn = "TraceBPC";
                   4762: //            break;
1.1.1.5   root     4763:         default:
                   4764:             goto die;
                   4765:         }
                   4766:         break;
                   4767:     case 24:
                   4768:         switch (sel) {
                   4769:         case 0:
1.1.1.7   root     4770:             /* EJTAG support */
1.1.1.8   root     4771:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
1.1.1.6   root     4772:             rn = "DEPC";
                   4773:             break;
1.1.1.5   root     4774:         default:
                   4775:             goto die;
                   4776:         }
                   4777:         break;
                   4778:     case 25:
                   4779:         switch (sel) {
                   4780:         case 0:
1.1.1.8   root     4781:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Performance0));
1.1.1.6   root     4782:             rn = "Performance0";
1.1.1.5   root     4783:             break;
                   4784:         case 1:
1.1.1.8   root     4785: //            gen_helper_dmfc0_performance1(arg);
1.1.1.6   root     4786:             rn = "Performance1";
                   4787: //            break;
1.1.1.5   root     4788:         case 2:
1.1.1.8   root     4789: //            gen_helper_dmfc0_performance2(arg);
1.1.1.6   root     4790:             rn = "Performance2";
                   4791: //            break;
1.1.1.5   root     4792:         case 3:
1.1.1.8   root     4793: //            gen_helper_dmfc0_performance3(arg);
1.1.1.6   root     4794:             rn = "Performance3";
                   4795: //            break;
1.1.1.5   root     4796:         case 4:
1.1.1.8   root     4797: //            gen_helper_dmfc0_performance4(arg);
1.1.1.6   root     4798:             rn = "Performance4";
                   4799: //            break;
1.1.1.5   root     4800:         case 5:
1.1.1.8   root     4801: //            gen_helper_dmfc0_performance5(arg);
1.1.1.6   root     4802:             rn = "Performance5";
                   4803: //            break;
1.1.1.5   root     4804:         case 6:
1.1.1.8   root     4805: //            gen_helper_dmfc0_performance6(arg);
1.1.1.6   root     4806:             rn = "Performance6";
                   4807: //            break;
1.1.1.5   root     4808:         case 7:
1.1.1.8   root     4809: //            gen_helper_dmfc0_performance7(arg);
1.1.1.6   root     4810:             rn = "Performance7";
                   4811: //            break;
1.1.1.5   root     4812:         default:
                   4813:             goto die;
                   4814:         }
                   4815:         break;
                   4816:     case 26:
1.1.1.8   root     4817:         tcg_gen_movi_tl(arg, 0); /* unimplemented */
1.1.1.7   root     4818:         rn = "ECC";
                   4819:         break;
1.1.1.5   root     4820:     case 27:
                   4821:         switch (sel) {
                   4822:         /* ignored */
                   4823:         case 0 ... 3:
1.1.1.8   root     4824:             tcg_gen_movi_tl(arg, 0); /* unimplemented */
1.1.1.6   root     4825:             rn = "CacheErr";
                   4826:             break;
1.1.1.5   root     4827:         default:
                   4828:             goto die;
                   4829:         }
                   4830:         break;
                   4831:     case 28:
                   4832:         switch (sel) {
                   4833:         case 0:
                   4834:         case 2:
                   4835:         case 4:
                   4836:         case 6:
1.1.1.8   root     4837:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagLo));
1.1.1.5   root     4838:             rn = "TagLo";
                   4839:             break;
                   4840:         case 1:
                   4841:         case 3:
                   4842:         case 5:
                   4843:         case 7:
1.1.1.8   root     4844:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataLo));
1.1.1.5   root     4845:             rn = "DataLo";
                   4846:             break;
                   4847:         default:
                   4848:             goto die;
                   4849:         }
                   4850:         break;
                   4851:     case 29:
                   4852:         switch (sel) {
                   4853:         case 0:
                   4854:         case 2:
                   4855:         case 4:
                   4856:         case 6:
1.1.1.8   root     4857:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagHi));
1.1.1.5   root     4858:             rn = "TagHi";
                   4859:             break;
                   4860:         case 1:
                   4861:         case 3:
                   4862:         case 5:
                   4863:         case 7:
1.1.1.8   root     4864:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataHi));
1.1.1.5   root     4865:             rn = "DataHi";
                   4866:             break;
                   4867:         default:
                   4868:             goto die;
                   4869:         }
                   4870:         break;
                   4871:     case 30:
                   4872:         switch (sel) {
                   4873:         case 0:
1.1.1.8   root     4874:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
1.1.1.6   root     4875:             rn = "ErrorEPC";
                   4876:             break;
1.1.1.5   root     4877:         default:
                   4878:             goto die;
                   4879:         }
                   4880:         break;
                   4881:     case 31:
                   4882:         switch (sel) {
                   4883:         case 0:
1.1.1.7   root     4884:             /* EJTAG support */
1.1.1.8   root     4885:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_DESAVE));
1.1.1.6   root     4886:             rn = "DESAVE";
                   4887:             break;
1.1.1.5   root     4888:         default:
                   4889:             goto die;
                   4890:         }
                   4891:         break;
                   4892:     default:
1.1.1.6   root     4893:         goto die;
1.1.1.5   root     4894:     }
1.1.1.7   root     4895:     LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
1.1.1.5   root     4896:     return;
                   4897: 
                   4898: die:
1.1.1.7   root     4899:     LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
1.1.1.5   root     4900:     generate_exception(ctx, EXCP_RI);
                   4901: }
                   4902: 
1.1.1.8   root     4903: static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
1.1.1.5   root     4904: {
                   4905:     const char *rn = "invalid";
                   4906: 
1.1.1.6   root     4907:     if (sel != 0)
                   4908:         check_insn(env, ctx, ISA_MIPS64);
                   4909: 
1.1.1.7   root     4910:     if (use_icount)
                   4911:         gen_io_start();
                   4912: 
1.1.1.5   root     4913:     switch (reg) {
                   4914:     case 0:
                   4915:         switch (sel) {
                   4916:         case 0:
1.1.1.8   root     4917:             gen_helper_mtc0_index(arg);
1.1.1.5   root     4918:             rn = "Index";
                   4919:             break;
                   4920:         case 1:
1.1.1.6   root     4921:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4922:             gen_helper_mtc0_mvpcontrol(arg);
1.1.1.5   root     4923:             rn = "MVPControl";
1.1.1.6   root     4924:             break;
1.1.1.5   root     4925:         case 2:
1.1.1.6   root     4926:             check_insn(env, ctx, ASE_MT);
                   4927:             /* ignored */
1.1.1.5   root     4928:             rn = "MVPConf0";
1.1.1.6   root     4929:             break;
1.1.1.5   root     4930:         case 3:
1.1.1.6   root     4931:             check_insn(env, ctx, ASE_MT);
                   4932:             /* ignored */
1.1.1.5   root     4933:             rn = "MVPConf1";
1.1.1.6   root     4934:             break;
1.1.1.5   root     4935:         default:
                   4936:             goto die;
                   4937:         }
                   4938:         break;
                   4939:     case 1:
                   4940:         switch (sel) {
                   4941:         case 0:
1.1.1.6   root     4942:             /* ignored */
1.1.1.5   root     4943:             rn = "Random";
1.1.1.6   root     4944:             break;
1.1.1.5   root     4945:         case 1:
1.1.1.6   root     4946:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4947:             gen_helper_mtc0_vpecontrol(arg);
1.1.1.5   root     4948:             rn = "VPEControl";
1.1.1.6   root     4949:             break;
1.1.1.5   root     4950:         case 2:
1.1.1.6   root     4951:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4952:             gen_helper_mtc0_vpeconf0(arg);
1.1.1.5   root     4953:             rn = "VPEConf0";
1.1.1.6   root     4954:             break;
1.1.1.5   root     4955:         case 3:
1.1.1.6   root     4956:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4957:             gen_helper_mtc0_vpeconf1(arg);
1.1.1.5   root     4958:             rn = "VPEConf1";
1.1.1.6   root     4959:             break;
1.1.1.5   root     4960:         case 4:
1.1.1.6   root     4961:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4962:             gen_helper_mtc0_yqmask(arg);
1.1.1.5   root     4963:             rn = "YQMask";
1.1.1.6   root     4964:             break;
1.1.1.5   root     4965:         case 5:
1.1.1.6   root     4966:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4967:             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_VPESchedule));
1.1.1.5   root     4968:             rn = "VPESchedule";
1.1.1.6   root     4969:             break;
1.1.1.5   root     4970:         case 6:
1.1.1.6   root     4971:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4972:             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
1.1.1.5   root     4973:             rn = "VPEScheFBack";
1.1.1.6   root     4974:             break;
1.1.1.5   root     4975:         case 7:
1.1.1.6   root     4976:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4977:             gen_helper_mtc0_vpeopt(arg);
1.1.1.5   root     4978:             rn = "VPEOpt";
1.1.1.6   root     4979:             break;
1.1.1.5   root     4980:         default:
                   4981:             goto die;
                   4982:         }
                   4983:         break;
                   4984:     case 2:
                   4985:         switch (sel) {
                   4986:         case 0:
1.1.1.8   root     4987:             gen_helper_mtc0_entrylo0(arg);
1.1.1.6   root     4988:             rn = "EntryLo0";
                   4989:             break;
                   4990:         case 1:
                   4991:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4992:             gen_helper_mtc0_tcstatus(arg);
1.1.1.6   root     4993:             rn = "TCStatus";
                   4994:             break;
                   4995:         case 2:
                   4996:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4997:             gen_helper_mtc0_tcbind(arg);
1.1.1.6   root     4998:             rn = "TCBind";
                   4999:             break;
1.1.1.5   root     5000:         case 3:
1.1.1.6   root     5001:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     5002:             gen_helper_mtc0_tcrestart(arg);
1.1.1.6   root     5003:             rn = "TCRestart";
                   5004:             break;
1.1.1.5   root     5005:         case 4:
1.1.1.6   root     5006:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     5007:             gen_helper_mtc0_tchalt(arg);
1.1.1.6   root     5008:             rn = "TCHalt";
                   5009:             break;
1.1.1.5   root     5010:         case 5:
1.1.1.6   root     5011:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     5012:             gen_helper_mtc0_tccontext(arg);
1.1.1.6   root     5013:             rn = "TCContext";
                   5014:             break;
1.1.1.5   root     5015:         case 6:
1.1.1.6   root     5016:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     5017:             gen_helper_mtc0_tcschedule(arg);
1.1.1.6   root     5018:             rn = "TCSchedule";
                   5019:             break;
1.1.1.5   root     5020:         case 7:
1.1.1.6   root     5021:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     5022:             gen_helper_mtc0_tcschefback(arg);
1.1.1.6   root     5023:             rn = "TCScheFBack";
                   5024:             break;
1.1.1.5   root     5025:         default:
                   5026:             goto die;
                   5027:         }
                   5028:         break;
                   5029:     case 3:
                   5030:         switch (sel) {
                   5031:         case 0:
1.1.1.8   root     5032:             gen_helper_mtc0_entrylo1(arg);
1.1.1.6   root     5033:             rn = "EntryLo1";
                   5034:             break;
1.1.1.5   root     5035:         default:
                   5036:             goto die;
1.1.1.6   root     5037:         }
1.1.1.5   root     5038:         break;
                   5039:     case 4:
                   5040:         switch (sel) {
                   5041:         case 0:
1.1.1.8   root     5042:             gen_helper_mtc0_context(arg);
1.1.1.6   root     5043:             rn = "Context";
                   5044:             break;
                   5045:         case 1:
1.1.1.8   root     5046: //           gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
1.1.1.6   root     5047:             rn = "ContextConfig";
                   5048: //           break;
1.1.1.5   root     5049:         default:
                   5050:             goto die;
1.1.1.6   root     5051:         }
1.1.1.5   root     5052:         break;
                   5053:     case 5:
                   5054:         switch (sel) {
                   5055:         case 0:
1.1.1.8   root     5056:             gen_helper_mtc0_pagemask(arg);
1.1.1.6   root     5057:             rn = "PageMask";
                   5058:             break;
                   5059:         case 1:
                   5060:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5061:             gen_helper_mtc0_pagegrain(arg);
1.1.1.6   root     5062:             rn = "PageGrain";
                   5063:             break;
1.1.1.5   root     5064:         default:
                   5065:             goto die;
1.1.1.6   root     5066:         }
1.1.1.5   root     5067:         break;
                   5068:     case 6:
                   5069:         switch (sel) {
                   5070:         case 0:
1.1.1.8   root     5071:             gen_helper_mtc0_wired(arg);
1.1.1.6   root     5072:             rn = "Wired";
                   5073:             break;
                   5074:         case 1:
                   5075:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5076:             gen_helper_mtc0_srsconf0(arg);
1.1.1.6   root     5077:             rn = "SRSConf0";
                   5078:             break;
                   5079:         case 2:
                   5080:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5081:             gen_helper_mtc0_srsconf1(arg);
1.1.1.6   root     5082:             rn = "SRSConf1";
                   5083:             break;
1.1.1.5   root     5084:         case 3:
1.1.1.6   root     5085:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5086:             gen_helper_mtc0_srsconf2(arg);
1.1.1.6   root     5087:             rn = "SRSConf2";
                   5088:             break;
1.1.1.5   root     5089:         case 4:
1.1.1.6   root     5090:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5091:             gen_helper_mtc0_srsconf3(arg);
1.1.1.6   root     5092:             rn = "SRSConf3";
                   5093:             break;
1.1.1.5   root     5094:         case 5:
1.1.1.6   root     5095:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5096:             gen_helper_mtc0_srsconf4(arg);
1.1.1.6   root     5097:             rn = "SRSConf4";
                   5098:             break;
1.1.1.5   root     5099:         default:
                   5100:             goto die;
1.1.1.6   root     5101:         }
1.1.1.5   root     5102:         break;
                   5103:     case 7:
                   5104:         switch (sel) {
                   5105:         case 0:
1.1.1.6   root     5106:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5107:             gen_helper_mtc0_hwrena(arg);
1.1.1.6   root     5108:             rn = "HWREna";
                   5109:             break;
1.1.1.5   root     5110:         default:
                   5111:             goto die;
1.1.1.6   root     5112:         }
1.1.1.5   root     5113:         break;
                   5114:     case 8:
                   5115:         /* ignored */
1.1.1.7   root     5116:         rn = "BadVAddr";
1.1.1.5   root     5117:         break;
                   5118:     case 9:
                   5119:         switch (sel) {
                   5120:         case 0:
1.1.1.8   root     5121:             gen_helper_mtc0_count(arg);
1.1.1.6   root     5122:             rn = "Count";
                   5123:             break;
                   5124:         /* 6,7 are implementation dependent */
1.1.1.5   root     5125:         default:
                   5126:             goto die;
1.1.1.6   root     5127:         }
                   5128:         /* Stop translation as we may have switched the execution mode */
                   5129:         ctx->bstate = BS_STOP;
1.1.1.5   root     5130:         break;
                   5131:     case 10:
                   5132:         switch (sel) {
                   5133:         case 0:
1.1.1.8   root     5134:             gen_helper_mtc0_entryhi(arg);
1.1.1.6   root     5135:             rn = "EntryHi";
                   5136:             break;
1.1.1.5   root     5137:         default:
                   5138:             goto die;
1.1.1.6   root     5139:         }
1.1.1.5   root     5140:         break;
                   5141:     case 11:
                   5142:         switch (sel) {
                   5143:         case 0:
1.1.1.8   root     5144:             gen_helper_mtc0_compare(arg);
1.1.1.6   root     5145:             rn = "Compare";
                   5146:             break;
                   5147:         /* 6,7 are implementation dependent */
1.1.1.5   root     5148:         default:
                   5149:             goto die;
1.1.1.6   root     5150:         }
                   5151:         /* Stop translation as we may have switched the execution mode */
                   5152:         ctx->bstate = BS_STOP;
1.1.1.5   root     5153:         break;
                   5154:     case 12:
                   5155:         switch (sel) {
                   5156:         case 0:
1.1.1.8   root     5157:             save_cpu_state(ctx, 1);
                   5158:             gen_helper_mtc0_status(arg);
1.1.1.6   root     5159:             /* BS_STOP isn't good enough here, hflags may have changed. */
                   5160:             gen_save_pc(ctx->pc + 4);
                   5161:             ctx->bstate = BS_EXCP;
                   5162:             rn = "Status";
                   5163:             break;
                   5164:         case 1:
                   5165:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5166:             gen_helper_mtc0_intctl(arg);
1.1.1.6   root     5167:             /* Stop translation as we may have switched the execution mode */
                   5168:             ctx->bstate = BS_STOP;
                   5169:             rn = "IntCtl";
                   5170:             break;
                   5171:         case 2:
                   5172:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5173:             gen_helper_mtc0_srsctl(arg);
1.1.1.6   root     5174:             /* Stop translation as we may have switched the execution mode */
                   5175:             ctx->bstate = BS_STOP;
                   5176:             rn = "SRSCtl";
                   5177:             break;
1.1.1.5   root     5178:         case 3:
1.1.1.6   root     5179:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5180:             gen_mtc0_store32(arg, offsetof(CPUState, CP0_SRSMap));
1.1.1.6   root     5181:             /* Stop translation as we may have switched the execution mode */
                   5182:             ctx->bstate = BS_STOP;
                   5183:             rn = "SRSMap";
                   5184:             break;
1.1.1.5   root     5185:         default:
                   5186:             goto die;
1.1.1.6   root     5187:         }
1.1.1.5   root     5188:         break;
                   5189:     case 13:
                   5190:         switch (sel) {
                   5191:         case 0:
1.1.1.8   root     5192:             save_cpu_state(ctx, 1);
1.1.1.12! root     5193:             /* Mark as an IO operation because we may trigger a software
        !          5194:                interrupt.  */
        !          5195:             if (use_icount) {
        !          5196:                 gen_io_start();
        !          5197:             }
1.1.1.8   root     5198:             gen_helper_mtc0_cause(arg);
1.1.1.12! root     5199:             if (use_icount) {
        !          5200:                 gen_io_end();
        !          5201:             }
        !          5202:             /* Stop translation as we may have triggered an intetrupt */
        !          5203:             ctx->bstate = BS_STOP;
1.1.1.6   root     5204:             rn = "Cause";
                   5205:             break;
1.1.1.5   root     5206:         default:
                   5207:             goto die;
1.1.1.6   root     5208:         }
1.1.1.5   root     5209:         break;
                   5210:     case 14:
                   5211:         switch (sel) {
                   5212:         case 0:
1.1.1.8   root     5213:             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
1.1.1.6   root     5214:             rn = "EPC";
                   5215:             break;
1.1.1.5   root     5216:         default:
                   5217:             goto die;
1.1.1.6   root     5218:         }
1.1.1.5   root     5219:         break;
                   5220:     case 15:
                   5221:         switch (sel) {
                   5222:         case 0:
1.1.1.6   root     5223:             /* ignored */
                   5224:             rn = "PRid";
                   5225:             break;
                   5226:         case 1:
                   5227:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5228:             gen_helper_mtc0_ebase(arg);
1.1.1.6   root     5229:             rn = "EBase";
                   5230:             break;
1.1.1.5   root     5231:         default:
                   5232:             goto die;
1.1.1.6   root     5233:         }
1.1.1.5   root     5234:         break;
                   5235:     case 16:
                   5236:         switch (sel) {
                   5237:         case 0:
1.1.1.8   root     5238:             gen_helper_mtc0_config0(arg);
1.1.1.5   root     5239:             rn = "Config";
1.1.1.6   root     5240:             /* Stop translation as we may have switched the execution mode */
                   5241:             ctx->bstate = BS_STOP;
1.1.1.5   root     5242:             break;
                   5243:         case 1:
1.1.1.8   root     5244:             /* ignored, read only */
1.1.1.5   root     5245:             rn = "Config1";
                   5246:             break;
                   5247:         case 2:
1.1.1.8   root     5248:             gen_helper_mtc0_config2(arg);
1.1.1.5   root     5249:             rn = "Config2";
1.1.1.6   root     5250:             /* Stop translation as we may have switched the execution mode */
                   5251:             ctx->bstate = BS_STOP;
1.1.1.5   root     5252:             break;
                   5253:         case 3:
1.1.1.6   root     5254:             /* ignored */
1.1.1.5   root     5255:             rn = "Config3";
                   5256:             break;
                   5257:         /* 6,7 are implementation dependent */
                   5258:         default:
                   5259:             rn = "Invalid config selector";
                   5260:             goto die;
                   5261:         }
                   5262:         break;
                   5263:     case 17:
                   5264:         switch (sel) {
                   5265:         case 0:
1.1.1.9   root     5266:             gen_helper_mtc0_lladdr(arg);
1.1.1.6   root     5267:             rn = "LLAddr";
                   5268:             break;
1.1.1.5   root     5269:         default:
                   5270:             goto die;
                   5271:         }
                   5272:         break;
                   5273:     case 18:
                   5274:         switch (sel) {
1.1.1.6   root     5275:         case 0 ... 7:
1.1.1.8   root     5276:             gen_helper_1i(mtc0_watchlo, arg, sel);
1.1.1.6   root     5277:             rn = "WatchLo";
                   5278:             break;
1.1.1.5   root     5279:         default:
                   5280:             goto die;
                   5281:         }
                   5282:         break;
                   5283:     case 19:
                   5284:         switch (sel) {
1.1.1.6   root     5285:         case 0 ... 7:
1.1.1.8   root     5286:             gen_helper_1i(mtc0_watchhi, arg, sel);
1.1.1.6   root     5287:             rn = "WatchHi";
                   5288:             break;
1.1.1.5   root     5289:         default:
                   5290:             goto die;
                   5291:         }
                   5292:         break;
                   5293:     case 20:
                   5294:         switch (sel) {
                   5295:         case 0:
1.1.1.6   root     5296:             check_insn(env, ctx, ISA_MIPS3);
1.1.1.8   root     5297:             gen_helper_mtc0_xcontext(arg);
1.1.1.6   root     5298:             rn = "XContext";
                   5299:             break;
1.1.1.5   root     5300:         default:
                   5301:             goto die;
                   5302:         }
                   5303:         break;
                   5304:     case 21:
                   5305:        /* Officially reserved, but sel 0 is used for R1x000 framemask */
                   5306:         switch (sel) {
                   5307:         case 0:
1.1.1.8   root     5308:             gen_helper_mtc0_framemask(arg);
1.1.1.6   root     5309:             rn = "Framemask";
                   5310:             break;
1.1.1.5   root     5311:         default:
                   5312:             goto die;
                   5313:         }
                   5314:         break;
                   5315:     case 22:
                   5316:         /* ignored */
                   5317:         rn = "Diagnostic"; /* implementation dependent */
1.1.1.6   root     5318:         break;
1.1.1.5   root     5319:     case 23:
                   5320:         switch (sel) {
                   5321:         case 0:
1.1.1.8   root     5322:             gen_helper_mtc0_debug(arg); /* EJTAG support */
1.1.1.6   root     5323:             /* BS_STOP isn't good enough here, hflags may have changed. */
                   5324:             gen_save_pc(ctx->pc + 4);
                   5325:             ctx->bstate = BS_EXCP;
                   5326:             rn = "Debug";
                   5327:             break;
                   5328:         case 1:
1.1.1.8   root     5329: //            gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
1.1.1.6   root     5330:             /* Stop translation as we may have switched the execution mode */
                   5331:             ctx->bstate = BS_STOP;
                   5332:             rn = "TraceControl";
                   5333: //            break;
                   5334:         case 2:
1.1.1.8   root     5335: //            gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
1.1.1.6   root     5336:             /* Stop translation as we may have switched the execution mode */
                   5337:             ctx->bstate = BS_STOP;
                   5338:             rn = "TraceControl2";
                   5339: //            break;
                   5340:         case 3:
1.1.1.8   root     5341: //            gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
1.1.1.6   root     5342:             /* Stop translation as we may have switched the execution mode */
                   5343:             ctx->bstate = BS_STOP;
                   5344:             rn = "UserTraceData";
                   5345: //            break;
1.1.1.5   root     5346:         case 4:
1.1.1.8   root     5347: //            gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
1.1.1.6   root     5348:             /* Stop translation as we may have switched the execution mode */
                   5349:             ctx->bstate = BS_STOP;
                   5350:             rn = "TraceBPC";
                   5351: //            break;
1.1.1.5   root     5352:         default:
                   5353:             goto die;
                   5354:         }
                   5355:         break;
                   5356:     case 24:
                   5357:         switch (sel) {
                   5358:         case 0:
1.1.1.7   root     5359:             /* EJTAG support */
1.1.1.8   root     5360:             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
1.1.1.6   root     5361:             rn = "DEPC";
                   5362:             break;
1.1.1.5   root     5363:         default:
                   5364:             goto die;
                   5365:         }
                   5366:         break;
                   5367:     case 25:
                   5368:         switch (sel) {
                   5369:         case 0:
1.1.1.8   root     5370:             gen_helper_mtc0_performance0(arg);
1.1.1.6   root     5371:             rn = "Performance0";
                   5372:             break;
                   5373:         case 1:
1.1.1.8   root     5374: //            gen_helper_mtc0_performance1(arg);
1.1.1.6   root     5375:             rn = "Performance1";
                   5376: //            break;
                   5377:         case 2:
1.1.1.8   root     5378: //            gen_helper_mtc0_performance2(arg);
1.1.1.6   root     5379:             rn = "Performance2";
                   5380: //            break;
1.1.1.5   root     5381:         case 3:
1.1.1.8   root     5382: //            gen_helper_mtc0_performance3(arg);
1.1.1.6   root     5383:             rn = "Performance3";
                   5384: //            break;
1.1.1.5   root     5385:         case 4:
1.1.1.8   root     5386: //            gen_helper_mtc0_performance4(arg);
1.1.1.6   root     5387:             rn = "Performance4";
                   5388: //            break;
1.1.1.5   root     5389:         case 5:
1.1.1.8   root     5390: //            gen_helper_mtc0_performance5(arg);
1.1.1.6   root     5391:             rn = "Performance5";
                   5392: //            break;
1.1.1.5   root     5393:         case 6:
1.1.1.8   root     5394: //            gen_helper_mtc0_performance6(arg);
1.1.1.6   root     5395:             rn = "Performance6";
                   5396: //            break;
1.1.1.5   root     5397:         case 7:
1.1.1.8   root     5398: //            gen_helper_mtc0_performance7(arg);
1.1.1.6   root     5399:             rn = "Performance7";
                   5400: //            break;
1.1.1.5   root     5401:         default:
                   5402:             goto die;
                   5403:         }
1.1.1.6   root     5404:         break;
1.1.1.5   root     5405:     case 26:
1.1.1.6   root     5406:         /* ignored */
1.1.1.5   root     5407:         rn = "ECC";
1.1.1.6   root     5408:         break;
1.1.1.5   root     5409:     case 27:
                   5410:         switch (sel) {
                   5411:         case 0 ... 3:
1.1.1.6   root     5412:             /* ignored */
                   5413:             rn = "CacheErr";
                   5414:             break;
1.1.1.5   root     5415:         default:
                   5416:             goto die;
                   5417:         }
1.1.1.6   root     5418:         break;
1.1.1.5   root     5419:     case 28:
                   5420:         switch (sel) {
                   5421:         case 0:
                   5422:         case 2:
                   5423:         case 4:
                   5424:         case 6:
1.1.1.8   root     5425:             gen_helper_mtc0_taglo(arg);
1.1.1.5   root     5426:             rn = "TagLo";
                   5427:             break;
                   5428:         case 1:
                   5429:         case 3:
                   5430:         case 5:
                   5431:         case 7:
1.1.1.8   root     5432:             gen_helper_mtc0_datalo(arg);
1.1.1.5   root     5433:             rn = "DataLo";
                   5434:             break;
                   5435:         default:
                   5436:             goto die;
                   5437:         }
                   5438:         break;
                   5439:     case 29:
                   5440:         switch (sel) {
                   5441:         case 0:
                   5442:         case 2:
                   5443:         case 4:
                   5444:         case 6:
1.1.1.8   root     5445:             gen_helper_mtc0_taghi(arg);
1.1.1.5   root     5446:             rn = "TagHi";
                   5447:             break;
                   5448:         case 1:
                   5449:         case 3:
                   5450:         case 5:
                   5451:         case 7:
1.1.1.8   root     5452:             gen_helper_mtc0_datahi(arg);
1.1.1.5   root     5453:             rn = "DataHi";
                   5454:             break;
                   5455:         default:
                   5456:             rn = "invalid sel";
                   5457:             goto die;
                   5458:         }
1.1.1.6   root     5459:         break;
1.1.1.5   root     5460:     case 30:
                   5461:         switch (sel) {
                   5462:         case 0:
1.1.1.8   root     5463:             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
1.1.1.6   root     5464:             rn = "ErrorEPC";
                   5465:             break;
1.1.1.5   root     5466:         default:
                   5467:             goto die;
                   5468:         }
                   5469:         break;
                   5470:     case 31:
                   5471:         switch (sel) {
                   5472:         case 0:
1.1.1.7   root     5473:             /* EJTAG support */
1.1.1.8   root     5474:             gen_mtc0_store32(arg, offsetof(CPUState, CP0_DESAVE));
1.1.1.6   root     5475:             rn = "DESAVE";
                   5476:             break;
1.1.1.5   root     5477:         default:
                   5478:             goto die;
                   5479:         }
1.1.1.6   root     5480:         /* Stop translation as we may have switched the execution mode */
                   5481:         ctx->bstate = BS_STOP;
1.1.1.5   root     5482:         break;
                   5483:     default:
1.1.1.6   root     5484:         goto die;
1.1.1.5   root     5485:     }
1.1.1.7   root     5486:     LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
                   5487:     /* For simplicity assume that all writes can cause interrupts.  */
                   5488:     if (use_icount) {
                   5489:         gen_io_end();
                   5490:         ctx->bstate = BS_STOP;
1.1.1.5   root     5491:     }
                   5492:     return;
                   5493: 
                   5494: die:
1.1.1.7   root     5495:     LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
1.1.1.5   root     5496:     generate_exception(ctx, EXCP_RI);
                   5497: }
1.1.1.6   root     5498: #endif /* TARGET_MIPS64 */
1.1.1.5   root     5499: 
1.1.1.7   root     5500: static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
1.1.1.6   root     5501:                      int u, int sel, int h)
1.1.1.5   root     5502: {
1.1.1.6   root     5503:     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1.1.1.7   root     5504:     TCGv t0 = tcg_temp_local_new();
1.1.1.5   root     5505: 
1.1.1.6   root     5506:     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
1.1.1.7   root     5507:         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
                   5508:          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
                   5509:         tcg_gen_movi_tl(t0, -1);
1.1.1.6   root     5510:     else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
                   5511:              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1.1.1.7   root     5512:         tcg_gen_movi_tl(t0, -1);
1.1.1.6   root     5513:     else if (u == 0) {
                   5514:         switch (rt) {
                   5515:         case 2:
                   5516:             switch (sel) {
                   5517:             case 1:
1.1.1.7   root     5518:                 gen_helper_mftc0_tcstatus(t0);
1.1.1.6   root     5519:                 break;
                   5520:             case 2:
1.1.1.7   root     5521:                 gen_helper_mftc0_tcbind(t0);
1.1.1.6   root     5522:                 break;
                   5523:             case 3:
1.1.1.7   root     5524:                 gen_helper_mftc0_tcrestart(t0);
1.1.1.6   root     5525:                 break;
                   5526:             case 4:
1.1.1.7   root     5527:                 gen_helper_mftc0_tchalt(t0);
1.1.1.6   root     5528:                 break;
                   5529:             case 5:
1.1.1.7   root     5530:                 gen_helper_mftc0_tccontext(t0);
1.1.1.6   root     5531:                 break;
                   5532:             case 6:
1.1.1.7   root     5533:                 gen_helper_mftc0_tcschedule(t0);
1.1.1.6   root     5534:                 break;
                   5535:             case 7:
1.1.1.7   root     5536:                 gen_helper_mftc0_tcschefback(t0);
1.1.1.6   root     5537:                 break;
                   5538:             default:
1.1.1.7   root     5539:                 gen_mfc0(env, ctx, t0, rt, sel);
1.1.1.6   root     5540:                 break;
                   5541:             }
                   5542:             break;
                   5543:         case 10:
                   5544:             switch (sel) {
                   5545:             case 0:
1.1.1.7   root     5546:                 gen_helper_mftc0_entryhi(t0);
1.1.1.6   root     5547:                 break;
                   5548:             default:
1.1.1.7   root     5549:                 gen_mfc0(env, ctx, t0, rt, sel);
1.1.1.6   root     5550:                 break;
                   5551:             }
                   5552:         case 12:
                   5553:             switch (sel) {
                   5554:             case 0:
1.1.1.7   root     5555:                 gen_helper_mftc0_status(t0);
1.1.1.6   root     5556:                 break;
                   5557:             default:
1.1.1.7   root     5558:                 gen_mfc0(env, ctx, t0, rt, sel);
1.1.1.6   root     5559:                 break;
                   5560:             }
                   5561:         case 23:
                   5562:             switch (sel) {
                   5563:             case 0:
1.1.1.7   root     5564:                 gen_helper_mftc0_debug(t0);
1.1.1.6   root     5565:                 break;
                   5566:             default:
1.1.1.7   root     5567:                 gen_mfc0(env, ctx, t0, rt, sel);
1.1.1.6   root     5568:                 break;
                   5569:             }
                   5570:             break;
                   5571:         default:
1.1.1.7   root     5572:             gen_mfc0(env, ctx, t0, rt, sel);
1.1.1.6   root     5573:         }
                   5574:     } else switch (sel) {
                   5575:     /* GPR registers. */
                   5576:     case 0:
1.1.1.7   root     5577:         gen_helper_1i(mftgpr, t0, rt);
1.1.1.6   root     5578:         break;
                   5579:     /* Auxiliary CPU registers */
                   5580:     case 1:
                   5581:         switch (rt) {
                   5582:         case 0:
1.1.1.7   root     5583:             gen_helper_1i(mftlo, t0, 0);
1.1.1.6   root     5584:             break;
                   5585:         case 1:
1.1.1.7   root     5586:             gen_helper_1i(mfthi, t0, 0);
1.1.1.6   root     5587:             break;
                   5588:         case 2:
1.1.1.7   root     5589:             gen_helper_1i(mftacx, t0, 0);
1.1.1.6   root     5590:             break;
                   5591:         case 4:
1.1.1.7   root     5592:             gen_helper_1i(mftlo, t0, 1);
1.1.1.6   root     5593:             break;
                   5594:         case 5:
1.1.1.7   root     5595:             gen_helper_1i(mfthi, t0, 1);
1.1.1.6   root     5596:             break;
                   5597:         case 6:
1.1.1.7   root     5598:             gen_helper_1i(mftacx, t0, 1);
1.1.1.6   root     5599:             break;
                   5600:         case 8:
1.1.1.7   root     5601:             gen_helper_1i(mftlo, t0, 2);
1.1.1.6   root     5602:             break;
                   5603:         case 9:
1.1.1.7   root     5604:             gen_helper_1i(mfthi, t0, 2);
1.1.1.6   root     5605:             break;
                   5606:         case 10:
1.1.1.7   root     5607:             gen_helper_1i(mftacx, t0, 2);
1.1.1.6   root     5608:             break;
                   5609:         case 12:
1.1.1.7   root     5610:             gen_helper_1i(mftlo, t0, 3);
1.1.1.6   root     5611:             break;
                   5612:         case 13:
1.1.1.7   root     5613:             gen_helper_1i(mfthi, t0, 3);
1.1.1.6   root     5614:             break;
                   5615:         case 14:
1.1.1.7   root     5616:             gen_helper_1i(mftacx, t0, 3);
1.1.1.6   root     5617:             break;
                   5618:         case 16:
1.1.1.7   root     5619:             gen_helper_mftdsp(t0);
1.1.1.6   root     5620:             break;
                   5621:         default:
                   5622:             goto die;
                   5623:         }
                   5624:         break;
                   5625:     /* Floating point (COP1). */
                   5626:     case 2:
                   5627:         /* XXX: For now we support only a single FPU context. */
                   5628:         if (h == 0) {
1.1.1.7   root     5629:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   5630: 
                   5631:             gen_load_fpr32(fp0, rt);
                   5632:             tcg_gen_ext_i32_tl(t0, fp0);
                   5633:             tcg_temp_free_i32(fp0);
1.1.1.6   root     5634:         } else {
1.1.1.7   root     5635:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   5636: 
                   5637:             gen_load_fpr32h(fp0, rt);
                   5638:             tcg_gen_ext_i32_tl(t0, fp0);
                   5639:             tcg_temp_free_i32(fp0);
1.1.1.6   root     5640:         }
                   5641:         break;
                   5642:     case 3:
                   5643:         /* XXX: For now we support only a single FPU context. */
1.1.1.7   root     5644:         gen_helper_1i(cfc1, t0, rt);
1.1.1.6   root     5645:         break;
                   5646:     /* COP2: Not implemented. */
                   5647:     case 4:
                   5648:     case 5:
                   5649:         /* fall through */
                   5650:     default:
                   5651:         goto die;
                   5652:     }
1.1.1.7   root     5653:     LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
                   5654:     gen_store_gpr(t0, rd);
                   5655:     tcg_temp_free(t0);
1.1.1.6   root     5656:     return;
                   5657: 
                   5658: die:
1.1.1.7   root     5659:     tcg_temp_free(t0);
                   5660:     LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1.1.1.6   root     5661:     generate_exception(ctx, EXCP_RI);
                   5662: }
                   5663: 
1.1.1.7   root     5664: static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
1.1.1.6   root     5665:                      int u, int sel, int h)
                   5666: {
                   5667:     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1.1.1.7   root     5668:     TCGv t0 = tcg_temp_local_new();
1.1.1.6   root     5669: 
1.1.1.7   root     5670:     gen_load_gpr(t0, rt);
1.1.1.6   root     5671:     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
1.1.1.7   root     5672:         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
                   5673:          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1.1.1.6   root     5674:         /* NOP */ ;
                   5675:     else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
                   5676:              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
                   5677:         /* NOP */ ;
                   5678:     else if (u == 0) {
                   5679:         switch (rd) {
                   5680:         case 2:
                   5681:             switch (sel) {
                   5682:             case 1:
1.1.1.7   root     5683:                 gen_helper_mttc0_tcstatus(t0);
1.1.1.6   root     5684:                 break;
                   5685:             case 2:
1.1.1.7   root     5686:                 gen_helper_mttc0_tcbind(t0);
1.1.1.6   root     5687:                 break;
                   5688:             case 3:
1.1.1.7   root     5689:                 gen_helper_mttc0_tcrestart(t0);
1.1.1.6   root     5690:                 break;
                   5691:             case 4:
1.1.1.7   root     5692:                 gen_helper_mttc0_tchalt(t0);
1.1.1.6   root     5693:                 break;
                   5694:             case 5:
1.1.1.7   root     5695:                 gen_helper_mttc0_tccontext(t0);
1.1.1.6   root     5696:                 break;
                   5697:             case 6:
1.1.1.7   root     5698:                 gen_helper_mttc0_tcschedule(t0);
1.1.1.6   root     5699:                 break;
                   5700:             case 7:
1.1.1.7   root     5701:                 gen_helper_mttc0_tcschefback(t0);
1.1.1.6   root     5702:                 break;
                   5703:             default:
1.1.1.7   root     5704:                 gen_mtc0(env, ctx, t0, rd, sel);
1.1.1.6   root     5705:                 break;
                   5706:             }
                   5707:             break;
                   5708:         case 10:
                   5709:             switch (sel) {
                   5710:             case 0:
1.1.1.7   root     5711:                 gen_helper_mttc0_entryhi(t0);
1.1.1.6   root     5712:                 break;
                   5713:             default:
1.1.1.7   root     5714:                 gen_mtc0(env, ctx, t0, rd, sel);
1.1.1.6   root     5715:                 break;
                   5716:             }
                   5717:         case 12:
                   5718:             switch (sel) {
                   5719:             case 0:
1.1.1.7   root     5720:                 gen_helper_mttc0_status(t0);
1.1.1.6   root     5721:                 break;
                   5722:             default:
1.1.1.7   root     5723:                 gen_mtc0(env, ctx, t0, rd, sel);
1.1.1.6   root     5724:                 break;
                   5725:             }
                   5726:         case 23:
                   5727:             switch (sel) {
                   5728:             case 0:
1.1.1.7   root     5729:                 gen_helper_mttc0_debug(t0);
1.1.1.6   root     5730:                 break;
                   5731:             default:
1.1.1.7   root     5732:                 gen_mtc0(env, ctx, t0, rd, sel);
1.1.1.6   root     5733:                 break;
                   5734:             }
                   5735:             break;
                   5736:         default:
1.1.1.7   root     5737:             gen_mtc0(env, ctx, t0, rd, sel);
1.1.1.6   root     5738:         }
                   5739:     } else switch (sel) {
                   5740:     /* GPR registers. */
                   5741:     case 0:
1.1.1.7   root     5742:         gen_helper_1i(mttgpr, t0, rd);
1.1.1.6   root     5743:         break;
                   5744:     /* Auxiliary CPU registers */
                   5745:     case 1:
                   5746:         switch (rd) {
                   5747:         case 0:
1.1.1.7   root     5748:             gen_helper_1i(mttlo, t0, 0);
1.1.1.6   root     5749:             break;
                   5750:         case 1:
1.1.1.7   root     5751:             gen_helper_1i(mtthi, t0, 0);
1.1.1.6   root     5752:             break;
                   5753:         case 2:
1.1.1.7   root     5754:             gen_helper_1i(mttacx, t0, 0);
1.1.1.6   root     5755:             break;
                   5756:         case 4:
1.1.1.7   root     5757:             gen_helper_1i(mttlo, t0, 1);
1.1.1.6   root     5758:             break;
                   5759:         case 5:
1.1.1.7   root     5760:             gen_helper_1i(mtthi, t0, 1);
1.1.1.6   root     5761:             break;
                   5762:         case 6:
1.1.1.7   root     5763:             gen_helper_1i(mttacx, t0, 1);
1.1.1.6   root     5764:             break;
                   5765:         case 8:
1.1.1.7   root     5766:             gen_helper_1i(mttlo, t0, 2);
1.1.1.6   root     5767:             break;
                   5768:         case 9:
1.1.1.7   root     5769:             gen_helper_1i(mtthi, t0, 2);
1.1.1.6   root     5770:             break;
                   5771:         case 10:
1.1.1.7   root     5772:             gen_helper_1i(mttacx, t0, 2);
1.1.1.6   root     5773:             break;
                   5774:         case 12:
1.1.1.7   root     5775:             gen_helper_1i(mttlo, t0, 3);
1.1.1.6   root     5776:             break;
                   5777:         case 13:
1.1.1.7   root     5778:             gen_helper_1i(mtthi, t0, 3);
1.1.1.6   root     5779:             break;
                   5780:         case 14:
1.1.1.7   root     5781:             gen_helper_1i(mttacx, t0, 3);
1.1.1.6   root     5782:             break;
                   5783:         case 16:
1.1.1.7   root     5784:             gen_helper_mttdsp(t0);
1.1.1.6   root     5785:             break;
                   5786:         default:
                   5787:             goto die;
                   5788:         }
                   5789:         break;
                   5790:     /* Floating point (COP1). */
                   5791:     case 2:
                   5792:         /* XXX: For now we support only a single FPU context. */
                   5793:         if (h == 0) {
1.1.1.7   root     5794:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   5795: 
                   5796:             tcg_gen_trunc_tl_i32(fp0, t0);
                   5797:             gen_store_fpr32(fp0, rd);
                   5798:             tcg_temp_free_i32(fp0);
1.1.1.6   root     5799:         } else {
1.1.1.7   root     5800:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   5801: 
                   5802:             tcg_gen_trunc_tl_i32(fp0, t0);
                   5803:             gen_store_fpr32h(fp0, rd);
                   5804:             tcg_temp_free_i32(fp0);
1.1.1.6   root     5805:         }
                   5806:         break;
                   5807:     case 3:
                   5808:         /* XXX: For now we support only a single FPU context. */
1.1.1.7   root     5809:         gen_helper_1i(ctc1, t0, rd);
1.1.1.6   root     5810:         break;
                   5811:     /* COP2: Not implemented. */
                   5812:     case 4:
                   5813:     case 5:
                   5814:         /* fall through */
                   5815:     default:
                   5816:         goto die;
                   5817:     }
1.1.1.7   root     5818:     LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
                   5819:     tcg_temp_free(t0);
1.1.1.6   root     5820:     return;
                   5821: 
                   5822: die:
1.1.1.7   root     5823:     tcg_temp_free(t0);
                   5824:     LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1.1.1.6   root     5825:     generate_exception(ctx, EXCP_RI);
                   5826: }
                   5827: 
                   5828: static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
                   5829: {
                   5830:     const char *opn = "ldst";
1.1.1.5   root     5831: 
                   5832:     switch (opc) {
                   5833:     case OPC_MFC0:
                   5834:         if (rt == 0) {
1.1.1.6   root     5835:             /* Treat as NOP. */
1.1.1.5   root     5836:             return;
                   5837:         }
1.1.1.8   root     5838:         gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
1.1.1.5   root     5839:         opn = "mfc0";
                   5840:         break;
                   5841:     case OPC_MTC0:
1.1.1.7   root     5842:         {
1.1.1.8   root     5843:             TCGv t0 = tcg_temp_new();
1.1.1.7   root     5844: 
                   5845:             gen_load_gpr(t0, rt);
                   5846:             gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
                   5847:             tcg_temp_free(t0);
                   5848:         }
1.1.1.5   root     5849:         opn = "mtc0";
                   5850:         break;
1.1.1.6   root     5851: #if defined(TARGET_MIPS64)
1.1.1.5   root     5852:     case OPC_DMFC0:
1.1.1.6   root     5853:         check_insn(env, ctx, ISA_MIPS3);
1.1.1.5   root     5854:         if (rt == 0) {
1.1.1.6   root     5855:             /* Treat as NOP. */
1.1.1.5   root     5856:             return;
                   5857:         }
1.1.1.8   root     5858:         gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
1.1.1.5   root     5859:         opn = "dmfc0";
                   5860:         break;
                   5861:     case OPC_DMTC0:
1.1.1.6   root     5862:         check_insn(env, ctx, ISA_MIPS3);
1.1.1.7   root     5863:         {
1.1.1.8   root     5864:             TCGv t0 = tcg_temp_new();
1.1.1.7   root     5865: 
                   5866:             gen_load_gpr(t0, rt);
                   5867:             gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
                   5868:             tcg_temp_free(t0);
                   5869:         }
1.1.1.5   root     5870:         opn = "dmtc0";
                   5871:         break;
1.1.1.6   root     5872: #endif
                   5873:     case OPC_MFTR:
                   5874:         check_insn(env, ctx, ASE_MT);
                   5875:         if (rd == 0) {
                   5876:             /* Treat as NOP. */
                   5877:             return;
                   5878:         }
1.1.1.7   root     5879:         gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
1.1.1.6   root     5880:                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
                   5881:         opn = "mftr";
                   5882:         break;
                   5883:     case OPC_MTTR:
                   5884:         check_insn(env, ctx, ASE_MT);
1.1.1.7   root     5885:         gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
1.1.1.6   root     5886:                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
                   5887:         opn = "mttr";
                   5888:         break;
1.1.1.5   root     5889:     case OPC_TLBWI:
                   5890:         opn = "tlbwi";
1.1.1.8   root     5891:         if (!env->tlb->helper_tlbwi)
1.1.1.6   root     5892:             goto die;
1.1.1.7   root     5893:         gen_helper_tlbwi();
1.1.1.5   root     5894:         break;
                   5895:     case OPC_TLBWR:
                   5896:         opn = "tlbwr";
1.1.1.8   root     5897:         if (!env->tlb->helper_tlbwr)
1.1.1.6   root     5898:             goto die;
1.1.1.7   root     5899:         gen_helper_tlbwr();
1.1.1.5   root     5900:         break;
                   5901:     case OPC_TLBP:
                   5902:         opn = "tlbp";
1.1.1.8   root     5903:         if (!env->tlb->helper_tlbp)
1.1.1.6   root     5904:             goto die;
1.1.1.7   root     5905:         gen_helper_tlbp();
1.1.1.5   root     5906:         break;
                   5907:     case OPC_TLBR:
                   5908:         opn = "tlbr";
1.1.1.8   root     5909:         if (!env->tlb->helper_tlbr)
1.1.1.6   root     5910:             goto die;
1.1.1.7   root     5911:         gen_helper_tlbr();
1.1.1.5   root     5912:         break;
                   5913:     case OPC_ERET:
                   5914:         opn = "eret";
1.1.1.6   root     5915:         check_insn(env, ctx, ISA_MIPS2);
1.1.1.7   root     5916:         gen_helper_eret();
1.1.1.5   root     5917:         ctx->bstate = BS_EXCP;
                   5918:         break;
                   5919:     case OPC_DERET:
                   5920:         opn = "deret";
1.1.1.6   root     5921:         check_insn(env, ctx, ISA_MIPS32);
1.1.1.5   root     5922:         if (!(ctx->hflags & MIPS_HFLAG_DM)) {
1.1.1.6   root     5923:             MIPS_INVAL(opn);
1.1.1.5   root     5924:             generate_exception(ctx, EXCP_RI);
                   5925:         } else {
1.1.1.7   root     5926:             gen_helper_deret();
1.1.1.5   root     5927:             ctx->bstate = BS_EXCP;
                   5928:         }
                   5929:         break;
                   5930:     case OPC_WAIT:
                   5931:         opn = "wait";
1.1.1.6   root     5932:         check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
1.1.1.5   root     5933:         /* If we get an exception, we want to restart at next instruction */
                   5934:         ctx->pc += 4;
                   5935:         save_cpu_state(ctx, 1);
                   5936:         ctx->pc -= 4;
1.1.1.7   root     5937:         gen_helper_wait();
1.1.1.5   root     5938:         ctx->bstate = BS_EXCP;
                   5939:         break;
                   5940:     default:
1.1.1.6   root     5941:  die:
                   5942:         MIPS_INVAL(opn);
1.1.1.5   root     5943:         generate_exception(ctx, EXCP_RI);
                   5944:         return;
                   5945:     }
                   5946:     MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
                   5947: }
1.1.1.7   root     5948: #endif /* !CONFIG_USER_ONLY */
1.1.1.5   root     5949: 
                   5950: /* CP1 Branches (before delay slot) */
1.1.1.6   root     5951: static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
                   5952:                                  int32_t cc, int32_t offset)
1.1.1.5   root     5953: {
                   5954:     target_ulong btarget;
1.1.1.6   root     5955:     const char *opn = "cp1 cond branch";
1.1.1.7   root     5956:     TCGv_i32 t0 = tcg_temp_new_i32();
1.1.1.6   root     5957: 
                   5958:     if (cc != 0)
                   5959:         check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
1.1.1.5   root     5960: 
                   5961:     btarget = ctx->pc + 4 + offset;
                   5962: 
                   5963:     switch (op) {
                   5964:     case OPC_BC1F:
1.1.1.8   root     5965:         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   5966:         tcg_gen_not_i32(t0, t0);
                   5967:         tcg_gen_andi_i32(t0, t0, 1);
                   5968:         tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.6   root     5969:         opn = "bc1f";
1.1.1.5   root     5970:         goto not_likely;
                   5971:     case OPC_BC1FL:
1.1.1.8   root     5972:         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   5973:         tcg_gen_not_i32(t0, t0);
                   5974:         tcg_gen_andi_i32(t0, t0, 1);
                   5975:         tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.6   root     5976:         opn = "bc1fl";
1.1.1.5   root     5977:         goto likely;
                   5978:     case OPC_BC1T:
1.1.1.8   root     5979:         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   5980:         tcg_gen_andi_i32(t0, t0, 1);
                   5981:         tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.6   root     5982:         opn = "bc1t";
                   5983:         goto not_likely;
1.1.1.5   root     5984:     case OPC_BC1TL:
1.1.1.8   root     5985:         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   5986:         tcg_gen_andi_i32(t0, t0, 1);
                   5987:         tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.6   root     5988:         opn = "bc1tl";
1.1.1.5   root     5989:     likely:
                   5990:         ctx->hflags |= MIPS_HFLAG_BL;
1.1.1.6   root     5991:         break;
                   5992:     case OPC_BC1FANY2:
1.1.1.7   root     5993:         {
1.1.1.8   root     5994:             TCGv_i32 t1 = tcg_temp_new_i32();
                   5995:             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   5996:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
1.1.1.12! root     5997:             tcg_gen_nor_i32(t0, t0, t1);
1.1.1.8   root     5998:             tcg_temp_free_i32(t1);
                   5999:             tcg_gen_andi_i32(t0, t0, 1);
                   6000:             tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.7   root     6001:         }
1.1.1.6   root     6002:         opn = "bc1any2f";
                   6003:         goto not_likely;
                   6004:     case OPC_BC1TANY2:
1.1.1.7   root     6005:         {
1.1.1.8   root     6006:             TCGv_i32 t1 = tcg_temp_new_i32();
                   6007:             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   6008:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
                   6009:             tcg_gen_or_i32(t0, t0, t1);
                   6010:             tcg_temp_free_i32(t1);
                   6011:             tcg_gen_andi_i32(t0, t0, 1);
                   6012:             tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.7   root     6013:         }
1.1.1.6   root     6014:         opn = "bc1any2t";
                   6015:         goto not_likely;
                   6016:     case OPC_BC1FANY4:
1.1.1.7   root     6017:         {
1.1.1.8   root     6018:             TCGv_i32 t1 = tcg_temp_new_i32();
                   6019:             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   6020:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
                   6021:             tcg_gen_or_i32(t0, t0, t1);
                   6022:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
                   6023:             tcg_gen_or_i32(t0, t0, t1);
                   6024:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
1.1.1.12! root     6025:             tcg_gen_nor_i32(t0, t0, t1);
1.1.1.8   root     6026:             tcg_temp_free_i32(t1);
                   6027:             tcg_gen_andi_i32(t0, t0, 1);
                   6028:             tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.7   root     6029:         }
1.1.1.6   root     6030:         opn = "bc1any4f";
                   6031:         goto not_likely;
                   6032:     case OPC_BC1TANY4:
1.1.1.7   root     6033:         {
1.1.1.8   root     6034:             TCGv_i32 t1 = tcg_temp_new_i32();
                   6035:             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   6036:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
                   6037:             tcg_gen_or_i32(t0, t0, t1);
                   6038:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
                   6039:             tcg_gen_or_i32(t0, t0, t1);
                   6040:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
                   6041:             tcg_gen_or_i32(t0, t0, t1);
                   6042:             tcg_temp_free_i32(t1);
                   6043:             tcg_gen_andi_i32(t0, t0, 1);
                   6044:             tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.7   root     6045:         }
1.1.1.6   root     6046:         opn = "bc1any4t";
                   6047:     not_likely:
                   6048:         ctx->hflags |= MIPS_HFLAG_BC;
1.1.1.5   root     6049:         break;
1.1.1.6   root     6050:     default:
                   6051:         MIPS_INVAL(opn);
                   6052:         generate_exception (ctx, EXCP_RI);
1.1.1.7   root     6053:         goto out;
1.1.1.5   root     6054:     }
1.1.1.6   root     6055:     MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
1.1.1.5   root     6056:                ctx->hflags, btarget);
                   6057:     ctx->btarget = btarget;
1.1.1.7   root     6058: 
                   6059:  out:
                   6060:     tcg_temp_free_i32(t0);
1.1.1.5   root     6061: }
                   6062: 
                   6063: /* Coprocessor 1 (FPU) */
1.1.1.6   root     6064: 
                   6065: #define FOP(func, fmt) (((fmt) << 21) | (func))
                   6066: 
1.1.1.12! root     6067: enum fopcode {
        !          6068:     OPC_ADD_S = FOP(0, FMT_S),
        !          6069:     OPC_SUB_S = FOP(1, FMT_S),
        !          6070:     OPC_MUL_S = FOP(2, FMT_S),
        !          6071:     OPC_DIV_S = FOP(3, FMT_S),
        !          6072:     OPC_SQRT_S = FOP(4, FMT_S),
        !          6073:     OPC_ABS_S = FOP(5, FMT_S),
        !          6074:     OPC_MOV_S = FOP(6, FMT_S),
        !          6075:     OPC_NEG_S = FOP(7, FMT_S),
        !          6076:     OPC_ROUND_L_S = FOP(8, FMT_S),
        !          6077:     OPC_TRUNC_L_S = FOP(9, FMT_S),
        !          6078:     OPC_CEIL_L_S = FOP(10, FMT_S),
        !          6079:     OPC_FLOOR_L_S = FOP(11, FMT_S),
        !          6080:     OPC_ROUND_W_S = FOP(12, FMT_S),
        !          6081:     OPC_TRUNC_W_S = FOP(13, FMT_S),
        !          6082:     OPC_CEIL_W_S = FOP(14, FMT_S),
        !          6083:     OPC_FLOOR_W_S = FOP(15, FMT_S),
        !          6084:     OPC_MOVCF_S = FOP(17, FMT_S),
        !          6085:     OPC_MOVZ_S = FOP(18, FMT_S),
        !          6086:     OPC_MOVN_S = FOP(19, FMT_S),
        !          6087:     OPC_RECIP_S = FOP(21, FMT_S),
        !          6088:     OPC_RSQRT_S = FOP(22, FMT_S),
        !          6089:     OPC_RECIP2_S = FOP(28, FMT_S),
        !          6090:     OPC_RECIP1_S = FOP(29, FMT_S),
        !          6091:     OPC_RSQRT1_S = FOP(30, FMT_S),
        !          6092:     OPC_RSQRT2_S = FOP(31, FMT_S),
        !          6093:     OPC_CVT_D_S = FOP(33, FMT_S),
        !          6094:     OPC_CVT_W_S = FOP(36, FMT_S),
        !          6095:     OPC_CVT_L_S = FOP(37, FMT_S),
        !          6096:     OPC_CVT_PS_S = FOP(38, FMT_S),
        !          6097:     OPC_CMP_F_S = FOP (48, FMT_S),
        !          6098:     OPC_CMP_UN_S = FOP (49, FMT_S),
        !          6099:     OPC_CMP_EQ_S = FOP (50, FMT_S),
        !          6100:     OPC_CMP_UEQ_S = FOP (51, FMT_S),
        !          6101:     OPC_CMP_OLT_S = FOP (52, FMT_S),
        !          6102:     OPC_CMP_ULT_S = FOP (53, FMT_S),
        !          6103:     OPC_CMP_OLE_S = FOP (54, FMT_S),
        !          6104:     OPC_CMP_ULE_S = FOP (55, FMT_S),
        !          6105:     OPC_CMP_SF_S = FOP (56, FMT_S),
        !          6106:     OPC_CMP_NGLE_S = FOP (57, FMT_S),
        !          6107:     OPC_CMP_SEQ_S = FOP (58, FMT_S),
        !          6108:     OPC_CMP_NGL_S = FOP (59, FMT_S),
        !          6109:     OPC_CMP_LT_S = FOP (60, FMT_S),
        !          6110:     OPC_CMP_NGE_S = FOP (61, FMT_S),
        !          6111:     OPC_CMP_LE_S = FOP (62, FMT_S),
        !          6112:     OPC_CMP_NGT_S = FOP (63, FMT_S),
        !          6113: 
        !          6114:     OPC_ADD_D = FOP(0, FMT_D),
        !          6115:     OPC_SUB_D = FOP(1, FMT_D),
        !          6116:     OPC_MUL_D = FOP(2, FMT_D),
        !          6117:     OPC_DIV_D = FOP(3, FMT_D),
        !          6118:     OPC_SQRT_D = FOP(4, FMT_D),
        !          6119:     OPC_ABS_D = FOP(5, FMT_D),
        !          6120:     OPC_MOV_D = FOP(6, FMT_D),
        !          6121:     OPC_NEG_D = FOP(7, FMT_D),
        !          6122:     OPC_ROUND_L_D = FOP(8, FMT_D),
        !          6123:     OPC_TRUNC_L_D = FOP(9, FMT_D),
        !          6124:     OPC_CEIL_L_D = FOP(10, FMT_D),
        !          6125:     OPC_FLOOR_L_D = FOP(11, FMT_D),
        !          6126:     OPC_ROUND_W_D = FOP(12, FMT_D),
        !          6127:     OPC_TRUNC_W_D = FOP(13, FMT_D),
        !          6128:     OPC_CEIL_W_D = FOP(14, FMT_D),
        !          6129:     OPC_FLOOR_W_D = FOP(15, FMT_D),
        !          6130:     OPC_MOVCF_D = FOP(17, FMT_D),
        !          6131:     OPC_MOVZ_D = FOP(18, FMT_D),
        !          6132:     OPC_MOVN_D = FOP(19, FMT_D),
        !          6133:     OPC_RECIP_D = FOP(21, FMT_D),
        !          6134:     OPC_RSQRT_D = FOP(22, FMT_D),
        !          6135:     OPC_RECIP2_D = FOP(28, FMT_D),
        !          6136:     OPC_RECIP1_D = FOP(29, FMT_D),
        !          6137:     OPC_RSQRT1_D = FOP(30, FMT_D),
        !          6138:     OPC_RSQRT2_D = FOP(31, FMT_D),
        !          6139:     OPC_CVT_S_D = FOP(32, FMT_D),
        !          6140:     OPC_CVT_W_D = FOP(36, FMT_D),
        !          6141:     OPC_CVT_L_D = FOP(37, FMT_D),
        !          6142:     OPC_CMP_F_D = FOP (48, FMT_D),
        !          6143:     OPC_CMP_UN_D = FOP (49, FMT_D),
        !          6144:     OPC_CMP_EQ_D = FOP (50, FMT_D),
        !          6145:     OPC_CMP_UEQ_D = FOP (51, FMT_D),
        !          6146:     OPC_CMP_OLT_D = FOP (52, FMT_D),
        !          6147:     OPC_CMP_ULT_D = FOP (53, FMT_D),
        !          6148:     OPC_CMP_OLE_D = FOP (54, FMT_D),
        !          6149:     OPC_CMP_ULE_D = FOP (55, FMT_D),
        !          6150:     OPC_CMP_SF_D = FOP (56, FMT_D),
        !          6151:     OPC_CMP_NGLE_D = FOP (57, FMT_D),
        !          6152:     OPC_CMP_SEQ_D = FOP (58, FMT_D),
        !          6153:     OPC_CMP_NGL_D = FOP (59, FMT_D),
        !          6154:     OPC_CMP_LT_D = FOP (60, FMT_D),
        !          6155:     OPC_CMP_NGE_D = FOP (61, FMT_D),
        !          6156:     OPC_CMP_LE_D = FOP (62, FMT_D),
        !          6157:     OPC_CMP_NGT_D = FOP (63, FMT_D),
        !          6158: 
        !          6159:     OPC_CVT_S_W = FOP(32, FMT_W),
        !          6160:     OPC_CVT_D_W = FOP(33, FMT_W),
        !          6161:     OPC_CVT_S_L = FOP(32, FMT_L),
        !          6162:     OPC_CVT_D_L = FOP(33, FMT_L),
        !          6163:     OPC_CVT_PS_PW = FOP(38, FMT_W),
        !          6164: 
        !          6165:     OPC_ADD_PS = FOP(0, FMT_PS),
        !          6166:     OPC_SUB_PS = FOP(1, FMT_PS),
        !          6167:     OPC_MUL_PS = FOP(2, FMT_PS),
        !          6168:     OPC_DIV_PS = FOP(3, FMT_PS),
        !          6169:     OPC_ABS_PS = FOP(5, FMT_PS),
        !          6170:     OPC_MOV_PS = FOP(6, FMT_PS),
        !          6171:     OPC_NEG_PS = FOP(7, FMT_PS),
        !          6172:     OPC_MOVCF_PS = FOP(17, FMT_PS),
        !          6173:     OPC_MOVZ_PS = FOP(18, FMT_PS),
        !          6174:     OPC_MOVN_PS = FOP(19, FMT_PS),
        !          6175:     OPC_ADDR_PS = FOP(24, FMT_PS),
        !          6176:     OPC_MULR_PS = FOP(26, FMT_PS),
        !          6177:     OPC_RECIP2_PS = FOP(28, FMT_PS),
        !          6178:     OPC_RECIP1_PS = FOP(29, FMT_PS),
        !          6179:     OPC_RSQRT1_PS = FOP(30, FMT_PS),
        !          6180:     OPC_RSQRT2_PS = FOP(31, FMT_PS),
        !          6181: 
        !          6182:     OPC_CVT_S_PU = FOP(32, FMT_PS),
        !          6183:     OPC_CVT_PW_PS = FOP(36, FMT_PS),
        !          6184:     OPC_CVT_S_PL = FOP(40, FMT_PS),
        !          6185:     OPC_PLL_PS = FOP(44, FMT_PS),
        !          6186:     OPC_PLU_PS = FOP(45, FMT_PS),
        !          6187:     OPC_PUL_PS = FOP(46, FMT_PS),
        !          6188:     OPC_PUU_PS = FOP(47, FMT_PS),
        !          6189:     OPC_CMP_F_PS = FOP (48, FMT_PS),
        !          6190:     OPC_CMP_UN_PS = FOP (49, FMT_PS),
        !          6191:     OPC_CMP_EQ_PS = FOP (50, FMT_PS),
        !          6192:     OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
        !          6193:     OPC_CMP_OLT_PS = FOP (52, FMT_PS),
        !          6194:     OPC_CMP_ULT_PS = FOP (53, FMT_PS),
        !          6195:     OPC_CMP_OLE_PS = FOP (54, FMT_PS),
        !          6196:     OPC_CMP_ULE_PS = FOP (55, FMT_PS),
        !          6197:     OPC_CMP_SF_PS = FOP (56, FMT_PS),
        !          6198:     OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
        !          6199:     OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
        !          6200:     OPC_CMP_NGL_PS = FOP (59, FMT_PS),
        !          6201:     OPC_CMP_LT_PS = FOP (60, FMT_PS),
        !          6202:     OPC_CMP_NGE_PS = FOP (61, FMT_PS),
        !          6203:     OPC_CMP_LE_PS = FOP (62, FMT_PS),
        !          6204:     OPC_CMP_NGT_PS = FOP (63, FMT_PS),
        !          6205: };
        !          6206: 
1.1.1.5   root     6207: static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
                   6208: {
1.1.1.6   root     6209:     const char *opn = "cp1 move";
1.1.1.8   root     6210:     TCGv t0 = tcg_temp_new();
1.1.1.5   root     6211: 
                   6212:     switch (opc) {
                   6213:     case OPC_MFC1:
1.1.1.7   root     6214:         {
                   6215:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6216: 
                   6217:             gen_load_fpr32(fp0, fs);
                   6218:             tcg_gen_ext_i32_tl(t0, fp0);
                   6219:             tcg_temp_free_i32(fp0);
                   6220:         }
                   6221:         gen_store_gpr(t0, rt);
1.1.1.5   root     6222:         opn = "mfc1";
                   6223:         break;
                   6224:     case OPC_MTC1:
1.1.1.7   root     6225:         gen_load_gpr(t0, rt);
                   6226:         {
                   6227:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6228: 
                   6229:             tcg_gen_trunc_tl_i32(fp0, t0);
                   6230:             gen_store_fpr32(fp0, fs);
                   6231:             tcg_temp_free_i32(fp0);
                   6232:         }
1.1.1.5   root     6233:         opn = "mtc1";
                   6234:         break;
                   6235:     case OPC_CFC1:
1.1.1.7   root     6236:         gen_helper_1i(cfc1, t0, fs);
                   6237:         gen_store_gpr(t0, rt);
1.1.1.5   root     6238:         opn = "cfc1";
                   6239:         break;
                   6240:     case OPC_CTC1:
1.1.1.7   root     6241:         gen_load_gpr(t0, rt);
                   6242:         gen_helper_1i(ctc1, t0, fs);
1.1.1.5   root     6243:         opn = "ctc1";
                   6244:         break;
1.1.1.8   root     6245: #if defined(TARGET_MIPS64)
1.1.1.5   root     6246:     case OPC_DMFC1:
1.1.1.8   root     6247:         gen_load_fpr64(ctx, t0, fs);
1.1.1.7   root     6248:         gen_store_gpr(t0, rt);
1.1.1.6   root     6249:         opn = "dmfc1";
                   6250:         break;
1.1.1.5   root     6251:     case OPC_DMTC1:
1.1.1.7   root     6252:         gen_load_gpr(t0, rt);
1.1.1.8   root     6253:         gen_store_fpr64(ctx, t0, fs);
1.1.1.6   root     6254:         opn = "dmtc1";
                   6255:         break;
1.1.1.8   root     6256: #endif
1.1.1.6   root     6257:     case OPC_MFHC1:
1.1.1.7   root     6258:         {
                   6259:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6260: 
                   6261:             gen_load_fpr32h(fp0, fs);
                   6262:             tcg_gen_ext_i32_tl(t0, fp0);
                   6263:             tcg_temp_free_i32(fp0);
                   6264:         }
                   6265:         gen_store_gpr(t0, rt);
1.1.1.6   root     6266:         opn = "mfhc1";
                   6267:         break;
                   6268:     case OPC_MTHC1:
1.1.1.7   root     6269:         gen_load_gpr(t0, rt);
                   6270:         {
                   6271:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6272: 
                   6273:             tcg_gen_trunc_tl_i32(fp0, t0);
                   6274:             gen_store_fpr32h(fp0, fs);
                   6275:             tcg_temp_free_i32(fp0);
                   6276:         }
1.1.1.6   root     6277:         opn = "mthc1";
                   6278:         break;
1.1.1.5   root     6279:     default:
1.1.1.6   root     6280:         MIPS_INVAL(opn);
                   6281:         generate_exception (ctx, EXCP_RI);
1.1.1.7   root     6282:         goto out;
1.1.1.4   root     6283:     }
                   6284:     MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
1.1.1.7   root     6285: 
                   6286:  out:
                   6287:     tcg_temp_free(t0);
1.1.1.4   root     6288: }
                   6289: 
1.1.1.6   root     6290: static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
                   6291: {
1.1.1.8   root     6292:     int l1;
1.1.1.7   root     6293:     TCGCond cond;
1.1.1.8   root     6294:     TCGv_i32 t0;
                   6295: 
                   6296:     if (rd == 0) {
                   6297:         /* Treat as NOP. */
                   6298:         return;
                   6299:     }
1.1.1.7   root     6300: 
                   6301:     if (tf)
                   6302:         cond = TCG_COND_EQ;
                   6303:     else
                   6304:         cond = TCG_COND_NE;
                   6305: 
1.1.1.8   root     6306:     l1 = gen_new_label();
                   6307:     t0 = tcg_temp_new_i32();
                   6308:     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
                   6309:     tcg_gen_brcondi_i32(cond, t0, 0, l1);
                   6310:     tcg_temp_free_i32(t0);
                   6311:     if (rs == 0) {
                   6312:         tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   6313:     } else {
                   6314:         tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   6315:     }
1.1.1.7   root     6316:     gen_set_label(l1);
                   6317: }
                   6318: 
                   6319: static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
                   6320: {
                   6321:     int cond;
1.1.1.8   root     6322:     TCGv_i32 t0 = tcg_temp_new_i32();
1.1.1.7   root     6323:     int l1 = gen_new_label();
                   6324: 
                   6325:     if (tf)
                   6326:         cond = TCG_COND_EQ;
                   6327:     else
                   6328:         cond = TCG_COND_NE;
                   6329: 
1.1.1.8   root     6330:     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
                   6331:     tcg_gen_brcondi_i32(cond, t0, 0, l1);
                   6332:     gen_load_fpr32(t0, fs);
                   6333:     gen_store_fpr32(t0, fd);
1.1.1.7   root     6334:     gen_set_label(l1);
1.1.1.8   root     6335:     tcg_temp_free_i32(t0);
1.1.1.7   root     6336: }
                   6337: 
                   6338: static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
                   6339: {
                   6340:     int cond;
1.1.1.8   root     6341:     TCGv_i32 t0 = tcg_temp_new_i32();
                   6342:     TCGv_i64 fp0;
1.1.1.7   root     6343:     int l1 = gen_new_label();
                   6344: 
                   6345:     if (tf)
                   6346:         cond = TCG_COND_EQ;
                   6347:     else
                   6348:         cond = TCG_COND_NE;
                   6349: 
1.1.1.8   root     6350:     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
                   6351:     tcg_gen_brcondi_i32(cond, t0, 0, l1);
                   6352:     tcg_temp_free_i32(t0);
                   6353:     fp0 = tcg_temp_new_i64();
1.1.1.7   root     6354:     gen_load_fpr64(ctx, fp0, fs);
                   6355:     gen_store_fpr64(ctx, fp0, fd);
                   6356:     tcg_temp_free_i64(fp0);
1.1.1.8   root     6357:     gen_set_label(l1);
1.1.1.7   root     6358: }
                   6359: 
                   6360: static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
                   6361: {
                   6362:     int cond;
1.1.1.8   root     6363:     TCGv_i32 t0 = tcg_temp_new_i32();
1.1.1.7   root     6364:     int l1 = gen_new_label();
                   6365:     int l2 = gen_new_label();
1.1.1.4   root     6366: 
1.1.1.7   root     6367:     if (tf)
                   6368:         cond = TCG_COND_EQ;
1.1.1.6   root     6369:     else
1.1.1.7   root     6370:         cond = TCG_COND_NE;
                   6371: 
1.1.1.8   root     6372:     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
                   6373:     tcg_gen_brcondi_i32(cond, t0, 0, l1);
                   6374:     gen_load_fpr32(t0, fs);
                   6375:     gen_store_fpr32(t0, fd);
1.1.1.7   root     6376:     gen_set_label(l1);
                   6377: 
1.1.1.8   root     6378:     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
                   6379:     tcg_gen_brcondi_i32(cond, t0, 0, l2);
                   6380:     gen_load_fpr32h(t0, fs);
                   6381:     gen_store_fpr32h(t0, fd);
                   6382:     tcg_temp_free_i32(t0);
1.1.1.7   root     6383:     gen_set_label(l2);
1.1.1.6   root     6384: }
                   6385: 
1.1.1.4   root     6386: 
1.1.1.12! root     6387: static void gen_farith (DisasContext *ctx, enum fopcode op1,
1.1.1.6   root     6388:                         int ft, int fs, int fd, int cc)
1.1.1.4   root     6389: {
1.1.1.6   root     6390:     const char *opn = "farith";
1.1.1.4   root     6391:     const char *condnames[] = {
                   6392:             "c.f",
                   6393:             "c.un",
                   6394:             "c.eq",
                   6395:             "c.ueq",
                   6396:             "c.olt",
                   6397:             "c.ult",
                   6398:             "c.ole",
                   6399:             "c.ule",
                   6400:             "c.sf",
                   6401:             "c.ngle",
                   6402:             "c.seq",
                   6403:             "c.ngl",
                   6404:             "c.lt",
                   6405:             "c.nge",
                   6406:             "c.le",
                   6407:             "c.ngt",
                   6408:     };
1.1.1.6   root     6409:     const char *condnames_abs[] = {
                   6410:             "cabs.f",
                   6411:             "cabs.un",
                   6412:             "cabs.eq",
                   6413:             "cabs.ueq",
                   6414:             "cabs.olt",
                   6415:             "cabs.ult",
                   6416:             "cabs.ole",
                   6417:             "cabs.ule",
                   6418:             "cabs.sf",
                   6419:             "cabs.ngle",
                   6420:             "cabs.seq",
                   6421:             "cabs.ngl",
                   6422:             "cabs.lt",
                   6423:             "cabs.nge",
                   6424:             "cabs.le",
                   6425:             "cabs.ngt",
                   6426:     };
                   6427:     enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
1.1.1.5   root     6428:     uint32_t func = ctx->opcode & 0x3f;
                   6429: 
1.1.1.12! root     6430:     switch (op1) {
        !          6431:     case OPC_ADD_S:
1.1.1.7   root     6432:         {
                   6433:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6434:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   6435: 
                   6436:             gen_load_fpr32(fp0, fs);
                   6437:             gen_load_fpr32(fp1, ft);
                   6438:             gen_helper_float_add_s(fp0, fp0, fp1);
                   6439:             tcg_temp_free_i32(fp1);
                   6440:             gen_store_fpr32(fp0, fd);
                   6441:             tcg_temp_free_i32(fp0);
                   6442:         }
1.1.1.6   root     6443:         opn = "add.s";
                   6444:         optype = BINOP;
                   6445:         break;
1.1.1.12! root     6446:     case OPC_SUB_S:
1.1.1.7   root     6447:         {
                   6448:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6449:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   6450: 
                   6451:             gen_load_fpr32(fp0, fs);
                   6452:             gen_load_fpr32(fp1, ft);
                   6453:             gen_helper_float_sub_s(fp0, fp0, fp1);
                   6454:             tcg_temp_free_i32(fp1);
                   6455:             gen_store_fpr32(fp0, fd);
                   6456:             tcg_temp_free_i32(fp0);
                   6457:         }
1.1.1.6   root     6458:         opn = "sub.s";
                   6459:         optype = BINOP;
                   6460:         break;
1.1.1.12! root     6461:     case OPC_MUL_S:
1.1.1.7   root     6462:         {
                   6463:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6464:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   6465: 
                   6466:             gen_load_fpr32(fp0, fs);
                   6467:             gen_load_fpr32(fp1, ft);
                   6468:             gen_helper_float_mul_s(fp0, fp0, fp1);
                   6469:             tcg_temp_free_i32(fp1);
                   6470:             gen_store_fpr32(fp0, fd);
                   6471:             tcg_temp_free_i32(fp0);
                   6472:         }
1.1.1.6   root     6473:         opn = "mul.s";
                   6474:         optype = BINOP;
                   6475:         break;
1.1.1.12! root     6476:     case OPC_DIV_S:
1.1.1.7   root     6477:         {
                   6478:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6479:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   6480: 
                   6481:             gen_load_fpr32(fp0, fs);
                   6482:             gen_load_fpr32(fp1, ft);
                   6483:             gen_helper_float_div_s(fp0, fp0, fp1);
                   6484:             tcg_temp_free_i32(fp1);
                   6485:             gen_store_fpr32(fp0, fd);
                   6486:             tcg_temp_free_i32(fp0);
                   6487:         }
1.1.1.6   root     6488:         opn = "div.s";
                   6489:         optype = BINOP;
                   6490:         break;
1.1.1.12! root     6491:     case OPC_SQRT_S:
1.1.1.7   root     6492:         {
                   6493:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6494: 
                   6495:             gen_load_fpr32(fp0, fs);
                   6496:             gen_helper_float_sqrt_s(fp0, fp0);
                   6497:             gen_store_fpr32(fp0, fd);
                   6498:             tcg_temp_free_i32(fp0);
                   6499:         }
1.1.1.6   root     6500:         opn = "sqrt.s";
                   6501:         break;
1.1.1.12! root     6502:     case OPC_ABS_S:
1.1.1.7   root     6503:         {
                   6504:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6505: 
                   6506:             gen_load_fpr32(fp0, fs);
                   6507:             gen_helper_float_abs_s(fp0, fp0);
                   6508:             gen_store_fpr32(fp0, fd);
                   6509:             tcg_temp_free_i32(fp0);
                   6510:         }
1.1.1.6   root     6511:         opn = "abs.s";
                   6512:         break;
1.1.1.12! root     6513:     case OPC_MOV_S:
1.1.1.7   root     6514:         {
                   6515:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6516: 
                   6517:             gen_load_fpr32(fp0, fs);
                   6518:             gen_store_fpr32(fp0, fd);
                   6519:             tcg_temp_free_i32(fp0);
                   6520:         }
1.1.1.6   root     6521:         opn = "mov.s";
                   6522:         break;
1.1.1.12! root     6523:     case OPC_NEG_S:
1.1.1.7   root     6524:         {
                   6525:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6526: 
                   6527:             gen_load_fpr32(fp0, fs);
                   6528:             gen_helper_float_chs_s(fp0, fp0);
                   6529:             gen_store_fpr32(fp0, fd);
                   6530:             tcg_temp_free_i32(fp0);
                   6531:         }
1.1.1.6   root     6532:         opn = "neg.s";
                   6533:         break;
1.1.1.12! root     6534:     case OPC_ROUND_L_S:
1.1.1.6   root     6535:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6536:         {
                   6537:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   6538:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   6539: 
                   6540:             gen_load_fpr32(fp32, fs);
                   6541:             gen_helper_float_roundl_s(fp64, fp32);
                   6542:             tcg_temp_free_i32(fp32);
                   6543:             gen_store_fpr64(ctx, fp64, fd);
                   6544:             tcg_temp_free_i64(fp64);
                   6545:         }
1.1.1.6   root     6546:         opn = "round.l.s";
                   6547:         break;
1.1.1.12! root     6548:     case OPC_TRUNC_L_S:
1.1.1.6   root     6549:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6550:         {
                   6551:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   6552:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   6553: 
                   6554:             gen_load_fpr32(fp32, fs);
                   6555:             gen_helper_float_truncl_s(fp64, fp32);
                   6556:             tcg_temp_free_i32(fp32);
                   6557:             gen_store_fpr64(ctx, fp64, fd);
                   6558:             tcg_temp_free_i64(fp64);
                   6559:         }
1.1.1.6   root     6560:         opn = "trunc.l.s";
                   6561:         break;
1.1.1.12! root     6562:     case OPC_CEIL_L_S:
1.1.1.6   root     6563:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6564:         {
                   6565:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   6566:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   6567: 
                   6568:             gen_load_fpr32(fp32, fs);
                   6569:             gen_helper_float_ceill_s(fp64, fp32);
                   6570:             tcg_temp_free_i32(fp32);
                   6571:             gen_store_fpr64(ctx, fp64, fd);
                   6572:             tcg_temp_free_i64(fp64);
                   6573:         }
1.1.1.6   root     6574:         opn = "ceil.l.s";
                   6575:         break;
1.1.1.12! root     6576:     case OPC_FLOOR_L_S:
1.1.1.6   root     6577:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6578:         {
                   6579:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   6580:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   6581: 
                   6582:             gen_load_fpr32(fp32, fs);
                   6583:             gen_helper_float_floorl_s(fp64, fp32);
                   6584:             tcg_temp_free_i32(fp32);
                   6585:             gen_store_fpr64(ctx, fp64, fd);
                   6586:             tcg_temp_free_i64(fp64);
                   6587:         }
1.1.1.6   root     6588:         opn = "floor.l.s";
                   6589:         break;
1.1.1.12! root     6590:     case OPC_ROUND_W_S:
1.1.1.7   root     6591:         {
                   6592:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6593: 
                   6594:             gen_load_fpr32(fp0, fs);
                   6595:             gen_helper_float_roundw_s(fp0, fp0);
                   6596:             gen_store_fpr32(fp0, fd);
                   6597:             tcg_temp_free_i32(fp0);
                   6598:         }
1.1.1.6   root     6599:         opn = "round.w.s";
                   6600:         break;
1.1.1.12! root     6601:     case OPC_TRUNC_W_S:
1.1.1.7   root     6602:         {
                   6603:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6604: 
                   6605:             gen_load_fpr32(fp0, fs);
                   6606:             gen_helper_float_truncw_s(fp0, fp0);
                   6607:             gen_store_fpr32(fp0, fd);
                   6608:             tcg_temp_free_i32(fp0);
                   6609:         }
1.1.1.6   root     6610:         opn = "trunc.w.s";
                   6611:         break;
1.1.1.12! root     6612:     case OPC_CEIL_W_S:
1.1.1.7   root     6613:         {
                   6614:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6615: 
                   6616:             gen_load_fpr32(fp0, fs);
                   6617:             gen_helper_float_ceilw_s(fp0, fp0);
                   6618:             gen_store_fpr32(fp0, fd);
                   6619:             tcg_temp_free_i32(fp0);
                   6620:         }
1.1.1.6   root     6621:         opn = "ceil.w.s";
                   6622:         break;
1.1.1.12! root     6623:     case OPC_FLOOR_W_S:
1.1.1.7   root     6624:         {
                   6625:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6626: 
                   6627:             gen_load_fpr32(fp0, fs);
                   6628:             gen_helper_float_floorw_s(fp0, fp0);
                   6629:             gen_store_fpr32(fp0, fd);
                   6630:             tcg_temp_free_i32(fp0);
                   6631:         }
1.1.1.6   root     6632:         opn = "floor.w.s";
                   6633:         break;
1.1.1.12! root     6634:     case OPC_MOVCF_S:
1.1.1.7   root     6635:         gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
1.1.1.6   root     6636:         opn = "movcf.s";
                   6637:         break;
1.1.1.12! root     6638:     case OPC_MOVZ_S:
1.1.1.7   root     6639:         {
                   6640:             int l1 = gen_new_label();
1.1.1.8   root     6641:             TCGv_i32 fp0;
1.1.1.7   root     6642: 
1.1.1.8   root     6643:             if (ft != 0) {
                   6644:                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
                   6645:             }
                   6646:             fp0 = tcg_temp_new_i32();
1.1.1.7   root     6647:             gen_load_fpr32(fp0, fs);
                   6648:             gen_store_fpr32(fp0, fd);
                   6649:             tcg_temp_free_i32(fp0);
                   6650:             gen_set_label(l1);
                   6651:         }
1.1.1.6   root     6652:         opn = "movz.s";
                   6653:         break;
1.1.1.12! root     6654:     case OPC_MOVN_S:
1.1.1.7   root     6655:         {
                   6656:             int l1 = gen_new_label();
1.1.1.8   root     6657:             TCGv_i32 fp0;
1.1.1.7   root     6658: 
1.1.1.8   root     6659:             if (ft != 0) {
                   6660:                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
                   6661:                 fp0 = tcg_temp_new_i32();
                   6662:                 gen_load_fpr32(fp0, fs);
                   6663:                 gen_store_fpr32(fp0, fd);
                   6664:                 tcg_temp_free_i32(fp0);
                   6665:                 gen_set_label(l1);
                   6666:             }
1.1.1.7   root     6667:         }
1.1.1.6   root     6668:         opn = "movn.s";
                   6669:         break;
1.1.1.12! root     6670:     case OPC_RECIP_S:
1.1.1.6   root     6671:         check_cop1x(ctx);
1.1.1.7   root     6672:         {
                   6673:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6674: 
                   6675:             gen_load_fpr32(fp0, fs);
                   6676:             gen_helper_float_recip_s(fp0, fp0);
                   6677:             gen_store_fpr32(fp0, fd);
                   6678:             tcg_temp_free_i32(fp0);
                   6679:         }
1.1.1.6   root     6680:         opn = "recip.s";
                   6681:         break;
1.1.1.12! root     6682:     case OPC_RSQRT_S:
1.1.1.6   root     6683:         check_cop1x(ctx);
1.1.1.7   root     6684:         {
                   6685:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6686: 
                   6687:             gen_load_fpr32(fp0, fs);
                   6688:             gen_helper_float_rsqrt_s(fp0, fp0);
                   6689:             gen_store_fpr32(fp0, fd);
                   6690:             tcg_temp_free_i32(fp0);
                   6691:         }
1.1.1.6   root     6692:         opn = "rsqrt.s";
                   6693:         break;
1.1.1.12! root     6694:     case OPC_RECIP2_S:
1.1.1.6   root     6695:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6696:         {
                   6697:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6698:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   6699: 
                   6700:             gen_load_fpr32(fp0, fs);
                   6701:             gen_load_fpr32(fp1, fd);
                   6702:             gen_helper_float_recip2_s(fp0, fp0, fp1);
                   6703:             tcg_temp_free_i32(fp1);
                   6704:             gen_store_fpr32(fp0, fd);
                   6705:             tcg_temp_free_i32(fp0);
                   6706:         }
1.1.1.6   root     6707:         opn = "recip2.s";
                   6708:         break;
1.1.1.12! root     6709:     case OPC_RECIP1_S:
1.1.1.6   root     6710:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6711:         {
                   6712:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6713: 
                   6714:             gen_load_fpr32(fp0, fs);
                   6715:             gen_helper_float_recip1_s(fp0, fp0);
                   6716:             gen_store_fpr32(fp0, fd);
                   6717:             tcg_temp_free_i32(fp0);
                   6718:         }
1.1.1.6   root     6719:         opn = "recip1.s";
                   6720:         break;
1.1.1.12! root     6721:     case OPC_RSQRT1_S:
1.1.1.6   root     6722:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6723:         {
                   6724:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6725: 
                   6726:             gen_load_fpr32(fp0, fs);
                   6727:             gen_helper_float_rsqrt1_s(fp0, fp0);
                   6728:             gen_store_fpr32(fp0, fd);
                   6729:             tcg_temp_free_i32(fp0);
                   6730:         }
1.1.1.6   root     6731:         opn = "rsqrt1.s";
                   6732:         break;
1.1.1.12! root     6733:     case OPC_RSQRT2_S:
1.1.1.6   root     6734:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6735:         {
                   6736:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6737:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   6738: 
                   6739:             gen_load_fpr32(fp0, fs);
                   6740:             gen_load_fpr32(fp1, ft);
                   6741:             gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
                   6742:             tcg_temp_free_i32(fp1);
                   6743:             gen_store_fpr32(fp0, fd);
                   6744:             tcg_temp_free_i32(fp0);
                   6745:         }
1.1.1.6   root     6746:         opn = "rsqrt2.s";
                   6747:         break;
1.1.1.12! root     6748:     case OPC_CVT_D_S:
1.1.1.6   root     6749:         check_cp1_registers(ctx, fd);
1.1.1.7   root     6750:         {
                   6751:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   6752:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   6753: 
                   6754:             gen_load_fpr32(fp32, fs);
                   6755:             gen_helper_float_cvtd_s(fp64, fp32);
                   6756:             tcg_temp_free_i32(fp32);
                   6757:             gen_store_fpr64(ctx, fp64, fd);
                   6758:             tcg_temp_free_i64(fp64);
                   6759:         }
1.1.1.6   root     6760:         opn = "cvt.d.s";
                   6761:         break;
1.1.1.12! root     6762:     case OPC_CVT_W_S:
1.1.1.7   root     6763:         {
                   6764:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6765: 
                   6766:             gen_load_fpr32(fp0, fs);
                   6767:             gen_helper_float_cvtw_s(fp0, fp0);
                   6768:             gen_store_fpr32(fp0, fd);
                   6769:             tcg_temp_free_i32(fp0);
                   6770:         }
1.1.1.6   root     6771:         opn = "cvt.w.s";
                   6772:         break;
1.1.1.12! root     6773:     case OPC_CVT_L_S:
1.1.1.6   root     6774:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6775:         {
                   6776:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   6777:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   6778: 
                   6779:             gen_load_fpr32(fp32, fs);
                   6780:             gen_helper_float_cvtl_s(fp64, fp32);
                   6781:             tcg_temp_free_i32(fp32);
                   6782:             gen_store_fpr64(ctx, fp64, fd);
                   6783:             tcg_temp_free_i64(fp64);
                   6784:         }
1.1.1.6   root     6785:         opn = "cvt.l.s";
                   6786:         break;
1.1.1.12! root     6787:     case OPC_CVT_PS_S:
1.1.1.6   root     6788:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6789:         {
                   6790:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   6791:             TCGv_i32 fp32_0 = tcg_temp_new_i32();
                   6792:             TCGv_i32 fp32_1 = tcg_temp_new_i32();
                   6793: 
                   6794:             gen_load_fpr32(fp32_0, fs);
                   6795:             gen_load_fpr32(fp32_1, ft);
                   6796:             tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
                   6797:             tcg_temp_free_i32(fp32_1);
                   6798:             tcg_temp_free_i32(fp32_0);
                   6799:             gen_store_fpr64(ctx, fp64, fd);
                   6800:             tcg_temp_free_i64(fp64);
                   6801:         }
1.1.1.6   root     6802:         opn = "cvt.ps.s";
                   6803:         break;
1.1.1.12! root     6804:     case OPC_CMP_F_S:
        !          6805:     case OPC_CMP_UN_S:
        !          6806:     case OPC_CMP_EQ_S:
        !          6807:     case OPC_CMP_UEQ_S:
        !          6808:     case OPC_CMP_OLT_S:
        !          6809:     case OPC_CMP_ULT_S:
        !          6810:     case OPC_CMP_OLE_S:
        !          6811:     case OPC_CMP_ULE_S:
        !          6812:     case OPC_CMP_SF_S:
        !          6813:     case OPC_CMP_NGLE_S:
        !          6814:     case OPC_CMP_SEQ_S:
        !          6815:     case OPC_CMP_NGL_S:
        !          6816:     case OPC_CMP_LT_S:
        !          6817:     case OPC_CMP_NGE_S:
        !          6818:     case OPC_CMP_LE_S:
        !          6819:     case OPC_CMP_NGT_S:
        !          6820:         if (ctx->opcode & (1 << 6)) {
        !          6821:             gen_cmpabs_s(ctx, func-48, ft, fs, cc);
        !          6822:             opn = condnames_abs[func-48];
        !          6823:         } else {
        !          6824:             gen_cmp_s(ctx, func-48, ft, fs, cc);
        !          6825:             opn = condnames[func-48];
1.1.1.6   root     6826:         }
                   6827:         break;
1.1.1.12! root     6828:     case OPC_ADD_D:
1.1.1.6   root     6829:         check_cp1_registers(ctx, fs | ft | fd);
1.1.1.7   root     6830:         {
                   6831:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6832:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   6833: 
                   6834:             gen_load_fpr64(ctx, fp0, fs);
                   6835:             gen_load_fpr64(ctx, fp1, ft);
                   6836:             gen_helper_float_add_d(fp0, fp0, fp1);
                   6837:             tcg_temp_free_i64(fp1);
                   6838:             gen_store_fpr64(ctx, fp0, fd);
                   6839:             tcg_temp_free_i64(fp0);
                   6840:         }
1.1.1.4   root     6841:         opn = "add.d";
1.1.1.6   root     6842:         optype = BINOP;
1.1.1.4   root     6843:         break;
1.1.1.12! root     6844:     case OPC_SUB_D:
1.1.1.6   root     6845:         check_cp1_registers(ctx, fs | ft | fd);
1.1.1.7   root     6846:         {
                   6847:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6848:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   6849: 
                   6850:             gen_load_fpr64(ctx, fp0, fs);
                   6851:             gen_load_fpr64(ctx, fp1, ft);
                   6852:             gen_helper_float_sub_d(fp0, fp0, fp1);
                   6853:             tcg_temp_free_i64(fp1);
                   6854:             gen_store_fpr64(ctx, fp0, fd);
                   6855:             tcg_temp_free_i64(fp0);
                   6856:         }
1.1.1.4   root     6857:         opn = "sub.d";
1.1.1.6   root     6858:         optype = BINOP;
1.1.1.4   root     6859:         break;
1.1.1.12! root     6860:     case OPC_MUL_D:
1.1.1.6   root     6861:         check_cp1_registers(ctx, fs | ft | fd);
1.1.1.7   root     6862:         {
                   6863:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6864:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   6865: 
                   6866:             gen_load_fpr64(ctx, fp0, fs);
                   6867:             gen_load_fpr64(ctx, fp1, ft);
                   6868:             gen_helper_float_mul_d(fp0, fp0, fp1);
                   6869:             tcg_temp_free_i64(fp1);
                   6870:             gen_store_fpr64(ctx, fp0, fd);
                   6871:             tcg_temp_free_i64(fp0);
                   6872:         }
1.1.1.4   root     6873:         opn = "mul.d";
1.1.1.6   root     6874:         optype = BINOP;
1.1.1.4   root     6875:         break;
1.1.1.12! root     6876:     case OPC_DIV_D:
1.1.1.6   root     6877:         check_cp1_registers(ctx, fs | ft | fd);
1.1.1.7   root     6878:         {
                   6879:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6880:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   6881: 
                   6882:             gen_load_fpr64(ctx, fp0, fs);
                   6883:             gen_load_fpr64(ctx, fp1, ft);
                   6884:             gen_helper_float_div_d(fp0, fp0, fp1);
                   6885:             tcg_temp_free_i64(fp1);
                   6886:             gen_store_fpr64(ctx, fp0, fd);
                   6887:             tcg_temp_free_i64(fp0);
                   6888:         }
1.1.1.4   root     6889:         opn = "div.d";
1.1.1.6   root     6890:         optype = BINOP;
1.1.1.4   root     6891:         break;
1.1.1.12! root     6892:     case OPC_SQRT_D:
1.1.1.6   root     6893:         check_cp1_registers(ctx, fs | fd);
1.1.1.7   root     6894:         {
                   6895:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6896: 
                   6897:             gen_load_fpr64(ctx, fp0, fs);
                   6898:             gen_helper_float_sqrt_d(fp0, fp0);
                   6899:             gen_store_fpr64(ctx, fp0, fd);
                   6900:             tcg_temp_free_i64(fp0);
                   6901:         }
1.1.1.4   root     6902:         opn = "sqrt.d";
                   6903:         break;
1.1.1.12! root     6904:     case OPC_ABS_D:
1.1.1.6   root     6905:         check_cp1_registers(ctx, fs | fd);
1.1.1.7   root     6906:         {
                   6907:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6908: 
                   6909:             gen_load_fpr64(ctx, fp0, fs);
                   6910:             gen_helper_float_abs_d(fp0, fp0);
                   6911:             gen_store_fpr64(ctx, fp0, fd);
                   6912:             tcg_temp_free_i64(fp0);
                   6913:         }
1.1.1.4   root     6914:         opn = "abs.d";
                   6915:         break;
1.1.1.12! root     6916:     case OPC_MOV_D:
1.1.1.6   root     6917:         check_cp1_registers(ctx, fs | fd);
1.1.1.7   root     6918:         {
                   6919:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6920: 
                   6921:             gen_load_fpr64(ctx, fp0, fs);
                   6922:             gen_store_fpr64(ctx, fp0, fd);
                   6923:             tcg_temp_free_i64(fp0);
                   6924:         }
1.1.1.4   root     6925:         opn = "mov.d";
                   6926:         break;
1.1.1.12! root     6927:     case OPC_NEG_D:
1.1.1.6   root     6928:         check_cp1_registers(ctx, fs | fd);
1.1.1.7   root     6929:         {
                   6930:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6931: 
                   6932:             gen_load_fpr64(ctx, fp0, fs);
                   6933:             gen_helper_float_chs_d(fp0, fp0);
                   6934:             gen_store_fpr64(ctx, fp0, fd);
                   6935:             tcg_temp_free_i64(fp0);
                   6936:         }
1.1.1.4   root     6937:         opn = "neg.d";
                   6938:         break;
1.1.1.12! root     6939:     case OPC_ROUND_L_D:
1.1.1.6   root     6940:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6941:         {
                   6942:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6943: 
                   6944:             gen_load_fpr64(ctx, fp0, fs);
                   6945:             gen_helper_float_roundl_d(fp0, fp0);
                   6946:             gen_store_fpr64(ctx, fp0, fd);
                   6947:             tcg_temp_free_i64(fp0);
                   6948:         }
1.1.1.6   root     6949:         opn = "round.l.d";
                   6950:         break;
1.1.1.12! root     6951:     case OPC_TRUNC_L_D:
1.1.1.6   root     6952:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6953:         {
                   6954:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6955: 
                   6956:             gen_load_fpr64(ctx, fp0, fs);
                   6957:             gen_helper_float_truncl_d(fp0, fp0);
                   6958:             gen_store_fpr64(ctx, fp0, fd);
                   6959:             tcg_temp_free_i64(fp0);
                   6960:         }
1.1.1.6   root     6961:         opn = "trunc.l.d";
                   6962:         break;
1.1.1.12! root     6963:     case OPC_CEIL_L_D:
1.1.1.6   root     6964:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6965:         {
                   6966:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6967: 
                   6968:             gen_load_fpr64(ctx, fp0, fs);
                   6969:             gen_helper_float_ceill_d(fp0, fp0);
                   6970:             gen_store_fpr64(ctx, fp0, fd);
                   6971:             tcg_temp_free_i64(fp0);
                   6972:         }
1.1.1.6   root     6973:         opn = "ceil.l.d";
                   6974:         break;
1.1.1.12! root     6975:     case OPC_FLOOR_L_D:
1.1.1.6   root     6976:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6977:         {
                   6978:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6979: 
                   6980:             gen_load_fpr64(ctx, fp0, fs);
                   6981:             gen_helper_float_floorl_d(fp0, fp0);
                   6982:             gen_store_fpr64(ctx, fp0, fd);
                   6983:             tcg_temp_free_i64(fp0);
                   6984:         }
1.1.1.6   root     6985:         opn = "floor.l.d";
                   6986:         break;
1.1.1.12! root     6987:     case OPC_ROUND_W_D:
1.1.1.6   root     6988:         check_cp1_registers(ctx, fs);
1.1.1.7   root     6989:         {
                   6990:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   6991:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   6992: 
                   6993:             gen_load_fpr64(ctx, fp64, fs);
                   6994:             gen_helper_float_roundw_d(fp32, fp64);
                   6995:             tcg_temp_free_i64(fp64);
                   6996:             gen_store_fpr32(fp32, fd);
                   6997:             tcg_temp_free_i32(fp32);
                   6998:         }
1.1.1.4   root     6999:         opn = "round.w.d";
                   7000:         break;
1.1.1.12! root     7001:     case OPC_TRUNC_W_D:
1.1.1.6   root     7002:         check_cp1_registers(ctx, fs);
1.1.1.7   root     7003:         {
                   7004:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   7005:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   7006: 
                   7007:             gen_load_fpr64(ctx, fp64, fs);
                   7008:             gen_helper_float_truncw_d(fp32, fp64);
                   7009:             tcg_temp_free_i64(fp64);
                   7010:             gen_store_fpr32(fp32, fd);
                   7011:             tcg_temp_free_i32(fp32);
                   7012:         }
1.1.1.4   root     7013:         opn = "trunc.w.d";
                   7014:         break;
1.1.1.12! root     7015:     case OPC_CEIL_W_D:
1.1.1.6   root     7016:         check_cp1_registers(ctx, fs);
1.1.1.7   root     7017:         {
                   7018:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   7019:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   7020: 
                   7021:             gen_load_fpr64(ctx, fp64, fs);
                   7022:             gen_helper_float_ceilw_d(fp32, fp64);
                   7023:             tcg_temp_free_i64(fp64);
                   7024:             gen_store_fpr32(fp32, fd);
                   7025:             tcg_temp_free_i32(fp32);
                   7026:         }
1.1.1.4   root     7027:         opn = "ceil.w.d";
                   7028:         break;
1.1.1.12! root     7029:     case OPC_FLOOR_W_D:
1.1.1.6   root     7030:         check_cp1_registers(ctx, fs);
1.1.1.7   root     7031:         {
                   7032:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   7033:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   7034: 
                   7035:             gen_load_fpr64(ctx, fp64, fs);
                   7036:             gen_helper_float_floorw_d(fp32, fp64);
                   7037:             tcg_temp_free_i64(fp64);
                   7038:             gen_store_fpr32(fp32, fd);
                   7039:             tcg_temp_free_i32(fp32);
                   7040:         }
1.1.1.5   root     7041:         opn = "floor.w.d";
                   7042:         break;
1.1.1.12! root     7043:     case OPC_MOVCF_D:
1.1.1.7   root     7044:         gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
1.1.1.6   root     7045:         opn = "movcf.d";
1.1.1.4   root     7046:         break;
1.1.1.12! root     7047:     case OPC_MOVZ_D:
1.1.1.7   root     7048:         {
                   7049:             int l1 = gen_new_label();
1.1.1.8   root     7050:             TCGv_i64 fp0;
1.1.1.7   root     7051: 
1.1.1.8   root     7052:             if (ft != 0) {
                   7053:                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
                   7054:             }
                   7055:             fp0 = tcg_temp_new_i64();
1.1.1.7   root     7056:             gen_load_fpr64(ctx, fp0, fs);
                   7057:             gen_store_fpr64(ctx, fp0, fd);
                   7058:             tcg_temp_free_i64(fp0);
                   7059:             gen_set_label(l1);
                   7060:         }
1.1.1.6   root     7061:         opn = "movz.d";
                   7062:         break;
1.1.1.12! root     7063:     case OPC_MOVN_D:
1.1.1.7   root     7064:         {
                   7065:             int l1 = gen_new_label();
1.1.1.8   root     7066:             TCGv_i64 fp0;
1.1.1.7   root     7067: 
1.1.1.8   root     7068:             if (ft != 0) {
                   7069:                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
                   7070:                 fp0 = tcg_temp_new_i64();
                   7071:                 gen_load_fpr64(ctx, fp0, fs);
                   7072:                 gen_store_fpr64(ctx, fp0, fd);
                   7073:                 tcg_temp_free_i64(fp0);
                   7074:                 gen_set_label(l1);
                   7075:             }
1.1.1.7   root     7076:         }
1.1.1.6   root     7077:         opn = "movn.d";
                   7078:         break;
1.1.1.12! root     7079:     case OPC_RECIP_D:
1.1.1.6   root     7080:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7081:         {
                   7082:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7083: 
                   7084:             gen_load_fpr64(ctx, fp0, fs);
                   7085:             gen_helper_float_recip_d(fp0, fp0);
                   7086:             gen_store_fpr64(ctx, fp0, fd);
                   7087:             tcg_temp_free_i64(fp0);
                   7088:         }
1.1.1.6   root     7089:         opn = "recip.d";
                   7090:         break;
1.1.1.12! root     7091:     case OPC_RSQRT_D:
1.1.1.6   root     7092:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7093:         {
                   7094:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7095: 
                   7096:             gen_load_fpr64(ctx, fp0, fs);
                   7097:             gen_helper_float_rsqrt_d(fp0, fp0);
                   7098:             gen_store_fpr64(ctx, fp0, fd);
                   7099:             tcg_temp_free_i64(fp0);
                   7100:         }
1.1.1.6   root     7101:         opn = "rsqrt.d";
                   7102:         break;
1.1.1.12! root     7103:     case OPC_RECIP2_D:
1.1.1.6   root     7104:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7105:         {
                   7106:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7107:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7108: 
                   7109:             gen_load_fpr64(ctx, fp0, fs);
                   7110:             gen_load_fpr64(ctx, fp1, ft);
                   7111:             gen_helper_float_recip2_d(fp0, fp0, fp1);
                   7112:             tcg_temp_free_i64(fp1);
                   7113:             gen_store_fpr64(ctx, fp0, fd);
                   7114:             tcg_temp_free_i64(fp0);
                   7115:         }
1.1.1.6   root     7116:         opn = "recip2.d";
                   7117:         break;
1.1.1.12! root     7118:     case OPC_RECIP1_D:
1.1.1.6   root     7119:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7120:         {
                   7121:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7122: 
                   7123:             gen_load_fpr64(ctx, fp0, fs);
                   7124:             gen_helper_float_recip1_d(fp0, fp0);
                   7125:             gen_store_fpr64(ctx, fp0, fd);
                   7126:             tcg_temp_free_i64(fp0);
                   7127:         }
1.1.1.6   root     7128:         opn = "recip1.d";
                   7129:         break;
1.1.1.12! root     7130:     case OPC_RSQRT1_D:
1.1.1.6   root     7131:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7132:         {
                   7133:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7134: 
                   7135:             gen_load_fpr64(ctx, fp0, fs);
                   7136:             gen_helper_float_rsqrt1_d(fp0, fp0);
                   7137:             gen_store_fpr64(ctx, fp0, fd);
                   7138:             tcg_temp_free_i64(fp0);
                   7139:         }
1.1.1.6   root     7140:         opn = "rsqrt1.d";
                   7141:         break;
1.1.1.12! root     7142:     case OPC_RSQRT2_D:
1.1.1.6   root     7143:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7144:         {
                   7145:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7146:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7147: 
                   7148:             gen_load_fpr64(ctx, fp0, fs);
                   7149:             gen_load_fpr64(ctx, fp1, ft);
                   7150:             gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
                   7151:             tcg_temp_free_i64(fp1);
                   7152:             gen_store_fpr64(ctx, fp0, fd);
                   7153:             tcg_temp_free_i64(fp0);
                   7154:         }
1.1.1.6   root     7155:         opn = "rsqrt2.d";
1.1.1.4   root     7156:         break;
1.1.1.12! root     7157:     case OPC_CMP_F_D:
        !          7158:     case OPC_CMP_UN_D:
        !          7159:     case OPC_CMP_EQ_D:
        !          7160:     case OPC_CMP_UEQ_D:
        !          7161:     case OPC_CMP_OLT_D:
        !          7162:     case OPC_CMP_ULT_D:
        !          7163:     case OPC_CMP_OLE_D:
        !          7164:     case OPC_CMP_ULE_D:
        !          7165:     case OPC_CMP_SF_D:
        !          7166:     case OPC_CMP_NGLE_D:
        !          7167:     case OPC_CMP_SEQ_D:
        !          7168:     case OPC_CMP_NGL_D:
        !          7169:     case OPC_CMP_LT_D:
        !          7170:     case OPC_CMP_NGE_D:
        !          7171:     case OPC_CMP_LE_D:
        !          7172:     case OPC_CMP_NGT_D:
        !          7173:         if (ctx->opcode & (1 << 6)) {
        !          7174:             gen_cmpabs_d(ctx, func-48, ft, fs, cc);
        !          7175:             opn = condnames_abs[func-48];
        !          7176:         } else {
        !          7177:             gen_cmp_d(ctx, func-48, ft, fs, cc);
        !          7178:             opn = condnames[func-48];
1.1.1.6   root     7179:         }
                   7180:         break;
1.1.1.12! root     7181:     case OPC_CVT_S_D:
1.1.1.6   root     7182:         check_cp1_registers(ctx, fs);
1.1.1.7   root     7183:         {
                   7184:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   7185:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   7186: 
                   7187:             gen_load_fpr64(ctx, fp64, fs);
                   7188:             gen_helper_float_cvts_d(fp32, fp64);
                   7189:             tcg_temp_free_i64(fp64);
                   7190:             gen_store_fpr32(fp32, fd);
                   7191:             tcg_temp_free_i32(fp32);
                   7192:         }
1.1.1.6   root     7193:         opn = "cvt.s.d";
                   7194:         break;
1.1.1.12! root     7195:     case OPC_CVT_W_D:
1.1.1.6   root     7196:         check_cp1_registers(ctx, fs);
1.1.1.7   root     7197:         {
                   7198:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   7199:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   7200: 
                   7201:             gen_load_fpr64(ctx, fp64, fs);
                   7202:             gen_helper_float_cvtw_d(fp32, fp64);
                   7203:             tcg_temp_free_i64(fp64);
                   7204:             gen_store_fpr32(fp32, fd);
                   7205:             tcg_temp_free_i32(fp32);
                   7206:         }
1.1.1.6   root     7207:         opn = "cvt.w.d";
                   7208:         break;
1.1.1.12! root     7209:     case OPC_CVT_L_D:
1.1.1.6   root     7210:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7211:         {
                   7212:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7213: 
                   7214:             gen_load_fpr64(ctx, fp0, fs);
                   7215:             gen_helper_float_cvtl_d(fp0, fp0);
                   7216:             gen_store_fpr64(ctx, fp0, fd);
                   7217:             tcg_temp_free_i64(fp0);
                   7218:         }
1.1.1.6   root     7219:         opn = "cvt.l.d";
                   7220:         break;
1.1.1.12! root     7221:     case OPC_CVT_S_W:
1.1.1.7   root     7222:         {
                   7223:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7224: 
                   7225:             gen_load_fpr32(fp0, fs);
                   7226:             gen_helper_float_cvts_w(fp0, fp0);
                   7227:             gen_store_fpr32(fp0, fd);
                   7228:             tcg_temp_free_i32(fp0);
                   7229:         }
1.1.1.6   root     7230:         opn = "cvt.s.w";
                   7231:         break;
1.1.1.12! root     7232:     case OPC_CVT_D_W:
1.1.1.6   root     7233:         check_cp1_registers(ctx, fd);
1.1.1.7   root     7234:         {
                   7235:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   7236:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   7237: 
                   7238:             gen_load_fpr32(fp32, fs);
                   7239:             gen_helper_float_cvtd_w(fp64, fp32);
                   7240:             tcg_temp_free_i32(fp32);
                   7241:             gen_store_fpr64(ctx, fp64, fd);
                   7242:             tcg_temp_free_i64(fp64);
                   7243:         }
1.1.1.6   root     7244:         opn = "cvt.d.w";
                   7245:         break;
1.1.1.12! root     7246:     case OPC_CVT_S_L:
1.1.1.6   root     7247:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7248:         {
                   7249:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   7250:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   7251: 
                   7252:             gen_load_fpr64(ctx, fp64, fs);
                   7253:             gen_helper_float_cvts_l(fp32, fp64);
                   7254:             tcg_temp_free_i64(fp64);
                   7255:             gen_store_fpr32(fp32, fd);
                   7256:             tcg_temp_free_i32(fp32);
                   7257:         }
1.1.1.6   root     7258:         opn = "cvt.s.l";
                   7259:         break;
1.1.1.12! root     7260:     case OPC_CVT_D_L:
1.1.1.6   root     7261:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7262:         {
                   7263:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7264: 
                   7265:             gen_load_fpr64(ctx, fp0, fs);
                   7266:             gen_helper_float_cvtd_l(fp0, fp0);
                   7267:             gen_store_fpr64(ctx, fp0, fd);
                   7268:             tcg_temp_free_i64(fp0);
                   7269:         }
1.1.1.6   root     7270:         opn = "cvt.d.l";
                   7271:         break;
1.1.1.12! root     7272:     case OPC_CVT_PS_PW:
1.1.1.6   root     7273:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7274:         {
                   7275:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7276: 
                   7277:             gen_load_fpr64(ctx, fp0, fs);
                   7278:             gen_helper_float_cvtps_pw(fp0, fp0);
                   7279:             gen_store_fpr64(ctx, fp0, fd);
                   7280:             tcg_temp_free_i64(fp0);
                   7281:         }
1.1.1.6   root     7282:         opn = "cvt.ps.pw";
                   7283:         break;
1.1.1.12! root     7284:     case OPC_ADD_PS:
1.1.1.6   root     7285:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7286:         {
                   7287:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7288:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7289: 
                   7290:             gen_load_fpr64(ctx, fp0, fs);
                   7291:             gen_load_fpr64(ctx, fp1, ft);
                   7292:             gen_helper_float_add_ps(fp0, fp0, fp1);
                   7293:             tcg_temp_free_i64(fp1);
                   7294:             gen_store_fpr64(ctx, fp0, fd);
                   7295:             tcg_temp_free_i64(fp0);
                   7296:         }
1.1.1.6   root     7297:         opn = "add.ps";
                   7298:         break;
1.1.1.12! root     7299:     case OPC_SUB_PS:
1.1.1.6   root     7300:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7301:         {
                   7302:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7303:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7304: 
                   7305:             gen_load_fpr64(ctx, fp0, fs);
                   7306:             gen_load_fpr64(ctx, fp1, ft);
                   7307:             gen_helper_float_sub_ps(fp0, fp0, fp1);
                   7308:             tcg_temp_free_i64(fp1);
                   7309:             gen_store_fpr64(ctx, fp0, fd);
                   7310:             tcg_temp_free_i64(fp0);
                   7311:         }
1.1.1.6   root     7312:         opn = "sub.ps";
                   7313:         break;
1.1.1.12! root     7314:     case OPC_MUL_PS:
1.1.1.6   root     7315:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7316:         {
                   7317:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7318:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7319: 
                   7320:             gen_load_fpr64(ctx, fp0, fs);
                   7321:             gen_load_fpr64(ctx, fp1, ft);
                   7322:             gen_helper_float_mul_ps(fp0, fp0, fp1);
                   7323:             tcg_temp_free_i64(fp1);
                   7324:             gen_store_fpr64(ctx, fp0, fd);
                   7325:             tcg_temp_free_i64(fp0);
                   7326:         }
1.1.1.6   root     7327:         opn = "mul.ps";
                   7328:         break;
1.1.1.12! root     7329:     case OPC_ABS_PS:
1.1.1.6   root     7330:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7331:         {
                   7332:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7333: 
                   7334:             gen_load_fpr64(ctx, fp0, fs);
                   7335:             gen_helper_float_abs_ps(fp0, fp0);
                   7336:             gen_store_fpr64(ctx, fp0, fd);
                   7337:             tcg_temp_free_i64(fp0);
                   7338:         }
1.1.1.6   root     7339:         opn = "abs.ps";
                   7340:         break;
1.1.1.12! root     7341:     case OPC_MOV_PS:
1.1.1.6   root     7342:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7343:         {
                   7344:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7345: 
                   7346:             gen_load_fpr64(ctx, fp0, fs);
                   7347:             gen_store_fpr64(ctx, fp0, fd);
                   7348:             tcg_temp_free_i64(fp0);
                   7349:         }
1.1.1.6   root     7350:         opn = "mov.ps";
                   7351:         break;
1.1.1.12! root     7352:     case OPC_NEG_PS:
1.1.1.6   root     7353:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7354:         {
                   7355:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7356: 
                   7357:             gen_load_fpr64(ctx, fp0, fs);
                   7358:             gen_helper_float_chs_ps(fp0, fp0);
                   7359:             gen_store_fpr64(ctx, fp0, fd);
                   7360:             tcg_temp_free_i64(fp0);
                   7361:         }
1.1.1.6   root     7362:         opn = "neg.ps";
                   7363:         break;
1.1.1.12! root     7364:     case OPC_MOVCF_PS:
1.1.1.6   root     7365:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7366:         gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
1.1.1.6   root     7367:         opn = "movcf.ps";
                   7368:         break;
1.1.1.12! root     7369:     case OPC_MOVZ_PS:
1.1.1.6   root     7370:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7371:         {
                   7372:             int l1 = gen_new_label();
1.1.1.8   root     7373:             TCGv_i64 fp0;
1.1.1.7   root     7374: 
1.1.1.8   root     7375:             if (ft != 0)
                   7376:                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
                   7377:             fp0 = tcg_temp_new_i64();
                   7378:             gen_load_fpr64(ctx, fp0, fs);
                   7379:             gen_store_fpr64(ctx, fp0, fd);
                   7380:             tcg_temp_free_i64(fp0);
1.1.1.7   root     7381:             gen_set_label(l1);
                   7382:         }
1.1.1.6   root     7383:         opn = "movz.ps";
                   7384:         break;
1.1.1.12! root     7385:     case OPC_MOVN_PS:
1.1.1.6   root     7386:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7387:         {
                   7388:             int l1 = gen_new_label();
1.1.1.8   root     7389:             TCGv_i64 fp0;
1.1.1.7   root     7390: 
1.1.1.8   root     7391:             if (ft != 0) {
                   7392:                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
                   7393:                 fp0 = tcg_temp_new_i64();
                   7394:                 gen_load_fpr64(ctx, fp0, fs);
                   7395:                 gen_store_fpr64(ctx, fp0, fd);
                   7396:                 tcg_temp_free_i64(fp0);
                   7397:                 gen_set_label(l1);
                   7398:             }
1.1.1.7   root     7399:         }
1.1.1.6   root     7400:         opn = "movn.ps";
                   7401:         break;
1.1.1.12! root     7402:     case OPC_ADDR_PS:
1.1.1.6   root     7403:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7404:         {
                   7405:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7406:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7407: 
                   7408:             gen_load_fpr64(ctx, fp0, ft);
                   7409:             gen_load_fpr64(ctx, fp1, fs);
                   7410:             gen_helper_float_addr_ps(fp0, fp0, fp1);
                   7411:             tcg_temp_free_i64(fp1);
                   7412:             gen_store_fpr64(ctx, fp0, fd);
                   7413:             tcg_temp_free_i64(fp0);
                   7414:         }
1.1.1.6   root     7415:         opn = "addr.ps";
                   7416:         break;
1.1.1.12! root     7417:     case OPC_MULR_PS:
1.1.1.6   root     7418:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7419:         {
                   7420:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7421:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7422: 
                   7423:             gen_load_fpr64(ctx, fp0, ft);
                   7424:             gen_load_fpr64(ctx, fp1, fs);
                   7425:             gen_helper_float_mulr_ps(fp0, fp0, fp1);
                   7426:             tcg_temp_free_i64(fp1);
                   7427:             gen_store_fpr64(ctx, fp0, fd);
                   7428:             tcg_temp_free_i64(fp0);
                   7429:         }
1.1.1.6   root     7430:         opn = "mulr.ps";
                   7431:         break;
1.1.1.12! root     7432:     case OPC_RECIP2_PS:
1.1.1.6   root     7433:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7434:         {
                   7435:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7436:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7437: 
                   7438:             gen_load_fpr64(ctx, fp0, fs);
                   7439:             gen_load_fpr64(ctx, fp1, fd);
                   7440:             gen_helper_float_recip2_ps(fp0, fp0, fp1);
                   7441:             tcg_temp_free_i64(fp1);
                   7442:             gen_store_fpr64(ctx, fp0, fd);
                   7443:             tcg_temp_free_i64(fp0);
                   7444:         }
1.1.1.6   root     7445:         opn = "recip2.ps";
                   7446:         break;
1.1.1.12! root     7447:     case OPC_RECIP1_PS:
1.1.1.6   root     7448:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7449:         {
                   7450:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7451: 
                   7452:             gen_load_fpr64(ctx, fp0, fs);
                   7453:             gen_helper_float_recip1_ps(fp0, fp0);
                   7454:             gen_store_fpr64(ctx, fp0, fd);
                   7455:             tcg_temp_free_i64(fp0);
                   7456:         }
1.1.1.6   root     7457:         opn = "recip1.ps";
                   7458:         break;
1.1.1.12! root     7459:     case OPC_RSQRT1_PS:
1.1.1.6   root     7460:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7461:         {
                   7462:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7463: 
                   7464:             gen_load_fpr64(ctx, fp0, fs);
                   7465:             gen_helper_float_rsqrt1_ps(fp0, fp0);
                   7466:             gen_store_fpr64(ctx, fp0, fd);
                   7467:             tcg_temp_free_i64(fp0);
                   7468:         }
1.1.1.6   root     7469:         opn = "rsqrt1.ps";
                   7470:         break;
1.1.1.12! root     7471:     case OPC_RSQRT2_PS:
1.1.1.6   root     7472:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7473:         {
                   7474:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7475:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7476: 
                   7477:             gen_load_fpr64(ctx, fp0, fs);
                   7478:             gen_load_fpr64(ctx, fp1, ft);
                   7479:             gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
                   7480:             tcg_temp_free_i64(fp1);
                   7481:             gen_store_fpr64(ctx, fp0, fd);
                   7482:             tcg_temp_free_i64(fp0);
                   7483:         }
1.1.1.6   root     7484:         opn = "rsqrt2.ps";
                   7485:         break;
1.1.1.12! root     7486:     case OPC_CVT_S_PU:
1.1.1.6   root     7487:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7488:         {
                   7489:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7490: 
                   7491:             gen_load_fpr32h(fp0, fs);
                   7492:             gen_helper_float_cvts_pu(fp0, fp0);
                   7493:             gen_store_fpr32(fp0, fd);
                   7494:             tcg_temp_free_i32(fp0);
                   7495:         }
1.1.1.6   root     7496:         opn = "cvt.s.pu";
                   7497:         break;
1.1.1.12! root     7498:     case OPC_CVT_PW_PS:
1.1.1.6   root     7499:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7500:         {
                   7501:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7502: 
                   7503:             gen_load_fpr64(ctx, fp0, fs);
                   7504:             gen_helper_float_cvtpw_ps(fp0, fp0);
                   7505:             gen_store_fpr64(ctx, fp0, fd);
                   7506:             tcg_temp_free_i64(fp0);
                   7507:         }
1.1.1.6   root     7508:         opn = "cvt.pw.ps";
1.1.1.4   root     7509:         break;
1.1.1.12! root     7510:     case OPC_CVT_S_PL:
1.1.1.6   root     7511:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7512:         {
                   7513:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7514: 
                   7515:             gen_load_fpr32(fp0, fs);
                   7516:             gen_helper_float_cvts_pl(fp0, fp0);
                   7517:             gen_store_fpr32(fp0, fd);
                   7518:             tcg_temp_free_i32(fp0);
                   7519:         }
1.1.1.6   root     7520:         opn = "cvt.s.pl";
1.1.1.4   root     7521:         break;
1.1.1.12! root     7522:     case OPC_PLL_PS:
1.1.1.6   root     7523:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7524:         {
                   7525:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7526:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   7527: 
                   7528:             gen_load_fpr32(fp0, fs);
                   7529:             gen_load_fpr32(fp1, ft);
                   7530:             gen_store_fpr32h(fp0, fd);
                   7531:             gen_store_fpr32(fp1, fd);
                   7532:             tcg_temp_free_i32(fp0);
                   7533:             tcg_temp_free_i32(fp1);
                   7534:         }
1.1.1.6   root     7535:         opn = "pll.ps";
1.1.1.4   root     7536:         break;
1.1.1.12! root     7537:     case OPC_PLU_PS:
1.1.1.6   root     7538:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7539:         {
                   7540:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7541:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   7542: 
                   7543:             gen_load_fpr32(fp0, fs);
                   7544:             gen_load_fpr32h(fp1, ft);
                   7545:             gen_store_fpr32(fp1, fd);
                   7546:             gen_store_fpr32h(fp0, fd);
                   7547:             tcg_temp_free_i32(fp0);
                   7548:             tcg_temp_free_i32(fp1);
                   7549:         }
1.1.1.6   root     7550:         opn = "plu.ps";
                   7551:         break;
1.1.1.12! root     7552:     case OPC_PUL_PS:
1.1.1.6   root     7553:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7554:         {
                   7555:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7556:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   7557: 
                   7558:             gen_load_fpr32h(fp0, fs);
                   7559:             gen_load_fpr32(fp1, ft);
                   7560:             gen_store_fpr32(fp1, fd);
                   7561:             gen_store_fpr32h(fp0, fd);
                   7562:             tcg_temp_free_i32(fp0);
                   7563:             tcg_temp_free_i32(fp1);
                   7564:         }
1.1.1.6   root     7565:         opn = "pul.ps";
1.1.1.4   root     7566:         break;
1.1.1.12! root     7567:     case OPC_PUU_PS:
1.1.1.6   root     7568:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7569:         {
                   7570:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7571:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   7572: 
                   7573:             gen_load_fpr32h(fp0, fs);
                   7574:             gen_load_fpr32h(fp1, ft);
                   7575:             gen_store_fpr32(fp1, fd);
                   7576:             gen_store_fpr32h(fp0, fd);
                   7577:             tcg_temp_free_i32(fp0);
                   7578:             tcg_temp_free_i32(fp1);
                   7579:         }
1.1.1.6   root     7580:         opn = "puu.ps";
                   7581:         break;
1.1.1.12! root     7582:     case OPC_CMP_F_PS:
        !          7583:     case OPC_CMP_UN_PS:
        !          7584:     case OPC_CMP_EQ_PS:
        !          7585:     case OPC_CMP_UEQ_PS:
        !          7586:     case OPC_CMP_OLT_PS:
        !          7587:     case OPC_CMP_ULT_PS:
        !          7588:     case OPC_CMP_OLE_PS:
        !          7589:     case OPC_CMP_ULE_PS:
        !          7590:     case OPC_CMP_SF_PS:
        !          7591:     case OPC_CMP_NGLE_PS:
        !          7592:     case OPC_CMP_SEQ_PS:
        !          7593:     case OPC_CMP_NGL_PS:
        !          7594:     case OPC_CMP_LT_PS:
        !          7595:     case OPC_CMP_NGE_PS:
        !          7596:     case OPC_CMP_LE_PS:
        !          7597:     case OPC_CMP_NGT_PS:
        !          7598:         if (ctx->opcode & (1 << 6)) {
        !          7599:             gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
        !          7600:             opn = condnames_abs[func-48];
        !          7601:         } else {
        !          7602:             gen_cmp_ps(ctx, func-48, ft, fs, cc);
        !          7603:             opn = condnames[func-48];
1.1.1.6   root     7604:         }
1.1.1.4   root     7605:         break;
1.1.1.6   root     7606:     default:
                   7607:         MIPS_INVAL(opn);
                   7608:         generate_exception (ctx, EXCP_RI);
                   7609:         return;
                   7610:     }
                   7611:     switch (optype) {
                   7612:     case BINOP:
                   7613:         MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
                   7614:         break;
                   7615:     case CMPOP:
                   7616:         MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
                   7617:         break;
                   7618:     default:
                   7619:         MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
                   7620:         break;
                   7621:     }
                   7622: }
                   7623: 
                   7624: /* Coprocessor 3 (FPU) */
                   7625: static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
                   7626:                            int fd, int fs, int base, int index)
                   7627: {
                   7628:     const char *opn = "extended float load/store";
                   7629:     int store = 0;
1.1.1.8   root     7630:     TCGv t0 = tcg_temp_new();
1.1.1.6   root     7631: 
                   7632:     if (base == 0) {
1.1.1.7   root     7633:         gen_load_gpr(t0, index);
1.1.1.6   root     7634:     } else if (index == 0) {
1.1.1.7   root     7635:         gen_load_gpr(t0, base);
1.1.1.6   root     7636:     } else {
1.1.1.7   root     7637:         gen_load_gpr(t0, index);
1.1.1.9   root     7638:         gen_op_addr_add(ctx, t0, cpu_gpr[base], t0);
1.1.1.6   root     7639:     }
                   7640:     /* Don't do NOP if destination is zero: we must perform the actual
                   7641:        memory access. */
1.1.1.8   root     7642:     save_cpu_state(ctx, 0);
1.1.1.6   root     7643:     switch (opc) {
                   7644:     case OPC_LWXC1:
                   7645:         check_cop1x(ctx);
1.1.1.7   root     7646:         {
                   7647:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7648: 
1.1.1.8   root     7649:             tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
                   7650:             tcg_gen_trunc_tl_i32(fp0, t0);
1.1.1.7   root     7651:             gen_store_fpr32(fp0, fd);
                   7652:             tcg_temp_free_i32(fp0);
                   7653:         }
1.1.1.6   root     7654:         opn = "lwxc1";
                   7655:         break;
                   7656:     case OPC_LDXC1:
                   7657:         check_cop1x(ctx);
                   7658:         check_cp1_registers(ctx, fd);
1.1.1.7   root     7659:         {
                   7660:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7661: 
                   7662:             tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
                   7663:             gen_store_fpr64(ctx, fp0, fd);
                   7664:             tcg_temp_free_i64(fp0);
                   7665:         }
1.1.1.6   root     7666:         opn = "ldxc1";
                   7667:         break;
                   7668:     case OPC_LUXC1:
                   7669:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7670:         tcg_gen_andi_tl(t0, t0, ~0x7);
                   7671:         {
                   7672:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7673: 
                   7674:             tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
                   7675:             gen_store_fpr64(ctx, fp0, fd);
                   7676:             tcg_temp_free_i64(fp0);
                   7677:         }
1.1.1.6   root     7678:         opn = "luxc1";
                   7679:         break;
                   7680:     case OPC_SWXC1:
                   7681:         check_cop1x(ctx);
1.1.1.7   root     7682:         {
                   7683:             TCGv_i32 fp0 = tcg_temp_new_i32();
1.1.1.8   root     7684:             TCGv t1 = tcg_temp_new();
1.1.1.7   root     7685: 
                   7686:             gen_load_fpr32(fp0, fs);
                   7687:             tcg_gen_extu_i32_tl(t1, fp0);
                   7688:             tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
                   7689:             tcg_temp_free_i32(fp0);
1.1.1.8   root     7690:             tcg_temp_free(t1);
1.1.1.7   root     7691:         }
1.1.1.6   root     7692:         opn = "swxc1";
                   7693:         store = 1;
1.1.1.4   root     7694:         break;
1.1.1.6   root     7695:     case OPC_SDXC1:
                   7696:         check_cop1x(ctx);
                   7697:         check_cp1_registers(ctx, fs);
1.1.1.7   root     7698:         {
                   7699:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7700: 
                   7701:             gen_load_fpr64(ctx, fp0, fs);
                   7702:             tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
                   7703:             tcg_temp_free_i64(fp0);
                   7704:         }
1.1.1.6   root     7705:         opn = "sdxc1";
                   7706:         store = 1;
                   7707:         break;
                   7708:     case OPC_SUXC1:
                   7709:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7710:         tcg_gen_andi_tl(t0, t0, ~0x7);
                   7711:         {
                   7712:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7713: 
                   7714:             gen_load_fpr64(ctx, fp0, fs);
                   7715:             tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
                   7716:             tcg_temp_free_i64(fp0);
                   7717:         }
1.1.1.6   root     7718:         opn = "suxc1";
                   7719:         store = 1;
                   7720:         break;
                   7721:     }
1.1.1.7   root     7722:     tcg_temp_free(t0);
1.1.1.6   root     7723:     MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
                   7724:                regnames[index], regnames[base]);
                   7725: }
                   7726: 
                   7727: static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
                   7728:                             int fd, int fr, int fs, int ft)
                   7729: {
                   7730:     const char *opn = "flt3_arith";
                   7731: 
                   7732:     switch (opc) {
                   7733:     case OPC_ALNV_PS:
                   7734:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7735:         {
                   7736:             TCGv t0 = tcg_temp_local_new();
1.1.1.8   root     7737:             TCGv_i32 fp = tcg_temp_new_i32();
                   7738:             TCGv_i32 fph = tcg_temp_new_i32();
1.1.1.7   root     7739:             int l1 = gen_new_label();
                   7740:             int l2 = gen_new_label();
                   7741: 
                   7742:             gen_load_gpr(t0, fr);
                   7743:             tcg_gen_andi_tl(t0, t0, 0x7);
                   7744: 
                   7745:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
1.1.1.8   root     7746:             gen_load_fpr32(fp, fs);
                   7747:             gen_load_fpr32h(fph, fs);
                   7748:             gen_store_fpr32(fp, fd);
                   7749:             gen_store_fpr32h(fph, fd);
1.1.1.7   root     7750:             tcg_gen_br(l2);
                   7751:             gen_set_label(l1);
                   7752:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
                   7753:             tcg_temp_free(t0);
                   7754: #ifdef TARGET_WORDS_BIGENDIAN
1.1.1.8   root     7755:             gen_load_fpr32(fp, fs);
                   7756:             gen_load_fpr32h(fph, ft);
                   7757:             gen_store_fpr32h(fp, fd);
                   7758:             gen_store_fpr32(fph, fd);
1.1.1.7   root     7759: #else
1.1.1.8   root     7760:             gen_load_fpr32h(fph, fs);
                   7761:             gen_load_fpr32(fp, ft);
                   7762:             gen_store_fpr32(fph, fd);
                   7763:             gen_store_fpr32h(fp, fd);
1.1.1.7   root     7764: #endif
                   7765:             gen_set_label(l2);
1.1.1.8   root     7766:             tcg_temp_free_i32(fp);
                   7767:             tcg_temp_free_i32(fph);
1.1.1.7   root     7768:         }
1.1.1.6   root     7769:         opn = "alnv.ps";
                   7770:         break;
                   7771:     case OPC_MADD_S:
                   7772:         check_cop1x(ctx);
1.1.1.7   root     7773:         {
                   7774:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7775:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   7776:             TCGv_i32 fp2 = tcg_temp_new_i32();
                   7777: 
                   7778:             gen_load_fpr32(fp0, fs);
                   7779:             gen_load_fpr32(fp1, ft);
                   7780:             gen_load_fpr32(fp2, fr);
                   7781:             gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
                   7782:             tcg_temp_free_i32(fp0);
                   7783:             tcg_temp_free_i32(fp1);
                   7784:             gen_store_fpr32(fp2, fd);
                   7785:             tcg_temp_free_i32(fp2);
                   7786:         }
1.1.1.6   root     7787:         opn = "madd.s";
1.1.1.4   root     7788:         break;
1.1.1.6   root     7789:     case OPC_MADD_D:
                   7790:         check_cop1x(ctx);
                   7791:         check_cp1_registers(ctx, fd | fs | ft | fr);
1.1.1.7   root     7792:         {
                   7793:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7794:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7795:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   7796: 
                   7797:             gen_load_fpr64(ctx, fp0, fs);
                   7798:             gen_load_fpr64(ctx, fp1, ft);
                   7799:             gen_load_fpr64(ctx, fp2, fr);
                   7800:             gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
                   7801:             tcg_temp_free_i64(fp0);
                   7802:             tcg_temp_free_i64(fp1);
                   7803:             gen_store_fpr64(ctx, fp2, fd);
                   7804:             tcg_temp_free_i64(fp2);
                   7805:         }
1.1.1.6   root     7806:         opn = "madd.d";
                   7807:         break;
                   7808:     case OPC_MADD_PS:
                   7809:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7810:         {
                   7811:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7812:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7813:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   7814: 
                   7815:             gen_load_fpr64(ctx, fp0, fs);
                   7816:             gen_load_fpr64(ctx, fp1, ft);
                   7817:             gen_load_fpr64(ctx, fp2, fr);
                   7818:             gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
                   7819:             tcg_temp_free_i64(fp0);
                   7820:             tcg_temp_free_i64(fp1);
                   7821:             gen_store_fpr64(ctx, fp2, fd);
                   7822:             tcg_temp_free_i64(fp2);
                   7823:         }
1.1.1.6   root     7824:         opn = "madd.ps";
1.1.1.4   root     7825:         break;
1.1.1.6   root     7826:     case OPC_MSUB_S:
                   7827:         check_cop1x(ctx);
1.1.1.7   root     7828:         {
                   7829:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7830:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   7831:             TCGv_i32 fp2 = tcg_temp_new_i32();
                   7832: 
                   7833:             gen_load_fpr32(fp0, fs);
                   7834:             gen_load_fpr32(fp1, ft);
                   7835:             gen_load_fpr32(fp2, fr);
                   7836:             gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
                   7837:             tcg_temp_free_i32(fp0);
                   7838:             tcg_temp_free_i32(fp1);
                   7839:             gen_store_fpr32(fp2, fd);
                   7840:             tcg_temp_free_i32(fp2);
                   7841:         }
1.1.1.6   root     7842:         opn = "msub.s";
1.1.1.4   root     7843:         break;
1.1.1.6   root     7844:     case OPC_MSUB_D:
                   7845:         check_cop1x(ctx);
                   7846:         check_cp1_registers(ctx, fd | fs | ft | fr);
1.1.1.7   root     7847:         {
                   7848:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7849:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7850:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   7851: 
                   7852:             gen_load_fpr64(ctx, fp0, fs);
                   7853:             gen_load_fpr64(ctx, fp1, ft);
                   7854:             gen_load_fpr64(ctx, fp2, fr);
                   7855:             gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
                   7856:             tcg_temp_free_i64(fp0);
                   7857:             tcg_temp_free_i64(fp1);
                   7858:             gen_store_fpr64(ctx, fp2, fd);
                   7859:             tcg_temp_free_i64(fp2);
                   7860:         }
1.1.1.6   root     7861:         opn = "msub.d";
                   7862:         break;
                   7863:     case OPC_MSUB_PS:
                   7864:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7865:         {
                   7866:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7867:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7868:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   7869: 
                   7870:             gen_load_fpr64(ctx, fp0, fs);
                   7871:             gen_load_fpr64(ctx, fp1, ft);
                   7872:             gen_load_fpr64(ctx, fp2, fr);
                   7873:             gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
                   7874:             tcg_temp_free_i64(fp0);
                   7875:             tcg_temp_free_i64(fp1);
                   7876:             gen_store_fpr64(ctx, fp2, fd);
                   7877:             tcg_temp_free_i64(fp2);
                   7878:         }
1.1.1.6   root     7879:         opn = "msub.ps";
1.1.1.4   root     7880:         break;
1.1.1.6   root     7881:     case OPC_NMADD_S:
                   7882:         check_cop1x(ctx);
1.1.1.7   root     7883:         {
                   7884:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7885:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   7886:             TCGv_i32 fp2 = tcg_temp_new_i32();
                   7887: 
                   7888:             gen_load_fpr32(fp0, fs);
                   7889:             gen_load_fpr32(fp1, ft);
                   7890:             gen_load_fpr32(fp2, fr);
                   7891:             gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
                   7892:             tcg_temp_free_i32(fp0);
                   7893:             tcg_temp_free_i32(fp1);
                   7894:             gen_store_fpr32(fp2, fd);
                   7895:             tcg_temp_free_i32(fp2);
                   7896:         }
1.1.1.6   root     7897:         opn = "nmadd.s";
1.1.1.4   root     7898:         break;
1.1.1.6   root     7899:     case OPC_NMADD_D:
                   7900:         check_cop1x(ctx);
                   7901:         check_cp1_registers(ctx, fd | fs | ft | fr);
1.1.1.7   root     7902:         {
                   7903:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7904:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7905:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   7906: 
                   7907:             gen_load_fpr64(ctx, fp0, fs);
                   7908:             gen_load_fpr64(ctx, fp1, ft);
                   7909:             gen_load_fpr64(ctx, fp2, fr);
                   7910:             gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
                   7911:             tcg_temp_free_i64(fp0);
                   7912:             tcg_temp_free_i64(fp1);
                   7913:             gen_store_fpr64(ctx, fp2, fd);
                   7914:             tcg_temp_free_i64(fp2);
                   7915:         }
1.1.1.6   root     7916:         opn = "nmadd.d";
1.1.1.5   root     7917:         break;
1.1.1.6   root     7918:     case OPC_NMADD_PS:
                   7919:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7920:         {
                   7921:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7922:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7923:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   7924: 
                   7925:             gen_load_fpr64(ctx, fp0, fs);
                   7926:             gen_load_fpr64(ctx, fp1, ft);
                   7927:             gen_load_fpr64(ctx, fp2, fr);
                   7928:             gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
                   7929:             tcg_temp_free_i64(fp0);
                   7930:             tcg_temp_free_i64(fp1);
                   7931:             gen_store_fpr64(ctx, fp2, fd);
                   7932:             tcg_temp_free_i64(fp2);
                   7933:         }
1.1.1.6   root     7934:         opn = "nmadd.ps";
1.1.1.4   root     7935:         break;
1.1.1.6   root     7936:     case OPC_NMSUB_S:
                   7937:         check_cop1x(ctx);
1.1.1.7   root     7938:         {
                   7939:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7940:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   7941:             TCGv_i32 fp2 = tcg_temp_new_i32();
                   7942: 
                   7943:             gen_load_fpr32(fp0, fs);
                   7944:             gen_load_fpr32(fp1, ft);
                   7945:             gen_load_fpr32(fp2, fr);
                   7946:             gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
                   7947:             tcg_temp_free_i32(fp0);
                   7948:             tcg_temp_free_i32(fp1);
                   7949:             gen_store_fpr32(fp2, fd);
                   7950:             tcg_temp_free_i32(fp2);
                   7951:         }
1.1.1.6   root     7952:         opn = "nmsub.s";
1.1.1.4   root     7953:         break;
1.1.1.6   root     7954:     case OPC_NMSUB_D:
                   7955:         check_cop1x(ctx);
                   7956:         check_cp1_registers(ctx, fd | fs | ft | fr);
1.1.1.7   root     7957:         {
                   7958:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7959:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7960:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   7961: 
                   7962:             gen_load_fpr64(ctx, fp0, fs);
                   7963:             gen_load_fpr64(ctx, fp1, ft);
                   7964:             gen_load_fpr64(ctx, fp2, fr);
                   7965:             gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
                   7966:             tcg_temp_free_i64(fp0);
                   7967:             tcg_temp_free_i64(fp1);
                   7968:             gen_store_fpr64(ctx, fp2, fd);
                   7969:             tcg_temp_free_i64(fp2);
                   7970:         }
1.1.1.6   root     7971:         opn = "nmsub.d";
1.1.1.4   root     7972:         break;
1.1.1.6   root     7973:     case OPC_NMSUB_PS:
                   7974:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7975:         {
                   7976:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7977:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7978:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   7979: 
                   7980:             gen_load_fpr64(ctx, fp0, fs);
                   7981:             gen_load_fpr64(ctx, fp1, ft);
                   7982:             gen_load_fpr64(ctx, fp2, fr);
                   7983:             gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
                   7984:             tcg_temp_free_i64(fp0);
                   7985:             tcg_temp_free_i64(fp1);
                   7986:             gen_store_fpr64(ctx, fp2, fd);
                   7987:             tcg_temp_free_i64(fp2);
                   7988:         }
1.1.1.6   root     7989:         opn = "nmsub.ps";
1.1.1.4   root     7990:         break;
1.1.1.6   root     7991:     default:
                   7992:         MIPS_INVAL(opn);
                   7993:         generate_exception (ctx, EXCP_RI);
1.1.1.4   root     7994:         return;
                   7995:     }
1.1.1.6   root     7996:     MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
                   7997:                fregnames[fs], fregnames[ft]);
1.1       root     7998: }
                   7999: 
1.1.1.12! root     8000: static void
        !          8001: gen_rdhwr (CPUState *env, DisasContext *ctx, int rt, int rd)
        !          8002: {
        !          8003:     TCGv t0;
1.1       root     8004: 
1.1.1.12! root     8005:     check_insn(env, ctx, ISA_MIPS32R2);
        !          8006:     t0 = tcg_temp_new();
1.1       root     8007: 
1.1.1.12! root     8008:     switch (rd) {
        !          8009:     case 0:
        !          8010:         save_cpu_state(ctx, 1);
        !          8011:         gen_helper_rdhwr_cpunum(t0);
        !          8012:         gen_store_gpr(t0, rt);
        !          8013:         break;
        !          8014:     case 1:
        !          8015:         save_cpu_state(ctx, 1);
        !          8016:         gen_helper_rdhwr_synci_step(t0);
        !          8017:         gen_store_gpr(t0, rt);
        !          8018:         break;
        !          8019:     case 2:
        !          8020:         save_cpu_state(ctx, 1);
        !          8021:         gen_helper_rdhwr_cc(t0);
        !          8022:         gen_store_gpr(t0, rt);
        !          8023:         break;
        !          8024:     case 3:
        !          8025:         save_cpu_state(ctx, 1);
        !          8026:         gen_helper_rdhwr_ccres(t0);
        !          8027:         gen_store_gpr(t0, rt);
        !          8028:         break;
        !          8029:     case 29:
        !          8030: #if defined(CONFIG_USER_ONLY)
        !          8031:         tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
        !          8032:         gen_store_gpr(t0, rt);
        !          8033:         break;
        !          8034: #else
        !          8035:         /* XXX: Some CPUs implement this in hardware.
        !          8036:            Not supported yet. */
1.1       root     8037: #endif
1.1.1.12! root     8038:     default:            /* Invalid */
        !          8039:         MIPS_INVAL("rdhwr");
        !          8040:         generate_exception(ctx, EXCP_RI);
        !          8041:         break;
1.1.1.4   root     8042:     }
1.1.1.12! root     8043:     tcg_temp_free(t0);
        !          8044: }
1.1.1.4   root     8045: 
1.1.1.12! root     8046: static void handle_delay_slot (CPUState *env, DisasContext *ctx,
        !          8047:                                int insn_bytes)
        !          8048: {
        !          8049:     if (ctx->hflags & MIPS_HFLAG_BMASK) {
        !          8050:         int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
        !          8051:         /* Branches completion */
        !          8052:         ctx->hflags &= ~MIPS_HFLAG_BMASK;
        !          8053:         ctx->bstate = BS_BRANCH;
        !          8054:         save_cpu_state(ctx, 0);
        !          8055:         /* FIXME: Need to clear can_do_io.  */
        !          8056:         switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
        !          8057:         case MIPS_HFLAG_B:
        !          8058:             /* unconditional branch */
        !          8059:             MIPS_DEBUG("unconditional branch");
        !          8060:             if (proc_hflags & MIPS_HFLAG_BX) {
        !          8061:                 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
        !          8062:             }
        !          8063:             gen_goto_tb(ctx, 0, ctx->btarget);
        !          8064:             break;
        !          8065:         case MIPS_HFLAG_BL:
        !          8066:             /* blikely taken case */
        !          8067:             MIPS_DEBUG("blikely branch taken");
        !          8068:             gen_goto_tb(ctx, 0, ctx->btarget);
        !          8069:             break;
        !          8070:         case MIPS_HFLAG_BC:
        !          8071:             /* Conditional branch */
        !          8072:             MIPS_DEBUG("conditional branch");
        !          8073:             {
        !          8074:                 int l1 = gen_new_label();
1.1.1.7   root     8075: 
1.1.1.12! root     8076:                 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
        !          8077:                 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
        !          8078:                 gen_set_label(l1);
        !          8079:                 gen_goto_tb(ctx, 0, ctx->btarget);
        !          8080:             }
        !          8081:             break;
        !          8082:         case MIPS_HFLAG_BR:
        !          8083:             /* unconditional branch to register */
        !          8084:             MIPS_DEBUG("branch to register");
        !          8085:             if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
        !          8086:                 TCGv t0 = tcg_temp_new();
        !          8087:                 TCGv_i32 t1 = tcg_temp_new_i32();
        !          8088: 
        !          8089:                 tcg_gen_andi_tl(t0, btarget, 0x1);
        !          8090:                 tcg_gen_trunc_tl_i32(t1, t0);
        !          8091:                 tcg_temp_free(t0);
        !          8092:                 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
        !          8093:                 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
        !          8094:                 tcg_gen_or_i32(hflags, hflags, t1);
        !          8095:                 tcg_temp_free_i32(t1);
        !          8096: 
        !          8097:                 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
        !          8098:             } else {
        !          8099:                 tcg_gen_mov_tl(cpu_PC, btarget);
        !          8100:             }
        !          8101:             if (ctx->singlestep_enabled) {
        !          8102:                 save_cpu_state(ctx, 0);
        !          8103:                 gen_helper_0i(raise_exception, EXCP_DEBUG);
        !          8104:             }
        !          8105:             tcg_gen_exit_tb(0);
        !          8106:             break;
        !          8107:         default:
        !          8108:             MIPS_DEBUG("unknown branch");
        !          8109:             break;
        !          8110:         }
        !          8111:     }
        !          8112: }
        !          8113: 
        !          8114: /* ISA extensions (ASEs) */
        !          8115: /* MIPS16 extension to MIPS32 */
        !          8116: 
        !          8117: /* MIPS16 major opcodes */
        !          8118: enum {
        !          8119:   M16_OPC_ADDIUSP = 0x00,
        !          8120:   M16_OPC_ADDIUPC = 0x01,
        !          8121:   M16_OPC_B = 0x02,
        !          8122:   M16_OPC_JAL = 0x03,
        !          8123:   M16_OPC_BEQZ = 0x04,
        !          8124:   M16_OPC_BNEQZ = 0x05,
        !          8125:   M16_OPC_SHIFT = 0x06,
        !          8126:   M16_OPC_LD = 0x07,
        !          8127:   M16_OPC_RRIA = 0x08,
        !          8128:   M16_OPC_ADDIU8 = 0x09,
        !          8129:   M16_OPC_SLTI = 0x0a,
        !          8130:   M16_OPC_SLTIU = 0x0b,
        !          8131:   M16_OPC_I8 = 0x0c,
        !          8132:   M16_OPC_LI = 0x0d,
        !          8133:   M16_OPC_CMPI = 0x0e,
        !          8134:   M16_OPC_SD = 0x0f,
        !          8135:   M16_OPC_LB = 0x10,
        !          8136:   M16_OPC_LH = 0x11,
        !          8137:   M16_OPC_LWSP = 0x12,
        !          8138:   M16_OPC_LW = 0x13,
        !          8139:   M16_OPC_LBU = 0x14,
        !          8140:   M16_OPC_LHU = 0x15,
        !          8141:   M16_OPC_LWPC = 0x16,
        !          8142:   M16_OPC_LWU = 0x17,
        !          8143:   M16_OPC_SB = 0x18,
        !          8144:   M16_OPC_SH = 0x19,
        !          8145:   M16_OPC_SWSP = 0x1a,
        !          8146:   M16_OPC_SW = 0x1b,
        !          8147:   M16_OPC_RRR = 0x1c,
        !          8148:   M16_OPC_RR = 0x1d,
        !          8149:   M16_OPC_EXTEND = 0x1e,
        !          8150:   M16_OPC_I64 = 0x1f
        !          8151: };
        !          8152: 
        !          8153: /* I8 funct field */
        !          8154: enum {
        !          8155:   I8_BTEQZ = 0x0,
        !          8156:   I8_BTNEZ = 0x1,
        !          8157:   I8_SWRASP = 0x2,
        !          8158:   I8_ADJSP = 0x3,
        !          8159:   I8_SVRS = 0x4,
        !          8160:   I8_MOV32R = 0x5,
        !          8161:   I8_MOVR32 = 0x7
        !          8162: };
        !          8163: 
        !          8164: /* RRR f field */
        !          8165: enum {
        !          8166:   RRR_DADDU = 0x0,
        !          8167:   RRR_ADDU = 0x1,
        !          8168:   RRR_DSUBU = 0x2,
        !          8169:   RRR_SUBU = 0x3
        !          8170: };
        !          8171: 
        !          8172: /* RR funct field */
        !          8173: enum {
        !          8174:   RR_JR = 0x00,
        !          8175:   RR_SDBBP = 0x01,
        !          8176:   RR_SLT = 0x02,
        !          8177:   RR_SLTU = 0x03,
        !          8178:   RR_SLLV = 0x04,
        !          8179:   RR_BREAK = 0x05,
        !          8180:   RR_SRLV = 0x06,
        !          8181:   RR_SRAV = 0x07,
        !          8182:   RR_DSRL = 0x08,
        !          8183:   RR_CMP = 0x0a,
        !          8184:   RR_NEG = 0x0b,
        !          8185:   RR_AND = 0x0c,
        !          8186:   RR_OR = 0x0d,
        !          8187:   RR_XOR = 0x0e,
        !          8188:   RR_NOT = 0x0f,
        !          8189:   RR_MFHI = 0x10,
        !          8190:   RR_CNVT = 0x11,
        !          8191:   RR_MFLO = 0x12,
        !          8192:   RR_DSRA = 0x13,
        !          8193:   RR_DSLLV = 0x14,
        !          8194:   RR_DSRLV = 0x16,
        !          8195:   RR_DSRAV = 0x17,
        !          8196:   RR_MULT = 0x18,
        !          8197:   RR_MULTU = 0x19,
        !          8198:   RR_DIV = 0x1a,
        !          8199:   RR_DIVU = 0x1b,
        !          8200:   RR_DMULT = 0x1c,
        !          8201:   RR_DMULTU = 0x1d,
        !          8202:   RR_DDIV = 0x1e,
        !          8203:   RR_DDIVU = 0x1f
        !          8204: };
        !          8205: 
        !          8206: /* I64 funct field */
        !          8207: enum {
        !          8208:   I64_LDSP = 0x0,
        !          8209:   I64_SDSP = 0x1,
        !          8210:   I64_SDRASP = 0x2,
        !          8211:   I64_DADJSP = 0x3,
        !          8212:   I64_LDPC = 0x4,
        !          8213:   I64_DADDIU5 = 0x5,
        !          8214:   I64_DADDIUPC = 0x6,
        !          8215:   I64_DADDIUSP = 0x7
        !          8216: };
        !          8217: 
        !          8218: /* RR ry field for CNVT */
        !          8219: enum {
        !          8220:   RR_RY_CNVT_ZEB = 0x0,
        !          8221:   RR_RY_CNVT_ZEH = 0x1,
        !          8222:   RR_RY_CNVT_ZEW = 0x2,
        !          8223:   RR_RY_CNVT_SEB = 0x4,
        !          8224:   RR_RY_CNVT_SEH = 0x5,
        !          8225:   RR_RY_CNVT_SEW = 0x6,
        !          8226: };
        !          8227: 
        !          8228: static int xlat (int r)
        !          8229: {
        !          8230:   static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
        !          8231: 
        !          8232:   return map[r];
        !          8233: }
        !          8234: 
        !          8235: static void gen_mips16_save (DisasContext *ctx,
        !          8236:                              int xsregs, int aregs,
        !          8237:                              int do_ra, int do_s0, int do_s1,
        !          8238:                              int framesize)
        !          8239: {
        !          8240:     TCGv t0 = tcg_temp_new();
        !          8241:     TCGv t1 = tcg_temp_new();
        !          8242:     int args, astatic;
        !          8243: 
        !          8244:     switch (aregs) {
        !          8245:     case 0:
        !          8246:     case 1:
        !          8247:     case 2:
        !          8248:     case 3:
        !          8249:     case 11:
        !          8250:         args = 0;
        !          8251:         break;
        !          8252:     case 4:
        !          8253:     case 5:
        !          8254:     case 6:
        !          8255:     case 7:
        !          8256:         args = 1;
        !          8257:         break;
        !          8258:     case 8:
        !          8259:     case 9:
        !          8260:     case 10:
        !          8261:         args = 2;
        !          8262:         break;
        !          8263:     case 12:
        !          8264:     case 13:
        !          8265:         args = 3;
        !          8266:         break;
        !          8267:     case 14:
        !          8268:         args = 4;
        !          8269:         break;
        !          8270:     default:
        !          8271:         generate_exception(ctx, EXCP_RI);
        !          8272:         return;
        !          8273:     }
        !          8274: 
        !          8275:     switch (args) {
        !          8276:     case 4:
        !          8277:         gen_base_offset_addr(ctx, t0, 29, 12);
        !          8278:         gen_load_gpr(t1, 7);
        !          8279:         op_st_sw(t1, t0, ctx);
        !          8280:         /* Fall through */
        !          8281:     case 3:
        !          8282:         gen_base_offset_addr(ctx, t0, 29, 8);
        !          8283:         gen_load_gpr(t1, 6);
        !          8284:         op_st_sw(t1, t0, ctx);
        !          8285:         /* Fall through */
        !          8286:     case 2:
        !          8287:         gen_base_offset_addr(ctx, t0, 29, 4);
        !          8288:         gen_load_gpr(t1, 5);
        !          8289:         op_st_sw(t1, t0, ctx);
        !          8290:         /* Fall through */
        !          8291:     case 1:
        !          8292:         gen_base_offset_addr(ctx, t0, 29, 0);
        !          8293:         gen_load_gpr(t1, 4);
        !          8294:         op_st_sw(t1, t0, ctx);
        !          8295:     }
        !          8296: 
        !          8297:     gen_load_gpr(t0, 29);
        !          8298: 
        !          8299: #define DECR_AND_STORE(reg) do {                \
        !          8300:         tcg_gen_subi_tl(t0, t0, 4);             \
        !          8301:         gen_load_gpr(t1, reg);                  \
        !          8302:         op_st_sw(t1, t0, ctx);                  \
        !          8303:     } while (0)
        !          8304: 
        !          8305:     if (do_ra) {
        !          8306:         DECR_AND_STORE(31);
        !          8307:     }
        !          8308: 
        !          8309:     switch (xsregs) {
        !          8310:     case 7:
        !          8311:         DECR_AND_STORE(30);
        !          8312:         /* Fall through */
        !          8313:     case 6:
        !          8314:         DECR_AND_STORE(23);
        !          8315:         /* Fall through */
        !          8316:     case 5:
        !          8317:         DECR_AND_STORE(22);
        !          8318:         /* Fall through */
        !          8319:     case 4:
        !          8320:         DECR_AND_STORE(21);
        !          8321:         /* Fall through */
        !          8322:     case 3:
        !          8323:         DECR_AND_STORE(20);
        !          8324:         /* Fall through */
        !          8325:     case 2:
        !          8326:         DECR_AND_STORE(19);
        !          8327:         /* Fall through */
        !          8328:     case 1:
        !          8329:         DECR_AND_STORE(18);
        !          8330:     }
        !          8331: 
        !          8332:     if (do_s1) {
        !          8333:         DECR_AND_STORE(17);
        !          8334:     }
        !          8335:     if (do_s0) {
        !          8336:         DECR_AND_STORE(16);
        !          8337:     }
        !          8338: 
        !          8339:     switch (aregs) {
        !          8340:     case 0:
        !          8341:     case 4:
        !          8342:     case 8:
        !          8343:     case 12:
        !          8344:     case 14:
        !          8345:         astatic = 0;
        !          8346:         break;
        !          8347:     case 1:
        !          8348:     case 5:
        !          8349:     case 9:
        !          8350:     case 13:
        !          8351:         astatic = 1;
        !          8352:         break;
        !          8353:     case 2:
        !          8354:     case 6:
        !          8355:     case 10:
        !          8356:         astatic = 2;
        !          8357:         break;
        !          8358:     case 3:
        !          8359:     case 7:
        !          8360:         astatic = 3;
        !          8361:         break;
        !          8362:     case 11:
        !          8363:         astatic = 4;
        !          8364:         break;
        !          8365:     default:
        !          8366:         generate_exception(ctx, EXCP_RI);
        !          8367:         return;
        !          8368:     }
        !          8369: 
        !          8370:     if (astatic > 0) {
        !          8371:         DECR_AND_STORE(7);
        !          8372:         if (astatic > 1) {
        !          8373:             DECR_AND_STORE(6);
        !          8374:             if (astatic > 2) {
        !          8375:                 DECR_AND_STORE(5);
        !          8376:                 if (astatic > 3) {
        !          8377:                     DECR_AND_STORE(4);
        !          8378:                 }
        !          8379:             }
        !          8380:         }
        !          8381:     }
        !          8382: #undef DECR_AND_STORE
        !          8383: 
        !          8384:     tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
        !          8385:     tcg_temp_free(t0);
        !          8386:     tcg_temp_free(t1);
        !          8387: }
        !          8388: 
        !          8389: static void gen_mips16_restore (DisasContext *ctx,
        !          8390:                                 int xsregs, int aregs,
        !          8391:                                 int do_ra, int do_s0, int do_s1,
        !          8392:                                 int framesize)
        !          8393: {
        !          8394:     int astatic;
        !          8395:     TCGv t0 = tcg_temp_new();
        !          8396:     TCGv t1 = tcg_temp_new();
        !          8397: 
        !          8398:     tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
        !          8399: 
        !          8400: #define DECR_AND_LOAD(reg) do {                 \
        !          8401:         tcg_gen_subi_tl(t0, t0, 4);             \
        !          8402:         op_ld_lw(t1, t0, ctx);                  \
        !          8403:         gen_store_gpr(t1, reg);                 \
        !          8404:     } while (0)
        !          8405: 
        !          8406:     if (do_ra) {
        !          8407:         DECR_AND_LOAD(31);
        !          8408:     }
        !          8409: 
        !          8410:     switch (xsregs) {
        !          8411:     case 7:
        !          8412:         DECR_AND_LOAD(30);
        !          8413:         /* Fall through */
        !          8414:     case 6:
        !          8415:         DECR_AND_LOAD(23);
        !          8416:         /* Fall through */
        !          8417:     case 5:
        !          8418:         DECR_AND_LOAD(22);
        !          8419:         /* Fall through */
        !          8420:     case 4:
        !          8421:         DECR_AND_LOAD(21);
        !          8422:         /* Fall through */
        !          8423:     case 3:
        !          8424:         DECR_AND_LOAD(20);
        !          8425:         /* Fall through */
        !          8426:     case 2:
        !          8427:         DECR_AND_LOAD(19);
        !          8428:         /* Fall through */
        !          8429:     case 1:
        !          8430:         DECR_AND_LOAD(18);
        !          8431:     }
        !          8432: 
        !          8433:     if (do_s1) {
        !          8434:         DECR_AND_LOAD(17);
        !          8435:     }
        !          8436:     if (do_s0) {
        !          8437:         DECR_AND_LOAD(16);
        !          8438:     }
        !          8439: 
        !          8440:     switch (aregs) {
        !          8441:     case 0:
        !          8442:     case 4:
        !          8443:     case 8:
        !          8444:     case 12:
        !          8445:     case 14:
        !          8446:         astatic = 0;
        !          8447:         break;
        !          8448:     case 1:
        !          8449:     case 5:
        !          8450:     case 9:
        !          8451:     case 13:
        !          8452:         astatic = 1;
        !          8453:         break;
        !          8454:     case 2:
        !          8455:     case 6:
        !          8456:     case 10:
        !          8457:         astatic = 2;
        !          8458:         break;
        !          8459:     case 3:
        !          8460:     case 7:
        !          8461:         astatic = 3;
        !          8462:         break;
        !          8463:     case 11:
        !          8464:         astatic = 4;
        !          8465:         break;
        !          8466:     default:
        !          8467:         generate_exception(ctx, EXCP_RI);
        !          8468:         return;
        !          8469:     }
        !          8470: 
        !          8471:     if (astatic > 0) {
        !          8472:         DECR_AND_LOAD(7);
        !          8473:         if (astatic > 1) {
        !          8474:             DECR_AND_LOAD(6);
        !          8475:             if (astatic > 2) {
        !          8476:                 DECR_AND_LOAD(5);
        !          8477:                 if (astatic > 3) {
        !          8478:                     DECR_AND_LOAD(4);
        !          8479:                 }
        !          8480:             }
        !          8481:         }
        !          8482:     }
        !          8483: #undef DECR_AND_LOAD
        !          8484: 
        !          8485:     tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
        !          8486:     tcg_temp_free(t0);
        !          8487:     tcg_temp_free(t1);
        !          8488: }
        !          8489: 
        !          8490: static void gen_addiupc (DisasContext *ctx, int rx, int imm,
        !          8491:                          int is_64_bit, int extended)
        !          8492: {
        !          8493:     TCGv t0;
        !          8494: 
        !          8495:     if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
        !          8496:         generate_exception(ctx, EXCP_RI);
        !          8497:         return;
        !          8498:     }
        !          8499: 
        !          8500:     t0 = tcg_temp_new();
        !          8501: 
        !          8502:     tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
        !          8503:     tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
        !          8504:     if (!is_64_bit) {
        !          8505:         tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
        !          8506:     }
        !          8507: 
        !          8508:     tcg_temp_free(t0);
        !          8509: }
        !          8510: 
        !          8511: #if defined(TARGET_MIPS64)
        !          8512: static void decode_i64_mips16 (CPUState *env, DisasContext *ctx,
        !          8513:                                int ry, int funct, int16_t offset,
        !          8514:                                int extended)
        !          8515: {
        !          8516:     switch (funct) {
        !          8517:     case I64_LDSP:
        !          8518:         check_mips_64(ctx);
        !          8519:         offset = extended ? offset : offset << 3;
        !          8520:         gen_ld(env, ctx, OPC_LD, ry, 29, offset);
        !          8521:         break;
        !          8522:     case I64_SDSP:
        !          8523:         check_mips_64(ctx);
        !          8524:         offset = extended ? offset : offset << 3;
        !          8525:         gen_st(ctx, OPC_SD, ry, 29, offset);
        !          8526:         break;
        !          8527:     case I64_SDRASP:
        !          8528:         check_mips_64(ctx);
        !          8529:         offset = extended ? offset : (ctx->opcode & 0xff) << 3;
        !          8530:         gen_st(ctx, OPC_SD, 31, 29, offset);
        !          8531:         break;
        !          8532:     case I64_DADJSP:
        !          8533:         check_mips_64(ctx);
        !          8534:         offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
        !          8535:         gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
        !          8536:         break;
        !          8537:     case I64_LDPC:
        !          8538:         if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
        !          8539:             generate_exception(ctx, EXCP_RI);
        !          8540:         } else {
        !          8541:             offset = extended ? offset : offset << 3;
        !          8542:             gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
        !          8543:         }
        !          8544:         break;
        !          8545:     case I64_DADDIU5:
        !          8546:         check_mips_64(ctx);
        !          8547:         offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
        !          8548:         gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
        !          8549:         break;
        !          8550:     case I64_DADDIUPC:
        !          8551:         check_mips_64(ctx);
        !          8552:         offset = extended ? offset : offset << 2;
        !          8553:         gen_addiupc(ctx, ry, offset, 1, extended);
        !          8554:         break;
        !          8555:     case I64_DADDIUSP:
        !          8556:         check_mips_64(ctx);
        !          8557:         offset = extended ? offset : offset << 2;
        !          8558:         gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
        !          8559:         break;
        !          8560:     }
        !          8561: }
        !          8562: #endif
        !          8563: 
        !          8564: static int decode_extended_mips16_opc (CPUState *env, DisasContext *ctx,
        !          8565:                                        int *is_branch)
        !          8566: {
        !          8567:     int extend = lduw_code(ctx->pc + 2);
        !          8568:     int op, rx, ry, funct, sa;
        !          8569:     int16_t imm, offset;
        !          8570: 
        !          8571:     ctx->opcode = (ctx->opcode << 16) | extend;
        !          8572:     op = (ctx->opcode >> 11) & 0x1f;
        !          8573:     sa = (ctx->opcode >> 22) & 0x1f;
        !          8574:     funct = (ctx->opcode >> 8) & 0x7;
        !          8575:     rx = xlat((ctx->opcode >> 8) & 0x7);
        !          8576:     ry = xlat((ctx->opcode >> 5) & 0x7);
        !          8577:     offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
        !          8578:                               | ((ctx->opcode >> 21) & 0x3f) << 5
        !          8579:                               | (ctx->opcode & 0x1f));
        !          8580: 
        !          8581:     /* The extended opcodes cleverly reuse the opcodes from their 16-bit
        !          8582:        counterparts.  */
        !          8583:     switch (op) {
        !          8584:     case M16_OPC_ADDIUSP:
        !          8585:         gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
        !          8586:         break;
        !          8587:     case M16_OPC_ADDIUPC:
        !          8588:         gen_addiupc(ctx, rx, imm, 0, 1);
        !          8589:         break;
        !          8590:     case M16_OPC_B:
        !          8591:         gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
        !          8592:         /* No delay slot, so just process as a normal instruction */
        !          8593:         break;
        !          8594:     case M16_OPC_BEQZ:
        !          8595:         gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
        !          8596:         /* No delay slot, so just process as a normal instruction */
        !          8597:         break;
        !          8598:     case M16_OPC_BNEQZ:
        !          8599:         gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
        !          8600:         /* No delay slot, so just process as a normal instruction */
        !          8601:         break;
        !          8602:     case M16_OPC_SHIFT:
        !          8603:         switch (ctx->opcode & 0x3) {
        !          8604:         case 0x0:
        !          8605:             gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
        !          8606:             break;
        !          8607:         case 0x1:
        !          8608: #if defined(TARGET_MIPS64)
        !          8609:             check_mips_64(ctx);
        !          8610:             gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
        !          8611: #else
        !          8612:             generate_exception(ctx, EXCP_RI);
        !          8613: #endif
        !          8614:             break;
        !          8615:         case 0x2:
        !          8616:             gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
        !          8617:             break;
        !          8618:         case 0x3:
        !          8619:             gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
        !          8620:             break;
        !          8621:         }
        !          8622:         break;
        !          8623: #if defined(TARGET_MIPS64)
        !          8624:     case M16_OPC_LD:
        !          8625:             check_mips_64(ctx);
        !          8626:         gen_ld(env, ctx, OPC_LD, ry, rx, offset);
        !          8627:         break;
        !          8628: #endif
        !          8629:     case M16_OPC_RRIA:
        !          8630:         imm = ctx->opcode & 0xf;
        !          8631:         imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
        !          8632:         imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
        !          8633:         imm = (int16_t) (imm << 1) >> 1;
        !          8634:         if ((ctx->opcode >> 4) & 0x1) {
        !          8635: #if defined(TARGET_MIPS64)
        !          8636:             check_mips_64(ctx);
        !          8637:             gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
        !          8638: #else
        !          8639:             generate_exception(ctx, EXCP_RI);
        !          8640: #endif
        !          8641:         } else {
        !          8642:             gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
        !          8643:         }
        !          8644:         break;
        !          8645:     case M16_OPC_ADDIU8:
        !          8646:         gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
        !          8647:         break;
        !          8648:     case M16_OPC_SLTI:
        !          8649:         gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
        !          8650:         break;
        !          8651:     case M16_OPC_SLTIU:
        !          8652:         gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
        !          8653:         break;
        !          8654:     case M16_OPC_I8:
        !          8655:         switch (funct) {
        !          8656:         case I8_BTEQZ:
        !          8657:             gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
        !          8658:             break;
        !          8659:         case I8_BTNEZ:
        !          8660:             gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
        !          8661:             break;
        !          8662:         case I8_SWRASP:
        !          8663:             gen_st(ctx, OPC_SW, 31, 29, imm);
        !          8664:             break;
        !          8665:         case I8_ADJSP:
        !          8666:             gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
        !          8667:             break;
        !          8668:         case I8_SVRS:
        !          8669:             {
        !          8670:                 int xsregs = (ctx->opcode >> 24) & 0x7;
        !          8671:                 int aregs = (ctx->opcode >> 16) & 0xf;
        !          8672:                 int do_ra = (ctx->opcode >> 6) & 0x1;
        !          8673:                 int do_s0 = (ctx->opcode >> 5) & 0x1;
        !          8674:                 int do_s1 = (ctx->opcode >> 4) & 0x1;
        !          8675:                 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
        !          8676:                                  | (ctx->opcode & 0xf)) << 3;
        !          8677: 
        !          8678:                 if (ctx->opcode & (1 << 7)) {
        !          8679:                     gen_mips16_save(ctx, xsregs, aregs,
        !          8680:                                     do_ra, do_s0, do_s1,
        !          8681:                                     framesize);
        !          8682:                 } else {
        !          8683:                     gen_mips16_restore(ctx, xsregs, aregs,
        !          8684:                                        do_ra, do_s0, do_s1,
        !          8685:                                        framesize);
        !          8686:                 }
        !          8687:             }
        !          8688:             break;
        !          8689:         default:
        !          8690:             generate_exception(ctx, EXCP_RI);
        !          8691:             break;
        !          8692:         }
        !          8693:         break;
        !          8694:     case M16_OPC_LI:
        !          8695:         tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
        !          8696:         break;
        !          8697:     case M16_OPC_CMPI:
        !          8698:         tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
        !          8699:         break;
        !          8700: #if defined(TARGET_MIPS64)
        !          8701:     case M16_OPC_SD:
        !          8702:         gen_st(ctx, OPC_SD, ry, rx, offset);
        !          8703:         break;
        !          8704: #endif
        !          8705:     case M16_OPC_LB:
        !          8706:         gen_ld(env, ctx, OPC_LB, ry, rx, offset);
        !          8707:         break;
        !          8708:     case M16_OPC_LH:
        !          8709:         gen_ld(env, ctx, OPC_LH, ry, rx, offset);
        !          8710:         break;
        !          8711:     case M16_OPC_LWSP:
        !          8712:         gen_ld(env, ctx, OPC_LW, rx, 29, offset);
        !          8713:         break;
        !          8714:     case M16_OPC_LW:
        !          8715:         gen_ld(env, ctx, OPC_LW, ry, rx, offset);
        !          8716:         break;
        !          8717:     case M16_OPC_LBU:
        !          8718:         gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
        !          8719:         break;
        !          8720:     case M16_OPC_LHU:
        !          8721:         gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
        !          8722:         break;
        !          8723:     case M16_OPC_LWPC:
        !          8724:         gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
        !          8725:         break;
        !          8726: #if defined(TARGET_MIPS64)
        !          8727:     case M16_OPC_LWU:
        !          8728:         gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
        !          8729:         break;
        !          8730: #endif
        !          8731:     case M16_OPC_SB:
        !          8732:         gen_st(ctx, OPC_SB, ry, rx, offset);
        !          8733:         break;
        !          8734:     case M16_OPC_SH:
        !          8735:         gen_st(ctx, OPC_SH, ry, rx, offset);
        !          8736:         break;
        !          8737:     case M16_OPC_SWSP:
        !          8738:         gen_st(ctx, OPC_SW, rx, 29, offset);
        !          8739:         break;
        !          8740:     case M16_OPC_SW:
        !          8741:         gen_st(ctx, OPC_SW, ry, rx, offset);
        !          8742:         break;
        !          8743: #if defined(TARGET_MIPS64)
        !          8744:     case M16_OPC_I64:
        !          8745:         decode_i64_mips16(env, ctx, ry, funct, offset, 1);
        !          8746:         break;
        !          8747: #endif
        !          8748:     default:
        !          8749:         generate_exception(ctx, EXCP_RI);
        !          8750:         break;
        !          8751:     }
        !          8752: 
        !          8753:     return 4;
        !          8754: }
        !          8755: 
        !          8756: static int decode_mips16_opc (CPUState *env, DisasContext *ctx,
        !          8757:                               int *is_branch)
        !          8758: {
        !          8759:     int rx, ry;
        !          8760:     int sa;
        !          8761:     int op, cnvt_op, op1, offset;
        !          8762:     int funct;
        !          8763:     int n_bytes;
        !          8764: 
        !          8765:     op = (ctx->opcode >> 11) & 0x1f;
        !          8766:     sa = (ctx->opcode >> 2) & 0x7;
        !          8767:     sa = sa == 0 ? 8 : sa;
        !          8768:     rx = xlat((ctx->opcode >> 8) & 0x7);
        !          8769:     cnvt_op = (ctx->opcode >> 5) & 0x7;
        !          8770:     ry = xlat((ctx->opcode >> 5) & 0x7);
        !          8771:     op1 = offset = ctx->opcode & 0x1f;
        !          8772: 
        !          8773:     n_bytes = 2;
        !          8774: 
        !          8775:     switch (op) {
        !          8776:     case M16_OPC_ADDIUSP:
        !          8777:         {
        !          8778:             int16_t imm = ((uint8_t) ctx->opcode) << 2;
        !          8779: 
        !          8780:             gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
        !          8781:         }
        !          8782:         break;
        !          8783:     case M16_OPC_ADDIUPC:
        !          8784:         gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
        !          8785:         break;
        !          8786:     case M16_OPC_B:
        !          8787:         offset = (ctx->opcode & 0x7ff) << 1;
        !          8788:         offset = (int16_t)(offset << 4) >> 4;
        !          8789:         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
        !          8790:         /* No delay slot, so just process as a normal instruction */
        !          8791:         break;
        !          8792:     case M16_OPC_JAL:
        !          8793:         offset = lduw_code(ctx->pc + 2);
        !          8794:         offset = (((ctx->opcode & 0x1f) << 21)
        !          8795:                   | ((ctx->opcode >> 5) & 0x1f) << 16
        !          8796:                   | offset) << 2;
        !          8797:         op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
        !          8798:         gen_compute_branch(ctx, op, 4, rx, ry, offset);
        !          8799:         n_bytes = 4;
        !          8800:         *is_branch = 1;
        !          8801:         break;
        !          8802:     case M16_OPC_BEQZ:
        !          8803:         gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
        !          8804:         /* No delay slot, so just process as a normal instruction */
        !          8805:         break;
        !          8806:     case M16_OPC_BNEQZ:
        !          8807:         gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
        !          8808:         /* No delay slot, so just process as a normal instruction */
        !          8809:         break;
        !          8810:     case M16_OPC_SHIFT:
        !          8811:         switch (ctx->opcode & 0x3) {
        !          8812:         case 0x0:
        !          8813:             gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
        !          8814:             break;
        !          8815:         case 0x1:
        !          8816: #if defined(TARGET_MIPS64)
        !          8817:             check_mips_64(ctx);
        !          8818:             gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
        !          8819: #else
        !          8820:             generate_exception(ctx, EXCP_RI);
        !          8821: #endif
        !          8822:             break;
        !          8823:         case 0x2:
        !          8824:             gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
        !          8825:             break;
        !          8826:         case 0x3:
        !          8827:             gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
        !          8828:             break;
        !          8829:         }
        !          8830:         break;
        !          8831: #if defined(TARGET_MIPS64)
        !          8832:     case M16_OPC_LD:
        !          8833:         check_mips_64(ctx);
        !          8834:         gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
        !          8835:         break;
        !          8836: #endif
        !          8837:     case M16_OPC_RRIA:
        !          8838:         {
        !          8839:             int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
        !          8840: 
        !          8841:             if ((ctx->opcode >> 4) & 1) {
        !          8842: #if defined(TARGET_MIPS64)
        !          8843:                 check_mips_64(ctx);
        !          8844:                 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
        !          8845: #else
        !          8846:                 generate_exception(ctx, EXCP_RI);
        !          8847: #endif
        !          8848:             } else {
        !          8849:                 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
        !          8850:             }
        !          8851:         }
        !          8852:         break;
        !          8853:     case M16_OPC_ADDIU8:
        !          8854:         {
        !          8855:             int16_t imm = (int8_t) ctx->opcode;
        !          8856: 
        !          8857:             gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
        !          8858:         }
        !          8859:         break;
        !          8860:     case M16_OPC_SLTI:
        !          8861:         {
        !          8862:             int16_t imm = (uint8_t) ctx->opcode;
        !          8863: 
        !          8864:             gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
        !          8865:         }
        !          8866:         break;
        !          8867:     case M16_OPC_SLTIU:
        !          8868:         {
        !          8869:             int16_t imm = (uint8_t) ctx->opcode;
        !          8870: 
        !          8871:             gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
        !          8872:         }
        !          8873:         break;
        !          8874:     case M16_OPC_I8:
        !          8875:         {
        !          8876:             int reg32;
        !          8877: 
        !          8878:             funct = (ctx->opcode >> 8) & 0x7;
        !          8879:             switch (funct) {
        !          8880:             case I8_BTEQZ:
        !          8881:                 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
        !          8882:                                    ((int8_t)ctx->opcode) << 1);
        !          8883:                 break;
        !          8884:             case I8_BTNEZ:
        !          8885:                 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
        !          8886:                                    ((int8_t)ctx->opcode) << 1);
        !          8887:                 break;
        !          8888:             case I8_SWRASP:
        !          8889:                 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
        !          8890:                 break;
        !          8891:             case I8_ADJSP:
        !          8892:                 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
        !          8893:                               ((int8_t)ctx->opcode) << 3);
        !          8894:                 break;
        !          8895:             case I8_SVRS:
        !          8896:                 {
        !          8897:                     int do_ra = ctx->opcode & (1 << 6);
        !          8898:                     int do_s0 = ctx->opcode & (1 << 5);
        !          8899:                     int do_s1 = ctx->opcode & (1 << 4);
        !          8900:                     int framesize = ctx->opcode & 0xf;
        !          8901: 
        !          8902:                     if (framesize == 0) {
        !          8903:                         framesize = 128;
        !          8904:                     } else {
        !          8905:                         framesize = framesize << 3;
        !          8906:                     }
        !          8907: 
        !          8908:                     if (ctx->opcode & (1 << 7)) {
        !          8909:                         gen_mips16_save(ctx, 0, 0,
        !          8910:                                         do_ra, do_s0, do_s1, framesize);
        !          8911:                     } else {
        !          8912:                         gen_mips16_restore(ctx, 0, 0,
        !          8913:                                            do_ra, do_s0, do_s1, framesize);
        !          8914:                     }
        !          8915:                 }
        !          8916:                 break;
        !          8917:             case I8_MOV32R:
        !          8918:                 {
        !          8919:                     int rz = xlat(ctx->opcode & 0x7);
        !          8920: 
        !          8921:                     reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
        !          8922:                         ((ctx->opcode >> 5) & 0x7);
        !          8923:                     gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
        !          8924:                 }
        !          8925:                 break;
        !          8926:             case I8_MOVR32:
        !          8927:                 reg32 = ctx->opcode & 0x1f;
        !          8928:                 gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
        !          8929:                 break;
        !          8930:             default:
        !          8931:                 generate_exception(ctx, EXCP_RI);
        !          8932:                 break;
        !          8933:             }
        !          8934:         }
        !          8935:         break;
        !          8936:     case M16_OPC_LI:
        !          8937:         {
        !          8938:             int16_t imm = (uint8_t) ctx->opcode;
        !          8939: 
        !          8940:             gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
        !          8941:         }
        !          8942:         break;
        !          8943:     case M16_OPC_CMPI:
        !          8944:         {
        !          8945:             int16_t imm = (uint8_t) ctx->opcode;
        !          8946: 
        !          8947:             gen_logic_imm(env, OPC_XORI, 24, rx, imm);
        !          8948:         }
        !          8949:         break;
        !          8950: #if defined(TARGET_MIPS64)
        !          8951:     case M16_OPC_SD:
        !          8952:         check_mips_64(ctx);
        !          8953:         gen_st(ctx, OPC_SD, ry, rx, offset << 3);
        !          8954:         break;
        !          8955: #endif
        !          8956:     case M16_OPC_LB:
        !          8957:         gen_ld(env, ctx, OPC_LB, ry, rx, offset);
        !          8958:         break;
        !          8959:     case M16_OPC_LH:
        !          8960:         gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
        !          8961:         break;
        !          8962:     case M16_OPC_LWSP:
        !          8963:         gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
        !          8964:         break;
        !          8965:     case M16_OPC_LW:
        !          8966:         gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
        !          8967:         break;
        !          8968:     case M16_OPC_LBU:
        !          8969:         gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
        !          8970:         break;
        !          8971:     case M16_OPC_LHU:
        !          8972:         gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
        !          8973:         break;
        !          8974:     case M16_OPC_LWPC:
        !          8975:         gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
        !          8976:         break;
        !          8977: #if defined (TARGET_MIPS64)
        !          8978:     case M16_OPC_LWU:
        !          8979:         check_mips_64(ctx);
        !          8980:         gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
        !          8981:         break;
        !          8982: #endif
        !          8983:     case M16_OPC_SB:
        !          8984:         gen_st(ctx, OPC_SB, ry, rx, offset);
        !          8985:         break;
        !          8986:     case M16_OPC_SH:
        !          8987:         gen_st(ctx, OPC_SH, ry, rx, offset << 1);
        !          8988:         break;
        !          8989:     case M16_OPC_SWSP:
        !          8990:         gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
        !          8991:         break;
        !          8992:     case M16_OPC_SW:
        !          8993:         gen_st(ctx, OPC_SW, ry, rx, offset << 2);
        !          8994:         break;
        !          8995:     case M16_OPC_RRR:
        !          8996:         {
        !          8997:             int rz = xlat((ctx->opcode >> 2) & 0x7);
        !          8998:             int mips32_op;
        !          8999: 
        !          9000:             switch (ctx->opcode & 0x3) {
        !          9001:             case RRR_ADDU:
        !          9002:                 mips32_op = OPC_ADDU;
        !          9003:                 break;
        !          9004:             case RRR_SUBU:
        !          9005:                 mips32_op = OPC_SUBU;
        !          9006:                 break;
        !          9007: #if defined(TARGET_MIPS64)
        !          9008:             case RRR_DADDU:
        !          9009:                 mips32_op = OPC_DADDU;
        !          9010:                 check_mips_64(ctx);
        !          9011:                 break;
        !          9012:             case RRR_DSUBU:
        !          9013:                 mips32_op = OPC_DSUBU;
        !          9014:                 check_mips_64(ctx);
        !          9015:                 break;
        !          9016: #endif
        !          9017:             default:
        !          9018:                 generate_exception(ctx, EXCP_RI);
        !          9019:                 goto done;
        !          9020:             }
        !          9021: 
        !          9022:             gen_arith(env, ctx, mips32_op, rz, rx, ry);
        !          9023:         done:
        !          9024:             ;
        !          9025:         }
        !          9026:         break;
        !          9027:     case M16_OPC_RR:
        !          9028:         switch (op1) {
        !          9029:         case RR_JR:
        !          9030:             {
        !          9031:                 int nd = (ctx->opcode >> 7) & 0x1;
        !          9032:                 int link = (ctx->opcode >> 6) & 0x1;
        !          9033:                 int ra = (ctx->opcode >> 5) & 0x1;
        !          9034: 
        !          9035:                 if (link) {
        !          9036:                     op = nd ? OPC_JALRC : OPC_JALRS;
        !          9037:                 } else {
        !          9038:                     op = OPC_JR;
        !          9039:                 }
        !          9040: 
        !          9041:                 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
        !          9042:                 if (!nd) {
        !          9043:                     *is_branch = 1;
        !          9044:                 }
        !          9045:             }
        !          9046:             break;
        !          9047:         case RR_SDBBP:
        !          9048:             /* XXX: not clear which exception should be raised
        !          9049:              *      when in debug mode...
        !          9050:              */
        !          9051:             check_insn(env, ctx, ISA_MIPS32);
        !          9052:             if (!(ctx->hflags & MIPS_HFLAG_DM)) {
        !          9053:                 generate_exception(ctx, EXCP_DBp);
        !          9054:             } else {
        !          9055:                 generate_exception(ctx, EXCP_DBp);
        !          9056:             }
        !          9057:             break;
        !          9058:         case RR_SLT:
        !          9059:             gen_slt(env, OPC_SLT, 24, rx, ry);
        !          9060:             break;
        !          9061:         case RR_SLTU:
        !          9062:             gen_slt(env, OPC_SLTU, 24, rx, ry);
        !          9063:             break;
        !          9064:         case RR_BREAK:
        !          9065:             generate_exception(ctx, EXCP_BREAK);
        !          9066:             break;
        !          9067:         case RR_SLLV:
        !          9068:             gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
        !          9069:             break;
        !          9070:         case RR_SRLV:
        !          9071:             gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
        !          9072:             break;
        !          9073:         case RR_SRAV:
        !          9074:             gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
        !          9075:             break;
        !          9076: #if defined (TARGET_MIPS64)
        !          9077:         case RR_DSRL:
        !          9078:             check_mips_64(ctx);
        !          9079:             gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
        !          9080:             break;
        !          9081: #endif
        !          9082:         case RR_CMP:
        !          9083:             gen_logic(env, OPC_XOR, 24, rx, ry);
        !          9084:             break;
        !          9085:         case RR_NEG:
        !          9086:             gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
        !          9087:             break;
        !          9088:         case RR_AND:
        !          9089:             gen_logic(env, OPC_AND, rx, rx, ry);
        !          9090:             break;
        !          9091:         case RR_OR:
        !          9092:             gen_logic(env, OPC_OR, rx, rx, ry);
        !          9093:             break;
        !          9094:         case RR_XOR:
        !          9095:             gen_logic(env, OPC_XOR, rx, rx, ry);
        !          9096:             break;
        !          9097:         case RR_NOT:
        !          9098:             gen_logic(env, OPC_NOR, rx, ry, 0);
        !          9099:             break;
        !          9100:         case RR_MFHI:
        !          9101:             gen_HILO(ctx, OPC_MFHI, rx);
        !          9102:             break;
        !          9103:         case RR_CNVT:
        !          9104:             switch (cnvt_op) {
        !          9105:             case RR_RY_CNVT_ZEB:
        !          9106:                 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
        !          9107:                 break;
        !          9108:             case RR_RY_CNVT_ZEH:
        !          9109:                 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
        !          9110:                 break;
        !          9111:             case RR_RY_CNVT_SEB:
        !          9112:                 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
        !          9113:                 break;
        !          9114:             case RR_RY_CNVT_SEH:
        !          9115:                 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
        !          9116:                 break;
        !          9117: #if defined (TARGET_MIPS64)
        !          9118:             case RR_RY_CNVT_ZEW:
        !          9119:                 check_mips_64(ctx);
        !          9120:                 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
        !          9121:                 break;
        !          9122:             case RR_RY_CNVT_SEW:
        !          9123:                 check_mips_64(ctx);
        !          9124:                 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
        !          9125:                 break;
        !          9126: #endif
        !          9127:             default:
        !          9128:                 generate_exception(ctx, EXCP_RI);
        !          9129:                 break;
        !          9130:             }
        !          9131:             break;
        !          9132:         case RR_MFLO:
        !          9133:             gen_HILO(ctx, OPC_MFLO, rx);
        !          9134:             break;
        !          9135: #if defined (TARGET_MIPS64)
        !          9136:         case RR_DSRA:
        !          9137:             check_mips_64(ctx);
        !          9138:             gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
        !          9139:             break;
        !          9140:         case RR_DSLLV:
        !          9141:             check_mips_64(ctx);
        !          9142:             gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
        !          9143:             break;
        !          9144:         case RR_DSRLV:
        !          9145:             check_mips_64(ctx);
        !          9146:             gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
        !          9147:             break;
        !          9148:         case RR_DSRAV:
        !          9149:             check_mips_64(ctx);
        !          9150:             gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
        !          9151:             break;
        !          9152: #endif
        !          9153:         case RR_MULT:
        !          9154:             gen_muldiv(ctx, OPC_MULT, rx, ry);
        !          9155:             break;
        !          9156:         case RR_MULTU:
        !          9157:             gen_muldiv(ctx, OPC_MULTU, rx, ry);
        !          9158:             break;
        !          9159:         case RR_DIV:
        !          9160:             gen_muldiv(ctx, OPC_DIV, rx, ry);
        !          9161:             break;
        !          9162:         case RR_DIVU:
        !          9163:             gen_muldiv(ctx, OPC_DIVU, rx, ry);
        !          9164:             break;
        !          9165: #if defined (TARGET_MIPS64)
        !          9166:         case RR_DMULT:
        !          9167:             check_mips_64(ctx);
        !          9168:             gen_muldiv(ctx, OPC_DMULT, rx, ry);
        !          9169:             break;
        !          9170:         case RR_DMULTU:
        !          9171:             check_mips_64(ctx);
        !          9172:             gen_muldiv(ctx, OPC_DMULTU, rx, ry);
        !          9173:             break;
        !          9174:         case RR_DDIV:
        !          9175:             check_mips_64(ctx);
        !          9176:             gen_muldiv(ctx, OPC_DDIV, rx, ry);
        !          9177:             break;
        !          9178:         case RR_DDIVU:
        !          9179:             check_mips_64(ctx);
        !          9180:             gen_muldiv(ctx, OPC_DDIVU, rx, ry);
        !          9181:             break;
        !          9182: #endif
        !          9183:         default:
        !          9184:             generate_exception(ctx, EXCP_RI);
        !          9185:             break;
        !          9186:         }
        !          9187:         break;
        !          9188:     case M16_OPC_EXTEND:
        !          9189:         decode_extended_mips16_opc(env, ctx, is_branch);
        !          9190:         n_bytes = 4;
        !          9191:         break;
        !          9192: #if defined(TARGET_MIPS64)
        !          9193:     case M16_OPC_I64:
        !          9194:         funct = (ctx->opcode >> 8) & 0x7;
        !          9195:         decode_i64_mips16(env, ctx, ry, funct, offset, 0);
        !          9196:         break;
        !          9197: #endif
        !          9198:     default:
        !          9199:         generate_exception(ctx, EXCP_RI);
        !          9200:         break;
        !          9201:     }
        !          9202: 
        !          9203:     return n_bytes;
        !          9204: }
        !          9205: 
        !          9206: /* microMIPS extension to MIPS32 */
        !          9207: 
        !          9208: /* microMIPS32 major opcodes */
        !          9209: 
        !          9210: enum {
        !          9211:     POOL32A = 0x00,
        !          9212:     POOL16A = 0x01,
        !          9213:     LBU16 = 0x02,
        !          9214:     MOVE16 = 0x03,
        !          9215:     ADDI32 = 0x04,
        !          9216:     LBU32 = 0x05,
        !          9217:     SB32 = 0x06,
        !          9218:     LB32 = 0x07,
        !          9219: 
        !          9220:     POOL32B = 0x08,
        !          9221:     POOL16B = 0x09,
        !          9222:     LHU16 = 0x0a,
        !          9223:     ANDI16 = 0x0b,
        !          9224:     ADDIU32 = 0x0c,
        !          9225:     LHU32 = 0x0d,
        !          9226:     SH32 = 0x0e,
        !          9227:     LH32 = 0x0f,
        !          9228: 
        !          9229:     POOL32I = 0x10,
        !          9230:     POOL16C = 0x11,
        !          9231:     LWSP16 = 0x12,
        !          9232:     POOL16D = 0x13,
        !          9233:     ORI32 = 0x14,
        !          9234:     POOL32F = 0x15,
        !          9235:     POOL32S = 0x16,
        !          9236:     DADDIU32 = 0x17,
        !          9237: 
        !          9238:     POOL32C = 0x18,
        !          9239:     LWGP16 = 0x19,
        !          9240:     LW16 = 0x1a,
        !          9241:     POOL16E = 0x1b,
        !          9242:     XORI32 = 0x1c,
        !          9243:     JALS32 = 0x1d,
        !          9244:     ADDIUPC = 0x1e,
        !          9245:     POOL48A = 0x1f,
        !          9246: 
        !          9247:     /* 0x20 is reserved */
        !          9248:     RES_20 = 0x20,
        !          9249:     POOL16F = 0x21,
        !          9250:     SB16 = 0x22,
        !          9251:     BEQZ16 = 0x23,
        !          9252:     SLTI32 = 0x24,
        !          9253:     BEQ32 = 0x25,
        !          9254:     SWC132 = 0x26,
        !          9255:     LWC132 = 0x27,
        !          9256: 
        !          9257:     /* 0x28 and 0x29 are reserved */
        !          9258:     RES_28 = 0x28,
        !          9259:     RES_29 = 0x29,
        !          9260:     SH16 = 0x2a,
        !          9261:     BNEZ16 = 0x2b,
        !          9262:     SLTIU32 = 0x2c,
        !          9263:     BNE32 = 0x2d,
        !          9264:     SDC132 = 0x2e,
        !          9265:     LDC132 = 0x2f,
        !          9266: 
        !          9267:     /* 0x30 and 0x31 are reserved */
        !          9268:     RES_30 = 0x30,
        !          9269:     RES_31 = 0x31,
        !          9270:     SWSP16 = 0x32,
        !          9271:     B16 = 0x33,
        !          9272:     ANDI32 = 0x34,
        !          9273:     J32 = 0x35,
        !          9274:     SD32 = 0x36,
        !          9275:     LD32 = 0x37,
        !          9276: 
        !          9277:     /* 0x38 and 0x39 are reserved */
        !          9278:     RES_38 = 0x38,
        !          9279:     RES_39 = 0x39,
        !          9280:     SW16 = 0x3a,
        !          9281:     LI16 = 0x3b,
        !          9282:     JALX32 = 0x3c,
        !          9283:     JAL32 = 0x3d,
        !          9284:     SW32 = 0x3e,
        !          9285:     LW32 = 0x3f
        !          9286: };
        !          9287: 
        !          9288: /* POOL32A encoding of minor opcode field */
        !          9289: 
        !          9290: enum {
        !          9291:     /* These opcodes are distinguished only by bits 9..6; those bits are
        !          9292:      * what are recorded below. */
        !          9293:     SLL32 = 0x0,
        !          9294:     SRL32 = 0x1,
        !          9295:     SRA = 0x2,
        !          9296:     ROTR = 0x3,
        !          9297: 
        !          9298:     SLLV = 0x0,
        !          9299:     SRLV = 0x1,
        !          9300:     SRAV = 0x2,
        !          9301:     ROTRV = 0x3,
        !          9302:     ADD = 0x4,
        !          9303:     ADDU32 = 0x5,
        !          9304:     SUB = 0x6,
        !          9305:     SUBU32 = 0x7,
        !          9306:     MUL = 0x8,
        !          9307:     AND = 0x9,
        !          9308:     OR32 = 0xa,
        !          9309:     NOR = 0xb,
        !          9310:     XOR32 = 0xc,
        !          9311:     SLT = 0xd,
        !          9312:     SLTU = 0xe,
        !          9313: 
        !          9314:     MOVN = 0x0,
        !          9315:     MOVZ = 0x1,
        !          9316:     LWXS = 0x4,
        !          9317: 
        !          9318:     /* The following can be distinguished by their lower 6 bits. */
        !          9319:     INS = 0x0c,
        !          9320:     EXT = 0x2c,
        !          9321:     POOL32AXF = 0x3c
        !          9322: };
        !          9323: 
        !          9324: /* POOL32AXF encoding of minor opcode field extension */
        !          9325: 
        !          9326: enum {
        !          9327:     /* bits 11..6 */
        !          9328:     TEQ = 0x00,
        !          9329:     TGE = 0x08,
        !          9330:     TGEU = 0x10,
        !          9331:     TLT = 0x20,
        !          9332:     TLTU = 0x28,
        !          9333:     TNE = 0x30,
        !          9334: 
        !          9335:     MFC0 = 0x03,
        !          9336:     MTC0 = 0x0b,
        !          9337: 
        !          9338:     /* bits 13..12 for 0x01 */
        !          9339:     MFHI_ACC = 0x0,
        !          9340:     MFLO_ACC = 0x1,
        !          9341:     MTHI_ACC = 0x2,
        !          9342:     MTLO_ACC = 0x3,
        !          9343: 
        !          9344:     /* bits 13..12 for 0x2a */
        !          9345:     MADD_ACC = 0x0,
        !          9346:     MADDU_ACC = 0x1,
        !          9347:     MSUB_ACC = 0x2,
        !          9348:     MSUBU_ACC = 0x3,
        !          9349: 
        !          9350:     /* bits 13..12 for 0x32 */
        !          9351:     MULT_ACC = 0x0,
        !          9352:     MULTU_ACC = 0x0,
        !          9353: 
        !          9354:     /* bits 15..12 for 0x2c */
        !          9355:     SEB = 0x2,
        !          9356:     SEH = 0x3,
        !          9357:     CLO = 0x4,
        !          9358:     CLZ = 0x5,
        !          9359:     RDHWR = 0x6,
        !          9360:     WSBH = 0x7,
        !          9361:     MULT = 0x8,
        !          9362:     MULTU = 0x9,
        !          9363:     DIV = 0xa,
        !          9364:     DIVU = 0xb,
        !          9365:     MADD = 0xc,
        !          9366:     MADDU = 0xd,
        !          9367:     MSUB = 0xe,
        !          9368:     MSUBU = 0xf,
        !          9369: 
        !          9370:     /* bits 15..12 for 0x34 */
        !          9371:     MFC2 = 0x4,
        !          9372:     MTC2 = 0x5,
        !          9373:     MFHC2 = 0x8,
        !          9374:     MTHC2 = 0x9,
        !          9375:     CFC2 = 0xc,
        !          9376:     CTC2 = 0xd,
        !          9377: 
        !          9378:     /* bits 15..12 for 0x3c */
        !          9379:     JALR = 0x0,
        !          9380:     JR = 0x0,                   /* alias */
        !          9381:     JALR_HB = 0x1,
        !          9382:     JALRS = 0x4,
        !          9383:     JALRS_HB = 0x5,
        !          9384: 
        !          9385:     /* bits 15..12 for 0x05 */
        !          9386:     RDPGPR = 0xe,
        !          9387:     WRPGPR = 0xf,
        !          9388: 
        !          9389:     /* bits 15..12 for 0x0d */
        !          9390:     TLBP = 0x0,
        !          9391:     TLBR = 0x1,
        !          9392:     TLBWI = 0x2,
        !          9393:     TLBWR = 0x3,
        !          9394:     WAIT = 0x9,
        !          9395:     IRET = 0xd,
        !          9396:     DERET = 0xe,
        !          9397:     ERET = 0xf,
        !          9398: 
        !          9399:     /* bits 15..12 for 0x15 */
        !          9400:     DMT = 0x0,
        !          9401:     DVPE = 0x1,
        !          9402:     EMT = 0x2,
        !          9403:     EVPE = 0x3,
        !          9404: 
        !          9405:     /* bits 15..12 for 0x1d */
        !          9406:     DI = 0x4,
        !          9407:     EI = 0x5,
        !          9408: 
        !          9409:     /* bits 15..12 for 0x2d */
        !          9410:     SYNC = 0x6,
        !          9411:     SYSCALL = 0x8,
        !          9412:     SDBBP = 0xd,
        !          9413: 
        !          9414:     /* bits 15..12 for 0x35 */
        !          9415:     MFHI32 = 0x0,
        !          9416:     MFLO32 = 0x1,
        !          9417:     MTHI32 = 0x2,
        !          9418:     MTLO32 = 0x3,
        !          9419: };
        !          9420: 
        !          9421: /* POOL32B encoding of minor opcode field (bits 15..12) */
        !          9422: 
        !          9423: enum {
        !          9424:     LWC2 = 0x0,
        !          9425:     LWP = 0x1,
        !          9426:     LDP = 0x4,
        !          9427:     LWM32 = 0x5,
        !          9428:     CACHE = 0x6,
        !          9429:     LDM = 0x7,
        !          9430:     SWC2 = 0x8,
        !          9431:     SWP = 0x9,
        !          9432:     SDP = 0xc,
        !          9433:     SWM32 = 0xd,
        !          9434:     SDM = 0xf
        !          9435: };
        !          9436: 
        !          9437: /* POOL32C encoding of minor opcode field (bits 15..12) */
        !          9438: 
        !          9439: enum {
        !          9440:     LWL = 0x0,
        !          9441:     SWL = 0x8,
        !          9442:     LWR = 0x1,
        !          9443:     SWR = 0x9,
        !          9444:     PREF = 0x2,
        !          9445:     /* 0xa is reserved */
        !          9446:     LL = 0x3,
        !          9447:     SC = 0xb,
        !          9448:     LDL = 0x4,
        !          9449:     SDL = 0xc,
        !          9450:     LDR = 0x5,
        !          9451:     SDR = 0xd,
        !          9452:     /* 0x6 is reserved */
        !          9453:     LWU = 0xe,
        !          9454:     LLD = 0x7,
        !          9455:     SCD = 0xf
        !          9456: };
        !          9457: 
        !          9458: /* POOL32F encoding of minor opcode field (bits 5..0) */
        !          9459: 
        !          9460: enum {
        !          9461:     /* These are the bit 7..6 values */
        !          9462:     ADD_FMT = 0x0,
        !          9463:     MOVN_FMT = 0x0,
        !          9464: 
        !          9465:     SUB_FMT = 0x1,
        !          9466:     MOVZ_FMT = 0x1,
        !          9467: 
        !          9468:     MUL_FMT = 0x2,
        !          9469: 
        !          9470:     DIV_FMT = 0x3,
        !          9471: 
        !          9472:     /* These are the bit 8..6 values */
        !          9473:     RSQRT2_FMT = 0x0,
        !          9474:     MOVF_FMT = 0x0,
        !          9475: 
        !          9476:     LWXC1 = 0x1,
        !          9477:     MOVT_FMT = 0x1,
        !          9478: 
        !          9479:     PLL_PS = 0x2,
        !          9480:     SWXC1 = 0x2,
        !          9481: 
        !          9482:     PLU_PS = 0x3,
        !          9483:     LDXC1 = 0x3,
        !          9484: 
        !          9485:     PUL_PS = 0x4,
        !          9486:     SDXC1 = 0x4,
        !          9487:     RECIP2_FMT = 0x4,
        !          9488: 
        !          9489:     PUU_PS = 0x5,
        !          9490:     LUXC1 = 0x5,
        !          9491: 
        !          9492:     CVT_PS_S = 0x6,
        !          9493:     SUXC1 = 0x6,
        !          9494:     ADDR_PS = 0x6,
        !          9495:     PREFX = 0x6,
        !          9496: 
        !          9497:     MULR_PS = 0x7,
        !          9498: 
        !          9499:     MADD_S = 0x01,
        !          9500:     MADD_D = 0x09,
        !          9501:     MADD_PS = 0x11,
        !          9502:     ALNV_PS = 0x19,
        !          9503:     MSUB_S = 0x21,
        !          9504:     MSUB_D = 0x29,
        !          9505:     MSUB_PS = 0x31,
        !          9506: 
        !          9507:     NMADD_S = 0x02,
        !          9508:     NMADD_D = 0x0a,
        !          9509:     NMADD_PS = 0x12,
        !          9510:     NMSUB_S = 0x22,
        !          9511:     NMSUB_D = 0x2a,
        !          9512:     NMSUB_PS = 0x32,
        !          9513: 
        !          9514:     POOL32FXF = 0x3b,
        !          9515: 
        !          9516:     CABS_COND_FMT = 0x1c,              /* MIPS3D */
        !          9517:     C_COND_FMT = 0x3c
        !          9518: };
        !          9519: 
        !          9520: /* POOL32Fxf encoding of minor opcode extension field */
        !          9521: 
        !          9522: enum {
        !          9523:     CVT_L = 0x04,
        !          9524:     RSQRT_FMT = 0x08,
        !          9525:     FLOOR_L = 0x0c,
        !          9526:     CVT_PW_PS = 0x1c,
        !          9527:     CVT_W = 0x24,
        !          9528:     SQRT_FMT = 0x28,
        !          9529:     FLOOR_W = 0x2c,
        !          9530:     CVT_PS_PW = 0x3c,
        !          9531:     CFC1 = 0x40,
        !          9532:     RECIP_FMT = 0x48,
        !          9533:     CEIL_L = 0x4c,
        !          9534:     CTC1 = 0x60,
        !          9535:     CEIL_W = 0x6c,
        !          9536:     MFC1 = 0x80,
        !          9537:     CVT_S_PL = 0x84,
        !          9538:     TRUNC_L = 0x8c,
        !          9539:     MTC1 = 0xa0,
        !          9540:     CVT_S_PU = 0xa4,
        !          9541:     TRUNC_W = 0xac,
        !          9542:     MFHC1 = 0xc0,
        !          9543:     ROUND_L = 0xcc,
        !          9544:     MTHC1 = 0xe0,
        !          9545:     ROUND_W = 0xec,
        !          9546: 
        !          9547:     MOV_FMT = 0x01,
        !          9548:     MOVF = 0x05,
        !          9549:     ABS_FMT = 0x0d,
        !          9550:     RSQRT1_FMT = 0x1d,
        !          9551:     MOVT = 0x25,
        !          9552:     NEG_FMT = 0x2d,
        !          9553:     CVT_D = 0x4d,
        !          9554:     RECIP1_FMT = 0x5d,
        !          9555:     CVT_S = 0x6d
        !          9556: };
        !          9557: 
        !          9558: /* POOL32I encoding of minor opcode field (bits 25..21) */
        !          9559: 
        !          9560: enum {
        !          9561:     BLTZ = 0x00,
        !          9562:     BLTZAL = 0x01,
        !          9563:     BGEZ = 0x02,
        !          9564:     BGEZAL = 0x03,
        !          9565:     BLEZ = 0x04,
        !          9566:     BNEZC = 0x05,
        !          9567:     BGTZ = 0x06,
        !          9568:     BEQZC = 0x07,
        !          9569:     TLTI = 0x08,
        !          9570:     TGEI = 0x09,
        !          9571:     TLTIU = 0x0a,
        !          9572:     TGEIU = 0x0b,
        !          9573:     TNEI = 0x0c,
        !          9574:     LUI = 0x0d,
        !          9575:     TEQI = 0x0e,
        !          9576:     SYNCI = 0x10,
        !          9577:     BLTZALS = 0x11,
        !          9578:     BGEZALS = 0x13,
        !          9579:     BC2F = 0x14,
        !          9580:     BC2T = 0x15,
        !          9581:     BPOSGE64 = 0x1a,
        !          9582:     BPOSGE32 = 0x1b,
        !          9583:     /* These overlap and are distinguished by bit16 of the instruction */
        !          9584:     BC1F = 0x1c,
        !          9585:     BC1T = 0x1d,
        !          9586:     BC1ANY2F = 0x1c,
        !          9587:     BC1ANY2T = 0x1d,
        !          9588:     BC1ANY4F = 0x1e,
        !          9589:     BC1ANY4T = 0x1f
        !          9590: };
        !          9591: 
        !          9592: /* POOL16A encoding of minor opcode field */
        !          9593: 
        !          9594: enum {
        !          9595:     ADDU16 = 0x0,
        !          9596:     SUBU16 = 0x1
        !          9597: };
        !          9598: 
        !          9599: /* POOL16B encoding of minor opcode field */
        !          9600: 
        !          9601: enum {
        !          9602:     SLL16 = 0x0,
        !          9603:     SRL16 = 0x1
        !          9604: };
        !          9605: 
        !          9606: /* POOL16C encoding of minor opcode field */
        !          9607: 
        !          9608: enum {
        !          9609:     NOT16 = 0x00,
        !          9610:     XOR16 = 0x04,
        !          9611:     AND16 = 0x08,
        !          9612:     OR16 = 0x0c,
        !          9613:     LWM16 = 0x10,
        !          9614:     SWM16 = 0x14,
        !          9615:     JR16 = 0x18,
        !          9616:     JRC16 = 0x1a,
        !          9617:     JALR16 = 0x1c,
        !          9618:     JALR16S = 0x1e,
        !          9619:     MFHI16 = 0x20,
        !          9620:     MFLO16 = 0x24,
        !          9621:     BREAK16 = 0x28,
        !          9622:     SDBBP16 = 0x2c,
        !          9623:     JRADDIUSP = 0x30
        !          9624: };
        !          9625: 
        !          9626: /* POOL16D encoding of minor opcode field */
        !          9627: 
        !          9628: enum {
        !          9629:     ADDIUS5 = 0x0,
        !          9630:     ADDIUSP = 0x1
        !          9631: };
        !          9632: 
        !          9633: /* POOL16E encoding of minor opcode field */
        !          9634: 
        !          9635: enum {
        !          9636:     ADDIUR2 = 0x0,
        !          9637:     ADDIUR1SP = 0x1
        !          9638: };
        !          9639: 
        !          9640: static int mmreg (int r)
        !          9641: {
        !          9642:     static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
        !          9643: 
        !          9644:     return map[r];
        !          9645: }
        !          9646: 
        !          9647: /* Used for 16-bit store instructions.  */
        !          9648: static int mmreg2 (int r)
        !          9649: {
        !          9650:     static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
        !          9651: 
        !          9652:     return map[r];
        !          9653: }
        !          9654: 
        !          9655: #define uMIPS_RD(op) ((op >> 7) & 0x7)
        !          9656: #define uMIPS_RS(op) ((op >> 4) & 0x7)
        !          9657: #define uMIPS_RS2(op) uMIPS_RS(op)
        !          9658: #define uMIPS_RS1(op) ((op >> 1) & 0x7)
        !          9659: #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
        !          9660: #define uMIPS_RS5(op) (op & 0x1f)
        !          9661: 
        !          9662: /* Signed immediate */
        !          9663: #define SIMM(op, start, width)                                          \
        !          9664:     ((int32_t)(((op >> start) & ((~0U) >> (32-width)))                 \
        !          9665:                << (32-width))                                           \
        !          9666:      >> (32-width))
        !          9667: /* Zero-extended immediate */
        !          9668: #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
        !          9669: 
        !          9670: static void gen_addiur1sp (CPUState *env, DisasContext *ctx)
        !          9671: {
        !          9672:     int rd = mmreg(uMIPS_RD(ctx->opcode));
        !          9673: 
        !          9674:     gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
        !          9675: }
        !          9676: 
        !          9677: static void gen_addiur2 (CPUState *env, DisasContext *ctx)
        !          9678: {
        !          9679:     static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
        !          9680:     int rd = mmreg(uMIPS_RD(ctx->opcode));
        !          9681:     int rs = mmreg(uMIPS_RS(ctx->opcode));
        !          9682: 
        !          9683:     gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
        !          9684: }
        !          9685: 
        !          9686: static void gen_addiusp (CPUState *env, DisasContext *ctx)
        !          9687: {
        !          9688:     int encoded = ZIMM(ctx->opcode, 1, 9);
        !          9689:     int decoded;
        !          9690: 
        !          9691:     if (encoded <= 1) {
        !          9692:         decoded = 256 + encoded;
        !          9693:     } else if (encoded <= 255) {
        !          9694:         decoded = encoded;
        !          9695:     } else if (encoded <= 509) {
        !          9696:         decoded = encoded - 512;
        !          9697:     } else {
        !          9698:         decoded = encoded - 768;
        !          9699:     }
        !          9700: 
        !          9701:     gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
        !          9702: }
        !          9703: 
        !          9704: static void gen_addius5 (CPUState *env, DisasContext *ctx)
        !          9705: {
        !          9706:     int imm = SIMM(ctx->opcode, 1, 4);
        !          9707:     int rd = (ctx->opcode >> 5) & 0x1f;
        !          9708: 
        !          9709:     gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
        !          9710: }
        !          9711: 
        !          9712: static void gen_andi16 (CPUState *env, DisasContext *ctx)
        !          9713: {
        !          9714:     static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
        !          9715:                                  31, 32, 63, 64, 255, 32768, 65535 };
        !          9716:     int rd = mmreg(uMIPS_RD(ctx->opcode));
        !          9717:     int rs = mmreg(uMIPS_RS(ctx->opcode));
        !          9718:     int encoded = ZIMM(ctx->opcode, 0, 4);
        !          9719: 
        !          9720:     gen_logic_imm(env, OPC_ANDI, rd, rs, decoded_imm[encoded]);
        !          9721: }
        !          9722: 
        !          9723: static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
        !          9724:                                int base, int16_t offset)
        !          9725: {
        !          9726:     TCGv t0, t1;
        !          9727:     TCGv_i32 t2;
        !          9728: 
        !          9729:     if (ctx->hflags & MIPS_HFLAG_BMASK) {
        !          9730:         generate_exception(ctx, EXCP_RI);
        !          9731:         return;
        !          9732:     }
        !          9733: 
        !          9734:     t0 = tcg_temp_new();
        !          9735: 
        !          9736:     gen_base_offset_addr(ctx, t0, base, offset);
        !          9737: 
        !          9738:     t1 = tcg_const_tl(reglist);
        !          9739:     t2 = tcg_const_i32(ctx->mem_idx);
        !          9740: 
        !          9741:     save_cpu_state(ctx, 1);
        !          9742:     switch (opc) {
        !          9743:     case LWM32:
        !          9744:         gen_helper_lwm(t0, t1, t2);
        !          9745:         break;
        !          9746:     case SWM32:
        !          9747:         gen_helper_swm(t0, t1, t2);
        !          9748:         break;
        !          9749: #ifdef TARGET_MIPS64
        !          9750:     case LDM:
        !          9751:         gen_helper_ldm(t0, t1, t2);
        !          9752:         break;
        !          9753:     case SDM:
        !          9754:         gen_helper_sdm(t0, t1, t2);
        !          9755:         break;
        !          9756: #endif
        !          9757:     }
        !          9758:     MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
        !          9759:     tcg_temp_free(t0);
        !          9760:     tcg_temp_free(t1);
        !          9761:     tcg_temp_free_i32(t2);
        !          9762: }
        !          9763: 
        !          9764: 
        !          9765: static void gen_pool16c_insn (CPUState *env, DisasContext *ctx, int *is_branch)
        !          9766: {
        !          9767:     int rd = mmreg((ctx->opcode >> 3) & 0x7);
        !          9768:     int rs = mmreg(ctx->opcode & 0x7);
        !          9769:     int opc;
        !          9770: 
        !          9771:     switch (((ctx->opcode) >> 4) & 0x3f) {
        !          9772:     case NOT16 + 0:
        !          9773:     case NOT16 + 1:
        !          9774:     case NOT16 + 2:
        !          9775:     case NOT16 + 3:
        !          9776:         gen_logic(env, OPC_NOR, rd, rs, 0);
        !          9777:         break;
        !          9778:     case XOR16 + 0:
        !          9779:     case XOR16 + 1:
        !          9780:     case XOR16 + 2:
        !          9781:     case XOR16 + 3:
        !          9782:         gen_logic(env, OPC_XOR, rd, rd, rs);
        !          9783:         break;
        !          9784:     case AND16 + 0:
        !          9785:     case AND16 + 1:
        !          9786:     case AND16 + 2:
        !          9787:     case AND16 + 3:
        !          9788:         gen_logic(env, OPC_AND, rd, rd, rs);
        !          9789:         break;
        !          9790:     case OR16 + 0:
        !          9791:     case OR16 + 1:
        !          9792:     case OR16 + 2:
        !          9793:     case OR16 + 3:
        !          9794:         gen_logic(env, OPC_OR, rd, rd, rs);
        !          9795:         break;
        !          9796:     case LWM16 + 0:
        !          9797:     case LWM16 + 1:
        !          9798:     case LWM16 + 2:
        !          9799:     case LWM16 + 3:
        !          9800:         {
        !          9801:             static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
        !          9802:             int offset = ZIMM(ctx->opcode, 0, 4);
        !          9803: 
        !          9804:             gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
        !          9805:                               29, offset << 2);
        !          9806:         }
        !          9807:         break;
        !          9808:     case SWM16 + 0:
        !          9809:     case SWM16 + 1:
        !          9810:     case SWM16 + 2:
        !          9811:     case SWM16 + 3:
        !          9812:         {
        !          9813:             static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
        !          9814:             int offset = ZIMM(ctx->opcode, 0, 4);
        !          9815: 
        !          9816:             gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
        !          9817:                               29, offset << 2);
        !          9818:         }
        !          9819:         break;
        !          9820:     case JR16 + 0:
        !          9821:     case JR16 + 1:
        !          9822:         {
        !          9823:             int reg = ctx->opcode & 0x1f;
        !          9824: 
        !          9825:             gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
        !          9826:         }
        !          9827:         *is_branch = 1;
        !          9828:         break;
        !          9829:     case JRC16 + 0:
        !          9830:     case JRC16 + 1:
        !          9831:         {
        !          9832:             int reg = ctx->opcode & 0x1f;
        !          9833: 
        !          9834:             gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
        !          9835:             /* Let normal delay slot handling in our caller take us
        !          9836:                to the branch target.  */
        !          9837:         }
        !          9838:         break;
        !          9839:     case JALR16 + 0:
        !          9840:     case JALR16 + 1:
        !          9841:         opc = OPC_JALR;
        !          9842:         goto do_jalr;
        !          9843:     case JALR16S + 0:
        !          9844:     case JALR16S + 1:
        !          9845:         opc = OPC_JALRS;
        !          9846:     do_jalr:
        !          9847:         {
        !          9848:             int reg = ctx->opcode & 0x1f;
        !          9849: 
        !          9850:             gen_compute_branch(ctx, opc, 2, reg, 31, 0);
        !          9851:         }
        !          9852:         *is_branch = 1;
        !          9853:         break;
        !          9854:     case MFHI16 + 0:
        !          9855:     case MFHI16 + 1:
        !          9856:         gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
        !          9857:         break;
        !          9858:     case MFLO16 + 0:
        !          9859:     case MFLO16 + 1:
        !          9860:         gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
        !          9861:         break;
        !          9862:     case BREAK16:
        !          9863:         generate_exception(ctx, EXCP_BREAK);
        !          9864:         break;
        !          9865:     case SDBBP16:
        !          9866:         /* XXX: not clear which exception should be raised
        !          9867:          *      when in debug mode...
        !          9868:          */
        !          9869:         check_insn(env, ctx, ISA_MIPS32);
        !          9870:         if (!(ctx->hflags & MIPS_HFLAG_DM)) {
        !          9871:             generate_exception(ctx, EXCP_DBp);
        !          9872:         } else {
        !          9873:             generate_exception(ctx, EXCP_DBp);
        !          9874:         }
        !          9875:         break;
        !          9876:     case JRADDIUSP + 0:
        !          9877:     case JRADDIUSP + 1:
        !          9878:         {
        !          9879:             int imm = ZIMM(ctx->opcode, 0, 5);
        !          9880: 
        !          9881:             gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
        !          9882:             gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
        !          9883:             /* Let normal delay slot handling in our caller take us
        !          9884:                to the branch target.  */
        !          9885:         }
        !          9886:         break;
        !          9887:     default:
        !          9888:         generate_exception(ctx, EXCP_RI);
        !          9889:         break;
        !          9890:     }
        !          9891: }
        !          9892: 
        !          9893: static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
        !          9894: {
        !          9895:     TCGv t0 = tcg_temp_new();
        !          9896:     TCGv t1 = tcg_temp_new();
        !          9897: 
        !          9898:     gen_load_gpr(t0, base);
        !          9899: 
        !          9900:     if (index != 0) {
        !          9901:         gen_load_gpr(t1, index);
        !          9902:         tcg_gen_shli_tl(t1, t1, 2);
        !          9903:         gen_op_addr_add(ctx, t0, t1, t0);
        !          9904:     }
        !          9905: 
        !          9906:     save_cpu_state(ctx, 0);
        !          9907:     op_ld_lw(t1, t0, ctx);
        !          9908:     gen_store_gpr(t1, rd);
        !          9909: 
        !          9910:     tcg_temp_free(t0);
        !          9911:     tcg_temp_free(t1);
        !          9912: }
        !          9913: 
        !          9914: static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
        !          9915:                            int base, int16_t offset)
        !          9916: {
        !          9917:     const char *opn = "ldst_pair";
        !          9918:     TCGv t0, t1;
        !          9919: 
        !          9920:     if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31 || rd == base) {
        !          9921:         generate_exception(ctx, EXCP_RI);
        !          9922:         return;
        !          9923:     }
        !          9924: 
        !          9925:     t0 = tcg_temp_new();
        !          9926:     t1 = tcg_temp_new();
        !          9927: 
        !          9928:     gen_base_offset_addr(ctx, t0, base, offset);
        !          9929: 
        !          9930:     switch (opc) {
        !          9931:     case LWP:
        !          9932:         save_cpu_state(ctx, 0);
        !          9933:         op_ld_lw(t1, t0, ctx);
        !          9934:         gen_store_gpr(t1, rd);
        !          9935:         tcg_gen_movi_tl(t1, 4);
        !          9936:         gen_op_addr_add(ctx, t0, t0, t1);
        !          9937:         op_ld_lw(t1, t0, ctx);
        !          9938:         gen_store_gpr(t1, rd+1);
        !          9939:         opn = "lwp";
        !          9940:         break;
        !          9941:     case SWP:
        !          9942:         save_cpu_state(ctx, 1);
        !          9943:         gen_load_gpr(t1, rd);
        !          9944:         op_st_sw(t1, t0, ctx);
        !          9945:         tcg_gen_movi_tl(t1, 4);
        !          9946:         gen_op_addr_add(ctx, t0, t0, t1);
        !          9947:         gen_load_gpr(t1, rd+1);
        !          9948:         op_st_sw(t1, t0, ctx);
        !          9949:         opn = "swp";
        !          9950:         break;
        !          9951: #ifdef TARGET_MIPS64
        !          9952:     case LDP:
        !          9953:         save_cpu_state(ctx, 0);
        !          9954:         op_ld_ld(t1, t0, ctx);
        !          9955:         gen_store_gpr(t1, rd);
        !          9956:         tcg_gen_movi_tl(t1, 8);
        !          9957:         gen_op_addr_add(ctx, t0, t0, t1);
        !          9958:         op_ld_ld(t1, t0, ctx);
        !          9959:         gen_store_gpr(t1, rd+1);
        !          9960:         opn = "ldp";
        !          9961:         break;
        !          9962:     case SDP:
        !          9963:         save_cpu_state(ctx, 1);
        !          9964:         gen_load_gpr(t1, rd);
        !          9965:         op_st_sd(t1, t0, ctx);
        !          9966:         tcg_gen_movi_tl(t1, 8);
        !          9967:         gen_op_addr_add(ctx, t0, t0, t1);
        !          9968:         gen_load_gpr(t1, rd+1);
        !          9969:         op_st_sd(t1, t0, ctx);
        !          9970:         opn = "sdp";
        !          9971:         break;
        !          9972: #endif
        !          9973:     }
        !          9974:     MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
        !          9975:     tcg_temp_free(t0);
        !          9976:     tcg_temp_free(t1);
        !          9977: }
        !          9978: 
        !          9979: static void gen_pool32axf (CPUState *env, DisasContext *ctx, int rt, int rs,
        !          9980:                            int *is_branch)
        !          9981: {
        !          9982:     int extension = (ctx->opcode >> 6) & 0x3f;
        !          9983:     int minor = (ctx->opcode >> 12) & 0xf;
        !          9984:     uint32_t mips32_op;
        !          9985: 
        !          9986:     switch (extension) {
        !          9987:     case TEQ:
        !          9988:         mips32_op = OPC_TEQ;
        !          9989:         goto do_trap;
        !          9990:     case TGE:
        !          9991:         mips32_op = OPC_TGE;
        !          9992:         goto do_trap;
        !          9993:     case TGEU:
        !          9994:         mips32_op = OPC_TGEU;
        !          9995:         goto do_trap;
        !          9996:     case TLT:
        !          9997:         mips32_op = OPC_TLT;
        !          9998:         goto do_trap;
        !          9999:     case TLTU:
        !          10000:         mips32_op = OPC_TLTU;
        !          10001:         goto do_trap;
        !          10002:     case TNE:
        !          10003:         mips32_op = OPC_TNE;
        !          10004:     do_trap:
        !          10005:         gen_trap(ctx, mips32_op, rs, rt, -1);
        !          10006:         break;
        !          10007: #ifndef CONFIG_USER_ONLY
        !          10008:     case MFC0:
        !          10009:     case MFC0 + 32:
        !          10010:         if (rt == 0) {
        !          10011:             /* Treat as NOP. */
        !          10012:             break;
        !          10013:         }
        !          10014:         gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
        !          10015:         break;
        !          10016:     case MTC0:
        !          10017:     case MTC0 + 32:
        !          10018:         {
        !          10019:             TCGv t0 = tcg_temp_new();
        !          10020: 
        !          10021:             gen_load_gpr(t0, rt);
        !          10022:             gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
        !          10023:             tcg_temp_free(t0);
        !          10024:         }
        !          10025:         break;
        !          10026: #endif
        !          10027:     case 0x2c:
        !          10028:         switch (minor) {
        !          10029:         case SEB:
        !          10030:             gen_bshfl(ctx, OPC_SEB, rs, rt);
        !          10031:             break;
        !          10032:         case SEH:
        !          10033:             gen_bshfl(ctx, OPC_SEH, rs, rt);
        !          10034:             break;
        !          10035:         case CLO:
        !          10036:             mips32_op = OPC_CLO;
        !          10037:             goto do_cl;
        !          10038:         case CLZ:
        !          10039:             mips32_op = OPC_CLZ;
        !          10040:         do_cl:
        !          10041:             check_insn(env, ctx, ISA_MIPS32);
        !          10042:             gen_cl(ctx, mips32_op, rt, rs);
        !          10043:             break;
        !          10044:         case RDHWR:
        !          10045:             gen_rdhwr(env, ctx, rt, rs);
        !          10046:             break;
        !          10047:         case WSBH:
        !          10048:             gen_bshfl(ctx, OPC_WSBH, rs, rt);
        !          10049:             break;
        !          10050:         case MULT:
        !          10051:             mips32_op = OPC_MULT;
        !          10052:             goto do_muldiv;
        !          10053:         case MULTU:
        !          10054:             mips32_op = OPC_MULTU;
        !          10055:             goto do_muldiv;
        !          10056:         case DIV:
        !          10057:             mips32_op = OPC_DIV;
        !          10058:             goto do_muldiv;
        !          10059:         case DIVU:
        !          10060:             mips32_op = OPC_DIVU;
        !          10061:             goto do_muldiv;
        !          10062:         case MADD:
        !          10063:             mips32_op = OPC_MADD;
        !          10064:             goto do_muldiv;
        !          10065:         case MADDU:
        !          10066:             mips32_op = OPC_MADDU;
        !          10067:             goto do_muldiv;
        !          10068:         case MSUB:
        !          10069:             mips32_op = OPC_MSUB;
        !          10070:             goto do_muldiv;
        !          10071:         case MSUBU:
        !          10072:             mips32_op = OPC_MSUBU;
        !          10073:         do_muldiv:
        !          10074:             check_insn(env, ctx, ISA_MIPS32);
        !          10075:             gen_muldiv(ctx, mips32_op, rs, rt);
        !          10076:             break;
        !          10077:         default:
        !          10078:             goto pool32axf_invalid;
        !          10079:         }
        !          10080:         break;
        !          10081:     case 0x34:
        !          10082:         switch (minor) {
        !          10083:         case MFC2:
        !          10084:         case MTC2:
        !          10085:         case MFHC2:
        !          10086:         case MTHC2:
        !          10087:         case CFC2:
        !          10088:         case CTC2:
        !          10089:             generate_exception_err(ctx, EXCP_CpU, 2);
        !          10090:             break;
        !          10091:         default:
        !          10092:             goto pool32axf_invalid;
        !          10093:         }
        !          10094:         break;
        !          10095:     case 0x3c:
        !          10096:         switch (minor) {
        !          10097:         case JALR:
        !          10098:         case JALR_HB:
        !          10099:             gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
        !          10100:             *is_branch = 1;
        !          10101:             break;
        !          10102:         case JALRS:
        !          10103:         case JALRS_HB:
        !          10104:             gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
        !          10105:             *is_branch = 1;
        !          10106:             break;
        !          10107:         default:
        !          10108:             goto pool32axf_invalid;
        !          10109:         }
        !          10110:         break;
        !          10111:     case 0x05:
        !          10112:         switch (minor) {
        !          10113:         case RDPGPR:
        !          10114:             check_insn(env, ctx, ISA_MIPS32R2);
        !          10115:             gen_load_srsgpr(rt, rs);
        !          10116:             break;
        !          10117:         case WRPGPR:
        !          10118:             check_insn(env, ctx, ISA_MIPS32R2);
        !          10119:             gen_store_srsgpr(rt, rs);
        !          10120:             break;
        !          10121:         default:
        !          10122:             goto pool32axf_invalid;
        !          10123:         }
        !          10124:         break;
        !          10125: #ifndef CONFIG_USER_ONLY
        !          10126:     case 0x0d:
        !          10127:         switch (minor) {
        !          10128:         case TLBP:
        !          10129:             mips32_op = OPC_TLBP;
        !          10130:             goto do_cp0;
        !          10131:         case TLBR:
        !          10132:             mips32_op = OPC_TLBR;
        !          10133:             goto do_cp0;
        !          10134:         case TLBWI:
        !          10135:             mips32_op = OPC_TLBWI;
        !          10136:             goto do_cp0;
        !          10137:         case TLBWR:
        !          10138:             mips32_op = OPC_TLBWR;
        !          10139:             goto do_cp0;
        !          10140:         case WAIT:
        !          10141:             mips32_op = OPC_WAIT;
        !          10142:             goto do_cp0;
        !          10143:         case DERET:
        !          10144:             mips32_op = OPC_DERET;
        !          10145:             goto do_cp0;
        !          10146:         case ERET:
        !          10147:             mips32_op = OPC_ERET;
        !          10148:         do_cp0:
        !          10149:             gen_cp0(env, ctx, mips32_op, rt, rs);
        !          10150:             break;
        !          10151:         default:
        !          10152:             goto pool32axf_invalid;
        !          10153:         }
        !          10154:         break;
        !          10155:     case 0x1d:
        !          10156:         switch (minor) {
        !          10157:         case DI:
        !          10158:             {
        !          10159:                 TCGv t0 = tcg_temp_new();
        !          10160: 
        !          10161:                 save_cpu_state(ctx, 1);
        !          10162:                 gen_helper_di(t0);
        !          10163:                 gen_store_gpr(t0, rs);
        !          10164:                 /* Stop translation as we may have switched the execution mode */
        !          10165:                 ctx->bstate = BS_STOP;
        !          10166:                 tcg_temp_free(t0);
        !          10167:             }
        !          10168:             break;
        !          10169:         case EI:
        !          10170:             {
        !          10171:                 TCGv t0 = tcg_temp_new();
        !          10172: 
        !          10173:                 save_cpu_state(ctx, 1);
        !          10174:                 gen_helper_ei(t0);
        !          10175:                 gen_store_gpr(t0, rs);
        !          10176:                 /* Stop translation as we may have switched the execution mode */
        !          10177:                 ctx->bstate = BS_STOP;
        !          10178:                 tcg_temp_free(t0);
        !          10179:             }
        !          10180:             break;
        !          10181:         default:
        !          10182:             goto pool32axf_invalid;
        !          10183:         }
        !          10184:         break;
        !          10185: #endif
        !          10186:     case 0x2d:
        !          10187:         switch (minor) {
        !          10188:         case SYNC:
        !          10189:             /* NOP */
        !          10190:             break;
        !          10191:         case SYSCALL:
        !          10192:             generate_exception(ctx, EXCP_SYSCALL);
        !          10193:             ctx->bstate = BS_STOP;
        !          10194:             break;
        !          10195:         case SDBBP:
        !          10196:             check_insn(env, ctx, ISA_MIPS32);
        !          10197:             if (!(ctx->hflags & MIPS_HFLAG_DM)) {
        !          10198:                 generate_exception(ctx, EXCP_DBp);
        !          10199:             } else {
        !          10200:                 generate_exception(ctx, EXCP_DBp);
        !          10201:             }
        !          10202:             break;
        !          10203:         default:
        !          10204:             goto pool32axf_invalid;
        !          10205:         }
        !          10206:         break;
        !          10207:     case 0x35:
        !          10208:         switch (minor) {
        !          10209:         case MFHI32:
        !          10210:             gen_HILO(ctx, OPC_MFHI, rs);
        !          10211:             break;
        !          10212:         case MFLO32:
        !          10213:             gen_HILO(ctx, OPC_MFLO, rs);
        !          10214:             break;
        !          10215:         case MTHI32:
        !          10216:             gen_HILO(ctx, OPC_MTHI, rs);
        !          10217:             break;
        !          10218:         case MTLO32:
        !          10219:             gen_HILO(ctx, OPC_MTLO, rs);
        !          10220:             break;
        !          10221:         default:
        !          10222:             goto pool32axf_invalid;
        !          10223:         }
        !          10224:         break;
        !          10225:     default:
        !          10226:     pool32axf_invalid:
        !          10227:         MIPS_INVAL("pool32axf");
        !          10228:         generate_exception(ctx, EXCP_RI);
        !          10229:         break;
        !          10230:     }
        !          10231: }
        !          10232: 
        !          10233: /* Values for microMIPS fmt field.  Variable-width, depending on which
        !          10234:    formats the instruction supports.  */
        !          10235: 
        !          10236: enum {
        !          10237:     FMT_SD_S = 0,
        !          10238:     FMT_SD_D = 1,
        !          10239: 
        !          10240:     FMT_SDPS_S = 0,
        !          10241:     FMT_SDPS_D = 1,
        !          10242:     FMT_SDPS_PS = 2,
        !          10243: 
        !          10244:     FMT_SWL_S = 0,
        !          10245:     FMT_SWL_W = 1,
        !          10246:     FMT_SWL_L = 2,
        !          10247: 
        !          10248:     FMT_DWL_D = 0,
        !          10249:     FMT_DWL_W = 1,
        !          10250:     FMT_DWL_L = 2
        !          10251: };
        !          10252: 
        !          10253: static void gen_pool32fxf (CPUState *env, DisasContext *ctx, int rt, int rs)
        !          10254: {
        !          10255:     int extension = (ctx->opcode >> 6) & 0x3ff;
        !          10256:     uint32_t mips32_op;
        !          10257: 
        !          10258: #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
        !          10259: #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
        !          10260: #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
        !          10261: 
        !          10262:     switch (extension) {
        !          10263:     case FLOAT_1BIT_FMT(CFC1, 0):
        !          10264:         mips32_op = OPC_CFC1;
        !          10265:         goto do_cp1;
        !          10266:     case FLOAT_1BIT_FMT(CTC1, 0):
        !          10267:         mips32_op = OPC_CTC1;
        !          10268:         goto do_cp1;
        !          10269:     case FLOAT_1BIT_FMT(MFC1, 0):
        !          10270:         mips32_op = OPC_MFC1;
        !          10271:         goto do_cp1;
        !          10272:     case FLOAT_1BIT_FMT(MTC1, 0):
        !          10273:         mips32_op = OPC_MTC1;
        !          10274:         goto do_cp1;
        !          10275:     case FLOAT_1BIT_FMT(MFHC1, 0):
        !          10276:         mips32_op = OPC_MFHC1;
        !          10277:         goto do_cp1;
        !          10278:     case FLOAT_1BIT_FMT(MTHC1, 0):
        !          10279:         mips32_op = OPC_MTHC1;
        !          10280:     do_cp1:
        !          10281:         gen_cp1(ctx, mips32_op, rt, rs);
        !          10282:         break;
        !          10283: 
        !          10284:         /* Reciprocal square root */
        !          10285:     case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
        !          10286:         mips32_op = OPC_RSQRT_S;
        !          10287:         goto do_unaryfp;
        !          10288:     case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
        !          10289:         mips32_op = OPC_RSQRT_D;
        !          10290:         goto do_unaryfp;
        !          10291: 
        !          10292:         /* Square root */
        !          10293:     case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
        !          10294:         mips32_op = OPC_SQRT_S;
        !          10295:         goto do_unaryfp;
        !          10296:     case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
        !          10297:         mips32_op = OPC_SQRT_D;
        !          10298:         goto do_unaryfp;
        !          10299: 
        !          10300:         /* Reciprocal */
        !          10301:     case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
        !          10302:         mips32_op = OPC_RECIP_S;
        !          10303:         goto do_unaryfp;
        !          10304:     case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
        !          10305:         mips32_op = OPC_RECIP_D;
        !          10306:         goto do_unaryfp;
        !          10307: 
        !          10308:         /* Floor */
        !          10309:     case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
        !          10310:         mips32_op = OPC_FLOOR_L_S;
        !          10311:         goto do_unaryfp;
        !          10312:     case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
        !          10313:         mips32_op = OPC_FLOOR_L_D;
        !          10314:         goto do_unaryfp;
        !          10315:     case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
        !          10316:         mips32_op = OPC_FLOOR_W_S;
        !          10317:         goto do_unaryfp;
        !          10318:     case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
        !          10319:         mips32_op = OPC_FLOOR_W_D;
        !          10320:         goto do_unaryfp;
        !          10321: 
        !          10322:         /* Ceiling */
        !          10323:     case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
        !          10324:         mips32_op = OPC_CEIL_L_S;
        !          10325:         goto do_unaryfp;
        !          10326:     case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
        !          10327:         mips32_op = OPC_CEIL_L_D;
        !          10328:         goto do_unaryfp;
        !          10329:     case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
        !          10330:         mips32_op = OPC_CEIL_W_S;
        !          10331:         goto do_unaryfp;
        !          10332:     case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
        !          10333:         mips32_op = OPC_CEIL_W_D;
        !          10334:         goto do_unaryfp;
        !          10335: 
        !          10336:         /* Truncation */
        !          10337:     case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
        !          10338:         mips32_op = OPC_TRUNC_L_S;
        !          10339:         goto do_unaryfp;
        !          10340:     case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
        !          10341:         mips32_op = OPC_TRUNC_L_D;
        !          10342:         goto do_unaryfp;
        !          10343:     case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
        !          10344:         mips32_op = OPC_TRUNC_W_S;
        !          10345:         goto do_unaryfp;
        !          10346:     case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
        !          10347:         mips32_op = OPC_TRUNC_W_D;
        !          10348:         goto do_unaryfp;
        !          10349: 
        !          10350:         /* Round */
        !          10351:     case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
        !          10352:         mips32_op = OPC_ROUND_L_S;
        !          10353:         goto do_unaryfp;
        !          10354:     case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
        !          10355:         mips32_op = OPC_ROUND_L_D;
        !          10356:         goto do_unaryfp;
        !          10357:     case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
        !          10358:         mips32_op = OPC_ROUND_W_S;
        !          10359:         goto do_unaryfp;
        !          10360:     case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
        !          10361:         mips32_op = OPC_ROUND_W_D;
        !          10362:         goto do_unaryfp;
        !          10363: 
        !          10364:         /* Integer to floating-point conversion */
        !          10365:     case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
        !          10366:         mips32_op = OPC_CVT_L_S;
        !          10367:         goto do_unaryfp;
        !          10368:     case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
        !          10369:         mips32_op = OPC_CVT_L_D;
        !          10370:         goto do_unaryfp;
        !          10371:     case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
        !          10372:         mips32_op = OPC_CVT_W_S;
        !          10373:         goto do_unaryfp;
        !          10374:     case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
        !          10375:         mips32_op = OPC_CVT_W_D;
        !          10376:         goto do_unaryfp;
        !          10377: 
        !          10378:         /* Paired-foo conversions */
        !          10379:     case FLOAT_1BIT_FMT(CVT_S_PL, 0):
        !          10380:         mips32_op = OPC_CVT_S_PL;
        !          10381:         goto do_unaryfp;
        !          10382:     case FLOAT_1BIT_FMT(CVT_S_PU, 0):
        !          10383:         mips32_op = OPC_CVT_S_PU;
        !          10384:         goto do_unaryfp;
        !          10385:     case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
        !          10386:         mips32_op = OPC_CVT_PW_PS;
        !          10387:         goto do_unaryfp;
        !          10388:     case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
        !          10389:         mips32_op = OPC_CVT_PS_PW;
        !          10390:         goto do_unaryfp;
        !          10391: 
        !          10392:         /* Floating-point moves */
        !          10393:     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
        !          10394:         mips32_op = OPC_MOV_S;
        !          10395:         goto do_unaryfp;
        !          10396:     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
        !          10397:         mips32_op = OPC_MOV_D;
        !          10398:         goto do_unaryfp;
        !          10399:     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
        !          10400:         mips32_op = OPC_MOV_PS;
        !          10401:         goto do_unaryfp;
        !          10402: 
        !          10403:         /* Absolute value */
        !          10404:     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
        !          10405:         mips32_op = OPC_ABS_S;
        !          10406:         goto do_unaryfp;
        !          10407:     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
        !          10408:         mips32_op = OPC_ABS_D;
        !          10409:         goto do_unaryfp;
        !          10410:     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
        !          10411:         mips32_op = OPC_ABS_PS;
        !          10412:         goto do_unaryfp;
        !          10413: 
        !          10414:         /* Negation */
        !          10415:     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
        !          10416:         mips32_op = OPC_NEG_S;
        !          10417:         goto do_unaryfp;
        !          10418:     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
        !          10419:         mips32_op = OPC_NEG_D;
        !          10420:         goto do_unaryfp;
        !          10421:     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
        !          10422:         mips32_op = OPC_NEG_PS;
        !          10423:         goto do_unaryfp;
        !          10424: 
        !          10425:         /* Reciprocal square root step */
        !          10426:     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
        !          10427:         mips32_op = OPC_RSQRT1_S;
        !          10428:         goto do_unaryfp;
        !          10429:     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
        !          10430:         mips32_op = OPC_RSQRT1_D;
        !          10431:         goto do_unaryfp;
        !          10432:     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
        !          10433:         mips32_op = OPC_RSQRT1_PS;
        !          10434:         goto do_unaryfp;
        !          10435: 
        !          10436:         /* Reciprocal step */
        !          10437:     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
        !          10438:         mips32_op = OPC_RECIP1_S;
        !          10439:         goto do_unaryfp;
        !          10440:     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
        !          10441:         mips32_op = OPC_RECIP1_S;
        !          10442:         goto do_unaryfp;
        !          10443:     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
        !          10444:         mips32_op = OPC_RECIP1_PS;
        !          10445:         goto do_unaryfp;
        !          10446: 
        !          10447:         /* Conversions from double */
        !          10448:     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
        !          10449:         mips32_op = OPC_CVT_D_S;
        !          10450:         goto do_unaryfp;
        !          10451:     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
        !          10452:         mips32_op = OPC_CVT_D_W;
        !          10453:         goto do_unaryfp;
        !          10454:     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
        !          10455:         mips32_op = OPC_CVT_D_L;
        !          10456:         goto do_unaryfp;
        !          10457: 
        !          10458:         /* Conversions from single */
        !          10459:     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
        !          10460:         mips32_op = OPC_CVT_S_D;
        !          10461:         goto do_unaryfp;
        !          10462:     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
        !          10463:         mips32_op = OPC_CVT_S_W;
        !          10464:         goto do_unaryfp;
        !          10465:     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
        !          10466:         mips32_op = OPC_CVT_S_L;
        !          10467:     do_unaryfp:
        !          10468:         gen_farith(ctx, mips32_op, -1, rs, rt, 0);
        !          10469:         break;
        !          10470: 
        !          10471:         /* Conditional moves on floating-point codes */
        !          10472:     case COND_FLOAT_MOV(MOVT, 0):
        !          10473:     case COND_FLOAT_MOV(MOVT, 1):
        !          10474:     case COND_FLOAT_MOV(MOVT, 2):
        !          10475:     case COND_FLOAT_MOV(MOVT, 3):
        !          10476:     case COND_FLOAT_MOV(MOVT, 4):
        !          10477:     case COND_FLOAT_MOV(MOVT, 5):
        !          10478:     case COND_FLOAT_MOV(MOVT, 6):
        !          10479:     case COND_FLOAT_MOV(MOVT, 7):
        !          10480:         gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
        !          10481:         break;
        !          10482:     case COND_FLOAT_MOV(MOVF, 0):
        !          10483:     case COND_FLOAT_MOV(MOVF, 1):
        !          10484:     case COND_FLOAT_MOV(MOVF, 2):
        !          10485:     case COND_FLOAT_MOV(MOVF, 3):
        !          10486:     case COND_FLOAT_MOV(MOVF, 4):
        !          10487:     case COND_FLOAT_MOV(MOVF, 5):
        !          10488:     case COND_FLOAT_MOV(MOVF, 6):
        !          10489:     case COND_FLOAT_MOV(MOVF, 7):
        !          10490:         gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
        !          10491:         break;
        !          10492:     default:
        !          10493:         MIPS_INVAL("pool32fxf");
        !          10494:         generate_exception(ctx, EXCP_RI);
        !          10495:         break;
        !          10496:     }
        !          10497: }
        !          10498: 
        !          10499: static void decode_micromips32_opc (CPUState *env, DisasContext *ctx,
        !          10500:                                     uint16_t insn_hw1, int *is_branch)
        !          10501: {
        !          10502:     int32_t offset;
        !          10503:     uint16_t insn;
        !          10504:     int rt, rs, rd, rr;
        !          10505:     int16_t imm;
        !          10506:     uint32_t op, minor, mips32_op;
        !          10507:     uint32_t cond, fmt, cc;
        !          10508: 
        !          10509:     insn = lduw_code(ctx->pc + 2);
        !          10510:     ctx->opcode = (ctx->opcode << 16) | insn;
        !          10511: 
        !          10512:     rt = (ctx->opcode >> 21) & 0x1f;
        !          10513:     rs = (ctx->opcode >> 16) & 0x1f;
        !          10514:     rd = (ctx->opcode >> 11) & 0x1f;
        !          10515:     rr = (ctx->opcode >> 6) & 0x1f;
        !          10516:     imm = (int16_t) ctx->opcode;
        !          10517: 
        !          10518:     op = (ctx->opcode >> 26) & 0x3f;
        !          10519:     switch (op) {
        !          10520:     case POOL32A:
        !          10521:         minor = ctx->opcode & 0x3f;
        !          10522:         switch (minor) {
        !          10523:         case 0x00:
        !          10524:             minor = (ctx->opcode >> 6) & 0xf;
        !          10525:             switch (minor) {
        !          10526:             case SLL32:
        !          10527:                 mips32_op = OPC_SLL;
        !          10528:                 goto do_shifti;
        !          10529:             case SRA:
        !          10530:                 mips32_op = OPC_SRA;
        !          10531:                 goto do_shifti;
        !          10532:             case SRL32:
        !          10533:                 mips32_op = OPC_SRL;
        !          10534:                 goto do_shifti;
        !          10535:             case ROTR:
        !          10536:                 mips32_op = OPC_ROTR;
        !          10537:             do_shifti:
        !          10538:                 gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
        !          10539:                 break;
        !          10540:             default:
        !          10541:                 goto pool32a_invalid;
        !          10542:             }
        !          10543:             break;
        !          10544:         case 0x10:
        !          10545:             minor = (ctx->opcode >> 6) & 0xf;
        !          10546:             switch (minor) {
        !          10547:                 /* Arithmetic */
        !          10548:             case ADD:
        !          10549:                 mips32_op = OPC_ADD;
        !          10550:                 goto do_arith;
        !          10551:             case ADDU32:
        !          10552:                 mips32_op = OPC_ADDU;
        !          10553:                 goto do_arith;
        !          10554:             case SUB:
        !          10555:                 mips32_op = OPC_SUB;
        !          10556:                 goto do_arith;
        !          10557:             case SUBU32:
        !          10558:                 mips32_op = OPC_SUBU;
        !          10559:                 goto do_arith;
        !          10560:             case MUL:
        !          10561:                 mips32_op = OPC_MUL;
        !          10562:             do_arith:
        !          10563:                 gen_arith(env, ctx, mips32_op, rd, rs, rt);
        !          10564:                 break;
        !          10565:                 /* Shifts */
        !          10566:             case SLLV:
        !          10567:                 mips32_op = OPC_SLLV;
        !          10568:                 goto do_shift;
        !          10569:             case SRLV:
        !          10570:                 mips32_op = OPC_SRLV;
        !          10571:                 goto do_shift;
        !          10572:             case SRAV:
        !          10573:                 mips32_op = OPC_SRAV;
        !          10574:                 goto do_shift;
        !          10575:             case ROTRV:
        !          10576:                 mips32_op = OPC_ROTRV;
        !          10577:             do_shift:
        !          10578:                 gen_shift(env, ctx, mips32_op, rd, rs, rt);
        !          10579:                 break;
        !          10580:                 /* Logical operations */
        !          10581:             case AND:
        !          10582:                 mips32_op = OPC_AND;
        !          10583:                 goto do_logic;
        !          10584:             case OR32:
        !          10585:                 mips32_op = OPC_OR;
        !          10586:                 goto do_logic;
        !          10587:             case NOR:
        !          10588:                 mips32_op = OPC_NOR;
        !          10589:                 goto do_logic;
        !          10590:             case XOR32:
        !          10591:                 mips32_op = OPC_XOR;
        !          10592:             do_logic:
        !          10593:                 gen_logic(env, mips32_op, rd, rs, rt);
        !          10594:                 break;
        !          10595:                 /* Set less than */
        !          10596:             case SLT:
        !          10597:                 mips32_op = OPC_SLT;
        !          10598:                 goto do_slt;
        !          10599:             case SLTU:
        !          10600:                 mips32_op = OPC_SLTU;
        !          10601:             do_slt:
        !          10602:                 gen_slt(env, mips32_op, rd, rs, rt);
        !          10603:                 break;
        !          10604:             default:
        !          10605:                 goto pool32a_invalid;
        !          10606:             }
        !          10607:             break;
        !          10608:         case 0x18:
        !          10609:             minor = (ctx->opcode >> 6) & 0xf;
        !          10610:             switch (minor) {
        !          10611:                 /* Conditional moves */
        !          10612:             case MOVN:
        !          10613:                 mips32_op = OPC_MOVN;
        !          10614:                 goto do_cmov;
        !          10615:             case MOVZ:
        !          10616:                 mips32_op = OPC_MOVZ;
        !          10617:             do_cmov:
        !          10618:                 gen_cond_move(env, mips32_op, rd, rs, rt);
        !          10619:                 break;
        !          10620:             case LWXS:
        !          10621:                 gen_ldxs(ctx, rs, rt, rd);
        !          10622:                 break;
        !          10623:             default:
        !          10624:                 goto pool32a_invalid;
        !          10625:             }
        !          10626:             break;
        !          10627:         case INS:
        !          10628:             gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
        !          10629:             return;
        !          10630:         case EXT:
        !          10631:             gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
        !          10632:             return;
        !          10633:         case POOL32AXF:
        !          10634:             gen_pool32axf(env, ctx, rt, rs, is_branch);
        !          10635:             break;
        !          10636:         case 0x07:
        !          10637:             generate_exception(ctx, EXCP_BREAK);
        !          10638:             break;
        !          10639:         default:
        !          10640:         pool32a_invalid:
        !          10641:                 MIPS_INVAL("pool32a");
        !          10642:                 generate_exception(ctx, EXCP_RI);
        !          10643:                 break;
        !          10644:         }
        !          10645:         break;
        !          10646:     case POOL32B:
        !          10647:         minor = (ctx->opcode >> 12) & 0xf;
        !          10648:         switch (minor) {
        !          10649:         case CACHE:
        !          10650:             /* Treat as no-op. */
        !          10651:             break;
        !          10652:         case LWC2:
        !          10653:         case SWC2:
        !          10654:             /* COP2: Not implemented. */
        !          10655:             generate_exception_err(ctx, EXCP_CpU, 2);
        !          10656:             break;
        !          10657:         case LWP:
        !          10658:         case SWP:
        !          10659: #ifdef TARGET_MIPS64
        !          10660:         case LDP:
        !          10661:         case SDP:
        !          10662: #endif
        !          10663:             gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
        !          10664:             break;
        !          10665:         case LWM32:
        !          10666:         case SWM32:
        !          10667: #ifdef TARGET_MIPS64
        !          10668:         case LDM:
        !          10669:         case SDM:
        !          10670: #endif
        !          10671:             gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
        !          10672:             break;
        !          10673:         default:
        !          10674:             MIPS_INVAL("pool32b");
        !          10675:             generate_exception(ctx, EXCP_RI);
        !          10676:             break;
        !          10677:         }
        !          10678:         break;
        !          10679:     case POOL32F:
        !          10680:         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
        !          10681:             minor = ctx->opcode & 0x3f;
        !          10682:             check_cp1_enabled(ctx);
        !          10683:             switch (minor) {
        !          10684:             case ALNV_PS:
        !          10685:                 mips32_op = OPC_ALNV_PS;
        !          10686:                 goto do_madd;
        !          10687:             case MADD_S:
        !          10688:                 mips32_op = OPC_MADD_S;
        !          10689:                 goto do_madd;
        !          10690:             case MADD_D:
        !          10691:                 mips32_op = OPC_MADD_D;
        !          10692:                 goto do_madd;
        !          10693:             case MADD_PS:
        !          10694:                 mips32_op = OPC_MADD_PS;
        !          10695:                 goto do_madd;
        !          10696:             case MSUB_S:
        !          10697:                 mips32_op = OPC_MSUB_S;
        !          10698:                 goto do_madd;
        !          10699:             case MSUB_D:
        !          10700:                 mips32_op = OPC_MSUB_D;
        !          10701:                 goto do_madd;
        !          10702:             case MSUB_PS:
        !          10703:                 mips32_op = OPC_MSUB_PS;
        !          10704:                 goto do_madd;
        !          10705:             case NMADD_S:
        !          10706:                 mips32_op = OPC_NMADD_S;
        !          10707:                 goto do_madd;
        !          10708:             case NMADD_D:
        !          10709:                 mips32_op = OPC_NMADD_D;
        !          10710:                 goto do_madd;
        !          10711:             case NMADD_PS:
        !          10712:                 mips32_op = OPC_NMADD_PS;
        !          10713:                 goto do_madd;
        !          10714:             case NMSUB_S:
        !          10715:                 mips32_op = OPC_NMSUB_S;
        !          10716:                 goto do_madd;
        !          10717:             case NMSUB_D:
        !          10718:                 mips32_op = OPC_NMSUB_D;
        !          10719:                 goto do_madd;
        !          10720:             case NMSUB_PS:
        !          10721:                 mips32_op = OPC_NMSUB_PS;
        !          10722:             do_madd:
        !          10723:                 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
        !          10724:                 break;
        !          10725:             case CABS_COND_FMT:
        !          10726:                 cond = (ctx->opcode >> 6) & 0xf;
        !          10727:                 cc = (ctx->opcode >> 13) & 0x7;
        !          10728:                 fmt = (ctx->opcode >> 10) & 0x3;
        !          10729:                 switch (fmt) {
        !          10730:                 case 0x0:
        !          10731:                     gen_cmpabs_s(ctx, cond, rt, rs, cc);
        !          10732:                     break;
        !          10733:                 case 0x1:
        !          10734:                     gen_cmpabs_d(ctx, cond, rt, rs, cc);
        !          10735:                     break;
        !          10736:                 case 0x2:
        !          10737:                     gen_cmpabs_ps(ctx, cond, rt, rs, cc);
        !          10738:                     break;
        !          10739:                 default:
        !          10740:                     goto pool32f_invalid;
        !          10741:                 }
        !          10742:                 break;
        !          10743:             case C_COND_FMT:
        !          10744:                 cond = (ctx->opcode >> 6) & 0xf;
        !          10745:                 cc = (ctx->opcode >> 13) & 0x7;
        !          10746:                 fmt = (ctx->opcode >> 10) & 0x3;
        !          10747:                 switch (fmt) {
        !          10748:                 case 0x0:
        !          10749:                     gen_cmp_s(ctx, cond, rt, rs, cc);
        !          10750:                     break;
        !          10751:                 case 0x1:
        !          10752:                     gen_cmp_d(ctx, cond, rt, rs, cc);
        !          10753:                     break;
        !          10754:                 case 0x2:
        !          10755:                     gen_cmp_ps(ctx, cond, rt, rs, cc);
        !          10756:                     break;
        !          10757:                 default:
        !          10758:                     goto pool32f_invalid;
        !          10759:                 }
        !          10760:                 break;
        !          10761:             case POOL32FXF:
        !          10762:                 gen_pool32fxf(env, ctx, rt, rs);
        !          10763:                 break;
        !          10764:             case 0x00:
        !          10765:                 /* PLL foo */
        !          10766:                 switch ((ctx->opcode >> 6) & 0x7) {
        !          10767:                 case PLL_PS:
        !          10768:                     mips32_op = OPC_PLL_PS;
        !          10769:                     goto do_ps;
        !          10770:                 case PLU_PS:
        !          10771:                     mips32_op = OPC_PLU_PS;
        !          10772:                     goto do_ps;
        !          10773:                 case PUL_PS:
        !          10774:                     mips32_op = OPC_PUL_PS;
        !          10775:                     goto do_ps;
        !          10776:                 case PUU_PS:
        !          10777:                     mips32_op = OPC_PUU_PS;
        !          10778:                     goto do_ps;
        !          10779:                 case CVT_PS_S:
        !          10780:                     mips32_op = OPC_CVT_PS_S;
        !          10781:                 do_ps:
        !          10782:                     gen_farith(ctx, mips32_op, rt, rs, rd, 0);
        !          10783:                     break;
        !          10784:                 default:
        !          10785:                     goto pool32f_invalid;
        !          10786:                 }
        !          10787:                 break;
        !          10788:             case 0x08:
        !          10789:                 /* [LS][WDU]XC1 */
        !          10790:                 switch ((ctx->opcode >> 6) & 0x7) {
        !          10791:                 case LWXC1:
        !          10792:                     mips32_op = OPC_LWXC1;
        !          10793:                     goto do_ldst_cp1;
        !          10794:                 case SWXC1:
        !          10795:                     mips32_op = OPC_SWXC1;
        !          10796:                     goto do_ldst_cp1;
        !          10797:                 case LDXC1:
        !          10798:                     mips32_op = OPC_LDXC1;
        !          10799:                     goto do_ldst_cp1;
        !          10800:                 case SDXC1:
        !          10801:                     mips32_op = OPC_SDXC1;
        !          10802:                     goto do_ldst_cp1;
        !          10803:                 case LUXC1:
        !          10804:                     mips32_op = OPC_LUXC1;
        !          10805:                     goto do_ldst_cp1;
        !          10806:                 case SUXC1:
        !          10807:                     mips32_op = OPC_SUXC1;
        !          10808:                 do_ldst_cp1:
        !          10809:                     gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
        !          10810:                     break;
        !          10811:                 default:
        !          10812:                     goto pool32f_invalid;
        !          10813:                 }
        !          10814:                 break;
        !          10815:             case 0x18:
        !          10816:                 /* 3D insns */
        !          10817:                 fmt = (ctx->opcode >> 9) & 0x3;
        !          10818:                 switch ((ctx->opcode >> 6) & 0x7) {
        !          10819:                 case RSQRT2_FMT:
        !          10820:                     switch (fmt) {
        !          10821:                     case FMT_SDPS_S:
        !          10822:                         mips32_op = OPC_RSQRT2_S;
        !          10823:                         goto do_3d;
        !          10824:                     case FMT_SDPS_D:
        !          10825:                         mips32_op = OPC_RSQRT2_D;
        !          10826:                         goto do_3d;
        !          10827:                     case FMT_SDPS_PS:
        !          10828:                         mips32_op = OPC_RSQRT2_PS;
        !          10829:                         goto do_3d;
        !          10830:                     default:
        !          10831:                         goto pool32f_invalid;
        !          10832:                     }
        !          10833:                     break;
        !          10834:                 case RECIP2_FMT:
        !          10835:                     switch (fmt) {
        !          10836:                     case FMT_SDPS_S:
        !          10837:                         mips32_op = OPC_RECIP2_S;
        !          10838:                         goto do_3d;
        !          10839:                     case FMT_SDPS_D:
        !          10840:                         mips32_op = OPC_RECIP2_D;
        !          10841:                         goto do_3d;
        !          10842:                     case FMT_SDPS_PS:
        !          10843:                         mips32_op = OPC_RECIP2_PS;
        !          10844:                         goto do_3d;
        !          10845:                     default:
        !          10846:                         goto pool32f_invalid;
        !          10847:                     }
        !          10848:                     break;
        !          10849:                 case ADDR_PS:
        !          10850:                     mips32_op = OPC_ADDR_PS;
        !          10851:                     goto do_3d;
        !          10852:                 case MULR_PS:
        !          10853:                     mips32_op = OPC_MULR_PS;
        !          10854:                 do_3d:
        !          10855:                     gen_farith(ctx, mips32_op, rt, rs, rd, 0);
        !          10856:                     break;
        !          10857:                 default:
        !          10858:                     goto pool32f_invalid;
        !          10859:                 }
        !          10860:                 break;
        !          10861:             case 0x20:
        !          10862:                 /* MOV[FT].fmt and PREFX */
        !          10863:                 cc = (ctx->opcode >> 13) & 0x7;
        !          10864:                 fmt = (ctx->opcode >> 9) & 0x3;
        !          10865:                 switch ((ctx->opcode >> 6) & 0x7) {
        !          10866:                 case MOVF_FMT:
        !          10867:                     switch (fmt) {
        !          10868:                     case FMT_SDPS_S:
        !          10869:                         gen_movcf_s(rs, rt, cc, 0);
        !          10870:                         break;
        !          10871:                     case FMT_SDPS_D:
        !          10872:                         gen_movcf_d(ctx, rs, rt, cc, 0);
        !          10873:                         break;
        !          10874:                     case FMT_SDPS_PS:
        !          10875:                         gen_movcf_ps(rs, rt, cc, 0);
        !          10876:                         break;
        !          10877:                     default:
        !          10878:                         goto pool32f_invalid;
        !          10879:                     }
        !          10880:                     break;
        !          10881:                 case MOVT_FMT:
        !          10882:                     switch (fmt) {
        !          10883:                     case FMT_SDPS_S:
        !          10884:                         gen_movcf_s(rs, rt, cc, 1);
        !          10885:                         break;
        !          10886:                     case FMT_SDPS_D:
        !          10887:                         gen_movcf_d(ctx, rs, rt, cc, 1);
        !          10888:                         break;
        !          10889:                     case FMT_SDPS_PS:
        !          10890:                         gen_movcf_ps(rs, rt, cc, 1);
        !          10891:                         break;
        !          10892:                     default:
        !          10893:                         goto pool32f_invalid;
        !          10894:                     }
        !          10895:                     break;
        !          10896:                 case PREFX:
        !          10897:                     break;
        !          10898:                 default:
        !          10899:                     goto pool32f_invalid;
        !          10900:                 }
        !          10901:                 break;
        !          10902: #define FINSN_3ARG_SDPS(prfx)                           \
        !          10903:                 switch ((ctx->opcode >> 8) & 0x3) {     \
        !          10904:                 case FMT_SDPS_S:                        \
        !          10905:                     mips32_op = OPC_##prfx##_S;         \
        !          10906:                     goto do_fpop;                       \
        !          10907:                 case FMT_SDPS_D:                        \
        !          10908:                     mips32_op = OPC_##prfx##_D;         \
        !          10909:                     goto do_fpop;                       \
        !          10910:                 case FMT_SDPS_PS:                       \
        !          10911:                     mips32_op = OPC_##prfx##_PS;        \
        !          10912:                     goto do_fpop;                       \
        !          10913:                 default:                                \
        !          10914:                     goto pool32f_invalid;               \
        !          10915:                 }
        !          10916:             case 0x30:
        !          10917:                 /* regular FP ops */
        !          10918:                 switch ((ctx->opcode >> 6) & 0x3) {
        !          10919:                 case ADD_FMT:
        !          10920:                     FINSN_3ARG_SDPS(ADD);
        !          10921:                     break;
        !          10922:                 case SUB_FMT:
        !          10923:                     FINSN_3ARG_SDPS(SUB);
        !          10924:                     break;
        !          10925:                 case MUL_FMT:
        !          10926:                     FINSN_3ARG_SDPS(MUL);
        !          10927:                     break;
        !          10928:                 case DIV_FMT:
        !          10929:                     fmt = (ctx->opcode >> 8) & 0x3;
        !          10930:                     if (fmt == 1) {
        !          10931:                         mips32_op = OPC_DIV_D;
        !          10932:                     } else if (fmt == 0) {
        !          10933:                         mips32_op = OPC_DIV_S;
        !          10934:                     } else {
        !          10935:                         goto pool32f_invalid;
        !          10936:                     }
        !          10937:                     goto do_fpop;
        !          10938:                 default:
        !          10939:                     goto pool32f_invalid;
        !          10940:                 }
        !          10941:                 break;
        !          10942:             case 0x38:
        !          10943:                 /* cmovs */
        !          10944:                 switch ((ctx->opcode >> 6) & 0x3) {
        !          10945:                 case MOVN_FMT:
        !          10946:                     FINSN_3ARG_SDPS(MOVN);
        !          10947:                     break;
        !          10948:                 case MOVZ_FMT:
        !          10949:                     FINSN_3ARG_SDPS(MOVZ);
        !          10950:                     break;
        !          10951:                 default:
        !          10952:                     goto pool32f_invalid;
        !          10953:                 }
        !          10954:                 break;
        !          10955:             do_fpop:
        !          10956:                 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
        !          10957:                 break;
        !          10958:             default:
        !          10959:             pool32f_invalid:
        !          10960:                 MIPS_INVAL("pool32f");
        !          10961:                 generate_exception(ctx, EXCP_RI);
        !          10962:                 break;
        !          10963:             }
        !          10964:         } else {
        !          10965:             generate_exception_err(ctx, EXCP_CpU, 1);
        !          10966:         }
        !          10967:         break;
        !          10968:     case POOL32I:
        !          10969:         minor = (ctx->opcode >> 21) & 0x1f;
        !          10970:         switch (minor) {
        !          10971:         case BLTZ:
        !          10972:             mips32_op = OPC_BLTZ;
        !          10973:             goto do_branch;
        !          10974:         case BLTZAL:
        !          10975:             mips32_op = OPC_BLTZAL;
        !          10976:             goto do_branch;
        !          10977:         case BLTZALS:
        !          10978:             mips32_op = OPC_BLTZALS;
        !          10979:             goto do_branch;
        !          10980:         case BGEZ:
        !          10981:             mips32_op = OPC_BGEZ;
        !          10982:             goto do_branch;
        !          10983:         case BGEZAL:
        !          10984:             mips32_op = OPC_BGEZAL;
        !          10985:             goto do_branch;
        !          10986:         case BGEZALS:
        !          10987:             mips32_op = OPC_BGEZALS;
        !          10988:             goto do_branch;
        !          10989:         case BLEZ:
        !          10990:             mips32_op = OPC_BLEZ;
        !          10991:             goto do_branch;
        !          10992:         case BGTZ:
        !          10993:             mips32_op = OPC_BGTZ;
        !          10994:         do_branch:
        !          10995:             gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
        !          10996:             *is_branch = 1;
        !          10997:             break;
        !          10998: 
        !          10999:             /* Traps */
        !          11000:         case TLTI:
        !          11001:             mips32_op = OPC_TLTI;
        !          11002:             goto do_trapi;
        !          11003:         case TGEI:
        !          11004:             mips32_op = OPC_TGEI;
        !          11005:             goto do_trapi;
        !          11006:         case TLTIU:
        !          11007:             mips32_op = OPC_TLTIU;
        !          11008:             goto do_trapi;
        !          11009:         case TGEIU:
        !          11010:             mips32_op = OPC_TGEIU;
        !          11011:             goto do_trapi;
        !          11012:         case TNEI:
        !          11013:             mips32_op = OPC_TNEI;
        !          11014:             goto do_trapi;
        !          11015:         case TEQI:
        !          11016:             mips32_op = OPC_TEQI;
        !          11017:         do_trapi:
        !          11018:             gen_trap(ctx, mips32_op, rs, -1, imm);
        !          11019:             break;
        !          11020: 
        !          11021:         case BNEZC:
        !          11022:         case BEQZC:
        !          11023:             gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
        !          11024:                                4, rs, 0, imm << 1);
        !          11025:             /* Compact branches don't have a delay slot, so just let
        !          11026:                the normal delay slot handling take us to the branch
        !          11027:                target. */
        !          11028:             break;
        !          11029:         case LUI:
        !          11030:             gen_logic_imm(env, OPC_LUI, rs, -1, imm);
        !          11031:             break;
        !          11032:         case SYNCI:
        !          11033:             break;
        !          11034:         case BC2F:
        !          11035:         case BC2T:
        !          11036:             /* COP2: Not implemented. */
        !          11037:             generate_exception_err(ctx, EXCP_CpU, 2);
        !          11038:             break;
        !          11039:         case BC1F:
        !          11040:             mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
        !          11041:             goto do_cp1branch;
        !          11042:         case BC1T:
        !          11043:             mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
        !          11044:             goto do_cp1branch;
        !          11045:         case BC1ANY4F:
        !          11046:             mips32_op = OPC_BC1FANY4;
        !          11047:             goto do_cp1mips3d;
        !          11048:         case BC1ANY4T:
        !          11049:             mips32_op = OPC_BC1TANY4;
        !          11050:         do_cp1mips3d:
        !          11051:             check_cop1x(ctx);
        !          11052:             check_insn(env, ctx, ASE_MIPS3D);
        !          11053:             /* Fall through */
        !          11054:         do_cp1branch:
        !          11055:             gen_compute_branch1(env, ctx, mips32_op,
        !          11056:                                 (ctx->opcode >> 18) & 0x7, imm << 1);
        !          11057:             *is_branch = 1;
        !          11058:             break;
        !          11059:         case BPOSGE64:
        !          11060:         case BPOSGE32:
        !          11061:             /* MIPS DSP: not implemented */
        !          11062:             /* Fall through */
        !          11063:         default:
        !          11064:             MIPS_INVAL("pool32i");
        !          11065:             generate_exception(ctx, EXCP_RI);
        !          11066:             break;
        !          11067:         }
        !          11068:         break;
        !          11069:     case POOL32C:
        !          11070:         minor = (ctx->opcode >> 12) & 0xf;
        !          11071:         switch (minor) {
        !          11072:         case LWL:
        !          11073:             mips32_op = OPC_LWL;
        !          11074:             goto do_ld_lr;
        !          11075:         case SWL:
        !          11076:             mips32_op = OPC_SWL;
        !          11077:             goto do_st_lr;
        !          11078:         case LWR:
        !          11079:             mips32_op = OPC_LWR;
        !          11080:             goto do_ld_lr;
        !          11081:         case SWR:
        !          11082:             mips32_op = OPC_SWR;
        !          11083:             goto do_st_lr;
        !          11084: #if defined(TARGET_MIPS64)
        !          11085:         case LDL:
        !          11086:             mips32_op = OPC_LDL;
        !          11087:             goto do_ld_lr;
        !          11088:         case SDL:
        !          11089:             mips32_op = OPC_SDL;
        !          11090:             goto do_st_lr;
        !          11091:         case LDR:
        !          11092:             mips32_op = OPC_LDR;
        !          11093:             goto do_ld_lr;
        !          11094:         case SDR:
        !          11095:             mips32_op = OPC_SDR;
        !          11096:             goto do_st_lr;
        !          11097:         case LWU:
        !          11098:             mips32_op = OPC_LWU;
        !          11099:             goto do_ld_lr;
        !          11100:         case LLD:
        !          11101:             mips32_op = OPC_LLD;
        !          11102:             goto do_ld_lr;
        !          11103: #endif
        !          11104:         case LL:
        !          11105:             mips32_op = OPC_LL;
        !          11106:             goto do_ld_lr;
        !          11107:         do_ld_lr:
        !          11108:             gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
        !          11109:             break;
        !          11110:         do_st_lr:
        !          11111:             gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
        !          11112:             break;
        !          11113:         case SC:
        !          11114:             gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
        !          11115:             break;
        !          11116: #if defined(TARGET_MIPS64)
        !          11117:         case SCD:
        !          11118:             gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
        !          11119:             break;
        !          11120: #endif
        !          11121:         case PREF:
        !          11122:             /* Treat as no-op */
        !          11123:             break;
        !          11124:         default:
        !          11125:             MIPS_INVAL("pool32c");
        !          11126:             generate_exception(ctx, EXCP_RI);
        !          11127:             break;
        !          11128:         }
        !          11129:         break;
        !          11130:     case ADDI32:
        !          11131:         mips32_op = OPC_ADDI;
        !          11132:         goto do_addi;
        !          11133:     case ADDIU32:
        !          11134:         mips32_op = OPC_ADDIU;
        !          11135:     do_addi:
        !          11136:         gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
        !          11137:         break;
        !          11138: 
        !          11139:         /* Logical operations */
        !          11140:     case ORI32:
        !          11141:         mips32_op = OPC_ORI;
        !          11142:         goto do_logici;
        !          11143:     case XORI32:
        !          11144:         mips32_op = OPC_XORI;
        !          11145:         goto do_logici;
        !          11146:     case ANDI32:
        !          11147:         mips32_op = OPC_ANDI;
        !          11148:     do_logici:
        !          11149:         gen_logic_imm(env, mips32_op, rt, rs, imm);
        !          11150:         break;
        !          11151: 
        !          11152:         /* Set less than immediate */
        !          11153:     case SLTI32:
        !          11154:         mips32_op = OPC_SLTI;
        !          11155:         goto do_slti;
        !          11156:     case SLTIU32:
        !          11157:         mips32_op = OPC_SLTIU;
        !          11158:     do_slti:
        !          11159:         gen_slt_imm(env, mips32_op, rt, rs, imm);
        !          11160:         break;
        !          11161:     case JALX32:
        !          11162:         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
        !          11163:         gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
        !          11164:         *is_branch = 1;
        !          11165:         break;
        !          11166:     case JALS32:
        !          11167:         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
        !          11168:         gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
        !          11169:         *is_branch = 1;
        !          11170:         break;
        !          11171:     case BEQ32:
        !          11172:         gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
        !          11173:         *is_branch = 1;
        !          11174:         break;
        !          11175:     case BNE32:
        !          11176:         gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
        !          11177:         *is_branch = 1;
        !          11178:         break;
        !          11179:     case J32:
        !          11180:         gen_compute_branch(ctx, OPC_J, 4, rt, rs,
        !          11181:                            (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
        !          11182:         *is_branch = 1;
        !          11183:         break;
        !          11184:     case JAL32:
        !          11185:         gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
        !          11186:                            (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
        !          11187:         *is_branch = 1;
        !          11188:         break;
        !          11189:         /* Floating point (COP1) */
        !          11190:     case LWC132:
        !          11191:         mips32_op = OPC_LWC1;
        !          11192:         goto do_cop1;
        !          11193:     case LDC132:
        !          11194:         mips32_op = OPC_LDC1;
        !          11195:         goto do_cop1;
        !          11196:     case SWC132:
        !          11197:         mips32_op = OPC_SWC1;
        !          11198:         goto do_cop1;
        !          11199:     case SDC132:
        !          11200:         mips32_op = OPC_SDC1;
        !          11201:     do_cop1:
        !          11202:         gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
        !          11203:         break;
        !          11204:     case ADDIUPC:
        !          11205:         {
        !          11206:             int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
        !          11207:             int offset = SIMM(ctx->opcode, 0, 23) << 2;
        !          11208: 
        !          11209:             gen_addiupc(ctx, reg, offset, 0, 0);
        !          11210:         }
        !          11211:         break;
        !          11212:         /* Loads and stores */
        !          11213:     case LB32:
        !          11214:         mips32_op = OPC_LB;
        !          11215:         goto do_ld;
        !          11216:     case LBU32:
        !          11217:         mips32_op = OPC_LBU;
        !          11218:         goto do_ld;
        !          11219:     case LH32:
        !          11220:         mips32_op = OPC_LH;
        !          11221:         goto do_ld;
        !          11222:     case LHU32:
        !          11223:         mips32_op = OPC_LHU;
        !          11224:         goto do_ld;
        !          11225:     case LW32:
        !          11226:         mips32_op = OPC_LW;
        !          11227:         goto do_ld;
        !          11228: #ifdef TARGET_MIPS64
        !          11229:     case LD32:
        !          11230:         mips32_op = OPC_LD;
        !          11231:         goto do_ld;
        !          11232:     case SD32:
        !          11233:         mips32_op = OPC_SD;
        !          11234:         goto do_st;
        !          11235: #endif
        !          11236:     case SB32:
        !          11237:         mips32_op = OPC_SB;
        !          11238:         goto do_st;
        !          11239:     case SH32:
        !          11240:         mips32_op = OPC_SH;
        !          11241:         goto do_st;
        !          11242:     case SW32:
        !          11243:         mips32_op = OPC_SW;
        !          11244:         goto do_st;
        !          11245:     do_ld:
        !          11246:         gen_ld(env, ctx, mips32_op, rt, rs, imm);
        !          11247:         break;
        !          11248:     do_st:
        !          11249:         gen_st(ctx, mips32_op, rt, rs, imm);
        !          11250:         break;
        !          11251:     default:
        !          11252:         generate_exception(ctx, EXCP_RI);
        !          11253:         break;
        !          11254:     }
        !          11255: }
        !          11256: 
        !          11257: static int decode_micromips_opc (CPUState *env, DisasContext *ctx, int *is_branch)
        !          11258: {
        !          11259:     uint32_t op;
        !          11260: 
        !          11261:     /* make sure instructions are on a halfword boundary */
        !          11262:     if (ctx->pc & 0x1) {
        !          11263:         env->CP0_BadVAddr = ctx->pc;
        !          11264:         generate_exception(ctx, EXCP_AdEL);
        !          11265:         ctx->bstate = BS_STOP;
        !          11266:         return 2;
        !          11267:     }
        !          11268: 
        !          11269:     op = (ctx->opcode >> 10) & 0x3f;
        !          11270:     /* Enforce properly-sized instructions in a delay slot */
        !          11271:     if (ctx->hflags & MIPS_HFLAG_BMASK) {
        !          11272:         int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
        !          11273: 
        !          11274:         switch (op) {
        !          11275:         case POOL32A:
        !          11276:         case POOL32B:
        !          11277:         case POOL32I:
        !          11278:         case POOL32C:
        !          11279:         case ADDI32:
        !          11280:         case ADDIU32:
        !          11281:         case ORI32:
        !          11282:         case XORI32:
        !          11283:         case SLTI32:
        !          11284:         case SLTIU32:
        !          11285:         case ANDI32:
        !          11286:         case JALX32:
        !          11287:         case LBU32:
        !          11288:         case LHU32:
        !          11289:         case POOL32F:
        !          11290:         case JALS32:
        !          11291:         case BEQ32:
        !          11292:         case BNE32:
        !          11293:         case J32:
        !          11294:         case JAL32:
        !          11295:         case SB32:
        !          11296:         case SH32:
        !          11297:         case POOL32S:
        !          11298:         case ADDIUPC:
        !          11299:         case SWC132:
        !          11300:         case SDC132:
        !          11301:         case SD32:
        !          11302:         case SW32:
        !          11303:         case LB32:
        !          11304:         case LH32:
        !          11305:         case DADDIU32:
        !          11306:         case POOL48A:           /* ??? */
        !          11307:         case LWC132:
        !          11308:         case LDC132:
        !          11309:         case LD32:
        !          11310:         case LW32:
        !          11311:             if (bits & MIPS_HFLAG_BDS16) {
        !          11312:                 generate_exception(ctx, EXCP_RI);
        !          11313:                 /* Just stop translation; the user is confused.  */
        !          11314:                 ctx->bstate = BS_STOP;
        !          11315:                 return 2;
        !          11316:             }
        !          11317:             break;
        !          11318:         case POOL16A:
        !          11319:         case POOL16B:
        !          11320:         case POOL16C:
        !          11321:         case LWGP16:
        !          11322:         case POOL16F:
        !          11323:         case LBU16:
        !          11324:         case LHU16:
        !          11325:         case LWSP16:
        !          11326:         case LW16:
        !          11327:         case SB16:
        !          11328:         case SH16:
        !          11329:         case SWSP16:
        !          11330:         case SW16:
        !          11331:         case MOVE16:
        !          11332:         case ANDI16:
        !          11333:         case POOL16D:
        !          11334:         case POOL16E:
        !          11335:         case BEQZ16:
        !          11336:         case BNEZ16:
        !          11337:         case B16:
        !          11338:         case LI16:
        !          11339:             if (bits & MIPS_HFLAG_BDS32) {
        !          11340:                 generate_exception(ctx, EXCP_RI);
        !          11341:                 /* Just stop translation; the user is confused.  */
        !          11342:                 ctx->bstate = BS_STOP;
        !          11343:                 return 2;
        !          11344:             }
        !          11345:             break;
        !          11346:         default:
        !          11347:             break;
        !          11348:         }
        !          11349:     }
        !          11350:     switch (op) {
        !          11351:     case POOL16A:
        !          11352:         {
        !          11353:             int rd = mmreg(uMIPS_RD(ctx->opcode));
        !          11354:             int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
        !          11355:             int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
        !          11356:             uint32_t opc = 0;
        !          11357: 
        !          11358:             switch (ctx->opcode & 0x1) {
        !          11359:             case ADDU16:
        !          11360:                 opc = OPC_ADDU;
        !          11361:                 break;
        !          11362:             case SUBU16:
        !          11363:                 opc = OPC_SUBU;
        !          11364:                 break;
        !          11365:             }
        !          11366: 
        !          11367:             gen_arith(env, ctx, opc, rd, rs1, rs2);
        !          11368:         }
        !          11369:         break;
        !          11370:     case POOL16B:
        !          11371:         {
        !          11372:             int rd = mmreg(uMIPS_RD(ctx->opcode));
        !          11373:             int rs = mmreg(uMIPS_RS(ctx->opcode));
        !          11374:             int amount = (ctx->opcode >> 1) & 0x7;
        !          11375:             uint32_t opc = 0;
        !          11376:             amount = amount == 0 ? 8 : amount;
        !          11377: 
        !          11378:             switch (ctx->opcode & 0x1) {
        !          11379:             case SLL16:
        !          11380:                 opc = OPC_SLL;
        !          11381:                 break;
        !          11382:             case SRL16:
        !          11383:                 opc = OPC_SRL;
        !          11384:                 break;
        !          11385:             }
        !          11386: 
        !          11387:             gen_shift_imm(env, ctx, opc, rd, rs, amount);
        !          11388:         }
        !          11389:         break;
        !          11390:     case POOL16C:
        !          11391:         gen_pool16c_insn(env, ctx, is_branch);
        !          11392:         break;
        !          11393:     case LWGP16:
        !          11394:         {
        !          11395:             int rd = mmreg(uMIPS_RD(ctx->opcode));
        !          11396:             int rb = 28;            /* GP */
        !          11397:             int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
        !          11398: 
        !          11399:             gen_ld(env, ctx, OPC_LW, rd, rb, offset);
        !          11400:         }
        !          11401:         break;
        !          11402:     case POOL16F:
        !          11403:         if (ctx->opcode & 1) {
        !          11404:             generate_exception(ctx, EXCP_RI);
        !          11405:         } else {
        !          11406:             /* MOVEP */
        !          11407:             int enc_dest = uMIPS_RD(ctx->opcode);
        !          11408:             int enc_rt = uMIPS_RS2(ctx->opcode);
        !          11409:             int enc_rs = uMIPS_RS1(ctx->opcode);
        !          11410:             int rd, rs, re, rt;
        !          11411:             static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
        !          11412:             static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
        !          11413:             static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
        !          11414: 
        !          11415:             rd = rd_enc[enc_dest];
        !          11416:             re = re_enc[enc_dest];
        !          11417:             rs = rs_rt_enc[enc_rs];
        !          11418:             rt = rs_rt_enc[enc_rt];
        !          11419: 
        !          11420:             gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
        !          11421:             gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
        !          11422:         }
        !          11423:         break;
        !          11424:     case LBU16:
        !          11425:         {
        !          11426:             int rd = mmreg(uMIPS_RD(ctx->opcode));
        !          11427:             int rb = mmreg(uMIPS_RS(ctx->opcode));
        !          11428:             int16_t offset = ZIMM(ctx->opcode, 0, 4);
        !          11429:             offset = (offset == 0xf ? -1 : offset);
        !          11430: 
        !          11431:             gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
        !          11432:         }
        !          11433:         break;
        !          11434:     case LHU16:
        !          11435:         {
        !          11436:             int rd = mmreg(uMIPS_RD(ctx->opcode));
        !          11437:             int rb = mmreg(uMIPS_RS(ctx->opcode));
        !          11438:             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
        !          11439: 
        !          11440:             gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
        !          11441:         }
        !          11442:         break;
        !          11443:     case LWSP16:
        !          11444:         {
        !          11445:             int rd = (ctx->opcode >> 5) & 0x1f;
        !          11446:             int rb = 29;            /* SP */
        !          11447:             int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
        !          11448: 
        !          11449:             gen_ld(env, ctx, OPC_LW, rd, rb, offset);
        !          11450:         }
        !          11451:         break;
        !          11452:     case LW16:
        !          11453:         {
        !          11454:             int rd = mmreg(uMIPS_RD(ctx->opcode));
        !          11455:             int rb = mmreg(uMIPS_RS(ctx->opcode));
        !          11456:             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
        !          11457: 
        !          11458:             gen_ld(env, ctx, OPC_LW, rd, rb, offset);
        !          11459:         }
        !          11460:         break;
        !          11461:     case SB16:
        !          11462:         {
        !          11463:             int rd = mmreg2(uMIPS_RD(ctx->opcode));
        !          11464:             int rb = mmreg(uMIPS_RS(ctx->opcode));
        !          11465:             int16_t offset = ZIMM(ctx->opcode, 0, 4);
        !          11466: 
        !          11467:             gen_st(ctx, OPC_SB, rd, rb, offset);
        !          11468:         }
        !          11469:         break;
        !          11470:     case SH16:
        !          11471:         {
        !          11472:             int rd = mmreg2(uMIPS_RD(ctx->opcode));
        !          11473:             int rb = mmreg(uMIPS_RS(ctx->opcode));
        !          11474:             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
        !          11475: 
        !          11476:             gen_st(ctx, OPC_SH, rd, rb, offset);
        !          11477:         }
        !          11478:         break;
        !          11479:     case SWSP16:
        !          11480:         {
        !          11481:             int rd = (ctx->opcode >> 5) & 0x1f;
        !          11482:             int rb = 29;            /* SP */
        !          11483:             int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
        !          11484: 
        !          11485:             gen_st(ctx, OPC_SW, rd, rb, offset);
        !          11486:         }
        !          11487:         break;
        !          11488:     case SW16:
        !          11489:         {
        !          11490:             int rd = mmreg2(uMIPS_RD(ctx->opcode));
        !          11491:             int rb = mmreg(uMIPS_RS(ctx->opcode));
        !          11492:             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
        !          11493: 
        !          11494:             gen_st(ctx, OPC_SW, rd, rb, offset);
        !          11495:         }
        !          11496:         break;
        !          11497:     case MOVE16:
        !          11498:         {
        !          11499:             int rd = uMIPS_RD5(ctx->opcode);
        !          11500:             int rs = uMIPS_RS5(ctx->opcode);
        !          11501: 
        !          11502:             gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
        !          11503:         }
        !          11504:         break;
        !          11505:     case ANDI16:
        !          11506:         gen_andi16(env, ctx);
        !          11507:         break;
        !          11508:     case POOL16D:
        !          11509:         switch (ctx->opcode & 0x1) {
        !          11510:         case ADDIUS5:
        !          11511:             gen_addius5(env, ctx);
        !          11512:             break;
        !          11513:         case ADDIUSP:
        !          11514:             gen_addiusp(env, ctx);
        !          11515:             break;
        !          11516:         }
        !          11517:         break;
        !          11518:     case POOL16E:
        !          11519:         switch (ctx->opcode & 0x1) {
        !          11520:         case ADDIUR2:
        !          11521:             gen_addiur2(env, ctx);
        !          11522:             break;
        !          11523:         case ADDIUR1SP:
        !          11524:             gen_addiur1sp(env, ctx);
        !          11525:             break;
        !          11526:         }
        !          11527:         break;
        !          11528:     case B16:
        !          11529:         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
        !          11530:                            SIMM(ctx->opcode, 0, 10) << 1);
        !          11531:         *is_branch = 1;
        !          11532:         break;
        !          11533:     case BNEZ16:
        !          11534:     case BEQZ16:
        !          11535:         gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
        !          11536:                            mmreg(uMIPS_RD(ctx->opcode)),
        !          11537:                            0, SIMM(ctx->opcode, 0, 7) << 1);
        !          11538:         *is_branch = 1;
        !          11539:         break;
        !          11540:     case LI16:
        !          11541:         {
        !          11542:             int reg = mmreg(uMIPS_RD(ctx->opcode));
        !          11543:             int imm = ZIMM(ctx->opcode, 0, 7);
        !          11544: 
        !          11545:             imm = (imm == 0x7f ? -1 : imm);
        !          11546:             tcg_gen_movi_tl(cpu_gpr[reg], imm);
        !          11547:         }
        !          11548:         break;
        !          11549:     case RES_20:
        !          11550:     case RES_28:
        !          11551:     case RES_29:
        !          11552:     case RES_30:
        !          11553:     case RES_31:
        !          11554:     case RES_38:
        !          11555:     case RES_39:
        !          11556:         generate_exception(ctx, EXCP_RI);
        !          11557:         break;
        !          11558:     default:
        !          11559:         decode_micromips32_opc (env, ctx, op, is_branch);
        !          11560:         return 4;
        !          11561:     }
        !          11562: 
        !          11563:     return 2;
        !          11564: }
        !          11565: 
        !          11566: /* SmartMIPS extension to MIPS32 */
        !          11567: 
        !          11568: #if defined(TARGET_MIPS64)
        !          11569: 
        !          11570: /* MDMX extension to MIPS64 */
        !          11571: 
        !          11572: #endif
        !          11573: 
        !          11574: static void decode_opc (CPUState *env, DisasContext *ctx, int *is_branch)
        !          11575: {
        !          11576:     int32_t offset;
        !          11577:     int rs, rt, rd, sa;
        !          11578:     uint32_t op, op1, op2;
        !          11579:     int16_t imm;
        !          11580: 
        !          11581:     /* make sure instructions are on a word boundary */
        !          11582:     if (ctx->pc & 0x3) {
        !          11583:         env->CP0_BadVAddr = ctx->pc;
        !          11584:         generate_exception(ctx, EXCP_AdEL);
        !          11585:         return;
        !          11586:     }
        !          11587: 
        !          11588:     /* Handle blikely not taken case */
        !          11589:     if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
        !          11590:         int l1 = gen_new_label();
        !          11591: 
        !          11592:         MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
1.1.1.8   root     11593:         tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
                   11594:         tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
1.1.1.6   root     11595:         gen_goto_tb(ctx, 1, ctx->pc + 4);
                   11596:         gen_set_label(l1);
1.1       root     11597:     }
1.1.1.9   root     11598: 
                   11599:     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
                   11600:         tcg_gen_debug_insn_start(ctx->pc);
                   11601: 
1.1.1.5   root     11602:     op = MASK_OP_MAJOR(ctx->opcode);
                   11603:     rs = (ctx->opcode >> 21) & 0x1f;
                   11604:     rt = (ctx->opcode >> 16) & 0x1f;
                   11605:     rd = (ctx->opcode >> 11) & 0x1f;
                   11606:     sa = (ctx->opcode >> 6) & 0x1f;
1.1       root     11607:     imm = (int16_t)ctx->opcode;
                   11608:     switch (op) {
1.1.1.5   root     11609:     case OPC_SPECIAL:
                   11610:         op1 = MASK_SPECIAL(ctx->opcode);
1.1       root     11611:         switch (op1) {
1.1.1.8   root     11612:         case OPC_SLL:          /* Shift with immediate */
                   11613:         case OPC_SRA:
                   11614:             gen_shift_imm(env, ctx, op1, rd, rt, sa);
1.1.1.5   root     11615:             break;
1.1.1.12! root     11616:         case OPC_SRL:
        !          11617:             switch ((ctx->opcode >> 21) & 0x1f) {
        !          11618:             case 1:
        !          11619:                 /* rotr is decoded as srl on non-R2 CPUs */
        !          11620:                 if (env->insn_flags & ISA_MIPS32R2) {
        !          11621:                     op1 = OPC_ROTR;
        !          11622:                 }
        !          11623:                 /* Fallthrough */
        !          11624:             case 0:
        !          11625:                 gen_shift_imm(env, ctx, op1, rd, rt, sa);
        !          11626:                 break;
        !          11627:             default:
        !          11628:                 generate_exception(ctx, EXCP_RI);
        !          11629:                 break;
        !          11630:             }
        !          11631:             break;
1.1.1.8   root     11632:         case OPC_MOVN:         /* Conditional move */
                   11633:         case OPC_MOVZ:
1.1.1.12! root     11634:             check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
        !          11635:                                  INSN_LOONGSON2E | INSN_LOONGSON2F);
1.1.1.8   root     11636:             gen_cond_move(env, op1, rd, rs, rt);
                   11637:             break;
                   11638:         case OPC_ADD ... OPC_SUBU:
1.1.1.6   root     11639:             gen_arith(env, ctx, op1, rd, rs, rt);
1.1       root     11640:             break;
1.1.1.8   root     11641:         case OPC_SLLV:         /* Shifts */
                   11642:         case OPC_SRAV:
                   11643:             gen_shift(env, ctx, op1, rd, rs, rt);
                   11644:             break;
1.1.1.12! root     11645:         case OPC_SRLV:
        !          11646:             switch ((ctx->opcode >> 6) & 0x1f) {
        !          11647:             case 1:
        !          11648:                 /* rotrv is decoded as srlv on non-R2 CPUs */
        !          11649:                 if (env->insn_flags & ISA_MIPS32R2) {
        !          11650:                     op1 = OPC_ROTRV;
        !          11651:                 }
        !          11652:                 /* Fallthrough */
        !          11653:             case 0:
        !          11654:                 gen_shift(env, ctx, op1, rd, rs, rt);
        !          11655:                 break;
        !          11656:             default:
        !          11657:                 generate_exception(ctx, EXCP_RI);
        !          11658:                 break;
        !          11659:             }
        !          11660:             break;
1.1.1.8   root     11661:         case OPC_SLT:          /* Set on less than */
                   11662:         case OPC_SLTU:
                   11663:             gen_slt(env, op1, rd, rs, rt);
                   11664:             break;
                   11665:         case OPC_AND:          /* Logic*/
                   11666:         case OPC_OR:
                   11667:         case OPC_NOR:
                   11668:         case OPC_XOR:
                   11669:             gen_logic(env, op1, rd, rs, rt);
                   11670:             break;
1.1.1.5   root     11671:         case OPC_MULT ... OPC_DIVU:
1.1.1.6   root     11672:             if (sa) {
                   11673:                 check_insn(env, ctx, INSN_VR54XX);
                   11674:                 op1 = MASK_MUL_VR54XX(ctx->opcode);
                   11675:                 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
                   11676:             } else
                   11677:                 gen_muldiv(ctx, op1, rs, rt);
1.1       root     11678:             break;
1.1.1.5   root     11679:         case OPC_JR ... OPC_JALR:
1.1.1.12! root     11680:             gen_compute_branch(ctx, op1, 4, rs, rd, sa);
        !          11681:             *is_branch = 1;
        !          11682:             break;
1.1.1.5   root     11683:         case OPC_TGE ... OPC_TEQ: /* Traps */
                   11684:         case OPC_TNE:
                   11685:             gen_trap(ctx, op1, rs, rt, -1);
                   11686:             break;
                   11687:         case OPC_MFHI:          /* Move from HI/LO */
                   11688:         case OPC_MFLO:
                   11689:             gen_HILO(ctx, op1, rd);
1.1       root     11690:             break;
1.1.1.5   root     11691:         case OPC_MTHI:
                   11692:         case OPC_MTLO:          /* Move to HI/LO */
                   11693:             gen_HILO(ctx, op1, rs);
                   11694:             break;
1.1.1.6   root     11695:         case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
                   11696: #ifdef MIPS_STRICT_STANDARD
                   11697:             MIPS_INVAL("PMON / selsl");
                   11698:             generate_exception(ctx, EXCP_RI);
                   11699: #else
1.1.1.7   root     11700:             gen_helper_0i(pmon, sa);
1.1.1.6   root     11701: #endif
1.1.1.5   root     11702:             break;
                   11703:         case OPC_SYSCALL:
1.1       root     11704:             generate_exception(ctx, EXCP_SYSCALL);
1.1.1.8   root     11705:             ctx->bstate = BS_STOP;
1.1       root     11706:             break;
1.1.1.5   root     11707:         case OPC_BREAK:
1.1       root     11708:             generate_exception(ctx, EXCP_BREAK);
                   11709:             break;
1.1.1.6   root     11710:         case OPC_SPIM:
                   11711: #ifdef MIPS_STRICT_STANDARD
                   11712:             MIPS_INVAL("SPIM");
                   11713:             generate_exception(ctx, EXCP_RI);
                   11714: #else
1.1.1.5   root     11715:            /* Implemented as RI exception for now. */
                   11716:             MIPS_INVAL("spim (unofficial)");
                   11717:             generate_exception(ctx, EXCP_RI);
1.1.1.6   root     11718: #endif
1.1       root     11719:             break;
1.1.1.5   root     11720:         case OPC_SYNC:
1.1.1.6   root     11721:             /* Treat as NOP. */
1.1       root     11722:             break;
1.1.1.2   root     11723: 
1.1.1.5   root     11724:         case OPC_MOVCI:
1.1.1.6   root     11725:             check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
                   11726:             if (env->CP0_Config1 & (1 << CP0C1_FP)) {
                   11727:                 check_cp1_enabled(ctx);
                   11728:                 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
                   11729:                           (ctx->opcode >> 16) & 1);
                   11730:             } else {
                   11731:                 generate_exception_err(ctx, EXCP_CpU, 1);
                   11732:             }
1.1.1.2   root     11733:             break;
                   11734: 
1.1.1.6   root     11735: #if defined(TARGET_MIPS64)
1.1.1.5   root     11736:        /* MIPS64 specific opcodes */
                   11737:         case OPC_DSLL:
1.1.1.8   root     11738:         case OPC_DSRA:
1.1.1.5   root     11739:         case OPC_DSLL32:
1.1.1.8   root     11740:         case OPC_DSRA32:
1.1.1.6   root     11741:             check_insn(env, ctx, ISA_MIPS3);
                   11742:             check_mips_64(ctx);
1.1.1.8   root     11743:             gen_shift_imm(env, ctx, op1, rd, rt, sa);
1.1.1.5   root     11744:             break;
1.1.1.12! root     11745:         case OPC_DSRL:
        !          11746:             switch ((ctx->opcode >> 21) & 0x1f) {
        !          11747:             case 1:
        !          11748:                 /* drotr is decoded as dsrl on non-R2 CPUs */
        !          11749:                 if (env->insn_flags & ISA_MIPS32R2) {
        !          11750:                     op1 = OPC_DROTR;
        !          11751:                 }
        !          11752:                 /* Fallthrough */
        !          11753:             case 0:
        !          11754:                 check_insn(env, ctx, ISA_MIPS3);
        !          11755:                 check_mips_64(ctx);
        !          11756:                 gen_shift_imm(env, ctx, op1, rd, rt, sa);
        !          11757:                 break;
        !          11758:             default:
        !          11759:                 generate_exception(ctx, EXCP_RI);
        !          11760:                 break;
        !          11761:             }
        !          11762:             break;
        !          11763:         case OPC_DSRL32:
        !          11764:             switch ((ctx->opcode >> 21) & 0x1f) {
        !          11765:             case 1:
        !          11766:                 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
        !          11767:                 if (env->insn_flags & ISA_MIPS32R2) {
        !          11768:                     op1 = OPC_DROTR32;
        !          11769:                 }
        !          11770:                 /* Fallthrough */
        !          11771:             case 0:
        !          11772:                 check_insn(env, ctx, ISA_MIPS3);
        !          11773:                 check_mips_64(ctx);
        !          11774:                 gen_shift_imm(env, ctx, op1, rd, rt, sa);
        !          11775:                 break;
        !          11776:             default:
        !          11777:                 generate_exception(ctx, EXCP_RI);
        !          11778:                 break;
        !          11779:             }
        !          11780:             break;
1.1.1.5   root     11781:         case OPC_DADD ... OPC_DSUBU:
1.1.1.6   root     11782:             check_insn(env, ctx, ISA_MIPS3);
                   11783:             check_mips_64(ctx);
                   11784:             gen_arith(env, ctx, op1, rd, rs, rt);
1.1.1.5   root     11785:             break;
1.1.1.8   root     11786:         case OPC_DSLLV:
                   11787:         case OPC_DSRAV:
                   11788:             check_insn(env, ctx, ISA_MIPS3);
                   11789:             check_mips_64(ctx);
                   11790:             gen_shift(env, ctx, op1, rd, rs, rt);
                   11791:             break;
1.1.1.12! root     11792:         case OPC_DSRLV:
        !          11793:             switch ((ctx->opcode >> 6) & 0x1f) {
        !          11794:             case 1:
        !          11795:                 /* drotrv is decoded as dsrlv on non-R2 CPUs */
        !          11796:                 if (env->insn_flags & ISA_MIPS32R2) {
        !          11797:                     op1 = OPC_DROTRV;
        !          11798:                 }
        !          11799:                 /* Fallthrough */
        !          11800:             case 0:
        !          11801:                 check_insn(env, ctx, ISA_MIPS3);
        !          11802:                 check_mips_64(ctx);
        !          11803:                 gen_shift(env, ctx, op1, rd, rs, rt);
        !          11804:                 break;
        !          11805:             default:
        !          11806:                 generate_exception(ctx, EXCP_RI);
        !          11807:                 break;
        !          11808:             }
        !          11809:             break;
1.1.1.5   root     11810:         case OPC_DMULT ... OPC_DDIVU:
1.1.1.6   root     11811:             check_insn(env, ctx, ISA_MIPS3);
                   11812:             check_mips_64(ctx);
1.1.1.5   root     11813:             gen_muldiv(ctx, op1, rs, rt);
                   11814:             break;
1.1       root     11815: #endif
                   11816:         default:            /* Invalid */
                   11817:             MIPS_INVAL("special");
                   11818:             generate_exception(ctx, EXCP_RI);
                   11819:             break;
                   11820:         }
                   11821:         break;
1.1.1.5   root     11822:     case OPC_SPECIAL2:
                   11823:         op1 = MASK_SPECIAL2(ctx->opcode);
1.1       root     11824:         switch (op1) {
1.1.1.5   root     11825:         case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
                   11826:         case OPC_MSUB ... OPC_MSUBU:
1.1.1.6   root     11827:             check_insn(env, ctx, ISA_MIPS32);
1.1.1.5   root     11828:             gen_muldiv(ctx, op1, rs, rt);
1.1       root     11829:             break;
1.1.1.5   root     11830:         case OPC_MUL:
1.1.1.6   root     11831:             gen_arith(env, ctx, op1, rd, rs, rt);
1.1       root     11832:             break;
1.1.1.8   root     11833:         case OPC_CLO:
                   11834:         case OPC_CLZ:
1.1.1.6   root     11835:             check_insn(env, ctx, ISA_MIPS32);
1.1.1.5   root     11836:             gen_cl(ctx, op1, rd, rs);
1.1       root     11837:             break;
1.1.1.5   root     11838:         case OPC_SDBBP:
1.1       root     11839:             /* XXX: not clear which exception should be raised
                   11840:              *      when in debug mode...
                   11841:              */
1.1.1.6   root     11842:             check_insn(env, ctx, ISA_MIPS32);
1.1       root     11843:             if (!(ctx->hflags & MIPS_HFLAG_DM)) {
                   11844:                 generate_exception(ctx, EXCP_DBp);
                   11845:             } else {
                   11846:                 generate_exception(ctx, EXCP_DBp);
                   11847:             }
1.1.1.6   root     11848:             /* Treat as NOP. */
1.1       root     11849:             break;
1.1.1.12! root     11850:         case OPC_DIV_G_2F:
        !          11851:         case OPC_DIVU_G_2F:
        !          11852:         case OPC_MULT_G_2F:
        !          11853:         case OPC_MULTU_G_2F:
        !          11854:         case OPC_MOD_G_2F:
        !          11855:         case OPC_MODU_G_2F:
        !          11856:             check_insn(env, ctx, INSN_LOONGSON2F);
        !          11857:             gen_loongson_integer(ctx, op1, rd, rs, rt);
        !          11858:             break;
1.1.1.6   root     11859: #if defined(TARGET_MIPS64)
1.1.1.8   root     11860:         case OPC_DCLO:
                   11861:         case OPC_DCLZ:
1.1.1.6   root     11862:             check_insn(env, ctx, ISA_MIPS64);
                   11863:             check_mips_64(ctx);
1.1.1.5   root     11864:             gen_cl(ctx, op1, rd, rs);
                   11865:             break;
1.1.1.12! root     11866:         case OPC_DMULT_G_2F:
        !          11867:         case OPC_DMULTU_G_2F:
        !          11868:         case OPC_DDIV_G_2F:
        !          11869:         case OPC_DDIVU_G_2F:
        !          11870:         case OPC_DMOD_G_2F:
        !          11871:         case OPC_DMODU_G_2F:
        !          11872:             check_insn(env, ctx, INSN_LOONGSON2F);
        !          11873:             gen_loongson_integer(ctx, op1, rd, rs, rt);
        !          11874:             break;
1.1.1.5   root     11875: #endif
1.1       root     11876:         default:            /* Invalid */
                   11877:             MIPS_INVAL("special2");
                   11878:             generate_exception(ctx, EXCP_RI);
                   11879:             break;
                   11880:         }
                   11881:         break;
1.1.1.5   root     11882:     case OPC_SPECIAL3:
1.1.1.7   root     11883:         op1 = MASK_SPECIAL3(ctx->opcode);
                   11884:         switch (op1) {
                   11885:         case OPC_EXT:
                   11886:         case OPC_INS:
                   11887:             check_insn(env, ctx, ISA_MIPS32R2);
                   11888:             gen_bitops(ctx, op1, rt, rs, sa, rd);
                   11889:             break;
                   11890:         case OPC_BSHFL:
                   11891:             check_insn(env, ctx, ISA_MIPS32R2);
                   11892:             op2 = MASK_BSHFL(ctx->opcode);
                   11893:             gen_bshfl(ctx, op2, rt, rd);
1.1.1.6   root     11894:             break;
                   11895:         case OPC_RDHWR:
1.1.1.12! root     11896:             gen_rdhwr(env, ctx, rt, rd);
1.1.1.6   root     11897:             break;
                   11898:         case OPC_FORK:
                   11899:             check_insn(env, ctx, ASE_MT);
1.1.1.7   root     11900:             {
1.1.1.8   root     11901:                 TCGv t0 = tcg_temp_new();
                   11902:                 TCGv t1 = tcg_temp_new();
1.1.1.7   root     11903: 
                   11904:                 gen_load_gpr(t0, rt);
                   11905:                 gen_load_gpr(t1, rs);
                   11906:                 gen_helper_fork(t0, t1);
                   11907:                 tcg_temp_free(t0);
                   11908:                 tcg_temp_free(t1);
                   11909:             }
1.1.1.6   root     11910:             break;
                   11911:         case OPC_YIELD:
                   11912:             check_insn(env, ctx, ASE_MT);
1.1.1.7   root     11913:             {
1.1.1.8   root     11914:                 TCGv t0 = tcg_temp_new();
1.1.1.7   root     11915: 
1.1.1.8   root     11916:                 save_cpu_state(ctx, 1);
1.1.1.7   root     11917:                 gen_load_gpr(t0, rs);
                   11918:                 gen_helper_yield(t0, t0);
                   11919:                 gen_store_gpr(t0, rd);
                   11920:                 tcg_temp_free(t0);
                   11921:             }
1.1.1.6   root     11922:             break;
1.1.1.12! root     11923:         case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
        !          11924:         case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
        !          11925:         case OPC_MOD_G_2E ... OPC_MODU_G_2E:
        !          11926:             check_insn(env, ctx, INSN_LOONGSON2E);
        !          11927:             gen_loongson_integer(ctx, op1, rd, rs, rt);
        !          11928:             break;
1.1.1.6   root     11929: #if defined(TARGET_MIPS64)
                   11930:         case OPC_DEXTM ... OPC_DEXT:
                   11931:         case OPC_DINSM ... OPC_DINS:
                   11932:             check_insn(env, ctx, ISA_MIPS64R2);
                   11933:             check_mips_64(ctx);
1.1.1.5   root     11934:             gen_bitops(ctx, op1, rt, rs, sa, rd);
                   11935:             break;
1.1.1.6   root     11936:         case OPC_DBSHFL:
                   11937:             check_insn(env, ctx, ISA_MIPS64R2);
                   11938:             check_mips_64(ctx);
                   11939:             op2 = MASK_DBSHFL(ctx->opcode);
1.1.1.7   root     11940:             gen_bshfl(ctx, op2, rt, rd);
1.1.1.6   root     11941:             break;
1.1.1.12! root     11942:         case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
        !          11943:         case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
        !          11944:         case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
        !          11945:             check_insn(env, ctx, INSN_LOONGSON2E);
        !          11946:             gen_loongson_integer(ctx, op1, rd, rs, rt);
        !          11947:             break;
1.1.1.5   root     11948: #endif
                   11949:         default:            /* Invalid */
                   11950:             MIPS_INVAL("special3");
                   11951:             generate_exception(ctx, EXCP_RI);
                   11952:             break;
                   11953:         }
                   11954:         break;
                   11955:     case OPC_REGIMM:
                   11956:         op1 = MASK_REGIMM(ctx->opcode);
1.1       root     11957:         switch (op1) {
1.1.1.5   root     11958:         case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
                   11959:         case OPC_BLTZAL ... OPC_BGEZALL:
1.1.1.12! root     11960:             gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
        !          11961:             *is_branch = 1;
        !          11962:             break;
1.1.1.5   root     11963:         case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
                   11964:         case OPC_TNEI:
                   11965:             gen_trap(ctx, op1, rs, -1, imm);
                   11966:             break;
                   11967:         case OPC_SYNCI:
1.1.1.6   root     11968:             check_insn(env, ctx, ISA_MIPS32R2);
                   11969:             /* Treat as NOP. */
1.1       root     11970:             break;
                   11971:         default:            /* Invalid */
1.1.1.6   root     11972:             MIPS_INVAL("regimm");
1.1       root     11973:             generate_exception(ctx, EXCP_RI);
                   11974:             break;
                   11975:         }
                   11976:         break;
1.1.1.5   root     11977:     case OPC_CP0:
1.1.1.6   root     11978:         check_cp0_enabled(ctx);
1.1.1.5   root     11979:         op1 = MASK_CP0(ctx->opcode);
1.1       root     11980:         switch (op1) {
1.1.1.5   root     11981:         case OPC_MFC0:
                   11982:         case OPC_MTC0:
1.1.1.6   root     11983:         case OPC_MFTR:
                   11984:         case OPC_MTTR:
                   11985: #if defined(TARGET_MIPS64)
1.1.1.5   root     11986:         case OPC_DMFC0:
                   11987:         case OPC_DMTC0:
                   11988: #endif
1.1.1.7   root     11989: #ifndef CONFIG_USER_ONLY
1.1.1.6   root     11990:             gen_cp0(env, ctx, op1, rt, rd);
1.1.1.7   root     11991: #endif /* !CONFIG_USER_ONLY */
1.1.1.5   root     11992:             break;
                   11993:         case OPC_C0_FIRST ... OPC_C0_LAST:
1.1.1.7   root     11994: #ifndef CONFIG_USER_ONLY
1.1.1.6   root     11995:             gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
1.1.1.7   root     11996: #endif /* !CONFIG_USER_ONLY */
1.1.1.5   root     11997:             break;
                   11998:         case OPC_MFMC0:
1.1.1.7   root     11999: #ifndef CONFIG_USER_ONLY
                   12000:             {
1.1.1.8   root     12001:                 TCGv t0 = tcg_temp_new();
1.1.1.7   root     12002: 
                   12003:                 op2 = MASK_MFMC0(ctx->opcode);
                   12004:                 switch (op2) {
                   12005:                 case OPC_DMT:
                   12006:                     check_insn(env, ctx, ASE_MT);
                   12007:                     gen_helper_dmt(t0, t0);
1.1.1.8   root     12008:                     gen_store_gpr(t0, rt);
1.1.1.7   root     12009:                     break;
                   12010:                 case OPC_EMT:
                   12011:                     check_insn(env, ctx, ASE_MT);
                   12012:                     gen_helper_emt(t0, t0);
1.1.1.8   root     12013:                     gen_store_gpr(t0, rt);
1.1.1.7   root     12014:                     break;
                   12015:                 case OPC_DVPE:
                   12016:                     check_insn(env, ctx, ASE_MT);
                   12017:                     gen_helper_dvpe(t0, t0);
1.1.1.8   root     12018:                     gen_store_gpr(t0, rt);
1.1.1.7   root     12019:                     break;
                   12020:                 case OPC_EVPE:
                   12021:                     check_insn(env, ctx, ASE_MT);
                   12022:                     gen_helper_evpe(t0, t0);
1.1.1.8   root     12023:                     gen_store_gpr(t0, rt);
1.1.1.7   root     12024:                     break;
                   12025:                 case OPC_DI:
                   12026:                     check_insn(env, ctx, ISA_MIPS32R2);
                   12027:                     save_cpu_state(ctx, 1);
                   12028:                     gen_helper_di(t0);
1.1.1.8   root     12029:                     gen_store_gpr(t0, rt);
1.1.1.7   root     12030:                     /* Stop translation as we may have switched the execution mode */
                   12031:                     ctx->bstate = BS_STOP;
                   12032:                     break;
                   12033:                 case OPC_EI:
                   12034:                     check_insn(env, ctx, ISA_MIPS32R2);
                   12035:                     save_cpu_state(ctx, 1);
                   12036:                     gen_helper_ei(t0);
1.1.1.8   root     12037:                     gen_store_gpr(t0, rt);
1.1.1.7   root     12038:                     /* Stop translation as we may have switched the execution mode */
                   12039:                     ctx->bstate = BS_STOP;
                   12040:                     break;
                   12041:                 default:            /* Invalid */
                   12042:                     MIPS_INVAL("mfmc0");
                   12043:                     generate_exception(ctx, EXCP_RI);
                   12044:                     break;
                   12045:                 }
                   12046:                 tcg_temp_free(t0);
1.1.1.5   root     12047:             }
1.1.1.7   root     12048: #endif /* !CONFIG_USER_ONLY */
1.1       root     12049:             break;
1.1.1.5   root     12050:         case OPC_RDPGPR:
1.1.1.6   root     12051:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7   root     12052:             gen_load_srsgpr(rt, rd);
1.1.1.6   root     12053:             break;
1.1.1.5   root     12054:         case OPC_WRPGPR:
1.1.1.6   root     12055:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7   root     12056:             gen_store_srsgpr(rt, rd);
1.1.1.6   root     12057:             break;
1.1       root     12058:         default:
1.1.1.6   root     12059:             MIPS_INVAL("cp0");
1.1.1.5   root     12060:             generate_exception(ctx, EXCP_RI);
1.1       root     12061:             break;
                   12062:         }
                   12063:         break;
1.1.1.8   root     12064:     case OPC_ADDI: /* Arithmetic with immediate opcode */
                   12065:     case OPC_ADDIU:
1.1.1.6   root     12066:          gen_arith_imm(env, ctx, op, rt, rs, imm);
1.1.1.5   root     12067:          break;
1.1.1.8   root     12068:     case OPC_SLTI: /* Set on less than with immediate opcode */
                   12069:     case OPC_SLTIU:
                   12070:          gen_slt_imm(env, op, rt, rs, imm);
                   12071:          break;
                   12072:     case OPC_ANDI: /* Arithmetic with immediate opcode */
                   12073:     case OPC_LUI:
                   12074:     case OPC_ORI:
                   12075:     case OPC_XORI:
                   12076:          gen_logic_imm(env, op, rt, rs, imm);
                   12077:          break;
1.1.1.5   root     12078:     case OPC_J ... OPC_JAL: /* Jump */
                   12079:          offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
1.1.1.12! root     12080:          gen_compute_branch(ctx, op, 4, rs, rt, offset);
        !          12081:          *is_branch = 1;
        !          12082:          break;
1.1.1.5   root     12083:     case OPC_BEQ ... OPC_BGTZ: /* Branch */
                   12084:     case OPC_BEQL ... OPC_BGTZL:
1.1.1.12! root     12085:          gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
        !          12086:          *is_branch = 1;
        !          12087:          break;
1.1.1.5   root     12088:     case OPC_LB ... OPC_LWR: /* Load and stores */
1.1.1.12! root     12089:     case OPC_LL:
        !          12090:          gen_ld(env, ctx, op, rt, rs, imm);
        !          12091:          break;
1.1.1.5   root     12092:     case OPC_SB ... OPC_SW:
                   12093:     case OPC_SWR:
1.1.1.12! root     12094:          gen_st(ctx, op, rt, rs, imm);
1.1.1.5   root     12095:          break;
1.1.1.8   root     12096:     case OPC_SC:
                   12097:          gen_st_cond(ctx, op, rt, rs, imm);
                   12098:          break;
1.1.1.5   root     12099:     case OPC_CACHE:
1.1.1.6   root     12100:         check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
                   12101:         /* Treat as NOP. */
                   12102:         break;
1.1.1.5   root     12103:     case OPC_PREF:
1.1.1.6   root     12104:         check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
                   12105:         /* Treat as NOP. */
1.1       root     12106:         break;
1.1.1.2   root     12107: 
1.1.1.6   root     12108:     /* Floating point (COP1). */
1.1.1.5   root     12109:     case OPC_LWC1:
                   12110:     case OPC_LDC1:
                   12111:     case OPC_SWC1:
                   12112:     case OPC_SDC1:
1.1.1.12! root     12113:         gen_cop1_ldst(env, ctx, op, rt, rs, imm);
1.1.1.4   root     12114:         break;
                   12115: 
1.1.1.5   root     12116:     case OPC_CP1:
1.1.1.6   root     12117:         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
                   12118:             check_cp1_enabled(ctx);
                   12119:             op1 = MASK_CP1(ctx->opcode);
                   12120:             switch (op1) {
                   12121:             case OPC_MFHC1:
                   12122:             case OPC_MTHC1:
                   12123:                 check_insn(env, ctx, ISA_MIPS32R2);
                   12124:             case OPC_MFC1:
                   12125:             case OPC_CFC1:
                   12126:             case OPC_MTC1:
                   12127:             case OPC_CTC1:
                   12128:                 gen_cp1(ctx, op1, rt, rd);
                   12129:                 break;
                   12130: #if defined(TARGET_MIPS64)
                   12131:             case OPC_DMFC1:
                   12132:             case OPC_DMTC1:
                   12133:                 check_insn(env, ctx, ISA_MIPS3);
                   12134:                 gen_cp1(ctx, op1, rt, rd);
                   12135:                 break;
1.1.1.5   root     12136: #endif
1.1.1.6   root     12137:             case OPC_BC1ANY2:
                   12138:             case OPC_BC1ANY4:
                   12139:                 check_cop1x(ctx);
                   12140:                 check_insn(env, ctx, ASE_MIPS3D);
                   12141:                 /* fall through */
                   12142:             case OPC_BC1:
                   12143:                 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
                   12144:                                     (rt >> 2) & 0x7, imm << 2);
1.1.1.12! root     12145:                 *is_branch = 1;
        !          12146:                 break;
1.1.1.6   root     12147:             case OPC_S_FMT:
                   12148:             case OPC_D_FMT:
                   12149:             case OPC_W_FMT:
                   12150:             case OPC_L_FMT:
                   12151:             case OPC_PS_FMT:
1.1.1.12! root     12152:                 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
1.1.1.6   root     12153:                            (imm >> 8) & 0x7);
                   12154:                 break;
                   12155:             default:
                   12156:                 MIPS_INVAL("cp1");
                   12157:                 generate_exception (ctx, EXCP_RI);
                   12158:                 break;
                   12159:             }
                   12160:         } else {
                   12161:             generate_exception_err(ctx, EXCP_CpU, 1);
1.1.1.4   root     12162:         }
1.1.1.2   root     12163:         break;
                   12164: 
                   12165:     /* COP2.  */
1.1.1.5   root     12166:     case OPC_LWC2:
                   12167:     case OPC_LDC2:
                   12168:     case OPC_SWC2:
                   12169:     case OPC_SDC2:
                   12170:     case OPC_CP2:
                   12171:         /* COP2: Not implemented. */
1.1.1.2   root     12172:         generate_exception_err(ctx, EXCP_CpU, 2);
                   12173:         break;
                   12174: 
1.1.1.5   root     12175:     case OPC_CP3:
1.1.1.6   root     12176:         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
                   12177:             check_cp1_enabled(ctx);
                   12178:             op1 = MASK_CP3(ctx->opcode);
                   12179:             switch (op1) {
                   12180:             case OPC_LWXC1:
                   12181:             case OPC_LDXC1:
                   12182:             case OPC_LUXC1:
                   12183:             case OPC_SWXC1:
                   12184:             case OPC_SDXC1:
                   12185:             case OPC_SUXC1:
                   12186:                 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
                   12187:                 break;
                   12188:             case OPC_PREFX:
                   12189:                 /* Treat as NOP. */
                   12190:                 break;
                   12191:             case OPC_ALNV_PS:
                   12192:             case OPC_MADD_S:
                   12193:             case OPC_MADD_D:
                   12194:             case OPC_MADD_PS:
                   12195:             case OPC_MSUB_S:
                   12196:             case OPC_MSUB_D:
                   12197:             case OPC_MSUB_PS:
                   12198:             case OPC_NMADD_S:
                   12199:             case OPC_NMADD_D:
                   12200:             case OPC_NMADD_PS:
                   12201:             case OPC_NMSUB_S:
                   12202:             case OPC_NMSUB_D:
                   12203:             case OPC_NMSUB_PS:
                   12204:                 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
                   12205:                 break;
                   12206:             default:
                   12207:                 MIPS_INVAL("cp3");
                   12208:                 generate_exception (ctx, EXCP_RI);
                   12209:                 break;
                   12210:             }
                   12211:         } else {
                   12212:             generate_exception_err(ctx, EXCP_CpU, 1);
1.1.1.5   root     12213:         }
1.1.1.2   root     12214:         break;
                   12215: 
1.1.1.6   root     12216: #if defined(TARGET_MIPS64)
1.1.1.5   root     12217:     /* MIPS64 opcodes */
                   12218:     case OPC_LWU:
                   12219:     case OPC_LDL ... OPC_LDR:
                   12220:     case OPC_LLD:
                   12221:     case OPC_LD:
1.1.1.12! root     12222:         check_insn(env, ctx, ISA_MIPS3);
        !          12223:         check_mips_64(ctx);
        !          12224:         gen_ld(env, ctx, op, rt, rs, imm);
        !          12225:         break;
        !          12226:     case OPC_SDL ... OPC_SDR:
1.1.1.5   root     12227:     case OPC_SD:
1.1.1.6   root     12228:         check_insn(env, ctx, ISA_MIPS3);
                   12229:         check_mips_64(ctx);
1.1.1.12! root     12230:         gen_st(ctx, op, rt, rs, imm);
1.1.1.5   root     12231:         break;
1.1.1.8   root     12232:     case OPC_SCD:
                   12233:         check_insn(env, ctx, ISA_MIPS3);
                   12234:         check_mips_64(ctx);
                   12235:         gen_st_cond(ctx, op, rt, rs, imm);
                   12236:         break;
                   12237:     case OPC_DADDI:
                   12238:     case OPC_DADDIU:
1.1.1.6   root     12239:         check_insn(env, ctx, ISA_MIPS3);
                   12240:         check_mips_64(ctx);
                   12241:         gen_arith_imm(env, ctx, op, rt, rs, imm);
1.1.1.5   root     12242:         break;
                   12243: #endif
                   12244:     case OPC_JALX:
1.1.1.12! root     12245:         check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
        !          12246:         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
        !          12247:         gen_compute_branch(ctx, op, 4, rs, rt, offset);
        !          12248:         *is_branch = 1;
        !          12249:         break;
1.1.1.5   root     12250:     case OPC_MDMX:
1.1.1.6   root     12251:         check_insn(env, ctx, ASE_MDMX);
1.1.1.5   root     12252:         /* MDMX: Not implemented. */
1.1       root     12253:     default:            /* Invalid */
1.1.1.6   root     12254:         MIPS_INVAL("major opcode");
1.1       root     12255:         generate_exception(ctx, EXCP_RI);
                   12256:         break;
                   12257:     }
                   12258: }
                   12259: 
1.1.1.7   root     12260: static inline void
1.1.1.6   root     12261: gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
                   12262:                                 int search_pc)
1.1       root     12263: {
1.1.1.6   root     12264:     DisasContext ctx;
1.1       root     12265:     target_ulong pc_start;
                   12266:     uint16_t *gen_opc_end;
1.1.1.7   root     12267:     CPUBreakpoint *bp;
1.1       root     12268:     int j, lj = -1;
1.1.1.7   root     12269:     int num_insns;
                   12270:     int max_insns;
1.1.1.12! root     12271:     int insn_bytes;
        !          12272:     int is_branch;
1.1       root     12273: 
1.1.1.7   root     12274:     if (search_pc)
                   12275:         qemu_log("search pc %d\n", search_pc);
1.1.1.2   root     12276: 
1.1       root     12277:     pc_start = tb->pc;
1.1.1.9   root     12278:     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1.1       root     12279:     ctx.pc = pc_start;
1.1.1.2   root     12280:     ctx.saved_pc = -1;
1.1.1.9   root     12281:     ctx.singlestep_enabled = env->singlestep_enabled;
1.1       root     12282:     ctx.tb = tb;
                   12283:     ctx.bstate = BS_NONE;
1.1.1.2   root     12284:     /* Restore delay slot state from the tb context.  */
1.1.1.6   root     12285:     ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
                   12286:     restore_cpu_state(env, &ctx);
1.1.1.7   root     12287: #ifdef CONFIG_USER_ONLY
                   12288:         ctx.mem_idx = MIPS_HFLAG_UM;
1.1       root     12289: #else
1.1.1.7   root     12290:         ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
1.1       root     12291: #endif
1.1.1.7   root     12292:     num_insns = 0;
                   12293:     max_insns = tb->cflags & CF_COUNT_MASK;
                   12294:     if (max_insns == 0)
                   12295:         max_insns = CF_COUNT_MASK;
                   12296:     LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
                   12297:     gen_icount_start();
                   12298:     while (ctx.bstate == BS_NONE) {
1.1.1.9   root     12299:         if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
                   12300:             QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
1.1.1.7   root     12301:                 if (bp->pc == ctx.pc) {
1.1.1.6   root     12302:                     save_cpu_state(&ctx, 1);
1.1.1.2   root     12303:                     ctx.bstate = BS_BRANCH;
1.1.1.7   root     12304:                     gen_helper_0i(raise_exception, EXCP_DEBUG);
1.1.1.6   root     12305:                     /* Include the breakpoint location or the tb won't
                   12306:                      * be flushed when it must be.  */
                   12307:                     ctx.pc += 4;
1.1.1.2   root     12308:                     goto done_generating;
                   12309:                 }
                   12310:             }
                   12311:         }
                   12312: 
1.1       root     12313:         if (search_pc) {
                   12314:             j = gen_opc_ptr - gen_opc_buf;
                   12315:             if (lj < j) {
                   12316:                 lj++;
                   12317:                 while (lj < j)
                   12318:                     gen_opc_instr_start[lj++] = 0;
                   12319:             }
1.1.1.2   root     12320:             gen_opc_pc[lj] = ctx.pc;
                   12321:             gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
                   12322:             gen_opc_instr_start[lj] = 1;
1.1.1.7   root     12323:             gen_opc_icount[lj] = num_insns;
1.1       root     12324:         }
1.1.1.7   root     12325:         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
                   12326:             gen_io_start();
1.1.1.12! root     12327: 
        !          12328:         is_branch = 0;
        !          12329:         if (!(ctx.hflags & MIPS_HFLAG_M16)) {
        !          12330:             ctx.opcode = ldl_code(ctx.pc);
        !          12331:             insn_bytes = 4;
        !          12332:             decode_opc(env, &ctx, &is_branch);
        !          12333:         } else if (env->insn_flags & ASE_MICROMIPS) {
        !          12334:             ctx.opcode = lduw_code(ctx.pc);
        !          12335:             insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
        !          12336:         } else if (env->insn_flags & ASE_MIPS16) {
        !          12337:             ctx.opcode = lduw_code(ctx.pc);
        !          12338:             insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
        !          12339:         } else {
        !          12340:             generate_exception(&ctx, EXCP_RI);
        !          12341:             ctx.bstate = BS_STOP;
        !          12342:             break;
        !          12343:         }
        !          12344:         if (!is_branch) {
        !          12345:             handle_delay_slot(env, &ctx, insn_bytes);
        !          12346:         }
        !          12347:         ctx.pc += insn_bytes;
        !          12348: 
1.1.1.7   root     12349:         num_insns++;
1.1.1.2   root     12350: 
1.1.1.9   root     12351:         /* Execute a branch and its delay slot as a single instruction.
                   12352:            This is what GDB expects and is consistent with what the
                   12353:            hardware does (e.g. if a delay slot instruction faults, the
                   12354:            reported PC is the PC of the branch).  */
                   12355:         if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
1.1.1.2   root     12356:             break;
                   12357: 
1.1       root     12358:         if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
                   12359:             break;
1.1.1.2   root     12360: 
1.1.1.7   root     12361:         if (gen_opc_ptr >= gen_opc_end)
                   12362:             break;
                   12363: 
                   12364:         if (num_insns >= max_insns)
                   12365:             break;
1.1.1.8   root     12366: 
                   12367:         if (singlestep)
                   12368:             break;
1.1       root     12369:     }
1.1.1.7   root     12370:     if (tb->cflags & CF_LAST_IO)
                   12371:         gen_io_end();
1.1.1.9   root     12372:     if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
1.1.1.6   root     12373:         save_cpu_state(&ctx, ctx.bstate == BS_NONE);
1.1.1.7   root     12374:         gen_helper_0i(raise_exception, EXCP_DEBUG);
1.1.1.6   root     12375:     } else {
1.1.1.7   root     12376:         switch (ctx.bstate) {
1.1.1.6   root     12377:         case BS_STOP:
                   12378:             gen_goto_tb(&ctx, 0, ctx.pc);
                   12379:             break;
                   12380:         case BS_NONE:
                   12381:             save_cpu_state(&ctx, 0);
                   12382:             gen_goto_tb(&ctx, 0, ctx.pc);
                   12383:             break;
                   12384:         case BS_EXCP:
1.1.1.7   root     12385:             tcg_gen_exit_tb(0);
1.1.1.6   root     12386:             break;
                   12387:         case BS_BRANCH:
                   12388:         default:
                   12389:             break;
1.1.1.7   root     12390:         }
1.1       root     12391:     }
1.1.1.2   root     12392: done_generating:
1.1.1.7   root     12393:     gen_icount_end(tb, num_insns);
1.1       root     12394:     *gen_opc_ptr = INDEX_op_end;
                   12395:     if (search_pc) {
                   12396:         j = gen_opc_ptr - gen_opc_buf;
                   12397:         lj++;
                   12398:         while (lj <= j)
                   12399:             gen_opc_instr_start[lj++] = 0;
                   12400:     } else {
                   12401:         tb->size = ctx.pc - pc_start;
1.1.1.7   root     12402:         tb->icount = num_insns;
1.1       root     12403:     }
                   12404: #ifdef DEBUG_DISAS
1.1.1.7   root     12405:     LOG_DISAS("\n");
                   12406:     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
                   12407:         qemu_log("IN: %s\n", lookup_symbol(pc_start));
                   12408:         log_target_disas(pc_start, ctx.pc - pc_start, 0);
                   12409:         qemu_log("\n");
1.1       root     12410:     }
                   12411: #endif
                   12412: }
                   12413: 
1.1.1.7   root     12414: void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
1.1       root     12415: {
1.1.1.7   root     12416:     gen_intermediate_code_internal(env, tb, 0);
1.1       root     12417: }
                   12418: 
1.1.1.7   root     12419: void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
1.1       root     12420: {
1.1.1.7   root     12421:     gen_intermediate_code_internal(env, tb, 1);
1.1       root     12422: }
                   12423: 
1.1.1.7   root     12424: static void fpu_dump_state(CPUState *env, FILE *f,
                   12425:                            int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
                   12426:                            int flags)
1.1.1.4   root     12427: {
                   12428:     int i;
1.1.1.6   root     12429:     int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
1.1.1.4   root     12430: 
1.1.1.12! root     12431: #define printfpr(fp)                                                    \
        !          12432:     do {                                                                \
        !          12433:         if (is_fpu64)                                                   \
        !          12434:             fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
        !          12435:                         " fd:%13g fs:%13g psu: %13g\n",                 \
        !          12436:                         (fp)->w[FP_ENDIAN_IDX], (fp)->d,                \
        !          12437:                         (double)(fp)->fd,                               \
        !          12438:                         (double)(fp)->fs[FP_ENDIAN_IDX],                \
        !          12439:                         (double)(fp)->fs[!FP_ENDIAN_IDX]);              \
        !          12440:         else {                                                          \
        !          12441:             fpr_t tmp;                                                  \
        !          12442:             tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
        !          12443:             tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
        !          12444:             fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
        !          12445:                         " fd:%13g fs:%13g psu:%13g\n",                  \
        !          12446:                         tmp.w[FP_ENDIAN_IDX], tmp.d,                    \
        !          12447:                         (double)tmp.fd,                                 \
        !          12448:                         (double)tmp.fs[FP_ENDIAN_IDX],                  \
        !          12449:                         (double)tmp.fs[!FP_ENDIAN_IDX]);                \
        !          12450:         }                                                               \
1.1.1.4   root     12451:     } while(0)
                   12452: 
1.1.1.6   root     12453: 
                   12454:     fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
1.1.1.7   root     12455:                 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
                   12456:                 get_float_exception_flags(&env->active_fpu.fp_status));
1.1.1.6   root     12457:     for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
                   12458:         fpu_fprintf(f, "%3s: ", fregnames[i]);
1.1.1.7   root     12459:         printfpr(&env->active_fpu.fpr[i]);
1.1.1.4   root     12460:     }
                   12461: 
                   12462: #undef printfpr
                   12463: }
                   12464: 
1.1.1.6   root     12465: #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
1.1.1.5   root     12466: /* Debug help: The architecture requires 32bit code to maintain proper
1.1.1.7   root     12467:    sign-extended values on 64bit machines.  */
1.1.1.5   root     12468: 
                   12469: #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
                   12470: 
1.1.1.7   root     12471: static void
                   12472: cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
                   12473:                                 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
                   12474:                                 int flags)
1.1.1.5   root     12475: {
                   12476:     int i;
                   12477: 
1.1.1.7   root     12478:     if (!SIGN_EXT_P(env->active_tc.PC))
                   12479:         cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
                   12480:     if (!SIGN_EXT_P(env->active_tc.HI[0]))
                   12481:         cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
                   12482:     if (!SIGN_EXT_P(env->active_tc.LO[0]))
                   12483:         cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
1.1.1.5   root     12484:     if (!SIGN_EXT_P(env->btarget))
1.1.1.6   root     12485:         cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
1.1.1.5   root     12486: 
                   12487:     for (i = 0; i < 32; i++) {
1.1.1.7   root     12488:         if (!SIGN_EXT_P(env->active_tc.gpr[i]))
                   12489:             cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
1.1.1.5   root     12490:     }
                   12491: 
                   12492:     if (!SIGN_EXT_P(env->CP0_EPC))
1.1.1.6   root     12493:         cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
1.1.1.9   root     12494:     if (!SIGN_EXT_P(env->lladdr))
                   12495:         cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
1.1.1.5   root     12496: }
                   12497: #endif
                   12498: 
1.1.1.6   root     12499: void cpu_dump_state (CPUState *env, FILE *f,
1.1       root     12500:                      int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
                   12501:                      int flags)
                   12502: {
                   12503:     int i;
1.1.1.6   root     12504: 
1.1.1.12! root     12505:     cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
        !          12506:                 " LO=0x" TARGET_FMT_lx " ds %04x "
        !          12507:                 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
1.1.1.7   root     12508:                 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
                   12509:                 env->hflags, env->btarget, env->bcond);
1.1       root     12510:     for (i = 0; i < 32; i++) {
                   12511:         if ((i & 3) == 0)
                   12512:             cpu_fprintf(f, "GPR%02d:", i);
1.1.1.7   root     12513:         cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
1.1       root     12514:         if ((i & 3) == 3)
                   12515:             cpu_fprintf(f, "\n");
                   12516:     }
                   12517: 
1.1.1.6   root     12518:     cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
                   12519:                 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
                   12520:     cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
1.1.1.9   root     12521:                 env->CP0_Config0, env->CP0_Config1, env->lladdr);
1.1.1.6   root     12522:     if (env->hflags & MIPS_HFLAG_FPU)
1.1.1.5   root     12523:         fpu_dump_state(env, f, cpu_fprintf, flags);
1.1.1.6   root     12524: #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
1.1.1.5   root     12525:     cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
1.1.1.4   root     12526: #endif
1.1       root     12527: }
                   12528: 
1.1.1.7   root     12529: static void mips_tcg_init(void)
                   12530: {
                   12531:     int i;
                   12532:     static int inited;
                   12533: 
                   12534:     /* Initialize various static tables. */
                   12535:     if (inited)
                   12536:         return;
                   12537: 
                   12538:     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
1.1.1.8   root     12539:     TCGV_UNUSED(cpu_gpr[0]);
                   12540:     for (i = 1; i < 32; i++)
1.1.1.7   root     12541:         cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
                   12542:                                         offsetof(CPUState, active_tc.gpr[i]),
                   12543:                                         regnames[i]);
                   12544:     cpu_PC = tcg_global_mem_new(TCG_AREG0,
                   12545:                                 offsetof(CPUState, active_tc.PC), "PC");
                   12546:     for (i = 0; i < MIPS_DSP_ACC; i++) {
                   12547:         cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
                   12548:                                        offsetof(CPUState, active_tc.HI[i]),
                   12549:                                        regnames_HI[i]);
                   12550:         cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
                   12551:                                        offsetof(CPUState, active_tc.LO[i]),
                   12552:                                        regnames_LO[i]);
                   12553:         cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
                   12554:                                         offsetof(CPUState, active_tc.ACX[i]),
                   12555:                                         regnames_ACX[i]);
                   12556:     }
                   12557:     cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
                   12558:                                      offsetof(CPUState, active_tc.DSPControl),
                   12559:                                      "DSPControl");
1.1.1.8   root     12560:     bcond = tcg_global_mem_new(TCG_AREG0,
                   12561:                                offsetof(CPUState, bcond), "bcond");
1.1.1.7   root     12562:     btarget = tcg_global_mem_new(TCG_AREG0,
                   12563:                                  offsetof(CPUState, btarget), "btarget");
1.1.1.8   root     12564:     hflags = tcg_global_mem_new_i32(TCG_AREG0,
                   12565:                                     offsetof(CPUState, hflags), "hflags");
                   12566: 
1.1.1.7   root     12567:     fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
                   12568:                                       offsetof(CPUState, active_fpu.fcr0),
                   12569:                                       "fcr0");
                   12570:     fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
                   12571:                                        offsetof(CPUState, active_fpu.fcr31),
                   12572:                                        "fcr31");
                   12573: 
                   12574:     /* register helpers */
                   12575: #define GEN_HELPER 2
                   12576: #include "helper.h"
                   12577: 
                   12578:     inited = 1;
                   12579: }
                   12580: 
1.1.1.6   root     12581: #include "translate_init.c"
                   12582: 
                   12583: CPUMIPSState *cpu_mips_init (const char *cpu_model)
1.1       root     12584: {
                   12585:     CPUMIPSState *env;
1.1.1.6   root     12586:     const mips_def_t *def;
1.1       root     12587: 
1.1.1.6   root     12588:     def = cpu_mips_find_by_name(cpu_model);
                   12589:     if (!def)
                   12590:         return NULL;
1.1       root     12591:     env = qemu_mallocz(sizeof(CPUMIPSState));
1.1.1.6   root     12592:     env->cpu_model = def;
1.1.1.9   root     12593:     env->cpu_model_str = cpu_model;
1.1.1.6   root     12594: 
1.1.1.2   root     12595:     cpu_exec_init(env);
1.1.1.9   root     12596: #ifndef CONFIG_USER_ONLY
                   12597:     mmu_init(env, def);
                   12598: #endif
                   12599:     fpu_init(env, def);
                   12600:     mvp_init(env, def);
1.1.1.7   root     12601:     mips_tcg_init();
1.1.1.5   root     12602:     cpu_reset(env);
1.1.1.8   root     12603:     qemu_init_vcpu(env);
1.1.1.5   root     12604:     return env;
                   12605: }
                   12606: 
                   12607: void cpu_reset (CPUMIPSState *env)
                   12608: {
1.1.1.7   root     12609:     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
                   12610:         qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
                   12611:         log_cpu_state(env, 0);
                   12612:     }
                   12613: 
1.1.1.5   root     12614:     memset(env, 0, offsetof(CPUMIPSState, breakpoints));
1.1       root     12615:     tlb_flush(env, 1);
1.1.1.5   root     12616: 
1.1.1.9   root     12617:     /* Reset registers to their default values */
                   12618:     env->CP0_PRid = env->cpu_model->CP0_PRid;
                   12619:     env->CP0_Config0 = env->cpu_model->CP0_Config0;
                   12620: #ifdef TARGET_WORDS_BIGENDIAN
                   12621:     env->CP0_Config0 |= (1 << CP0C0_BE);
                   12622: #endif
                   12623:     env->CP0_Config1 = env->cpu_model->CP0_Config1;
                   12624:     env->CP0_Config2 = env->cpu_model->CP0_Config2;
                   12625:     env->CP0_Config3 = env->cpu_model->CP0_Config3;
                   12626:     env->CP0_Config6 = env->cpu_model->CP0_Config6;
                   12627:     env->CP0_Config7 = env->cpu_model->CP0_Config7;
                   12628:     env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
                   12629:                                  << env->cpu_model->CP0_LLAddr_shift;
                   12630:     env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
                   12631:     env->SYNCI_Step = env->cpu_model->SYNCI_Step;
                   12632:     env->CCRes = env->cpu_model->CCRes;
                   12633:     env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
                   12634:     env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
                   12635:     env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
                   12636:     env->current_tc = 0;
                   12637:     env->SEGBITS = env->cpu_model->SEGBITS;
                   12638:     env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
                   12639: #if defined(TARGET_MIPS64)
                   12640:     if (env->cpu_model->insn_flags & ISA_MIPS3) {
                   12641:         env->SEGMask |= 3ULL << 62;
                   12642:     }
                   12643: #endif
                   12644:     env->PABITS = env->cpu_model->PABITS;
                   12645:     env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
                   12646:     env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
                   12647:     env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
                   12648:     env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
                   12649:     env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
                   12650:     env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
                   12651:     env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
                   12652:     env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
                   12653:     env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
                   12654:     env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
                   12655:     env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
                   12656:     env->insn_flags = env->cpu_model->insn_flags;
                   12657: 
1.1.1.7   root     12658: #if defined(CONFIG_USER_ONLY)
                   12659:     env->hflags = MIPS_HFLAG_UM;
1.1.1.8   root     12660:     /* Enable access to the SYNCI_Step register.  */
                   12661:     env->CP0_HWREna |= (1 << 1);
1.1.1.9   root     12662:     if (env->CP0_Config1 & (1 << CP0C1_FP)) {
                   12663:         env->hflags |= MIPS_HFLAG_FPU;
                   12664:     }
                   12665: #ifdef TARGET_MIPS64
                   12666:     if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
                   12667:         env->hflags |= MIPS_HFLAG_F64;
                   12668:     }
                   12669: #endif
1.1.1.7   root     12670: #else
1.1.1.5   root     12671:     if (env->hflags & MIPS_HFLAG_BMASK) {
                   12672:         /* If the exception was raised from a delay slot,
1.1.1.7   root     12673:            come back to the jump.  */
                   12674:         env->CP0_ErrorEPC = env->active_tc.PC - 4;
1.1.1.5   root     12675:     } else {
1.1.1.7   root     12676:         env->CP0_ErrorEPC = env->active_tc.PC;
1.1.1.5   root     12677:     }
1.1.1.7   root     12678:     env->active_tc.PC = (int32_t)0xBFC00000;
1.1.1.9   root     12679:     env->CP0_Random = env->tlb->nb_tlb - 1;
                   12680:     env->tlb->tlb_in_use = env->tlb->nb_tlb;
1.1       root     12681:     env->CP0_Wired = 0;
1.1.1.5   root     12682:     /* SMP not implemented */
                   12683:     env->CP0_EBase = 0x80000000;
                   12684:     env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
1.1.1.6   root     12685:     /* vectored interrupts not implemented, timer on int 7,
                   12686:        no performance counters. */
                   12687:     env->CP0_IntCtl = 0xe0000000;
                   12688:     {
                   12689:         int i;
                   12690: 
                   12691:         for (i = 0; i < 7; i++) {
                   12692:             env->CP0_WatchLo[i] = 0;
                   12693:             env->CP0_WatchHi[i] = 0x80000000;
                   12694:         }
                   12695:         env->CP0_WatchLo[7] = 0;
                   12696:         env->CP0_WatchHi[7] = 0;
                   12697:     }
1.1       root     12698:     /* Count register increments in debug mode, EJTAG version 1 */
                   12699:     env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
1.1.1.6   root     12700:     env->hflags = MIPS_HFLAG_CP0;
1.1.1.2   root     12701: #endif
1.1.1.9   root     12702: #if defined(TARGET_MIPS64)
                   12703:     if (env->cpu_model->insn_flags & ISA_MIPS3) {
                   12704:         env->hflags |= MIPS_HFLAG_64;
                   12705:     }
                   12706: #endif
1.1.1.7   root     12707:     env->exception_index = EXCP_NONE;
1.1       root     12708: }
1.1.1.7   root     12709: 
                   12710: void gen_pc_load(CPUState *env, TranslationBlock *tb,
                   12711:                 unsigned long searched_pc, int pc_pos, void *puc)
                   12712: {
                   12713:     env->active_tc.PC = gen_opc_pc[pc_pos];
                   12714:     env->hflags &= ~MIPS_HFLAG_BMASK;
                   12715:     env->hflags |= gen_opc_hflags[pc_pos];
                   12716: }

unix.superglobalmegacorp.com

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