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

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 "cpu.h"
                     24: #include "disas.h"
1.1.1.7   root       25: #include "tcg-op.h"
                     26: 
                     27: #include "helper.h"
                     28: #define GEN_HELPER 1
                     29: #include "helper.h"
1.1       root       30: 
1.1.1.2   root       31: //#define MIPS_DEBUG_DISAS
1.1.1.5   root       32: //#define MIPS_DEBUG_SIGN_EXTENSIONS
1.1       root       33: 
1.1.1.5   root       34: /* MIPS major opcodes */
                     35: #define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
1.1       root       36: 
                     37: enum {
                     38:     /* indirect opcode tables */
1.1.1.5   root       39:     OPC_SPECIAL  = (0x00 << 26),
                     40:     OPC_REGIMM   = (0x01 << 26),
                     41:     OPC_CP0      = (0x10 << 26),
                     42:     OPC_CP1      = (0x11 << 26),
                     43:     OPC_CP2      = (0x12 << 26),
                     44:     OPC_CP3      = (0x13 << 26),
                     45:     OPC_SPECIAL2 = (0x1C << 26),
                     46:     OPC_SPECIAL3 = (0x1F << 26),
1.1       root       47:     /* arithmetic with immediate */
1.1.1.5   root       48:     OPC_ADDI     = (0x08 << 26),
                     49:     OPC_ADDIU    = (0x09 << 26),
                     50:     OPC_SLTI     = (0x0A << 26),
                     51:     OPC_SLTIU    = (0x0B << 26),
1.1.1.8   root       52:     /* logic with immediate */
1.1.1.5   root       53:     OPC_ANDI     = (0x0C << 26),
                     54:     OPC_ORI      = (0x0D << 26),
                     55:     OPC_XORI     = (0x0E << 26),
                     56:     OPC_LUI      = (0x0F << 26),
1.1.1.8   root       57:     /* arithmetic with immediate */
1.1.1.5   root       58:     OPC_DADDI    = (0x18 << 26),
                     59:     OPC_DADDIU   = (0x19 << 26),
1.1       root       60:     /* Jump and branches */
1.1.1.5   root       61:     OPC_J        = (0x02 << 26),
                     62:     OPC_JAL      = (0x03 << 26),
1.1.1.12  root       63:     OPC_JALS     = OPC_JAL | 0x5,
1.1.1.5   root       64:     OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
                     65:     OPC_BEQL     = (0x14 << 26),
                     66:     OPC_BNE      = (0x05 << 26),
                     67:     OPC_BNEL     = (0x15 << 26),
                     68:     OPC_BLEZ     = (0x06 << 26),
                     69:     OPC_BLEZL    = (0x16 << 26),
                     70:     OPC_BGTZ     = (0x07 << 26),
                     71:     OPC_BGTZL    = (0x17 << 26),
                     72:     OPC_JALX     = (0x1D << 26),  /* MIPS 16 only */
1.1.1.12  root       73:     OPC_JALXS    = OPC_JALX | 0x5,
1.1       root       74:     /* Load and stores */
1.1.1.5   root       75:     OPC_LDL      = (0x1A << 26),
                     76:     OPC_LDR      = (0x1B << 26),
                     77:     OPC_LB       = (0x20 << 26),
                     78:     OPC_LH       = (0x21 << 26),
                     79:     OPC_LWL      = (0x22 << 26),
                     80:     OPC_LW       = (0x23 << 26),
1.1.1.12  root       81:     OPC_LWPC     = OPC_LW | 0x5,
1.1.1.5   root       82:     OPC_LBU      = (0x24 << 26),
                     83:     OPC_LHU      = (0x25 << 26),
                     84:     OPC_LWR      = (0x26 << 26),
                     85:     OPC_LWU      = (0x27 << 26),
                     86:     OPC_SB       = (0x28 << 26),
                     87:     OPC_SH       = (0x29 << 26),
                     88:     OPC_SWL      = (0x2A << 26),
                     89:     OPC_SW       = (0x2B << 26),
                     90:     OPC_SDL      = (0x2C << 26),
                     91:     OPC_SDR      = (0x2D << 26),
                     92:     OPC_SWR      = (0x2E << 26),
                     93:     OPC_LL       = (0x30 << 26),
                     94:     OPC_LLD      = (0x34 << 26),
                     95:     OPC_LD       = (0x37 << 26),
1.1.1.12  root       96:     OPC_LDPC     = OPC_LD | 0x5,
1.1.1.5   root       97:     OPC_SC       = (0x38 << 26),
                     98:     OPC_SCD      = (0x3C << 26),
                     99:     OPC_SD       = (0x3F << 26),
1.1       root      100:     /* Floating point load/store */
1.1.1.5   root      101:     OPC_LWC1     = (0x31 << 26),
                    102:     OPC_LWC2     = (0x32 << 26),
                    103:     OPC_LDC1     = (0x35 << 26),
                    104:     OPC_LDC2     = (0x36 << 26),
                    105:     OPC_SWC1     = (0x39 << 26),
                    106:     OPC_SWC2     = (0x3A << 26),
                    107:     OPC_SDC1     = (0x3D << 26),
                    108:     OPC_SDC2     = (0x3E << 26),
                    109:     /* MDMX ASE specific */
                    110:     OPC_MDMX     = (0x1E << 26),
1.1       root      111:     /* Cache and prefetch */
1.1.1.5   root      112:     OPC_CACHE    = (0x2F << 26),
                    113:     OPC_PREF     = (0x33 << 26),
                    114:     /* Reserved major opcode */
                    115:     OPC_MAJOR3B_RESERVED = (0x3B << 26),
1.1       root      116: };
                    117: 
                    118: /* MIPS special opcodes */
1.1.1.5   root      119: #define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
                    120: 
1.1       root      121: enum {
                    122:     /* Shifts */
1.1.1.5   root      123:     OPC_SLL      = 0x00 | OPC_SPECIAL,
1.1       root      124:     /* NOP is SLL r0, r0, 0   */
                    125:     /* SSNOP is SLL r0, r0, 1 */
1.1.1.5   root      126:     /* EHB is SLL r0, r0, 3 */
                    127:     OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
1.1.1.12  root      128:     OPC_ROTR     = OPC_SRL | (1 << 21),
1.1.1.5   root      129:     OPC_SRA      = 0x03 | OPC_SPECIAL,
                    130:     OPC_SLLV     = 0x04 | OPC_SPECIAL,
1.1.1.6   root      131:     OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
1.1.1.12  root      132:     OPC_ROTRV    = OPC_SRLV | (1 << 6),
1.1.1.5   root      133:     OPC_SRAV     = 0x07 | OPC_SPECIAL,
                    134:     OPC_DSLLV    = 0x14 | OPC_SPECIAL,
                    135:     OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
1.1.1.12  root      136:     OPC_DROTRV   = OPC_DSRLV | (1 << 6),
1.1.1.5   root      137:     OPC_DSRAV    = 0x17 | OPC_SPECIAL,
                    138:     OPC_DSLL     = 0x38 | OPC_SPECIAL,
                    139:     OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
1.1.1.12  root      140:     OPC_DROTR    = OPC_DSRL | (1 << 21),
1.1.1.5   root      141:     OPC_DSRA     = 0x3B | OPC_SPECIAL,
                    142:     OPC_DSLL32   = 0x3C | OPC_SPECIAL,
                    143:     OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
1.1.1.12  root      144:     OPC_DROTR32  = OPC_DSRL32 | (1 << 21),
1.1.1.5   root      145:     OPC_DSRA32   = 0x3F | OPC_SPECIAL,
1.1       root      146:     /* Multiplication / division */
1.1.1.5   root      147:     OPC_MULT     = 0x18 | OPC_SPECIAL,
                    148:     OPC_MULTU    = 0x19 | OPC_SPECIAL,
                    149:     OPC_DIV      = 0x1A | OPC_SPECIAL,
                    150:     OPC_DIVU     = 0x1B | OPC_SPECIAL,
                    151:     OPC_DMULT    = 0x1C | OPC_SPECIAL,
                    152:     OPC_DMULTU   = 0x1D | OPC_SPECIAL,
                    153:     OPC_DDIV     = 0x1E | OPC_SPECIAL,
                    154:     OPC_DDIVU    = 0x1F | OPC_SPECIAL,
1.1       root      155:     /* 2 registers arithmetic / logic */
1.1.1.5   root      156:     OPC_ADD      = 0x20 | OPC_SPECIAL,
                    157:     OPC_ADDU     = 0x21 | OPC_SPECIAL,
                    158:     OPC_SUB      = 0x22 | OPC_SPECIAL,
                    159:     OPC_SUBU     = 0x23 | OPC_SPECIAL,
                    160:     OPC_AND      = 0x24 | OPC_SPECIAL,
                    161:     OPC_OR       = 0x25 | OPC_SPECIAL,
                    162:     OPC_XOR      = 0x26 | OPC_SPECIAL,
                    163:     OPC_NOR      = 0x27 | OPC_SPECIAL,
                    164:     OPC_SLT      = 0x2A | OPC_SPECIAL,
                    165:     OPC_SLTU     = 0x2B | OPC_SPECIAL,
                    166:     OPC_DADD     = 0x2C | OPC_SPECIAL,
                    167:     OPC_DADDU    = 0x2D | OPC_SPECIAL,
                    168:     OPC_DSUB     = 0x2E | OPC_SPECIAL,
                    169:     OPC_DSUBU    = 0x2F | OPC_SPECIAL,
1.1       root      170:     /* Jumps */
1.1.1.5   root      171:     OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
                    172:     OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
1.1.1.12  root      173:     OPC_JALRC    = OPC_JALR | (0x5 << 6),
                    174:     OPC_JALRS    = 0x10 | OPC_SPECIAL | (0x5 << 6),
1.1       root      175:     /* Traps */
1.1.1.5   root      176:     OPC_TGE      = 0x30 | OPC_SPECIAL,
                    177:     OPC_TGEU     = 0x31 | OPC_SPECIAL,
                    178:     OPC_TLT      = 0x32 | OPC_SPECIAL,
                    179:     OPC_TLTU     = 0x33 | OPC_SPECIAL,
                    180:     OPC_TEQ      = 0x34 | OPC_SPECIAL,
                    181:     OPC_TNE      = 0x36 | OPC_SPECIAL,
1.1       root      182:     /* HI / LO registers load & stores */
1.1.1.5   root      183:     OPC_MFHI     = 0x10 | OPC_SPECIAL,
                    184:     OPC_MTHI     = 0x11 | OPC_SPECIAL,
                    185:     OPC_MFLO     = 0x12 | OPC_SPECIAL,
                    186:     OPC_MTLO     = 0x13 | OPC_SPECIAL,
1.1       root      187:     /* Conditional moves */
1.1.1.5   root      188:     OPC_MOVZ     = 0x0A | OPC_SPECIAL,
                    189:     OPC_MOVN     = 0x0B | OPC_SPECIAL,
1.1       root      190: 
1.1.1.5   root      191:     OPC_MOVCI    = 0x01 | OPC_SPECIAL,
1.1       root      192: 
                    193:     /* Special */
1.1.1.9   root      194:     OPC_PMON     = 0x05 | OPC_SPECIAL, /* unofficial */
1.1.1.5   root      195:     OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
                    196:     OPC_BREAK    = 0x0D | OPC_SPECIAL,
1.1.1.9   root      197:     OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
1.1.1.5   root      198:     OPC_SYNC     = 0x0F | OPC_SPECIAL,
                    199: 
                    200:     OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
                    201:     OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
                    202:     OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
                    203:     OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
                    204:     OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
                    205:     OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
                    206:     OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
                    207: };
                    208: 
1.1.1.6   root      209: /* Multiplication variants of the vr54xx. */
                    210: #define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
                    211: 
                    212: enum {
                    213:     OPC_VR54XX_MULS    = (0x03 << 6) | OPC_MULT,
                    214:     OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,
                    215:     OPC_VR54XX_MACC    = (0x05 << 6) | OPC_MULT,
                    216:     OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,
                    217:     OPC_VR54XX_MSAC    = (0x07 << 6) | OPC_MULT,
                    218:     OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,
                    219:     OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,
                    220:     OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,
                    221:     OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,
                    222:     OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
                    223:     OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,
                    224:     OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
                    225:     OPC_VR54XX_MSACHI  = (0x0F << 6) | OPC_MULT,
                    226:     OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
                    227: };
                    228: 
1.1.1.5   root      229: /* REGIMM (rt field) opcodes */
                    230: #define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
                    231: 
                    232: enum {
                    233:     OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
                    234:     OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
                    235:     OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
                    236:     OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
                    237:     OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
1.1.1.12  root      238:     OPC_BLTZALS  = OPC_BLTZAL | 0x5, /* microMIPS */
1.1.1.5   root      239:     OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
                    240:     OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
1.1.1.12  root      241:     OPC_BGEZALS  = OPC_BGEZAL | 0x5, /* microMIPS */
1.1.1.5   root      242:     OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
                    243:     OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
                    244:     OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
                    245:     OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
                    246:     OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
                    247:     OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
                    248:     OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
                    249:     OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
1.1       root      250: };
                    251: 
1.1.1.5   root      252: /* Special2 opcodes */
                    253: #define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
                    254: 
1.1       root      255: enum {
1.1.1.5   root      256:     /* Multiply & xxx operations */
                    257:     OPC_MADD     = 0x00 | OPC_SPECIAL2,
                    258:     OPC_MADDU    = 0x01 | OPC_SPECIAL2,
                    259:     OPC_MUL      = 0x02 | OPC_SPECIAL2,
                    260:     OPC_MSUB     = 0x04 | OPC_SPECIAL2,
                    261:     OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
1.1.1.12  root      262:     /* Loongson 2F */
                    263:     OPC_MULT_G_2F   = 0x10 | OPC_SPECIAL2,
                    264:     OPC_DMULT_G_2F  = 0x11 | OPC_SPECIAL2,
                    265:     OPC_MULTU_G_2F  = 0x12 | OPC_SPECIAL2,
                    266:     OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
                    267:     OPC_DIV_G_2F    = 0x14 | OPC_SPECIAL2,
                    268:     OPC_DDIV_G_2F   = 0x15 | OPC_SPECIAL2,
                    269:     OPC_DIVU_G_2F   = 0x16 | OPC_SPECIAL2,
                    270:     OPC_DDIVU_G_2F  = 0x17 | OPC_SPECIAL2,
                    271:     OPC_MOD_G_2F    = 0x1c | OPC_SPECIAL2,
                    272:     OPC_DMOD_G_2F   = 0x1d | OPC_SPECIAL2,
                    273:     OPC_MODU_G_2F   = 0x1e | OPC_SPECIAL2,
                    274:     OPC_DMODU_G_2F  = 0x1f | OPC_SPECIAL2,
1.1       root      275:     /* Misc */
1.1.1.5   root      276:     OPC_CLZ      = 0x20 | OPC_SPECIAL2,
                    277:     OPC_CLO      = 0x21 | OPC_SPECIAL2,
                    278:     OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
                    279:     OPC_DCLO     = 0x25 | OPC_SPECIAL2,
1.1       root      280:     /* Special */
1.1.1.5   root      281:     OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
                    282: };
                    283: 
                    284: /* Special3 opcodes */
                    285: #define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
                    286: 
                    287: enum {
                    288:     OPC_EXT      = 0x00 | OPC_SPECIAL3,
                    289:     OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
                    290:     OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
                    291:     OPC_DEXT     = 0x03 | OPC_SPECIAL3,
                    292:     OPC_INS      = 0x04 | OPC_SPECIAL3,
                    293:     OPC_DINSM    = 0x05 | OPC_SPECIAL3,
                    294:     OPC_DINSU    = 0x06 | OPC_SPECIAL3,
                    295:     OPC_DINS     = 0x07 | OPC_SPECIAL3,
1.1.1.6   root      296:     OPC_FORK     = 0x08 | OPC_SPECIAL3,
                    297:     OPC_YIELD    = 0x09 | OPC_SPECIAL3,
1.1.1.5   root      298:     OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
                    299:     OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
                    300:     OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
1.1.1.12  root      301: 
                    302:     /* Loongson 2E */
                    303:     OPC_MULT_G_2E   = 0x18 | OPC_SPECIAL3,
                    304:     OPC_MULTU_G_2E  = 0x19 | OPC_SPECIAL3,
                    305:     OPC_DIV_G_2E    = 0x1A | OPC_SPECIAL3,
                    306:     OPC_DIVU_G_2E   = 0x1B | OPC_SPECIAL3,
                    307:     OPC_DMULT_G_2E  = 0x1C | OPC_SPECIAL3,
                    308:     OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
                    309:     OPC_DDIV_G_2E   = 0x1E | OPC_SPECIAL3,
                    310:     OPC_DDIVU_G_2E  = 0x1F | OPC_SPECIAL3,
                    311:     OPC_MOD_G_2E    = 0x22 | OPC_SPECIAL3,
                    312:     OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
                    313:     OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
                    314:     OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
1.1       root      315: };
                    316: 
1.1.1.5   root      317: /* BSHFL opcodes */
                    318: #define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
                    319: 
1.1       root      320: enum {
1.1.1.5   root      321:     OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
                    322:     OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
                    323:     OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
1.1       root      324: };
                    325: 
1.1.1.5   root      326: /* DBSHFL opcodes */
                    327: #define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
                    328: 
1.1       root      329: enum {
1.1.1.5   root      330:     OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
                    331:     OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
1.1       root      332: };
                    333: 
1.1.1.5   root      334: /* Coprocessor 0 (rs field) */
                    335: #define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
                    336: 
1.1.1.4   root      337: enum {
1.1.1.5   root      338:     OPC_MFC0     = (0x00 << 21) | OPC_CP0,
                    339:     OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
                    340:     OPC_MTC0     = (0x04 << 21) | OPC_CP0,
                    341:     OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
1.1.1.6   root      342:     OPC_MFTR     = (0x08 << 21) | OPC_CP0,
1.1.1.5   root      343:     OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
                    344:     OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
1.1.1.6   root      345:     OPC_MTTR     = (0x0C << 21) | OPC_CP0,
1.1.1.5   root      346:     OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
                    347:     OPC_C0       = (0x10 << 21) | OPC_CP0,
                    348:     OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
                    349:     OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,
1.1.1.4   root      350: };
1.1.1.5   root      351: 
                    352: /* MFMC0 opcodes */
1.1.1.6   root      353: #define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
1.1.1.5   root      354: 
                    355: enum {
1.1.1.6   root      356:     OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
                    357:     OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
                    358:     OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
                    359:     OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
1.1.1.5   root      360:     OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
                    361:     OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
                    362: };
                    363: 
                    364: /* Coprocessor 0 (with rs == C0) */
                    365: #define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
                    366: 
                    367: enum {
                    368:     OPC_TLBR     = 0x01 | OPC_C0,
                    369:     OPC_TLBWI    = 0x02 | OPC_C0,
                    370:     OPC_TLBWR    = 0x06 | OPC_C0,
                    371:     OPC_TLBP     = 0x08 | OPC_C0,
                    372:     OPC_RFE      = 0x10 | OPC_C0,
                    373:     OPC_ERET     = 0x18 | OPC_C0,
                    374:     OPC_DERET    = 0x1F | OPC_C0,
                    375:     OPC_WAIT     = 0x20 | OPC_C0,
                    376: };
                    377: 
                    378: /* Coprocessor 1 (rs field) */
                    379: #define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
                    380: 
1.1.1.12  root      381: /* Values for the fmt field in FP instructions */
                    382: enum {
                    383:     /* 0 - 15 are reserved */
                    384:     FMT_S = 16,          /* single fp */
                    385:     FMT_D = 17,          /* double fp */
                    386:     FMT_E = 18,          /* extended fp */
                    387:     FMT_Q = 19,          /* quad fp */
                    388:     FMT_W = 20,          /* 32-bit fixed */
                    389:     FMT_L = 21,          /* 64-bit fixed */
                    390:     FMT_PS = 22,         /* paired single fp */
                    391:     /* 23 - 31 are reserved */
                    392: };
                    393: 
1.1.1.5   root      394: enum {
                    395:     OPC_MFC1     = (0x00 << 21) | OPC_CP1,
                    396:     OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
                    397:     OPC_CFC1     = (0x02 << 21) | OPC_CP1,
1.1.1.6   root      398:     OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
1.1.1.5   root      399:     OPC_MTC1     = (0x04 << 21) | OPC_CP1,
                    400:     OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
                    401:     OPC_CTC1     = (0x06 << 21) | OPC_CP1,
1.1.1.6   root      402:     OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
1.1.1.5   root      403:     OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
1.1.1.6   root      404:     OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
                    405:     OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
1.1.1.12  root      406:     OPC_S_FMT    = (FMT_S << 21) | OPC_CP1,
                    407:     OPC_D_FMT    = (FMT_D << 21) | OPC_CP1,
                    408:     OPC_E_FMT    = (FMT_E << 21) | OPC_CP1,
                    409:     OPC_Q_FMT    = (FMT_Q << 21) | OPC_CP1,
                    410:     OPC_W_FMT    = (FMT_W << 21) | OPC_CP1,
                    411:     OPC_L_FMT    = (FMT_L << 21) | OPC_CP1,
                    412:     OPC_PS_FMT   = (FMT_PS << 21) | OPC_CP1,
1.1.1.5   root      413: };
                    414: 
1.1.1.6   root      415: #define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
                    416: #define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
                    417: 
1.1.1.5   root      418: enum {
                    419:     OPC_BC1F     = (0x00 << 16) | OPC_BC1,
                    420:     OPC_BC1T     = (0x01 << 16) | OPC_BC1,
                    421:     OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
                    422:     OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
                    423: };
                    424: 
1.1.1.6   root      425: enum {
                    426:     OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
                    427:     OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
                    428: };
                    429: 
                    430: enum {
                    431:     OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
                    432:     OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
                    433: };
1.1.1.5   root      434: 
                    435: #define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
1.1.1.6   root      436: 
                    437: enum {
                    438:     OPC_MFC2    = (0x00 << 21) | OPC_CP2,
                    439:     OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
                    440:     OPC_CFC2    = (0x02 << 21) | OPC_CP2,
                    441:     OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
                    442:     OPC_MTC2    = (0x04 << 21) | OPC_CP2,
                    443:     OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
                    444:     OPC_CTC2    = (0x06 << 21) | OPC_CP2,
                    445:     OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
                    446:     OPC_BC2     = (0x08 << 21) | OPC_CP2,
                    447: };
                    448: 
                    449: #define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
                    450: 
                    451: enum {
                    452:     OPC_LWXC1   = 0x00 | OPC_CP3,
                    453:     OPC_LDXC1   = 0x01 | OPC_CP3,
                    454:     OPC_LUXC1   = 0x05 | OPC_CP3,
                    455:     OPC_SWXC1   = 0x08 | OPC_CP3,
                    456:     OPC_SDXC1   = 0x09 | OPC_CP3,
                    457:     OPC_SUXC1   = 0x0D | OPC_CP3,
                    458:     OPC_PREFX   = 0x0F | OPC_CP3,
                    459:     OPC_ALNV_PS = 0x1E | OPC_CP3,
                    460:     OPC_MADD_S  = 0x20 | OPC_CP3,
                    461:     OPC_MADD_D  = 0x21 | OPC_CP3,
                    462:     OPC_MADD_PS = 0x26 | OPC_CP3,
                    463:     OPC_MSUB_S  = 0x28 | OPC_CP3,
                    464:     OPC_MSUB_D  = 0x29 | OPC_CP3,
                    465:     OPC_MSUB_PS = 0x2E | OPC_CP3,
                    466:     OPC_NMADD_S = 0x30 | OPC_CP3,
                    467:     OPC_NMADD_D = 0x31 | OPC_CP3,
                    468:     OPC_NMADD_PS= 0x36 | OPC_CP3,
                    469:     OPC_NMSUB_S = 0x38 | OPC_CP3,
                    470:     OPC_NMSUB_D = 0x39 | OPC_CP3,
                    471:     OPC_NMSUB_PS= 0x3E | OPC_CP3,
                    472: };
                    473: 
1.1.1.7   root      474: /* global register indices */
                    475: static TCGv_ptr cpu_env;
                    476: static TCGv cpu_gpr[32], cpu_PC;
                    477: static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
1.1.1.8   root      478: static TCGv cpu_dspctrl, btarget, bcond;
                    479: static TCGv_i32 hflags;
1.1.1.7   root      480: static TCGv_i32 fpu_fcr0, fpu_fcr31;
                    481: 
1.1.1.12  root      482: static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
                    483: 
1.1.1.7   root      484: #include "gen-icount.h"
                    485: 
                    486: #define gen_helper_0i(name, arg) do {                             \
                    487:     TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
                    488:     gen_helper_##name(helper_tmp);                                \
                    489:     tcg_temp_free_i32(helper_tmp);                                \
                    490:     } while(0)
1.1.1.4   root      491: 
1.1.1.7   root      492: #define gen_helper_1i(name, arg1, arg2) do {                      \
                    493:     TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
                    494:     gen_helper_##name(arg1, helper_tmp);                          \
                    495:     tcg_temp_free_i32(helper_tmp);                                \
                    496:     } while(0)
1.1.1.4   root      497: 
1.1.1.7   root      498: #define gen_helper_2i(name, arg1, arg2, arg3) do {                \
                    499:     TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
                    500:     gen_helper_##name(arg1, arg2, helper_tmp);                    \
                    501:     tcg_temp_free_i32(helper_tmp);                                \
                    502:     } while(0)
1.1.1.4   root      503: 
1.1.1.7   root      504: #define gen_helper_3i(name, arg1, arg2, arg3, arg4) do {          \
                    505:     TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
                    506:     gen_helper_##name(arg1, arg2, arg3, helper_tmp);              \
                    507:     tcg_temp_free_i32(helper_tmp);                                \
                    508:     } while(0)
1.1.1.4   root      509: 
1.1       root      510: typedef struct DisasContext {
                    511:     struct TranslationBlock *tb;
                    512:     target_ulong pc, saved_pc;
                    513:     uint32_t opcode;
1.1.1.9   root      514:     int singlestep_enabled;
1.1       root      515:     /* Routine used to access memory */
                    516:     int mem_idx;
                    517:     uint32_t hflags, saved_hflags;
                    518:     int bstate;
                    519:     target_ulong btarget;
                    520: } DisasContext;
                    521: 
                    522: enum {
                    523:     BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
1.1.1.7   root      524:                       * exception condition */
1.1       root      525:     BS_STOP     = 1, /* We want to stop translation for any reason */
                    526:     BS_BRANCH   = 2, /* We reached a branch condition     */
                    527:     BS_EXCP     = 3, /* We reached an exception condition */
                    528: };
                    529: 
1.1.1.7   root      530: static const char *regnames[] =
                    531:     { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
                    532:       "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
                    533:       "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
                    534:       "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
                    535: 
                    536: static const char *regnames_HI[] =
                    537:     { "HI0", "HI1", "HI2", "HI3", };
                    538: 
                    539: static const char *regnames_LO[] =
                    540:     { "LO0", "LO1", "LO2", "LO3", };
                    541: 
                    542: static const char *regnames_ACX[] =
                    543:     { "ACX0", "ACX1", "ACX2", "ACX3", };
                    544: 
                    545: static const char *fregnames[] =
                    546:     { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
                    547:       "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
                    548:       "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
                    549:       "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
                    550: 
1.1.1.6   root      551: #ifdef MIPS_DEBUG_DISAS
1.1.1.8   root      552: #define MIPS_DEBUG(fmt, ...)                         \
1.1.1.7   root      553:         qemu_log_mask(CPU_LOG_TB_IN_ASM,                \
                    554:                        TARGET_FMT_lx ": %08x " fmt "\n", \
1.1.1.8   root      555:                        ctx->pc, ctx->opcode , ## __VA_ARGS__)
1.1.1.7   root      556: #define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
1.1       root      557: #else
1.1.1.8   root      558: #define MIPS_DEBUG(fmt, ...) do { } while(0)
1.1.1.7   root      559: #define LOG_DISAS(...) do { } while (0)
1.1       root      560: #endif
                    561: 
                    562: #define MIPS_INVAL(op)                                                        \
                    563: do {                                                                          \
                    564:     MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
                    565:                ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
                    566: } while (0)
                    567: 
1.1.1.7   root      568: /* General purpose registers moves. */
                    569: static inline void gen_load_gpr (TCGv t, int reg)
                    570: {
                    571:     if (reg == 0)
                    572:         tcg_gen_movi_tl(t, 0);
                    573:     else
                    574:         tcg_gen_mov_tl(t, cpu_gpr[reg]);
                    575: }
1.1.1.6   root      576: 
1.1.1.7   root      577: static inline void gen_store_gpr (TCGv t, int reg)
                    578: {
                    579:     if (reg != 0)
                    580:         tcg_gen_mov_tl(cpu_gpr[reg], t);
                    581: }
1.1.1.6   root      582: 
1.1.1.7   root      583: /* Moves to/from ACX register.  */
                    584: static inline void gen_load_ACX (TCGv t, int reg)
                    585: {
                    586:     tcg_gen_mov_tl(t, cpu_ACX[reg]);
                    587: }
1.1.1.6   root      588: 
1.1.1.7   root      589: static inline void gen_store_ACX (TCGv t, int reg)
                    590: {
                    591:     tcg_gen_mov_tl(cpu_ACX[reg], t);
                    592: }
1.1       root      593: 
1.1.1.7   root      594: /* Moves to/from shadow registers. */
                    595: static inline void gen_load_srsgpr (int from, int to)
                    596: {
1.1.1.8   root      597:     TCGv t0 = tcg_temp_new();
1.1.1.6   root      598: 
1.1.1.7   root      599:     if (from == 0)
1.1.1.8   root      600:         tcg_gen_movi_tl(t0, 0);
1.1.1.7   root      601:     else {
1.1.1.8   root      602:         TCGv_i32 t2 = tcg_temp_new_i32();
1.1.1.7   root      603:         TCGv_ptr addr = tcg_temp_new_ptr();
1.1.1.6   root      604: 
1.1.1.16! root      605:         tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1.1.1.8   root      606:         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
                    607:         tcg_gen_andi_i32(t2, t2, 0xf);
                    608:         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
                    609:         tcg_gen_ext_i32_ptr(addr, t2);
1.1.1.7   root      610:         tcg_gen_add_ptr(addr, cpu_env, addr);
1.1       root      611: 
1.1.1.8   root      612:         tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1.1.1.7   root      613:         tcg_temp_free_ptr(addr);
1.1.1.8   root      614:         tcg_temp_free_i32(t2);
1.1.1.7   root      615:     }
1.1.1.8   root      616:     gen_store_gpr(t0, to);
                    617:     tcg_temp_free(t0);
1.1.1.7   root      618: }
1.1       root      619: 
1.1.1.7   root      620: static inline void gen_store_srsgpr (int from, int to)
                    621: {
                    622:     if (to != 0) {
1.1.1.8   root      623:         TCGv t0 = tcg_temp_new();
                    624:         TCGv_i32 t2 = tcg_temp_new_i32();
1.1.1.7   root      625:         TCGv_ptr addr = tcg_temp_new_ptr();
1.1.1.4   root      626: 
1.1.1.8   root      627:         gen_load_gpr(t0, from);
1.1.1.16! root      628:         tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUMIPSState, CP0_SRSCtl));
1.1.1.8   root      629:         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
                    630:         tcg_gen_andi_i32(t2, t2, 0xf);
                    631:         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
                    632:         tcg_gen_ext_i32_ptr(addr, t2);
1.1.1.7   root      633:         tcg_gen_add_ptr(addr, cpu_env, addr);
1.1.1.4   root      634: 
1.1.1.8   root      635:         tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1.1.1.7   root      636:         tcg_temp_free_ptr(addr);
1.1.1.8   root      637:         tcg_temp_free_i32(t2);
                    638:         tcg_temp_free(t0);
1.1.1.6   root      639:     }
                    640: }
                    641: 
1.1.1.7   root      642: /* Floating point register moves. */
                    643: static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
1.1.1.6   root      644: {
1.1.1.16! root      645:     tcg_gen_ld_i32(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
1.1.1.7   root      646: }
                    647: 
                    648: static inline void gen_store_fpr32 (TCGv_i32 t, int reg)
                    649: {
1.1.1.16! root      650:     tcg_gen_st_i32(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
1.1.1.7   root      651: }
                    652: 
1.1.1.8   root      653: static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
1.1.1.7   root      654: {
1.1.1.16! root      655:     tcg_gen_ld_i32(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
1.1.1.6   root      656: }
                    657: 
1.1.1.8   root      658: static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
1.1       root      659: {
1.1.1.16! root      660:     tcg_gen_st_i32(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
1.1.1.7   root      661: }
                    662: 
1.1.1.8   root      663: static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
1.1.1.7   root      664: {
1.1.1.8   root      665:     if (ctx->hflags & MIPS_HFLAG_F64) {
1.1.1.16! root      666:         tcg_gen_ld_i64(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].d));
1.1.1.8   root      667:     } else {
                    668:         TCGv_i32 t0 = tcg_temp_new_i32();
                    669:         TCGv_i32 t1 = tcg_temp_new_i32();
                    670:         gen_load_fpr32(t0, reg & ~1);
                    671:         gen_load_fpr32(t1, reg | 1);
                    672:         tcg_gen_concat_i32_i64(t, t0, t1);
                    673:         tcg_temp_free_i32(t0);
                    674:         tcg_temp_free_i32(t1);
                    675:     }
1.1.1.7   root      676: }
                    677: 
1.1.1.8   root      678: static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
1.1.1.7   root      679: {
1.1.1.8   root      680:     if (ctx->hflags & MIPS_HFLAG_F64) {
1.1.1.16! root      681:         tcg_gen_st_i64(t, cpu_env, offsetof(CPUMIPSState, active_fpu.fpr[reg].d));
1.1.1.8   root      682:     } else {
                    683:         TCGv_i64 t0 = tcg_temp_new_i64();
                    684:         TCGv_i32 t1 = tcg_temp_new_i32();
                    685:         tcg_gen_trunc_i64_i32(t1, t);
                    686:         gen_store_fpr32(t1, reg & ~1);
                    687:         tcg_gen_shri_i64(t0, t, 32);
                    688:         tcg_gen_trunc_i64_i32(t1, t0);
                    689:         gen_store_fpr32(t1, reg | 1);
                    690:         tcg_temp_free_i32(t1);
                    691:         tcg_temp_free_i64(t0);
                    692:     }
1.1.1.7   root      693: }
                    694: 
1.1.1.8   root      695: static inline int get_fp_bit (int cc)
1.1.1.7   root      696: {
1.1.1.8   root      697:     if (cc)
                    698:         return 24 + cc;
                    699:     else
                    700:         return 23;
1.1.1.7   root      701: }
                    702: 
                    703: /* Tests */
                    704: static inline void gen_save_pc(target_ulong pc)
                    705: {
                    706:     tcg_gen_movi_tl(cpu_PC, pc);
                    707: }
                    708: 
                    709: static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
                    710: {
                    711:     LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1.1       root      712:     if (do_save_pc && ctx->pc != ctx->saved_pc) {
1.1.1.6   root      713:         gen_save_pc(ctx->pc);
1.1       root      714:         ctx->saved_pc = ctx->pc;
                    715:     }
                    716:     if (ctx->hflags != ctx->saved_hflags) {
1.1.1.8   root      717:         tcg_gen_movi_i32(hflags, ctx->hflags);
1.1       root      718:         ctx->saved_hflags = ctx->hflags;
1.1.1.12  root      719:         switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1.1.1.6   root      720:         case MIPS_HFLAG_BR:
                    721:             break;
                    722:         case MIPS_HFLAG_BC:
                    723:         case MIPS_HFLAG_BL:
                    724:         case MIPS_HFLAG_B:
1.1.1.7   root      725:             tcg_gen_movi_tl(btarget, ctx->btarget);
1.1.1.6   root      726:             break;
1.1       root      727:         }
                    728:     }
                    729: }
                    730: 
1.1.1.16! root      731: static inline void restore_cpu_state (CPUMIPSState *env, DisasContext *ctx)
1.1.1.6   root      732: {
                    733:     ctx->saved_hflags = ctx->hflags;
1.1.1.12  root      734:     switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1.1.1.6   root      735:     case MIPS_HFLAG_BR:
                    736:         break;
                    737:     case MIPS_HFLAG_BC:
                    738:     case MIPS_HFLAG_BL:
1.1.1.7   root      739:     case MIPS_HFLAG_B:
1.1.1.6   root      740:         ctx->btarget = env->btarget;
                    741:         break;
                    742:     }
                    743: }
                    744: 
1.1.1.7   root      745: static inline void
                    746: generate_exception_err (DisasContext *ctx, int excp, int err)
1.1       root      747: {
1.1.1.7   root      748:     TCGv_i32 texcp = tcg_const_i32(excp);
                    749:     TCGv_i32 terr = tcg_const_i32(err);
1.1       root      750:     save_cpu_state(ctx, 1);
1.1.1.7   root      751:     gen_helper_raise_exception_err(texcp, terr);
                    752:     tcg_temp_free_i32(terr);
                    753:     tcg_temp_free_i32(texcp);
                    754: }
                    755: 
                    756: static inline void
                    757: generate_exception (DisasContext *ctx, int excp)
                    758: {
                    759:     save_cpu_state(ctx, 1);
                    760:     gen_helper_0i(raise_exception, excp);
1.1       root      761: }
                    762: 
1.1.1.7   root      763: /* Addresses computation */
1.1.1.9   root      764: static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1.1.1.2   root      765: {
1.1.1.9   root      766:     tcg_gen_add_tl(ret, arg0, arg1);
1.1.1.7   root      767: 
                    768: #if defined(TARGET_MIPS64)
                    769:     /* For compatibility with 32-bit code, data reference in user mode
                    770:        with Status_UX = 0 should be casted to 32-bit and sign extended.
                    771:        See the MIPS64 PRA manual, section 4.10. */
                    772:     if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
                    773:         !(ctx->hflags & MIPS_HFLAG_UX)) {
1.1.1.9   root      774:         tcg_gen_ext32s_i64(ret, ret);
1.1.1.7   root      775:     }
                    776: #endif
1.1.1.2   root      777: }
                    778: 
1.1.1.7   root      779: static inline void check_cp0_enabled(DisasContext *ctx)
1.1.1.6   root      780: {
                    781:     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1.1.1.10  root      782:         generate_exception_err(ctx, EXCP_CpU, 0);
1.1.1.6   root      783: }
                    784: 
1.1.1.7   root      785: static inline void check_cp1_enabled(DisasContext *ctx)
1.1.1.6   root      786: {
                    787:     if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
                    788:         generate_exception_err(ctx, EXCP_CpU, 1);
                    789: }
                    790: 
                    791: /* Verify that the processor is running with COP1X instructions enabled.
                    792:    This is associated with the nabla symbol in the MIPS32 and MIPS64
                    793:    opcode tables.  */
                    794: 
1.1.1.7   root      795: static inline void check_cop1x(DisasContext *ctx)
1.1.1.6   root      796: {
                    797:     if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
                    798:         generate_exception(ctx, EXCP_RI);
                    799: }
                    800: 
                    801: /* Verify that the processor is running with 64-bit floating-point
                    802:    operations enabled.  */
                    803: 
1.1.1.7   root      804: static inline void check_cp1_64bitmode(DisasContext *ctx)
1.1.1.6   root      805: {
                    806:     if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
                    807:         generate_exception(ctx, EXCP_RI);
                    808: }
                    809: 
                    810: /*
                    811:  * Verify if floating point register is valid; an operation is not defined
                    812:  * if bit 0 of any register specification is set and the FR bit in the
                    813:  * Status register equals zero, since the register numbers specify an
                    814:  * even-odd pair of adjacent coprocessor general registers. When the FR bit
                    815:  * in the Status register equals one, both even and odd register numbers
                    816:  * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
                    817:  *
                    818:  * Multiple 64 bit wide registers can be checked by calling
                    819:  * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
                    820:  */
1.1.1.7   root      821: static inline void check_cp1_registers(DisasContext *ctx, int regs)
1.1.1.6   root      822: {
                    823:     if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
                    824:         generate_exception(ctx, EXCP_RI);
                    825: }
                    826: 
                    827: /* This code generates a "reserved instruction" exception if the
                    828:    CPU does not support the instruction set corresponding to flags. */
1.1.1.16! root      829: static inline void check_insn(CPUMIPSState *env, DisasContext *ctx, int flags)
1.1.1.6   root      830: {
                    831:     if (unlikely(!(env->insn_flags & flags)))
                    832:         generate_exception(ctx, EXCP_RI);
                    833: }
                    834: 
                    835: /* This code generates a "reserved instruction" exception if 64-bit
                    836:    instructions are not enabled. */
1.1.1.7   root      837: static inline void check_mips_64(DisasContext *ctx)
1.1.1.6   root      838: {
                    839:     if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
                    840:         generate_exception(ctx, EXCP_RI);
                    841: }
                    842: 
1.1.1.12  root      843: /* Define small wrappers for gen_load_fpr* so that we have a uniform
                    844:    calling interface for 32 and 64-bit FPRs.  No sense in changing
                    845:    all callers for gen_load_fpr32 when we need the CTX parameter for
                    846:    this one use.  */
                    847: #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
                    848: #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
                    849: #define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
                    850: static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
                    851:                                                int ft, int fs, int cc)        \
                    852: {                                                                             \
                    853:     TCGv_i##bits fp0 = tcg_temp_new_i##bits ();                               \
                    854:     TCGv_i##bits fp1 = tcg_temp_new_i##bits ();                               \
                    855:     switch (ifmt) {                                                           \
                    856:     case FMT_PS:                                                              \
                    857:         check_cp1_64bitmode(ctx);                                             \
                    858:         break;                                                                \
                    859:     case FMT_D:                                                               \
                    860:         if (abs) {                                                            \
                    861:             check_cop1x(ctx);                                                 \
                    862:         }                                                                     \
                    863:         check_cp1_registers(ctx, fs | ft);                                    \
                    864:         break;                                                                \
                    865:     case FMT_S:                                                               \
                    866:         if (abs) {                                                            \
                    867:             check_cop1x(ctx);                                                 \
                    868:         }                                                                     \
                    869:         break;                                                                \
                    870:     }                                                                         \
                    871:     gen_ldcmp_fpr##bits (ctx, fp0, fs);                                       \
                    872:     gen_ldcmp_fpr##bits (ctx, fp1, ft);                                       \
                    873:     switch (n) {                                                              \
                    874:     case  0: gen_helper_2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);    break;\
                    875:     case  1: gen_helper_2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);   break;\
                    876:     case  2: gen_helper_2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);   break;\
                    877:     case  3: gen_helper_2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);  break;\
                    878:     case  4: gen_helper_2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);  break;\
                    879:     case  5: gen_helper_2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);  break;\
                    880:     case  6: gen_helper_2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);  break;\
                    881:     case  7: gen_helper_2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);  break;\
                    882:     case  8: gen_helper_2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);   break;\
                    883:     case  9: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
                    884:     case 10: gen_helper_2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);  break;\
                    885:     case 11: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);  break;\
                    886:     case 12: gen_helper_2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);   break;\
                    887:     case 13: gen_helper_2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);  break;\
                    888:     case 14: gen_helper_2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);   break;\
                    889:     case 15: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);  break;\
                    890:     default: abort();                                                         \
                    891:     }                                                                         \
                    892:     tcg_temp_free_i##bits (fp0);                                              \
                    893:     tcg_temp_free_i##bits (fp1);                                              \
                    894: }
                    895: 
                    896: FOP_CONDS(, 0, d, FMT_D, 64)
                    897: FOP_CONDS(abs, 1, d, FMT_D, 64)
                    898: FOP_CONDS(, 0, s, FMT_S, 32)
                    899: FOP_CONDS(abs, 1, s, FMT_S, 32)
                    900: FOP_CONDS(, 0, ps, FMT_PS, 64)
                    901: FOP_CONDS(abs, 1, ps, FMT_PS, 64)
                    902: #undef FOP_CONDS
                    903: #undef gen_ldcmp_fpr32
                    904: #undef gen_ldcmp_fpr64
                    905: 
1.1.1.7   root      906: /* load/store instructions. */
1.1.1.8   root      907: #define OP_LD(insn,fname)                                                 \
1.1.1.12  root      908: static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)   \
1.1.1.8   root      909: {                                                                         \
                    910:     tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                        \
1.1.1.7   root      911: }
                    912: OP_LD(lb,ld8s);
                    913: OP_LD(lbu,ld8u);
                    914: OP_LD(lh,ld16s);
                    915: OP_LD(lhu,ld16u);
                    916: OP_LD(lw,ld32s);
                    917: #if defined(TARGET_MIPS64)
                    918: OP_LD(lwu,ld32u);
                    919: OP_LD(ld,ld64);
                    920: #endif
                    921: #undef OP_LD
                    922: 
1.1.1.8   root      923: #define OP_ST(insn,fname)                                                  \
1.1.1.12  root      924: static inline void op_st_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx)   \
1.1.1.8   root      925: {                                                                          \
                    926:     tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx);                        \
1.1.1.7   root      927: }
                    928: OP_ST(sb,st8);
                    929: OP_ST(sh,st16);
                    930: OP_ST(sw,st32);
                    931: #if defined(TARGET_MIPS64)
                    932: OP_ST(sd,st64);
                    933: #endif
                    934: #undef OP_ST
                    935: 
1.1.1.9   root      936: #ifdef CONFIG_USER_ONLY
1.1.1.8   root      937: #define OP_LD_ATOMIC(insn,fname)                                           \
1.1.1.12  root      938: static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
1.1.1.8   root      939: {                                                                          \
                    940:     TCGv t0 = tcg_temp_new();                                              \
                    941:     tcg_gen_mov_tl(t0, arg1);                                              \
                    942:     tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
1.1.1.16! root      943:     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                \
        !           944:     tcg_gen_st_tl(ret, cpu_env, offsetof(CPUMIPSState, llval));                \
1.1.1.8   root      945:     tcg_temp_free(t0);                                                     \
1.1       root      946: }
1.1.1.9   root      947: #else
                    948: #define OP_LD_ATOMIC(insn,fname)                                           \
1.1.1.12  root      949: static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
1.1.1.9   root      950: {                                                                          \
                    951:     gen_helper_2i(insn, ret, arg1, ctx->mem_idx);                          \
                    952: }
                    953: #endif
1.1.1.7   root      954: OP_LD_ATOMIC(ll,ld32s);
                    955: #if defined(TARGET_MIPS64)
                    956: OP_LD_ATOMIC(lld,ld64);
1.1       root      957: #endif
1.1.1.7   root      958: #undef OP_LD_ATOMIC
1.1       root      959: 
1.1.1.8   root      960: #ifdef CONFIG_USER_ONLY
                    961: #define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
1.1.1.12  root      962: static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1.1.1.8   root      963: {                                                                            \
                    964:     TCGv t0 = tcg_temp_new();                                                \
                    965:     int l1 = gen_new_label();                                                \
                    966:     int l2 = gen_new_label();                                                \
                    967:                                                                              \
                    968:     tcg_gen_andi_tl(t0, arg2, almask);                                       \
                    969:     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                              \
1.1.1.16! root      970:     tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));          \
1.1.1.8   root      971:     generate_exception(ctx, EXCP_AdES);                                      \
                    972:     gen_set_label(l1);                                                       \
1.1.1.16! root      973:     tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, lladdr));                  \
1.1.1.8   root      974:     tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                            \
                    975:     tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20));                        \
1.1.1.16! root      976:     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUMIPSState, llreg));                   \
        !           977:     tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUMIPSState, llnewval));              \
1.1.1.8   root      978:     gen_helper_0i(raise_exception, EXCP_SC);                                 \
                    979:     gen_set_label(l2);                                                       \
                    980:     tcg_gen_movi_tl(t0, 0);                                                  \
                    981:     gen_store_gpr(t0, rt);                                                   \
                    982:     tcg_temp_free(t0);                                                       \
                    983: }
                    984: #else
                    985: #define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
1.1.1.12  root      986: static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1.1.1.8   root      987: {                                                                            \
                    988:     TCGv t0 = tcg_temp_new();                                                \
1.1.1.9   root      989:     gen_helper_3i(insn, t0, arg1, arg2, ctx->mem_idx);                       \
1.1.1.8   root      990:     gen_store_gpr(t0, rt);                                                   \
                    991:     tcg_temp_free(t0);                                                       \
1.1.1.7   root      992: }
1.1.1.8   root      993: #endif
                    994: OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1.1.1.6   root      995: #if defined(TARGET_MIPS64)
1.1.1.8   root      996: OP_ST_ATOMIC(scd,st64,ld64,0x7);
1.1       root      997: #endif
1.1.1.7   root      998: #undef OP_ST_ATOMIC
1.1       root      999: 
1.1.1.12  root     1000: static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
                   1001:                                   int base, int16_t offset)
1.1       root     1002: {
                   1003:     if (base == 0) {
1.1.1.12  root     1004:         tcg_gen_movi_tl(addr, offset);
1.1       root     1005:     } else if (offset == 0) {
1.1.1.12  root     1006:         gen_load_gpr(addr, base);
1.1       root     1007:     } else {
1.1.1.12  root     1008:         tcg_gen_movi_tl(addr, offset);
                   1009:         gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1.1       root     1010:     }
1.1.1.12  root     1011: }
                   1012: 
                   1013: static target_ulong pc_relative_pc (DisasContext *ctx)
                   1014: {
                   1015:     target_ulong pc = ctx->pc;
                   1016: 
                   1017:     if (ctx->hflags & MIPS_HFLAG_BMASK) {
                   1018:         int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
                   1019: 
                   1020:         pc -= branch_bytes;
                   1021:     }
                   1022: 
                   1023:     pc &= ~(target_ulong)3;
                   1024:     return pc;
                   1025: }
                   1026: 
                   1027: /* Load */
1.1.1.16! root     1028: static void gen_ld (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1.1.1.12  root     1029:                     int rt, int base, int16_t offset)
                   1030: {
                   1031:     const char *opn = "ld";
                   1032:     TCGv t0, t1;
                   1033: 
                   1034:     if (rt == 0 && env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
                   1035:         /* Loongson CPU uses a load to zero register for prefetch.
                   1036:            We emulate it as a NOP. On other CPU we must perform the
                   1037:            actual memory access. */
                   1038:         MIPS_DEBUG("NOP");
                   1039:         return;
                   1040:     }
                   1041: 
                   1042:     t0 = tcg_temp_new();
                   1043:     t1 = tcg_temp_new();
                   1044:     gen_base_offset_addr(ctx, t0, base, offset);
                   1045: 
1.1       root     1046:     switch (opc) {
1.1.1.6   root     1047: #if defined(TARGET_MIPS64)
                   1048:     case OPC_LWU:
1.1.1.8   root     1049:         save_cpu_state(ctx, 0);
1.1.1.12  root     1050:         op_ld_lwu(t0, t0, ctx);
1.1.1.7   root     1051:         gen_store_gpr(t0, rt);
1.1.1.6   root     1052:         opn = "lwu";
                   1053:         break;
1.1       root     1054:     case OPC_LD:
1.1.1.8   root     1055:         save_cpu_state(ctx, 0);
1.1.1.12  root     1056:         op_ld_ld(t0, t0, ctx);
1.1.1.7   root     1057:         gen_store_gpr(t0, rt);
1.1       root     1058:         opn = "ld";
                   1059:         break;
1.1.1.5   root     1060:     case OPC_LLD:
1.1.1.13  root     1061:         save_cpu_state(ctx, 1);
1.1.1.12  root     1062:         op_ld_lld(t0, t0, ctx);
1.1.1.7   root     1063:         gen_store_gpr(t0, rt);
1.1.1.5   root     1064:         opn = "lld";
                   1065:         break;
1.1       root     1066:     case OPC_LDL:
1.1.1.7   root     1067:         save_cpu_state(ctx, 1);
                   1068:         gen_load_gpr(t1, rt);
1.1.1.8   root     1069:         gen_helper_3i(ldl, t1, t1, t0, ctx->mem_idx);
1.1.1.7   root     1070:         gen_store_gpr(t1, rt);
1.1       root     1071:         opn = "ldl";
                   1072:         break;
                   1073:     case OPC_LDR:
1.1.1.7   root     1074:         save_cpu_state(ctx, 1);
                   1075:         gen_load_gpr(t1, rt);
1.1.1.8   root     1076:         gen_helper_3i(ldr, t1, t1, t0, ctx->mem_idx);
1.1.1.7   root     1077:         gen_store_gpr(t1, rt);
1.1       root     1078:         opn = "ldr";
                   1079:         break;
1.1.1.12  root     1080:     case OPC_LDPC:
1.1.1.13  root     1081:         save_cpu_state(ctx, 0);
1.1.1.12  root     1082:         tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
                   1083:         gen_op_addr_add(ctx, t0, t0, t1);
                   1084:         op_ld_ld(t0, t0, ctx);
                   1085:         gen_store_gpr(t0, rt);
                   1086:         opn = "ldpc";
1.1       root     1087:         break;
                   1088: #endif
1.1.1.12  root     1089:     case OPC_LWPC:
1.1.1.13  root     1090:         save_cpu_state(ctx, 0);
1.1.1.12  root     1091:         tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
                   1092:         gen_op_addr_add(ctx, t0, t0, t1);
                   1093:         op_ld_lw(t0, t0, ctx);
                   1094:         gen_store_gpr(t0, rt);
                   1095:         opn = "lwpc";
                   1096:         break;
1.1       root     1097:     case OPC_LW:
1.1.1.8   root     1098:         save_cpu_state(ctx, 0);
1.1.1.12  root     1099:         op_ld_lw(t0, t0, ctx);
1.1.1.7   root     1100:         gen_store_gpr(t0, rt);
1.1       root     1101:         opn = "lw";
                   1102:         break;
                   1103:     case OPC_LH:
1.1.1.8   root     1104:         save_cpu_state(ctx, 0);
1.1.1.12  root     1105:         op_ld_lh(t0, t0, ctx);
1.1.1.7   root     1106:         gen_store_gpr(t0, rt);
1.1       root     1107:         opn = "lh";
                   1108:         break;
                   1109:     case OPC_LHU:
1.1.1.8   root     1110:         save_cpu_state(ctx, 0);
1.1.1.12  root     1111:         op_ld_lhu(t0, t0, ctx);
1.1.1.7   root     1112:         gen_store_gpr(t0, rt);
1.1       root     1113:         opn = "lhu";
                   1114:         break;
                   1115:     case OPC_LB:
1.1.1.8   root     1116:         save_cpu_state(ctx, 0);
1.1.1.12  root     1117:         op_ld_lb(t0, t0, ctx);
1.1.1.7   root     1118:         gen_store_gpr(t0, rt);
1.1       root     1119:         opn = "lb";
                   1120:         break;
                   1121:     case OPC_LBU:
1.1.1.8   root     1122:         save_cpu_state(ctx, 0);
1.1.1.12  root     1123:         op_ld_lbu(t0, t0, ctx);
1.1.1.7   root     1124:         gen_store_gpr(t0, rt);
1.1       root     1125:         opn = "lbu";
                   1126:         break;
                   1127:     case OPC_LWL:
1.1.1.7   root     1128:         save_cpu_state(ctx, 1);
                   1129:         gen_load_gpr(t1, rt);
1.1.1.8   root     1130:         gen_helper_3i(lwl, t1, t1, t0, ctx->mem_idx);
1.1.1.7   root     1131:         gen_store_gpr(t1, rt);
1.1       root     1132:         opn = "lwl";
                   1133:         break;
                   1134:     case OPC_LWR:
1.1.1.7   root     1135:         save_cpu_state(ctx, 1);
                   1136:         gen_load_gpr(t1, rt);
1.1.1.8   root     1137:         gen_helper_3i(lwr, t1, t1, t0, ctx->mem_idx);
1.1.1.7   root     1138:         gen_store_gpr(t1, rt);
1.1       root     1139:         opn = "lwr";
                   1140:         break;
                   1141:     case OPC_LL:
1.1.1.9   root     1142:         save_cpu_state(ctx, 1);
1.1.1.12  root     1143:         op_ld_ll(t0, t0, ctx);
1.1.1.7   root     1144:         gen_store_gpr(t0, rt);
1.1       root     1145:         opn = "ll";
                   1146:         break;
1.1.1.8   root     1147:     }
1.1.1.13  root     1148:     (void)opn; /* avoid a compiler warning */
1.1.1.8   root     1149:     MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
                   1150:     tcg_temp_free(t0);
                   1151:     tcg_temp_free(t1);
                   1152: }
                   1153: 
1.1.1.12  root     1154: /* Store */
                   1155: static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
                   1156:                     int base, int16_t offset)
                   1157: {
                   1158:     const char *opn = "st";
                   1159:     TCGv t0 = tcg_temp_new();
                   1160:     TCGv t1 = tcg_temp_new();
                   1161: 
                   1162:     gen_base_offset_addr(ctx, t0, base, offset);
                   1163:     gen_load_gpr(t1, rt);
                   1164:     switch (opc) {
                   1165: #if defined(TARGET_MIPS64)
                   1166:     case OPC_SD:
                   1167:         save_cpu_state(ctx, 0);
                   1168:         op_st_sd(t1, t0, ctx);
                   1169:         opn = "sd";
                   1170:         break;
                   1171:     case OPC_SDL:
                   1172:         save_cpu_state(ctx, 1);
                   1173:         gen_helper_2i(sdl, t1, t0, ctx->mem_idx);
                   1174:         opn = "sdl";
                   1175:         break;
                   1176:     case OPC_SDR:
                   1177:         save_cpu_state(ctx, 1);
                   1178:         gen_helper_2i(sdr, t1, t0, ctx->mem_idx);
                   1179:         opn = "sdr";
                   1180:         break;
                   1181: #endif
                   1182:     case OPC_SW:
                   1183:         save_cpu_state(ctx, 0);
                   1184:         op_st_sw(t1, t0, ctx);
                   1185:         opn = "sw";
                   1186:         break;
                   1187:     case OPC_SH:
                   1188:         save_cpu_state(ctx, 0);
                   1189:         op_st_sh(t1, t0, ctx);
                   1190:         opn = "sh";
                   1191:         break;
                   1192:     case OPC_SB:
                   1193:         save_cpu_state(ctx, 0);
                   1194:         op_st_sb(t1, t0, ctx);
                   1195:         opn = "sb";
                   1196:         break;
                   1197:     case OPC_SWL:
                   1198:         save_cpu_state(ctx, 1);
                   1199:         gen_helper_2i(swl, t1, t0, ctx->mem_idx);
                   1200:         opn = "swl";
                   1201:         break;
                   1202:     case OPC_SWR:
                   1203:         save_cpu_state(ctx, 1);
                   1204:         gen_helper_2i(swr, t1, t0, ctx->mem_idx);
                   1205:         opn = "swr";
                   1206:         break;
                   1207:     }
1.1.1.13  root     1208:     (void)opn; /* avoid a compiler warning */
1.1.1.12  root     1209:     MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
                   1210:     tcg_temp_free(t0);
                   1211:     tcg_temp_free(t1);
                   1212: }
                   1213: 
                   1214: 
1.1.1.8   root     1215: /* Store conditional */
                   1216: static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
                   1217:                          int base, int16_t offset)
                   1218: {
                   1219:     const char *opn = "st_cond";
                   1220:     TCGv t0, t1;
                   1221: 
                   1222:     t0 = tcg_temp_local_new();
                   1223: 
1.1.1.12  root     1224:     gen_base_offset_addr(ctx, t0, base, offset);
1.1.1.8   root     1225:     /* Don't do NOP if destination is zero: we must perform the actual
                   1226:        memory access. */
                   1227: 
                   1228:     t1 = tcg_temp_local_new();
                   1229:     gen_load_gpr(t1, rt);
                   1230:     switch (opc) {
                   1231: #if defined(TARGET_MIPS64)
                   1232:     case OPC_SCD:
1.1.1.13  root     1233:         save_cpu_state(ctx, 1);
1.1.1.12  root     1234:         op_st_scd(t1, t0, rt, ctx);
1.1.1.8   root     1235:         opn = "scd";
                   1236:         break;
                   1237: #endif
1.1       root     1238:     case OPC_SC:
1.1.1.9   root     1239:         save_cpu_state(ctx, 1);
1.1.1.12  root     1240:         op_st_sc(t1, t0, rt, ctx);
1.1       root     1241:         opn = "sc";
                   1242:         break;
                   1243:     }
1.1.1.13  root     1244:     (void)opn; /* avoid a compiler warning */
1.1       root     1245:     MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1.1.1.7   root     1246:     tcg_temp_free(t1);
1.1.1.8   root     1247:     tcg_temp_free(t0);
1.1       root     1248: }
                   1249: 
1.1.1.4   root     1250: /* Load and store */
1.1.1.5   root     1251: static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1.1.1.7   root     1252:                           int base, int16_t offset)
1.1.1.4   root     1253: {
1.1.1.6   root     1254:     const char *opn = "flt_ldst";
1.1.1.8   root     1255:     TCGv t0 = tcg_temp_new();
1.1.1.4   root     1256: 
1.1.1.12  root     1257:     gen_base_offset_addr(ctx, t0, base, offset);
1.1.1.4   root     1258:     /* Don't do NOP if destination is zero: we must perform the actual
1.1.1.6   root     1259:        memory access. */
1.1.1.4   root     1260:     switch (opc) {
                   1261:     case OPC_LWC1:
1.1.1.7   root     1262:         {
                   1263:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   1264: 
1.1.1.8   root     1265:             tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
                   1266:             tcg_gen_trunc_tl_i32(fp0, t0);
1.1.1.7   root     1267:             gen_store_fpr32(fp0, ft);
                   1268:             tcg_temp_free_i32(fp0);
                   1269:         }
1.1.1.4   root     1270:         opn = "lwc1";
                   1271:         break;
                   1272:     case OPC_SWC1:
1.1.1.7   root     1273:         {
                   1274:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   1275:             TCGv t1 = tcg_temp_new();
                   1276: 
                   1277:             gen_load_fpr32(fp0, ft);
                   1278:             tcg_gen_extu_i32_tl(t1, fp0);
                   1279:             tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
                   1280:             tcg_temp_free(t1);
                   1281:             tcg_temp_free_i32(fp0);
                   1282:         }
1.1.1.4   root     1283:         opn = "swc1";
                   1284:         break;
                   1285:     case OPC_LDC1:
1.1.1.7   root     1286:         {
                   1287:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   1288: 
                   1289:             tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
                   1290:             gen_store_fpr64(ctx, fp0, ft);
                   1291:             tcg_temp_free_i64(fp0);
                   1292:         }
1.1.1.4   root     1293:         opn = "ldc1";
                   1294:         break;
                   1295:     case OPC_SDC1:
1.1.1.7   root     1296:         {
                   1297:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   1298: 
                   1299:             gen_load_fpr64(ctx, fp0, ft);
                   1300:             tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
                   1301:             tcg_temp_free_i64(fp0);
                   1302:         }
1.1.1.4   root     1303:         opn = "sdc1";
                   1304:         break;
                   1305:     default:
1.1.1.6   root     1306:         MIPS_INVAL(opn);
                   1307:         generate_exception(ctx, EXCP_RI);
1.1.1.7   root     1308:         goto out;
1.1.1.4   root     1309:     }
1.1.1.13  root     1310:     (void)opn; /* avoid a compiler warning */
1.1.1.4   root     1311:     MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1.1.1.7   root     1312:  out:
                   1313:     tcg_temp_free(t0);
1.1.1.4   root     1314: }
1.1.1.5   root     1315: 
1.1.1.16! root     1316: static void gen_cop1_ldst(CPUMIPSState *env, DisasContext *ctx,
1.1.1.12  root     1317:                           uint32_t op, int rt, int rs, int16_t imm)
                   1318: {
                   1319:     if (env->CP0_Config1 & (1 << CP0C1_FP)) {
                   1320:         check_cp1_enabled(ctx);
                   1321:         gen_flt_ldst(ctx, op, rt, rs, imm);
                   1322:     } else {
                   1323:         generate_exception_err(ctx, EXCP_CpU, 1);
                   1324:     }
                   1325: }
                   1326: 
1.1       root     1327: /* Arithmetic with immediate operand */
1.1.1.16! root     1328: static void gen_arith_imm (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1.1.1.6   root     1329:                            int rt, int rs, int16_t imm)
1.1       root     1330: {
1.1.1.8   root     1331:     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1.1.1.6   root     1332:     const char *opn = "imm arith";
1.1       root     1333: 
1.1.1.5   root     1334:     if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1.1.1.6   root     1335:         /* If no destination, treat it as a NOP.
                   1336:            For addi, we must generate the overflow exception when needed. */
1.1       root     1337:         MIPS_DEBUG("NOP");
1.1.1.8   root     1338:         return;
1.1       root     1339:     }
                   1340:     switch (opc) {
                   1341:     case OPC_ADDI:
1.1.1.7   root     1342:         {
1.1.1.8   root     1343:             TCGv t0 = tcg_temp_local_new();
                   1344:             TCGv t1 = tcg_temp_new();
                   1345:             TCGv t2 = tcg_temp_new();
1.1.1.7   root     1346:             int l1 = gen_new_label();
                   1347: 
1.1.1.8   root     1348:             gen_load_gpr(t1, rs);
                   1349:             tcg_gen_addi_tl(t0, t1, uimm);
                   1350:             tcg_gen_ext32s_tl(t0, t0);
1.1.1.7   root     1351: 
1.1.1.8   root     1352:             tcg_gen_xori_tl(t1, t1, ~uimm);
                   1353:             tcg_gen_xori_tl(t2, t0, uimm);
                   1354:             tcg_gen_and_tl(t1, t1, t2);
                   1355:             tcg_temp_free(t2);
                   1356:             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
                   1357:             tcg_temp_free(t1);
1.1.1.7   root     1358:             /* operands of same sign, result different sign */
                   1359:             generate_exception(ctx, EXCP_OVERFLOW);
                   1360:             gen_set_label(l1);
                   1361:             tcg_gen_ext32s_tl(t0, t0);
1.1.1.8   root     1362:             gen_store_gpr(t0, rt);
                   1363:             tcg_temp_free(t0);
1.1.1.7   root     1364:         }
1.1       root     1365:         opn = "addi";
                   1366:         break;
                   1367:     case OPC_ADDIU:
1.1.1.8   root     1368:         if (rs != 0) {
                   1369:             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
                   1370:             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
                   1371:         } else {
                   1372:             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
                   1373:         }
1.1       root     1374:         opn = "addiu";
                   1375:         break;
1.1.1.6   root     1376: #if defined(TARGET_MIPS64)
1.1.1.5   root     1377:     case OPC_DADDI:
1.1.1.7   root     1378:         {
1.1.1.8   root     1379:             TCGv t0 = tcg_temp_local_new();
                   1380:             TCGv t1 = tcg_temp_new();
                   1381:             TCGv t2 = tcg_temp_new();
1.1.1.7   root     1382:             int l1 = gen_new_label();
                   1383: 
1.1.1.8   root     1384:             gen_load_gpr(t1, rs);
                   1385:             tcg_gen_addi_tl(t0, t1, uimm);
1.1.1.7   root     1386: 
1.1.1.8   root     1387:             tcg_gen_xori_tl(t1, t1, ~uimm);
                   1388:             tcg_gen_xori_tl(t2, t0, uimm);
                   1389:             tcg_gen_and_tl(t1, t1, t2);
                   1390:             tcg_temp_free(t2);
                   1391:             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
                   1392:             tcg_temp_free(t1);
1.1.1.7   root     1393:             /* operands of same sign, result different sign */
                   1394:             generate_exception(ctx, EXCP_OVERFLOW);
                   1395:             gen_set_label(l1);
1.1.1.8   root     1396:             gen_store_gpr(t0, rt);
                   1397:             tcg_temp_free(t0);
1.1.1.7   root     1398:         }
1.1.1.5   root     1399:         opn = "daddi";
                   1400:         break;
                   1401:     case OPC_DADDIU:
1.1.1.8   root     1402:         if (rs != 0) {
                   1403:             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
                   1404:         } else {
                   1405:             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
                   1406:         }
1.1.1.5   root     1407:         opn = "daddiu";
                   1408:         break;
                   1409: #endif
1.1.1.8   root     1410:     }
1.1.1.13  root     1411:     (void)opn; /* avoid a compiler warning */
1.1.1.8   root     1412:     MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
                   1413: }
                   1414: 
                   1415: /* Logic with immediate operand */
1.1.1.16! root     1416: static void gen_logic_imm (CPUMIPSState *env, uint32_t opc, int rt, int rs, int16_t imm)
1.1.1.8   root     1417: {
                   1418:     target_ulong uimm;
                   1419:     const char *opn = "imm logic";
                   1420: 
                   1421:     if (rt == 0) {
                   1422:         /* If no destination, treat it as a NOP. */
                   1423:         MIPS_DEBUG("NOP");
                   1424:         return;
                   1425:     }
                   1426:     uimm = (uint16_t)imm;
                   1427:     switch (opc) {
1.1       root     1428:     case OPC_ANDI:
1.1.1.8   root     1429:         if (likely(rs != 0))
                   1430:             tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
                   1431:         else
                   1432:             tcg_gen_movi_tl(cpu_gpr[rt], 0);
1.1       root     1433:         opn = "andi";
                   1434:         break;
                   1435:     case OPC_ORI:
1.1.1.8   root     1436:         if (rs != 0)
                   1437:             tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
                   1438:         else
                   1439:             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1.1       root     1440:         opn = "ori";
                   1441:         break;
                   1442:     case OPC_XORI:
1.1.1.8   root     1443:         if (likely(rs != 0))
                   1444:             tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
                   1445:         else
                   1446:             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1.1       root     1447:         opn = "xori";
                   1448:         break;
                   1449:     case OPC_LUI:
1.1.1.8   root     1450:         tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
1.1       root     1451:         opn = "lui";
                   1452:         break;
1.1.1.8   root     1453:     }
1.1.1.13  root     1454:     (void)opn; /* avoid a compiler warning */
1.1.1.8   root     1455:     MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
                   1456: }
                   1457: 
                   1458: /* Set on less than with immediate operand */
1.1.1.16! root     1459: static void gen_slt_imm (CPUMIPSState *env, uint32_t opc, int rt, int rs, int16_t imm)
1.1.1.8   root     1460: {
                   1461:     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
                   1462:     const char *opn = "imm arith";
                   1463:     TCGv t0;
                   1464: 
                   1465:     if (rt == 0) {
                   1466:         /* If no destination, treat it as a NOP. */
                   1467:         MIPS_DEBUG("NOP");
                   1468:         return;
                   1469:     }
                   1470:     t0 = tcg_temp_new();
                   1471:     gen_load_gpr(t0, rs);
                   1472:     switch (opc) {
                   1473:     case OPC_SLTI:
1.1.1.12  root     1474:         tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
1.1.1.8   root     1475:         opn = "slti";
                   1476:         break;
                   1477:     case OPC_SLTIU:
1.1.1.12  root     1478:         tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
1.1.1.8   root     1479:         opn = "sltiu";
                   1480:         break;
                   1481:     }
1.1.1.13  root     1482:     (void)opn; /* avoid a compiler warning */
1.1.1.8   root     1483:     MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
                   1484:     tcg_temp_free(t0);
                   1485: }
                   1486: 
                   1487: /* Shifts with immediate operand */
1.1.1.16! root     1488: static void gen_shift_imm(CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1.1.1.8   root     1489:                           int rt, int rs, int16_t imm)
                   1490: {
                   1491:     target_ulong uimm = ((uint16_t)imm) & 0x1f;
                   1492:     const char *opn = "imm shift";
                   1493:     TCGv t0;
                   1494: 
                   1495:     if (rt == 0) {
                   1496:         /* If no destination, treat it as a NOP. */
                   1497:         MIPS_DEBUG("NOP");
                   1498:         return;
                   1499:     }
                   1500: 
                   1501:     t0 = tcg_temp_new();
                   1502:     gen_load_gpr(t0, rs);
                   1503:     switch (opc) {
1.1       root     1504:     case OPC_SLL:
1.1.1.7   root     1505:         tcg_gen_shli_tl(t0, t0, uimm);
1.1.1.8   root     1506:         tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1.1       root     1507:         opn = "sll";
                   1508:         break;
                   1509:     case OPC_SRA:
1.1.1.8   root     1510:         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1.1       root     1511:         opn = "sra";
                   1512:         break;
                   1513:     case OPC_SRL:
1.1.1.12  root     1514:         if (uimm != 0) {
                   1515:             tcg_gen_ext32u_tl(t0, t0);
                   1516:             tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
                   1517:         } else {
                   1518:             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
                   1519:         }
                   1520:         opn = "srl";
                   1521:         break;
                   1522:     case OPC_ROTR:
                   1523:         if (uimm != 0) {
                   1524:             TCGv_i32 t1 = tcg_temp_new_i32();
1.1.1.7   root     1525: 
1.1.1.12  root     1526:             tcg_gen_trunc_tl_i32(t1, t0);
                   1527:             tcg_gen_rotri_i32(t1, t1, uimm);
                   1528:             tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
                   1529:             tcg_temp_free_i32(t1);
                   1530:         } else {
                   1531:             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1.1.1.6   root     1532:         }
1.1.1.12  root     1533:         opn = "rotr";
1.1.1.5   root     1534:         break;
1.1.1.6   root     1535: #if defined(TARGET_MIPS64)
1.1.1.5   root     1536:     case OPC_DSLL:
1.1.1.8   root     1537:         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
1.1.1.5   root     1538:         opn = "dsll";
                   1539:         break;
                   1540:     case OPC_DSRA:
1.1.1.8   root     1541:         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1.1.1.5   root     1542:         opn = "dsra";
                   1543:         break;
                   1544:     case OPC_DSRL:
1.1.1.12  root     1545:         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
                   1546:         opn = "dsrl";
                   1547:         break;
                   1548:     case OPC_DROTR:
                   1549:         if (uimm != 0) {
                   1550:             tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
                   1551:         } else {
                   1552:             tcg_gen_mov_tl(cpu_gpr[rt], t0);
1.1.1.6   root     1553:         }
1.1.1.12  root     1554:         opn = "drotr";
1.1.1.5   root     1555:         break;
                   1556:     case OPC_DSLL32:
1.1.1.8   root     1557:         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
1.1.1.5   root     1558:         opn = "dsll32";
                   1559:         break;
                   1560:     case OPC_DSRA32:
1.1.1.8   root     1561:         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
1.1.1.5   root     1562:         opn = "dsra32";
                   1563:         break;
                   1564:     case OPC_DSRL32:
1.1.1.12  root     1565:         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
                   1566:         opn = "dsrl32";
                   1567:         break;
                   1568:     case OPC_DROTR32:
                   1569:         tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
                   1570:         opn = "drotr32";
1.1       root     1571:         break;
1.1.1.5   root     1572: #endif
1.1       root     1573:     }
1.1.1.13  root     1574:     (void)opn; /* avoid a compiler warning */
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.16! root     1580: static void gen_arith (CPUMIPSState *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:     }
1.1.1.13  root     1755:     (void)opn; /* avoid a compiler warning */
1.1.1.8   root     1756:     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
                   1757: }
                   1758: 
                   1759: /* Conditional move */
1.1.1.16! root     1760: static void gen_cond_move (CPUMIPSState *env, uint32_t opc, int rd, int rs, int rt)
1.1.1.8   root     1761: {
                   1762:     const char *opn = "cond move";
                   1763:     int l1;
                   1764: 
                   1765:     if (rd == 0) {
                   1766:         /* If no destination, treat it as a NOP.
                   1767:            For add & sub, we must generate the overflow exception when needed. */
                   1768:         MIPS_DEBUG("NOP");
                   1769:         return;
                   1770:     }
                   1771: 
                   1772:     l1 = gen_new_label();
                   1773:     switch (opc) {
                   1774:     case OPC_MOVN:
                   1775:         if (likely(rt != 0))
                   1776:             tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
                   1777:         else
                   1778:             tcg_gen_br(l1);
                   1779:         opn = "movn";
1.1       root     1780:         break;
1.1.1.8   root     1781:     case OPC_MOVZ:
                   1782:         if (likely(rt != 0))
                   1783:             tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
                   1784:         opn = "movz";
                   1785:         break;
                   1786:     }
                   1787:     if (rs != 0)
                   1788:         tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   1789:     else
                   1790:         tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   1791:     gen_set_label(l1);
                   1792: 
1.1.1.13  root     1793:     (void)opn; /* avoid a compiler warning */
1.1.1.8   root     1794:     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
                   1795: }
                   1796: 
                   1797: /* Logic */
1.1.1.16! root     1798: static void gen_logic (CPUMIPSState *env, uint32_t opc, int rd, int rs, int rt)
1.1.1.8   root     1799: {
                   1800:     const char *opn = "logic";
                   1801: 
                   1802:     if (rd == 0) {
                   1803:         /* If no destination, treat it as a NOP. */
                   1804:         MIPS_DEBUG("NOP");
                   1805:         return;
                   1806:     }
                   1807: 
                   1808:     switch (opc) {
1.1       root     1809:     case OPC_AND:
1.1.1.8   root     1810:         if (likely(rs != 0 && rt != 0)) {
                   1811:             tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
                   1812:         } else {
                   1813:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   1814:         }
1.1       root     1815:         opn = "and";
                   1816:         break;
                   1817:     case OPC_NOR:
1.1.1.8   root     1818:         if (rs != 0 && rt != 0) {
                   1819:             tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
                   1820:         } else if (rs == 0 && rt != 0) {
                   1821:             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
                   1822:         } else if (rs != 0 && rt == 0) {
                   1823:             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   1824:         } else {
                   1825:             tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
                   1826:         }
1.1       root     1827:         opn = "nor";
                   1828:         break;
                   1829:     case OPC_OR:
1.1.1.8   root     1830:         if (likely(rs != 0 && rt != 0)) {
                   1831:             tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
                   1832:         } else if (rs == 0 && rt != 0) {
                   1833:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
                   1834:         } else if (rs != 0 && rt == 0) {
                   1835:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   1836:         } else {
                   1837:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   1838:         }
1.1       root     1839:         opn = "or";
                   1840:         break;
                   1841:     case OPC_XOR:
1.1.1.8   root     1842:         if (likely(rs != 0 && rt != 0)) {
                   1843:             tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
                   1844:         } else if (rs == 0 && rt != 0) {
                   1845:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
                   1846:         } else if (rs != 0 && rt == 0) {
                   1847:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   1848:         } else {
                   1849:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   1850:         }
1.1       root     1851:         opn = "xor";
                   1852:         break;
1.1.1.8   root     1853:     }
1.1.1.13  root     1854:     (void)opn; /* avoid a compiler warning */
1.1.1.8   root     1855:     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
                   1856: }
                   1857: 
                   1858: /* Set on lower than */
1.1.1.16! root     1859: static void gen_slt (CPUMIPSState *env, uint32_t opc, int rd, int rs, int rt)
1.1.1.8   root     1860: {
                   1861:     const char *opn = "slt";
                   1862:     TCGv t0, t1;
                   1863: 
                   1864:     if (rd == 0) {
                   1865:         /* If no destination, treat it as a NOP. */
                   1866:         MIPS_DEBUG("NOP");
                   1867:         return;
                   1868:     }
                   1869: 
                   1870:     t0 = tcg_temp_new();
                   1871:     t1 = tcg_temp_new();
                   1872:     gen_load_gpr(t0, rs);
                   1873:     gen_load_gpr(t1, rt);
                   1874:     switch (opc) {
                   1875:     case OPC_SLT:
1.1.1.12  root     1876:         tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
1.1.1.8   root     1877:         opn = "slt";
1.1       root     1878:         break;
1.1.1.8   root     1879:     case OPC_SLTU:
1.1.1.12  root     1880:         tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
1.1.1.8   root     1881:         opn = "sltu";
                   1882:         break;
                   1883:     }
1.1.1.13  root     1884:     (void)opn; /* avoid a compiler warning */
1.1.1.8   root     1885:     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
                   1886:     tcg_temp_free(t0);
                   1887:     tcg_temp_free(t1);
                   1888: }
1.1.1.7   root     1889: 
1.1.1.8   root     1890: /* Shifts */
1.1.1.16! root     1891: static void gen_shift (CPUMIPSState *env, DisasContext *ctx, uint32_t opc,
1.1.1.8   root     1892:                        int rd, int rs, int rt)
                   1893: {
                   1894:     const char *opn = "shifts";
                   1895:     TCGv t0, t1;
1.1.1.7   root     1896: 
1.1.1.8   root     1897:     if (rd == 0) {
                   1898:         /* If no destination, treat it as a NOP.
                   1899:            For add & sub, we must generate the overflow exception when needed. */
                   1900:         MIPS_DEBUG("NOP");
                   1901:         return;
                   1902:     }
                   1903: 
                   1904:     t0 = tcg_temp_new();
                   1905:     t1 = tcg_temp_new();
                   1906:     gen_load_gpr(t0, rs);
                   1907:     gen_load_gpr(t1, rt);
                   1908:     switch (opc) {
1.1       root     1909:     case OPC_SLLV:
1.1.1.7   root     1910:         tcg_gen_andi_tl(t0, t0, 0x1f);
                   1911:         tcg_gen_shl_tl(t0, t1, t0);
1.1.1.8   root     1912:         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1.1       root     1913:         opn = "sllv";
                   1914:         break;
                   1915:     case OPC_SRAV:
1.1.1.7   root     1916:         tcg_gen_andi_tl(t0, t0, 0x1f);
1.1.1.8   root     1917:         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1.1       root     1918:         opn = "srav";
                   1919:         break;
                   1920:     case OPC_SRLV:
1.1.1.12  root     1921:         tcg_gen_ext32u_tl(t1, t1);
                   1922:         tcg_gen_andi_tl(t0, t0, 0x1f);
                   1923:         tcg_gen_shr_tl(t0, t1, t0);
                   1924:         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
                   1925:         opn = "srlv";
                   1926:         break;
                   1927:     case OPC_ROTRV:
                   1928:         {
                   1929:             TCGv_i32 t2 = tcg_temp_new_i32();
                   1930:             TCGv_i32 t3 = tcg_temp_new_i32();
                   1931: 
                   1932:             tcg_gen_trunc_tl_i32(t2, t0);
                   1933:             tcg_gen_trunc_tl_i32(t3, t1);
                   1934:             tcg_gen_andi_i32(t2, t2, 0x1f);
                   1935:             tcg_gen_rotr_i32(t2, t3, t2);
                   1936:             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
                   1937:             tcg_temp_free_i32(t2);
                   1938:             tcg_temp_free_i32(t3);
                   1939:             opn = "rotrv";
1.1.1.6   root     1940:         }
1.1.1.5   root     1941:         break;
1.1.1.6   root     1942: #if defined(TARGET_MIPS64)
1.1.1.5   root     1943:     case OPC_DSLLV:
1.1.1.7   root     1944:         tcg_gen_andi_tl(t0, t0, 0x3f);
1.1.1.8   root     1945:         tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
1.1.1.5   root     1946:         opn = "dsllv";
                   1947:         break;
                   1948:     case OPC_DSRAV:
1.1.1.7   root     1949:         tcg_gen_andi_tl(t0, t0, 0x3f);
1.1.1.8   root     1950:         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1.1.1.5   root     1951:         opn = "dsrav";
                   1952:         break;
                   1953:     case OPC_DSRLV:
1.1.1.12  root     1954:         tcg_gen_andi_tl(t0, t0, 0x3f);
                   1955:         tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
                   1956:         opn = "dsrlv";
                   1957:         break;
                   1958:     case OPC_DROTRV:
                   1959:         tcg_gen_andi_tl(t0, t0, 0x3f);
                   1960:         tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
                   1961:         opn = "drotrv";
1.1       root     1962:         break;
1.1.1.5   root     1963: #endif
1.1       root     1964:     }
1.1.1.13  root     1965:     (void)opn; /* avoid a compiler warning */
1.1       root     1966:     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1.1.1.7   root     1967:     tcg_temp_free(t0);
                   1968:     tcg_temp_free(t1);
1.1       root     1969: }
                   1970: 
                   1971: /* Arithmetic on HI/LO registers */
1.1.1.5   root     1972: static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1.1       root     1973: {
1.1.1.6   root     1974:     const char *opn = "hilo";
1.1       root     1975: 
                   1976:     if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1.1.1.6   root     1977:         /* Treat as NOP. */
1.1       root     1978:         MIPS_DEBUG("NOP");
1.1.1.8   root     1979:         return;
1.1       root     1980:     }
                   1981:     switch (opc) {
                   1982:     case OPC_MFHI:
1.1.1.8   root     1983:         tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1.1       root     1984:         opn = "mfhi";
                   1985:         break;
                   1986:     case OPC_MFLO:
1.1.1.8   root     1987:         tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1.1       root     1988:         opn = "mflo";
                   1989:         break;
                   1990:     case OPC_MTHI:
1.1.1.8   root     1991:         if (reg != 0)
                   1992:             tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
                   1993:         else
                   1994:             tcg_gen_movi_tl(cpu_HI[0], 0);
1.1       root     1995:         opn = "mthi";
                   1996:         break;
                   1997:     case OPC_MTLO:
1.1.1.8   root     1998:         if (reg != 0)
                   1999:             tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
                   2000:         else
                   2001:             tcg_gen_movi_tl(cpu_LO[0], 0);
1.1       root     2002:         opn = "mtlo";
                   2003:         break;
                   2004:     }
1.1.1.13  root     2005:     (void)opn; /* avoid a compiler warning */
1.1       root     2006:     MIPS_DEBUG("%s %s", opn, regnames[reg]);
                   2007: }
                   2008: 
1.1.1.5   root     2009: static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1.1       root     2010:                         int rs, int rt)
                   2011: {
1.1.1.6   root     2012:     const char *opn = "mul/div";
1.1.1.8   root     2013:     TCGv t0, t1;
                   2014: 
                   2015:     switch (opc) {
                   2016:     case OPC_DIV:
                   2017:     case OPC_DIVU:
                   2018: #if defined(TARGET_MIPS64)
                   2019:     case OPC_DDIV:
                   2020:     case OPC_DDIVU:
                   2021: #endif
                   2022:         t0 = tcg_temp_local_new();
                   2023:         t1 = tcg_temp_local_new();
                   2024:         break;
                   2025:     default:
                   2026:         t0 = tcg_temp_new();
                   2027:         t1 = tcg_temp_new();
                   2028:         break;
                   2029:     }
1.1       root     2030: 
1.1.1.7   root     2031:     gen_load_gpr(t0, rs);
                   2032:     gen_load_gpr(t1, rt);
1.1       root     2033:     switch (opc) {
                   2034:     case OPC_DIV:
1.1.1.7   root     2035:         {
                   2036:             int l1 = gen_new_label();
1.1.1.8   root     2037:             int l2 = gen_new_label();
1.1.1.7   root     2038: 
1.1.1.8   root     2039:             tcg_gen_ext32s_tl(t0, t0);
                   2040:             tcg_gen_ext32s_tl(t1, t1);
1.1.1.7   root     2041:             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1.1.1.8   root     2042:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
                   2043:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
                   2044: 
                   2045:             tcg_gen_mov_tl(cpu_LO[0], t0);
                   2046:             tcg_gen_movi_tl(cpu_HI[0], 0);
                   2047:             tcg_gen_br(l1);
                   2048:             gen_set_label(l2);
                   2049:             tcg_gen_div_tl(cpu_LO[0], t0, t1);
                   2050:             tcg_gen_rem_tl(cpu_HI[0], t0, t1);
                   2051:             tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
                   2052:             tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
1.1.1.7   root     2053:             gen_set_label(l1);
                   2054:         }
1.1       root     2055:         opn = "div";
                   2056:         break;
                   2057:     case OPC_DIVU:
1.1.1.7   root     2058:         {
                   2059:             int l1 = gen_new_label();
                   2060: 
1.1.1.8   root     2061:             tcg_gen_ext32u_tl(t0, t0);
                   2062:             tcg_gen_ext32u_tl(t1, t1);
1.1.1.7   root     2063:             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1.1.1.8   root     2064:             tcg_gen_divu_tl(cpu_LO[0], t0, t1);
                   2065:             tcg_gen_remu_tl(cpu_HI[0], t0, t1);
                   2066:             tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
                   2067:             tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
1.1.1.7   root     2068:             gen_set_label(l1);
                   2069:         }
1.1       root     2070:         opn = "divu";
                   2071:         break;
                   2072:     case OPC_MULT:
1.1.1.7   root     2073:         {
1.1.1.8   root     2074:             TCGv_i64 t2 = tcg_temp_new_i64();
                   2075:             TCGv_i64 t3 = tcg_temp_new_i64();
1.1.1.7   root     2076: 
1.1.1.8   root     2077:             tcg_gen_ext_tl_i64(t2, t0);
                   2078:             tcg_gen_ext_tl_i64(t3, t1);
                   2079:             tcg_gen_mul_i64(t2, t2, t3);
                   2080:             tcg_temp_free_i64(t3);
                   2081:             tcg_gen_trunc_i64_tl(t0, t2);
                   2082:             tcg_gen_shri_i64(t2, t2, 32);
                   2083:             tcg_gen_trunc_i64_tl(t1, t2);
                   2084:             tcg_temp_free_i64(t2);
1.1.1.7   root     2085:             tcg_gen_ext32s_tl(cpu_LO[0], t0);
                   2086:             tcg_gen_ext32s_tl(cpu_HI[0], t1);
                   2087:         }
1.1       root     2088:         opn = "mult";
                   2089:         break;
                   2090:     case OPC_MULTU:
1.1.1.7   root     2091:         {
1.1.1.8   root     2092:             TCGv_i64 t2 = tcg_temp_new_i64();
                   2093:             TCGv_i64 t3 = tcg_temp_new_i64();
1.1.1.7   root     2094: 
                   2095:             tcg_gen_ext32u_tl(t0, t0);
                   2096:             tcg_gen_ext32u_tl(t1, t1);
1.1.1.8   root     2097:             tcg_gen_extu_tl_i64(t2, t0);
                   2098:             tcg_gen_extu_tl_i64(t3, t1);
                   2099:             tcg_gen_mul_i64(t2, t2, t3);
                   2100:             tcg_temp_free_i64(t3);
                   2101:             tcg_gen_trunc_i64_tl(t0, t2);
                   2102:             tcg_gen_shri_i64(t2, t2, 32);
                   2103:             tcg_gen_trunc_i64_tl(t1, t2);
                   2104:             tcg_temp_free_i64(t2);
1.1.1.7   root     2105:             tcg_gen_ext32s_tl(cpu_LO[0], t0);
                   2106:             tcg_gen_ext32s_tl(cpu_HI[0], t1);
                   2107:         }
1.1       root     2108:         opn = "multu";
                   2109:         break;
1.1.1.6   root     2110: #if defined(TARGET_MIPS64)
1.1.1.5   root     2111:     case OPC_DDIV:
1.1.1.7   root     2112:         {
                   2113:             int l1 = gen_new_label();
1.1.1.8   root     2114:             int l2 = gen_new_label();
1.1.1.7   root     2115: 
                   2116:             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1.1.1.8   root     2117:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
                   2118:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
                   2119:             tcg_gen_mov_tl(cpu_LO[0], t0);
                   2120:             tcg_gen_movi_tl(cpu_HI[0], 0);
                   2121:             tcg_gen_br(l1);
                   2122:             gen_set_label(l2);
                   2123:             tcg_gen_div_i64(cpu_LO[0], t0, t1);
                   2124:             tcg_gen_rem_i64(cpu_HI[0], t0, t1);
1.1.1.7   root     2125:             gen_set_label(l1);
                   2126:         }
1.1.1.5   root     2127:         opn = "ddiv";
                   2128:         break;
                   2129:     case OPC_DDIVU:
1.1.1.7   root     2130:         {
                   2131:             int l1 = gen_new_label();
                   2132: 
                   2133:             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
                   2134:             tcg_gen_divu_i64(cpu_LO[0], t0, t1);
                   2135:             tcg_gen_remu_i64(cpu_HI[0], t0, t1);
                   2136:             gen_set_label(l1);
                   2137:         }
1.1.1.5   root     2138:         opn = "ddivu";
                   2139:         break;
                   2140:     case OPC_DMULT:
1.1.1.7   root     2141:         gen_helper_dmult(t0, t1);
1.1.1.5   root     2142:         opn = "dmult";
                   2143:         break;
                   2144:     case OPC_DMULTU:
1.1.1.7   root     2145:         gen_helper_dmultu(t0, t1);
1.1.1.5   root     2146:         opn = "dmultu";
                   2147:         break;
                   2148: #endif
1.1       root     2149:     case OPC_MADD:
1.1.1.7   root     2150:         {
1.1.1.8   root     2151:             TCGv_i64 t2 = tcg_temp_new_i64();
                   2152:             TCGv_i64 t3 = tcg_temp_new_i64();
1.1.1.7   root     2153: 
1.1.1.8   root     2154:             tcg_gen_ext_tl_i64(t2, t0);
                   2155:             tcg_gen_ext_tl_i64(t3, t1);
                   2156:             tcg_gen_mul_i64(t2, t2, t3);
                   2157:             tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
                   2158:             tcg_gen_add_i64(t2, t2, t3);
                   2159:             tcg_temp_free_i64(t3);
                   2160:             tcg_gen_trunc_i64_tl(t0, t2);
                   2161:             tcg_gen_shri_i64(t2, t2, 32);
                   2162:             tcg_gen_trunc_i64_tl(t1, t2);
                   2163:             tcg_temp_free_i64(t2);
1.1.1.7   root     2164:             tcg_gen_ext32s_tl(cpu_LO[0], t0);
1.1.1.8   root     2165:             tcg_gen_ext32s_tl(cpu_HI[0], t1);
1.1.1.7   root     2166:         }
1.1       root     2167:         opn = "madd";
                   2168:         break;
                   2169:     case OPC_MADDU:
1.1.1.7   root     2170:        {
1.1.1.8   root     2171:             TCGv_i64 t2 = tcg_temp_new_i64();
                   2172:             TCGv_i64 t3 = tcg_temp_new_i64();
1.1.1.7   root     2173: 
                   2174:             tcg_gen_ext32u_tl(t0, t0);
                   2175:             tcg_gen_ext32u_tl(t1, t1);
1.1.1.8   root     2176:             tcg_gen_extu_tl_i64(t2, t0);
                   2177:             tcg_gen_extu_tl_i64(t3, t1);
                   2178:             tcg_gen_mul_i64(t2, t2, t3);
                   2179:             tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
                   2180:             tcg_gen_add_i64(t2, t2, t3);
                   2181:             tcg_temp_free_i64(t3);
                   2182:             tcg_gen_trunc_i64_tl(t0, t2);
                   2183:             tcg_gen_shri_i64(t2, t2, 32);
                   2184:             tcg_gen_trunc_i64_tl(t1, t2);
                   2185:             tcg_temp_free_i64(t2);
1.1.1.7   root     2186:             tcg_gen_ext32s_tl(cpu_LO[0], t0);
                   2187:             tcg_gen_ext32s_tl(cpu_HI[0], t1);
                   2188:         }
1.1       root     2189:         opn = "maddu";
                   2190:         break;
                   2191:     case OPC_MSUB:
1.1.1.7   root     2192:         {
1.1.1.8   root     2193:             TCGv_i64 t2 = tcg_temp_new_i64();
                   2194:             TCGv_i64 t3 = tcg_temp_new_i64();
1.1.1.7   root     2195: 
1.1.1.8   root     2196:             tcg_gen_ext_tl_i64(t2, t0);
                   2197:             tcg_gen_ext_tl_i64(t3, t1);
                   2198:             tcg_gen_mul_i64(t2, t2, t3);
                   2199:             tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
                   2200:             tcg_gen_sub_i64(t2, t3, t2);
                   2201:             tcg_temp_free_i64(t3);
                   2202:             tcg_gen_trunc_i64_tl(t0, t2);
                   2203:             tcg_gen_shri_i64(t2, t2, 32);
                   2204:             tcg_gen_trunc_i64_tl(t1, t2);
                   2205:             tcg_temp_free_i64(t2);
1.1.1.7   root     2206:             tcg_gen_ext32s_tl(cpu_LO[0], t0);
                   2207:             tcg_gen_ext32s_tl(cpu_HI[0], t1);
                   2208:         }
1.1       root     2209:         opn = "msub";
                   2210:         break;
                   2211:     case OPC_MSUBU:
1.1.1.7   root     2212:         {
1.1.1.8   root     2213:             TCGv_i64 t2 = tcg_temp_new_i64();
                   2214:             TCGv_i64 t3 = tcg_temp_new_i64();
1.1.1.7   root     2215: 
                   2216:             tcg_gen_ext32u_tl(t0, t0);
                   2217:             tcg_gen_ext32u_tl(t1, t1);
1.1.1.8   root     2218:             tcg_gen_extu_tl_i64(t2, t0);
                   2219:             tcg_gen_extu_tl_i64(t3, t1);
                   2220:             tcg_gen_mul_i64(t2, t2, t3);
                   2221:             tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
                   2222:             tcg_gen_sub_i64(t2, t3, t2);
                   2223:             tcg_temp_free_i64(t3);
                   2224:             tcg_gen_trunc_i64_tl(t0, t2);
                   2225:             tcg_gen_shri_i64(t2, t2, 32);
                   2226:             tcg_gen_trunc_i64_tl(t1, t2);
                   2227:             tcg_temp_free_i64(t2);
1.1.1.7   root     2228:             tcg_gen_ext32s_tl(cpu_LO[0], t0);
                   2229:             tcg_gen_ext32s_tl(cpu_HI[0], t1);
                   2230:         }
1.1       root     2231:         opn = "msubu";
                   2232:         break;
                   2233:     default:
1.1.1.6   root     2234:         MIPS_INVAL(opn);
1.1       root     2235:         generate_exception(ctx, EXCP_RI);
1.1.1.7   root     2236:         goto out;
1.1       root     2237:     }
1.1.1.13  root     2238:     (void)opn; /* avoid a compiler warning */
1.1       root     2239:     MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
1.1.1.7   root     2240:  out:
                   2241:     tcg_temp_free(t0);
                   2242:     tcg_temp_free(t1);
1.1       root     2243: }
                   2244: 
1.1.1.6   root     2245: static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
                   2246:                             int rd, int rs, int rt)
                   2247: {
                   2248:     const char *opn = "mul vr54xx";
1.1.1.8   root     2249:     TCGv t0 = tcg_temp_new();
                   2250:     TCGv t1 = tcg_temp_new();
1.1.1.6   root     2251: 
1.1.1.7   root     2252:     gen_load_gpr(t0, rs);
                   2253:     gen_load_gpr(t1, rt);
1.1.1.6   root     2254: 
                   2255:     switch (opc) {
                   2256:     case OPC_VR54XX_MULS:
1.1.1.7   root     2257:         gen_helper_muls(t0, t0, t1);
1.1.1.6   root     2258:         opn = "muls";
1.1.1.7   root     2259:         break;
1.1.1.6   root     2260:     case OPC_VR54XX_MULSU:
1.1.1.7   root     2261:         gen_helper_mulsu(t0, t0, t1);
1.1.1.6   root     2262:         opn = "mulsu";
1.1.1.7   root     2263:         break;
1.1.1.6   root     2264:     case OPC_VR54XX_MACC:
1.1.1.7   root     2265:         gen_helper_macc(t0, t0, t1);
1.1.1.6   root     2266:         opn = "macc";
1.1.1.7   root     2267:         break;
1.1.1.6   root     2268:     case OPC_VR54XX_MACCU:
1.1.1.7   root     2269:         gen_helper_maccu(t0, t0, t1);
1.1.1.6   root     2270:         opn = "maccu";
1.1.1.7   root     2271:         break;
1.1.1.6   root     2272:     case OPC_VR54XX_MSAC:
1.1.1.7   root     2273:         gen_helper_msac(t0, t0, t1);
1.1.1.6   root     2274:         opn = "msac";
1.1.1.7   root     2275:         break;
1.1.1.6   root     2276:     case OPC_VR54XX_MSACU:
1.1.1.7   root     2277:         gen_helper_msacu(t0, t0, t1);
1.1.1.6   root     2278:         opn = "msacu";
1.1.1.7   root     2279:         break;
1.1.1.6   root     2280:     case OPC_VR54XX_MULHI:
1.1.1.7   root     2281:         gen_helper_mulhi(t0, t0, t1);
1.1.1.6   root     2282:         opn = "mulhi";
1.1.1.7   root     2283:         break;
1.1.1.6   root     2284:     case OPC_VR54XX_MULHIU:
1.1.1.7   root     2285:         gen_helper_mulhiu(t0, t0, t1);
1.1.1.6   root     2286:         opn = "mulhiu";
1.1.1.7   root     2287:         break;
1.1.1.6   root     2288:     case OPC_VR54XX_MULSHI:
1.1.1.7   root     2289:         gen_helper_mulshi(t0, t0, t1);
1.1.1.6   root     2290:         opn = "mulshi";
1.1.1.7   root     2291:         break;
1.1.1.6   root     2292:     case OPC_VR54XX_MULSHIU:
1.1.1.7   root     2293:         gen_helper_mulshiu(t0, t0, t1);
1.1.1.6   root     2294:         opn = "mulshiu";
1.1.1.7   root     2295:         break;
1.1.1.6   root     2296:     case OPC_VR54XX_MACCHI:
1.1.1.7   root     2297:         gen_helper_macchi(t0, t0, t1);
1.1.1.6   root     2298:         opn = "macchi";
1.1.1.7   root     2299:         break;
1.1.1.6   root     2300:     case OPC_VR54XX_MACCHIU:
1.1.1.7   root     2301:         gen_helper_macchiu(t0, t0, t1);
1.1.1.6   root     2302:         opn = "macchiu";
1.1.1.7   root     2303:         break;
1.1.1.6   root     2304:     case OPC_VR54XX_MSACHI:
1.1.1.7   root     2305:         gen_helper_msachi(t0, t0, t1);
1.1.1.6   root     2306:         opn = "msachi";
1.1.1.7   root     2307:         break;
1.1.1.6   root     2308:     case OPC_VR54XX_MSACHIU:
1.1.1.7   root     2309:         gen_helper_msachiu(t0, t0, t1);
1.1.1.6   root     2310:         opn = "msachiu";
1.1.1.7   root     2311:         break;
1.1.1.6   root     2312:     default:
                   2313:         MIPS_INVAL("mul vr54xx");
                   2314:         generate_exception(ctx, EXCP_RI);
1.1.1.7   root     2315:         goto out;
1.1.1.6   root     2316:     }
1.1.1.7   root     2317:     gen_store_gpr(t0, rd);
1.1.1.13  root     2318:     (void)opn; /* avoid a compiler warning */
1.1.1.6   root     2319:     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1.1.1.7   root     2320: 
                   2321:  out:
                   2322:     tcg_temp_free(t0);
                   2323:     tcg_temp_free(t1);
1.1.1.6   root     2324: }
                   2325: 
1.1.1.5   root     2326: static void gen_cl (DisasContext *ctx, uint32_t opc,
1.1       root     2327:                     int rd, int rs)
                   2328: {
1.1.1.6   root     2329:     const char *opn = "CLx";
1.1.1.8   root     2330:     TCGv t0;
1.1.1.7   root     2331: 
1.1       root     2332:     if (rd == 0) {
1.1.1.6   root     2333:         /* Treat as NOP. */
1.1       root     2334:         MIPS_DEBUG("NOP");
1.1.1.8   root     2335:         return;
1.1       root     2336:     }
1.1.1.8   root     2337:     t0 = tcg_temp_new();
1.1.1.7   root     2338:     gen_load_gpr(t0, rs);
1.1       root     2339:     switch (opc) {
                   2340:     case OPC_CLO:
1.1.1.8   root     2341:         gen_helper_clo(cpu_gpr[rd], t0);
1.1       root     2342:         opn = "clo";
                   2343:         break;
                   2344:     case OPC_CLZ:
1.1.1.8   root     2345:         gen_helper_clz(cpu_gpr[rd], t0);
1.1       root     2346:         opn = "clz";
                   2347:         break;
1.1.1.6   root     2348: #if defined(TARGET_MIPS64)
1.1.1.5   root     2349:     case OPC_DCLO:
1.1.1.8   root     2350:         gen_helper_dclo(cpu_gpr[rd], t0);
1.1.1.5   root     2351:         opn = "dclo";
                   2352:         break;
                   2353:     case OPC_DCLZ:
1.1.1.8   root     2354:         gen_helper_dclz(cpu_gpr[rd], t0);
1.1.1.5   root     2355:         opn = "dclz";
                   2356:         break;
                   2357: #endif
1.1       root     2358:     }
1.1.1.13  root     2359:     (void)opn; /* avoid a compiler warning */
1.1       root     2360:     MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
1.1.1.7   root     2361:     tcg_temp_free(t0);
1.1       root     2362: }
                   2363: 
1.1.1.12  root     2364: /* Godson integer instructions */
                   2365: static void gen_loongson_integer (DisasContext *ctx, uint32_t opc,
                   2366:                                 int rd, int rs, int rt)
                   2367: {
                   2368:     const char *opn = "loongson";
                   2369:     TCGv t0, t1;
                   2370: 
                   2371:     if (rd == 0) {
                   2372:         /* Treat as NOP. */
                   2373:         MIPS_DEBUG("NOP");
                   2374:         return;
                   2375:     }
                   2376: 
                   2377:     switch (opc) {
                   2378:     case OPC_MULT_G_2E:
                   2379:     case OPC_MULT_G_2F:
                   2380:     case OPC_MULTU_G_2E:
                   2381:     case OPC_MULTU_G_2F:
                   2382: #if defined(TARGET_MIPS64)
                   2383:     case OPC_DMULT_G_2E:
                   2384:     case OPC_DMULT_G_2F:
                   2385:     case OPC_DMULTU_G_2E:
                   2386:     case OPC_DMULTU_G_2F:
                   2387: #endif
                   2388:         t0 = tcg_temp_new();
                   2389:         t1 = tcg_temp_new();
                   2390:         break;
                   2391:     default:
                   2392:         t0 = tcg_temp_local_new();
                   2393:         t1 = tcg_temp_local_new();
                   2394:         break;
                   2395:     }
                   2396: 
                   2397:     gen_load_gpr(t0, rs);
                   2398:     gen_load_gpr(t1, rt);
                   2399: 
                   2400:     switch (opc) {
                   2401:     case OPC_MULT_G_2E:
                   2402:     case OPC_MULT_G_2F:
                   2403:         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
                   2404:         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
                   2405:         opn = "mult.g";
                   2406:         break;
                   2407:     case OPC_MULTU_G_2E:
                   2408:     case OPC_MULTU_G_2F:
                   2409:         tcg_gen_ext32u_tl(t0, t0);
                   2410:         tcg_gen_ext32u_tl(t1, t1);
                   2411:         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
                   2412:         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
                   2413:         opn = "multu.g";
                   2414:         break;
                   2415:     case OPC_DIV_G_2E:
                   2416:     case OPC_DIV_G_2F:
                   2417:         {
                   2418:             int l1 = gen_new_label();
                   2419:             int l2 = gen_new_label();
                   2420:             int l3 = gen_new_label();
                   2421:             tcg_gen_ext32s_tl(t0, t0);
                   2422:             tcg_gen_ext32s_tl(t1, t1);
                   2423:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
                   2424:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   2425:             tcg_gen_br(l3);
                   2426:             gen_set_label(l1);
                   2427:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
                   2428:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
                   2429:             tcg_gen_mov_tl(cpu_gpr[rd], t0);
                   2430:             tcg_gen_br(l3);
                   2431:             gen_set_label(l2);
                   2432:             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
                   2433:             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
                   2434:             gen_set_label(l3);
                   2435:         }
                   2436:         opn = "div.g";
                   2437:         break;
                   2438:     case OPC_DIVU_G_2E:
                   2439:     case OPC_DIVU_G_2F:
                   2440:         {
                   2441:             int l1 = gen_new_label();
                   2442:             int l2 = gen_new_label();
                   2443:             tcg_gen_ext32u_tl(t0, t0);
                   2444:             tcg_gen_ext32u_tl(t1, t1);
                   2445:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
                   2446:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   2447:             tcg_gen_br(l2);
                   2448:             gen_set_label(l1);
                   2449:             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
                   2450:             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
                   2451:             gen_set_label(l2);
                   2452:         }
                   2453:         opn = "divu.g";
                   2454:         break;
                   2455:     case OPC_MOD_G_2E:
                   2456:     case OPC_MOD_G_2F:
                   2457:         {
                   2458:             int l1 = gen_new_label();
                   2459:             int l2 = gen_new_label();
                   2460:             int l3 = gen_new_label();
                   2461:             tcg_gen_ext32u_tl(t0, t0);
                   2462:             tcg_gen_ext32u_tl(t1, t1);
                   2463:             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
                   2464:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
                   2465:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
                   2466:             gen_set_label(l1);
                   2467:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   2468:             tcg_gen_br(l3);
                   2469:             gen_set_label(l2);
                   2470:             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
                   2471:             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
                   2472:             gen_set_label(l3);
                   2473:         }
                   2474:         opn = "mod.g";
                   2475:         break;
                   2476:     case OPC_MODU_G_2E:
                   2477:     case OPC_MODU_G_2F:
                   2478:         {
                   2479:             int l1 = gen_new_label();
                   2480:             int l2 = gen_new_label();
                   2481:             tcg_gen_ext32u_tl(t0, t0);
                   2482:             tcg_gen_ext32u_tl(t1, t1);
                   2483:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
                   2484:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   2485:             tcg_gen_br(l2);
                   2486:             gen_set_label(l1);
                   2487:             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
                   2488:             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
                   2489:             gen_set_label(l2);
                   2490:         }
                   2491:         opn = "modu.g";
                   2492:         break;
                   2493: #if defined(TARGET_MIPS64)
                   2494:     case OPC_DMULT_G_2E:
                   2495:     case OPC_DMULT_G_2F:
                   2496:         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
                   2497:         opn = "dmult.g";
                   2498:         break;
                   2499:     case OPC_DMULTU_G_2E:
                   2500:     case OPC_DMULTU_G_2F:
                   2501:         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
                   2502:         opn = "dmultu.g";
                   2503:         break;
                   2504:     case OPC_DDIV_G_2E:
                   2505:     case OPC_DDIV_G_2F:
                   2506:         {
                   2507:             int l1 = gen_new_label();
                   2508:             int l2 = gen_new_label();
                   2509:             int l3 = gen_new_label();
                   2510:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
                   2511:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   2512:             tcg_gen_br(l3);
                   2513:             gen_set_label(l1);
                   2514:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
                   2515:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
                   2516:             tcg_gen_mov_tl(cpu_gpr[rd], t0);
                   2517:             tcg_gen_br(l3);
                   2518:             gen_set_label(l2);
                   2519:             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
                   2520:             gen_set_label(l3);
                   2521:         }
                   2522:         opn = "ddiv.g";
                   2523:         break;
                   2524:     case OPC_DDIVU_G_2E:
                   2525:     case OPC_DDIVU_G_2F:
                   2526:         {
                   2527:             int l1 = gen_new_label();
                   2528:             int l2 = gen_new_label();
                   2529:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
                   2530:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   2531:             tcg_gen_br(l2);
                   2532:             gen_set_label(l1);
                   2533:             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
                   2534:             gen_set_label(l2);
                   2535:         }
                   2536:         opn = "ddivu.g";
                   2537:         break;
                   2538:     case OPC_DMOD_G_2E:
                   2539:     case OPC_DMOD_G_2F:
                   2540:         {
                   2541:             int l1 = gen_new_label();
                   2542:             int l2 = gen_new_label();
                   2543:             int l3 = gen_new_label();
                   2544:             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
                   2545:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
                   2546:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
                   2547:             gen_set_label(l1);
                   2548:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   2549:             tcg_gen_br(l3);
                   2550:             gen_set_label(l2);
                   2551:             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
                   2552:             gen_set_label(l3);
                   2553:         }
                   2554:         opn = "dmod.g";
                   2555:         break;
                   2556:     case OPC_DMODU_G_2E:
                   2557:     case OPC_DMODU_G_2F:
                   2558:         {
                   2559:             int l1 = gen_new_label();
                   2560:             int l2 = gen_new_label();
                   2561:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
                   2562:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   2563:             tcg_gen_br(l2);
                   2564:             gen_set_label(l1);
                   2565:             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
                   2566:             gen_set_label(l2);
                   2567:         }
                   2568:         opn = "dmodu.g";
                   2569:         break;
                   2570: #endif
                   2571:     }
                   2572: 
1.1.1.13  root     2573:     (void)opn; /* avoid a compiler warning */
1.1.1.12  root     2574:     MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
                   2575:     tcg_temp_free(t0);
                   2576:     tcg_temp_free(t1);
                   2577: }
                   2578: 
                   2579: /* Traps */
1.1.1.5   root     2580: static void gen_trap (DisasContext *ctx, uint32_t opc,
1.1       root     2581:                       int rs, int rt, int16_t imm)
                   2582: {
                   2583:     int cond;
1.1.1.8   root     2584:     TCGv t0 = tcg_temp_new();
                   2585:     TCGv t1 = tcg_temp_new();
1.1       root     2586: 
                   2587:     cond = 0;
                   2588:     /* Load needed operands */
                   2589:     switch (opc) {
                   2590:     case OPC_TEQ:
                   2591:     case OPC_TGE:
                   2592:     case OPC_TGEU:
                   2593:     case OPC_TLT:
                   2594:     case OPC_TLTU:
                   2595:     case OPC_TNE:
                   2596:         /* Compare two registers */
                   2597:         if (rs != rt) {
1.1.1.7   root     2598:             gen_load_gpr(t0, rs);
                   2599:             gen_load_gpr(t1, rt);
1.1       root     2600:             cond = 1;
                   2601:         }
1.1.1.5   root     2602:         break;
1.1       root     2603:     case OPC_TEQI:
                   2604:     case OPC_TGEI:
                   2605:     case OPC_TGEIU:
                   2606:     case OPC_TLTI:
                   2607:     case OPC_TLTIU:
                   2608:     case OPC_TNEI:
                   2609:         /* Compare register to immediate */
                   2610:         if (rs != 0 || imm != 0) {
1.1.1.7   root     2611:             gen_load_gpr(t0, rs);
                   2612:             tcg_gen_movi_tl(t1, (int32_t)imm);
1.1       root     2613:             cond = 1;
                   2614:         }
                   2615:         break;
                   2616:     }
                   2617:     if (cond == 0) {
                   2618:         switch (opc) {
                   2619:         case OPC_TEQ:   /* rs == rs */
                   2620:         case OPC_TEQI:  /* r0 == 0  */
                   2621:         case OPC_TGE:   /* rs >= rs */
                   2622:         case OPC_TGEI:  /* r0 >= 0  */
                   2623:         case OPC_TGEU:  /* rs >= rs unsigned */
                   2624:         case OPC_TGEIU: /* r0 >= 0  unsigned */
                   2625:             /* Always trap */
1.1.1.8   root     2626:             generate_exception(ctx, EXCP_TRAP);
1.1       root     2627:             break;
                   2628:         case OPC_TLT:   /* rs < rs           */
                   2629:         case OPC_TLTI:  /* r0 < 0            */
                   2630:         case OPC_TLTU:  /* rs < rs unsigned  */
                   2631:         case OPC_TLTIU: /* r0 < 0  unsigned  */
                   2632:         case OPC_TNE:   /* rs != rs          */
                   2633:         case OPC_TNEI:  /* r0 != 0           */
1.1.1.6   root     2634:             /* Never trap: treat as NOP. */
1.1.1.8   root     2635:             break;
1.1       root     2636:         }
                   2637:     } else {
1.1.1.8   root     2638:         int l1 = gen_new_label();
                   2639: 
1.1       root     2640:         switch (opc) {
                   2641:         case OPC_TEQ:
                   2642:         case OPC_TEQI:
1.1.1.8   root     2643:             tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
1.1       root     2644:             break;
                   2645:         case OPC_TGE:
                   2646:         case OPC_TGEI:
1.1.1.8   root     2647:             tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
1.1       root     2648:             break;
                   2649:         case OPC_TGEU:
                   2650:         case OPC_TGEIU:
1.1.1.8   root     2651:             tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
1.1       root     2652:             break;
                   2653:         case OPC_TLT:
                   2654:         case OPC_TLTI:
1.1.1.8   root     2655:             tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
1.1       root     2656:             break;
                   2657:         case OPC_TLTU:
                   2658:         case OPC_TLTIU:
1.1.1.8   root     2659:             tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
1.1       root     2660:             break;
                   2661:         case OPC_TNE:
                   2662:         case OPC_TNEI:
1.1.1.8   root     2663:             tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
1.1       root     2664:             break;
                   2665:         }
1.1.1.8   root     2666:         generate_exception(ctx, EXCP_TRAP);
1.1.1.7   root     2667:         gen_set_label(l1);
                   2668:     }
                   2669:     tcg_temp_free(t0);
                   2670:     tcg_temp_free(t1);
1.1       root     2671: }
                   2672: 
1.1.1.7   root     2673: static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1.1.1.2   root     2674: {
                   2675:     TranslationBlock *tb;
                   2676:     tb = ctx->tb;
1.1.1.9   root     2677:     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
                   2678:         likely(!ctx->singlestep_enabled)) {
1.1.1.7   root     2679:         tcg_gen_goto_tb(n);
1.1.1.6   root     2680:         gen_save_pc(dest);
1.1.1.14  root     2681:         tcg_gen_exit_tb((tcg_target_long)tb + n);
1.1.1.2   root     2682:     } else {
1.1.1.6   root     2683:         gen_save_pc(dest);
1.1.1.9   root     2684:         if (ctx->singlestep_enabled) {
                   2685:             save_cpu_state(ctx, 0);
                   2686:             gen_helper_0i(raise_exception, EXCP_DEBUG);
                   2687:         }
1.1.1.7   root     2688:         tcg_gen_exit_tb(0);
1.1.1.2   root     2689:     }
                   2690: }
                   2691: 
1.1       root     2692: /* Branches (before delay slot) */
1.1.1.5   root     2693: static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1.1.1.12  root     2694:                                 int insn_bytes,
1.1       root     2695:                                 int rs, int rt, int32_t offset)
                   2696: {
1.1.1.7   root     2697:     target_ulong btgt = -1;
1.1.1.6   root     2698:     int blink = 0;
1.1.1.7   root     2699:     int bcond_compute = 0;
1.1.1.8   root     2700:     TCGv t0 = tcg_temp_new();
                   2701:     TCGv t1 = tcg_temp_new();
1.1       root     2702: 
1.1.1.6   root     2703:     if (ctx->hflags & MIPS_HFLAG_BMASK) {
                   2704: #ifdef MIPS_DEBUG_DISAS
1.1.1.7   root     2705:         LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
1.1.1.6   root     2706: #endif
                   2707:         generate_exception(ctx, EXCP_RI);
1.1.1.7   root     2708:         goto out;
1.1.1.6   root     2709:     }
                   2710: 
                   2711:     /* Load needed operands */
                   2712:     switch (opc) {
                   2713:     case OPC_BEQ:
                   2714:     case OPC_BEQL:
                   2715:     case OPC_BNE:
                   2716:     case OPC_BNEL:
1.1       root     2717:         /* Compare two registers */
                   2718:         if (rs != rt) {
1.1.1.7   root     2719:             gen_load_gpr(t0, rs);
                   2720:             gen_load_gpr(t1, rt);
                   2721:             bcond_compute = 1;
1.1       root     2722:         }
1.1.1.12  root     2723:         btgt = ctx->pc + insn_bytes + offset;
1.1       root     2724:         break;
                   2725:     case OPC_BGEZ:
                   2726:     case OPC_BGEZAL:
1.1.1.12  root     2727:     case OPC_BGEZALS:
1.1       root     2728:     case OPC_BGEZALL:
                   2729:     case OPC_BGEZL:
                   2730:     case OPC_BGTZ:
                   2731:     case OPC_BGTZL:
                   2732:     case OPC_BLEZ:
                   2733:     case OPC_BLEZL:
                   2734:     case OPC_BLTZ:
                   2735:     case OPC_BLTZAL:
1.1.1.12  root     2736:     case OPC_BLTZALS:
1.1       root     2737:     case OPC_BLTZALL:
                   2738:     case OPC_BLTZL:
                   2739:         /* Compare to zero */
                   2740:         if (rs != 0) {
1.1.1.7   root     2741:             gen_load_gpr(t0, rs);
                   2742:             bcond_compute = 1;
1.1       root     2743:         }
1.1.1.12  root     2744:         btgt = ctx->pc + insn_bytes + offset;
1.1       root     2745:         break;
                   2746:     case OPC_J:
                   2747:     case OPC_JAL:
1.1.1.12  root     2748:     case OPC_JALX:
                   2749:     case OPC_JALS:
                   2750:     case OPC_JALXS:
1.1       root     2751:         /* Jump to immediate */
1.1.1.12  root     2752:         btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
1.1       root     2753:         break;
                   2754:     case OPC_JR:
                   2755:     case OPC_JALR:
1.1.1.12  root     2756:     case OPC_JALRC:
                   2757:     case OPC_JALRS:
1.1       root     2758:         /* Jump to register */
1.1.1.5   root     2759:         if (offset != 0 && offset != 16) {
                   2760:             /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
1.1.1.6   root     2761:                others are reserved. */
                   2762:             MIPS_INVAL("jump hint");
1.1       root     2763:             generate_exception(ctx, EXCP_RI);
1.1.1.7   root     2764:             goto out;
1.1       root     2765:         }
1.1.1.7   root     2766:         gen_load_gpr(btarget, rs);
1.1       root     2767:         break;
                   2768:     default:
                   2769:         MIPS_INVAL("branch/jump");
                   2770:         generate_exception(ctx, EXCP_RI);
1.1.1.7   root     2771:         goto out;
1.1       root     2772:     }
1.1.1.7   root     2773:     if (bcond_compute == 0) {
1.1       root     2774:         /* No condition to be computed */
                   2775:         switch (opc) {
                   2776:         case OPC_BEQ:     /* rx == rx        */
                   2777:         case OPC_BEQL:    /* rx == rx likely */
                   2778:         case OPC_BGEZ:    /* 0 >= 0          */
                   2779:         case OPC_BGEZL:   /* 0 >= 0 likely   */
                   2780:         case OPC_BLEZ:    /* 0 <= 0          */
                   2781:         case OPC_BLEZL:   /* 0 <= 0 likely   */
                   2782:             /* Always take */
1.1.1.2   root     2783:             ctx->hflags |= MIPS_HFLAG_B;
1.1       root     2784:             MIPS_DEBUG("balways");
                   2785:             break;
1.1.1.12  root     2786:         case OPC_BGEZALS:
1.1       root     2787:         case OPC_BGEZAL:  /* 0 >= 0          */
                   2788:         case OPC_BGEZALL: /* 0 >= 0 likely   */
1.1.1.12  root     2789:             ctx->hflags |= (opc == OPC_BGEZALS
                   2790:                             ? MIPS_HFLAG_BDS16
                   2791:                             : MIPS_HFLAG_BDS32);
1.1       root     2792:             /* Always take and link */
                   2793:             blink = 31;
1.1.1.2   root     2794:             ctx->hflags |= MIPS_HFLAG_B;
1.1       root     2795:             MIPS_DEBUG("balways and link");
                   2796:             break;
                   2797:         case OPC_BNE:     /* rx != rx        */
                   2798:         case OPC_BGTZ:    /* 0 > 0           */
                   2799:         case OPC_BLTZ:    /* 0 < 0           */
1.1.1.6   root     2800:             /* Treat as NOP. */
1.1       root     2801:             MIPS_DEBUG("bnever (NOP)");
1.1.1.7   root     2802:             goto out;
1.1.1.12  root     2803:         case OPC_BLTZALS:
1.1.1.2   root     2804:         case OPC_BLTZAL:  /* 0 < 0           */
1.1.1.12  root     2805:             ctx->hflags |= (opc == OPC_BLTZALS
                   2806:                             ? MIPS_HFLAG_BDS16
                   2807:                             : MIPS_HFLAG_BDS32);
                   2808:             /* Handle as an unconditional branch to get correct delay
                   2809:                slot checking.  */
                   2810:             blink = 31;
                   2811:             btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
                   2812:             ctx->hflags |= MIPS_HFLAG_B;
1.1.1.6   root     2813:             MIPS_DEBUG("bnever and link");
1.1.1.12  root     2814:             break;
1.1.1.2   root     2815:         case OPC_BLTZALL: /* 0 < 0 likely */
1.1.1.8   root     2816:             tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
1.1.1.6   root     2817:             /* Skip the instruction in the delay slot */
                   2818:             MIPS_DEBUG("bnever, link and skip");
                   2819:             ctx->pc += 4;
1.1.1.7   root     2820:             goto out;
1.1       root     2821:         case OPC_BNEL:    /* rx != rx likely */
                   2822:         case OPC_BGTZL:   /* 0 > 0 likely */
                   2823:         case OPC_BLTZL:   /* 0 < 0 likely */
                   2824:             /* Skip the instruction in the delay slot */
                   2825:             MIPS_DEBUG("bnever and skip");
1.1.1.6   root     2826:             ctx->pc += 4;
1.1.1.7   root     2827:             goto out;
1.1       root     2828:         case OPC_J:
1.1.1.2   root     2829:             ctx->hflags |= MIPS_HFLAG_B;
1.1.1.7   root     2830:             MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
1.1       root     2831:             break;
1.1.1.12  root     2832:         case OPC_JALXS:
                   2833:         case OPC_JALX:
                   2834:             ctx->hflags |= MIPS_HFLAG_BX;
                   2835:             /* Fallthrough */
                   2836:         case OPC_JALS:
1.1       root     2837:         case OPC_JAL:
                   2838:             blink = 31;
1.1.1.2   root     2839:             ctx->hflags |= MIPS_HFLAG_B;
1.1.1.12  root     2840:             ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
                   2841:                             ? MIPS_HFLAG_BDS16
                   2842:                             : MIPS_HFLAG_BDS32);
1.1.1.7   root     2843:             MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
1.1       root     2844:             break;
                   2845:         case OPC_JR:
1.1.1.2   root     2846:             ctx->hflags |= MIPS_HFLAG_BR;
1.1.1.12  root     2847:             if (insn_bytes == 4)
                   2848:                 ctx->hflags |= MIPS_HFLAG_BDS32;
1.1       root     2849:             MIPS_DEBUG("jr %s", regnames[rs]);
                   2850:             break;
1.1.1.12  root     2851:         case OPC_JALRS:
1.1       root     2852:         case OPC_JALR:
1.1.1.12  root     2853:         case OPC_JALRC:
1.1       root     2854:             blink = rt;
1.1.1.2   root     2855:             ctx->hflags |= MIPS_HFLAG_BR;
1.1.1.12  root     2856:             ctx->hflags |= (opc == OPC_JALRS
                   2857:                             ? MIPS_HFLAG_BDS16
                   2858:                             : MIPS_HFLAG_BDS32);
1.1       root     2859:             MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
                   2860:             break;
                   2861:         default:
                   2862:             MIPS_INVAL("branch/jump");
                   2863:             generate_exception(ctx, EXCP_RI);
1.1.1.7   root     2864:             goto out;
1.1       root     2865:         }
                   2866:     } else {
                   2867:         switch (opc) {
                   2868:         case OPC_BEQ:
1.1.1.12  root     2869:             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
1.1.1.6   root     2870:             MIPS_DEBUG("beq %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_BEQL:
1.1.1.12  root     2874:             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
1.1.1.6   root     2875:             MIPS_DEBUG("beql %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_BNE:
1.1.1.12  root     2879:             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
1.1.1.6   root     2880:             MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
1.1.1.7   root     2881:                        regnames[rs], regnames[rt], btgt);
1.1       root     2882:             goto not_likely;
                   2883:         case OPC_BNEL:
1.1.1.12  root     2884:             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
1.1.1.6   root     2885:             MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
1.1.1.7   root     2886:                        regnames[rs], regnames[rt], btgt);
1.1       root     2887:             goto likely;
                   2888:         case OPC_BGEZ:
1.1.1.12  root     2889:             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
1.1.1.7   root     2890:             MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2891:             goto not_likely;
                   2892:         case OPC_BGEZL:
1.1.1.12  root     2893:             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
1.1.1.7   root     2894:             MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2895:             goto likely;
1.1.1.12  root     2896:         case OPC_BGEZALS:
1.1       root     2897:         case OPC_BGEZAL:
1.1.1.12  root     2898:             ctx->hflags |= (opc == OPC_BGEZALS
                   2899:                             ? MIPS_HFLAG_BDS16
                   2900:                             : MIPS_HFLAG_BDS32);
                   2901:             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
1.1.1.7   root     2902:             MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2903:             blink = 31;
                   2904:             goto not_likely;
                   2905:         case OPC_BGEZALL:
1.1.1.12  root     2906:             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
1.1       root     2907:             blink = 31;
1.1.1.7   root     2908:             MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2909:             goto likely;
                   2910:         case OPC_BGTZ:
1.1.1.12  root     2911:             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
1.1.1.7   root     2912:             MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2913:             goto not_likely;
                   2914:         case OPC_BGTZL:
1.1.1.12  root     2915:             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
1.1.1.7   root     2916:             MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2917:             goto likely;
                   2918:         case OPC_BLEZ:
1.1.1.12  root     2919:             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
1.1.1.7   root     2920:             MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2921:             goto not_likely;
                   2922:         case OPC_BLEZL:
1.1.1.12  root     2923:             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
1.1.1.7   root     2924:             MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2925:             goto likely;
                   2926:         case OPC_BLTZ:
1.1.1.12  root     2927:             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
1.1.1.7   root     2928:             MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2929:             goto not_likely;
                   2930:         case OPC_BLTZL:
1.1.1.12  root     2931:             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
1.1.1.7   root     2932:             MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2933:             goto likely;
1.1.1.12  root     2934:         case OPC_BLTZALS:
1.1       root     2935:         case OPC_BLTZAL:
1.1.1.12  root     2936:             ctx->hflags |= (opc == OPC_BLTZALS
                   2937:                             ? MIPS_HFLAG_BDS16
                   2938:                             : MIPS_HFLAG_BDS32);
                   2939:             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
1.1       root     2940:             blink = 31;
1.1.1.7   root     2941:             MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2942:         not_likely:
1.1.1.2   root     2943:             ctx->hflags |= MIPS_HFLAG_BC;
1.1       root     2944:             break;
                   2945:         case OPC_BLTZALL:
1.1.1.12  root     2946:             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
1.1       root     2947:             blink = 31;
1.1.1.7   root     2948:             MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2949:         likely:
1.1.1.2   root     2950:             ctx->hflags |= MIPS_HFLAG_BL;
1.1       root     2951:             break;
1.1.1.6   root     2952:         default:
                   2953:             MIPS_INVAL("conditional branch/jump");
                   2954:             generate_exception(ctx, EXCP_RI);
1.1.1.7   root     2955:             goto out;
1.1       root     2956:         }
                   2957:     }
1.1.1.6   root     2958:     MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
1.1.1.7   root     2959:                blink, ctx->hflags, btgt);
1.1.1.6   root     2960: 
1.1.1.7   root     2961:     ctx->btarget = btgt;
1.1       root     2962:     if (blink > 0) {
1.1.1.12  root     2963:         int post_delay = insn_bytes;
                   2964:         int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
                   2965: 
                   2966:         if (opc != OPC_JALRC)
                   2967:             post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
                   2968: 
                   2969:         tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
1.1       root     2970:     }
1.1.1.7   root     2971: 
                   2972:  out:
1.1.1.12  root     2973:     if (insn_bytes == 2)
                   2974:         ctx->hflags |= MIPS_HFLAG_B16;
1.1.1.7   root     2975:     tcg_temp_free(t0);
                   2976:     tcg_temp_free(t1);
1.1       root     2977: }
                   2978: 
1.1.1.5   root     2979: /* special3 bitfield operations */
                   2980: static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
1.1.1.7   root     2981:                         int rs, int lsb, int msb)
1.1       root     2982: {
1.1.1.7   root     2983:     TCGv t0 = tcg_temp_new();
                   2984:     TCGv t1 = tcg_temp_new();
                   2985:     target_ulong mask;
                   2986: 
                   2987:     gen_load_gpr(t1, rs);
1.1.1.5   root     2988:     switch (opc) {
                   2989:     case OPC_EXT:
                   2990:         if (lsb + msb > 31)
                   2991:             goto fail;
1.1.1.7   root     2992:         tcg_gen_shri_tl(t0, t1, lsb);
                   2993:         if (msb != 31) {
                   2994:             tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
                   2995:         } else {
                   2996:             tcg_gen_ext32s_tl(t0, t0);
                   2997:         }
1.1.1.5   root     2998:         break;
1.1.1.6   root     2999: #if defined(TARGET_MIPS64)
1.1.1.5   root     3000:     case OPC_DEXTM:
1.1.1.7   root     3001:         tcg_gen_shri_tl(t0, t1, lsb);
                   3002:         if (msb != 31) {
                   3003:             tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
                   3004:         }
1.1.1.5   root     3005:         break;
                   3006:     case OPC_DEXTU:
1.1.1.7   root     3007:         tcg_gen_shri_tl(t0, t1, lsb + 32);
                   3008:         tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
1.1.1.5   root     3009:         break;
                   3010:     case OPC_DEXT:
1.1.1.7   root     3011:         tcg_gen_shri_tl(t0, t1, lsb);
                   3012:         tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
1.1.1.5   root     3013:         break;
1.1.1.6   root     3014: #endif
1.1.1.5   root     3015:     case OPC_INS:
                   3016:         if (lsb > msb)
                   3017:             goto fail;
1.1.1.7   root     3018:         mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
                   3019:         gen_load_gpr(t0, rt);
                   3020:         tcg_gen_andi_tl(t0, t0, ~mask);
                   3021:         tcg_gen_shli_tl(t1, t1, lsb);
                   3022:         tcg_gen_andi_tl(t1, t1, mask);
                   3023:         tcg_gen_or_tl(t0, t0, t1);
                   3024:         tcg_gen_ext32s_tl(t0, t0);
1.1.1.5   root     3025:         break;
1.1.1.6   root     3026: #if defined(TARGET_MIPS64)
1.1.1.5   root     3027:     case OPC_DINSM:
                   3028:         if (lsb > msb)
                   3029:             goto fail;
1.1.1.7   root     3030:         mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
                   3031:         gen_load_gpr(t0, rt);
                   3032:         tcg_gen_andi_tl(t0, t0, ~mask);
                   3033:         tcg_gen_shli_tl(t1, t1, lsb);
                   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_DINSU:
                   3038:         if (lsb > msb)
                   3039:             goto fail;
1.1.1.11  root     3040:         mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
1.1.1.7   root     3041:         gen_load_gpr(t0, rt);
                   3042:         tcg_gen_andi_tl(t0, t0, ~mask);
                   3043:         tcg_gen_shli_tl(t1, t1, lsb + 32);
                   3044:         tcg_gen_andi_tl(t1, t1, mask);
                   3045:         tcg_gen_or_tl(t0, t0, t1);
1.1.1.5   root     3046:         break;
                   3047:     case OPC_DINS:
                   3048:         if (lsb > msb)
                   3049:             goto fail;
1.1.1.7   root     3050:         gen_load_gpr(t0, rt);
                   3051:         mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
                   3052:         gen_load_gpr(t0, rt);
                   3053:         tcg_gen_andi_tl(t0, t0, ~mask);
                   3054:         tcg_gen_shli_tl(t1, t1, lsb);
                   3055:         tcg_gen_andi_tl(t1, t1, mask);
                   3056:         tcg_gen_or_tl(t0, t0, t1);
1.1.1.5   root     3057:         break;
1.1.1.6   root     3058: #endif
1.1.1.5   root     3059:     default:
                   3060: fail:
                   3061:         MIPS_INVAL("bitops");
                   3062:         generate_exception(ctx, EXCP_RI);
1.1.1.7   root     3063:         tcg_temp_free(t0);
                   3064:         tcg_temp_free(t1);
1.1       root     3065:         return;
                   3066:     }
1.1.1.7   root     3067:     gen_store_gpr(t0, rt);
                   3068:     tcg_temp_free(t0);
                   3069:     tcg_temp_free(t1);
                   3070: }
                   3071: 
                   3072: static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
                   3073: {
1.1.1.8   root     3074:     TCGv t0;
1.1.1.7   root     3075: 
1.1.1.8   root     3076:     if (rd == 0) {
                   3077:         /* If no destination, treat it as a NOP. */
                   3078:         MIPS_DEBUG("NOP");
                   3079:         return;
                   3080:     }
                   3081: 
                   3082:     t0 = tcg_temp_new();
                   3083:     gen_load_gpr(t0, rt);
1.1.1.7   root     3084:     switch (op2) {
                   3085:     case OPC_WSBH:
1.1.1.8   root     3086:         {
                   3087:             TCGv t1 = tcg_temp_new();
                   3088: 
                   3089:             tcg_gen_shri_tl(t1, t0, 8);
                   3090:             tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
                   3091:             tcg_gen_shli_tl(t0, t0, 8);
                   3092:             tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
                   3093:             tcg_gen_or_tl(t0, t0, t1);
                   3094:             tcg_temp_free(t1);
                   3095:             tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
                   3096:         }
1.1.1.7   root     3097:         break;
                   3098:     case OPC_SEB:
1.1.1.8   root     3099:         tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
1.1.1.7   root     3100:         break;
                   3101:     case OPC_SEH:
1.1.1.8   root     3102:         tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
1.1.1.7   root     3103:         break;
                   3104: #if defined(TARGET_MIPS64)
                   3105:     case OPC_DSBH:
1.1.1.8   root     3106:         {
                   3107:             TCGv t1 = tcg_temp_new();
                   3108: 
                   3109:             tcg_gen_shri_tl(t1, t0, 8);
                   3110:             tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
                   3111:             tcg_gen_shli_tl(t0, t0, 8);
                   3112:             tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
                   3113:             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
                   3114:             tcg_temp_free(t1);
                   3115:         }
1.1.1.7   root     3116:         break;
                   3117:     case OPC_DSHD:
1.1.1.8   root     3118:         {
                   3119:             TCGv t1 = tcg_temp_new();
                   3120: 
                   3121:             tcg_gen_shri_tl(t1, t0, 16);
                   3122:             tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
                   3123:             tcg_gen_shli_tl(t0, t0, 16);
                   3124:             tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
                   3125:             tcg_gen_or_tl(t0, t0, t1);
                   3126:             tcg_gen_shri_tl(t1, t0, 32);
                   3127:             tcg_gen_shli_tl(t0, t0, 32);
                   3128:             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
                   3129:             tcg_temp_free(t1);
                   3130:         }
1.1.1.7   root     3131:         break;
                   3132: #endif
                   3133:     default:
                   3134:         MIPS_INVAL("bsfhl");
                   3135:         generate_exception(ctx, EXCP_RI);
                   3136:         tcg_temp_free(t0);
                   3137:         return;
                   3138:     }
                   3139:     tcg_temp_free(t0);
1.1.1.5   root     3140: }
1.1.1.4   root     3141: 
1.1.1.7   root     3142: #ifndef CONFIG_USER_ONLY
1.1.1.5   root     3143: /* CP0 (MMU and control) */
1.1.1.8   root     3144: static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
1.1.1.7   root     3145: {
1.1.1.8   root     3146:     TCGv_i32 t0 = tcg_temp_new_i32();
1.1.1.7   root     3147: 
1.1.1.8   root     3148:     tcg_gen_ld_i32(t0, cpu_env, off);
                   3149:     tcg_gen_ext_i32_tl(arg, t0);
                   3150:     tcg_temp_free_i32(t0);
1.1.1.7   root     3151: }
                   3152: 
1.1.1.8   root     3153: static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
1.1.1.7   root     3154: {
1.1.1.8   root     3155:     tcg_gen_ld_tl(arg, cpu_env, off);
                   3156:     tcg_gen_ext32s_tl(arg, arg);
1.1.1.7   root     3157: }
                   3158: 
1.1.1.8   root     3159: static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
1.1.1.7   root     3160: {
1.1.1.8   root     3161:     TCGv_i32 t0 = tcg_temp_new_i32();
1.1.1.7   root     3162: 
1.1.1.8   root     3163:     tcg_gen_trunc_tl_i32(t0, arg);
                   3164:     tcg_gen_st_i32(t0, cpu_env, off);
                   3165:     tcg_temp_free_i32(t0);
1.1.1.7   root     3166: }
                   3167: 
1.1.1.8   root     3168: static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
1.1.1.7   root     3169: {
1.1.1.8   root     3170:     tcg_gen_ext32s_tl(arg, arg);
                   3171:     tcg_gen_st_tl(arg, cpu_env, off);
1.1.1.7   root     3172: }
                   3173: 
1.1.1.16! root     3174: static void gen_mfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
1.1.1.5   root     3175: {
                   3176:     const char *rn = "invalid";
                   3177: 
1.1.1.6   root     3178:     if (sel != 0)
                   3179:         check_insn(env, ctx, ISA_MIPS32);
                   3180: 
1.1.1.5   root     3181:     switch (reg) {
                   3182:     case 0:
                   3183:         switch (sel) {
                   3184:         case 0:
1.1.1.16! root     3185:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
1.1.1.5   root     3186:             rn = "Index";
                   3187:             break;
                   3188:         case 1:
1.1.1.6   root     3189:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3190:             gen_helper_mfc0_mvpcontrol(arg);
1.1.1.5   root     3191:             rn = "MVPControl";
1.1.1.6   root     3192:             break;
1.1.1.5   root     3193:         case 2:
1.1.1.6   root     3194:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3195:             gen_helper_mfc0_mvpconf0(arg);
1.1.1.5   root     3196:             rn = "MVPConf0";
1.1.1.6   root     3197:             break;
1.1.1.5   root     3198:         case 3:
1.1.1.6   root     3199:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3200:             gen_helper_mfc0_mvpconf1(arg);
1.1.1.5   root     3201:             rn = "MVPConf1";
1.1.1.6   root     3202:             break;
1.1.1.5   root     3203:         default:
                   3204:             goto die;
1.1       root     3205:         }
                   3206:         break;
1.1.1.5   root     3207:     case 1:
                   3208:         switch (sel) {
                   3209:         case 0:
1.1.1.8   root     3210:             gen_helper_mfc0_random(arg);
1.1.1.5   root     3211:             rn = "Random";
1.1.1.6   root     3212:             break;
1.1.1.5   root     3213:         case 1:
1.1.1.6   root     3214:             check_insn(env, ctx, ASE_MT);
1.1.1.16! root     3215:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
1.1.1.5   root     3216:             rn = "VPEControl";
1.1.1.6   root     3217:             break;
1.1.1.5   root     3218:         case 2:
1.1.1.6   root     3219:             check_insn(env, ctx, ASE_MT);
1.1.1.16! root     3220:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
1.1.1.5   root     3221:             rn = "VPEConf0";
1.1.1.6   root     3222:             break;
1.1.1.5   root     3223:         case 3:
1.1.1.6   root     3224:             check_insn(env, ctx, ASE_MT);
1.1.1.16! root     3225:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
1.1.1.5   root     3226:             rn = "VPEConf1";
1.1.1.6   root     3227:             break;
1.1.1.5   root     3228:         case 4:
1.1.1.6   root     3229:             check_insn(env, ctx, ASE_MT);
1.1.1.16! root     3230:             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_YQMask));
1.1.1.5   root     3231:             rn = "YQMask";
1.1.1.6   root     3232:             break;
1.1.1.5   root     3233:         case 5:
1.1.1.6   root     3234:             check_insn(env, ctx, ASE_MT);
1.1.1.16! root     3235:             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
1.1.1.5   root     3236:             rn = "VPESchedule";
1.1.1.6   root     3237:             break;
1.1.1.5   root     3238:         case 6:
1.1.1.6   root     3239:             check_insn(env, ctx, ASE_MT);
1.1.1.16! root     3240:             gen_mfc0_load64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
1.1.1.5   root     3241:             rn = "VPEScheFBack";
1.1.1.6   root     3242:             break;
1.1.1.5   root     3243:         case 7:
1.1.1.6   root     3244:             check_insn(env, ctx, ASE_MT);
1.1.1.16! root     3245:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
1.1.1.5   root     3246:             rn = "VPEOpt";
1.1.1.6   root     3247:             break;
1.1.1.5   root     3248:         default:
                   3249:             goto die;
                   3250:         }
1.1       root     3251:         break;
1.1.1.5   root     3252:     case 2:
                   3253:         switch (sel) {
                   3254:         case 0:
1.1.1.16! root     3255:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
1.1.1.8   root     3256:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3257:             rn = "EntryLo0";
                   3258:             break;
                   3259:         case 1:
                   3260:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3261:             gen_helper_mfc0_tcstatus(arg);
1.1.1.6   root     3262:             rn = "TCStatus";
                   3263:             break;
                   3264:         case 2:
                   3265:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3266:             gen_helper_mfc0_tcbind(arg);
1.1.1.6   root     3267:             rn = "TCBind";
                   3268:             break;
1.1.1.5   root     3269:         case 3:
1.1.1.6   root     3270:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3271:             gen_helper_mfc0_tcrestart(arg);
1.1.1.6   root     3272:             rn = "TCRestart";
                   3273:             break;
1.1.1.5   root     3274:         case 4:
1.1.1.6   root     3275:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3276:             gen_helper_mfc0_tchalt(arg);
1.1.1.6   root     3277:             rn = "TCHalt";
                   3278:             break;
1.1.1.5   root     3279:         case 5:
1.1.1.6   root     3280:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3281:             gen_helper_mfc0_tccontext(arg);
1.1.1.6   root     3282:             rn = "TCContext";
                   3283:             break;
1.1.1.5   root     3284:         case 6:
1.1.1.6   root     3285:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3286:             gen_helper_mfc0_tcschedule(arg);
1.1.1.6   root     3287:             rn = "TCSchedule";
                   3288:             break;
1.1.1.5   root     3289:         case 7:
1.1.1.6   root     3290:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3291:             gen_helper_mfc0_tcschefback(arg);
1.1.1.6   root     3292:             rn = "TCScheFBack";
                   3293:             break;
1.1.1.5   root     3294:         default:
                   3295:             goto die;
                   3296:         }
1.1       root     3297:         break;
1.1.1.5   root     3298:     case 3:
                   3299:         switch (sel) {
                   3300:         case 0:
1.1.1.16! root     3301:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
1.1.1.8   root     3302:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3303:             rn = "EntryLo1";
                   3304:             break;
1.1.1.5   root     3305:         default:
                   3306:             goto die;
1.1.1.6   root     3307:         }
1.1       root     3308:         break;
1.1.1.5   root     3309:     case 4:
                   3310:         switch (sel) {
                   3311:         case 0:
1.1.1.16! root     3312:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
1.1.1.8   root     3313:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3314:             rn = "Context";
                   3315:             break;
                   3316:         case 1:
1.1.1.8   root     3317: //            gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
1.1.1.6   root     3318:             rn = "ContextConfig";
                   3319: //            break;
1.1.1.5   root     3320:         default:
                   3321:             goto die;
1.1.1.6   root     3322:         }
1.1       root     3323:         break;
1.1.1.5   root     3324:     case 5:
                   3325:         switch (sel) {
                   3326:         case 0:
1.1.1.16! root     3327:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
1.1.1.6   root     3328:             rn = "PageMask";
                   3329:             break;
                   3330:         case 1:
                   3331:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.16! root     3332:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
1.1.1.6   root     3333:             rn = "PageGrain";
                   3334:             break;
1.1.1.5   root     3335:         default:
                   3336:             goto die;
1.1.1.6   root     3337:         }
1.1       root     3338:         break;
1.1.1.5   root     3339:     case 6:
                   3340:         switch (sel) {
                   3341:         case 0:
1.1.1.16! root     3342:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
1.1.1.6   root     3343:             rn = "Wired";
                   3344:             break;
                   3345:         case 1:
                   3346:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.16! root     3347:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
1.1.1.6   root     3348:             rn = "SRSConf0";
                   3349:             break;
                   3350:         case 2:
                   3351:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.16! root     3352:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
1.1.1.6   root     3353:             rn = "SRSConf1";
                   3354:             break;
1.1.1.5   root     3355:         case 3:
1.1.1.6   root     3356:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.16! root     3357:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
1.1.1.6   root     3358:             rn = "SRSConf2";
                   3359:             break;
1.1.1.5   root     3360:         case 4:
1.1.1.6   root     3361:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.16! root     3362:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
1.1.1.6   root     3363:             rn = "SRSConf3";
                   3364:             break;
1.1.1.5   root     3365:         case 5:
1.1.1.6   root     3366:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.16! root     3367:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
1.1.1.6   root     3368:             rn = "SRSConf4";
                   3369:             break;
1.1.1.5   root     3370:         default:
                   3371:             goto die;
1.1.1.6   root     3372:         }
1.1       root     3373:         break;
1.1.1.5   root     3374:     case 7:
                   3375:         switch (sel) {
                   3376:         case 0:
1.1.1.6   root     3377:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.16! root     3378:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
1.1.1.6   root     3379:             rn = "HWREna";
                   3380:             break;
1.1.1.5   root     3381:         default:
                   3382:             goto die;
1.1.1.6   root     3383:         }
1.1       root     3384:         break;
1.1.1.5   root     3385:     case 8:
                   3386:         switch (sel) {
                   3387:         case 0:
1.1.1.16! root     3388:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
1.1.1.8   root     3389:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.7   root     3390:             rn = "BadVAddr";
1.1.1.6   root     3391:             break;
1.1.1.5   root     3392:         default:
                   3393:             goto die;
                   3394:        }
1.1.1.2   root     3395:         break;
1.1.1.5   root     3396:     case 9:
                   3397:         switch (sel) {
                   3398:         case 0:
1.1.1.7   root     3399:             /* Mark as an IO operation because we read the time.  */
                   3400:             if (use_icount)
                   3401:                 gen_io_start();
1.1.1.8   root     3402:             gen_helper_mfc0_count(arg);
1.1.1.7   root     3403:             if (use_icount) {
                   3404:                 gen_io_end();
                   3405:             }
1.1.1.13  root     3406:             /* Break the TB to be able to take timer interrupts immediately
                   3407:                after reading count.  */
                   3408:             ctx->bstate = BS_STOP;
1.1.1.6   root     3409:             rn = "Count";
                   3410:             break;
                   3411:         /* 6,7 are implementation dependent */
1.1.1.5   root     3412:         default:
                   3413:             goto die;
1.1.1.6   root     3414:         }
1.1.1.5   root     3415:         break;
                   3416:     case 10:
                   3417:         switch (sel) {
                   3418:         case 0:
1.1.1.16! root     3419:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
1.1.1.8   root     3420:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3421:             rn = "EntryHi";
                   3422:             break;
1.1.1.5   root     3423:         default:
                   3424:             goto die;
1.1.1.6   root     3425:         }
1.1.1.5   root     3426:         break;
                   3427:     case 11:
                   3428:         switch (sel) {
                   3429:         case 0:
1.1.1.16! root     3430:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
1.1.1.6   root     3431:             rn = "Compare";
                   3432:             break;
                   3433:         /* 6,7 are implementation dependent */
1.1.1.5   root     3434:         default:
                   3435:             goto die;
1.1.1.6   root     3436:         }
1.1.1.5   root     3437:         break;
                   3438:     case 12:
                   3439:         switch (sel) {
                   3440:         case 0:
1.1.1.16! root     3441:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
1.1.1.6   root     3442:             rn = "Status";
                   3443:             break;
                   3444:         case 1:
                   3445:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.16! root     3446:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
1.1.1.6   root     3447:             rn = "IntCtl";
                   3448:             break;
                   3449:         case 2:
                   3450:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.16! root     3451:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
1.1.1.6   root     3452:             rn = "SRSCtl";
                   3453:             break;
1.1.1.5   root     3454:         case 3:
1.1.1.6   root     3455:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.16! root     3456:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
1.1.1.6   root     3457:             rn = "SRSMap";
                   3458:             break;
1.1.1.5   root     3459:         default:
                   3460:             goto die;
                   3461:        }
                   3462:         break;
                   3463:     case 13:
                   3464:         switch (sel) {
                   3465:         case 0:
1.1.1.16! root     3466:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
1.1.1.6   root     3467:             rn = "Cause";
                   3468:             break;
1.1.1.5   root     3469:         default:
                   3470:             goto die;
                   3471:        }
                   3472:         break;
                   3473:     case 14:
                   3474:         switch (sel) {
                   3475:         case 0:
1.1.1.16! root     3476:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
1.1.1.8   root     3477:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3478:             rn = "EPC";
                   3479:             break;
1.1.1.5   root     3480:         default:
                   3481:             goto die;
1.1.1.6   root     3482:         }
1.1.1.5   root     3483:         break;
                   3484:     case 15:
                   3485:         switch (sel) {
                   3486:         case 0:
1.1.1.16! root     3487:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
1.1.1.6   root     3488:             rn = "PRid";
                   3489:             break;
                   3490:         case 1:
                   3491:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.16! root     3492:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
1.1.1.6   root     3493:             rn = "EBase";
                   3494:             break;
1.1.1.5   root     3495:         default:
                   3496:             goto die;
                   3497:        }
                   3498:         break;
                   3499:     case 16:
                   3500:         switch (sel) {
                   3501:         case 0:
1.1.1.16! root     3502:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
1.1.1.5   root     3503:             rn = "Config";
                   3504:             break;
                   3505:         case 1:
1.1.1.16! root     3506:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
1.1.1.5   root     3507:             rn = "Config1";
                   3508:             break;
                   3509:         case 2:
1.1.1.16! root     3510:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
1.1.1.5   root     3511:             rn = "Config2";
                   3512:             break;
                   3513:         case 3:
1.1.1.16! root     3514:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
1.1.1.5   root     3515:             rn = "Config3";
                   3516:             break;
1.1.1.6   root     3517:         /* 4,5 are reserved */
                   3518:         /* 6,7 are implementation dependent */
                   3519:         case 6:
1.1.1.16! root     3520:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
1.1.1.6   root     3521:             rn = "Config6";
                   3522:             break;
                   3523:         case 7:
1.1.1.16! root     3524:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
1.1.1.6   root     3525:             rn = "Config7";
                   3526:             break;
1.1.1.5   root     3527:         default:
                   3528:             goto die;
1.1       root     3529:         }
1.1.1.4   root     3530:         break;
1.1.1.5   root     3531:     case 17:
                   3532:         switch (sel) {
                   3533:         case 0:
1.1.1.8   root     3534:             gen_helper_mfc0_lladdr(arg);
1.1.1.6   root     3535:             rn = "LLAddr";
                   3536:             break;
1.1.1.5   root     3537:         default:
                   3538:             goto die;
                   3539:         }
1.1.1.4   root     3540:         break;
1.1.1.5   root     3541:     case 18:
                   3542:         switch (sel) {
1.1.1.6   root     3543:         case 0 ... 7:
1.1.1.8   root     3544:             gen_helper_1i(mfc0_watchlo, arg, sel);
1.1.1.6   root     3545:             rn = "WatchLo";
                   3546:             break;
1.1.1.5   root     3547:         default:
                   3548:             goto die;
                   3549:         }
1.1.1.4   root     3550:         break;
1.1.1.5   root     3551:     case 19:
                   3552:         switch (sel) {
1.1.1.6   root     3553:         case 0 ...7:
1.1.1.8   root     3554:             gen_helper_1i(mfc0_watchhi, arg, sel);
1.1.1.6   root     3555:             rn = "WatchHi";
                   3556:             break;
1.1.1.5   root     3557:         default:
                   3558:             goto die;
                   3559:         }
1.1.1.4   root     3560:         break;
1.1.1.5   root     3561:     case 20:
                   3562:         switch (sel) {
                   3563:         case 0:
1.1.1.6   root     3564: #if defined(TARGET_MIPS64)
                   3565:             check_insn(env, ctx, ISA_MIPS3);
1.1.1.16! root     3566:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
1.1.1.8   root     3567:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3568:             rn = "XContext";
                   3569:             break;
                   3570: #endif
1.1.1.5   root     3571:         default:
                   3572:             goto die;
1.1.1.4   root     3573:         }
                   3574:         break;
1.1.1.5   root     3575:     case 21:
                   3576:        /* Officially reserved, but sel 0 is used for R1x000 framemask */
                   3577:         switch (sel) {
                   3578:         case 0:
1.1.1.16! root     3579:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
1.1.1.6   root     3580:             rn = "Framemask";
                   3581:             break;
1.1.1.5   root     3582:         default:
                   3583:             goto die;
1.1.1.4   root     3584:         }
                   3585:         break;
1.1.1.5   root     3586:     case 22:
1.1.1.8   root     3587:         tcg_gen_movi_tl(arg, 0); /* unimplemented */
1.1.1.6   root     3588:         rn = "'Diagnostic"; /* implementation dependent */
                   3589:         break;
1.1.1.5   root     3590:     case 23:
                   3591:         switch (sel) {
                   3592:         case 0:
1.1.1.8   root     3593:             gen_helper_mfc0_debug(arg); /* EJTAG support */
1.1.1.6   root     3594:             rn = "Debug";
                   3595:             break;
                   3596:         case 1:
1.1.1.8   root     3597: //            gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
1.1.1.6   root     3598:             rn = "TraceControl";
                   3599: //            break;
                   3600:         case 2:
1.1.1.8   root     3601: //            gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
1.1.1.6   root     3602:             rn = "TraceControl2";
                   3603: //            break;
1.1.1.5   root     3604:         case 3:
1.1.1.8   root     3605: //            gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
1.1.1.6   root     3606:             rn = "UserTraceData";
                   3607: //            break;
1.1.1.5   root     3608:         case 4:
1.1.1.8   root     3609: //            gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
1.1.1.6   root     3610:             rn = "TraceBPC";
                   3611: //            break;
1.1.1.5   root     3612:         default:
                   3613:             goto die;
1.1.1.4   root     3614:         }
1.1.1.5   root     3615:         break;
                   3616:     case 24:
                   3617:         switch (sel) {
                   3618:         case 0:
1.1.1.7   root     3619:             /* EJTAG support */
1.1.1.16! root     3620:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
1.1.1.8   root     3621:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3622:             rn = "DEPC";
                   3623:             break;
1.1.1.5   root     3624:         default:
                   3625:             goto die;
                   3626:         }
                   3627:         break;
                   3628:     case 25:
                   3629:         switch (sel) {
                   3630:         case 0:
1.1.1.16! root     3631:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
1.1.1.6   root     3632:             rn = "Performance0";
1.1.1.5   root     3633:             break;
                   3634:         case 1:
1.1.1.8   root     3635: //            gen_helper_mfc0_performance1(arg);
1.1.1.6   root     3636:             rn = "Performance1";
                   3637: //            break;
1.1.1.5   root     3638:         case 2:
1.1.1.8   root     3639: //            gen_helper_mfc0_performance2(arg);
1.1.1.6   root     3640:             rn = "Performance2";
                   3641: //            break;
1.1.1.5   root     3642:         case 3:
1.1.1.8   root     3643: //            gen_helper_mfc0_performance3(arg);
1.1.1.6   root     3644:             rn = "Performance3";
                   3645: //            break;
1.1.1.5   root     3646:         case 4:
1.1.1.8   root     3647: //            gen_helper_mfc0_performance4(arg);
1.1.1.6   root     3648:             rn = "Performance4";
                   3649: //            break;
1.1.1.5   root     3650:         case 5:
1.1.1.8   root     3651: //            gen_helper_mfc0_performance5(arg);
1.1.1.6   root     3652:             rn = "Performance5";
                   3653: //            break;
1.1.1.5   root     3654:         case 6:
1.1.1.8   root     3655: //            gen_helper_mfc0_performance6(arg);
1.1.1.6   root     3656:             rn = "Performance6";
                   3657: //            break;
1.1.1.5   root     3658:         case 7:
1.1.1.8   root     3659: //            gen_helper_mfc0_performance7(arg);
1.1.1.6   root     3660:             rn = "Performance7";
                   3661: //            break;
1.1.1.5   root     3662:         default:
                   3663:             goto die;
                   3664:         }
                   3665:         break;
                   3666:     case 26:
1.1.1.8   root     3667:         tcg_gen_movi_tl(arg, 0); /* unimplemented */
1.1.1.7   root     3668:         rn = "ECC";
                   3669:         break;
1.1.1.5   root     3670:     case 27:
                   3671:         switch (sel) {
                   3672:         case 0 ... 3:
1.1.1.8   root     3673:             tcg_gen_movi_tl(arg, 0); /* unimplemented */
1.1.1.6   root     3674:             rn = "CacheErr";
                   3675:             break;
1.1.1.5   root     3676:         default:
                   3677:             goto die;
                   3678:         }
                   3679:         break;
                   3680:     case 28:
                   3681:         switch (sel) {
                   3682:         case 0:
                   3683:         case 2:
                   3684:         case 4:
                   3685:         case 6:
1.1.1.16! root     3686:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
1.1.1.5   root     3687:             rn = "TagLo";
                   3688:             break;
                   3689:         case 1:
                   3690:         case 3:
                   3691:         case 5:
                   3692:         case 7:
1.1.1.16! root     3693:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
1.1.1.5   root     3694:             rn = "DataLo";
                   3695:             break;
                   3696:         default:
                   3697:             goto die;
                   3698:         }
                   3699:         break;
                   3700:     case 29:
                   3701:         switch (sel) {
                   3702:         case 0:
                   3703:         case 2:
                   3704:         case 4:
                   3705:         case 6:
1.1.1.16! root     3706:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
1.1.1.5   root     3707:             rn = "TagHi";
                   3708:             break;
                   3709:         case 1:
                   3710:         case 3:
                   3711:         case 5:
                   3712:         case 7:
1.1.1.16! root     3713:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
1.1.1.5   root     3714:             rn = "DataHi";
                   3715:             break;
                   3716:         default:
                   3717:             goto die;
                   3718:         }
                   3719:         break;
                   3720:     case 30:
                   3721:         switch (sel) {
                   3722:         case 0:
1.1.1.16! root     3723:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
1.1.1.8   root     3724:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3725:             rn = "ErrorEPC";
                   3726:             break;
1.1.1.5   root     3727:         default:
                   3728:             goto die;
                   3729:         }
                   3730:         break;
                   3731:     case 31:
                   3732:         switch (sel) {
                   3733:         case 0:
1.1.1.7   root     3734:             /* EJTAG support */
1.1.1.16! root     3735:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
1.1.1.6   root     3736:             rn = "DESAVE";
                   3737:             break;
1.1.1.5   root     3738:         default:
                   3739:             goto die;
                   3740:         }
                   3741:         break;
                   3742:     default:
                   3743:        goto die;
                   3744:     }
1.1.1.13  root     3745:     (void)rn; /* avoid a compiler warning */
1.1.1.7   root     3746:     LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
1.1.1.5   root     3747:     return;
                   3748: 
                   3749: die:
1.1.1.7   root     3750:     LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
1.1.1.5   root     3751:     generate_exception(ctx, EXCP_RI);
                   3752: }
                   3753: 
1.1.1.16! root     3754: static void gen_mtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
1.1.1.5   root     3755: {
                   3756:     const char *rn = "invalid";
                   3757: 
1.1.1.6   root     3758:     if (sel != 0)
                   3759:         check_insn(env, ctx, ISA_MIPS32);
                   3760: 
1.1.1.7   root     3761:     if (use_icount)
                   3762:         gen_io_start();
                   3763: 
1.1.1.5   root     3764:     switch (reg) {
                   3765:     case 0:
                   3766:         switch (sel) {
                   3767:         case 0:
1.1.1.8   root     3768:             gen_helper_mtc0_index(arg);
1.1.1.5   root     3769:             rn = "Index";
                   3770:             break;
                   3771:         case 1:
1.1.1.6   root     3772:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3773:             gen_helper_mtc0_mvpcontrol(arg);
1.1.1.5   root     3774:             rn = "MVPControl";
1.1.1.6   root     3775:             break;
1.1.1.5   root     3776:         case 2:
1.1.1.6   root     3777:             check_insn(env, ctx, ASE_MT);
                   3778:             /* ignored */
1.1.1.5   root     3779:             rn = "MVPConf0";
1.1.1.6   root     3780:             break;
1.1.1.5   root     3781:         case 3:
1.1.1.6   root     3782:             check_insn(env, ctx, ASE_MT);
                   3783:             /* ignored */
1.1.1.5   root     3784:             rn = "MVPConf1";
1.1.1.6   root     3785:             break;
1.1.1.5   root     3786:         default:
                   3787:             goto die;
                   3788:         }
                   3789:         break;
                   3790:     case 1:
                   3791:         switch (sel) {
                   3792:         case 0:
1.1.1.6   root     3793:             /* ignored */
1.1.1.5   root     3794:             rn = "Random";
1.1.1.6   root     3795:             break;
1.1.1.5   root     3796:         case 1:
1.1.1.6   root     3797:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3798:             gen_helper_mtc0_vpecontrol(arg);
1.1.1.5   root     3799:             rn = "VPEControl";
1.1.1.6   root     3800:             break;
1.1.1.5   root     3801:         case 2:
1.1.1.6   root     3802:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3803:             gen_helper_mtc0_vpeconf0(arg);
1.1.1.5   root     3804:             rn = "VPEConf0";
1.1.1.6   root     3805:             break;
1.1.1.5   root     3806:         case 3:
1.1.1.6   root     3807:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3808:             gen_helper_mtc0_vpeconf1(arg);
1.1.1.5   root     3809:             rn = "VPEConf1";
1.1.1.6   root     3810:             break;
1.1.1.5   root     3811:         case 4:
1.1.1.6   root     3812:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3813:             gen_helper_mtc0_yqmask(arg);
1.1.1.5   root     3814:             rn = "YQMask";
1.1.1.6   root     3815:             break;
1.1.1.5   root     3816:         case 5:
1.1.1.6   root     3817:             check_insn(env, ctx, ASE_MT);
1.1.1.16! root     3818:             gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPESchedule));
1.1.1.5   root     3819:             rn = "VPESchedule";
1.1.1.6   root     3820:             break;
1.1.1.5   root     3821:         case 6:
1.1.1.6   root     3822:             check_insn(env, ctx, ASE_MT);
1.1.1.16! root     3823:             gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_VPEScheFBack));
1.1.1.5   root     3824:             rn = "VPEScheFBack";
1.1.1.6   root     3825:             break;
1.1.1.5   root     3826:         case 7:
1.1.1.6   root     3827:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3828:             gen_helper_mtc0_vpeopt(arg);
1.1.1.5   root     3829:             rn = "VPEOpt";
1.1.1.6   root     3830:             break;
1.1.1.5   root     3831:         default:
                   3832:             goto die;
                   3833:         }
                   3834:         break;
                   3835:     case 2:
                   3836:         switch (sel) {
                   3837:         case 0:
1.1.1.8   root     3838:             gen_helper_mtc0_entrylo0(arg);
1.1.1.6   root     3839:             rn = "EntryLo0";
                   3840:             break;
                   3841:         case 1:
                   3842:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3843:             gen_helper_mtc0_tcstatus(arg);
1.1.1.6   root     3844:             rn = "TCStatus";
                   3845:             break;
                   3846:         case 2:
                   3847:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3848:             gen_helper_mtc0_tcbind(arg);
1.1.1.6   root     3849:             rn = "TCBind";
                   3850:             break;
1.1.1.5   root     3851:         case 3:
1.1.1.6   root     3852:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3853:             gen_helper_mtc0_tcrestart(arg);
1.1.1.6   root     3854:             rn = "TCRestart";
                   3855:             break;
1.1.1.5   root     3856:         case 4:
1.1.1.6   root     3857:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3858:             gen_helper_mtc0_tchalt(arg);
1.1.1.6   root     3859:             rn = "TCHalt";
                   3860:             break;
1.1.1.5   root     3861:         case 5:
1.1.1.6   root     3862:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3863:             gen_helper_mtc0_tccontext(arg);
1.1.1.6   root     3864:             rn = "TCContext";
                   3865:             break;
1.1.1.5   root     3866:         case 6:
1.1.1.6   root     3867:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3868:             gen_helper_mtc0_tcschedule(arg);
1.1.1.6   root     3869:             rn = "TCSchedule";
                   3870:             break;
1.1.1.5   root     3871:         case 7:
1.1.1.6   root     3872:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3873:             gen_helper_mtc0_tcschefback(arg);
1.1.1.6   root     3874:             rn = "TCScheFBack";
                   3875:             break;
1.1.1.5   root     3876:         default:
                   3877:             goto die;
                   3878:         }
                   3879:         break;
                   3880:     case 3:
                   3881:         switch (sel) {
                   3882:         case 0:
1.1.1.8   root     3883:             gen_helper_mtc0_entrylo1(arg);
1.1.1.6   root     3884:             rn = "EntryLo1";
                   3885:             break;
1.1.1.5   root     3886:         default:
                   3887:             goto die;
1.1.1.6   root     3888:         }
1.1.1.5   root     3889:         break;
                   3890:     case 4:
                   3891:         switch (sel) {
                   3892:         case 0:
1.1.1.8   root     3893:             gen_helper_mtc0_context(arg);
1.1.1.6   root     3894:             rn = "Context";
                   3895:             break;
                   3896:         case 1:
1.1.1.8   root     3897: //            gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
1.1.1.6   root     3898:             rn = "ContextConfig";
                   3899: //            break;
1.1.1.5   root     3900:         default:
                   3901:             goto die;
1.1.1.6   root     3902:         }
1.1.1.5   root     3903:         break;
                   3904:     case 5:
                   3905:         switch (sel) {
                   3906:         case 0:
1.1.1.8   root     3907:             gen_helper_mtc0_pagemask(arg);
1.1.1.6   root     3908:             rn = "PageMask";
                   3909:             break;
                   3910:         case 1:
                   3911:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3912:             gen_helper_mtc0_pagegrain(arg);
1.1.1.6   root     3913:             rn = "PageGrain";
                   3914:             break;
1.1.1.5   root     3915:         default:
                   3916:             goto die;
1.1.1.6   root     3917:         }
1.1.1.5   root     3918:         break;
                   3919:     case 6:
                   3920:         switch (sel) {
                   3921:         case 0:
1.1.1.8   root     3922:             gen_helper_mtc0_wired(arg);
1.1.1.6   root     3923:             rn = "Wired";
                   3924:             break;
                   3925:         case 1:
                   3926:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3927:             gen_helper_mtc0_srsconf0(arg);
1.1.1.6   root     3928:             rn = "SRSConf0";
                   3929:             break;
                   3930:         case 2:
                   3931:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3932:             gen_helper_mtc0_srsconf1(arg);
1.1.1.6   root     3933:             rn = "SRSConf1";
                   3934:             break;
1.1.1.5   root     3935:         case 3:
1.1.1.6   root     3936:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3937:             gen_helper_mtc0_srsconf2(arg);
1.1.1.6   root     3938:             rn = "SRSConf2";
                   3939:             break;
1.1.1.5   root     3940:         case 4:
1.1.1.6   root     3941:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3942:             gen_helper_mtc0_srsconf3(arg);
1.1.1.6   root     3943:             rn = "SRSConf3";
                   3944:             break;
1.1.1.5   root     3945:         case 5:
1.1.1.6   root     3946:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3947:             gen_helper_mtc0_srsconf4(arg);
1.1.1.6   root     3948:             rn = "SRSConf4";
                   3949:             break;
1.1.1.5   root     3950:         default:
                   3951:             goto die;
1.1.1.6   root     3952:         }
1.1.1.5   root     3953:         break;
                   3954:     case 7:
                   3955:         switch (sel) {
                   3956:         case 0:
1.1.1.6   root     3957:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3958:             gen_helper_mtc0_hwrena(arg);
1.1.1.6   root     3959:             rn = "HWREna";
                   3960:             break;
1.1.1.5   root     3961:         default:
                   3962:             goto die;
1.1.1.6   root     3963:         }
1.1.1.5   root     3964:         break;
                   3965:     case 8:
                   3966:         /* ignored */
1.1.1.7   root     3967:         rn = "BadVAddr";
1.1.1.5   root     3968:         break;
                   3969:     case 9:
                   3970:         switch (sel) {
                   3971:         case 0:
1.1.1.8   root     3972:             gen_helper_mtc0_count(arg);
1.1.1.6   root     3973:             rn = "Count";
                   3974:             break;
                   3975:         /* 6,7 are implementation dependent */
1.1.1.5   root     3976:         default:
                   3977:             goto die;
1.1.1.6   root     3978:         }
1.1.1.5   root     3979:         break;
                   3980:     case 10:
                   3981:         switch (sel) {
                   3982:         case 0:
1.1.1.8   root     3983:             gen_helper_mtc0_entryhi(arg);
1.1.1.6   root     3984:             rn = "EntryHi";
                   3985:             break;
1.1.1.5   root     3986:         default:
                   3987:             goto die;
1.1.1.6   root     3988:         }
1.1.1.5   root     3989:         break;
                   3990:     case 11:
                   3991:         switch (sel) {
                   3992:         case 0:
1.1.1.8   root     3993:             gen_helper_mtc0_compare(arg);
1.1.1.6   root     3994:             rn = "Compare";
                   3995:             break;
                   3996:         /* 6,7 are implementation dependent */
1.1.1.5   root     3997:         default:
                   3998:             goto die;
1.1.1.6   root     3999:         }
1.1.1.5   root     4000:         break;
                   4001:     case 12:
                   4002:         switch (sel) {
                   4003:         case 0:
1.1.1.8   root     4004:             save_cpu_state(ctx, 1);
                   4005:             gen_helper_mtc0_status(arg);
1.1.1.6   root     4006:             /* BS_STOP isn't good enough here, hflags may have changed. */
                   4007:             gen_save_pc(ctx->pc + 4);
                   4008:             ctx->bstate = BS_EXCP;
                   4009:             rn = "Status";
                   4010:             break;
                   4011:         case 1:
                   4012:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4013:             gen_helper_mtc0_intctl(arg);
1.1.1.6   root     4014:             /* Stop translation as we may have switched the execution mode */
                   4015:             ctx->bstate = BS_STOP;
                   4016:             rn = "IntCtl";
                   4017:             break;
                   4018:         case 2:
                   4019:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4020:             gen_helper_mtc0_srsctl(arg);
1.1.1.6   root     4021:             /* Stop translation as we may have switched the execution mode */
                   4022:             ctx->bstate = BS_STOP;
                   4023:             rn = "SRSCtl";
                   4024:             break;
1.1.1.5   root     4025:         case 3:
1.1.1.6   root     4026:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.16! root     4027:             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
1.1.1.6   root     4028:             /* Stop translation as we may have switched the execution mode */
                   4029:             ctx->bstate = BS_STOP;
                   4030:             rn = "SRSMap";
                   4031:             break;
1.1.1.5   root     4032:         default:
                   4033:             goto die;
1.1.1.6   root     4034:         }
1.1.1.5   root     4035:         break;
                   4036:     case 13:
                   4037:         switch (sel) {
                   4038:         case 0:
1.1.1.8   root     4039:             save_cpu_state(ctx, 1);
                   4040:             gen_helper_mtc0_cause(arg);
1.1.1.6   root     4041:             rn = "Cause";
                   4042:             break;
1.1.1.5   root     4043:         default:
                   4044:             goto die;
1.1.1.6   root     4045:         }
1.1.1.5   root     4046:         break;
                   4047:     case 14:
                   4048:         switch (sel) {
                   4049:         case 0:
1.1.1.16! root     4050:             gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_EPC));
1.1.1.6   root     4051:             rn = "EPC";
                   4052:             break;
1.1.1.5   root     4053:         default:
                   4054:             goto die;
1.1.1.6   root     4055:         }
1.1.1.5   root     4056:         break;
                   4057:     case 15:
                   4058:         switch (sel) {
                   4059:         case 0:
1.1.1.6   root     4060:             /* ignored */
                   4061:             rn = "PRid";
                   4062:             break;
                   4063:         case 1:
                   4064:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4065:             gen_helper_mtc0_ebase(arg);
1.1.1.6   root     4066:             rn = "EBase";
                   4067:             break;
1.1.1.5   root     4068:         default:
                   4069:             goto die;
1.1.1.6   root     4070:         }
1.1.1.5   root     4071:         break;
                   4072:     case 16:
                   4073:         switch (sel) {
                   4074:         case 0:
1.1.1.8   root     4075:             gen_helper_mtc0_config0(arg);
1.1.1.5   root     4076:             rn = "Config";
1.1.1.6   root     4077:             /* Stop translation as we may have switched the execution mode */
                   4078:             ctx->bstate = BS_STOP;
1.1.1.5   root     4079:             break;
                   4080:         case 1:
1.1.1.6   root     4081:             /* ignored, read only */
1.1.1.5   root     4082:             rn = "Config1";
                   4083:             break;
                   4084:         case 2:
1.1.1.8   root     4085:             gen_helper_mtc0_config2(arg);
1.1.1.5   root     4086:             rn = "Config2";
1.1.1.6   root     4087:             /* Stop translation as we may have switched the execution mode */
                   4088:             ctx->bstate = BS_STOP;
1.1.1.5   root     4089:             break;
                   4090:         case 3:
1.1.1.6   root     4091:             /* ignored, read only */
1.1.1.5   root     4092:             rn = "Config3";
                   4093:             break;
1.1.1.6   root     4094:         /* 4,5 are reserved */
                   4095:         /* 6,7 are implementation dependent */
                   4096:         case 6:
                   4097:             /* ignored */
                   4098:             rn = "Config6";
                   4099:             break;
                   4100:         case 7:
                   4101:             /* ignored */
                   4102:             rn = "Config7";
                   4103:             break;
1.1.1.5   root     4104:         default:
                   4105:             rn = "Invalid config selector";
                   4106:             goto die;
                   4107:         }
                   4108:         break;
                   4109:     case 17:
                   4110:         switch (sel) {
                   4111:         case 0:
1.1.1.9   root     4112:             gen_helper_mtc0_lladdr(arg);
1.1.1.6   root     4113:             rn = "LLAddr";
                   4114:             break;
1.1.1.5   root     4115:         default:
                   4116:             goto die;
                   4117:         }
                   4118:         break;
                   4119:     case 18:
                   4120:         switch (sel) {
1.1.1.6   root     4121:         case 0 ... 7:
1.1.1.8   root     4122:             gen_helper_1i(mtc0_watchlo, arg, sel);
1.1.1.6   root     4123:             rn = "WatchLo";
                   4124:             break;
1.1.1.5   root     4125:         default:
                   4126:             goto die;
                   4127:         }
                   4128:         break;
                   4129:     case 19:
                   4130:         switch (sel) {
1.1.1.6   root     4131:         case 0 ... 7:
1.1.1.8   root     4132:             gen_helper_1i(mtc0_watchhi, arg, sel);
1.1.1.6   root     4133:             rn = "WatchHi";
                   4134:             break;
1.1.1.5   root     4135:         default:
                   4136:             goto die;
                   4137:         }
                   4138:         break;
                   4139:     case 20:
                   4140:         switch (sel) {
                   4141:         case 0:
1.1.1.6   root     4142: #if defined(TARGET_MIPS64)
                   4143:             check_insn(env, ctx, ISA_MIPS3);
1.1.1.8   root     4144:             gen_helper_mtc0_xcontext(arg);
1.1.1.6   root     4145:             rn = "XContext";
                   4146:             break;
                   4147: #endif
1.1.1.5   root     4148:         default:
                   4149:             goto die;
                   4150:         }
                   4151:         break;
                   4152:     case 21:
                   4153:        /* Officially reserved, but sel 0 is used for R1x000 framemask */
                   4154:         switch (sel) {
                   4155:         case 0:
1.1.1.8   root     4156:             gen_helper_mtc0_framemask(arg);
1.1.1.6   root     4157:             rn = "Framemask";
                   4158:             break;
1.1.1.5   root     4159:         default:
                   4160:             goto die;
                   4161:         }
                   4162:         break;
                   4163:     case 22:
                   4164:         /* ignored */
                   4165:         rn = "Diagnostic"; /* implementation dependent */
1.1.1.6   root     4166:         break;
1.1.1.5   root     4167:     case 23:
                   4168:         switch (sel) {
                   4169:         case 0:
1.1.1.8   root     4170:             gen_helper_mtc0_debug(arg); /* EJTAG support */
1.1.1.6   root     4171:             /* BS_STOP isn't good enough here, hflags may have changed. */
                   4172:             gen_save_pc(ctx->pc + 4);
                   4173:             ctx->bstate = BS_EXCP;
                   4174:             rn = "Debug";
                   4175:             break;
                   4176:         case 1:
1.1.1.8   root     4177: //            gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
1.1.1.6   root     4178:             rn = "TraceControl";
                   4179:             /* Stop translation as we may have switched the execution mode */
                   4180:             ctx->bstate = BS_STOP;
                   4181: //            break;
                   4182:         case 2:
1.1.1.8   root     4183: //            gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
1.1.1.6   root     4184:             rn = "TraceControl2";
                   4185:             /* Stop translation as we may have switched the execution mode */
                   4186:             ctx->bstate = BS_STOP;
                   4187: //            break;
                   4188:         case 3:
                   4189:             /* Stop translation as we may have switched the execution mode */
                   4190:             ctx->bstate = BS_STOP;
1.1.1.8   root     4191: //            gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
1.1.1.6   root     4192:             rn = "UserTraceData";
                   4193:             /* Stop translation as we may have switched the execution mode */
                   4194:             ctx->bstate = BS_STOP;
                   4195: //            break;
1.1.1.5   root     4196:         case 4:
1.1.1.8   root     4197: //            gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
1.1.1.6   root     4198:             /* Stop translation as we may have switched the execution mode */
                   4199:             ctx->bstate = BS_STOP;
                   4200:             rn = "TraceBPC";
                   4201: //            break;
1.1.1.5   root     4202:         default:
                   4203:             goto die;
                   4204:         }
                   4205:         break;
                   4206:     case 24:
                   4207:         switch (sel) {
                   4208:         case 0:
1.1.1.7   root     4209:             /* EJTAG support */
1.1.1.16! root     4210:             gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_DEPC));
1.1.1.6   root     4211:             rn = "DEPC";
                   4212:             break;
1.1.1.5   root     4213:         default:
                   4214:             goto die;
                   4215:         }
                   4216:         break;
                   4217:     case 25:
                   4218:         switch (sel) {
                   4219:         case 0:
1.1.1.8   root     4220:             gen_helper_mtc0_performance0(arg);
1.1.1.6   root     4221:             rn = "Performance0";
                   4222:             break;
                   4223:         case 1:
1.1.1.8   root     4224: //            gen_helper_mtc0_performance1(arg);
1.1.1.6   root     4225:             rn = "Performance1";
                   4226: //            break;
                   4227:         case 2:
1.1.1.8   root     4228: //            gen_helper_mtc0_performance2(arg);
1.1.1.6   root     4229:             rn = "Performance2";
                   4230: //            break;
                   4231:         case 3:
1.1.1.8   root     4232: //            gen_helper_mtc0_performance3(arg);
1.1.1.6   root     4233:             rn = "Performance3";
                   4234: //            break;
1.1.1.5   root     4235:         case 4:
1.1.1.8   root     4236: //            gen_helper_mtc0_performance4(arg);
1.1.1.6   root     4237:             rn = "Performance4";
                   4238: //            break;
1.1.1.5   root     4239:         case 5:
1.1.1.8   root     4240: //            gen_helper_mtc0_performance5(arg);
1.1.1.6   root     4241:             rn = "Performance5";
                   4242: //            break;
1.1.1.5   root     4243:         case 6:
1.1.1.8   root     4244: //            gen_helper_mtc0_performance6(arg);
1.1.1.6   root     4245:             rn = "Performance6";
                   4246: //            break;
1.1.1.5   root     4247:         case 7:
1.1.1.8   root     4248: //            gen_helper_mtc0_performance7(arg);
1.1.1.6   root     4249:             rn = "Performance7";
                   4250: //            break;
1.1.1.5   root     4251:         default:
                   4252:             goto die;
                   4253:         }
                   4254:        break;
                   4255:     case 26:
1.1.1.6   root     4256:         /* ignored */
1.1.1.5   root     4257:         rn = "ECC";
1.1.1.6   root     4258:         break;
1.1.1.5   root     4259:     case 27:
                   4260:         switch (sel) {
                   4261:         case 0 ... 3:
1.1.1.6   root     4262:             /* ignored */
                   4263:             rn = "CacheErr";
                   4264:             break;
1.1.1.5   root     4265:         default:
                   4266:             goto die;
                   4267:         }
                   4268:        break;
                   4269:     case 28:
                   4270:         switch (sel) {
                   4271:         case 0:
                   4272:         case 2:
                   4273:         case 4:
                   4274:         case 6:
1.1.1.8   root     4275:             gen_helper_mtc0_taglo(arg);
1.1.1.5   root     4276:             rn = "TagLo";
                   4277:             break;
                   4278:         case 1:
                   4279:         case 3:
                   4280:         case 5:
                   4281:         case 7:
1.1.1.8   root     4282:             gen_helper_mtc0_datalo(arg);
1.1.1.5   root     4283:             rn = "DataLo";
                   4284:             break;
                   4285:         default:
                   4286:             goto die;
                   4287:         }
                   4288:         break;
                   4289:     case 29:
                   4290:         switch (sel) {
                   4291:         case 0:
                   4292:         case 2:
                   4293:         case 4:
                   4294:         case 6:
1.1.1.8   root     4295:             gen_helper_mtc0_taghi(arg);
1.1.1.5   root     4296:             rn = "TagHi";
                   4297:             break;
                   4298:         case 1:
                   4299:         case 3:
                   4300:         case 5:
                   4301:         case 7:
1.1.1.8   root     4302:             gen_helper_mtc0_datahi(arg);
1.1.1.5   root     4303:             rn = "DataHi";
                   4304:             break;
                   4305:         default:
                   4306:             rn = "invalid sel";
                   4307:             goto die;
                   4308:         }
                   4309:        break;
                   4310:     case 30:
                   4311:         switch (sel) {
                   4312:         case 0:
1.1.1.16! root     4313:             gen_mtc0_store64(arg, offsetof(CPUMIPSState, CP0_ErrorEPC));
1.1.1.6   root     4314:             rn = "ErrorEPC";
                   4315:             break;
1.1.1.5   root     4316:         default:
                   4317:             goto die;
                   4318:         }
                   4319:         break;
                   4320:     case 31:
                   4321:         switch (sel) {
                   4322:         case 0:
1.1.1.7   root     4323:             /* EJTAG support */
1.1.1.16! root     4324:             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
1.1.1.6   root     4325:             rn = "DESAVE";
                   4326:             break;
1.1.1.5   root     4327:         default:
                   4328:             goto die;
                   4329:         }
1.1.1.6   root     4330:         /* Stop translation as we may have switched the execution mode */
                   4331:         ctx->bstate = BS_STOP;
1.1.1.5   root     4332:         break;
                   4333:     default:
                   4334:        goto die;
                   4335:     }
1.1.1.13  root     4336:     (void)rn; /* avoid a compiler warning */
1.1.1.7   root     4337:     LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
                   4338:     /* For simplicity assume that all writes can cause interrupts.  */
                   4339:     if (use_icount) {
                   4340:         gen_io_end();
                   4341:         ctx->bstate = BS_STOP;
1.1.1.5   root     4342:     }
                   4343:     return;
                   4344: 
                   4345: die:
1.1.1.7   root     4346:     LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
1.1.1.5   root     4347:     generate_exception(ctx, EXCP_RI);
                   4348: }
                   4349: 
1.1.1.6   root     4350: #if defined(TARGET_MIPS64)
1.1.1.16! root     4351: static void gen_dmfc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
1.1.1.5   root     4352: {
                   4353:     const char *rn = "invalid";
                   4354: 
1.1.1.6   root     4355:     if (sel != 0)
                   4356:         check_insn(env, ctx, ISA_MIPS64);
                   4357: 
1.1.1.5   root     4358:     switch (reg) {
                   4359:     case 0:
                   4360:         switch (sel) {
                   4361:         case 0:
1.1.1.16! root     4362:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Index));
1.1.1.5   root     4363:             rn = "Index";
                   4364:             break;
                   4365:         case 1:
1.1.1.6   root     4366:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4367:             gen_helper_mfc0_mvpcontrol(arg);
1.1.1.5   root     4368:             rn = "MVPControl";
1.1.1.6   root     4369:             break;
1.1.1.5   root     4370:         case 2:
1.1.1.6   root     4371:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4372:             gen_helper_mfc0_mvpconf0(arg);
1.1.1.5   root     4373:             rn = "MVPConf0";
1.1.1.6   root     4374:             break;
1.1.1.5   root     4375:         case 3:
1.1.1.6   root     4376:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4377:             gen_helper_mfc0_mvpconf1(arg);
1.1.1.5   root     4378:             rn = "MVPConf1";
1.1.1.6   root     4379:             break;
1.1.1.5   root     4380:         default:
                   4381:             goto die;
                   4382:         }
                   4383:         break;
                   4384:     case 1:
                   4385:         switch (sel) {
                   4386:         case 0:
1.1.1.8   root     4387:             gen_helper_mfc0_random(arg);
1.1.1.5   root     4388:             rn = "Random";
1.1.1.6   root     4389:             break;
1.1.1.5   root     4390:         case 1:
1.1.1.6   root     4391:             check_insn(env, ctx, ASE_MT);
1.1.1.16! root     4392:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEControl));
1.1.1.5   root     4393:             rn = "VPEControl";
1.1.1.6   root     4394:             break;
1.1.1.5   root     4395:         case 2:
1.1.1.6   root     4396:             check_insn(env, ctx, ASE_MT);
1.1.1.16! root     4397:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf0));
1.1.1.5   root     4398:             rn = "VPEConf0";
1.1.1.6   root     4399:             break;
1.1.1.5   root     4400:         case 3:
1.1.1.6   root     4401:             check_insn(env, ctx, ASE_MT);
1.1.1.16! root     4402:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEConf1));
1.1.1.5   root     4403:             rn = "VPEConf1";
1.1.1.6   root     4404:             break;
1.1.1.5   root     4405:         case 4:
1.1.1.6   root     4406:             check_insn(env, ctx, ASE_MT);
1.1.1.16! root     4407:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_YQMask));
1.1.1.5   root     4408:             rn = "YQMask";
1.1.1.6   root     4409:             break;
1.1.1.5   root     4410:         case 5:
1.1.1.6   root     4411:             check_insn(env, ctx, ASE_MT);
1.1.1.16! root     4412:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
1.1.1.5   root     4413:             rn = "VPESchedule";
1.1.1.6   root     4414:             break;
1.1.1.5   root     4415:         case 6:
1.1.1.6   root     4416:             check_insn(env, ctx, ASE_MT);
1.1.1.16! root     4417:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
1.1.1.5   root     4418:             rn = "VPEScheFBack";
1.1.1.6   root     4419:             break;
1.1.1.5   root     4420:         case 7:
1.1.1.6   root     4421:             check_insn(env, ctx, ASE_MT);
1.1.1.16! root     4422:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_VPEOpt));
1.1.1.5   root     4423:             rn = "VPEOpt";
1.1.1.6   root     4424:             break;
1.1.1.5   root     4425:         default:
                   4426:             goto die;
                   4427:         }
                   4428:         break;
                   4429:     case 2:
                   4430:         switch (sel) {
                   4431:         case 0:
1.1.1.16! root     4432:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo0));
1.1.1.6   root     4433:             rn = "EntryLo0";
                   4434:             break;
                   4435:         case 1:
                   4436:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4437:             gen_helper_mfc0_tcstatus(arg);
1.1.1.6   root     4438:             rn = "TCStatus";
                   4439:             break;
                   4440:         case 2:
                   4441:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4442:             gen_helper_mfc0_tcbind(arg);
1.1.1.6   root     4443:             rn = "TCBind";
                   4444:             break;
1.1.1.5   root     4445:         case 3:
1.1.1.6   root     4446:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4447:             gen_helper_dmfc0_tcrestart(arg);
1.1.1.6   root     4448:             rn = "TCRestart";
                   4449:             break;
1.1.1.5   root     4450:         case 4:
1.1.1.6   root     4451:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4452:             gen_helper_dmfc0_tchalt(arg);
1.1.1.6   root     4453:             rn = "TCHalt";
                   4454:             break;
1.1.1.5   root     4455:         case 5:
1.1.1.6   root     4456:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4457:             gen_helper_dmfc0_tccontext(arg);
1.1.1.6   root     4458:             rn = "TCContext";
                   4459:             break;
1.1.1.5   root     4460:         case 6:
1.1.1.6   root     4461:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4462:             gen_helper_dmfc0_tcschedule(arg);
1.1.1.6   root     4463:             rn = "TCSchedule";
                   4464:             break;
1.1.1.5   root     4465:         case 7:
1.1.1.6   root     4466:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4467:             gen_helper_dmfc0_tcschefback(arg);
1.1.1.6   root     4468:             rn = "TCScheFBack";
                   4469:             break;
1.1.1.5   root     4470:         default:
                   4471:             goto die;
                   4472:         }
                   4473:         break;
                   4474:     case 3:
                   4475:         switch (sel) {
                   4476:         case 0:
1.1.1.16! root     4477:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryLo1));
1.1.1.6   root     4478:             rn = "EntryLo1";
                   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 4:
                   4485:         switch (sel) {
                   4486:         case 0:
1.1.1.16! root     4487:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_Context));
1.1.1.6   root     4488:             rn = "Context";
                   4489:             break;
                   4490:         case 1:
1.1.1.8   root     4491: //            gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
1.1.1.6   root     4492:             rn = "ContextConfig";
                   4493: //            break;
1.1.1.5   root     4494:         default:
                   4495:             goto die;
1.1.1.6   root     4496:         }
1.1.1.5   root     4497:         break;
                   4498:     case 5:
                   4499:         switch (sel) {
                   4500:         case 0:
1.1.1.16! root     4501:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageMask));
1.1.1.6   root     4502:             rn = "PageMask";
                   4503:             break;
                   4504:         case 1:
                   4505:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.16! root     4506:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PageGrain));
1.1.1.6   root     4507:             rn = "PageGrain";
                   4508:             break;
1.1.1.5   root     4509:         default:
                   4510:             goto die;
1.1.1.6   root     4511:         }
1.1.1.5   root     4512:         break;
                   4513:     case 6:
                   4514:         switch (sel) {
                   4515:         case 0:
1.1.1.16! root     4516:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Wired));
1.1.1.6   root     4517:             rn = "Wired";
                   4518:             break;
                   4519:         case 1:
                   4520:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.16! root     4521:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf0));
1.1.1.6   root     4522:             rn = "SRSConf0";
                   4523:             break;
                   4524:         case 2:
                   4525:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.16! root     4526:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf1));
1.1.1.6   root     4527:             rn = "SRSConf1";
                   4528:             break;
1.1.1.5   root     4529:         case 3:
1.1.1.6   root     4530:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.16! root     4531:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf2));
1.1.1.6   root     4532:             rn = "SRSConf2";
                   4533:             break;
1.1.1.5   root     4534:         case 4:
1.1.1.6   root     4535:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.16! root     4536:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf3));
1.1.1.6   root     4537:             rn = "SRSConf3";
                   4538:             break;
1.1.1.5   root     4539:         case 5:
1.1.1.6   root     4540:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.16! root     4541:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSConf4));
1.1.1.6   root     4542:             rn = "SRSConf4";
                   4543:             break;
1.1.1.5   root     4544:         default:
                   4545:             goto die;
1.1.1.6   root     4546:         }
1.1.1.5   root     4547:         break;
                   4548:     case 7:
                   4549:         switch (sel) {
                   4550:         case 0:
1.1.1.6   root     4551:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.16! root     4552:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_HWREna));
1.1.1.6   root     4553:             rn = "HWREna";
                   4554:             break;
1.1.1.5   root     4555:         default:
                   4556:             goto die;
1.1.1.6   root     4557:         }
1.1.1.5   root     4558:         break;
                   4559:     case 8:
                   4560:         switch (sel) {
                   4561:         case 0:
1.1.1.16! root     4562:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_BadVAddr));
1.1.1.7   root     4563:             rn = "BadVAddr";
1.1.1.6   root     4564:             break;
1.1.1.5   root     4565:         default:
                   4566:             goto die;
1.1.1.6   root     4567:         }
1.1.1.5   root     4568:         break;
                   4569:     case 9:
                   4570:         switch (sel) {
                   4571:         case 0:
1.1.1.7   root     4572:             /* Mark as an IO operation because we read the time.  */
                   4573:             if (use_icount)
                   4574:                 gen_io_start();
1.1.1.8   root     4575:             gen_helper_mfc0_count(arg);
1.1.1.7   root     4576:             if (use_icount) {
                   4577:                 gen_io_end();
                   4578:             }
1.1.1.13  root     4579:             /* Break the TB to be able to take timer interrupts immediately
                   4580:                after reading count.  */
                   4581:             ctx->bstate = BS_STOP;
1.1.1.6   root     4582:             rn = "Count";
                   4583:             break;
                   4584:         /* 6,7 are implementation dependent */
1.1.1.5   root     4585:         default:
                   4586:             goto die;
1.1.1.6   root     4587:         }
1.1.1.5   root     4588:         break;
                   4589:     case 10:
                   4590:         switch (sel) {
                   4591:         case 0:
1.1.1.16! root     4592:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EntryHi));
1.1.1.6   root     4593:             rn = "EntryHi";
                   4594:             break;
1.1.1.5   root     4595:         default:
                   4596:             goto die;
1.1.1.6   root     4597:         }
1.1.1.5   root     4598:         break;
                   4599:     case 11:
                   4600:         switch (sel) {
                   4601:         case 0:
1.1.1.16! root     4602:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Compare));
1.1.1.6   root     4603:             rn = "Compare";
                   4604:             break;
                   4605:         /* 6,7 are implementation dependent */
1.1.1.5   root     4606:         default:
                   4607:             goto die;
1.1.1.6   root     4608:         }
1.1.1.5   root     4609:         break;
                   4610:     case 12:
                   4611:         switch (sel) {
                   4612:         case 0:
1.1.1.16! root     4613:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Status));
1.1.1.6   root     4614:             rn = "Status";
                   4615:             break;
                   4616:         case 1:
                   4617:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.16! root     4618:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_IntCtl));
1.1.1.6   root     4619:             rn = "IntCtl";
                   4620:             break;
                   4621:         case 2:
                   4622:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.16! root     4623:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSCtl));
1.1.1.6   root     4624:             rn = "SRSCtl";
                   4625:             break;
1.1.1.5   root     4626:         case 3:
1.1.1.6   root     4627:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.16! root     4628:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
1.1.1.6   root     4629:             rn = "SRSMap";
                   4630:             break;
1.1.1.5   root     4631:         default:
                   4632:             goto die;
1.1.1.6   root     4633:         }
1.1.1.5   root     4634:         break;
                   4635:     case 13:
                   4636:         switch (sel) {
                   4637:         case 0:
1.1.1.16! root     4638:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Cause));
1.1.1.6   root     4639:             rn = "Cause";
                   4640:             break;
1.1.1.5   root     4641:         default:
                   4642:             goto die;
1.1.1.6   root     4643:         }
1.1.1.5   root     4644:         break;
                   4645:     case 14:
                   4646:         switch (sel) {
                   4647:         case 0:
1.1.1.16! root     4648:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
1.1.1.6   root     4649:             rn = "EPC";
                   4650:             break;
1.1.1.5   root     4651:         default:
                   4652:             goto die;
1.1.1.6   root     4653:         }
1.1.1.5   root     4654:         break;
                   4655:     case 15:
                   4656:         switch (sel) {
                   4657:         case 0:
1.1.1.16! root     4658:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_PRid));
1.1.1.6   root     4659:             rn = "PRid";
                   4660:             break;
                   4661:         case 1:
                   4662:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.16! root     4663:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_EBase));
1.1.1.6   root     4664:             rn = "EBase";
                   4665:             break;
1.1.1.5   root     4666:         default:
                   4667:             goto die;
1.1.1.6   root     4668:         }
1.1.1.5   root     4669:         break;
                   4670:     case 16:
                   4671:         switch (sel) {
                   4672:         case 0:
1.1.1.16! root     4673:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config0));
1.1.1.5   root     4674:             rn = "Config";
                   4675:             break;
                   4676:         case 1:
1.1.1.16! root     4677:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config1));
1.1.1.5   root     4678:             rn = "Config1";
                   4679:             break;
                   4680:         case 2:
1.1.1.16! root     4681:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config2));
1.1.1.5   root     4682:             rn = "Config2";
                   4683:             break;
                   4684:         case 3:
1.1.1.16! root     4685:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config3));
1.1.1.5   root     4686:             rn = "Config3";
                   4687:             break;
                   4688:        /* 6,7 are implementation dependent */
1.1.1.7   root     4689:         case 6:
1.1.1.16! root     4690:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config6));
1.1.1.7   root     4691:             rn = "Config6";
                   4692:             break;
                   4693:         case 7:
1.1.1.16! root     4694:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Config7));
1.1.1.7   root     4695:             rn = "Config7";
                   4696:             break;
1.1.1.5   root     4697:         default:
                   4698:             goto die;
                   4699:         }
                   4700:         break;
                   4701:     case 17:
                   4702:         switch (sel) {
                   4703:         case 0:
1.1.1.8   root     4704:             gen_helper_dmfc0_lladdr(arg);
1.1.1.6   root     4705:             rn = "LLAddr";
                   4706:             break;
1.1.1.5   root     4707:         default:
                   4708:             goto die;
                   4709:         }
                   4710:         break;
                   4711:     case 18:
                   4712:         switch (sel) {
1.1.1.6   root     4713:         case 0 ... 7:
1.1.1.8   root     4714:             gen_helper_1i(dmfc0_watchlo, arg, sel);
1.1.1.6   root     4715:             rn = "WatchLo";
                   4716:             break;
1.1.1.5   root     4717:         default:
                   4718:             goto die;
                   4719:         }
                   4720:         break;
                   4721:     case 19:
                   4722:         switch (sel) {
1.1.1.6   root     4723:         case 0 ... 7:
1.1.1.8   root     4724:             gen_helper_1i(mfc0_watchhi, arg, sel);
1.1.1.6   root     4725:             rn = "WatchHi";
                   4726:             break;
1.1.1.5   root     4727:         default:
                   4728:             goto die;
                   4729:         }
                   4730:         break;
                   4731:     case 20:
                   4732:         switch (sel) {
                   4733:         case 0:
1.1.1.6   root     4734:             check_insn(env, ctx, ISA_MIPS3);
1.1.1.16! root     4735:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_XContext));
1.1.1.6   root     4736:             rn = "XContext";
                   4737:             break;
1.1.1.5   root     4738:         default:
                   4739:             goto die;
                   4740:         }
                   4741:         break;
                   4742:     case 21:
                   4743:        /* Officially reserved, but sel 0 is used for R1x000 framemask */
                   4744:         switch (sel) {
                   4745:         case 0:
1.1.1.16! root     4746:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Framemask));
1.1.1.6   root     4747:             rn = "Framemask";
                   4748:             break;
1.1.1.5   root     4749:         default:
                   4750:             goto die;
                   4751:         }
                   4752:         break;
                   4753:     case 22:
1.1.1.8   root     4754:         tcg_gen_movi_tl(arg, 0); /* unimplemented */
1.1.1.6   root     4755:         rn = "'Diagnostic"; /* implementation dependent */
                   4756:         break;
1.1.1.5   root     4757:     case 23:
                   4758:         switch (sel) {
                   4759:         case 0:
1.1.1.8   root     4760:             gen_helper_mfc0_debug(arg); /* EJTAG support */
1.1.1.6   root     4761:             rn = "Debug";
                   4762:             break;
                   4763:         case 1:
1.1.1.8   root     4764: //            gen_helper_dmfc0_tracecontrol(arg); /* PDtrace support */
1.1.1.6   root     4765:             rn = "TraceControl";
                   4766: //            break;
                   4767:         case 2:
1.1.1.8   root     4768: //            gen_helper_dmfc0_tracecontrol2(arg); /* PDtrace support */
1.1.1.6   root     4769:             rn = "TraceControl2";
                   4770: //            break;
1.1.1.5   root     4771:         case 3:
1.1.1.8   root     4772: //            gen_helper_dmfc0_usertracedata(arg); /* PDtrace support */
1.1.1.6   root     4773:             rn = "UserTraceData";
                   4774: //            break;
1.1.1.5   root     4775:         case 4:
1.1.1.8   root     4776: //            gen_helper_dmfc0_tracebpc(arg); /* PDtrace support */
1.1.1.6   root     4777:             rn = "TraceBPC";
                   4778: //            break;
1.1.1.5   root     4779:         default:
                   4780:             goto die;
                   4781:         }
                   4782:         break;
                   4783:     case 24:
                   4784:         switch (sel) {
                   4785:         case 0:
1.1.1.7   root     4786:             /* EJTAG support */
1.1.1.16! root     4787:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
1.1.1.6   root     4788:             rn = "DEPC";
                   4789:             break;
1.1.1.5   root     4790:         default:
                   4791:             goto die;
                   4792:         }
                   4793:         break;
                   4794:     case 25:
                   4795:         switch (sel) {
                   4796:         case 0:
1.1.1.16! root     4797:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_Performance0));
1.1.1.6   root     4798:             rn = "Performance0";
1.1.1.5   root     4799:             break;
                   4800:         case 1:
1.1.1.8   root     4801: //            gen_helper_dmfc0_performance1(arg);
1.1.1.6   root     4802:             rn = "Performance1";
                   4803: //            break;
1.1.1.5   root     4804:         case 2:
1.1.1.8   root     4805: //            gen_helper_dmfc0_performance2(arg);
1.1.1.6   root     4806:             rn = "Performance2";
                   4807: //            break;
1.1.1.5   root     4808:         case 3:
1.1.1.8   root     4809: //            gen_helper_dmfc0_performance3(arg);
1.1.1.6   root     4810:             rn = "Performance3";
                   4811: //            break;
1.1.1.5   root     4812:         case 4:
1.1.1.8   root     4813: //            gen_helper_dmfc0_performance4(arg);
1.1.1.6   root     4814:             rn = "Performance4";
                   4815: //            break;
1.1.1.5   root     4816:         case 5:
1.1.1.8   root     4817: //            gen_helper_dmfc0_performance5(arg);
1.1.1.6   root     4818:             rn = "Performance5";
                   4819: //            break;
1.1.1.5   root     4820:         case 6:
1.1.1.8   root     4821: //            gen_helper_dmfc0_performance6(arg);
1.1.1.6   root     4822:             rn = "Performance6";
                   4823: //            break;
1.1.1.5   root     4824:         case 7:
1.1.1.8   root     4825: //            gen_helper_dmfc0_performance7(arg);
1.1.1.6   root     4826:             rn = "Performance7";
                   4827: //            break;
1.1.1.5   root     4828:         default:
                   4829:             goto die;
                   4830:         }
                   4831:         break;
                   4832:     case 26:
1.1.1.8   root     4833:         tcg_gen_movi_tl(arg, 0); /* unimplemented */
1.1.1.7   root     4834:         rn = "ECC";
                   4835:         break;
1.1.1.5   root     4836:     case 27:
                   4837:         switch (sel) {
                   4838:         /* ignored */
                   4839:         case 0 ... 3:
1.1.1.8   root     4840:             tcg_gen_movi_tl(arg, 0); /* unimplemented */
1.1.1.6   root     4841:             rn = "CacheErr";
                   4842:             break;
1.1.1.5   root     4843:         default:
                   4844:             goto die;
                   4845:         }
                   4846:         break;
                   4847:     case 28:
                   4848:         switch (sel) {
                   4849:         case 0:
                   4850:         case 2:
                   4851:         case 4:
                   4852:         case 6:
1.1.1.16! root     4853:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagLo));
1.1.1.5   root     4854:             rn = "TagLo";
                   4855:             break;
                   4856:         case 1:
                   4857:         case 3:
                   4858:         case 5:
                   4859:         case 7:
1.1.1.16! root     4860:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataLo));
1.1.1.5   root     4861:             rn = "DataLo";
                   4862:             break;
                   4863:         default:
                   4864:             goto die;
                   4865:         }
                   4866:         break;
                   4867:     case 29:
                   4868:         switch (sel) {
                   4869:         case 0:
                   4870:         case 2:
                   4871:         case 4:
                   4872:         case 6:
1.1.1.16! root     4873:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_TagHi));
1.1.1.5   root     4874:             rn = "TagHi";
                   4875:             break;
                   4876:         case 1:
                   4877:         case 3:
                   4878:         case 5:
                   4879:         case 7:
1.1.1.16! root     4880:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DataHi));
1.1.1.5   root     4881:             rn = "DataHi";
                   4882:             break;
                   4883:         default:
                   4884:             goto die;
                   4885:         }
                   4886:         break;
                   4887:     case 30:
                   4888:         switch (sel) {
                   4889:         case 0:
1.1.1.16! root     4890:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
1.1.1.6   root     4891:             rn = "ErrorEPC";
                   4892:             break;
1.1.1.5   root     4893:         default:
                   4894:             goto die;
                   4895:         }
                   4896:         break;
                   4897:     case 31:
                   4898:         switch (sel) {
                   4899:         case 0:
1.1.1.7   root     4900:             /* EJTAG support */
1.1.1.16! root     4901:             gen_mfc0_load32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
1.1.1.6   root     4902:             rn = "DESAVE";
                   4903:             break;
1.1.1.5   root     4904:         default:
                   4905:             goto die;
                   4906:         }
                   4907:         break;
                   4908:     default:
1.1.1.6   root     4909:         goto die;
1.1.1.5   root     4910:     }
1.1.1.13  root     4911:     (void)rn; /* avoid a compiler warning */
1.1.1.7   root     4912:     LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
1.1.1.5   root     4913:     return;
                   4914: 
                   4915: die:
1.1.1.7   root     4916:     LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
1.1.1.5   root     4917:     generate_exception(ctx, EXCP_RI);
                   4918: }
                   4919: 
1.1.1.16! root     4920: static void gen_dmtc0 (CPUMIPSState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
1.1.1.5   root     4921: {
                   4922:     const char *rn = "invalid";
                   4923: 
1.1.1.6   root     4924:     if (sel != 0)
                   4925:         check_insn(env, ctx, ISA_MIPS64);
                   4926: 
1.1.1.7   root     4927:     if (use_icount)
                   4928:         gen_io_start();
                   4929: 
1.1.1.5   root     4930:     switch (reg) {
                   4931:     case 0:
                   4932:         switch (sel) {
                   4933:         case 0:
1.1.1.8   root     4934:             gen_helper_mtc0_index(arg);
1.1.1.5   root     4935:             rn = "Index";
                   4936:             break;
                   4937:         case 1:
1.1.1.6   root     4938:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4939:             gen_helper_mtc0_mvpcontrol(arg);
1.1.1.5   root     4940:             rn = "MVPControl";
1.1.1.6   root     4941:             break;
1.1.1.5   root     4942:         case 2:
1.1.1.6   root     4943:             check_insn(env, ctx, ASE_MT);
                   4944:             /* ignored */
1.1.1.5   root     4945:             rn = "MVPConf0";
1.1.1.6   root     4946:             break;
1.1.1.5   root     4947:         case 3:
1.1.1.6   root     4948:             check_insn(env, ctx, ASE_MT);
                   4949:             /* ignored */
1.1.1.5   root     4950:             rn = "MVPConf1";
1.1.1.6   root     4951:             break;
1.1.1.5   root     4952:         default:
                   4953:             goto die;
                   4954:         }
                   4955:         break;
                   4956:     case 1:
                   4957:         switch (sel) {
                   4958:         case 0:
1.1.1.6   root     4959:             /* ignored */
1.1.1.5   root     4960:             rn = "Random";
1.1.1.6   root     4961:             break;
1.1.1.5   root     4962:         case 1:
1.1.1.6   root     4963:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4964:             gen_helper_mtc0_vpecontrol(arg);
1.1.1.5   root     4965:             rn = "VPEControl";
1.1.1.6   root     4966:             break;
1.1.1.5   root     4967:         case 2:
1.1.1.6   root     4968:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4969:             gen_helper_mtc0_vpeconf0(arg);
1.1.1.5   root     4970:             rn = "VPEConf0";
1.1.1.6   root     4971:             break;
1.1.1.5   root     4972:         case 3:
1.1.1.6   root     4973:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4974:             gen_helper_mtc0_vpeconf1(arg);
1.1.1.5   root     4975:             rn = "VPEConf1";
1.1.1.6   root     4976:             break;
1.1.1.5   root     4977:         case 4:
1.1.1.6   root     4978:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4979:             gen_helper_mtc0_yqmask(arg);
1.1.1.5   root     4980:             rn = "YQMask";
1.1.1.6   root     4981:             break;
1.1.1.5   root     4982:         case 5:
1.1.1.6   root     4983:             check_insn(env, ctx, ASE_MT);
1.1.1.16! root     4984:             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPESchedule));
1.1.1.5   root     4985:             rn = "VPESchedule";
1.1.1.6   root     4986:             break;
1.1.1.5   root     4987:         case 6:
1.1.1.6   root     4988:             check_insn(env, ctx, ASE_MT);
1.1.1.16! root     4989:             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_VPEScheFBack));
1.1.1.5   root     4990:             rn = "VPEScheFBack";
1.1.1.6   root     4991:             break;
1.1.1.5   root     4992:         case 7:
1.1.1.6   root     4993:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4994:             gen_helper_mtc0_vpeopt(arg);
1.1.1.5   root     4995:             rn = "VPEOpt";
1.1.1.6   root     4996:             break;
1.1.1.5   root     4997:         default:
                   4998:             goto die;
                   4999:         }
                   5000:         break;
                   5001:     case 2:
                   5002:         switch (sel) {
                   5003:         case 0:
1.1.1.8   root     5004:             gen_helper_mtc0_entrylo0(arg);
1.1.1.6   root     5005:             rn = "EntryLo0";
                   5006:             break;
                   5007:         case 1:
                   5008:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     5009:             gen_helper_mtc0_tcstatus(arg);
1.1.1.6   root     5010:             rn = "TCStatus";
                   5011:             break;
                   5012:         case 2:
                   5013:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     5014:             gen_helper_mtc0_tcbind(arg);
1.1.1.6   root     5015:             rn = "TCBind";
                   5016:             break;
1.1.1.5   root     5017:         case 3:
1.1.1.6   root     5018:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     5019:             gen_helper_mtc0_tcrestart(arg);
1.1.1.6   root     5020:             rn = "TCRestart";
                   5021:             break;
1.1.1.5   root     5022:         case 4:
1.1.1.6   root     5023:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     5024:             gen_helper_mtc0_tchalt(arg);
1.1.1.6   root     5025:             rn = "TCHalt";
                   5026:             break;
1.1.1.5   root     5027:         case 5:
1.1.1.6   root     5028:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     5029:             gen_helper_mtc0_tccontext(arg);
1.1.1.6   root     5030:             rn = "TCContext";
                   5031:             break;
1.1.1.5   root     5032:         case 6:
1.1.1.6   root     5033:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     5034:             gen_helper_mtc0_tcschedule(arg);
1.1.1.6   root     5035:             rn = "TCSchedule";
                   5036:             break;
1.1.1.5   root     5037:         case 7:
1.1.1.6   root     5038:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     5039:             gen_helper_mtc0_tcschefback(arg);
1.1.1.6   root     5040:             rn = "TCScheFBack";
                   5041:             break;
1.1.1.5   root     5042:         default:
                   5043:             goto die;
                   5044:         }
                   5045:         break;
                   5046:     case 3:
                   5047:         switch (sel) {
                   5048:         case 0:
1.1.1.8   root     5049:             gen_helper_mtc0_entrylo1(arg);
1.1.1.6   root     5050:             rn = "EntryLo1";
                   5051:             break;
1.1.1.5   root     5052:         default:
                   5053:             goto die;
1.1.1.6   root     5054:         }
1.1.1.5   root     5055:         break;
                   5056:     case 4:
                   5057:         switch (sel) {
                   5058:         case 0:
1.1.1.8   root     5059:             gen_helper_mtc0_context(arg);
1.1.1.6   root     5060:             rn = "Context";
                   5061:             break;
                   5062:         case 1:
1.1.1.8   root     5063: //           gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
1.1.1.6   root     5064:             rn = "ContextConfig";
                   5065: //           break;
1.1.1.5   root     5066:         default:
                   5067:             goto die;
1.1.1.6   root     5068:         }
1.1.1.5   root     5069:         break;
                   5070:     case 5:
                   5071:         switch (sel) {
                   5072:         case 0:
1.1.1.8   root     5073:             gen_helper_mtc0_pagemask(arg);
1.1.1.6   root     5074:             rn = "PageMask";
                   5075:             break;
                   5076:         case 1:
                   5077:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5078:             gen_helper_mtc0_pagegrain(arg);
1.1.1.6   root     5079:             rn = "PageGrain";
                   5080:             break;
1.1.1.5   root     5081:         default:
                   5082:             goto die;
1.1.1.6   root     5083:         }
1.1.1.5   root     5084:         break;
                   5085:     case 6:
                   5086:         switch (sel) {
                   5087:         case 0:
1.1.1.8   root     5088:             gen_helper_mtc0_wired(arg);
1.1.1.6   root     5089:             rn = "Wired";
                   5090:             break;
                   5091:         case 1:
                   5092:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5093:             gen_helper_mtc0_srsconf0(arg);
1.1.1.6   root     5094:             rn = "SRSConf0";
                   5095:             break;
                   5096:         case 2:
                   5097:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5098:             gen_helper_mtc0_srsconf1(arg);
1.1.1.6   root     5099:             rn = "SRSConf1";
                   5100:             break;
1.1.1.5   root     5101:         case 3:
1.1.1.6   root     5102:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5103:             gen_helper_mtc0_srsconf2(arg);
1.1.1.6   root     5104:             rn = "SRSConf2";
                   5105:             break;
1.1.1.5   root     5106:         case 4:
1.1.1.6   root     5107:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5108:             gen_helper_mtc0_srsconf3(arg);
1.1.1.6   root     5109:             rn = "SRSConf3";
                   5110:             break;
1.1.1.5   root     5111:         case 5:
1.1.1.6   root     5112:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5113:             gen_helper_mtc0_srsconf4(arg);
1.1.1.6   root     5114:             rn = "SRSConf4";
                   5115:             break;
1.1.1.5   root     5116:         default:
                   5117:             goto die;
1.1.1.6   root     5118:         }
1.1.1.5   root     5119:         break;
                   5120:     case 7:
                   5121:         switch (sel) {
                   5122:         case 0:
1.1.1.6   root     5123:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5124:             gen_helper_mtc0_hwrena(arg);
1.1.1.6   root     5125:             rn = "HWREna";
                   5126:             break;
1.1.1.5   root     5127:         default:
                   5128:             goto die;
1.1.1.6   root     5129:         }
1.1.1.5   root     5130:         break;
                   5131:     case 8:
                   5132:         /* ignored */
1.1.1.7   root     5133:         rn = "BadVAddr";
1.1.1.5   root     5134:         break;
                   5135:     case 9:
                   5136:         switch (sel) {
                   5137:         case 0:
1.1.1.8   root     5138:             gen_helper_mtc0_count(arg);
1.1.1.6   root     5139:             rn = "Count";
                   5140:             break;
                   5141:         /* 6,7 are implementation dependent */
1.1.1.5   root     5142:         default:
                   5143:             goto die;
1.1.1.6   root     5144:         }
                   5145:         /* Stop translation as we may have switched the execution mode */
                   5146:         ctx->bstate = BS_STOP;
1.1.1.5   root     5147:         break;
                   5148:     case 10:
                   5149:         switch (sel) {
                   5150:         case 0:
1.1.1.8   root     5151:             gen_helper_mtc0_entryhi(arg);
1.1.1.6   root     5152:             rn = "EntryHi";
                   5153:             break;
1.1.1.5   root     5154:         default:
                   5155:             goto die;
1.1.1.6   root     5156:         }
1.1.1.5   root     5157:         break;
                   5158:     case 11:
                   5159:         switch (sel) {
                   5160:         case 0:
1.1.1.8   root     5161:             gen_helper_mtc0_compare(arg);
1.1.1.6   root     5162:             rn = "Compare";
                   5163:             break;
                   5164:         /* 6,7 are implementation dependent */
1.1.1.5   root     5165:         default:
                   5166:             goto die;
1.1.1.6   root     5167:         }
                   5168:         /* Stop translation as we may have switched the execution mode */
                   5169:         ctx->bstate = BS_STOP;
1.1.1.5   root     5170:         break;
                   5171:     case 12:
                   5172:         switch (sel) {
                   5173:         case 0:
1.1.1.8   root     5174:             save_cpu_state(ctx, 1);
                   5175:             gen_helper_mtc0_status(arg);
1.1.1.6   root     5176:             /* BS_STOP isn't good enough here, hflags may have changed. */
                   5177:             gen_save_pc(ctx->pc + 4);
                   5178:             ctx->bstate = BS_EXCP;
                   5179:             rn = "Status";
                   5180:             break;
                   5181:         case 1:
                   5182:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5183:             gen_helper_mtc0_intctl(arg);
1.1.1.6   root     5184:             /* Stop translation as we may have switched the execution mode */
                   5185:             ctx->bstate = BS_STOP;
                   5186:             rn = "IntCtl";
                   5187:             break;
                   5188:         case 2:
                   5189:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5190:             gen_helper_mtc0_srsctl(arg);
1.1.1.6   root     5191:             /* Stop translation as we may have switched the execution mode */
                   5192:             ctx->bstate = BS_STOP;
                   5193:             rn = "SRSCtl";
                   5194:             break;
1.1.1.5   root     5195:         case 3:
1.1.1.6   root     5196:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.16! root     5197:             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_SRSMap));
1.1.1.6   root     5198:             /* Stop translation as we may have switched the execution mode */
                   5199:             ctx->bstate = BS_STOP;
                   5200:             rn = "SRSMap";
                   5201:             break;
1.1.1.5   root     5202:         default:
                   5203:             goto die;
1.1.1.6   root     5204:         }
1.1.1.5   root     5205:         break;
                   5206:     case 13:
                   5207:         switch (sel) {
                   5208:         case 0:
1.1.1.8   root     5209:             save_cpu_state(ctx, 1);
1.1.1.12  root     5210:             /* Mark as an IO operation because we may trigger a software
                   5211:                interrupt.  */
                   5212:             if (use_icount) {
                   5213:                 gen_io_start();
                   5214:             }
1.1.1.8   root     5215:             gen_helper_mtc0_cause(arg);
1.1.1.12  root     5216:             if (use_icount) {
                   5217:                 gen_io_end();
                   5218:             }
                   5219:             /* Stop translation as we may have triggered an intetrupt */
                   5220:             ctx->bstate = BS_STOP;
1.1.1.6   root     5221:             rn = "Cause";
                   5222:             break;
1.1.1.5   root     5223:         default:
                   5224:             goto die;
1.1.1.6   root     5225:         }
1.1.1.5   root     5226:         break;
                   5227:     case 14:
                   5228:         switch (sel) {
                   5229:         case 0:
1.1.1.16! root     5230:             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_EPC));
1.1.1.6   root     5231:             rn = "EPC";
                   5232:             break;
1.1.1.5   root     5233:         default:
                   5234:             goto die;
1.1.1.6   root     5235:         }
1.1.1.5   root     5236:         break;
                   5237:     case 15:
                   5238:         switch (sel) {
                   5239:         case 0:
1.1.1.6   root     5240:             /* ignored */
                   5241:             rn = "PRid";
                   5242:             break;
                   5243:         case 1:
                   5244:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5245:             gen_helper_mtc0_ebase(arg);
1.1.1.6   root     5246:             rn = "EBase";
                   5247:             break;
1.1.1.5   root     5248:         default:
                   5249:             goto die;
1.1.1.6   root     5250:         }
1.1.1.5   root     5251:         break;
                   5252:     case 16:
                   5253:         switch (sel) {
                   5254:         case 0:
1.1.1.8   root     5255:             gen_helper_mtc0_config0(arg);
1.1.1.5   root     5256:             rn = "Config";
1.1.1.6   root     5257:             /* Stop translation as we may have switched the execution mode */
                   5258:             ctx->bstate = BS_STOP;
1.1.1.5   root     5259:             break;
                   5260:         case 1:
1.1.1.8   root     5261:             /* ignored, read only */
1.1.1.5   root     5262:             rn = "Config1";
                   5263:             break;
                   5264:         case 2:
1.1.1.8   root     5265:             gen_helper_mtc0_config2(arg);
1.1.1.5   root     5266:             rn = "Config2";
1.1.1.6   root     5267:             /* Stop translation as we may have switched the execution mode */
                   5268:             ctx->bstate = BS_STOP;
1.1.1.5   root     5269:             break;
                   5270:         case 3:
1.1.1.6   root     5271:             /* ignored */
1.1.1.5   root     5272:             rn = "Config3";
                   5273:             break;
                   5274:         /* 6,7 are implementation dependent */
                   5275:         default:
                   5276:             rn = "Invalid config selector";
                   5277:             goto die;
                   5278:         }
                   5279:         break;
                   5280:     case 17:
                   5281:         switch (sel) {
                   5282:         case 0:
1.1.1.9   root     5283:             gen_helper_mtc0_lladdr(arg);
1.1.1.6   root     5284:             rn = "LLAddr";
                   5285:             break;
1.1.1.5   root     5286:         default:
                   5287:             goto die;
                   5288:         }
                   5289:         break;
                   5290:     case 18:
                   5291:         switch (sel) {
1.1.1.6   root     5292:         case 0 ... 7:
1.1.1.8   root     5293:             gen_helper_1i(mtc0_watchlo, arg, sel);
1.1.1.6   root     5294:             rn = "WatchLo";
                   5295:             break;
1.1.1.5   root     5296:         default:
                   5297:             goto die;
                   5298:         }
                   5299:         break;
                   5300:     case 19:
                   5301:         switch (sel) {
1.1.1.6   root     5302:         case 0 ... 7:
1.1.1.8   root     5303:             gen_helper_1i(mtc0_watchhi, arg, sel);
1.1.1.6   root     5304:             rn = "WatchHi";
                   5305:             break;
1.1.1.5   root     5306:         default:
                   5307:             goto die;
                   5308:         }
                   5309:         break;
                   5310:     case 20:
                   5311:         switch (sel) {
                   5312:         case 0:
1.1.1.6   root     5313:             check_insn(env, ctx, ISA_MIPS3);
1.1.1.8   root     5314:             gen_helper_mtc0_xcontext(arg);
1.1.1.6   root     5315:             rn = "XContext";
                   5316:             break;
1.1.1.5   root     5317:         default:
                   5318:             goto die;
                   5319:         }
                   5320:         break;
                   5321:     case 21:
                   5322:        /* Officially reserved, but sel 0 is used for R1x000 framemask */
                   5323:         switch (sel) {
                   5324:         case 0:
1.1.1.8   root     5325:             gen_helper_mtc0_framemask(arg);
1.1.1.6   root     5326:             rn = "Framemask";
                   5327:             break;
1.1.1.5   root     5328:         default:
                   5329:             goto die;
                   5330:         }
                   5331:         break;
                   5332:     case 22:
                   5333:         /* ignored */
                   5334:         rn = "Diagnostic"; /* implementation dependent */
1.1.1.6   root     5335:         break;
1.1.1.5   root     5336:     case 23:
                   5337:         switch (sel) {
                   5338:         case 0:
1.1.1.8   root     5339:             gen_helper_mtc0_debug(arg); /* EJTAG support */
1.1.1.6   root     5340:             /* BS_STOP isn't good enough here, hflags may have changed. */
                   5341:             gen_save_pc(ctx->pc + 4);
                   5342:             ctx->bstate = BS_EXCP;
                   5343:             rn = "Debug";
                   5344:             break;
                   5345:         case 1:
1.1.1.8   root     5346: //            gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
1.1.1.6   root     5347:             /* Stop translation as we may have switched the execution mode */
                   5348:             ctx->bstate = BS_STOP;
                   5349:             rn = "TraceControl";
                   5350: //            break;
                   5351:         case 2:
1.1.1.8   root     5352: //            gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
1.1.1.6   root     5353:             /* Stop translation as we may have switched the execution mode */
                   5354:             ctx->bstate = BS_STOP;
                   5355:             rn = "TraceControl2";
                   5356: //            break;
                   5357:         case 3:
1.1.1.8   root     5358: //            gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
1.1.1.6   root     5359:             /* Stop translation as we may have switched the execution mode */
                   5360:             ctx->bstate = BS_STOP;
                   5361:             rn = "UserTraceData";
                   5362: //            break;
1.1.1.5   root     5363:         case 4:
1.1.1.8   root     5364: //            gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
1.1.1.6   root     5365:             /* Stop translation as we may have switched the execution mode */
                   5366:             ctx->bstate = BS_STOP;
                   5367:             rn = "TraceBPC";
                   5368: //            break;
1.1.1.5   root     5369:         default:
                   5370:             goto die;
                   5371:         }
                   5372:         break;
                   5373:     case 24:
                   5374:         switch (sel) {
                   5375:         case 0:
1.1.1.7   root     5376:             /* EJTAG support */
1.1.1.16! root     5377:             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_DEPC));
1.1.1.6   root     5378:             rn = "DEPC";
                   5379:             break;
1.1.1.5   root     5380:         default:
                   5381:             goto die;
                   5382:         }
                   5383:         break;
                   5384:     case 25:
                   5385:         switch (sel) {
                   5386:         case 0:
1.1.1.8   root     5387:             gen_helper_mtc0_performance0(arg);
1.1.1.6   root     5388:             rn = "Performance0";
                   5389:             break;
                   5390:         case 1:
1.1.1.8   root     5391: //            gen_helper_mtc0_performance1(arg);
1.1.1.6   root     5392:             rn = "Performance1";
                   5393: //            break;
                   5394:         case 2:
1.1.1.8   root     5395: //            gen_helper_mtc0_performance2(arg);
1.1.1.6   root     5396:             rn = "Performance2";
                   5397: //            break;
1.1.1.5   root     5398:         case 3:
1.1.1.8   root     5399: //            gen_helper_mtc0_performance3(arg);
1.1.1.6   root     5400:             rn = "Performance3";
                   5401: //            break;
1.1.1.5   root     5402:         case 4:
1.1.1.8   root     5403: //            gen_helper_mtc0_performance4(arg);
1.1.1.6   root     5404:             rn = "Performance4";
                   5405: //            break;
1.1.1.5   root     5406:         case 5:
1.1.1.8   root     5407: //            gen_helper_mtc0_performance5(arg);
1.1.1.6   root     5408:             rn = "Performance5";
                   5409: //            break;
1.1.1.5   root     5410:         case 6:
1.1.1.8   root     5411: //            gen_helper_mtc0_performance6(arg);
1.1.1.6   root     5412:             rn = "Performance6";
                   5413: //            break;
1.1.1.5   root     5414:         case 7:
1.1.1.8   root     5415: //            gen_helper_mtc0_performance7(arg);
1.1.1.6   root     5416:             rn = "Performance7";
                   5417: //            break;
1.1.1.5   root     5418:         default:
                   5419:             goto die;
                   5420:         }
1.1.1.6   root     5421:         break;
1.1.1.5   root     5422:     case 26:
1.1.1.6   root     5423:         /* ignored */
1.1.1.5   root     5424:         rn = "ECC";
1.1.1.6   root     5425:         break;
1.1.1.5   root     5426:     case 27:
                   5427:         switch (sel) {
                   5428:         case 0 ... 3:
1.1.1.6   root     5429:             /* ignored */
                   5430:             rn = "CacheErr";
                   5431:             break;
1.1.1.5   root     5432:         default:
                   5433:             goto die;
                   5434:         }
1.1.1.6   root     5435:         break;
1.1.1.5   root     5436:     case 28:
                   5437:         switch (sel) {
                   5438:         case 0:
                   5439:         case 2:
                   5440:         case 4:
                   5441:         case 6:
1.1.1.8   root     5442:             gen_helper_mtc0_taglo(arg);
1.1.1.5   root     5443:             rn = "TagLo";
                   5444:             break;
                   5445:         case 1:
                   5446:         case 3:
                   5447:         case 5:
                   5448:         case 7:
1.1.1.8   root     5449:             gen_helper_mtc0_datalo(arg);
1.1.1.5   root     5450:             rn = "DataLo";
                   5451:             break;
                   5452:         default:
                   5453:             goto die;
                   5454:         }
                   5455:         break;
                   5456:     case 29:
                   5457:         switch (sel) {
                   5458:         case 0:
                   5459:         case 2:
                   5460:         case 4:
                   5461:         case 6:
1.1.1.8   root     5462:             gen_helper_mtc0_taghi(arg);
1.1.1.5   root     5463:             rn = "TagHi";
                   5464:             break;
                   5465:         case 1:
                   5466:         case 3:
                   5467:         case 5:
                   5468:         case 7:
1.1.1.8   root     5469:             gen_helper_mtc0_datahi(arg);
1.1.1.5   root     5470:             rn = "DataHi";
                   5471:             break;
                   5472:         default:
                   5473:             rn = "invalid sel";
                   5474:             goto die;
                   5475:         }
1.1.1.6   root     5476:         break;
1.1.1.5   root     5477:     case 30:
                   5478:         switch (sel) {
                   5479:         case 0:
1.1.1.16! root     5480:             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUMIPSState, CP0_ErrorEPC));
1.1.1.6   root     5481:             rn = "ErrorEPC";
                   5482:             break;
1.1.1.5   root     5483:         default:
                   5484:             goto die;
                   5485:         }
                   5486:         break;
                   5487:     case 31:
                   5488:         switch (sel) {
                   5489:         case 0:
1.1.1.7   root     5490:             /* EJTAG support */
1.1.1.16! root     5491:             gen_mtc0_store32(arg, offsetof(CPUMIPSState, CP0_DESAVE));
1.1.1.6   root     5492:             rn = "DESAVE";
                   5493:             break;
1.1.1.5   root     5494:         default:
                   5495:             goto die;
                   5496:         }
1.1.1.6   root     5497:         /* Stop translation as we may have switched the execution mode */
                   5498:         ctx->bstate = BS_STOP;
1.1.1.5   root     5499:         break;
                   5500:     default:
1.1.1.6   root     5501:         goto die;
1.1.1.5   root     5502:     }
1.1.1.13  root     5503:     (void)rn; /* avoid a compiler warning */
1.1.1.7   root     5504:     LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
                   5505:     /* For simplicity assume that all writes can cause interrupts.  */
                   5506:     if (use_icount) {
                   5507:         gen_io_end();
                   5508:         ctx->bstate = BS_STOP;
1.1.1.5   root     5509:     }
                   5510:     return;
                   5511: 
                   5512: die:
1.1.1.7   root     5513:     LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
1.1.1.5   root     5514:     generate_exception(ctx, EXCP_RI);
                   5515: }
1.1.1.6   root     5516: #endif /* TARGET_MIPS64 */
1.1.1.5   root     5517: 
1.1.1.16! root     5518: static void gen_mftr(CPUMIPSState *env, DisasContext *ctx, int rt, int rd,
1.1.1.6   root     5519:                      int u, int sel, int h)
1.1.1.5   root     5520: {
1.1.1.6   root     5521:     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1.1.1.7   root     5522:     TCGv t0 = tcg_temp_local_new();
1.1.1.5   root     5523: 
1.1.1.6   root     5524:     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
1.1.1.7   root     5525:         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
                   5526:          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
                   5527:         tcg_gen_movi_tl(t0, -1);
1.1.1.6   root     5528:     else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
                   5529:              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1.1.1.7   root     5530:         tcg_gen_movi_tl(t0, -1);
1.1.1.6   root     5531:     else if (u == 0) {
                   5532:         switch (rt) {
1.1.1.15  root     5533:         case 1:
                   5534:             switch (sel) {
                   5535:             case 1:
                   5536:                 gen_helper_mftc0_vpecontrol(t0);
                   5537:                 break;
                   5538:             case 2:
                   5539:                 gen_helper_mftc0_vpeconf0(t0);
                   5540:                 break;
                   5541:             default:
                   5542:                 goto die;
                   5543:                 break;
                   5544:             }
                   5545:             break;
1.1.1.6   root     5546:         case 2:
                   5547:             switch (sel) {
                   5548:             case 1:
1.1.1.7   root     5549:                 gen_helper_mftc0_tcstatus(t0);
1.1.1.6   root     5550:                 break;
                   5551:             case 2:
1.1.1.7   root     5552:                 gen_helper_mftc0_tcbind(t0);
1.1.1.6   root     5553:                 break;
                   5554:             case 3:
1.1.1.7   root     5555:                 gen_helper_mftc0_tcrestart(t0);
1.1.1.6   root     5556:                 break;
                   5557:             case 4:
1.1.1.7   root     5558:                 gen_helper_mftc0_tchalt(t0);
1.1.1.6   root     5559:                 break;
                   5560:             case 5:
1.1.1.7   root     5561:                 gen_helper_mftc0_tccontext(t0);
1.1.1.6   root     5562:                 break;
                   5563:             case 6:
1.1.1.7   root     5564:                 gen_helper_mftc0_tcschedule(t0);
1.1.1.6   root     5565:                 break;
                   5566:             case 7:
1.1.1.7   root     5567:                 gen_helper_mftc0_tcschefback(t0);
1.1.1.6   root     5568:                 break;
                   5569:             default:
1.1.1.7   root     5570:                 gen_mfc0(env, ctx, t0, rt, sel);
1.1.1.6   root     5571:                 break;
                   5572:             }
                   5573:             break;
                   5574:         case 10:
                   5575:             switch (sel) {
                   5576:             case 0:
1.1.1.7   root     5577:                 gen_helper_mftc0_entryhi(t0);
1.1.1.6   root     5578:                 break;
                   5579:             default:
1.1.1.7   root     5580:                 gen_mfc0(env, ctx, t0, rt, sel);
1.1.1.6   root     5581:                 break;
                   5582:             }
                   5583:         case 12:
                   5584:             switch (sel) {
                   5585:             case 0:
1.1.1.7   root     5586:                 gen_helper_mftc0_status(t0);
1.1.1.6   root     5587:                 break;
                   5588:             default:
1.1.1.7   root     5589:                 gen_mfc0(env, ctx, t0, rt, sel);
1.1.1.6   root     5590:                 break;
                   5591:             }
1.1.1.15  root     5592:         case 13:
                   5593:             switch (sel) {
                   5594:             case 0:
                   5595:                 gen_helper_mftc0_cause(t0);
                   5596:                 break;
                   5597:             default:
                   5598:                 goto die;
                   5599:                 break;
                   5600:             }
                   5601:             break;
                   5602:         case 14:
                   5603:             switch (sel) {
                   5604:             case 0:
                   5605:                 gen_helper_mftc0_epc(t0);
                   5606:                 break;
                   5607:             default:
                   5608:                 goto die;
                   5609:                 break;
                   5610:             }
                   5611:             break;
                   5612:         case 15:
                   5613:             switch (sel) {
                   5614:             case 1:
                   5615:                 gen_helper_mftc0_ebase(t0);
                   5616:                 break;
                   5617:             default:
                   5618:                 goto die;
                   5619:                 break;
                   5620:             }
                   5621:             break;
                   5622:         case 16:
                   5623:             switch (sel) {
                   5624:             case 0 ... 7:
                   5625:                 gen_helper_mftc0_configx(t0, tcg_const_tl(sel));
                   5626:                 break;
                   5627:             default:
                   5628:                 goto die;
                   5629:                 break;
                   5630:             }
                   5631:             break;
1.1.1.6   root     5632:         case 23:
                   5633:             switch (sel) {
                   5634:             case 0:
1.1.1.7   root     5635:                 gen_helper_mftc0_debug(t0);
1.1.1.6   root     5636:                 break;
                   5637:             default:
1.1.1.7   root     5638:                 gen_mfc0(env, ctx, t0, rt, sel);
1.1.1.6   root     5639:                 break;
                   5640:             }
                   5641:             break;
                   5642:         default:
1.1.1.7   root     5643:             gen_mfc0(env, ctx, t0, rt, sel);
1.1.1.6   root     5644:         }
                   5645:     } else switch (sel) {
                   5646:     /* GPR registers. */
                   5647:     case 0:
1.1.1.7   root     5648:         gen_helper_1i(mftgpr, t0, rt);
1.1.1.6   root     5649:         break;
                   5650:     /* Auxiliary CPU registers */
                   5651:     case 1:
                   5652:         switch (rt) {
                   5653:         case 0:
1.1.1.7   root     5654:             gen_helper_1i(mftlo, t0, 0);
1.1.1.6   root     5655:             break;
                   5656:         case 1:
1.1.1.7   root     5657:             gen_helper_1i(mfthi, t0, 0);
1.1.1.6   root     5658:             break;
                   5659:         case 2:
1.1.1.7   root     5660:             gen_helper_1i(mftacx, t0, 0);
1.1.1.6   root     5661:             break;
                   5662:         case 4:
1.1.1.7   root     5663:             gen_helper_1i(mftlo, t0, 1);
1.1.1.6   root     5664:             break;
                   5665:         case 5:
1.1.1.7   root     5666:             gen_helper_1i(mfthi, t0, 1);
1.1.1.6   root     5667:             break;
                   5668:         case 6:
1.1.1.7   root     5669:             gen_helper_1i(mftacx, t0, 1);
1.1.1.6   root     5670:             break;
                   5671:         case 8:
1.1.1.7   root     5672:             gen_helper_1i(mftlo, t0, 2);
1.1.1.6   root     5673:             break;
                   5674:         case 9:
1.1.1.7   root     5675:             gen_helper_1i(mfthi, t0, 2);
1.1.1.6   root     5676:             break;
                   5677:         case 10:
1.1.1.7   root     5678:             gen_helper_1i(mftacx, t0, 2);
1.1.1.6   root     5679:             break;
                   5680:         case 12:
1.1.1.7   root     5681:             gen_helper_1i(mftlo, t0, 3);
1.1.1.6   root     5682:             break;
                   5683:         case 13:
1.1.1.7   root     5684:             gen_helper_1i(mfthi, t0, 3);
1.1.1.6   root     5685:             break;
                   5686:         case 14:
1.1.1.7   root     5687:             gen_helper_1i(mftacx, t0, 3);
1.1.1.6   root     5688:             break;
                   5689:         case 16:
1.1.1.7   root     5690:             gen_helper_mftdsp(t0);
1.1.1.6   root     5691:             break;
                   5692:         default:
                   5693:             goto die;
                   5694:         }
                   5695:         break;
                   5696:     /* Floating point (COP1). */
                   5697:     case 2:
                   5698:         /* XXX: For now we support only a single FPU context. */
                   5699:         if (h == 0) {
1.1.1.7   root     5700:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   5701: 
                   5702:             gen_load_fpr32(fp0, rt);
                   5703:             tcg_gen_ext_i32_tl(t0, fp0);
                   5704:             tcg_temp_free_i32(fp0);
1.1.1.6   root     5705:         } else {
1.1.1.7   root     5706:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   5707: 
                   5708:             gen_load_fpr32h(fp0, rt);
                   5709:             tcg_gen_ext_i32_tl(t0, fp0);
                   5710:             tcg_temp_free_i32(fp0);
1.1.1.6   root     5711:         }
                   5712:         break;
                   5713:     case 3:
                   5714:         /* XXX: For now we support only a single FPU context. */
1.1.1.7   root     5715:         gen_helper_1i(cfc1, t0, rt);
1.1.1.6   root     5716:         break;
                   5717:     /* COP2: Not implemented. */
                   5718:     case 4:
                   5719:     case 5:
                   5720:         /* fall through */
                   5721:     default:
                   5722:         goto die;
                   5723:     }
1.1.1.7   root     5724:     LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
                   5725:     gen_store_gpr(t0, rd);
                   5726:     tcg_temp_free(t0);
1.1.1.6   root     5727:     return;
                   5728: 
                   5729: die:
1.1.1.7   root     5730:     tcg_temp_free(t0);
                   5731:     LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1.1.1.6   root     5732:     generate_exception(ctx, EXCP_RI);
                   5733: }
                   5734: 
1.1.1.16! root     5735: static void gen_mttr(CPUMIPSState *env, DisasContext *ctx, int rd, int rt,
1.1.1.6   root     5736:                      int u, int sel, int h)
                   5737: {
                   5738:     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1.1.1.7   root     5739:     TCGv t0 = tcg_temp_local_new();
1.1.1.6   root     5740: 
1.1.1.7   root     5741:     gen_load_gpr(t0, rt);
1.1.1.6   root     5742:     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
1.1.1.7   root     5743:         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
                   5744:          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1.1.1.6   root     5745:         /* NOP */ ;
                   5746:     else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
                   5747:              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
                   5748:         /* NOP */ ;
                   5749:     else if (u == 0) {
                   5750:         switch (rd) {
1.1.1.15  root     5751:         case 1:
                   5752:             switch (sel) {
                   5753:             case 1:
                   5754:                 gen_helper_mttc0_vpecontrol(t0);
                   5755:                 break;
                   5756:             case 2:
                   5757:                 gen_helper_mttc0_vpeconf0(t0);
                   5758:                 break;
                   5759:             default:
                   5760:                 goto die;
                   5761:                 break;
                   5762:             }
                   5763:             break;
1.1.1.6   root     5764:         case 2:
                   5765:             switch (sel) {
                   5766:             case 1:
1.1.1.7   root     5767:                 gen_helper_mttc0_tcstatus(t0);
1.1.1.6   root     5768:                 break;
                   5769:             case 2:
1.1.1.7   root     5770:                 gen_helper_mttc0_tcbind(t0);
1.1.1.6   root     5771:                 break;
                   5772:             case 3:
1.1.1.7   root     5773:                 gen_helper_mttc0_tcrestart(t0);
1.1.1.6   root     5774:                 break;
                   5775:             case 4:
1.1.1.7   root     5776:                 gen_helper_mttc0_tchalt(t0);
1.1.1.6   root     5777:                 break;
                   5778:             case 5:
1.1.1.7   root     5779:                 gen_helper_mttc0_tccontext(t0);
1.1.1.6   root     5780:                 break;
                   5781:             case 6:
1.1.1.7   root     5782:                 gen_helper_mttc0_tcschedule(t0);
1.1.1.6   root     5783:                 break;
                   5784:             case 7:
1.1.1.7   root     5785:                 gen_helper_mttc0_tcschefback(t0);
1.1.1.6   root     5786:                 break;
                   5787:             default:
1.1.1.7   root     5788:                 gen_mtc0(env, ctx, t0, rd, sel);
1.1.1.6   root     5789:                 break;
                   5790:             }
                   5791:             break;
                   5792:         case 10:
                   5793:             switch (sel) {
                   5794:             case 0:
1.1.1.7   root     5795:                 gen_helper_mttc0_entryhi(t0);
1.1.1.6   root     5796:                 break;
                   5797:             default:
1.1.1.7   root     5798:                 gen_mtc0(env, ctx, t0, rd, sel);
1.1.1.6   root     5799:                 break;
                   5800:             }
                   5801:         case 12:
                   5802:             switch (sel) {
                   5803:             case 0:
1.1.1.7   root     5804:                 gen_helper_mttc0_status(t0);
1.1.1.6   root     5805:                 break;
                   5806:             default:
1.1.1.7   root     5807:                 gen_mtc0(env, ctx, t0, rd, sel);
1.1.1.6   root     5808:                 break;
                   5809:             }
1.1.1.15  root     5810:         case 13:
                   5811:             switch (sel) {
                   5812:             case 0:
                   5813:                 gen_helper_mttc0_cause(t0);
                   5814:                 break;
                   5815:             default:
                   5816:                 goto die;
                   5817:                 break;
                   5818:             }
                   5819:             break;
                   5820:         case 15:
                   5821:             switch (sel) {
                   5822:             case 1:
                   5823:                 gen_helper_mttc0_ebase(t0);
                   5824:                 break;
                   5825:             default:
                   5826:                 goto die;
                   5827:                 break;
                   5828:             }
                   5829:             break;
1.1.1.6   root     5830:         case 23:
                   5831:             switch (sel) {
                   5832:             case 0:
1.1.1.7   root     5833:                 gen_helper_mttc0_debug(t0);
1.1.1.6   root     5834:                 break;
                   5835:             default:
1.1.1.7   root     5836:                 gen_mtc0(env, ctx, t0, rd, sel);
1.1.1.6   root     5837:                 break;
                   5838:             }
                   5839:             break;
                   5840:         default:
1.1.1.7   root     5841:             gen_mtc0(env, ctx, t0, rd, sel);
1.1.1.6   root     5842:         }
                   5843:     } else switch (sel) {
                   5844:     /* GPR registers. */
                   5845:     case 0:
1.1.1.7   root     5846:         gen_helper_1i(mttgpr, t0, rd);
1.1.1.6   root     5847:         break;
                   5848:     /* Auxiliary CPU registers */
                   5849:     case 1:
                   5850:         switch (rd) {
                   5851:         case 0:
1.1.1.7   root     5852:             gen_helper_1i(mttlo, t0, 0);
1.1.1.6   root     5853:             break;
                   5854:         case 1:
1.1.1.7   root     5855:             gen_helper_1i(mtthi, t0, 0);
1.1.1.6   root     5856:             break;
                   5857:         case 2:
1.1.1.7   root     5858:             gen_helper_1i(mttacx, t0, 0);
1.1.1.6   root     5859:             break;
                   5860:         case 4:
1.1.1.7   root     5861:             gen_helper_1i(mttlo, t0, 1);
1.1.1.6   root     5862:             break;
                   5863:         case 5:
1.1.1.7   root     5864:             gen_helper_1i(mtthi, t0, 1);
1.1.1.6   root     5865:             break;
                   5866:         case 6:
1.1.1.7   root     5867:             gen_helper_1i(mttacx, t0, 1);
1.1.1.6   root     5868:             break;
                   5869:         case 8:
1.1.1.7   root     5870:             gen_helper_1i(mttlo, t0, 2);
1.1.1.6   root     5871:             break;
                   5872:         case 9:
1.1.1.7   root     5873:             gen_helper_1i(mtthi, t0, 2);
1.1.1.6   root     5874:             break;
                   5875:         case 10:
1.1.1.7   root     5876:             gen_helper_1i(mttacx, t0, 2);
1.1.1.6   root     5877:             break;
                   5878:         case 12:
1.1.1.7   root     5879:             gen_helper_1i(mttlo, t0, 3);
1.1.1.6   root     5880:             break;
                   5881:         case 13:
1.1.1.7   root     5882:             gen_helper_1i(mtthi, t0, 3);
1.1.1.6   root     5883:             break;
                   5884:         case 14:
1.1.1.7   root     5885:             gen_helper_1i(mttacx, t0, 3);
1.1.1.6   root     5886:             break;
                   5887:         case 16:
1.1.1.7   root     5888:             gen_helper_mttdsp(t0);
1.1.1.6   root     5889:             break;
                   5890:         default:
                   5891:             goto die;
                   5892:         }
                   5893:         break;
                   5894:     /* Floating point (COP1). */
                   5895:     case 2:
                   5896:         /* XXX: For now we support only a single FPU context. */
                   5897:         if (h == 0) {
1.1.1.7   root     5898:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   5899: 
                   5900:             tcg_gen_trunc_tl_i32(fp0, t0);
                   5901:             gen_store_fpr32(fp0, rd);
                   5902:             tcg_temp_free_i32(fp0);
1.1.1.6   root     5903:         } else {
1.1.1.7   root     5904:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   5905: 
                   5906:             tcg_gen_trunc_tl_i32(fp0, t0);
                   5907:             gen_store_fpr32h(fp0, rd);
                   5908:             tcg_temp_free_i32(fp0);
1.1.1.6   root     5909:         }
                   5910:         break;
                   5911:     case 3:
                   5912:         /* XXX: For now we support only a single FPU context. */
1.1.1.7   root     5913:         gen_helper_1i(ctc1, t0, rd);
1.1.1.6   root     5914:         break;
                   5915:     /* COP2: Not implemented. */
                   5916:     case 4:
                   5917:     case 5:
                   5918:         /* fall through */
                   5919:     default:
                   5920:         goto die;
                   5921:     }
1.1.1.7   root     5922:     LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
                   5923:     tcg_temp_free(t0);
1.1.1.6   root     5924:     return;
                   5925: 
                   5926: die:
1.1.1.7   root     5927:     tcg_temp_free(t0);
                   5928:     LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1.1.1.6   root     5929:     generate_exception(ctx, EXCP_RI);
                   5930: }
                   5931: 
1.1.1.16! root     5932: static void gen_cp0 (CPUMIPSState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
1.1.1.6   root     5933: {
                   5934:     const char *opn = "ldst";
1.1.1.5   root     5935: 
                   5936:     switch (opc) {
                   5937:     case OPC_MFC0:
                   5938:         if (rt == 0) {
1.1.1.6   root     5939:             /* Treat as NOP. */
1.1.1.5   root     5940:             return;
                   5941:         }
1.1.1.8   root     5942:         gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
1.1.1.5   root     5943:         opn = "mfc0";
                   5944:         break;
                   5945:     case OPC_MTC0:
1.1.1.7   root     5946:         {
1.1.1.8   root     5947:             TCGv t0 = tcg_temp_new();
1.1.1.7   root     5948: 
                   5949:             gen_load_gpr(t0, rt);
                   5950:             gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
                   5951:             tcg_temp_free(t0);
                   5952:         }
1.1.1.5   root     5953:         opn = "mtc0";
                   5954:         break;
1.1.1.6   root     5955: #if defined(TARGET_MIPS64)
1.1.1.5   root     5956:     case OPC_DMFC0:
1.1.1.6   root     5957:         check_insn(env, ctx, ISA_MIPS3);
1.1.1.5   root     5958:         if (rt == 0) {
1.1.1.6   root     5959:             /* Treat as NOP. */
1.1.1.5   root     5960:             return;
                   5961:         }
1.1.1.8   root     5962:         gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
1.1.1.5   root     5963:         opn = "dmfc0";
                   5964:         break;
                   5965:     case OPC_DMTC0:
1.1.1.6   root     5966:         check_insn(env, ctx, ISA_MIPS3);
1.1.1.7   root     5967:         {
1.1.1.8   root     5968:             TCGv t0 = tcg_temp_new();
1.1.1.7   root     5969: 
                   5970:             gen_load_gpr(t0, rt);
                   5971:             gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
                   5972:             tcg_temp_free(t0);
                   5973:         }
1.1.1.5   root     5974:         opn = "dmtc0";
                   5975:         break;
1.1.1.6   root     5976: #endif
                   5977:     case OPC_MFTR:
                   5978:         check_insn(env, ctx, ASE_MT);
                   5979:         if (rd == 0) {
                   5980:             /* Treat as NOP. */
                   5981:             return;
                   5982:         }
1.1.1.7   root     5983:         gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
1.1.1.6   root     5984:                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
                   5985:         opn = "mftr";
                   5986:         break;
                   5987:     case OPC_MTTR:
                   5988:         check_insn(env, ctx, ASE_MT);
1.1.1.7   root     5989:         gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
1.1.1.6   root     5990:                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
                   5991:         opn = "mttr";
                   5992:         break;
1.1.1.5   root     5993:     case OPC_TLBWI:
                   5994:         opn = "tlbwi";
1.1.1.8   root     5995:         if (!env->tlb->helper_tlbwi)
1.1.1.6   root     5996:             goto die;
1.1.1.7   root     5997:         gen_helper_tlbwi();
1.1.1.5   root     5998:         break;
                   5999:     case OPC_TLBWR:
                   6000:         opn = "tlbwr";
1.1.1.8   root     6001:         if (!env->tlb->helper_tlbwr)
1.1.1.6   root     6002:             goto die;
1.1.1.7   root     6003:         gen_helper_tlbwr();
1.1.1.5   root     6004:         break;
                   6005:     case OPC_TLBP:
                   6006:         opn = "tlbp";
1.1.1.8   root     6007:         if (!env->tlb->helper_tlbp)
1.1.1.6   root     6008:             goto die;
1.1.1.7   root     6009:         gen_helper_tlbp();
1.1.1.5   root     6010:         break;
                   6011:     case OPC_TLBR:
                   6012:         opn = "tlbr";
1.1.1.8   root     6013:         if (!env->tlb->helper_tlbr)
1.1.1.6   root     6014:             goto die;
1.1.1.7   root     6015:         gen_helper_tlbr();
1.1.1.5   root     6016:         break;
                   6017:     case OPC_ERET:
                   6018:         opn = "eret";
1.1.1.6   root     6019:         check_insn(env, ctx, ISA_MIPS2);
1.1.1.7   root     6020:         gen_helper_eret();
1.1.1.5   root     6021:         ctx->bstate = BS_EXCP;
                   6022:         break;
                   6023:     case OPC_DERET:
                   6024:         opn = "deret";
1.1.1.6   root     6025:         check_insn(env, ctx, ISA_MIPS32);
1.1.1.5   root     6026:         if (!(ctx->hflags & MIPS_HFLAG_DM)) {
1.1.1.6   root     6027:             MIPS_INVAL(opn);
1.1.1.5   root     6028:             generate_exception(ctx, EXCP_RI);
                   6029:         } else {
1.1.1.7   root     6030:             gen_helper_deret();
1.1.1.5   root     6031:             ctx->bstate = BS_EXCP;
                   6032:         }
                   6033:         break;
                   6034:     case OPC_WAIT:
                   6035:         opn = "wait";
1.1.1.6   root     6036:         check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
1.1.1.5   root     6037:         /* If we get an exception, we want to restart at next instruction */
                   6038:         ctx->pc += 4;
                   6039:         save_cpu_state(ctx, 1);
                   6040:         ctx->pc -= 4;
1.1.1.7   root     6041:         gen_helper_wait();
1.1.1.5   root     6042:         ctx->bstate = BS_EXCP;
                   6043:         break;
                   6044:     default:
1.1.1.6   root     6045:  die:
                   6046:         MIPS_INVAL(opn);
1.1.1.5   root     6047:         generate_exception(ctx, EXCP_RI);
                   6048:         return;
                   6049:     }
1.1.1.13  root     6050:     (void)opn; /* avoid a compiler warning */
1.1.1.5   root     6051:     MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
                   6052: }
1.1.1.7   root     6053: #endif /* !CONFIG_USER_ONLY */
1.1.1.5   root     6054: 
                   6055: /* CP1 Branches (before delay slot) */
1.1.1.16! root     6056: static void gen_compute_branch1 (CPUMIPSState *env, DisasContext *ctx, uint32_t op,
1.1.1.6   root     6057:                                  int32_t cc, int32_t offset)
1.1.1.5   root     6058: {
                   6059:     target_ulong btarget;
1.1.1.6   root     6060:     const char *opn = "cp1 cond branch";
1.1.1.7   root     6061:     TCGv_i32 t0 = tcg_temp_new_i32();
1.1.1.6   root     6062: 
                   6063:     if (cc != 0)
                   6064:         check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
1.1.1.5   root     6065: 
                   6066:     btarget = ctx->pc + 4 + offset;
                   6067: 
                   6068:     switch (op) {
                   6069:     case OPC_BC1F:
1.1.1.8   root     6070:         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   6071:         tcg_gen_not_i32(t0, t0);
                   6072:         tcg_gen_andi_i32(t0, t0, 1);
                   6073:         tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.6   root     6074:         opn = "bc1f";
1.1.1.5   root     6075:         goto not_likely;
                   6076:     case OPC_BC1FL:
1.1.1.8   root     6077:         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   6078:         tcg_gen_not_i32(t0, t0);
                   6079:         tcg_gen_andi_i32(t0, t0, 1);
                   6080:         tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.6   root     6081:         opn = "bc1fl";
1.1.1.5   root     6082:         goto likely;
                   6083:     case OPC_BC1T:
1.1.1.8   root     6084:         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   6085:         tcg_gen_andi_i32(t0, t0, 1);
                   6086:         tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.6   root     6087:         opn = "bc1t";
                   6088:         goto not_likely;
1.1.1.5   root     6089:     case OPC_BC1TL:
1.1.1.8   root     6090:         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   6091:         tcg_gen_andi_i32(t0, t0, 1);
                   6092:         tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.6   root     6093:         opn = "bc1tl";
1.1.1.5   root     6094:     likely:
                   6095:         ctx->hflags |= MIPS_HFLAG_BL;
1.1.1.6   root     6096:         break;
                   6097:     case OPC_BC1FANY2:
1.1.1.7   root     6098:         {
1.1.1.8   root     6099:             TCGv_i32 t1 = tcg_temp_new_i32();
                   6100:             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   6101:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
1.1.1.16! root     6102:             tcg_gen_nand_i32(t0, t0, t1);
1.1.1.8   root     6103:             tcg_temp_free_i32(t1);
                   6104:             tcg_gen_andi_i32(t0, t0, 1);
                   6105:             tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.7   root     6106:         }
1.1.1.6   root     6107:         opn = "bc1any2f";
                   6108:         goto not_likely;
                   6109:     case OPC_BC1TANY2:
1.1.1.7   root     6110:         {
1.1.1.8   root     6111:             TCGv_i32 t1 = tcg_temp_new_i32();
                   6112:             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   6113:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
                   6114:             tcg_gen_or_i32(t0, t0, t1);
                   6115:             tcg_temp_free_i32(t1);
                   6116:             tcg_gen_andi_i32(t0, t0, 1);
                   6117:             tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.7   root     6118:         }
1.1.1.6   root     6119:         opn = "bc1any2t";
                   6120:         goto not_likely;
                   6121:     case OPC_BC1FANY4:
1.1.1.7   root     6122:         {
1.1.1.8   root     6123:             TCGv_i32 t1 = tcg_temp_new_i32();
                   6124:             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   6125:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
1.1.1.16! root     6126:             tcg_gen_and_i32(t0, t0, t1);
1.1.1.8   root     6127:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
1.1.1.16! root     6128:             tcg_gen_and_i32(t0, t0, t1);
1.1.1.8   root     6129:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
1.1.1.16! root     6130:             tcg_gen_nand_i32(t0, t0, t1);
1.1.1.8   root     6131:             tcg_temp_free_i32(t1);
                   6132:             tcg_gen_andi_i32(t0, t0, 1);
                   6133:             tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.7   root     6134:         }
1.1.1.6   root     6135:         opn = "bc1any4f";
                   6136:         goto not_likely;
                   6137:     case OPC_BC1TANY4:
1.1.1.7   root     6138:         {
1.1.1.8   root     6139:             TCGv_i32 t1 = tcg_temp_new_i32();
                   6140:             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   6141:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
                   6142:             tcg_gen_or_i32(t0, t0, t1);
                   6143:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
                   6144:             tcg_gen_or_i32(t0, t0, t1);
                   6145:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
                   6146:             tcg_gen_or_i32(t0, t0, t1);
                   6147:             tcg_temp_free_i32(t1);
                   6148:             tcg_gen_andi_i32(t0, t0, 1);
                   6149:             tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.7   root     6150:         }
1.1.1.6   root     6151:         opn = "bc1any4t";
                   6152:     not_likely:
                   6153:         ctx->hflags |= MIPS_HFLAG_BC;
1.1.1.5   root     6154:         break;
1.1.1.6   root     6155:     default:
                   6156:         MIPS_INVAL(opn);
                   6157:         generate_exception (ctx, EXCP_RI);
1.1.1.7   root     6158:         goto out;
1.1.1.5   root     6159:     }
1.1.1.13  root     6160:     (void)opn; /* avoid a compiler warning */
1.1.1.6   root     6161:     MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
1.1.1.5   root     6162:                ctx->hflags, btarget);
                   6163:     ctx->btarget = btarget;
1.1.1.7   root     6164: 
                   6165:  out:
                   6166:     tcg_temp_free_i32(t0);
1.1.1.5   root     6167: }
                   6168: 
                   6169: /* Coprocessor 1 (FPU) */
1.1.1.6   root     6170: 
                   6171: #define FOP(func, fmt) (((fmt) << 21) | (func))
                   6172: 
1.1.1.12  root     6173: enum fopcode {
                   6174:     OPC_ADD_S = FOP(0, FMT_S),
                   6175:     OPC_SUB_S = FOP(1, FMT_S),
                   6176:     OPC_MUL_S = FOP(2, FMT_S),
                   6177:     OPC_DIV_S = FOP(3, FMT_S),
                   6178:     OPC_SQRT_S = FOP(4, FMT_S),
                   6179:     OPC_ABS_S = FOP(5, FMT_S),
                   6180:     OPC_MOV_S = FOP(6, FMT_S),
                   6181:     OPC_NEG_S = FOP(7, FMT_S),
                   6182:     OPC_ROUND_L_S = FOP(8, FMT_S),
                   6183:     OPC_TRUNC_L_S = FOP(9, FMT_S),
                   6184:     OPC_CEIL_L_S = FOP(10, FMT_S),
                   6185:     OPC_FLOOR_L_S = FOP(11, FMT_S),
                   6186:     OPC_ROUND_W_S = FOP(12, FMT_S),
                   6187:     OPC_TRUNC_W_S = FOP(13, FMT_S),
                   6188:     OPC_CEIL_W_S = FOP(14, FMT_S),
                   6189:     OPC_FLOOR_W_S = FOP(15, FMT_S),
                   6190:     OPC_MOVCF_S = FOP(17, FMT_S),
                   6191:     OPC_MOVZ_S = FOP(18, FMT_S),
                   6192:     OPC_MOVN_S = FOP(19, FMT_S),
                   6193:     OPC_RECIP_S = FOP(21, FMT_S),
                   6194:     OPC_RSQRT_S = FOP(22, FMT_S),
                   6195:     OPC_RECIP2_S = FOP(28, FMT_S),
                   6196:     OPC_RECIP1_S = FOP(29, FMT_S),
                   6197:     OPC_RSQRT1_S = FOP(30, FMT_S),
                   6198:     OPC_RSQRT2_S = FOP(31, FMT_S),
                   6199:     OPC_CVT_D_S = FOP(33, FMT_S),
                   6200:     OPC_CVT_W_S = FOP(36, FMT_S),
                   6201:     OPC_CVT_L_S = FOP(37, FMT_S),
                   6202:     OPC_CVT_PS_S = FOP(38, FMT_S),
                   6203:     OPC_CMP_F_S = FOP (48, FMT_S),
                   6204:     OPC_CMP_UN_S = FOP (49, FMT_S),
                   6205:     OPC_CMP_EQ_S = FOP (50, FMT_S),
                   6206:     OPC_CMP_UEQ_S = FOP (51, FMT_S),
                   6207:     OPC_CMP_OLT_S = FOP (52, FMT_S),
                   6208:     OPC_CMP_ULT_S = FOP (53, FMT_S),
                   6209:     OPC_CMP_OLE_S = FOP (54, FMT_S),
                   6210:     OPC_CMP_ULE_S = FOP (55, FMT_S),
                   6211:     OPC_CMP_SF_S = FOP (56, FMT_S),
                   6212:     OPC_CMP_NGLE_S = FOP (57, FMT_S),
                   6213:     OPC_CMP_SEQ_S = FOP (58, FMT_S),
                   6214:     OPC_CMP_NGL_S = FOP (59, FMT_S),
                   6215:     OPC_CMP_LT_S = FOP (60, FMT_S),
                   6216:     OPC_CMP_NGE_S = FOP (61, FMT_S),
                   6217:     OPC_CMP_LE_S = FOP (62, FMT_S),
                   6218:     OPC_CMP_NGT_S = FOP (63, FMT_S),
                   6219: 
                   6220:     OPC_ADD_D = FOP(0, FMT_D),
                   6221:     OPC_SUB_D = FOP(1, FMT_D),
                   6222:     OPC_MUL_D = FOP(2, FMT_D),
                   6223:     OPC_DIV_D = FOP(3, FMT_D),
                   6224:     OPC_SQRT_D = FOP(4, FMT_D),
                   6225:     OPC_ABS_D = FOP(5, FMT_D),
                   6226:     OPC_MOV_D = FOP(6, FMT_D),
                   6227:     OPC_NEG_D = FOP(7, FMT_D),
                   6228:     OPC_ROUND_L_D = FOP(8, FMT_D),
                   6229:     OPC_TRUNC_L_D = FOP(9, FMT_D),
                   6230:     OPC_CEIL_L_D = FOP(10, FMT_D),
                   6231:     OPC_FLOOR_L_D = FOP(11, FMT_D),
                   6232:     OPC_ROUND_W_D = FOP(12, FMT_D),
                   6233:     OPC_TRUNC_W_D = FOP(13, FMT_D),
                   6234:     OPC_CEIL_W_D = FOP(14, FMT_D),
                   6235:     OPC_FLOOR_W_D = FOP(15, FMT_D),
                   6236:     OPC_MOVCF_D = FOP(17, FMT_D),
                   6237:     OPC_MOVZ_D = FOP(18, FMT_D),
                   6238:     OPC_MOVN_D = FOP(19, FMT_D),
                   6239:     OPC_RECIP_D = FOP(21, FMT_D),
                   6240:     OPC_RSQRT_D = FOP(22, FMT_D),
                   6241:     OPC_RECIP2_D = FOP(28, FMT_D),
                   6242:     OPC_RECIP1_D = FOP(29, FMT_D),
                   6243:     OPC_RSQRT1_D = FOP(30, FMT_D),
                   6244:     OPC_RSQRT2_D = FOP(31, FMT_D),
                   6245:     OPC_CVT_S_D = FOP(32, FMT_D),
                   6246:     OPC_CVT_W_D = FOP(36, FMT_D),
                   6247:     OPC_CVT_L_D = FOP(37, FMT_D),
                   6248:     OPC_CMP_F_D = FOP (48, FMT_D),
                   6249:     OPC_CMP_UN_D = FOP (49, FMT_D),
                   6250:     OPC_CMP_EQ_D = FOP (50, FMT_D),
                   6251:     OPC_CMP_UEQ_D = FOP (51, FMT_D),
                   6252:     OPC_CMP_OLT_D = FOP (52, FMT_D),
                   6253:     OPC_CMP_ULT_D = FOP (53, FMT_D),
                   6254:     OPC_CMP_OLE_D = FOP (54, FMT_D),
                   6255:     OPC_CMP_ULE_D = FOP (55, FMT_D),
                   6256:     OPC_CMP_SF_D = FOP (56, FMT_D),
                   6257:     OPC_CMP_NGLE_D = FOP (57, FMT_D),
                   6258:     OPC_CMP_SEQ_D = FOP (58, FMT_D),
                   6259:     OPC_CMP_NGL_D = FOP (59, FMT_D),
                   6260:     OPC_CMP_LT_D = FOP (60, FMT_D),
                   6261:     OPC_CMP_NGE_D = FOP (61, FMT_D),
                   6262:     OPC_CMP_LE_D = FOP (62, FMT_D),
                   6263:     OPC_CMP_NGT_D = FOP (63, FMT_D),
                   6264: 
                   6265:     OPC_CVT_S_W = FOP(32, FMT_W),
                   6266:     OPC_CVT_D_W = FOP(33, FMT_W),
                   6267:     OPC_CVT_S_L = FOP(32, FMT_L),
                   6268:     OPC_CVT_D_L = FOP(33, FMT_L),
                   6269:     OPC_CVT_PS_PW = FOP(38, FMT_W),
                   6270: 
                   6271:     OPC_ADD_PS = FOP(0, FMT_PS),
                   6272:     OPC_SUB_PS = FOP(1, FMT_PS),
                   6273:     OPC_MUL_PS = FOP(2, FMT_PS),
                   6274:     OPC_DIV_PS = FOP(3, FMT_PS),
                   6275:     OPC_ABS_PS = FOP(5, FMT_PS),
                   6276:     OPC_MOV_PS = FOP(6, FMT_PS),
                   6277:     OPC_NEG_PS = FOP(7, FMT_PS),
                   6278:     OPC_MOVCF_PS = FOP(17, FMT_PS),
                   6279:     OPC_MOVZ_PS = FOP(18, FMT_PS),
                   6280:     OPC_MOVN_PS = FOP(19, FMT_PS),
                   6281:     OPC_ADDR_PS = FOP(24, FMT_PS),
                   6282:     OPC_MULR_PS = FOP(26, FMT_PS),
                   6283:     OPC_RECIP2_PS = FOP(28, FMT_PS),
                   6284:     OPC_RECIP1_PS = FOP(29, FMT_PS),
                   6285:     OPC_RSQRT1_PS = FOP(30, FMT_PS),
                   6286:     OPC_RSQRT2_PS = FOP(31, FMT_PS),
                   6287: 
                   6288:     OPC_CVT_S_PU = FOP(32, FMT_PS),
                   6289:     OPC_CVT_PW_PS = FOP(36, FMT_PS),
                   6290:     OPC_CVT_S_PL = FOP(40, FMT_PS),
                   6291:     OPC_PLL_PS = FOP(44, FMT_PS),
                   6292:     OPC_PLU_PS = FOP(45, FMT_PS),
                   6293:     OPC_PUL_PS = FOP(46, FMT_PS),
                   6294:     OPC_PUU_PS = FOP(47, FMT_PS),
                   6295:     OPC_CMP_F_PS = FOP (48, FMT_PS),
                   6296:     OPC_CMP_UN_PS = FOP (49, FMT_PS),
                   6297:     OPC_CMP_EQ_PS = FOP (50, FMT_PS),
                   6298:     OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
                   6299:     OPC_CMP_OLT_PS = FOP (52, FMT_PS),
                   6300:     OPC_CMP_ULT_PS = FOP (53, FMT_PS),
                   6301:     OPC_CMP_OLE_PS = FOP (54, FMT_PS),
                   6302:     OPC_CMP_ULE_PS = FOP (55, FMT_PS),
                   6303:     OPC_CMP_SF_PS = FOP (56, FMT_PS),
                   6304:     OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
                   6305:     OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
                   6306:     OPC_CMP_NGL_PS = FOP (59, FMT_PS),
                   6307:     OPC_CMP_LT_PS = FOP (60, FMT_PS),
                   6308:     OPC_CMP_NGE_PS = FOP (61, FMT_PS),
                   6309:     OPC_CMP_LE_PS = FOP (62, FMT_PS),
                   6310:     OPC_CMP_NGT_PS = FOP (63, FMT_PS),
                   6311: };
                   6312: 
1.1.1.5   root     6313: static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
                   6314: {
1.1.1.6   root     6315:     const char *opn = "cp1 move";
1.1.1.8   root     6316:     TCGv t0 = tcg_temp_new();
1.1.1.5   root     6317: 
                   6318:     switch (opc) {
                   6319:     case OPC_MFC1:
1.1.1.7   root     6320:         {
                   6321:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6322: 
                   6323:             gen_load_fpr32(fp0, fs);
                   6324:             tcg_gen_ext_i32_tl(t0, fp0);
                   6325:             tcg_temp_free_i32(fp0);
                   6326:         }
                   6327:         gen_store_gpr(t0, rt);
1.1.1.5   root     6328:         opn = "mfc1";
                   6329:         break;
                   6330:     case OPC_MTC1:
1.1.1.7   root     6331:         gen_load_gpr(t0, rt);
                   6332:         {
                   6333:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6334: 
                   6335:             tcg_gen_trunc_tl_i32(fp0, t0);
                   6336:             gen_store_fpr32(fp0, fs);
                   6337:             tcg_temp_free_i32(fp0);
                   6338:         }
1.1.1.5   root     6339:         opn = "mtc1";
                   6340:         break;
                   6341:     case OPC_CFC1:
1.1.1.7   root     6342:         gen_helper_1i(cfc1, t0, fs);
                   6343:         gen_store_gpr(t0, rt);
1.1.1.5   root     6344:         opn = "cfc1";
                   6345:         break;
                   6346:     case OPC_CTC1:
1.1.1.7   root     6347:         gen_load_gpr(t0, rt);
                   6348:         gen_helper_1i(ctc1, t0, fs);
1.1.1.5   root     6349:         opn = "ctc1";
                   6350:         break;
1.1.1.8   root     6351: #if defined(TARGET_MIPS64)
1.1.1.5   root     6352:     case OPC_DMFC1:
1.1.1.8   root     6353:         gen_load_fpr64(ctx, t0, fs);
1.1.1.7   root     6354:         gen_store_gpr(t0, rt);
1.1.1.6   root     6355:         opn = "dmfc1";
                   6356:         break;
1.1.1.5   root     6357:     case OPC_DMTC1:
1.1.1.7   root     6358:         gen_load_gpr(t0, rt);
1.1.1.8   root     6359:         gen_store_fpr64(ctx, t0, fs);
1.1.1.6   root     6360:         opn = "dmtc1";
                   6361:         break;
1.1.1.8   root     6362: #endif
1.1.1.6   root     6363:     case OPC_MFHC1:
1.1.1.7   root     6364:         {
                   6365:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6366: 
                   6367:             gen_load_fpr32h(fp0, fs);
                   6368:             tcg_gen_ext_i32_tl(t0, fp0);
                   6369:             tcg_temp_free_i32(fp0);
                   6370:         }
                   6371:         gen_store_gpr(t0, rt);
1.1.1.6   root     6372:         opn = "mfhc1";
                   6373:         break;
                   6374:     case OPC_MTHC1:
1.1.1.7   root     6375:         gen_load_gpr(t0, rt);
                   6376:         {
                   6377:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6378: 
                   6379:             tcg_gen_trunc_tl_i32(fp0, t0);
                   6380:             gen_store_fpr32h(fp0, fs);
                   6381:             tcg_temp_free_i32(fp0);
                   6382:         }
1.1.1.6   root     6383:         opn = "mthc1";
                   6384:         break;
1.1.1.5   root     6385:     default:
1.1.1.6   root     6386:         MIPS_INVAL(opn);
                   6387:         generate_exception (ctx, EXCP_RI);
1.1.1.7   root     6388:         goto out;
1.1.1.4   root     6389:     }
1.1.1.13  root     6390:     (void)opn; /* avoid a compiler warning */
1.1.1.4   root     6391:     MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
1.1.1.7   root     6392: 
                   6393:  out:
                   6394:     tcg_temp_free(t0);
1.1.1.4   root     6395: }
                   6396: 
1.1.1.6   root     6397: static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
                   6398: {
1.1.1.8   root     6399:     int l1;
1.1.1.7   root     6400:     TCGCond cond;
1.1.1.8   root     6401:     TCGv_i32 t0;
                   6402: 
                   6403:     if (rd == 0) {
                   6404:         /* Treat as NOP. */
                   6405:         return;
                   6406:     }
1.1.1.7   root     6407: 
                   6408:     if (tf)
                   6409:         cond = TCG_COND_EQ;
                   6410:     else
                   6411:         cond = TCG_COND_NE;
                   6412: 
1.1.1.8   root     6413:     l1 = gen_new_label();
                   6414:     t0 = tcg_temp_new_i32();
                   6415:     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
                   6416:     tcg_gen_brcondi_i32(cond, t0, 0, l1);
                   6417:     tcg_temp_free_i32(t0);
                   6418:     if (rs == 0) {
                   6419:         tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   6420:     } else {
                   6421:         tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   6422:     }
1.1.1.7   root     6423:     gen_set_label(l1);
                   6424: }
                   6425: 
                   6426: static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
                   6427: {
                   6428:     int cond;
1.1.1.8   root     6429:     TCGv_i32 t0 = tcg_temp_new_i32();
1.1.1.7   root     6430:     int l1 = gen_new_label();
                   6431: 
                   6432:     if (tf)
                   6433:         cond = TCG_COND_EQ;
                   6434:     else
                   6435:         cond = TCG_COND_NE;
                   6436: 
1.1.1.8   root     6437:     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
                   6438:     tcg_gen_brcondi_i32(cond, t0, 0, l1);
                   6439:     gen_load_fpr32(t0, fs);
                   6440:     gen_store_fpr32(t0, fd);
1.1.1.7   root     6441:     gen_set_label(l1);
1.1.1.8   root     6442:     tcg_temp_free_i32(t0);
1.1.1.7   root     6443: }
                   6444: 
                   6445: static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
                   6446: {
                   6447:     int cond;
1.1.1.8   root     6448:     TCGv_i32 t0 = tcg_temp_new_i32();
                   6449:     TCGv_i64 fp0;
1.1.1.7   root     6450:     int l1 = gen_new_label();
                   6451: 
                   6452:     if (tf)
                   6453:         cond = TCG_COND_EQ;
                   6454:     else
                   6455:         cond = TCG_COND_NE;
                   6456: 
1.1.1.8   root     6457:     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
                   6458:     tcg_gen_brcondi_i32(cond, t0, 0, l1);
                   6459:     tcg_temp_free_i32(t0);
                   6460:     fp0 = tcg_temp_new_i64();
1.1.1.7   root     6461:     gen_load_fpr64(ctx, fp0, fs);
                   6462:     gen_store_fpr64(ctx, fp0, fd);
                   6463:     tcg_temp_free_i64(fp0);
1.1.1.8   root     6464:     gen_set_label(l1);
1.1.1.7   root     6465: }
                   6466: 
                   6467: static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
                   6468: {
                   6469:     int cond;
1.1.1.8   root     6470:     TCGv_i32 t0 = tcg_temp_new_i32();
1.1.1.7   root     6471:     int l1 = gen_new_label();
                   6472:     int l2 = gen_new_label();
1.1.1.4   root     6473: 
1.1.1.7   root     6474:     if (tf)
                   6475:         cond = TCG_COND_EQ;
1.1.1.6   root     6476:     else
1.1.1.7   root     6477:         cond = TCG_COND_NE;
                   6478: 
1.1.1.8   root     6479:     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
                   6480:     tcg_gen_brcondi_i32(cond, t0, 0, l1);
                   6481:     gen_load_fpr32(t0, fs);
                   6482:     gen_store_fpr32(t0, fd);
1.1.1.7   root     6483:     gen_set_label(l1);
                   6484: 
1.1.1.8   root     6485:     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
                   6486:     tcg_gen_brcondi_i32(cond, t0, 0, l2);
                   6487:     gen_load_fpr32h(t0, fs);
                   6488:     gen_store_fpr32h(t0, fd);
                   6489:     tcg_temp_free_i32(t0);
1.1.1.7   root     6490:     gen_set_label(l2);
1.1.1.6   root     6491: }
                   6492: 
1.1.1.4   root     6493: 
1.1.1.12  root     6494: static void gen_farith (DisasContext *ctx, enum fopcode op1,
1.1.1.6   root     6495:                         int ft, int fs, int fd, int cc)
1.1.1.4   root     6496: {
1.1.1.6   root     6497:     const char *opn = "farith";
1.1.1.4   root     6498:     const char *condnames[] = {
                   6499:             "c.f",
                   6500:             "c.un",
                   6501:             "c.eq",
                   6502:             "c.ueq",
                   6503:             "c.olt",
                   6504:             "c.ult",
                   6505:             "c.ole",
                   6506:             "c.ule",
                   6507:             "c.sf",
                   6508:             "c.ngle",
                   6509:             "c.seq",
                   6510:             "c.ngl",
                   6511:             "c.lt",
                   6512:             "c.nge",
                   6513:             "c.le",
                   6514:             "c.ngt",
                   6515:     };
1.1.1.6   root     6516:     const char *condnames_abs[] = {
                   6517:             "cabs.f",
                   6518:             "cabs.un",
                   6519:             "cabs.eq",
                   6520:             "cabs.ueq",
                   6521:             "cabs.olt",
                   6522:             "cabs.ult",
                   6523:             "cabs.ole",
                   6524:             "cabs.ule",
                   6525:             "cabs.sf",
                   6526:             "cabs.ngle",
                   6527:             "cabs.seq",
                   6528:             "cabs.ngl",
                   6529:             "cabs.lt",
                   6530:             "cabs.nge",
                   6531:             "cabs.le",
                   6532:             "cabs.ngt",
                   6533:     };
                   6534:     enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
1.1.1.5   root     6535:     uint32_t func = ctx->opcode & 0x3f;
                   6536: 
1.1.1.12  root     6537:     switch (op1) {
                   6538:     case OPC_ADD_S:
1.1.1.7   root     6539:         {
                   6540:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6541:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   6542: 
                   6543:             gen_load_fpr32(fp0, fs);
                   6544:             gen_load_fpr32(fp1, ft);
                   6545:             gen_helper_float_add_s(fp0, fp0, fp1);
                   6546:             tcg_temp_free_i32(fp1);
                   6547:             gen_store_fpr32(fp0, fd);
                   6548:             tcg_temp_free_i32(fp0);
                   6549:         }
1.1.1.6   root     6550:         opn = "add.s";
                   6551:         optype = BINOP;
                   6552:         break;
1.1.1.12  root     6553:     case OPC_SUB_S:
1.1.1.7   root     6554:         {
                   6555:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6556:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   6557: 
                   6558:             gen_load_fpr32(fp0, fs);
                   6559:             gen_load_fpr32(fp1, ft);
                   6560:             gen_helper_float_sub_s(fp0, fp0, fp1);
                   6561:             tcg_temp_free_i32(fp1);
                   6562:             gen_store_fpr32(fp0, fd);
                   6563:             tcg_temp_free_i32(fp0);
                   6564:         }
1.1.1.6   root     6565:         opn = "sub.s";
                   6566:         optype = BINOP;
                   6567:         break;
1.1.1.12  root     6568:     case OPC_MUL_S:
1.1.1.7   root     6569:         {
                   6570:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6571:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   6572: 
                   6573:             gen_load_fpr32(fp0, fs);
                   6574:             gen_load_fpr32(fp1, ft);
                   6575:             gen_helper_float_mul_s(fp0, fp0, fp1);
                   6576:             tcg_temp_free_i32(fp1);
                   6577:             gen_store_fpr32(fp0, fd);
                   6578:             tcg_temp_free_i32(fp0);
                   6579:         }
1.1.1.6   root     6580:         opn = "mul.s";
                   6581:         optype = BINOP;
                   6582:         break;
1.1.1.12  root     6583:     case OPC_DIV_S:
1.1.1.7   root     6584:         {
                   6585:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6586:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   6587: 
                   6588:             gen_load_fpr32(fp0, fs);
                   6589:             gen_load_fpr32(fp1, ft);
                   6590:             gen_helper_float_div_s(fp0, fp0, fp1);
                   6591:             tcg_temp_free_i32(fp1);
                   6592:             gen_store_fpr32(fp0, fd);
                   6593:             tcg_temp_free_i32(fp0);
                   6594:         }
1.1.1.6   root     6595:         opn = "div.s";
                   6596:         optype = BINOP;
                   6597:         break;
1.1.1.12  root     6598:     case OPC_SQRT_S:
1.1.1.7   root     6599:         {
                   6600:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6601: 
                   6602:             gen_load_fpr32(fp0, fs);
                   6603:             gen_helper_float_sqrt_s(fp0, fp0);
                   6604:             gen_store_fpr32(fp0, fd);
                   6605:             tcg_temp_free_i32(fp0);
                   6606:         }
1.1.1.6   root     6607:         opn = "sqrt.s";
                   6608:         break;
1.1.1.12  root     6609:     case OPC_ABS_S:
1.1.1.7   root     6610:         {
                   6611:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6612: 
                   6613:             gen_load_fpr32(fp0, fs);
                   6614:             gen_helper_float_abs_s(fp0, fp0);
                   6615:             gen_store_fpr32(fp0, fd);
                   6616:             tcg_temp_free_i32(fp0);
                   6617:         }
1.1.1.6   root     6618:         opn = "abs.s";
                   6619:         break;
1.1.1.12  root     6620:     case OPC_MOV_S:
1.1.1.7   root     6621:         {
                   6622:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6623: 
                   6624:             gen_load_fpr32(fp0, fs);
                   6625:             gen_store_fpr32(fp0, fd);
                   6626:             tcg_temp_free_i32(fp0);
                   6627:         }
1.1.1.6   root     6628:         opn = "mov.s";
                   6629:         break;
1.1.1.12  root     6630:     case OPC_NEG_S:
1.1.1.7   root     6631:         {
                   6632:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6633: 
                   6634:             gen_load_fpr32(fp0, fs);
                   6635:             gen_helper_float_chs_s(fp0, fp0);
                   6636:             gen_store_fpr32(fp0, fd);
                   6637:             tcg_temp_free_i32(fp0);
                   6638:         }
1.1.1.6   root     6639:         opn = "neg.s";
                   6640:         break;
1.1.1.12  root     6641:     case OPC_ROUND_L_S:
1.1.1.6   root     6642:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6643:         {
                   6644:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   6645:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   6646: 
                   6647:             gen_load_fpr32(fp32, fs);
                   6648:             gen_helper_float_roundl_s(fp64, fp32);
                   6649:             tcg_temp_free_i32(fp32);
                   6650:             gen_store_fpr64(ctx, fp64, fd);
                   6651:             tcg_temp_free_i64(fp64);
                   6652:         }
1.1.1.6   root     6653:         opn = "round.l.s";
                   6654:         break;
1.1.1.12  root     6655:     case OPC_TRUNC_L_S:
1.1.1.6   root     6656:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6657:         {
                   6658:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   6659:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   6660: 
                   6661:             gen_load_fpr32(fp32, fs);
                   6662:             gen_helper_float_truncl_s(fp64, fp32);
                   6663:             tcg_temp_free_i32(fp32);
                   6664:             gen_store_fpr64(ctx, fp64, fd);
                   6665:             tcg_temp_free_i64(fp64);
                   6666:         }
1.1.1.6   root     6667:         opn = "trunc.l.s";
                   6668:         break;
1.1.1.12  root     6669:     case OPC_CEIL_L_S:
1.1.1.6   root     6670:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6671:         {
                   6672:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   6673:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   6674: 
                   6675:             gen_load_fpr32(fp32, fs);
                   6676:             gen_helper_float_ceill_s(fp64, fp32);
                   6677:             tcg_temp_free_i32(fp32);
                   6678:             gen_store_fpr64(ctx, fp64, fd);
                   6679:             tcg_temp_free_i64(fp64);
                   6680:         }
1.1.1.6   root     6681:         opn = "ceil.l.s";
                   6682:         break;
1.1.1.12  root     6683:     case OPC_FLOOR_L_S:
1.1.1.6   root     6684:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6685:         {
                   6686:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   6687:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   6688: 
                   6689:             gen_load_fpr32(fp32, fs);
                   6690:             gen_helper_float_floorl_s(fp64, fp32);
                   6691:             tcg_temp_free_i32(fp32);
                   6692:             gen_store_fpr64(ctx, fp64, fd);
                   6693:             tcg_temp_free_i64(fp64);
                   6694:         }
1.1.1.6   root     6695:         opn = "floor.l.s";
                   6696:         break;
1.1.1.12  root     6697:     case OPC_ROUND_W_S:
1.1.1.7   root     6698:         {
                   6699:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6700: 
                   6701:             gen_load_fpr32(fp0, fs);
                   6702:             gen_helper_float_roundw_s(fp0, fp0);
                   6703:             gen_store_fpr32(fp0, fd);
                   6704:             tcg_temp_free_i32(fp0);
                   6705:         }
1.1.1.6   root     6706:         opn = "round.w.s";
                   6707:         break;
1.1.1.12  root     6708:     case OPC_TRUNC_W_S:
1.1.1.7   root     6709:         {
                   6710:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6711: 
                   6712:             gen_load_fpr32(fp0, fs);
                   6713:             gen_helper_float_truncw_s(fp0, fp0);
                   6714:             gen_store_fpr32(fp0, fd);
                   6715:             tcg_temp_free_i32(fp0);
                   6716:         }
1.1.1.6   root     6717:         opn = "trunc.w.s";
                   6718:         break;
1.1.1.12  root     6719:     case OPC_CEIL_W_S:
1.1.1.7   root     6720:         {
                   6721:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6722: 
                   6723:             gen_load_fpr32(fp0, fs);
                   6724:             gen_helper_float_ceilw_s(fp0, fp0);
                   6725:             gen_store_fpr32(fp0, fd);
                   6726:             tcg_temp_free_i32(fp0);
                   6727:         }
1.1.1.6   root     6728:         opn = "ceil.w.s";
                   6729:         break;
1.1.1.12  root     6730:     case OPC_FLOOR_W_S:
1.1.1.7   root     6731:         {
                   6732:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6733: 
                   6734:             gen_load_fpr32(fp0, fs);
                   6735:             gen_helper_float_floorw_s(fp0, fp0);
                   6736:             gen_store_fpr32(fp0, fd);
                   6737:             tcg_temp_free_i32(fp0);
                   6738:         }
1.1.1.6   root     6739:         opn = "floor.w.s";
                   6740:         break;
1.1.1.12  root     6741:     case OPC_MOVCF_S:
1.1.1.7   root     6742:         gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
1.1.1.6   root     6743:         opn = "movcf.s";
                   6744:         break;
1.1.1.12  root     6745:     case OPC_MOVZ_S:
1.1.1.7   root     6746:         {
                   6747:             int l1 = gen_new_label();
1.1.1.8   root     6748:             TCGv_i32 fp0;
1.1.1.7   root     6749: 
1.1.1.8   root     6750:             if (ft != 0) {
                   6751:                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
                   6752:             }
                   6753:             fp0 = tcg_temp_new_i32();
1.1.1.7   root     6754:             gen_load_fpr32(fp0, fs);
                   6755:             gen_store_fpr32(fp0, fd);
                   6756:             tcg_temp_free_i32(fp0);
                   6757:             gen_set_label(l1);
                   6758:         }
1.1.1.6   root     6759:         opn = "movz.s";
                   6760:         break;
1.1.1.12  root     6761:     case OPC_MOVN_S:
1.1.1.7   root     6762:         {
                   6763:             int l1 = gen_new_label();
1.1.1.8   root     6764:             TCGv_i32 fp0;
1.1.1.7   root     6765: 
1.1.1.8   root     6766:             if (ft != 0) {
                   6767:                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
                   6768:                 fp0 = tcg_temp_new_i32();
                   6769:                 gen_load_fpr32(fp0, fs);
                   6770:                 gen_store_fpr32(fp0, fd);
                   6771:                 tcg_temp_free_i32(fp0);
                   6772:                 gen_set_label(l1);
                   6773:             }
1.1.1.7   root     6774:         }
1.1.1.6   root     6775:         opn = "movn.s";
                   6776:         break;
1.1.1.12  root     6777:     case OPC_RECIP_S:
1.1.1.6   root     6778:         check_cop1x(ctx);
1.1.1.7   root     6779:         {
                   6780:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6781: 
                   6782:             gen_load_fpr32(fp0, fs);
                   6783:             gen_helper_float_recip_s(fp0, fp0);
                   6784:             gen_store_fpr32(fp0, fd);
                   6785:             tcg_temp_free_i32(fp0);
                   6786:         }
1.1.1.6   root     6787:         opn = "recip.s";
                   6788:         break;
1.1.1.12  root     6789:     case OPC_RSQRT_S:
1.1.1.6   root     6790:         check_cop1x(ctx);
1.1.1.7   root     6791:         {
                   6792:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6793: 
                   6794:             gen_load_fpr32(fp0, fs);
                   6795:             gen_helper_float_rsqrt_s(fp0, fp0);
                   6796:             gen_store_fpr32(fp0, fd);
                   6797:             tcg_temp_free_i32(fp0);
                   6798:         }
1.1.1.6   root     6799:         opn = "rsqrt.s";
                   6800:         break;
1.1.1.12  root     6801:     case OPC_RECIP2_S:
1.1.1.6   root     6802:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6803:         {
                   6804:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6805:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   6806: 
                   6807:             gen_load_fpr32(fp0, fs);
                   6808:             gen_load_fpr32(fp1, fd);
                   6809:             gen_helper_float_recip2_s(fp0, fp0, fp1);
                   6810:             tcg_temp_free_i32(fp1);
                   6811:             gen_store_fpr32(fp0, fd);
                   6812:             tcg_temp_free_i32(fp0);
                   6813:         }
1.1.1.6   root     6814:         opn = "recip2.s";
                   6815:         break;
1.1.1.12  root     6816:     case OPC_RECIP1_S:
1.1.1.6   root     6817:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6818:         {
                   6819:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6820: 
                   6821:             gen_load_fpr32(fp0, fs);
                   6822:             gen_helper_float_recip1_s(fp0, fp0);
                   6823:             gen_store_fpr32(fp0, fd);
                   6824:             tcg_temp_free_i32(fp0);
                   6825:         }
1.1.1.6   root     6826:         opn = "recip1.s";
                   6827:         break;
1.1.1.12  root     6828:     case OPC_RSQRT1_S:
1.1.1.6   root     6829:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6830:         {
                   6831:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6832: 
                   6833:             gen_load_fpr32(fp0, fs);
                   6834:             gen_helper_float_rsqrt1_s(fp0, fp0);
                   6835:             gen_store_fpr32(fp0, fd);
                   6836:             tcg_temp_free_i32(fp0);
                   6837:         }
1.1.1.6   root     6838:         opn = "rsqrt1.s";
                   6839:         break;
1.1.1.12  root     6840:     case OPC_RSQRT2_S:
1.1.1.6   root     6841:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6842:         {
                   6843:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6844:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   6845: 
                   6846:             gen_load_fpr32(fp0, fs);
                   6847:             gen_load_fpr32(fp1, ft);
                   6848:             gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
                   6849:             tcg_temp_free_i32(fp1);
                   6850:             gen_store_fpr32(fp0, fd);
                   6851:             tcg_temp_free_i32(fp0);
                   6852:         }
1.1.1.6   root     6853:         opn = "rsqrt2.s";
                   6854:         break;
1.1.1.12  root     6855:     case OPC_CVT_D_S:
1.1.1.6   root     6856:         check_cp1_registers(ctx, fd);
1.1.1.7   root     6857:         {
                   6858:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   6859:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   6860: 
                   6861:             gen_load_fpr32(fp32, fs);
                   6862:             gen_helper_float_cvtd_s(fp64, fp32);
                   6863:             tcg_temp_free_i32(fp32);
                   6864:             gen_store_fpr64(ctx, fp64, fd);
                   6865:             tcg_temp_free_i64(fp64);
                   6866:         }
1.1.1.6   root     6867:         opn = "cvt.d.s";
                   6868:         break;
1.1.1.12  root     6869:     case OPC_CVT_W_S:
1.1.1.7   root     6870:         {
                   6871:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6872: 
                   6873:             gen_load_fpr32(fp0, fs);
                   6874:             gen_helper_float_cvtw_s(fp0, fp0);
                   6875:             gen_store_fpr32(fp0, fd);
                   6876:             tcg_temp_free_i32(fp0);
                   6877:         }
1.1.1.6   root     6878:         opn = "cvt.w.s";
                   6879:         break;
1.1.1.12  root     6880:     case OPC_CVT_L_S:
1.1.1.6   root     6881:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6882:         {
                   6883:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   6884:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   6885: 
                   6886:             gen_load_fpr32(fp32, fs);
                   6887:             gen_helper_float_cvtl_s(fp64, fp32);
                   6888:             tcg_temp_free_i32(fp32);
                   6889:             gen_store_fpr64(ctx, fp64, fd);
                   6890:             tcg_temp_free_i64(fp64);
                   6891:         }
1.1.1.6   root     6892:         opn = "cvt.l.s";
                   6893:         break;
1.1.1.12  root     6894:     case OPC_CVT_PS_S:
1.1.1.6   root     6895:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6896:         {
                   6897:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   6898:             TCGv_i32 fp32_0 = tcg_temp_new_i32();
                   6899:             TCGv_i32 fp32_1 = tcg_temp_new_i32();
                   6900: 
                   6901:             gen_load_fpr32(fp32_0, fs);
                   6902:             gen_load_fpr32(fp32_1, ft);
                   6903:             tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
                   6904:             tcg_temp_free_i32(fp32_1);
                   6905:             tcg_temp_free_i32(fp32_0);
                   6906:             gen_store_fpr64(ctx, fp64, fd);
                   6907:             tcg_temp_free_i64(fp64);
                   6908:         }
1.1.1.6   root     6909:         opn = "cvt.ps.s";
                   6910:         break;
1.1.1.12  root     6911:     case OPC_CMP_F_S:
                   6912:     case OPC_CMP_UN_S:
                   6913:     case OPC_CMP_EQ_S:
                   6914:     case OPC_CMP_UEQ_S:
                   6915:     case OPC_CMP_OLT_S:
                   6916:     case OPC_CMP_ULT_S:
                   6917:     case OPC_CMP_OLE_S:
                   6918:     case OPC_CMP_ULE_S:
                   6919:     case OPC_CMP_SF_S:
                   6920:     case OPC_CMP_NGLE_S:
                   6921:     case OPC_CMP_SEQ_S:
                   6922:     case OPC_CMP_NGL_S:
                   6923:     case OPC_CMP_LT_S:
                   6924:     case OPC_CMP_NGE_S:
                   6925:     case OPC_CMP_LE_S:
                   6926:     case OPC_CMP_NGT_S:
                   6927:         if (ctx->opcode & (1 << 6)) {
                   6928:             gen_cmpabs_s(ctx, func-48, ft, fs, cc);
                   6929:             opn = condnames_abs[func-48];
                   6930:         } else {
                   6931:             gen_cmp_s(ctx, func-48, ft, fs, cc);
                   6932:             opn = condnames[func-48];
1.1.1.6   root     6933:         }
                   6934:         break;
1.1.1.12  root     6935:     case OPC_ADD_D:
1.1.1.6   root     6936:         check_cp1_registers(ctx, fs | ft | fd);
1.1.1.7   root     6937:         {
                   6938:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6939:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   6940: 
                   6941:             gen_load_fpr64(ctx, fp0, fs);
                   6942:             gen_load_fpr64(ctx, fp1, ft);
                   6943:             gen_helper_float_add_d(fp0, fp0, fp1);
                   6944:             tcg_temp_free_i64(fp1);
                   6945:             gen_store_fpr64(ctx, fp0, fd);
                   6946:             tcg_temp_free_i64(fp0);
                   6947:         }
1.1.1.4   root     6948:         opn = "add.d";
1.1.1.6   root     6949:         optype = BINOP;
1.1.1.4   root     6950:         break;
1.1.1.12  root     6951:     case OPC_SUB_D:
1.1.1.6   root     6952:         check_cp1_registers(ctx, fs | ft | fd);
1.1.1.7   root     6953:         {
                   6954:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6955:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   6956: 
                   6957:             gen_load_fpr64(ctx, fp0, fs);
                   6958:             gen_load_fpr64(ctx, fp1, ft);
                   6959:             gen_helper_float_sub_d(fp0, fp0, fp1);
                   6960:             tcg_temp_free_i64(fp1);
                   6961:             gen_store_fpr64(ctx, fp0, fd);
                   6962:             tcg_temp_free_i64(fp0);
                   6963:         }
1.1.1.4   root     6964:         opn = "sub.d";
1.1.1.6   root     6965:         optype = BINOP;
1.1.1.4   root     6966:         break;
1.1.1.12  root     6967:     case OPC_MUL_D:
1.1.1.6   root     6968:         check_cp1_registers(ctx, fs | ft | fd);
1.1.1.7   root     6969:         {
                   6970:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6971:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   6972: 
                   6973:             gen_load_fpr64(ctx, fp0, fs);
                   6974:             gen_load_fpr64(ctx, fp1, ft);
                   6975:             gen_helper_float_mul_d(fp0, fp0, fp1);
                   6976:             tcg_temp_free_i64(fp1);
                   6977:             gen_store_fpr64(ctx, fp0, fd);
                   6978:             tcg_temp_free_i64(fp0);
                   6979:         }
1.1.1.4   root     6980:         opn = "mul.d";
1.1.1.6   root     6981:         optype = BINOP;
1.1.1.4   root     6982:         break;
1.1.1.12  root     6983:     case OPC_DIV_D:
1.1.1.6   root     6984:         check_cp1_registers(ctx, fs | ft | fd);
1.1.1.7   root     6985:         {
                   6986:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6987:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   6988: 
                   6989:             gen_load_fpr64(ctx, fp0, fs);
                   6990:             gen_load_fpr64(ctx, fp1, ft);
                   6991:             gen_helper_float_div_d(fp0, fp0, fp1);
                   6992:             tcg_temp_free_i64(fp1);
                   6993:             gen_store_fpr64(ctx, fp0, fd);
                   6994:             tcg_temp_free_i64(fp0);
                   6995:         }
1.1.1.4   root     6996:         opn = "div.d";
1.1.1.6   root     6997:         optype = BINOP;
1.1.1.4   root     6998:         break;
1.1.1.12  root     6999:     case OPC_SQRT_D:
1.1.1.6   root     7000:         check_cp1_registers(ctx, fs | fd);
1.1.1.7   root     7001:         {
                   7002:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7003: 
                   7004:             gen_load_fpr64(ctx, fp0, fs);
                   7005:             gen_helper_float_sqrt_d(fp0, fp0);
                   7006:             gen_store_fpr64(ctx, fp0, fd);
                   7007:             tcg_temp_free_i64(fp0);
                   7008:         }
1.1.1.4   root     7009:         opn = "sqrt.d";
                   7010:         break;
1.1.1.12  root     7011:     case OPC_ABS_D:
1.1.1.6   root     7012:         check_cp1_registers(ctx, fs | fd);
1.1.1.7   root     7013:         {
                   7014:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7015: 
                   7016:             gen_load_fpr64(ctx, fp0, fs);
                   7017:             gen_helper_float_abs_d(fp0, fp0);
                   7018:             gen_store_fpr64(ctx, fp0, fd);
                   7019:             tcg_temp_free_i64(fp0);
                   7020:         }
1.1.1.4   root     7021:         opn = "abs.d";
                   7022:         break;
1.1.1.12  root     7023:     case OPC_MOV_D:
1.1.1.6   root     7024:         check_cp1_registers(ctx, fs | fd);
1.1.1.7   root     7025:         {
                   7026:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7027: 
                   7028:             gen_load_fpr64(ctx, fp0, fs);
                   7029:             gen_store_fpr64(ctx, fp0, fd);
                   7030:             tcg_temp_free_i64(fp0);
                   7031:         }
1.1.1.4   root     7032:         opn = "mov.d";
                   7033:         break;
1.1.1.12  root     7034:     case OPC_NEG_D:
1.1.1.6   root     7035:         check_cp1_registers(ctx, fs | fd);
1.1.1.7   root     7036:         {
                   7037:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7038: 
                   7039:             gen_load_fpr64(ctx, fp0, fs);
                   7040:             gen_helper_float_chs_d(fp0, fp0);
                   7041:             gen_store_fpr64(ctx, fp0, fd);
                   7042:             tcg_temp_free_i64(fp0);
                   7043:         }
1.1.1.4   root     7044:         opn = "neg.d";
                   7045:         break;
1.1.1.12  root     7046:     case OPC_ROUND_L_D:
1.1.1.6   root     7047:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7048:         {
                   7049:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7050: 
                   7051:             gen_load_fpr64(ctx, fp0, fs);
                   7052:             gen_helper_float_roundl_d(fp0, fp0);
                   7053:             gen_store_fpr64(ctx, fp0, fd);
                   7054:             tcg_temp_free_i64(fp0);
                   7055:         }
1.1.1.6   root     7056:         opn = "round.l.d";
                   7057:         break;
1.1.1.12  root     7058:     case OPC_TRUNC_L_D:
1.1.1.6   root     7059:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7060:         {
                   7061:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7062: 
                   7063:             gen_load_fpr64(ctx, fp0, fs);
                   7064:             gen_helper_float_truncl_d(fp0, fp0);
                   7065:             gen_store_fpr64(ctx, fp0, fd);
                   7066:             tcg_temp_free_i64(fp0);
                   7067:         }
1.1.1.6   root     7068:         opn = "trunc.l.d";
                   7069:         break;
1.1.1.12  root     7070:     case OPC_CEIL_L_D:
1.1.1.6   root     7071:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7072:         {
                   7073:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7074: 
                   7075:             gen_load_fpr64(ctx, fp0, fs);
                   7076:             gen_helper_float_ceill_d(fp0, fp0);
                   7077:             gen_store_fpr64(ctx, fp0, fd);
                   7078:             tcg_temp_free_i64(fp0);
                   7079:         }
1.1.1.6   root     7080:         opn = "ceil.l.d";
                   7081:         break;
1.1.1.12  root     7082:     case OPC_FLOOR_L_D:
1.1.1.6   root     7083:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7084:         {
                   7085:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7086: 
                   7087:             gen_load_fpr64(ctx, fp0, fs);
                   7088:             gen_helper_float_floorl_d(fp0, fp0);
                   7089:             gen_store_fpr64(ctx, fp0, fd);
                   7090:             tcg_temp_free_i64(fp0);
                   7091:         }
1.1.1.6   root     7092:         opn = "floor.l.d";
                   7093:         break;
1.1.1.12  root     7094:     case OPC_ROUND_W_D:
1.1.1.6   root     7095:         check_cp1_registers(ctx, fs);
1.1.1.7   root     7096:         {
                   7097:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   7098:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   7099: 
                   7100:             gen_load_fpr64(ctx, fp64, fs);
                   7101:             gen_helper_float_roundw_d(fp32, fp64);
                   7102:             tcg_temp_free_i64(fp64);
                   7103:             gen_store_fpr32(fp32, fd);
                   7104:             tcg_temp_free_i32(fp32);
                   7105:         }
1.1.1.4   root     7106:         opn = "round.w.d";
                   7107:         break;
1.1.1.12  root     7108:     case OPC_TRUNC_W_D:
1.1.1.6   root     7109:         check_cp1_registers(ctx, fs);
1.1.1.7   root     7110:         {
                   7111:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   7112:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   7113: 
                   7114:             gen_load_fpr64(ctx, fp64, fs);
                   7115:             gen_helper_float_truncw_d(fp32, fp64);
                   7116:             tcg_temp_free_i64(fp64);
                   7117:             gen_store_fpr32(fp32, fd);
                   7118:             tcg_temp_free_i32(fp32);
                   7119:         }
1.1.1.4   root     7120:         opn = "trunc.w.d";
                   7121:         break;
1.1.1.12  root     7122:     case OPC_CEIL_W_D:
1.1.1.6   root     7123:         check_cp1_registers(ctx, fs);
1.1.1.7   root     7124:         {
                   7125:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   7126:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   7127: 
                   7128:             gen_load_fpr64(ctx, fp64, fs);
                   7129:             gen_helper_float_ceilw_d(fp32, fp64);
                   7130:             tcg_temp_free_i64(fp64);
                   7131:             gen_store_fpr32(fp32, fd);
                   7132:             tcg_temp_free_i32(fp32);
                   7133:         }
1.1.1.4   root     7134:         opn = "ceil.w.d";
                   7135:         break;
1.1.1.12  root     7136:     case OPC_FLOOR_W_D:
1.1.1.6   root     7137:         check_cp1_registers(ctx, fs);
1.1.1.7   root     7138:         {
                   7139:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   7140:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   7141: 
                   7142:             gen_load_fpr64(ctx, fp64, fs);
                   7143:             gen_helper_float_floorw_d(fp32, fp64);
                   7144:             tcg_temp_free_i64(fp64);
                   7145:             gen_store_fpr32(fp32, fd);
                   7146:             tcg_temp_free_i32(fp32);
                   7147:         }
1.1.1.5   root     7148:         opn = "floor.w.d";
                   7149:         break;
1.1.1.12  root     7150:     case OPC_MOVCF_D:
1.1.1.7   root     7151:         gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
1.1.1.6   root     7152:         opn = "movcf.d";
1.1.1.4   root     7153:         break;
1.1.1.12  root     7154:     case OPC_MOVZ_D:
1.1.1.7   root     7155:         {
                   7156:             int l1 = gen_new_label();
1.1.1.8   root     7157:             TCGv_i64 fp0;
1.1.1.7   root     7158: 
1.1.1.8   root     7159:             if (ft != 0) {
                   7160:                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
                   7161:             }
                   7162:             fp0 = tcg_temp_new_i64();
1.1.1.7   root     7163:             gen_load_fpr64(ctx, fp0, fs);
                   7164:             gen_store_fpr64(ctx, fp0, fd);
                   7165:             tcg_temp_free_i64(fp0);
                   7166:             gen_set_label(l1);
                   7167:         }
1.1.1.6   root     7168:         opn = "movz.d";
                   7169:         break;
1.1.1.12  root     7170:     case OPC_MOVN_D:
1.1.1.7   root     7171:         {
                   7172:             int l1 = gen_new_label();
1.1.1.8   root     7173:             TCGv_i64 fp0;
1.1.1.7   root     7174: 
1.1.1.8   root     7175:             if (ft != 0) {
                   7176:                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
                   7177:                 fp0 = tcg_temp_new_i64();
                   7178:                 gen_load_fpr64(ctx, fp0, fs);
                   7179:                 gen_store_fpr64(ctx, fp0, fd);
                   7180:                 tcg_temp_free_i64(fp0);
                   7181:                 gen_set_label(l1);
                   7182:             }
1.1.1.7   root     7183:         }
1.1.1.6   root     7184:         opn = "movn.d";
                   7185:         break;
1.1.1.12  root     7186:     case OPC_RECIP_D:
1.1.1.6   root     7187:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7188:         {
                   7189:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7190: 
                   7191:             gen_load_fpr64(ctx, fp0, fs);
                   7192:             gen_helper_float_recip_d(fp0, fp0);
                   7193:             gen_store_fpr64(ctx, fp0, fd);
                   7194:             tcg_temp_free_i64(fp0);
                   7195:         }
1.1.1.6   root     7196:         opn = "recip.d";
                   7197:         break;
1.1.1.12  root     7198:     case OPC_RSQRT_D:
1.1.1.6   root     7199:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7200:         {
                   7201:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7202: 
                   7203:             gen_load_fpr64(ctx, fp0, fs);
                   7204:             gen_helper_float_rsqrt_d(fp0, fp0);
                   7205:             gen_store_fpr64(ctx, fp0, fd);
                   7206:             tcg_temp_free_i64(fp0);
                   7207:         }
1.1.1.6   root     7208:         opn = "rsqrt.d";
                   7209:         break;
1.1.1.12  root     7210:     case OPC_RECIP2_D:
1.1.1.6   root     7211:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7212:         {
                   7213:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7214:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7215: 
                   7216:             gen_load_fpr64(ctx, fp0, fs);
                   7217:             gen_load_fpr64(ctx, fp1, ft);
                   7218:             gen_helper_float_recip2_d(fp0, fp0, fp1);
                   7219:             tcg_temp_free_i64(fp1);
                   7220:             gen_store_fpr64(ctx, fp0, fd);
                   7221:             tcg_temp_free_i64(fp0);
                   7222:         }
1.1.1.6   root     7223:         opn = "recip2.d";
                   7224:         break;
1.1.1.12  root     7225:     case OPC_RECIP1_D:
1.1.1.6   root     7226:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7227:         {
                   7228:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7229: 
                   7230:             gen_load_fpr64(ctx, fp0, fs);
                   7231:             gen_helper_float_recip1_d(fp0, fp0);
                   7232:             gen_store_fpr64(ctx, fp0, fd);
                   7233:             tcg_temp_free_i64(fp0);
                   7234:         }
1.1.1.6   root     7235:         opn = "recip1.d";
                   7236:         break;
1.1.1.12  root     7237:     case OPC_RSQRT1_D:
1.1.1.6   root     7238:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7239:         {
                   7240:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7241: 
                   7242:             gen_load_fpr64(ctx, fp0, fs);
                   7243:             gen_helper_float_rsqrt1_d(fp0, fp0);
                   7244:             gen_store_fpr64(ctx, fp0, fd);
                   7245:             tcg_temp_free_i64(fp0);
                   7246:         }
1.1.1.6   root     7247:         opn = "rsqrt1.d";
                   7248:         break;
1.1.1.12  root     7249:     case OPC_RSQRT2_D:
1.1.1.6   root     7250:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7251:         {
                   7252:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7253:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7254: 
                   7255:             gen_load_fpr64(ctx, fp0, fs);
                   7256:             gen_load_fpr64(ctx, fp1, ft);
                   7257:             gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
                   7258:             tcg_temp_free_i64(fp1);
                   7259:             gen_store_fpr64(ctx, fp0, fd);
                   7260:             tcg_temp_free_i64(fp0);
                   7261:         }
1.1.1.6   root     7262:         opn = "rsqrt2.d";
1.1.1.4   root     7263:         break;
1.1.1.12  root     7264:     case OPC_CMP_F_D:
                   7265:     case OPC_CMP_UN_D:
                   7266:     case OPC_CMP_EQ_D:
                   7267:     case OPC_CMP_UEQ_D:
                   7268:     case OPC_CMP_OLT_D:
                   7269:     case OPC_CMP_ULT_D:
                   7270:     case OPC_CMP_OLE_D:
                   7271:     case OPC_CMP_ULE_D:
                   7272:     case OPC_CMP_SF_D:
                   7273:     case OPC_CMP_NGLE_D:
                   7274:     case OPC_CMP_SEQ_D:
                   7275:     case OPC_CMP_NGL_D:
                   7276:     case OPC_CMP_LT_D:
                   7277:     case OPC_CMP_NGE_D:
                   7278:     case OPC_CMP_LE_D:
                   7279:     case OPC_CMP_NGT_D:
                   7280:         if (ctx->opcode & (1 << 6)) {
                   7281:             gen_cmpabs_d(ctx, func-48, ft, fs, cc);
                   7282:             opn = condnames_abs[func-48];
                   7283:         } else {
                   7284:             gen_cmp_d(ctx, func-48, ft, fs, cc);
                   7285:             opn = condnames[func-48];
1.1.1.6   root     7286:         }
                   7287:         break;
1.1.1.12  root     7288:     case OPC_CVT_S_D:
1.1.1.6   root     7289:         check_cp1_registers(ctx, fs);
1.1.1.7   root     7290:         {
                   7291:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   7292:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   7293: 
                   7294:             gen_load_fpr64(ctx, fp64, fs);
                   7295:             gen_helper_float_cvts_d(fp32, fp64);
                   7296:             tcg_temp_free_i64(fp64);
                   7297:             gen_store_fpr32(fp32, fd);
                   7298:             tcg_temp_free_i32(fp32);
                   7299:         }
1.1.1.6   root     7300:         opn = "cvt.s.d";
                   7301:         break;
1.1.1.12  root     7302:     case OPC_CVT_W_D:
1.1.1.6   root     7303:         check_cp1_registers(ctx, fs);
1.1.1.7   root     7304:         {
                   7305:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   7306:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   7307: 
                   7308:             gen_load_fpr64(ctx, fp64, fs);
                   7309:             gen_helper_float_cvtw_d(fp32, fp64);
                   7310:             tcg_temp_free_i64(fp64);
                   7311:             gen_store_fpr32(fp32, fd);
                   7312:             tcg_temp_free_i32(fp32);
                   7313:         }
1.1.1.6   root     7314:         opn = "cvt.w.d";
                   7315:         break;
1.1.1.12  root     7316:     case OPC_CVT_L_D:
1.1.1.6   root     7317:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7318:         {
                   7319:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7320: 
                   7321:             gen_load_fpr64(ctx, fp0, fs);
                   7322:             gen_helper_float_cvtl_d(fp0, fp0);
                   7323:             gen_store_fpr64(ctx, fp0, fd);
                   7324:             tcg_temp_free_i64(fp0);
                   7325:         }
1.1.1.6   root     7326:         opn = "cvt.l.d";
                   7327:         break;
1.1.1.12  root     7328:     case OPC_CVT_S_W:
1.1.1.7   root     7329:         {
                   7330:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7331: 
                   7332:             gen_load_fpr32(fp0, fs);
                   7333:             gen_helper_float_cvts_w(fp0, fp0);
                   7334:             gen_store_fpr32(fp0, fd);
                   7335:             tcg_temp_free_i32(fp0);
                   7336:         }
1.1.1.6   root     7337:         opn = "cvt.s.w";
                   7338:         break;
1.1.1.12  root     7339:     case OPC_CVT_D_W:
1.1.1.6   root     7340:         check_cp1_registers(ctx, fd);
1.1.1.7   root     7341:         {
                   7342:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   7343:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   7344: 
                   7345:             gen_load_fpr32(fp32, fs);
                   7346:             gen_helper_float_cvtd_w(fp64, fp32);
                   7347:             tcg_temp_free_i32(fp32);
                   7348:             gen_store_fpr64(ctx, fp64, fd);
                   7349:             tcg_temp_free_i64(fp64);
                   7350:         }
1.1.1.6   root     7351:         opn = "cvt.d.w";
                   7352:         break;
1.1.1.12  root     7353:     case OPC_CVT_S_L:
1.1.1.6   root     7354:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7355:         {
                   7356:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   7357:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   7358: 
                   7359:             gen_load_fpr64(ctx, fp64, fs);
                   7360:             gen_helper_float_cvts_l(fp32, fp64);
                   7361:             tcg_temp_free_i64(fp64);
                   7362:             gen_store_fpr32(fp32, fd);
                   7363:             tcg_temp_free_i32(fp32);
                   7364:         }
1.1.1.6   root     7365:         opn = "cvt.s.l";
                   7366:         break;
1.1.1.12  root     7367:     case OPC_CVT_D_L:
1.1.1.6   root     7368:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7369:         {
                   7370:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7371: 
                   7372:             gen_load_fpr64(ctx, fp0, fs);
                   7373:             gen_helper_float_cvtd_l(fp0, fp0);
                   7374:             gen_store_fpr64(ctx, fp0, fd);
                   7375:             tcg_temp_free_i64(fp0);
                   7376:         }
1.1.1.6   root     7377:         opn = "cvt.d.l";
                   7378:         break;
1.1.1.12  root     7379:     case OPC_CVT_PS_PW:
1.1.1.6   root     7380:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7381:         {
                   7382:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7383: 
                   7384:             gen_load_fpr64(ctx, fp0, fs);
                   7385:             gen_helper_float_cvtps_pw(fp0, fp0);
                   7386:             gen_store_fpr64(ctx, fp0, fd);
                   7387:             tcg_temp_free_i64(fp0);
                   7388:         }
1.1.1.6   root     7389:         opn = "cvt.ps.pw";
                   7390:         break;
1.1.1.12  root     7391:     case OPC_ADD_PS:
1.1.1.6   root     7392:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7393:         {
                   7394:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7395:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7396: 
                   7397:             gen_load_fpr64(ctx, fp0, fs);
                   7398:             gen_load_fpr64(ctx, fp1, ft);
                   7399:             gen_helper_float_add_ps(fp0, fp0, fp1);
                   7400:             tcg_temp_free_i64(fp1);
                   7401:             gen_store_fpr64(ctx, fp0, fd);
                   7402:             tcg_temp_free_i64(fp0);
                   7403:         }
1.1.1.6   root     7404:         opn = "add.ps";
                   7405:         break;
1.1.1.12  root     7406:     case OPC_SUB_PS:
1.1.1.6   root     7407:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7408:         {
                   7409:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7410:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7411: 
                   7412:             gen_load_fpr64(ctx, fp0, fs);
                   7413:             gen_load_fpr64(ctx, fp1, ft);
                   7414:             gen_helper_float_sub_ps(fp0, fp0, fp1);
                   7415:             tcg_temp_free_i64(fp1);
                   7416:             gen_store_fpr64(ctx, fp0, fd);
                   7417:             tcg_temp_free_i64(fp0);
                   7418:         }
1.1.1.6   root     7419:         opn = "sub.ps";
                   7420:         break;
1.1.1.12  root     7421:     case OPC_MUL_PS:
1.1.1.6   root     7422:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7423:         {
                   7424:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7425:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7426: 
                   7427:             gen_load_fpr64(ctx, fp0, fs);
                   7428:             gen_load_fpr64(ctx, fp1, ft);
                   7429:             gen_helper_float_mul_ps(fp0, fp0, fp1);
                   7430:             tcg_temp_free_i64(fp1);
                   7431:             gen_store_fpr64(ctx, fp0, fd);
                   7432:             tcg_temp_free_i64(fp0);
                   7433:         }
1.1.1.6   root     7434:         opn = "mul.ps";
                   7435:         break;
1.1.1.12  root     7436:     case OPC_ABS_PS:
1.1.1.6   root     7437:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7438:         {
                   7439:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7440: 
                   7441:             gen_load_fpr64(ctx, fp0, fs);
                   7442:             gen_helper_float_abs_ps(fp0, fp0);
                   7443:             gen_store_fpr64(ctx, fp0, fd);
                   7444:             tcg_temp_free_i64(fp0);
                   7445:         }
1.1.1.6   root     7446:         opn = "abs.ps";
                   7447:         break;
1.1.1.12  root     7448:     case OPC_MOV_PS:
1.1.1.6   root     7449:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7450:         {
                   7451:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7452: 
                   7453:             gen_load_fpr64(ctx, fp0, fs);
                   7454:             gen_store_fpr64(ctx, fp0, fd);
                   7455:             tcg_temp_free_i64(fp0);
                   7456:         }
1.1.1.6   root     7457:         opn = "mov.ps";
                   7458:         break;
1.1.1.12  root     7459:     case OPC_NEG_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_chs_ps(fp0, fp0);
                   7466:             gen_store_fpr64(ctx, fp0, fd);
                   7467:             tcg_temp_free_i64(fp0);
                   7468:         }
1.1.1.6   root     7469:         opn = "neg.ps";
                   7470:         break;
1.1.1.12  root     7471:     case OPC_MOVCF_PS:
1.1.1.6   root     7472:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7473:         gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
1.1.1.6   root     7474:         opn = "movcf.ps";
                   7475:         break;
1.1.1.12  root     7476:     case OPC_MOVZ_PS:
1.1.1.6   root     7477:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7478:         {
                   7479:             int l1 = gen_new_label();
1.1.1.8   root     7480:             TCGv_i64 fp0;
1.1.1.7   root     7481: 
1.1.1.8   root     7482:             if (ft != 0)
                   7483:                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
                   7484:             fp0 = tcg_temp_new_i64();
                   7485:             gen_load_fpr64(ctx, fp0, fs);
                   7486:             gen_store_fpr64(ctx, fp0, fd);
                   7487:             tcg_temp_free_i64(fp0);
1.1.1.7   root     7488:             gen_set_label(l1);
                   7489:         }
1.1.1.6   root     7490:         opn = "movz.ps";
                   7491:         break;
1.1.1.12  root     7492:     case OPC_MOVN_PS:
1.1.1.6   root     7493:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7494:         {
                   7495:             int l1 = gen_new_label();
1.1.1.8   root     7496:             TCGv_i64 fp0;
1.1.1.7   root     7497: 
1.1.1.8   root     7498:             if (ft != 0) {
                   7499:                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
                   7500:                 fp0 = tcg_temp_new_i64();
                   7501:                 gen_load_fpr64(ctx, fp0, fs);
                   7502:                 gen_store_fpr64(ctx, fp0, fd);
                   7503:                 tcg_temp_free_i64(fp0);
                   7504:                 gen_set_label(l1);
                   7505:             }
1.1.1.7   root     7506:         }
1.1.1.6   root     7507:         opn = "movn.ps";
                   7508:         break;
1.1.1.12  root     7509:     case OPC_ADDR_PS:
1.1.1.6   root     7510:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7511:         {
                   7512:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7513:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7514: 
                   7515:             gen_load_fpr64(ctx, fp0, ft);
                   7516:             gen_load_fpr64(ctx, fp1, fs);
                   7517:             gen_helper_float_addr_ps(fp0, fp0, fp1);
                   7518:             tcg_temp_free_i64(fp1);
                   7519:             gen_store_fpr64(ctx, fp0, fd);
                   7520:             tcg_temp_free_i64(fp0);
                   7521:         }
1.1.1.6   root     7522:         opn = "addr.ps";
                   7523:         break;
1.1.1.12  root     7524:     case OPC_MULR_PS:
1.1.1.6   root     7525:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7526:         {
                   7527:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7528:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7529: 
                   7530:             gen_load_fpr64(ctx, fp0, ft);
                   7531:             gen_load_fpr64(ctx, fp1, fs);
                   7532:             gen_helper_float_mulr_ps(fp0, fp0, fp1);
                   7533:             tcg_temp_free_i64(fp1);
                   7534:             gen_store_fpr64(ctx, fp0, fd);
                   7535:             tcg_temp_free_i64(fp0);
                   7536:         }
1.1.1.6   root     7537:         opn = "mulr.ps";
                   7538:         break;
1.1.1.12  root     7539:     case OPC_RECIP2_PS:
1.1.1.6   root     7540:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7541:         {
                   7542:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7543:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7544: 
                   7545:             gen_load_fpr64(ctx, fp0, fs);
                   7546:             gen_load_fpr64(ctx, fp1, fd);
                   7547:             gen_helper_float_recip2_ps(fp0, fp0, fp1);
                   7548:             tcg_temp_free_i64(fp1);
                   7549:             gen_store_fpr64(ctx, fp0, fd);
                   7550:             tcg_temp_free_i64(fp0);
                   7551:         }
1.1.1.6   root     7552:         opn = "recip2.ps";
                   7553:         break;
1.1.1.12  root     7554:     case OPC_RECIP1_PS:
1.1.1.6   root     7555:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7556:         {
                   7557:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7558: 
                   7559:             gen_load_fpr64(ctx, fp0, fs);
                   7560:             gen_helper_float_recip1_ps(fp0, fp0);
                   7561:             gen_store_fpr64(ctx, fp0, fd);
                   7562:             tcg_temp_free_i64(fp0);
                   7563:         }
1.1.1.6   root     7564:         opn = "recip1.ps";
                   7565:         break;
1.1.1.12  root     7566:     case OPC_RSQRT1_PS:
1.1.1.6   root     7567:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7568:         {
                   7569:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7570: 
                   7571:             gen_load_fpr64(ctx, fp0, fs);
                   7572:             gen_helper_float_rsqrt1_ps(fp0, fp0);
                   7573:             gen_store_fpr64(ctx, fp0, fd);
                   7574:             tcg_temp_free_i64(fp0);
                   7575:         }
1.1.1.6   root     7576:         opn = "rsqrt1.ps";
                   7577:         break;
1.1.1.12  root     7578:     case OPC_RSQRT2_PS:
1.1.1.6   root     7579:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7580:         {
                   7581:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7582:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7583: 
                   7584:             gen_load_fpr64(ctx, fp0, fs);
                   7585:             gen_load_fpr64(ctx, fp1, ft);
                   7586:             gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
                   7587:             tcg_temp_free_i64(fp1);
                   7588:             gen_store_fpr64(ctx, fp0, fd);
                   7589:             tcg_temp_free_i64(fp0);
                   7590:         }
1.1.1.6   root     7591:         opn = "rsqrt2.ps";
                   7592:         break;
1.1.1.12  root     7593:     case OPC_CVT_S_PU:
1.1.1.6   root     7594:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7595:         {
                   7596:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7597: 
                   7598:             gen_load_fpr32h(fp0, fs);
                   7599:             gen_helper_float_cvts_pu(fp0, fp0);
                   7600:             gen_store_fpr32(fp0, fd);
                   7601:             tcg_temp_free_i32(fp0);
                   7602:         }
1.1.1.6   root     7603:         opn = "cvt.s.pu";
                   7604:         break;
1.1.1.12  root     7605:     case OPC_CVT_PW_PS:
1.1.1.6   root     7606:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7607:         {
                   7608:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7609: 
                   7610:             gen_load_fpr64(ctx, fp0, fs);
                   7611:             gen_helper_float_cvtpw_ps(fp0, fp0);
                   7612:             gen_store_fpr64(ctx, fp0, fd);
                   7613:             tcg_temp_free_i64(fp0);
                   7614:         }
1.1.1.6   root     7615:         opn = "cvt.pw.ps";
1.1.1.4   root     7616:         break;
1.1.1.12  root     7617:     case OPC_CVT_S_PL:
1.1.1.6   root     7618:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7619:         {
                   7620:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7621: 
                   7622:             gen_load_fpr32(fp0, fs);
                   7623:             gen_helper_float_cvts_pl(fp0, fp0);
                   7624:             gen_store_fpr32(fp0, fd);
                   7625:             tcg_temp_free_i32(fp0);
                   7626:         }
1.1.1.6   root     7627:         opn = "cvt.s.pl";
1.1.1.4   root     7628:         break;
1.1.1.12  root     7629:     case OPC_PLL_PS:
1.1.1.6   root     7630:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7631:         {
                   7632:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7633:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   7634: 
                   7635:             gen_load_fpr32(fp0, fs);
                   7636:             gen_load_fpr32(fp1, ft);
                   7637:             gen_store_fpr32h(fp0, fd);
                   7638:             gen_store_fpr32(fp1, fd);
                   7639:             tcg_temp_free_i32(fp0);
                   7640:             tcg_temp_free_i32(fp1);
                   7641:         }
1.1.1.6   root     7642:         opn = "pll.ps";
1.1.1.4   root     7643:         break;
1.1.1.12  root     7644:     case OPC_PLU_PS:
1.1.1.6   root     7645:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7646:         {
                   7647:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7648:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   7649: 
                   7650:             gen_load_fpr32(fp0, fs);
                   7651:             gen_load_fpr32h(fp1, ft);
                   7652:             gen_store_fpr32(fp1, fd);
                   7653:             gen_store_fpr32h(fp0, fd);
                   7654:             tcg_temp_free_i32(fp0);
                   7655:             tcg_temp_free_i32(fp1);
                   7656:         }
1.1.1.6   root     7657:         opn = "plu.ps";
                   7658:         break;
1.1.1.12  root     7659:     case OPC_PUL_PS:
1.1.1.6   root     7660:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7661:         {
                   7662:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7663:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   7664: 
                   7665:             gen_load_fpr32h(fp0, fs);
                   7666:             gen_load_fpr32(fp1, ft);
                   7667:             gen_store_fpr32(fp1, fd);
                   7668:             gen_store_fpr32h(fp0, fd);
                   7669:             tcg_temp_free_i32(fp0);
                   7670:             tcg_temp_free_i32(fp1);
                   7671:         }
1.1.1.6   root     7672:         opn = "pul.ps";
1.1.1.4   root     7673:         break;
1.1.1.12  root     7674:     case OPC_PUU_PS:
1.1.1.6   root     7675:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7676:         {
                   7677:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7678:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   7679: 
                   7680:             gen_load_fpr32h(fp0, fs);
                   7681:             gen_load_fpr32h(fp1, ft);
                   7682:             gen_store_fpr32(fp1, fd);
                   7683:             gen_store_fpr32h(fp0, fd);
                   7684:             tcg_temp_free_i32(fp0);
                   7685:             tcg_temp_free_i32(fp1);
                   7686:         }
1.1.1.6   root     7687:         opn = "puu.ps";
                   7688:         break;
1.1.1.12  root     7689:     case OPC_CMP_F_PS:
                   7690:     case OPC_CMP_UN_PS:
                   7691:     case OPC_CMP_EQ_PS:
                   7692:     case OPC_CMP_UEQ_PS:
                   7693:     case OPC_CMP_OLT_PS:
                   7694:     case OPC_CMP_ULT_PS:
                   7695:     case OPC_CMP_OLE_PS:
                   7696:     case OPC_CMP_ULE_PS:
                   7697:     case OPC_CMP_SF_PS:
                   7698:     case OPC_CMP_NGLE_PS:
                   7699:     case OPC_CMP_SEQ_PS:
                   7700:     case OPC_CMP_NGL_PS:
                   7701:     case OPC_CMP_LT_PS:
                   7702:     case OPC_CMP_NGE_PS:
                   7703:     case OPC_CMP_LE_PS:
                   7704:     case OPC_CMP_NGT_PS:
                   7705:         if (ctx->opcode & (1 << 6)) {
                   7706:             gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
                   7707:             opn = condnames_abs[func-48];
                   7708:         } else {
                   7709:             gen_cmp_ps(ctx, func-48, ft, fs, cc);
                   7710:             opn = condnames[func-48];
1.1.1.6   root     7711:         }
1.1.1.4   root     7712:         break;
1.1.1.6   root     7713:     default:
                   7714:         MIPS_INVAL(opn);
                   7715:         generate_exception (ctx, EXCP_RI);
                   7716:         return;
                   7717:     }
1.1.1.13  root     7718:     (void)opn; /* avoid a compiler warning */
1.1.1.6   root     7719:     switch (optype) {
                   7720:     case BINOP:
                   7721:         MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
                   7722:         break;
                   7723:     case CMPOP:
                   7724:         MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
                   7725:         break;
                   7726:     default:
                   7727:         MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
                   7728:         break;
                   7729:     }
                   7730: }
                   7731: 
                   7732: /* Coprocessor 3 (FPU) */
                   7733: static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
                   7734:                            int fd, int fs, int base, int index)
                   7735: {
                   7736:     const char *opn = "extended float load/store";
                   7737:     int store = 0;
1.1.1.8   root     7738:     TCGv t0 = tcg_temp_new();
1.1.1.6   root     7739: 
                   7740:     if (base == 0) {
1.1.1.7   root     7741:         gen_load_gpr(t0, index);
1.1.1.6   root     7742:     } else if (index == 0) {
1.1.1.7   root     7743:         gen_load_gpr(t0, base);
1.1.1.6   root     7744:     } else {
1.1.1.7   root     7745:         gen_load_gpr(t0, index);
1.1.1.9   root     7746:         gen_op_addr_add(ctx, t0, cpu_gpr[base], t0);
1.1.1.6   root     7747:     }
                   7748:     /* Don't do NOP if destination is zero: we must perform the actual
                   7749:        memory access. */
1.1.1.8   root     7750:     save_cpu_state(ctx, 0);
1.1.1.6   root     7751:     switch (opc) {
                   7752:     case OPC_LWXC1:
                   7753:         check_cop1x(ctx);
1.1.1.7   root     7754:         {
                   7755:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7756: 
1.1.1.8   root     7757:             tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
                   7758:             tcg_gen_trunc_tl_i32(fp0, t0);
1.1.1.7   root     7759:             gen_store_fpr32(fp0, fd);
                   7760:             tcg_temp_free_i32(fp0);
                   7761:         }
1.1.1.6   root     7762:         opn = "lwxc1";
                   7763:         break;
                   7764:     case OPC_LDXC1:
                   7765:         check_cop1x(ctx);
                   7766:         check_cp1_registers(ctx, fd);
1.1.1.7   root     7767:         {
                   7768:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7769: 
                   7770:             tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
                   7771:             gen_store_fpr64(ctx, fp0, fd);
                   7772:             tcg_temp_free_i64(fp0);
                   7773:         }
1.1.1.6   root     7774:         opn = "ldxc1";
                   7775:         break;
                   7776:     case OPC_LUXC1:
                   7777:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7778:         tcg_gen_andi_tl(t0, t0, ~0x7);
                   7779:         {
                   7780:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7781: 
                   7782:             tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
                   7783:             gen_store_fpr64(ctx, fp0, fd);
                   7784:             tcg_temp_free_i64(fp0);
                   7785:         }
1.1.1.6   root     7786:         opn = "luxc1";
                   7787:         break;
                   7788:     case OPC_SWXC1:
                   7789:         check_cop1x(ctx);
1.1.1.7   root     7790:         {
                   7791:             TCGv_i32 fp0 = tcg_temp_new_i32();
1.1.1.8   root     7792:             TCGv t1 = tcg_temp_new();
1.1.1.7   root     7793: 
                   7794:             gen_load_fpr32(fp0, fs);
                   7795:             tcg_gen_extu_i32_tl(t1, fp0);
                   7796:             tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
                   7797:             tcg_temp_free_i32(fp0);
1.1.1.8   root     7798:             tcg_temp_free(t1);
1.1.1.7   root     7799:         }
1.1.1.6   root     7800:         opn = "swxc1";
                   7801:         store = 1;
1.1.1.4   root     7802:         break;
1.1.1.6   root     7803:     case OPC_SDXC1:
                   7804:         check_cop1x(ctx);
                   7805:         check_cp1_registers(ctx, fs);
1.1.1.7   root     7806:         {
                   7807:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7808: 
                   7809:             gen_load_fpr64(ctx, fp0, fs);
                   7810:             tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
                   7811:             tcg_temp_free_i64(fp0);
                   7812:         }
1.1.1.6   root     7813:         opn = "sdxc1";
                   7814:         store = 1;
                   7815:         break;
                   7816:     case OPC_SUXC1:
                   7817:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7818:         tcg_gen_andi_tl(t0, t0, ~0x7);
                   7819:         {
                   7820:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7821: 
                   7822:             gen_load_fpr64(ctx, fp0, fs);
                   7823:             tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
                   7824:             tcg_temp_free_i64(fp0);
                   7825:         }
1.1.1.6   root     7826:         opn = "suxc1";
                   7827:         store = 1;
                   7828:         break;
                   7829:     }
1.1.1.7   root     7830:     tcg_temp_free(t0);
1.1.1.13  root     7831:     (void)opn; (void)store; /* avoid compiler warnings */
1.1.1.6   root     7832:     MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
                   7833:                regnames[index], regnames[base]);
                   7834: }
                   7835: 
                   7836: static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
                   7837:                             int fd, int fr, int fs, int ft)
                   7838: {
                   7839:     const char *opn = "flt3_arith";
                   7840: 
                   7841:     switch (opc) {
                   7842:     case OPC_ALNV_PS:
                   7843:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7844:         {
                   7845:             TCGv t0 = tcg_temp_local_new();
1.1.1.8   root     7846:             TCGv_i32 fp = tcg_temp_new_i32();
                   7847:             TCGv_i32 fph = tcg_temp_new_i32();
1.1.1.7   root     7848:             int l1 = gen_new_label();
                   7849:             int l2 = gen_new_label();
                   7850: 
                   7851:             gen_load_gpr(t0, fr);
                   7852:             tcg_gen_andi_tl(t0, t0, 0x7);
                   7853: 
                   7854:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
1.1.1.8   root     7855:             gen_load_fpr32(fp, fs);
                   7856:             gen_load_fpr32h(fph, fs);
                   7857:             gen_store_fpr32(fp, fd);
                   7858:             gen_store_fpr32h(fph, fd);
1.1.1.7   root     7859:             tcg_gen_br(l2);
                   7860:             gen_set_label(l1);
                   7861:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
                   7862:             tcg_temp_free(t0);
                   7863: #ifdef TARGET_WORDS_BIGENDIAN
1.1.1.8   root     7864:             gen_load_fpr32(fp, fs);
                   7865:             gen_load_fpr32h(fph, ft);
                   7866:             gen_store_fpr32h(fp, fd);
                   7867:             gen_store_fpr32(fph, fd);
1.1.1.7   root     7868: #else
1.1.1.8   root     7869:             gen_load_fpr32h(fph, fs);
                   7870:             gen_load_fpr32(fp, ft);
                   7871:             gen_store_fpr32(fph, fd);
                   7872:             gen_store_fpr32h(fp, fd);
1.1.1.7   root     7873: #endif
                   7874:             gen_set_label(l2);
1.1.1.8   root     7875:             tcg_temp_free_i32(fp);
                   7876:             tcg_temp_free_i32(fph);
1.1.1.7   root     7877:         }
1.1.1.6   root     7878:         opn = "alnv.ps";
                   7879:         break;
                   7880:     case OPC_MADD_S:
                   7881:         check_cop1x(ctx);
1.1.1.7   root     7882:         {
                   7883:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7884:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   7885:             TCGv_i32 fp2 = tcg_temp_new_i32();
                   7886: 
                   7887:             gen_load_fpr32(fp0, fs);
                   7888:             gen_load_fpr32(fp1, ft);
                   7889:             gen_load_fpr32(fp2, fr);
                   7890:             gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
                   7891:             tcg_temp_free_i32(fp0);
                   7892:             tcg_temp_free_i32(fp1);
                   7893:             gen_store_fpr32(fp2, fd);
                   7894:             tcg_temp_free_i32(fp2);
                   7895:         }
1.1.1.6   root     7896:         opn = "madd.s";
1.1.1.4   root     7897:         break;
1.1.1.6   root     7898:     case OPC_MADD_D:
                   7899:         check_cop1x(ctx);
                   7900:         check_cp1_registers(ctx, fd | fs | ft | fr);
1.1.1.7   root     7901:         {
                   7902:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7903:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7904:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   7905: 
                   7906:             gen_load_fpr64(ctx, fp0, fs);
                   7907:             gen_load_fpr64(ctx, fp1, ft);
                   7908:             gen_load_fpr64(ctx, fp2, fr);
                   7909:             gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
                   7910:             tcg_temp_free_i64(fp0);
                   7911:             tcg_temp_free_i64(fp1);
                   7912:             gen_store_fpr64(ctx, fp2, fd);
                   7913:             tcg_temp_free_i64(fp2);
                   7914:         }
1.1.1.6   root     7915:         opn = "madd.d";
                   7916:         break;
                   7917:     case OPC_MADD_PS:
                   7918:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7919:         {
                   7920:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7921:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7922:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   7923: 
                   7924:             gen_load_fpr64(ctx, fp0, fs);
                   7925:             gen_load_fpr64(ctx, fp1, ft);
                   7926:             gen_load_fpr64(ctx, fp2, fr);
                   7927:             gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
                   7928:             tcg_temp_free_i64(fp0);
                   7929:             tcg_temp_free_i64(fp1);
                   7930:             gen_store_fpr64(ctx, fp2, fd);
                   7931:             tcg_temp_free_i64(fp2);
                   7932:         }
1.1.1.6   root     7933:         opn = "madd.ps";
1.1.1.4   root     7934:         break;
1.1.1.6   root     7935:     case OPC_MSUB_S:
                   7936:         check_cop1x(ctx);
1.1.1.7   root     7937:         {
                   7938:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7939:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   7940:             TCGv_i32 fp2 = tcg_temp_new_i32();
                   7941: 
                   7942:             gen_load_fpr32(fp0, fs);
                   7943:             gen_load_fpr32(fp1, ft);
                   7944:             gen_load_fpr32(fp2, fr);
                   7945:             gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
                   7946:             tcg_temp_free_i32(fp0);
                   7947:             tcg_temp_free_i32(fp1);
                   7948:             gen_store_fpr32(fp2, fd);
                   7949:             tcg_temp_free_i32(fp2);
                   7950:         }
1.1.1.6   root     7951:         opn = "msub.s";
1.1.1.4   root     7952:         break;
1.1.1.6   root     7953:     case OPC_MSUB_D:
                   7954:         check_cop1x(ctx);
                   7955:         check_cp1_registers(ctx, fd | fs | ft | fr);
1.1.1.7   root     7956:         {
                   7957:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7958:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7959:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   7960: 
                   7961:             gen_load_fpr64(ctx, fp0, fs);
                   7962:             gen_load_fpr64(ctx, fp1, ft);
                   7963:             gen_load_fpr64(ctx, fp2, fr);
                   7964:             gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
                   7965:             tcg_temp_free_i64(fp0);
                   7966:             tcg_temp_free_i64(fp1);
                   7967:             gen_store_fpr64(ctx, fp2, fd);
                   7968:             tcg_temp_free_i64(fp2);
                   7969:         }
1.1.1.6   root     7970:         opn = "msub.d";
                   7971:         break;
                   7972:     case OPC_MSUB_PS:
                   7973:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7974:         {
                   7975:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7976:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7977:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   7978: 
                   7979:             gen_load_fpr64(ctx, fp0, fs);
                   7980:             gen_load_fpr64(ctx, fp1, ft);
                   7981:             gen_load_fpr64(ctx, fp2, fr);
                   7982:             gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
                   7983:             tcg_temp_free_i64(fp0);
                   7984:             tcg_temp_free_i64(fp1);
                   7985:             gen_store_fpr64(ctx, fp2, fd);
                   7986:             tcg_temp_free_i64(fp2);
                   7987:         }
1.1.1.6   root     7988:         opn = "msub.ps";
1.1.1.4   root     7989:         break;
1.1.1.6   root     7990:     case OPC_NMADD_S:
                   7991:         check_cop1x(ctx);
1.1.1.7   root     7992:         {
                   7993:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7994:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   7995:             TCGv_i32 fp2 = tcg_temp_new_i32();
                   7996: 
                   7997:             gen_load_fpr32(fp0, fs);
                   7998:             gen_load_fpr32(fp1, ft);
                   7999:             gen_load_fpr32(fp2, fr);
                   8000:             gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
                   8001:             tcg_temp_free_i32(fp0);
                   8002:             tcg_temp_free_i32(fp1);
                   8003:             gen_store_fpr32(fp2, fd);
                   8004:             tcg_temp_free_i32(fp2);
                   8005:         }
1.1.1.6   root     8006:         opn = "nmadd.s";
1.1.1.4   root     8007:         break;
1.1.1.6   root     8008:     case OPC_NMADD_D:
                   8009:         check_cop1x(ctx);
                   8010:         check_cp1_registers(ctx, fd | fs | ft | fr);
1.1.1.7   root     8011:         {
                   8012:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   8013:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   8014:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   8015: 
                   8016:             gen_load_fpr64(ctx, fp0, fs);
                   8017:             gen_load_fpr64(ctx, fp1, ft);
                   8018:             gen_load_fpr64(ctx, fp2, fr);
                   8019:             gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
                   8020:             tcg_temp_free_i64(fp0);
                   8021:             tcg_temp_free_i64(fp1);
                   8022:             gen_store_fpr64(ctx, fp2, fd);
                   8023:             tcg_temp_free_i64(fp2);
                   8024:         }
1.1.1.6   root     8025:         opn = "nmadd.d";
1.1.1.5   root     8026:         break;
1.1.1.6   root     8027:     case OPC_NMADD_PS:
                   8028:         check_cp1_64bitmode(ctx);
1.1.1.7   root     8029:         {
                   8030:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   8031:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   8032:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   8033: 
                   8034:             gen_load_fpr64(ctx, fp0, fs);
                   8035:             gen_load_fpr64(ctx, fp1, ft);
                   8036:             gen_load_fpr64(ctx, fp2, fr);
                   8037:             gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
                   8038:             tcg_temp_free_i64(fp0);
                   8039:             tcg_temp_free_i64(fp1);
                   8040:             gen_store_fpr64(ctx, fp2, fd);
                   8041:             tcg_temp_free_i64(fp2);
                   8042:         }
1.1.1.6   root     8043:         opn = "nmadd.ps";
1.1.1.4   root     8044:         break;
1.1.1.6   root     8045:     case OPC_NMSUB_S:
                   8046:         check_cop1x(ctx);
1.1.1.7   root     8047:         {
                   8048:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   8049:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   8050:             TCGv_i32 fp2 = tcg_temp_new_i32();
                   8051: 
                   8052:             gen_load_fpr32(fp0, fs);
                   8053:             gen_load_fpr32(fp1, ft);
                   8054:             gen_load_fpr32(fp2, fr);
                   8055:             gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
                   8056:             tcg_temp_free_i32(fp0);
                   8057:             tcg_temp_free_i32(fp1);
                   8058:             gen_store_fpr32(fp2, fd);
                   8059:             tcg_temp_free_i32(fp2);
                   8060:         }
1.1.1.6   root     8061:         opn = "nmsub.s";
1.1.1.4   root     8062:         break;
1.1.1.6   root     8063:     case OPC_NMSUB_D:
                   8064:         check_cop1x(ctx);
                   8065:         check_cp1_registers(ctx, fd | fs | ft | fr);
1.1.1.7   root     8066:         {
                   8067:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   8068:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   8069:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   8070: 
                   8071:             gen_load_fpr64(ctx, fp0, fs);
                   8072:             gen_load_fpr64(ctx, fp1, ft);
                   8073:             gen_load_fpr64(ctx, fp2, fr);
                   8074:             gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
                   8075:             tcg_temp_free_i64(fp0);
                   8076:             tcg_temp_free_i64(fp1);
                   8077:             gen_store_fpr64(ctx, fp2, fd);
                   8078:             tcg_temp_free_i64(fp2);
                   8079:         }
1.1.1.6   root     8080:         opn = "nmsub.d";
1.1.1.4   root     8081:         break;
1.1.1.6   root     8082:     case OPC_NMSUB_PS:
                   8083:         check_cp1_64bitmode(ctx);
1.1.1.7   root     8084:         {
                   8085:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   8086:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   8087:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   8088: 
                   8089:             gen_load_fpr64(ctx, fp0, fs);
                   8090:             gen_load_fpr64(ctx, fp1, ft);
                   8091:             gen_load_fpr64(ctx, fp2, fr);
                   8092:             gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
                   8093:             tcg_temp_free_i64(fp0);
                   8094:             tcg_temp_free_i64(fp1);
                   8095:             gen_store_fpr64(ctx, fp2, fd);
                   8096:             tcg_temp_free_i64(fp2);
                   8097:         }
1.1.1.6   root     8098:         opn = "nmsub.ps";
1.1.1.4   root     8099:         break;
1.1.1.6   root     8100:     default:
                   8101:         MIPS_INVAL(opn);
                   8102:         generate_exception (ctx, EXCP_RI);
1.1.1.4   root     8103:         return;
                   8104:     }
1.1.1.13  root     8105:     (void)opn; /* avoid a compiler warning */
1.1.1.6   root     8106:     MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
                   8107:                fregnames[fs], fregnames[ft]);
1.1       root     8108: }
                   8109: 
1.1.1.12  root     8110: static void
1.1.1.16! root     8111: gen_rdhwr (CPUMIPSState *env, DisasContext *ctx, int rt, int rd)
1.1.1.12  root     8112: {
                   8113:     TCGv t0;
1.1       root     8114: 
1.1.1.12  root     8115:     check_insn(env, ctx, ISA_MIPS32R2);
                   8116:     t0 = tcg_temp_new();
1.1       root     8117: 
1.1.1.12  root     8118:     switch (rd) {
                   8119:     case 0:
                   8120:         save_cpu_state(ctx, 1);
                   8121:         gen_helper_rdhwr_cpunum(t0);
                   8122:         gen_store_gpr(t0, rt);
                   8123:         break;
                   8124:     case 1:
                   8125:         save_cpu_state(ctx, 1);
                   8126:         gen_helper_rdhwr_synci_step(t0);
                   8127:         gen_store_gpr(t0, rt);
                   8128:         break;
                   8129:     case 2:
                   8130:         save_cpu_state(ctx, 1);
                   8131:         gen_helper_rdhwr_cc(t0);
                   8132:         gen_store_gpr(t0, rt);
                   8133:         break;
                   8134:     case 3:
                   8135:         save_cpu_state(ctx, 1);
                   8136:         gen_helper_rdhwr_ccres(t0);
                   8137:         gen_store_gpr(t0, rt);
                   8138:         break;
                   8139:     case 29:
                   8140: #if defined(CONFIG_USER_ONLY)
1.1.1.16! root     8141:         tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUMIPSState, tls_value));
1.1.1.12  root     8142:         gen_store_gpr(t0, rt);
                   8143:         break;
                   8144: #else
                   8145:         /* XXX: Some CPUs implement this in hardware.
                   8146:            Not supported yet. */
1.1       root     8147: #endif
1.1.1.12  root     8148:     default:            /* Invalid */
                   8149:         MIPS_INVAL("rdhwr");
                   8150:         generate_exception(ctx, EXCP_RI);
                   8151:         break;
1.1.1.4   root     8152:     }
1.1.1.12  root     8153:     tcg_temp_free(t0);
                   8154: }
1.1.1.4   root     8155: 
1.1.1.16! root     8156: static void handle_delay_slot (CPUMIPSState *env, DisasContext *ctx,
1.1.1.12  root     8157:                                int insn_bytes)
                   8158: {
                   8159:     if (ctx->hflags & MIPS_HFLAG_BMASK) {
                   8160:         int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
                   8161:         /* Branches completion */
                   8162:         ctx->hflags &= ~MIPS_HFLAG_BMASK;
                   8163:         ctx->bstate = BS_BRANCH;
                   8164:         save_cpu_state(ctx, 0);
                   8165:         /* FIXME: Need to clear can_do_io.  */
                   8166:         switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
                   8167:         case MIPS_HFLAG_B:
                   8168:             /* unconditional branch */
                   8169:             MIPS_DEBUG("unconditional branch");
                   8170:             if (proc_hflags & MIPS_HFLAG_BX) {
                   8171:                 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
                   8172:             }
                   8173:             gen_goto_tb(ctx, 0, ctx->btarget);
                   8174:             break;
                   8175:         case MIPS_HFLAG_BL:
                   8176:             /* blikely taken case */
                   8177:             MIPS_DEBUG("blikely branch taken");
                   8178:             gen_goto_tb(ctx, 0, ctx->btarget);
                   8179:             break;
                   8180:         case MIPS_HFLAG_BC:
                   8181:             /* Conditional branch */
                   8182:             MIPS_DEBUG("conditional branch");
                   8183:             {
                   8184:                 int l1 = gen_new_label();
1.1.1.7   root     8185: 
1.1.1.12  root     8186:                 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
                   8187:                 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
                   8188:                 gen_set_label(l1);
                   8189:                 gen_goto_tb(ctx, 0, ctx->btarget);
                   8190:             }
                   8191:             break;
                   8192:         case MIPS_HFLAG_BR:
                   8193:             /* unconditional branch to register */
                   8194:             MIPS_DEBUG("branch to register");
                   8195:             if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
                   8196:                 TCGv t0 = tcg_temp_new();
                   8197:                 TCGv_i32 t1 = tcg_temp_new_i32();
                   8198: 
                   8199:                 tcg_gen_andi_tl(t0, btarget, 0x1);
                   8200:                 tcg_gen_trunc_tl_i32(t1, t0);
                   8201:                 tcg_temp_free(t0);
                   8202:                 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
                   8203:                 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
                   8204:                 tcg_gen_or_i32(hflags, hflags, t1);
                   8205:                 tcg_temp_free_i32(t1);
                   8206: 
                   8207:                 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
                   8208:             } else {
                   8209:                 tcg_gen_mov_tl(cpu_PC, btarget);
                   8210:             }
                   8211:             if (ctx->singlestep_enabled) {
                   8212:                 save_cpu_state(ctx, 0);
                   8213:                 gen_helper_0i(raise_exception, EXCP_DEBUG);
                   8214:             }
                   8215:             tcg_gen_exit_tb(0);
                   8216:             break;
                   8217:         default:
                   8218:             MIPS_DEBUG("unknown branch");
                   8219:             break;
                   8220:         }
                   8221:     }
                   8222: }
                   8223: 
                   8224: /* ISA extensions (ASEs) */
                   8225: /* MIPS16 extension to MIPS32 */
                   8226: 
                   8227: /* MIPS16 major opcodes */
                   8228: enum {
                   8229:   M16_OPC_ADDIUSP = 0x00,
                   8230:   M16_OPC_ADDIUPC = 0x01,
                   8231:   M16_OPC_B = 0x02,
                   8232:   M16_OPC_JAL = 0x03,
                   8233:   M16_OPC_BEQZ = 0x04,
                   8234:   M16_OPC_BNEQZ = 0x05,
                   8235:   M16_OPC_SHIFT = 0x06,
                   8236:   M16_OPC_LD = 0x07,
                   8237:   M16_OPC_RRIA = 0x08,
                   8238:   M16_OPC_ADDIU8 = 0x09,
                   8239:   M16_OPC_SLTI = 0x0a,
                   8240:   M16_OPC_SLTIU = 0x0b,
                   8241:   M16_OPC_I8 = 0x0c,
                   8242:   M16_OPC_LI = 0x0d,
                   8243:   M16_OPC_CMPI = 0x0e,
                   8244:   M16_OPC_SD = 0x0f,
                   8245:   M16_OPC_LB = 0x10,
                   8246:   M16_OPC_LH = 0x11,
                   8247:   M16_OPC_LWSP = 0x12,
                   8248:   M16_OPC_LW = 0x13,
                   8249:   M16_OPC_LBU = 0x14,
                   8250:   M16_OPC_LHU = 0x15,
                   8251:   M16_OPC_LWPC = 0x16,
                   8252:   M16_OPC_LWU = 0x17,
                   8253:   M16_OPC_SB = 0x18,
                   8254:   M16_OPC_SH = 0x19,
                   8255:   M16_OPC_SWSP = 0x1a,
                   8256:   M16_OPC_SW = 0x1b,
                   8257:   M16_OPC_RRR = 0x1c,
                   8258:   M16_OPC_RR = 0x1d,
                   8259:   M16_OPC_EXTEND = 0x1e,
                   8260:   M16_OPC_I64 = 0x1f
                   8261: };
                   8262: 
                   8263: /* I8 funct field */
                   8264: enum {
                   8265:   I8_BTEQZ = 0x0,
                   8266:   I8_BTNEZ = 0x1,
                   8267:   I8_SWRASP = 0x2,
                   8268:   I8_ADJSP = 0x3,
                   8269:   I8_SVRS = 0x4,
                   8270:   I8_MOV32R = 0x5,
                   8271:   I8_MOVR32 = 0x7
                   8272: };
                   8273: 
                   8274: /* RRR f field */
                   8275: enum {
                   8276:   RRR_DADDU = 0x0,
                   8277:   RRR_ADDU = 0x1,
                   8278:   RRR_DSUBU = 0x2,
                   8279:   RRR_SUBU = 0x3
                   8280: };
                   8281: 
                   8282: /* RR funct field */
                   8283: enum {
                   8284:   RR_JR = 0x00,
                   8285:   RR_SDBBP = 0x01,
                   8286:   RR_SLT = 0x02,
                   8287:   RR_SLTU = 0x03,
                   8288:   RR_SLLV = 0x04,
                   8289:   RR_BREAK = 0x05,
                   8290:   RR_SRLV = 0x06,
                   8291:   RR_SRAV = 0x07,
                   8292:   RR_DSRL = 0x08,
                   8293:   RR_CMP = 0x0a,
                   8294:   RR_NEG = 0x0b,
                   8295:   RR_AND = 0x0c,
                   8296:   RR_OR = 0x0d,
                   8297:   RR_XOR = 0x0e,
                   8298:   RR_NOT = 0x0f,
                   8299:   RR_MFHI = 0x10,
                   8300:   RR_CNVT = 0x11,
                   8301:   RR_MFLO = 0x12,
                   8302:   RR_DSRA = 0x13,
                   8303:   RR_DSLLV = 0x14,
                   8304:   RR_DSRLV = 0x16,
                   8305:   RR_DSRAV = 0x17,
                   8306:   RR_MULT = 0x18,
                   8307:   RR_MULTU = 0x19,
                   8308:   RR_DIV = 0x1a,
                   8309:   RR_DIVU = 0x1b,
                   8310:   RR_DMULT = 0x1c,
                   8311:   RR_DMULTU = 0x1d,
                   8312:   RR_DDIV = 0x1e,
                   8313:   RR_DDIVU = 0x1f
                   8314: };
                   8315: 
                   8316: /* I64 funct field */
                   8317: enum {
                   8318:   I64_LDSP = 0x0,
                   8319:   I64_SDSP = 0x1,
                   8320:   I64_SDRASP = 0x2,
                   8321:   I64_DADJSP = 0x3,
                   8322:   I64_LDPC = 0x4,
                   8323:   I64_DADDIU5 = 0x5,
                   8324:   I64_DADDIUPC = 0x6,
                   8325:   I64_DADDIUSP = 0x7
                   8326: };
                   8327: 
                   8328: /* RR ry field for CNVT */
                   8329: enum {
                   8330:   RR_RY_CNVT_ZEB = 0x0,
                   8331:   RR_RY_CNVT_ZEH = 0x1,
                   8332:   RR_RY_CNVT_ZEW = 0x2,
                   8333:   RR_RY_CNVT_SEB = 0x4,
                   8334:   RR_RY_CNVT_SEH = 0x5,
                   8335:   RR_RY_CNVT_SEW = 0x6,
                   8336: };
                   8337: 
                   8338: static int xlat (int r)
                   8339: {
                   8340:   static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
                   8341: 
                   8342:   return map[r];
                   8343: }
                   8344: 
                   8345: static void gen_mips16_save (DisasContext *ctx,
                   8346:                              int xsregs, int aregs,
                   8347:                              int do_ra, int do_s0, int do_s1,
                   8348:                              int framesize)
                   8349: {
                   8350:     TCGv t0 = tcg_temp_new();
                   8351:     TCGv t1 = tcg_temp_new();
                   8352:     int args, astatic;
                   8353: 
                   8354:     switch (aregs) {
                   8355:     case 0:
                   8356:     case 1:
                   8357:     case 2:
                   8358:     case 3:
                   8359:     case 11:
                   8360:         args = 0;
                   8361:         break;
                   8362:     case 4:
                   8363:     case 5:
                   8364:     case 6:
                   8365:     case 7:
                   8366:         args = 1;
                   8367:         break;
                   8368:     case 8:
                   8369:     case 9:
                   8370:     case 10:
                   8371:         args = 2;
                   8372:         break;
                   8373:     case 12:
                   8374:     case 13:
                   8375:         args = 3;
                   8376:         break;
                   8377:     case 14:
                   8378:         args = 4;
                   8379:         break;
                   8380:     default:
                   8381:         generate_exception(ctx, EXCP_RI);
                   8382:         return;
                   8383:     }
                   8384: 
                   8385:     switch (args) {
                   8386:     case 4:
                   8387:         gen_base_offset_addr(ctx, t0, 29, 12);
                   8388:         gen_load_gpr(t1, 7);
                   8389:         op_st_sw(t1, t0, ctx);
                   8390:         /* Fall through */
                   8391:     case 3:
                   8392:         gen_base_offset_addr(ctx, t0, 29, 8);
                   8393:         gen_load_gpr(t1, 6);
                   8394:         op_st_sw(t1, t0, ctx);
                   8395:         /* Fall through */
                   8396:     case 2:
                   8397:         gen_base_offset_addr(ctx, t0, 29, 4);
                   8398:         gen_load_gpr(t1, 5);
                   8399:         op_st_sw(t1, t0, ctx);
                   8400:         /* Fall through */
                   8401:     case 1:
                   8402:         gen_base_offset_addr(ctx, t0, 29, 0);
                   8403:         gen_load_gpr(t1, 4);
                   8404:         op_st_sw(t1, t0, ctx);
                   8405:     }
                   8406: 
                   8407:     gen_load_gpr(t0, 29);
                   8408: 
                   8409: #define DECR_AND_STORE(reg) do {                \
                   8410:         tcg_gen_subi_tl(t0, t0, 4);             \
                   8411:         gen_load_gpr(t1, reg);                  \
                   8412:         op_st_sw(t1, t0, ctx);                  \
                   8413:     } while (0)
                   8414: 
                   8415:     if (do_ra) {
                   8416:         DECR_AND_STORE(31);
                   8417:     }
                   8418: 
                   8419:     switch (xsregs) {
                   8420:     case 7:
                   8421:         DECR_AND_STORE(30);
                   8422:         /* Fall through */
                   8423:     case 6:
                   8424:         DECR_AND_STORE(23);
                   8425:         /* Fall through */
                   8426:     case 5:
                   8427:         DECR_AND_STORE(22);
                   8428:         /* Fall through */
                   8429:     case 4:
                   8430:         DECR_AND_STORE(21);
                   8431:         /* Fall through */
                   8432:     case 3:
                   8433:         DECR_AND_STORE(20);
                   8434:         /* Fall through */
                   8435:     case 2:
                   8436:         DECR_AND_STORE(19);
                   8437:         /* Fall through */
                   8438:     case 1:
                   8439:         DECR_AND_STORE(18);
                   8440:     }
                   8441: 
                   8442:     if (do_s1) {
                   8443:         DECR_AND_STORE(17);
                   8444:     }
                   8445:     if (do_s0) {
                   8446:         DECR_AND_STORE(16);
                   8447:     }
                   8448: 
                   8449:     switch (aregs) {
                   8450:     case 0:
                   8451:     case 4:
                   8452:     case 8:
                   8453:     case 12:
                   8454:     case 14:
                   8455:         astatic = 0;
                   8456:         break;
                   8457:     case 1:
                   8458:     case 5:
                   8459:     case 9:
                   8460:     case 13:
                   8461:         astatic = 1;
                   8462:         break;
                   8463:     case 2:
                   8464:     case 6:
                   8465:     case 10:
                   8466:         astatic = 2;
                   8467:         break;
                   8468:     case 3:
                   8469:     case 7:
                   8470:         astatic = 3;
                   8471:         break;
                   8472:     case 11:
                   8473:         astatic = 4;
                   8474:         break;
                   8475:     default:
                   8476:         generate_exception(ctx, EXCP_RI);
                   8477:         return;
                   8478:     }
                   8479: 
                   8480:     if (astatic > 0) {
                   8481:         DECR_AND_STORE(7);
                   8482:         if (astatic > 1) {
                   8483:             DECR_AND_STORE(6);
                   8484:             if (astatic > 2) {
                   8485:                 DECR_AND_STORE(5);
                   8486:                 if (astatic > 3) {
                   8487:                     DECR_AND_STORE(4);
                   8488:                 }
                   8489:             }
                   8490:         }
                   8491:     }
                   8492: #undef DECR_AND_STORE
                   8493: 
                   8494:     tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
                   8495:     tcg_temp_free(t0);
                   8496:     tcg_temp_free(t1);
                   8497: }
                   8498: 
                   8499: static void gen_mips16_restore (DisasContext *ctx,
                   8500:                                 int xsregs, int aregs,
                   8501:                                 int do_ra, int do_s0, int do_s1,
                   8502:                                 int framesize)
                   8503: {
                   8504:     int astatic;
                   8505:     TCGv t0 = tcg_temp_new();
                   8506:     TCGv t1 = tcg_temp_new();
                   8507: 
                   8508:     tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
                   8509: 
                   8510: #define DECR_AND_LOAD(reg) do {                 \
                   8511:         tcg_gen_subi_tl(t0, t0, 4);             \
                   8512:         op_ld_lw(t1, t0, ctx);                  \
                   8513:         gen_store_gpr(t1, reg);                 \
                   8514:     } while (0)
                   8515: 
                   8516:     if (do_ra) {
                   8517:         DECR_AND_LOAD(31);
                   8518:     }
                   8519: 
                   8520:     switch (xsregs) {
                   8521:     case 7:
                   8522:         DECR_AND_LOAD(30);
                   8523:         /* Fall through */
                   8524:     case 6:
                   8525:         DECR_AND_LOAD(23);
                   8526:         /* Fall through */
                   8527:     case 5:
                   8528:         DECR_AND_LOAD(22);
                   8529:         /* Fall through */
                   8530:     case 4:
                   8531:         DECR_AND_LOAD(21);
                   8532:         /* Fall through */
                   8533:     case 3:
                   8534:         DECR_AND_LOAD(20);
                   8535:         /* Fall through */
                   8536:     case 2:
                   8537:         DECR_AND_LOAD(19);
                   8538:         /* Fall through */
                   8539:     case 1:
                   8540:         DECR_AND_LOAD(18);
                   8541:     }
                   8542: 
                   8543:     if (do_s1) {
                   8544:         DECR_AND_LOAD(17);
                   8545:     }
                   8546:     if (do_s0) {
                   8547:         DECR_AND_LOAD(16);
                   8548:     }
                   8549: 
                   8550:     switch (aregs) {
                   8551:     case 0:
                   8552:     case 4:
                   8553:     case 8:
                   8554:     case 12:
                   8555:     case 14:
                   8556:         astatic = 0;
                   8557:         break;
                   8558:     case 1:
                   8559:     case 5:
                   8560:     case 9:
                   8561:     case 13:
                   8562:         astatic = 1;
                   8563:         break;
                   8564:     case 2:
                   8565:     case 6:
                   8566:     case 10:
                   8567:         astatic = 2;
                   8568:         break;
                   8569:     case 3:
                   8570:     case 7:
                   8571:         astatic = 3;
                   8572:         break;
                   8573:     case 11:
                   8574:         astatic = 4;
                   8575:         break;
                   8576:     default:
                   8577:         generate_exception(ctx, EXCP_RI);
                   8578:         return;
                   8579:     }
                   8580: 
                   8581:     if (astatic > 0) {
                   8582:         DECR_AND_LOAD(7);
                   8583:         if (astatic > 1) {
                   8584:             DECR_AND_LOAD(6);
                   8585:             if (astatic > 2) {
                   8586:                 DECR_AND_LOAD(5);
                   8587:                 if (astatic > 3) {
                   8588:                     DECR_AND_LOAD(4);
                   8589:                 }
                   8590:             }
                   8591:         }
                   8592:     }
                   8593: #undef DECR_AND_LOAD
                   8594: 
                   8595:     tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
                   8596:     tcg_temp_free(t0);
                   8597:     tcg_temp_free(t1);
                   8598: }
                   8599: 
                   8600: static void gen_addiupc (DisasContext *ctx, int rx, int imm,
                   8601:                          int is_64_bit, int extended)
                   8602: {
                   8603:     TCGv t0;
                   8604: 
                   8605:     if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
                   8606:         generate_exception(ctx, EXCP_RI);
                   8607:         return;
                   8608:     }
                   8609: 
                   8610:     t0 = tcg_temp_new();
                   8611: 
                   8612:     tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
                   8613:     tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
                   8614:     if (!is_64_bit) {
                   8615:         tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
                   8616:     }
                   8617: 
                   8618:     tcg_temp_free(t0);
                   8619: }
                   8620: 
                   8621: #if defined(TARGET_MIPS64)
1.1.1.16! root     8622: static void decode_i64_mips16 (CPUMIPSState *env, DisasContext *ctx,
1.1.1.12  root     8623:                                int ry, int funct, int16_t offset,
                   8624:                                int extended)
                   8625: {
                   8626:     switch (funct) {
                   8627:     case I64_LDSP:
                   8628:         check_mips_64(ctx);
                   8629:         offset = extended ? offset : offset << 3;
                   8630:         gen_ld(env, ctx, OPC_LD, ry, 29, offset);
                   8631:         break;
                   8632:     case I64_SDSP:
                   8633:         check_mips_64(ctx);
                   8634:         offset = extended ? offset : offset << 3;
                   8635:         gen_st(ctx, OPC_SD, ry, 29, offset);
                   8636:         break;
                   8637:     case I64_SDRASP:
                   8638:         check_mips_64(ctx);
                   8639:         offset = extended ? offset : (ctx->opcode & 0xff) << 3;
                   8640:         gen_st(ctx, OPC_SD, 31, 29, offset);
                   8641:         break;
                   8642:     case I64_DADJSP:
                   8643:         check_mips_64(ctx);
                   8644:         offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
                   8645:         gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
                   8646:         break;
                   8647:     case I64_LDPC:
                   8648:         if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
                   8649:             generate_exception(ctx, EXCP_RI);
                   8650:         } else {
                   8651:             offset = extended ? offset : offset << 3;
                   8652:             gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
                   8653:         }
                   8654:         break;
                   8655:     case I64_DADDIU5:
                   8656:         check_mips_64(ctx);
                   8657:         offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
                   8658:         gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
                   8659:         break;
                   8660:     case I64_DADDIUPC:
                   8661:         check_mips_64(ctx);
                   8662:         offset = extended ? offset : offset << 2;
                   8663:         gen_addiupc(ctx, ry, offset, 1, extended);
                   8664:         break;
                   8665:     case I64_DADDIUSP:
                   8666:         check_mips_64(ctx);
                   8667:         offset = extended ? offset : offset << 2;
                   8668:         gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
                   8669:         break;
                   8670:     }
                   8671: }
                   8672: #endif
                   8673: 
1.1.1.16! root     8674: static int decode_extended_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
1.1.1.12  root     8675:                                        int *is_branch)
                   8676: {
                   8677:     int extend = lduw_code(ctx->pc + 2);
                   8678:     int op, rx, ry, funct, sa;
                   8679:     int16_t imm, offset;
                   8680: 
                   8681:     ctx->opcode = (ctx->opcode << 16) | extend;
                   8682:     op = (ctx->opcode >> 11) & 0x1f;
                   8683:     sa = (ctx->opcode >> 22) & 0x1f;
                   8684:     funct = (ctx->opcode >> 8) & 0x7;
                   8685:     rx = xlat((ctx->opcode >> 8) & 0x7);
                   8686:     ry = xlat((ctx->opcode >> 5) & 0x7);
                   8687:     offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
                   8688:                               | ((ctx->opcode >> 21) & 0x3f) << 5
                   8689:                               | (ctx->opcode & 0x1f));
                   8690: 
                   8691:     /* The extended opcodes cleverly reuse the opcodes from their 16-bit
                   8692:        counterparts.  */
                   8693:     switch (op) {
                   8694:     case M16_OPC_ADDIUSP:
                   8695:         gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
                   8696:         break;
                   8697:     case M16_OPC_ADDIUPC:
                   8698:         gen_addiupc(ctx, rx, imm, 0, 1);
                   8699:         break;
                   8700:     case M16_OPC_B:
                   8701:         gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
                   8702:         /* No delay slot, so just process as a normal instruction */
                   8703:         break;
                   8704:     case M16_OPC_BEQZ:
                   8705:         gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
                   8706:         /* No delay slot, so just process as a normal instruction */
                   8707:         break;
                   8708:     case M16_OPC_BNEQZ:
                   8709:         gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
                   8710:         /* No delay slot, so just process as a normal instruction */
                   8711:         break;
                   8712:     case M16_OPC_SHIFT:
                   8713:         switch (ctx->opcode & 0x3) {
                   8714:         case 0x0:
                   8715:             gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
                   8716:             break;
                   8717:         case 0x1:
                   8718: #if defined(TARGET_MIPS64)
                   8719:             check_mips_64(ctx);
                   8720:             gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
                   8721: #else
                   8722:             generate_exception(ctx, EXCP_RI);
                   8723: #endif
                   8724:             break;
                   8725:         case 0x2:
                   8726:             gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
                   8727:             break;
                   8728:         case 0x3:
                   8729:             gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
                   8730:             break;
                   8731:         }
                   8732:         break;
                   8733: #if defined(TARGET_MIPS64)
                   8734:     case M16_OPC_LD:
                   8735:             check_mips_64(ctx);
                   8736:         gen_ld(env, ctx, OPC_LD, ry, rx, offset);
                   8737:         break;
                   8738: #endif
                   8739:     case M16_OPC_RRIA:
                   8740:         imm = ctx->opcode & 0xf;
                   8741:         imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
                   8742:         imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
                   8743:         imm = (int16_t) (imm << 1) >> 1;
                   8744:         if ((ctx->opcode >> 4) & 0x1) {
                   8745: #if defined(TARGET_MIPS64)
                   8746:             check_mips_64(ctx);
                   8747:             gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
                   8748: #else
                   8749:             generate_exception(ctx, EXCP_RI);
                   8750: #endif
                   8751:         } else {
                   8752:             gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
                   8753:         }
                   8754:         break;
                   8755:     case M16_OPC_ADDIU8:
                   8756:         gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
                   8757:         break;
                   8758:     case M16_OPC_SLTI:
                   8759:         gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
                   8760:         break;
                   8761:     case M16_OPC_SLTIU:
                   8762:         gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
                   8763:         break;
                   8764:     case M16_OPC_I8:
                   8765:         switch (funct) {
                   8766:         case I8_BTEQZ:
                   8767:             gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
                   8768:             break;
                   8769:         case I8_BTNEZ:
                   8770:             gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
                   8771:             break;
                   8772:         case I8_SWRASP:
                   8773:             gen_st(ctx, OPC_SW, 31, 29, imm);
                   8774:             break;
                   8775:         case I8_ADJSP:
                   8776:             gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
                   8777:             break;
                   8778:         case I8_SVRS:
                   8779:             {
                   8780:                 int xsregs = (ctx->opcode >> 24) & 0x7;
                   8781:                 int aregs = (ctx->opcode >> 16) & 0xf;
                   8782:                 int do_ra = (ctx->opcode >> 6) & 0x1;
                   8783:                 int do_s0 = (ctx->opcode >> 5) & 0x1;
                   8784:                 int do_s1 = (ctx->opcode >> 4) & 0x1;
                   8785:                 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
                   8786:                                  | (ctx->opcode & 0xf)) << 3;
                   8787: 
                   8788:                 if (ctx->opcode & (1 << 7)) {
                   8789:                     gen_mips16_save(ctx, xsregs, aregs,
                   8790:                                     do_ra, do_s0, do_s1,
                   8791:                                     framesize);
                   8792:                 } else {
                   8793:                     gen_mips16_restore(ctx, xsregs, aregs,
                   8794:                                        do_ra, do_s0, do_s1,
                   8795:                                        framesize);
                   8796:                 }
                   8797:             }
                   8798:             break;
                   8799:         default:
                   8800:             generate_exception(ctx, EXCP_RI);
                   8801:             break;
                   8802:         }
                   8803:         break;
                   8804:     case M16_OPC_LI:
                   8805:         tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
                   8806:         break;
                   8807:     case M16_OPC_CMPI:
                   8808:         tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
                   8809:         break;
                   8810: #if defined(TARGET_MIPS64)
                   8811:     case M16_OPC_SD:
                   8812:         gen_st(ctx, OPC_SD, ry, rx, offset);
                   8813:         break;
                   8814: #endif
                   8815:     case M16_OPC_LB:
                   8816:         gen_ld(env, ctx, OPC_LB, ry, rx, offset);
                   8817:         break;
                   8818:     case M16_OPC_LH:
                   8819:         gen_ld(env, ctx, OPC_LH, ry, rx, offset);
                   8820:         break;
                   8821:     case M16_OPC_LWSP:
                   8822:         gen_ld(env, ctx, OPC_LW, rx, 29, offset);
                   8823:         break;
                   8824:     case M16_OPC_LW:
                   8825:         gen_ld(env, ctx, OPC_LW, ry, rx, offset);
                   8826:         break;
                   8827:     case M16_OPC_LBU:
                   8828:         gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
                   8829:         break;
                   8830:     case M16_OPC_LHU:
                   8831:         gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
                   8832:         break;
                   8833:     case M16_OPC_LWPC:
                   8834:         gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
                   8835:         break;
                   8836: #if defined(TARGET_MIPS64)
                   8837:     case M16_OPC_LWU:
                   8838:         gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
                   8839:         break;
                   8840: #endif
                   8841:     case M16_OPC_SB:
                   8842:         gen_st(ctx, OPC_SB, ry, rx, offset);
                   8843:         break;
                   8844:     case M16_OPC_SH:
                   8845:         gen_st(ctx, OPC_SH, ry, rx, offset);
                   8846:         break;
                   8847:     case M16_OPC_SWSP:
                   8848:         gen_st(ctx, OPC_SW, rx, 29, offset);
                   8849:         break;
                   8850:     case M16_OPC_SW:
                   8851:         gen_st(ctx, OPC_SW, ry, rx, offset);
                   8852:         break;
                   8853: #if defined(TARGET_MIPS64)
                   8854:     case M16_OPC_I64:
                   8855:         decode_i64_mips16(env, ctx, ry, funct, offset, 1);
                   8856:         break;
                   8857: #endif
                   8858:     default:
                   8859:         generate_exception(ctx, EXCP_RI);
                   8860:         break;
                   8861:     }
                   8862: 
                   8863:     return 4;
                   8864: }
                   8865: 
1.1.1.16! root     8866: static int decode_mips16_opc (CPUMIPSState *env, DisasContext *ctx,
1.1.1.12  root     8867:                               int *is_branch)
                   8868: {
                   8869:     int rx, ry;
                   8870:     int sa;
                   8871:     int op, cnvt_op, op1, offset;
                   8872:     int funct;
                   8873:     int n_bytes;
                   8874: 
                   8875:     op = (ctx->opcode >> 11) & 0x1f;
                   8876:     sa = (ctx->opcode >> 2) & 0x7;
                   8877:     sa = sa == 0 ? 8 : sa;
                   8878:     rx = xlat((ctx->opcode >> 8) & 0x7);
                   8879:     cnvt_op = (ctx->opcode >> 5) & 0x7;
                   8880:     ry = xlat((ctx->opcode >> 5) & 0x7);
                   8881:     op1 = offset = ctx->opcode & 0x1f;
                   8882: 
                   8883:     n_bytes = 2;
                   8884: 
                   8885:     switch (op) {
                   8886:     case M16_OPC_ADDIUSP:
                   8887:         {
                   8888:             int16_t imm = ((uint8_t) ctx->opcode) << 2;
                   8889: 
                   8890:             gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
                   8891:         }
                   8892:         break;
                   8893:     case M16_OPC_ADDIUPC:
                   8894:         gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
                   8895:         break;
                   8896:     case M16_OPC_B:
                   8897:         offset = (ctx->opcode & 0x7ff) << 1;
                   8898:         offset = (int16_t)(offset << 4) >> 4;
                   8899:         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
                   8900:         /* No delay slot, so just process as a normal instruction */
                   8901:         break;
                   8902:     case M16_OPC_JAL:
                   8903:         offset = lduw_code(ctx->pc + 2);
                   8904:         offset = (((ctx->opcode & 0x1f) << 21)
                   8905:                   | ((ctx->opcode >> 5) & 0x1f) << 16
                   8906:                   | offset) << 2;
                   8907:         op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
                   8908:         gen_compute_branch(ctx, op, 4, rx, ry, offset);
                   8909:         n_bytes = 4;
                   8910:         *is_branch = 1;
                   8911:         break;
                   8912:     case M16_OPC_BEQZ:
                   8913:         gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
                   8914:         /* No delay slot, so just process as a normal instruction */
                   8915:         break;
                   8916:     case M16_OPC_BNEQZ:
                   8917:         gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
                   8918:         /* No delay slot, so just process as a normal instruction */
                   8919:         break;
                   8920:     case M16_OPC_SHIFT:
                   8921:         switch (ctx->opcode & 0x3) {
                   8922:         case 0x0:
                   8923:             gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
                   8924:             break;
                   8925:         case 0x1:
                   8926: #if defined(TARGET_MIPS64)
                   8927:             check_mips_64(ctx);
                   8928:             gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
                   8929: #else
                   8930:             generate_exception(ctx, EXCP_RI);
                   8931: #endif
                   8932:             break;
                   8933:         case 0x2:
                   8934:             gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
                   8935:             break;
                   8936:         case 0x3:
                   8937:             gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
                   8938:             break;
                   8939:         }
                   8940:         break;
                   8941: #if defined(TARGET_MIPS64)
                   8942:     case M16_OPC_LD:
                   8943:         check_mips_64(ctx);
                   8944:         gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
                   8945:         break;
                   8946: #endif
                   8947:     case M16_OPC_RRIA:
                   8948:         {
                   8949:             int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
                   8950: 
                   8951:             if ((ctx->opcode >> 4) & 1) {
                   8952: #if defined(TARGET_MIPS64)
                   8953:                 check_mips_64(ctx);
                   8954:                 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
                   8955: #else
                   8956:                 generate_exception(ctx, EXCP_RI);
                   8957: #endif
                   8958:             } else {
                   8959:                 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
                   8960:             }
                   8961:         }
                   8962:         break;
                   8963:     case M16_OPC_ADDIU8:
                   8964:         {
                   8965:             int16_t imm = (int8_t) ctx->opcode;
                   8966: 
                   8967:             gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
                   8968:         }
                   8969:         break;
                   8970:     case M16_OPC_SLTI:
                   8971:         {
                   8972:             int16_t imm = (uint8_t) ctx->opcode;
                   8973: 
                   8974:             gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
                   8975:         }
                   8976:         break;
                   8977:     case M16_OPC_SLTIU:
                   8978:         {
                   8979:             int16_t imm = (uint8_t) ctx->opcode;
                   8980: 
                   8981:             gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
                   8982:         }
                   8983:         break;
                   8984:     case M16_OPC_I8:
                   8985:         {
                   8986:             int reg32;
                   8987: 
                   8988:             funct = (ctx->opcode >> 8) & 0x7;
                   8989:             switch (funct) {
                   8990:             case I8_BTEQZ:
                   8991:                 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
                   8992:                                    ((int8_t)ctx->opcode) << 1);
                   8993:                 break;
                   8994:             case I8_BTNEZ:
                   8995:                 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
                   8996:                                    ((int8_t)ctx->opcode) << 1);
                   8997:                 break;
                   8998:             case I8_SWRASP:
                   8999:                 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
                   9000:                 break;
                   9001:             case I8_ADJSP:
                   9002:                 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
                   9003:                               ((int8_t)ctx->opcode) << 3);
                   9004:                 break;
                   9005:             case I8_SVRS:
                   9006:                 {
                   9007:                     int do_ra = ctx->opcode & (1 << 6);
                   9008:                     int do_s0 = ctx->opcode & (1 << 5);
                   9009:                     int do_s1 = ctx->opcode & (1 << 4);
                   9010:                     int framesize = ctx->opcode & 0xf;
                   9011: 
                   9012:                     if (framesize == 0) {
                   9013:                         framesize = 128;
                   9014:                     } else {
                   9015:                         framesize = framesize << 3;
                   9016:                     }
                   9017: 
                   9018:                     if (ctx->opcode & (1 << 7)) {
                   9019:                         gen_mips16_save(ctx, 0, 0,
                   9020:                                         do_ra, do_s0, do_s1, framesize);
                   9021:                     } else {
                   9022:                         gen_mips16_restore(ctx, 0, 0,
                   9023:                                            do_ra, do_s0, do_s1, framesize);
                   9024:                     }
                   9025:                 }
                   9026:                 break;
                   9027:             case I8_MOV32R:
                   9028:                 {
                   9029:                     int rz = xlat(ctx->opcode & 0x7);
                   9030: 
                   9031:                     reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
                   9032:                         ((ctx->opcode >> 5) & 0x7);
                   9033:                     gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
                   9034:                 }
                   9035:                 break;
                   9036:             case I8_MOVR32:
                   9037:                 reg32 = ctx->opcode & 0x1f;
                   9038:                 gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
                   9039:                 break;
                   9040:             default:
                   9041:                 generate_exception(ctx, EXCP_RI);
                   9042:                 break;
                   9043:             }
                   9044:         }
                   9045:         break;
                   9046:     case M16_OPC_LI:
                   9047:         {
                   9048:             int16_t imm = (uint8_t) ctx->opcode;
                   9049: 
                   9050:             gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
                   9051:         }
                   9052:         break;
                   9053:     case M16_OPC_CMPI:
                   9054:         {
                   9055:             int16_t imm = (uint8_t) ctx->opcode;
                   9056: 
                   9057:             gen_logic_imm(env, OPC_XORI, 24, rx, imm);
                   9058:         }
                   9059:         break;
                   9060: #if defined(TARGET_MIPS64)
                   9061:     case M16_OPC_SD:
                   9062:         check_mips_64(ctx);
                   9063:         gen_st(ctx, OPC_SD, ry, rx, offset << 3);
                   9064:         break;
                   9065: #endif
                   9066:     case M16_OPC_LB:
                   9067:         gen_ld(env, ctx, OPC_LB, ry, rx, offset);
                   9068:         break;
                   9069:     case M16_OPC_LH:
                   9070:         gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
                   9071:         break;
                   9072:     case M16_OPC_LWSP:
                   9073:         gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
                   9074:         break;
                   9075:     case M16_OPC_LW:
                   9076:         gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
                   9077:         break;
                   9078:     case M16_OPC_LBU:
                   9079:         gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
                   9080:         break;
                   9081:     case M16_OPC_LHU:
                   9082:         gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
                   9083:         break;
                   9084:     case M16_OPC_LWPC:
                   9085:         gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
                   9086:         break;
                   9087: #if defined (TARGET_MIPS64)
                   9088:     case M16_OPC_LWU:
                   9089:         check_mips_64(ctx);
                   9090:         gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
                   9091:         break;
                   9092: #endif
                   9093:     case M16_OPC_SB:
                   9094:         gen_st(ctx, OPC_SB, ry, rx, offset);
                   9095:         break;
                   9096:     case M16_OPC_SH:
                   9097:         gen_st(ctx, OPC_SH, ry, rx, offset << 1);
                   9098:         break;
                   9099:     case M16_OPC_SWSP:
                   9100:         gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
                   9101:         break;
                   9102:     case M16_OPC_SW:
                   9103:         gen_st(ctx, OPC_SW, ry, rx, offset << 2);
                   9104:         break;
                   9105:     case M16_OPC_RRR:
                   9106:         {
                   9107:             int rz = xlat((ctx->opcode >> 2) & 0x7);
                   9108:             int mips32_op;
                   9109: 
                   9110:             switch (ctx->opcode & 0x3) {
                   9111:             case RRR_ADDU:
                   9112:                 mips32_op = OPC_ADDU;
                   9113:                 break;
                   9114:             case RRR_SUBU:
                   9115:                 mips32_op = OPC_SUBU;
                   9116:                 break;
                   9117: #if defined(TARGET_MIPS64)
                   9118:             case RRR_DADDU:
                   9119:                 mips32_op = OPC_DADDU;
                   9120:                 check_mips_64(ctx);
                   9121:                 break;
                   9122:             case RRR_DSUBU:
                   9123:                 mips32_op = OPC_DSUBU;
                   9124:                 check_mips_64(ctx);
                   9125:                 break;
                   9126: #endif
                   9127:             default:
                   9128:                 generate_exception(ctx, EXCP_RI);
                   9129:                 goto done;
                   9130:             }
                   9131: 
                   9132:             gen_arith(env, ctx, mips32_op, rz, rx, ry);
                   9133:         done:
                   9134:             ;
                   9135:         }
                   9136:         break;
                   9137:     case M16_OPC_RR:
                   9138:         switch (op1) {
                   9139:         case RR_JR:
                   9140:             {
                   9141:                 int nd = (ctx->opcode >> 7) & 0x1;
                   9142:                 int link = (ctx->opcode >> 6) & 0x1;
                   9143:                 int ra = (ctx->opcode >> 5) & 0x1;
                   9144: 
                   9145:                 if (link) {
                   9146:                     op = nd ? OPC_JALRC : OPC_JALRS;
                   9147:                 } else {
                   9148:                     op = OPC_JR;
                   9149:                 }
                   9150: 
                   9151:                 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
                   9152:                 if (!nd) {
                   9153:                     *is_branch = 1;
                   9154:                 }
                   9155:             }
                   9156:             break;
                   9157:         case RR_SDBBP:
                   9158:             /* XXX: not clear which exception should be raised
                   9159:              *      when in debug mode...
                   9160:              */
                   9161:             check_insn(env, ctx, ISA_MIPS32);
                   9162:             if (!(ctx->hflags & MIPS_HFLAG_DM)) {
                   9163:                 generate_exception(ctx, EXCP_DBp);
                   9164:             } else {
                   9165:                 generate_exception(ctx, EXCP_DBp);
                   9166:             }
                   9167:             break;
                   9168:         case RR_SLT:
                   9169:             gen_slt(env, OPC_SLT, 24, rx, ry);
                   9170:             break;
                   9171:         case RR_SLTU:
                   9172:             gen_slt(env, OPC_SLTU, 24, rx, ry);
                   9173:             break;
                   9174:         case RR_BREAK:
                   9175:             generate_exception(ctx, EXCP_BREAK);
                   9176:             break;
                   9177:         case RR_SLLV:
                   9178:             gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
                   9179:             break;
                   9180:         case RR_SRLV:
                   9181:             gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
                   9182:             break;
                   9183:         case RR_SRAV:
                   9184:             gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
                   9185:             break;
                   9186: #if defined (TARGET_MIPS64)
                   9187:         case RR_DSRL:
                   9188:             check_mips_64(ctx);
                   9189:             gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
                   9190:             break;
                   9191: #endif
                   9192:         case RR_CMP:
                   9193:             gen_logic(env, OPC_XOR, 24, rx, ry);
                   9194:             break;
                   9195:         case RR_NEG:
                   9196:             gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
                   9197:             break;
                   9198:         case RR_AND:
                   9199:             gen_logic(env, OPC_AND, rx, rx, ry);
                   9200:             break;
                   9201:         case RR_OR:
                   9202:             gen_logic(env, OPC_OR, rx, rx, ry);
                   9203:             break;
                   9204:         case RR_XOR:
                   9205:             gen_logic(env, OPC_XOR, rx, rx, ry);
                   9206:             break;
                   9207:         case RR_NOT:
                   9208:             gen_logic(env, OPC_NOR, rx, ry, 0);
                   9209:             break;
                   9210:         case RR_MFHI:
                   9211:             gen_HILO(ctx, OPC_MFHI, rx);
                   9212:             break;
                   9213:         case RR_CNVT:
                   9214:             switch (cnvt_op) {
                   9215:             case RR_RY_CNVT_ZEB:
                   9216:                 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
                   9217:                 break;
                   9218:             case RR_RY_CNVT_ZEH:
                   9219:                 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
                   9220:                 break;
                   9221:             case RR_RY_CNVT_SEB:
                   9222:                 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
                   9223:                 break;
                   9224:             case RR_RY_CNVT_SEH:
                   9225:                 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
                   9226:                 break;
                   9227: #if defined (TARGET_MIPS64)
                   9228:             case RR_RY_CNVT_ZEW:
                   9229:                 check_mips_64(ctx);
                   9230:                 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
                   9231:                 break;
                   9232:             case RR_RY_CNVT_SEW:
                   9233:                 check_mips_64(ctx);
                   9234:                 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
                   9235:                 break;
                   9236: #endif
                   9237:             default:
                   9238:                 generate_exception(ctx, EXCP_RI);
                   9239:                 break;
                   9240:             }
                   9241:             break;
                   9242:         case RR_MFLO:
                   9243:             gen_HILO(ctx, OPC_MFLO, rx);
                   9244:             break;
                   9245: #if defined (TARGET_MIPS64)
                   9246:         case RR_DSRA:
                   9247:             check_mips_64(ctx);
                   9248:             gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
                   9249:             break;
                   9250:         case RR_DSLLV:
                   9251:             check_mips_64(ctx);
                   9252:             gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
                   9253:             break;
                   9254:         case RR_DSRLV:
                   9255:             check_mips_64(ctx);
                   9256:             gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
                   9257:             break;
                   9258:         case RR_DSRAV:
                   9259:             check_mips_64(ctx);
                   9260:             gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
                   9261:             break;
                   9262: #endif
                   9263:         case RR_MULT:
                   9264:             gen_muldiv(ctx, OPC_MULT, rx, ry);
                   9265:             break;
                   9266:         case RR_MULTU:
                   9267:             gen_muldiv(ctx, OPC_MULTU, rx, ry);
                   9268:             break;
                   9269:         case RR_DIV:
                   9270:             gen_muldiv(ctx, OPC_DIV, rx, ry);
                   9271:             break;
                   9272:         case RR_DIVU:
                   9273:             gen_muldiv(ctx, OPC_DIVU, rx, ry);
                   9274:             break;
                   9275: #if defined (TARGET_MIPS64)
                   9276:         case RR_DMULT:
                   9277:             check_mips_64(ctx);
                   9278:             gen_muldiv(ctx, OPC_DMULT, rx, ry);
                   9279:             break;
                   9280:         case RR_DMULTU:
                   9281:             check_mips_64(ctx);
                   9282:             gen_muldiv(ctx, OPC_DMULTU, rx, ry);
                   9283:             break;
                   9284:         case RR_DDIV:
                   9285:             check_mips_64(ctx);
                   9286:             gen_muldiv(ctx, OPC_DDIV, rx, ry);
                   9287:             break;
                   9288:         case RR_DDIVU:
                   9289:             check_mips_64(ctx);
                   9290:             gen_muldiv(ctx, OPC_DDIVU, rx, ry);
                   9291:             break;
                   9292: #endif
                   9293:         default:
                   9294:             generate_exception(ctx, EXCP_RI);
                   9295:             break;
                   9296:         }
                   9297:         break;
                   9298:     case M16_OPC_EXTEND:
                   9299:         decode_extended_mips16_opc(env, ctx, is_branch);
                   9300:         n_bytes = 4;
                   9301:         break;
                   9302: #if defined(TARGET_MIPS64)
                   9303:     case M16_OPC_I64:
                   9304:         funct = (ctx->opcode >> 8) & 0x7;
                   9305:         decode_i64_mips16(env, ctx, ry, funct, offset, 0);
                   9306:         break;
                   9307: #endif
                   9308:     default:
                   9309:         generate_exception(ctx, EXCP_RI);
                   9310:         break;
                   9311:     }
                   9312: 
                   9313:     return n_bytes;
                   9314: }
                   9315: 
                   9316: /* microMIPS extension to MIPS32 */
                   9317: 
                   9318: /* microMIPS32 major opcodes */
                   9319: 
                   9320: enum {
                   9321:     POOL32A = 0x00,
                   9322:     POOL16A = 0x01,
                   9323:     LBU16 = 0x02,
                   9324:     MOVE16 = 0x03,
                   9325:     ADDI32 = 0x04,
                   9326:     LBU32 = 0x05,
                   9327:     SB32 = 0x06,
                   9328:     LB32 = 0x07,
                   9329: 
                   9330:     POOL32B = 0x08,
                   9331:     POOL16B = 0x09,
                   9332:     LHU16 = 0x0a,
                   9333:     ANDI16 = 0x0b,
                   9334:     ADDIU32 = 0x0c,
                   9335:     LHU32 = 0x0d,
                   9336:     SH32 = 0x0e,
                   9337:     LH32 = 0x0f,
                   9338: 
                   9339:     POOL32I = 0x10,
                   9340:     POOL16C = 0x11,
                   9341:     LWSP16 = 0x12,
                   9342:     POOL16D = 0x13,
                   9343:     ORI32 = 0x14,
                   9344:     POOL32F = 0x15,
                   9345:     POOL32S = 0x16,
                   9346:     DADDIU32 = 0x17,
                   9347: 
                   9348:     POOL32C = 0x18,
                   9349:     LWGP16 = 0x19,
                   9350:     LW16 = 0x1a,
                   9351:     POOL16E = 0x1b,
                   9352:     XORI32 = 0x1c,
                   9353:     JALS32 = 0x1d,
                   9354:     ADDIUPC = 0x1e,
                   9355:     POOL48A = 0x1f,
                   9356: 
                   9357:     /* 0x20 is reserved */
                   9358:     RES_20 = 0x20,
                   9359:     POOL16F = 0x21,
                   9360:     SB16 = 0x22,
                   9361:     BEQZ16 = 0x23,
                   9362:     SLTI32 = 0x24,
                   9363:     BEQ32 = 0x25,
                   9364:     SWC132 = 0x26,
                   9365:     LWC132 = 0x27,
                   9366: 
                   9367:     /* 0x28 and 0x29 are reserved */
                   9368:     RES_28 = 0x28,
                   9369:     RES_29 = 0x29,
                   9370:     SH16 = 0x2a,
                   9371:     BNEZ16 = 0x2b,
                   9372:     SLTIU32 = 0x2c,
                   9373:     BNE32 = 0x2d,
                   9374:     SDC132 = 0x2e,
                   9375:     LDC132 = 0x2f,
                   9376: 
                   9377:     /* 0x30 and 0x31 are reserved */
                   9378:     RES_30 = 0x30,
                   9379:     RES_31 = 0x31,
                   9380:     SWSP16 = 0x32,
                   9381:     B16 = 0x33,
                   9382:     ANDI32 = 0x34,
                   9383:     J32 = 0x35,
                   9384:     SD32 = 0x36,
                   9385:     LD32 = 0x37,
                   9386: 
                   9387:     /* 0x38 and 0x39 are reserved */
                   9388:     RES_38 = 0x38,
                   9389:     RES_39 = 0x39,
                   9390:     SW16 = 0x3a,
                   9391:     LI16 = 0x3b,
                   9392:     JALX32 = 0x3c,
                   9393:     JAL32 = 0x3d,
                   9394:     SW32 = 0x3e,
                   9395:     LW32 = 0x3f
                   9396: };
                   9397: 
                   9398: /* POOL32A encoding of minor opcode field */
                   9399: 
                   9400: enum {
                   9401:     /* These opcodes are distinguished only by bits 9..6; those bits are
                   9402:      * what are recorded below. */
                   9403:     SLL32 = 0x0,
                   9404:     SRL32 = 0x1,
                   9405:     SRA = 0x2,
                   9406:     ROTR = 0x3,
                   9407: 
                   9408:     SLLV = 0x0,
                   9409:     SRLV = 0x1,
                   9410:     SRAV = 0x2,
                   9411:     ROTRV = 0x3,
                   9412:     ADD = 0x4,
                   9413:     ADDU32 = 0x5,
                   9414:     SUB = 0x6,
                   9415:     SUBU32 = 0x7,
                   9416:     MUL = 0x8,
                   9417:     AND = 0x9,
                   9418:     OR32 = 0xa,
                   9419:     NOR = 0xb,
                   9420:     XOR32 = 0xc,
                   9421:     SLT = 0xd,
                   9422:     SLTU = 0xe,
                   9423: 
                   9424:     MOVN = 0x0,
                   9425:     MOVZ = 0x1,
                   9426:     LWXS = 0x4,
                   9427: 
                   9428:     /* The following can be distinguished by their lower 6 bits. */
                   9429:     INS = 0x0c,
                   9430:     EXT = 0x2c,
                   9431:     POOL32AXF = 0x3c
                   9432: };
                   9433: 
                   9434: /* POOL32AXF encoding of minor opcode field extension */
                   9435: 
                   9436: enum {
                   9437:     /* bits 11..6 */
                   9438:     TEQ = 0x00,
                   9439:     TGE = 0x08,
                   9440:     TGEU = 0x10,
                   9441:     TLT = 0x20,
                   9442:     TLTU = 0x28,
                   9443:     TNE = 0x30,
                   9444: 
                   9445:     MFC0 = 0x03,
                   9446:     MTC0 = 0x0b,
                   9447: 
                   9448:     /* bits 13..12 for 0x01 */
                   9449:     MFHI_ACC = 0x0,
                   9450:     MFLO_ACC = 0x1,
                   9451:     MTHI_ACC = 0x2,
                   9452:     MTLO_ACC = 0x3,
                   9453: 
                   9454:     /* bits 13..12 for 0x2a */
                   9455:     MADD_ACC = 0x0,
                   9456:     MADDU_ACC = 0x1,
                   9457:     MSUB_ACC = 0x2,
                   9458:     MSUBU_ACC = 0x3,
                   9459: 
                   9460:     /* bits 13..12 for 0x32 */
                   9461:     MULT_ACC = 0x0,
                   9462:     MULTU_ACC = 0x0,
                   9463: 
                   9464:     /* bits 15..12 for 0x2c */
                   9465:     SEB = 0x2,
                   9466:     SEH = 0x3,
                   9467:     CLO = 0x4,
                   9468:     CLZ = 0x5,
                   9469:     RDHWR = 0x6,
                   9470:     WSBH = 0x7,
                   9471:     MULT = 0x8,
                   9472:     MULTU = 0x9,
                   9473:     DIV = 0xa,
                   9474:     DIVU = 0xb,
                   9475:     MADD = 0xc,
                   9476:     MADDU = 0xd,
                   9477:     MSUB = 0xe,
                   9478:     MSUBU = 0xf,
                   9479: 
                   9480:     /* bits 15..12 for 0x34 */
                   9481:     MFC2 = 0x4,
                   9482:     MTC2 = 0x5,
                   9483:     MFHC2 = 0x8,
                   9484:     MTHC2 = 0x9,
                   9485:     CFC2 = 0xc,
                   9486:     CTC2 = 0xd,
                   9487: 
                   9488:     /* bits 15..12 for 0x3c */
                   9489:     JALR = 0x0,
                   9490:     JR = 0x0,                   /* alias */
                   9491:     JALR_HB = 0x1,
                   9492:     JALRS = 0x4,
                   9493:     JALRS_HB = 0x5,
                   9494: 
                   9495:     /* bits 15..12 for 0x05 */
                   9496:     RDPGPR = 0xe,
                   9497:     WRPGPR = 0xf,
                   9498: 
                   9499:     /* bits 15..12 for 0x0d */
                   9500:     TLBP = 0x0,
                   9501:     TLBR = 0x1,
                   9502:     TLBWI = 0x2,
                   9503:     TLBWR = 0x3,
                   9504:     WAIT = 0x9,
                   9505:     IRET = 0xd,
                   9506:     DERET = 0xe,
                   9507:     ERET = 0xf,
                   9508: 
                   9509:     /* bits 15..12 for 0x15 */
                   9510:     DMT = 0x0,
                   9511:     DVPE = 0x1,
                   9512:     EMT = 0x2,
                   9513:     EVPE = 0x3,
                   9514: 
                   9515:     /* bits 15..12 for 0x1d */
                   9516:     DI = 0x4,
                   9517:     EI = 0x5,
                   9518: 
                   9519:     /* bits 15..12 for 0x2d */
                   9520:     SYNC = 0x6,
                   9521:     SYSCALL = 0x8,
                   9522:     SDBBP = 0xd,
                   9523: 
                   9524:     /* bits 15..12 for 0x35 */
                   9525:     MFHI32 = 0x0,
                   9526:     MFLO32 = 0x1,
                   9527:     MTHI32 = 0x2,
                   9528:     MTLO32 = 0x3,
                   9529: };
                   9530: 
                   9531: /* POOL32B encoding of minor opcode field (bits 15..12) */
                   9532: 
                   9533: enum {
                   9534:     LWC2 = 0x0,
                   9535:     LWP = 0x1,
                   9536:     LDP = 0x4,
                   9537:     LWM32 = 0x5,
                   9538:     CACHE = 0x6,
                   9539:     LDM = 0x7,
                   9540:     SWC2 = 0x8,
                   9541:     SWP = 0x9,
                   9542:     SDP = 0xc,
                   9543:     SWM32 = 0xd,
                   9544:     SDM = 0xf
                   9545: };
                   9546: 
                   9547: /* POOL32C encoding of minor opcode field (bits 15..12) */
                   9548: 
                   9549: enum {
                   9550:     LWL = 0x0,
                   9551:     SWL = 0x8,
                   9552:     LWR = 0x1,
                   9553:     SWR = 0x9,
                   9554:     PREF = 0x2,
                   9555:     /* 0xa is reserved */
                   9556:     LL = 0x3,
                   9557:     SC = 0xb,
                   9558:     LDL = 0x4,
                   9559:     SDL = 0xc,
                   9560:     LDR = 0x5,
                   9561:     SDR = 0xd,
                   9562:     /* 0x6 is reserved */
                   9563:     LWU = 0xe,
                   9564:     LLD = 0x7,
                   9565:     SCD = 0xf
                   9566: };
                   9567: 
                   9568: /* POOL32F encoding of minor opcode field (bits 5..0) */
                   9569: 
                   9570: enum {
                   9571:     /* These are the bit 7..6 values */
                   9572:     ADD_FMT = 0x0,
                   9573:     MOVN_FMT = 0x0,
                   9574: 
                   9575:     SUB_FMT = 0x1,
                   9576:     MOVZ_FMT = 0x1,
                   9577: 
                   9578:     MUL_FMT = 0x2,
                   9579: 
                   9580:     DIV_FMT = 0x3,
                   9581: 
                   9582:     /* These are the bit 8..6 values */
                   9583:     RSQRT2_FMT = 0x0,
                   9584:     MOVF_FMT = 0x0,
                   9585: 
                   9586:     LWXC1 = 0x1,
                   9587:     MOVT_FMT = 0x1,
                   9588: 
                   9589:     PLL_PS = 0x2,
                   9590:     SWXC1 = 0x2,
                   9591: 
                   9592:     PLU_PS = 0x3,
                   9593:     LDXC1 = 0x3,
                   9594: 
                   9595:     PUL_PS = 0x4,
                   9596:     SDXC1 = 0x4,
                   9597:     RECIP2_FMT = 0x4,
                   9598: 
                   9599:     PUU_PS = 0x5,
                   9600:     LUXC1 = 0x5,
                   9601: 
                   9602:     CVT_PS_S = 0x6,
                   9603:     SUXC1 = 0x6,
                   9604:     ADDR_PS = 0x6,
                   9605:     PREFX = 0x6,
                   9606: 
                   9607:     MULR_PS = 0x7,
                   9608: 
                   9609:     MADD_S = 0x01,
                   9610:     MADD_D = 0x09,
                   9611:     MADD_PS = 0x11,
                   9612:     ALNV_PS = 0x19,
                   9613:     MSUB_S = 0x21,
                   9614:     MSUB_D = 0x29,
                   9615:     MSUB_PS = 0x31,
                   9616: 
                   9617:     NMADD_S = 0x02,
                   9618:     NMADD_D = 0x0a,
                   9619:     NMADD_PS = 0x12,
                   9620:     NMSUB_S = 0x22,
                   9621:     NMSUB_D = 0x2a,
                   9622:     NMSUB_PS = 0x32,
                   9623: 
                   9624:     POOL32FXF = 0x3b,
                   9625: 
                   9626:     CABS_COND_FMT = 0x1c,              /* MIPS3D */
                   9627:     C_COND_FMT = 0x3c
                   9628: };
                   9629: 
                   9630: /* POOL32Fxf encoding of minor opcode extension field */
                   9631: 
                   9632: enum {
                   9633:     CVT_L = 0x04,
                   9634:     RSQRT_FMT = 0x08,
                   9635:     FLOOR_L = 0x0c,
                   9636:     CVT_PW_PS = 0x1c,
                   9637:     CVT_W = 0x24,
                   9638:     SQRT_FMT = 0x28,
                   9639:     FLOOR_W = 0x2c,
                   9640:     CVT_PS_PW = 0x3c,
                   9641:     CFC1 = 0x40,
                   9642:     RECIP_FMT = 0x48,
                   9643:     CEIL_L = 0x4c,
                   9644:     CTC1 = 0x60,
                   9645:     CEIL_W = 0x6c,
                   9646:     MFC1 = 0x80,
                   9647:     CVT_S_PL = 0x84,
                   9648:     TRUNC_L = 0x8c,
                   9649:     MTC1 = 0xa0,
                   9650:     CVT_S_PU = 0xa4,
                   9651:     TRUNC_W = 0xac,
                   9652:     MFHC1 = 0xc0,
                   9653:     ROUND_L = 0xcc,
                   9654:     MTHC1 = 0xe0,
                   9655:     ROUND_W = 0xec,
                   9656: 
                   9657:     MOV_FMT = 0x01,
                   9658:     MOVF = 0x05,
                   9659:     ABS_FMT = 0x0d,
                   9660:     RSQRT1_FMT = 0x1d,
                   9661:     MOVT = 0x25,
                   9662:     NEG_FMT = 0x2d,
                   9663:     CVT_D = 0x4d,
                   9664:     RECIP1_FMT = 0x5d,
                   9665:     CVT_S = 0x6d
                   9666: };
                   9667: 
                   9668: /* POOL32I encoding of minor opcode field (bits 25..21) */
                   9669: 
                   9670: enum {
                   9671:     BLTZ = 0x00,
                   9672:     BLTZAL = 0x01,
                   9673:     BGEZ = 0x02,
                   9674:     BGEZAL = 0x03,
                   9675:     BLEZ = 0x04,
                   9676:     BNEZC = 0x05,
                   9677:     BGTZ = 0x06,
                   9678:     BEQZC = 0x07,
                   9679:     TLTI = 0x08,
                   9680:     TGEI = 0x09,
                   9681:     TLTIU = 0x0a,
                   9682:     TGEIU = 0x0b,
                   9683:     TNEI = 0x0c,
                   9684:     LUI = 0x0d,
                   9685:     TEQI = 0x0e,
                   9686:     SYNCI = 0x10,
                   9687:     BLTZALS = 0x11,
                   9688:     BGEZALS = 0x13,
                   9689:     BC2F = 0x14,
                   9690:     BC2T = 0x15,
                   9691:     BPOSGE64 = 0x1a,
                   9692:     BPOSGE32 = 0x1b,
                   9693:     /* These overlap and are distinguished by bit16 of the instruction */
                   9694:     BC1F = 0x1c,
                   9695:     BC1T = 0x1d,
                   9696:     BC1ANY2F = 0x1c,
                   9697:     BC1ANY2T = 0x1d,
                   9698:     BC1ANY4F = 0x1e,
                   9699:     BC1ANY4T = 0x1f
                   9700: };
                   9701: 
                   9702: /* POOL16A encoding of minor opcode field */
                   9703: 
                   9704: enum {
                   9705:     ADDU16 = 0x0,
                   9706:     SUBU16 = 0x1
                   9707: };
                   9708: 
                   9709: /* POOL16B encoding of minor opcode field */
                   9710: 
                   9711: enum {
                   9712:     SLL16 = 0x0,
                   9713:     SRL16 = 0x1
                   9714: };
                   9715: 
                   9716: /* POOL16C encoding of minor opcode field */
                   9717: 
                   9718: enum {
                   9719:     NOT16 = 0x00,
                   9720:     XOR16 = 0x04,
                   9721:     AND16 = 0x08,
                   9722:     OR16 = 0x0c,
                   9723:     LWM16 = 0x10,
                   9724:     SWM16 = 0x14,
                   9725:     JR16 = 0x18,
                   9726:     JRC16 = 0x1a,
                   9727:     JALR16 = 0x1c,
                   9728:     JALR16S = 0x1e,
                   9729:     MFHI16 = 0x20,
                   9730:     MFLO16 = 0x24,
                   9731:     BREAK16 = 0x28,
                   9732:     SDBBP16 = 0x2c,
                   9733:     JRADDIUSP = 0x30
                   9734: };
                   9735: 
                   9736: /* POOL16D encoding of minor opcode field */
                   9737: 
                   9738: enum {
                   9739:     ADDIUS5 = 0x0,
                   9740:     ADDIUSP = 0x1
                   9741: };
                   9742: 
                   9743: /* POOL16E encoding of minor opcode field */
                   9744: 
                   9745: enum {
                   9746:     ADDIUR2 = 0x0,
                   9747:     ADDIUR1SP = 0x1
                   9748: };
                   9749: 
                   9750: static int mmreg (int r)
                   9751: {
                   9752:     static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
                   9753: 
                   9754:     return map[r];
                   9755: }
                   9756: 
                   9757: /* Used for 16-bit store instructions.  */
                   9758: static int mmreg2 (int r)
                   9759: {
                   9760:     static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
                   9761: 
                   9762:     return map[r];
                   9763: }
                   9764: 
                   9765: #define uMIPS_RD(op) ((op >> 7) & 0x7)
                   9766: #define uMIPS_RS(op) ((op >> 4) & 0x7)
                   9767: #define uMIPS_RS2(op) uMIPS_RS(op)
                   9768: #define uMIPS_RS1(op) ((op >> 1) & 0x7)
                   9769: #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
                   9770: #define uMIPS_RS5(op) (op & 0x1f)
                   9771: 
                   9772: /* Signed immediate */
                   9773: #define SIMM(op, start, width)                                          \
                   9774:     ((int32_t)(((op >> start) & ((~0U) >> (32-width)))                 \
                   9775:                << (32-width))                                           \
                   9776:      >> (32-width))
                   9777: /* Zero-extended immediate */
                   9778: #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
                   9779: 
1.1.1.16! root     9780: static void gen_addiur1sp (CPUMIPSState *env, DisasContext *ctx)
1.1.1.12  root     9781: {
                   9782:     int rd = mmreg(uMIPS_RD(ctx->opcode));
                   9783: 
                   9784:     gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
                   9785: }
                   9786: 
1.1.1.16! root     9787: static void gen_addiur2 (CPUMIPSState *env, DisasContext *ctx)
1.1.1.12  root     9788: {
                   9789:     static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
                   9790:     int rd = mmreg(uMIPS_RD(ctx->opcode));
                   9791:     int rs = mmreg(uMIPS_RS(ctx->opcode));
                   9792: 
                   9793:     gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
                   9794: }
                   9795: 
1.1.1.16! root     9796: static void gen_addiusp (CPUMIPSState *env, DisasContext *ctx)
1.1.1.12  root     9797: {
                   9798:     int encoded = ZIMM(ctx->opcode, 1, 9);
                   9799:     int decoded;
                   9800: 
                   9801:     if (encoded <= 1) {
                   9802:         decoded = 256 + encoded;
                   9803:     } else if (encoded <= 255) {
                   9804:         decoded = encoded;
                   9805:     } else if (encoded <= 509) {
                   9806:         decoded = encoded - 512;
                   9807:     } else {
                   9808:         decoded = encoded - 768;
                   9809:     }
                   9810: 
                   9811:     gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
                   9812: }
                   9813: 
1.1.1.16! root     9814: static void gen_addius5 (CPUMIPSState *env, DisasContext *ctx)
1.1.1.12  root     9815: {
                   9816:     int imm = SIMM(ctx->opcode, 1, 4);
                   9817:     int rd = (ctx->opcode >> 5) & 0x1f;
                   9818: 
                   9819:     gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
                   9820: }
                   9821: 
1.1.1.16! root     9822: static void gen_andi16 (CPUMIPSState *env, DisasContext *ctx)
1.1.1.12  root     9823: {
                   9824:     static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
                   9825:                                  31, 32, 63, 64, 255, 32768, 65535 };
                   9826:     int rd = mmreg(uMIPS_RD(ctx->opcode));
                   9827:     int rs = mmreg(uMIPS_RS(ctx->opcode));
                   9828:     int encoded = ZIMM(ctx->opcode, 0, 4);
                   9829: 
                   9830:     gen_logic_imm(env, OPC_ANDI, rd, rs, decoded_imm[encoded]);
                   9831: }
                   9832: 
                   9833: static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
                   9834:                                int base, int16_t offset)
                   9835: {
                   9836:     TCGv t0, t1;
                   9837:     TCGv_i32 t2;
                   9838: 
                   9839:     if (ctx->hflags & MIPS_HFLAG_BMASK) {
                   9840:         generate_exception(ctx, EXCP_RI);
                   9841:         return;
                   9842:     }
                   9843: 
                   9844:     t0 = tcg_temp_new();
                   9845: 
                   9846:     gen_base_offset_addr(ctx, t0, base, offset);
                   9847: 
                   9848:     t1 = tcg_const_tl(reglist);
                   9849:     t2 = tcg_const_i32(ctx->mem_idx);
                   9850: 
                   9851:     save_cpu_state(ctx, 1);
                   9852:     switch (opc) {
                   9853:     case LWM32:
                   9854:         gen_helper_lwm(t0, t1, t2);
                   9855:         break;
                   9856:     case SWM32:
                   9857:         gen_helper_swm(t0, t1, t2);
                   9858:         break;
                   9859: #ifdef TARGET_MIPS64
                   9860:     case LDM:
                   9861:         gen_helper_ldm(t0, t1, t2);
                   9862:         break;
                   9863:     case SDM:
                   9864:         gen_helper_sdm(t0, t1, t2);
                   9865:         break;
                   9866: #endif
                   9867:     }
                   9868:     MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
                   9869:     tcg_temp_free(t0);
                   9870:     tcg_temp_free(t1);
                   9871:     tcg_temp_free_i32(t2);
                   9872: }
                   9873: 
                   9874: 
1.1.1.16! root     9875: static void gen_pool16c_insn (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
1.1.1.12  root     9876: {
                   9877:     int rd = mmreg((ctx->opcode >> 3) & 0x7);
                   9878:     int rs = mmreg(ctx->opcode & 0x7);
                   9879:     int opc;
                   9880: 
                   9881:     switch (((ctx->opcode) >> 4) & 0x3f) {
                   9882:     case NOT16 + 0:
                   9883:     case NOT16 + 1:
                   9884:     case NOT16 + 2:
                   9885:     case NOT16 + 3:
                   9886:         gen_logic(env, OPC_NOR, rd, rs, 0);
                   9887:         break;
                   9888:     case XOR16 + 0:
                   9889:     case XOR16 + 1:
                   9890:     case XOR16 + 2:
                   9891:     case XOR16 + 3:
                   9892:         gen_logic(env, OPC_XOR, rd, rd, rs);
                   9893:         break;
                   9894:     case AND16 + 0:
                   9895:     case AND16 + 1:
                   9896:     case AND16 + 2:
                   9897:     case AND16 + 3:
                   9898:         gen_logic(env, OPC_AND, rd, rd, rs);
                   9899:         break;
                   9900:     case OR16 + 0:
                   9901:     case OR16 + 1:
                   9902:     case OR16 + 2:
                   9903:     case OR16 + 3:
                   9904:         gen_logic(env, OPC_OR, rd, rd, rs);
                   9905:         break;
                   9906:     case LWM16 + 0:
                   9907:     case LWM16 + 1:
                   9908:     case LWM16 + 2:
                   9909:     case LWM16 + 3:
                   9910:         {
                   9911:             static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
                   9912:             int offset = ZIMM(ctx->opcode, 0, 4);
                   9913: 
                   9914:             gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
                   9915:                               29, offset << 2);
                   9916:         }
                   9917:         break;
                   9918:     case SWM16 + 0:
                   9919:     case SWM16 + 1:
                   9920:     case SWM16 + 2:
                   9921:     case SWM16 + 3:
                   9922:         {
                   9923:             static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
                   9924:             int offset = ZIMM(ctx->opcode, 0, 4);
                   9925: 
                   9926:             gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
                   9927:                               29, offset << 2);
                   9928:         }
                   9929:         break;
                   9930:     case JR16 + 0:
                   9931:     case JR16 + 1:
                   9932:         {
                   9933:             int reg = ctx->opcode & 0x1f;
                   9934: 
                   9935:             gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
                   9936:         }
                   9937:         *is_branch = 1;
                   9938:         break;
                   9939:     case JRC16 + 0:
                   9940:     case JRC16 + 1:
                   9941:         {
                   9942:             int reg = ctx->opcode & 0x1f;
                   9943: 
                   9944:             gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
                   9945:             /* Let normal delay slot handling in our caller take us
                   9946:                to the branch target.  */
                   9947:         }
                   9948:         break;
                   9949:     case JALR16 + 0:
                   9950:     case JALR16 + 1:
                   9951:         opc = OPC_JALR;
                   9952:         goto do_jalr;
                   9953:     case JALR16S + 0:
                   9954:     case JALR16S + 1:
                   9955:         opc = OPC_JALRS;
                   9956:     do_jalr:
                   9957:         {
                   9958:             int reg = ctx->opcode & 0x1f;
                   9959: 
                   9960:             gen_compute_branch(ctx, opc, 2, reg, 31, 0);
                   9961:         }
                   9962:         *is_branch = 1;
                   9963:         break;
                   9964:     case MFHI16 + 0:
                   9965:     case MFHI16 + 1:
                   9966:         gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
                   9967:         break;
                   9968:     case MFLO16 + 0:
                   9969:     case MFLO16 + 1:
                   9970:         gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
                   9971:         break;
                   9972:     case BREAK16:
                   9973:         generate_exception(ctx, EXCP_BREAK);
                   9974:         break;
                   9975:     case SDBBP16:
                   9976:         /* XXX: not clear which exception should be raised
                   9977:          *      when in debug mode...
                   9978:          */
                   9979:         check_insn(env, ctx, ISA_MIPS32);
                   9980:         if (!(ctx->hflags & MIPS_HFLAG_DM)) {
                   9981:             generate_exception(ctx, EXCP_DBp);
                   9982:         } else {
                   9983:             generate_exception(ctx, EXCP_DBp);
                   9984:         }
                   9985:         break;
                   9986:     case JRADDIUSP + 0:
                   9987:     case JRADDIUSP + 1:
                   9988:         {
                   9989:             int imm = ZIMM(ctx->opcode, 0, 5);
                   9990: 
                   9991:             gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
                   9992:             gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
                   9993:             /* Let normal delay slot handling in our caller take us
                   9994:                to the branch target.  */
                   9995:         }
                   9996:         break;
                   9997:     default:
                   9998:         generate_exception(ctx, EXCP_RI);
                   9999:         break;
                   10000:     }
                   10001: }
                   10002: 
                   10003: static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
                   10004: {
                   10005:     TCGv t0 = tcg_temp_new();
                   10006:     TCGv t1 = tcg_temp_new();
                   10007: 
                   10008:     gen_load_gpr(t0, base);
                   10009: 
                   10010:     if (index != 0) {
                   10011:         gen_load_gpr(t1, index);
                   10012:         tcg_gen_shli_tl(t1, t1, 2);
                   10013:         gen_op_addr_add(ctx, t0, t1, t0);
                   10014:     }
                   10015: 
                   10016:     save_cpu_state(ctx, 0);
                   10017:     op_ld_lw(t1, t0, ctx);
                   10018:     gen_store_gpr(t1, rd);
                   10019: 
                   10020:     tcg_temp_free(t0);
                   10021:     tcg_temp_free(t1);
                   10022: }
                   10023: 
                   10024: static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
                   10025:                            int base, int16_t offset)
                   10026: {
                   10027:     const char *opn = "ldst_pair";
                   10028:     TCGv t0, t1;
                   10029: 
                   10030:     if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31 || rd == base) {
                   10031:         generate_exception(ctx, EXCP_RI);
                   10032:         return;
                   10033:     }
                   10034: 
                   10035:     t0 = tcg_temp_new();
                   10036:     t1 = tcg_temp_new();
                   10037: 
                   10038:     gen_base_offset_addr(ctx, t0, base, offset);
                   10039: 
                   10040:     switch (opc) {
                   10041:     case LWP:
                   10042:         save_cpu_state(ctx, 0);
                   10043:         op_ld_lw(t1, t0, ctx);
                   10044:         gen_store_gpr(t1, rd);
                   10045:         tcg_gen_movi_tl(t1, 4);
                   10046:         gen_op_addr_add(ctx, t0, t0, t1);
                   10047:         op_ld_lw(t1, t0, ctx);
                   10048:         gen_store_gpr(t1, rd+1);
                   10049:         opn = "lwp";
                   10050:         break;
                   10051:     case SWP:
1.1.1.13  root     10052:         save_cpu_state(ctx, 0);
1.1.1.12  root     10053:         gen_load_gpr(t1, rd);
                   10054:         op_st_sw(t1, t0, ctx);
                   10055:         tcg_gen_movi_tl(t1, 4);
                   10056:         gen_op_addr_add(ctx, t0, t0, t1);
                   10057:         gen_load_gpr(t1, rd+1);
                   10058:         op_st_sw(t1, t0, ctx);
                   10059:         opn = "swp";
                   10060:         break;
                   10061: #ifdef TARGET_MIPS64
                   10062:     case LDP:
                   10063:         save_cpu_state(ctx, 0);
                   10064:         op_ld_ld(t1, t0, ctx);
                   10065:         gen_store_gpr(t1, rd);
                   10066:         tcg_gen_movi_tl(t1, 8);
                   10067:         gen_op_addr_add(ctx, t0, t0, t1);
                   10068:         op_ld_ld(t1, t0, ctx);
                   10069:         gen_store_gpr(t1, rd+1);
                   10070:         opn = "ldp";
                   10071:         break;
                   10072:     case SDP:
1.1.1.13  root     10073:         save_cpu_state(ctx, 0);
1.1.1.12  root     10074:         gen_load_gpr(t1, rd);
                   10075:         op_st_sd(t1, t0, ctx);
                   10076:         tcg_gen_movi_tl(t1, 8);
                   10077:         gen_op_addr_add(ctx, t0, t0, t1);
                   10078:         gen_load_gpr(t1, rd+1);
                   10079:         op_st_sd(t1, t0, ctx);
                   10080:         opn = "sdp";
                   10081:         break;
                   10082: #endif
                   10083:     }
1.1.1.13  root     10084:     (void)opn; /* avoid a compiler warning */
1.1.1.12  root     10085:     MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
                   10086:     tcg_temp_free(t0);
                   10087:     tcg_temp_free(t1);
                   10088: }
                   10089: 
1.1.1.16! root     10090: static void gen_pool32axf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs,
1.1.1.12  root     10091:                            int *is_branch)
                   10092: {
                   10093:     int extension = (ctx->opcode >> 6) & 0x3f;
                   10094:     int minor = (ctx->opcode >> 12) & 0xf;
                   10095:     uint32_t mips32_op;
                   10096: 
                   10097:     switch (extension) {
                   10098:     case TEQ:
                   10099:         mips32_op = OPC_TEQ;
                   10100:         goto do_trap;
                   10101:     case TGE:
                   10102:         mips32_op = OPC_TGE;
                   10103:         goto do_trap;
                   10104:     case TGEU:
                   10105:         mips32_op = OPC_TGEU;
                   10106:         goto do_trap;
                   10107:     case TLT:
                   10108:         mips32_op = OPC_TLT;
                   10109:         goto do_trap;
                   10110:     case TLTU:
                   10111:         mips32_op = OPC_TLTU;
                   10112:         goto do_trap;
                   10113:     case TNE:
                   10114:         mips32_op = OPC_TNE;
                   10115:     do_trap:
                   10116:         gen_trap(ctx, mips32_op, rs, rt, -1);
                   10117:         break;
                   10118: #ifndef CONFIG_USER_ONLY
                   10119:     case MFC0:
                   10120:     case MFC0 + 32:
                   10121:         if (rt == 0) {
                   10122:             /* Treat as NOP. */
                   10123:             break;
                   10124:         }
                   10125:         gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
                   10126:         break;
                   10127:     case MTC0:
                   10128:     case MTC0 + 32:
                   10129:         {
                   10130:             TCGv t0 = tcg_temp_new();
                   10131: 
                   10132:             gen_load_gpr(t0, rt);
                   10133:             gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
                   10134:             tcg_temp_free(t0);
                   10135:         }
                   10136:         break;
                   10137: #endif
                   10138:     case 0x2c:
                   10139:         switch (minor) {
                   10140:         case SEB:
                   10141:             gen_bshfl(ctx, OPC_SEB, rs, rt);
                   10142:             break;
                   10143:         case SEH:
                   10144:             gen_bshfl(ctx, OPC_SEH, rs, rt);
                   10145:             break;
                   10146:         case CLO:
                   10147:             mips32_op = OPC_CLO;
                   10148:             goto do_cl;
                   10149:         case CLZ:
                   10150:             mips32_op = OPC_CLZ;
                   10151:         do_cl:
                   10152:             check_insn(env, ctx, ISA_MIPS32);
                   10153:             gen_cl(ctx, mips32_op, rt, rs);
                   10154:             break;
                   10155:         case RDHWR:
                   10156:             gen_rdhwr(env, ctx, rt, rs);
                   10157:             break;
                   10158:         case WSBH:
                   10159:             gen_bshfl(ctx, OPC_WSBH, rs, rt);
                   10160:             break;
                   10161:         case MULT:
                   10162:             mips32_op = OPC_MULT;
                   10163:             goto do_muldiv;
                   10164:         case MULTU:
                   10165:             mips32_op = OPC_MULTU;
                   10166:             goto do_muldiv;
                   10167:         case DIV:
                   10168:             mips32_op = OPC_DIV;
                   10169:             goto do_muldiv;
                   10170:         case DIVU:
                   10171:             mips32_op = OPC_DIVU;
                   10172:             goto do_muldiv;
                   10173:         case MADD:
                   10174:             mips32_op = OPC_MADD;
                   10175:             goto do_muldiv;
                   10176:         case MADDU:
                   10177:             mips32_op = OPC_MADDU;
                   10178:             goto do_muldiv;
                   10179:         case MSUB:
                   10180:             mips32_op = OPC_MSUB;
                   10181:             goto do_muldiv;
                   10182:         case MSUBU:
                   10183:             mips32_op = OPC_MSUBU;
                   10184:         do_muldiv:
                   10185:             check_insn(env, ctx, ISA_MIPS32);
                   10186:             gen_muldiv(ctx, mips32_op, rs, rt);
                   10187:             break;
                   10188:         default:
                   10189:             goto pool32axf_invalid;
                   10190:         }
                   10191:         break;
                   10192:     case 0x34:
                   10193:         switch (minor) {
                   10194:         case MFC2:
                   10195:         case MTC2:
                   10196:         case MFHC2:
                   10197:         case MTHC2:
                   10198:         case CFC2:
                   10199:         case CTC2:
                   10200:             generate_exception_err(ctx, EXCP_CpU, 2);
                   10201:             break;
                   10202:         default:
                   10203:             goto pool32axf_invalid;
                   10204:         }
                   10205:         break;
                   10206:     case 0x3c:
                   10207:         switch (minor) {
                   10208:         case JALR:
                   10209:         case JALR_HB:
                   10210:             gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
                   10211:             *is_branch = 1;
                   10212:             break;
                   10213:         case JALRS:
                   10214:         case JALRS_HB:
                   10215:             gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
                   10216:             *is_branch = 1;
                   10217:             break;
                   10218:         default:
                   10219:             goto pool32axf_invalid;
                   10220:         }
                   10221:         break;
                   10222:     case 0x05:
                   10223:         switch (minor) {
                   10224:         case RDPGPR:
                   10225:             check_insn(env, ctx, ISA_MIPS32R2);
                   10226:             gen_load_srsgpr(rt, rs);
                   10227:             break;
                   10228:         case WRPGPR:
                   10229:             check_insn(env, ctx, ISA_MIPS32R2);
                   10230:             gen_store_srsgpr(rt, rs);
                   10231:             break;
                   10232:         default:
                   10233:             goto pool32axf_invalid;
                   10234:         }
                   10235:         break;
                   10236: #ifndef CONFIG_USER_ONLY
                   10237:     case 0x0d:
                   10238:         switch (minor) {
                   10239:         case TLBP:
                   10240:             mips32_op = OPC_TLBP;
                   10241:             goto do_cp0;
                   10242:         case TLBR:
                   10243:             mips32_op = OPC_TLBR;
                   10244:             goto do_cp0;
                   10245:         case TLBWI:
                   10246:             mips32_op = OPC_TLBWI;
                   10247:             goto do_cp0;
                   10248:         case TLBWR:
                   10249:             mips32_op = OPC_TLBWR;
                   10250:             goto do_cp0;
                   10251:         case WAIT:
                   10252:             mips32_op = OPC_WAIT;
                   10253:             goto do_cp0;
                   10254:         case DERET:
                   10255:             mips32_op = OPC_DERET;
                   10256:             goto do_cp0;
                   10257:         case ERET:
                   10258:             mips32_op = OPC_ERET;
                   10259:         do_cp0:
                   10260:             gen_cp0(env, ctx, mips32_op, rt, rs);
                   10261:             break;
                   10262:         default:
                   10263:             goto pool32axf_invalid;
                   10264:         }
                   10265:         break;
                   10266:     case 0x1d:
                   10267:         switch (minor) {
                   10268:         case DI:
                   10269:             {
                   10270:                 TCGv t0 = tcg_temp_new();
                   10271: 
                   10272:                 save_cpu_state(ctx, 1);
                   10273:                 gen_helper_di(t0);
                   10274:                 gen_store_gpr(t0, rs);
                   10275:                 /* Stop translation as we may have switched the execution mode */
                   10276:                 ctx->bstate = BS_STOP;
                   10277:                 tcg_temp_free(t0);
                   10278:             }
                   10279:             break;
                   10280:         case EI:
                   10281:             {
                   10282:                 TCGv t0 = tcg_temp_new();
                   10283: 
                   10284:                 save_cpu_state(ctx, 1);
                   10285:                 gen_helper_ei(t0);
                   10286:                 gen_store_gpr(t0, rs);
                   10287:                 /* Stop translation as we may have switched the execution mode */
                   10288:                 ctx->bstate = BS_STOP;
                   10289:                 tcg_temp_free(t0);
                   10290:             }
                   10291:             break;
                   10292:         default:
                   10293:             goto pool32axf_invalid;
                   10294:         }
                   10295:         break;
                   10296: #endif
                   10297:     case 0x2d:
                   10298:         switch (minor) {
                   10299:         case SYNC:
                   10300:             /* NOP */
                   10301:             break;
                   10302:         case SYSCALL:
                   10303:             generate_exception(ctx, EXCP_SYSCALL);
                   10304:             ctx->bstate = BS_STOP;
                   10305:             break;
                   10306:         case SDBBP:
                   10307:             check_insn(env, ctx, ISA_MIPS32);
                   10308:             if (!(ctx->hflags & MIPS_HFLAG_DM)) {
                   10309:                 generate_exception(ctx, EXCP_DBp);
                   10310:             } else {
                   10311:                 generate_exception(ctx, EXCP_DBp);
                   10312:             }
                   10313:             break;
                   10314:         default:
                   10315:             goto pool32axf_invalid;
                   10316:         }
                   10317:         break;
                   10318:     case 0x35:
                   10319:         switch (minor) {
                   10320:         case MFHI32:
                   10321:             gen_HILO(ctx, OPC_MFHI, rs);
                   10322:             break;
                   10323:         case MFLO32:
                   10324:             gen_HILO(ctx, OPC_MFLO, rs);
                   10325:             break;
                   10326:         case MTHI32:
                   10327:             gen_HILO(ctx, OPC_MTHI, rs);
                   10328:             break;
                   10329:         case MTLO32:
                   10330:             gen_HILO(ctx, OPC_MTLO, rs);
                   10331:             break;
                   10332:         default:
                   10333:             goto pool32axf_invalid;
                   10334:         }
                   10335:         break;
                   10336:     default:
                   10337:     pool32axf_invalid:
                   10338:         MIPS_INVAL("pool32axf");
                   10339:         generate_exception(ctx, EXCP_RI);
                   10340:         break;
                   10341:     }
                   10342: }
                   10343: 
                   10344: /* Values for microMIPS fmt field.  Variable-width, depending on which
                   10345:    formats the instruction supports.  */
                   10346: 
                   10347: enum {
                   10348:     FMT_SD_S = 0,
                   10349:     FMT_SD_D = 1,
                   10350: 
                   10351:     FMT_SDPS_S = 0,
                   10352:     FMT_SDPS_D = 1,
                   10353:     FMT_SDPS_PS = 2,
                   10354: 
                   10355:     FMT_SWL_S = 0,
                   10356:     FMT_SWL_W = 1,
                   10357:     FMT_SWL_L = 2,
                   10358: 
                   10359:     FMT_DWL_D = 0,
                   10360:     FMT_DWL_W = 1,
                   10361:     FMT_DWL_L = 2
                   10362: };
                   10363: 
1.1.1.16! root     10364: static void gen_pool32fxf (CPUMIPSState *env, DisasContext *ctx, int rt, int rs)
1.1.1.12  root     10365: {
                   10366:     int extension = (ctx->opcode >> 6) & 0x3ff;
                   10367:     uint32_t mips32_op;
                   10368: 
                   10369: #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
                   10370: #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
                   10371: #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
                   10372: 
                   10373:     switch (extension) {
                   10374:     case FLOAT_1BIT_FMT(CFC1, 0):
                   10375:         mips32_op = OPC_CFC1;
                   10376:         goto do_cp1;
                   10377:     case FLOAT_1BIT_FMT(CTC1, 0):
                   10378:         mips32_op = OPC_CTC1;
                   10379:         goto do_cp1;
                   10380:     case FLOAT_1BIT_FMT(MFC1, 0):
                   10381:         mips32_op = OPC_MFC1;
                   10382:         goto do_cp1;
                   10383:     case FLOAT_1BIT_FMT(MTC1, 0):
                   10384:         mips32_op = OPC_MTC1;
                   10385:         goto do_cp1;
                   10386:     case FLOAT_1BIT_FMT(MFHC1, 0):
                   10387:         mips32_op = OPC_MFHC1;
                   10388:         goto do_cp1;
                   10389:     case FLOAT_1BIT_FMT(MTHC1, 0):
                   10390:         mips32_op = OPC_MTHC1;
                   10391:     do_cp1:
                   10392:         gen_cp1(ctx, mips32_op, rt, rs);
                   10393:         break;
                   10394: 
                   10395:         /* Reciprocal square root */
                   10396:     case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
                   10397:         mips32_op = OPC_RSQRT_S;
                   10398:         goto do_unaryfp;
                   10399:     case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
                   10400:         mips32_op = OPC_RSQRT_D;
                   10401:         goto do_unaryfp;
                   10402: 
                   10403:         /* Square root */
                   10404:     case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
                   10405:         mips32_op = OPC_SQRT_S;
                   10406:         goto do_unaryfp;
                   10407:     case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
                   10408:         mips32_op = OPC_SQRT_D;
                   10409:         goto do_unaryfp;
                   10410: 
                   10411:         /* Reciprocal */
                   10412:     case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
                   10413:         mips32_op = OPC_RECIP_S;
                   10414:         goto do_unaryfp;
                   10415:     case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
                   10416:         mips32_op = OPC_RECIP_D;
                   10417:         goto do_unaryfp;
                   10418: 
                   10419:         /* Floor */
                   10420:     case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
                   10421:         mips32_op = OPC_FLOOR_L_S;
                   10422:         goto do_unaryfp;
                   10423:     case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
                   10424:         mips32_op = OPC_FLOOR_L_D;
                   10425:         goto do_unaryfp;
                   10426:     case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
                   10427:         mips32_op = OPC_FLOOR_W_S;
                   10428:         goto do_unaryfp;
                   10429:     case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
                   10430:         mips32_op = OPC_FLOOR_W_D;
                   10431:         goto do_unaryfp;
                   10432: 
                   10433:         /* Ceiling */
                   10434:     case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
                   10435:         mips32_op = OPC_CEIL_L_S;
                   10436:         goto do_unaryfp;
                   10437:     case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
                   10438:         mips32_op = OPC_CEIL_L_D;
                   10439:         goto do_unaryfp;
                   10440:     case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
                   10441:         mips32_op = OPC_CEIL_W_S;
                   10442:         goto do_unaryfp;
                   10443:     case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
                   10444:         mips32_op = OPC_CEIL_W_D;
                   10445:         goto do_unaryfp;
                   10446: 
                   10447:         /* Truncation */
                   10448:     case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
                   10449:         mips32_op = OPC_TRUNC_L_S;
                   10450:         goto do_unaryfp;
                   10451:     case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
                   10452:         mips32_op = OPC_TRUNC_L_D;
                   10453:         goto do_unaryfp;
                   10454:     case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
                   10455:         mips32_op = OPC_TRUNC_W_S;
                   10456:         goto do_unaryfp;
                   10457:     case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
                   10458:         mips32_op = OPC_TRUNC_W_D;
                   10459:         goto do_unaryfp;
                   10460: 
                   10461:         /* Round */
                   10462:     case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
                   10463:         mips32_op = OPC_ROUND_L_S;
                   10464:         goto do_unaryfp;
                   10465:     case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
                   10466:         mips32_op = OPC_ROUND_L_D;
                   10467:         goto do_unaryfp;
                   10468:     case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
                   10469:         mips32_op = OPC_ROUND_W_S;
                   10470:         goto do_unaryfp;
                   10471:     case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
                   10472:         mips32_op = OPC_ROUND_W_D;
                   10473:         goto do_unaryfp;
                   10474: 
                   10475:         /* Integer to floating-point conversion */
                   10476:     case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
                   10477:         mips32_op = OPC_CVT_L_S;
                   10478:         goto do_unaryfp;
                   10479:     case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
                   10480:         mips32_op = OPC_CVT_L_D;
                   10481:         goto do_unaryfp;
                   10482:     case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
                   10483:         mips32_op = OPC_CVT_W_S;
                   10484:         goto do_unaryfp;
                   10485:     case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
                   10486:         mips32_op = OPC_CVT_W_D;
                   10487:         goto do_unaryfp;
                   10488: 
                   10489:         /* Paired-foo conversions */
                   10490:     case FLOAT_1BIT_FMT(CVT_S_PL, 0):
                   10491:         mips32_op = OPC_CVT_S_PL;
                   10492:         goto do_unaryfp;
                   10493:     case FLOAT_1BIT_FMT(CVT_S_PU, 0):
                   10494:         mips32_op = OPC_CVT_S_PU;
                   10495:         goto do_unaryfp;
                   10496:     case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
                   10497:         mips32_op = OPC_CVT_PW_PS;
                   10498:         goto do_unaryfp;
                   10499:     case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
                   10500:         mips32_op = OPC_CVT_PS_PW;
                   10501:         goto do_unaryfp;
                   10502: 
                   10503:         /* Floating-point moves */
                   10504:     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
                   10505:         mips32_op = OPC_MOV_S;
                   10506:         goto do_unaryfp;
                   10507:     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
                   10508:         mips32_op = OPC_MOV_D;
                   10509:         goto do_unaryfp;
                   10510:     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
                   10511:         mips32_op = OPC_MOV_PS;
                   10512:         goto do_unaryfp;
                   10513: 
                   10514:         /* Absolute value */
                   10515:     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
                   10516:         mips32_op = OPC_ABS_S;
                   10517:         goto do_unaryfp;
                   10518:     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
                   10519:         mips32_op = OPC_ABS_D;
                   10520:         goto do_unaryfp;
                   10521:     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
                   10522:         mips32_op = OPC_ABS_PS;
                   10523:         goto do_unaryfp;
                   10524: 
                   10525:         /* Negation */
                   10526:     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
                   10527:         mips32_op = OPC_NEG_S;
                   10528:         goto do_unaryfp;
                   10529:     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
                   10530:         mips32_op = OPC_NEG_D;
                   10531:         goto do_unaryfp;
                   10532:     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
                   10533:         mips32_op = OPC_NEG_PS;
                   10534:         goto do_unaryfp;
                   10535: 
                   10536:         /* Reciprocal square root step */
                   10537:     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
                   10538:         mips32_op = OPC_RSQRT1_S;
                   10539:         goto do_unaryfp;
                   10540:     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
                   10541:         mips32_op = OPC_RSQRT1_D;
                   10542:         goto do_unaryfp;
                   10543:     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
                   10544:         mips32_op = OPC_RSQRT1_PS;
                   10545:         goto do_unaryfp;
                   10546: 
                   10547:         /* Reciprocal step */
                   10548:     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
                   10549:         mips32_op = OPC_RECIP1_S;
                   10550:         goto do_unaryfp;
                   10551:     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
                   10552:         mips32_op = OPC_RECIP1_S;
                   10553:         goto do_unaryfp;
                   10554:     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
                   10555:         mips32_op = OPC_RECIP1_PS;
                   10556:         goto do_unaryfp;
                   10557: 
                   10558:         /* Conversions from double */
                   10559:     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
                   10560:         mips32_op = OPC_CVT_D_S;
                   10561:         goto do_unaryfp;
                   10562:     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
                   10563:         mips32_op = OPC_CVT_D_W;
                   10564:         goto do_unaryfp;
                   10565:     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
                   10566:         mips32_op = OPC_CVT_D_L;
                   10567:         goto do_unaryfp;
                   10568: 
                   10569:         /* Conversions from single */
                   10570:     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
                   10571:         mips32_op = OPC_CVT_S_D;
                   10572:         goto do_unaryfp;
                   10573:     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
                   10574:         mips32_op = OPC_CVT_S_W;
                   10575:         goto do_unaryfp;
                   10576:     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
                   10577:         mips32_op = OPC_CVT_S_L;
                   10578:     do_unaryfp:
                   10579:         gen_farith(ctx, mips32_op, -1, rs, rt, 0);
                   10580:         break;
                   10581: 
                   10582:         /* Conditional moves on floating-point codes */
                   10583:     case COND_FLOAT_MOV(MOVT, 0):
                   10584:     case COND_FLOAT_MOV(MOVT, 1):
                   10585:     case COND_FLOAT_MOV(MOVT, 2):
                   10586:     case COND_FLOAT_MOV(MOVT, 3):
                   10587:     case COND_FLOAT_MOV(MOVT, 4):
                   10588:     case COND_FLOAT_MOV(MOVT, 5):
                   10589:     case COND_FLOAT_MOV(MOVT, 6):
                   10590:     case COND_FLOAT_MOV(MOVT, 7):
                   10591:         gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
                   10592:         break;
                   10593:     case COND_FLOAT_MOV(MOVF, 0):
                   10594:     case COND_FLOAT_MOV(MOVF, 1):
                   10595:     case COND_FLOAT_MOV(MOVF, 2):
                   10596:     case COND_FLOAT_MOV(MOVF, 3):
                   10597:     case COND_FLOAT_MOV(MOVF, 4):
                   10598:     case COND_FLOAT_MOV(MOVF, 5):
                   10599:     case COND_FLOAT_MOV(MOVF, 6):
                   10600:     case COND_FLOAT_MOV(MOVF, 7):
                   10601:         gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
                   10602:         break;
                   10603:     default:
                   10604:         MIPS_INVAL("pool32fxf");
                   10605:         generate_exception(ctx, EXCP_RI);
                   10606:         break;
                   10607:     }
                   10608: }
                   10609: 
1.1.1.16! root     10610: static void decode_micromips32_opc (CPUMIPSState *env, DisasContext *ctx,
1.1.1.12  root     10611:                                     uint16_t insn_hw1, int *is_branch)
                   10612: {
                   10613:     int32_t offset;
                   10614:     uint16_t insn;
                   10615:     int rt, rs, rd, rr;
                   10616:     int16_t imm;
                   10617:     uint32_t op, minor, mips32_op;
                   10618:     uint32_t cond, fmt, cc;
                   10619: 
                   10620:     insn = lduw_code(ctx->pc + 2);
                   10621:     ctx->opcode = (ctx->opcode << 16) | insn;
                   10622: 
                   10623:     rt = (ctx->opcode >> 21) & 0x1f;
                   10624:     rs = (ctx->opcode >> 16) & 0x1f;
                   10625:     rd = (ctx->opcode >> 11) & 0x1f;
                   10626:     rr = (ctx->opcode >> 6) & 0x1f;
                   10627:     imm = (int16_t) ctx->opcode;
                   10628: 
                   10629:     op = (ctx->opcode >> 26) & 0x3f;
                   10630:     switch (op) {
                   10631:     case POOL32A:
                   10632:         minor = ctx->opcode & 0x3f;
                   10633:         switch (minor) {
                   10634:         case 0x00:
                   10635:             minor = (ctx->opcode >> 6) & 0xf;
                   10636:             switch (minor) {
                   10637:             case SLL32:
                   10638:                 mips32_op = OPC_SLL;
                   10639:                 goto do_shifti;
                   10640:             case SRA:
                   10641:                 mips32_op = OPC_SRA;
                   10642:                 goto do_shifti;
                   10643:             case SRL32:
                   10644:                 mips32_op = OPC_SRL;
                   10645:                 goto do_shifti;
                   10646:             case ROTR:
                   10647:                 mips32_op = OPC_ROTR;
                   10648:             do_shifti:
                   10649:                 gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
                   10650:                 break;
                   10651:             default:
                   10652:                 goto pool32a_invalid;
                   10653:             }
                   10654:             break;
                   10655:         case 0x10:
                   10656:             minor = (ctx->opcode >> 6) & 0xf;
                   10657:             switch (minor) {
                   10658:                 /* Arithmetic */
                   10659:             case ADD:
                   10660:                 mips32_op = OPC_ADD;
                   10661:                 goto do_arith;
                   10662:             case ADDU32:
                   10663:                 mips32_op = OPC_ADDU;
                   10664:                 goto do_arith;
                   10665:             case SUB:
                   10666:                 mips32_op = OPC_SUB;
                   10667:                 goto do_arith;
                   10668:             case SUBU32:
                   10669:                 mips32_op = OPC_SUBU;
                   10670:                 goto do_arith;
                   10671:             case MUL:
                   10672:                 mips32_op = OPC_MUL;
                   10673:             do_arith:
                   10674:                 gen_arith(env, ctx, mips32_op, rd, rs, rt);
                   10675:                 break;
                   10676:                 /* Shifts */
                   10677:             case SLLV:
                   10678:                 mips32_op = OPC_SLLV;
                   10679:                 goto do_shift;
                   10680:             case SRLV:
                   10681:                 mips32_op = OPC_SRLV;
                   10682:                 goto do_shift;
                   10683:             case SRAV:
                   10684:                 mips32_op = OPC_SRAV;
                   10685:                 goto do_shift;
                   10686:             case ROTRV:
                   10687:                 mips32_op = OPC_ROTRV;
                   10688:             do_shift:
                   10689:                 gen_shift(env, ctx, mips32_op, rd, rs, rt);
                   10690:                 break;
                   10691:                 /* Logical operations */
                   10692:             case AND:
                   10693:                 mips32_op = OPC_AND;
                   10694:                 goto do_logic;
                   10695:             case OR32:
                   10696:                 mips32_op = OPC_OR;
                   10697:                 goto do_logic;
                   10698:             case NOR:
                   10699:                 mips32_op = OPC_NOR;
                   10700:                 goto do_logic;
                   10701:             case XOR32:
                   10702:                 mips32_op = OPC_XOR;
                   10703:             do_logic:
                   10704:                 gen_logic(env, mips32_op, rd, rs, rt);
                   10705:                 break;
                   10706:                 /* Set less than */
                   10707:             case SLT:
                   10708:                 mips32_op = OPC_SLT;
                   10709:                 goto do_slt;
                   10710:             case SLTU:
                   10711:                 mips32_op = OPC_SLTU;
                   10712:             do_slt:
                   10713:                 gen_slt(env, mips32_op, rd, rs, rt);
                   10714:                 break;
                   10715:             default:
                   10716:                 goto pool32a_invalid;
                   10717:             }
                   10718:             break;
                   10719:         case 0x18:
                   10720:             minor = (ctx->opcode >> 6) & 0xf;
                   10721:             switch (minor) {
                   10722:                 /* Conditional moves */
                   10723:             case MOVN:
                   10724:                 mips32_op = OPC_MOVN;
                   10725:                 goto do_cmov;
                   10726:             case MOVZ:
                   10727:                 mips32_op = OPC_MOVZ;
                   10728:             do_cmov:
                   10729:                 gen_cond_move(env, mips32_op, rd, rs, rt);
                   10730:                 break;
                   10731:             case LWXS:
                   10732:                 gen_ldxs(ctx, rs, rt, rd);
                   10733:                 break;
                   10734:             default:
                   10735:                 goto pool32a_invalid;
                   10736:             }
                   10737:             break;
                   10738:         case INS:
                   10739:             gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
                   10740:             return;
                   10741:         case EXT:
                   10742:             gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
                   10743:             return;
                   10744:         case POOL32AXF:
                   10745:             gen_pool32axf(env, ctx, rt, rs, is_branch);
                   10746:             break;
                   10747:         case 0x07:
                   10748:             generate_exception(ctx, EXCP_BREAK);
                   10749:             break;
                   10750:         default:
                   10751:         pool32a_invalid:
                   10752:                 MIPS_INVAL("pool32a");
                   10753:                 generate_exception(ctx, EXCP_RI);
                   10754:                 break;
                   10755:         }
                   10756:         break;
                   10757:     case POOL32B:
                   10758:         minor = (ctx->opcode >> 12) & 0xf;
                   10759:         switch (minor) {
                   10760:         case CACHE:
                   10761:             /* Treat as no-op. */
                   10762:             break;
                   10763:         case LWC2:
                   10764:         case SWC2:
                   10765:             /* COP2: Not implemented. */
                   10766:             generate_exception_err(ctx, EXCP_CpU, 2);
                   10767:             break;
                   10768:         case LWP:
                   10769:         case SWP:
                   10770: #ifdef TARGET_MIPS64
                   10771:         case LDP:
                   10772:         case SDP:
                   10773: #endif
                   10774:             gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
                   10775:             break;
                   10776:         case LWM32:
                   10777:         case SWM32:
                   10778: #ifdef TARGET_MIPS64
                   10779:         case LDM:
                   10780:         case SDM:
                   10781: #endif
                   10782:             gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
                   10783:             break;
                   10784:         default:
                   10785:             MIPS_INVAL("pool32b");
                   10786:             generate_exception(ctx, EXCP_RI);
                   10787:             break;
                   10788:         }
                   10789:         break;
                   10790:     case POOL32F:
                   10791:         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
                   10792:             minor = ctx->opcode & 0x3f;
                   10793:             check_cp1_enabled(ctx);
                   10794:             switch (minor) {
                   10795:             case ALNV_PS:
                   10796:                 mips32_op = OPC_ALNV_PS;
                   10797:                 goto do_madd;
                   10798:             case MADD_S:
                   10799:                 mips32_op = OPC_MADD_S;
                   10800:                 goto do_madd;
                   10801:             case MADD_D:
                   10802:                 mips32_op = OPC_MADD_D;
                   10803:                 goto do_madd;
                   10804:             case MADD_PS:
                   10805:                 mips32_op = OPC_MADD_PS;
                   10806:                 goto do_madd;
                   10807:             case MSUB_S:
                   10808:                 mips32_op = OPC_MSUB_S;
                   10809:                 goto do_madd;
                   10810:             case MSUB_D:
                   10811:                 mips32_op = OPC_MSUB_D;
                   10812:                 goto do_madd;
                   10813:             case MSUB_PS:
                   10814:                 mips32_op = OPC_MSUB_PS;
                   10815:                 goto do_madd;
                   10816:             case NMADD_S:
                   10817:                 mips32_op = OPC_NMADD_S;
                   10818:                 goto do_madd;
                   10819:             case NMADD_D:
                   10820:                 mips32_op = OPC_NMADD_D;
                   10821:                 goto do_madd;
                   10822:             case NMADD_PS:
                   10823:                 mips32_op = OPC_NMADD_PS;
                   10824:                 goto do_madd;
                   10825:             case NMSUB_S:
                   10826:                 mips32_op = OPC_NMSUB_S;
                   10827:                 goto do_madd;
                   10828:             case NMSUB_D:
                   10829:                 mips32_op = OPC_NMSUB_D;
                   10830:                 goto do_madd;
                   10831:             case NMSUB_PS:
                   10832:                 mips32_op = OPC_NMSUB_PS;
                   10833:             do_madd:
                   10834:                 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
                   10835:                 break;
                   10836:             case CABS_COND_FMT:
                   10837:                 cond = (ctx->opcode >> 6) & 0xf;
                   10838:                 cc = (ctx->opcode >> 13) & 0x7;
                   10839:                 fmt = (ctx->opcode >> 10) & 0x3;
                   10840:                 switch (fmt) {
                   10841:                 case 0x0:
                   10842:                     gen_cmpabs_s(ctx, cond, rt, rs, cc);
                   10843:                     break;
                   10844:                 case 0x1:
                   10845:                     gen_cmpabs_d(ctx, cond, rt, rs, cc);
                   10846:                     break;
                   10847:                 case 0x2:
                   10848:                     gen_cmpabs_ps(ctx, cond, rt, rs, cc);
                   10849:                     break;
                   10850:                 default:
                   10851:                     goto pool32f_invalid;
                   10852:                 }
                   10853:                 break;
                   10854:             case C_COND_FMT:
                   10855:                 cond = (ctx->opcode >> 6) & 0xf;
                   10856:                 cc = (ctx->opcode >> 13) & 0x7;
                   10857:                 fmt = (ctx->opcode >> 10) & 0x3;
                   10858:                 switch (fmt) {
                   10859:                 case 0x0:
                   10860:                     gen_cmp_s(ctx, cond, rt, rs, cc);
                   10861:                     break;
                   10862:                 case 0x1:
                   10863:                     gen_cmp_d(ctx, cond, rt, rs, cc);
                   10864:                     break;
                   10865:                 case 0x2:
                   10866:                     gen_cmp_ps(ctx, cond, rt, rs, cc);
                   10867:                     break;
                   10868:                 default:
                   10869:                     goto pool32f_invalid;
                   10870:                 }
                   10871:                 break;
                   10872:             case POOL32FXF:
                   10873:                 gen_pool32fxf(env, ctx, rt, rs);
                   10874:                 break;
                   10875:             case 0x00:
                   10876:                 /* PLL foo */
                   10877:                 switch ((ctx->opcode >> 6) & 0x7) {
                   10878:                 case PLL_PS:
                   10879:                     mips32_op = OPC_PLL_PS;
                   10880:                     goto do_ps;
                   10881:                 case PLU_PS:
                   10882:                     mips32_op = OPC_PLU_PS;
                   10883:                     goto do_ps;
                   10884:                 case PUL_PS:
                   10885:                     mips32_op = OPC_PUL_PS;
                   10886:                     goto do_ps;
                   10887:                 case PUU_PS:
                   10888:                     mips32_op = OPC_PUU_PS;
                   10889:                     goto do_ps;
                   10890:                 case CVT_PS_S:
                   10891:                     mips32_op = OPC_CVT_PS_S;
                   10892:                 do_ps:
                   10893:                     gen_farith(ctx, mips32_op, rt, rs, rd, 0);
                   10894:                     break;
                   10895:                 default:
                   10896:                     goto pool32f_invalid;
                   10897:                 }
                   10898:                 break;
                   10899:             case 0x08:
                   10900:                 /* [LS][WDU]XC1 */
                   10901:                 switch ((ctx->opcode >> 6) & 0x7) {
                   10902:                 case LWXC1:
                   10903:                     mips32_op = OPC_LWXC1;
                   10904:                     goto do_ldst_cp1;
                   10905:                 case SWXC1:
                   10906:                     mips32_op = OPC_SWXC1;
                   10907:                     goto do_ldst_cp1;
                   10908:                 case LDXC1:
                   10909:                     mips32_op = OPC_LDXC1;
                   10910:                     goto do_ldst_cp1;
                   10911:                 case SDXC1:
                   10912:                     mips32_op = OPC_SDXC1;
                   10913:                     goto do_ldst_cp1;
                   10914:                 case LUXC1:
                   10915:                     mips32_op = OPC_LUXC1;
                   10916:                     goto do_ldst_cp1;
                   10917:                 case SUXC1:
                   10918:                     mips32_op = OPC_SUXC1;
                   10919:                 do_ldst_cp1:
                   10920:                     gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
                   10921:                     break;
                   10922:                 default:
                   10923:                     goto pool32f_invalid;
                   10924:                 }
                   10925:                 break;
                   10926:             case 0x18:
                   10927:                 /* 3D insns */
                   10928:                 fmt = (ctx->opcode >> 9) & 0x3;
                   10929:                 switch ((ctx->opcode >> 6) & 0x7) {
                   10930:                 case RSQRT2_FMT:
                   10931:                     switch (fmt) {
                   10932:                     case FMT_SDPS_S:
                   10933:                         mips32_op = OPC_RSQRT2_S;
                   10934:                         goto do_3d;
                   10935:                     case FMT_SDPS_D:
                   10936:                         mips32_op = OPC_RSQRT2_D;
                   10937:                         goto do_3d;
                   10938:                     case FMT_SDPS_PS:
                   10939:                         mips32_op = OPC_RSQRT2_PS;
                   10940:                         goto do_3d;
                   10941:                     default:
                   10942:                         goto pool32f_invalid;
                   10943:                     }
                   10944:                     break;
                   10945:                 case RECIP2_FMT:
                   10946:                     switch (fmt) {
                   10947:                     case FMT_SDPS_S:
                   10948:                         mips32_op = OPC_RECIP2_S;
                   10949:                         goto do_3d;
                   10950:                     case FMT_SDPS_D:
                   10951:                         mips32_op = OPC_RECIP2_D;
                   10952:                         goto do_3d;
                   10953:                     case FMT_SDPS_PS:
                   10954:                         mips32_op = OPC_RECIP2_PS;
                   10955:                         goto do_3d;
                   10956:                     default:
                   10957:                         goto pool32f_invalid;
                   10958:                     }
                   10959:                     break;
                   10960:                 case ADDR_PS:
                   10961:                     mips32_op = OPC_ADDR_PS;
                   10962:                     goto do_3d;
                   10963:                 case MULR_PS:
                   10964:                     mips32_op = OPC_MULR_PS;
                   10965:                 do_3d:
                   10966:                     gen_farith(ctx, mips32_op, rt, rs, rd, 0);
                   10967:                     break;
                   10968:                 default:
                   10969:                     goto pool32f_invalid;
                   10970:                 }
                   10971:                 break;
                   10972:             case 0x20:
                   10973:                 /* MOV[FT].fmt and PREFX */
                   10974:                 cc = (ctx->opcode >> 13) & 0x7;
                   10975:                 fmt = (ctx->opcode >> 9) & 0x3;
                   10976:                 switch ((ctx->opcode >> 6) & 0x7) {
                   10977:                 case MOVF_FMT:
                   10978:                     switch (fmt) {
                   10979:                     case FMT_SDPS_S:
                   10980:                         gen_movcf_s(rs, rt, cc, 0);
                   10981:                         break;
                   10982:                     case FMT_SDPS_D:
                   10983:                         gen_movcf_d(ctx, rs, rt, cc, 0);
                   10984:                         break;
                   10985:                     case FMT_SDPS_PS:
                   10986:                         gen_movcf_ps(rs, rt, cc, 0);
                   10987:                         break;
                   10988:                     default:
                   10989:                         goto pool32f_invalid;
                   10990:                     }
                   10991:                     break;
                   10992:                 case MOVT_FMT:
                   10993:                     switch (fmt) {
                   10994:                     case FMT_SDPS_S:
                   10995:                         gen_movcf_s(rs, rt, cc, 1);
                   10996:                         break;
                   10997:                     case FMT_SDPS_D:
                   10998:                         gen_movcf_d(ctx, rs, rt, cc, 1);
                   10999:                         break;
                   11000:                     case FMT_SDPS_PS:
                   11001:                         gen_movcf_ps(rs, rt, cc, 1);
                   11002:                         break;
                   11003:                     default:
                   11004:                         goto pool32f_invalid;
                   11005:                     }
                   11006:                     break;
                   11007:                 case PREFX:
                   11008:                     break;
                   11009:                 default:
                   11010:                     goto pool32f_invalid;
                   11011:                 }
                   11012:                 break;
                   11013: #define FINSN_3ARG_SDPS(prfx)                           \
                   11014:                 switch ((ctx->opcode >> 8) & 0x3) {     \
                   11015:                 case FMT_SDPS_S:                        \
                   11016:                     mips32_op = OPC_##prfx##_S;         \
                   11017:                     goto do_fpop;                       \
                   11018:                 case FMT_SDPS_D:                        \
                   11019:                     mips32_op = OPC_##prfx##_D;         \
                   11020:                     goto do_fpop;                       \
                   11021:                 case FMT_SDPS_PS:                       \
                   11022:                     mips32_op = OPC_##prfx##_PS;        \
                   11023:                     goto do_fpop;                       \
                   11024:                 default:                                \
                   11025:                     goto pool32f_invalid;               \
                   11026:                 }
                   11027:             case 0x30:
                   11028:                 /* regular FP ops */
                   11029:                 switch ((ctx->opcode >> 6) & 0x3) {
                   11030:                 case ADD_FMT:
                   11031:                     FINSN_3ARG_SDPS(ADD);
                   11032:                     break;
                   11033:                 case SUB_FMT:
                   11034:                     FINSN_3ARG_SDPS(SUB);
                   11035:                     break;
                   11036:                 case MUL_FMT:
                   11037:                     FINSN_3ARG_SDPS(MUL);
                   11038:                     break;
                   11039:                 case DIV_FMT:
                   11040:                     fmt = (ctx->opcode >> 8) & 0x3;
                   11041:                     if (fmt == 1) {
                   11042:                         mips32_op = OPC_DIV_D;
                   11043:                     } else if (fmt == 0) {
                   11044:                         mips32_op = OPC_DIV_S;
                   11045:                     } else {
                   11046:                         goto pool32f_invalid;
                   11047:                     }
                   11048:                     goto do_fpop;
                   11049:                 default:
                   11050:                     goto pool32f_invalid;
                   11051:                 }
                   11052:                 break;
                   11053:             case 0x38:
                   11054:                 /* cmovs */
                   11055:                 switch ((ctx->opcode >> 6) & 0x3) {
                   11056:                 case MOVN_FMT:
                   11057:                     FINSN_3ARG_SDPS(MOVN);
                   11058:                     break;
                   11059:                 case MOVZ_FMT:
                   11060:                     FINSN_3ARG_SDPS(MOVZ);
                   11061:                     break;
                   11062:                 default:
                   11063:                     goto pool32f_invalid;
                   11064:                 }
                   11065:                 break;
                   11066:             do_fpop:
                   11067:                 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
                   11068:                 break;
                   11069:             default:
                   11070:             pool32f_invalid:
                   11071:                 MIPS_INVAL("pool32f");
                   11072:                 generate_exception(ctx, EXCP_RI);
                   11073:                 break;
                   11074:             }
                   11075:         } else {
                   11076:             generate_exception_err(ctx, EXCP_CpU, 1);
                   11077:         }
                   11078:         break;
                   11079:     case POOL32I:
                   11080:         minor = (ctx->opcode >> 21) & 0x1f;
                   11081:         switch (minor) {
                   11082:         case BLTZ:
                   11083:             mips32_op = OPC_BLTZ;
                   11084:             goto do_branch;
                   11085:         case BLTZAL:
                   11086:             mips32_op = OPC_BLTZAL;
                   11087:             goto do_branch;
                   11088:         case BLTZALS:
                   11089:             mips32_op = OPC_BLTZALS;
                   11090:             goto do_branch;
                   11091:         case BGEZ:
                   11092:             mips32_op = OPC_BGEZ;
                   11093:             goto do_branch;
                   11094:         case BGEZAL:
                   11095:             mips32_op = OPC_BGEZAL;
                   11096:             goto do_branch;
                   11097:         case BGEZALS:
                   11098:             mips32_op = OPC_BGEZALS;
                   11099:             goto do_branch;
                   11100:         case BLEZ:
                   11101:             mips32_op = OPC_BLEZ;
                   11102:             goto do_branch;
                   11103:         case BGTZ:
                   11104:             mips32_op = OPC_BGTZ;
                   11105:         do_branch:
                   11106:             gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
                   11107:             *is_branch = 1;
                   11108:             break;
                   11109: 
                   11110:             /* Traps */
                   11111:         case TLTI:
                   11112:             mips32_op = OPC_TLTI;
                   11113:             goto do_trapi;
                   11114:         case TGEI:
                   11115:             mips32_op = OPC_TGEI;
                   11116:             goto do_trapi;
                   11117:         case TLTIU:
                   11118:             mips32_op = OPC_TLTIU;
                   11119:             goto do_trapi;
                   11120:         case TGEIU:
                   11121:             mips32_op = OPC_TGEIU;
                   11122:             goto do_trapi;
                   11123:         case TNEI:
                   11124:             mips32_op = OPC_TNEI;
                   11125:             goto do_trapi;
                   11126:         case TEQI:
                   11127:             mips32_op = OPC_TEQI;
                   11128:         do_trapi:
                   11129:             gen_trap(ctx, mips32_op, rs, -1, imm);
                   11130:             break;
                   11131: 
                   11132:         case BNEZC:
                   11133:         case BEQZC:
                   11134:             gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
                   11135:                                4, rs, 0, imm << 1);
                   11136:             /* Compact branches don't have a delay slot, so just let
                   11137:                the normal delay slot handling take us to the branch
                   11138:                target. */
                   11139:             break;
                   11140:         case LUI:
                   11141:             gen_logic_imm(env, OPC_LUI, rs, -1, imm);
                   11142:             break;
                   11143:         case SYNCI:
                   11144:             break;
                   11145:         case BC2F:
                   11146:         case BC2T:
                   11147:             /* COP2: Not implemented. */
                   11148:             generate_exception_err(ctx, EXCP_CpU, 2);
                   11149:             break;
                   11150:         case BC1F:
                   11151:             mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
                   11152:             goto do_cp1branch;
                   11153:         case BC1T:
                   11154:             mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
                   11155:             goto do_cp1branch;
                   11156:         case BC1ANY4F:
                   11157:             mips32_op = OPC_BC1FANY4;
                   11158:             goto do_cp1mips3d;
                   11159:         case BC1ANY4T:
                   11160:             mips32_op = OPC_BC1TANY4;
                   11161:         do_cp1mips3d:
                   11162:             check_cop1x(ctx);
                   11163:             check_insn(env, ctx, ASE_MIPS3D);
                   11164:             /* Fall through */
                   11165:         do_cp1branch:
                   11166:             gen_compute_branch1(env, ctx, mips32_op,
                   11167:                                 (ctx->opcode >> 18) & 0x7, imm << 1);
                   11168:             *is_branch = 1;
                   11169:             break;
                   11170:         case BPOSGE64:
                   11171:         case BPOSGE32:
                   11172:             /* MIPS DSP: not implemented */
                   11173:             /* Fall through */
                   11174:         default:
                   11175:             MIPS_INVAL("pool32i");
                   11176:             generate_exception(ctx, EXCP_RI);
                   11177:             break;
                   11178:         }
                   11179:         break;
                   11180:     case POOL32C:
                   11181:         minor = (ctx->opcode >> 12) & 0xf;
                   11182:         switch (minor) {
                   11183:         case LWL:
                   11184:             mips32_op = OPC_LWL;
                   11185:             goto do_ld_lr;
                   11186:         case SWL:
                   11187:             mips32_op = OPC_SWL;
                   11188:             goto do_st_lr;
                   11189:         case LWR:
                   11190:             mips32_op = OPC_LWR;
                   11191:             goto do_ld_lr;
                   11192:         case SWR:
                   11193:             mips32_op = OPC_SWR;
                   11194:             goto do_st_lr;
                   11195: #if defined(TARGET_MIPS64)
                   11196:         case LDL:
                   11197:             mips32_op = OPC_LDL;
                   11198:             goto do_ld_lr;
                   11199:         case SDL:
                   11200:             mips32_op = OPC_SDL;
                   11201:             goto do_st_lr;
                   11202:         case LDR:
                   11203:             mips32_op = OPC_LDR;
                   11204:             goto do_ld_lr;
                   11205:         case SDR:
                   11206:             mips32_op = OPC_SDR;
                   11207:             goto do_st_lr;
                   11208:         case LWU:
                   11209:             mips32_op = OPC_LWU;
                   11210:             goto do_ld_lr;
                   11211:         case LLD:
                   11212:             mips32_op = OPC_LLD;
                   11213:             goto do_ld_lr;
                   11214: #endif
                   11215:         case LL:
                   11216:             mips32_op = OPC_LL;
                   11217:             goto do_ld_lr;
                   11218:         do_ld_lr:
                   11219:             gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
                   11220:             break;
                   11221:         do_st_lr:
                   11222:             gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
                   11223:             break;
                   11224:         case SC:
                   11225:             gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
                   11226:             break;
                   11227: #if defined(TARGET_MIPS64)
                   11228:         case SCD:
                   11229:             gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
                   11230:             break;
                   11231: #endif
                   11232:         case PREF:
                   11233:             /* Treat as no-op */
                   11234:             break;
                   11235:         default:
                   11236:             MIPS_INVAL("pool32c");
                   11237:             generate_exception(ctx, EXCP_RI);
                   11238:             break;
                   11239:         }
                   11240:         break;
                   11241:     case ADDI32:
                   11242:         mips32_op = OPC_ADDI;
                   11243:         goto do_addi;
                   11244:     case ADDIU32:
                   11245:         mips32_op = OPC_ADDIU;
                   11246:     do_addi:
                   11247:         gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
                   11248:         break;
                   11249: 
                   11250:         /* Logical operations */
                   11251:     case ORI32:
                   11252:         mips32_op = OPC_ORI;
                   11253:         goto do_logici;
                   11254:     case XORI32:
                   11255:         mips32_op = OPC_XORI;
                   11256:         goto do_logici;
                   11257:     case ANDI32:
                   11258:         mips32_op = OPC_ANDI;
                   11259:     do_logici:
                   11260:         gen_logic_imm(env, mips32_op, rt, rs, imm);
                   11261:         break;
                   11262: 
                   11263:         /* Set less than immediate */
                   11264:     case SLTI32:
                   11265:         mips32_op = OPC_SLTI;
                   11266:         goto do_slti;
                   11267:     case SLTIU32:
                   11268:         mips32_op = OPC_SLTIU;
                   11269:     do_slti:
                   11270:         gen_slt_imm(env, mips32_op, rt, rs, imm);
                   11271:         break;
                   11272:     case JALX32:
                   11273:         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
                   11274:         gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
                   11275:         *is_branch = 1;
                   11276:         break;
                   11277:     case JALS32:
                   11278:         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
                   11279:         gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
                   11280:         *is_branch = 1;
                   11281:         break;
                   11282:     case BEQ32:
                   11283:         gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
                   11284:         *is_branch = 1;
                   11285:         break;
                   11286:     case BNE32:
                   11287:         gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
                   11288:         *is_branch = 1;
                   11289:         break;
                   11290:     case J32:
                   11291:         gen_compute_branch(ctx, OPC_J, 4, rt, rs,
                   11292:                            (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
                   11293:         *is_branch = 1;
                   11294:         break;
                   11295:     case JAL32:
                   11296:         gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
                   11297:                            (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
                   11298:         *is_branch = 1;
                   11299:         break;
                   11300:         /* Floating point (COP1) */
                   11301:     case LWC132:
                   11302:         mips32_op = OPC_LWC1;
                   11303:         goto do_cop1;
                   11304:     case LDC132:
                   11305:         mips32_op = OPC_LDC1;
                   11306:         goto do_cop1;
                   11307:     case SWC132:
                   11308:         mips32_op = OPC_SWC1;
                   11309:         goto do_cop1;
                   11310:     case SDC132:
                   11311:         mips32_op = OPC_SDC1;
                   11312:     do_cop1:
                   11313:         gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
                   11314:         break;
                   11315:     case ADDIUPC:
                   11316:         {
                   11317:             int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
                   11318:             int offset = SIMM(ctx->opcode, 0, 23) << 2;
                   11319: 
                   11320:             gen_addiupc(ctx, reg, offset, 0, 0);
                   11321:         }
                   11322:         break;
                   11323:         /* Loads and stores */
                   11324:     case LB32:
                   11325:         mips32_op = OPC_LB;
                   11326:         goto do_ld;
                   11327:     case LBU32:
                   11328:         mips32_op = OPC_LBU;
                   11329:         goto do_ld;
                   11330:     case LH32:
                   11331:         mips32_op = OPC_LH;
                   11332:         goto do_ld;
                   11333:     case LHU32:
                   11334:         mips32_op = OPC_LHU;
                   11335:         goto do_ld;
                   11336:     case LW32:
                   11337:         mips32_op = OPC_LW;
                   11338:         goto do_ld;
                   11339: #ifdef TARGET_MIPS64
                   11340:     case LD32:
                   11341:         mips32_op = OPC_LD;
                   11342:         goto do_ld;
                   11343:     case SD32:
                   11344:         mips32_op = OPC_SD;
                   11345:         goto do_st;
                   11346: #endif
                   11347:     case SB32:
                   11348:         mips32_op = OPC_SB;
                   11349:         goto do_st;
                   11350:     case SH32:
                   11351:         mips32_op = OPC_SH;
                   11352:         goto do_st;
                   11353:     case SW32:
                   11354:         mips32_op = OPC_SW;
                   11355:         goto do_st;
                   11356:     do_ld:
                   11357:         gen_ld(env, ctx, mips32_op, rt, rs, imm);
                   11358:         break;
                   11359:     do_st:
                   11360:         gen_st(ctx, mips32_op, rt, rs, imm);
                   11361:         break;
                   11362:     default:
                   11363:         generate_exception(ctx, EXCP_RI);
                   11364:         break;
                   11365:     }
                   11366: }
                   11367: 
1.1.1.16! root     11368: static int decode_micromips_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
1.1.1.12  root     11369: {
                   11370:     uint32_t op;
                   11371: 
                   11372:     /* make sure instructions are on a halfword boundary */
                   11373:     if (ctx->pc & 0x1) {
                   11374:         env->CP0_BadVAddr = ctx->pc;
                   11375:         generate_exception(ctx, EXCP_AdEL);
                   11376:         ctx->bstate = BS_STOP;
                   11377:         return 2;
                   11378:     }
                   11379: 
                   11380:     op = (ctx->opcode >> 10) & 0x3f;
                   11381:     /* Enforce properly-sized instructions in a delay slot */
                   11382:     if (ctx->hflags & MIPS_HFLAG_BMASK) {
                   11383:         int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
                   11384: 
                   11385:         switch (op) {
                   11386:         case POOL32A:
                   11387:         case POOL32B:
                   11388:         case POOL32I:
                   11389:         case POOL32C:
                   11390:         case ADDI32:
                   11391:         case ADDIU32:
                   11392:         case ORI32:
                   11393:         case XORI32:
                   11394:         case SLTI32:
                   11395:         case SLTIU32:
                   11396:         case ANDI32:
                   11397:         case JALX32:
                   11398:         case LBU32:
                   11399:         case LHU32:
                   11400:         case POOL32F:
                   11401:         case JALS32:
                   11402:         case BEQ32:
                   11403:         case BNE32:
                   11404:         case J32:
                   11405:         case JAL32:
                   11406:         case SB32:
                   11407:         case SH32:
                   11408:         case POOL32S:
                   11409:         case ADDIUPC:
                   11410:         case SWC132:
                   11411:         case SDC132:
                   11412:         case SD32:
                   11413:         case SW32:
                   11414:         case LB32:
                   11415:         case LH32:
                   11416:         case DADDIU32:
                   11417:         case POOL48A:           /* ??? */
                   11418:         case LWC132:
                   11419:         case LDC132:
                   11420:         case LD32:
                   11421:         case LW32:
                   11422:             if (bits & MIPS_HFLAG_BDS16) {
                   11423:                 generate_exception(ctx, EXCP_RI);
                   11424:                 /* Just stop translation; the user is confused.  */
                   11425:                 ctx->bstate = BS_STOP;
                   11426:                 return 2;
                   11427:             }
                   11428:             break;
                   11429:         case POOL16A:
                   11430:         case POOL16B:
                   11431:         case POOL16C:
                   11432:         case LWGP16:
                   11433:         case POOL16F:
                   11434:         case LBU16:
                   11435:         case LHU16:
                   11436:         case LWSP16:
                   11437:         case LW16:
                   11438:         case SB16:
                   11439:         case SH16:
                   11440:         case SWSP16:
                   11441:         case SW16:
                   11442:         case MOVE16:
                   11443:         case ANDI16:
                   11444:         case POOL16D:
                   11445:         case POOL16E:
                   11446:         case BEQZ16:
                   11447:         case BNEZ16:
                   11448:         case B16:
                   11449:         case LI16:
                   11450:             if (bits & MIPS_HFLAG_BDS32) {
                   11451:                 generate_exception(ctx, EXCP_RI);
                   11452:                 /* Just stop translation; the user is confused.  */
                   11453:                 ctx->bstate = BS_STOP;
                   11454:                 return 2;
                   11455:             }
                   11456:             break;
                   11457:         default:
                   11458:             break;
                   11459:         }
                   11460:     }
                   11461:     switch (op) {
                   11462:     case POOL16A:
                   11463:         {
                   11464:             int rd = mmreg(uMIPS_RD(ctx->opcode));
                   11465:             int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
                   11466:             int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
                   11467:             uint32_t opc = 0;
                   11468: 
                   11469:             switch (ctx->opcode & 0x1) {
                   11470:             case ADDU16:
                   11471:                 opc = OPC_ADDU;
                   11472:                 break;
                   11473:             case SUBU16:
                   11474:                 opc = OPC_SUBU;
                   11475:                 break;
                   11476:             }
                   11477: 
                   11478:             gen_arith(env, ctx, opc, rd, rs1, rs2);
                   11479:         }
                   11480:         break;
                   11481:     case POOL16B:
                   11482:         {
                   11483:             int rd = mmreg(uMIPS_RD(ctx->opcode));
                   11484:             int rs = mmreg(uMIPS_RS(ctx->opcode));
                   11485:             int amount = (ctx->opcode >> 1) & 0x7;
                   11486:             uint32_t opc = 0;
                   11487:             amount = amount == 0 ? 8 : amount;
                   11488: 
                   11489:             switch (ctx->opcode & 0x1) {
                   11490:             case SLL16:
                   11491:                 opc = OPC_SLL;
                   11492:                 break;
                   11493:             case SRL16:
                   11494:                 opc = OPC_SRL;
                   11495:                 break;
                   11496:             }
                   11497: 
                   11498:             gen_shift_imm(env, ctx, opc, rd, rs, amount);
                   11499:         }
                   11500:         break;
                   11501:     case POOL16C:
                   11502:         gen_pool16c_insn(env, ctx, is_branch);
                   11503:         break;
                   11504:     case LWGP16:
                   11505:         {
                   11506:             int rd = mmreg(uMIPS_RD(ctx->opcode));
                   11507:             int rb = 28;            /* GP */
                   11508:             int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
                   11509: 
                   11510:             gen_ld(env, ctx, OPC_LW, rd, rb, offset);
                   11511:         }
                   11512:         break;
                   11513:     case POOL16F:
                   11514:         if (ctx->opcode & 1) {
                   11515:             generate_exception(ctx, EXCP_RI);
                   11516:         } else {
                   11517:             /* MOVEP */
                   11518:             int enc_dest = uMIPS_RD(ctx->opcode);
                   11519:             int enc_rt = uMIPS_RS2(ctx->opcode);
                   11520:             int enc_rs = uMIPS_RS1(ctx->opcode);
                   11521:             int rd, rs, re, rt;
                   11522:             static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
                   11523:             static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
                   11524:             static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
                   11525: 
                   11526:             rd = rd_enc[enc_dest];
                   11527:             re = re_enc[enc_dest];
                   11528:             rs = rs_rt_enc[enc_rs];
                   11529:             rt = rs_rt_enc[enc_rt];
                   11530: 
                   11531:             gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
                   11532:             gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
                   11533:         }
                   11534:         break;
                   11535:     case LBU16:
                   11536:         {
                   11537:             int rd = mmreg(uMIPS_RD(ctx->opcode));
                   11538:             int rb = mmreg(uMIPS_RS(ctx->opcode));
                   11539:             int16_t offset = ZIMM(ctx->opcode, 0, 4);
                   11540:             offset = (offset == 0xf ? -1 : offset);
                   11541: 
                   11542:             gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
                   11543:         }
                   11544:         break;
                   11545:     case LHU16:
                   11546:         {
                   11547:             int rd = mmreg(uMIPS_RD(ctx->opcode));
                   11548:             int rb = mmreg(uMIPS_RS(ctx->opcode));
                   11549:             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
                   11550: 
                   11551:             gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
                   11552:         }
                   11553:         break;
                   11554:     case LWSP16:
                   11555:         {
                   11556:             int rd = (ctx->opcode >> 5) & 0x1f;
                   11557:             int rb = 29;            /* SP */
                   11558:             int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
                   11559: 
                   11560:             gen_ld(env, ctx, OPC_LW, rd, rb, offset);
                   11561:         }
                   11562:         break;
                   11563:     case LW16:
                   11564:         {
                   11565:             int rd = mmreg(uMIPS_RD(ctx->opcode));
                   11566:             int rb = mmreg(uMIPS_RS(ctx->opcode));
                   11567:             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
                   11568: 
                   11569:             gen_ld(env, ctx, OPC_LW, rd, rb, offset);
                   11570:         }
                   11571:         break;
                   11572:     case SB16:
                   11573:         {
                   11574:             int rd = mmreg2(uMIPS_RD(ctx->opcode));
                   11575:             int rb = mmreg(uMIPS_RS(ctx->opcode));
                   11576:             int16_t offset = ZIMM(ctx->opcode, 0, 4);
                   11577: 
                   11578:             gen_st(ctx, OPC_SB, rd, rb, offset);
                   11579:         }
                   11580:         break;
                   11581:     case SH16:
                   11582:         {
                   11583:             int rd = mmreg2(uMIPS_RD(ctx->opcode));
                   11584:             int rb = mmreg(uMIPS_RS(ctx->opcode));
                   11585:             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
                   11586: 
                   11587:             gen_st(ctx, OPC_SH, rd, rb, offset);
                   11588:         }
                   11589:         break;
                   11590:     case SWSP16:
                   11591:         {
                   11592:             int rd = (ctx->opcode >> 5) & 0x1f;
                   11593:             int rb = 29;            /* SP */
                   11594:             int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
                   11595: 
                   11596:             gen_st(ctx, OPC_SW, rd, rb, offset);
                   11597:         }
                   11598:         break;
                   11599:     case SW16:
                   11600:         {
                   11601:             int rd = mmreg2(uMIPS_RD(ctx->opcode));
                   11602:             int rb = mmreg(uMIPS_RS(ctx->opcode));
                   11603:             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
                   11604: 
                   11605:             gen_st(ctx, OPC_SW, rd, rb, offset);
                   11606:         }
                   11607:         break;
                   11608:     case MOVE16:
                   11609:         {
                   11610:             int rd = uMIPS_RD5(ctx->opcode);
                   11611:             int rs = uMIPS_RS5(ctx->opcode);
                   11612: 
                   11613:             gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
                   11614:         }
                   11615:         break;
                   11616:     case ANDI16:
                   11617:         gen_andi16(env, ctx);
                   11618:         break;
                   11619:     case POOL16D:
                   11620:         switch (ctx->opcode & 0x1) {
                   11621:         case ADDIUS5:
                   11622:             gen_addius5(env, ctx);
                   11623:             break;
                   11624:         case ADDIUSP:
                   11625:             gen_addiusp(env, ctx);
                   11626:             break;
                   11627:         }
                   11628:         break;
                   11629:     case POOL16E:
                   11630:         switch (ctx->opcode & 0x1) {
                   11631:         case ADDIUR2:
                   11632:             gen_addiur2(env, ctx);
                   11633:             break;
                   11634:         case ADDIUR1SP:
                   11635:             gen_addiur1sp(env, ctx);
                   11636:             break;
                   11637:         }
                   11638:         break;
                   11639:     case B16:
                   11640:         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
                   11641:                            SIMM(ctx->opcode, 0, 10) << 1);
                   11642:         *is_branch = 1;
                   11643:         break;
                   11644:     case BNEZ16:
                   11645:     case BEQZ16:
                   11646:         gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
                   11647:                            mmreg(uMIPS_RD(ctx->opcode)),
                   11648:                            0, SIMM(ctx->opcode, 0, 7) << 1);
                   11649:         *is_branch = 1;
                   11650:         break;
                   11651:     case LI16:
                   11652:         {
                   11653:             int reg = mmreg(uMIPS_RD(ctx->opcode));
                   11654:             int imm = ZIMM(ctx->opcode, 0, 7);
                   11655: 
                   11656:             imm = (imm == 0x7f ? -1 : imm);
                   11657:             tcg_gen_movi_tl(cpu_gpr[reg], imm);
                   11658:         }
                   11659:         break;
                   11660:     case RES_20:
                   11661:     case RES_28:
                   11662:     case RES_29:
                   11663:     case RES_30:
                   11664:     case RES_31:
                   11665:     case RES_38:
                   11666:     case RES_39:
                   11667:         generate_exception(ctx, EXCP_RI);
                   11668:         break;
                   11669:     default:
                   11670:         decode_micromips32_opc (env, ctx, op, is_branch);
                   11671:         return 4;
                   11672:     }
                   11673: 
                   11674:     return 2;
                   11675: }
                   11676: 
                   11677: /* SmartMIPS extension to MIPS32 */
                   11678: 
                   11679: #if defined(TARGET_MIPS64)
                   11680: 
                   11681: /* MDMX extension to MIPS64 */
                   11682: 
                   11683: #endif
                   11684: 
1.1.1.16! root     11685: static void decode_opc (CPUMIPSState *env, DisasContext *ctx, int *is_branch)
1.1.1.12  root     11686: {
                   11687:     int32_t offset;
                   11688:     int rs, rt, rd, sa;
                   11689:     uint32_t op, op1, op2;
                   11690:     int16_t imm;
                   11691: 
                   11692:     /* make sure instructions are on a word boundary */
                   11693:     if (ctx->pc & 0x3) {
                   11694:         env->CP0_BadVAddr = ctx->pc;
                   11695:         generate_exception(ctx, EXCP_AdEL);
                   11696:         return;
                   11697:     }
                   11698: 
                   11699:     /* Handle blikely not taken case */
                   11700:     if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
                   11701:         int l1 = gen_new_label();
                   11702: 
                   11703:         MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
1.1.1.8   root     11704:         tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
                   11705:         tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
1.1.1.6   root     11706:         gen_goto_tb(ctx, 1, ctx->pc + 4);
                   11707:         gen_set_label(l1);
1.1       root     11708:     }
1.1.1.9   root     11709: 
                   11710:     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
                   11711:         tcg_gen_debug_insn_start(ctx->pc);
                   11712: 
1.1.1.5   root     11713:     op = MASK_OP_MAJOR(ctx->opcode);
                   11714:     rs = (ctx->opcode >> 21) & 0x1f;
                   11715:     rt = (ctx->opcode >> 16) & 0x1f;
                   11716:     rd = (ctx->opcode >> 11) & 0x1f;
                   11717:     sa = (ctx->opcode >> 6) & 0x1f;
1.1       root     11718:     imm = (int16_t)ctx->opcode;
                   11719:     switch (op) {
1.1.1.5   root     11720:     case OPC_SPECIAL:
                   11721:         op1 = MASK_SPECIAL(ctx->opcode);
1.1       root     11722:         switch (op1) {
1.1.1.8   root     11723:         case OPC_SLL:          /* Shift with immediate */
                   11724:         case OPC_SRA:
                   11725:             gen_shift_imm(env, ctx, op1, rd, rt, sa);
1.1.1.5   root     11726:             break;
1.1.1.12  root     11727:         case OPC_SRL:
                   11728:             switch ((ctx->opcode >> 21) & 0x1f) {
                   11729:             case 1:
                   11730:                 /* rotr is decoded as srl on non-R2 CPUs */
                   11731:                 if (env->insn_flags & ISA_MIPS32R2) {
                   11732:                     op1 = OPC_ROTR;
                   11733:                 }
                   11734:                 /* Fallthrough */
                   11735:             case 0:
                   11736:                 gen_shift_imm(env, ctx, op1, rd, rt, sa);
                   11737:                 break;
                   11738:             default:
                   11739:                 generate_exception(ctx, EXCP_RI);
                   11740:                 break;
                   11741:             }
                   11742:             break;
1.1.1.8   root     11743:         case OPC_MOVN:         /* Conditional move */
                   11744:         case OPC_MOVZ:
1.1.1.12  root     11745:             check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
                   11746:                                  INSN_LOONGSON2E | INSN_LOONGSON2F);
1.1.1.8   root     11747:             gen_cond_move(env, op1, rd, rs, rt);
                   11748:             break;
                   11749:         case OPC_ADD ... OPC_SUBU:
1.1.1.6   root     11750:             gen_arith(env, ctx, op1, rd, rs, rt);
1.1       root     11751:             break;
1.1.1.8   root     11752:         case OPC_SLLV:         /* Shifts */
                   11753:         case OPC_SRAV:
                   11754:             gen_shift(env, ctx, op1, rd, rs, rt);
                   11755:             break;
1.1.1.12  root     11756:         case OPC_SRLV:
                   11757:             switch ((ctx->opcode >> 6) & 0x1f) {
                   11758:             case 1:
                   11759:                 /* rotrv is decoded as srlv on non-R2 CPUs */
                   11760:                 if (env->insn_flags & ISA_MIPS32R2) {
                   11761:                     op1 = OPC_ROTRV;
                   11762:                 }
                   11763:                 /* Fallthrough */
                   11764:             case 0:
                   11765:                 gen_shift(env, ctx, op1, rd, rs, rt);
                   11766:                 break;
                   11767:             default:
                   11768:                 generate_exception(ctx, EXCP_RI);
                   11769:                 break;
                   11770:             }
                   11771:             break;
1.1.1.8   root     11772:         case OPC_SLT:          /* Set on less than */
                   11773:         case OPC_SLTU:
                   11774:             gen_slt(env, op1, rd, rs, rt);
                   11775:             break;
                   11776:         case OPC_AND:          /* Logic*/
                   11777:         case OPC_OR:
                   11778:         case OPC_NOR:
                   11779:         case OPC_XOR:
                   11780:             gen_logic(env, op1, rd, rs, rt);
                   11781:             break;
1.1.1.5   root     11782:         case OPC_MULT ... OPC_DIVU:
1.1.1.6   root     11783:             if (sa) {
                   11784:                 check_insn(env, ctx, INSN_VR54XX);
                   11785:                 op1 = MASK_MUL_VR54XX(ctx->opcode);
                   11786:                 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
                   11787:             } else
                   11788:                 gen_muldiv(ctx, op1, rs, rt);
1.1       root     11789:             break;
1.1.1.5   root     11790:         case OPC_JR ... OPC_JALR:
1.1.1.12  root     11791:             gen_compute_branch(ctx, op1, 4, rs, rd, sa);
                   11792:             *is_branch = 1;
                   11793:             break;
1.1.1.5   root     11794:         case OPC_TGE ... OPC_TEQ: /* Traps */
                   11795:         case OPC_TNE:
                   11796:             gen_trap(ctx, op1, rs, rt, -1);
                   11797:             break;
                   11798:         case OPC_MFHI:          /* Move from HI/LO */
                   11799:         case OPC_MFLO:
                   11800:             gen_HILO(ctx, op1, rd);
1.1       root     11801:             break;
1.1.1.5   root     11802:         case OPC_MTHI:
                   11803:         case OPC_MTLO:          /* Move to HI/LO */
                   11804:             gen_HILO(ctx, op1, rs);
                   11805:             break;
1.1.1.6   root     11806:         case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
                   11807: #ifdef MIPS_STRICT_STANDARD
                   11808:             MIPS_INVAL("PMON / selsl");
                   11809:             generate_exception(ctx, EXCP_RI);
                   11810: #else
1.1.1.7   root     11811:             gen_helper_0i(pmon, sa);
1.1.1.6   root     11812: #endif
1.1.1.5   root     11813:             break;
                   11814:         case OPC_SYSCALL:
1.1       root     11815:             generate_exception(ctx, EXCP_SYSCALL);
1.1.1.8   root     11816:             ctx->bstate = BS_STOP;
1.1       root     11817:             break;
1.1.1.5   root     11818:         case OPC_BREAK:
1.1       root     11819:             generate_exception(ctx, EXCP_BREAK);
                   11820:             break;
1.1.1.6   root     11821:         case OPC_SPIM:
                   11822: #ifdef MIPS_STRICT_STANDARD
                   11823:             MIPS_INVAL("SPIM");
                   11824:             generate_exception(ctx, EXCP_RI);
                   11825: #else
1.1.1.5   root     11826:            /* Implemented as RI exception for now. */
                   11827:             MIPS_INVAL("spim (unofficial)");
                   11828:             generate_exception(ctx, EXCP_RI);
1.1.1.6   root     11829: #endif
1.1       root     11830:             break;
1.1.1.5   root     11831:         case OPC_SYNC:
1.1.1.6   root     11832:             /* Treat as NOP. */
1.1       root     11833:             break;
1.1.1.2   root     11834: 
1.1.1.5   root     11835:         case OPC_MOVCI:
1.1.1.6   root     11836:             check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
                   11837:             if (env->CP0_Config1 & (1 << CP0C1_FP)) {
                   11838:                 check_cp1_enabled(ctx);
                   11839:                 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
                   11840:                           (ctx->opcode >> 16) & 1);
                   11841:             } else {
                   11842:                 generate_exception_err(ctx, EXCP_CpU, 1);
                   11843:             }
1.1.1.2   root     11844:             break;
                   11845: 
1.1.1.6   root     11846: #if defined(TARGET_MIPS64)
1.1.1.5   root     11847:        /* MIPS64 specific opcodes */
                   11848:         case OPC_DSLL:
1.1.1.8   root     11849:         case OPC_DSRA:
1.1.1.5   root     11850:         case OPC_DSLL32:
1.1.1.8   root     11851:         case OPC_DSRA32:
1.1.1.6   root     11852:             check_insn(env, ctx, ISA_MIPS3);
                   11853:             check_mips_64(ctx);
1.1.1.8   root     11854:             gen_shift_imm(env, ctx, op1, rd, rt, sa);
1.1.1.5   root     11855:             break;
1.1.1.12  root     11856:         case OPC_DSRL:
                   11857:             switch ((ctx->opcode >> 21) & 0x1f) {
                   11858:             case 1:
                   11859:                 /* drotr is decoded as dsrl on non-R2 CPUs */
                   11860:                 if (env->insn_flags & ISA_MIPS32R2) {
                   11861:                     op1 = OPC_DROTR;
                   11862:                 }
                   11863:                 /* Fallthrough */
                   11864:             case 0:
                   11865:                 check_insn(env, ctx, ISA_MIPS3);
                   11866:                 check_mips_64(ctx);
                   11867:                 gen_shift_imm(env, ctx, op1, rd, rt, sa);
                   11868:                 break;
                   11869:             default:
                   11870:                 generate_exception(ctx, EXCP_RI);
                   11871:                 break;
                   11872:             }
                   11873:             break;
                   11874:         case OPC_DSRL32:
                   11875:             switch ((ctx->opcode >> 21) & 0x1f) {
                   11876:             case 1:
                   11877:                 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
                   11878:                 if (env->insn_flags & ISA_MIPS32R2) {
                   11879:                     op1 = OPC_DROTR32;
                   11880:                 }
                   11881:                 /* Fallthrough */
                   11882:             case 0:
                   11883:                 check_insn(env, ctx, ISA_MIPS3);
                   11884:                 check_mips_64(ctx);
                   11885:                 gen_shift_imm(env, ctx, op1, rd, rt, sa);
                   11886:                 break;
                   11887:             default:
                   11888:                 generate_exception(ctx, EXCP_RI);
                   11889:                 break;
                   11890:             }
                   11891:             break;
1.1.1.5   root     11892:         case OPC_DADD ... OPC_DSUBU:
1.1.1.6   root     11893:             check_insn(env, ctx, ISA_MIPS3);
                   11894:             check_mips_64(ctx);
                   11895:             gen_arith(env, ctx, op1, rd, rs, rt);
1.1.1.5   root     11896:             break;
1.1.1.8   root     11897:         case OPC_DSLLV:
                   11898:         case OPC_DSRAV:
                   11899:             check_insn(env, ctx, ISA_MIPS3);
                   11900:             check_mips_64(ctx);
                   11901:             gen_shift(env, ctx, op1, rd, rs, rt);
                   11902:             break;
1.1.1.12  root     11903:         case OPC_DSRLV:
                   11904:             switch ((ctx->opcode >> 6) & 0x1f) {
                   11905:             case 1:
                   11906:                 /* drotrv is decoded as dsrlv on non-R2 CPUs */
                   11907:                 if (env->insn_flags & ISA_MIPS32R2) {
                   11908:                     op1 = OPC_DROTRV;
                   11909:                 }
                   11910:                 /* Fallthrough */
                   11911:             case 0:
                   11912:                 check_insn(env, ctx, ISA_MIPS3);
                   11913:                 check_mips_64(ctx);
                   11914:                 gen_shift(env, ctx, op1, rd, rs, rt);
                   11915:                 break;
                   11916:             default:
                   11917:                 generate_exception(ctx, EXCP_RI);
                   11918:                 break;
                   11919:             }
                   11920:             break;
1.1.1.5   root     11921:         case OPC_DMULT ... OPC_DDIVU:
1.1.1.6   root     11922:             check_insn(env, ctx, ISA_MIPS3);
                   11923:             check_mips_64(ctx);
1.1.1.5   root     11924:             gen_muldiv(ctx, op1, rs, rt);
                   11925:             break;
1.1       root     11926: #endif
                   11927:         default:            /* Invalid */
                   11928:             MIPS_INVAL("special");
                   11929:             generate_exception(ctx, EXCP_RI);
                   11930:             break;
                   11931:         }
                   11932:         break;
1.1.1.5   root     11933:     case OPC_SPECIAL2:
                   11934:         op1 = MASK_SPECIAL2(ctx->opcode);
1.1       root     11935:         switch (op1) {
1.1.1.5   root     11936:         case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
                   11937:         case OPC_MSUB ... OPC_MSUBU:
1.1.1.6   root     11938:             check_insn(env, ctx, ISA_MIPS32);
1.1.1.5   root     11939:             gen_muldiv(ctx, op1, rs, rt);
1.1       root     11940:             break;
1.1.1.5   root     11941:         case OPC_MUL:
1.1.1.6   root     11942:             gen_arith(env, ctx, op1, rd, rs, rt);
1.1       root     11943:             break;
1.1.1.8   root     11944:         case OPC_CLO:
                   11945:         case OPC_CLZ:
1.1.1.6   root     11946:             check_insn(env, ctx, ISA_MIPS32);
1.1.1.5   root     11947:             gen_cl(ctx, op1, rd, rs);
1.1       root     11948:             break;
1.1.1.5   root     11949:         case OPC_SDBBP:
1.1       root     11950:             /* XXX: not clear which exception should be raised
                   11951:              *      when in debug mode...
                   11952:              */
1.1.1.6   root     11953:             check_insn(env, ctx, ISA_MIPS32);
1.1       root     11954:             if (!(ctx->hflags & MIPS_HFLAG_DM)) {
                   11955:                 generate_exception(ctx, EXCP_DBp);
                   11956:             } else {
                   11957:                 generate_exception(ctx, EXCP_DBp);
                   11958:             }
1.1.1.6   root     11959:             /* Treat as NOP. */
1.1       root     11960:             break;
1.1.1.12  root     11961:         case OPC_DIV_G_2F:
                   11962:         case OPC_DIVU_G_2F:
                   11963:         case OPC_MULT_G_2F:
                   11964:         case OPC_MULTU_G_2F:
                   11965:         case OPC_MOD_G_2F:
                   11966:         case OPC_MODU_G_2F:
                   11967:             check_insn(env, ctx, INSN_LOONGSON2F);
                   11968:             gen_loongson_integer(ctx, op1, rd, rs, rt);
                   11969:             break;
1.1.1.6   root     11970: #if defined(TARGET_MIPS64)
1.1.1.8   root     11971:         case OPC_DCLO:
                   11972:         case OPC_DCLZ:
1.1.1.6   root     11973:             check_insn(env, ctx, ISA_MIPS64);
                   11974:             check_mips_64(ctx);
1.1.1.5   root     11975:             gen_cl(ctx, op1, rd, rs);
                   11976:             break;
1.1.1.12  root     11977:         case OPC_DMULT_G_2F:
                   11978:         case OPC_DMULTU_G_2F:
                   11979:         case OPC_DDIV_G_2F:
                   11980:         case OPC_DDIVU_G_2F:
                   11981:         case OPC_DMOD_G_2F:
                   11982:         case OPC_DMODU_G_2F:
                   11983:             check_insn(env, ctx, INSN_LOONGSON2F);
                   11984:             gen_loongson_integer(ctx, op1, rd, rs, rt);
                   11985:             break;
1.1.1.5   root     11986: #endif
1.1       root     11987:         default:            /* Invalid */
                   11988:             MIPS_INVAL("special2");
                   11989:             generate_exception(ctx, EXCP_RI);
                   11990:             break;
                   11991:         }
                   11992:         break;
1.1.1.5   root     11993:     case OPC_SPECIAL3:
1.1.1.7   root     11994:         op1 = MASK_SPECIAL3(ctx->opcode);
                   11995:         switch (op1) {
                   11996:         case OPC_EXT:
                   11997:         case OPC_INS:
                   11998:             check_insn(env, ctx, ISA_MIPS32R2);
                   11999:             gen_bitops(ctx, op1, rt, rs, sa, rd);
                   12000:             break;
                   12001:         case OPC_BSHFL:
                   12002:             check_insn(env, ctx, ISA_MIPS32R2);
                   12003:             op2 = MASK_BSHFL(ctx->opcode);
                   12004:             gen_bshfl(ctx, op2, rt, rd);
1.1.1.6   root     12005:             break;
                   12006:         case OPC_RDHWR:
1.1.1.12  root     12007:             gen_rdhwr(env, ctx, rt, rd);
1.1.1.6   root     12008:             break;
                   12009:         case OPC_FORK:
                   12010:             check_insn(env, ctx, ASE_MT);
1.1.1.7   root     12011:             {
1.1.1.8   root     12012:                 TCGv t0 = tcg_temp_new();
                   12013:                 TCGv t1 = tcg_temp_new();
1.1.1.7   root     12014: 
                   12015:                 gen_load_gpr(t0, rt);
                   12016:                 gen_load_gpr(t1, rs);
                   12017:                 gen_helper_fork(t0, t1);
                   12018:                 tcg_temp_free(t0);
                   12019:                 tcg_temp_free(t1);
                   12020:             }
1.1.1.6   root     12021:             break;
                   12022:         case OPC_YIELD:
                   12023:             check_insn(env, ctx, ASE_MT);
1.1.1.7   root     12024:             {
1.1.1.8   root     12025:                 TCGv t0 = tcg_temp_new();
1.1.1.7   root     12026: 
1.1.1.8   root     12027:                 save_cpu_state(ctx, 1);
1.1.1.7   root     12028:                 gen_load_gpr(t0, rs);
                   12029:                 gen_helper_yield(t0, t0);
                   12030:                 gen_store_gpr(t0, rd);
                   12031:                 tcg_temp_free(t0);
                   12032:             }
1.1.1.6   root     12033:             break;
1.1.1.12  root     12034:         case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
                   12035:         case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
                   12036:         case OPC_MOD_G_2E ... OPC_MODU_G_2E:
                   12037:             check_insn(env, ctx, INSN_LOONGSON2E);
                   12038:             gen_loongson_integer(ctx, op1, rd, rs, rt);
                   12039:             break;
1.1.1.6   root     12040: #if defined(TARGET_MIPS64)
                   12041:         case OPC_DEXTM ... OPC_DEXT:
                   12042:         case OPC_DINSM ... OPC_DINS:
                   12043:             check_insn(env, ctx, ISA_MIPS64R2);
                   12044:             check_mips_64(ctx);
1.1.1.5   root     12045:             gen_bitops(ctx, op1, rt, rs, sa, rd);
                   12046:             break;
1.1.1.6   root     12047:         case OPC_DBSHFL:
                   12048:             check_insn(env, ctx, ISA_MIPS64R2);
                   12049:             check_mips_64(ctx);
                   12050:             op2 = MASK_DBSHFL(ctx->opcode);
1.1.1.7   root     12051:             gen_bshfl(ctx, op2, rt, rd);
1.1.1.6   root     12052:             break;
1.1.1.12  root     12053:         case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
                   12054:         case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
                   12055:         case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
                   12056:             check_insn(env, ctx, INSN_LOONGSON2E);
                   12057:             gen_loongson_integer(ctx, op1, rd, rs, rt);
                   12058:             break;
1.1.1.5   root     12059: #endif
                   12060:         default:            /* Invalid */
                   12061:             MIPS_INVAL("special3");
                   12062:             generate_exception(ctx, EXCP_RI);
                   12063:             break;
                   12064:         }
                   12065:         break;
                   12066:     case OPC_REGIMM:
                   12067:         op1 = MASK_REGIMM(ctx->opcode);
1.1       root     12068:         switch (op1) {
1.1.1.5   root     12069:         case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
                   12070:         case OPC_BLTZAL ... OPC_BGEZALL:
1.1.1.12  root     12071:             gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
                   12072:             *is_branch = 1;
                   12073:             break;
1.1.1.5   root     12074:         case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
                   12075:         case OPC_TNEI:
                   12076:             gen_trap(ctx, op1, rs, -1, imm);
                   12077:             break;
                   12078:         case OPC_SYNCI:
1.1.1.6   root     12079:             check_insn(env, ctx, ISA_MIPS32R2);
                   12080:             /* Treat as NOP. */
1.1       root     12081:             break;
                   12082:         default:            /* Invalid */
1.1.1.6   root     12083:             MIPS_INVAL("regimm");
1.1       root     12084:             generate_exception(ctx, EXCP_RI);
                   12085:             break;
                   12086:         }
                   12087:         break;
1.1.1.5   root     12088:     case OPC_CP0:
1.1.1.6   root     12089:         check_cp0_enabled(ctx);
1.1.1.5   root     12090:         op1 = MASK_CP0(ctx->opcode);
1.1       root     12091:         switch (op1) {
1.1.1.5   root     12092:         case OPC_MFC0:
                   12093:         case OPC_MTC0:
1.1.1.6   root     12094:         case OPC_MFTR:
                   12095:         case OPC_MTTR:
                   12096: #if defined(TARGET_MIPS64)
1.1.1.5   root     12097:         case OPC_DMFC0:
                   12098:         case OPC_DMTC0:
                   12099: #endif
1.1.1.7   root     12100: #ifndef CONFIG_USER_ONLY
1.1.1.6   root     12101:             gen_cp0(env, ctx, op1, rt, rd);
1.1.1.7   root     12102: #endif /* !CONFIG_USER_ONLY */
1.1.1.5   root     12103:             break;
                   12104:         case OPC_C0_FIRST ... OPC_C0_LAST:
1.1.1.7   root     12105: #ifndef CONFIG_USER_ONLY
1.1.1.6   root     12106:             gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
1.1.1.7   root     12107: #endif /* !CONFIG_USER_ONLY */
1.1.1.5   root     12108:             break;
                   12109:         case OPC_MFMC0:
1.1.1.7   root     12110: #ifndef CONFIG_USER_ONLY
                   12111:             {
1.1.1.8   root     12112:                 TCGv t0 = tcg_temp_new();
1.1.1.7   root     12113: 
                   12114:                 op2 = MASK_MFMC0(ctx->opcode);
                   12115:                 switch (op2) {
                   12116:                 case OPC_DMT:
                   12117:                     check_insn(env, ctx, ASE_MT);
1.1.1.13  root     12118:                     gen_helper_dmt(t0);
1.1.1.8   root     12119:                     gen_store_gpr(t0, rt);
1.1.1.7   root     12120:                     break;
                   12121:                 case OPC_EMT:
                   12122:                     check_insn(env, ctx, ASE_MT);
1.1.1.13  root     12123:                     gen_helper_emt(t0);
1.1.1.8   root     12124:                     gen_store_gpr(t0, rt);
1.1.1.7   root     12125:                     break;
                   12126:                 case OPC_DVPE:
                   12127:                     check_insn(env, ctx, ASE_MT);
1.1.1.13  root     12128:                     gen_helper_dvpe(t0);
1.1.1.8   root     12129:                     gen_store_gpr(t0, rt);
1.1.1.7   root     12130:                     break;
                   12131:                 case OPC_EVPE:
                   12132:                     check_insn(env, ctx, ASE_MT);
1.1.1.13  root     12133:                     gen_helper_evpe(t0);
1.1.1.8   root     12134:                     gen_store_gpr(t0, rt);
1.1.1.7   root     12135:                     break;
                   12136:                 case OPC_DI:
                   12137:                     check_insn(env, ctx, ISA_MIPS32R2);
                   12138:                     save_cpu_state(ctx, 1);
                   12139:                     gen_helper_di(t0);
1.1.1.8   root     12140:                     gen_store_gpr(t0, rt);
1.1.1.7   root     12141:                     /* Stop translation as we may have switched the execution mode */
                   12142:                     ctx->bstate = BS_STOP;
                   12143:                     break;
                   12144:                 case OPC_EI:
                   12145:                     check_insn(env, ctx, ISA_MIPS32R2);
                   12146:                     save_cpu_state(ctx, 1);
                   12147:                     gen_helper_ei(t0);
1.1.1.8   root     12148:                     gen_store_gpr(t0, rt);
1.1.1.7   root     12149:                     /* Stop translation as we may have switched the execution mode */
                   12150:                     ctx->bstate = BS_STOP;
                   12151:                     break;
                   12152:                 default:            /* Invalid */
                   12153:                     MIPS_INVAL("mfmc0");
                   12154:                     generate_exception(ctx, EXCP_RI);
                   12155:                     break;
                   12156:                 }
                   12157:                 tcg_temp_free(t0);
1.1.1.5   root     12158:             }
1.1.1.7   root     12159: #endif /* !CONFIG_USER_ONLY */
1.1       root     12160:             break;
1.1.1.5   root     12161:         case OPC_RDPGPR:
1.1.1.6   root     12162:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7   root     12163:             gen_load_srsgpr(rt, rd);
1.1.1.6   root     12164:             break;
1.1.1.5   root     12165:         case OPC_WRPGPR:
1.1.1.6   root     12166:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7   root     12167:             gen_store_srsgpr(rt, rd);
1.1.1.6   root     12168:             break;
1.1       root     12169:         default:
1.1.1.6   root     12170:             MIPS_INVAL("cp0");
1.1.1.5   root     12171:             generate_exception(ctx, EXCP_RI);
1.1       root     12172:             break;
                   12173:         }
                   12174:         break;
1.1.1.8   root     12175:     case OPC_ADDI: /* Arithmetic with immediate opcode */
                   12176:     case OPC_ADDIU:
1.1.1.6   root     12177:          gen_arith_imm(env, ctx, op, rt, rs, imm);
1.1.1.5   root     12178:          break;
1.1.1.8   root     12179:     case OPC_SLTI: /* Set on less than with immediate opcode */
                   12180:     case OPC_SLTIU:
                   12181:          gen_slt_imm(env, op, rt, rs, imm);
                   12182:          break;
                   12183:     case OPC_ANDI: /* Arithmetic with immediate opcode */
                   12184:     case OPC_LUI:
                   12185:     case OPC_ORI:
                   12186:     case OPC_XORI:
                   12187:          gen_logic_imm(env, op, rt, rs, imm);
                   12188:          break;
1.1.1.5   root     12189:     case OPC_J ... OPC_JAL: /* Jump */
                   12190:          offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
1.1.1.12  root     12191:          gen_compute_branch(ctx, op, 4, rs, rt, offset);
                   12192:          *is_branch = 1;
                   12193:          break;
1.1.1.5   root     12194:     case OPC_BEQ ... OPC_BGTZ: /* Branch */
                   12195:     case OPC_BEQL ... OPC_BGTZL:
1.1.1.12  root     12196:          gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
                   12197:          *is_branch = 1;
                   12198:          break;
1.1.1.5   root     12199:     case OPC_LB ... OPC_LWR: /* Load and stores */
1.1.1.12  root     12200:     case OPC_LL:
                   12201:          gen_ld(env, ctx, op, rt, rs, imm);
                   12202:          break;
1.1.1.5   root     12203:     case OPC_SB ... OPC_SW:
                   12204:     case OPC_SWR:
1.1.1.12  root     12205:          gen_st(ctx, op, rt, rs, imm);
1.1.1.5   root     12206:          break;
1.1.1.8   root     12207:     case OPC_SC:
                   12208:          gen_st_cond(ctx, op, rt, rs, imm);
                   12209:          break;
1.1.1.5   root     12210:     case OPC_CACHE:
1.1.1.6   root     12211:         check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
                   12212:         /* Treat as NOP. */
                   12213:         break;
1.1.1.5   root     12214:     case OPC_PREF:
1.1.1.6   root     12215:         check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
                   12216:         /* Treat as NOP. */
1.1       root     12217:         break;
1.1.1.2   root     12218: 
1.1.1.6   root     12219:     /* Floating point (COP1). */
1.1.1.5   root     12220:     case OPC_LWC1:
                   12221:     case OPC_LDC1:
                   12222:     case OPC_SWC1:
                   12223:     case OPC_SDC1:
1.1.1.12  root     12224:         gen_cop1_ldst(env, ctx, op, rt, rs, imm);
1.1.1.4   root     12225:         break;
                   12226: 
1.1.1.5   root     12227:     case OPC_CP1:
1.1.1.6   root     12228:         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
                   12229:             check_cp1_enabled(ctx);
                   12230:             op1 = MASK_CP1(ctx->opcode);
                   12231:             switch (op1) {
                   12232:             case OPC_MFHC1:
                   12233:             case OPC_MTHC1:
                   12234:                 check_insn(env, ctx, ISA_MIPS32R2);
                   12235:             case OPC_MFC1:
                   12236:             case OPC_CFC1:
                   12237:             case OPC_MTC1:
                   12238:             case OPC_CTC1:
                   12239:                 gen_cp1(ctx, op1, rt, rd);
                   12240:                 break;
                   12241: #if defined(TARGET_MIPS64)
                   12242:             case OPC_DMFC1:
                   12243:             case OPC_DMTC1:
                   12244:                 check_insn(env, ctx, ISA_MIPS3);
                   12245:                 gen_cp1(ctx, op1, rt, rd);
                   12246:                 break;
1.1.1.5   root     12247: #endif
1.1.1.6   root     12248:             case OPC_BC1ANY2:
                   12249:             case OPC_BC1ANY4:
                   12250:                 check_cop1x(ctx);
                   12251:                 check_insn(env, ctx, ASE_MIPS3D);
                   12252:                 /* fall through */
                   12253:             case OPC_BC1:
                   12254:                 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
                   12255:                                     (rt >> 2) & 0x7, imm << 2);
1.1.1.12  root     12256:                 *is_branch = 1;
                   12257:                 break;
1.1.1.6   root     12258:             case OPC_S_FMT:
                   12259:             case OPC_D_FMT:
                   12260:             case OPC_W_FMT:
                   12261:             case OPC_L_FMT:
                   12262:             case OPC_PS_FMT:
1.1.1.12  root     12263:                 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
1.1.1.6   root     12264:                            (imm >> 8) & 0x7);
                   12265:                 break;
                   12266:             default:
                   12267:                 MIPS_INVAL("cp1");
                   12268:                 generate_exception (ctx, EXCP_RI);
                   12269:                 break;
                   12270:             }
                   12271:         } else {
                   12272:             generate_exception_err(ctx, EXCP_CpU, 1);
1.1.1.4   root     12273:         }
1.1.1.2   root     12274:         break;
                   12275: 
                   12276:     /* COP2.  */
1.1.1.5   root     12277:     case OPC_LWC2:
                   12278:     case OPC_LDC2:
                   12279:     case OPC_SWC2:
                   12280:     case OPC_SDC2:
                   12281:     case OPC_CP2:
                   12282:         /* COP2: Not implemented. */
1.1.1.2   root     12283:         generate_exception_err(ctx, EXCP_CpU, 2);
                   12284:         break;
                   12285: 
1.1.1.5   root     12286:     case OPC_CP3:
1.1.1.6   root     12287:         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
                   12288:             check_cp1_enabled(ctx);
                   12289:             op1 = MASK_CP3(ctx->opcode);
                   12290:             switch (op1) {
                   12291:             case OPC_LWXC1:
                   12292:             case OPC_LDXC1:
                   12293:             case OPC_LUXC1:
                   12294:             case OPC_SWXC1:
                   12295:             case OPC_SDXC1:
                   12296:             case OPC_SUXC1:
                   12297:                 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
                   12298:                 break;
                   12299:             case OPC_PREFX:
                   12300:                 /* Treat as NOP. */
                   12301:                 break;
                   12302:             case OPC_ALNV_PS:
                   12303:             case OPC_MADD_S:
                   12304:             case OPC_MADD_D:
                   12305:             case OPC_MADD_PS:
                   12306:             case OPC_MSUB_S:
                   12307:             case OPC_MSUB_D:
                   12308:             case OPC_MSUB_PS:
                   12309:             case OPC_NMADD_S:
                   12310:             case OPC_NMADD_D:
                   12311:             case OPC_NMADD_PS:
                   12312:             case OPC_NMSUB_S:
                   12313:             case OPC_NMSUB_D:
                   12314:             case OPC_NMSUB_PS:
                   12315:                 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
                   12316:                 break;
                   12317:             default:
                   12318:                 MIPS_INVAL("cp3");
                   12319:                 generate_exception (ctx, EXCP_RI);
                   12320:                 break;
                   12321:             }
                   12322:         } else {
                   12323:             generate_exception_err(ctx, EXCP_CpU, 1);
1.1.1.5   root     12324:         }
1.1.1.2   root     12325:         break;
                   12326: 
1.1.1.6   root     12327: #if defined(TARGET_MIPS64)
1.1.1.5   root     12328:     /* MIPS64 opcodes */
                   12329:     case OPC_LWU:
                   12330:     case OPC_LDL ... OPC_LDR:
                   12331:     case OPC_LLD:
                   12332:     case OPC_LD:
1.1.1.12  root     12333:         check_insn(env, ctx, ISA_MIPS3);
                   12334:         check_mips_64(ctx);
                   12335:         gen_ld(env, ctx, op, rt, rs, imm);
                   12336:         break;
                   12337:     case OPC_SDL ... OPC_SDR:
1.1.1.5   root     12338:     case OPC_SD:
1.1.1.6   root     12339:         check_insn(env, ctx, ISA_MIPS3);
                   12340:         check_mips_64(ctx);
1.1.1.12  root     12341:         gen_st(ctx, op, rt, rs, imm);
1.1.1.5   root     12342:         break;
1.1.1.8   root     12343:     case OPC_SCD:
                   12344:         check_insn(env, ctx, ISA_MIPS3);
                   12345:         check_mips_64(ctx);
                   12346:         gen_st_cond(ctx, op, rt, rs, imm);
                   12347:         break;
                   12348:     case OPC_DADDI:
                   12349:     case OPC_DADDIU:
1.1.1.6   root     12350:         check_insn(env, ctx, ISA_MIPS3);
                   12351:         check_mips_64(ctx);
                   12352:         gen_arith_imm(env, ctx, op, rt, rs, imm);
1.1.1.5   root     12353:         break;
                   12354: #endif
                   12355:     case OPC_JALX:
1.1.1.12  root     12356:         check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
                   12357:         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
                   12358:         gen_compute_branch(ctx, op, 4, rs, rt, offset);
                   12359:         *is_branch = 1;
                   12360:         break;
1.1.1.5   root     12361:     case OPC_MDMX:
1.1.1.6   root     12362:         check_insn(env, ctx, ASE_MDMX);
1.1.1.5   root     12363:         /* MDMX: Not implemented. */
1.1       root     12364:     default:            /* Invalid */
1.1.1.6   root     12365:         MIPS_INVAL("major opcode");
1.1       root     12366:         generate_exception(ctx, EXCP_RI);
                   12367:         break;
                   12368:     }
                   12369: }
                   12370: 
1.1.1.7   root     12371: static inline void
1.1.1.16! root     12372: gen_intermediate_code_internal (CPUMIPSState *env, TranslationBlock *tb,
1.1.1.6   root     12373:                                 int search_pc)
1.1       root     12374: {
1.1.1.6   root     12375:     DisasContext ctx;
1.1       root     12376:     target_ulong pc_start;
                   12377:     uint16_t *gen_opc_end;
1.1.1.7   root     12378:     CPUBreakpoint *bp;
1.1       root     12379:     int j, lj = -1;
1.1.1.7   root     12380:     int num_insns;
                   12381:     int max_insns;
1.1.1.12  root     12382:     int insn_bytes;
                   12383:     int is_branch;
1.1       root     12384: 
1.1.1.7   root     12385:     if (search_pc)
                   12386:         qemu_log("search pc %d\n", search_pc);
1.1.1.2   root     12387: 
1.1       root     12388:     pc_start = tb->pc;
1.1.1.9   root     12389:     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1.1       root     12390:     ctx.pc = pc_start;
1.1.1.2   root     12391:     ctx.saved_pc = -1;
1.1.1.9   root     12392:     ctx.singlestep_enabled = env->singlestep_enabled;
1.1       root     12393:     ctx.tb = tb;
                   12394:     ctx.bstate = BS_NONE;
1.1.1.2   root     12395:     /* Restore delay slot state from the tb context.  */
1.1.1.6   root     12396:     ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
                   12397:     restore_cpu_state(env, &ctx);
1.1.1.7   root     12398: #ifdef CONFIG_USER_ONLY
                   12399:         ctx.mem_idx = MIPS_HFLAG_UM;
1.1       root     12400: #else
1.1.1.7   root     12401:         ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
1.1       root     12402: #endif
1.1.1.7   root     12403:     num_insns = 0;
                   12404:     max_insns = tb->cflags & CF_COUNT_MASK;
                   12405:     if (max_insns == 0)
                   12406:         max_insns = CF_COUNT_MASK;
                   12407:     LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
                   12408:     gen_icount_start();
                   12409:     while (ctx.bstate == BS_NONE) {
1.1.1.9   root     12410:         if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
                   12411:             QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
1.1.1.7   root     12412:                 if (bp->pc == ctx.pc) {
1.1.1.6   root     12413:                     save_cpu_state(&ctx, 1);
1.1.1.2   root     12414:                     ctx.bstate = BS_BRANCH;
1.1.1.7   root     12415:                     gen_helper_0i(raise_exception, EXCP_DEBUG);
1.1.1.6   root     12416:                     /* Include the breakpoint location or the tb won't
                   12417:                      * be flushed when it must be.  */
                   12418:                     ctx.pc += 4;
1.1.1.2   root     12419:                     goto done_generating;
                   12420:                 }
                   12421:             }
                   12422:         }
                   12423: 
1.1       root     12424:         if (search_pc) {
                   12425:             j = gen_opc_ptr - gen_opc_buf;
                   12426:             if (lj < j) {
                   12427:                 lj++;
                   12428:                 while (lj < j)
                   12429:                     gen_opc_instr_start[lj++] = 0;
                   12430:             }
1.1.1.2   root     12431:             gen_opc_pc[lj] = ctx.pc;
                   12432:             gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
                   12433:             gen_opc_instr_start[lj] = 1;
1.1.1.7   root     12434:             gen_opc_icount[lj] = num_insns;
1.1       root     12435:         }
1.1.1.7   root     12436:         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
                   12437:             gen_io_start();
1.1.1.12  root     12438: 
                   12439:         is_branch = 0;
                   12440:         if (!(ctx.hflags & MIPS_HFLAG_M16)) {
                   12441:             ctx.opcode = ldl_code(ctx.pc);
                   12442:             insn_bytes = 4;
                   12443:             decode_opc(env, &ctx, &is_branch);
                   12444:         } else if (env->insn_flags & ASE_MICROMIPS) {
                   12445:             ctx.opcode = lduw_code(ctx.pc);
                   12446:             insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
                   12447:         } else if (env->insn_flags & ASE_MIPS16) {
                   12448:             ctx.opcode = lduw_code(ctx.pc);
                   12449:             insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
                   12450:         } else {
                   12451:             generate_exception(&ctx, EXCP_RI);
                   12452:             ctx.bstate = BS_STOP;
                   12453:             break;
                   12454:         }
                   12455:         if (!is_branch) {
                   12456:             handle_delay_slot(env, &ctx, insn_bytes);
                   12457:         }
                   12458:         ctx.pc += insn_bytes;
                   12459: 
1.1.1.7   root     12460:         num_insns++;
1.1.1.2   root     12461: 
1.1.1.9   root     12462:         /* Execute a branch and its delay slot as a single instruction.
                   12463:            This is what GDB expects and is consistent with what the
                   12464:            hardware does (e.g. if a delay slot instruction faults, the
                   12465:            reported PC is the PC of the branch).  */
                   12466:         if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
1.1.1.2   root     12467:             break;
                   12468: 
1.1       root     12469:         if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
                   12470:             break;
1.1.1.2   root     12471: 
1.1.1.7   root     12472:         if (gen_opc_ptr >= gen_opc_end)
                   12473:             break;
                   12474: 
                   12475:         if (num_insns >= max_insns)
                   12476:             break;
1.1.1.8   root     12477: 
                   12478:         if (singlestep)
                   12479:             break;
1.1       root     12480:     }
1.1.1.7   root     12481:     if (tb->cflags & CF_LAST_IO)
                   12482:         gen_io_end();
1.1.1.9   root     12483:     if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
1.1.1.6   root     12484:         save_cpu_state(&ctx, ctx.bstate == BS_NONE);
1.1.1.7   root     12485:         gen_helper_0i(raise_exception, EXCP_DEBUG);
1.1.1.6   root     12486:     } else {
1.1.1.7   root     12487:         switch (ctx.bstate) {
1.1.1.6   root     12488:         case BS_STOP:
                   12489:             gen_goto_tb(&ctx, 0, ctx.pc);
                   12490:             break;
                   12491:         case BS_NONE:
                   12492:             save_cpu_state(&ctx, 0);
                   12493:             gen_goto_tb(&ctx, 0, ctx.pc);
                   12494:             break;
                   12495:         case BS_EXCP:
1.1.1.7   root     12496:             tcg_gen_exit_tb(0);
1.1.1.6   root     12497:             break;
                   12498:         case BS_BRANCH:
                   12499:         default:
                   12500:             break;
1.1.1.7   root     12501:         }
1.1       root     12502:     }
1.1.1.2   root     12503: done_generating:
1.1.1.7   root     12504:     gen_icount_end(tb, num_insns);
1.1       root     12505:     *gen_opc_ptr = INDEX_op_end;
                   12506:     if (search_pc) {
                   12507:         j = gen_opc_ptr - gen_opc_buf;
                   12508:         lj++;
                   12509:         while (lj <= j)
                   12510:             gen_opc_instr_start[lj++] = 0;
                   12511:     } else {
                   12512:         tb->size = ctx.pc - pc_start;
1.1.1.7   root     12513:         tb->icount = num_insns;
1.1       root     12514:     }
                   12515: #ifdef DEBUG_DISAS
1.1.1.7   root     12516:     LOG_DISAS("\n");
                   12517:     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
                   12518:         qemu_log("IN: %s\n", lookup_symbol(pc_start));
                   12519:         log_target_disas(pc_start, ctx.pc - pc_start, 0);
                   12520:         qemu_log("\n");
1.1       root     12521:     }
                   12522: #endif
                   12523: }
                   12524: 
1.1.1.16! root     12525: void gen_intermediate_code (CPUMIPSState *env, struct TranslationBlock *tb)
1.1       root     12526: {
1.1.1.7   root     12527:     gen_intermediate_code_internal(env, tb, 0);
1.1       root     12528: }
                   12529: 
1.1.1.16! root     12530: void gen_intermediate_code_pc (CPUMIPSState *env, struct TranslationBlock *tb)
1.1       root     12531: {
1.1.1.7   root     12532:     gen_intermediate_code_internal(env, tb, 1);
1.1       root     12533: }
                   12534: 
1.1.1.16! root     12535: static void fpu_dump_state(CPUMIPSState *env, FILE *f, fprintf_function fpu_fprintf,
1.1.1.7   root     12536:                            int flags)
1.1.1.4   root     12537: {
                   12538:     int i;
1.1.1.6   root     12539:     int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
1.1.1.4   root     12540: 
1.1.1.12  root     12541: #define printfpr(fp)                                                    \
                   12542:     do {                                                                \
                   12543:         if (is_fpu64)                                                   \
                   12544:             fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
                   12545:                         " fd:%13g fs:%13g psu: %13g\n",                 \
                   12546:                         (fp)->w[FP_ENDIAN_IDX], (fp)->d,                \
                   12547:                         (double)(fp)->fd,                               \
                   12548:                         (double)(fp)->fs[FP_ENDIAN_IDX],                \
                   12549:                         (double)(fp)->fs[!FP_ENDIAN_IDX]);              \
                   12550:         else {                                                          \
                   12551:             fpr_t tmp;                                                  \
                   12552:             tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
                   12553:             tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
                   12554:             fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
                   12555:                         " fd:%13g fs:%13g psu:%13g\n",                  \
                   12556:                         tmp.w[FP_ENDIAN_IDX], tmp.d,                    \
                   12557:                         (double)tmp.fd,                                 \
                   12558:                         (double)tmp.fs[FP_ENDIAN_IDX],                  \
                   12559:                         (double)tmp.fs[!FP_ENDIAN_IDX]);                \
                   12560:         }                                                               \
1.1.1.4   root     12561:     } while(0)
                   12562: 
1.1.1.6   root     12563: 
1.1.1.13  root     12564:     fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%02x\n",
                   12565:                 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
1.1.1.7   root     12566:                 get_float_exception_flags(&env->active_fpu.fp_status));
1.1.1.6   root     12567:     for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
                   12568:         fpu_fprintf(f, "%3s: ", fregnames[i]);
1.1.1.7   root     12569:         printfpr(&env->active_fpu.fpr[i]);
1.1.1.4   root     12570:     }
                   12571: 
                   12572: #undef printfpr
                   12573: }
                   12574: 
1.1.1.6   root     12575: #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
1.1.1.5   root     12576: /* Debug help: The architecture requires 32bit code to maintain proper
1.1.1.7   root     12577:    sign-extended values on 64bit machines.  */
1.1.1.5   root     12578: 
                   12579: #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
                   12580: 
1.1.1.7   root     12581: static void
1.1.1.16! root     12582: cpu_mips_check_sign_extensions (CPUMIPSState *env, FILE *f,
1.1.1.13  root     12583:                                 fprintf_function cpu_fprintf,
1.1.1.7   root     12584:                                 int flags)
1.1.1.5   root     12585: {
                   12586:     int i;
                   12587: 
1.1.1.7   root     12588:     if (!SIGN_EXT_P(env->active_tc.PC))
                   12589:         cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
                   12590:     if (!SIGN_EXT_P(env->active_tc.HI[0]))
                   12591:         cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
                   12592:     if (!SIGN_EXT_P(env->active_tc.LO[0]))
                   12593:         cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
1.1.1.5   root     12594:     if (!SIGN_EXT_P(env->btarget))
1.1.1.6   root     12595:         cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
1.1.1.5   root     12596: 
                   12597:     for (i = 0; i < 32; i++) {
1.1.1.7   root     12598:         if (!SIGN_EXT_P(env->active_tc.gpr[i]))
                   12599:             cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
1.1.1.5   root     12600:     }
                   12601: 
                   12602:     if (!SIGN_EXT_P(env->CP0_EPC))
1.1.1.6   root     12603:         cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
1.1.1.9   root     12604:     if (!SIGN_EXT_P(env->lladdr))
                   12605:         cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
1.1.1.5   root     12606: }
                   12607: #endif
                   12608: 
1.1.1.16! root     12609: void cpu_dump_state (CPUMIPSState *env, FILE *f, fprintf_function cpu_fprintf,
1.1       root     12610:                      int flags)
                   12611: {
                   12612:     int i;
1.1.1.6   root     12613: 
1.1.1.12  root     12614:     cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
                   12615:                 " LO=0x" TARGET_FMT_lx " ds %04x "
                   12616:                 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
1.1.1.7   root     12617:                 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
                   12618:                 env->hflags, env->btarget, env->bcond);
1.1       root     12619:     for (i = 0; i < 32; i++) {
                   12620:         if ((i & 3) == 0)
                   12621:             cpu_fprintf(f, "GPR%02d:", i);
1.1.1.7   root     12622:         cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
1.1       root     12623:         if ((i & 3) == 3)
                   12624:             cpu_fprintf(f, "\n");
                   12625:     }
                   12626: 
1.1.1.6   root     12627:     cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
                   12628:                 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
                   12629:     cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
1.1.1.9   root     12630:                 env->CP0_Config0, env->CP0_Config1, env->lladdr);
1.1.1.6   root     12631:     if (env->hflags & MIPS_HFLAG_FPU)
1.1.1.5   root     12632:         fpu_dump_state(env, f, cpu_fprintf, flags);
1.1.1.6   root     12633: #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
1.1.1.5   root     12634:     cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
1.1.1.4   root     12635: #endif
1.1       root     12636: }
                   12637: 
1.1.1.7   root     12638: static void mips_tcg_init(void)
                   12639: {
                   12640:     int i;
                   12641:     static int inited;
                   12642: 
                   12643:     /* Initialize various static tables. */
                   12644:     if (inited)
                   12645:         return;
                   12646: 
                   12647:     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
1.1.1.8   root     12648:     TCGV_UNUSED(cpu_gpr[0]);
                   12649:     for (i = 1; i < 32; i++)
1.1.1.7   root     12650:         cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
1.1.1.16! root     12651:                                         offsetof(CPUMIPSState, active_tc.gpr[i]),
1.1.1.7   root     12652:                                         regnames[i]);
                   12653:     cpu_PC = tcg_global_mem_new(TCG_AREG0,
1.1.1.16! root     12654:                                 offsetof(CPUMIPSState, active_tc.PC), "PC");
1.1.1.7   root     12655:     for (i = 0; i < MIPS_DSP_ACC; i++) {
                   12656:         cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
1.1.1.16! root     12657:                                        offsetof(CPUMIPSState, active_tc.HI[i]),
1.1.1.7   root     12658:                                        regnames_HI[i]);
                   12659:         cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
1.1.1.16! root     12660:                                        offsetof(CPUMIPSState, active_tc.LO[i]),
1.1.1.7   root     12661:                                        regnames_LO[i]);
                   12662:         cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
1.1.1.16! root     12663:                                         offsetof(CPUMIPSState, active_tc.ACX[i]),
1.1.1.7   root     12664:                                         regnames_ACX[i]);
                   12665:     }
                   12666:     cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
1.1.1.16! root     12667:                                      offsetof(CPUMIPSState, active_tc.DSPControl),
1.1.1.7   root     12668:                                      "DSPControl");
1.1.1.8   root     12669:     bcond = tcg_global_mem_new(TCG_AREG0,
1.1.1.16! root     12670:                                offsetof(CPUMIPSState, bcond), "bcond");
1.1.1.7   root     12671:     btarget = tcg_global_mem_new(TCG_AREG0,
1.1.1.16! root     12672:                                  offsetof(CPUMIPSState, btarget), "btarget");
1.1.1.8   root     12673:     hflags = tcg_global_mem_new_i32(TCG_AREG0,
1.1.1.16! root     12674:                                     offsetof(CPUMIPSState, hflags), "hflags");
1.1.1.8   root     12675: 
1.1.1.7   root     12676:     fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
1.1.1.16! root     12677:                                       offsetof(CPUMIPSState, active_fpu.fcr0),
1.1.1.7   root     12678:                                       "fcr0");
                   12679:     fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
1.1.1.16! root     12680:                                        offsetof(CPUMIPSState, active_fpu.fcr31),
1.1.1.7   root     12681:                                        "fcr31");
                   12682: 
                   12683:     /* register helpers */
                   12684: #define GEN_HELPER 2
                   12685: #include "helper.h"
                   12686: 
                   12687:     inited = 1;
                   12688: }
                   12689: 
1.1.1.6   root     12690: #include "translate_init.c"
                   12691: 
                   12692: CPUMIPSState *cpu_mips_init (const char *cpu_model)
1.1       root     12693: {
1.1.1.16! root     12694:     MIPSCPU *cpu;
1.1       root     12695:     CPUMIPSState *env;
1.1.1.6   root     12696:     const mips_def_t *def;
1.1       root     12697: 
1.1.1.6   root     12698:     def = cpu_mips_find_by_name(cpu_model);
                   12699:     if (!def)
                   12700:         return NULL;
1.1.1.16! root     12701:     cpu = MIPS_CPU(object_new(TYPE_MIPS_CPU));
        !          12702:     env = &cpu->env;
1.1.1.6   root     12703:     env->cpu_model = def;
1.1.1.9   root     12704:     env->cpu_model_str = cpu_model;
1.1.1.6   root     12705: 
1.1.1.9   root     12706: #ifndef CONFIG_USER_ONLY
                   12707:     mmu_init(env, def);
                   12708: #endif
                   12709:     fpu_init(env, def);
                   12710:     mvp_init(env, def);
1.1.1.7   root     12711:     mips_tcg_init();
1.1.1.16! root     12712:     cpu_state_reset(env);
1.1.1.8   root     12713:     qemu_init_vcpu(env);
1.1.1.5   root     12714:     return env;
                   12715: }
                   12716: 
1.1.1.16! root     12717: void cpu_state_reset(CPUMIPSState *env)
1.1.1.5   root     12718: {
1.1.1.7   root     12719:     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
                   12720:         qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
                   12721:         log_cpu_state(env, 0);
                   12722:     }
                   12723: 
1.1.1.5   root     12724:     memset(env, 0, offsetof(CPUMIPSState, breakpoints));
1.1       root     12725:     tlb_flush(env, 1);
1.1.1.5   root     12726: 
1.1.1.9   root     12727:     /* Reset registers to their default values */
                   12728:     env->CP0_PRid = env->cpu_model->CP0_PRid;
                   12729:     env->CP0_Config0 = env->cpu_model->CP0_Config0;
                   12730: #ifdef TARGET_WORDS_BIGENDIAN
                   12731:     env->CP0_Config0 |= (1 << CP0C0_BE);
                   12732: #endif
                   12733:     env->CP0_Config1 = env->cpu_model->CP0_Config1;
                   12734:     env->CP0_Config2 = env->cpu_model->CP0_Config2;
                   12735:     env->CP0_Config3 = env->cpu_model->CP0_Config3;
                   12736:     env->CP0_Config6 = env->cpu_model->CP0_Config6;
                   12737:     env->CP0_Config7 = env->cpu_model->CP0_Config7;
                   12738:     env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
                   12739:                                  << env->cpu_model->CP0_LLAddr_shift;
                   12740:     env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
                   12741:     env->SYNCI_Step = env->cpu_model->SYNCI_Step;
                   12742:     env->CCRes = env->cpu_model->CCRes;
                   12743:     env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
                   12744:     env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
                   12745:     env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
                   12746:     env->current_tc = 0;
                   12747:     env->SEGBITS = env->cpu_model->SEGBITS;
                   12748:     env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
                   12749: #if defined(TARGET_MIPS64)
                   12750:     if (env->cpu_model->insn_flags & ISA_MIPS3) {
                   12751:         env->SEGMask |= 3ULL << 62;
                   12752:     }
                   12753: #endif
                   12754:     env->PABITS = env->cpu_model->PABITS;
                   12755:     env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
                   12756:     env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
                   12757:     env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
                   12758:     env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
                   12759:     env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
                   12760:     env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
                   12761:     env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
                   12762:     env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
                   12763:     env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
                   12764:     env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
                   12765:     env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
                   12766:     env->insn_flags = env->cpu_model->insn_flags;
                   12767: 
1.1.1.7   root     12768: #if defined(CONFIG_USER_ONLY)
                   12769:     env->hflags = MIPS_HFLAG_UM;
1.1.1.8   root     12770:     /* Enable access to the SYNCI_Step register.  */
                   12771:     env->CP0_HWREna |= (1 << 1);
1.1.1.9   root     12772:     if (env->CP0_Config1 & (1 << CP0C1_FP)) {
                   12773:         env->hflags |= MIPS_HFLAG_FPU;
                   12774:     }
                   12775: #ifdef TARGET_MIPS64
                   12776:     if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
                   12777:         env->hflags |= MIPS_HFLAG_F64;
                   12778:     }
                   12779: #endif
1.1.1.7   root     12780: #else
1.1.1.5   root     12781:     if (env->hflags & MIPS_HFLAG_BMASK) {
                   12782:         /* If the exception was raised from a delay slot,
1.1.1.7   root     12783:            come back to the jump.  */
                   12784:         env->CP0_ErrorEPC = env->active_tc.PC - 4;
1.1.1.5   root     12785:     } else {
1.1.1.7   root     12786:         env->CP0_ErrorEPC = env->active_tc.PC;
1.1.1.5   root     12787:     }
1.1.1.7   root     12788:     env->active_tc.PC = (int32_t)0xBFC00000;
1.1.1.9   root     12789:     env->CP0_Random = env->tlb->nb_tlb - 1;
                   12790:     env->tlb->tlb_in_use = env->tlb->nb_tlb;
1.1       root     12791:     env->CP0_Wired = 0;
1.1.1.13  root     12792:     env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
1.1.1.5   root     12793:     env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
1.1.1.6   root     12794:     /* vectored interrupts not implemented, timer on int 7,
                   12795:        no performance counters. */
                   12796:     env->CP0_IntCtl = 0xe0000000;
                   12797:     {
                   12798:         int i;
                   12799: 
                   12800:         for (i = 0; i < 7; i++) {
                   12801:             env->CP0_WatchLo[i] = 0;
                   12802:             env->CP0_WatchHi[i] = 0x80000000;
                   12803:         }
                   12804:         env->CP0_WatchLo[7] = 0;
                   12805:         env->CP0_WatchHi[7] = 0;
                   12806:     }
1.1       root     12807:     /* Count register increments in debug mode, EJTAG version 1 */
                   12808:     env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
1.1.1.6   root     12809:     env->hflags = MIPS_HFLAG_CP0;
1.1.1.15  root     12810: 
                   12811:     if (env->CP0_Config3 & (1 << CP0C3_MT)) {
                   12812:         int i;
                   12813: 
                   12814:         /* Only TC0 on VPE 0 starts as active.  */
                   12815:         for (i = 0; i < ARRAY_SIZE(env->tcs); i++) {
                   12816:             env->tcs[i].CP0_TCBind = env->cpu_index << CP0TCBd_CurVPE;
                   12817:             env->tcs[i].CP0_TCHalt = 1;
                   12818:         }
                   12819:         env->active_tc.CP0_TCHalt = 1;
                   12820:         env->halted = 1;
                   12821: 
                   12822:         if (!env->cpu_index) {
                   12823:             /* VPE0 starts up enabled.  */
                   12824:             env->mvp->CP0_MVPControl |= (1 << CP0MVPCo_EVP);
                   12825:             env->CP0_VPEConf0 |= (1 << CP0VPEC0_MVP) | (1 << CP0VPEC0_VPA);
                   12826: 
                   12827:             /* TC0 starts up unhalted.  */
                   12828:             env->halted = 0;
                   12829:             env->active_tc.CP0_TCHalt = 0;
                   12830:             env->tcs[0].CP0_TCHalt = 0;
                   12831:             /* With thread 0 active.  */
                   12832:             env->active_tc.CP0_TCStatus = (1 << CP0TCSt_A);
                   12833:             env->tcs[0].CP0_TCStatus = (1 << CP0TCSt_A);
                   12834:         }
                   12835:     }
1.1.1.2   root     12836: #endif
1.1.1.9   root     12837: #if defined(TARGET_MIPS64)
                   12838:     if (env->cpu_model->insn_flags & ISA_MIPS3) {
                   12839:         env->hflags |= MIPS_HFLAG_64;
                   12840:     }
                   12841: #endif
1.1.1.7   root     12842:     env->exception_index = EXCP_NONE;
1.1       root     12843: }
1.1.1.7   root     12844: 
1.1.1.16! root     12845: void restore_state_to_opc(CPUMIPSState *env, TranslationBlock *tb, int pc_pos)
1.1.1.7   root     12846: {
                   12847:     env->active_tc.PC = gen_opc_pc[pc_pos];
                   12848:     env->hflags &= ~MIPS_HFLAG_BMASK;
                   12849:     env->hflags |= gen_opc_hflags[pc_pos];
                   12850: }

unix.superglobalmegacorp.com

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