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

1.1       root        1: /*
                      2:  *  MIPS32 emulation for qemu: main translation routines.
1.1.1.6   root        3:  *
1.1       root        4:  *  Copyright (c) 2004-2005 Jocelyn Mayer
1.1.1.4   root        5:  *  Copyright (c) 2006 Marius Groeger (FPU operations)
1.1.1.5   root        6:  *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
1.1.1.12  root        7:  *  Copyright (c) 2009 CodeSourcery (MIPS16 and microMIPS support)
1.1       root        8:  *
                      9:  * This library is free software; you can redistribute it and/or
                     10:  * modify it under the terms of the GNU Lesser General Public
                     11:  * License as published by the Free Software Foundation; either
                     12:  * version 2 of the License, or (at your option) any later version.
                     13:  *
                     14:  * This library is distributed in the hope that it will be useful,
                     15:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     16:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     17:  * Lesser General Public License for more details.
                     18:  *
                     19:  * You should have received a copy of the GNU Lesser General Public
1.1.1.8   root       20:  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
1.1       root       21:  */
                     22: 
                     23: #include <stdarg.h>
                     24: #include <stdlib.h>
                     25: #include <stdio.h>
                     26: #include <string.h>
                     27: #include <inttypes.h>
                     28: 
                     29: #include "cpu.h"
                     30: #include "exec-all.h"
                     31: #include "disas.h"
1.1.1.7   root       32: #include "tcg-op.h"
                     33: #include "qemu-common.h"
                     34: 
                     35: #include "helper.h"
                     36: #define GEN_HELPER 1
                     37: #include "helper.h"
1.1       root       38: 
1.1.1.2   root       39: //#define MIPS_DEBUG_DISAS
1.1.1.5   root       40: //#define MIPS_DEBUG_SIGN_EXTENSIONS
1.1       root       41: 
1.1.1.5   root       42: /* MIPS major opcodes */
                     43: #define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
1.1       root       44: 
                     45: enum {
                     46:     /* indirect opcode tables */
1.1.1.5   root       47:     OPC_SPECIAL  = (0x00 << 26),
                     48:     OPC_REGIMM   = (0x01 << 26),
                     49:     OPC_CP0      = (0x10 << 26),
                     50:     OPC_CP1      = (0x11 << 26),
                     51:     OPC_CP2      = (0x12 << 26),
                     52:     OPC_CP3      = (0x13 << 26),
                     53:     OPC_SPECIAL2 = (0x1C << 26),
                     54:     OPC_SPECIAL3 = (0x1F << 26),
1.1       root       55:     /* arithmetic with immediate */
1.1.1.5   root       56:     OPC_ADDI     = (0x08 << 26),
                     57:     OPC_ADDIU    = (0x09 << 26),
                     58:     OPC_SLTI     = (0x0A << 26),
                     59:     OPC_SLTIU    = (0x0B << 26),
1.1.1.8   root       60:     /* logic with immediate */
1.1.1.5   root       61:     OPC_ANDI     = (0x0C << 26),
                     62:     OPC_ORI      = (0x0D << 26),
                     63:     OPC_XORI     = (0x0E << 26),
                     64:     OPC_LUI      = (0x0F << 26),
1.1.1.8   root       65:     /* arithmetic with immediate */
1.1.1.5   root       66:     OPC_DADDI    = (0x18 << 26),
                     67:     OPC_DADDIU   = (0x19 << 26),
1.1       root       68:     /* Jump and branches */
1.1.1.5   root       69:     OPC_J        = (0x02 << 26),
                     70:     OPC_JAL      = (0x03 << 26),
1.1.1.12  root       71:     OPC_JALS     = OPC_JAL | 0x5,
1.1.1.5   root       72:     OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
                     73:     OPC_BEQL     = (0x14 << 26),
                     74:     OPC_BNE      = (0x05 << 26),
                     75:     OPC_BNEL     = (0x15 << 26),
                     76:     OPC_BLEZ     = (0x06 << 26),
                     77:     OPC_BLEZL    = (0x16 << 26),
                     78:     OPC_BGTZ     = (0x07 << 26),
                     79:     OPC_BGTZL    = (0x17 << 26),
                     80:     OPC_JALX     = (0x1D << 26),  /* MIPS 16 only */
1.1.1.12  root       81:     OPC_JALXS    = OPC_JALX | 0x5,
1.1       root       82:     /* Load and stores */
1.1.1.5   root       83:     OPC_LDL      = (0x1A << 26),
                     84:     OPC_LDR      = (0x1B << 26),
                     85:     OPC_LB       = (0x20 << 26),
                     86:     OPC_LH       = (0x21 << 26),
                     87:     OPC_LWL      = (0x22 << 26),
                     88:     OPC_LW       = (0x23 << 26),
1.1.1.12  root       89:     OPC_LWPC     = OPC_LW | 0x5,
1.1.1.5   root       90:     OPC_LBU      = (0x24 << 26),
                     91:     OPC_LHU      = (0x25 << 26),
                     92:     OPC_LWR      = (0x26 << 26),
                     93:     OPC_LWU      = (0x27 << 26),
                     94:     OPC_SB       = (0x28 << 26),
                     95:     OPC_SH       = (0x29 << 26),
                     96:     OPC_SWL      = (0x2A << 26),
                     97:     OPC_SW       = (0x2B << 26),
                     98:     OPC_SDL      = (0x2C << 26),
                     99:     OPC_SDR      = (0x2D << 26),
                    100:     OPC_SWR      = (0x2E << 26),
                    101:     OPC_LL       = (0x30 << 26),
                    102:     OPC_LLD      = (0x34 << 26),
                    103:     OPC_LD       = (0x37 << 26),
1.1.1.12  root      104:     OPC_LDPC     = OPC_LD | 0x5,
1.1.1.5   root      105:     OPC_SC       = (0x38 << 26),
                    106:     OPC_SCD      = (0x3C << 26),
                    107:     OPC_SD       = (0x3F << 26),
1.1       root      108:     /* Floating point load/store */
1.1.1.5   root      109:     OPC_LWC1     = (0x31 << 26),
                    110:     OPC_LWC2     = (0x32 << 26),
                    111:     OPC_LDC1     = (0x35 << 26),
                    112:     OPC_LDC2     = (0x36 << 26),
                    113:     OPC_SWC1     = (0x39 << 26),
                    114:     OPC_SWC2     = (0x3A << 26),
                    115:     OPC_SDC1     = (0x3D << 26),
                    116:     OPC_SDC2     = (0x3E << 26),
                    117:     /* MDMX ASE specific */
                    118:     OPC_MDMX     = (0x1E << 26),
1.1       root      119:     /* Cache and prefetch */
1.1.1.5   root      120:     OPC_CACHE    = (0x2F << 26),
                    121:     OPC_PREF     = (0x33 << 26),
                    122:     /* Reserved major opcode */
                    123:     OPC_MAJOR3B_RESERVED = (0x3B << 26),
1.1       root      124: };
                    125: 
                    126: /* MIPS special opcodes */
1.1.1.5   root      127: #define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
                    128: 
1.1       root      129: enum {
                    130:     /* Shifts */
1.1.1.5   root      131:     OPC_SLL      = 0x00 | OPC_SPECIAL,
1.1       root      132:     /* NOP is SLL r0, r0, 0   */
                    133:     /* SSNOP is SLL r0, r0, 1 */
1.1.1.5   root      134:     /* EHB is SLL r0, r0, 3 */
                    135:     OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
1.1.1.12  root      136:     OPC_ROTR     = OPC_SRL | (1 << 21),
1.1.1.5   root      137:     OPC_SRA      = 0x03 | OPC_SPECIAL,
                    138:     OPC_SLLV     = 0x04 | OPC_SPECIAL,
1.1.1.6   root      139:     OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
1.1.1.12  root      140:     OPC_ROTRV    = OPC_SRLV | (1 << 6),
1.1.1.5   root      141:     OPC_SRAV     = 0x07 | OPC_SPECIAL,
                    142:     OPC_DSLLV    = 0x14 | OPC_SPECIAL,
                    143:     OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
1.1.1.12  root      144:     OPC_DROTRV   = OPC_DSRLV | (1 << 6),
1.1.1.5   root      145:     OPC_DSRAV    = 0x17 | OPC_SPECIAL,
                    146:     OPC_DSLL     = 0x38 | OPC_SPECIAL,
                    147:     OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
1.1.1.12  root      148:     OPC_DROTR    = OPC_DSRL | (1 << 21),
1.1.1.5   root      149:     OPC_DSRA     = 0x3B | OPC_SPECIAL,
                    150:     OPC_DSLL32   = 0x3C | OPC_SPECIAL,
                    151:     OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
1.1.1.12  root      152:     OPC_DROTR32  = OPC_DSRL32 | (1 << 21),
1.1.1.5   root      153:     OPC_DSRA32   = 0x3F | OPC_SPECIAL,
1.1       root      154:     /* Multiplication / division */
1.1.1.5   root      155:     OPC_MULT     = 0x18 | OPC_SPECIAL,
                    156:     OPC_MULTU    = 0x19 | OPC_SPECIAL,
                    157:     OPC_DIV      = 0x1A | OPC_SPECIAL,
                    158:     OPC_DIVU     = 0x1B | OPC_SPECIAL,
                    159:     OPC_DMULT    = 0x1C | OPC_SPECIAL,
                    160:     OPC_DMULTU   = 0x1D | OPC_SPECIAL,
                    161:     OPC_DDIV     = 0x1E | OPC_SPECIAL,
                    162:     OPC_DDIVU    = 0x1F | OPC_SPECIAL,
1.1       root      163:     /* 2 registers arithmetic / logic */
1.1.1.5   root      164:     OPC_ADD      = 0x20 | OPC_SPECIAL,
                    165:     OPC_ADDU     = 0x21 | OPC_SPECIAL,
                    166:     OPC_SUB      = 0x22 | OPC_SPECIAL,
                    167:     OPC_SUBU     = 0x23 | OPC_SPECIAL,
                    168:     OPC_AND      = 0x24 | OPC_SPECIAL,
                    169:     OPC_OR       = 0x25 | OPC_SPECIAL,
                    170:     OPC_XOR      = 0x26 | OPC_SPECIAL,
                    171:     OPC_NOR      = 0x27 | OPC_SPECIAL,
                    172:     OPC_SLT      = 0x2A | OPC_SPECIAL,
                    173:     OPC_SLTU     = 0x2B | OPC_SPECIAL,
                    174:     OPC_DADD     = 0x2C | OPC_SPECIAL,
                    175:     OPC_DADDU    = 0x2D | OPC_SPECIAL,
                    176:     OPC_DSUB     = 0x2E | OPC_SPECIAL,
                    177:     OPC_DSUBU    = 0x2F | OPC_SPECIAL,
1.1       root      178:     /* Jumps */
1.1.1.5   root      179:     OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
                    180:     OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
1.1.1.12  root      181:     OPC_JALRC    = OPC_JALR | (0x5 << 6),
                    182:     OPC_JALRS    = 0x10 | OPC_SPECIAL | (0x5 << 6),
1.1       root      183:     /* Traps */
1.1.1.5   root      184:     OPC_TGE      = 0x30 | OPC_SPECIAL,
                    185:     OPC_TGEU     = 0x31 | OPC_SPECIAL,
                    186:     OPC_TLT      = 0x32 | OPC_SPECIAL,
                    187:     OPC_TLTU     = 0x33 | OPC_SPECIAL,
                    188:     OPC_TEQ      = 0x34 | OPC_SPECIAL,
                    189:     OPC_TNE      = 0x36 | OPC_SPECIAL,
1.1       root      190:     /* HI / LO registers load & stores */
1.1.1.5   root      191:     OPC_MFHI     = 0x10 | OPC_SPECIAL,
                    192:     OPC_MTHI     = 0x11 | OPC_SPECIAL,
                    193:     OPC_MFLO     = 0x12 | OPC_SPECIAL,
                    194:     OPC_MTLO     = 0x13 | OPC_SPECIAL,
1.1       root      195:     /* Conditional moves */
1.1.1.5   root      196:     OPC_MOVZ     = 0x0A | OPC_SPECIAL,
                    197:     OPC_MOVN     = 0x0B | OPC_SPECIAL,
1.1       root      198: 
1.1.1.5   root      199:     OPC_MOVCI    = 0x01 | OPC_SPECIAL,
1.1       root      200: 
                    201:     /* Special */
1.1.1.9   root      202:     OPC_PMON     = 0x05 | OPC_SPECIAL, /* unofficial */
1.1.1.5   root      203:     OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
                    204:     OPC_BREAK    = 0x0D | OPC_SPECIAL,
1.1.1.9   root      205:     OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
1.1.1.5   root      206:     OPC_SYNC     = 0x0F | OPC_SPECIAL,
                    207: 
                    208:     OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
                    209:     OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
                    210:     OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
                    211:     OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
                    212:     OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
                    213:     OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
                    214:     OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
                    215: };
                    216: 
1.1.1.6   root      217: /* Multiplication variants of the vr54xx. */
                    218: #define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
                    219: 
                    220: enum {
                    221:     OPC_VR54XX_MULS    = (0x03 << 6) | OPC_MULT,
                    222:     OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,
                    223:     OPC_VR54XX_MACC    = (0x05 << 6) | OPC_MULT,
                    224:     OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,
                    225:     OPC_VR54XX_MSAC    = (0x07 << 6) | OPC_MULT,
                    226:     OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,
                    227:     OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,
                    228:     OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,
                    229:     OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,
                    230:     OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
                    231:     OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,
                    232:     OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
                    233:     OPC_VR54XX_MSACHI  = (0x0F << 6) | OPC_MULT,
                    234:     OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
                    235: };
                    236: 
1.1.1.5   root      237: /* REGIMM (rt field) opcodes */
                    238: #define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
                    239: 
                    240: enum {
                    241:     OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
                    242:     OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
                    243:     OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
                    244:     OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
                    245:     OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
1.1.1.12  root      246:     OPC_BLTZALS  = OPC_BLTZAL | 0x5, /* microMIPS */
1.1.1.5   root      247:     OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
                    248:     OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
1.1.1.12  root      249:     OPC_BGEZALS  = OPC_BGEZAL | 0x5, /* microMIPS */
1.1.1.5   root      250:     OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
                    251:     OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
                    252:     OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
                    253:     OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
                    254:     OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
                    255:     OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
                    256:     OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
                    257:     OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
1.1       root      258: };
                    259: 
1.1.1.5   root      260: /* Special2 opcodes */
                    261: #define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
                    262: 
1.1       root      263: enum {
1.1.1.5   root      264:     /* Multiply & xxx operations */
                    265:     OPC_MADD     = 0x00 | OPC_SPECIAL2,
                    266:     OPC_MADDU    = 0x01 | OPC_SPECIAL2,
                    267:     OPC_MUL      = 0x02 | OPC_SPECIAL2,
                    268:     OPC_MSUB     = 0x04 | OPC_SPECIAL2,
                    269:     OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
1.1.1.12  root      270:     /* Loongson 2F */
                    271:     OPC_MULT_G_2F   = 0x10 | OPC_SPECIAL2,
                    272:     OPC_DMULT_G_2F  = 0x11 | OPC_SPECIAL2,
                    273:     OPC_MULTU_G_2F  = 0x12 | OPC_SPECIAL2,
                    274:     OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
                    275:     OPC_DIV_G_2F    = 0x14 | OPC_SPECIAL2,
                    276:     OPC_DDIV_G_2F   = 0x15 | OPC_SPECIAL2,
                    277:     OPC_DIVU_G_2F   = 0x16 | OPC_SPECIAL2,
                    278:     OPC_DDIVU_G_2F  = 0x17 | OPC_SPECIAL2,
                    279:     OPC_MOD_G_2F    = 0x1c | OPC_SPECIAL2,
                    280:     OPC_DMOD_G_2F   = 0x1d | OPC_SPECIAL2,
                    281:     OPC_MODU_G_2F   = 0x1e | OPC_SPECIAL2,
                    282:     OPC_DMODU_G_2F  = 0x1f | OPC_SPECIAL2,
1.1       root      283:     /* Misc */
1.1.1.5   root      284:     OPC_CLZ      = 0x20 | OPC_SPECIAL2,
                    285:     OPC_CLO      = 0x21 | OPC_SPECIAL2,
                    286:     OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
                    287:     OPC_DCLO     = 0x25 | OPC_SPECIAL2,
1.1       root      288:     /* Special */
1.1.1.5   root      289:     OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
                    290: };
                    291: 
                    292: /* Special3 opcodes */
                    293: #define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
                    294: 
                    295: enum {
                    296:     OPC_EXT      = 0x00 | OPC_SPECIAL3,
                    297:     OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
                    298:     OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
                    299:     OPC_DEXT     = 0x03 | OPC_SPECIAL3,
                    300:     OPC_INS      = 0x04 | OPC_SPECIAL3,
                    301:     OPC_DINSM    = 0x05 | OPC_SPECIAL3,
                    302:     OPC_DINSU    = 0x06 | OPC_SPECIAL3,
                    303:     OPC_DINS     = 0x07 | OPC_SPECIAL3,
1.1.1.6   root      304:     OPC_FORK     = 0x08 | OPC_SPECIAL3,
                    305:     OPC_YIELD    = 0x09 | OPC_SPECIAL3,
1.1.1.5   root      306:     OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
                    307:     OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
                    308:     OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
1.1.1.12  root      309: 
                    310:     /* Loongson 2E */
                    311:     OPC_MULT_G_2E   = 0x18 | OPC_SPECIAL3,
                    312:     OPC_MULTU_G_2E  = 0x19 | OPC_SPECIAL3,
                    313:     OPC_DIV_G_2E    = 0x1A | OPC_SPECIAL3,
                    314:     OPC_DIVU_G_2E   = 0x1B | OPC_SPECIAL3,
                    315:     OPC_DMULT_G_2E  = 0x1C | OPC_SPECIAL3,
                    316:     OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
                    317:     OPC_DDIV_G_2E   = 0x1E | OPC_SPECIAL3,
                    318:     OPC_DDIVU_G_2E  = 0x1F | OPC_SPECIAL3,
                    319:     OPC_MOD_G_2E    = 0x22 | OPC_SPECIAL3,
                    320:     OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
                    321:     OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
                    322:     OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
1.1       root      323: };
                    324: 
1.1.1.5   root      325: /* BSHFL opcodes */
                    326: #define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
                    327: 
1.1       root      328: enum {
1.1.1.5   root      329:     OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
                    330:     OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
                    331:     OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
1.1       root      332: };
                    333: 
1.1.1.5   root      334: /* DBSHFL opcodes */
                    335: #define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
                    336: 
1.1       root      337: enum {
1.1.1.5   root      338:     OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
                    339:     OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
1.1       root      340: };
                    341: 
1.1.1.5   root      342: /* Coprocessor 0 (rs field) */
                    343: #define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
                    344: 
1.1.1.4   root      345: enum {
1.1.1.5   root      346:     OPC_MFC0     = (0x00 << 21) | OPC_CP0,
                    347:     OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
                    348:     OPC_MTC0     = (0x04 << 21) | OPC_CP0,
                    349:     OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
1.1.1.6   root      350:     OPC_MFTR     = (0x08 << 21) | OPC_CP0,
1.1.1.5   root      351:     OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
                    352:     OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
1.1.1.6   root      353:     OPC_MTTR     = (0x0C << 21) | OPC_CP0,
1.1.1.5   root      354:     OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
                    355:     OPC_C0       = (0x10 << 21) | OPC_CP0,
                    356:     OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
                    357:     OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,
1.1.1.4   root      358: };
1.1.1.5   root      359: 
                    360: /* MFMC0 opcodes */
1.1.1.6   root      361: #define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
1.1.1.5   root      362: 
                    363: enum {
1.1.1.6   root      364:     OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
                    365:     OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
                    366:     OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
                    367:     OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
1.1.1.5   root      368:     OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
                    369:     OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
                    370: };
                    371: 
                    372: /* Coprocessor 0 (with rs == C0) */
                    373: #define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
                    374: 
                    375: enum {
                    376:     OPC_TLBR     = 0x01 | OPC_C0,
                    377:     OPC_TLBWI    = 0x02 | OPC_C0,
                    378:     OPC_TLBWR    = 0x06 | OPC_C0,
                    379:     OPC_TLBP     = 0x08 | OPC_C0,
                    380:     OPC_RFE      = 0x10 | OPC_C0,
                    381:     OPC_ERET     = 0x18 | OPC_C0,
                    382:     OPC_DERET    = 0x1F | OPC_C0,
                    383:     OPC_WAIT     = 0x20 | OPC_C0,
                    384: };
                    385: 
                    386: /* Coprocessor 1 (rs field) */
                    387: #define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
                    388: 
1.1.1.12  root      389: /* Values for the fmt field in FP instructions */
                    390: enum {
                    391:     /* 0 - 15 are reserved */
                    392:     FMT_S = 16,          /* single fp */
                    393:     FMT_D = 17,          /* double fp */
                    394:     FMT_E = 18,          /* extended fp */
                    395:     FMT_Q = 19,          /* quad fp */
                    396:     FMT_W = 20,          /* 32-bit fixed */
                    397:     FMT_L = 21,          /* 64-bit fixed */
                    398:     FMT_PS = 22,         /* paired single fp */
                    399:     /* 23 - 31 are reserved */
                    400: };
                    401: 
1.1.1.5   root      402: enum {
                    403:     OPC_MFC1     = (0x00 << 21) | OPC_CP1,
                    404:     OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
                    405:     OPC_CFC1     = (0x02 << 21) | OPC_CP1,
1.1.1.6   root      406:     OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
1.1.1.5   root      407:     OPC_MTC1     = (0x04 << 21) | OPC_CP1,
                    408:     OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
                    409:     OPC_CTC1     = (0x06 << 21) | OPC_CP1,
1.1.1.6   root      410:     OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
1.1.1.5   root      411:     OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
1.1.1.6   root      412:     OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
                    413:     OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
1.1.1.12  root      414:     OPC_S_FMT    = (FMT_S << 21) | OPC_CP1,
                    415:     OPC_D_FMT    = (FMT_D << 21) | OPC_CP1,
                    416:     OPC_E_FMT    = (FMT_E << 21) | OPC_CP1,
                    417:     OPC_Q_FMT    = (FMT_Q << 21) | OPC_CP1,
                    418:     OPC_W_FMT    = (FMT_W << 21) | OPC_CP1,
                    419:     OPC_L_FMT    = (FMT_L << 21) | OPC_CP1,
                    420:     OPC_PS_FMT   = (FMT_PS << 21) | OPC_CP1,
1.1.1.5   root      421: };
                    422: 
1.1.1.6   root      423: #define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
                    424: #define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
                    425: 
1.1.1.5   root      426: enum {
                    427:     OPC_BC1F     = (0x00 << 16) | OPC_BC1,
                    428:     OPC_BC1T     = (0x01 << 16) | OPC_BC1,
                    429:     OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
                    430:     OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
                    431: };
                    432: 
1.1.1.6   root      433: enum {
                    434:     OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
                    435:     OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
                    436: };
                    437: 
                    438: enum {
                    439:     OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
                    440:     OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
                    441: };
1.1.1.5   root      442: 
                    443: #define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
1.1.1.6   root      444: 
                    445: enum {
                    446:     OPC_MFC2    = (0x00 << 21) | OPC_CP2,
                    447:     OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
                    448:     OPC_CFC2    = (0x02 << 21) | OPC_CP2,
                    449:     OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
                    450:     OPC_MTC2    = (0x04 << 21) | OPC_CP2,
                    451:     OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
                    452:     OPC_CTC2    = (0x06 << 21) | OPC_CP2,
                    453:     OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
                    454:     OPC_BC2     = (0x08 << 21) | OPC_CP2,
                    455: };
                    456: 
                    457: #define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
                    458: 
                    459: enum {
                    460:     OPC_LWXC1   = 0x00 | OPC_CP3,
                    461:     OPC_LDXC1   = 0x01 | OPC_CP3,
                    462:     OPC_LUXC1   = 0x05 | OPC_CP3,
                    463:     OPC_SWXC1   = 0x08 | OPC_CP3,
                    464:     OPC_SDXC1   = 0x09 | OPC_CP3,
                    465:     OPC_SUXC1   = 0x0D | OPC_CP3,
                    466:     OPC_PREFX   = 0x0F | OPC_CP3,
                    467:     OPC_ALNV_PS = 0x1E | OPC_CP3,
                    468:     OPC_MADD_S  = 0x20 | OPC_CP3,
                    469:     OPC_MADD_D  = 0x21 | OPC_CP3,
                    470:     OPC_MADD_PS = 0x26 | OPC_CP3,
                    471:     OPC_MSUB_S  = 0x28 | OPC_CP3,
                    472:     OPC_MSUB_D  = 0x29 | OPC_CP3,
                    473:     OPC_MSUB_PS = 0x2E | OPC_CP3,
                    474:     OPC_NMADD_S = 0x30 | OPC_CP3,
                    475:     OPC_NMADD_D = 0x31 | OPC_CP3,
                    476:     OPC_NMADD_PS= 0x36 | OPC_CP3,
                    477:     OPC_NMSUB_S = 0x38 | OPC_CP3,
                    478:     OPC_NMSUB_D = 0x39 | OPC_CP3,
                    479:     OPC_NMSUB_PS= 0x3E | OPC_CP3,
                    480: };
                    481: 
1.1.1.7   root      482: /* global register indices */
                    483: static TCGv_ptr cpu_env;
                    484: static TCGv cpu_gpr[32], cpu_PC;
                    485: static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
1.1.1.8   root      486: static TCGv cpu_dspctrl, btarget, bcond;
                    487: static TCGv_i32 hflags;
1.1.1.7   root      488: static TCGv_i32 fpu_fcr0, fpu_fcr31;
                    489: 
1.1.1.12  root      490: static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
                    491: 
1.1.1.7   root      492: #include "gen-icount.h"
                    493: 
                    494: #define gen_helper_0i(name, arg) do {                             \
                    495:     TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
                    496:     gen_helper_##name(helper_tmp);                                \
                    497:     tcg_temp_free_i32(helper_tmp);                                \
                    498:     } while(0)
1.1.1.4   root      499: 
1.1.1.7   root      500: #define gen_helper_1i(name, arg1, arg2) do {                      \
                    501:     TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
                    502:     gen_helper_##name(arg1, helper_tmp);                          \
                    503:     tcg_temp_free_i32(helper_tmp);                                \
                    504:     } while(0)
1.1.1.4   root      505: 
1.1.1.7   root      506: #define gen_helper_2i(name, arg1, arg2, arg3) do {                \
                    507:     TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
                    508:     gen_helper_##name(arg1, arg2, helper_tmp);                    \
                    509:     tcg_temp_free_i32(helper_tmp);                                \
                    510:     } while(0)
1.1.1.4   root      511: 
1.1.1.7   root      512: #define gen_helper_3i(name, arg1, arg2, arg3, arg4) do {          \
                    513:     TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
                    514:     gen_helper_##name(arg1, arg2, arg3, helper_tmp);              \
                    515:     tcg_temp_free_i32(helper_tmp);                                \
                    516:     } while(0)
1.1.1.4   root      517: 
1.1       root      518: typedef struct DisasContext {
                    519:     struct TranslationBlock *tb;
                    520:     target_ulong pc, saved_pc;
                    521:     uint32_t opcode;
1.1.1.9   root      522:     int singlestep_enabled;
1.1       root      523:     /* Routine used to access memory */
                    524:     int mem_idx;
                    525:     uint32_t hflags, saved_hflags;
                    526:     int bstate;
                    527:     target_ulong btarget;
                    528: } DisasContext;
                    529: 
                    530: enum {
                    531:     BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
1.1.1.7   root      532:                       * exception condition */
1.1       root      533:     BS_STOP     = 1, /* We want to stop translation for any reason */
                    534:     BS_BRANCH   = 2, /* We reached a branch condition     */
                    535:     BS_EXCP     = 3, /* We reached an exception condition */
                    536: };
                    537: 
1.1.1.7   root      538: static const char *regnames[] =
                    539:     { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
                    540:       "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
                    541:       "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
                    542:       "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
                    543: 
                    544: static const char *regnames_HI[] =
                    545:     { "HI0", "HI1", "HI2", "HI3", };
                    546: 
                    547: static const char *regnames_LO[] =
                    548:     { "LO0", "LO1", "LO2", "LO3", };
                    549: 
                    550: static const char *regnames_ACX[] =
                    551:     { "ACX0", "ACX1", "ACX2", "ACX3", };
                    552: 
                    553: static const char *fregnames[] =
                    554:     { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
                    555:       "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
                    556:       "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
                    557:       "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
                    558: 
1.1.1.6   root      559: #ifdef MIPS_DEBUG_DISAS
1.1.1.8   root      560: #define MIPS_DEBUG(fmt, ...)                         \
1.1.1.7   root      561:         qemu_log_mask(CPU_LOG_TB_IN_ASM,                \
                    562:                        TARGET_FMT_lx ": %08x " fmt "\n", \
1.1.1.8   root      563:                        ctx->pc, ctx->opcode , ## __VA_ARGS__)
1.1.1.7   root      564: #define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
1.1       root      565: #else
1.1.1.8   root      566: #define MIPS_DEBUG(fmt, ...) do { } while(0)
1.1.1.7   root      567: #define LOG_DISAS(...) do { } while (0)
1.1       root      568: #endif
                    569: 
                    570: #define MIPS_INVAL(op)                                                        \
                    571: do {                                                                          \
                    572:     MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
                    573:                ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
                    574: } while (0)
                    575: 
1.1.1.7   root      576: /* General purpose registers moves. */
                    577: static inline void gen_load_gpr (TCGv t, int reg)
                    578: {
                    579:     if (reg == 0)
                    580:         tcg_gen_movi_tl(t, 0);
                    581:     else
                    582:         tcg_gen_mov_tl(t, cpu_gpr[reg]);
                    583: }
1.1.1.6   root      584: 
1.1.1.7   root      585: static inline void gen_store_gpr (TCGv t, int reg)
                    586: {
                    587:     if (reg != 0)
                    588:         tcg_gen_mov_tl(cpu_gpr[reg], t);
                    589: }
1.1.1.6   root      590: 
1.1.1.7   root      591: /* Moves to/from ACX register.  */
                    592: static inline void gen_load_ACX (TCGv t, int reg)
                    593: {
                    594:     tcg_gen_mov_tl(t, cpu_ACX[reg]);
                    595: }
1.1.1.6   root      596: 
1.1.1.7   root      597: static inline void gen_store_ACX (TCGv t, int reg)
                    598: {
                    599:     tcg_gen_mov_tl(cpu_ACX[reg], t);
                    600: }
1.1       root      601: 
1.1.1.7   root      602: /* Moves to/from shadow registers. */
                    603: static inline void gen_load_srsgpr (int from, int to)
                    604: {
1.1.1.8   root      605:     TCGv t0 = tcg_temp_new();
1.1.1.6   root      606: 
1.1.1.7   root      607:     if (from == 0)
1.1.1.8   root      608:         tcg_gen_movi_tl(t0, 0);
1.1.1.7   root      609:     else {
1.1.1.8   root      610:         TCGv_i32 t2 = tcg_temp_new_i32();
1.1.1.7   root      611:         TCGv_ptr addr = tcg_temp_new_ptr();
1.1.1.6   root      612: 
1.1.1.8   root      613:         tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
                    614:         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
                    615:         tcg_gen_andi_i32(t2, t2, 0xf);
                    616:         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
                    617:         tcg_gen_ext_i32_ptr(addr, t2);
1.1.1.7   root      618:         tcg_gen_add_ptr(addr, cpu_env, addr);
1.1       root      619: 
1.1.1.8   root      620:         tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1.1.1.7   root      621:         tcg_temp_free_ptr(addr);
1.1.1.8   root      622:         tcg_temp_free_i32(t2);
1.1.1.7   root      623:     }
1.1.1.8   root      624:     gen_store_gpr(t0, to);
                    625:     tcg_temp_free(t0);
1.1.1.7   root      626: }
1.1       root      627: 
1.1.1.7   root      628: static inline void gen_store_srsgpr (int from, int to)
                    629: {
                    630:     if (to != 0) {
1.1.1.8   root      631:         TCGv t0 = tcg_temp_new();
                    632:         TCGv_i32 t2 = tcg_temp_new_i32();
1.1.1.7   root      633:         TCGv_ptr addr = tcg_temp_new_ptr();
1.1.1.4   root      634: 
1.1.1.8   root      635:         gen_load_gpr(t0, from);
                    636:         tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
                    637:         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
                    638:         tcg_gen_andi_i32(t2, t2, 0xf);
                    639:         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
                    640:         tcg_gen_ext_i32_ptr(addr, t2);
1.1.1.7   root      641:         tcg_gen_add_ptr(addr, cpu_env, addr);
1.1.1.4   root      642: 
1.1.1.8   root      643:         tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1.1.1.7   root      644:         tcg_temp_free_ptr(addr);
1.1.1.8   root      645:         tcg_temp_free_i32(t2);
                    646:         tcg_temp_free(t0);
1.1.1.6   root      647:     }
                    648: }
                    649: 
1.1.1.7   root      650: /* Floating point register moves. */
                    651: static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
1.1.1.6   root      652: {
1.1.1.8   root      653:     tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
1.1.1.7   root      654: }
                    655: 
                    656: static inline void gen_store_fpr32 (TCGv_i32 t, int reg)
                    657: {
1.1.1.8   root      658:     tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
1.1.1.7   root      659: }
                    660: 
1.1.1.8   root      661: static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
1.1.1.7   root      662: {
1.1.1.8   root      663:     tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
1.1.1.6   root      664: }
                    665: 
1.1.1.8   root      666: static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
1.1       root      667: {
1.1.1.8   root      668:     tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
1.1.1.7   root      669: }
                    670: 
1.1.1.8   root      671: static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
1.1.1.7   root      672: {
1.1.1.8   root      673:     if (ctx->hflags & MIPS_HFLAG_F64) {
                    674:         tcg_gen_ld_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
                    675:     } else {
                    676:         TCGv_i32 t0 = tcg_temp_new_i32();
                    677:         TCGv_i32 t1 = tcg_temp_new_i32();
                    678:         gen_load_fpr32(t0, reg & ~1);
                    679:         gen_load_fpr32(t1, reg | 1);
                    680:         tcg_gen_concat_i32_i64(t, t0, t1);
                    681:         tcg_temp_free_i32(t0);
                    682:         tcg_temp_free_i32(t1);
                    683:     }
1.1.1.7   root      684: }
                    685: 
1.1.1.8   root      686: static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
1.1.1.7   root      687: {
1.1.1.8   root      688:     if (ctx->hflags & MIPS_HFLAG_F64) {
                    689:         tcg_gen_st_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
                    690:     } else {
                    691:         TCGv_i64 t0 = tcg_temp_new_i64();
                    692:         TCGv_i32 t1 = tcg_temp_new_i32();
                    693:         tcg_gen_trunc_i64_i32(t1, t);
                    694:         gen_store_fpr32(t1, reg & ~1);
                    695:         tcg_gen_shri_i64(t0, t, 32);
                    696:         tcg_gen_trunc_i64_i32(t1, t0);
                    697:         gen_store_fpr32(t1, reg | 1);
                    698:         tcg_temp_free_i32(t1);
                    699:         tcg_temp_free_i64(t0);
                    700:     }
1.1.1.7   root      701: }
                    702: 
1.1.1.8   root      703: static inline int get_fp_bit (int cc)
1.1.1.7   root      704: {
1.1.1.8   root      705:     if (cc)
                    706:         return 24 + cc;
                    707:     else
                    708:         return 23;
1.1.1.7   root      709: }
                    710: 
                    711: /* Tests */
                    712: static inline void gen_save_pc(target_ulong pc)
                    713: {
                    714:     tcg_gen_movi_tl(cpu_PC, pc);
                    715: }
                    716: 
                    717: static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
                    718: {
                    719:     LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1.1       root      720:     if (do_save_pc && ctx->pc != ctx->saved_pc) {
1.1.1.6   root      721:         gen_save_pc(ctx->pc);
1.1       root      722:         ctx->saved_pc = ctx->pc;
                    723:     }
                    724:     if (ctx->hflags != ctx->saved_hflags) {
1.1.1.8   root      725:         tcg_gen_movi_i32(hflags, ctx->hflags);
1.1       root      726:         ctx->saved_hflags = ctx->hflags;
1.1.1.12  root      727:         switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1.1.1.6   root      728:         case MIPS_HFLAG_BR:
                    729:             break;
                    730:         case MIPS_HFLAG_BC:
                    731:         case MIPS_HFLAG_BL:
                    732:         case MIPS_HFLAG_B:
1.1.1.7   root      733:             tcg_gen_movi_tl(btarget, ctx->btarget);
1.1.1.6   root      734:             break;
1.1       root      735:         }
                    736:     }
                    737: }
                    738: 
1.1.1.7   root      739: static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
1.1.1.6   root      740: {
                    741:     ctx->saved_hflags = ctx->hflags;
1.1.1.12  root      742:     switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1.1.1.6   root      743:     case MIPS_HFLAG_BR:
                    744:         break;
                    745:     case MIPS_HFLAG_BC:
                    746:     case MIPS_HFLAG_BL:
1.1.1.7   root      747:     case MIPS_HFLAG_B:
1.1.1.6   root      748:         ctx->btarget = env->btarget;
                    749:         break;
                    750:     }
                    751: }
                    752: 
1.1.1.7   root      753: static inline void
                    754: generate_exception_err (DisasContext *ctx, int excp, int err)
1.1       root      755: {
1.1.1.7   root      756:     TCGv_i32 texcp = tcg_const_i32(excp);
                    757:     TCGv_i32 terr = tcg_const_i32(err);
1.1       root      758:     save_cpu_state(ctx, 1);
1.1.1.7   root      759:     gen_helper_raise_exception_err(texcp, terr);
                    760:     tcg_temp_free_i32(terr);
                    761:     tcg_temp_free_i32(texcp);
                    762: }
                    763: 
                    764: static inline void
                    765: generate_exception (DisasContext *ctx, int excp)
                    766: {
                    767:     save_cpu_state(ctx, 1);
                    768:     gen_helper_0i(raise_exception, excp);
1.1       root      769: }
                    770: 
1.1.1.7   root      771: /* Addresses computation */
1.1.1.9   root      772: static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1.1.1.2   root      773: {
1.1.1.9   root      774:     tcg_gen_add_tl(ret, arg0, arg1);
1.1.1.7   root      775: 
                    776: #if defined(TARGET_MIPS64)
                    777:     /* For compatibility with 32-bit code, data reference in user mode
                    778:        with Status_UX = 0 should be casted to 32-bit and sign extended.
                    779:        See the MIPS64 PRA manual, section 4.10. */
                    780:     if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
                    781:         !(ctx->hflags & MIPS_HFLAG_UX)) {
1.1.1.9   root      782:         tcg_gen_ext32s_i64(ret, ret);
1.1.1.7   root      783:     }
                    784: #endif
1.1.1.2   root      785: }
                    786: 
1.1.1.7   root      787: static inline void check_cp0_enabled(DisasContext *ctx)
1.1.1.6   root      788: {
                    789:     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1.1.1.10  root      790:         generate_exception_err(ctx, EXCP_CpU, 0);
1.1.1.6   root      791: }
                    792: 
1.1.1.7   root      793: static inline void check_cp1_enabled(DisasContext *ctx)
1.1.1.6   root      794: {
                    795:     if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
                    796:         generate_exception_err(ctx, EXCP_CpU, 1);
                    797: }
                    798: 
                    799: /* Verify that the processor is running with COP1X instructions enabled.
                    800:    This is associated with the nabla symbol in the MIPS32 and MIPS64
                    801:    opcode tables.  */
                    802: 
1.1.1.7   root      803: static inline void check_cop1x(DisasContext *ctx)
1.1.1.6   root      804: {
                    805:     if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
                    806:         generate_exception(ctx, EXCP_RI);
                    807: }
                    808: 
                    809: /* Verify that the processor is running with 64-bit floating-point
                    810:    operations enabled.  */
                    811: 
1.1.1.7   root      812: static inline void check_cp1_64bitmode(DisasContext *ctx)
1.1.1.6   root      813: {
                    814:     if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
                    815:         generate_exception(ctx, EXCP_RI);
                    816: }
                    817: 
                    818: /*
                    819:  * Verify if floating point register is valid; an operation is not defined
                    820:  * if bit 0 of any register specification is set and the FR bit in the
                    821:  * Status register equals zero, since the register numbers specify an
                    822:  * even-odd pair of adjacent coprocessor general registers. When the FR bit
                    823:  * in the Status register equals one, both even and odd register numbers
                    824:  * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
                    825:  *
                    826:  * Multiple 64 bit wide registers can be checked by calling
                    827:  * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
                    828:  */
1.1.1.7   root      829: static inline void check_cp1_registers(DisasContext *ctx, int regs)
1.1.1.6   root      830: {
                    831:     if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
                    832:         generate_exception(ctx, EXCP_RI);
                    833: }
                    834: 
                    835: /* This code generates a "reserved instruction" exception if the
                    836:    CPU does not support the instruction set corresponding to flags. */
1.1.1.7   root      837: static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
1.1.1.6   root      838: {
                    839:     if (unlikely(!(env->insn_flags & flags)))
                    840:         generate_exception(ctx, EXCP_RI);
                    841: }
                    842: 
                    843: /* This code generates a "reserved instruction" exception if 64-bit
                    844:    instructions are not enabled. */
1.1.1.7   root      845: static inline void check_mips_64(DisasContext *ctx)
1.1.1.6   root      846: {
                    847:     if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
                    848:         generate_exception(ctx, EXCP_RI);
                    849: }
                    850: 
1.1.1.12  root      851: /* Define small wrappers for gen_load_fpr* so that we have a uniform
                    852:    calling interface for 32 and 64-bit FPRs.  No sense in changing
                    853:    all callers for gen_load_fpr32 when we need the CTX parameter for
                    854:    this one use.  */
                    855: #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
                    856: #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
                    857: #define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
                    858: static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
                    859:                                                int ft, int fs, int cc)        \
                    860: {                                                                             \
                    861:     TCGv_i##bits fp0 = tcg_temp_new_i##bits ();                               \
                    862:     TCGv_i##bits fp1 = tcg_temp_new_i##bits ();                               \
                    863:     switch (ifmt) {                                                           \
                    864:     case FMT_PS:                                                              \
                    865:         check_cp1_64bitmode(ctx);                                             \
                    866:         break;                                                                \
                    867:     case FMT_D:                                                               \
                    868:         if (abs) {                                                            \
                    869:             check_cop1x(ctx);                                                 \
                    870:         }                                                                     \
                    871:         check_cp1_registers(ctx, fs | ft);                                    \
                    872:         break;                                                                \
                    873:     case FMT_S:                                                               \
                    874:         if (abs) {                                                            \
                    875:             check_cop1x(ctx);                                                 \
                    876:         }                                                                     \
                    877:         break;                                                                \
                    878:     }                                                                         \
                    879:     gen_ldcmp_fpr##bits (ctx, fp0, fs);                                       \
                    880:     gen_ldcmp_fpr##bits (ctx, fp1, ft);                                       \
                    881:     switch (n) {                                                              \
                    882:     case  0: gen_helper_2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);    break;\
                    883:     case  1: gen_helper_2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);   break;\
                    884:     case  2: gen_helper_2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);   break;\
                    885:     case  3: gen_helper_2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);  break;\
                    886:     case  4: gen_helper_2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);  break;\
                    887:     case  5: gen_helper_2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);  break;\
                    888:     case  6: gen_helper_2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);  break;\
                    889:     case  7: gen_helper_2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);  break;\
                    890:     case  8: gen_helper_2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);   break;\
                    891:     case  9: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
                    892:     case 10: gen_helper_2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);  break;\
                    893:     case 11: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);  break;\
                    894:     case 12: gen_helper_2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);   break;\
                    895:     case 13: gen_helper_2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);  break;\
                    896:     case 14: gen_helper_2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);   break;\
                    897:     case 15: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);  break;\
                    898:     default: abort();                                                         \
                    899:     }                                                                         \
                    900:     tcg_temp_free_i##bits (fp0);                                              \
                    901:     tcg_temp_free_i##bits (fp1);                                              \
                    902: }
                    903: 
                    904: FOP_CONDS(, 0, d, FMT_D, 64)
                    905: FOP_CONDS(abs, 1, d, FMT_D, 64)
                    906: FOP_CONDS(, 0, s, FMT_S, 32)
                    907: FOP_CONDS(abs, 1, s, FMT_S, 32)
                    908: FOP_CONDS(, 0, ps, FMT_PS, 64)
                    909: FOP_CONDS(abs, 1, ps, FMT_PS, 64)
                    910: #undef FOP_CONDS
                    911: #undef gen_ldcmp_fpr32
                    912: #undef gen_ldcmp_fpr64
                    913: 
1.1.1.7   root      914: /* load/store instructions. */
1.1.1.8   root      915: #define OP_LD(insn,fname)                                                 \
1.1.1.12  root      916: static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)   \
1.1.1.8   root      917: {                                                                         \
                    918:     tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                        \
1.1.1.7   root      919: }
                    920: OP_LD(lb,ld8s);
                    921: OP_LD(lbu,ld8u);
                    922: OP_LD(lh,ld16s);
                    923: OP_LD(lhu,ld16u);
                    924: OP_LD(lw,ld32s);
                    925: #if defined(TARGET_MIPS64)
                    926: OP_LD(lwu,ld32u);
                    927: OP_LD(ld,ld64);
                    928: #endif
                    929: #undef OP_LD
                    930: 
1.1.1.8   root      931: #define OP_ST(insn,fname)                                                  \
1.1.1.12  root      932: static inline void op_st_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx)   \
1.1.1.8   root      933: {                                                                          \
                    934:     tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx);                        \
1.1.1.7   root      935: }
                    936: OP_ST(sb,st8);
                    937: OP_ST(sh,st16);
                    938: OP_ST(sw,st32);
                    939: #if defined(TARGET_MIPS64)
                    940: OP_ST(sd,st64);
                    941: #endif
                    942: #undef OP_ST
                    943: 
1.1.1.9   root      944: #ifdef CONFIG_USER_ONLY
1.1.1.8   root      945: #define OP_LD_ATOMIC(insn,fname)                                           \
1.1.1.12  root      946: static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
1.1.1.8   root      947: {                                                                          \
                    948:     TCGv t0 = tcg_temp_new();                                              \
                    949:     tcg_gen_mov_tl(t0, arg1);                                              \
                    950:     tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
1.1.1.9   root      951:     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, lladdr));                \
1.1.1.8   root      952:     tcg_gen_st_tl(ret, cpu_env, offsetof(CPUState, llval));                \
                    953:     tcg_temp_free(t0);                                                     \
1.1       root      954: }
1.1.1.9   root      955: #else
                    956: #define OP_LD_ATOMIC(insn,fname)                                           \
1.1.1.12  root      957: static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
1.1.1.9   root      958: {                                                                          \
                    959:     gen_helper_2i(insn, ret, arg1, ctx->mem_idx);                          \
                    960: }
                    961: #endif
1.1.1.7   root      962: OP_LD_ATOMIC(ll,ld32s);
                    963: #if defined(TARGET_MIPS64)
                    964: OP_LD_ATOMIC(lld,ld64);
1.1       root      965: #endif
1.1.1.7   root      966: #undef OP_LD_ATOMIC
1.1       root      967: 
1.1.1.8   root      968: #ifdef CONFIG_USER_ONLY
                    969: #define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
1.1.1.12  root      970: static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1.1.1.8   root      971: {                                                                            \
                    972:     TCGv t0 = tcg_temp_new();                                                \
                    973:     int l1 = gen_new_label();                                                \
                    974:     int l2 = gen_new_label();                                                \
                    975:                                                                              \
                    976:     tcg_gen_andi_tl(t0, arg2, almask);                                       \
                    977:     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                              \
                    978:     tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUState, CP0_BadVAddr));          \
                    979:     generate_exception(ctx, EXCP_AdES);                                      \
                    980:     gen_set_label(l1);                                                       \
1.1.1.9   root      981:     tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, lladdr));                  \
1.1.1.8   root      982:     tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                            \
                    983:     tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20));                        \
                    984:     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, llreg));                   \
                    985:     tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUState, llnewval));              \
                    986:     gen_helper_0i(raise_exception, EXCP_SC);                                 \
                    987:     gen_set_label(l2);                                                       \
                    988:     tcg_gen_movi_tl(t0, 0);                                                  \
                    989:     gen_store_gpr(t0, rt);                                                   \
                    990:     tcg_temp_free(t0);                                                       \
                    991: }
                    992: #else
                    993: #define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
1.1.1.12  root      994: static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1.1.1.8   root      995: {                                                                            \
                    996:     TCGv t0 = tcg_temp_new();                                                \
1.1.1.9   root      997:     gen_helper_3i(insn, t0, arg1, arg2, ctx->mem_idx);                       \
1.1.1.8   root      998:     gen_store_gpr(t0, rt);                                                   \
                    999:     tcg_temp_free(t0);                                                       \
1.1.1.7   root     1000: }
1.1.1.8   root     1001: #endif
                   1002: OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1.1.1.6   root     1003: #if defined(TARGET_MIPS64)
1.1.1.8   root     1004: OP_ST_ATOMIC(scd,st64,ld64,0x7);
1.1       root     1005: #endif
1.1.1.7   root     1006: #undef OP_ST_ATOMIC
1.1       root     1007: 
1.1.1.12  root     1008: static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
                   1009:                                   int base, int16_t offset)
1.1       root     1010: {
                   1011:     if (base == 0) {
1.1.1.12  root     1012:         tcg_gen_movi_tl(addr, offset);
1.1       root     1013:     } else if (offset == 0) {
1.1.1.12  root     1014:         gen_load_gpr(addr, base);
1.1       root     1015:     } else {
1.1.1.12  root     1016:         tcg_gen_movi_tl(addr, offset);
                   1017:         gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1.1       root     1018:     }
1.1.1.12  root     1019: }
                   1020: 
                   1021: static target_ulong pc_relative_pc (DisasContext *ctx)
                   1022: {
                   1023:     target_ulong pc = ctx->pc;
                   1024: 
                   1025:     if (ctx->hflags & MIPS_HFLAG_BMASK) {
                   1026:         int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
                   1027: 
                   1028:         pc -= branch_bytes;
                   1029:     }
                   1030: 
                   1031:     pc &= ~(target_ulong)3;
                   1032:     return pc;
                   1033: }
                   1034: 
                   1035: /* Load */
                   1036: static void gen_ld (CPUState *env, DisasContext *ctx, uint32_t opc,
                   1037:                     int rt, int base, int16_t offset)
                   1038: {
                   1039:     const char *opn = "ld";
                   1040:     TCGv t0, t1;
                   1041: 
                   1042:     if (rt == 0 && env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
                   1043:         /* Loongson CPU uses a load to zero register for prefetch.
                   1044:            We emulate it as a NOP. On other CPU we must perform the
                   1045:            actual memory access. */
                   1046:         MIPS_DEBUG("NOP");
                   1047:         return;
                   1048:     }
                   1049: 
                   1050:     t0 = tcg_temp_new();
                   1051:     t1 = tcg_temp_new();
                   1052:     gen_base_offset_addr(ctx, t0, base, offset);
                   1053: 
1.1       root     1054:     switch (opc) {
1.1.1.6   root     1055: #if defined(TARGET_MIPS64)
                   1056:     case OPC_LWU:
1.1.1.8   root     1057:         save_cpu_state(ctx, 0);
1.1.1.12  root     1058:         op_ld_lwu(t0, t0, ctx);
1.1.1.7   root     1059:         gen_store_gpr(t0, rt);
1.1.1.6   root     1060:         opn = "lwu";
                   1061:         break;
1.1       root     1062:     case OPC_LD:
1.1.1.8   root     1063:         save_cpu_state(ctx, 0);
1.1.1.12  root     1064:         op_ld_ld(t0, t0, ctx);
1.1.1.7   root     1065:         gen_store_gpr(t0, rt);
1.1       root     1066:         opn = "ld";
                   1067:         break;
1.1.1.5   root     1068:     case OPC_LLD:
1.1.1.13! root     1069:         save_cpu_state(ctx, 1);
1.1.1.12  root     1070:         op_ld_lld(t0, t0, ctx);
1.1.1.7   root     1071:         gen_store_gpr(t0, rt);
1.1.1.5   root     1072:         opn = "lld";
                   1073:         break;
1.1       root     1074:     case OPC_LDL:
1.1.1.7   root     1075:         save_cpu_state(ctx, 1);
                   1076:         gen_load_gpr(t1, rt);
1.1.1.8   root     1077:         gen_helper_3i(ldl, t1, t1, t0, ctx->mem_idx);
1.1.1.7   root     1078:         gen_store_gpr(t1, rt);
1.1       root     1079:         opn = "ldl";
                   1080:         break;
                   1081:     case OPC_LDR:
1.1.1.7   root     1082:         save_cpu_state(ctx, 1);
                   1083:         gen_load_gpr(t1, rt);
1.1.1.8   root     1084:         gen_helper_3i(ldr, t1, t1, t0, ctx->mem_idx);
1.1.1.7   root     1085:         gen_store_gpr(t1, rt);
1.1       root     1086:         opn = "ldr";
                   1087:         break;
1.1.1.12  root     1088:     case OPC_LDPC:
1.1.1.13! root     1089:         save_cpu_state(ctx, 0);
1.1.1.12  root     1090:         tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
                   1091:         gen_op_addr_add(ctx, t0, t0, t1);
                   1092:         op_ld_ld(t0, t0, ctx);
                   1093:         gen_store_gpr(t0, rt);
                   1094:         opn = "ldpc";
1.1       root     1095:         break;
                   1096: #endif
1.1.1.12  root     1097:     case OPC_LWPC:
1.1.1.13! root     1098:         save_cpu_state(ctx, 0);
1.1.1.12  root     1099:         tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
                   1100:         gen_op_addr_add(ctx, t0, t0, t1);
                   1101:         op_ld_lw(t0, t0, ctx);
                   1102:         gen_store_gpr(t0, rt);
                   1103:         opn = "lwpc";
                   1104:         break;
1.1       root     1105:     case OPC_LW:
1.1.1.8   root     1106:         save_cpu_state(ctx, 0);
1.1.1.12  root     1107:         op_ld_lw(t0, t0, ctx);
1.1.1.7   root     1108:         gen_store_gpr(t0, rt);
1.1       root     1109:         opn = "lw";
                   1110:         break;
                   1111:     case OPC_LH:
1.1.1.8   root     1112:         save_cpu_state(ctx, 0);
1.1.1.12  root     1113:         op_ld_lh(t0, t0, ctx);
1.1.1.7   root     1114:         gen_store_gpr(t0, rt);
1.1       root     1115:         opn = "lh";
                   1116:         break;
                   1117:     case OPC_LHU:
1.1.1.8   root     1118:         save_cpu_state(ctx, 0);
1.1.1.12  root     1119:         op_ld_lhu(t0, t0, ctx);
1.1.1.7   root     1120:         gen_store_gpr(t0, rt);
1.1       root     1121:         opn = "lhu";
                   1122:         break;
                   1123:     case OPC_LB:
1.1.1.8   root     1124:         save_cpu_state(ctx, 0);
1.1.1.12  root     1125:         op_ld_lb(t0, t0, ctx);
1.1.1.7   root     1126:         gen_store_gpr(t0, rt);
1.1       root     1127:         opn = "lb";
                   1128:         break;
                   1129:     case OPC_LBU:
1.1.1.8   root     1130:         save_cpu_state(ctx, 0);
1.1.1.12  root     1131:         op_ld_lbu(t0, t0, ctx);
1.1.1.7   root     1132:         gen_store_gpr(t0, rt);
1.1       root     1133:         opn = "lbu";
                   1134:         break;
                   1135:     case OPC_LWL:
1.1.1.7   root     1136:         save_cpu_state(ctx, 1);
                   1137:         gen_load_gpr(t1, rt);
1.1.1.8   root     1138:         gen_helper_3i(lwl, t1, t1, t0, ctx->mem_idx);
1.1.1.7   root     1139:         gen_store_gpr(t1, rt);
1.1       root     1140:         opn = "lwl";
                   1141:         break;
                   1142:     case OPC_LWR:
1.1.1.7   root     1143:         save_cpu_state(ctx, 1);
                   1144:         gen_load_gpr(t1, rt);
1.1.1.8   root     1145:         gen_helper_3i(lwr, t1, t1, t0, ctx->mem_idx);
1.1.1.7   root     1146:         gen_store_gpr(t1, rt);
1.1       root     1147:         opn = "lwr";
                   1148:         break;
                   1149:     case OPC_LL:
1.1.1.9   root     1150:         save_cpu_state(ctx, 1);
1.1.1.12  root     1151:         op_ld_ll(t0, t0, ctx);
1.1.1.7   root     1152:         gen_store_gpr(t0, rt);
1.1       root     1153:         opn = "ll";
                   1154:         break;
1.1.1.8   root     1155:     }
1.1.1.13! root     1156:     (void)opn; /* avoid a compiler warning */
1.1.1.8   root     1157:     MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
                   1158:     tcg_temp_free(t0);
                   1159:     tcg_temp_free(t1);
                   1160: }
                   1161: 
1.1.1.12  root     1162: /* Store */
                   1163: static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
                   1164:                     int base, int16_t offset)
                   1165: {
                   1166:     const char *opn = "st";
                   1167:     TCGv t0 = tcg_temp_new();
                   1168:     TCGv t1 = tcg_temp_new();
                   1169: 
                   1170:     gen_base_offset_addr(ctx, t0, base, offset);
                   1171:     gen_load_gpr(t1, rt);
                   1172:     switch (opc) {
                   1173: #if defined(TARGET_MIPS64)
                   1174:     case OPC_SD:
                   1175:         save_cpu_state(ctx, 0);
                   1176:         op_st_sd(t1, t0, ctx);
                   1177:         opn = "sd";
                   1178:         break;
                   1179:     case OPC_SDL:
                   1180:         save_cpu_state(ctx, 1);
                   1181:         gen_helper_2i(sdl, t1, t0, ctx->mem_idx);
                   1182:         opn = "sdl";
                   1183:         break;
                   1184:     case OPC_SDR:
                   1185:         save_cpu_state(ctx, 1);
                   1186:         gen_helper_2i(sdr, t1, t0, ctx->mem_idx);
                   1187:         opn = "sdr";
                   1188:         break;
                   1189: #endif
                   1190:     case OPC_SW:
                   1191:         save_cpu_state(ctx, 0);
                   1192:         op_st_sw(t1, t0, ctx);
                   1193:         opn = "sw";
                   1194:         break;
                   1195:     case OPC_SH:
                   1196:         save_cpu_state(ctx, 0);
                   1197:         op_st_sh(t1, t0, ctx);
                   1198:         opn = "sh";
                   1199:         break;
                   1200:     case OPC_SB:
                   1201:         save_cpu_state(ctx, 0);
                   1202:         op_st_sb(t1, t0, ctx);
                   1203:         opn = "sb";
                   1204:         break;
                   1205:     case OPC_SWL:
                   1206:         save_cpu_state(ctx, 1);
                   1207:         gen_helper_2i(swl, t1, t0, ctx->mem_idx);
                   1208:         opn = "swl";
                   1209:         break;
                   1210:     case OPC_SWR:
                   1211:         save_cpu_state(ctx, 1);
                   1212:         gen_helper_2i(swr, t1, t0, ctx->mem_idx);
                   1213:         opn = "swr";
                   1214:         break;
                   1215:     }
1.1.1.13! root     1216:     (void)opn; /* avoid a compiler warning */
1.1.1.12  root     1217:     MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
                   1218:     tcg_temp_free(t0);
                   1219:     tcg_temp_free(t1);
                   1220: }
                   1221: 
                   1222: 
1.1.1.8   root     1223: /* Store conditional */
                   1224: static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
                   1225:                          int base, int16_t offset)
                   1226: {
                   1227:     const char *opn = "st_cond";
                   1228:     TCGv t0, t1;
                   1229: 
                   1230:     t0 = tcg_temp_local_new();
                   1231: 
1.1.1.12  root     1232:     gen_base_offset_addr(ctx, t0, base, offset);
1.1.1.8   root     1233:     /* Don't do NOP if destination is zero: we must perform the actual
                   1234:        memory access. */
                   1235: 
                   1236:     t1 = tcg_temp_local_new();
                   1237:     gen_load_gpr(t1, rt);
                   1238:     switch (opc) {
                   1239: #if defined(TARGET_MIPS64)
                   1240:     case OPC_SCD:
1.1.1.13! root     1241:         save_cpu_state(ctx, 1);
1.1.1.12  root     1242:         op_st_scd(t1, t0, rt, ctx);
1.1.1.8   root     1243:         opn = "scd";
                   1244:         break;
                   1245: #endif
1.1       root     1246:     case OPC_SC:
1.1.1.9   root     1247:         save_cpu_state(ctx, 1);
1.1.1.12  root     1248:         op_st_sc(t1, t0, rt, ctx);
1.1       root     1249:         opn = "sc";
                   1250:         break;
                   1251:     }
1.1.1.13! root     1252:     (void)opn; /* avoid a compiler warning */
1.1       root     1253:     MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1.1.1.7   root     1254:     tcg_temp_free(t1);
1.1.1.8   root     1255:     tcg_temp_free(t0);
1.1       root     1256: }
                   1257: 
1.1.1.4   root     1258: /* Load and store */
1.1.1.5   root     1259: static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1.1.1.7   root     1260:                           int base, int16_t offset)
1.1.1.4   root     1261: {
1.1.1.6   root     1262:     const char *opn = "flt_ldst";
1.1.1.8   root     1263:     TCGv t0 = tcg_temp_new();
1.1.1.4   root     1264: 
1.1.1.12  root     1265:     gen_base_offset_addr(ctx, t0, base, offset);
1.1.1.4   root     1266:     /* Don't do NOP if destination is zero: we must perform the actual
1.1.1.6   root     1267:        memory access. */
1.1.1.4   root     1268:     switch (opc) {
                   1269:     case OPC_LWC1:
1.1.1.7   root     1270:         {
                   1271:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   1272: 
1.1.1.8   root     1273:             tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
                   1274:             tcg_gen_trunc_tl_i32(fp0, t0);
1.1.1.7   root     1275:             gen_store_fpr32(fp0, ft);
                   1276:             tcg_temp_free_i32(fp0);
                   1277:         }
1.1.1.4   root     1278:         opn = "lwc1";
                   1279:         break;
                   1280:     case OPC_SWC1:
1.1.1.7   root     1281:         {
                   1282:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   1283:             TCGv t1 = tcg_temp_new();
                   1284: 
                   1285:             gen_load_fpr32(fp0, ft);
                   1286:             tcg_gen_extu_i32_tl(t1, fp0);
                   1287:             tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
                   1288:             tcg_temp_free(t1);
                   1289:             tcg_temp_free_i32(fp0);
                   1290:         }
1.1.1.4   root     1291:         opn = "swc1";
                   1292:         break;
                   1293:     case OPC_LDC1:
1.1.1.7   root     1294:         {
                   1295:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   1296: 
                   1297:             tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
                   1298:             gen_store_fpr64(ctx, fp0, ft);
                   1299:             tcg_temp_free_i64(fp0);
                   1300:         }
1.1.1.4   root     1301:         opn = "ldc1";
                   1302:         break;
                   1303:     case OPC_SDC1:
1.1.1.7   root     1304:         {
                   1305:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   1306: 
                   1307:             gen_load_fpr64(ctx, fp0, ft);
                   1308:             tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
                   1309:             tcg_temp_free_i64(fp0);
                   1310:         }
1.1.1.4   root     1311:         opn = "sdc1";
                   1312:         break;
                   1313:     default:
1.1.1.6   root     1314:         MIPS_INVAL(opn);
                   1315:         generate_exception(ctx, EXCP_RI);
1.1.1.7   root     1316:         goto out;
1.1.1.4   root     1317:     }
1.1.1.13! root     1318:     (void)opn; /* avoid a compiler warning */
1.1.1.4   root     1319:     MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1.1.1.7   root     1320:  out:
                   1321:     tcg_temp_free(t0);
1.1.1.4   root     1322: }
1.1.1.5   root     1323: 
1.1.1.12  root     1324: static void gen_cop1_ldst(CPUState *env, DisasContext *ctx,
                   1325:                           uint32_t op, int rt, int rs, int16_t imm)
                   1326: {
                   1327:     if (env->CP0_Config1 & (1 << CP0C1_FP)) {
                   1328:         check_cp1_enabled(ctx);
                   1329:         gen_flt_ldst(ctx, op, rt, rs, imm);
                   1330:     } else {
                   1331:         generate_exception_err(ctx, EXCP_CpU, 1);
                   1332:     }
                   1333: }
                   1334: 
1.1       root     1335: /* Arithmetic with immediate operand */
1.1.1.6   root     1336: static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
                   1337:                            int rt, int rs, int16_t imm)
1.1       root     1338: {
1.1.1.8   root     1339:     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1.1.1.6   root     1340:     const char *opn = "imm arith";
1.1       root     1341: 
1.1.1.5   root     1342:     if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1.1.1.6   root     1343:         /* If no destination, treat it as a NOP.
                   1344:            For addi, we must generate the overflow exception when needed. */
1.1       root     1345:         MIPS_DEBUG("NOP");
1.1.1.8   root     1346:         return;
1.1       root     1347:     }
                   1348:     switch (opc) {
                   1349:     case OPC_ADDI:
1.1.1.7   root     1350:         {
1.1.1.8   root     1351:             TCGv t0 = tcg_temp_local_new();
                   1352:             TCGv t1 = tcg_temp_new();
                   1353:             TCGv t2 = tcg_temp_new();
1.1.1.7   root     1354:             int l1 = gen_new_label();
                   1355: 
1.1.1.8   root     1356:             gen_load_gpr(t1, rs);
                   1357:             tcg_gen_addi_tl(t0, t1, uimm);
                   1358:             tcg_gen_ext32s_tl(t0, t0);
1.1.1.7   root     1359: 
1.1.1.8   root     1360:             tcg_gen_xori_tl(t1, t1, ~uimm);
                   1361:             tcg_gen_xori_tl(t2, t0, uimm);
                   1362:             tcg_gen_and_tl(t1, t1, t2);
                   1363:             tcg_temp_free(t2);
                   1364:             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
                   1365:             tcg_temp_free(t1);
1.1.1.7   root     1366:             /* operands of same sign, result different sign */
                   1367:             generate_exception(ctx, EXCP_OVERFLOW);
                   1368:             gen_set_label(l1);
                   1369:             tcg_gen_ext32s_tl(t0, t0);
1.1.1.8   root     1370:             gen_store_gpr(t0, rt);
                   1371:             tcg_temp_free(t0);
1.1.1.7   root     1372:         }
1.1       root     1373:         opn = "addi";
                   1374:         break;
                   1375:     case OPC_ADDIU:
1.1.1.8   root     1376:         if (rs != 0) {
                   1377:             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
                   1378:             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
                   1379:         } else {
                   1380:             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
                   1381:         }
1.1       root     1382:         opn = "addiu";
                   1383:         break;
1.1.1.6   root     1384: #if defined(TARGET_MIPS64)
1.1.1.5   root     1385:     case OPC_DADDI:
1.1.1.7   root     1386:         {
1.1.1.8   root     1387:             TCGv t0 = tcg_temp_local_new();
                   1388:             TCGv t1 = tcg_temp_new();
                   1389:             TCGv t2 = tcg_temp_new();
1.1.1.7   root     1390:             int l1 = gen_new_label();
                   1391: 
1.1.1.8   root     1392:             gen_load_gpr(t1, rs);
                   1393:             tcg_gen_addi_tl(t0, t1, uimm);
1.1.1.7   root     1394: 
1.1.1.8   root     1395:             tcg_gen_xori_tl(t1, t1, ~uimm);
                   1396:             tcg_gen_xori_tl(t2, t0, uimm);
                   1397:             tcg_gen_and_tl(t1, t1, t2);
                   1398:             tcg_temp_free(t2);
                   1399:             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
                   1400:             tcg_temp_free(t1);
1.1.1.7   root     1401:             /* operands of same sign, result different sign */
                   1402:             generate_exception(ctx, EXCP_OVERFLOW);
                   1403:             gen_set_label(l1);
1.1.1.8   root     1404:             gen_store_gpr(t0, rt);
                   1405:             tcg_temp_free(t0);
1.1.1.7   root     1406:         }
1.1.1.5   root     1407:         opn = "daddi";
                   1408:         break;
                   1409:     case OPC_DADDIU:
1.1.1.8   root     1410:         if (rs != 0) {
                   1411:             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
                   1412:         } else {
                   1413:             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
                   1414:         }
1.1.1.5   root     1415:         opn = "daddiu";
                   1416:         break;
                   1417: #endif
1.1.1.8   root     1418:     }
1.1.1.13! root     1419:     (void)opn; /* avoid a compiler warning */
1.1.1.8   root     1420:     MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
                   1421: }
                   1422: 
                   1423: /* Logic with immediate operand */
                   1424: static void gen_logic_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
                   1425: {
                   1426:     target_ulong uimm;
                   1427:     const char *opn = "imm logic";
                   1428: 
                   1429:     if (rt == 0) {
                   1430:         /* If no destination, treat it as a NOP. */
                   1431:         MIPS_DEBUG("NOP");
                   1432:         return;
                   1433:     }
                   1434:     uimm = (uint16_t)imm;
                   1435:     switch (opc) {
1.1       root     1436:     case OPC_ANDI:
1.1.1.8   root     1437:         if (likely(rs != 0))
                   1438:             tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
                   1439:         else
                   1440:             tcg_gen_movi_tl(cpu_gpr[rt], 0);
1.1       root     1441:         opn = "andi";
                   1442:         break;
                   1443:     case OPC_ORI:
1.1.1.8   root     1444:         if (rs != 0)
                   1445:             tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
                   1446:         else
                   1447:             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1.1       root     1448:         opn = "ori";
                   1449:         break;
                   1450:     case OPC_XORI:
1.1.1.8   root     1451:         if (likely(rs != 0))
                   1452:             tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
                   1453:         else
                   1454:             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1.1       root     1455:         opn = "xori";
                   1456:         break;
                   1457:     case OPC_LUI:
1.1.1.8   root     1458:         tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
1.1       root     1459:         opn = "lui";
                   1460:         break;
1.1.1.8   root     1461:     }
1.1.1.13! root     1462:     (void)opn; /* avoid a compiler warning */
1.1.1.8   root     1463:     MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
                   1464: }
                   1465: 
                   1466: /* Set on less than with immediate operand */
                   1467: static void gen_slt_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
                   1468: {
                   1469:     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
                   1470:     const char *opn = "imm arith";
                   1471:     TCGv t0;
                   1472: 
                   1473:     if (rt == 0) {
                   1474:         /* If no destination, treat it as a NOP. */
                   1475:         MIPS_DEBUG("NOP");
                   1476:         return;
                   1477:     }
                   1478:     t0 = tcg_temp_new();
                   1479:     gen_load_gpr(t0, rs);
                   1480:     switch (opc) {
                   1481:     case OPC_SLTI:
1.1.1.12  root     1482:         tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
1.1.1.8   root     1483:         opn = "slti";
                   1484:         break;
                   1485:     case OPC_SLTIU:
1.1.1.12  root     1486:         tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
1.1.1.8   root     1487:         opn = "sltiu";
                   1488:         break;
                   1489:     }
1.1.1.13! root     1490:     (void)opn; /* avoid a compiler warning */
1.1.1.8   root     1491:     MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
                   1492:     tcg_temp_free(t0);
                   1493: }
                   1494: 
                   1495: /* Shifts with immediate operand */
                   1496: static void gen_shift_imm(CPUState *env, DisasContext *ctx, uint32_t opc,
                   1497:                           int rt, int rs, int16_t imm)
                   1498: {
                   1499:     target_ulong uimm = ((uint16_t)imm) & 0x1f;
                   1500:     const char *opn = "imm shift";
                   1501:     TCGv t0;
                   1502: 
                   1503:     if (rt == 0) {
                   1504:         /* If no destination, treat it as a NOP. */
                   1505:         MIPS_DEBUG("NOP");
                   1506:         return;
                   1507:     }
                   1508: 
                   1509:     t0 = tcg_temp_new();
                   1510:     gen_load_gpr(t0, rs);
                   1511:     switch (opc) {
1.1       root     1512:     case OPC_SLL:
1.1.1.7   root     1513:         tcg_gen_shli_tl(t0, t0, uimm);
1.1.1.8   root     1514:         tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1.1       root     1515:         opn = "sll";
                   1516:         break;
                   1517:     case OPC_SRA:
1.1.1.8   root     1518:         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1.1       root     1519:         opn = "sra";
                   1520:         break;
                   1521:     case OPC_SRL:
1.1.1.12  root     1522:         if (uimm != 0) {
                   1523:             tcg_gen_ext32u_tl(t0, t0);
                   1524:             tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
                   1525:         } else {
                   1526:             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
                   1527:         }
                   1528:         opn = "srl";
                   1529:         break;
                   1530:     case OPC_ROTR:
                   1531:         if (uimm != 0) {
                   1532:             TCGv_i32 t1 = tcg_temp_new_i32();
1.1.1.7   root     1533: 
1.1.1.12  root     1534:             tcg_gen_trunc_tl_i32(t1, t0);
                   1535:             tcg_gen_rotri_i32(t1, t1, uimm);
                   1536:             tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
                   1537:             tcg_temp_free_i32(t1);
                   1538:         } else {
                   1539:             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1.1.1.6   root     1540:         }
1.1.1.12  root     1541:         opn = "rotr";
1.1.1.5   root     1542:         break;
1.1.1.6   root     1543: #if defined(TARGET_MIPS64)
1.1.1.5   root     1544:     case OPC_DSLL:
1.1.1.8   root     1545:         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
1.1.1.5   root     1546:         opn = "dsll";
                   1547:         break;
                   1548:     case OPC_DSRA:
1.1.1.8   root     1549:         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1.1.1.5   root     1550:         opn = "dsra";
                   1551:         break;
                   1552:     case OPC_DSRL:
1.1.1.12  root     1553:         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
                   1554:         opn = "dsrl";
                   1555:         break;
                   1556:     case OPC_DROTR:
                   1557:         if (uimm != 0) {
                   1558:             tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
                   1559:         } else {
                   1560:             tcg_gen_mov_tl(cpu_gpr[rt], t0);
1.1.1.6   root     1561:         }
1.1.1.12  root     1562:         opn = "drotr";
1.1.1.5   root     1563:         break;
                   1564:     case OPC_DSLL32:
1.1.1.8   root     1565:         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
1.1.1.5   root     1566:         opn = "dsll32";
                   1567:         break;
                   1568:     case OPC_DSRA32:
1.1.1.8   root     1569:         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
1.1.1.5   root     1570:         opn = "dsra32";
                   1571:         break;
                   1572:     case OPC_DSRL32:
1.1.1.12  root     1573:         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
                   1574:         opn = "dsrl32";
                   1575:         break;
                   1576:     case OPC_DROTR32:
                   1577:         tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
                   1578:         opn = "drotr32";
1.1       root     1579:         break;
1.1.1.5   root     1580: #endif
1.1       root     1581:     }
1.1.1.13! root     1582:     (void)opn; /* avoid a compiler warning */
1.1.1.6   root     1583:     MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1.1.1.7   root     1584:     tcg_temp_free(t0);
1.1       root     1585: }
                   1586: 
                   1587: /* Arithmetic */
1.1.1.6   root     1588: static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1.1       root     1589:                        int rd, int rs, int rt)
                   1590: {
1.1.1.6   root     1591:     const char *opn = "arith";
1.1       root     1592: 
1.1.1.5   root     1593:     if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
                   1594:        && opc != OPC_DADD && opc != OPC_DSUB) {
1.1.1.6   root     1595:         /* If no destination, treat it as a NOP.
                   1596:            For add & sub, we must generate the overflow exception when needed. */
1.1       root     1597:         MIPS_DEBUG("NOP");
1.1.1.8   root     1598:         return;
1.1.1.6   root     1599:     }
1.1.1.8   root     1600: 
1.1       root     1601:     switch (opc) {
                   1602:     case OPC_ADD:
1.1.1.7   root     1603:         {
1.1.1.8   root     1604:             TCGv t0 = tcg_temp_local_new();
                   1605:             TCGv t1 = tcg_temp_new();
                   1606:             TCGv t2 = tcg_temp_new();
1.1.1.7   root     1607:             int l1 = gen_new_label();
                   1608: 
1.1.1.8   root     1609:             gen_load_gpr(t1, rs);
                   1610:             gen_load_gpr(t2, rt);
                   1611:             tcg_gen_add_tl(t0, t1, t2);
                   1612:             tcg_gen_ext32s_tl(t0, t0);
                   1613:             tcg_gen_xor_tl(t1, t1, t2);
                   1614:             tcg_gen_xor_tl(t2, t0, t2);
1.1.1.12  root     1615:             tcg_gen_andc_tl(t1, t2, t1);
1.1.1.8   root     1616:             tcg_temp_free(t2);
                   1617:             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
                   1618:             tcg_temp_free(t1);
1.1.1.7   root     1619:             /* operands of same sign, result different sign */
                   1620:             generate_exception(ctx, EXCP_OVERFLOW);
                   1621:             gen_set_label(l1);
1.1.1.8   root     1622:             gen_store_gpr(t0, rd);
                   1623:             tcg_temp_free(t0);
1.1.1.7   root     1624:         }
1.1       root     1625:         opn = "add";
                   1626:         break;
                   1627:     case OPC_ADDU:
1.1.1.8   root     1628:         if (rs != 0 && rt != 0) {
                   1629:             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
                   1630:             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
                   1631:         } else if (rs == 0 && rt != 0) {
                   1632:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
                   1633:         } else if (rs != 0 && rt == 0) {
                   1634:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   1635:         } else {
                   1636:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   1637:         }
1.1       root     1638:         opn = "addu";
                   1639:         break;
                   1640:     case OPC_SUB:
1.1.1.7   root     1641:         {
1.1.1.8   root     1642:             TCGv t0 = tcg_temp_local_new();
                   1643:             TCGv t1 = tcg_temp_new();
                   1644:             TCGv t2 = tcg_temp_new();
1.1.1.7   root     1645:             int l1 = gen_new_label();
                   1646: 
1.1.1.8   root     1647:             gen_load_gpr(t1, rs);
                   1648:             gen_load_gpr(t2, rt);
                   1649:             tcg_gen_sub_tl(t0, t1, t2);
                   1650:             tcg_gen_ext32s_tl(t0, t0);
                   1651:             tcg_gen_xor_tl(t2, t1, t2);
                   1652:             tcg_gen_xor_tl(t1, t0, t1);
                   1653:             tcg_gen_and_tl(t1, t1, t2);
                   1654:             tcg_temp_free(t2);
                   1655:             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
                   1656:             tcg_temp_free(t1);
1.1.1.9   root     1657:             /* operands of different sign, first operand and result different sign */
1.1.1.7   root     1658:             generate_exception(ctx, EXCP_OVERFLOW);
                   1659:             gen_set_label(l1);
1.1.1.8   root     1660:             gen_store_gpr(t0, rd);
                   1661:             tcg_temp_free(t0);
1.1.1.7   root     1662:         }
1.1       root     1663:         opn = "sub";
                   1664:         break;
                   1665:     case OPC_SUBU:
1.1.1.8   root     1666:         if (rs != 0 && rt != 0) {
                   1667:             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
                   1668:             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
                   1669:         } else if (rs == 0 && rt != 0) {
                   1670:             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
                   1671:             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
                   1672:         } else if (rs != 0 && rt == 0) {
                   1673:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   1674:         } else {
                   1675:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   1676:         }
1.1       root     1677:         opn = "subu";
                   1678:         break;
1.1.1.6   root     1679: #if defined(TARGET_MIPS64)
1.1.1.5   root     1680:     case OPC_DADD:
1.1.1.7   root     1681:         {
1.1.1.8   root     1682:             TCGv t0 = tcg_temp_local_new();
                   1683:             TCGv t1 = tcg_temp_new();
                   1684:             TCGv t2 = tcg_temp_new();
1.1.1.7   root     1685:             int l1 = gen_new_label();
                   1686: 
1.1.1.8   root     1687:             gen_load_gpr(t1, rs);
                   1688:             gen_load_gpr(t2, rt);
                   1689:             tcg_gen_add_tl(t0, t1, t2);
                   1690:             tcg_gen_xor_tl(t1, t1, t2);
                   1691:             tcg_gen_xor_tl(t2, t0, t2);
1.1.1.12  root     1692:             tcg_gen_andc_tl(t1, t2, t1);
1.1.1.8   root     1693:             tcg_temp_free(t2);
                   1694:             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
                   1695:             tcg_temp_free(t1);
1.1.1.7   root     1696:             /* operands of same sign, result different sign */
                   1697:             generate_exception(ctx, EXCP_OVERFLOW);
                   1698:             gen_set_label(l1);
1.1.1.8   root     1699:             gen_store_gpr(t0, rd);
                   1700:             tcg_temp_free(t0);
1.1.1.7   root     1701:         }
1.1.1.5   root     1702:         opn = "dadd";
                   1703:         break;
                   1704:     case OPC_DADDU:
1.1.1.8   root     1705:         if (rs != 0 && rt != 0) {
                   1706:             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
                   1707:         } else if (rs == 0 && rt != 0) {
                   1708:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
                   1709:         } else if (rs != 0 && rt == 0) {
                   1710:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   1711:         } else {
                   1712:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   1713:         }
1.1.1.5   root     1714:         opn = "daddu";
                   1715:         break;
                   1716:     case OPC_DSUB:
1.1.1.7   root     1717:         {
1.1.1.8   root     1718:             TCGv t0 = tcg_temp_local_new();
                   1719:             TCGv t1 = tcg_temp_new();
                   1720:             TCGv t2 = tcg_temp_new();
1.1.1.7   root     1721:             int l1 = gen_new_label();
                   1722: 
1.1.1.8   root     1723:             gen_load_gpr(t1, rs);
                   1724:             gen_load_gpr(t2, rt);
                   1725:             tcg_gen_sub_tl(t0, t1, t2);
                   1726:             tcg_gen_xor_tl(t2, t1, t2);
                   1727:             tcg_gen_xor_tl(t1, t0, t1);
                   1728:             tcg_gen_and_tl(t1, t1, t2);
                   1729:             tcg_temp_free(t2);
                   1730:             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
                   1731:             tcg_temp_free(t1);
1.1.1.9   root     1732:             /* operands of different sign, first operand and result different sign */
1.1.1.7   root     1733:             generate_exception(ctx, EXCP_OVERFLOW);
                   1734:             gen_set_label(l1);
1.1.1.8   root     1735:             gen_store_gpr(t0, rd);
                   1736:             tcg_temp_free(t0);
1.1.1.7   root     1737:         }
1.1.1.5   root     1738:         opn = "dsub";
                   1739:         break;
                   1740:     case OPC_DSUBU:
1.1.1.8   root     1741:         if (rs != 0 && rt != 0) {
                   1742:             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
                   1743:         } else if (rs == 0 && rt != 0) {
                   1744:             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
                   1745:         } else if (rs != 0 && rt == 0) {
                   1746:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   1747:         } else {
                   1748:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   1749:         }
1.1.1.5   root     1750:         opn = "dsubu";
                   1751:         break;
                   1752: #endif
1.1.1.8   root     1753:     case OPC_MUL:
                   1754:         if (likely(rs != 0 && rt != 0)) {
                   1755:             tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
                   1756:             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
                   1757:         } else {
                   1758:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   1759:         }
                   1760:         opn = "mul";
1.1       root     1761:         break;
1.1.1.8   root     1762:     }
1.1.1.13! root     1763:     (void)opn; /* avoid a compiler warning */
1.1.1.8   root     1764:     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
                   1765: }
                   1766: 
                   1767: /* Conditional move */
                   1768: static void gen_cond_move (CPUState *env, uint32_t opc, int rd, int rs, int rt)
                   1769: {
                   1770:     const char *opn = "cond move";
                   1771:     int l1;
                   1772: 
                   1773:     if (rd == 0) {
                   1774:         /* If no destination, treat it as a NOP.
                   1775:            For add & sub, we must generate the overflow exception when needed. */
                   1776:         MIPS_DEBUG("NOP");
                   1777:         return;
                   1778:     }
                   1779: 
                   1780:     l1 = gen_new_label();
                   1781:     switch (opc) {
                   1782:     case OPC_MOVN:
                   1783:         if (likely(rt != 0))
                   1784:             tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
                   1785:         else
                   1786:             tcg_gen_br(l1);
                   1787:         opn = "movn";
1.1       root     1788:         break;
1.1.1.8   root     1789:     case OPC_MOVZ:
                   1790:         if (likely(rt != 0))
                   1791:             tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
                   1792:         opn = "movz";
                   1793:         break;
                   1794:     }
                   1795:     if (rs != 0)
                   1796:         tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   1797:     else
                   1798:         tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   1799:     gen_set_label(l1);
                   1800: 
1.1.1.13! root     1801:     (void)opn; /* avoid a compiler warning */
1.1.1.8   root     1802:     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
                   1803: }
                   1804: 
                   1805: /* Logic */
                   1806: static void gen_logic (CPUState *env, uint32_t opc, int rd, int rs, int rt)
                   1807: {
                   1808:     const char *opn = "logic";
                   1809: 
                   1810:     if (rd == 0) {
                   1811:         /* If no destination, treat it as a NOP. */
                   1812:         MIPS_DEBUG("NOP");
                   1813:         return;
                   1814:     }
                   1815: 
                   1816:     switch (opc) {
1.1       root     1817:     case OPC_AND:
1.1.1.8   root     1818:         if (likely(rs != 0 && rt != 0)) {
                   1819:             tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
                   1820:         } else {
                   1821:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   1822:         }
1.1       root     1823:         opn = "and";
                   1824:         break;
                   1825:     case OPC_NOR:
1.1.1.8   root     1826:         if (rs != 0 && rt != 0) {
                   1827:             tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
                   1828:         } else if (rs == 0 && rt != 0) {
                   1829:             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
                   1830:         } else if (rs != 0 && rt == 0) {
                   1831:             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   1832:         } else {
                   1833:             tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
                   1834:         }
1.1       root     1835:         opn = "nor";
                   1836:         break;
                   1837:     case OPC_OR:
1.1.1.8   root     1838:         if (likely(rs != 0 && rt != 0)) {
                   1839:             tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
                   1840:         } else if (rs == 0 && rt != 0) {
                   1841:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
                   1842:         } else if (rs != 0 && rt == 0) {
                   1843:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   1844:         } else {
                   1845:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   1846:         }
1.1       root     1847:         opn = "or";
                   1848:         break;
                   1849:     case OPC_XOR:
1.1.1.8   root     1850:         if (likely(rs != 0 && rt != 0)) {
                   1851:             tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
                   1852:         } else if (rs == 0 && rt != 0) {
                   1853:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
                   1854:         } else if (rs != 0 && rt == 0) {
                   1855:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   1856:         } else {
                   1857:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   1858:         }
1.1       root     1859:         opn = "xor";
                   1860:         break;
1.1.1.8   root     1861:     }
1.1.1.13! root     1862:     (void)opn; /* avoid a compiler warning */
1.1.1.8   root     1863:     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
                   1864: }
                   1865: 
                   1866: /* Set on lower than */
                   1867: static void gen_slt (CPUState *env, uint32_t opc, int rd, int rs, int rt)
                   1868: {
                   1869:     const char *opn = "slt";
                   1870:     TCGv t0, t1;
                   1871: 
                   1872:     if (rd == 0) {
                   1873:         /* If no destination, treat it as a NOP. */
                   1874:         MIPS_DEBUG("NOP");
                   1875:         return;
                   1876:     }
                   1877: 
                   1878:     t0 = tcg_temp_new();
                   1879:     t1 = tcg_temp_new();
                   1880:     gen_load_gpr(t0, rs);
                   1881:     gen_load_gpr(t1, rt);
                   1882:     switch (opc) {
                   1883:     case OPC_SLT:
1.1.1.12  root     1884:         tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
1.1.1.8   root     1885:         opn = "slt";
1.1       root     1886:         break;
1.1.1.8   root     1887:     case OPC_SLTU:
1.1.1.12  root     1888:         tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
1.1.1.8   root     1889:         opn = "sltu";
                   1890:         break;
                   1891:     }
1.1.1.13! root     1892:     (void)opn; /* avoid a compiler warning */
1.1.1.8   root     1893:     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
                   1894:     tcg_temp_free(t0);
                   1895:     tcg_temp_free(t1);
                   1896: }
1.1.1.7   root     1897: 
1.1.1.8   root     1898: /* Shifts */
                   1899: static void gen_shift (CPUState *env, DisasContext *ctx, uint32_t opc,
                   1900:                        int rd, int rs, int rt)
                   1901: {
                   1902:     const char *opn = "shifts";
                   1903:     TCGv t0, t1;
1.1.1.7   root     1904: 
1.1.1.8   root     1905:     if (rd == 0) {
                   1906:         /* If no destination, treat it as a NOP.
                   1907:            For add & sub, we must generate the overflow exception when needed. */
                   1908:         MIPS_DEBUG("NOP");
                   1909:         return;
                   1910:     }
                   1911: 
                   1912:     t0 = tcg_temp_new();
                   1913:     t1 = tcg_temp_new();
                   1914:     gen_load_gpr(t0, rs);
                   1915:     gen_load_gpr(t1, rt);
                   1916:     switch (opc) {
1.1       root     1917:     case OPC_SLLV:
1.1.1.7   root     1918:         tcg_gen_andi_tl(t0, t0, 0x1f);
                   1919:         tcg_gen_shl_tl(t0, t1, t0);
1.1.1.8   root     1920:         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1.1       root     1921:         opn = "sllv";
                   1922:         break;
                   1923:     case OPC_SRAV:
1.1.1.7   root     1924:         tcg_gen_andi_tl(t0, t0, 0x1f);
1.1.1.8   root     1925:         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1.1       root     1926:         opn = "srav";
                   1927:         break;
                   1928:     case OPC_SRLV:
1.1.1.12  root     1929:         tcg_gen_ext32u_tl(t1, t1);
                   1930:         tcg_gen_andi_tl(t0, t0, 0x1f);
                   1931:         tcg_gen_shr_tl(t0, t1, t0);
                   1932:         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
                   1933:         opn = "srlv";
                   1934:         break;
                   1935:     case OPC_ROTRV:
                   1936:         {
                   1937:             TCGv_i32 t2 = tcg_temp_new_i32();
                   1938:             TCGv_i32 t3 = tcg_temp_new_i32();
                   1939: 
                   1940:             tcg_gen_trunc_tl_i32(t2, t0);
                   1941:             tcg_gen_trunc_tl_i32(t3, t1);
                   1942:             tcg_gen_andi_i32(t2, t2, 0x1f);
                   1943:             tcg_gen_rotr_i32(t2, t3, t2);
                   1944:             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
                   1945:             tcg_temp_free_i32(t2);
                   1946:             tcg_temp_free_i32(t3);
                   1947:             opn = "rotrv";
1.1.1.6   root     1948:         }
1.1.1.5   root     1949:         break;
1.1.1.6   root     1950: #if defined(TARGET_MIPS64)
1.1.1.5   root     1951:     case OPC_DSLLV:
1.1.1.7   root     1952:         tcg_gen_andi_tl(t0, t0, 0x3f);
1.1.1.8   root     1953:         tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
1.1.1.5   root     1954:         opn = "dsllv";
                   1955:         break;
                   1956:     case OPC_DSRAV:
1.1.1.7   root     1957:         tcg_gen_andi_tl(t0, t0, 0x3f);
1.1.1.8   root     1958:         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1.1.1.5   root     1959:         opn = "dsrav";
                   1960:         break;
                   1961:     case OPC_DSRLV:
1.1.1.12  root     1962:         tcg_gen_andi_tl(t0, t0, 0x3f);
                   1963:         tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
                   1964:         opn = "dsrlv";
                   1965:         break;
                   1966:     case OPC_DROTRV:
                   1967:         tcg_gen_andi_tl(t0, t0, 0x3f);
                   1968:         tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
                   1969:         opn = "drotrv";
1.1       root     1970:         break;
1.1.1.5   root     1971: #endif
1.1       root     1972:     }
1.1.1.13! root     1973:     (void)opn; /* avoid a compiler warning */
1.1       root     1974:     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1.1.1.7   root     1975:     tcg_temp_free(t0);
                   1976:     tcg_temp_free(t1);
1.1       root     1977: }
                   1978: 
                   1979: /* Arithmetic on HI/LO registers */
1.1.1.5   root     1980: static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1.1       root     1981: {
1.1.1.6   root     1982:     const char *opn = "hilo";
1.1       root     1983: 
                   1984:     if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1.1.1.6   root     1985:         /* Treat as NOP. */
1.1       root     1986:         MIPS_DEBUG("NOP");
1.1.1.8   root     1987:         return;
1.1       root     1988:     }
                   1989:     switch (opc) {
                   1990:     case OPC_MFHI:
1.1.1.8   root     1991:         tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1.1       root     1992:         opn = "mfhi";
                   1993:         break;
                   1994:     case OPC_MFLO:
1.1.1.8   root     1995:         tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1.1       root     1996:         opn = "mflo";
                   1997:         break;
                   1998:     case OPC_MTHI:
1.1.1.8   root     1999:         if (reg != 0)
                   2000:             tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
                   2001:         else
                   2002:             tcg_gen_movi_tl(cpu_HI[0], 0);
1.1       root     2003:         opn = "mthi";
                   2004:         break;
                   2005:     case OPC_MTLO:
1.1.1.8   root     2006:         if (reg != 0)
                   2007:             tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
                   2008:         else
                   2009:             tcg_gen_movi_tl(cpu_LO[0], 0);
1.1       root     2010:         opn = "mtlo";
                   2011:         break;
                   2012:     }
1.1.1.13! root     2013:     (void)opn; /* avoid a compiler warning */
1.1       root     2014:     MIPS_DEBUG("%s %s", opn, regnames[reg]);
                   2015: }
                   2016: 
1.1.1.5   root     2017: static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1.1       root     2018:                         int rs, int rt)
                   2019: {
1.1.1.6   root     2020:     const char *opn = "mul/div";
1.1.1.8   root     2021:     TCGv t0, t1;
                   2022: 
                   2023:     switch (opc) {
                   2024:     case OPC_DIV:
                   2025:     case OPC_DIVU:
                   2026: #if defined(TARGET_MIPS64)
                   2027:     case OPC_DDIV:
                   2028:     case OPC_DDIVU:
                   2029: #endif
                   2030:         t0 = tcg_temp_local_new();
                   2031:         t1 = tcg_temp_local_new();
                   2032:         break;
                   2033:     default:
                   2034:         t0 = tcg_temp_new();
                   2035:         t1 = tcg_temp_new();
                   2036:         break;
                   2037:     }
1.1       root     2038: 
1.1.1.7   root     2039:     gen_load_gpr(t0, rs);
                   2040:     gen_load_gpr(t1, rt);
1.1       root     2041:     switch (opc) {
                   2042:     case OPC_DIV:
1.1.1.7   root     2043:         {
                   2044:             int l1 = gen_new_label();
1.1.1.8   root     2045:             int l2 = gen_new_label();
1.1.1.7   root     2046: 
1.1.1.8   root     2047:             tcg_gen_ext32s_tl(t0, t0);
                   2048:             tcg_gen_ext32s_tl(t1, t1);
1.1.1.7   root     2049:             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1.1.1.8   root     2050:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
                   2051:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
                   2052: 
                   2053:             tcg_gen_mov_tl(cpu_LO[0], t0);
                   2054:             tcg_gen_movi_tl(cpu_HI[0], 0);
                   2055:             tcg_gen_br(l1);
                   2056:             gen_set_label(l2);
                   2057:             tcg_gen_div_tl(cpu_LO[0], t0, t1);
                   2058:             tcg_gen_rem_tl(cpu_HI[0], t0, t1);
                   2059:             tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
                   2060:             tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
1.1.1.7   root     2061:             gen_set_label(l1);
                   2062:         }
1.1       root     2063:         opn = "div";
                   2064:         break;
                   2065:     case OPC_DIVU:
1.1.1.7   root     2066:         {
                   2067:             int l1 = gen_new_label();
                   2068: 
1.1.1.8   root     2069:             tcg_gen_ext32u_tl(t0, t0);
                   2070:             tcg_gen_ext32u_tl(t1, t1);
1.1.1.7   root     2071:             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1.1.1.8   root     2072:             tcg_gen_divu_tl(cpu_LO[0], t0, t1);
                   2073:             tcg_gen_remu_tl(cpu_HI[0], t0, t1);
                   2074:             tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
                   2075:             tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
1.1.1.7   root     2076:             gen_set_label(l1);
                   2077:         }
1.1       root     2078:         opn = "divu";
                   2079:         break;
                   2080:     case OPC_MULT:
1.1.1.7   root     2081:         {
1.1.1.8   root     2082:             TCGv_i64 t2 = tcg_temp_new_i64();
                   2083:             TCGv_i64 t3 = tcg_temp_new_i64();
1.1.1.7   root     2084: 
1.1.1.8   root     2085:             tcg_gen_ext_tl_i64(t2, t0);
                   2086:             tcg_gen_ext_tl_i64(t3, t1);
                   2087:             tcg_gen_mul_i64(t2, t2, t3);
                   2088:             tcg_temp_free_i64(t3);
                   2089:             tcg_gen_trunc_i64_tl(t0, t2);
                   2090:             tcg_gen_shri_i64(t2, t2, 32);
                   2091:             tcg_gen_trunc_i64_tl(t1, t2);
                   2092:             tcg_temp_free_i64(t2);
1.1.1.7   root     2093:             tcg_gen_ext32s_tl(cpu_LO[0], t0);
                   2094:             tcg_gen_ext32s_tl(cpu_HI[0], t1);
                   2095:         }
1.1       root     2096:         opn = "mult";
                   2097:         break;
                   2098:     case OPC_MULTU:
1.1.1.7   root     2099:         {
1.1.1.8   root     2100:             TCGv_i64 t2 = tcg_temp_new_i64();
                   2101:             TCGv_i64 t3 = tcg_temp_new_i64();
1.1.1.7   root     2102: 
                   2103:             tcg_gen_ext32u_tl(t0, t0);
                   2104:             tcg_gen_ext32u_tl(t1, t1);
1.1.1.8   root     2105:             tcg_gen_extu_tl_i64(t2, t0);
                   2106:             tcg_gen_extu_tl_i64(t3, t1);
                   2107:             tcg_gen_mul_i64(t2, t2, t3);
                   2108:             tcg_temp_free_i64(t3);
                   2109:             tcg_gen_trunc_i64_tl(t0, t2);
                   2110:             tcg_gen_shri_i64(t2, t2, 32);
                   2111:             tcg_gen_trunc_i64_tl(t1, t2);
                   2112:             tcg_temp_free_i64(t2);
1.1.1.7   root     2113:             tcg_gen_ext32s_tl(cpu_LO[0], t0);
                   2114:             tcg_gen_ext32s_tl(cpu_HI[0], t1);
                   2115:         }
1.1       root     2116:         opn = "multu";
                   2117:         break;
1.1.1.6   root     2118: #if defined(TARGET_MIPS64)
1.1.1.5   root     2119:     case OPC_DDIV:
1.1.1.7   root     2120:         {
                   2121:             int l1 = gen_new_label();
1.1.1.8   root     2122:             int l2 = gen_new_label();
1.1.1.7   root     2123: 
                   2124:             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1.1.1.8   root     2125:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
                   2126:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
                   2127:             tcg_gen_mov_tl(cpu_LO[0], t0);
                   2128:             tcg_gen_movi_tl(cpu_HI[0], 0);
                   2129:             tcg_gen_br(l1);
                   2130:             gen_set_label(l2);
                   2131:             tcg_gen_div_i64(cpu_LO[0], t0, t1);
                   2132:             tcg_gen_rem_i64(cpu_HI[0], t0, t1);
1.1.1.7   root     2133:             gen_set_label(l1);
                   2134:         }
1.1.1.5   root     2135:         opn = "ddiv";
                   2136:         break;
                   2137:     case OPC_DDIVU:
1.1.1.7   root     2138:         {
                   2139:             int l1 = gen_new_label();
                   2140: 
                   2141:             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
                   2142:             tcg_gen_divu_i64(cpu_LO[0], t0, t1);
                   2143:             tcg_gen_remu_i64(cpu_HI[0], t0, t1);
                   2144:             gen_set_label(l1);
                   2145:         }
1.1.1.5   root     2146:         opn = "ddivu";
                   2147:         break;
                   2148:     case OPC_DMULT:
1.1.1.7   root     2149:         gen_helper_dmult(t0, t1);
1.1.1.5   root     2150:         opn = "dmult";
                   2151:         break;
                   2152:     case OPC_DMULTU:
1.1.1.7   root     2153:         gen_helper_dmultu(t0, t1);
1.1.1.5   root     2154:         opn = "dmultu";
                   2155:         break;
                   2156: #endif
1.1       root     2157:     case OPC_MADD:
1.1.1.7   root     2158:         {
1.1.1.8   root     2159:             TCGv_i64 t2 = tcg_temp_new_i64();
                   2160:             TCGv_i64 t3 = tcg_temp_new_i64();
1.1.1.7   root     2161: 
1.1.1.8   root     2162:             tcg_gen_ext_tl_i64(t2, t0);
                   2163:             tcg_gen_ext_tl_i64(t3, t1);
                   2164:             tcg_gen_mul_i64(t2, t2, t3);
                   2165:             tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
                   2166:             tcg_gen_add_i64(t2, t2, t3);
                   2167:             tcg_temp_free_i64(t3);
                   2168:             tcg_gen_trunc_i64_tl(t0, t2);
                   2169:             tcg_gen_shri_i64(t2, t2, 32);
                   2170:             tcg_gen_trunc_i64_tl(t1, t2);
                   2171:             tcg_temp_free_i64(t2);
1.1.1.7   root     2172:             tcg_gen_ext32s_tl(cpu_LO[0], t0);
1.1.1.8   root     2173:             tcg_gen_ext32s_tl(cpu_HI[0], t1);
1.1.1.7   root     2174:         }
1.1       root     2175:         opn = "madd";
                   2176:         break;
                   2177:     case OPC_MADDU:
1.1.1.7   root     2178:        {
1.1.1.8   root     2179:             TCGv_i64 t2 = tcg_temp_new_i64();
                   2180:             TCGv_i64 t3 = tcg_temp_new_i64();
1.1.1.7   root     2181: 
                   2182:             tcg_gen_ext32u_tl(t0, t0);
                   2183:             tcg_gen_ext32u_tl(t1, t1);
1.1.1.8   root     2184:             tcg_gen_extu_tl_i64(t2, t0);
                   2185:             tcg_gen_extu_tl_i64(t3, t1);
                   2186:             tcg_gen_mul_i64(t2, t2, t3);
                   2187:             tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
                   2188:             tcg_gen_add_i64(t2, t2, t3);
                   2189:             tcg_temp_free_i64(t3);
                   2190:             tcg_gen_trunc_i64_tl(t0, t2);
                   2191:             tcg_gen_shri_i64(t2, t2, 32);
                   2192:             tcg_gen_trunc_i64_tl(t1, t2);
                   2193:             tcg_temp_free_i64(t2);
1.1.1.7   root     2194:             tcg_gen_ext32s_tl(cpu_LO[0], t0);
                   2195:             tcg_gen_ext32s_tl(cpu_HI[0], t1);
                   2196:         }
1.1       root     2197:         opn = "maddu";
                   2198:         break;
                   2199:     case OPC_MSUB:
1.1.1.7   root     2200:         {
1.1.1.8   root     2201:             TCGv_i64 t2 = tcg_temp_new_i64();
                   2202:             TCGv_i64 t3 = tcg_temp_new_i64();
1.1.1.7   root     2203: 
1.1.1.8   root     2204:             tcg_gen_ext_tl_i64(t2, t0);
                   2205:             tcg_gen_ext_tl_i64(t3, t1);
                   2206:             tcg_gen_mul_i64(t2, t2, t3);
                   2207:             tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
                   2208:             tcg_gen_sub_i64(t2, t3, t2);
                   2209:             tcg_temp_free_i64(t3);
                   2210:             tcg_gen_trunc_i64_tl(t0, t2);
                   2211:             tcg_gen_shri_i64(t2, t2, 32);
                   2212:             tcg_gen_trunc_i64_tl(t1, t2);
                   2213:             tcg_temp_free_i64(t2);
1.1.1.7   root     2214:             tcg_gen_ext32s_tl(cpu_LO[0], t0);
                   2215:             tcg_gen_ext32s_tl(cpu_HI[0], t1);
                   2216:         }
1.1       root     2217:         opn = "msub";
                   2218:         break;
                   2219:     case OPC_MSUBU:
1.1.1.7   root     2220:         {
1.1.1.8   root     2221:             TCGv_i64 t2 = tcg_temp_new_i64();
                   2222:             TCGv_i64 t3 = tcg_temp_new_i64();
1.1.1.7   root     2223: 
                   2224:             tcg_gen_ext32u_tl(t0, t0);
                   2225:             tcg_gen_ext32u_tl(t1, t1);
1.1.1.8   root     2226:             tcg_gen_extu_tl_i64(t2, t0);
                   2227:             tcg_gen_extu_tl_i64(t3, t1);
                   2228:             tcg_gen_mul_i64(t2, t2, t3);
                   2229:             tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
                   2230:             tcg_gen_sub_i64(t2, t3, t2);
                   2231:             tcg_temp_free_i64(t3);
                   2232:             tcg_gen_trunc_i64_tl(t0, t2);
                   2233:             tcg_gen_shri_i64(t2, t2, 32);
                   2234:             tcg_gen_trunc_i64_tl(t1, t2);
                   2235:             tcg_temp_free_i64(t2);
1.1.1.7   root     2236:             tcg_gen_ext32s_tl(cpu_LO[0], t0);
                   2237:             tcg_gen_ext32s_tl(cpu_HI[0], t1);
                   2238:         }
1.1       root     2239:         opn = "msubu";
                   2240:         break;
                   2241:     default:
1.1.1.6   root     2242:         MIPS_INVAL(opn);
1.1       root     2243:         generate_exception(ctx, EXCP_RI);
1.1.1.7   root     2244:         goto out;
1.1       root     2245:     }
1.1.1.13! root     2246:     (void)opn; /* avoid a compiler warning */
1.1       root     2247:     MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
1.1.1.7   root     2248:  out:
                   2249:     tcg_temp_free(t0);
                   2250:     tcg_temp_free(t1);
1.1       root     2251: }
                   2252: 
1.1.1.6   root     2253: static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
                   2254:                             int rd, int rs, int rt)
                   2255: {
                   2256:     const char *opn = "mul vr54xx";
1.1.1.8   root     2257:     TCGv t0 = tcg_temp_new();
                   2258:     TCGv t1 = tcg_temp_new();
1.1.1.6   root     2259: 
1.1.1.7   root     2260:     gen_load_gpr(t0, rs);
                   2261:     gen_load_gpr(t1, rt);
1.1.1.6   root     2262: 
                   2263:     switch (opc) {
                   2264:     case OPC_VR54XX_MULS:
1.1.1.7   root     2265:         gen_helper_muls(t0, t0, t1);
1.1.1.6   root     2266:         opn = "muls";
1.1.1.7   root     2267:         break;
1.1.1.6   root     2268:     case OPC_VR54XX_MULSU:
1.1.1.7   root     2269:         gen_helper_mulsu(t0, t0, t1);
1.1.1.6   root     2270:         opn = "mulsu";
1.1.1.7   root     2271:         break;
1.1.1.6   root     2272:     case OPC_VR54XX_MACC:
1.1.1.7   root     2273:         gen_helper_macc(t0, t0, t1);
1.1.1.6   root     2274:         opn = "macc";
1.1.1.7   root     2275:         break;
1.1.1.6   root     2276:     case OPC_VR54XX_MACCU:
1.1.1.7   root     2277:         gen_helper_maccu(t0, t0, t1);
1.1.1.6   root     2278:         opn = "maccu";
1.1.1.7   root     2279:         break;
1.1.1.6   root     2280:     case OPC_VR54XX_MSAC:
1.1.1.7   root     2281:         gen_helper_msac(t0, t0, t1);
1.1.1.6   root     2282:         opn = "msac";
1.1.1.7   root     2283:         break;
1.1.1.6   root     2284:     case OPC_VR54XX_MSACU:
1.1.1.7   root     2285:         gen_helper_msacu(t0, t0, t1);
1.1.1.6   root     2286:         opn = "msacu";
1.1.1.7   root     2287:         break;
1.1.1.6   root     2288:     case OPC_VR54XX_MULHI:
1.1.1.7   root     2289:         gen_helper_mulhi(t0, t0, t1);
1.1.1.6   root     2290:         opn = "mulhi";
1.1.1.7   root     2291:         break;
1.1.1.6   root     2292:     case OPC_VR54XX_MULHIU:
1.1.1.7   root     2293:         gen_helper_mulhiu(t0, t0, t1);
1.1.1.6   root     2294:         opn = "mulhiu";
1.1.1.7   root     2295:         break;
1.1.1.6   root     2296:     case OPC_VR54XX_MULSHI:
1.1.1.7   root     2297:         gen_helper_mulshi(t0, t0, t1);
1.1.1.6   root     2298:         opn = "mulshi";
1.1.1.7   root     2299:         break;
1.1.1.6   root     2300:     case OPC_VR54XX_MULSHIU:
1.1.1.7   root     2301:         gen_helper_mulshiu(t0, t0, t1);
1.1.1.6   root     2302:         opn = "mulshiu";
1.1.1.7   root     2303:         break;
1.1.1.6   root     2304:     case OPC_VR54XX_MACCHI:
1.1.1.7   root     2305:         gen_helper_macchi(t0, t0, t1);
1.1.1.6   root     2306:         opn = "macchi";
1.1.1.7   root     2307:         break;
1.1.1.6   root     2308:     case OPC_VR54XX_MACCHIU:
1.1.1.7   root     2309:         gen_helper_macchiu(t0, t0, t1);
1.1.1.6   root     2310:         opn = "macchiu";
1.1.1.7   root     2311:         break;
1.1.1.6   root     2312:     case OPC_VR54XX_MSACHI:
1.1.1.7   root     2313:         gen_helper_msachi(t0, t0, t1);
1.1.1.6   root     2314:         opn = "msachi";
1.1.1.7   root     2315:         break;
1.1.1.6   root     2316:     case OPC_VR54XX_MSACHIU:
1.1.1.7   root     2317:         gen_helper_msachiu(t0, t0, t1);
1.1.1.6   root     2318:         opn = "msachiu";
1.1.1.7   root     2319:         break;
1.1.1.6   root     2320:     default:
                   2321:         MIPS_INVAL("mul vr54xx");
                   2322:         generate_exception(ctx, EXCP_RI);
1.1.1.7   root     2323:         goto out;
1.1.1.6   root     2324:     }
1.1.1.7   root     2325:     gen_store_gpr(t0, rd);
1.1.1.13! root     2326:     (void)opn; /* avoid a compiler warning */
1.1.1.6   root     2327:     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1.1.1.7   root     2328: 
                   2329:  out:
                   2330:     tcg_temp_free(t0);
                   2331:     tcg_temp_free(t1);
1.1.1.6   root     2332: }
                   2333: 
1.1.1.5   root     2334: static void gen_cl (DisasContext *ctx, uint32_t opc,
1.1       root     2335:                     int rd, int rs)
                   2336: {
1.1.1.6   root     2337:     const char *opn = "CLx";
1.1.1.8   root     2338:     TCGv t0;
1.1.1.7   root     2339: 
1.1       root     2340:     if (rd == 0) {
1.1.1.6   root     2341:         /* Treat as NOP. */
1.1       root     2342:         MIPS_DEBUG("NOP");
1.1.1.8   root     2343:         return;
1.1       root     2344:     }
1.1.1.8   root     2345:     t0 = tcg_temp_new();
1.1.1.7   root     2346:     gen_load_gpr(t0, rs);
1.1       root     2347:     switch (opc) {
                   2348:     case OPC_CLO:
1.1.1.8   root     2349:         gen_helper_clo(cpu_gpr[rd], t0);
1.1       root     2350:         opn = "clo";
                   2351:         break;
                   2352:     case OPC_CLZ:
1.1.1.8   root     2353:         gen_helper_clz(cpu_gpr[rd], t0);
1.1       root     2354:         opn = "clz";
                   2355:         break;
1.1.1.6   root     2356: #if defined(TARGET_MIPS64)
1.1.1.5   root     2357:     case OPC_DCLO:
1.1.1.8   root     2358:         gen_helper_dclo(cpu_gpr[rd], t0);
1.1.1.5   root     2359:         opn = "dclo";
                   2360:         break;
                   2361:     case OPC_DCLZ:
1.1.1.8   root     2362:         gen_helper_dclz(cpu_gpr[rd], t0);
1.1.1.5   root     2363:         opn = "dclz";
                   2364:         break;
                   2365: #endif
1.1       root     2366:     }
1.1.1.13! root     2367:     (void)opn; /* avoid a compiler warning */
1.1       root     2368:     MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
1.1.1.7   root     2369:     tcg_temp_free(t0);
1.1       root     2370: }
                   2371: 
1.1.1.12  root     2372: /* Godson integer instructions */
                   2373: static void gen_loongson_integer (DisasContext *ctx, uint32_t opc,
                   2374:                                 int rd, int rs, int rt)
                   2375: {
                   2376:     const char *opn = "loongson";
                   2377:     TCGv t0, t1;
                   2378: 
                   2379:     if (rd == 0) {
                   2380:         /* Treat as NOP. */
                   2381:         MIPS_DEBUG("NOP");
                   2382:         return;
                   2383:     }
                   2384: 
                   2385:     switch (opc) {
                   2386:     case OPC_MULT_G_2E:
                   2387:     case OPC_MULT_G_2F:
                   2388:     case OPC_MULTU_G_2E:
                   2389:     case OPC_MULTU_G_2F:
                   2390: #if defined(TARGET_MIPS64)
                   2391:     case OPC_DMULT_G_2E:
                   2392:     case OPC_DMULT_G_2F:
                   2393:     case OPC_DMULTU_G_2E:
                   2394:     case OPC_DMULTU_G_2F:
                   2395: #endif
                   2396:         t0 = tcg_temp_new();
                   2397:         t1 = tcg_temp_new();
                   2398:         break;
                   2399:     default:
                   2400:         t0 = tcg_temp_local_new();
                   2401:         t1 = tcg_temp_local_new();
                   2402:         break;
                   2403:     }
                   2404: 
                   2405:     gen_load_gpr(t0, rs);
                   2406:     gen_load_gpr(t1, rt);
                   2407: 
                   2408:     switch (opc) {
                   2409:     case OPC_MULT_G_2E:
                   2410:     case OPC_MULT_G_2F:
                   2411:         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
                   2412:         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
                   2413:         opn = "mult.g";
                   2414:         break;
                   2415:     case OPC_MULTU_G_2E:
                   2416:     case OPC_MULTU_G_2F:
                   2417:         tcg_gen_ext32u_tl(t0, t0);
                   2418:         tcg_gen_ext32u_tl(t1, t1);
                   2419:         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
                   2420:         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
                   2421:         opn = "multu.g";
                   2422:         break;
                   2423:     case OPC_DIV_G_2E:
                   2424:     case OPC_DIV_G_2F:
                   2425:         {
                   2426:             int l1 = gen_new_label();
                   2427:             int l2 = gen_new_label();
                   2428:             int l3 = gen_new_label();
                   2429:             tcg_gen_ext32s_tl(t0, t0);
                   2430:             tcg_gen_ext32s_tl(t1, t1);
                   2431:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
                   2432:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   2433:             tcg_gen_br(l3);
                   2434:             gen_set_label(l1);
                   2435:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
                   2436:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
                   2437:             tcg_gen_mov_tl(cpu_gpr[rd], t0);
                   2438:             tcg_gen_br(l3);
                   2439:             gen_set_label(l2);
                   2440:             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
                   2441:             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
                   2442:             gen_set_label(l3);
                   2443:         }
                   2444:         opn = "div.g";
                   2445:         break;
                   2446:     case OPC_DIVU_G_2E:
                   2447:     case OPC_DIVU_G_2F:
                   2448:         {
                   2449:             int l1 = gen_new_label();
                   2450:             int l2 = gen_new_label();
                   2451:             tcg_gen_ext32u_tl(t0, t0);
                   2452:             tcg_gen_ext32u_tl(t1, t1);
                   2453:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
                   2454:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   2455:             tcg_gen_br(l2);
                   2456:             gen_set_label(l1);
                   2457:             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
                   2458:             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
                   2459:             gen_set_label(l2);
                   2460:         }
                   2461:         opn = "divu.g";
                   2462:         break;
                   2463:     case OPC_MOD_G_2E:
                   2464:     case OPC_MOD_G_2F:
                   2465:         {
                   2466:             int l1 = gen_new_label();
                   2467:             int l2 = gen_new_label();
                   2468:             int l3 = gen_new_label();
                   2469:             tcg_gen_ext32u_tl(t0, t0);
                   2470:             tcg_gen_ext32u_tl(t1, t1);
                   2471:             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
                   2472:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
                   2473:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
                   2474:             gen_set_label(l1);
                   2475:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   2476:             tcg_gen_br(l3);
                   2477:             gen_set_label(l2);
                   2478:             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
                   2479:             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
                   2480:             gen_set_label(l3);
                   2481:         }
                   2482:         opn = "mod.g";
                   2483:         break;
                   2484:     case OPC_MODU_G_2E:
                   2485:     case OPC_MODU_G_2F:
                   2486:         {
                   2487:             int l1 = gen_new_label();
                   2488:             int l2 = gen_new_label();
                   2489:             tcg_gen_ext32u_tl(t0, t0);
                   2490:             tcg_gen_ext32u_tl(t1, t1);
                   2491:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
                   2492:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   2493:             tcg_gen_br(l2);
                   2494:             gen_set_label(l1);
                   2495:             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
                   2496:             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
                   2497:             gen_set_label(l2);
                   2498:         }
                   2499:         opn = "modu.g";
                   2500:         break;
                   2501: #if defined(TARGET_MIPS64)
                   2502:     case OPC_DMULT_G_2E:
                   2503:     case OPC_DMULT_G_2F:
                   2504:         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
                   2505:         opn = "dmult.g";
                   2506:         break;
                   2507:     case OPC_DMULTU_G_2E:
                   2508:     case OPC_DMULTU_G_2F:
                   2509:         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
                   2510:         opn = "dmultu.g";
                   2511:         break;
                   2512:     case OPC_DDIV_G_2E:
                   2513:     case OPC_DDIV_G_2F:
                   2514:         {
                   2515:             int l1 = gen_new_label();
                   2516:             int l2 = gen_new_label();
                   2517:             int l3 = gen_new_label();
                   2518:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
                   2519:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   2520:             tcg_gen_br(l3);
                   2521:             gen_set_label(l1);
                   2522:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
                   2523:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
                   2524:             tcg_gen_mov_tl(cpu_gpr[rd], t0);
                   2525:             tcg_gen_br(l3);
                   2526:             gen_set_label(l2);
                   2527:             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
                   2528:             gen_set_label(l3);
                   2529:         }
                   2530:         opn = "ddiv.g";
                   2531:         break;
                   2532:     case OPC_DDIVU_G_2E:
                   2533:     case OPC_DDIVU_G_2F:
                   2534:         {
                   2535:             int l1 = gen_new_label();
                   2536:             int l2 = gen_new_label();
                   2537:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
                   2538:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   2539:             tcg_gen_br(l2);
                   2540:             gen_set_label(l1);
                   2541:             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
                   2542:             gen_set_label(l2);
                   2543:         }
                   2544:         opn = "ddivu.g";
                   2545:         break;
                   2546:     case OPC_DMOD_G_2E:
                   2547:     case OPC_DMOD_G_2F:
                   2548:         {
                   2549:             int l1 = gen_new_label();
                   2550:             int l2 = gen_new_label();
                   2551:             int l3 = gen_new_label();
                   2552:             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
                   2553:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
                   2554:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
                   2555:             gen_set_label(l1);
                   2556:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   2557:             tcg_gen_br(l3);
                   2558:             gen_set_label(l2);
                   2559:             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
                   2560:             gen_set_label(l3);
                   2561:         }
                   2562:         opn = "dmod.g";
                   2563:         break;
                   2564:     case OPC_DMODU_G_2E:
                   2565:     case OPC_DMODU_G_2F:
                   2566:         {
                   2567:             int l1 = gen_new_label();
                   2568:             int l2 = gen_new_label();
                   2569:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
                   2570:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   2571:             tcg_gen_br(l2);
                   2572:             gen_set_label(l1);
                   2573:             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
                   2574:             gen_set_label(l2);
                   2575:         }
                   2576:         opn = "dmodu.g";
                   2577:         break;
                   2578: #endif
                   2579:     }
                   2580: 
1.1.1.13! root     2581:     (void)opn; /* avoid a compiler warning */
1.1.1.12  root     2582:     MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
                   2583:     tcg_temp_free(t0);
                   2584:     tcg_temp_free(t1);
                   2585: }
                   2586: 
                   2587: /* Traps */
1.1.1.5   root     2588: static void gen_trap (DisasContext *ctx, uint32_t opc,
1.1       root     2589:                       int rs, int rt, int16_t imm)
                   2590: {
                   2591:     int cond;
1.1.1.8   root     2592:     TCGv t0 = tcg_temp_new();
                   2593:     TCGv t1 = tcg_temp_new();
1.1       root     2594: 
                   2595:     cond = 0;
                   2596:     /* Load needed operands */
                   2597:     switch (opc) {
                   2598:     case OPC_TEQ:
                   2599:     case OPC_TGE:
                   2600:     case OPC_TGEU:
                   2601:     case OPC_TLT:
                   2602:     case OPC_TLTU:
                   2603:     case OPC_TNE:
                   2604:         /* Compare two registers */
                   2605:         if (rs != rt) {
1.1.1.7   root     2606:             gen_load_gpr(t0, rs);
                   2607:             gen_load_gpr(t1, rt);
1.1       root     2608:             cond = 1;
                   2609:         }
1.1.1.5   root     2610:         break;
1.1       root     2611:     case OPC_TEQI:
                   2612:     case OPC_TGEI:
                   2613:     case OPC_TGEIU:
                   2614:     case OPC_TLTI:
                   2615:     case OPC_TLTIU:
                   2616:     case OPC_TNEI:
                   2617:         /* Compare register to immediate */
                   2618:         if (rs != 0 || imm != 0) {
1.1.1.7   root     2619:             gen_load_gpr(t0, rs);
                   2620:             tcg_gen_movi_tl(t1, (int32_t)imm);
1.1       root     2621:             cond = 1;
                   2622:         }
                   2623:         break;
                   2624:     }
                   2625:     if (cond == 0) {
                   2626:         switch (opc) {
                   2627:         case OPC_TEQ:   /* rs == rs */
                   2628:         case OPC_TEQI:  /* r0 == 0  */
                   2629:         case OPC_TGE:   /* rs >= rs */
                   2630:         case OPC_TGEI:  /* r0 >= 0  */
                   2631:         case OPC_TGEU:  /* rs >= rs unsigned */
                   2632:         case OPC_TGEIU: /* r0 >= 0  unsigned */
                   2633:             /* Always trap */
1.1.1.8   root     2634:             generate_exception(ctx, EXCP_TRAP);
1.1       root     2635:             break;
                   2636:         case OPC_TLT:   /* rs < rs           */
                   2637:         case OPC_TLTI:  /* r0 < 0            */
                   2638:         case OPC_TLTU:  /* rs < rs unsigned  */
                   2639:         case OPC_TLTIU: /* r0 < 0  unsigned  */
                   2640:         case OPC_TNE:   /* rs != rs          */
                   2641:         case OPC_TNEI:  /* r0 != 0           */
1.1.1.6   root     2642:             /* Never trap: treat as NOP. */
1.1.1.8   root     2643:             break;
1.1       root     2644:         }
                   2645:     } else {
1.1.1.8   root     2646:         int l1 = gen_new_label();
                   2647: 
1.1       root     2648:         switch (opc) {
                   2649:         case OPC_TEQ:
                   2650:         case OPC_TEQI:
1.1.1.8   root     2651:             tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
1.1       root     2652:             break;
                   2653:         case OPC_TGE:
                   2654:         case OPC_TGEI:
1.1.1.8   root     2655:             tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
1.1       root     2656:             break;
                   2657:         case OPC_TGEU:
                   2658:         case OPC_TGEIU:
1.1.1.8   root     2659:             tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
1.1       root     2660:             break;
                   2661:         case OPC_TLT:
                   2662:         case OPC_TLTI:
1.1.1.8   root     2663:             tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
1.1       root     2664:             break;
                   2665:         case OPC_TLTU:
                   2666:         case OPC_TLTIU:
1.1.1.8   root     2667:             tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
1.1       root     2668:             break;
                   2669:         case OPC_TNE:
                   2670:         case OPC_TNEI:
1.1.1.8   root     2671:             tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
1.1       root     2672:             break;
                   2673:         }
1.1.1.8   root     2674:         generate_exception(ctx, EXCP_TRAP);
1.1.1.7   root     2675:         gen_set_label(l1);
                   2676:     }
                   2677:     tcg_temp_free(t0);
                   2678:     tcg_temp_free(t1);
1.1       root     2679: }
                   2680: 
1.1.1.7   root     2681: static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1.1.1.2   root     2682: {
                   2683:     TranslationBlock *tb;
                   2684:     tb = ctx->tb;
1.1.1.9   root     2685:     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
                   2686:         likely(!ctx->singlestep_enabled)) {
1.1.1.7   root     2687:         tcg_gen_goto_tb(n);
1.1.1.6   root     2688:         gen_save_pc(dest);
1.1.1.7   root     2689:         tcg_gen_exit_tb((long)tb + n);
1.1.1.2   root     2690:     } else {
1.1.1.6   root     2691:         gen_save_pc(dest);
1.1.1.9   root     2692:         if (ctx->singlestep_enabled) {
                   2693:             save_cpu_state(ctx, 0);
                   2694:             gen_helper_0i(raise_exception, EXCP_DEBUG);
                   2695:         }
1.1.1.7   root     2696:         tcg_gen_exit_tb(0);
1.1.1.2   root     2697:     }
                   2698: }
                   2699: 
1.1       root     2700: /* Branches (before delay slot) */
1.1.1.5   root     2701: static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1.1.1.12  root     2702:                                 int insn_bytes,
1.1       root     2703:                                 int rs, int rt, int32_t offset)
                   2704: {
1.1.1.7   root     2705:     target_ulong btgt = -1;
1.1.1.6   root     2706:     int blink = 0;
1.1.1.7   root     2707:     int bcond_compute = 0;
1.1.1.8   root     2708:     TCGv t0 = tcg_temp_new();
                   2709:     TCGv t1 = tcg_temp_new();
1.1       root     2710: 
1.1.1.6   root     2711:     if (ctx->hflags & MIPS_HFLAG_BMASK) {
                   2712: #ifdef MIPS_DEBUG_DISAS
1.1.1.7   root     2713:         LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
1.1.1.6   root     2714: #endif
                   2715:         generate_exception(ctx, EXCP_RI);
1.1.1.7   root     2716:         goto out;
1.1.1.6   root     2717:     }
                   2718: 
                   2719:     /* Load needed operands */
                   2720:     switch (opc) {
                   2721:     case OPC_BEQ:
                   2722:     case OPC_BEQL:
                   2723:     case OPC_BNE:
                   2724:     case OPC_BNEL:
1.1       root     2725:         /* Compare two registers */
                   2726:         if (rs != rt) {
1.1.1.7   root     2727:             gen_load_gpr(t0, rs);
                   2728:             gen_load_gpr(t1, rt);
                   2729:             bcond_compute = 1;
1.1       root     2730:         }
1.1.1.12  root     2731:         btgt = ctx->pc + insn_bytes + offset;
1.1       root     2732:         break;
                   2733:     case OPC_BGEZ:
                   2734:     case OPC_BGEZAL:
1.1.1.12  root     2735:     case OPC_BGEZALS:
1.1       root     2736:     case OPC_BGEZALL:
                   2737:     case OPC_BGEZL:
                   2738:     case OPC_BGTZ:
                   2739:     case OPC_BGTZL:
                   2740:     case OPC_BLEZ:
                   2741:     case OPC_BLEZL:
                   2742:     case OPC_BLTZ:
                   2743:     case OPC_BLTZAL:
1.1.1.12  root     2744:     case OPC_BLTZALS:
1.1       root     2745:     case OPC_BLTZALL:
                   2746:     case OPC_BLTZL:
                   2747:         /* Compare to zero */
                   2748:         if (rs != 0) {
1.1.1.7   root     2749:             gen_load_gpr(t0, rs);
                   2750:             bcond_compute = 1;
1.1       root     2751:         }
1.1.1.12  root     2752:         btgt = ctx->pc + insn_bytes + offset;
1.1       root     2753:         break;
                   2754:     case OPC_J:
                   2755:     case OPC_JAL:
1.1.1.12  root     2756:     case OPC_JALX:
                   2757:     case OPC_JALS:
                   2758:     case OPC_JALXS:
1.1       root     2759:         /* Jump to immediate */
1.1.1.12  root     2760:         btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
1.1       root     2761:         break;
                   2762:     case OPC_JR:
                   2763:     case OPC_JALR:
1.1.1.12  root     2764:     case OPC_JALRC:
                   2765:     case OPC_JALRS:
1.1       root     2766:         /* Jump to register */
1.1.1.5   root     2767:         if (offset != 0 && offset != 16) {
                   2768:             /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
1.1.1.6   root     2769:                others are reserved. */
                   2770:             MIPS_INVAL("jump hint");
1.1       root     2771:             generate_exception(ctx, EXCP_RI);
1.1.1.7   root     2772:             goto out;
1.1       root     2773:         }
1.1.1.7   root     2774:         gen_load_gpr(btarget, rs);
1.1       root     2775:         break;
                   2776:     default:
                   2777:         MIPS_INVAL("branch/jump");
                   2778:         generate_exception(ctx, EXCP_RI);
1.1.1.7   root     2779:         goto out;
1.1       root     2780:     }
1.1.1.7   root     2781:     if (bcond_compute == 0) {
1.1       root     2782:         /* No condition to be computed */
                   2783:         switch (opc) {
                   2784:         case OPC_BEQ:     /* rx == rx        */
                   2785:         case OPC_BEQL:    /* rx == rx likely */
                   2786:         case OPC_BGEZ:    /* 0 >= 0          */
                   2787:         case OPC_BGEZL:   /* 0 >= 0 likely   */
                   2788:         case OPC_BLEZ:    /* 0 <= 0          */
                   2789:         case OPC_BLEZL:   /* 0 <= 0 likely   */
                   2790:             /* Always take */
1.1.1.2   root     2791:             ctx->hflags |= MIPS_HFLAG_B;
1.1       root     2792:             MIPS_DEBUG("balways");
                   2793:             break;
1.1.1.12  root     2794:         case OPC_BGEZALS:
1.1       root     2795:         case OPC_BGEZAL:  /* 0 >= 0          */
                   2796:         case OPC_BGEZALL: /* 0 >= 0 likely   */
1.1.1.12  root     2797:             ctx->hflags |= (opc == OPC_BGEZALS
                   2798:                             ? MIPS_HFLAG_BDS16
                   2799:                             : MIPS_HFLAG_BDS32);
1.1       root     2800:             /* Always take and link */
                   2801:             blink = 31;
1.1.1.2   root     2802:             ctx->hflags |= MIPS_HFLAG_B;
1.1       root     2803:             MIPS_DEBUG("balways and link");
                   2804:             break;
                   2805:         case OPC_BNE:     /* rx != rx        */
                   2806:         case OPC_BGTZ:    /* 0 > 0           */
                   2807:         case OPC_BLTZ:    /* 0 < 0           */
1.1.1.6   root     2808:             /* Treat as NOP. */
1.1       root     2809:             MIPS_DEBUG("bnever (NOP)");
1.1.1.7   root     2810:             goto out;
1.1.1.12  root     2811:         case OPC_BLTZALS:
1.1.1.2   root     2812:         case OPC_BLTZAL:  /* 0 < 0           */
1.1.1.12  root     2813:             ctx->hflags |= (opc == OPC_BLTZALS
                   2814:                             ? MIPS_HFLAG_BDS16
                   2815:                             : MIPS_HFLAG_BDS32);
                   2816:             /* Handle as an unconditional branch to get correct delay
                   2817:                slot checking.  */
                   2818:             blink = 31;
                   2819:             btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
                   2820:             ctx->hflags |= MIPS_HFLAG_B;
1.1.1.6   root     2821:             MIPS_DEBUG("bnever and link");
1.1.1.12  root     2822:             break;
1.1.1.2   root     2823:         case OPC_BLTZALL: /* 0 < 0 likely */
1.1.1.8   root     2824:             tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
1.1.1.6   root     2825:             /* Skip the instruction in the delay slot */
                   2826:             MIPS_DEBUG("bnever, link and skip");
                   2827:             ctx->pc += 4;
1.1.1.7   root     2828:             goto out;
1.1       root     2829:         case OPC_BNEL:    /* rx != rx likely */
                   2830:         case OPC_BGTZL:   /* 0 > 0 likely */
                   2831:         case OPC_BLTZL:   /* 0 < 0 likely */
                   2832:             /* Skip the instruction in the delay slot */
                   2833:             MIPS_DEBUG("bnever and skip");
1.1.1.6   root     2834:             ctx->pc += 4;
1.1.1.7   root     2835:             goto out;
1.1       root     2836:         case OPC_J:
1.1.1.2   root     2837:             ctx->hflags |= MIPS_HFLAG_B;
1.1.1.7   root     2838:             MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
1.1       root     2839:             break;
1.1.1.12  root     2840:         case OPC_JALXS:
                   2841:         case OPC_JALX:
                   2842:             ctx->hflags |= MIPS_HFLAG_BX;
                   2843:             /* Fallthrough */
                   2844:         case OPC_JALS:
1.1       root     2845:         case OPC_JAL:
                   2846:             blink = 31;
1.1.1.2   root     2847:             ctx->hflags |= MIPS_HFLAG_B;
1.1.1.12  root     2848:             ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
                   2849:                             ? MIPS_HFLAG_BDS16
                   2850:                             : MIPS_HFLAG_BDS32);
1.1.1.7   root     2851:             MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
1.1       root     2852:             break;
                   2853:         case OPC_JR:
1.1.1.2   root     2854:             ctx->hflags |= MIPS_HFLAG_BR;
1.1.1.12  root     2855:             if (insn_bytes == 4)
                   2856:                 ctx->hflags |= MIPS_HFLAG_BDS32;
1.1       root     2857:             MIPS_DEBUG("jr %s", regnames[rs]);
                   2858:             break;
1.1.1.12  root     2859:         case OPC_JALRS:
1.1       root     2860:         case OPC_JALR:
1.1.1.12  root     2861:         case OPC_JALRC:
1.1       root     2862:             blink = rt;
1.1.1.2   root     2863:             ctx->hflags |= MIPS_HFLAG_BR;
1.1.1.12  root     2864:             ctx->hflags |= (opc == OPC_JALRS
                   2865:                             ? MIPS_HFLAG_BDS16
                   2866:                             : MIPS_HFLAG_BDS32);
1.1       root     2867:             MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
                   2868:             break;
                   2869:         default:
                   2870:             MIPS_INVAL("branch/jump");
                   2871:             generate_exception(ctx, EXCP_RI);
1.1.1.7   root     2872:             goto out;
1.1       root     2873:         }
                   2874:     } else {
                   2875:         switch (opc) {
                   2876:         case OPC_BEQ:
1.1.1.12  root     2877:             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
1.1.1.6   root     2878:             MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
1.1.1.7   root     2879:                        regnames[rs], regnames[rt], btgt);
1.1       root     2880:             goto not_likely;
                   2881:         case OPC_BEQL:
1.1.1.12  root     2882:             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
1.1.1.6   root     2883:             MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
1.1.1.7   root     2884:                        regnames[rs], regnames[rt], btgt);
1.1       root     2885:             goto likely;
                   2886:         case OPC_BNE:
1.1.1.12  root     2887:             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
1.1.1.6   root     2888:             MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
1.1.1.7   root     2889:                        regnames[rs], regnames[rt], btgt);
1.1       root     2890:             goto not_likely;
                   2891:         case OPC_BNEL:
1.1.1.12  root     2892:             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
1.1.1.6   root     2893:             MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
1.1.1.7   root     2894:                        regnames[rs], regnames[rt], btgt);
1.1       root     2895:             goto likely;
                   2896:         case OPC_BGEZ:
1.1.1.12  root     2897:             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
1.1.1.7   root     2898:             MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2899:             goto not_likely;
                   2900:         case OPC_BGEZL:
1.1.1.12  root     2901:             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
1.1.1.7   root     2902:             MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2903:             goto likely;
1.1.1.12  root     2904:         case OPC_BGEZALS:
1.1       root     2905:         case OPC_BGEZAL:
1.1.1.12  root     2906:             ctx->hflags |= (opc == OPC_BGEZALS
                   2907:                             ? MIPS_HFLAG_BDS16
                   2908:                             : MIPS_HFLAG_BDS32);
                   2909:             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
1.1.1.7   root     2910:             MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2911:             blink = 31;
                   2912:             goto not_likely;
                   2913:         case OPC_BGEZALL:
1.1.1.12  root     2914:             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
1.1       root     2915:             blink = 31;
1.1.1.7   root     2916:             MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2917:             goto likely;
                   2918:         case OPC_BGTZ:
1.1.1.12  root     2919:             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
1.1.1.7   root     2920:             MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2921:             goto not_likely;
                   2922:         case OPC_BGTZL:
1.1.1.12  root     2923:             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
1.1.1.7   root     2924:             MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2925:             goto likely;
                   2926:         case OPC_BLEZ:
1.1.1.12  root     2927:             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
1.1.1.7   root     2928:             MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2929:             goto not_likely;
                   2930:         case OPC_BLEZL:
1.1.1.12  root     2931:             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
1.1.1.7   root     2932:             MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2933:             goto likely;
                   2934:         case OPC_BLTZ:
1.1.1.12  root     2935:             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
1.1.1.7   root     2936:             MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2937:             goto not_likely;
                   2938:         case OPC_BLTZL:
1.1.1.12  root     2939:             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
1.1.1.7   root     2940:             MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2941:             goto likely;
1.1.1.12  root     2942:         case OPC_BLTZALS:
1.1       root     2943:         case OPC_BLTZAL:
1.1.1.12  root     2944:             ctx->hflags |= (opc == OPC_BLTZALS
                   2945:                             ? MIPS_HFLAG_BDS16
                   2946:                             : MIPS_HFLAG_BDS32);
                   2947:             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
1.1       root     2948:             blink = 31;
1.1.1.7   root     2949:             MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2950:         not_likely:
1.1.1.2   root     2951:             ctx->hflags |= MIPS_HFLAG_BC;
1.1       root     2952:             break;
                   2953:         case OPC_BLTZALL:
1.1.1.12  root     2954:             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
1.1       root     2955:             blink = 31;
1.1.1.7   root     2956:             MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2957:         likely:
1.1.1.2   root     2958:             ctx->hflags |= MIPS_HFLAG_BL;
1.1       root     2959:             break;
1.1.1.6   root     2960:         default:
                   2961:             MIPS_INVAL("conditional branch/jump");
                   2962:             generate_exception(ctx, EXCP_RI);
1.1.1.7   root     2963:             goto out;
1.1       root     2964:         }
                   2965:     }
1.1.1.6   root     2966:     MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
1.1.1.7   root     2967:                blink, ctx->hflags, btgt);
1.1.1.6   root     2968: 
1.1.1.7   root     2969:     ctx->btarget = btgt;
1.1       root     2970:     if (blink > 0) {
1.1.1.12  root     2971:         int post_delay = insn_bytes;
                   2972:         int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
                   2973: 
                   2974:         if (opc != OPC_JALRC)
                   2975:             post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
                   2976: 
                   2977:         tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
1.1       root     2978:     }
1.1.1.7   root     2979: 
                   2980:  out:
1.1.1.12  root     2981:     if (insn_bytes == 2)
                   2982:         ctx->hflags |= MIPS_HFLAG_B16;
1.1.1.7   root     2983:     tcg_temp_free(t0);
                   2984:     tcg_temp_free(t1);
1.1       root     2985: }
                   2986: 
1.1.1.5   root     2987: /* special3 bitfield operations */
                   2988: static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
1.1.1.7   root     2989:                         int rs, int lsb, int msb)
1.1       root     2990: {
1.1.1.7   root     2991:     TCGv t0 = tcg_temp_new();
                   2992:     TCGv t1 = tcg_temp_new();
                   2993:     target_ulong mask;
                   2994: 
                   2995:     gen_load_gpr(t1, rs);
1.1.1.5   root     2996:     switch (opc) {
                   2997:     case OPC_EXT:
                   2998:         if (lsb + msb > 31)
                   2999:             goto fail;
1.1.1.7   root     3000:         tcg_gen_shri_tl(t0, t1, lsb);
                   3001:         if (msb != 31) {
                   3002:             tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
                   3003:         } else {
                   3004:             tcg_gen_ext32s_tl(t0, t0);
                   3005:         }
1.1.1.5   root     3006:         break;
1.1.1.6   root     3007: #if defined(TARGET_MIPS64)
1.1.1.5   root     3008:     case OPC_DEXTM:
1.1.1.7   root     3009:         tcg_gen_shri_tl(t0, t1, lsb);
                   3010:         if (msb != 31) {
                   3011:             tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
                   3012:         }
1.1.1.5   root     3013:         break;
                   3014:     case OPC_DEXTU:
1.1.1.7   root     3015:         tcg_gen_shri_tl(t0, t1, lsb + 32);
                   3016:         tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
1.1.1.5   root     3017:         break;
                   3018:     case OPC_DEXT:
1.1.1.7   root     3019:         tcg_gen_shri_tl(t0, t1, lsb);
                   3020:         tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
1.1.1.5   root     3021:         break;
1.1.1.6   root     3022: #endif
1.1.1.5   root     3023:     case OPC_INS:
                   3024:         if (lsb > msb)
                   3025:             goto fail;
1.1.1.7   root     3026:         mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
                   3027:         gen_load_gpr(t0, rt);
                   3028:         tcg_gen_andi_tl(t0, t0, ~mask);
                   3029:         tcg_gen_shli_tl(t1, t1, lsb);
                   3030:         tcg_gen_andi_tl(t1, t1, mask);
                   3031:         tcg_gen_or_tl(t0, t0, t1);
                   3032:         tcg_gen_ext32s_tl(t0, t0);
1.1.1.5   root     3033:         break;
1.1.1.6   root     3034: #if defined(TARGET_MIPS64)
1.1.1.5   root     3035:     case OPC_DINSM:
                   3036:         if (lsb > msb)
                   3037:             goto fail;
1.1.1.7   root     3038:         mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
                   3039:         gen_load_gpr(t0, rt);
                   3040:         tcg_gen_andi_tl(t0, t0, ~mask);
                   3041:         tcg_gen_shli_tl(t1, t1, lsb);
                   3042:         tcg_gen_andi_tl(t1, t1, mask);
                   3043:         tcg_gen_or_tl(t0, t0, t1);
1.1.1.5   root     3044:         break;
                   3045:     case OPC_DINSU:
                   3046:         if (lsb > msb)
                   3047:             goto fail;
1.1.1.11  root     3048:         mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
1.1.1.7   root     3049:         gen_load_gpr(t0, rt);
                   3050:         tcg_gen_andi_tl(t0, t0, ~mask);
                   3051:         tcg_gen_shli_tl(t1, t1, lsb + 32);
                   3052:         tcg_gen_andi_tl(t1, t1, mask);
                   3053:         tcg_gen_or_tl(t0, t0, t1);
1.1.1.5   root     3054:         break;
                   3055:     case OPC_DINS:
                   3056:         if (lsb > msb)
                   3057:             goto fail;
1.1.1.7   root     3058:         gen_load_gpr(t0, rt);
                   3059:         mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
                   3060:         gen_load_gpr(t0, rt);
                   3061:         tcg_gen_andi_tl(t0, t0, ~mask);
                   3062:         tcg_gen_shli_tl(t1, t1, lsb);
                   3063:         tcg_gen_andi_tl(t1, t1, mask);
                   3064:         tcg_gen_or_tl(t0, t0, t1);
1.1.1.5   root     3065:         break;
1.1.1.6   root     3066: #endif
1.1.1.5   root     3067:     default:
                   3068: fail:
                   3069:         MIPS_INVAL("bitops");
                   3070:         generate_exception(ctx, EXCP_RI);
1.1.1.7   root     3071:         tcg_temp_free(t0);
                   3072:         tcg_temp_free(t1);
1.1       root     3073:         return;
                   3074:     }
1.1.1.7   root     3075:     gen_store_gpr(t0, rt);
                   3076:     tcg_temp_free(t0);
                   3077:     tcg_temp_free(t1);
                   3078: }
                   3079: 
                   3080: static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
                   3081: {
1.1.1.8   root     3082:     TCGv t0;
1.1.1.7   root     3083: 
1.1.1.8   root     3084:     if (rd == 0) {
                   3085:         /* If no destination, treat it as a NOP. */
                   3086:         MIPS_DEBUG("NOP");
                   3087:         return;
                   3088:     }
                   3089: 
                   3090:     t0 = tcg_temp_new();
                   3091:     gen_load_gpr(t0, rt);
1.1.1.7   root     3092:     switch (op2) {
                   3093:     case OPC_WSBH:
1.1.1.8   root     3094:         {
                   3095:             TCGv t1 = tcg_temp_new();
                   3096: 
                   3097:             tcg_gen_shri_tl(t1, t0, 8);
                   3098:             tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
                   3099:             tcg_gen_shli_tl(t0, t0, 8);
                   3100:             tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
                   3101:             tcg_gen_or_tl(t0, t0, t1);
                   3102:             tcg_temp_free(t1);
                   3103:             tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
                   3104:         }
1.1.1.7   root     3105:         break;
                   3106:     case OPC_SEB:
1.1.1.8   root     3107:         tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
1.1.1.7   root     3108:         break;
                   3109:     case OPC_SEH:
1.1.1.8   root     3110:         tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
1.1.1.7   root     3111:         break;
                   3112: #if defined(TARGET_MIPS64)
                   3113:     case OPC_DSBH:
1.1.1.8   root     3114:         {
                   3115:             TCGv t1 = tcg_temp_new();
                   3116: 
                   3117:             tcg_gen_shri_tl(t1, t0, 8);
                   3118:             tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
                   3119:             tcg_gen_shli_tl(t0, t0, 8);
                   3120:             tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
                   3121:             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
                   3122:             tcg_temp_free(t1);
                   3123:         }
1.1.1.7   root     3124:         break;
                   3125:     case OPC_DSHD:
1.1.1.8   root     3126:         {
                   3127:             TCGv t1 = tcg_temp_new();
                   3128: 
                   3129:             tcg_gen_shri_tl(t1, t0, 16);
                   3130:             tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
                   3131:             tcg_gen_shli_tl(t0, t0, 16);
                   3132:             tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
                   3133:             tcg_gen_or_tl(t0, t0, t1);
                   3134:             tcg_gen_shri_tl(t1, t0, 32);
                   3135:             tcg_gen_shli_tl(t0, t0, 32);
                   3136:             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
                   3137:             tcg_temp_free(t1);
                   3138:         }
1.1.1.7   root     3139:         break;
                   3140: #endif
                   3141:     default:
                   3142:         MIPS_INVAL("bsfhl");
                   3143:         generate_exception(ctx, EXCP_RI);
                   3144:         tcg_temp_free(t0);
                   3145:         return;
                   3146:     }
                   3147:     tcg_temp_free(t0);
1.1.1.5   root     3148: }
1.1.1.4   root     3149: 
1.1.1.7   root     3150: #ifndef CONFIG_USER_ONLY
1.1.1.5   root     3151: /* CP0 (MMU and control) */
1.1.1.8   root     3152: static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
1.1.1.7   root     3153: {
1.1.1.8   root     3154:     TCGv_i32 t0 = tcg_temp_new_i32();
1.1.1.7   root     3155: 
1.1.1.8   root     3156:     tcg_gen_ld_i32(t0, cpu_env, off);
                   3157:     tcg_gen_ext_i32_tl(arg, t0);
                   3158:     tcg_temp_free_i32(t0);
1.1.1.7   root     3159: }
                   3160: 
1.1.1.8   root     3161: static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
1.1.1.7   root     3162: {
1.1.1.8   root     3163:     tcg_gen_ld_tl(arg, cpu_env, off);
                   3164:     tcg_gen_ext32s_tl(arg, arg);
1.1.1.7   root     3165: }
                   3166: 
1.1.1.8   root     3167: static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
1.1.1.7   root     3168: {
1.1.1.8   root     3169:     TCGv_i32 t0 = tcg_temp_new_i32();
1.1.1.7   root     3170: 
1.1.1.8   root     3171:     tcg_gen_trunc_tl_i32(t0, arg);
                   3172:     tcg_gen_st_i32(t0, cpu_env, off);
                   3173:     tcg_temp_free_i32(t0);
1.1.1.7   root     3174: }
                   3175: 
1.1.1.8   root     3176: static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
1.1.1.7   root     3177: {
1.1.1.8   root     3178:     tcg_gen_ext32s_tl(arg, arg);
                   3179:     tcg_gen_st_tl(arg, cpu_env, off);
1.1.1.7   root     3180: }
                   3181: 
1.1.1.8   root     3182: static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
1.1.1.5   root     3183: {
                   3184:     const char *rn = "invalid";
                   3185: 
1.1.1.6   root     3186:     if (sel != 0)
                   3187:         check_insn(env, ctx, ISA_MIPS32);
                   3188: 
1.1.1.5   root     3189:     switch (reg) {
                   3190:     case 0:
                   3191:         switch (sel) {
                   3192:         case 0:
1.1.1.8   root     3193:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Index));
1.1.1.5   root     3194:             rn = "Index";
                   3195:             break;
                   3196:         case 1:
1.1.1.6   root     3197:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3198:             gen_helper_mfc0_mvpcontrol(arg);
1.1.1.5   root     3199:             rn = "MVPControl";
1.1.1.6   root     3200:             break;
1.1.1.5   root     3201:         case 2:
1.1.1.6   root     3202:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3203:             gen_helper_mfc0_mvpconf0(arg);
1.1.1.5   root     3204:             rn = "MVPConf0";
1.1.1.6   root     3205:             break;
1.1.1.5   root     3206:         case 3:
1.1.1.6   root     3207:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3208:             gen_helper_mfc0_mvpconf1(arg);
1.1.1.5   root     3209:             rn = "MVPConf1";
1.1.1.6   root     3210:             break;
1.1.1.5   root     3211:         default:
                   3212:             goto die;
1.1       root     3213:         }
                   3214:         break;
1.1.1.5   root     3215:     case 1:
                   3216:         switch (sel) {
                   3217:         case 0:
1.1.1.8   root     3218:             gen_helper_mfc0_random(arg);
1.1.1.5   root     3219:             rn = "Random";
1.1.1.6   root     3220:             break;
1.1.1.5   root     3221:         case 1:
1.1.1.6   root     3222:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3223:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEControl));
1.1.1.5   root     3224:             rn = "VPEControl";
1.1.1.6   root     3225:             break;
1.1.1.5   root     3226:         case 2:
1.1.1.6   root     3227:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3228:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf0));
1.1.1.5   root     3229:             rn = "VPEConf0";
1.1.1.6   root     3230:             break;
1.1.1.5   root     3231:         case 3:
1.1.1.6   root     3232:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3233:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf1));
1.1.1.5   root     3234:             rn = "VPEConf1";
1.1.1.6   root     3235:             break;
1.1.1.5   root     3236:         case 4:
1.1.1.6   root     3237:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3238:             gen_mfc0_load64(arg, offsetof(CPUState, CP0_YQMask));
1.1.1.5   root     3239:             rn = "YQMask";
1.1.1.6   root     3240:             break;
1.1.1.5   root     3241:         case 5:
1.1.1.6   root     3242:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3243:             gen_mfc0_load64(arg, offsetof(CPUState, CP0_VPESchedule));
1.1.1.5   root     3244:             rn = "VPESchedule";
1.1.1.6   root     3245:             break;
1.1.1.5   root     3246:         case 6:
1.1.1.6   root     3247:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3248:             gen_mfc0_load64(arg, offsetof(CPUState, CP0_VPEScheFBack));
1.1.1.5   root     3249:             rn = "VPEScheFBack";
1.1.1.6   root     3250:             break;
1.1.1.5   root     3251:         case 7:
1.1.1.6   root     3252:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3253:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEOpt));
1.1.1.5   root     3254:             rn = "VPEOpt";
1.1.1.6   root     3255:             break;
1.1.1.5   root     3256:         default:
                   3257:             goto die;
                   3258:         }
1.1       root     3259:         break;
1.1.1.5   root     3260:     case 2:
                   3261:         switch (sel) {
                   3262:         case 0:
1.1.1.8   root     3263:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo0));
                   3264:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3265:             rn = "EntryLo0";
                   3266:             break;
                   3267:         case 1:
                   3268:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3269:             gen_helper_mfc0_tcstatus(arg);
1.1.1.6   root     3270:             rn = "TCStatus";
                   3271:             break;
                   3272:         case 2:
                   3273:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3274:             gen_helper_mfc0_tcbind(arg);
1.1.1.6   root     3275:             rn = "TCBind";
                   3276:             break;
1.1.1.5   root     3277:         case 3:
1.1.1.6   root     3278:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3279:             gen_helper_mfc0_tcrestart(arg);
1.1.1.6   root     3280:             rn = "TCRestart";
                   3281:             break;
1.1.1.5   root     3282:         case 4:
1.1.1.6   root     3283:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3284:             gen_helper_mfc0_tchalt(arg);
1.1.1.6   root     3285:             rn = "TCHalt";
                   3286:             break;
1.1.1.5   root     3287:         case 5:
1.1.1.6   root     3288:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3289:             gen_helper_mfc0_tccontext(arg);
1.1.1.6   root     3290:             rn = "TCContext";
                   3291:             break;
1.1.1.5   root     3292:         case 6:
1.1.1.6   root     3293:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3294:             gen_helper_mfc0_tcschedule(arg);
1.1.1.6   root     3295:             rn = "TCSchedule";
                   3296:             break;
1.1.1.5   root     3297:         case 7:
1.1.1.6   root     3298:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3299:             gen_helper_mfc0_tcschefback(arg);
1.1.1.6   root     3300:             rn = "TCScheFBack";
                   3301:             break;
1.1.1.5   root     3302:         default:
                   3303:             goto die;
                   3304:         }
1.1       root     3305:         break;
1.1.1.5   root     3306:     case 3:
                   3307:         switch (sel) {
                   3308:         case 0:
1.1.1.8   root     3309:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo1));
                   3310:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3311:             rn = "EntryLo1";
                   3312:             break;
1.1.1.5   root     3313:         default:
                   3314:             goto die;
1.1.1.6   root     3315:         }
1.1       root     3316:         break;
1.1.1.5   root     3317:     case 4:
                   3318:         switch (sel) {
                   3319:         case 0:
1.1.1.8   root     3320:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_Context));
                   3321:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3322:             rn = "Context";
                   3323:             break;
                   3324:         case 1:
1.1.1.8   root     3325: //            gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
1.1.1.6   root     3326:             rn = "ContextConfig";
                   3327: //            break;
1.1.1.5   root     3328:         default:
                   3329:             goto die;
1.1.1.6   root     3330:         }
1.1       root     3331:         break;
1.1.1.5   root     3332:     case 5:
                   3333:         switch (sel) {
                   3334:         case 0:
1.1.1.8   root     3335:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageMask));
1.1.1.6   root     3336:             rn = "PageMask";
                   3337:             break;
                   3338:         case 1:
                   3339:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3340:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageGrain));
1.1.1.6   root     3341:             rn = "PageGrain";
                   3342:             break;
1.1.1.5   root     3343:         default:
                   3344:             goto die;
1.1.1.6   root     3345:         }
1.1       root     3346:         break;
1.1.1.5   root     3347:     case 6:
                   3348:         switch (sel) {
                   3349:         case 0:
1.1.1.8   root     3350:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Wired));
1.1.1.6   root     3351:             rn = "Wired";
                   3352:             break;
                   3353:         case 1:
                   3354:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3355:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf0));
1.1.1.6   root     3356:             rn = "SRSConf0";
                   3357:             break;
                   3358:         case 2:
                   3359:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3360:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf1));
1.1.1.6   root     3361:             rn = "SRSConf1";
                   3362:             break;
1.1.1.5   root     3363:         case 3:
1.1.1.6   root     3364:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3365:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf2));
1.1.1.6   root     3366:             rn = "SRSConf2";
                   3367:             break;
1.1.1.5   root     3368:         case 4:
1.1.1.6   root     3369:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3370:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf3));
1.1.1.6   root     3371:             rn = "SRSConf3";
                   3372:             break;
1.1.1.5   root     3373:         case 5:
1.1.1.6   root     3374:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3375:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf4));
1.1.1.6   root     3376:             rn = "SRSConf4";
                   3377:             break;
1.1.1.5   root     3378:         default:
                   3379:             goto die;
1.1.1.6   root     3380:         }
1.1       root     3381:         break;
1.1.1.5   root     3382:     case 7:
                   3383:         switch (sel) {
                   3384:         case 0:
1.1.1.6   root     3385:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3386:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_HWREna));
1.1.1.6   root     3387:             rn = "HWREna";
                   3388:             break;
1.1.1.5   root     3389:         default:
                   3390:             goto die;
1.1.1.6   root     3391:         }
1.1       root     3392:         break;
1.1.1.5   root     3393:     case 8:
                   3394:         switch (sel) {
                   3395:         case 0:
1.1.1.8   root     3396:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_BadVAddr));
                   3397:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.7   root     3398:             rn = "BadVAddr";
1.1.1.6   root     3399:             break;
1.1.1.5   root     3400:         default:
                   3401:             goto die;
                   3402:        }
1.1.1.2   root     3403:         break;
1.1.1.5   root     3404:     case 9:
                   3405:         switch (sel) {
                   3406:         case 0:
1.1.1.7   root     3407:             /* Mark as an IO operation because we read the time.  */
                   3408:             if (use_icount)
                   3409:                 gen_io_start();
1.1.1.8   root     3410:             gen_helper_mfc0_count(arg);
1.1.1.7   root     3411:             if (use_icount) {
                   3412:                 gen_io_end();
                   3413:             }
1.1.1.13! root     3414:             /* Break the TB to be able to take timer interrupts immediately
        !          3415:                after reading count.  */
        !          3416:             ctx->bstate = BS_STOP;
1.1.1.6   root     3417:             rn = "Count";
                   3418:             break;
                   3419:         /* 6,7 are implementation dependent */
1.1.1.5   root     3420:         default:
                   3421:             goto die;
1.1.1.6   root     3422:         }
1.1.1.5   root     3423:         break;
                   3424:     case 10:
                   3425:         switch (sel) {
                   3426:         case 0:
1.1.1.8   root     3427:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryHi));
                   3428:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3429:             rn = "EntryHi";
                   3430:             break;
1.1.1.5   root     3431:         default:
                   3432:             goto die;
1.1.1.6   root     3433:         }
1.1.1.5   root     3434:         break;
                   3435:     case 11:
                   3436:         switch (sel) {
                   3437:         case 0:
1.1.1.8   root     3438:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Compare));
1.1.1.6   root     3439:             rn = "Compare";
                   3440:             break;
                   3441:         /* 6,7 are implementation dependent */
1.1.1.5   root     3442:         default:
                   3443:             goto die;
1.1.1.6   root     3444:         }
1.1.1.5   root     3445:         break;
                   3446:     case 12:
                   3447:         switch (sel) {
                   3448:         case 0:
1.1.1.8   root     3449:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Status));
1.1.1.6   root     3450:             rn = "Status";
                   3451:             break;
                   3452:         case 1:
                   3453:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3454:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_IntCtl));
1.1.1.6   root     3455:             rn = "IntCtl";
                   3456:             break;
                   3457:         case 2:
                   3458:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3459:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSCtl));
1.1.1.6   root     3460:             rn = "SRSCtl";
                   3461:             break;
1.1.1.5   root     3462:         case 3:
1.1.1.6   root     3463:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3464:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSMap));
1.1.1.6   root     3465:             rn = "SRSMap";
                   3466:             break;
1.1.1.5   root     3467:         default:
                   3468:             goto die;
                   3469:        }
                   3470:         break;
                   3471:     case 13:
                   3472:         switch (sel) {
                   3473:         case 0:
1.1.1.8   root     3474:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Cause));
1.1.1.6   root     3475:             rn = "Cause";
                   3476:             break;
1.1.1.5   root     3477:         default:
                   3478:             goto die;
                   3479:        }
                   3480:         break;
                   3481:     case 14:
                   3482:         switch (sel) {
                   3483:         case 0:
1.1.1.8   root     3484:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
                   3485:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3486:             rn = "EPC";
                   3487:             break;
1.1.1.5   root     3488:         default:
                   3489:             goto die;
1.1.1.6   root     3490:         }
1.1.1.5   root     3491:         break;
                   3492:     case 15:
                   3493:         switch (sel) {
                   3494:         case 0:
1.1.1.8   root     3495:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_PRid));
1.1.1.6   root     3496:             rn = "PRid";
                   3497:             break;
                   3498:         case 1:
                   3499:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3500:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_EBase));
1.1.1.6   root     3501:             rn = "EBase";
                   3502:             break;
1.1.1.5   root     3503:         default:
                   3504:             goto die;
                   3505:        }
                   3506:         break;
                   3507:     case 16:
                   3508:         switch (sel) {
                   3509:         case 0:
1.1.1.8   root     3510:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config0));
1.1.1.5   root     3511:             rn = "Config";
                   3512:             break;
                   3513:         case 1:
1.1.1.8   root     3514:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config1));
1.1.1.5   root     3515:             rn = "Config1";
                   3516:             break;
                   3517:         case 2:
1.1.1.8   root     3518:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config2));
1.1.1.5   root     3519:             rn = "Config2";
                   3520:             break;
                   3521:         case 3:
1.1.1.8   root     3522:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config3));
1.1.1.5   root     3523:             rn = "Config3";
                   3524:             break;
1.1.1.6   root     3525:         /* 4,5 are reserved */
                   3526:         /* 6,7 are implementation dependent */
                   3527:         case 6:
1.1.1.8   root     3528:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config6));
1.1.1.6   root     3529:             rn = "Config6";
                   3530:             break;
                   3531:         case 7:
1.1.1.8   root     3532:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config7));
1.1.1.6   root     3533:             rn = "Config7";
                   3534:             break;
1.1.1.5   root     3535:         default:
                   3536:             goto die;
1.1       root     3537:         }
1.1.1.4   root     3538:         break;
1.1.1.5   root     3539:     case 17:
                   3540:         switch (sel) {
                   3541:         case 0:
1.1.1.8   root     3542:             gen_helper_mfc0_lladdr(arg);
1.1.1.6   root     3543:             rn = "LLAddr";
                   3544:             break;
1.1.1.5   root     3545:         default:
                   3546:             goto die;
                   3547:         }
1.1.1.4   root     3548:         break;
1.1.1.5   root     3549:     case 18:
                   3550:         switch (sel) {
1.1.1.6   root     3551:         case 0 ... 7:
1.1.1.8   root     3552:             gen_helper_1i(mfc0_watchlo, arg, sel);
1.1.1.6   root     3553:             rn = "WatchLo";
                   3554:             break;
1.1.1.5   root     3555:         default:
                   3556:             goto die;
                   3557:         }
1.1.1.4   root     3558:         break;
1.1.1.5   root     3559:     case 19:
                   3560:         switch (sel) {
1.1.1.6   root     3561:         case 0 ...7:
1.1.1.8   root     3562:             gen_helper_1i(mfc0_watchhi, arg, sel);
1.1.1.6   root     3563:             rn = "WatchHi";
                   3564:             break;
1.1.1.5   root     3565:         default:
                   3566:             goto die;
                   3567:         }
1.1.1.4   root     3568:         break;
1.1.1.5   root     3569:     case 20:
                   3570:         switch (sel) {
                   3571:         case 0:
1.1.1.6   root     3572: #if defined(TARGET_MIPS64)
                   3573:             check_insn(env, ctx, ISA_MIPS3);
1.1.1.8   root     3574:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_XContext));
                   3575:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3576:             rn = "XContext";
                   3577:             break;
                   3578: #endif
1.1.1.5   root     3579:         default:
                   3580:             goto die;
1.1.1.4   root     3581:         }
                   3582:         break;
1.1.1.5   root     3583:     case 21:
                   3584:        /* Officially reserved, but sel 0 is used for R1x000 framemask */
                   3585:         switch (sel) {
                   3586:         case 0:
1.1.1.8   root     3587:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Framemask));
1.1.1.6   root     3588:             rn = "Framemask";
                   3589:             break;
1.1.1.5   root     3590:         default:
                   3591:             goto die;
1.1.1.4   root     3592:         }
                   3593:         break;
1.1.1.5   root     3594:     case 22:
1.1.1.8   root     3595:         tcg_gen_movi_tl(arg, 0); /* unimplemented */
1.1.1.6   root     3596:         rn = "'Diagnostic"; /* implementation dependent */
                   3597:         break;
1.1.1.5   root     3598:     case 23:
                   3599:         switch (sel) {
                   3600:         case 0:
1.1.1.8   root     3601:             gen_helper_mfc0_debug(arg); /* EJTAG support */
1.1.1.6   root     3602:             rn = "Debug";
                   3603:             break;
                   3604:         case 1:
1.1.1.8   root     3605: //            gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
1.1.1.6   root     3606:             rn = "TraceControl";
                   3607: //            break;
                   3608:         case 2:
1.1.1.8   root     3609: //            gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
1.1.1.6   root     3610:             rn = "TraceControl2";
                   3611: //            break;
1.1.1.5   root     3612:         case 3:
1.1.1.8   root     3613: //            gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
1.1.1.6   root     3614:             rn = "UserTraceData";
                   3615: //            break;
1.1.1.5   root     3616:         case 4:
1.1.1.8   root     3617: //            gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
1.1.1.6   root     3618:             rn = "TraceBPC";
                   3619: //            break;
1.1.1.5   root     3620:         default:
                   3621:             goto die;
1.1.1.4   root     3622:         }
1.1.1.5   root     3623:         break;
                   3624:     case 24:
                   3625:         switch (sel) {
                   3626:         case 0:
1.1.1.7   root     3627:             /* EJTAG support */
1.1.1.8   root     3628:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
                   3629:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3630:             rn = "DEPC";
                   3631:             break;
1.1.1.5   root     3632:         default:
                   3633:             goto die;
                   3634:         }
                   3635:         break;
                   3636:     case 25:
                   3637:         switch (sel) {
                   3638:         case 0:
1.1.1.8   root     3639:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Performance0));
1.1.1.6   root     3640:             rn = "Performance0";
1.1.1.5   root     3641:             break;
                   3642:         case 1:
1.1.1.8   root     3643: //            gen_helper_mfc0_performance1(arg);
1.1.1.6   root     3644:             rn = "Performance1";
                   3645: //            break;
1.1.1.5   root     3646:         case 2:
1.1.1.8   root     3647: //            gen_helper_mfc0_performance2(arg);
1.1.1.6   root     3648:             rn = "Performance2";
                   3649: //            break;
1.1.1.5   root     3650:         case 3:
1.1.1.8   root     3651: //            gen_helper_mfc0_performance3(arg);
1.1.1.6   root     3652:             rn = "Performance3";
                   3653: //            break;
1.1.1.5   root     3654:         case 4:
1.1.1.8   root     3655: //            gen_helper_mfc0_performance4(arg);
1.1.1.6   root     3656:             rn = "Performance4";
                   3657: //            break;
1.1.1.5   root     3658:         case 5:
1.1.1.8   root     3659: //            gen_helper_mfc0_performance5(arg);
1.1.1.6   root     3660:             rn = "Performance5";
                   3661: //            break;
1.1.1.5   root     3662:         case 6:
1.1.1.8   root     3663: //            gen_helper_mfc0_performance6(arg);
1.1.1.6   root     3664:             rn = "Performance6";
                   3665: //            break;
1.1.1.5   root     3666:         case 7:
1.1.1.8   root     3667: //            gen_helper_mfc0_performance7(arg);
1.1.1.6   root     3668:             rn = "Performance7";
                   3669: //            break;
1.1.1.5   root     3670:         default:
                   3671:             goto die;
                   3672:         }
                   3673:         break;
                   3674:     case 26:
1.1.1.8   root     3675:         tcg_gen_movi_tl(arg, 0); /* unimplemented */
1.1.1.7   root     3676:         rn = "ECC";
                   3677:         break;
1.1.1.5   root     3678:     case 27:
                   3679:         switch (sel) {
                   3680:         case 0 ... 3:
1.1.1.8   root     3681:             tcg_gen_movi_tl(arg, 0); /* unimplemented */
1.1.1.6   root     3682:             rn = "CacheErr";
                   3683:             break;
1.1.1.5   root     3684:         default:
                   3685:             goto die;
                   3686:         }
                   3687:         break;
                   3688:     case 28:
                   3689:         switch (sel) {
                   3690:         case 0:
                   3691:         case 2:
                   3692:         case 4:
                   3693:         case 6:
1.1.1.8   root     3694:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagLo));
1.1.1.5   root     3695:             rn = "TagLo";
                   3696:             break;
                   3697:         case 1:
                   3698:         case 3:
                   3699:         case 5:
                   3700:         case 7:
1.1.1.8   root     3701:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataLo));
1.1.1.5   root     3702:             rn = "DataLo";
                   3703:             break;
                   3704:         default:
                   3705:             goto die;
                   3706:         }
                   3707:         break;
                   3708:     case 29:
                   3709:         switch (sel) {
                   3710:         case 0:
                   3711:         case 2:
                   3712:         case 4:
                   3713:         case 6:
1.1.1.8   root     3714:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagHi));
1.1.1.5   root     3715:             rn = "TagHi";
                   3716:             break;
                   3717:         case 1:
                   3718:         case 3:
                   3719:         case 5:
                   3720:         case 7:
1.1.1.8   root     3721:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataHi));
1.1.1.5   root     3722:             rn = "DataHi";
                   3723:             break;
                   3724:         default:
                   3725:             goto die;
                   3726:         }
                   3727:         break;
                   3728:     case 30:
                   3729:         switch (sel) {
                   3730:         case 0:
1.1.1.8   root     3731:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
                   3732:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3733:             rn = "ErrorEPC";
                   3734:             break;
1.1.1.5   root     3735:         default:
                   3736:             goto die;
                   3737:         }
                   3738:         break;
                   3739:     case 31:
                   3740:         switch (sel) {
                   3741:         case 0:
1.1.1.7   root     3742:             /* EJTAG support */
1.1.1.8   root     3743:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_DESAVE));
1.1.1.6   root     3744:             rn = "DESAVE";
                   3745:             break;
1.1.1.5   root     3746:         default:
                   3747:             goto die;
                   3748:         }
                   3749:         break;
                   3750:     default:
                   3751:        goto die;
                   3752:     }
1.1.1.13! root     3753:     (void)rn; /* avoid a compiler warning */
1.1.1.7   root     3754:     LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
1.1.1.5   root     3755:     return;
                   3756: 
                   3757: die:
1.1.1.7   root     3758:     LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
1.1.1.5   root     3759:     generate_exception(ctx, EXCP_RI);
                   3760: }
                   3761: 
1.1.1.8   root     3762: static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
1.1.1.5   root     3763: {
                   3764:     const char *rn = "invalid";
                   3765: 
1.1.1.6   root     3766:     if (sel != 0)
                   3767:         check_insn(env, ctx, ISA_MIPS32);
                   3768: 
1.1.1.7   root     3769:     if (use_icount)
                   3770:         gen_io_start();
                   3771: 
1.1.1.5   root     3772:     switch (reg) {
                   3773:     case 0:
                   3774:         switch (sel) {
                   3775:         case 0:
1.1.1.8   root     3776:             gen_helper_mtc0_index(arg);
1.1.1.5   root     3777:             rn = "Index";
                   3778:             break;
                   3779:         case 1:
1.1.1.6   root     3780:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3781:             gen_helper_mtc0_mvpcontrol(arg);
1.1.1.5   root     3782:             rn = "MVPControl";
1.1.1.6   root     3783:             break;
1.1.1.5   root     3784:         case 2:
1.1.1.6   root     3785:             check_insn(env, ctx, ASE_MT);
                   3786:             /* ignored */
1.1.1.5   root     3787:             rn = "MVPConf0";
1.1.1.6   root     3788:             break;
1.1.1.5   root     3789:         case 3:
1.1.1.6   root     3790:             check_insn(env, ctx, ASE_MT);
                   3791:             /* ignored */
1.1.1.5   root     3792:             rn = "MVPConf1";
1.1.1.6   root     3793:             break;
1.1.1.5   root     3794:         default:
                   3795:             goto die;
                   3796:         }
                   3797:         break;
                   3798:     case 1:
                   3799:         switch (sel) {
                   3800:         case 0:
1.1.1.6   root     3801:             /* ignored */
1.1.1.5   root     3802:             rn = "Random";
1.1.1.6   root     3803:             break;
1.1.1.5   root     3804:         case 1:
1.1.1.6   root     3805:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3806:             gen_helper_mtc0_vpecontrol(arg);
1.1.1.5   root     3807:             rn = "VPEControl";
1.1.1.6   root     3808:             break;
1.1.1.5   root     3809:         case 2:
1.1.1.6   root     3810:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3811:             gen_helper_mtc0_vpeconf0(arg);
1.1.1.5   root     3812:             rn = "VPEConf0";
1.1.1.6   root     3813:             break;
1.1.1.5   root     3814:         case 3:
1.1.1.6   root     3815:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3816:             gen_helper_mtc0_vpeconf1(arg);
1.1.1.5   root     3817:             rn = "VPEConf1";
1.1.1.6   root     3818:             break;
1.1.1.5   root     3819:         case 4:
1.1.1.6   root     3820:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3821:             gen_helper_mtc0_yqmask(arg);
1.1.1.5   root     3822:             rn = "YQMask";
1.1.1.6   root     3823:             break;
1.1.1.5   root     3824:         case 5:
1.1.1.6   root     3825:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3826:             gen_mtc0_store64(arg, offsetof(CPUState, CP0_VPESchedule));
1.1.1.5   root     3827:             rn = "VPESchedule";
1.1.1.6   root     3828:             break;
1.1.1.5   root     3829:         case 6:
1.1.1.6   root     3830:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3831:             gen_mtc0_store64(arg, offsetof(CPUState, CP0_VPEScheFBack));
1.1.1.5   root     3832:             rn = "VPEScheFBack";
1.1.1.6   root     3833:             break;
1.1.1.5   root     3834:         case 7:
1.1.1.6   root     3835:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3836:             gen_helper_mtc0_vpeopt(arg);
1.1.1.5   root     3837:             rn = "VPEOpt";
1.1.1.6   root     3838:             break;
1.1.1.5   root     3839:         default:
                   3840:             goto die;
                   3841:         }
                   3842:         break;
                   3843:     case 2:
                   3844:         switch (sel) {
                   3845:         case 0:
1.1.1.8   root     3846:             gen_helper_mtc0_entrylo0(arg);
1.1.1.6   root     3847:             rn = "EntryLo0";
                   3848:             break;
                   3849:         case 1:
                   3850:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3851:             gen_helper_mtc0_tcstatus(arg);
1.1.1.6   root     3852:             rn = "TCStatus";
                   3853:             break;
                   3854:         case 2:
                   3855:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3856:             gen_helper_mtc0_tcbind(arg);
1.1.1.6   root     3857:             rn = "TCBind";
                   3858:             break;
1.1.1.5   root     3859:         case 3:
1.1.1.6   root     3860:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3861:             gen_helper_mtc0_tcrestart(arg);
1.1.1.6   root     3862:             rn = "TCRestart";
                   3863:             break;
1.1.1.5   root     3864:         case 4:
1.1.1.6   root     3865:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3866:             gen_helper_mtc0_tchalt(arg);
1.1.1.6   root     3867:             rn = "TCHalt";
                   3868:             break;
1.1.1.5   root     3869:         case 5:
1.1.1.6   root     3870:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3871:             gen_helper_mtc0_tccontext(arg);
1.1.1.6   root     3872:             rn = "TCContext";
                   3873:             break;
1.1.1.5   root     3874:         case 6:
1.1.1.6   root     3875:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3876:             gen_helper_mtc0_tcschedule(arg);
1.1.1.6   root     3877:             rn = "TCSchedule";
                   3878:             break;
1.1.1.5   root     3879:         case 7:
1.1.1.6   root     3880:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3881:             gen_helper_mtc0_tcschefback(arg);
1.1.1.6   root     3882:             rn = "TCScheFBack";
                   3883:             break;
1.1.1.5   root     3884:         default:
                   3885:             goto die;
                   3886:         }
                   3887:         break;
                   3888:     case 3:
                   3889:         switch (sel) {
                   3890:         case 0:
1.1.1.8   root     3891:             gen_helper_mtc0_entrylo1(arg);
1.1.1.6   root     3892:             rn = "EntryLo1";
                   3893:             break;
1.1.1.5   root     3894:         default:
                   3895:             goto die;
1.1.1.6   root     3896:         }
1.1.1.5   root     3897:         break;
                   3898:     case 4:
                   3899:         switch (sel) {
                   3900:         case 0:
1.1.1.8   root     3901:             gen_helper_mtc0_context(arg);
1.1.1.6   root     3902:             rn = "Context";
                   3903:             break;
                   3904:         case 1:
1.1.1.8   root     3905: //            gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
1.1.1.6   root     3906:             rn = "ContextConfig";
                   3907: //            break;
1.1.1.5   root     3908:         default:
                   3909:             goto die;
1.1.1.6   root     3910:         }
1.1.1.5   root     3911:         break;
                   3912:     case 5:
                   3913:         switch (sel) {
                   3914:         case 0:
1.1.1.8   root     3915:             gen_helper_mtc0_pagemask(arg);
1.1.1.6   root     3916:             rn = "PageMask";
                   3917:             break;
                   3918:         case 1:
                   3919:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3920:             gen_helper_mtc0_pagegrain(arg);
1.1.1.6   root     3921:             rn = "PageGrain";
                   3922:             break;
1.1.1.5   root     3923:         default:
                   3924:             goto die;
1.1.1.6   root     3925:         }
1.1.1.5   root     3926:         break;
                   3927:     case 6:
                   3928:         switch (sel) {
                   3929:         case 0:
1.1.1.8   root     3930:             gen_helper_mtc0_wired(arg);
1.1.1.6   root     3931:             rn = "Wired";
                   3932:             break;
                   3933:         case 1:
                   3934:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3935:             gen_helper_mtc0_srsconf0(arg);
1.1.1.6   root     3936:             rn = "SRSConf0";
                   3937:             break;
                   3938:         case 2:
                   3939:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3940:             gen_helper_mtc0_srsconf1(arg);
1.1.1.6   root     3941:             rn = "SRSConf1";
                   3942:             break;
1.1.1.5   root     3943:         case 3:
1.1.1.6   root     3944:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3945:             gen_helper_mtc0_srsconf2(arg);
1.1.1.6   root     3946:             rn = "SRSConf2";
                   3947:             break;
1.1.1.5   root     3948:         case 4:
1.1.1.6   root     3949:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3950:             gen_helper_mtc0_srsconf3(arg);
1.1.1.6   root     3951:             rn = "SRSConf3";
                   3952:             break;
1.1.1.5   root     3953:         case 5:
1.1.1.6   root     3954:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3955:             gen_helper_mtc0_srsconf4(arg);
1.1.1.6   root     3956:             rn = "SRSConf4";
                   3957:             break;
1.1.1.5   root     3958:         default:
                   3959:             goto die;
1.1.1.6   root     3960:         }
1.1.1.5   root     3961:         break;
                   3962:     case 7:
                   3963:         switch (sel) {
                   3964:         case 0:
1.1.1.6   root     3965:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3966:             gen_helper_mtc0_hwrena(arg);
1.1.1.6   root     3967:             rn = "HWREna";
                   3968:             break;
1.1.1.5   root     3969:         default:
                   3970:             goto die;
1.1.1.6   root     3971:         }
1.1.1.5   root     3972:         break;
                   3973:     case 8:
                   3974:         /* ignored */
1.1.1.7   root     3975:         rn = "BadVAddr";
1.1.1.5   root     3976:         break;
                   3977:     case 9:
                   3978:         switch (sel) {
                   3979:         case 0:
1.1.1.8   root     3980:             gen_helper_mtc0_count(arg);
1.1.1.6   root     3981:             rn = "Count";
                   3982:             break;
                   3983:         /* 6,7 are implementation dependent */
1.1.1.5   root     3984:         default:
                   3985:             goto die;
1.1.1.6   root     3986:         }
1.1.1.5   root     3987:         break;
                   3988:     case 10:
                   3989:         switch (sel) {
                   3990:         case 0:
1.1.1.8   root     3991:             gen_helper_mtc0_entryhi(arg);
1.1.1.6   root     3992:             rn = "EntryHi";
                   3993:             break;
1.1.1.5   root     3994:         default:
                   3995:             goto die;
1.1.1.6   root     3996:         }
1.1.1.5   root     3997:         break;
                   3998:     case 11:
                   3999:         switch (sel) {
                   4000:         case 0:
1.1.1.8   root     4001:             gen_helper_mtc0_compare(arg);
1.1.1.6   root     4002:             rn = "Compare";
                   4003:             break;
                   4004:         /* 6,7 are implementation dependent */
1.1.1.5   root     4005:         default:
                   4006:             goto die;
1.1.1.6   root     4007:         }
1.1.1.5   root     4008:         break;
                   4009:     case 12:
                   4010:         switch (sel) {
                   4011:         case 0:
1.1.1.8   root     4012:             save_cpu_state(ctx, 1);
                   4013:             gen_helper_mtc0_status(arg);
1.1.1.6   root     4014:             /* BS_STOP isn't good enough here, hflags may have changed. */
                   4015:             gen_save_pc(ctx->pc + 4);
                   4016:             ctx->bstate = BS_EXCP;
                   4017:             rn = "Status";
                   4018:             break;
                   4019:         case 1:
                   4020:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4021:             gen_helper_mtc0_intctl(arg);
1.1.1.6   root     4022:             /* Stop translation as we may have switched the execution mode */
                   4023:             ctx->bstate = BS_STOP;
                   4024:             rn = "IntCtl";
                   4025:             break;
                   4026:         case 2:
                   4027:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4028:             gen_helper_mtc0_srsctl(arg);
1.1.1.6   root     4029:             /* Stop translation as we may have switched the execution mode */
                   4030:             ctx->bstate = BS_STOP;
                   4031:             rn = "SRSCtl";
                   4032:             break;
1.1.1.5   root     4033:         case 3:
1.1.1.6   root     4034:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4035:             gen_mtc0_store32(arg, offsetof(CPUState, CP0_SRSMap));
1.1.1.6   root     4036:             /* Stop translation as we may have switched the execution mode */
                   4037:             ctx->bstate = BS_STOP;
                   4038:             rn = "SRSMap";
                   4039:             break;
1.1.1.5   root     4040:         default:
                   4041:             goto die;
1.1.1.6   root     4042:         }
1.1.1.5   root     4043:         break;
                   4044:     case 13:
                   4045:         switch (sel) {
                   4046:         case 0:
1.1.1.8   root     4047:             save_cpu_state(ctx, 1);
                   4048:             gen_helper_mtc0_cause(arg);
1.1.1.6   root     4049:             rn = "Cause";
                   4050:             break;
1.1.1.5   root     4051:         default:
                   4052:             goto die;
1.1.1.6   root     4053:         }
1.1.1.5   root     4054:         break;
                   4055:     case 14:
                   4056:         switch (sel) {
                   4057:         case 0:
1.1.1.8   root     4058:             gen_mtc0_store64(arg, offsetof(CPUState, CP0_EPC));
1.1.1.6   root     4059:             rn = "EPC";
                   4060:             break;
1.1.1.5   root     4061:         default:
                   4062:             goto die;
1.1.1.6   root     4063:         }
1.1.1.5   root     4064:         break;
                   4065:     case 15:
                   4066:         switch (sel) {
                   4067:         case 0:
1.1.1.6   root     4068:             /* ignored */
                   4069:             rn = "PRid";
                   4070:             break;
                   4071:         case 1:
                   4072:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4073:             gen_helper_mtc0_ebase(arg);
1.1.1.6   root     4074:             rn = "EBase";
                   4075:             break;
1.1.1.5   root     4076:         default:
                   4077:             goto die;
1.1.1.6   root     4078:         }
1.1.1.5   root     4079:         break;
                   4080:     case 16:
                   4081:         switch (sel) {
                   4082:         case 0:
1.1.1.8   root     4083:             gen_helper_mtc0_config0(arg);
1.1.1.5   root     4084:             rn = "Config";
1.1.1.6   root     4085:             /* Stop translation as we may have switched the execution mode */
                   4086:             ctx->bstate = BS_STOP;
1.1.1.5   root     4087:             break;
                   4088:         case 1:
1.1.1.6   root     4089:             /* ignored, read only */
1.1.1.5   root     4090:             rn = "Config1";
                   4091:             break;
                   4092:         case 2:
1.1.1.8   root     4093:             gen_helper_mtc0_config2(arg);
1.1.1.5   root     4094:             rn = "Config2";
1.1.1.6   root     4095:             /* Stop translation as we may have switched the execution mode */
                   4096:             ctx->bstate = BS_STOP;
1.1.1.5   root     4097:             break;
                   4098:         case 3:
1.1.1.6   root     4099:             /* ignored, read only */
1.1.1.5   root     4100:             rn = "Config3";
                   4101:             break;
1.1.1.6   root     4102:         /* 4,5 are reserved */
                   4103:         /* 6,7 are implementation dependent */
                   4104:         case 6:
                   4105:             /* ignored */
                   4106:             rn = "Config6";
                   4107:             break;
                   4108:         case 7:
                   4109:             /* ignored */
                   4110:             rn = "Config7";
                   4111:             break;
1.1.1.5   root     4112:         default:
                   4113:             rn = "Invalid config selector";
                   4114:             goto die;
                   4115:         }
                   4116:         break;
                   4117:     case 17:
                   4118:         switch (sel) {
                   4119:         case 0:
1.1.1.9   root     4120:             gen_helper_mtc0_lladdr(arg);
1.1.1.6   root     4121:             rn = "LLAddr";
                   4122:             break;
1.1.1.5   root     4123:         default:
                   4124:             goto die;
                   4125:         }
                   4126:         break;
                   4127:     case 18:
                   4128:         switch (sel) {
1.1.1.6   root     4129:         case 0 ... 7:
1.1.1.8   root     4130:             gen_helper_1i(mtc0_watchlo, arg, sel);
1.1.1.6   root     4131:             rn = "WatchLo";
                   4132:             break;
1.1.1.5   root     4133:         default:
                   4134:             goto die;
                   4135:         }
                   4136:         break;
                   4137:     case 19:
                   4138:         switch (sel) {
1.1.1.6   root     4139:         case 0 ... 7:
1.1.1.8   root     4140:             gen_helper_1i(mtc0_watchhi, arg, sel);
1.1.1.6   root     4141:             rn = "WatchHi";
                   4142:             break;
1.1.1.5   root     4143:         default:
                   4144:             goto die;
                   4145:         }
                   4146:         break;
                   4147:     case 20:
                   4148:         switch (sel) {
                   4149:         case 0:
1.1.1.6   root     4150: #if defined(TARGET_MIPS64)
                   4151:             check_insn(env, ctx, ISA_MIPS3);
1.1.1.8   root     4152:             gen_helper_mtc0_xcontext(arg);
1.1.1.6   root     4153:             rn = "XContext";
                   4154:             break;
                   4155: #endif
1.1.1.5   root     4156:         default:
                   4157:             goto die;
                   4158:         }
                   4159:         break;
                   4160:     case 21:
                   4161:        /* Officially reserved, but sel 0 is used for R1x000 framemask */
                   4162:         switch (sel) {
                   4163:         case 0:
1.1.1.8   root     4164:             gen_helper_mtc0_framemask(arg);
1.1.1.6   root     4165:             rn = "Framemask";
                   4166:             break;
1.1.1.5   root     4167:         default:
                   4168:             goto die;
                   4169:         }
                   4170:         break;
                   4171:     case 22:
                   4172:         /* ignored */
                   4173:         rn = "Diagnostic"; /* implementation dependent */
1.1.1.6   root     4174:         break;
1.1.1.5   root     4175:     case 23:
                   4176:         switch (sel) {
                   4177:         case 0:
1.1.1.8   root     4178:             gen_helper_mtc0_debug(arg); /* EJTAG support */
1.1.1.6   root     4179:             /* BS_STOP isn't good enough here, hflags may have changed. */
                   4180:             gen_save_pc(ctx->pc + 4);
                   4181:             ctx->bstate = BS_EXCP;
                   4182:             rn = "Debug";
                   4183:             break;
                   4184:         case 1:
1.1.1.8   root     4185: //            gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
1.1.1.6   root     4186:             rn = "TraceControl";
                   4187:             /* Stop translation as we may have switched the execution mode */
                   4188:             ctx->bstate = BS_STOP;
                   4189: //            break;
                   4190:         case 2:
1.1.1.8   root     4191: //            gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
1.1.1.6   root     4192:             rn = "TraceControl2";
                   4193:             /* Stop translation as we may have switched the execution mode */
                   4194:             ctx->bstate = BS_STOP;
                   4195: //            break;
                   4196:         case 3:
                   4197:             /* Stop translation as we may have switched the execution mode */
                   4198:             ctx->bstate = BS_STOP;
1.1.1.8   root     4199: //            gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
1.1.1.6   root     4200:             rn = "UserTraceData";
                   4201:             /* Stop translation as we may have switched the execution mode */
                   4202:             ctx->bstate = BS_STOP;
                   4203: //            break;
1.1.1.5   root     4204:         case 4:
1.1.1.8   root     4205: //            gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
1.1.1.6   root     4206:             /* Stop translation as we may have switched the execution mode */
                   4207:             ctx->bstate = BS_STOP;
                   4208:             rn = "TraceBPC";
                   4209: //            break;
1.1.1.5   root     4210:         default:
                   4211:             goto die;
                   4212:         }
                   4213:         break;
                   4214:     case 24:
                   4215:         switch (sel) {
                   4216:         case 0:
1.1.1.7   root     4217:             /* EJTAG support */
1.1.1.8   root     4218:             gen_mtc0_store64(arg, offsetof(CPUState, CP0_DEPC));
1.1.1.6   root     4219:             rn = "DEPC";
                   4220:             break;
1.1.1.5   root     4221:         default:
                   4222:             goto die;
                   4223:         }
                   4224:         break;
                   4225:     case 25:
                   4226:         switch (sel) {
                   4227:         case 0:
1.1.1.8   root     4228:             gen_helper_mtc0_performance0(arg);
1.1.1.6   root     4229:             rn = "Performance0";
                   4230:             break;
                   4231:         case 1:
1.1.1.8   root     4232: //            gen_helper_mtc0_performance1(arg);
1.1.1.6   root     4233:             rn = "Performance1";
                   4234: //            break;
                   4235:         case 2:
1.1.1.8   root     4236: //            gen_helper_mtc0_performance2(arg);
1.1.1.6   root     4237:             rn = "Performance2";
                   4238: //            break;
                   4239:         case 3:
1.1.1.8   root     4240: //            gen_helper_mtc0_performance3(arg);
1.1.1.6   root     4241:             rn = "Performance3";
                   4242: //            break;
1.1.1.5   root     4243:         case 4:
1.1.1.8   root     4244: //            gen_helper_mtc0_performance4(arg);
1.1.1.6   root     4245:             rn = "Performance4";
                   4246: //            break;
1.1.1.5   root     4247:         case 5:
1.1.1.8   root     4248: //            gen_helper_mtc0_performance5(arg);
1.1.1.6   root     4249:             rn = "Performance5";
                   4250: //            break;
1.1.1.5   root     4251:         case 6:
1.1.1.8   root     4252: //            gen_helper_mtc0_performance6(arg);
1.1.1.6   root     4253:             rn = "Performance6";
                   4254: //            break;
1.1.1.5   root     4255:         case 7:
1.1.1.8   root     4256: //            gen_helper_mtc0_performance7(arg);
1.1.1.6   root     4257:             rn = "Performance7";
                   4258: //            break;
1.1.1.5   root     4259:         default:
                   4260:             goto die;
                   4261:         }
                   4262:        break;
                   4263:     case 26:
1.1.1.6   root     4264:         /* ignored */
1.1.1.5   root     4265:         rn = "ECC";
1.1.1.6   root     4266:         break;
1.1.1.5   root     4267:     case 27:
                   4268:         switch (sel) {
                   4269:         case 0 ... 3:
1.1.1.6   root     4270:             /* ignored */
                   4271:             rn = "CacheErr";
                   4272:             break;
1.1.1.5   root     4273:         default:
                   4274:             goto die;
                   4275:         }
                   4276:        break;
                   4277:     case 28:
                   4278:         switch (sel) {
                   4279:         case 0:
                   4280:         case 2:
                   4281:         case 4:
                   4282:         case 6:
1.1.1.8   root     4283:             gen_helper_mtc0_taglo(arg);
1.1.1.5   root     4284:             rn = "TagLo";
                   4285:             break;
                   4286:         case 1:
                   4287:         case 3:
                   4288:         case 5:
                   4289:         case 7:
1.1.1.8   root     4290:             gen_helper_mtc0_datalo(arg);
1.1.1.5   root     4291:             rn = "DataLo";
                   4292:             break;
                   4293:         default:
                   4294:             goto die;
                   4295:         }
                   4296:         break;
                   4297:     case 29:
                   4298:         switch (sel) {
                   4299:         case 0:
                   4300:         case 2:
                   4301:         case 4:
                   4302:         case 6:
1.1.1.8   root     4303:             gen_helper_mtc0_taghi(arg);
1.1.1.5   root     4304:             rn = "TagHi";
                   4305:             break;
                   4306:         case 1:
                   4307:         case 3:
                   4308:         case 5:
                   4309:         case 7:
1.1.1.8   root     4310:             gen_helper_mtc0_datahi(arg);
1.1.1.5   root     4311:             rn = "DataHi";
                   4312:             break;
                   4313:         default:
                   4314:             rn = "invalid sel";
                   4315:             goto die;
                   4316:         }
                   4317:        break;
                   4318:     case 30:
                   4319:         switch (sel) {
                   4320:         case 0:
1.1.1.8   root     4321:             gen_mtc0_store64(arg, offsetof(CPUState, CP0_ErrorEPC));
1.1.1.6   root     4322:             rn = "ErrorEPC";
                   4323:             break;
1.1.1.5   root     4324:         default:
                   4325:             goto die;
                   4326:         }
                   4327:         break;
                   4328:     case 31:
                   4329:         switch (sel) {
                   4330:         case 0:
1.1.1.7   root     4331:             /* EJTAG support */
1.1.1.8   root     4332:             gen_mtc0_store32(arg, offsetof(CPUState, CP0_DESAVE));
1.1.1.6   root     4333:             rn = "DESAVE";
                   4334:             break;
1.1.1.5   root     4335:         default:
                   4336:             goto die;
                   4337:         }
1.1.1.6   root     4338:         /* Stop translation as we may have switched the execution mode */
                   4339:         ctx->bstate = BS_STOP;
1.1.1.5   root     4340:         break;
                   4341:     default:
                   4342:        goto die;
                   4343:     }
1.1.1.13! root     4344:     (void)rn; /* avoid a compiler warning */
1.1.1.7   root     4345:     LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
                   4346:     /* For simplicity assume that all writes can cause interrupts.  */
                   4347:     if (use_icount) {
                   4348:         gen_io_end();
                   4349:         ctx->bstate = BS_STOP;
1.1.1.5   root     4350:     }
                   4351:     return;
                   4352: 
                   4353: die:
1.1.1.7   root     4354:     LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
1.1.1.5   root     4355:     generate_exception(ctx, EXCP_RI);
                   4356: }
                   4357: 
1.1.1.6   root     4358: #if defined(TARGET_MIPS64)
1.1.1.8   root     4359: static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
1.1.1.5   root     4360: {
                   4361:     const char *rn = "invalid";
                   4362: 
1.1.1.6   root     4363:     if (sel != 0)
                   4364:         check_insn(env, ctx, ISA_MIPS64);
                   4365: 
1.1.1.5   root     4366:     switch (reg) {
                   4367:     case 0:
                   4368:         switch (sel) {
                   4369:         case 0:
1.1.1.8   root     4370:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Index));
1.1.1.5   root     4371:             rn = "Index";
                   4372:             break;
                   4373:         case 1:
1.1.1.6   root     4374:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4375:             gen_helper_mfc0_mvpcontrol(arg);
1.1.1.5   root     4376:             rn = "MVPControl";
1.1.1.6   root     4377:             break;
1.1.1.5   root     4378:         case 2:
1.1.1.6   root     4379:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4380:             gen_helper_mfc0_mvpconf0(arg);
1.1.1.5   root     4381:             rn = "MVPConf0";
1.1.1.6   root     4382:             break;
1.1.1.5   root     4383:         case 3:
1.1.1.6   root     4384:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4385:             gen_helper_mfc0_mvpconf1(arg);
1.1.1.5   root     4386:             rn = "MVPConf1";
1.1.1.6   root     4387:             break;
1.1.1.5   root     4388:         default:
                   4389:             goto die;
                   4390:         }
                   4391:         break;
                   4392:     case 1:
                   4393:         switch (sel) {
                   4394:         case 0:
1.1.1.8   root     4395:             gen_helper_mfc0_random(arg);
1.1.1.5   root     4396:             rn = "Random";
1.1.1.6   root     4397:             break;
1.1.1.5   root     4398:         case 1:
1.1.1.6   root     4399:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4400:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEControl));
1.1.1.5   root     4401:             rn = "VPEControl";
1.1.1.6   root     4402:             break;
1.1.1.5   root     4403:         case 2:
1.1.1.6   root     4404:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4405:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf0));
1.1.1.5   root     4406:             rn = "VPEConf0";
1.1.1.6   root     4407:             break;
1.1.1.5   root     4408:         case 3:
1.1.1.6   root     4409:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4410:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf1));
1.1.1.5   root     4411:             rn = "VPEConf1";
1.1.1.6   root     4412:             break;
1.1.1.5   root     4413:         case 4:
1.1.1.6   root     4414:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4415:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_YQMask));
1.1.1.5   root     4416:             rn = "YQMask";
1.1.1.6   root     4417:             break;
1.1.1.5   root     4418:         case 5:
1.1.1.6   root     4419:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4420:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPESchedule));
1.1.1.5   root     4421:             rn = "VPESchedule";
1.1.1.6   root     4422:             break;
1.1.1.5   root     4423:         case 6:
1.1.1.6   root     4424:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4425:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
1.1.1.5   root     4426:             rn = "VPEScheFBack";
1.1.1.6   root     4427:             break;
1.1.1.5   root     4428:         case 7:
1.1.1.6   root     4429:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4430:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEOpt));
1.1.1.5   root     4431:             rn = "VPEOpt";
1.1.1.6   root     4432:             break;
1.1.1.5   root     4433:         default:
                   4434:             goto die;
                   4435:         }
                   4436:         break;
                   4437:     case 2:
                   4438:         switch (sel) {
                   4439:         case 0:
1.1.1.8   root     4440:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo0));
1.1.1.6   root     4441:             rn = "EntryLo0";
                   4442:             break;
                   4443:         case 1:
                   4444:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4445:             gen_helper_mfc0_tcstatus(arg);
1.1.1.6   root     4446:             rn = "TCStatus";
                   4447:             break;
                   4448:         case 2:
                   4449:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4450:             gen_helper_mfc0_tcbind(arg);
1.1.1.6   root     4451:             rn = "TCBind";
                   4452:             break;
1.1.1.5   root     4453:         case 3:
1.1.1.6   root     4454:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4455:             gen_helper_dmfc0_tcrestart(arg);
1.1.1.6   root     4456:             rn = "TCRestart";
                   4457:             break;
1.1.1.5   root     4458:         case 4:
1.1.1.6   root     4459:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4460:             gen_helper_dmfc0_tchalt(arg);
1.1.1.6   root     4461:             rn = "TCHalt";
                   4462:             break;
1.1.1.5   root     4463:         case 5:
1.1.1.6   root     4464:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4465:             gen_helper_dmfc0_tccontext(arg);
1.1.1.6   root     4466:             rn = "TCContext";
                   4467:             break;
1.1.1.5   root     4468:         case 6:
1.1.1.6   root     4469:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4470:             gen_helper_dmfc0_tcschedule(arg);
1.1.1.6   root     4471:             rn = "TCSchedule";
                   4472:             break;
1.1.1.5   root     4473:         case 7:
1.1.1.6   root     4474:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4475:             gen_helper_dmfc0_tcschefback(arg);
1.1.1.6   root     4476:             rn = "TCScheFBack";
                   4477:             break;
1.1.1.5   root     4478:         default:
                   4479:             goto die;
                   4480:         }
                   4481:         break;
                   4482:     case 3:
                   4483:         switch (sel) {
                   4484:         case 0:
1.1.1.8   root     4485:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo1));
1.1.1.6   root     4486:             rn = "EntryLo1";
                   4487:             break;
1.1.1.5   root     4488:         default:
                   4489:             goto die;
1.1.1.6   root     4490:         }
1.1.1.5   root     4491:         break;
                   4492:     case 4:
                   4493:         switch (sel) {
                   4494:         case 0:
1.1.1.8   root     4495:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_Context));
1.1.1.6   root     4496:             rn = "Context";
                   4497:             break;
                   4498:         case 1:
1.1.1.8   root     4499: //            gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
1.1.1.6   root     4500:             rn = "ContextConfig";
                   4501: //            break;
1.1.1.5   root     4502:         default:
                   4503:             goto die;
1.1.1.6   root     4504:         }
1.1.1.5   root     4505:         break;
                   4506:     case 5:
                   4507:         switch (sel) {
                   4508:         case 0:
1.1.1.8   root     4509:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageMask));
1.1.1.6   root     4510:             rn = "PageMask";
                   4511:             break;
                   4512:         case 1:
                   4513:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4514:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageGrain));
1.1.1.6   root     4515:             rn = "PageGrain";
                   4516:             break;
1.1.1.5   root     4517:         default:
                   4518:             goto die;
1.1.1.6   root     4519:         }
1.1.1.5   root     4520:         break;
                   4521:     case 6:
                   4522:         switch (sel) {
                   4523:         case 0:
1.1.1.8   root     4524:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Wired));
1.1.1.6   root     4525:             rn = "Wired";
                   4526:             break;
                   4527:         case 1:
                   4528:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4529:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf0));
1.1.1.6   root     4530:             rn = "SRSConf0";
                   4531:             break;
                   4532:         case 2:
                   4533:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4534:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf1));
1.1.1.6   root     4535:             rn = "SRSConf1";
                   4536:             break;
1.1.1.5   root     4537:         case 3:
1.1.1.6   root     4538:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4539:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf2));
1.1.1.6   root     4540:             rn = "SRSConf2";
                   4541:             break;
1.1.1.5   root     4542:         case 4:
1.1.1.6   root     4543:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4544:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf3));
1.1.1.6   root     4545:             rn = "SRSConf3";
                   4546:             break;
1.1.1.5   root     4547:         case 5:
1.1.1.6   root     4548:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4549:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf4));
1.1.1.6   root     4550:             rn = "SRSConf4";
                   4551:             break;
1.1.1.5   root     4552:         default:
                   4553:             goto die;
1.1.1.6   root     4554:         }
1.1.1.5   root     4555:         break;
                   4556:     case 7:
                   4557:         switch (sel) {
                   4558:         case 0:
1.1.1.6   root     4559:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4560:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_HWREna));
1.1.1.6   root     4561:             rn = "HWREna";
                   4562:             break;
1.1.1.5   root     4563:         default:
                   4564:             goto die;
1.1.1.6   root     4565:         }
1.1.1.5   root     4566:         break;
                   4567:     case 8:
                   4568:         switch (sel) {
                   4569:         case 0:
1.1.1.8   root     4570:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_BadVAddr));
1.1.1.7   root     4571:             rn = "BadVAddr";
1.1.1.6   root     4572:             break;
1.1.1.5   root     4573:         default:
                   4574:             goto die;
1.1.1.6   root     4575:         }
1.1.1.5   root     4576:         break;
                   4577:     case 9:
                   4578:         switch (sel) {
                   4579:         case 0:
1.1.1.7   root     4580:             /* Mark as an IO operation because we read the time.  */
                   4581:             if (use_icount)
                   4582:                 gen_io_start();
1.1.1.8   root     4583:             gen_helper_mfc0_count(arg);
1.1.1.7   root     4584:             if (use_icount) {
                   4585:                 gen_io_end();
                   4586:             }
1.1.1.13! root     4587:             /* Break the TB to be able to take timer interrupts immediately
        !          4588:                after reading count.  */
        !          4589:             ctx->bstate = BS_STOP;
1.1.1.6   root     4590:             rn = "Count";
                   4591:             break;
                   4592:         /* 6,7 are implementation dependent */
1.1.1.5   root     4593:         default:
                   4594:             goto die;
1.1.1.6   root     4595:         }
1.1.1.5   root     4596:         break;
                   4597:     case 10:
                   4598:         switch (sel) {
                   4599:         case 0:
1.1.1.8   root     4600:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryHi));
1.1.1.6   root     4601:             rn = "EntryHi";
                   4602:             break;
1.1.1.5   root     4603:         default:
                   4604:             goto die;
1.1.1.6   root     4605:         }
1.1.1.5   root     4606:         break;
                   4607:     case 11:
                   4608:         switch (sel) {
                   4609:         case 0:
1.1.1.8   root     4610:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Compare));
1.1.1.6   root     4611:             rn = "Compare";
                   4612:             break;
                   4613:         /* 6,7 are implementation dependent */
1.1.1.5   root     4614:         default:
                   4615:             goto die;
1.1.1.6   root     4616:         }
1.1.1.5   root     4617:         break;
                   4618:     case 12:
                   4619:         switch (sel) {
                   4620:         case 0:
1.1.1.8   root     4621:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Status));
1.1.1.6   root     4622:             rn = "Status";
                   4623:             break;
                   4624:         case 1:
                   4625:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4626:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_IntCtl));
1.1.1.6   root     4627:             rn = "IntCtl";
                   4628:             break;
                   4629:         case 2:
                   4630:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4631:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSCtl));
1.1.1.6   root     4632:             rn = "SRSCtl";
                   4633:             break;
1.1.1.5   root     4634:         case 3:
1.1.1.6   root     4635:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4636:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSMap));
1.1.1.6   root     4637:             rn = "SRSMap";
                   4638:             break;
1.1.1.5   root     4639:         default:
                   4640:             goto die;
1.1.1.6   root     4641:         }
1.1.1.5   root     4642:         break;
                   4643:     case 13:
                   4644:         switch (sel) {
                   4645:         case 0:
1.1.1.8   root     4646:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Cause));
1.1.1.6   root     4647:             rn = "Cause";
                   4648:             break;
1.1.1.5   root     4649:         default:
                   4650:             goto die;
1.1.1.6   root     4651:         }
1.1.1.5   root     4652:         break;
                   4653:     case 14:
                   4654:         switch (sel) {
                   4655:         case 0:
1.1.1.8   root     4656:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
1.1.1.6   root     4657:             rn = "EPC";
                   4658:             break;
1.1.1.5   root     4659:         default:
                   4660:             goto die;
1.1.1.6   root     4661:         }
1.1.1.5   root     4662:         break;
                   4663:     case 15:
                   4664:         switch (sel) {
                   4665:         case 0:
1.1.1.8   root     4666:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_PRid));
1.1.1.6   root     4667:             rn = "PRid";
                   4668:             break;
                   4669:         case 1:
                   4670:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4671:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_EBase));
1.1.1.6   root     4672:             rn = "EBase";
                   4673:             break;
1.1.1.5   root     4674:         default:
                   4675:             goto die;
1.1.1.6   root     4676:         }
1.1.1.5   root     4677:         break;
                   4678:     case 16:
                   4679:         switch (sel) {
                   4680:         case 0:
1.1.1.8   root     4681:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config0));
1.1.1.5   root     4682:             rn = "Config";
                   4683:             break;
                   4684:         case 1:
1.1.1.8   root     4685:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config1));
1.1.1.5   root     4686:             rn = "Config1";
                   4687:             break;
                   4688:         case 2:
1.1.1.8   root     4689:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config2));
1.1.1.5   root     4690:             rn = "Config2";
                   4691:             break;
                   4692:         case 3:
1.1.1.8   root     4693:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config3));
1.1.1.5   root     4694:             rn = "Config3";
                   4695:             break;
                   4696:        /* 6,7 are implementation dependent */
1.1.1.7   root     4697:         case 6:
1.1.1.8   root     4698:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config6));
1.1.1.7   root     4699:             rn = "Config6";
                   4700:             break;
                   4701:         case 7:
1.1.1.8   root     4702:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config7));
1.1.1.7   root     4703:             rn = "Config7";
                   4704:             break;
1.1.1.5   root     4705:         default:
                   4706:             goto die;
                   4707:         }
                   4708:         break;
                   4709:     case 17:
                   4710:         switch (sel) {
                   4711:         case 0:
1.1.1.8   root     4712:             gen_helper_dmfc0_lladdr(arg);
1.1.1.6   root     4713:             rn = "LLAddr";
                   4714:             break;
1.1.1.5   root     4715:         default:
                   4716:             goto die;
                   4717:         }
                   4718:         break;
                   4719:     case 18:
                   4720:         switch (sel) {
1.1.1.6   root     4721:         case 0 ... 7:
1.1.1.8   root     4722:             gen_helper_1i(dmfc0_watchlo, arg, sel);
1.1.1.6   root     4723:             rn = "WatchLo";
                   4724:             break;
1.1.1.5   root     4725:         default:
                   4726:             goto die;
                   4727:         }
                   4728:         break;
                   4729:     case 19:
                   4730:         switch (sel) {
1.1.1.6   root     4731:         case 0 ... 7:
1.1.1.8   root     4732:             gen_helper_1i(mfc0_watchhi, arg, sel);
1.1.1.6   root     4733:             rn = "WatchHi";
                   4734:             break;
1.1.1.5   root     4735:         default:
                   4736:             goto die;
                   4737:         }
                   4738:         break;
                   4739:     case 20:
                   4740:         switch (sel) {
                   4741:         case 0:
1.1.1.6   root     4742:             check_insn(env, ctx, ISA_MIPS3);
1.1.1.8   root     4743:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_XContext));
1.1.1.6   root     4744:             rn = "XContext";
                   4745:             break;
1.1.1.5   root     4746:         default:
                   4747:             goto die;
                   4748:         }
                   4749:         break;
                   4750:     case 21:
                   4751:        /* Officially reserved, but sel 0 is used for R1x000 framemask */
                   4752:         switch (sel) {
                   4753:         case 0:
1.1.1.8   root     4754:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Framemask));
1.1.1.6   root     4755:             rn = "Framemask";
                   4756:             break;
1.1.1.5   root     4757:         default:
                   4758:             goto die;
                   4759:         }
                   4760:         break;
                   4761:     case 22:
1.1.1.8   root     4762:         tcg_gen_movi_tl(arg, 0); /* unimplemented */
1.1.1.6   root     4763:         rn = "'Diagnostic"; /* implementation dependent */
                   4764:         break;
1.1.1.5   root     4765:     case 23:
                   4766:         switch (sel) {
                   4767:         case 0:
1.1.1.8   root     4768:             gen_helper_mfc0_debug(arg); /* EJTAG support */
1.1.1.6   root     4769:             rn = "Debug";
                   4770:             break;
                   4771:         case 1:
1.1.1.8   root     4772: //            gen_helper_dmfc0_tracecontrol(arg); /* PDtrace support */
1.1.1.6   root     4773:             rn = "TraceControl";
                   4774: //            break;
                   4775:         case 2:
1.1.1.8   root     4776: //            gen_helper_dmfc0_tracecontrol2(arg); /* PDtrace support */
1.1.1.6   root     4777:             rn = "TraceControl2";
                   4778: //            break;
1.1.1.5   root     4779:         case 3:
1.1.1.8   root     4780: //            gen_helper_dmfc0_usertracedata(arg); /* PDtrace support */
1.1.1.6   root     4781:             rn = "UserTraceData";
                   4782: //            break;
1.1.1.5   root     4783:         case 4:
1.1.1.8   root     4784: //            gen_helper_dmfc0_tracebpc(arg); /* PDtrace support */
1.1.1.6   root     4785:             rn = "TraceBPC";
                   4786: //            break;
1.1.1.5   root     4787:         default:
                   4788:             goto die;
                   4789:         }
                   4790:         break;
                   4791:     case 24:
                   4792:         switch (sel) {
                   4793:         case 0:
1.1.1.7   root     4794:             /* EJTAG support */
1.1.1.8   root     4795:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
1.1.1.6   root     4796:             rn = "DEPC";
                   4797:             break;
1.1.1.5   root     4798:         default:
                   4799:             goto die;
                   4800:         }
                   4801:         break;
                   4802:     case 25:
                   4803:         switch (sel) {
                   4804:         case 0:
1.1.1.8   root     4805:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Performance0));
1.1.1.6   root     4806:             rn = "Performance0";
1.1.1.5   root     4807:             break;
                   4808:         case 1:
1.1.1.8   root     4809: //            gen_helper_dmfc0_performance1(arg);
1.1.1.6   root     4810:             rn = "Performance1";
                   4811: //            break;
1.1.1.5   root     4812:         case 2:
1.1.1.8   root     4813: //            gen_helper_dmfc0_performance2(arg);
1.1.1.6   root     4814:             rn = "Performance2";
                   4815: //            break;
1.1.1.5   root     4816:         case 3:
1.1.1.8   root     4817: //            gen_helper_dmfc0_performance3(arg);
1.1.1.6   root     4818:             rn = "Performance3";
                   4819: //            break;
1.1.1.5   root     4820:         case 4:
1.1.1.8   root     4821: //            gen_helper_dmfc0_performance4(arg);
1.1.1.6   root     4822:             rn = "Performance4";
                   4823: //            break;
1.1.1.5   root     4824:         case 5:
1.1.1.8   root     4825: //            gen_helper_dmfc0_performance5(arg);
1.1.1.6   root     4826:             rn = "Performance5";
                   4827: //            break;
1.1.1.5   root     4828:         case 6:
1.1.1.8   root     4829: //            gen_helper_dmfc0_performance6(arg);
1.1.1.6   root     4830:             rn = "Performance6";
                   4831: //            break;
1.1.1.5   root     4832:         case 7:
1.1.1.8   root     4833: //            gen_helper_dmfc0_performance7(arg);
1.1.1.6   root     4834:             rn = "Performance7";
                   4835: //            break;
1.1.1.5   root     4836:         default:
                   4837:             goto die;
                   4838:         }
                   4839:         break;
                   4840:     case 26:
1.1.1.8   root     4841:         tcg_gen_movi_tl(arg, 0); /* unimplemented */
1.1.1.7   root     4842:         rn = "ECC";
                   4843:         break;
1.1.1.5   root     4844:     case 27:
                   4845:         switch (sel) {
                   4846:         /* ignored */
                   4847:         case 0 ... 3:
1.1.1.8   root     4848:             tcg_gen_movi_tl(arg, 0); /* unimplemented */
1.1.1.6   root     4849:             rn = "CacheErr";
                   4850:             break;
1.1.1.5   root     4851:         default:
                   4852:             goto die;
                   4853:         }
                   4854:         break;
                   4855:     case 28:
                   4856:         switch (sel) {
                   4857:         case 0:
                   4858:         case 2:
                   4859:         case 4:
                   4860:         case 6:
1.1.1.8   root     4861:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagLo));
1.1.1.5   root     4862:             rn = "TagLo";
                   4863:             break;
                   4864:         case 1:
                   4865:         case 3:
                   4866:         case 5:
                   4867:         case 7:
1.1.1.8   root     4868:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataLo));
1.1.1.5   root     4869:             rn = "DataLo";
                   4870:             break;
                   4871:         default:
                   4872:             goto die;
                   4873:         }
                   4874:         break;
                   4875:     case 29:
                   4876:         switch (sel) {
                   4877:         case 0:
                   4878:         case 2:
                   4879:         case 4:
                   4880:         case 6:
1.1.1.8   root     4881:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagHi));
1.1.1.5   root     4882:             rn = "TagHi";
                   4883:             break;
                   4884:         case 1:
                   4885:         case 3:
                   4886:         case 5:
                   4887:         case 7:
1.1.1.8   root     4888:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataHi));
1.1.1.5   root     4889:             rn = "DataHi";
                   4890:             break;
                   4891:         default:
                   4892:             goto die;
                   4893:         }
                   4894:         break;
                   4895:     case 30:
                   4896:         switch (sel) {
                   4897:         case 0:
1.1.1.8   root     4898:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
1.1.1.6   root     4899:             rn = "ErrorEPC";
                   4900:             break;
1.1.1.5   root     4901:         default:
                   4902:             goto die;
                   4903:         }
                   4904:         break;
                   4905:     case 31:
                   4906:         switch (sel) {
                   4907:         case 0:
1.1.1.7   root     4908:             /* EJTAG support */
1.1.1.8   root     4909:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_DESAVE));
1.1.1.6   root     4910:             rn = "DESAVE";
                   4911:             break;
1.1.1.5   root     4912:         default:
                   4913:             goto die;
                   4914:         }
                   4915:         break;
                   4916:     default:
1.1.1.6   root     4917:         goto die;
1.1.1.5   root     4918:     }
1.1.1.13! root     4919:     (void)rn; /* avoid a compiler warning */
1.1.1.7   root     4920:     LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
1.1.1.5   root     4921:     return;
                   4922: 
                   4923: die:
1.1.1.7   root     4924:     LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
1.1.1.5   root     4925:     generate_exception(ctx, EXCP_RI);
                   4926: }
                   4927: 
1.1.1.8   root     4928: static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
1.1.1.5   root     4929: {
                   4930:     const char *rn = "invalid";
                   4931: 
1.1.1.6   root     4932:     if (sel != 0)
                   4933:         check_insn(env, ctx, ISA_MIPS64);
                   4934: 
1.1.1.7   root     4935:     if (use_icount)
                   4936:         gen_io_start();
                   4937: 
1.1.1.5   root     4938:     switch (reg) {
                   4939:     case 0:
                   4940:         switch (sel) {
                   4941:         case 0:
1.1.1.8   root     4942:             gen_helper_mtc0_index(arg);
1.1.1.5   root     4943:             rn = "Index";
                   4944:             break;
                   4945:         case 1:
1.1.1.6   root     4946:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4947:             gen_helper_mtc0_mvpcontrol(arg);
1.1.1.5   root     4948:             rn = "MVPControl";
1.1.1.6   root     4949:             break;
1.1.1.5   root     4950:         case 2:
1.1.1.6   root     4951:             check_insn(env, ctx, ASE_MT);
                   4952:             /* ignored */
1.1.1.5   root     4953:             rn = "MVPConf0";
1.1.1.6   root     4954:             break;
1.1.1.5   root     4955:         case 3:
1.1.1.6   root     4956:             check_insn(env, ctx, ASE_MT);
                   4957:             /* ignored */
1.1.1.5   root     4958:             rn = "MVPConf1";
1.1.1.6   root     4959:             break;
1.1.1.5   root     4960:         default:
                   4961:             goto die;
                   4962:         }
                   4963:         break;
                   4964:     case 1:
                   4965:         switch (sel) {
                   4966:         case 0:
1.1.1.6   root     4967:             /* ignored */
1.1.1.5   root     4968:             rn = "Random";
1.1.1.6   root     4969:             break;
1.1.1.5   root     4970:         case 1:
1.1.1.6   root     4971:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4972:             gen_helper_mtc0_vpecontrol(arg);
1.1.1.5   root     4973:             rn = "VPEControl";
1.1.1.6   root     4974:             break;
1.1.1.5   root     4975:         case 2:
1.1.1.6   root     4976:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4977:             gen_helper_mtc0_vpeconf0(arg);
1.1.1.5   root     4978:             rn = "VPEConf0";
1.1.1.6   root     4979:             break;
1.1.1.5   root     4980:         case 3:
1.1.1.6   root     4981:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4982:             gen_helper_mtc0_vpeconf1(arg);
1.1.1.5   root     4983:             rn = "VPEConf1";
1.1.1.6   root     4984:             break;
1.1.1.5   root     4985:         case 4:
1.1.1.6   root     4986:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4987:             gen_helper_mtc0_yqmask(arg);
1.1.1.5   root     4988:             rn = "YQMask";
1.1.1.6   root     4989:             break;
1.1.1.5   root     4990:         case 5:
1.1.1.6   root     4991:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4992:             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_VPESchedule));
1.1.1.5   root     4993:             rn = "VPESchedule";
1.1.1.6   root     4994:             break;
1.1.1.5   root     4995:         case 6:
1.1.1.6   root     4996:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4997:             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
1.1.1.5   root     4998:             rn = "VPEScheFBack";
1.1.1.6   root     4999:             break;
1.1.1.5   root     5000:         case 7:
1.1.1.6   root     5001:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     5002:             gen_helper_mtc0_vpeopt(arg);
1.1.1.5   root     5003:             rn = "VPEOpt";
1.1.1.6   root     5004:             break;
1.1.1.5   root     5005:         default:
                   5006:             goto die;
                   5007:         }
                   5008:         break;
                   5009:     case 2:
                   5010:         switch (sel) {
                   5011:         case 0:
1.1.1.8   root     5012:             gen_helper_mtc0_entrylo0(arg);
1.1.1.6   root     5013:             rn = "EntryLo0";
                   5014:             break;
                   5015:         case 1:
                   5016:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     5017:             gen_helper_mtc0_tcstatus(arg);
1.1.1.6   root     5018:             rn = "TCStatus";
                   5019:             break;
                   5020:         case 2:
                   5021:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     5022:             gen_helper_mtc0_tcbind(arg);
1.1.1.6   root     5023:             rn = "TCBind";
                   5024:             break;
1.1.1.5   root     5025:         case 3:
1.1.1.6   root     5026:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     5027:             gen_helper_mtc0_tcrestart(arg);
1.1.1.6   root     5028:             rn = "TCRestart";
                   5029:             break;
1.1.1.5   root     5030:         case 4:
1.1.1.6   root     5031:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     5032:             gen_helper_mtc0_tchalt(arg);
1.1.1.6   root     5033:             rn = "TCHalt";
                   5034:             break;
1.1.1.5   root     5035:         case 5:
1.1.1.6   root     5036:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     5037:             gen_helper_mtc0_tccontext(arg);
1.1.1.6   root     5038:             rn = "TCContext";
                   5039:             break;
1.1.1.5   root     5040:         case 6:
1.1.1.6   root     5041:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     5042:             gen_helper_mtc0_tcschedule(arg);
1.1.1.6   root     5043:             rn = "TCSchedule";
                   5044:             break;
1.1.1.5   root     5045:         case 7:
1.1.1.6   root     5046:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     5047:             gen_helper_mtc0_tcschefback(arg);
1.1.1.6   root     5048:             rn = "TCScheFBack";
                   5049:             break;
1.1.1.5   root     5050:         default:
                   5051:             goto die;
                   5052:         }
                   5053:         break;
                   5054:     case 3:
                   5055:         switch (sel) {
                   5056:         case 0:
1.1.1.8   root     5057:             gen_helper_mtc0_entrylo1(arg);
1.1.1.6   root     5058:             rn = "EntryLo1";
                   5059:             break;
1.1.1.5   root     5060:         default:
                   5061:             goto die;
1.1.1.6   root     5062:         }
1.1.1.5   root     5063:         break;
                   5064:     case 4:
                   5065:         switch (sel) {
                   5066:         case 0:
1.1.1.8   root     5067:             gen_helper_mtc0_context(arg);
1.1.1.6   root     5068:             rn = "Context";
                   5069:             break;
                   5070:         case 1:
1.1.1.8   root     5071: //           gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
1.1.1.6   root     5072:             rn = "ContextConfig";
                   5073: //           break;
1.1.1.5   root     5074:         default:
                   5075:             goto die;
1.1.1.6   root     5076:         }
1.1.1.5   root     5077:         break;
                   5078:     case 5:
                   5079:         switch (sel) {
                   5080:         case 0:
1.1.1.8   root     5081:             gen_helper_mtc0_pagemask(arg);
1.1.1.6   root     5082:             rn = "PageMask";
                   5083:             break;
                   5084:         case 1:
                   5085:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5086:             gen_helper_mtc0_pagegrain(arg);
1.1.1.6   root     5087:             rn = "PageGrain";
                   5088:             break;
1.1.1.5   root     5089:         default:
                   5090:             goto die;
1.1.1.6   root     5091:         }
1.1.1.5   root     5092:         break;
                   5093:     case 6:
                   5094:         switch (sel) {
                   5095:         case 0:
1.1.1.8   root     5096:             gen_helper_mtc0_wired(arg);
1.1.1.6   root     5097:             rn = "Wired";
                   5098:             break;
                   5099:         case 1:
                   5100:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5101:             gen_helper_mtc0_srsconf0(arg);
1.1.1.6   root     5102:             rn = "SRSConf0";
                   5103:             break;
                   5104:         case 2:
                   5105:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5106:             gen_helper_mtc0_srsconf1(arg);
1.1.1.6   root     5107:             rn = "SRSConf1";
                   5108:             break;
1.1.1.5   root     5109:         case 3:
1.1.1.6   root     5110:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5111:             gen_helper_mtc0_srsconf2(arg);
1.1.1.6   root     5112:             rn = "SRSConf2";
                   5113:             break;
1.1.1.5   root     5114:         case 4:
1.1.1.6   root     5115:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5116:             gen_helper_mtc0_srsconf3(arg);
1.1.1.6   root     5117:             rn = "SRSConf3";
                   5118:             break;
1.1.1.5   root     5119:         case 5:
1.1.1.6   root     5120:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5121:             gen_helper_mtc0_srsconf4(arg);
1.1.1.6   root     5122:             rn = "SRSConf4";
                   5123:             break;
1.1.1.5   root     5124:         default:
                   5125:             goto die;
1.1.1.6   root     5126:         }
1.1.1.5   root     5127:         break;
                   5128:     case 7:
                   5129:         switch (sel) {
                   5130:         case 0:
1.1.1.6   root     5131:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5132:             gen_helper_mtc0_hwrena(arg);
1.1.1.6   root     5133:             rn = "HWREna";
                   5134:             break;
1.1.1.5   root     5135:         default:
                   5136:             goto die;
1.1.1.6   root     5137:         }
1.1.1.5   root     5138:         break;
                   5139:     case 8:
                   5140:         /* ignored */
1.1.1.7   root     5141:         rn = "BadVAddr";
1.1.1.5   root     5142:         break;
                   5143:     case 9:
                   5144:         switch (sel) {
                   5145:         case 0:
1.1.1.8   root     5146:             gen_helper_mtc0_count(arg);
1.1.1.6   root     5147:             rn = "Count";
                   5148:             break;
                   5149:         /* 6,7 are implementation dependent */
1.1.1.5   root     5150:         default:
                   5151:             goto die;
1.1.1.6   root     5152:         }
                   5153:         /* Stop translation as we may have switched the execution mode */
                   5154:         ctx->bstate = BS_STOP;
1.1.1.5   root     5155:         break;
                   5156:     case 10:
                   5157:         switch (sel) {
                   5158:         case 0:
1.1.1.8   root     5159:             gen_helper_mtc0_entryhi(arg);
1.1.1.6   root     5160:             rn = "EntryHi";
                   5161:             break;
1.1.1.5   root     5162:         default:
                   5163:             goto die;
1.1.1.6   root     5164:         }
1.1.1.5   root     5165:         break;
                   5166:     case 11:
                   5167:         switch (sel) {
                   5168:         case 0:
1.1.1.8   root     5169:             gen_helper_mtc0_compare(arg);
1.1.1.6   root     5170:             rn = "Compare";
                   5171:             break;
                   5172:         /* 6,7 are implementation dependent */
1.1.1.5   root     5173:         default:
                   5174:             goto die;
1.1.1.6   root     5175:         }
                   5176:         /* Stop translation as we may have switched the execution mode */
                   5177:         ctx->bstate = BS_STOP;
1.1.1.5   root     5178:         break;
                   5179:     case 12:
                   5180:         switch (sel) {
                   5181:         case 0:
1.1.1.8   root     5182:             save_cpu_state(ctx, 1);
                   5183:             gen_helper_mtc0_status(arg);
1.1.1.6   root     5184:             /* BS_STOP isn't good enough here, hflags may have changed. */
                   5185:             gen_save_pc(ctx->pc + 4);
                   5186:             ctx->bstate = BS_EXCP;
                   5187:             rn = "Status";
                   5188:             break;
                   5189:         case 1:
                   5190:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5191:             gen_helper_mtc0_intctl(arg);
1.1.1.6   root     5192:             /* Stop translation as we may have switched the execution mode */
                   5193:             ctx->bstate = BS_STOP;
                   5194:             rn = "IntCtl";
                   5195:             break;
                   5196:         case 2:
                   5197:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5198:             gen_helper_mtc0_srsctl(arg);
1.1.1.6   root     5199:             /* Stop translation as we may have switched the execution mode */
                   5200:             ctx->bstate = BS_STOP;
                   5201:             rn = "SRSCtl";
                   5202:             break;
1.1.1.5   root     5203:         case 3:
1.1.1.6   root     5204:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5205:             gen_mtc0_store32(arg, offsetof(CPUState, CP0_SRSMap));
1.1.1.6   root     5206:             /* Stop translation as we may have switched the execution mode */
                   5207:             ctx->bstate = BS_STOP;
                   5208:             rn = "SRSMap";
                   5209:             break;
1.1.1.5   root     5210:         default:
                   5211:             goto die;
1.1.1.6   root     5212:         }
1.1.1.5   root     5213:         break;
                   5214:     case 13:
                   5215:         switch (sel) {
                   5216:         case 0:
1.1.1.8   root     5217:             save_cpu_state(ctx, 1);
1.1.1.12  root     5218:             /* Mark as an IO operation because we may trigger a software
                   5219:                interrupt.  */
                   5220:             if (use_icount) {
                   5221:                 gen_io_start();
                   5222:             }
1.1.1.8   root     5223:             gen_helper_mtc0_cause(arg);
1.1.1.12  root     5224:             if (use_icount) {
                   5225:                 gen_io_end();
                   5226:             }
                   5227:             /* Stop translation as we may have triggered an intetrupt */
                   5228:             ctx->bstate = BS_STOP;
1.1.1.6   root     5229:             rn = "Cause";
                   5230:             break;
1.1.1.5   root     5231:         default:
                   5232:             goto die;
1.1.1.6   root     5233:         }
1.1.1.5   root     5234:         break;
                   5235:     case 14:
                   5236:         switch (sel) {
                   5237:         case 0:
1.1.1.8   root     5238:             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
1.1.1.6   root     5239:             rn = "EPC";
                   5240:             break;
1.1.1.5   root     5241:         default:
                   5242:             goto die;
1.1.1.6   root     5243:         }
1.1.1.5   root     5244:         break;
                   5245:     case 15:
                   5246:         switch (sel) {
                   5247:         case 0:
1.1.1.6   root     5248:             /* ignored */
                   5249:             rn = "PRid";
                   5250:             break;
                   5251:         case 1:
                   5252:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5253:             gen_helper_mtc0_ebase(arg);
1.1.1.6   root     5254:             rn = "EBase";
                   5255:             break;
1.1.1.5   root     5256:         default:
                   5257:             goto die;
1.1.1.6   root     5258:         }
1.1.1.5   root     5259:         break;
                   5260:     case 16:
                   5261:         switch (sel) {
                   5262:         case 0:
1.1.1.8   root     5263:             gen_helper_mtc0_config0(arg);
1.1.1.5   root     5264:             rn = "Config";
1.1.1.6   root     5265:             /* Stop translation as we may have switched the execution mode */
                   5266:             ctx->bstate = BS_STOP;
1.1.1.5   root     5267:             break;
                   5268:         case 1:
1.1.1.8   root     5269:             /* ignored, read only */
1.1.1.5   root     5270:             rn = "Config1";
                   5271:             break;
                   5272:         case 2:
1.1.1.8   root     5273:             gen_helper_mtc0_config2(arg);
1.1.1.5   root     5274:             rn = "Config2";
1.1.1.6   root     5275:             /* Stop translation as we may have switched the execution mode */
                   5276:             ctx->bstate = BS_STOP;
1.1.1.5   root     5277:             break;
                   5278:         case 3:
1.1.1.6   root     5279:             /* ignored */
1.1.1.5   root     5280:             rn = "Config3";
                   5281:             break;
                   5282:         /* 6,7 are implementation dependent */
                   5283:         default:
                   5284:             rn = "Invalid config selector";
                   5285:             goto die;
                   5286:         }
                   5287:         break;
                   5288:     case 17:
                   5289:         switch (sel) {
                   5290:         case 0:
1.1.1.9   root     5291:             gen_helper_mtc0_lladdr(arg);
1.1.1.6   root     5292:             rn = "LLAddr";
                   5293:             break;
1.1.1.5   root     5294:         default:
                   5295:             goto die;
                   5296:         }
                   5297:         break;
                   5298:     case 18:
                   5299:         switch (sel) {
1.1.1.6   root     5300:         case 0 ... 7:
1.1.1.8   root     5301:             gen_helper_1i(mtc0_watchlo, arg, sel);
1.1.1.6   root     5302:             rn = "WatchLo";
                   5303:             break;
1.1.1.5   root     5304:         default:
                   5305:             goto die;
                   5306:         }
                   5307:         break;
                   5308:     case 19:
                   5309:         switch (sel) {
1.1.1.6   root     5310:         case 0 ... 7:
1.1.1.8   root     5311:             gen_helper_1i(mtc0_watchhi, arg, sel);
1.1.1.6   root     5312:             rn = "WatchHi";
                   5313:             break;
1.1.1.5   root     5314:         default:
                   5315:             goto die;
                   5316:         }
                   5317:         break;
                   5318:     case 20:
                   5319:         switch (sel) {
                   5320:         case 0:
1.1.1.6   root     5321:             check_insn(env, ctx, ISA_MIPS3);
1.1.1.8   root     5322:             gen_helper_mtc0_xcontext(arg);
1.1.1.6   root     5323:             rn = "XContext";
                   5324:             break;
1.1.1.5   root     5325:         default:
                   5326:             goto die;
                   5327:         }
                   5328:         break;
                   5329:     case 21:
                   5330:        /* Officially reserved, but sel 0 is used for R1x000 framemask */
                   5331:         switch (sel) {
                   5332:         case 0:
1.1.1.8   root     5333:             gen_helper_mtc0_framemask(arg);
1.1.1.6   root     5334:             rn = "Framemask";
                   5335:             break;
1.1.1.5   root     5336:         default:
                   5337:             goto die;
                   5338:         }
                   5339:         break;
                   5340:     case 22:
                   5341:         /* ignored */
                   5342:         rn = "Diagnostic"; /* implementation dependent */
1.1.1.6   root     5343:         break;
1.1.1.5   root     5344:     case 23:
                   5345:         switch (sel) {
                   5346:         case 0:
1.1.1.8   root     5347:             gen_helper_mtc0_debug(arg); /* EJTAG support */
1.1.1.6   root     5348:             /* BS_STOP isn't good enough here, hflags may have changed. */
                   5349:             gen_save_pc(ctx->pc + 4);
                   5350:             ctx->bstate = BS_EXCP;
                   5351:             rn = "Debug";
                   5352:             break;
                   5353:         case 1:
1.1.1.8   root     5354: //            gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
1.1.1.6   root     5355:             /* Stop translation as we may have switched the execution mode */
                   5356:             ctx->bstate = BS_STOP;
                   5357:             rn = "TraceControl";
                   5358: //            break;
                   5359:         case 2:
1.1.1.8   root     5360: //            gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
1.1.1.6   root     5361:             /* Stop translation as we may have switched the execution mode */
                   5362:             ctx->bstate = BS_STOP;
                   5363:             rn = "TraceControl2";
                   5364: //            break;
                   5365:         case 3:
1.1.1.8   root     5366: //            gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
1.1.1.6   root     5367:             /* Stop translation as we may have switched the execution mode */
                   5368:             ctx->bstate = BS_STOP;
                   5369:             rn = "UserTraceData";
                   5370: //            break;
1.1.1.5   root     5371:         case 4:
1.1.1.8   root     5372: //            gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
1.1.1.6   root     5373:             /* Stop translation as we may have switched the execution mode */
                   5374:             ctx->bstate = BS_STOP;
                   5375:             rn = "TraceBPC";
                   5376: //            break;
1.1.1.5   root     5377:         default:
                   5378:             goto die;
                   5379:         }
                   5380:         break;
                   5381:     case 24:
                   5382:         switch (sel) {
                   5383:         case 0:
1.1.1.7   root     5384:             /* EJTAG support */
1.1.1.8   root     5385:             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
1.1.1.6   root     5386:             rn = "DEPC";
                   5387:             break;
1.1.1.5   root     5388:         default:
                   5389:             goto die;
                   5390:         }
                   5391:         break;
                   5392:     case 25:
                   5393:         switch (sel) {
                   5394:         case 0:
1.1.1.8   root     5395:             gen_helper_mtc0_performance0(arg);
1.1.1.6   root     5396:             rn = "Performance0";
                   5397:             break;
                   5398:         case 1:
1.1.1.8   root     5399: //            gen_helper_mtc0_performance1(arg);
1.1.1.6   root     5400:             rn = "Performance1";
                   5401: //            break;
                   5402:         case 2:
1.1.1.8   root     5403: //            gen_helper_mtc0_performance2(arg);
1.1.1.6   root     5404:             rn = "Performance2";
                   5405: //            break;
1.1.1.5   root     5406:         case 3:
1.1.1.8   root     5407: //            gen_helper_mtc0_performance3(arg);
1.1.1.6   root     5408:             rn = "Performance3";
                   5409: //            break;
1.1.1.5   root     5410:         case 4:
1.1.1.8   root     5411: //            gen_helper_mtc0_performance4(arg);
1.1.1.6   root     5412:             rn = "Performance4";
                   5413: //            break;
1.1.1.5   root     5414:         case 5:
1.1.1.8   root     5415: //            gen_helper_mtc0_performance5(arg);
1.1.1.6   root     5416:             rn = "Performance5";
                   5417: //            break;
1.1.1.5   root     5418:         case 6:
1.1.1.8   root     5419: //            gen_helper_mtc0_performance6(arg);
1.1.1.6   root     5420:             rn = "Performance6";
                   5421: //            break;
1.1.1.5   root     5422:         case 7:
1.1.1.8   root     5423: //            gen_helper_mtc0_performance7(arg);
1.1.1.6   root     5424:             rn = "Performance7";
                   5425: //            break;
1.1.1.5   root     5426:         default:
                   5427:             goto die;
                   5428:         }
1.1.1.6   root     5429:         break;
1.1.1.5   root     5430:     case 26:
1.1.1.6   root     5431:         /* ignored */
1.1.1.5   root     5432:         rn = "ECC";
1.1.1.6   root     5433:         break;
1.1.1.5   root     5434:     case 27:
                   5435:         switch (sel) {
                   5436:         case 0 ... 3:
1.1.1.6   root     5437:             /* ignored */
                   5438:             rn = "CacheErr";
                   5439:             break;
1.1.1.5   root     5440:         default:
                   5441:             goto die;
                   5442:         }
1.1.1.6   root     5443:         break;
1.1.1.5   root     5444:     case 28:
                   5445:         switch (sel) {
                   5446:         case 0:
                   5447:         case 2:
                   5448:         case 4:
                   5449:         case 6:
1.1.1.8   root     5450:             gen_helper_mtc0_taglo(arg);
1.1.1.5   root     5451:             rn = "TagLo";
                   5452:             break;
                   5453:         case 1:
                   5454:         case 3:
                   5455:         case 5:
                   5456:         case 7:
1.1.1.8   root     5457:             gen_helper_mtc0_datalo(arg);
1.1.1.5   root     5458:             rn = "DataLo";
                   5459:             break;
                   5460:         default:
                   5461:             goto die;
                   5462:         }
                   5463:         break;
                   5464:     case 29:
                   5465:         switch (sel) {
                   5466:         case 0:
                   5467:         case 2:
                   5468:         case 4:
                   5469:         case 6:
1.1.1.8   root     5470:             gen_helper_mtc0_taghi(arg);
1.1.1.5   root     5471:             rn = "TagHi";
                   5472:             break;
                   5473:         case 1:
                   5474:         case 3:
                   5475:         case 5:
                   5476:         case 7:
1.1.1.8   root     5477:             gen_helper_mtc0_datahi(arg);
1.1.1.5   root     5478:             rn = "DataHi";
                   5479:             break;
                   5480:         default:
                   5481:             rn = "invalid sel";
                   5482:             goto die;
                   5483:         }
1.1.1.6   root     5484:         break;
1.1.1.5   root     5485:     case 30:
                   5486:         switch (sel) {
                   5487:         case 0:
1.1.1.8   root     5488:             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
1.1.1.6   root     5489:             rn = "ErrorEPC";
                   5490:             break;
1.1.1.5   root     5491:         default:
                   5492:             goto die;
                   5493:         }
                   5494:         break;
                   5495:     case 31:
                   5496:         switch (sel) {
                   5497:         case 0:
1.1.1.7   root     5498:             /* EJTAG support */
1.1.1.8   root     5499:             gen_mtc0_store32(arg, offsetof(CPUState, CP0_DESAVE));
1.1.1.6   root     5500:             rn = "DESAVE";
                   5501:             break;
1.1.1.5   root     5502:         default:
                   5503:             goto die;
                   5504:         }
1.1.1.6   root     5505:         /* Stop translation as we may have switched the execution mode */
                   5506:         ctx->bstate = BS_STOP;
1.1.1.5   root     5507:         break;
                   5508:     default:
1.1.1.6   root     5509:         goto die;
1.1.1.5   root     5510:     }
1.1.1.13! root     5511:     (void)rn; /* avoid a compiler warning */
1.1.1.7   root     5512:     LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
                   5513:     /* For simplicity assume that all writes can cause interrupts.  */
                   5514:     if (use_icount) {
                   5515:         gen_io_end();
                   5516:         ctx->bstate = BS_STOP;
1.1.1.5   root     5517:     }
                   5518:     return;
                   5519: 
                   5520: die:
1.1.1.7   root     5521:     LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
1.1.1.5   root     5522:     generate_exception(ctx, EXCP_RI);
                   5523: }
1.1.1.6   root     5524: #endif /* TARGET_MIPS64 */
1.1.1.5   root     5525: 
1.1.1.7   root     5526: static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
1.1.1.6   root     5527:                      int u, int sel, int h)
1.1.1.5   root     5528: {
1.1.1.6   root     5529:     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1.1.1.7   root     5530:     TCGv t0 = tcg_temp_local_new();
1.1.1.5   root     5531: 
1.1.1.6   root     5532:     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
1.1.1.7   root     5533:         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
                   5534:          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
                   5535:         tcg_gen_movi_tl(t0, -1);
1.1.1.6   root     5536:     else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
                   5537:              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1.1.1.7   root     5538:         tcg_gen_movi_tl(t0, -1);
1.1.1.6   root     5539:     else if (u == 0) {
                   5540:         switch (rt) {
                   5541:         case 2:
                   5542:             switch (sel) {
                   5543:             case 1:
1.1.1.7   root     5544:                 gen_helper_mftc0_tcstatus(t0);
1.1.1.6   root     5545:                 break;
                   5546:             case 2:
1.1.1.7   root     5547:                 gen_helper_mftc0_tcbind(t0);
1.1.1.6   root     5548:                 break;
                   5549:             case 3:
1.1.1.7   root     5550:                 gen_helper_mftc0_tcrestart(t0);
1.1.1.6   root     5551:                 break;
                   5552:             case 4:
1.1.1.7   root     5553:                 gen_helper_mftc0_tchalt(t0);
1.1.1.6   root     5554:                 break;
                   5555:             case 5:
1.1.1.7   root     5556:                 gen_helper_mftc0_tccontext(t0);
1.1.1.6   root     5557:                 break;
                   5558:             case 6:
1.1.1.7   root     5559:                 gen_helper_mftc0_tcschedule(t0);
1.1.1.6   root     5560:                 break;
                   5561:             case 7:
1.1.1.7   root     5562:                 gen_helper_mftc0_tcschefback(t0);
1.1.1.6   root     5563:                 break;
                   5564:             default:
1.1.1.7   root     5565:                 gen_mfc0(env, ctx, t0, rt, sel);
1.1.1.6   root     5566:                 break;
                   5567:             }
                   5568:             break;
                   5569:         case 10:
                   5570:             switch (sel) {
                   5571:             case 0:
1.1.1.7   root     5572:                 gen_helper_mftc0_entryhi(t0);
1.1.1.6   root     5573:                 break;
                   5574:             default:
1.1.1.7   root     5575:                 gen_mfc0(env, ctx, t0, rt, sel);
1.1.1.6   root     5576:                 break;
                   5577:             }
                   5578:         case 12:
                   5579:             switch (sel) {
                   5580:             case 0:
1.1.1.7   root     5581:                 gen_helper_mftc0_status(t0);
1.1.1.6   root     5582:                 break;
                   5583:             default:
1.1.1.7   root     5584:                 gen_mfc0(env, ctx, t0, rt, sel);
1.1.1.6   root     5585:                 break;
                   5586:             }
                   5587:         case 23:
                   5588:             switch (sel) {
                   5589:             case 0:
1.1.1.7   root     5590:                 gen_helper_mftc0_debug(t0);
1.1.1.6   root     5591:                 break;
                   5592:             default:
1.1.1.7   root     5593:                 gen_mfc0(env, ctx, t0, rt, sel);
1.1.1.6   root     5594:                 break;
                   5595:             }
                   5596:             break;
                   5597:         default:
1.1.1.7   root     5598:             gen_mfc0(env, ctx, t0, rt, sel);
1.1.1.6   root     5599:         }
                   5600:     } else switch (sel) {
                   5601:     /* GPR registers. */
                   5602:     case 0:
1.1.1.7   root     5603:         gen_helper_1i(mftgpr, t0, rt);
1.1.1.6   root     5604:         break;
                   5605:     /* Auxiliary CPU registers */
                   5606:     case 1:
                   5607:         switch (rt) {
                   5608:         case 0:
1.1.1.7   root     5609:             gen_helper_1i(mftlo, t0, 0);
1.1.1.6   root     5610:             break;
                   5611:         case 1:
1.1.1.7   root     5612:             gen_helper_1i(mfthi, t0, 0);
1.1.1.6   root     5613:             break;
                   5614:         case 2:
1.1.1.7   root     5615:             gen_helper_1i(mftacx, t0, 0);
1.1.1.6   root     5616:             break;
                   5617:         case 4:
1.1.1.7   root     5618:             gen_helper_1i(mftlo, t0, 1);
1.1.1.6   root     5619:             break;
                   5620:         case 5:
1.1.1.7   root     5621:             gen_helper_1i(mfthi, t0, 1);
1.1.1.6   root     5622:             break;
                   5623:         case 6:
1.1.1.7   root     5624:             gen_helper_1i(mftacx, t0, 1);
1.1.1.6   root     5625:             break;
                   5626:         case 8:
1.1.1.7   root     5627:             gen_helper_1i(mftlo, t0, 2);
1.1.1.6   root     5628:             break;
                   5629:         case 9:
1.1.1.7   root     5630:             gen_helper_1i(mfthi, t0, 2);
1.1.1.6   root     5631:             break;
                   5632:         case 10:
1.1.1.7   root     5633:             gen_helper_1i(mftacx, t0, 2);
1.1.1.6   root     5634:             break;
                   5635:         case 12:
1.1.1.7   root     5636:             gen_helper_1i(mftlo, t0, 3);
1.1.1.6   root     5637:             break;
                   5638:         case 13:
1.1.1.7   root     5639:             gen_helper_1i(mfthi, t0, 3);
1.1.1.6   root     5640:             break;
                   5641:         case 14:
1.1.1.7   root     5642:             gen_helper_1i(mftacx, t0, 3);
1.1.1.6   root     5643:             break;
                   5644:         case 16:
1.1.1.7   root     5645:             gen_helper_mftdsp(t0);
1.1.1.6   root     5646:             break;
                   5647:         default:
                   5648:             goto die;
                   5649:         }
                   5650:         break;
                   5651:     /* Floating point (COP1). */
                   5652:     case 2:
                   5653:         /* XXX: For now we support only a single FPU context. */
                   5654:         if (h == 0) {
1.1.1.7   root     5655:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   5656: 
                   5657:             gen_load_fpr32(fp0, rt);
                   5658:             tcg_gen_ext_i32_tl(t0, fp0);
                   5659:             tcg_temp_free_i32(fp0);
1.1.1.6   root     5660:         } else {
1.1.1.7   root     5661:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   5662: 
                   5663:             gen_load_fpr32h(fp0, rt);
                   5664:             tcg_gen_ext_i32_tl(t0, fp0);
                   5665:             tcg_temp_free_i32(fp0);
1.1.1.6   root     5666:         }
                   5667:         break;
                   5668:     case 3:
                   5669:         /* XXX: For now we support only a single FPU context. */
1.1.1.7   root     5670:         gen_helper_1i(cfc1, t0, rt);
1.1.1.6   root     5671:         break;
                   5672:     /* COP2: Not implemented. */
                   5673:     case 4:
                   5674:     case 5:
                   5675:         /* fall through */
                   5676:     default:
                   5677:         goto die;
                   5678:     }
1.1.1.7   root     5679:     LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
                   5680:     gen_store_gpr(t0, rd);
                   5681:     tcg_temp_free(t0);
1.1.1.6   root     5682:     return;
                   5683: 
                   5684: die:
1.1.1.7   root     5685:     tcg_temp_free(t0);
                   5686:     LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1.1.1.6   root     5687:     generate_exception(ctx, EXCP_RI);
                   5688: }
                   5689: 
1.1.1.7   root     5690: static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
1.1.1.6   root     5691:                      int u, int sel, int h)
                   5692: {
                   5693:     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1.1.1.7   root     5694:     TCGv t0 = tcg_temp_local_new();
1.1.1.6   root     5695: 
1.1.1.7   root     5696:     gen_load_gpr(t0, rt);
1.1.1.6   root     5697:     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
1.1.1.7   root     5698:         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
                   5699:          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1.1.1.6   root     5700:         /* NOP */ ;
                   5701:     else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
                   5702:              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
                   5703:         /* NOP */ ;
                   5704:     else if (u == 0) {
                   5705:         switch (rd) {
                   5706:         case 2:
                   5707:             switch (sel) {
                   5708:             case 1:
1.1.1.7   root     5709:                 gen_helper_mttc0_tcstatus(t0);
1.1.1.6   root     5710:                 break;
                   5711:             case 2:
1.1.1.7   root     5712:                 gen_helper_mttc0_tcbind(t0);
1.1.1.6   root     5713:                 break;
                   5714:             case 3:
1.1.1.7   root     5715:                 gen_helper_mttc0_tcrestart(t0);
1.1.1.6   root     5716:                 break;
                   5717:             case 4:
1.1.1.7   root     5718:                 gen_helper_mttc0_tchalt(t0);
1.1.1.6   root     5719:                 break;
                   5720:             case 5:
1.1.1.7   root     5721:                 gen_helper_mttc0_tccontext(t0);
1.1.1.6   root     5722:                 break;
                   5723:             case 6:
1.1.1.7   root     5724:                 gen_helper_mttc0_tcschedule(t0);
1.1.1.6   root     5725:                 break;
                   5726:             case 7:
1.1.1.7   root     5727:                 gen_helper_mttc0_tcschefback(t0);
1.1.1.6   root     5728:                 break;
                   5729:             default:
1.1.1.7   root     5730:                 gen_mtc0(env, ctx, t0, rd, sel);
1.1.1.6   root     5731:                 break;
                   5732:             }
                   5733:             break;
                   5734:         case 10:
                   5735:             switch (sel) {
                   5736:             case 0:
1.1.1.7   root     5737:                 gen_helper_mttc0_entryhi(t0);
1.1.1.6   root     5738:                 break;
                   5739:             default:
1.1.1.7   root     5740:                 gen_mtc0(env, ctx, t0, rd, sel);
1.1.1.6   root     5741:                 break;
                   5742:             }
                   5743:         case 12:
                   5744:             switch (sel) {
                   5745:             case 0:
1.1.1.7   root     5746:                 gen_helper_mttc0_status(t0);
1.1.1.6   root     5747:                 break;
                   5748:             default:
1.1.1.7   root     5749:                 gen_mtc0(env, ctx, t0, rd, sel);
1.1.1.6   root     5750:                 break;
                   5751:             }
                   5752:         case 23:
                   5753:             switch (sel) {
                   5754:             case 0:
1.1.1.7   root     5755:                 gen_helper_mttc0_debug(t0);
1.1.1.6   root     5756:                 break;
                   5757:             default:
1.1.1.7   root     5758:                 gen_mtc0(env, ctx, t0, rd, sel);
1.1.1.6   root     5759:                 break;
                   5760:             }
                   5761:             break;
                   5762:         default:
1.1.1.7   root     5763:             gen_mtc0(env, ctx, t0, rd, sel);
1.1.1.6   root     5764:         }
                   5765:     } else switch (sel) {
                   5766:     /* GPR registers. */
                   5767:     case 0:
1.1.1.7   root     5768:         gen_helper_1i(mttgpr, t0, rd);
1.1.1.6   root     5769:         break;
                   5770:     /* Auxiliary CPU registers */
                   5771:     case 1:
                   5772:         switch (rd) {
                   5773:         case 0:
1.1.1.7   root     5774:             gen_helper_1i(mttlo, t0, 0);
1.1.1.6   root     5775:             break;
                   5776:         case 1:
1.1.1.7   root     5777:             gen_helper_1i(mtthi, t0, 0);
1.1.1.6   root     5778:             break;
                   5779:         case 2:
1.1.1.7   root     5780:             gen_helper_1i(mttacx, t0, 0);
1.1.1.6   root     5781:             break;
                   5782:         case 4:
1.1.1.7   root     5783:             gen_helper_1i(mttlo, t0, 1);
1.1.1.6   root     5784:             break;
                   5785:         case 5:
1.1.1.7   root     5786:             gen_helper_1i(mtthi, t0, 1);
1.1.1.6   root     5787:             break;
                   5788:         case 6:
1.1.1.7   root     5789:             gen_helper_1i(mttacx, t0, 1);
1.1.1.6   root     5790:             break;
                   5791:         case 8:
1.1.1.7   root     5792:             gen_helper_1i(mttlo, t0, 2);
1.1.1.6   root     5793:             break;
                   5794:         case 9:
1.1.1.7   root     5795:             gen_helper_1i(mtthi, t0, 2);
1.1.1.6   root     5796:             break;
                   5797:         case 10:
1.1.1.7   root     5798:             gen_helper_1i(mttacx, t0, 2);
1.1.1.6   root     5799:             break;
                   5800:         case 12:
1.1.1.7   root     5801:             gen_helper_1i(mttlo, t0, 3);
1.1.1.6   root     5802:             break;
                   5803:         case 13:
1.1.1.7   root     5804:             gen_helper_1i(mtthi, t0, 3);
1.1.1.6   root     5805:             break;
                   5806:         case 14:
1.1.1.7   root     5807:             gen_helper_1i(mttacx, t0, 3);
1.1.1.6   root     5808:             break;
                   5809:         case 16:
1.1.1.7   root     5810:             gen_helper_mttdsp(t0);
1.1.1.6   root     5811:             break;
                   5812:         default:
                   5813:             goto die;
                   5814:         }
                   5815:         break;
                   5816:     /* Floating point (COP1). */
                   5817:     case 2:
                   5818:         /* XXX: For now we support only a single FPU context. */
                   5819:         if (h == 0) {
1.1.1.7   root     5820:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   5821: 
                   5822:             tcg_gen_trunc_tl_i32(fp0, t0);
                   5823:             gen_store_fpr32(fp0, rd);
                   5824:             tcg_temp_free_i32(fp0);
1.1.1.6   root     5825:         } else {
1.1.1.7   root     5826:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   5827: 
                   5828:             tcg_gen_trunc_tl_i32(fp0, t0);
                   5829:             gen_store_fpr32h(fp0, rd);
                   5830:             tcg_temp_free_i32(fp0);
1.1.1.6   root     5831:         }
                   5832:         break;
                   5833:     case 3:
                   5834:         /* XXX: For now we support only a single FPU context. */
1.1.1.7   root     5835:         gen_helper_1i(ctc1, t0, rd);
1.1.1.6   root     5836:         break;
                   5837:     /* COP2: Not implemented. */
                   5838:     case 4:
                   5839:     case 5:
                   5840:         /* fall through */
                   5841:     default:
                   5842:         goto die;
                   5843:     }
1.1.1.7   root     5844:     LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
                   5845:     tcg_temp_free(t0);
1.1.1.6   root     5846:     return;
                   5847: 
                   5848: die:
1.1.1.7   root     5849:     tcg_temp_free(t0);
                   5850:     LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1.1.1.6   root     5851:     generate_exception(ctx, EXCP_RI);
                   5852: }
                   5853: 
                   5854: static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
                   5855: {
                   5856:     const char *opn = "ldst";
1.1.1.5   root     5857: 
                   5858:     switch (opc) {
                   5859:     case OPC_MFC0:
                   5860:         if (rt == 0) {
1.1.1.6   root     5861:             /* Treat as NOP. */
1.1.1.5   root     5862:             return;
                   5863:         }
1.1.1.8   root     5864:         gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
1.1.1.5   root     5865:         opn = "mfc0";
                   5866:         break;
                   5867:     case OPC_MTC0:
1.1.1.7   root     5868:         {
1.1.1.8   root     5869:             TCGv t0 = tcg_temp_new();
1.1.1.7   root     5870: 
                   5871:             gen_load_gpr(t0, rt);
                   5872:             gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
                   5873:             tcg_temp_free(t0);
                   5874:         }
1.1.1.5   root     5875:         opn = "mtc0";
                   5876:         break;
1.1.1.6   root     5877: #if defined(TARGET_MIPS64)
1.1.1.5   root     5878:     case OPC_DMFC0:
1.1.1.6   root     5879:         check_insn(env, ctx, ISA_MIPS3);
1.1.1.5   root     5880:         if (rt == 0) {
1.1.1.6   root     5881:             /* Treat as NOP. */
1.1.1.5   root     5882:             return;
                   5883:         }
1.1.1.8   root     5884:         gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
1.1.1.5   root     5885:         opn = "dmfc0";
                   5886:         break;
                   5887:     case OPC_DMTC0:
1.1.1.6   root     5888:         check_insn(env, ctx, ISA_MIPS3);
1.1.1.7   root     5889:         {
1.1.1.8   root     5890:             TCGv t0 = tcg_temp_new();
1.1.1.7   root     5891: 
                   5892:             gen_load_gpr(t0, rt);
                   5893:             gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
                   5894:             tcg_temp_free(t0);
                   5895:         }
1.1.1.5   root     5896:         opn = "dmtc0";
                   5897:         break;
1.1.1.6   root     5898: #endif
                   5899:     case OPC_MFTR:
                   5900:         check_insn(env, ctx, ASE_MT);
                   5901:         if (rd == 0) {
                   5902:             /* Treat as NOP. */
                   5903:             return;
                   5904:         }
1.1.1.7   root     5905:         gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
1.1.1.6   root     5906:                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
                   5907:         opn = "mftr";
                   5908:         break;
                   5909:     case OPC_MTTR:
                   5910:         check_insn(env, ctx, ASE_MT);
1.1.1.7   root     5911:         gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
1.1.1.6   root     5912:                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
                   5913:         opn = "mttr";
                   5914:         break;
1.1.1.5   root     5915:     case OPC_TLBWI:
                   5916:         opn = "tlbwi";
1.1.1.8   root     5917:         if (!env->tlb->helper_tlbwi)
1.1.1.6   root     5918:             goto die;
1.1.1.7   root     5919:         gen_helper_tlbwi();
1.1.1.5   root     5920:         break;
                   5921:     case OPC_TLBWR:
                   5922:         opn = "tlbwr";
1.1.1.8   root     5923:         if (!env->tlb->helper_tlbwr)
1.1.1.6   root     5924:             goto die;
1.1.1.7   root     5925:         gen_helper_tlbwr();
1.1.1.5   root     5926:         break;
                   5927:     case OPC_TLBP:
                   5928:         opn = "tlbp";
1.1.1.8   root     5929:         if (!env->tlb->helper_tlbp)
1.1.1.6   root     5930:             goto die;
1.1.1.7   root     5931:         gen_helper_tlbp();
1.1.1.5   root     5932:         break;
                   5933:     case OPC_TLBR:
                   5934:         opn = "tlbr";
1.1.1.8   root     5935:         if (!env->tlb->helper_tlbr)
1.1.1.6   root     5936:             goto die;
1.1.1.7   root     5937:         gen_helper_tlbr();
1.1.1.5   root     5938:         break;
                   5939:     case OPC_ERET:
                   5940:         opn = "eret";
1.1.1.6   root     5941:         check_insn(env, ctx, ISA_MIPS2);
1.1.1.7   root     5942:         gen_helper_eret();
1.1.1.5   root     5943:         ctx->bstate = BS_EXCP;
                   5944:         break;
                   5945:     case OPC_DERET:
                   5946:         opn = "deret";
1.1.1.6   root     5947:         check_insn(env, ctx, ISA_MIPS32);
1.1.1.5   root     5948:         if (!(ctx->hflags & MIPS_HFLAG_DM)) {
1.1.1.6   root     5949:             MIPS_INVAL(opn);
1.1.1.5   root     5950:             generate_exception(ctx, EXCP_RI);
                   5951:         } else {
1.1.1.7   root     5952:             gen_helper_deret();
1.1.1.5   root     5953:             ctx->bstate = BS_EXCP;
                   5954:         }
                   5955:         break;
                   5956:     case OPC_WAIT:
                   5957:         opn = "wait";
1.1.1.6   root     5958:         check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
1.1.1.5   root     5959:         /* If we get an exception, we want to restart at next instruction */
                   5960:         ctx->pc += 4;
                   5961:         save_cpu_state(ctx, 1);
                   5962:         ctx->pc -= 4;
1.1.1.7   root     5963:         gen_helper_wait();
1.1.1.5   root     5964:         ctx->bstate = BS_EXCP;
                   5965:         break;
                   5966:     default:
1.1.1.6   root     5967:  die:
                   5968:         MIPS_INVAL(opn);
1.1.1.5   root     5969:         generate_exception(ctx, EXCP_RI);
                   5970:         return;
                   5971:     }
1.1.1.13! root     5972:     (void)opn; /* avoid a compiler warning */
1.1.1.5   root     5973:     MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
                   5974: }
1.1.1.7   root     5975: #endif /* !CONFIG_USER_ONLY */
1.1.1.5   root     5976: 
                   5977: /* CP1 Branches (before delay slot) */
1.1.1.6   root     5978: static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
                   5979:                                  int32_t cc, int32_t offset)
1.1.1.5   root     5980: {
                   5981:     target_ulong btarget;
1.1.1.6   root     5982:     const char *opn = "cp1 cond branch";
1.1.1.7   root     5983:     TCGv_i32 t0 = tcg_temp_new_i32();
1.1.1.6   root     5984: 
                   5985:     if (cc != 0)
                   5986:         check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
1.1.1.5   root     5987: 
                   5988:     btarget = ctx->pc + 4 + offset;
                   5989: 
                   5990:     switch (op) {
                   5991:     case OPC_BC1F:
1.1.1.8   root     5992:         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   5993:         tcg_gen_not_i32(t0, t0);
                   5994:         tcg_gen_andi_i32(t0, t0, 1);
                   5995:         tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.6   root     5996:         opn = "bc1f";
1.1.1.5   root     5997:         goto not_likely;
                   5998:     case OPC_BC1FL:
1.1.1.8   root     5999:         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   6000:         tcg_gen_not_i32(t0, t0);
                   6001:         tcg_gen_andi_i32(t0, t0, 1);
                   6002:         tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.6   root     6003:         opn = "bc1fl";
1.1.1.5   root     6004:         goto likely;
                   6005:     case OPC_BC1T:
1.1.1.8   root     6006:         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   6007:         tcg_gen_andi_i32(t0, t0, 1);
                   6008:         tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.6   root     6009:         opn = "bc1t";
                   6010:         goto not_likely;
1.1.1.5   root     6011:     case OPC_BC1TL:
1.1.1.8   root     6012:         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   6013:         tcg_gen_andi_i32(t0, t0, 1);
                   6014:         tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.6   root     6015:         opn = "bc1tl";
1.1.1.5   root     6016:     likely:
                   6017:         ctx->hflags |= MIPS_HFLAG_BL;
1.1.1.6   root     6018:         break;
                   6019:     case OPC_BC1FANY2:
1.1.1.7   root     6020:         {
1.1.1.8   root     6021:             TCGv_i32 t1 = tcg_temp_new_i32();
                   6022:             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   6023:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
1.1.1.12  root     6024:             tcg_gen_nor_i32(t0, t0, t1);
1.1.1.8   root     6025:             tcg_temp_free_i32(t1);
                   6026:             tcg_gen_andi_i32(t0, t0, 1);
                   6027:             tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.7   root     6028:         }
1.1.1.6   root     6029:         opn = "bc1any2f";
                   6030:         goto not_likely;
                   6031:     case OPC_BC1TANY2:
1.1.1.7   root     6032:         {
1.1.1.8   root     6033:             TCGv_i32 t1 = tcg_temp_new_i32();
                   6034:             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   6035:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
                   6036:             tcg_gen_or_i32(t0, t0, t1);
                   6037:             tcg_temp_free_i32(t1);
                   6038:             tcg_gen_andi_i32(t0, t0, 1);
                   6039:             tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.7   root     6040:         }
1.1.1.6   root     6041:         opn = "bc1any2t";
                   6042:         goto not_likely;
                   6043:     case OPC_BC1FANY4:
1.1.1.7   root     6044:         {
1.1.1.8   root     6045:             TCGv_i32 t1 = tcg_temp_new_i32();
                   6046:             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   6047:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
                   6048:             tcg_gen_or_i32(t0, t0, t1);
                   6049:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
                   6050:             tcg_gen_or_i32(t0, t0, t1);
                   6051:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
1.1.1.12  root     6052:             tcg_gen_nor_i32(t0, t0, t1);
1.1.1.8   root     6053:             tcg_temp_free_i32(t1);
                   6054:             tcg_gen_andi_i32(t0, t0, 1);
                   6055:             tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.7   root     6056:         }
1.1.1.6   root     6057:         opn = "bc1any4f";
                   6058:         goto not_likely;
                   6059:     case OPC_BC1TANY4:
1.1.1.7   root     6060:         {
1.1.1.8   root     6061:             TCGv_i32 t1 = tcg_temp_new_i32();
                   6062:             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   6063:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
                   6064:             tcg_gen_or_i32(t0, t0, t1);
                   6065:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
                   6066:             tcg_gen_or_i32(t0, t0, t1);
                   6067:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
                   6068:             tcg_gen_or_i32(t0, t0, t1);
                   6069:             tcg_temp_free_i32(t1);
                   6070:             tcg_gen_andi_i32(t0, t0, 1);
                   6071:             tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.7   root     6072:         }
1.1.1.6   root     6073:         opn = "bc1any4t";
                   6074:     not_likely:
                   6075:         ctx->hflags |= MIPS_HFLAG_BC;
1.1.1.5   root     6076:         break;
1.1.1.6   root     6077:     default:
                   6078:         MIPS_INVAL(opn);
                   6079:         generate_exception (ctx, EXCP_RI);
1.1.1.7   root     6080:         goto out;
1.1.1.5   root     6081:     }
1.1.1.13! root     6082:     (void)opn; /* avoid a compiler warning */
1.1.1.6   root     6083:     MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
1.1.1.5   root     6084:                ctx->hflags, btarget);
                   6085:     ctx->btarget = btarget;
1.1.1.7   root     6086: 
                   6087:  out:
                   6088:     tcg_temp_free_i32(t0);
1.1.1.5   root     6089: }
                   6090: 
                   6091: /* Coprocessor 1 (FPU) */
1.1.1.6   root     6092: 
                   6093: #define FOP(func, fmt) (((fmt) << 21) | (func))
                   6094: 
1.1.1.12  root     6095: enum fopcode {
                   6096:     OPC_ADD_S = FOP(0, FMT_S),
                   6097:     OPC_SUB_S = FOP(1, FMT_S),
                   6098:     OPC_MUL_S = FOP(2, FMT_S),
                   6099:     OPC_DIV_S = FOP(3, FMT_S),
                   6100:     OPC_SQRT_S = FOP(4, FMT_S),
                   6101:     OPC_ABS_S = FOP(5, FMT_S),
                   6102:     OPC_MOV_S = FOP(6, FMT_S),
                   6103:     OPC_NEG_S = FOP(7, FMT_S),
                   6104:     OPC_ROUND_L_S = FOP(8, FMT_S),
                   6105:     OPC_TRUNC_L_S = FOP(9, FMT_S),
                   6106:     OPC_CEIL_L_S = FOP(10, FMT_S),
                   6107:     OPC_FLOOR_L_S = FOP(11, FMT_S),
                   6108:     OPC_ROUND_W_S = FOP(12, FMT_S),
                   6109:     OPC_TRUNC_W_S = FOP(13, FMT_S),
                   6110:     OPC_CEIL_W_S = FOP(14, FMT_S),
                   6111:     OPC_FLOOR_W_S = FOP(15, FMT_S),
                   6112:     OPC_MOVCF_S = FOP(17, FMT_S),
                   6113:     OPC_MOVZ_S = FOP(18, FMT_S),
                   6114:     OPC_MOVN_S = FOP(19, FMT_S),
                   6115:     OPC_RECIP_S = FOP(21, FMT_S),
                   6116:     OPC_RSQRT_S = FOP(22, FMT_S),
                   6117:     OPC_RECIP2_S = FOP(28, FMT_S),
                   6118:     OPC_RECIP1_S = FOP(29, FMT_S),
                   6119:     OPC_RSQRT1_S = FOP(30, FMT_S),
                   6120:     OPC_RSQRT2_S = FOP(31, FMT_S),
                   6121:     OPC_CVT_D_S = FOP(33, FMT_S),
                   6122:     OPC_CVT_W_S = FOP(36, FMT_S),
                   6123:     OPC_CVT_L_S = FOP(37, FMT_S),
                   6124:     OPC_CVT_PS_S = FOP(38, FMT_S),
                   6125:     OPC_CMP_F_S = FOP (48, FMT_S),
                   6126:     OPC_CMP_UN_S = FOP (49, FMT_S),
                   6127:     OPC_CMP_EQ_S = FOP (50, FMT_S),
                   6128:     OPC_CMP_UEQ_S = FOP (51, FMT_S),
                   6129:     OPC_CMP_OLT_S = FOP (52, FMT_S),
                   6130:     OPC_CMP_ULT_S = FOP (53, FMT_S),
                   6131:     OPC_CMP_OLE_S = FOP (54, FMT_S),
                   6132:     OPC_CMP_ULE_S = FOP (55, FMT_S),
                   6133:     OPC_CMP_SF_S = FOP (56, FMT_S),
                   6134:     OPC_CMP_NGLE_S = FOP (57, FMT_S),
                   6135:     OPC_CMP_SEQ_S = FOP (58, FMT_S),
                   6136:     OPC_CMP_NGL_S = FOP (59, FMT_S),
                   6137:     OPC_CMP_LT_S = FOP (60, FMT_S),
                   6138:     OPC_CMP_NGE_S = FOP (61, FMT_S),
                   6139:     OPC_CMP_LE_S = FOP (62, FMT_S),
                   6140:     OPC_CMP_NGT_S = FOP (63, FMT_S),
                   6141: 
                   6142:     OPC_ADD_D = FOP(0, FMT_D),
                   6143:     OPC_SUB_D = FOP(1, FMT_D),
                   6144:     OPC_MUL_D = FOP(2, FMT_D),
                   6145:     OPC_DIV_D = FOP(3, FMT_D),
                   6146:     OPC_SQRT_D = FOP(4, FMT_D),
                   6147:     OPC_ABS_D = FOP(5, FMT_D),
                   6148:     OPC_MOV_D = FOP(6, FMT_D),
                   6149:     OPC_NEG_D = FOP(7, FMT_D),
                   6150:     OPC_ROUND_L_D = FOP(8, FMT_D),
                   6151:     OPC_TRUNC_L_D = FOP(9, FMT_D),
                   6152:     OPC_CEIL_L_D = FOP(10, FMT_D),
                   6153:     OPC_FLOOR_L_D = FOP(11, FMT_D),
                   6154:     OPC_ROUND_W_D = FOP(12, FMT_D),
                   6155:     OPC_TRUNC_W_D = FOP(13, FMT_D),
                   6156:     OPC_CEIL_W_D = FOP(14, FMT_D),
                   6157:     OPC_FLOOR_W_D = FOP(15, FMT_D),
                   6158:     OPC_MOVCF_D = FOP(17, FMT_D),
                   6159:     OPC_MOVZ_D = FOP(18, FMT_D),
                   6160:     OPC_MOVN_D = FOP(19, FMT_D),
                   6161:     OPC_RECIP_D = FOP(21, FMT_D),
                   6162:     OPC_RSQRT_D = FOP(22, FMT_D),
                   6163:     OPC_RECIP2_D = FOP(28, FMT_D),
                   6164:     OPC_RECIP1_D = FOP(29, FMT_D),
                   6165:     OPC_RSQRT1_D = FOP(30, FMT_D),
                   6166:     OPC_RSQRT2_D = FOP(31, FMT_D),
                   6167:     OPC_CVT_S_D = FOP(32, FMT_D),
                   6168:     OPC_CVT_W_D = FOP(36, FMT_D),
                   6169:     OPC_CVT_L_D = FOP(37, FMT_D),
                   6170:     OPC_CMP_F_D = FOP (48, FMT_D),
                   6171:     OPC_CMP_UN_D = FOP (49, FMT_D),
                   6172:     OPC_CMP_EQ_D = FOP (50, FMT_D),
                   6173:     OPC_CMP_UEQ_D = FOP (51, FMT_D),
                   6174:     OPC_CMP_OLT_D = FOP (52, FMT_D),
                   6175:     OPC_CMP_ULT_D = FOP (53, FMT_D),
                   6176:     OPC_CMP_OLE_D = FOP (54, FMT_D),
                   6177:     OPC_CMP_ULE_D = FOP (55, FMT_D),
                   6178:     OPC_CMP_SF_D = FOP (56, FMT_D),
                   6179:     OPC_CMP_NGLE_D = FOP (57, FMT_D),
                   6180:     OPC_CMP_SEQ_D = FOP (58, FMT_D),
                   6181:     OPC_CMP_NGL_D = FOP (59, FMT_D),
                   6182:     OPC_CMP_LT_D = FOP (60, FMT_D),
                   6183:     OPC_CMP_NGE_D = FOP (61, FMT_D),
                   6184:     OPC_CMP_LE_D = FOP (62, FMT_D),
                   6185:     OPC_CMP_NGT_D = FOP (63, FMT_D),
                   6186: 
                   6187:     OPC_CVT_S_W = FOP(32, FMT_W),
                   6188:     OPC_CVT_D_W = FOP(33, FMT_W),
                   6189:     OPC_CVT_S_L = FOP(32, FMT_L),
                   6190:     OPC_CVT_D_L = FOP(33, FMT_L),
                   6191:     OPC_CVT_PS_PW = FOP(38, FMT_W),
                   6192: 
                   6193:     OPC_ADD_PS = FOP(0, FMT_PS),
                   6194:     OPC_SUB_PS = FOP(1, FMT_PS),
                   6195:     OPC_MUL_PS = FOP(2, FMT_PS),
                   6196:     OPC_DIV_PS = FOP(3, FMT_PS),
                   6197:     OPC_ABS_PS = FOP(5, FMT_PS),
                   6198:     OPC_MOV_PS = FOP(6, FMT_PS),
                   6199:     OPC_NEG_PS = FOP(7, FMT_PS),
                   6200:     OPC_MOVCF_PS = FOP(17, FMT_PS),
                   6201:     OPC_MOVZ_PS = FOP(18, FMT_PS),
                   6202:     OPC_MOVN_PS = FOP(19, FMT_PS),
                   6203:     OPC_ADDR_PS = FOP(24, FMT_PS),
                   6204:     OPC_MULR_PS = FOP(26, FMT_PS),
                   6205:     OPC_RECIP2_PS = FOP(28, FMT_PS),
                   6206:     OPC_RECIP1_PS = FOP(29, FMT_PS),
                   6207:     OPC_RSQRT1_PS = FOP(30, FMT_PS),
                   6208:     OPC_RSQRT2_PS = FOP(31, FMT_PS),
                   6209: 
                   6210:     OPC_CVT_S_PU = FOP(32, FMT_PS),
                   6211:     OPC_CVT_PW_PS = FOP(36, FMT_PS),
                   6212:     OPC_CVT_S_PL = FOP(40, FMT_PS),
                   6213:     OPC_PLL_PS = FOP(44, FMT_PS),
                   6214:     OPC_PLU_PS = FOP(45, FMT_PS),
                   6215:     OPC_PUL_PS = FOP(46, FMT_PS),
                   6216:     OPC_PUU_PS = FOP(47, FMT_PS),
                   6217:     OPC_CMP_F_PS = FOP (48, FMT_PS),
                   6218:     OPC_CMP_UN_PS = FOP (49, FMT_PS),
                   6219:     OPC_CMP_EQ_PS = FOP (50, FMT_PS),
                   6220:     OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
                   6221:     OPC_CMP_OLT_PS = FOP (52, FMT_PS),
                   6222:     OPC_CMP_ULT_PS = FOP (53, FMT_PS),
                   6223:     OPC_CMP_OLE_PS = FOP (54, FMT_PS),
                   6224:     OPC_CMP_ULE_PS = FOP (55, FMT_PS),
                   6225:     OPC_CMP_SF_PS = FOP (56, FMT_PS),
                   6226:     OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
                   6227:     OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
                   6228:     OPC_CMP_NGL_PS = FOP (59, FMT_PS),
                   6229:     OPC_CMP_LT_PS = FOP (60, FMT_PS),
                   6230:     OPC_CMP_NGE_PS = FOP (61, FMT_PS),
                   6231:     OPC_CMP_LE_PS = FOP (62, FMT_PS),
                   6232:     OPC_CMP_NGT_PS = FOP (63, FMT_PS),
                   6233: };
                   6234: 
1.1.1.5   root     6235: static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
                   6236: {
1.1.1.6   root     6237:     const char *opn = "cp1 move";
1.1.1.8   root     6238:     TCGv t0 = tcg_temp_new();
1.1.1.5   root     6239: 
                   6240:     switch (opc) {
                   6241:     case OPC_MFC1:
1.1.1.7   root     6242:         {
                   6243:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6244: 
                   6245:             gen_load_fpr32(fp0, fs);
                   6246:             tcg_gen_ext_i32_tl(t0, fp0);
                   6247:             tcg_temp_free_i32(fp0);
                   6248:         }
                   6249:         gen_store_gpr(t0, rt);
1.1.1.5   root     6250:         opn = "mfc1";
                   6251:         break;
                   6252:     case OPC_MTC1:
1.1.1.7   root     6253:         gen_load_gpr(t0, rt);
                   6254:         {
                   6255:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6256: 
                   6257:             tcg_gen_trunc_tl_i32(fp0, t0);
                   6258:             gen_store_fpr32(fp0, fs);
                   6259:             tcg_temp_free_i32(fp0);
                   6260:         }
1.1.1.5   root     6261:         opn = "mtc1";
                   6262:         break;
                   6263:     case OPC_CFC1:
1.1.1.7   root     6264:         gen_helper_1i(cfc1, t0, fs);
                   6265:         gen_store_gpr(t0, rt);
1.1.1.5   root     6266:         opn = "cfc1";
                   6267:         break;
                   6268:     case OPC_CTC1:
1.1.1.7   root     6269:         gen_load_gpr(t0, rt);
                   6270:         gen_helper_1i(ctc1, t0, fs);
1.1.1.5   root     6271:         opn = "ctc1";
                   6272:         break;
1.1.1.8   root     6273: #if defined(TARGET_MIPS64)
1.1.1.5   root     6274:     case OPC_DMFC1:
1.1.1.8   root     6275:         gen_load_fpr64(ctx, t0, fs);
1.1.1.7   root     6276:         gen_store_gpr(t0, rt);
1.1.1.6   root     6277:         opn = "dmfc1";
                   6278:         break;
1.1.1.5   root     6279:     case OPC_DMTC1:
1.1.1.7   root     6280:         gen_load_gpr(t0, rt);
1.1.1.8   root     6281:         gen_store_fpr64(ctx, t0, fs);
1.1.1.6   root     6282:         opn = "dmtc1";
                   6283:         break;
1.1.1.8   root     6284: #endif
1.1.1.6   root     6285:     case OPC_MFHC1:
1.1.1.7   root     6286:         {
                   6287:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6288: 
                   6289:             gen_load_fpr32h(fp0, fs);
                   6290:             tcg_gen_ext_i32_tl(t0, fp0);
                   6291:             tcg_temp_free_i32(fp0);
                   6292:         }
                   6293:         gen_store_gpr(t0, rt);
1.1.1.6   root     6294:         opn = "mfhc1";
                   6295:         break;
                   6296:     case OPC_MTHC1:
1.1.1.7   root     6297:         gen_load_gpr(t0, rt);
                   6298:         {
                   6299:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6300: 
                   6301:             tcg_gen_trunc_tl_i32(fp0, t0);
                   6302:             gen_store_fpr32h(fp0, fs);
                   6303:             tcg_temp_free_i32(fp0);
                   6304:         }
1.1.1.6   root     6305:         opn = "mthc1";
                   6306:         break;
1.1.1.5   root     6307:     default:
1.1.1.6   root     6308:         MIPS_INVAL(opn);
                   6309:         generate_exception (ctx, EXCP_RI);
1.1.1.7   root     6310:         goto out;
1.1.1.4   root     6311:     }
1.1.1.13! root     6312:     (void)opn; /* avoid a compiler warning */
1.1.1.4   root     6313:     MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
1.1.1.7   root     6314: 
                   6315:  out:
                   6316:     tcg_temp_free(t0);
1.1.1.4   root     6317: }
                   6318: 
1.1.1.6   root     6319: static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
                   6320: {
1.1.1.8   root     6321:     int l1;
1.1.1.7   root     6322:     TCGCond cond;
1.1.1.8   root     6323:     TCGv_i32 t0;
                   6324: 
                   6325:     if (rd == 0) {
                   6326:         /* Treat as NOP. */
                   6327:         return;
                   6328:     }
1.1.1.7   root     6329: 
                   6330:     if (tf)
                   6331:         cond = TCG_COND_EQ;
                   6332:     else
                   6333:         cond = TCG_COND_NE;
                   6334: 
1.1.1.8   root     6335:     l1 = gen_new_label();
                   6336:     t0 = tcg_temp_new_i32();
                   6337:     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
                   6338:     tcg_gen_brcondi_i32(cond, t0, 0, l1);
                   6339:     tcg_temp_free_i32(t0);
                   6340:     if (rs == 0) {
                   6341:         tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   6342:     } else {
                   6343:         tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   6344:     }
1.1.1.7   root     6345:     gen_set_label(l1);
                   6346: }
                   6347: 
                   6348: static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
                   6349: {
                   6350:     int cond;
1.1.1.8   root     6351:     TCGv_i32 t0 = tcg_temp_new_i32();
1.1.1.7   root     6352:     int l1 = gen_new_label();
                   6353: 
                   6354:     if (tf)
                   6355:         cond = TCG_COND_EQ;
                   6356:     else
                   6357:         cond = TCG_COND_NE;
                   6358: 
1.1.1.8   root     6359:     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
                   6360:     tcg_gen_brcondi_i32(cond, t0, 0, l1);
                   6361:     gen_load_fpr32(t0, fs);
                   6362:     gen_store_fpr32(t0, fd);
1.1.1.7   root     6363:     gen_set_label(l1);
1.1.1.8   root     6364:     tcg_temp_free_i32(t0);
1.1.1.7   root     6365: }
                   6366: 
                   6367: static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
                   6368: {
                   6369:     int cond;
1.1.1.8   root     6370:     TCGv_i32 t0 = tcg_temp_new_i32();
                   6371:     TCGv_i64 fp0;
1.1.1.7   root     6372:     int l1 = gen_new_label();
                   6373: 
                   6374:     if (tf)
                   6375:         cond = TCG_COND_EQ;
                   6376:     else
                   6377:         cond = TCG_COND_NE;
                   6378: 
1.1.1.8   root     6379:     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
                   6380:     tcg_gen_brcondi_i32(cond, t0, 0, l1);
                   6381:     tcg_temp_free_i32(t0);
                   6382:     fp0 = tcg_temp_new_i64();
1.1.1.7   root     6383:     gen_load_fpr64(ctx, fp0, fs);
                   6384:     gen_store_fpr64(ctx, fp0, fd);
                   6385:     tcg_temp_free_i64(fp0);
1.1.1.8   root     6386:     gen_set_label(l1);
1.1.1.7   root     6387: }
                   6388: 
                   6389: static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
                   6390: {
                   6391:     int cond;
1.1.1.8   root     6392:     TCGv_i32 t0 = tcg_temp_new_i32();
1.1.1.7   root     6393:     int l1 = gen_new_label();
                   6394:     int l2 = gen_new_label();
1.1.1.4   root     6395: 
1.1.1.7   root     6396:     if (tf)
                   6397:         cond = TCG_COND_EQ;
1.1.1.6   root     6398:     else
1.1.1.7   root     6399:         cond = TCG_COND_NE;
                   6400: 
1.1.1.8   root     6401:     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
                   6402:     tcg_gen_brcondi_i32(cond, t0, 0, l1);
                   6403:     gen_load_fpr32(t0, fs);
                   6404:     gen_store_fpr32(t0, fd);
1.1.1.7   root     6405:     gen_set_label(l1);
                   6406: 
1.1.1.8   root     6407:     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
                   6408:     tcg_gen_brcondi_i32(cond, t0, 0, l2);
                   6409:     gen_load_fpr32h(t0, fs);
                   6410:     gen_store_fpr32h(t0, fd);
                   6411:     tcg_temp_free_i32(t0);
1.1.1.7   root     6412:     gen_set_label(l2);
1.1.1.6   root     6413: }
                   6414: 
1.1.1.4   root     6415: 
1.1.1.12  root     6416: static void gen_farith (DisasContext *ctx, enum fopcode op1,
1.1.1.6   root     6417:                         int ft, int fs, int fd, int cc)
1.1.1.4   root     6418: {
1.1.1.6   root     6419:     const char *opn = "farith";
1.1.1.4   root     6420:     const char *condnames[] = {
                   6421:             "c.f",
                   6422:             "c.un",
                   6423:             "c.eq",
                   6424:             "c.ueq",
                   6425:             "c.olt",
                   6426:             "c.ult",
                   6427:             "c.ole",
                   6428:             "c.ule",
                   6429:             "c.sf",
                   6430:             "c.ngle",
                   6431:             "c.seq",
                   6432:             "c.ngl",
                   6433:             "c.lt",
                   6434:             "c.nge",
                   6435:             "c.le",
                   6436:             "c.ngt",
                   6437:     };
1.1.1.6   root     6438:     const char *condnames_abs[] = {
                   6439:             "cabs.f",
                   6440:             "cabs.un",
                   6441:             "cabs.eq",
                   6442:             "cabs.ueq",
                   6443:             "cabs.olt",
                   6444:             "cabs.ult",
                   6445:             "cabs.ole",
                   6446:             "cabs.ule",
                   6447:             "cabs.sf",
                   6448:             "cabs.ngle",
                   6449:             "cabs.seq",
                   6450:             "cabs.ngl",
                   6451:             "cabs.lt",
                   6452:             "cabs.nge",
                   6453:             "cabs.le",
                   6454:             "cabs.ngt",
                   6455:     };
                   6456:     enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
1.1.1.5   root     6457:     uint32_t func = ctx->opcode & 0x3f;
                   6458: 
1.1.1.12  root     6459:     switch (op1) {
                   6460:     case OPC_ADD_S:
1.1.1.7   root     6461:         {
                   6462:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6463:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   6464: 
                   6465:             gen_load_fpr32(fp0, fs);
                   6466:             gen_load_fpr32(fp1, ft);
                   6467:             gen_helper_float_add_s(fp0, fp0, fp1);
                   6468:             tcg_temp_free_i32(fp1);
                   6469:             gen_store_fpr32(fp0, fd);
                   6470:             tcg_temp_free_i32(fp0);
                   6471:         }
1.1.1.6   root     6472:         opn = "add.s";
                   6473:         optype = BINOP;
                   6474:         break;
1.1.1.12  root     6475:     case OPC_SUB_S:
1.1.1.7   root     6476:         {
                   6477:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6478:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   6479: 
                   6480:             gen_load_fpr32(fp0, fs);
                   6481:             gen_load_fpr32(fp1, ft);
                   6482:             gen_helper_float_sub_s(fp0, fp0, fp1);
                   6483:             tcg_temp_free_i32(fp1);
                   6484:             gen_store_fpr32(fp0, fd);
                   6485:             tcg_temp_free_i32(fp0);
                   6486:         }
1.1.1.6   root     6487:         opn = "sub.s";
                   6488:         optype = BINOP;
                   6489:         break;
1.1.1.12  root     6490:     case OPC_MUL_S:
1.1.1.7   root     6491:         {
                   6492:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6493:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   6494: 
                   6495:             gen_load_fpr32(fp0, fs);
                   6496:             gen_load_fpr32(fp1, ft);
                   6497:             gen_helper_float_mul_s(fp0, fp0, fp1);
                   6498:             tcg_temp_free_i32(fp1);
                   6499:             gen_store_fpr32(fp0, fd);
                   6500:             tcg_temp_free_i32(fp0);
                   6501:         }
1.1.1.6   root     6502:         opn = "mul.s";
                   6503:         optype = BINOP;
                   6504:         break;
1.1.1.12  root     6505:     case OPC_DIV_S:
1.1.1.7   root     6506:         {
                   6507:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6508:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   6509: 
                   6510:             gen_load_fpr32(fp0, fs);
                   6511:             gen_load_fpr32(fp1, ft);
                   6512:             gen_helper_float_div_s(fp0, fp0, fp1);
                   6513:             tcg_temp_free_i32(fp1);
                   6514:             gen_store_fpr32(fp0, fd);
                   6515:             tcg_temp_free_i32(fp0);
                   6516:         }
1.1.1.6   root     6517:         opn = "div.s";
                   6518:         optype = BINOP;
                   6519:         break;
1.1.1.12  root     6520:     case OPC_SQRT_S:
1.1.1.7   root     6521:         {
                   6522:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6523: 
                   6524:             gen_load_fpr32(fp0, fs);
                   6525:             gen_helper_float_sqrt_s(fp0, fp0);
                   6526:             gen_store_fpr32(fp0, fd);
                   6527:             tcg_temp_free_i32(fp0);
                   6528:         }
1.1.1.6   root     6529:         opn = "sqrt.s";
                   6530:         break;
1.1.1.12  root     6531:     case OPC_ABS_S:
1.1.1.7   root     6532:         {
                   6533:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6534: 
                   6535:             gen_load_fpr32(fp0, fs);
                   6536:             gen_helper_float_abs_s(fp0, fp0);
                   6537:             gen_store_fpr32(fp0, fd);
                   6538:             tcg_temp_free_i32(fp0);
                   6539:         }
1.1.1.6   root     6540:         opn = "abs.s";
                   6541:         break;
1.1.1.12  root     6542:     case OPC_MOV_S:
1.1.1.7   root     6543:         {
                   6544:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6545: 
                   6546:             gen_load_fpr32(fp0, fs);
                   6547:             gen_store_fpr32(fp0, fd);
                   6548:             tcg_temp_free_i32(fp0);
                   6549:         }
1.1.1.6   root     6550:         opn = "mov.s";
                   6551:         break;
1.1.1.12  root     6552:     case OPC_NEG_S:
1.1.1.7   root     6553:         {
                   6554:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6555: 
                   6556:             gen_load_fpr32(fp0, fs);
                   6557:             gen_helper_float_chs_s(fp0, fp0);
                   6558:             gen_store_fpr32(fp0, fd);
                   6559:             tcg_temp_free_i32(fp0);
                   6560:         }
1.1.1.6   root     6561:         opn = "neg.s";
                   6562:         break;
1.1.1.12  root     6563:     case OPC_ROUND_L_S:
1.1.1.6   root     6564:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6565:         {
                   6566:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   6567:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   6568: 
                   6569:             gen_load_fpr32(fp32, fs);
                   6570:             gen_helper_float_roundl_s(fp64, fp32);
                   6571:             tcg_temp_free_i32(fp32);
                   6572:             gen_store_fpr64(ctx, fp64, fd);
                   6573:             tcg_temp_free_i64(fp64);
                   6574:         }
1.1.1.6   root     6575:         opn = "round.l.s";
                   6576:         break;
1.1.1.12  root     6577:     case OPC_TRUNC_L_S:
1.1.1.6   root     6578:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6579:         {
                   6580:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   6581:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   6582: 
                   6583:             gen_load_fpr32(fp32, fs);
                   6584:             gen_helper_float_truncl_s(fp64, fp32);
                   6585:             tcg_temp_free_i32(fp32);
                   6586:             gen_store_fpr64(ctx, fp64, fd);
                   6587:             tcg_temp_free_i64(fp64);
                   6588:         }
1.1.1.6   root     6589:         opn = "trunc.l.s";
                   6590:         break;
1.1.1.12  root     6591:     case OPC_CEIL_L_S:
1.1.1.6   root     6592:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6593:         {
                   6594:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   6595:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   6596: 
                   6597:             gen_load_fpr32(fp32, fs);
                   6598:             gen_helper_float_ceill_s(fp64, fp32);
                   6599:             tcg_temp_free_i32(fp32);
                   6600:             gen_store_fpr64(ctx, fp64, fd);
                   6601:             tcg_temp_free_i64(fp64);
                   6602:         }
1.1.1.6   root     6603:         opn = "ceil.l.s";
                   6604:         break;
1.1.1.12  root     6605:     case OPC_FLOOR_L_S:
1.1.1.6   root     6606:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6607:         {
                   6608:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   6609:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   6610: 
                   6611:             gen_load_fpr32(fp32, fs);
                   6612:             gen_helper_float_floorl_s(fp64, fp32);
                   6613:             tcg_temp_free_i32(fp32);
                   6614:             gen_store_fpr64(ctx, fp64, fd);
                   6615:             tcg_temp_free_i64(fp64);
                   6616:         }
1.1.1.6   root     6617:         opn = "floor.l.s";
                   6618:         break;
1.1.1.12  root     6619:     case OPC_ROUND_W_S:
1.1.1.7   root     6620:         {
                   6621:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6622: 
                   6623:             gen_load_fpr32(fp0, fs);
                   6624:             gen_helper_float_roundw_s(fp0, fp0);
                   6625:             gen_store_fpr32(fp0, fd);
                   6626:             tcg_temp_free_i32(fp0);
                   6627:         }
1.1.1.6   root     6628:         opn = "round.w.s";
                   6629:         break;
1.1.1.12  root     6630:     case OPC_TRUNC_W_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_truncw_s(fp0, fp0);
                   6636:             gen_store_fpr32(fp0, fd);
                   6637:             tcg_temp_free_i32(fp0);
                   6638:         }
1.1.1.6   root     6639:         opn = "trunc.w.s";
                   6640:         break;
1.1.1.12  root     6641:     case OPC_CEIL_W_S:
1.1.1.7   root     6642:         {
                   6643:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6644: 
                   6645:             gen_load_fpr32(fp0, fs);
                   6646:             gen_helper_float_ceilw_s(fp0, fp0);
                   6647:             gen_store_fpr32(fp0, fd);
                   6648:             tcg_temp_free_i32(fp0);
                   6649:         }
1.1.1.6   root     6650:         opn = "ceil.w.s";
                   6651:         break;
1.1.1.12  root     6652:     case OPC_FLOOR_W_S:
1.1.1.7   root     6653:         {
                   6654:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6655: 
                   6656:             gen_load_fpr32(fp0, fs);
                   6657:             gen_helper_float_floorw_s(fp0, fp0);
                   6658:             gen_store_fpr32(fp0, fd);
                   6659:             tcg_temp_free_i32(fp0);
                   6660:         }
1.1.1.6   root     6661:         opn = "floor.w.s";
                   6662:         break;
1.1.1.12  root     6663:     case OPC_MOVCF_S:
1.1.1.7   root     6664:         gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
1.1.1.6   root     6665:         opn = "movcf.s";
                   6666:         break;
1.1.1.12  root     6667:     case OPC_MOVZ_S:
1.1.1.7   root     6668:         {
                   6669:             int l1 = gen_new_label();
1.1.1.8   root     6670:             TCGv_i32 fp0;
1.1.1.7   root     6671: 
1.1.1.8   root     6672:             if (ft != 0) {
                   6673:                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
                   6674:             }
                   6675:             fp0 = tcg_temp_new_i32();
1.1.1.7   root     6676:             gen_load_fpr32(fp0, fs);
                   6677:             gen_store_fpr32(fp0, fd);
                   6678:             tcg_temp_free_i32(fp0);
                   6679:             gen_set_label(l1);
                   6680:         }
1.1.1.6   root     6681:         opn = "movz.s";
                   6682:         break;
1.1.1.12  root     6683:     case OPC_MOVN_S:
1.1.1.7   root     6684:         {
                   6685:             int l1 = gen_new_label();
1.1.1.8   root     6686:             TCGv_i32 fp0;
1.1.1.7   root     6687: 
1.1.1.8   root     6688:             if (ft != 0) {
                   6689:                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
                   6690:                 fp0 = tcg_temp_new_i32();
                   6691:                 gen_load_fpr32(fp0, fs);
                   6692:                 gen_store_fpr32(fp0, fd);
                   6693:                 tcg_temp_free_i32(fp0);
                   6694:                 gen_set_label(l1);
                   6695:             }
1.1.1.7   root     6696:         }
1.1.1.6   root     6697:         opn = "movn.s";
                   6698:         break;
1.1.1.12  root     6699:     case OPC_RECIP_S:
1.1.1.6   root     6700:         check_cop1x(ctx);
1.1.1.7   root     6701:         {
                   6702:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6703: 
                   6704:             gen_load_fpr32(fp0, fs);
                   6705:             gen_helper_float_recip_s(fp0, fp0);
                   6706:             gen_store_fpr32(fp0, fd);
                   6707:             tcg_temp_free_i32(fp0);
                   6708:         }
1.1.1.6   root     6709:         opn = "recip.s";
                   6710:         break;
1.1.1.12  root     6711:     case OPC_RSQRT_S:
1.1.1.6   root     6712:         check_cop1x(ctx);
1.1.1.7   root     6713:         {
                   6714:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6715: 
                   6716:             gen_load_fpr32(fp0, fs);
                   6717:             gen_helper_float_rsqrt_s(fp0, fp0);
                   6718:             gen_store_fpr32(fp0, fd);
                   6719:             tcg_temp_free_i32(fp0);
                   6720:         }
1.1.1.6   root     6721:         opn = "rsqrt.s";
                   6722:         break;
1.1.1.12  root     6723:     case OPC_RECIP2_S:
1.1.1.6   root     6724:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6725:         {
                   6726:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6727:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   6728: 
                   6729:             gen_load_fpr32(fp0, fs);
                   6730:             gen_load_fpr32(fp1, fd);
                   6731:             gen_helper_float_recip2_s(fp0, fp0, fp1);
                   6732:             tcg_temp_free_i32(fp1);
                   6733:             gen_store_fpr32(fp0, fd);
                   6734:             tcg_temp_free_i32(fp0);
                   6735:         }
1.1.1.6   root     6736:         opn = "recip2.s";
                   6737:         break;
1.1.1.12  root     6738:     case OPC_RECIP1_S:
1.1.1.6   root     6739:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6740:         {
                   6741:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6742: 
                   6743:             gen_load_fpr32(fp0, fs);
                   6744:             gen_helper_float_recip1_s(fp0, fp0);
                   6745:             gen_store_fpr32(fp0, fd);
                   6746:             tcg_temp_free_i32(fp0);
                   6747:         }
1.1.1.6   root     6748:         opn = "recip1.s";
                   6749:         break;
1.1.1.12  root     6750:     case OPC_RSQRT1_S:
1.1.1.6   root     6751:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6752:         {
                   6753:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6754: 
                   6755:             gen_load_fpr32(fp0, fs);
                   6756:             gen_helper_float_rsqrt1_s(fp0, fp0);
                   6757:             gen_store_fpr32(fp0, fd);
                   6758:             tcg_temp_free_i32(fp0);
                   6759:         }
1.1.1.6   root     6760:         opn = "rsqrt1.s";
                   6761:         break;
1.1.1.12  root     6762:     case OPC_RSQRT2_S:
1.1.1.6   root     6763:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6764:         {
                   6765:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6766:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   6767: 
                   6768:             gen_load_fpr32(fp0, fs);
                   6769:             gen_load_fpr32(fp1, ft);
                   6770:             gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
                   6771:             tcg_temp_free_i32(fp1);
                   6772:             gen_store_fpr32(fp0, fd);
                   6773:             tcg_temp_free_i32(fp0);
                   6774:         }
1.1.1.6   root     6775:         opn = "rsqrt2.s";
                   6776:         break;
1.1.1.12  root     6777:     case OPC_CVT_D_S:
1.1.1.6   root     6778:         check_cp1_registers(ctx, fd);
1.1.1.7   root     6779:         {
                   6780:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   6781:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   6782: 
                   6783:             gen_load_fpr32(fp32, fs);
                   6784:             gen_helper_float_cvtd_s(fp64, fp32);
                   6785:             tcg_temp_free_i32(fp32);
                   6786:             gen_store_fpr64(ctx, fp64, fd);
                   6787:             tcg_temp_free_i64(fp64);
                   6788:         }
1.1.1.6   root     6789:         opn = "cvt.d.s";
                   6790:         break;
1.1.1.12  root     6791:     case OPC_CVT_W_S:
1.1.1.7   root     6792:         {
                   6793:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6794: 
                   6795:             gen_load_fpr32(fp0, fs);
                   6796:             gen_helper_float_cvtw_s(fp0, fp0);
                   6797:             gen_store_fpr32(fp0, fd);
                   6798:             tcg_temp_free_i32(fp0);
                   6799:         }
1.1.1.6   root     6800:         opn = "cvt.w.s";
                   6801:         break;
1.1.1.12  root     6802:     case OPC_CVT_L_S:
1.1.1.6   root     6803:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6804:         {
                   6805:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   6806:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   6807: 
                   6808:             gen_load_fpr32(fp32, fs);
                   6809:             gen_helper_float_cvtl_s(fp64, fp32);
                   6810:             tcg_temp_free_i32(fp32);
                   6811:             gen_store_fpr64(ctx, fp64, fd);
                   6812:             tcg_temp_free_i64(fp64);
                   6813:         }
1.1.1.6   root     6814:         opn = "cvt.l.s";
                   6815:         break;
1.1.1.12  root     6816:     case OPC_CVT_PS_S:
1.1.1.6   root     6817:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6818:         {
                   6819:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   6820:             TCGv_i32 fp32_0 = tcg_temp_new_i32();
                   6821:             TCGv_i32 fp32_1 = tcg_temp_new_i32();
                   6822: 
                   6823:             gen_load_fpr32(fp32_0, fs);
                   6824:             gen_load_fpr32(fp32_1, ft);
                   6825:             tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
                   6826:             tcg_temp_free_i32(fp32_1);
                   6827:             tcg_temp_free_i32(fp32_0);
                   6828:             gen_store_fpr64(ctx, fp64, fd);
                   6829:             tcg_temp_free_i64(fp64);
                   6830:         }
1.1.1.6   root     6831:         opn = "cvt.ps.s";
                   6832:         break;
1.1.1.12  root     6833:     case OPC_CMP_F_S:
                   6834:     case OPC_CMP_UN_S:
                   6835:     case OPC_CMP_EQ_S:
                   6836:     case OPC_CMP_UEQ_S:
                   6837:     case OPC_CMP_OLT_S:
                   6838:     case OPC_CMP_ULT_S:
                   6839:     case OPC_CMP_OLE_S:
                   6840:     case OPC_CMP_ULE_S:
                   6841:     case OPC_CMP_SF_S:
                   6842:     case OPC_CMP_NGLE_S:
                   6843:     case OPC_CMP_SEQ_S:
                   6844:     case OPC_CMP_NGL_S:
                   6845:     case OPC_CMP_LT_S:
                   6846:     case OPC_CMP_NGE_S:
                   6847:     case OPC_CMP_LE_S:
                   6848:     case OPC_CMP_NGT_S:
                   6849:         if (ctx->opcode & (1 << 6)) {
                   6850:             gen_cmpabs_s(ctx, func-48, ft, fs, cc);
                   6851:             opn = condnames_abs[func-48];
                   6852:         } else {
                   6853:             gen_cmp_s(ctx, func-48, ft, fs, cc);
                   6854:             opn = condnames[func-48];
1.1.1.6   root     6855:         }
                   6856:         break;
1.1.1.12  root     6857:     case OPC_ADD_D:
1.1.1.6   root     6858:         check_cp1_registers(ctx, fs | ft | fd);
1.1.1.7   root     6859:         {
                   6860:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6861:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   6862: 
                   6863:             gen_load_fpr64(ctx, fp0, fs);
                   6864:             gen_load_fpr64(ctx, fp1, ft);
                   6865:             gen_helper_float_add_d(fp0, fp0, fp1);
                   6866:             tcg_temp_free_i64(fp1);
                   6867:             gen_store_fpr64(ctx, fp0, fd);
                   6868:             tcg_temp_free_i64(fp0);
                   6869:         }
1.1.1.4   root     6870:         opn = "add.d";
1.1.1.6   root     6871:         optype = BINOP;
1.1.1.4   root     6872:         break;
1.1.1.12  root     6873:     case OPC_SUB_D:
1.1.1.6   root     6874:         check_cp1_registers(ctx, fs | ft | fd);
1.1.1.7   root     6875:         {
                   6876:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6877:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   6878: 
                   6879:             gen_load_fpr64(ctx, fp0, fs);
                   6880:             gen_load_fpr64(ctx, fp1, ft);
                   6881:             gen_helper_float_sub_d(fp0, fp0, fp1);
                   6882:             tcg_temp_free_i64(fp1);
                   6883:             gen_store_fpr64(ctx, fp0, fd);
                   6884:             tcg_temp_free_i64(fp0);
                   6885:         }
1.1.1.4   root     6886:         opn = "sub.d";
1.1.1.6   root     6887:         optype = BINOP;
1.1.1.4   root     6888:         break;
1.1.1.12  root     6889:     case OPC_MUL_D:
1.1.1.6   root     6890:         check_cp1_registers(ctx, fs | ft | fd);
1.1.1.7   root     6891:         {
                   6892:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6893:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   6894: 
                   6895:             gen_load_fpr64(ctx, fp0, fs);
                   6896:             gen_load_fpr64(ctx, fp1, ft);
                   6897:             gen_helper_float_mul_d(fp0, fp0, fp1);
                   6898:             tcg_temp_free_i64(fp1);
                   6899:             gen_store_fpr64(ctx, fp0, fd);
                   6900:             tcg_temp_free_i64(fp0);
                   6901:         }
1.1.1.4   root     6902:         opn = "mul.d";
1.1.1.6   root     6903:         optype = BINOP;
1.1.1.4   root     6904:         break;
1.1.1.12  root     6905:     case OPC_DIV_D:
1.1.1.6   root     6906:         check_cp1_registers(ctx, fs | ft | fd);
1.1.1.7   root     6907:         {
                   6908:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6909:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   6910: 
                   6911:             gen_load_fpr64(ctx, fp0, fs);
                   6912:             gen_load_fpr64(ctx, fp1, ft);
                   6913:             gen_helper_float_div_d(fp0, fp0, fp1);
                   6914:             tcg_temp_free_i64(fp1);
                   6915:             gen_store_fpr64(ctx, fp0, fd);
                   6916:             tcg_temp_free_i64(fp0);
                   6917:         }
1.1.1.4   root     6918:         opn = "div.d";
1.1.1.6   root     6919:         optype = BINOP;
1.1.1.4   root     6920:         break;
1.1.1.12  root     6921:     case OPC_SQRT_D:
1.1.1.6   root     6922:         check_cp1_registers(ctx, fs | fd);
1.1.1.7   root     6923:         {
                   6924:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6925: 
                   6926:             gen_load_fpr64(ctx, fp0, fs);
                   6927:             gen_helper_float_sqrt_d(fp0, fp0);
                   6928:             gen_store_fpr64(ctx, fp0, fd);
                   6929:             tcg_temp_free_i64(fp0);
                   6930:         }
1.1.1.4   root     6931:         opn = "sqrt.d";
                   6932:         break;
1.1.1.12  root     6933:     case OPC_ABS_D:
1.1.1.6   root     6934:         check_cp1_registers(ctx, fs | fd);
1.1.1.7   root     6935:         {
                   6936:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6937: 
                   6938:             gen_load_fpr64(ctx, fp0, fs);
                   6939:             gen_helper_float_abs_d(fp0, fp0);
                   6940:             gen_store_fpr64(ctx, fp0, fd);
                   6941:             tcg_temp_free_i64(fp0);
                   6942:         }
1.1.1.4   root     6943:         opn = "abs.d";
                   6944:         break;
1.1.1.12  root     6945:     case OPC_MOV_D:
1.1.1.6   root     6946:         check_cp1_registers(ctx, fs | fd);
1.1.1.7   root     6947:         {
                   6948:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6949: 
                   6950:             gen_load_fpr64(ctx, fp0, fs);
                   6951:             gen_store_fpr64(ctx, fp0, fd);
                   6952:             tcg_temp_free_i64(fp0);
                   6953:         }
1.1.1.4   root     6954:         opn = "mov.d";
                   6955:         break;
1.1.1.12  root     6956:     case OPC_NEG_D:
1.1.1.6   root     6957:         check_cp1_registers(ctx, fs | fd);
1.1.1.7   root     6958:         {
                   6959:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6960: 
                   6961:             gen_load_fpr64(ctx, fp0, fs);
                   6962:             gen_helper_float_chs_d(fp0, fp0);
                   6963:             gen_store_fpr64(ctx, fp0, fd);
                   6964:             tcg_temp_free_i64(fp0);
                   6965:         }
1.1.1.4   root     6966:         opn = "neg.d";
                   6967:         break;
1.1.1.12  root     6968:     case OPC_ROUND_L_D:
1.1.1.6   root     6969:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6970:         {
                   6971:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6972: 
                   6973:             gen_load_fpr64(ctx, fp0, fs);
                   6974:             gen_helper_float_roundl_d(fp0, fp0);
                   6975:             gen_store_fpr64(ctx, fp0, fd);
                   6976:             tcg_temp_free_i64(fp0);
                   6977:         }
1.1.1.6   root     6978:         opn = "round.l.d";
                   6979:         break;
1.1.1.12  root     6980:     case OPC_TRUNC_L_D:
1.1.1.6   root     6981:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6982:         {
                   6983:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6984: 
                   6985:             gen_load_fpr64(ctx, fp0, fs);
                   6986:             gen_helper_float_truncl_d(fp0, fp0);
                   6987:             gen_store_fpr64(ctx, fp0, fd);
                   6988:             tcg_temp_free_i64(fp0);
                   6989:         }
1.1.1.6   root     6990:         opn = "trunc.l.d";
                   6991:         break;
1.1.1.12  root     6992:     case OPC_CEIL_L_D:
1.1.1.6   root     6993:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6994:         {
                   6995:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6996: 
                   6997:             gen_load_fpr64(ctx, fp0, fs);
                   6998:             gen_helper_float_ceill_d(fp0, fp0);
                   6999:             gen_store_fpr64(ctx, fp0, fd);
                   7000:             tcg_temp_free_i64(fp0);
                   7001:         }
1.1.1.6   root     7002:         opn = "ceil.l.d";
                   7003:         break;
1.1.1.12  root     7004:     case OPC_FLOOR_L_D:
1.1.1.6   root     7005:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7006:         {
                   7007:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7008: 
                   7009:             gen_load_fpr64(ctx, fp0, fs);
                   7010:             gen_helper_float_floorl_d(fp0, fp0);
                   7011:             gen_store_fpr64(ctx, fp0, fd);
                   7012:             tcg_temp_free_i64(fp0);
                   7013:         }
1.1.1.6   root     7014:         opn = "floor.l.d";
                   7015:         break;
1.1.1.12  root     7016:     case OPC_ROUND_W_D:
1.1.1.6   root     7017:         check_cp1_registers(ctx, fs);
1.1.1.7   root     7018:         {
                   7019:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   7020:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   7021: 
                   7022:             gen_load_fpr64(ctx, fp64, fs);
                   7023:             gen_helper_float_roundw_d(fp32, fp64);
                   7024:             tcg_temp_free_i64(fp64);
                   7025:             gen_store_fpr32(fp32, fd);
                   7026:             tcg_temp_free_i32(fp32);
                   7027:         }
1.1.1.4   root     7028:         opn = "round.w.d";
                   7029:         break;
1.1.1.12  root     7030:     case OPC_TRUNC_W_D:
1.1.1.6   root     7031:         check_cp1_registers(ctx, fs);
1.1.1.7   root     7032:         {
                   7033:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   7034:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   7035: 
                   7036:             gen_load_fpr64(ctx, fp64, fs);
                   7037:             gen_helper_float_truncw_d(fp32, fp64);
                   7038:             tcg_temp_free_i64(fp64);
                   7039:             gen_store_fpr32(fp32, fd);
                   7040:             tcg_temp_free_i32(fp32);
                   7041:         }
1.1.1.4   root     7042:         opn = "trunc.w.d";
                   7043:         break;
1.1.1.12  root     7044:     case OPC_CEIL_W_D:
1.1.1.6   root     7045:         check_cp1_registers(ctx, fs);
1.1.1.7   root     7046:         {
                   7047:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   7048:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   7049: 
                   7050:             gen_load_fpr64(ctx, fp64, fs);
                   7051:             gen_helper_float_ceilw_d(fp32, fp64);
                   7052:             tcg_temp_free_i64(fp64);
                   7053:             gen_store_fpr32(fp32, fd);
                   7054:             tcg_temp_free_i32(fp32);
                   7055:         }
1.1.1.4   root     7056:         opn = "ceil.w.d";
                   7057:         break;
1.1.1.12  root     7058:     case OPC_FLOOR_W_D:
1.1.1.6   root     7059:         check_cp1_registers(ctx, fs);
1.1.1.7   root     7060:         {
                   7061:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   7062:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   7063: 
                   7064:             gen_load_fpr64(ctx, fp64, fs);
                   7065:             gen_helper_float_floorw_d(fp32, fp64);
                   7066:             tcg_temp_free_i64(fp64);
                   7067:             gen_store_fpr32(fp32, fd);
                   7068:             tcg_temp_free_i32(fp32);
                   7069:         }
1.1.1.5   root     7070:         opn = "floor.w.d";
                   7071:         break;
1.1.1.12  root     7072:     case OPC_MOVCF_D:
1.1.1.7   root     7073:         gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
1.1.1.6   root     7074:         opn = "movcf.d";
1.1.1.4   root     7075:         break;
1.1.1.12  root     7076:     case OPC_MOVZ_D:
1.1.1.7   root     7077:         {
                   7078:             int l1 = gen_new_label();
1.1.1.8   root     7079:             TCGv_i64 fp0;
1.1.1.7   root     7080: 
1.1.1.8   root     7081:             if (ft != 0) {
                   7082:                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
                   7083:             }
                   7084:             fp0 = tcg_temp_new_i64();
1.1.1.7   root     7085:             gen_load_fpr64(ctx, fp0, fs);
                   7086:             gen_store_fpr64(ctx, fp0, fd);
                   7087:             tcg_temp_free_i64(fp0);
                   7088:             gen_set_label(l1);
                   7089:         }
1.1.1.6   root     7090:         opn = "movz.d";
                   7091:         break;
1.1.1.12  root     7092:     case OPC_MOVN_D:
1.1.1.7   root     7093:         {
                   7094:             int l1 = gen_new_label();
1.1.1.8   root     7095:             TCGv_i64 fp0;
1.1.1.7   root     7096: 
1.1.1.8   root     7097:             if (ft != 0) {
                   7098:                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
                   7099:                 fp0 = tcg_temp_new_i64();
                   7100:                 gen_load_fpr64(ctx, fp0, fs);
                   7101:                 gen_store_fpr64(ctx, fp0, fd);
                   7102:                 tcg_temp_free_i64(fp0);
                   7103:                 gen_set_label(l1);
                   7104:             }
1.1.1.7   root     7105:         }
1.1.1.6   root     7106:         opn = "movn.d";
                   7107:         break;
1.1.1.12  root     7108:     case OPC_RECIP_D:
1.1.1.6   root     7109:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7110:         {
                   7111:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7112: 
                   7113:             gen_load_fpr64(ctx, fp0, fs);
                   7114:             gen_helper_float_recip_d(fp0, fp0);
                   7115:             gen_store_fpr64(ctx, fp0, fd);
                   7116:             tcg_temp_free_i64(fp0);
                   7117:         }
1.1.1.6   root     7118:         opn = "recip.d";
                   7119:         break;
1.1.1.12  root     7120:     case OPC_RSQRT_D:
1.1.1.6   root     7121:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7122:         {
                   7123:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7124: 
                   7125:             gen_load_fpr64(ctx, fp0, fs);
                   7126:             gen_helper_float_rsqrt_d(fp0, fp0);
                   7127:             gen_store_fpr64(ctx, fp0, fd);
                   7128:             tcg_temp_free_i64(fp0);
                   7129:         }
1.1.1.6   root     7130:         opn = "rsqrt.d";
                   7131:         break;
1.1.1.12  root     7132:     case OPC_RECIP2_D:
1.1.1.6   root     7133:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7134:         {
                   7135:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7136:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7137: 
                   7138:             gen_load_fpr64(ctx, fp0, fs);
                   7139:             gen_load_fpr64(ctx, fp1, ft);
                   7140:             gen_helper_float_recip2_d(fp0, fp0, fp1);
                   7141:             tcg_temp_free_i64(fp1);
                   7142:             gen_store_fpr64(ctx, fp0, fd);
                   7143:             tcg_temp_free_i64(fp0);
                   7144:         }
1.1.1.6   root     7145:         opn = "recip2.d";
                   7146:         break;
1.1.1.12  root     7147:     case OPC_RECIP1_D:
1.1.1.6   root     7148:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7149:         {
                   7150:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7151: 
                   7152:             gen_load_fpr64(ctx, fp0, fs);
                   7153:             gen_helper_float_recip1_d(fp0, fp0);
                   7154:             gen_store_fpr64(ctx, fp0, fd);
                   7155:             tcg_temp_free_i64(fp0);
                   7156:         }
1.1.1.6   root     7157:         opn = "recip1.d";
                   7158:         break;
1.1.1.12  root     7159:     case OPC_RSQRT1_D:
1.1.1.6   root     7160:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7161:         {
                   7162:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7163: 
                   7164:             gen_load_fpr64(ctx, fp0, fs);
                   7165:             gen_helper_float_rsqrt1_d(fp0, fp0);
                   7166:             gen_store_fpr64(ctx, fp0, fd);
                   7167:             tcg_temp_free_i64(fp0);
                   7168:         }
1.1.1.6   root     7169:         opn = "rsqrt1.d";
                   7170:         break;
1.1.1.12  root     7171:     case OPC_RSQRT2_D:
1.1.1.6   root     7172:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7173:         {
                   7174:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7175:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7176: 
                   7177:             gen_load_fpr64(ctx, fp0, fs);
                   7178:             gen_load_fpr64(ctx, fp1, ft);
                   7179:             gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
                   7180:             tcg_temp_free_i64(fp1);
                   7181:             gen_store_fpr64(ctx, fp0, fd);
                   7182:             tcg_temp_free_i64(fp0);
                   7183:         }
1.1.1.6   root     7184:         opn = "rsqrt2.d";
1.1.1.4   root     7185:         break;
1.1.1.12  root     7186:     case OPC_CMP_F_D:
                   7187:     case OPC_CMP_UN_D:
                   7188:     case OPC_CMP_EQ_D:
                   7189:     case OPC_CMP_UEQ_D:
                   7190:     case OPC_CMP_OLT_D:
                   7191:     case OPC_CMP_ULT_D:
                   7192:     case OPC_CMP_OLE_D:
                   7193:     case OPC_CMP_ULE_D:
                   7194:     case OPC_CMP_SF_D:
                   7195:     case OPC_CMP_NGLE_D:
                   7196:     case OPC_CMP_SEQ_D:
                   7197:     case OPC_CMP_NGL_D:
                   7198:     case OPC_CMP_LT_D:
                   7199:     case OPC_CMP_NGE_D:
                   7200:     case OPC_CMP_LE_D:
                   7201:     case OPC_CMP_NGT_D:
                   7202:         if (ctx->opcode & (1 << 6)) {
                   7203:             gen_cmpabs_d(ctx, func-48, ft, fs, cc);
                   7204:             opn = condnames_abs[func-48];
                   7205:         } else {
                   7206:             gen_cmp_d(ctx, func-48, ft, fs, cc);
                   7207:             opn = condnames[func-48];
1.1.1.6   root     7208:         }
                   7209:         break;
1.1.1.12  root     7210:     case OPC_CVT_S_D:
1.1.1.6   root     7211:         check_cp1_registers(ctx, fs);
1.1.1.7   root     7212:         {
                   7213:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   7214:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   7215: 
                   7216:             gen_load_fpr64(ctx, fp64, fs);
                   7217:             gen_helper_float_cvts_d(fp32, fp64);
                   7218:             tcg_temp_free_i64(fp64);
                   7219:             gen_store_fpr32(fp32, fd);
                   7220:             tcg_temp_free_i32(fp32);
                   7221:         }
1.1.1.6   root     7222:         opn = "cvt.s.d";
                   7223:         break;
1.1.1.12  root     7224:     case OPC_CVT_W_D:
1.1.1.6   root     7225:         check_cp1_registers(ctx, fs);
1.1.1.7   root     7226:         {
                   7227:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   7228:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   7229: 
                   7230:             gen_load_fpr64(ctx, fp64, fs);
                   7231:             gen_helper_float_cvtw_d(fp32, fp64);
                   7232:             tcg_temp_free_i64(fp64);
                   7233:             gen_store_fpr32(fp32, fd);
                   7234:             tcg_temp_free_i32(fp32);
                   7235:         }
1.1.1.6   root     7236:         opn = "cvt.w.d";
                   7237:         break;
1.1.1.12  root     7238:     case OPC_CVT_L_D:
1.1.1.6   root     7239:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7240:         {
                   7241:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7242: 
                   7243:             gen_load_fpr64(ctx, fp0, fs);
                   7244:             gen_helper_float_cvtl_d(fp0, fp0);
                   7245:             gen_store_fpr64(ctx, fp0, fd);
                   7246:             tcg_temp_free_i64(fp0);
                   7247:         }
1.1.1.6   root     7248:         opn = "cvt.l.d";
                   7249:         break;
1.1.1.12  root     7250:     case OPC_CVT_S_W:
1.1.1.7   root     7251:         {
                   7252:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7253: 
                   7254:             gen_load_fpr32(fp0, fs);
                   7255:             gen_helper_float_cvts_w(fp0, fp0);
                   7256:             gen_store_fpr32(fp0, fd);
                   7257:             tcg_temp_free_i32(fp0);
                   7258:         }
1.1.1.6   root     7259:         opn = "cvt.s.w";
                   7260:         break;
1.1.1.12  root     7261:     case OPC_CVT_D_W:
1.1.1.6   root     7262:         check_cp1_registers(ctx, fd);
1.1.1.7   root     7263:         {
                   7264:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   7265:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   7266: 
                   7267:             gen_load_fpr32(fp32, fs);
                   7268:             gen_helper_float_cvtd_w(fp64, fp32);
                   7269:             tcg_temp_free_i32(fp32);
                   7270:             gen_store_fpr64(ctx, fp64, fd);
                   7271:             tcg_temp_free_i64(fp64);
                   7272:         }
1.1.1.6   root     7273:         opn = "cvt.d.w";
                   7274:         break;
1.1.1.12  root     7275:     case OPC_CVT_S_L:
1.1.1.6   root     7276:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7277:         {
                   7278:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   7279:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   7280: 
                   7281:             gen_load_fpr64(ctx, fp64, fs);
                   7282:             gen_helper_float_cvts_l(fp32, fp64);
                   7283:             tcg_temp_free_i64(fp64);
                   7284:             gen_store_fpr32(fp32, fd);
                   7285:             tcg_temp_free_i32(fp32);
                   7286:         }
1.1.1.6   root     7287:         opn = "cvt.s.l";
                   7288:         break;
1.1.1.12  root     7289:     case OPC_CVT_D_L:
1.1.1.6   root     7290:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7291:         {
                   7292:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7293: 
                   7294:             gen_load_fpr64(ctx, fp0, fs);
                   7295:             gen_helper_float_cvtd_l(fp0, fp0);
                   7296:             gen_store_fpr64(ctx, fp0, fd);
                   7297:             tcg_temp_free_i64(fp0);
                   7298:         }
1.1.1.6   root     7299:         opn = "cvt.d.l";
                   7300:         break;
1.1.1.12  root     7301:     case OPC_CVT_PS_PW:
1.1.1.6   root     7302:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7303:         {
                   7304:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7305: 
                   7306:             gen_load_fpr64(ctx, fp0, fs);
                   7307:             gen_helper_float_cvtps_pw(fp0, fp0);
                   7308:             gen_store_fpr64(ctx, fp0, fd);
                   7309:             tcg_temp_free_i64(fp0);
                   7310:         }
1.1.1.6   root     7311:         opn = "cvt.ps.pw";
                   7312:         break;
1.1.1.12  root     7313:     case OPC_ADD_PS:
1.1.1.6   root     7314:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7315:         {
                   7316:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7317:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7318: 
                   7319:             gen_load_fpr64(ctx, fp0, fs);
                   7320:             gen_load_fpr64(ctx, fp1, ft);
                   7321:             gen_helper_float_add_ps(fp0, fp0, fp1);
                   7322:             tcg_temp_free_i64(fp1);
                   7323:             gen_store_fpr64(ctx, fp0, fd);
                   7324:             tcg_temp_free_i64(fp0);
                   7325:         }
1.1.1.6   root     7326:         opn = "add.ps";
                   7327:         break;
1.1.1.12  root     7328:     case OPC_SUB_PS:
1.1.1.6   root     7329:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7330:         {
                   7331:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7332:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7333: 
                   7334:             gen_load_fpr64(ctx, fp0, fs);
                   7335:             gen_load_fpr64(ctx, fp1, ft);
                   7336:             gen_helper_float_sub_ps(fp0, fp0, fp1);
                   7337:             tcg_temp_free_i64(fp1);
                   7338:             gen_store_fpr64(ctx, fp0, fd);
                   7339:             tcg_temp_free_i64(fp0);
                   7340:         }
1.1.1.6   root     7341:         opn = "sub.ps";
                   7342:         break;
1.1.1.12  root     7343:     case OPC_MUL_PS:
1.1.1.6   root     7344:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7345:         {
                   7346:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7347:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7348: 
                   7349:             gen_load_fpr64(ctx, fp0, fs);
                   7350:             gen_load_fpr64(ctx, fp1, ft);
                   7351:             gen_helper_float_mul_ps(fp0, fp0, fp1);
                   7352:             tcg_temp_free_i64(fp1);
                   7353:             gen_store_fpr64(ctx, fp0, fd);
                   7354:             tcg_temp_free_i64(fp0);
                   7355:         }
1.1.1.6   root     7356:         opn = "mul.ps";
                   7357:         break;
1.1.1.12  root     7358:     case OPC_ABS_PS:
1.1.1.6   root     7359:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7360:         {
                   7361:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7362: 
                   7363:             gen_load_fpr64(ctx, fp0, fs);
                   7364:             gen_helper_float_abs_ps(fp0, fp0);
                   7365:             gen_store_fpr64(ctx, fp0, fd);
                   7366:             tcg_temp_free_i64(fp0);
                   7367:         }
1.1.1.6   root     7368:         opn = "abs.ps";
                   7369:         break;
1.1.1.12  root     7370:     case OPC_MOV_PS:
1.1.1.6   root     7371:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7372:         {
                   7373:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7374: 
                   7375:             gen_load_fpr64(ctx, fp0, fs);
                   7376:             gen_store_fpr64(ctx, fp0, fd);
                   7377:             tcg_temp_free_i64(fp0);
                   7378:         }
1.1.1.6   root     7379:         opn = "mov.ps";
                   7380:         break;
1.1.1.12  root     7381:     case OPC_NEG_PS:
1.1.1.6   root     7382:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7383:         {
                   7384:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7385: 
                   7386:             gen_load_fpr64(ctx, fp0, fs);
                   7387:             gen_helper_float_chs_ps(fp0, fp0);
                   7388:             gen_store_fpr64(ctx, fp0, fd);
                   7389:             tcg_temp_free_i64(fp0);
                   7390:         }
1.1.1.6   root     7391:         opn = "neg.ps";
                   7392:         break;
1.1.1.12  root     7393:     case OPC_MOVCF_PS:
1.1.1.6   root     7394:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7395:         gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
1.1.1.6   root     7396:         opn = "movcf.ps";
                   7397:         break;
1.1.1.12  root     7398:     case OPC_MOVZ_PS:
1.1.1.6   root     7399:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7400:         {
                   7401:             int l1 = gen_new_label();
1.1.1.8   root     7402:             TCGv_i64 fp0;
1.1.1.7   root     7403: 
1.1.1.8   root     7404:             if (ft != 0)
                   7405:                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
                   7406:             fp0 = tcg_temp_new_i64();
                   7407:             gen_load_fpr64(ctx, fp0, fs);
                   7408:             gen_store_fpr64(ctx, fp0, fd);
                   7409:             tcg_temp_free_i64(fp0);
1.1.1.7   root     7410:             gen_set_label(l1);
                   7411:         }
1.1.1.6   root     7412:         opn = "movz.ps";
                   7413:         break;
1.1.1.12  root     7414:     case OPC_MOVN_PS:
1.1.1.6   root     7415:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7416:         {
                   7417:             int l1 = gen_new_label();
1.1.1.8   root     7418:             TCGv_i64 fp0;
1.1.1.7   root     7419: 
1.1.1.8   root     7420:             if (ft != 0) {
                   7421:                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
                   7422:                 fp0 = tcg_temp_new_i64();
                   7423:                 gen_load_fpr64(ctx, fp0, fs);
                   7424:                 gen_store_fpr64(ctx, fp0, fd);
                   7425:                 tcg_temp_free_i64(fp0);
                   7426:                 gen_set_label(l1);
                   7427:             }
1.1.1.7   root     7428:         }
1.1.1.6   root     7429:         opn = "movn.ps";
                   7430:         break;
1.1.1.12  root     7431:     case OPC_ADDR_PS:
1.1.1.6   root     7432:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7433:         {
                   7434:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7435:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7436: 
                   7437:             gen_load_fpr64(ctx, fp0, ft);
                   7438:             gen_load_fpr64(ctx, fp1, fs);
                   7439:             gen_helper_float_addr_ps(fp0, fp0, fp1);
                   7440:             tcg_temp_free_i64(fp1);
                   7441:             gen_store_fpr64(ctx, fp0, fd);
                   7442:             tcg_temp_free_i64(fp0);
                   7443:         }
1.1.1.6   root     7444:         opn = "addr.ps";
                   7445:         break;
1.1.1.12  root     7446:     case OPC_MULR_PS:
1.1.1.6   root     7447:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7448:         {
                   7449:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7450:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7451: 
                   7452:             gen_load_fpr64(ctx, fp0, ft);
                   7453:             gen_load_fpr64(ctx, fp1, fs);
                   7454:             gen_helper_float_mulr_ps(fp0, fp0, fp1);
                   7455:             tcg_temp_free_i64(fp1);
                   7456:             gen_store_fpr64(ctx, fp0, fd);
                   7457:             tcg_temp_free_i64(fp0);
                   7458:         }
1.1.1.6   root     7459:         opn = "mulr.ps";
                   7460:         break;
1.1.1.12  root     7461:     case OPC_RECIP2_PS:
1.1.1.6   root     7462:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7463:         {
                   7464:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7465:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7466: 
                   7467:             gen_load_fpr64(ctx, fp0, fs);
                   7468:             gen_load_fpr64(ctx, fp1, fd);
                   7469:             gen_helper_float_recip2_ps(fp0, fp0, fp1);
                   7470:             tcg_temp_free_i64(fp1);
                   7471:             gen_store_fpr64(ctx, fp0, fd);
                   7472:             tcg_temp_free_i64(fp0);
                   7473:         }
1.1.1.6   root     7474:         opn = "recip2.ps";
                   7475:         break;
1.1.1.12  root     7476:     case OPC_RECIP1_PS:
1.1.1.6   root     7477:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7478:         {
                   7479:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7480: 
                   7481:             gen_load_fpr64(ctx, fp0, fs);
                   7482:             gen_helper_float_recip1_ps(fp0, fp0);
                   7483:             gen_store_fpr64(ctx, fp0, fd);
                   7484:             tcg_temp_free_i64(fp0);
                   7485:         }
1.1.1.6   root     7486:         opn = "recip1.ps";
                   7487:         break;
1.1.1.12  root     7488:     case OPC_RSQRT1_PS:
1.1.1.6   root     7489:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7490:         {
                   7491:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7492: 
                   7493:             gen_load_fpr64(ctx, fp0, fs);
                   7494:             gen_helper_float_rsqrt1_ps(fp0, fp0);
                   7495:             gen_store_fpr64(ctx, fp0, fd);
                   7496:             tcg_temp_free_i64(fp0);
                   7497:         }
1.1.1.6   root     7498:         opn = "rsqrt1.ps";
                   7499:         break;
1.1.1.12  root     7500:     case OPC_RSQRT2_PS:
1.1.1.6   root     7501:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7502:         {
                   7503:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7504:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7505: 
                   7506:             gen_load_fpr64(ctx, fp0, fs);
                   7507:             gen_load_fpr64(ctx, fp1, ft);
                   7508:             gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
                   7509:             tcg_temp_free_i64(fp1);
                   7510:             gen_store_fpr64(ctx, fp0, fd);
                   7511:             tcg_temp_free_i64(fp0);
                   7512:         }
1.1.1.6   root     7513:         opn = "rsqrt2.ps";
                   7514:         break;
1.1.1.12  root     7515:     case OPC_CVT_S_PU:
1.1.1.6   root     7516:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7517:         {
                   7518:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7519: 
                   7520:             gen_load_fpr32h(fp0, fs);
                   7521:             gen_helper_float_cvts_pu(fp0, fp0);
                   7522:             gen_store_fpr32(fp0, fd);
                   7523:             tcg_temp_free_i32(fp0);
                   7524:         }
1.1.1.6   root     7525:         opn = "cvt.s.pu";
                   7526:         break;
1.1.1.12  root     7527:     case OPC_CVT_PW_PS:
1.1.1.6   root     7528:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7529:         {
                   7530:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7531: 
                   7532:             gen_load_fpr64(ctx, fp0, fs);
                   7533:             gen_helper_float_cvtpw_ps(fp0, fp0);
                   7534:             gen_store_fpr64(ctx, fp0, fd);
                   7535:             tcg_temp_free_i64(fp0);
                   7536:         }
1.1.1.6   root     7537:         opn = "cvt.pw.ps";
1.1.1.4   root     7538:         break;
1.1.1.12  root     7539:     case OPC_CVT_S_PL:
1.1.1.6   root     7540:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7541:         {
                   7542:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7543: 
                   7544:             gen_load_fpr32(fp0, fs);
                   7545:             gen_helper_float_cvts_pl(fp0, fp0);
                   7546:             gen_store_fpr32(fp0, fd);
                   7547:             tcg_temp_free_i32(fp0);
                   7548:         }
1.1.1.6   root     7549:         opn = "cvt.s.pl";
1.1.1.4   root     7550:         break;
1.1.1.12  root     7551:     case OPC_PLL_PS:
1.1.1.6   root     7552:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7553:         {
                   7554:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7555:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   7556: 
                   7557:             gen_load_fpr32(fp0, fs);
                   7558:             gen_load_fpr32(fp1, ft);
                   7559:             gen_store_fpr32h(fp0, fd);
                   7560:             gen_store_fpr32(fp1, fd);
                   7561:             tcg_temp_free_i32(fp0);
                   7562:             tcg_temp_free_i32(fp1);
                   7563:         }
1.1.1.6   root     7564:         opn = "pll.ps";
1.1.1.4   root     7565:         break;
1.1.1.12  root     7566:     case OPC_PLU_PS:
1.1.1.6   root     7567:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7568:         {
                   7569:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7570:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   7571: 
                   7572:             gen_load_fpr32(fp0, fs);
                   7573:             gen_load_fpr32h(fp1, ft);
                   7574:             gen_store_fpr32(fp1, fd);
                   7575:             gen_store_fpr32h(fp0, fd);
                   7576:             tcg_temp_free_i32(fp0);
                   7577:             tcg_temp_free_i32(fp1);
                   7578:         }
1.1.1.6   root     7579:         opn = "plu.ps";
                   7580:         break;
1.1.1.12  root     7581:     case OPC_PUL_PS:
1.1.1.6   root     7582:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7583:         {
                   7584:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7585:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   7586: 
                   7587:             gen_load_fpr32h(fp0, fs);
                   7588:             gen_load_fpr32(fp1, ft);
                   7589:             gen_store_fpr32(fp1, fd);
                   7590:             gen_store_fpr32h(fp0, fd);
                   7591:             tcg_temp_free_i32(fp0);
                   7592:             tcg_temp_free_i32(fp1);
                   7593:         }
1.1.1.6   root     7594:         opn = "pul.ps";
1.1.1.4   root     7595:         break;
1.1.1.12  root     7596:     case OPC_PUU_PS:
1.1.1.6   root     7597:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7598:         {
                   7599:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7600:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   7601: 
                   7602:             gen_load_fpr32h(fp0, fs);
                   7603:             gen_load_fpr32h(fp1, ft);
                   7604:             gen_store_fpr32(fp1, fd);
                   7605:             gen_store_fpr32h(fp0, fd);
                   7606:             tcg_temp_free_i32(fp0);
                   7607:             tcg_temp_free_i32(fp1);
                   7608:         }
1.1.1.6   root     7609:         opn = "puu.ps";
                   7610:         break;
1.1.1.12  root     7611:     case OPC_CMP_F_PS:
                   7612:     case OPC_CMP_UN_PS:
                   7613:     case OPC_CMP_EQ_PS:
                   7614:     case OPC_CMP_UEQ_PS:
                   7615:     case OPC_CMP_OLT_PS:
                   7616:     case OPC_CMP_ULT_PS:
                   7617:     case OPC_CMP_OLE_PS:
                   7618:     case OPC_CMP_ULE_PS:
                   7619:     case OPC_CMP_SF_PS:
                   7620:     case OPC_CMP_NGLE_PS:
                   7621:     case OPC_CMP_SEQ_PS:
                   7622:     case OPC_CMP_NGL_PS:
                   7623:     case OPC_CMP_LT_PS:
                   7624:     case OPC_CMP_NGE_PS:
                   7625:     case OPC_CMP_LE_PS:
                   7626:     case OPC_CMP_NGT_PS:
                   7627:         if (ctx->opcode & (1 << 6)) {
                   7628:             gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
                   7629:             opn = condnames_abs[func-48];
                   7630:         } else {
                   7631:             gen_cmp_ps(ctx, func-48, ft, fs, cc);
                   7632:             opn = condnames[func-48];
1.1.1.6   root     7633:         }
1.1.1.4   root     7634:         break;
1.1.1.6   root     7635:     default:
                   7636:         MIPS_INVAL(opn);
                   7637:         generate_exception (ctx, EXCP_RI);
                   7638:         return;
                   7639:     }
1.1.1.13! root     7640:     (void)opn; /* avoid a compiler warning */
1.1.1.6   root     7641:     switch (optype) {
                   7642:     case BINOP:
                   7643:         MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
                   7644:         break;
                   7645:     case CMPOP:
                   7646:         MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
                   7647:         break;
                   7648:     default:
                   7649:         MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
                   7650:         break;
                   7651:     }
                   7652: }
                   7653: 
                   7654: /* Coprocessor 3 (FPU) */
                   7655: static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
                   7656:                            int fd, int fs, int base, int index)
                   7657: {
                   7658:     const char *opn = "extended float load/store";
                   7659:     int store = 0;
1.1.1.8   root     7660:     TCGv t0 = tcg_temp_new();
1.1.1.6   root     7661: 
                   7662:     if (base == 0) {
1.1.1.7   root     7663:         gen_load_gpr(t0, index);
1.1.1.6   root     7664:     } else if (index == 0) {
1.1.1.7   root     7665:         gen_load_gpr(t0, base);
1.1.1.6   root     7666:     } else {
1.1.1.7   root     7667:         gen_load_gpr(t0, index);
1.1.1.9   root     7668:         gen_op_addr_add(ctx, t0, cpu_gpr[base], t0);
1.1.1.6   root     7669:     }
                   7670:     /* Don't do NOP if destination is zero: we must perform the actual
                   7671:        memory access. */
1.1.1.8   root     7672:     save_cpu_state(ctx, 0);
1.1.1.6   root     7673:     switch (opc) {
                   7674:     case OPC_LWXC1:
                   7675:         check_cop1x(ctx);
1.1.1.7   root     7676:         {
                   7677:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7678: 
1.1.1.8   root     7679:             tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
                   7680:             tcg_gen_trunc_tl_i32(fp0, t0);
1.1.1.7   root     7681:             gen_store_fpr32(fp0, fd);
                   7682:             tcg_temp_free_i32(fp0);
                   7683:         }
1.1.1.6   root     7684:         opn = "lwxc1";
                   7685:         break;
                   7686:     case OPC_LDXC1:
                   7687:         check_cop1x(ctx);
                   7688:         check_cp1_registers(ctx, fd);
1.1.1.7   root     7689:         {
                   7690:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7691: 
                   7692:             tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
                   7693:             gen_store_fpr64(ctx, fp0, fd);
                   7694:             tcg_temp_free_i64(fp0);
                   7695:         }
1.1.1.6   root     7696:         opn = "ldxc1";
                   7697:         break;
                   7698:     case OPC_LUXC1:
                   7699:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7700:         tcg_gen_andi_tl(t0, t0, ~0x7);
                   7701:         {
                   7702:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7703: 
                   7704:             tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
                   7705:             gen_store_fpr64(ctx, fp0, fd);
                   7706:             tcg_temp_free_i64(fp0);
                   7707:         }
1.1.1.6   root     7708:         opn = "luxc1";
                   7709:         break;
                   7710:     case OPC_SWXC1:
                   7711:         check_cop1x(ctx);
1.1.1.7   root     7712:         {
                   7713:             TCGv_i32 fp0 = tcg_temp_new_i32();
1.1.1.8   root     7714:             TCGv t1 = tcg_temp_new();
1.1.1.7   root     7715: 
                   7716:             gen_load_fpr32(fp0, fs);
                   7717:             tcg_gen_extu_i32_tl(t1, fp0);
                   7718:             tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
                   7719:             tcg_temp_free_i32(fp0);
1.1.1.8   root     7720:             tcg_temp_free(t1);
1.1.1.7   root     7721:         }
1.1.1.6   root     7722:         opn = "swxc1";
                   7723:         store = 1;
1.1.1.4   root     7724:         break;
1.1.1.6   root     7725:     case OPC_SDXC1:
                   7726:         check_cop1x(ctx);
                   7727:         check_cp1_registers(ctx, fs);
1.1.1.7   root     7728:         {
                   7729:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7730: 
                   7731:             gen_load_fpr64(ctx, fp0, fs);
                   7732:             tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
                   7733:             tcg_temp_free_i64(fp0);
                   7734:         }
1.1.1.6   root     7735:         opn = "sdxc1";
                   7736:         store = 1;
                   7737:         break;
                   7738:     case OPC_SUXC1:
                   7739:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7740:         tcg_gen_andi_tl(t0, t0, ~0x7);
                   7741:         {
                   7742:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7743: 
                   7744:             gen_load_fpr64(ctx, fp0, fs);
                   7745:             tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
                   7746:             tcg_temp_free_i64(fp0);
                   7747:         }
1.1.1.6   root     7748:         opn = "suxc1";
                   7749:         store = 1;
                   7750:         break;
                   7751:     }
1.1.1.7   root     7752:     tcg_temp_free(t0);
1.1.1.13! root     7753:     (void)opn; (void)store; /* avoid compiler warnings */
1.1.1.6   root     7754:     MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
                   7755:                regnames[index], regnames[base]);
                   7756: }
                   7757: 
                   7758: static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
                   7759:                             int fd, int fr, int fs, int ft)
                   7760: {
                   7761:     const char *opn = "flt3_arith";
                   7762: 
                   7763:     switch (opc) {
                   7764:     case OPC_ALNV_PS:
                   7765:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7766:         {
                   7767:             TCGv t0 = tcg_temp_local_new();
1.1.1.8   root     7768:             TCGv_i32 fp = tcg_temp_new_i32();
                   7769:             TCGv_i32 fph = tcg_temp_new_i32();
1.1.1.7   root     7770:             int l1 = gen_new_label();
                   7771:             int l2 = gen_new_label();
                   7772: 
                   7773:             gen_load_gpr(t0, fr);
                   7774:             tcg_gen_andi_tl(t0, t0, 0x7);
                   7775: 
                   7776:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
1.1.1.8   root     7777:             gen_load_fpr32(fp, fs);
                   7778:             gen_load_fpr32h(fph, fs);
                   7779:             gen_store_fpr32(fp, fd);
                   7780:             gen_store_fpr32h(fph, fd);
1.1.1.7   root     7781:             tcg_gen_br(l2);
                   7782:             gen_set_label(l1);
                   7783:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
                   7784:             tcg_temp_free(t0);
                   7785: #ifdef TARGET_WORDS_BIGENDIAN
1.1.1.8   root     7786:             gen_load_fpr32(fp, fs);
                   7787:             gen_load_fpr32h(fph, ft);
                   7788:             gen_store_fpr32h(fp, fd);
                   7789:             gen_store_fpr32(fph, fd);
1.1.1.7   root     7790: #else
1.1.1.8   root     7791:             gen_load_fpr32h(fph, fs);
                   7792:             gen_load_fpr32(fp, ft);
                   7793:             gen_store_fpr32(fph, fd);
                   7794:             gen_store_fpr32h(fp, fd);
1.1.1.7   root     7795: #endif
                   7796:             gen_set_label(l2);
1.1.1.8   root     7797:             tcg_temp_free_i32(fp);
                   7798:             tcg_temp_free_i32(fph);
1.1.1.7   root     7799:         }
1.1.1.6   root     7800:         opn = "alnv.ps";
                   7801:         break;
                   7802:     case OPC_MADD_S:
                   7803:         check_cop1x(ctx);
1.1.1.7   root     7804:         {
                   7805:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7806:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   7807:             TCGv_i32 fp2 = tcg_temp_new_i32();
                   7808: 
                   7809:             gen_load_fpr32(fp0, fs);
                   7810:             gen_load_fpr32(fp1, ft);
                   7811:             gen_load_fpr32(fp2, fr);
                   7812:             gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
                   7813:             tcg_temp_free_i32(fp0);
                   7814:             tcg_temp_free_i32(fp1);
                   7815:             gen_store_fpr32(fp2, fd);
                   7816:             tcg_temp_free_i32(fp2);
                   7817:         }
1.1.1.6   root     7818:         opn = "madd.s";
1.1.1.4   root     7819:         break;
1.1.1.6   root     7820:     case OPC_MADD_D:
                   7821:         check_cop1x(ctx);
                   7822:         check_cp1_registers(ctx, fd | fs | ft | fr);
1.1.1.7   root     7823:         {
                   7824:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7825:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7826:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   7827: 
                   7828:             gen_load_fpr64(ctx, fp0, fs);
                   7829:             gen_load_fpr64(ctx, fp1, ft);
                   7830:             gen_load_fpr64(ctx, fp2, fr);
                   7831:             gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
                   7832:             tcg_temp_free_i64(fp0);
                   7833:             tcg_temp_free_i64(fp1);
                   7834:             gen_store_fpr64(ctx, fp2, fd);
                   7835:             tcg_temp_free_i64(fp2);
                   7836:         }
1.1.1.6   root     7837:         opn = "madd.d";
                   7838:         break;
                   7839:     case OPC_MADD_PS:
                   7840:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7841:         {
                   7842:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7843:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7844:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   7845: 
                   7846:             gen_load_fpr64(ctx, fp0, fs);
                   7847:             gen_load_fpr64(ctx, fp1, ft);
                   7848:             gen_load_fpr64(ctx, fp2, fr);
                   7849:             gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
                   7850:             tcg_temp_free_i64(fp0);
                   7851:             tcg_temp_free_i64(fp1);
                   7852:             gen_store_fpr64(ctx, fp2, fd);
                   7853:             tcg_temp_free_i64(fp2);
                   7854:         }
1.1.1.6   root     7855:         opn = "madd.ps";
1.1.1.4   root     7856:         break;
1.1.1.6   root     7857:     case OPC_MSUB_S:
                   7858:         check_cop1x(ctx);
1.1.1.7   root     7859:         {
                   7860:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7861:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   7862:             TCGv_i32 fp2 = tcg_temp_new_i32();
                   7863: 
                   7864:             gen_load_fpr32(fp0, fs);
                   7865:             gen_load_fpr32(fp1, ft);
                   7866:             gen_load_fpr32(fp2, fr);
                   7867:             gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
                   7868:             tcg_temp_free_i32(fp0);
                   7869:             tcg_temp_free_i32(fp1);
                   7870:             gen_store_fpr32(fp2, fd);
                   7871:             tcg_temp_free_i32(fp2);
                   7872:         }
1.1.1.6   root     7873:         opn = "msub.s";
1.1.1.4   root     7874:         break;
1.1.1.6   root     7875:     case OPC_MSUB_D:
                   7876:         check_cop1x(ctx);
                   7877:         check_cp1_registers(ctx, fd | fs | ft | fr);
1.1.1.7   root     7878:         {
                   7879:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7880:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7881:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   7882: 
                   7883:             gen_load_fpr64(ctx, fp0, fs);
                   7884:             gen_load_fpr64(ctx, fp1, ft);
                   7885:             gen_load_fpr64(ctx, fp2, fr);
                   7886:             gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
                   7887:             tcg_temp_free_i64(fp0);
                   7888:             tcg_temp_free_i64(fp1);
                   7889:             gen_store_fpr64(ctx, fp2, fd);
                   7890:             tcg_temp_free_i64(fp2);
                   7891:         }
1.1.1.6   root     7892:         opn = "msub.d";
                   7893:         break;
                   7894:     case OPC_MSUB_PS:
                   7895:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7896:         {
                   7897:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7898:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7899:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   7900: 
                   7901:             gen_load_fpr64(ctx, fp0, fs);
                   7902:             gen_load_fpr64(ctx, fp1, ft);
                   7903:             gen_load_fpr64(ctx, fp2, fr);
                   7904:             gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
                   7905:             tcg_temp_free_i64(fp0);
                   7906:             tcg_temp_free_i64(fp1);
                   7907:             gen_store_fpr64(ctx, fp2, fd);
                   7908:             tcg_temp_free_i64(fp2);
                   7909:         }
1.1.1.6   root     7910:         opn = "msub.ps";
1.1.1.4   root     7911:         break;
1.1.1.6   root     7912:     case OPC_NMADD_S:
                   7913:         check_cop1x(ctx);
1.1.1.7   root     7914:         {
                   7915:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7916:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   7917:             TCGv_i32 fp2 = tcg_temp_new_i32();
                   7918: 
                   7919:             gen_load_fpr32(fp0, fs);
                   7920:             gen_load_fpr32(fp1, ft);
                   7921:             gen_load_fpr32(fp2, fr);
                   7922:             gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
                   7923:             tcg_temp_free_i32(fp0);
                   7924:             tcg_temp_free_i32(fp1);
                   7925:             gen_store_fpr32(fp2, fd);
                   7926:             tcg_temp_free_i32(fp2);
                   7927:         }
1.1.1.6   root     7928:         opn = "nmadd.s";
1.1.1.4   root     7929:         break;
1.1.1.6   root     7930:     case OPC_NMADD_D:
                   7931:         check_cop1x(ctx);
                   7932:         check_cp1_registers(ctx, fd | fs | ft | fr);
1.1.1.7   root     7933:         {
                   7934:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7935:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7936:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   7937: 
                   7938:             gen_load_fpr64(ctx, fp0, fs);
                   7939:             gen_load_fpr64(ctx, fp1, ft);
                   7940:             gen_load_fpr64(ctx, fp2, fr);
                   7941:             gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
                   7942:             tcg_temp_free_i64(fp0);
                   7943:             tcg_temp_free_i64(fp1);
                   7944:             gen_store_fpr64(ctx, fp2, fd);
                   7945:             tcg_temp_free_i64(fp2);
                   7946:         }
1.1.1.6   root     7947:         opn = "nmadd.d";
1.1.1.5   root     7948:         break;
1.1.1.6   root     7949:     case OPC_NMADD_PS:
                   7950:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7951:         {
                   7952:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7953:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7954:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   7955: 
                   7956:             gen_load_fpr64(ctx, fp0, fs);
                   7957:             gen_load_fpr64(ctx, fp1, ft);
                   7958:             gen_load_fpr64(ctx, fp2, fr);
                   7959:             gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
                   7960:             tcg_temp_free_i64(fp0);
                   7961:             tcg_temp_free_i64(fp1);
                   7962:             gen_store_fpr64(ctx, fp2, fd);
                   7963:             tcg_temp_free_i64(fp2);
                   7964:         }
1.1.1.6   root     7965:         opn = "nmadd.ps";
1.1.1.4   root     7966:         break;
1.1.1.6   root     7967:     case OPC_NMSUB_S:
                   7968:         check_cop1x(ctx);
1.1.1.7   root     7969:         {
                   7970:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7971:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   7972:             TCGv_i32 fp2 = tcg_temp_new_i32();
                   7973: 
                   7974:             gen_load_fpr32(fp0, fs);
                   7975:             gen_load_fpr32(fp1, ft);
                   7976:             gen_load_fpr32(fp2, fr);
                   7977:             gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
                   7978:             tcg_temp_free_i32(fp0);
                   7979:             tcg_temp_free_i32(fp1);
                   7980:             gen_store_fpr32(fp2, fd);
                   7981:             tcg_temp_free_i32(fp2);
                   7982:         }
1.1.1.6   root     7983:         opn = "nmsub.s";
1.1.1.4   root     7984:         break;
1.1.1.6   root     7985:     case OPC_NMSUB_D:
                   7986:         check_cop1x(ctx);
                   7987:         check_cp1_registers(ctx, fd | fs | ft | fr);
1.1.1.7   root     7988:         {
                   7989:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7990:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7991:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   7992: 
                   7993:             gen_load_fpr64(ctx, fp0, fs);
                   7994:             gen_load_fpr64(ctx, fp1, ft);
                   7995:             gen_load_fpr64(ctx, fp2, fr);
                   7996:             gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
                   7997:             tcg_temp_free_i64(fp0);
                   7998:             tcg_temp_free_i64(fp1);
                   7999:             gen_store_fpr64(ctx, fp2, fd);
                   8000:             tcg_temp_free_i64(fp2);
                   8001:         }
1.1.1.6   root     8002:         opn = "nmsub.d";
1.1.1.4   root     8003:         break;
1.1.1.6   root     8004:     case OPC_NMSUB_PS:
                   8005:         check_cp1_64bitmode(ctx);
1.1.1.7   root     8006:         {
                   8007:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   8008:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   8009:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   8010: 
                   8011:             gen_load_fpr64(ctx, fp0, fs);
                   8012:             gen_load_fpr64(ctx, fp1, ft);
                   8013:             gen_load_fpr64(ctx, fp2, fr);
                   8014:             gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
                   8015:             tcg_temp_free_i64(fp0);
                   8016:             tcg_temp_free_i64(fp1);
                   8017:             gen_store_fpr64(ctx, fp2, fd);
                   8018:             tcg_temp_free_i64(fp2);
                   8019:         }
1.1.1.6   root     8020:         opn = "nmsub.ps";
1.1.1.4   root     8021:         break;
1.1.1.6   root     8022:     default:
                   8023:         MIPS_INVAL(opn);
                   8024:         generate_exception (ctx, EXCP_RI);
1.1.1.4   root     8025:         return;
                   8026:     }
1.1.1.13! root     8027:     (void)opn; /* avoid a compiler warning */
1.1.1.6   root     8028:     MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
                   8029:                fregnames[fs], fregnames[ft]);
1.1       root     8030: }
                   8031: 
1.1.1.12  root     8032: static void
                   8033: gen_rdhwr (CPUState *env, DisasContext *ctx, int rt, int rd)
                   8034: {
                   8035:     TCGv t0;
1.1       root     8036: 
1.1.1.12  root     8037:     check_insn(env, ctx, ISA_MIPS32R2);
                   8038:     t0 = tcg_temp_new();
1.1       root     8039: 
1.1.1.12  root     8040:     switch (rd) {
                   8041:     case 0:
                   8042:         save_cpu_state(ctx, 1);
                   8043:         gen_helper_rdhwr_cpunum(t0);
                   8044:         gen_store_gpr(t0, rt);
                   8045:         break;
                   8046:     case 1:
                   8047:         save_cpu_state(ctx, 1);
                   8048:         gen_helper_rdhwr_synci_step(t0);
                   8049:         gen_store_gpr(t0, rt);
                   8050:         break;
                   8051:     case 2:
                   8052:         save_cpu_state(ctx, 1);
                   8053:         gen_helper_rdhwr_cc(t0);
                   8054:         gen_store_gpr(t0, rt);
                   8055:         break;
                   8056:     case 3:
                   8057:         save_cpu_state(ctx, 1);
                   8058:         gen_helper_rdhwr_ccres(t0);
                   8059:         gen_store_gpr(t0, rt);
                   8060:         break;
                   8061:     case 29:
                   8062: #if defined(CONFIG_USER_ONLY)
                   8063:         tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
                   8064:         gen_store_gpr(t0, rt);
                   8065:         break;
                   8066: #else
                   8067:         /* XXX: Some CPUs implement this in hardware.
                   8068:            Not supported yet. */
1.1       root     8069: #endif
1.1.1.12  root     8070:     default:            /* Invalid */
                   8071:         MIPS_INVAL("rdhwr");
                   8072:         generate_exception(ctx, EXCP_RI);
                   8073:         break;
1.1.1.4   root     8074:     }
1.1.1.12  root     8075:     tcg_temp_free(t0);
                   8076: }
1.1.1.4   root     8077: 
1.1.1.12  root     8078: static void handle_delay_slot (CPUState *env, DisasContext *ctx,
                   8079:                                int insn_bytes)
                   8080: {
                   8081:     if (ctx->hflags & MIPS_HFLAG_BMASK) {
                   8082:         int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
                   8083:         /* Branches completion */
                   8084:         ctx->hflags &= ~MIPS_HFLAG_BMASK;
                   8085:         ctx->bstate = BS_BRANCH;
                   8086:         save_cpu_state(ctx, 0);
                   8087:         /* FIXME: Need to clear can_do_io.  */
                   8088:         switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
                   8089:         case MIPS_HFLAG_B:
                   8090:             /* unconditional branch */
                   8091:             MIPS_DEBUG("unconditional branch");
                   8092:             if (proc_hflags & MIPS_HFLAG_BX) {
                   8093:                 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
                   8094:             }
                   8095:             gen_goto_tb(ctx, 0, ctx->btarget);
                   8096:             break;
                   8097:         case MIPS_HFLAG_BL:
                   8098:             /* blikely taken case */
                   8099:             MIPS_DEBUG("blikely branch taken");
                   8100:             gen_goto_tb(ctx, 0, ctx->btarget);
                   8101:             break;
                   8102:         case MIPS_HFLAG_BC:
                   8103:             /* Conditional branch */
                   8104:             MIPS_DEBUG("conditional branch");
                   8105:             {
                   8106:                 int l1 = gen_new_label();
1.1.1.7   root     8107: 
1.1.1.12  root     8108:                 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
                   8109:                 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
                   8110:                 gen_set_label(l1);
                   8111:                 gen_goto_tb(ctx, 0, ctx->btarget);
                   8112:             }
                   8113:             break;
                   8114:         case MIPS_HFLAG_BR:
                   8115:             /* unconditional branch to register */
                   8116:             MIPS_DEBUG("branch to register");
                   8117:             if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
                   8118:                 TCGv t0 = tcg_temp_new();
                   8119:                 TCGv_i32 t1 = tcg_temp_new_i32();
                   8120: 
                   8121:                 tcg_gen_andi_tl(t0, btarget, 0x1);
                   8122:                 tcg_gen_trunc_tl_i32(t1, t0);
                   8123:                 tcg_temp_free(t0);
                   8124:                 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
                   8125:                 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
                   8126:                 tcg_gen_or_i32(hflags, hflags, t1);
                   8127:                 tcg_temp_free_i32(t1);
                   8128: 
                   8129:                 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
                   8130:             } else {
                   8131:                 tcg_gen_mov_tl(cpu_PC, btarget);
                   8132:             }
                   8133:             if (ctx->singlestep_enabled) {
                   8134:                 save_cpu_state(ctx, 0);
                   8135:                 gen_helper_0i(raise_exception, EXCP_DEBUG);
                   8136:             }
                   8137:             tcg_gen_exit_tb(0);
                   8138:             break;
                   8139:         default:
                   8140:             MIPS_DEBUG("unknown branch");
                   8141:             break;
                   8142:         }
                   8143:     }
                   8144: }
                   8145: 
                   8146: /* ISA extensions (ASEs) */
                   8147: /* MIPS16 extension to MIPS32 */
                   8148: 
                   8149: /* MIPS16 major opcodes */
                   8150: enum {
                   8151:   M16_OPC_ADDIUSP = 0x00,
                   8152:   M16_OPC_ADDIUPC = 0x01,
                   8153:   M16_OPC_B = 0x02,
                   8154:   M16_OPC_JAL = 0x03,
                   8155:   M16_OPC_BEQZ = 0x04,
                   8156:   M16_OPC_BNEQZ = 0x05,
                   8157:   M16_OPC_SHIFT = 0x06,
                   8158:   M16_OPC_LD = 0x07,
                   8159:   M16_OPC_RRIA = 0x08,
                   8160:   M16_OPC_ADDIU8 = 0x09,
                   8161:   M16_OPC_SLTI = 0x0a,
                   8162:   M16_OPC_SLTIU = 0x0b,
                   8163:   M16_OPC_I8 = 0x0c,
                   8164:   M16_OPC_LI = 0x0d,
                   8165:   M16_OPC_CMPI = 0x0e,
                   8166:   M16_OPC_SD = 0x0f,
                   8167:   M16_OPC_LB = 0x10,
                   8168:   M16_OPC_LH = 0x11,
                   8169:   M16_OPC_LWSP = 0x12,
                   8170:   M16_OPC_LW = 0x13,
                   8171:   M16_OPC_LBU = 0x14,
                   8172:   M16_OPC_LHU = 0x15,
                   8173:   M16_OPC_LWPC = 0x16,
                   8174:   M16_OPC_LWU = 0x17,
                   8175:   M16_OPC_SB = 0x18,
                   8176:   M16_OPC_SH = 0x19,
                   8177:   M16_OPC_SWSP = 0x1a,
                   8178:   M16_OPC_SW = 0x1b,
                   8179:   M16_OPC_RRR = 0x1c,
                   8180:   M16_OPC_RR = 0x1d,
                   8181:   M16_OPC_EXTEND = 0x1e,
                   8182:   M16_OPC_I64 = 0x1f
                   8183: };
                   8184: 
                   8185: /* I8 funct field */
                   8186: enum {
                   8187:   I8_BTEQZ = 0x0,
                   8188:   I8_BTNEZ = 0x1,
                   8189:   I8_SWRASP = 0x2,
                   8190:   I8_ADJSP = 0x3,
                   8191:   I8_SVRS = 0x4,
                   8192:   I8_MOV32R = 0x5,
                   8193:   I8_MOVR32 = 0x7
                   8194: };
                   8195: 
                   8196: /* RRR f field */
                   8197: enum {
                   8198:   RRR_DADDU = 0x0,
                   8199:   RRR_ADDU = 0x1,
                   8200:   RRR_DSUBU = 0x2,
                   8201:   RRR_SUBU = 0x3
                   8202: };
                   8203: 
                   8204: /* RR funct field */
                   8205: enum {
                   8206:   RR_JR = 0x00,
                   8207:   RR_SDBBP = 0x01,
                   8208:   RR_SLT = 0x02,
                   8209:   RR_SLTU = 0x03,
                   8210:   RR_SLLV = 0x04,
                   8211:   RR_BREAK = 0x05,
                   8212:   RR_SRLV = 0x06,
                   8213:   RR_SRAV = 0x07,
                   8214:   RR_DSRL = 0x08,
                   8215:   RR_CMP = 0x0a,
                   8216:   RR_NEG = 0x0b,
                   8217:   RR_AND = 0x0c,
                   8218:   RR_OR = 0x0d,
                   8219:   RR_XOR = 0x0e,
                   8220:   RR_NOT = 0x0f,
                   8221:   RR_MFHI = 0x10,
                   8222:   RR_CNVT = 0x11,
                   8223:   RR_MFLO = 0x12,
                   8224:   RR_DSRA = 0x13,
                   8225:   RR_DSLLV = 0x14,
                   8226:   RR_DSRLV = 0x16,
                   8227:   RR_DSRAV = 0x17,
                   8228:   RR_MULT = 0x18,
                   8229:   RR_MULTU = 0x19,
                   8230:   RR_DIV = 0x1a,
                   8231:   RR_DIVU = 0x1b,
                   8232:   RR_DMULT = 0x1c,
                   8233:   RR_DMULTU = 0x1d,
                   8234:   RR_DDIV = 0x1e,
                   8235:   RR_DDIVU = 0x1f
                   8236: };
                   8237: 
                   8238: /* I64 funct field */
                   8239: enum {
                   8240:   I64_LDSP = 0x0,
                   8241:   I64_SDSP = 0x1,
                   8242:   I64_SDRASP = 0x2,
                   8243:   I64_DADJSP = 0x3,
                   8244:   I64_LDPC = 0x4,
                   8245:   I64_DADDIU5 = 0x5,
                   8246:   I64_DADDIUPC = 0x6,
                   8247:   I64_DADDIUSP = 0x7
                   8248: };
                   8249: 
                   8250: /* RR ry field for CNVT */
                   8251: enum {
                   8252:   RR_RY_CNVT_ZEB = 0x0,
                   8253:   RR_RY_CNVT_ZEH = 0x1,
                   8254:   RR_RY_CNVT_ZEW = 0x2,
                   8255:   RR_RY_CNVT_SEB = 0x4,
                   8256:   RR_RY_CNVT_SEH = 0x5,
                   8257:   RR_RY_CNVT_SEW = 0x6,
                   8258: };
                   8259: 
                   8260: static int xlat (int r)
                   8261: {
                   8262:   static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
                   8263: 
                   8264:   return map[r];
                   8265: }
                   8266: 
                   8267: static void gen_mips16_save (DisasContext *ctx,
                   8268:                              int xsregs, int aregs,
                   8269:                              int do_ra, int do_s0, int do_s1,
                   8270:                              int framesize)
                   8271: {
                   8272:     TCGv t0 = tcg_temp_new();
                   8273:     TCGv t1 = tcg_temp_new();
                   8274:     int args, astatic;
                   8275: 
                   8276:     switch (aregs) {
                   8277:     case 0:
                   8278:     case 1:
                   8279:     case 2:
                   8280:     case 3:
                   8281:     case 11:
                   8282:         args = 0;
                   8283:         break;
                   8284:     case 4:
                   8285:     case 5:
                   8286:     case 6:
                   8287:     case 7:
                   8288:         args = 1;
                   8289:         break;
                   8290:     case 8:
                   8291:     case 9:
                   8292:     case 10:
                   8293:         args = 2;
                   8294:         break;
                   8295:     case 12:
                   8296:     case 13:
                   8297:         args = 3;
                   8298:         break;
                   8299:     case 14:
                   8300:         args = 4;
                   8301:         break;
                   8302:     default:
                   8303:         generate_exception(ctx, EXCP_RI);
                   8304:         return;
                   8305:     }
                   8306: 
                   8307:     switch (args) {
                   8308:     case 4:
                   8309:         gen_base_offset_addr(ctx, t0, 29, 12);
                   8310:         gen_load_gpr(t1, 7);
                   8311:         op_st_sw(t1, t0, ctx);
                   8312:         /* Fall through */
                   8313:     case 3:
                   8314:         gen_base_offset_addr(ctx, t0, 29, 8);
                   8315:         gen_load_gpr(t1, 6);
                   8316:         op_st_sw(t1, t0, ctx);
                   8317:         /* Fall through */
                   8318:     case 2:
                   8319:         gen_base_offset_addr(ctx, t0, 29, 4);
                   8320:         gen_load_gpr(t1, 5);
                   8321:         op_st_sw(t1, t0, ctx);
                   8322:         /* Fall through */
                   8323:     case 1:
                   8324:         gen_base_offset_addr(ctx, t0, 29, 0);
                   8325:         gen_load_gpr(t1, 4);
                   8326:         op_st_sw(t1, t0, ctx);
                   8327:     }
                   8328: 
                   8329:     gen_load_gpr(t0, 29);
                   8330: 
                   8331: #define DECR_AND_STORE(reg) do {                \
                   8332:         tcg_gen_subi_tl(t0, t0, 4);             \
                   8333:         gen_load_gpr(t1, reg);                  \
                   8334:         op_st_sw(t1, t0, ctx);                  \
                   8335:     } while (0)
                   8336: 
                   8337:     if (do_ra) {
                   8338:         DECR_AND_STORE(31);
                   8339:     }
                   8340: 
                   8341:     switch (xsregs) {
                   8342:     case 7:
                   8343:         DECR_AND_STORE(30);
                   8344:         /* Fall through */
                   8345:     case 6:
                   8346:         DECR_AND_STORE(23);
                   8347:         /* Fall through */
                   8348:     case 5:
                   8349:         DECR_AND_STORE(22);
                   8350:         /* Fall through */
                   8351:     case 4:
                   8352:         DECR_AND_STORE(21);
                   8353:         /* Fall through */
                   8354:     case 3:
                   8355:         DECR_AND_STORE(20);
                   8356:         /* Fall through */
                   8357:     case 2:
                   8358:         DECR_AND_STORE(19);
                   8359:         /* Fall through */
                   8360:     case 1:
                   8361:         DECR_AND_STORE(18);
                   8362:     }
                   8363: 
                   8364:     if (do_s1) {
                   8365:         DECR_AND_STORE(17);
                   8366:     }
                   8367:     if (do_s0) {
                   8368:         DECR_AND_STORE(16);
                   8369:     }
                   8370: 
                   8371:     switch (aregs) {
                   8372:     case 0:
                   8373:     case 4:
                   8374:     case 8:
                   8375:     case 12:
                   8376:     case 14:
                   8377:         astatic = 0;
                   8378:         break;
                   8379:     case 1:
                   8380:     case 5:
                   8381:     case 9:
                   8382:     case 13:
                   8383:         astatic = 1;
                   8384:         break;
                   8385:     case 2:
                   8386:     case 6:
                   8387:     case 10:
                   8388:         astatic = 2;
                   8389:         break;
                   8390:     case 3:
                   8391:     case 7:
                   8392:         astatic = 3;
                   8393:         break;
                   8394:     case 11:
                   8395:         astatic = 4;
                   8396:         break;
                   8397:     default:
                   8398:         generate_exception(ctx, EXCP_RI);
                   8399:         return;
                   8400:     }
                   8401: 
                   8402:     if (astatic > 0) {
                   8403:         DECR_AND_STORE(7);
                   8404:         if (astatic > 1) {
                   8405:             DECR_AND_STORE(6);
                   8406:             if (astatic > 2) {
                   8407:                 DECR_AND_STORE(5);
                   8408:                 if (astatic > 3) {
                   8409:                     DECR_AND_STORE(4);
                   8410:                 }
                   8411:             }
                   8412:         }
                   8413:     }
                   8414: #undef DECR_AND_STORE
                   8415: 
                   8416:     tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
                   8417:     tcg_temp_free(t0);
                   8418:     tcg_temp_free(t1);
                   8419: }
                   8420: 
                   8421: static void gen_mips16_restore (DisasContext *ctx,
                   8422:                                 int xsregs, int aregs,
                   8423:                                 int do_ra, int do_s0, int do_s1,
                   8424:                                 int framesize)
                   8425: {
                   8426:     int astatic;
                   8427:     TCGv t0 = tcg_temp_new();
                   8428:     TCGv t1 = tcg_temp_new();
                   8429: 
                   8430:     tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
                   8431: 
                   8432: #define DECR_AND_LOAD(reg) do {                 \
                   8433:         tcg_gen_subi_tl(t0, t0, 4);             \
                   8434:         op_ld_lw(t1, t0, ctx);                  \
                   8435:         gen_store_gpr(t1, reg);                 \
                   8436:     } while (0)
                   8437: 
                   8438:     if (do_ra) {
                   8439:         DECR_AND_LOAD(31);
                   8440:     }
                   8441: 
                   8442:     switch (xsregs) {
                   8443:     case 7:
                   8444:         DECR_AND_LOAD(30);
                   8445:         /* Fall through */
                   8446:     case 6:
                   8447:         DECR_AND_LOAD(23);
                   8448:         /* Fall through */
                   8449:     case 5:
                   8450:         DECR_AND_LOAD(22);
                   8451:         /* Fall through */
                   8452:     case 4:
                   8453:         DECR_AND_LOAD(21);
                   8454:         /* Fall through */
                   8455:     case 3:
                   8456:         DECR_AND_LOAD(20);
                   8457:         /* Fall through */
                   8458:     case 2:
                   8459:         DECR_AND_LOAD(19);
                   8460:         /* Fall through */
                   8461:     case 1:
                   8462:         DECR_AND_LOAD(18);
                   8463:     }
                   8464: 
                   8465:     if (do_s1) {
                   8466:         DECR_AND_LOAD(17);
                   8467:     }
                   8468:     if (do_s0) {
                   8469:         DECR_AND_LOAD(16);
                   8470:     }
                   8471: 
                   8472:     switch (aregs) {
                   8473:     case 0:
                   8474:     case 4:
                   8475:     case 8:
                   8476:     case 12:
                   8477:     case 14:
                   8478:         astatic = 0;
                   8479:         break;
                   8480:     case 1:
                   8481:     case 5:
                   8482:     case 9:
                   8483:     case 13:
                   8484:         astatic = 1;
                   8485:         break;
                   8486:     case 2:
                   8487:     case 6:
                   8488:     case 10:
                   8489:         astatic = 2;
                   8490:         break;
                   8491:     case 3:
                   8492:     case 7:
                   8493:         astatic = 3;
                   8494:         break;
                   8495:     case 11:
                   8496:         astatic = 4;
                   8497:         break;
                   8498:     default:
                   8499:         generate_exception(ctx, EXCP_RI);
                   8500:         return;
                   8501:     }
                   8502: 
                   8503:     if (astatic > 0) {
                   8504:         DECR_AND_LOAD(7);
                   8505:         if (astatic > 1) {
                   8506:             DECR_AND_LOAD(6);
                   8507:             if (astatic > 2) {
                   8508:                 DECR_AND_LOAD(5);
                   8509:                 if (astatic > 3) {
                   8510:                     DECR_AND_LOAD(4);
                   8511:                 }
                   8512:             }
                   8513:         }
                   8514:     }
                   8515: #undef DECR_AND_LOAD
                   8516: 
                   8517:     tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
                   8518:     tcg_temp_free(t0);
                   8519:     tcg_temp_free(t1);
                   8520: }
                   8521: 
                   8522: static void gen_addiupc (DisasContext *ctx, int rx, int imm,
                   8523:                          int is_64_bit, int extended)
                   8524: {
                   8525:     TCGv t0;
                   8526: 
                   8527:     if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
                   8528:         generate_exception(ctx, EXCP_RI);
                   8529:         return;
                   8530:     }
                   8531: 
                   8532:     t0 = tcg_temp_new();
                   8533: 
                   8534:     tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
                   8535:     tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
                   8536:     if (!is_64_bit) {
                   8537:         tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
                   8538:     }
                   8539: 
                   8540:     tcg_temp_free(t0);
                   8541: }
                   8542: 
                   8543: #if defined(TARGET_MIPS64)
                   8544: static void decode_i64_mips16 (CPUState *env, DisasContext *ctx,
                   8545:                                int ry, int funct, int16_t offset,
                   8546:                                int extended)
                   8547: {
                   8548:     switch (funct) {
                   8549:     case I64_LDSP:
                   8550:         check_mips_64(ctx);
                   8551:         offset = extended ? offset : offset << 3;
                   8552:         gen_ld(env, ctx, OPC_LD, ry, 29, offset);
                   8553:         break;
                   8554:     case I64_SDSP:
                   8555:         check_mips_64(ctx);
                   8556:         offset = extended ? offset : offset << 3;
                   8557:         gen_st(ctx, OPC_SD, ry, 29, offset);
                   8558:         break;
                   8559:     case I64_SDRASP:
                   8560:         check_mips_64(ctx);
                   8561:         offset = extended ? offset : (ctx->opcode & 0xff) << 3;
                   8562:         gen_st(ctx, OPC_SD, 31, 29, offset);
                   8563:         break;
                   8564:     case I64_DADJSP:
                   8565:         check_mips_64(ctx);
                   8566:         offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
                   8567:         gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
                   8568:         break;
                   8569:     case I64_LDPC:
                   8570:         if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
                   8571:             generate_exception(ctx, EXCP_RI);
                   8572:         } else {
                   8573:             offset = extended ? offset : offset << 3;
                   8574:             gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
                   8575:         }
                   8576:         break;
                   8577:     case I64_DADDIU5:
                   8578:         check_mips_64(ctx);
                   8579:         offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
                   8580:         gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
                   8581:         break;
                   8582:     case I64_DADDIUPC:
                   8583:         check_mips_64(ctx);
                   8584:         offset = extended ? offset : offset << 2;
                   8585:         gen_addiupc(ctx, ry, offset, 1, extended);
                   8586:         break;
                   8587:     case I64_DADDIUSP:
                   8588:         check_mips_64(ctx);
                   8589:         offset = extended ? offset : offset << 2;
                   8590:         gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
                   8591:         break;
                   8592:     }
                   8593: }
                   8594: #endif
                   8595: 
                   8596: static int decode_extended_mips16_opc (CPUState *env, DisasContext *ctx,
                   8597:                                        int *is_branch)
                   8598: {
                   8599:     int extend = lduw_code(ctx->pc + 2);
                   8600:     int op, rx, ry, funct, sa;
                   8601:     int16_t imm, offset;
                   8602: 
                   8603:     ctx->opcode = (ctx->opcode << 16) | extend;
                   8604:     op = (ctx->opcode >> 11) & 0x1f;
                   8605:     sa = (ctx->opcode >> 22) & 0x1f;
                   8606:     funct = (ctx->opcode >> 8) & 0x7;
                   8607:     rx = xlat((ctx->opcode >> 8) & 0x7);
                   8608:     ry = xlat((ctx->opcode >> 5) & 0x7);
                   8609:     offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
                   8610:                               | ((ctx->opcode >> 21) & 0x3f) << 5
                   8611:                               | (ctx->opcode & 0x1f));
                   8612: 
                   8613:     /* The extended opcodes cleverly reuse the opcodes from their 16-bit
                   8614:        counterparts.  */
                   8615:     switch (op) {
                   8616:     case M16_OPC_ADDIUSP:
                   8617:         gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
                   8618:         break;
                   8619:     case M16_OPC_ADDIUPC:
                   8620:         gen_addiupc(ctx, rx, imm, 0, 1);
                   8621:         break;
                   8622:     case M16_OPC_B:
                   8623:         gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
                   8624:         /* No delay slot, so just process as a normal instruction */
                   8625:         break;
                   8626:     case M16_OPC_BEQZ:
                   8627:         gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
                   8628:         /* No delay slot, so just process as a normal instruction */
                   8629:         break;
                   8630:     case M16_OPC_BNEQZ:
                   8631:         gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
                   8632:         /* No delay slot, so just process as a normal instruction */
                   8633:         break;
                   8634:     case M16_OPC_SHIFT:
                   8635:         switch (ctx->opcode & 0x3) {
                   8636:         case 0x0:
                   8637:             gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
                   8638:             break;
                   8639:         case 0x1:
                   8640: #if defined(TARGET_MIPS64)
                   8641:             check_mips_64(ctx);
                   8642:             gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
                   8643: #else
                   8644:             generate_exception(ctx, EXCP_RI);
                   8645: #endif
                   8646:             break;
                   8647:         case 0x2:
                   8648:             gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
                   8649:             break;
                   8650:         case 0x3:
                   8651:             gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
                   8652:             break;
                   8653:         }
                   8654:         break;
                   8655: #if defined(TARGET_MIPS64)
                   8656:     case M16_OPC_LD:
                   8657:             check_mips_64(ctx);
                   8658:         gen_ld(env, ctx, OPC_LD, ry, rx, offset);
                   8659:         break;
                   8660: #endif
                   8661:     case M16_OPC_RRIA:
                   8662:         imm = ctx->opcode & 0xf;
                   8663:         imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
                   8664:         imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
                   8665:         imm = (int16_t) (imm << 1) >> 1;
                   8666:         if ((ctx->opcode >> 4) & 0x1) {
                   8667: #if defined(TARGET_MIPS64)
                   8668:             check_mips_64(ctx);
                   8669:             gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
                   8670: #else
                   8671:             generate_exception(ctx, EXCP_RI);
                   8672: #endif
                   8673:         } else {
                   8674:             gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
                   8675:         }
                   8676:         break;
                   8677:     case M16_OPC_ADDIU8:
                   8678:         gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
                   8679:         break;
                   8680:     case M16_OPC_SLTI:
                   8681:         gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
                   8682:         break;
                   8683:     case M16_OPC_SLTIU:
                   8684:         gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
                   8685:         break;
                   8686:     case M16_OPC_I8:
                   8687:         switch (funct) {
                   8688:         case I8_BTEQZ:
                   8689:             gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
                   8690:             break;
                   8691:         case I8_BTNEZ:
                   8692:             gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
                   8693:             break;
                   8694:         case I8_SWRASP:
                   8695:             gen_st(ctx, OPC_SW, 31, 29, imm);
                   8696:             break;
                   8697:         case I8_ADJSP:
                   8698:             gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
                   8699:             break;
                   8700:         case I8_SVRS:
                   8701:             {
                   8702:                 int xsregs = (ctx->opcode >> 24) & 0x7;
                   8703:                 int aregs = (ctx->opcode >> 16) & 0xf;
                   8704:                 int do_ra = (ctx->opcode >> 6) & 0x1;
                   8705:                 int do_s0 = (ctx->opcode >> 5) & 0x1;
                   8706:                 int do_s1 = (ctx->opcode >> 4) & 0x1;
                   8707:                 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
                   8708:                                  | (ctx->opcode & 0xf)) << 3;
                   8709: 
                   8710:                 if (ctx->opcode & (1 << 7)) {
                   8711:                     gen_mips16_save(ctx, xsregs, aregs,
                   8712:                                     do_ra, do_s0, do_s1,
                   8713:                                     framesize);
                   8714:                 } else {
                   8715:                     gen_mips16_restore(ctx, xsregs, aregs,
                   8716:                                        do_ra, do_s0, do_s1,
                   8717:                                        framesize);
                   8718:                 }
                   8719:             }
                   8720:             break;
                   8721:         default:
                   8722:             generate_exception(ctx, EXCP_RI);
                   8723:             break;
                   8724:         }
                   8725:         break;
                   8726:     case M16_OPC_LI:
                   8727:         tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
                   8728:         break;
                   8729:     case M16_OPC_CMPI:
                   8730:         tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
                   8731:         break;
                   8732: #if defined(TARGET_MIPS64)
                   8733:     case M16_OPC_SD:
                   8734:         gen_st(ctx, OPC_SD, ry, rx, offset);
                   8735:         break;
                   8736: #endif
                   8737:     case M16_OPC_LB:
                   8738:         gen_ld(env, ctx, OPC_LB, ry, rx, offset);
                   8739:         break;
                   8740:     case M16_OPC_LH:
                   8741:         gen_ld(env, ctx, OPC_LH, ry, rx, offset);
                   8742:         break;
                   8743:     case M16_OPC_LWSP:
                   8744:         gen_ld(env, ctx, OPC_LW, rx, 29, offset);
                   8745:         break;
                   8746:     case M16_OPC_LW:
                   8747:         gen_ld(env, ctx, OPC_LW, ry, rx, offset);
                   8748:         break;
                   8749:     case M16_OPC_LBU:
                   8750:         gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
                   8751:         break;
                   8752:     case M16_OPC_LHU:
                   8753:         gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
                   8754:         break;
                   8755:     case M16_OPC_LWPC:
                   8756:         gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
                   8757:         break;
                   8758: #if defined(TARGET_MIPS64)
                   8759:     case M16_OPC_LWU:
                   8760:         gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
                   8761:         break;
                   8762: #endif
                   8763:     case M16_OPC_SB:
                   8764:         gen_st(ctx, OPC_SB, ry, rx, offset);
                   8765:         break;
                   8766:     case M16_OPC_SH:
                   8767:         gen_st(ctx, OPC_SH, ry, rx, offset);
                   8768:         break;
                   8769:     case M16_OPC_SWSP:
                   8770:         gen_st(ctx, OPC_SW, rx, 29, offset);
                   8771:         break;
                   8772:     case M16_OPC_SW:
                   8773:         gen_st(ctx, OPC_SW, ry, rx, offset);
                   8774:         break;
                   8775: #if defined(TARGET_MIPS64)
                   8776:     case M16_OPC_I64:
                   8777:         decode_i64_mips16(env, ctx, ry, funct, offset, 1);
                   8778:         break;
                   8779: #endif
                   8780:     default:
                   8781:         generate_exception(ctx, EXCP_RI);
                   8782:         break;
                   8783:     }
                   8784: 
                   8785:     return 4;
                   8786: }
                   8787: 
                   8788: static int decode_mips16_opc (CPUState *env, DisasContext *ctx,
                   8789:                               int *is_branch)
                   8790: {
                   8791:     int rx, ry;
                   8792:     int sa;
                   8793:     int op, cnvt_op, op1, offset;
                   8794:     int funct;
                   8795:     int n_bytes;
                   8796: 
                   8797:     op = (ctx->opcode >> 11) & 0x1f;
                   8798:     sa = (ctx->opcode >> 2) & 0x7;
                   8799:     sa = sa == 0 ? 8 : sa;
                   8800:     rx = xlat((ctx->opcode >> 8) & 0x7);
                   8801:     cnvt_op = (ctx->opcode >> 5) & 0x7;
                   8802:     ry = xlat((ctx->opcode >> 5) & 0x7);
                   8803:     op1 = offset = ctx->opcode & 0x1f;
                   8804: 
                   8805:     n_bytes = 2;
                   8806: 
                   8807:     switch (op) {
                   8808:     case M16_OPC_ADDIUSP:
                   8809:         {
                   8810:             int16_t imm = ((uint8_t) ctx->opcode) << 2;
                   8811: 
                   8812:             gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
                   8813:         }
                   8814:         break;
                   8815:     case M16_OPC_ADDIUPC:
                   8816:         gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
                   8817:         break;
                   8818:     case M16_OPC_B:
                   8819:         offset = (ctx->opcode & 0x7ff) << 1;
                   8820:         offset = (int16_t)(offset << 4) >> 4;
                   8821:         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
                   8822:         /* No delay slot, so just process as a normal instruction */
                   8823:         break;
                   8824:     case M16_OPC_JAL:
                   8825:         offset = lduw_code(ctx->pc + 2);
                   8826:         offset = (((ctx->opcode & 0x1f) << 21)
                   8827:                   | ((ctx->opcode >> 5) & 0x1f) << 16
                   8828:                   | offset) << 2;
                   8829:         op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
                   8830:         gen_compute_branch(ctx, op, 4, rx, ry, offset);
                   8831:         n_bytes = 4;
                   8832:         *is_branch = 1;
                   8833:         break;
                   8834:     case M16_OPC_BEQZ:
                   8835:         gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
                   8836:         /* No delay slot, so just process as a normal instruction */
                   8837:         break;
                   8838:     case M16_OPC_BNEQZ:
                   8839:         gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
                   8840:         /* No delay slot, so just process as a normal instruction */
                   8841:         break;
                   8842:     case M16_OPC_SHIFT:
                   8843:         switch (ctx->opcode & 0x3) {
                   8844:         case 0x0:
                   8845:             gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
                   8846:             break;
                   8847:         case 0x1:
                   8848: #if defined(TARGET_MIPS64)
                   8849:             check_mips_64(ctx);
                   8850:             gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
                   8851: #else
                   8852:             generate_exception(ctx, EXCP_RI);
                   8853: #endif
                   8854:             break;
                   8855:         case 0x2:
                   8856:             gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
                   8857:             break;
                   8858:         case 0x3:
                   8859:             gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
                   8860:             break;
                   8861:         }
                   8862:         break;
                   8863: #if defined(TARGET_MIPS64)
                   8864:     case M16_OPC_LD:
                   8865:         check_mips_64(ctx);
                   8866:         gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
                   8867:         break;
                   8868: #endif
                   8869:     case M16_OPC_RRIA:
                   8870:         {
                   8871:             int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
                   8872: 
                   8873:             if ((ctx->opcode >> 4) & 1) {
                   8874: #if defined(TARGET_MIPS64)
                   8875:                 check_mips_64(ctx);
                   8876:                 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
                   8877: #else
                   8878:                 generate_exception(ctx, EXCP_RI);
                   8879: #endif
                   8880:             } else {
                   8881:                 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
                   8882:             }
                   8883:         }
                   8884:         break;
                   8885:     case M16_OPC_ADDIU8:
                   8886:         {
                   8887:             int16_t imm = (int8_t) ctx->opcode;
                   8888: 
                   8889:             gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
                   8890:         }
                   8891:         break;
                   8892:     case M16_OPC_SLTI:
                   8893:         {
                   8894:             int16_t imm = (uint8_t) ctx->opcode;
                   8895: 
                   8896:             gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
                   8897:         }
                   8898:         break;
                   8899:     case M16_OPC_SLTIU:
                   8900:         {
                   8901:             int16_t imm = (uint8_t) ctx->opcode;
                   8902: 
                   8903:             gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
                   8904:         }
                   8905:         break;
                   8906:     case M16_OPC_I8:
                   8907:         {
                   8908:             int reg32;
                   8909: 
                   8910:             funct = (ctx->opcode >> 8) & 0x7;
                   8911:             switch (funct) {
                   8912:             case I8_BTEQZ:
                   8913:                 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
                   8914:                                    ((int8_t)ctx->opcode) << 1);
                   8915:                 break;
                   8916:             case I8_BTNEZ:
                   8917:                 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
                   8918:                                    ((int8_t)ctx->opcode) << 1);
                   8919:                 break;
                   8920:             case I8_SWRASP:
                   8921:                 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
                   8922:                 break;
                   8923:             case I8_ADJSP:
                   8924:                 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
                   8925:                               ((int8_t)ctx->opcode) << 3);
                   8926:                 break;
                   8927:             case I8_SVRS:
                   8928:                 {
                   8929:                     int do_ra = ctx->opcode & (1 << 6);
                   8930:                     int do_s0 = ctx->opcode & (1 << 5);
                   8931:                     int do_s1 = ctx->opcode & (1 << 4);
                   8932:                     int framesize = ctx->opcode & 0xf;
                   8933: 
                   8934:                     if (framesize == 0) {
                   8935:                         framesize = 128;
                   8936:                     } else {
                   8937:                         framesize = framesize << 3;
                   8938:                     }
                   8939: 
                   8940:                     if (ctx->opcode & (1 << 7)) {
                   8941:                         gen_mips16_save(ctx, 0, 0,
                   8942:                                         do_ra, do_s0, do_s1, framesize);
                   8943:                     } else {
                   8944:                         gen_mips16_restore(ctx, 0, 0,
                   8945:                                            do_ra, do_s0, do_s1, framesize);
                   8946:                     }
                   8947:                 }
                   8948:                 break;
                   8949:             case I8_MOV32R:
                   8950:                 {
                   8951:                     int rz = xlat(ctx->opcode & 0x7);
                   8952: 
                   8953:                     reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
                   8954:                         ((ctx->opcode >> 5) & 0x7);
                   8955:                     gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
                   8956:                 }
                   8957:                 break;
                   8958:             case I8_MOVR32:
                   8959:                 reg32 = ctx->opcode & 0x1f;
                   8960:                 gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
                   8961:                 break;
                   8962:             default:
                   8963:                 generate_exception(ctx, EXCP_RI);
                   8964:                 break;
                   8965:             }
                   8966:         }
                   8967:         break;
                   8968:     case M16_OPC_LI:
                   8969:         {
                   8970:             int16_t imm = (uint8_t) ctx->opcode;
                   8971: 
                   8972:             gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
                   8973:         }
                   8974:         break;
                   8975:     case M16_OPC_CMPI:
                   8976:         {
                   8977:             int16_t imm = (uint8_t) ctx->opcode;
                   8978: 
                   8979:             gen_logic_imm(env, OPC_XORI, 24, rx, imm);
                   8980:         }
                   8981:         break;
                   8982: #if defined(TARGET_MIPS64)
                   8983:     case M16_OPC_SD:
                   8984:         check_mips_64(ctx);
                   8985:         gen_st(ctx, OPC_SD, ry, rx, offset << 3);
                   8986:         break;
                   8987: #endif
                   8988:     case M16_OPC_LB:
                   8989:         gen_ld(env, ctx, OPC_LB, ry, rx, offset);
                   8990:         break;
                   8991:     case M16_OPC_LH:
                   8992:         gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
                   8993:         break;
                   8994:     case M16_OPC_LWSP:
                   8995:         gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
                   8996:         break;
                   8997:     case M16_OPC_LW:
                   8998:         gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
                   8999:         break;
                   9000:     case M16_OPC_LBU:
                   9001:         gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
                   9002:         break;
                   9003:     case M16_OPC_LHU:
                   9004:         gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
                   9005:         break;
                   9006:     case M16_OPC_LWPC:
                   9007:         gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
                   9008:         break;
                   9009: #if defined (TARGET_MIPS64)
                   9010:     case M16_OPC_LWU:
                   9011:         check_mips_64(ctx);
                   9012:         gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
                   9013:         break;
                   9014: #endif
                   9015:     case M16_OPC_SB:
                   9016:         gen_st(ctx, OPC_SB, ry, rx, offset);
                   9017:         break;
                   9018:     case M16_OPC_SH:
                   9019:         gen_st(ctx, OPC_SH, ry, rx, offset << 1);
                   9020:         break;
                   9021:     case M16_OPC_SWSP:
                   9022:         gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
                   9023:         break;
                   9024:     case M16_OPC_SW:
                   9025:         gen_st(ctx, OPC_SW, ry, rx, offset << 2);
                   9026:         break;
                   9027:     case M16_OPC_RRR:
                   9028:         {
                   9029:             int rz = xlat((ctx->opcode >> 2) & 0x7);
                   9030:             int mips32_op;
                   9031: 
                   9032:             switch (ctx->opcode & 0x3) {
                   9033:             case RRR_ADDU:
                   9034:                 mips32_op = OPC_ADDU;
                   9035:                 break;
                   9036:             case RRR_SUBU:
                   9037:                 mips32_op = OPC_SUBU;
                   9038:                 break;
                   9039: #if defined(TARGET_MIPS64)
                   9040:             case RRR_DADDU:
                   9041:                 mips32_op = OPC_DADDU;
                   9042:                 check_mips_64(ctx);
                   9043:                 break;
                   9044:             case RRR_DSUBU:
                   9045:                 mips32_op = OPC_DSUBU;
                   9046:                 check_mips_64(ctx);
                   9047:                 break;
                   9048: #endif
                   9049:             default:
                   9050:                 generate_exception(ctx, EXCP_RI);
                   9051:                 goto done;
                   9052:             }
                   9053: 
                   9054:             gen_arith(env, ctx, mips32_op, rz, rx, ry);
                   9055:         done:
                   9056:             ;
                   9057:         }
                   9058:         break;
                   9059:     case M16_OPC_RR:
                   9060:         switch (op1) {
                   9061:         case RR_JR:
                   9062:             {
                   9063:                 int nd = (ctx->opcode >> 7) & 0x1;
                   9064:                 int link = (ctx->opcode >> 6) & 0x1;
                   9065:                 int ra = (ctx->opcode >> 5) & 0x1;
                   9066: 
                   9067:                 if (link) {
                   9068:                     op = nd ? OPC_JALRC : OPC_JALRS;
                   9069:                 } else {
                   9070:                     op = OPC_JR;
                   9071:                 }
                   9072: 
                   9073:                 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
                   9074:                 if (!nd) {
                   9075:                     *is_branch = 1;
                   9076:                 }
                   9077:             }
                   9078:             break;
                   9079:         case RR_SDBBP:
                   9080:             /* XXX: not clear which exception should be raised
                   9081:              *      when in debug mode...
                   9082:              */
                   9083:             check_insn(env, ctx, ISA_MIPS32);
                   9084:             if (!(ctx->hflags & MIPS_HFLAG_DM)) {
                   9085:                 generate_exception(ctx, EXCP_DBp);
                   9086:             } else {
                   9087:                 generate_exception(ctx, EXCP_DBp);
                   9088:             }
                   9089:             break;
                   9090:         case RR_SLT:
                   9091:             gen_slt(env, OPC_SLT, 24, rx, ry);
                   9092:             break;
                   9093:         case RR_SLTU:
                   9094:             gen_slt(env, OPC_SLTU, 24, rx, ry);
                   9095:             break;
                   9096:         case RR_BREAK:
                   9097:             generate_exception(ctx, EXCP_BREAK);
                   9098:             break;
                   9099:         case RR_SLLV:
                   9100:             gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
                   9101:             break;
                   9102:         case RR_SRLV:
                   9103:             gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
                   9104:             break;
                   9105:         case RR_SRAV:
                   9106:             gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
                   9107:             break;
                   9108: #if defined (TARGET_MIPS64)
                   9109:         case RR_DSRL:
                   9110:             check_mips_64(ctx);
                   9111:             gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
                   9112:             break;
                   9113: #endif
                   9114:         case RR_CMP:
                   9115:             gen_logic(env, OPC_XOR, 24, rx, ry);
                   9116:             break;
                   9117:         case RR_NEG:
                   9118:             gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
                   9119:             break;
                   9120:         case RR_AND:
                   9121:             gen_logic(env, OPC_AND, rx, rx, ry);
                   9122:             break;
                   9123:         case RR_OR:
                   9124:             gen_logic(env, OPC_OR, rx, rx, ry);
                   9125:             break;
                   9126:         case RR_XOR:
                   9127:             gen_logic(env, OPC_XOR, rx, rx, ry);
                   9128:             break;
                   9129:         case RR_NOT:
                   9130:             gen_logic(env, OPC_NOR, rx, ry, 0);
                   9131:             break;
                   9132:         case RR_MFHI:
                   9133:             gen_HILO(ctx, OPC_MFHI, rx);
                   9134:             break;
                   9135:         case RR_CNVT:
                   9136:             switch (cnvt_op) {
                   9137:             case RR_RY_CNVT_ZEB:
                   9138:                 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
                   9139:                 break;
                   9140:             case RR_RY_CNVT_ZEH:
                   9141:                 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
                   9142:                 break;
                   9143:             case RR_RY_CNVT_SEB:
                   9144:                 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
                   9145:                 break;
                   9146:             case RR_RY_CNVT_SEH:
                   9147:                 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
                   9148:                 break;
                   9149: #if defined (TARGET_MIPS64)
                   9150:             case RR_RY_CNVT_ZEW:
                   9151:                 check_mips_64(ctx);
                   9152:                 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
                   9153:                 break;
                   9154:             case RR_RY_CNVT_SEW:
                   9155:                 check_mips_64(ctx);
                   9156:                 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
                   9157:                 break;
                   9158: #endif
                   9159:             default:
                   9160:                 generate_exception(ctx, EXCP_RI);
                   9161:                 break;
                   9162:             }
                   9163:             break;
                   9164:         case RR_MFLO:
                   9165:             gen_HILO(ctx, OPC_MFLO, rx);
                   9166:             break;
                   9167: #if defined (TARGET_MIPS64)
                   9168:         case RR_DSRA:
                   9169:             check_mips_64(ctx);
                   9170:             gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
                   9171:             break;
                   9172:         case RR_DSLLV:
                   9173:             check_mips_64(ctx);
                   9174:             gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
                   9175:             break;
                   9176:         case RR_DSRLV:
                   9177:             check_mips_64(ctx);
                   9178:             gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
                   9179:             break;
                   9180:         case RR_DSRAV:
                   9181:             check_mips_64(ctx);
                   9182:             gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
                   9183:             break;
                   9184: #endif
                   9185:         case RR_MULT:
                   9186:             gen_muldiv(ctx, OPC_MULT, rx, ry);
                   9187:             break;
                   9188:         case RR_MULTU:
                   9189:             gen_muldiv(ctx, OPC_MULTU, rx, ry);
                   9190:             break;
                   9191:         case RR_DIV:
                   9192:             gen_muldiv(ctx, OPC_DIV, rx, ry);
                   9193:             break;
                   9194:         case RR_DIVU:
                   9195:             gen_muldiv(ctx, OPC_DIVU, rx, ry);
                   9196:             break;
                   9197: #if defined (TARGET_MIPS64)
                   9198:         case RR_DMULT:
                   9199:             check_mips_64(ctx);
                   9200:             gen_muldiv(ctx, OPC_DMULT, rx, ry);
                   9201:             break;
                   9202:         case RR_DMULTU:
                   9203:             check_mips_64(ctx);
                   9204:             gen_muldiv(ctx, OPC_DMULTU, rx, ry);
                   9205:             break;
                   9206:         case RR_DDIV:
                   9207:             check_mips_64(ctx);
                   9208:             gen_muldiv(ctx, OPC_DDIV, rx, ry);
                   9209:             break;
                   9210:         case RR_DDIVU:
                   9211:             check_mips_64(ctx);
                   9212:             gen_muldiv(ctx, OPC_DDIVU, rx, ry);
                   9213:             break;
                   9214: #endif
                   9215:         default:
                   9216:             generate_exception(ctx, EXCP_RI);
                   9217:             break;
                   9218:         }
                   9219:         break;
                   9220:     case M16_OPC_EXTEND:
                   9221:         decode_extended_mips16_opc(env, ctx, is_branch);
                   9222:         n_bytes = 4;
                   9223:         break;
                   9224: #if defined(TARGET_MIPS64)
                   9225:     case M16_OPC_I64:
                   9226:         funct = (ctx->opcode >> 8) & 0x7;
                   9227:         decode_i64_mips16(env, ctx, ry, funct, offset, 0);
                   9228:         break;
                   9229: #endif
                   9230:     default:
                   9231:         generate_exception(ctx, EXCP_RI);
                   9232:         break;
                   9233:     }
                   9234: 
                   9235:     return n_bytes;
                   9236: }
                   9237: 
                   9238: /* microMIPS extension to MIPS32 */
                   9239: 
                   9240: /* microMIPS32 major opcodes */
                   9241: 
                   9242: enum {
                   9243:     POOL32A = 0x00,
                   9244:     POOL16A = 0x01,
                   9245:     LBU16 = 0x02,
                   9246:     MOVE16 = 0x03,
                   9247:     ADDI32 = 0x04,
                   9248:     LBU32 = 0x05,
                   9249:     SB32 = 0x06,
                   9250:     LB32 = 0x07,
                   9251: 
                   9252:     POOL32B = 0x08,
                   9253:     POOL16B = 0x09,
                   9254:     LHU16 = 0x0a,
                   9255:     ANDI16 = 0x0b,
                   9256:     ADDIU32 = 0x0c,
                   9257:     LHU32 = 0x0d,
                   9258:     SH32 = 0x0e,
                   9259:     LH32 = 0x0f,
                   9260: 
                   9261:     POOL32I = 0x10,
                   9262:     POOL16C = 0x11,
                   9263:     LWSP16 = 0x12,
                   9264:     POOL16D = 0x13,
                   9265:     ORI32 = 0x14,
                   9266:     POOL32F = 0x15,
                   9267:     POOL32S = 0x16,
                   9268:     DADDIU32 = 0x17,
                   9269: 
                   9270:     POOL32C = 0x18,
                   9271:     LWGP16 = 0x19,
                   9272:     LW16 = 0x1a,
                   9273:     POOL16E = 0x1b,
                   9274:     XORI32 = 0x1c,
                   9275:     JALS32 = 0x1d,
                   9276:     ADDIUPC = 0x1e,
                   9277:     POOL48A = 0x1f,
                   9278: 
                   9279:     /* 0x20 is reserved */
                   9280:     RES_20 = 0x20,
                   9281:     POOL16F = 0x21,
                   9282:     SB16 = 0x22,
                   9283:     BEQZ16 = 0x23,
                   9284:     SLTI32 = 0x24,
                   9285:     BEQ32 = 0x25,
                   9286:     SWC132 = 0x26,
                   9287:     LWC132 = 0x27,
                   9288: 
                   9289:     /* 0x28 and 0x29 are reserved */
                   9290:     RES_28 = 0x28,
                   9291:     RES_29 = 0x29,
                   9292:     SH16 = 0x2a,
                   9293:     BNEZ16 = 0x2b,
                   9294:     SLTIU32 = 0x2c,
                   9295:     BNE32 = 0x2d,
                   9296:     SDC132 = 0x2e,
                   9297:     LDC132 = 0x2f,
                   9298: 
                   9299:     /* 0x30 and 0x31 are reserved */
                   9300:     RES_30 = 0x30,
                   9301:     RES_31 = 0x31,
                   9302:     SWSP16 = 0x32,
                   9303:     B16 = 0x33,
                   9304:     ANDI32 = 0x34,
                   9305:     J32 = 0x35,
                   9306:     SD32 = 0x36,
                   9307:     LD32 = 0x37,
                   9308: 
                   9309:     /* 0x38 and 0x39 are reserved */
                   9310:     RES_38 = 0x38,
                   9311:     RES_39 = 0x39,
                   9312:     SW16 = 0x3a,
                   9313:     LI16 = 0x3b,
                   9314:     JALX32 = 0x3c,
                   9315:     JAL32 = 0x3d,
                   9316:     SW32 = 0x3e,
                   9317:     LW32 = 0x3f
                   9318: };
                   9319: 
                   9320: /* POOL32A encoding of minor opcode field */
                   9321: 
                   9322: enum {
                   9323:     /* These opcodes are distinguished only by bits 9..6; those bits are
                   9324:      * what are recorded below. */
                   9325:     SLL32 = 0x0,
                   9326:     SRL32 = 0x1,
                   9327:     SRA = 0x2,
                   9328:     ROTR = 0x3,
                   9329: 
                   9330:     SLLV = 0x0,
                   9331:     SRLV = 0x1,
                   9332:     SRAV = 0x2,
                   9333:     ROTRV = 0x3,
                   9334:     ADD = 0x4,
                   9335:     ADDU32 = 0x5,
                   9336:     SUB = 0x6,
                   9337:     SUBU32 = 0x7,
                   9338:     MUL = 0x8,
                   9339:     AND = 0x9,
                   9340:     OR32 = 0xa,
                   9341:     NOR = 0xb,
                   9342:     XOR32 = 0xc,
                   9343:     SLT = 0xd,
                   9344:     SLTU = 0xe,
                   9345: 
                   9346:     MOVN = 0x0,
                   9347:     MOVZ = 0x1,
                   9348:     LWXS = 0x4,
                   9349: 
                   9350:     /* The following can be distinguished by their lower 6 bits. */
                   9351:     INS = 0x0c,
                   9352:     EXT = 0x2c,
                   9353:     POOL32AXF = 0x3c
                   9354: };
                   9355: 
                   9356: /* POOL32AXF encoding of minor opcode field extension */
                   9357: 
                   9358: enum {
                   9359:     /* bits 11..6 */
                   9360:     TEQ = 0x00,
                   9361:     TGE = 0x08,
                   9362:     TGEU = 0x10,
                   9363:     TLT = 0x20,
                   9364:     TLTU = 0x28,
                   9365:     TNE = 0x30,
                   9366: 
                   9367:     MFC0 = 0x03,
                   9368:     MTC0 = 0x0b,
                   9369: 
                   9370:     /* bits 13..12 for 0x01 */
                   9371:     MFHI_ACC = 0x0,
                   9372:     MFLO_ACC = 0x1,
                   9373:     MTHI_ACC = 0x2,
                   9374:     MTLO_ACC = 0x3,
                   9375: 
                   9376:     /* bits 13..12 for 0x2a */
                   9377:     MADD_ACC = 0x0,
                   9378:     MADDU_ACC = 0x1,
                   9379:     MSUB_ACC = 0x2,
                   9380:     MSUBU_ACC = 0x3,
                   9381: 
                   9382:     /* bits 13..12 for 0x32 */
                   9383:     MULT_ACC = 0x0,
                   9384:     MULTU_ACC = 0x0,
                   9385: 
                   9386:     /* bits 15..12 for 0x2c */
                   9387:     SEB = 0x2,
                   9388:     SEH = 0x3,
                   9389:     CLO = 0x4,
                   9390:     CLZ = 0x5,
                   9391:     RDHWR = 0x6,
                   9392:     WSBH = 0x7,
                   9393:     MULT = 0x8,
                   9394:     MULTU = 0x9,
                   9395:     DIV = 0xa,
                   9396:     DIVU = 0xb,
                   9397:     MADD = 0xc,
                   9398:     MADDU = 0xd,
                   9399:     MSUB = 0xe,
                   9400:     MSUBU = 0xf,
                   9401: 
                   9402:     /* bits 15..12 for 0x34 */
                   9403:     MFC2 = 0x4,
                   9404:     MTC2 = 0x5,
                   9405:     MFHC2 = 0x8,
                   9406:     MTHC2 = 0x9,
                   9407:     CFC2 = 0xc,
                   9408:     CTC2 = 0xd,
                   9409: 
                   9410:     /* bits 15..12 for 0x3c */
                   9411:     JALR = 0x0,
                   9412:     JR = 0x0,                   /* alias */
                   9413:     JALR_HB = 0x1,
                   9414:     JALRS = 0x4,
                   9415:     JALRS_HB = 0x5,
                   9416: 
                   9417:     /* bits 15..12 for 0x05 */
                   9418:     RDPGPR = 0xe,
                   9419:     WRPGPR = 0xf,
                   9420: 
                   9421:     /* bits 15..12 for 0x0d */
                   9422:     TLBP = 0x0,
                   9423:     TLBR = 0x1,
                   9424:     TLBWI = 0x2,
                   9425:     TLBWR = 0x3,
                   9426:     WAIT = 0x9,
                   9427:     IRET = 0xd,
                   9428:     DERET = 0xe,
                   9429:     ERET = 0xf,
                   9430: 
                   9431:     /* bits 15..12 for 0x15 */
                   9432:     DMT = 0x0,
                   9433:     DVPE = 0x1,
                   9434:     EMT = 0x2,
                   9435:     EVPE = 0x3,
                   9436: 
                   9437:     /* bits 15..12 for 0x1d */
                   9438:     DI = 0x4,
                   9439:     EI = 0x5,
                   9440: 
                   9441:     /* bits 15..12 for 0x2d */
                   9442:     SYNC = 0x6,
                   9443:     SYSCALL = 0x8,
                   9444:     SDBBP = 0xd,
                   9445: 
                   9446:     /* bits 15..12 for 0x35 */
                   9447:     MFHI32 = 0x0,
                   9448:     MFLO32 = 0x1,
                   9449:     MTHI32 = 0x2,
                   9450:     MTLO32 = 0x3,
                   9451: };
                   9452: 
                   9453: /* POOL32B encoding of minor opcode field (bits 15..12) */
                   9454: 
                   9455: enum {
                   9456:     LWC2 = 0x0,
                   9457:     LWP = 0x1,
                   9458:     LDP = 0x4,
                   9459:     LWM32 = 0x5,
                   9460:     CACHE = 0x6,
                   9461:     LDM = 0x7,
                   9462:     SWC2 = 0x8,
                   9463:     SWP = 0x9,
                   9464:     SDP = 0xc,
                   9465:     SWM32 = 0xd,
                   9466:     SDM = 0xf
                   9467: };
                   9468: 
                   9469: /* POOL32C encoding of minor opcode field (bits 15..12) */
                   9470: 
                   9471: enum {
                   9472:     LWL = 0x0,
                   9473:     SWL = 0x8,
                   9474:     LWR = 0x1,
                   9475:     SWR = 0x9,
                   9476:     PREF = 0x2,
                   9477:     /* 0xa is reserved */
                   9478:     LL = 0x3,
                   9479:     SC = 0xb,
                   9480:     LDL = 0x4,
                   9481:     SDL = 0xc,
                   9482:     LDR = 0x5,
                   9483:     SDR = 0xd,
                   9484:     /* 0x6 is reserved */
                   9485:     LWU = 0xe,
                   9486:     LLD = 0x7,
                   9487:     SCD = 0xf
                   9488: };
                   9489: 
                   9490: /* POOL32F encoding of minor opcode field (bits 5..0) */
                   9491: 
                   9492: enum {
                   9493:     /* These are the bit 7..6 values */
                   9494:     ADD_FMT = 0x0,
                   9495:     MOVN_FMT = 0x0,
                   9496: 
                   9497:     SUB_FMT = 0x1,
                   9498:     MOVZ_FMT = 0x1,
                   9499: 
                   9500:     MUL_FMT = 0x2,
                   9501: 
                   9502:     DIV_FMT = 0x3,
                   9503: 
                   9504:     /* These are the bit 8..6 values */
                   9505:     RSQRT2_FMT = 0x0,
                   9506:     MOVF_FMT = 0x0,
                   9507: 
                   9508:     LWXC1 = 0x1,
                   9509:     MOVT_FMT = 0x1,
                   9510: 
                   9511:     PLL_PS = 0x2,
                   9512:     SWXC1 = 0x2,
                   9513: 
                   9514:     PLU_PS = 0x3,
                   9515:     LDXC1 = 0x3,
                   9516: 
                   9517:     PUL_PS = 0x4,
                   9518:     SDXC1 = 0x4,
                   9519:     RECIP2_FMT = 0x4,
                   9520: 
                   9521:     PUU_PS = 0x5,
                   9522:     LUXC1 = 0x5,
                   9523: 
                   9524:     CVT_PS_S = 0x6,
                   9525:     SUXC1 = 0x6,
                   9526:     ADDR_PS = 0x6,
                   9527:     PREFX = 0x6,
                   9528: 
                   9529:     MULR_PS = 0x7,
                   9530: 
                   9531:     MADD_S = 0x01,
                   9532:     MADD_D = 0x09,
                   9533:     MADD_PS = 0x11,
                   9534:     ALNV_PS = 0x19,
                   9535:     MSUB_S = 0x21,
                   9536:     MSUB_D = 0x29,
                   9537:     MSUB_PS = 0x31,
                   9538: 
                   9539:     NMADD_S = 0x02,
                   9540:     NMADD_D = 0x0a,
                   9541:     NMADD_PS = 0x12,
                   9542:     NMSUB_S = 0x22,
                   9543:     NMSUB_D = 0x2a,
                   9544:     NMSUB_PS = 0x32,
                   9545: 
                   9546:     POOL32FXF = 0x3b,
                   9547: 
                   9548:     CABS_COND_FMT = 0x1c,              /* MIPS3D */
                   9549:     C_COND_FMT = 0x3c
                   9550: };
                   9551: 
                   9552: /* POOL32Fxf encoding of minor opcode extension field */
                   9553: 
                   9554: enum {
                   9555:     CVT_L = 0x04,
                   9556:     RSQRT_FMT = 0x08,
                   9557:     FLOOR_L = 0x0c,
                   9558:     CVT_PW_PS = 0x1c,
                   9559:     CVT_W = 0x24,
                   9560:     SQRT_FMT = 0x28,
                   9561:     FLOOR_W = 0x2c,
                   9562:     CVT_PS_PW = 0x3c,
                   9563:     CFC1 = 0x40,
                   9564:     RECIP_FMT = 0x48,
                   9565:     CEIL_L = 0x4c,
                   9566:     CTC1 = 0x60,
                   9567:     CEIL_W = 0x6c,
                   9568:     MFC1 = 0x80,
                   9569:     CVT_S_PL = 0x84,
                   9570:     TRUNC_L = 0x8c,
                   9571:     MTC1 = 0xa0,
                   9572:     CVT_S_PU = 0xa4,
                   9573:     TRUNC_W = 0xac,
                   9574:     MFHC1 = 0xc0,
                   9575:     ROUND_L = 0xcc,
                   9576:     MTHC1 = 0xe0,
                   9577:     ROUND_W = 0xec,
                   9578: 
                   9579:     MOV_FMT = 0x01,
                   9580:     MOVF = 0x05,
                   9581:     ABS_FMT = 0x0d,
                   9582:     RSQRT1_FMT = 0x1d,
                   9583:     MOVT = 0x25,
                   9584:     NEG_FMT = 0x2d,
                   9585:     CVT_D = 0x4d,
                   9586:     RECIP1_FMT = 0x5d,
                   9587:     CVT_S = 0x6d
                   9588: };
                   9589: 
                   9590: /* POOL32I encoding of minor opcode field (bits 25..21) */
                   9591: 
                   9592: enum {
                   9593:     BLTZ = 0x00,
                   9594:     BLTZAL = 0x01,
                   9595:     BGEZ = 0x02,
                   9596:     BGEZAL = 0x03,
                   9597:     BLEZ = 0x04,
                   9598:     BNEZC = 0x05,
                   9599:     BGTZ = 0x06,
                   9600:     BEQZC = 0x07,
                   9601:     TLTI = 0x08,
                   9602:     TGEI = 0x09,
                   9603:     TLTIU = 0x0a,
                   9604:     TGEIU = 0x0b,
                   9605:     TNEI = 0x0c,
                   9606:     LUI = 0x0d,
                   9607:     TEQI = 0x0e,
                   9608:     SYNCI = 0x10,
                   9609:     BLTZALS = 0x11,
                   9610:     BGEZALS = 0x13,
                   9611:     BC2F = 0x14,
                   9612:     BC2T = 0x15,
                   9613:     BPOSGE64 = 0x1a,
                   9614:     BPOSGE32 = 0x1b,
                   9615:     /* These overlap and are distinguished by bit16 of the instruction */
                   9616:     BC1F = 0x1c,
                   9617:     BC1T = 0x1d,
                   9618:     BC1ANY2F = 0x1c,
                   9619:     BC1ANY2T = 0x1d,
                   9620:     BC1ANY4F = 0x1e,
                   9621:     BC1ANY4T = 0x1f
                   9622: };
                   9623: 
                   9624: /* POOL16A encoding of minor opcode field */
                   9625: 
                   9626: enum {
                   9627:     ADDU16 = 0x0,
                   9628:     SUBU16 = 0x1
                   9629: };
                   9630: 
                   9631: /* POOL16B encoding of minor opcode field */
                   9632: 
                   9633: enum {
                   9634:     SLL16 = 0x0,
                   9635:     SRL16 = 0x1
                   9636: };
                   9637: 
                   9638: /* POOL16C encoding of minor opcode field */
                   9639: 
                   9640: enum {
                   9641:     NOT16 = 0x00,
                   9642:     XOR16 = 0x04,
                   9643:     AND16 = 0x08,
                   9644:     OR16 = 0x0c,
                   9645:     LWM16 = 0x10,
                   9646:     SWM16 = 0x14,
                   9647:     JR16 = 0x18,
                   9648:     JRC16 = 0x1a,
                   9649:     JALR16 = 0x1c,
                   9650:     JALR16S = 0x1e,
                   9651:     MFHI16 = 0x20,
                   9652:     MFLO16 = 0x24,
                   9653:     BREAK16 = 0x28,
                   9654:     SDBBP16 = 0x2c,
                   9655:     JRADDIUSP = 0x30
                   9656: };
                   9657: 
                   9658: /* POOL16D encoding of minor opcode field */
                   9659: 
                   9660: enum {
                   9661:     ADDIUS5 = 0x0,
                   9662:     ADDIUSP = 0x1
                   9663: };
                   9664: 
                   9665: /* POOL16E encoding of minor opcode field */
                   9666: 
                   9667: enum {
                   9668:     ADDIUR2 = 0x0,
                   9669:     ADDIUR1SP = 0x1
                   9670: };
                   9671: 
                   9672: static int mmreg (int r)
                   9673: {
                   9674:     static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
                   9675: 
                   9676:     return map[r];
                   9677: }
                   9678: 
                   9679: /* Used for 16-bit store instructions.  */
                   9680: static int mmreg2 (int r)
                   9681: {
                   9682:     static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
                   9683: 
                   9684:     return map[r];
                   9685: }
                   9686: 
                   9687: #define uMIPS_RD(op) ((op >> 7) & 0x7)
                   9688: #define uMIPS_RS(op) ((op >> 4) & 0x7)
                   9689: #define uMIPS_RS2(op) uMIPS_RS(op)
                   9690: #define uMIPS_RS1(op) ((op >> 1) & 0x7)
                   9691: #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
                   9692: #define uMIPS_RS5(op) (op & 0x1f)
                   9693: 
                   9694: /* Signed immediate */
                   9695: #define SIMM(op, start, width)                                          \
                   9696:     ((int32_t)(((op >> start) & ((~0U) >> (32-width)))                 \
                   9697:                << (32-width))                                           \
                   9698:      >> (32-width))
                   9699: /* Zero-extended immediate */
                   9700: #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
                   9701: 
                   9702: static void gen_addiur1sp (CPUState *env, DisasContext *ctx)
                   9703: {
                   9704:     int rd = mmreg(uMIPS_RD(ctx->opcode));
                   9705: 
                   9706:     gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
                   9707: }
                   9708: 
                   9709: static void gen_addiur2 (CPUState *env, DisasContext *ctx)
                   9710: {
                   9711:     static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
                   9712:     int rd = mmreg(uMIPS_RD(ctx->opcode));
                   9713:     int rs = mmreg(uMIPS_RS(ctx->opcode));
                   9714: 
                   9715:     gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
                   9716: }
                   9717: 
                   9718: static void gen_addiusp (CPUState *env, DisasContext *ctx)
                   9719: {
                   9720:     int encoded = ZIMM(ctx->opcode, 1, 9);
                   9721:     int decoded;
                   9722: 
                   9723:     if (encoded <= 1) {
                   9724:         decoded = 256 + encoded;
                   9725:     } else if (encoded <= 255) {
                   9726:         decoded = encoded;
                   9727:     } else if (encoded <= 509) {
                   9728:         decoded = encoded - 512;
                   9729:     } else {
                   9730:         decoded = encoded - 768;
                   9731:     }
                   9732: 
                   9733:     gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
                   9734: }
                   9735: 
                   9736: static void gen_addius5 (CPUState *env, DisasContext *ctx)
                   9737: {
                   9738:     int imm = SIMM(ctx->opcode, 1, 4);
                   9739:     int rd = (ctx->opcode >> 5) & 0x1f;
                   9740: 
                   9741:     gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
                   9742: }
                   9743: 
                   9744: static void gen_andi16 (CPUState *env, DisasContext *ctx)
                   9745: {
                   9746:     static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
                   9747:                                  31, 32, 63, 64, 255, 32768, 65535 };
                   9748:     int rd = mmreg(uMIPS_RD(ctx->opcode));
                   9749:     int rs = mmreg(uMIPS_RS(ctx->opcode));
                   9750:     int encoded = ZIMM(ctx->opcode, 0, 4);
                   9751: 
                   9752:     gen_logic_imm(env, OPC_ANDI, rd, rs, decoded_imm[encoded]);
                   9753: }
                   9754: 
                   9755: static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
                   9756:                                int base, int16_t offset)
                   9757: {
                   9758:     TCGv t0, t1;
                   9759:     TCGv_i32 t2;
                   9760: 
                   9761:     if (ctx->hflags & MIPS_HFLAG_BMASK) {
                   9762:         generate_exception(ctx, EXCP_RI);
                   9763:         return;
                   9764:     }
                   9765: 
                   9766:     t0 = tcg_temp_new();
                   9767: 
                   9768:     gen_base_offset_addr(ctx, t0, base, offset);
                   9769: 
                   9770:     t1 = tcg_const_tl(reglist);
                   9771:     t2 = tcg_const_i32(ctx->mem_idx);
                   9772: 
                   9773:     save_cpu_state(ctx, 1);
                   9774:     switch (opc) {
                   9775:     case LWM32:
                   9776:         gen_helper_lwm(t0, t1, t2);
                   9777:         break;
                   9778:     case SWM32:
                   9779:         gen_helper_swm(t0, t1, t2);
                   9780:         break;
                   9781: #ifdef TARGET_MIPS64
                   9782:     case LDM:
                   9783:         gen_helper_ldm(t0, t1, t2);
                   9784:         break;
                   9785:     case SDM:
                   9786:         gen_helper_sdm(t0, t1, t2);
                   9787:         break;
                   9788: #endif
                   9789:     }
                   9790:     MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
                   9791:     tcg_temp_free(t0);
                   9792:     tcg_temp_free(t1);
                   9793:     tcg_temp_free_i32(t2);
                   9794: }
                   9795: 
                   9796: 
                   9797: static void gen_pool16c_insn (CPUState *env, DisasContext *ctx, int *is_branch)
                   9798: {
                   9799:     int rd = mmreg((ctx->opcode >> 3) & 0x7);
                   9800:     int rs = mmreg(ctx->opcode & 0x7);
                   9801:     int opc;
                   9802: 
                   9803:     switch (((ctx->opcode) >> 4) & 0x3f) {
                   9804:     case NOT16 + 0:
                   9805:     case NOT16 + 1:
                   9806:     case NOT16 + 2:
                   9807:     case NOT16 + 3:
                   9808:         gen_logic(env, OPC_NOR, rd, rs, 0);
                   9809:         break;
                   9810:     case XOR16 + 0:
                   9811:     case XOR16 + 1:
                   9812:     case XOR16 + 2:
                   9813:     case XOR16 + 3:
                   9814:         gen_logic(env, OPC_XOR, rd, rd, rs);
                   9815:         break;
                   9816:     case AND16 + 0:
                   9817:     case AND16 + 1:
                   9818:     case AND16 + 2:
                   9819:     case AND16 + 3:
                   9820:         gen_logic(env, OPC_AND, rd, rd, rs);
                   9821:         break;
                   9822:     case OR16 + 0:
                   9823:     case OR16 + 1:
                   9824:     case OR16 + 2:
                   9825:     case OR16 + 3:
                   9826:         gen_logic(env, OPC_OR, rd, rd, rs);
                   9827:         break;
                   9828:     case LWM16 + 0:
                   9829:     case LWM16 + 1:
                   9830:     case LWM16 + 2:
                   9831:     case LWM16 + 3:
                   9832:         {
                   9833:             static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
                   9834:             int offset = ZIMM(ctx->opcode, 0, 4);
                   9835: 
                   9836:             gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
                   9837:                               29, offset << 2);
                   9838:         }
                   9839:         break;
                   9840:     case SWM16 + 0:
                   9841:     case SWM16 + 1:
                   9842:     case SWM16 + 2:
                   9843:     case SWM16 + 3:
                   9844:         {
                   9845:             static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
                   9846:             int offset = ZIMM(ctx->opcode, 0, 4);
                   9847: 
                   9848:             gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
                   9849:                               29, offset << 2);
                   9850:         }
                   9851:         break;
                   9852:     case JR16 + 0:
                   9853:     case JR16 + 1:
                   9854:         {
                   9855:             int reg = ctx->opcode & 0x1f;
                   9856: 
                   9857:             gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
                   9858:         }
                   9859:         *is_branch = 1;
                   9860:         break;
                   9861:     case JRC16 + 0:
                   9862:     case JRC16 + 1:
                   9863:         {
                   9864:             int reg = ctx->opcode & 0x1f;
                   9865: 
                   9866:             gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
                   9867:             /* Let normal delay slot handling in our caller take us
                   9868:                to the branch target.  */
                   9869:         }
                   9870:         break;
                   9871:     case JALR16 + 0:
                   9872:     case JALR16 + 1:
                   9873:         opc = OPC_JALR;
                   9874:         goto do_jalr;
                   9875:     case JALR16S + 0:
                   9876:     case JALR16S + 1:
                   9877:         opc = OPC_JALRS;
                   9878:     do_jalr:
                   9879:         {
                   9880:             int reg = ctx->opcode & 0x1f;
                   9881: 
                   9882:             gen_compute_branch(ctx, opc, 2, reg, 31, 0);
                   9883:         }
                   9884:         *is_branch = 1;
                   9885:         break;
                   9886:     case MFHI16 + 0:
                   9887:     case MFHI16 + 1:
                   9888:         gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
                   9889:         break;
                   9890:     case MFLO16 + 0:
                   9891:     case MFLO16 + 1:
                   9892:         gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
                   9893:         break;
                   9894:     case BREAK16:
                   9895:         generate_exception(ctx, EXCP_BREAK);
                   9896:         break;
                   9897:     case SDBBP16:
                   9898:         /* XXX: not clear which exception should be raised
                   9899:          *      when in debug mode...
                   9900:          */
                   9901:         check_insn(env, ctx, ISA_MIPS32);
                   9902:         if (!(ctx->hflags & MIPS_HFLAG_DM)) {
                   9903:             generate_exception(ctx, EXCP_DBp);
                   9904:         } else {
                   9905:             generate_exception(ctx, EXCP_DBp);
                   9906:         }
                   9907:         break;
                   9908:     case JRADDIUSP + 0:
                   9909:     case JRADDIUSP + 1:
                   9910:         {
                   9911:             int imm = ZIMM(ctx->opcode, 0, 5);
                   9912: 
                   9913:             gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
                   9914:             gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
                   9915:             /* Let normal delay slot handling in our caller take us
                   9916:                to the branch target.  */
                   9917:         }
                   9918:         break;
                   9919:     default:
                   9920:         generate_exception(ctx, EXCP_RI);
                   9921:         break;
                   9922:     }
                   9923: }
                   9924: 
                   9925: static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
                   9926: {
                   9927:     TCGv t0 = tcg_temp_new();
                   9928:     TCGv t1 = tcg_temp_new();
                   9929: 
                   9930:     gen_load_gpr(t0, base);
                   9931: 
                   9932:     if (index != 0) {
                   9933:         gen_load_gpr(t1, index);
                   9934:         tcg_gen_shli_tl(t1, t1, 2);
                   9935:         gen_op_addr_add(ctx, t0, t1, t0);
                   9936:     }
                   9937: 
                   9938:     save_cpu_state(ctx, 0);
                   9939:     op_ld_lw(t1, t0, ctx);
                   9940:     gen_store_gpr(t1, rd);
                   9941: 
                   9942:     tcg_temp_free(t0);
                   9943:     tcg_temp_free(t1);
                   9944: }
                   9945: 
                   9946: static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
                   9947:                            int base, int16_t offset)
                   9948: {
                   9949:     const char *opn = "ldst_pair";
                   9950:     TCGv t0, t1;
                   9951: 
                   9952:     if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31 || rd == base) {
                   9953:         generate_exception(ctx, EXCP_RI);
                   9954:         return;
                   9955:     }
                   9956: 
                   9957:     t0 = tcg_temp_new();
                   9958:     t1 = tcg_temp_new();
                   9959: 
                   9960:     gen_base_offset_addr(ctx, t0, base, offset);
                   9961: 
                   9962:     switch (opc) {
                   9963:     case LWP:
                   9964:         save_cpu_state(ctx, 0);
                   9965:         op_ld_lw(t1, t0, ctx);
                   9966:         gen_store_gpr(t1, rd);
                   9967:         tcg_gen_movi_tl(t1, 4);
                   9968:         gen_op_addr_add(ctx, t0, t0, t1);
                   9969:         op_ld_lw(t1, t0, ctx);
                   9970:         gen_store_gpr(t1, rd+1);
                   9971:         opn = "lwp";
                   9972:         break;
                   9973:     case SWP:
1.1.1.13! root     9974:         save_cpu_state(ctx, 0);
1.1.1.12  root     9975:         gen_load_gpr(t1, rd);
                   9976:         op_st_sw(t1, t0, ctx);
                   9977:         tcg_gen_movi_tl(t1, 4);
                   9978:         gen_op_addr_add(ctx, t0, t0, t1);
                   9979:         gen_load_gpr(t1, rd+1);
                   9980:         op_st_sw(t1, t0, ctx);
                   9981:         opn = "swp";
                   9982:         break;
                   9983: #ifdef TARGET_MIPS64
                   9984:     case LDP:
                   9985:         save_cpu_state(ctx, 0);
                   9986:         op_ld_ld(t1, t0, ctx);
                   9987:         gen_store_gpr(t1, rd);
                   9988:         tcg_gen_movi_tl(t1, 8);
                   9989:         gen_op_addr_add(ctx, t0, t0, t1);
                   9990:         op_ld_ld(t1, t0, ctx);
                   9991:         gen_store_gpr(t1, rd+1);
                   9992:         opn = "ldp";
                   9993:         break;
                   9994:     case SDP:
1.1.1.13! root     9995:         save_cpu_state(ctx, 0);
1.1.1.12  root     9996:         gen_load_gpr(t1, rd);
                   9997:         op_st_sd(t1, t0, ctx);
                   9998:         tcg_gen_movi_tl(t1, 8);
                   9999:         gen_op_addr_add(ctx, t0, t0, t1);
                   10000:         gen_load_gpr(t1, rd+1);
                   10001:         op_st_sd(t1, t0, ctx);
                   10002:         opn = "sdp";
                   10003:         break;
                   10004: #endif
                   10005:     }
1.1.1.13! root     10006:     (void)opn; /* avoid a compiler warning */
1.1.1.12  root     10007:     MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
                   10008:     tcg_temp_free(t0);
                   10009:     tcg_temp_free(t1);
                   10010: }
                   10011: 
                   10012: static void gen_pool32axf (CPUState *env, DisasContext *ctx, int rt, int rs,
                   10013:                            int *is_branch)
                   10014: {
                   10015:     int extension = (ctx->opcode >> 6) & 0x3f;
                   10016:     int minor = (ctx->opcode >> 12) & 0xf;
                   10017:     uint32_t mips32_op;
                   10018: 
                   10019:     switch (extension) {
                   10020:     case TEQ:
                   10021:         mips32_op = OPC_TEQ;
                   10022:         goto do_trap;
                   10023:     case TGE:
                   10024:         mips32_op = OPC_TGE;
                   10025:         goto do_trap;
                   10026:     case TGEU:
                   10027:         mips32_op = OPC_TGEU;
                   10028:         goto do_trap;
                   10029:     case TLT:
                   10030:         mips32_op = OPC_TLT;
                   10031:         goto do_trap;
                   10032:     case TLTU:
                   10033:         mips32_op = OPC_TLTU;
                   10034:         goto do_trap;
                   10035:     case TNE:
                   10036:         mips32_op = OPC_TNE;
                   10037:     do_trap:
                   10038:         gen_trap(ctx, mips32_op, rs, rt, -1);
                   10039:         break;
                   10040: #ifndef CONFIG_USER_ONLY
                   10041:     case MFC0:
                   10042:     case MFC0 + 32:
                   10043:         if (rt == 0) {
                   10044:             /* Treat as NOP. */
                   10045:             break;
                   10046:         }
                   10047:         gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
                   10048:         break;
                   10049:     case MTC0:
                   10050:     case MTC0 + 32:
                   10051:         {
                   10052:             TCGv t0 = tcg_temp_new();
                   10053: 
                   10054:             gen_load_gpr(t0, rt);
                   10055:             gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
                   10056:             tcg_temp_free(t0);
                   10057:         }
                   10058:         break;
                   10059: #endif
                   10060:     case 0x2c:
                   10061:         switch (minor) {
                   10062:         case SEB:
                   10063:             gen_bshfl(ctx, OPC_SEB, rs, rt);
                   10064:             break;
                   10065:         case SEH:
                   10066:             gen_bshfl(ctx, OPC_SEH, rs, rt);
                   10067:             break;
                   10068:         case CLO:
                   10069:             mips32_op = OPC_CLO;
                   10070:             goto do_cl;
                   10071:         case CLZ:
                   10072:             mips32_op = OPC_CLZ;
                   10073:         do_cl:
                   10074:             check_insn(env, ctx, ISA_MIPS32);
                   10075:             gen_cl(ctx, mips32_op, rt, rs);
                   10076:             break;
                   10077:         case RDHWR:
                   10078:             gen_rdhwr(env, ctx, rt, rs);
                   10079:             break;
                   10080:         case WSBH:
                   10081:             gen_bshfl(ctx, OPC_WSBH, rs, rt);
                   10082:             break;
                   10083:         case MULT:
                   10084:             mips32_op = OPC_MULT;
                   10085:             goto do_muldiv;
                   10086:         case MULTU:
                   10087:             mips32_op = OPC_MULTU;
                   10088:             goto do_muldiv;
                   10089:         case DIV:
                   10090:             mips32_op = OPC_DIV;
                   10091:             goto do_muldiv;
                   10092:         case DIVU:
                   10093:             mips32_op = OPC_DIVU;
                   10094:             goto do_muldiv;
                   10095:         case MADD:
                   10096:             mips32_op = OPC_MADD;
                   10097:             goto do_muldiv;
                   10098:         case MADDU:
                   10099:             mips32_op = OPC_MADDU;
                   10100:             goto do_muldiv;
                   10101:         case MSUB:
                   10102:             mips32_op = OPC_MSUB;
                   10103:             goto do_muldiv;
                   10104:         case MSUBU:
                   10105:             mips32_op = OPC_MSUBU;
                   10106:         do_muldiv:
                   10107:             check_insn(env, ctx, ISA_MIPS32);
                   10108:             gen_muldiv(ctx, mips32_op, rs, rt);
                   10109:             break;
                   10110:         default:
                   10111:             goto pool32axf_invalid;
                   10112:         }
                   10113:         break;
                   10114:     case 0x34:
                   10115:         switch (minor) {
                   10116:         case MFC2:
                   10117:         case MTC2:
                   10118:         case MFHC2:
                   10119:         case MTHC2:
                   10120:         case CFC2:
                   10121:         case CTC2:
                   10122:             generate_exception_err(ctx, EXCP_CpU, 2);
                   10123:             break;
                   10124:         default:
                   10125:             goto pool32axf_invalid;
                   10126:         }
                   10127:         break;
                   10128:     case 0x3c:
                   10129:         switch (minor) {
                   10130:         case JALR:
                   10131:         case JALR_HB:
                   10132:             gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
                   10133:             *is_branch = 1;
                   10134:             break;
                   10135:         case JALRS:
                   10136:         case JALRS_HB:
                   10137:             gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
                   10138:             *is_branch = 1;
                   10139:             break;
                   10140:         default:
                   10141:             goto pool32axf_invalid;
                   10142:         }
                   10143:         break;
                   10144:     case 0x05:
                   10145:         switch (minor) {
                   10146:         case RDPGPR:
                   10147:             check_insn(env, ctx, ISA_MIPS32R2);
                   10148:             gen_load_srsgpr(rt, rs);
                   10149:             break;
                   10150:         case WRPGPR:
                   10151:             check_insn(env, ctx, ISA_MIPS32R2);
                   10152:             gen_store_srsgpr(rt, rs);
                   10153:             break;
                   10154:         default:
                   10155:             goto pool32axf_invalid;
                   10156:         }
                   10157:         break;
                   10158: #ifndef CONFIG_USER_ONLY
                   10159:     case 0x0d:
                   10160:         switch (minor) {
                   10161:         case TLBP:
                   10162:             mips32_op = OPC_TLBP;
                   10163:             goto do_cp0;
                   10164:         case TLBR:
                   10165:             mips32_op = OPC_TLBR;
                   10166:             goto do_cp0;
                   10167:         case TLBWI:
                   10168:             mips32_op = OPC_TLBWI;
                   10169:             goto do_cp0;
                   10170:         case TLBWR:
                   10171:             mips32_op = OPC_TLBWR;
                   10172:             goto do_cp0;
                   10173:         case WAIT:
                   10174:             mips32_op = OPC_WAIT;
                   10175:             goto do_cp0;
                   10176:         case DERET:
                   10177:             mips32_op = OPC_DERET;
                   10178:             goto do_cp0;
                   10179:         case ERET:
                   10180:             mips32_op = OPC_ERET;
                   10181:         do_cp0:
                   10182:             gen_cp0(env, ctx, mips32_op, rt, rs);
                   10183:             break;
                   10184:         default:
                   10185:             goto pool32axf_invalid;
                   10186:         }
                   10187:         break;
                   10188:     case 0x1d:
                   10189:         switch (minor) {
                   10190:         case DI:
                   10191:             {
                   10192:                 TCGv t0 = tcg_temp_new();
                   10193: 
                   10194:                 save_cpu_state(ctx, 1);
                   10195:                 gen_helper_di(t0);
                   10196:                 gen_store_gpr(t0, rs);
                   10197:                 /* Stop translation as we may have switched the execution mode */
                   10198:                 ctx->bstate = BS_STOP;
                   10199:                 tcg_temp_free(t0);
                   10200:             }
                   10201:             break;
                   10202:         case EI:
                   10203:             {
                   10204:                 TCGv t0 = tcg_temp_new();
                   10205: 
                   10206:                 save_cpu_state(ctx, 1);
                   10207:                 gen_helper_ei(t0);
                   10208:                 gen_store_gpr(t0, rs);
                   10209:                 /* Stop translation as we may have switched the execution mode */
                   10210:                 ctx->bstate = BS_STOP;
                   10211:                 tcg_temp_free(t0);
                   10212:             }
                   10213:             break;
                   10214:         default:
                   10215:             goto pool32axf_invalid;
                   10216:         }
                   10217:         break;
                   10218: #endif
                   10219:     case 0x2d:
                   10220:         switch (minor) {
                   10221:         case SYNC:
                   10222:             /* NOP */
                   10223:             break;
                   10224:         case SYSCALL:
                   10225:             generate_exception(ctx, EXCP_SYSCALL);
                   10226:             ctx->bstate = BS_STOP;
                   10227:             break;
                   10228:         case SDBBP:
                   10229:             check_insn(env, ctx, ISA_MIPS32);
                   10230:             if (!(ctx->hflags & MIPS_HFLAG_DM)) {
                   10231:                 generate_exception(ctx, EXCP_DBp);
                   10232:             } else {
                   10233:                 generate_exception(ctx, EXCP_DBp);
                   10234:             }
                   10235:             break;
                   10236:         default:
                   10237:             goto pool32axf_invalid;
                   10238:         }
                   10239:         break;
                   10240:     case 0x35:
                   10241:         switch (minor) {
                   10242:         case MFHI32:
                   10243:             gen_HILO(ctx, OPC_MFHI, rs);
                   10244:             break;
                   10245:         case MFLO32:
                   10246:             gen_HILO(ctx, OPC_MFLO, rs);
                   10247:             break;
                   10248:         case MTHI32:
                   10249:             gen_HILO(ctx, OPC_MTHI, rs);
                   10250:             break;
                   10251:         case MTLO32:
                   10252:             gen_HILO(ctx, OPC_MTLO, rs);
                   10253:             break;
                   10254:         default:
                   10255:             goto pool32axf_invalid;
                   10256:         }
                   10257:         break;
                   10258:     default:
                   10259:     pool32axf_invalid:
                   10260:         MIPS_INVAL("pool32axf");
                   10261:         generate_exception(ctx, EXCP_RI);
                   10262:         break;
                   10263:     }
                   10264: }
                   10265: 
                   10266: /* Values for microMIPS fmt field.  Variable-width, depending on which
                   10267:    formats the instruction supports.  */
                   10268: 
                   10269: enum {
                   10270:     FMT_SD_S = 0,
                   10271:     FMT_SD_D = 1,
                   10272: 
                   10273:     FMT_SDPS_S = 0,
                   10274:     FMT_SDPS_D = 1,
                   10275:     FMT_SDPS_PS = 2,
                   10276: 
                   10277:     FMT_SWL_S = 0,
                   10278:     FMT_SWL_W = 1,
                   10279:     FMT_SWL_L = 2,
                   10280: 
                   10281:     FMT_DWL_D = 0,
                   10282:     FMT_DWL_W = 1,
                   10283:     FMT_DWL_L = 2
                   10284: };
                   10285: 
                   10286: static void gen_pool32fxf (CPUState *env, DisasContext *ctx, int rt, int rs)
                   10287: {
                   10288:     int extension = (ctx->opcode >> 6) & 0x3ff;
                   10289:     uint32_t mips32_op;
                   10290: 
                   10291: #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
                   10292: #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
                   10293: #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
                   10294: 
                   10295:     switch (extension) {
                   10296:     case FLOAT_1BIT_FMT(CFC1, 0):
                   10297:         mips32_op = OPC_CFC1;
                   10298:         goto do_cp1;
                   10299:     case FLOAT_1BIT_FMT(CTC1, 0):
                   10300:         mips32_op = OPC_CTC1;
                   10301:         goto do_cp1;
                   10302:     case FLOAT_1BIT_FMT(MFC1, 0):
                   10303:         mips32_op = OPC_MFC1;
                   10304:         goto do_cp1;
                   10305:     case FLOAT_1BIT_FMT(MTC1, 0):
                   10306:         mips32_op = OPC_MTC1;
                   10307:         goto do_cp1;
                   10308:     case FLOAT_1BIT_FMT(MFHC1, 0):
                   10309:         mips32_op = OPC_MFHC1;
                   10310:         goto do_cp1;
                   10311:     case FLOAT_1BIT_FMT(MTHC1, 0):
                   10312:         mips32_op = OPC_MTHC1;
                   10313:     do_cp1:
                   10314:         gen_cp1(ctx, mips32_op, rt, rs);
                   10315:         break;
                   10316: 
                   10317:         /* Reciprocal square root */
                   10318:     case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
                   10319:         mips32_op = OPC_RSQRT_S;
                   10320:         goto do_unaryfp;
                   10321:     case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
                   10322:         mips32_op = OPC_RSQRT_D;
                   10323:         goto do_unaryfp;
                   10324: 
                   10325:         /* Square root */
                   10326:     case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
                   10327:         mips32_op = OPC_SQRT_S;
                   10328:         goto do_unaryfp;
                   10329:     case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
                   10330:         mips32_op = OPC_SQRT_D;
                   10331:         goto do_unaryfp;
                   10332: 
                   10333:         /* Reciprocal */
                   10334:     case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
                   10335:         mips32_op = OPC_RECIP_S;
                   10336:         goto do_unaryfp;
                   10337:     case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
                   10338:         mips32_op = OPC_RECIP_D;
                   10339:         goto do_unaryfp;
                   10340: 
                   10341:         /* Floor */
                   10342:     case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
                   10343:         mips32_op = OPC_FLOOR_L_S;
                   10344:         goto do_unaryfp;
                   10345:     case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
                   10346:         mips32_op = OPC_FLOOR_L_D;
                   10347:         goto do_unaryfp;
                   10348:     case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
                   10349:         mips32_op = OPC_FLOOR_W_S;
                   10350:         goto do_unaryfp;
                   10351:     case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
                   10352:         mips32_op = OPC_FLOOR_W_D;
                   10353:         goto do_unaryfp;
                   10354: 
                   10355:         /* Ceiling */
                   10356:     case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
                   10357:         mips32_op = OPC_CEIL_L_S;
                   10358:         goto do_unaryfp;
                   10359:     case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
                   10360:         mips32_op = OPC_CEIL_L_D;
                   10361:         goto do_unaryfp;
                   10362:     case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
                   10363:         mips32_op = OPC_CEIL_W_S;
                   10364:         goto do_unaryfp;
                   10365:     case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
                   10366:         mips32_op = OPC_CEIL_W_D;
                   10367:         goto do_unaryfp;
                   10368: 
                   10369:         /* Truncation */
                   10370:     case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
                   10371:         mips32_op = OPC_TRUNC_L_S;
                   10372:         goto do_unaryfp;
                   10373:     case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
                   10374:         mips32_op = OPC_TRUNC_L_D;
                   10375:         goto do_unaryfp;
                   10376:     case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
                   10377:         mips32_op = OPC_TRUNC_W_S;
                   10378:         goto do_unaryfp;
                   10379:     case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
                   10380:         mips32_op = OPC_TRUNC_W_D;
                   10381:         goto do_unaryfp;
                   10382: 
                   10383:         /* Round */
                   10384:     case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
                   10385:         mips32_op = OPC_ROUND_L_S;
                   10386:         goto do_unaryfp;
                   10387:     case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
                   10388:         mips32_op = OPC_ROUND_L_D;
                   10389:         goto do_unaryfp;
                   10390:     case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
                   10391:         mips32_op = OPC_ROUND_W_S;
                   10392:         goto do_unaryfp;
                   10393:     case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
                   10394:         mips32_op = OPC_ROUND_W_D;
                   10395:         goto do_unaryfp;
                   10396: 
                   10397:         /* Integer to floating-point conversion */
                   10398:     case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
                   10399:         mips32_op = OPC_CVT_L_S;
                   10400:         goto do_unaryfp;
                   10401:     case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
                   10402:         mips32_op = OPC_CVT_L_D;
                   10403:         goto do_unaryfp;
                   10404:     case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
                   10405:         mips32_op = OPC_CVT_W_S;
                   10406:         goto do_unaryfp;
                   10407:     case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
                   10408:         mips32_op = OPC_CVT_W_D;
                   10409:         goto do_unaryfp;
                   10410: 
                   10411:         /* Paired-foo conversions */
                   10412:     case FLOAT_1BIT_FMT(CVT_S_PL, 0):
                   10413:         mips32_op = OPC_CVT_S_PL;
                   10414:         goto do_unaryfp;
                   10415:     case FLOAT_1BIT_FMT(CVT_S_PU, 0):
                   10416:         mips32_op = OPC_CVT_S_PU;
                   10417:         goto do_unaryfp;
                   10418:     case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
                   10419:         mips32_op = OPC_CVT_PW_PS;
                   10420:         goto do_unaryfp;
                   10421:     case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
                   10422:         mips32_op = OPC_CVT_PS_PW;
                   10423:         goto do_unaryfp;
                   10424: 
                   10425:         /* Floating-point moves */
                   10426:     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
                   10427:         mips32_op = OPC_MOV_S;
                   10428:         goto do_unaryfp;
                   10429:     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
                   10430:         mips32_op = OPC_MOV_D;
                   10431:         goto do_unaryfp;
                   10432:     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
                   10433:         mips32_op = OPC_MOV_PS;
                   10434:         goto do_unaryfp;
                   10435: 
                   10436:         /* Absolute value */
                   10437:     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
                   10438:         mips32_op = OPC_ABS_S;
                   10439:         goto do_unaryfp;
                   10440:     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
                   10441:         mips32_op = OPC_ABS_D;
                   10442:         goto do_unaryfp;
                   10443:     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
                   10444:         mips32_op = OPC_ABS_PS;
                   10445:         goto do_unaryfp;
                   10446: 
                   10447:         /* Negation */
                   10448:     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
                   10449:         mips32_op = OPC_NEG_S;
                   10450:         goto do_unaryfp;
                   10451:     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
                   10452:         mips32_op = OPC_NEG_D;
                   10453:         goto do_unaryfp;
                   10454:     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
                   10455:         mips32_op = OPC_NEG_PS;
                   10456:         goto do_unaryfp;
                   10457: 
                   10458:         /* Reciprocal square root step */
                   10459:     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
                   10460:         mips32_op = OPC_RSQRT1_S;
                   10461:         goto do_unaryfp;
                   10462:     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
                   10463:         mips32_op = OPC_RSQRT1_D;
                   10464:         goto do_unaryfp;
                   10465:     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
                   10466:         mips32_op = OPC_RSQRT1_PS;
                   10467:         goto do_unaryfp;
                   10468: 
                   10469:         /* Reciprocal step */
                   10470:     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
                   10471:         mips32_op = OPC_RECIP1_S;
                   10472:         goto do_unaryfp;
                   10473:     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
                   10474:         mips32_op = OPC_RECIP1_S;
                   10475:         goto do_unaryfp;
                   10476:     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
                   10477:         mips32_op = OPC_RECIP1_PS;
                   10478:         goto do_unaryfp;
                   10479: 
                   10480:         /* Conversions from double */
                   10481:     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
                   10482:         mips32_op = OPC_CVT_D_S;
                   10483:         goto do_unaryfp;
                   10484:     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
                   10485:         mips32_op = OPC_CVT_D_W;
                   10486:         goto do_unaryfp;
                   10487:     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
                   10488:         mips32_op = OPC_CVT_D_L;
                   10489:         goto do_unaryfp;
                   10490: 
                   10491:         /* Conversions from single */
                   10492:     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
                   10493:         mips32_op = OPC_CVT_S_D;
                   10494:         goto do_unaryfp;
                   10495:     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
                   10496:         mips32_op = OPC_CVT_S_W;
                   10497:         goto do_unaryfp;
                   10498:     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
                   10499:         mips32_op = OPC_CVT_S_L;
                   10500:     do_unaryfp:
                   10501:         gen_farith(ctx, mips32_op, -1, rs, rt, 0);
                   10502:         break;
                   10503: 
                   10504:         /* Conditional moves on floating-point codes */
                   10505:     case COND_FLOAT_MOV(MOVT, 0):
                   10506:     case COND_FLOAT_MOV(MOVT, 1):
                   10507:     case COND_FLOAT_MOV(MOVT, 2):
                   10508:     case COND_FLOAT_MOV(MOVT, 3):
                   10509:     case COND_FLOAT_MOV(MOVT, 4):
                   10510:     case COND_FLOAT_MOV(MOVT, 5):
                   10511:     case COND_FLOAT_MOV(MOVT, 6):
                   10512:     case COND_FLOAT_MOV(MOVT, 7):
                   10513:         gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
                   10514:         break;
                   10515:     case COND_FLOAT_MOV(MOVF, 0):
                   10516:     case COND_FLOAT_MOV(MOVF, 1):
                   10517:     case COND_FLOAT_MOV(MOVF, 2):
                   10518:     case COND_FLOAT_MOV(MOVF, 3):
                   10519:     case COND_FLOAT_MOV(MOVF, 4):
                   10520:     case COND_FLOAT_MOV(MOVF, 5):
                   10521:     case COND_FLOAT_MOV(MOVF, 6):
                   10522:     case COND_FLOAT_MOV(MOVF, 7):
                   10523:         gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
                   10524:         break;
                   10525:     default:
                   10526:         MIPS_INVAL("pool32fxf");
                   10527:         generate_exception(ctx, EXCP_RI);
                   10528:         break;
                   10529:     }
                   10530: }
                   10531: 
                   10532: static void decode_micromips32_opc (CPUState *env, DisasContext *ctx,
                   10533:                                     uint16_t insn_hw1, int *is_branch)
                   10534: {
                   10535:     int32_t offset;
                   10536:     uint16_t insn;
                   10537:     int rt, rs, rd, rr;
                   10538:     int16_t imm;
                   10539:     uint32_t op, minor, mips32_op;
                   10540:     uint32_t cond, fmt, cc;
                   10541: 
                   10542:     insn = lduw_code(ctx->pc + 2);
                   10543:     ctx->opcode = (ctx->opcode << 16) | insn;
                   10544: 
                   10545:     rt = (ctx->opcode >> 21) & 0x1f;
                   10546:     rs = (ctx->opcode >> 16) & 0x1f;
                   10547:     rd = (ctx->opcode >> 11) & 0x1f;
                   10548:     rr = (ctx->opcode >> 6) & 0x1f;
                   10549:     imm = (int16_t) ctx->opcode;
                   10550: 
                   10551:     op = (ctx->opcode >> 26) & 0x3f;
                   10552:     switch (op) {
                   10553:     case POOL32A:
                   10554:         minor = ctx->opcode & 0x3f;
                   10555:         switch (minor) {
                   10556:         case 0x00:
                   10557:             minor = (ctx->opcode >> 6) & 0xf;
                   10558:             switch (minor) {
                   10559:             case SLL32:
                   10560:                 mips32_op = OPC_SLL;
                   10561:                 goto do_shifti;
                   10562:             case SRA:
                   10563:                 mips32_op = OPC_SRA;
                   10564:                 goto do_shifti;
                   10565:             case SRL32:
                   10566:                 mips32_op = OPC_SRL;
                   10567:                 goto do_shifti;
                   10568:             case ROTR:
                   10569:                 mips32_op = OPC_ROTR;
                   10570:             do_shifti:
                   10571:                 gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
                   10572:                 break;
                   10573:             default:
                   10574:                 goto pool32a_invalid;
                   10575:             }
                   10576:             break;
                   10577:         case 0x10:
                   10578:             minor = (ctx->opcode >> 6) & 0xf;
                   10579:             switch (minor) {
                   10580:                 /* Arithmetic */
                   10581:             case ADD:
                   10582:                 mips32_op = OPC_ADD;
                   10583:                 goto do_arith;
                   10584:             case ADDU32:
                   10585:                 mips32_op = OPC_ADDU;
                   10586:                 goto do_arith;
                   10587:             case SUB:
                   10588:                 mips32_op = OPC_SUB;
                   10589:                 goto do_arith;
                   10590:             case SUBU32:
                   10591:                 mips32_op = OPC_SUBU;
                   10592:                 goto do_arith;
                   10593:             case MUL:
                   10594:                 mips32_op = OPC_MUL;
                   10595:             do_arith:
                   10596:                 gen_arith(env, ctx, mips32_op, rd, rs, rt);
                   10597:                 break;
                   10598:                 /* Shifts */
                   10599:             case SLLV:
                   10600:                 mips32_op = OPC_SLLV;
                   10601:                 goto do_shift;
                   10602:             case SRLV:
                   10603:                 mips32_op = OPC_SRLV;
                   10604:                 goto do_shift;
                   10605:             case SRAV:
                   10606:                 mips32_op = OPC_SRAV;
                   10607:                 goto do_shift;
                   10608:             case ROTRV:
                   10609:                 mips32_op = OPC_ROTRV;
                   10610:             do_shift:
                   10611:                 gen_shift(env, ctx, mips32_op, rd, rs, rt);
                   10612:                 break;
                   10613:                 /* Logical operations */
                   10614:             case AND:
                   10615:                 mips32_op = OPC_AND;
                   10616:                 goto do_logic;
                   10617:             case OR32:
                   10618:                 mips32_op = OPC_OR;
                   10619:                 goto do_logic;
                   10620:             case NOR:
                   10621:                 mips32_op = OPC_NOR;
                   10622:                 goto do_logic;
                   10623:             case XOR32:
                   10624:                 mips32_op = OPC_XOR;
                   10625:             do_logic:
                   10626:                 gen_logic(env, mips32_op, rd, rs, rt);
                   10627:                 break;
                   10628:                 /* Set less than */
                   10629:             case SLT:
                   10630:                 mips32_op = OPC_SLT;
                   10631:                 goto do_slt;
                   10632:             case SLTU:
                   10633:                 mips32_op = OPC_SLTU;
                   10634:             do_slt:
                   10635:                 gen_slt(env, mips32_op, rd, rs, rt);
                   10636:                 break;
                   10637:             default:
                   10638:                 goto pool32a_invalid;
                   10639:             }
                   10640:             break;
                   10641:         case 0x18:
                   10642:             minor = (ctx->opcode >> 6) & 0xf;
                   10643:             switch (minor) {
                   10644:                 /* Conditional moves */
                   10645:             case MOVN:
                   10646:                 mips32_op = OPC_MOVN;
                   10647:                 goto do_cmov;
                   10648:             case MOVZ:
                   10649:                 mips32_op = OPC_MOVZ;
                   10650:             do_cmov:
                   10651:                 gen_cond_move(env, mips32_op, rd, rs, rt);
                   10652:                 break;
                   10653:             case LWXS:
                   10654:                 gen_ldxs(ctx, rs, rt, rd);
                   10655:                 break;
                   10656:             default:
                   10657:                 goto pool32a_invalid;
                   10658:             }
                   10659:             break;
                   10660:         case INS:
                   10661:             gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
                   10662:             return;
                   10663:         case EXT:
                   10664:             gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
                   10665:             return;
                   10666:         case POOL32AXF:
                   10667:             gen_pool32axf(env, ctx, rt, rs, is_branch);
                   10668:             break;
                   10669:         case 0x07:
                   10670:             generate_exception(ctx, EXCP_BREAK);
                   10671:             break;
                   10672:         default:
                   10673:         pool32a_invalid:
                   10674:                 MIPS_INVAL("pool32a");
                   10675:                 generate_exception(ctx, EXCP_RI);
                   10676:                 break;
                   10677:         }
                   10678:         break;
                   10679:     case POOL32B:
                   10680:         minor = (ctx->opcode >> 12) & 0xf;
                   10681:         switch (minor) {
                   10682:         case CACHE:
                   10683:             /* Treat as no-op. */
                   10684:             break;
                   10685:         case LWC2:
                   10686:         case SWC2:
                   10687:             /* COP2: Not implemented. */
                   10688:             generate_exception_err(ctx, EXCP_CpU, 2);
                   10689:             break;
                   10690:         case LWP:
                   10691:         case SWP:
                   10692: #ifdef TARGET_MIPS64
                   10693:         case LDP:
                   10694:         case SDP:
                   10695: #endif
                   10696:             gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
                   10697:             break;
                   10698:         case LWM32:
                   10699:         case SWM32:
                   10700: #ifdef TARGET_MIPS64
                   10701:         case LDM:
                   10702:         case SDM:
                   10703: #endif
                   10704:             gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
                   10705:             break;
                   10706:         default:
                   10707:             MIPS_INVAL("pool32b");
                   10708:             generate_exception(ctx, EXCP_RI);
                   10709:             break;
                   10710:         }
                   10711:         break;
                   10712:     case POOL32F:
                   10713:         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
                   10714:             minor = ctx->opcode & 0x3f;
                   10715:             check_cp1_enabled(ctx);
                   10716:             switch (minor) {
                   10717:             case ALNV_PS:
                   10718:                 mips32_op = OPC_ALNV_PS;
                   10719:                 goto do_madd;
                   10720:             case MADD_S:
                   10721:                 mips32_op = OPC_MADD_S;
                   10722:                 goto do_madd;
                   10723:             case MADD_D:
                   10724:                 mips32_op = OPC_MADD_D;
                   10725:                 goto do_madd;
                   10726:             case MADD_PS:
                   10727:                 mips32_op = OPC_MADD_PS;
                   10728:                 goto do_madd;
                   10729:             case MSUB_S:
                   10730:                 mips32_op = OPC_MSUB_S;
                   10731:                 goto do_madd;
                   10732:             case MSUB_D:
                   10733:                 mips32_op = OPC_MSUB_D;
                   10734:                 goto do_madd;
                   10735:             case MSUB_PS:
                   10736:                 mips32_op = OPC_MSUB_PS;
                   10737:                 goto do_madd;
                   10738:             case NMADD_S:
                   10739:                 mips32_op = OPC_NMADD_S;
                   10740:                 goto do_madd;
                   10741:             case NMADD_D:
                   10742:                 mips32_op = OPC_NMADD_D;
                   10743:                 goto do_madd;
                   10744:             case NMADD_PS:
                   10745:                 mips32_op = OPC_NMADD_PS;
                   10746:                 goto do_madd;
                   10747:             case NMSUB_S:
                   10748:                 mips32_op = OPC_NMSUB_S;
                   10749:                 goto do_madd;
                   10750:             case NMSUB_D:
                   10751:                 mips32_op = OPC_NMSUB_D;
                   10752:                 goto do_madd;
                   10753:             case NMSUB_PS:
                   10754:                 mips32_op = OPC_NMSUB_PS;
                   10755:             do_madd:
                   10756:                 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
                   10757:                 break;
                   10758:             case CABS_COND_FMT:
                   10759:                 cond = (ctx->opcode >> 6) & 0xf;
                   10760:                 cc = (ctx->opcode >> 13) & 0x7;
                   10761:                 fmt = (ctx->opcode >> 10) & 0x3;
                   10762:                 switch (fmt) {
                   10763:                 case 0x0:
                   10764:                     gen_cmpabs_s(ctx, cond, rt, rs, cc);
                   10765:                     break;
                   10766:                 case 0x1:
                   10767:                     gen_cmpabs_d(ctx, cond, rt, rs, cc);
                   10768:                     break;
                   10769:                 case 0x2:
                   10770:                     gen_cmpabs_ps(ctx, cond, rt, rs, cc);
                   10771:                     break;
                   10772:                 default:
                   10773:                     goto pool32f_invalid;
                   10774:                 }
                   10775:                 break;
                   10776:             case C_COND_FMT:
                   10777:                 cond = (ctx->opcode >> 6) & 0xf;
                   10778:                 cc = (ctx->opcode >> 13) & 0x7;
                   10779:                 fmt = (ctx->opcode >> 10) & 0x3;
                   10780:                 switch (fmt) {
                   10781:                 case 0x0:
                   10782:                     gen_cmp_s(ctx, cond, rt, rs, cc);
                   10783:                     break;
                   10784:                 case 0x1:
                   10785:                     gen_cmp_d(ctx, cond, rt, rs, cc);
                   10786:                     break;
                   10787:                 case 0x2:
                   10788:                     gen_cmp_ps(ctx, cond, rt, rs, cc);
                   10789:                     break;
                   10790:                 default:
                   10791:                     goto pool32f_invalid;
                   10792:                 }
                   10793:                 break;
                   10794:             case POOL32FXF:
                   10795:                 gen_pool32fxf(env, ctx, rt, rs);
                   10796:                 break;
                   10797:             case 0x00:
                   10798:                 /* PLL foo */
                   10799:                 switch ((ctx->opcode >> 6) & 0x7) {
                   10800:                 case PLL_PS:
                   10801:                     mips32_op = OPC_PLL_PS;
                   10802:                     goto do_ps;
                   10803:                 case PLU_PS:
                   10804:                     mips32_op = OPC_PLU_PS;
                   10805:                     goto do_ps;
                   10806:                 case PUL_PS:
                   10807:                     mips32_op = OPC_PUL_PS;
                   10808:                     goto do_ps;
                   10809:                 case PUU_PS:
                   10810:                     mips32_op = OPC_PUU_PS;
                   10811:                     goto do_ps;
                   10812:                 case CVT_PS_S:
                   10813:                     mips32_op = OPC_CVT_PS_S;
                   10814:                 do_ps:
                   10815:                     gen_farith(ctx, mips32_op, rt, rs, rd, 0);
                   10816:                     break;
                   10817:                 default:
                   10818:                     goto pool32f_invalid;
                   10819:                 }
                   10820:                 break;
                   10821:             case 0x08:
                   10822:                 /* [LS][WDU]XC1 */
                   10823:                 switch ((ctx->opcode >> 6) & 0x7) {
                   10824:                 case LWXC1:
                   10825:                     mips32_op = OPC_LWXC1;
                   10826:                     goto do_ldst_cp1;
                   10827:                 case SWXC1:
                   10828:                     mips32_op = OPC_SWXC1;
                   10829:                     goto do_ldst_cp1;
                   10830:                 case LDXC1:
                   10831:                     mips32_op = OPC_LDXC1;
                   10832:                     goto do_ldst_cp1;
                   10833:                 case SDXC1:
                   10834:                     mips32_op = OPC_SDXC1;
                   10835:                     goto do_ldst_cp1;
                   10836:                 case LUXC1:
                   10837:                     mips32_op = OPC_LUXC1;
                   10838:                     goto do_ldst_cp1;
                   10839:                 case SUXC1:
                   10840:                     mips32_op = OPC_SUXC1;
                   10841:                 do_ldst_cp1:
                   10842:                     gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
                   10843:                     break;
                   10844:                 default:
                   10845:                     goto pool32f_invalid;
                   10846:                 }
                   10847:                 break;
                   10848:             case 0x18:
                   10849:                 /* 3D insns */
                   10850:                 fmt = (ctx->opcode >> 9) & 0x3;
                   10851:                 switch ((ctx->opcode >> 6) & 0x7) {
                   10852:                 case RSQRT2_FMT:
                   10853:                     switch (fmt) {
                   10854:                     case FMT_SDPS_S:
                   10855:                         mips32_op = OPC_RSQRT2_S;
                   10856:                         goto do_3d;
                   10857:                     case FMT_SDPS_D:
                   10858:                         mips32_op = OPC_RSQRT2_D;
                   10859:                         goto do_3d;
                   10860:                     case FMT_SDPS_PS:
                   10861:                         mips32_op = OPC_RSQRT2_PS;
                   10862:                         goto do_3d;
                   10863:                     default:
                   10864:                         goto pool32f_invalid;
                   10865:                     }
                   10866:                     break;
                   10867:                 case RECIP2_FMT:
                   10868:                     switch (fmt) {
                   10869:                     case FMT_SDPS_S:
                   10870:                         mips32_op = OPC_RECIP2_S;
                   10871:                         goto do_3d;
                   10872:                     case FMT_SDPS_D:
                   10873:                         mips32_op = OPC_RECIP2_D;
                   10874:                         goto do_3d;
                   10875:                     case FMT_SDPS_PS:
                   10876:                         mips32_op = OPC_RECIP2_PS;
                   10877:                         goto do_3d;
                   10878:                     default:
                   10879:                         goto pool32f_invalid;
                   10880:                     }
                   10881:                     break;
                   10882:                 case ADDR_PS:
                   10883:                     mips32_op = OPC_ADDR_PS;
                   10884:                     goto do_3d;
                   10885:                 case MULR_PS:
                   10886:                     mips32_op = OPC_MULR_PS;
                   10887:                 do_3d:
                   10888:                     gen_farith(ctx, mips32_op, rt, rs, rd, 0);
                   10889:                     break;
                   10890:                 default:
                   10891:                     goto pool32f_invalid;
                   10892:                 }
                   10893:                 break;
                   10894:             case 0x20:
                   10895:                 /* MOV[FT].fmt and PREFX */
                   10896:                 cc = (ctx->opcode >> 13) & 0x7;
                   10897:                 fmt = (ctx->opcode >> 9) & 0x3;
                   10898:                 switch ((ctx->opcode >> 6) & 0x7) {
                   10899:                 case MOVF_FMT:
                   10900:                     switch (fmt) {
                   10901:                     case FMT_SDPS_S:
                   10902:                         gen_movcf_s(rs, rt, cc, 0);
                   10903:                         break;
                   10904:                     case FMT_SDPS_D:
                   10905:                         gen_movcf_d(ctx, rs, rt, cc, 0);
                   10906:                         break;
                   10907:                     case FMT_SDPS_PS:
                   10908:                         gen_movcf_ps(rs, rt, cc, 0);
                   10909:                         break;
                   10910:                     default:
                   10911:                         goto pool32f_invalid;
                   10912:                     }
                   10913:                     break;
                   10914:                 case MOVT_FMT:
                   10915:                     switch (fmt) {
                   10916:                     case FMT_SDPS_S:
                   10917:                         gen_movcf_s(rs, rt, cc, 1);
                   10918:                         break;
                   10919:                     case FMT_SDPS_D:
                   10920:                         gen_movcf_d(ctx, rs, rt, cc, 1);
                   10921:                         break;
                   10922:                     case FMT_SDPS_PS:
                   10923:                         gen_movcf_ps(rs, rt, cc, 1);
                   10924:                         break;
                   10925:                     default:
                   10926:                         goto pool32f_invalid;
                   10927:                     }
                   10928:                     break;
                   10929:                 case PREFX:
                   10930:                     break;
                   10931:                 default:
                   10932:                     goto pool32f_invalid;
                   10933:                 }
                   10934:                 break;
                   10935: #define FINSN_3ARG_SDPS(prfx)                           \
                   10936:                 switch ((ctx->opcode >> 8) & 0x3) {     \
                   10937:                 case FMT_SDPS_S:                        \
                   10938:                     mips32_op = OPC_##prfx##_S;         \
                   10939:                     goto do_fpop;                       \
                   10940:                 case FMT_SDPS_D:                        \
                   10941:                     mips32_op = OPC_##prfx##_D;         \
                   10942:                     goto do_fpop;                       \
                   10943:                 case FMT_SDPS_PS:                       \
                   10944:                     mips32_op = OPC_##prfx##_PS;        \
                   10945:                     goto do_fpop;                       \
                   10946:                 default:                                \
                   10947:                     goto pool32f_invalid;               \
                   10948:                 }
                   10949:             case 0x30:
                   10950:                 /* regular FP ops */
                   10951:                 switch ((ctx->opcode >> 6) & 0x3) {
                   10952:                 case ADD_FMT:
                   10953:                     FINSN_3ARG_SDPS(ADD);
                   10954:                     break;
                   10955:                 case SUB_FMT:
                   10956:                     FINSN_3ARG_SDPS(SUB);
                   10957:                     break;
                   10958:                 case MUL_FMT:
                   10959:                     FINSN_3ARG_SDPS(MUL);
                   10960:                     break;
                   10961:                 case DIV_FMT:
                   10962:                     fmt = (ctx->opcode >> 8) & 0x3;
                   10963:                     if (fmt == 1) {
                   10964:                         mips32_op = OPC_DIV_D;
                   10965:                     } else if (fmt == 0) {
                   10966:                         mips32_op = OPC_DIV_S;
                   10967:                     } else {
                   10968:                         goto pool32f_invalid;
                   10969:                     }
                   10970:                     goto do_fpop;
                   10971:                 default:
                   10972:                     goto pool32f_invalid;
                   10973:                 }
                   10974:                 break;
                   10975:             case 0x38:
                   10976:                 /* cmovs */
                   10977:                 switch ((ctx->opcode >> 6) & 0x3) {
                   10978:                 case MOVN_FMT:
                   10979:                     FINSN_3ARG_SDPS(MOVN);
                   10980:                     break;
                   10981:                 case MOVZ_FMT:
                   10982:                     FINSN_3ARG_SDPS(MOVZ);
                   10983:                     break;
                   10984:                 default:
                   10985:                     goto pool32f_invalid;
                   10986:                 }
                   10987:                 break;
                   10988:             do_fpop:
                   10989:                 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
                   10990:                 break;
                   10991:             default:
                   10992:             pool32f_invalid:
                   10993:                 MIPS_INVAL("pool32f");
                   10994:                 generate_exception(ctx, EXCP_RI);
                   10995:                 break;
                   10996:             }
                   10997:         } else {
                   10998:             generate_exception_err(ctx, EXCP_CpU, 1);
                   10999:         }
                   11000:         break;
                   11001:     case POOL32I:
                   11002:         minor = (ctx->opcode >> 21) & 0x1f;
                   11003:         switch (minor) {
                   11004:         case BLTZ:
                   11005:             mips32_op = OPC_BLTZ;
                   11006:             goto do_branch;
                   11007:         case BLTZAL:
                   11008:             mips32_op = OPC_BLTZAL;
                   11009:             goto do_branch;
                   11010:         case BLTZALS:
                   11011:             mips32_op = OPC_BLTZALS;
                   11012:             goto do_branch;
                   11013:         case BGEZ:
                   11014:             mips32_op = OPC_BGEZ;
                   11015:             goto do_branch;
                   11016:         case BGEZAL:
                   11017:             mips32_op = OPC_BGEZAL;
                   11018:             goto do_branch;
                   11019:         case BGEZALS:
                   11020:             mips32_op = OPC_BGEZALS;
                   11021:             goto do_branch;
                   11022:         case BLEZ:
                   11023:             mips32_op = OPC_BLEZ;
                   11024:             goto do_branch;
                   11025:         case BGTZ:
                   11026:             mips32_op = OPC_BGTZ;
                   11027:         do_branch:
                   11028:             gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
                   11029:             *is_branch = 1;
                   11030:             break;
                   11031: 
                   11032:             /* Traps */
                   11033:         case TLTI:
                   11034:             mips32_op = OPC_TLTI;
                   11035:             goto do_trapi;
                   11036:         case TGEI:
                   11037:             mips32_op = OPC_TGEI;
                   11038:             goto do_trapi;
                   11039:         case TLTIU:
                   11040:             mips32_op = OPC_TLTIU;
                   11041:             goto do_trapi;
                   11042:         case TGEIU:
                   11043:             mips32_op = OPC_TGEIU;
                   11044:             goto do_trapi;
                   11045:         case TNEI:
                   11046:             mips32_op = OPC_TNEI;
                   11047:             goto do_trapi;
                   11048:         case TEQI:
                   11049:             mips32_op = OPC_TEQI;
                   11050:         do_trapi:
                   11051:             gen_trap(ctx, mips32_op, rs, -1, imm);
                   11052:             break;
                   11053: 
                   11054:         case BNEZC:
                   11055:         case BEQZC:
                   11056:             gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
                   11057:                                4, rs, 0, imm << 1);
                   11058:             /* Compact branches don't have a delay slot, so just let
                   11059:                the normal delay slot handling take us to the branch
                   11060:                target. */
                   11061:             break;
                   11062:         case LUI:
                   11063:             gen_logic_imm(env, OPC_LUI, rs, -1, imm);
                   11064:             break;
                   11065:         case SYNCI:
                   11066:             break;
                   11067:         case BC2F:
                   11068:         case BC2T:
                   11069:             /* COP2: Not implemented. */
                   11070:             generate_exception_err(ctx, EXCP_CpU, 2);
                   11071:             break;
                   11072:         case BC1F:
                   11073:             mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
                   11074:             goto do_cp1branch;
                   11075:         case BC1T:
                   11076:             mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
                   11077:             goto do_cp1branch;
                   11078:         case BC1ANY4F:
                   11079:             mips32_op = OPC_BC1FANY4;
                   11080:             goto do_cp1mips3d;
                   11081:         case BC1ANY4T:
                   11082:             mips32_op = OPC_BC1TANY4;
                   11083:         do_cp1mips3d:
                   11084:             check_cop1x(ctx);
                   11085:             check_insn(env, ctx, ASE_MIPS3D);
                   11086:             /* Fall through */
                   11087:         do_cp1branch:
                   11088:             gen_compute_branch1(env, ctx, mips32_op,
                   11089:                                 (ctx->opcode >> 18) & 0x7, imm << 1);
                   11090:             *is_branch = 1;
                   11091:             break;
                   11092:         case BPOSGE64:
                   11093:         case BPOSGE32:
                   11094:             /* MIPS DSP: not implemented */
                   11095:             /* Fall through */
                   11096:         default:
                   11097:             MIPS_INVAL("pool32i");
                   11098:             generate_exception(ctx, EXCP_RI);
                   11099:             break;
                   11100:         }
                   11101:         break;
                   11102:     case POOL32C:
                   11103:         minor = (ctx->opcode >> 12) & 0xf;
                   11104:         switch (minor) {
                   11105:         case LWL:
                   11106:             mips32_op = OPC_LWL;
                   11107:             goto do_ld_lr;
                   11108:         case SWL:
                   11109:             mips32_op = OPC_SWL;
                   11110:             goto do_st_lr;
                   11111:         case LWR:
                   11112:             mips32_op = OPC_LWR;
                   11113:             goto do_ld_lr;
                   11114:         case SWR:
                   11115:             mips32_op = OPC_SWR;
                   11116:             goto do_st_lr;
                   11117: #if defined(TARGET_MIPS64)
                   11118:         case LDL:
                   11119:             mips32_op = OPC_LDL;
                   11120:             goto do_ld_lr;
                   11121:         case SDL:
                   11122:             mips32_op = OPC_SDL;
                   11123:             goto do_st_lr;
                   11124:         case LDR:
                   11125:             mips32_op = OPC_LDR;
                   11126:             goto do_ld_lr;
                   11127:         case SDR:
                   11128:             mips32_op = OPC_SDR;
                   11129:             goto do_st_lr;
                   11130:         case LWU:
                   11131:             mips32_op = OPC_LWU;
                   11132:             goto do_ld_lr;
                   11133:         case LLD:
                   11134:             mips32_op = OPC_LLD;
                   11135:             goto do_ld_lr;
                   11136: #endif
                   11137:         case LL:
                   11138:             mips32_op = OPC_LL;
                   11139:             goto do_ld_lr;
                   11140:         do_ld_lr:
                   11141:             gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
                   11142:             break;
                   11143:         do_st_lr:
                   11144:             gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
                   11145:             break;
                   11146:         case SC:
                   11147:             gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
                   11148:             break;
                   11149: #if defined(TARGET_MIPS64)
                   11150:         case SCD:
                   11151:             gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
                   11152:             break;
                   11153: #endif
                   11154:         case PREF:
                   11155:             /* Treat as no-op */
                   11156:             break;
                   11157:         default:
                   11158:             MIPS_INVAL("pool32c");
                   11159:             generate_exception(ctx, EXCP_RI);
                   11160:             break;
                   11161:         }
                   11162:         break;
                   11163:     case ADDI32:
                   11164:         mips32_op = OPC_ADDI;
                   11165:         goto do_addi;
                   11166:     case ADDIU32:
                   11167:         mips32_op = OPC_ADDIU;
                   11168:     do_addi:
                   11169:         gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
                   11170:         break;
                   11171: 
                   11172:         /* Logical operations */
                   11173:     case ORI32:
                   11174:         mips32_op = OPC_ORI;
                   11175:         goto do_logici;
                   11176:     case XORI32:
                   11177:         mips32_op = OPC_XORI;
                   11178:         goto do_logici;
                   11179:     case ANDI32:
                   11180:         mips32_op = OPC_ANDI;
                   11181:     do_logici:
                   11182:         gen_logic_imm(env, mips32_op, rt, rs, imm);
                   11183:         break;
                   11184: 
                   11185:         /* Set less than immediate */
                   11186:     case SLTI32:
                   11187:         mips32_op = OPC_SLTI;
                   11188:         goto do_slti;
                   11189:     case SLTIU32:
                   11190:         mips32_op = OPC_SLTIU;
                   11191:     do_slti:
                   11192:         gen_slt_imm(env, mips32_op, rt, rs, imm);
                   11193:         break;
                   11194:     case JALX32:
                   11195:         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
                   11196:         gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
                   11197:         *is_branch = 1;
                   11198:         break;
                   11199:     case JALS32:
                   11200:         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
                   11201:         gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
                   11202:         *is_branch = 1;
                   11203:         break;
                   11204:     case BEQ32:
                   11205:         gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
                   11206:         *is_branch = 1;
                   11207:         break;
                   11208:     case BNE32:
                   11209:         gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
                   11210:         *is_branch = 1;
                   11211:         break;
                   11212:     case J32:
                   11213:         gen_compute_branch(ctx, OPC_J, 4, rt, rs,
                   11214:                            (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
                   11215:         *is_branch = 1;
                   11216:         break;
                   11217:     case JAL32:
                   11218:         gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
                   11219:                            (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
                   11220:         *is_branch = 1;
                   11221:         break;
                   11222:         /* Floating point (COP1) */
                   11223:     case LWC132:
                   11224:         mips32_op = OPC_LWC1;
                   11225:         goto do_cop1;
                   11226:     case LDC132:
                   11227:         mips32_op = OPC_LDC1;
                   11228:         goto do_cop1;
                   11229:     case SWC132:
                   11230:         mips32_op = OPC_SWC1;
                   11231:         goto do_cop1;
                   11232:     case SDC132:
                   11233:         mips32_op = OPC_SDC1;
                   11234:     do_cop1:
                   11235:         gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
                   11236:         break;
                   11237:     case ADDIUPC:
                   11238:         {
                   11239:             int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
                   11240:             int offset = SIMM(ctx->opcode, 0, 23) << 2;
                   11241: 
                   11242:             gen_addiupc(ctx, reg, offset, 0, 0);
                   11243:         }
                   11244:         break;
                   11245:         /* Loads and stores */
                   11246:     case LB32:
                   11247:         mips32_op = OPC_LB;
                   11248:         goto do_ld;
                   11249:     case LBU32:
                   11250:         mips32_op = OPC_LBU;
                   11251:         goto do_ld;
                   11252:     case LH32:
                   11253:         mips32_op = OPC_LH;
                   11254:         goto do_ld;
                   11255:     case LHU32:
                   11256:         mips32_op = OPC_LHU;
                   11257:         goto do_ld;
                   11258:     case LW32:
                   11259:         mips32_op = OPC_LW;
                   11260:         goto do_ld;
                   11261: #ifdef TARGET_MIPS64
                   11262:     case LD32:
                   11263:         mips32_op = OPC_LD;
                   11264:         goto do_ld;
                   11265:     case SD32:
                   11266:         mips32_op = OPC_SD;
                   11267:         goto do_st;
                   11268: #endif
                   11269:     case SB32:
                   11270:         mips32_op = OPC_SB;
                   11271:         goto do_st;
                   11272:     case SH32:
                   11273:         mips32_op = OPC_SH;
                   11274:         goto do_st;
                   11275:     case SW32:
                   11276:         mips32_op = OPC_SW;
                   11277:         goto do_st;
                   11278:     do_ld:
                   11279:         gen_ld(env, ctx, mips32_op, rt, rs, imm);
                   11280:         break;
                   11281:     do_st:
                   11282:         gen_st(ctx, mips32_op, rt, rs, imm);
                   11283:         break;
                   11284:     default:
                   11285:         generate_exception(ctx, EXCP_RI);
                   11286:         break;
                   11287:     }
                   11288: }
                   11289: 
                   11290: static int decode_micromips_opc (CPUState *env, DisasContext *ctx, int *is_branch)
                   11291: {
                   11292:     uint32_t op;
                   11293: 
                   11294:     /* make sure instructions are on a halfword boundary */
                   11295:     if (ctx->pc & 0x1) {
                   11296:         env->CP0_BadVAddr = ctx->pc;
                   11297:         generate_exception(ctx, EXCP_AdEL);
                   11298:         ctx->bstate = BS_STOP;
                   11299:         return 2;
                   11300:     }
                   11301: 
                   11302:     op = (ctx->opcode >> 10) & 0x3f;
                   11303:     /* Enforce properly-sized instructions in a delay slot */
                   11304:     if (ctx->hflags & MIPS_HFLAG_BMASK) {
                   11305:         int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
                   11306: 
                   11307:         switch (op) {
                   11308:         case POOL32A:
                   11309:         case POOL32B:
                   11310:         case POOL32I:
                   11311:         case POOL32C:
                   11312:         case ADDI32:
                   11313:         case ADDIU32:
                   11314:         case ORI32:
                   11315:         case XORI32:
                   11316:         case SLTI32:
                   11317:         case SLTIU32:
                   11318:         case ANDI32:
                   11319:         case JALX32:
                   11320:         case LBU32:
                   11321:         case LHU32:
                   11322:         case POOL32F:
                   11323:         case JALS32:
                   11324:         case BEQ32:
                   11325:         case BNE32:
                   11326:         case J32:
                   11327:         case JAL32:
                   11328:         case SB32:
                   11329:         case SH32:
                   11330:         case POOL32S:
                   11331:         case ADDIUPC:
                   11332:         case SWC132:
                   11333:         case SDC132:
                   11334:         case SD32:
                   11335:         case SW32:
                   11336:         case LB32:
                   11337:         case LH32:
                   11338:         case DADDIU32:
                   11339:         case POOL48A:           /* ??? */
                   11340:         case LWC132:
                   11341:         case LDC132:
                   11342:         case LD32:
                   11343:         case LW32:
                   11344:             if (bits & MIPS_HFLAG_BDS16) {
                   11345:                 generate_exception(ctx, EXCP_RI);
                   11346:                 /* Just stop translation; the user is confused.  */
                   11347:                 ctx->bstate = BS_STOP;
                   11348:                 return 2;
                   11349:             }
                   11350:             break;
                   11351:         case POOL16A:
                   11352:         case POOL16B:
                   11353:         case POOL16C:
                   11354:         case LWGP16:
                   11355:         case POOL16F:
                   11356:         case LBU16:
                   11357:         case LHU16:
                   11358:         case LWSP16:
                   11359:         case LW16:
                   11360:         case SB16:
                   11361:         case SH16:
                   11362:         case SWSP16:
                   11363:         case SW16:
                   11364:         case MOVE16:
                   11365:         case ANDI16:
                   11366:         case POOL16D:
                   11367:         case POOL16E:
                   11368:         case BEQZ16:
                   11369:         case BNEZ16:
                   11370:         case B16:
                   11371:         case LI16:
                   11372:             if (bits & MIPS_HFLAG_BDS32) {
                   11373:                 generate_exception(ctx, EXCP_RI);
                   11374:                 /* Just stop translation; the user is confused.  */
                   11375:                 ctx->bstate = BS_STOP;
                   11376:                 return 2;
                   11377:             }
                   11378:             break;
                   11379:         default:
                   11380:             break;
                   11381:         }
                   11382:     }
                   11383:     switch (op) {
                   11384:     case POOL16A:
                   11385:         {
                   11386:             int rd = mmreg(uMIPS_RD(ctx->opcode));
                   11387:             int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
                   11388:             int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
                   11389:             uint32_t opc = 0;
                   11390: 
                   11391:             switch (ctx->opcode & 0x1) {
                   11392:             case ADDU16:
                   11393:                 opc = OPC_ADDU;
                   11394:                 break;
                   11395:             case SUBU16:
                   11396:                 opc = OPC_SUBU;
                   11397:                 break;
                   11398:             }
                   11399: 
                   11400:             gen_arith(env, ctx, opc, rd, rs1, rs2);
                   11401:         }
                   11402:         break;
                   11403:     case POOL16B:
                   11404:         {
                   11405:             int rd = mmreg(uMIPS_RD(ctx->opcode));
                   11406:             int rs = mmreg(uMIPS_RS(ctx->opcode));
                   11407:             int amount = (ctx->opcode >> 1) & 0x7;
                   11408:             uint32_t opc = 0;
                   11409:             amount = amount == 0 ? 8 : amount;
                   11410: 
                   11411:             switch (ctx->opcode & 0x1) {
                   11412:             case SLL16:
                   11413:                 opc = OPC_SLL;
                   11414:                 break;
                   11415:             case SRL16:
                   11416:                 opc = OPC_SRL;
                   11417:                 break;
                   11418:             }
                   11419: 
                   11420:             gen_shift_imm(env, ctx, opc, rd, rs, amount);
                   11421:         }
                   11422:         break;
                   11423:     case POOL16C:
                   11424:         gen_pool16c_insn(env, ctx, is_branch);
                   11425:         break;
                   11426:     case LWGP16:
                   11427:         {
                   11428:             int rd = mmreg(uMIPS_RD(ctx->opcode));
                   11429:             int rb = 28;            /* GP */
                   11430:             int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
                   11431: 
                   11432:             gen_ld(env, ctx, OPC_LW, rd, rb, offset);
                   11433:         }
                   11434:         break;
                   11435:     case POOL16F:
                   11436:         if (ctx->opcode & 1) {
                   11437:             generate_exception(ctx, EXCP_RI);
                   11438:         } else {
                   11439:             /* MOVEP */
                   11440:             int enc_dest = uMIPS_RD(ctx->opcode);
                   11441:             int enc_rt = uMIPS_RS2(ctx->opcode);
                   11442:             int enc_rs = uMIPS_RS1(ctx->opcode);
                   11443:             int rd, rs, re, rt;
                   11444:             static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
                   11445:             static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
                   11446:             static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
                   11447: 
                   11448:             rd = rd_enc[enc_dest];
                   11449:             re = re_enc[enc_dest];
                   11450:             rs = rs_rt_enc[enc_rs];
                   11451:             rt = rs_rt_enc[enc_rt];
                   11452: 
                   11453:             gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
                   11454:             gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
                   11455:         }
                   11456:         break;
                   11457:     case LBU16:
                   11458:         {
                   11459:             int rd = mmreg(uMIPS_RD(ctx->opcode));
                   11460:             int rb = mmreg(uMIPS_RS(ctx->opcode));
                   11461:             int16_t offset = ZIMM(ctx->opcode, 0, 4);
                   11462:             offset = (offset == 0xf ? -1 : offset);
                   11463: 
                   11464:             gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
                   11465:         }
                   11466:         break;
                   11467:     case LHU16:
                   11468:         {
                   11469:             int rd = mmreg(uMIPS_RD(ctx->opcode));
                   11470:             int rb = mmreg(uMIPS_RS(ctx->opcode));
                   11471:             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
                   11472: 
                   11473:             gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
                   11474:         }
                   11475:         break;
                   11476:     case LWSP16:
                   11477:         {
                   11478:             int rd = (ctx->opcode >> 5) & 0x1f;
                   11479:             int rb = 29;            /* SP */
                   11480:             int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
                   11481: 
                   11482:             gen_ld(env, ctx, OPC_LW, rd, rb, offset);
                   11483:         }
                   11484:         break;
                   11485:     case LW16:
                   11486:         {
                   11487:             int rd = mmreg(uMIPS_RD(ctx->opcode));
                   11488:             int rb = mmreg(uMIPS_RS(ctx->opcode));
                   11489:             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
                   11490: 
                   11491:             gen_ld(env, ctx, OPC_LW, rd, rb, offset);
                   11492:         }
                   11493:         break;
                   11494:     case SB16:
                   11495:         {
                   11496:             int rd = mmreg2(uMIPS_RD(ctx->opcode));
                   11497:             int rb = mmreg(uMIPS_RS(ctx->opcode));
                   11498:             int16_t offset = ZIMM(ctx->opcode, 0, 4);
                   11499: 
                   11500:             gen_st(ctx, OPC_SB, rd, rb, offset);
                   11501:         }
                   11502:         break;
                   11503:     case SH16:
                   11504:         {
                   11505:             int rd = mmreg2(uMIPS_RD(ctx->opcode));
                   11506:             int rb = mmreg(uMIPS_RS(ctx->opcode));
                   11507:             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
                   11508: 
                   11509:             gen_st(ctx, OPC_SH, rd, rb, offset);
                   11510:         }
                   11511:         break;
                   11512:     case SWSP16:
                   11513:         {
                   11514:             int rd = (ctx->opcode >> 5) & 0x1f;
                   11515:             int rb = 29;            /* SP */
                   11516:             int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
                   11517: 
                   11518:             gen_st(ctx, OPC_SW, rd, rb, offset);
                   11519:         }
                   11520:         break;
                   11521:     case SW16:
                   11522:         {
                   11523:             int rd = mmreg2(uMIPS_RD(ctx->opcode));
                   11524:             int rb = mmreg(uMIPS_RS(ctx->opcode));
                   11525:             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
                   11526: 
                   11527:             gen_st(ctx, OPC_SW, rd, rb, offset);
                   11528:         }
                   11529:         break;
                   11530:     case MOVE16:
                   11531:         {
                   11532:             int rd = uMIPS_RD5(ctx->opcode);
                   11533:             int rs = uMIPS_RS5(ctx->opcode);
                   11534: 
                   11535:             gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
                   11536:         }
                   11537:         break;
                   11538:     case ANDI16:
                   11539:         gen_andi16(env, ctx);
                   11540:         break;
                   11541:     case POOL16D:
                   11542:         switch (ctx->opcode & 0x1) {
                   11543:         case ADDIUS5:
                   11544:             gen_addius5(env, ctx);
                   11545:             break;
                   11546:         case ADDIUSP:
                   11547:             gen_addiusp(env, ctx);
                   11548:             break;
                   11549:         }
                   11550:         break;
                   11551:     case POOL16E:
                   11552:         switch (ctx->opcode & 0x1) {
                   11553:         case ADDIUR2:
                   11554:             gen_addiur2(env, ctx);
                   11555:             break;
                   11556:         case ADDIUR1SP:
                   11557:             gen_addiur1sp(env, ctx);
                   11558:             break;
                   11559:         }
                   11560:         break;
                   11561:     case B16:
                   11562:         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
                   11563:                            SIMM(ctx->opcode, 0, 10) << 1);
                   11564:         *is_branch = 1;
                   11565:         break;
                   11566:     case BNEZ16:
                   11567:     case BEQZ16:
                   11568:         gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
                   11569:                            mmreg(uMIPS_RD(ctx->opcode)),
                   11570:                            0, SIMM(ctx->opcode, 0, 7) << 1);
                   11571:         *is_branch = 1;
                   11572:         break;
                   11573:     case LI16:
                   11574:         {
                   11575:             int reg = mmreg(uMIPS_RD(ctx->opcode));
                   11576:             int imm = ZIMM(ctx->opcode, 0, 7);
                   11577: 
                   11578:             imm = (imm == 0x7f ? -1 : imm);
                   11579:             tcg_gen_movi_tl(cpu_gpr[reg], imm);
                   11580:         }
                   11581:         break;
                   11582:     case RES_20:
                   11583:     case RES_28:
                   11584:     case RES_29:
                   11585:     case RES_30:
                   11586:     case RES_31:
                   11587:     case RES_38:
                   11588:     case RES_39:
                   11589:         generate_exception(ctx, EXCP_RI);
                   11590:         break;
                   11591:     default:
                   11592:         decode_micromips32_opc (env, ctx, op, is_branch);
                   11593:         return 4;
                   11594:     }
                   11595: 
                   11596:     return 2;
                   11597: }
                   11598: 
                   11599: /* SmartMIPS extension to MIPS32 */
                   11600: 
                   11601: #if defined(TARGET_MIPS64)
                   11602: 
                   11603: /* MDMX extension to MIPS64 */
                   11604: 
                   11605: #endif
                   11606: 
                   11607: static void decode_opc (CPUState *env, DisasContext *ctx, int *is_branch)
                   11608: {
                   11609:     int32_t offset;
                   11610:     int rs, rt, rd, sa;
                   11611:     uint32_t op, op1, op2;
                   11612:     int16_t imm;
                   11613: 
                   11614:     /* make sure instructions are on a word boundary */
                   11615:     if (ctx->pc & 0x3) {
                   11616:         env->CP0_BadVAddr = ctx->pc;
                   11617:         generate_exception(ctx, EXCP_AdEL);
                   11618:         return;
                   11619:     }
                   11620: 
                   11621:     /* Handle blikely not taken case */
                   11622:     if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
                   11623:         int l1 = gen_new_label();
                   11624: 
                   11625:         MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
1.1.1.8   root     11626:         tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
                   11627:         tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
1.1.1.6   root     11628:         gen_goto_tb(ctx, 1, ctx->pc + 4);
                   11629:         gen_set_label(l1);
1.1       root     11630:     }
1.1.1.9   root     11631: 
                   11632:     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
                   11633:         tcg_gen_debug_insn_start(ctx->pc);
                   11634: 
1.1.1.5   root     11635:     op = MASK_OP_MAJOR(ctx->opcode);
                   11636:     rs = (ctx->opcode >> 21) & 0x1f;
                   11637:     rt = (ctx->opcode >> 16) & 0x1f;
                   11638:     rd = (ctx->opcode >> 11) & 0x1f;
                   11639:     sa = (ctx->opcode >> 6) & 0x1f;
1.1       root     11640:     imm = (int16_t)ctx->opcode;
                   11641:     switch (op) {
1.1.1.5   root     11642:     case OPC_SPECIAL:
                   11643:         op1 = MASK_SPECIAL(ctx->opcode);
1.1       root     11644:         switch (op1) {
1.1.1.8   root     11645:         case OPC_SLL:          /* Shift with immediate */
                   11646:         case OPC_SRA:
                   11647:             gen_shift_imm(env, ctx, op1, rd, rt, sa);
1.1.1.5   root     11648:             break;
1.1.1.12  root     11649:         case OPC_SRL:
                   11650:             switch ((ctx->opcode >> 21) & 0x1f) {
                   11651:             case 1:
                   11652:                 /* rotr is decoded as srl on non-R2 CPUs */
                   11653:                 if (env->insn_flags & ISA_MIPS32R2) {
                   11654:                     op1 = OPC_ROTR;
                   11655:                 }
                   11656:                 /* Fallthrough */
                   11657:             case 0:
                   11658:                 gen_shift_imm(env, ctx, op1, rd, rt, sa);
                   11659:                 break;
                   11660:             default:
                   11661:                 generate_exception(ctx, EXCP_RI);
                   11662:                 break;
                   11663:             }
                   11664:             break;
1.1.1.8   root     11665:         case OPC_MOVN:         /* Conditional move */
                   11666:         case OPC_MOVZ:
1.1.1.12  root     11667:             check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
                   11668:                                  INSN_LOONGSON2E | INSN_LOONGSON2F);
1.1.1.8   root     11669:             gen_cond_move(env, op1, rd, rs, rt);
                   11670:             break;
                   11671:         case OPC_ADD ... OPC_SUBU:
1.1.1.6   root     11672:             gen_arith(env, ctx, op1, rd, rs, rt);
1.1       root     11673:             break;
1.1.1.8   root     11674:         case OPC_SLLV:         /* Shifts */
                   11675:         case OPC_SRAV:
                   11676:             gen_shift(env, ctx, op1, rd, rs, rt);
                   11677:             break;
1.1.1.12  root     11678:         case OPC_SRLV:
                   11679:             switch ((ctx->opcode >> 6) & 0x1f) {
                   11680:             case 1:
                   11681:                 /* rotrv is decoded as srlv on non-R2 CPUs */
                   11682:                 if (env->insn_flags & ISA_MIPS32R2) {
                   11683:                     op1 = OPC_ROTRV;
                   11684:                 }
                   11685:                 /* Fallthrough */
                   11686:             case 0:
                   11687:                 gen_shift(env, ctx, op1, rd, rs, rt);
                   11688:                 break;
                   11689:             default:
                   11690:                 generate_exception(ctx, EXCP_RI);
                   11691:                 break;
                   11692:             }
                   11693:             break;
1.1.1.8   root     11694:         case OPC_SLT:          /* Set on less than */
                   11695:         case OPC_SLTU:
                   11696:             gen_slt(env, op1, rd, rs, rt);
                   11697:             break;
                   11698:         case OPC_AND:          /* Logic*/
                   11699:         case OPC_OR:
                   11700:         case OPC_NOR:
                   11701:         case OPC_XOR:
                   11702:             gen_logic(env, op1, rd, rs, rt);
                   11703:             break;
1.1.1.5   root     11704:         case OPC_MULT ... OPC_DIVU:
1.1.1.6   root     11705:             if (sa) {
                   11706:                 check_insn(env, ctx, INSN_VR54XX);
                   11707:                 op1 = MASK_MUL_VR54XX(ctx->opcode);
                   11708:                 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
                   11709:             } else
                   11710:                 gen_muldiv(ctx, op1, rs, rt);
1.1       root     11711:             break;
1.1.1.5   root     11712:         case OPC_JR ... OPC_JALR:
1.1.1.12  root     11713:             gen_compute_branch(ctx, op1, 4, rs, rd, sa);
                   11714:             *is_branch = 1;
                   11715:             break;
1.1.1.5   root     11716:         case OPC_TGE ... OPC_TEQ: /* Traps */
                   11717:         case OPC_TNE:
                   11718:             gen_trap(ctx, op1, rs, rt, -1);
                   11719:             break;
                   11720:         case OPC_MFHI:          /* Move from HI/LO */
                   11721:         case OPC_MFLO:
                   11722:             gen_HILO(ctx, op1, rd);
1.1       root     11723:             break;
1.1.1.5   root     11724:         case OPC_MTHI:
                   11725:         case OPC_MTLO:          /* Move to HI/LO */
                   11726:             gen_HILO(ctx, op1, rs);
                   11727:             break;
1.1.1.6   root     11728:         case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
                   11729: #ifdef MIPS_STRICT_STANDARD
                   11730:             MIPS_INVAL("PMON / selsl");
                   11731:             generate_exception(ctx, EXCP_RI);
                   11732: #else
1.1.1.7   root     11733:             gen_helper_0i(pmon, sa);
1.1.1.6   root     11734: #endif
1.1.1.5   root     11735:             break;
                   11736:         case OPC_SYSCALL:
1.1       root     11737:             generate_exception(ctx, EXCP_SYSCALL);
1.1.1.8   root     11738:             ctx->bstate = BS_STOP;
1.1       root     11739:             break;
1.1.1.5   root     11740:         case OPC_BREAK:
1.1       root     11741:             generate_exception(ctx, EXCP_BREAK);
                   11742:             break;
1.1.1.6   root     11743:         case OPC_SPIM:
                   11744: #ifdef MIPS_STRICT_STANDARD
                   11745:             MIPS_INVAL("SPIM");
                   11746:             generate_exception(ctx, EXCP_RI);
                   11747: #else
1.1.1.5   root     11748:            /* Implemented as RI exception for now. */
                   11749:             MIPS_INVAL("spim (unofficial)");
                   11750:             generate_exception(ctx, EXCP_RI);
1.1.1.6   root     11751: #endif
1.1       root     11752:             break;
1.1.1.5   root     11753:         case OPC_SYNC:
1.1.1.6   root     11754:             /* Treat as NOP. */
1.1       root     11755:             break;
1.1.1.2   root     11756: 
1.1.1.5   root     11757:         case OPC_MOVCI:
1.1.1.6   root     11758:             check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
                   11759:             if (env->CP0_Config1 & (1 << CP0C1_FP)) {
                   11760:                 check_cp1_enabled(ctx);
                   11761:                 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
                   11762:                           (ctx->opcode >> 16) & 1);
                   11763:             } else {
                   11764:                 generate_exception_err(ctx, EXCP_CpU, 1);
                   11765:             }
1.1.1.2   root     11766:             break;
                   11767: 
1.1.1.6   root     11768: #if defined(TARGET_MIPS64)
1.1.1.5   root     11769:        /* MIPS64 specific opcodes */
                   11770:         case OPC_DSLL:
1.1.1.8   root     11771:         case OPC_DSRA:
1.1.1.5   root     11772:         case OPC_DSLL32:
1.1.1.8   root     11773:         case OPC_DSRA32:
1.1.1.6   root     11774:             check_insn(env, ctx, ISA_MIPS3);
                   11775:             check_mips_64(ctx);
1.1.1.8   root     11776:             gen_shift_imm(env, ctx, op1, rd, rt, sa);
1.1.1.5   root     11777:             break;
1.1.1.12  root     11778:         case OPC_DSRL:
                   11779:             switch ((ctx->opcode >> 21) & 0x1f) {
                   11780:             case 1:
                   11781:                 /* drotr is decoded as dsrl on non-R2 CPUs */
                   11782:                 if (env->insn_flags & ISA_MIPS32R2) {
                   11783:                     op1 = OPC_DROTR;
                   11784:                 }
                   11785:                 /* Fallthrough */
                   11786:             case 0:
                   11787:                 check_insn(env, ctx, ISA_MIPS3);
                   11788:                 check_mips_64(ctx);
                   11789:                 gen_shift_imm(env, ctx, op1, rd, rt, sa);
                   11790:                 break;
                   11791:             default:
                   11792:                 generate_exception(ctx, EXCP_RI);
                   11793:                 break;
                   11794:             }
                   11795:             break;
                   11796:         case OPC_DSRL32:
                   11797:             switch ((ctx->opcode >> 21) & 0x1f) {
                   11798:             case 1:
                   11799:                 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
                   11800:                 if (env->insn_flags & ISA_MIPS32R2) {
                   11801:                     op1 = OPC_DROTR32;
                   11802:                 }
                   11803:                 /* Fallthrough */
                   11804:             case 0:
                   11805:                 check_insn(env, ctx, ISA_MIPS3);
                   11806:                 check_mips_64(ctx);
                   11807:                 gen_shift_imm(env, ctx, op1, rd, rt, sa);
                   11808:                 break;
                   11809:             default:
                   11810:                 generate_exception(ctx, EXCP_RI);
                   11811:                 break;
                   11812:             }
                   11813:             break;
1.1.1.5   root     11814:         case OPC_DADD ... OPC_DSUBU:
1.1.1.6   root     11815:             check_insn(env, ctx, ISA_MIPS3);
                   11816:             check_mips_64(ctx);
                   11817:             gen_arith(env, ctx, op1, rd, rs, rt);
1.1.1.5   root     11818:             break;
1.1.1.8   root     11819:         case OPC_DSLLV:
                   11820:         case OPC_DSRAV:
                   11821:             check_insn(env, ctx, ISA_MIPS3);
                   11822:             check_mips_64(ctx);
                   11823:             gen_shift(env, ctx, op1, rd, rs, rt);
                   11824:             break;
1.1.1.12  root     11825:         case OPC_DSRLV:
                   11826:             switch ((ctx->opcode >> 6) & 0x1f) {
                   11827:             case 1:
                   11828:                 /* drotrv is decoded as dsrlv on non-R2 CPUs */
                   11829:                 if (env->insn_flags & ISA_MIPS32R2) {
                   11830:                     op1 = OPC_DROTRV;
                   11831:                 }
                   11832:                 /* Fallthrough */
                   11833:             case 0:
                   11834:                 check_insn(env, ctx, ISA_MIPS3);
                   11835:                 check_mips_64(ctx);
                   11836:                 gen_shift(env, ctx, op1, rd, rs, rt);
                   11837:                 break;
                   11838:             default:
                   11839:                 generate_exception(ctx, EXCP_RI);
                   11840:                 break;
                   11841:             }
                   11842:             break;
1.1.1.5   root     11843:         case OPC_DMULT ... OPC_DDIVU:
1.1.1.6   root     11844:             check_insn(env, ctx, ISA_MIPS3);
                   11845:             check_mips_64(ctx);
1.1.1.5   root     11846:             gen_muldiv(ctx, op1, rs, rt);
                   11847:             break;
1.1       root     11848: #endif
                   11849:         default:            /* Invalid */
                   11850:             MIPS_INVAL("special");
                   11851:             generate_exception(ctx, EXCP_RI);
                   11852:             break;
                   11853:         }
                   11854:         break;
1.1.1.5   root     11855:     case OPC_SPECIAL2:
                   11856:         op1 = MASK_SPECIAL2(ctx->opcode);
1.1       root     11857:         switch (op1) {
1.1.1.5   root     11858:         case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
                   11859:         case OPC_MSUB ... OPC_MSUBU:
1.1.1.6   root     11860:             check_insn(env, ctx, ISA_MIPS32);
1.1.1.5   root     11861:             gen_muldiv(ctx, op1, rs, rt);
1.1       root     11862:             break;
1.1.1.5   root     11863:         case OPC_MUL:
1.1.1.6   root     11864:             gen_arith(env, ctx, op1, rd, rs, rt);
1.1       root     11865:             break;
1.1.1.8   root     11866:         case OPC_CLO:
                   11867:         case OPC_CLZ:
1.1.1.6   root     11868:             check_insn(env, ctx, ISA_MIPS32);
1.1.1.5   root     11869:             gen_cl(ctx, op1, rd, rs);
1.1       root     11870:             break;
1.1.1.5   root     11871:         case OPC_SDBBP:
1.1       root     11872:             /* XXX: not clear which exception should be raised
                   11873:              *      when in debug mode...
                   11874:              */
1.1.1.6   root     11875:             check_insn(env, ctx, ISA_MIPS32);
1.1       root     11876:             if (!(ctx->hflags & MIPS_HFLAG_DM)) {
                   11877:                 generate_exception(ctx, EXCP_DBp);
                   11878:             } else {
                   11879:                 generate_exception(ctx, EXCP_DBp);
                   11880:             }
1.1.1.6   root     11881:             /* Treat as NOP. */
1.1       root     11882:             break;
1.1.1.12  root     11883:         case OPC_DIV_G_2F:
                   11884:         case OPC_DIVU_G_2F:
                   11885:         case OPC_MULT_G_2F:
                   11886:         case OPC_MULTU_G_2F:
                   11887:         case OPC_MOD_G_2F:
                   11888:         case OPC_MODU_G_2F:
                   11889:             check_insn(env, ctx, INSN_LOONGSON2F);
                   11890:             gen_loongson_integer(ctx, op1, rd, rs, rt);
                   11891:             break;
1.1.1.6   root     11892: #if defined(TARGET_MIPS64)
1.1.1.8   root     11893:         case OPC_DCLO:
                   11894:         case OPC_DCLZ:
1.1.1.6   root     11895:             check_insn(env, ctx, ISA_MIPS64);
                   11896:             check_mips_64(ctx);
1.1.1.5   root     11897:             gen_cl(ctx, op1, rd, rs);
                   11898:             break;
1.1.1.12  root     11899:         case OPC_DMULT_G_2F:
                   11900:         case OPC_DMULTU_G_2F:
                   11901:         case OPC_DDIV_G_2F:
                   11902:         case OPC_DDIVU_G_2F:
                   11903:         case OPC_DMOD_G_2F:
                   11904:         case OPC_DMODU_G_2F:
                   11905:             check_insn(env, ctx, INSN_LOONGSON2F);
                   11906:             gen_loongson_integer(ctx, op1, rd, rs, rt);
                   11907:             break;
1.1.1.5   root     11908: #endif
1.1       root     11909:         default:            /* Invalid */
                   11910:             MIPS_INVAL("special2");
                   11911:             generate_exception(ctx, EXCP_RI);
                   11912:             break;
                   11913:         }
                   11914:         break;
1.1.1.5   root     11915:     case OPC_SPECIAL3:
1.1.1.7   root     11916:         op1 = MASK_SPECIAL3(ctx->opcode);
                   11917:         switch (op1) {
                   11918:         case OPC_EXT:
                   11919:         case OPC_INS:
                   11920:             check_insn(env, ctx, ISA_MIPS32R2);
                   11921:             gen_bitops(ctx, op1, rt, rs, sa, rd);
                   11922:             break;
                   11923:         case OPC_BSHFL:
                   11924:             check_insn(env, ctx, ISA_MIPS32R2);
                   11925:             op2 = MASK_BSHFL(ctx->opcode);
                   11926:             gen_bshfl(ctx, op2, rt, rd);
1.1.1.6   root     11927:             break;
                   11928:         case OPC_RDHWR:
1.1.1.12  root     11929:             gen_rdhwr(env, ctx, rt, rd);
1.1.1.6   root     11930:             break;
                   11931:         case OPC_FORK:
                   11932:             check_insn(env, ctx, ASE_MT);
1.1.1.7   root     11933:             {
1.1.1.8   root     11934:                 TCGv t0 = tcg_temp_new();
                   11935:                 TCGv t1 = tcg_temp_new();
1.1.1.7   root     11936: 
                   11937:                 gen_load_gpr(t0, rt);
                   11938:                 gen_load_gpr(t1, rs);
                   11939:                 gen_helper_fork(t0, t1);
                   11940:                 tcg_temp_free(t0);
                   11941:                 tcg_temp_free(t1);
                   11942:             }
1.1.1.6   root     11943:             break;
                   11944:         case OPC_YIELD:
                   11945:             check_insn(env, ctx, ASE_MT);
1.1.1.7   root     11946:             {
1.1.1.8   root     11947:                 TCGv t0 = tcg_temp_new();
1.1.1.7   root     11948: 
1.1.1.8   root     11949:                 save_cpu_state(ctx, 1);
1.1.1.7   root     11950:                 gen_load_gpr(t0, rs);
                   11951:                 gen_helper_yield(t0, t0);
                   11952:                 gen_store_gpr(t0, rd);
                   11953:                 tcg_temp_free(t0);
                   11954:             }
1.1.1.6   root     11955:             break;
1.1.1.12  root     11956:         case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
                   11957:         case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
                   11958:         case OPC_MOD_G_2E ... OPC_MODU_G_2E:
                   11959:             check_insn(env, ctx, INSN_LOONGSON2E);
                   11960:             gen_loongson_integer(ctx, op1, rd, rs, rt);
                   11961:             break;
1.1.1.6   root     11962: #if defined(TARGET_MIPS64)
                   11963:         case OPC_DEXTM ... OPC_DEXT:
                   11964:         case OPC_DINSM ... OPC_DINS:
                   11965:             check_insn(env, ctx, ISA_MIPS64R2);
                   11966:             check_mips_64(ctx);
1.1.1.5   root     11967:             gen_bitops(ctx, op1, rt, rs, sa, rd);
                   11968:             break;
1.1.1.6   root     11969:         case OPC_DBSHFL:
                   11970:             check_insn(env, ctx, ISA_MIPS64R2);
                   11971:             check_mips_64(ctx);
                   11972:             op2 = MASK_DBSHFL(ctx->opcode);
1.1.1.7   root     11973:             gen_bshfl(ctx, op2, rt, rd);
1.1.1.6   root     11974:             break;
1.1.1.12  root     11975:         case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
                   11976:         case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
                   11977:         case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
                   11978:             check_insn(env, ctx, INSN_LOONGSON2E);
                   11979:             gen_loongson_integer(ctx, op1, rd, rs, rt);
                   11980:             break;
1.1.1.5   root     11981: #endif
                   11982:         default:            /* Invalid */
                   11983:             MIPS_INVAL("special3");
                   11984:             generate_exception(ctx, EXCP_RI);
                   11985:             break;
                   11986:         }
                   11987:         break;
                   11988:     case OPC_REGIMM:
                   11989:         op1 = MASK_REGIMM(ctx->opcode);
1.1       root     11990:         switch (op1) {
1.1.1.5   root     11991:         case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
                   11992:         case OPC_BLTZAL ... OPC_BGEZALL:
1.1.1.12  root     11993:             gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
                   11994:             *is_branch = 1;
                   11995:             break;
1.1.1.5   root     11996:         case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
                   11997:         case OPC_TNEI:
                   11998:             gen_trap(ctx, op1, rs, -1, imm);
                   11999:             break;
                   12000:         case OPC_SYNCI:
1.1.1.6   root     12001:             check_insn(env, ctx, ISA_MIPS32R2);
                   12002:             /* Treat as NOP. */
1.1       root     12003:             break;
                   12004:         default:            /* Invalid */
1.1.1.6   root     12005:             MIPS_INVAL("regimm");
1.1       root     12006:             generate_exception(ctx, EXCP_RI);
                   12007:             break;
                   12008:         }
                   12009:         break;
1.1.1.5   root     12010:     case OPC_CP0:
1.1.1.6   root     12011:         check_cp0_enabled(ctx);
1.1.1.5   root     12012:         op1 = MASK_CP0(ctx->opcode);
1.1       root     12013:         switch (op1) {
1.1.1.5   root     12014:         case OPC_MFC0:
                   12015:         case OPC_MTC0:
1.1.1.6   root     12016:         case OPC_MFTR:
                   12017:         case OPC_MTTR:
                   12018: #if defined(TARGET_MIPS64)
1.1.1.5   root     12019:         case OPC_DMFC0:
                   12020:         case OPC_DMTC0:
                   12021: #endif
1.1.1.7   root     12022: #ifndef CONFIG_USER_ONLY
1.1.1.6   root     12023:             gen_cp0(env, ctx, op1, rt, rd);
1.1.1.7   root     12024: #endif /* !CONFIG_USER_ONLY */
1.1.1.5   root     12025:             break;
                   12026:         case OPC_C0_FIRST ... OPC_C0_LAST:
1.1.1.7   root     12027: #ifndef CONFIG_USER_ONLY
1.1.1.6   root     12028:             gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
1.1.1.7   root     12029: #endif /* !CONFIG_USER_ONLY */
1.1.1.5   root     12030:             break;
                   12031:         case OPC_MFMC0:
1.1.1.7   root     12032: #ifndef CONFIG_USER_ONLY
                   12033:             {
1.1.1.8   root     12034:                 TCGv t0 = tcg_temp_new();
1.1.1.7   root     12035: 
                   12036:                 op2 = MASK_MFMC0(ctx->opcode);
                   12037:                 switch (op2) {
                   12038:                 case OPC_DMT:
                   12039:                     check_insn(env, ctx, ASE_MT);
1.1.1.13! root     12040:                     gen_helper_dmt(t0);
1.1.1.8   root     12041:                     gen_store_gpr(t0, rt);
1.1.1.7   root     12042:                     break;
                   12043:                 case OPC_EMT:
                   12044:                     check_insn(env, ctx, ASE_MT);
1.1.1.13! root     12045:                     gen_helper_emt(t0);
1.1.1.8   root     12046:                     gen_store_gpr(t0, rt);
1.1.1.7   root     12047:                     break;
                   12048:                 case OPC_DVPE:
                   12049:                     check_insn(env, ctx, ASE_MT);
1.1.1.13! root     12050:                     gen_helper_dvpe(t0);
1.1.1.8   root     12051:                     gen_store_gpr(t0, rt);
1.1.1.7   root     12052:                     break;
                   12053:                 case OPC_EVPE:
                   12054:                     check_insn(env, ctx, ASE_MT);
1.1.1.13! root     12055:                     gen_helper_evpe(t0);
1.1.1.8   root     12056:                     gen_store_gpr(t0, rt);
1.1.1.7   root     12057:                     break;
                   12058:                 case OPC_DI:
                   12059:                     check_insn(env, ctx, ISA_MIPS32R2);
                   12060:                     save_cpu_state(ctx, 1);
                   12061:                     gen_helper_di(t0);
1.1.1.8   root     12062:                     gen_store_gpr(t0, rt);
1.1.1.7   root     12063:                     /* Stop translation as we may have switched the execution mode */
                   12064:                     ctx->bstate = BS_STOP;
                   12065:                     break;
                   12066:                 case OPC_EI:
                   12067:                     check_insn(env, ctx, ISA_MIPS32R2);
                   12068:                     save_cpu_state(ctx, 1);
                   12069:                     gen_helper_ei(t0);
1.1.1.8   root     12070:                     gen_store_gpr(t0, rt);
1.1.1.7   root     12071:                     /* Stop translation as we may have switched the execution mode */
                   12072:                     ctx->bstate = BS_STOP;
                   12073:                     break;
                   12074:                 default:            /* Invalid */
                   12075:                     MIPS_INVAL("mfmc0");
                   12076:                     generate_exception(ctx, EXCP_RI);
                   12077:                     break;
                   12078:                 }
                   12079:                 tcg_temp_free(t0);
1.1.1.5   root     12080:             }
1.1.1.7   root     12081: #endif /* !CONFIG_USER_ONLY */
1.1       root     12082:             break;
1.1.1.5   root     12083:         case OPC_RDPGPR:
1.1.1.6   root     12084:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7   root     12085:             gen_load_srsgpr(rt, rd);
1.1.1.6   root     12086:             break;
1.1.1.5   root     12087:         case OPC_WRPGPR:
1.1.1.6   root     12088:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7   root     12089:             gen_store_srsgpr(rt, rd);
1.1.1.6   root     12090:             break;
1.1       root     12091:         default:
1.1.1.6   root     12092:             MIPS_INVAL("cp0");
1.1.1.5   root     12093:             generate_exception(ctx, EXCP_RI);
1.1       root     12094:             break;
                   12095:         }
                   12096:         break;
1.1.1.8   root     12097:     case OPC_ADDI: /* Arithmetic with immediate opcode */
                   12098:     case OPC_ADDIU:
1.1.1.6   root     12099:          gen_arith_imm(env, ctx, op, rt, rs, imm);
1.1.1.5   root     12100:          break;
1.1.1.8   root     12101:     case OPC_SLTI: /* Set on less than with immediate opcode */
                   12102:     case OPC_SLTIU:
                   12103:          gen_slt_imm(env, op, rt, rs, imm);
                   12104:          break;
                   12105:     case OPC_ANDI: /* Arithmetic with immediate opcode */
                   12106:     case OPC_LUI:
                   12107:     case OPC_ORI:
                   12108:     case OPC_XORI:
                   12109:          gen_logic_imm(env, op, rt, rs, imm);
                   12110:          break;
1.1.1.5   root     12111:     case OPC_J ... OPC_JAL: /* Jump */
                   12112:          offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
1.1.1.12  root     12113:          gen_compute_branch(ctx, op, 4, rs, rt, offset);
                   12114:          *is_branch = 1;
                   12115:          break;
1.1.1.5   root     12116:     case OPC_BEQ ... OPC_BGTZ: /* Branch */
                   12117:     case OPC_BEQL ... OPC_BGTZL:
1.1.1.12  root     12118:          gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
                   12119:          *is_branch = 1;
                   12120:          break;
1.1.1.5   root     12121:     case OPC_LB ... OPC_LWR: /* Load and stores */
1.1.1.12  root     12122:     case OPC_LL:
                   12123:          gen_ld(env, ctx, op, rt, rs, imm);
                   12124:          break;
1.1.1.5   root     12125:     case OPC_SB ... OPC_SW:
                   12126:     case OPC_SWR:
1.1.1.12  root     12127:          gen_st(ctx, op, rt, rs, imm);
1.1.1.5   root     12128:          break;
1.1.1.8   root     12129:     case OPC_SC:
                   12130:          gen_st_cond(ctx, op, rt, rs, imm);
                   12131:          break;
1.1.1.5   root     12132:     case OPC_CACHE:
1.1.1.6   root     12133:         check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
                   12134:         /* Treat as NOP. */
                   12135:         break;
1.1.1.5   root     12136:     case OPC_PREF:
1.1.1.6   root     12137:         check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
                   12138:         /* Treat as NOP. */
1.1       root     12139:         break;
1.1.1.2   root     12140: 
1.1.1.6   root     12141:     /* Floating point (COP1). */
1.1.1.5   root     12142:     case OPC_LWC1:
                   12143:     case OPC_LDC1:
                   12144:     case OPC_SWC1:
                   12145:     case OPC_SDC1:
1.1.1.12  root     12146:         gen_cop1_ldst(env, ctx, op, rt, rs, imm);
1.1.1.4   root     12147:         break;
                   12148: 
1.1.1.5   root     12149:     case OPC_CP1:
1.1.1.6   root     12150:         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
                   12151:             check_cp1_enabled(ctx);
                   12152:             op1 = MASK_CP1(ctx->opcode);
                   12153:             switch (op1) {
                   12154:             case OPC_MFHC1:
                   12155:             case OPC_MTHC1:
                   12156:                 check_insn(env, ctx, ISA_MIPS32R2);
                   12157:             case OPC_MFC1:
                   12158:             case OPC_CFC1:
                   12159:             case OPC_MTC1:
                   12160:             case OPC_CTC1:
                   12161:                 gen_cp1(ctx, op1, rt, rd);
                   12162:                 break;
                   12163: #if defined(TARGET_MIPS64)
                   12164:             case OPC_DMFC1:
                   12165:             case OPC_DMTC1:
                   12166:                 check_insn(env, ctx, ISA_MIPS3);
                   12167:                 gen_cp1(ctx, op1, rt, rd);
                   12168:                 break;
1.1.1.5   root     12169: #endif
1.1.1.6   root     12170:             case OPC_BC1ANY2:
                   12171:             case OPC_BC1ANY4:
                   12172:                 check_cop1x(ctx);
                   12173:                 check_insn(env, ctx, ASE_MIPS3D);
                   12174:                 /* fall through */
                   12175:             case OPC_BC1:
                   12176:                 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
                   12177:                                     (rt >> 2) & 0x7, imm << 2);
1.1.1.12  root     12178:                 *is_branch = 1;
                   12179:                 break;
1.1.1.6   root     12180:             case OPC_S_FMT:
                   12181:             case OPC_D_FMT:
                   12182:             case OPC_W_FMT:
                   12183:             case OPC_L_FMT:
                   12184:             case OPC_PS_FMT:
1.1.1.12  root     12185:                 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
1.1.1.6   root     12186:                            (imm >> 8) & 0x7);
                   12187:                 break;
                   12188:             default:
                   12189:                 MIPS_INVAL("cp1");
                   12190:                 generate_exception (ctx, EXCP_RI);
                   12191:                 break;
                   12192:             }
                   12193:         } else {
                   12194:             generate_exception_err(ctx, EXCP_CpU, 1);
1.1.1.4   root     12195:         }
1.1.1.2   root     12196:         break;
                   12197: 
                   12198:     /* COP2.  */
1.1.1.5   root     12199:     case OPC_LWC2:
                   12200:     case OPC_LDC2:
                   12201:     case OPC_SWC2:
                   12202:     case OPC_SDC2:
                   12203:     case OPC_CP2:
                   12204:         /* COP2: Not implemented. */
1.1.1.2   root     12205:         generate_exception_err(ctx, EXCP_CpU, 2);
                   12206:         break;
                   12207: 
1.1.1.5   root     12208:     case OPC_CP3:
1.1.1.6   root     12209:         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
                   12210:             check_cp1_enabled(ctx);
                   12211:             op1 = MASK_CP3(ctx->opcode);
                   12212:             switch (op1) {
                   12213:             case OPC_LWXC1:
                   12214:             case OPC_LDXC1:
                   12215:             case OPC_LUXC1:
                   12216:             case OPC_SWXC1:
                   12217:             case OPC_SDXC1:
                   12218:             case OPC_SUXC1:
                   12219:                 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
                   12220:                 break;
                   12221:             case OPC_PREFX:
                   12222:                 /* Treat as NOP. */
                   12223:                 break;
                   12224:             case OPC_ALNV_PS:
                   12225:             case OPC_MADD_S:
                   12226:             case OPC_MADD_D:
                   12227:             case OPC_MADD_PS:
                   12228:             case OPC_MSUB_S:
                   12229:             case OPC_MSUB_D:
                   12230:             case OPC_MSUB_PS:
                   12231:             case OPC_NMADD_S:
                   12232:             case OPC_NMADD_D:
                   12233:             case OPC_NMADD_PS:
                   12234:             case OPC_NMSUB_S:
                   12235:             case OPC_NMSUB_D:
                   12236:             case OPC_NMSUB_PS:
                   12237:                 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
                   12238:                 break;
                   12239:             default:
                   12240:                 MIPS_INVAL("cp3");
                   12241:                 generate_exception (ctx, EXCP_RI);
                   12242:                 break;
                   12243:             }
                   12244:         } else {
                   12245:             generate_exception_err(ctx, EXCP_CpU, 1);
1.1.1.5   root     12246:         }
1.1.1.2   root     12247:         break;
                   12248: 
1.1.1.6   root     12249: #if defined(TARGET_MIPS64)
1.1.1.5   root     12250:     /* MIPS64 opcodes */
                   12251:     case OPC_LWU:
                   12252:     case OPC_LDL ... OPC_LDR:
                   12253:     case OPC_LLD:
                   12254:     case OPC_LD:
1.1.1.12  root     12255:         check_insn(env, ctx, ISA_MIPS3);
                   12256:         check_mips_64(ctx);
                   12257:         gen_ld(env, ctx, op, rt, rs, imm);
                   12258:         break;
                   12259:     case OPC_SDL ... OPC_SDR:
1.1.1.5   root     12260:     case OPC_SD:
1.1.1.6   root     12261:         check_insn(env, ctx, ISA_MIPS3);
                   12262:         check_mips_64(ctx);
1.1.1.12  root     12263:         gen_st(ctx, op, rt, rs, imm);
1.1.1.5   root     12264:         break;
1.1.1.8   root     12265:     case OPC_SCD:
                   12266:         check_insn(env, ctx, ISA_MIPS3);
                   12267:         check_mips_64(ctx);
                   12268:         gen_st_cond(ctx, op, rt, rs, imm);
                   12269:         break;
                   12270:     case OPC_DADDI:
                   12271:     case OPC_DADDIU:
1.1.1.6   root     12272:         check_insn(env, ctx, ISA_MIPS3);
                   12273:         check_mips_64(ctx);
                   12274:         gen_arith_imm(env, ctx, op, rt, rs, imm);
1.1.1.5   root     12275:         break;
                   12276: #endif
                   12277:     case OPC_JALX:
1.1.1.12  root     12278:         check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
                   12279:         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
                   12280:         gen_compute_branch(ctx, op, 4, rs, rt, offset);
                   12281:         *is_branch = 1;
                   12282:         break;
1.1.1.5   root     12283:     case OPC_MDMX:
1.1.1.6   root     12284:         check_insn(env, ctx, ASE_MDMX);
1.1.1.5   root     12285:         /* MDMX: Not implemented. */
1.1       root     12286:     default:            /* Invalid */
1.1.1.6   root     12287:         MIPS_INVAL("major opcode");
1.1       root     12288:         generate_exception(ctx, EXCP_RI);
                   12289:         break;
                   12290:     }
                   12291: }
                   12292: 
1.1.1.7   root     12293: static inline void
1.1.1.6   root     12294: gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
                   12295:                                 int search_pc)
1.1       root     12296: {
1.1.1.6   root     12297:     DisasContext ctx;
1.1       root     12298:     target_ulong pc_start;
                   12299:     uint16_t *gen_opc_end;
1.1.1.7   root     12300:     CPUBreakpoint *bp;
1.1       root     12301:     int j, lj = -1;
1.1.1.7   root     12302:     int num_insns;
                   12303:     int max_insns;
1.1.1.12  root     12304:     int insn_bytes;
                   12305:     int is_branch;
1.1       root     12306: 
1.1.1.7   root     12307:     if (search_pc)
                   12308:         qemu_log("search pc %d\n", search_pc);
1.1.1.2   root     12309: 
1.1       root     12310:     pc_start = tb->pc;
1.1.1.9   root     12311:     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1.1       root     12312:     ctx.pc = pc_start;
1.1.1.2   root     12313:     ctx.saved_pc = -1;
1.1.1.9   root     12314:     ctx.singlestep_enabled = env->singlestep_enabled;
1.1       root     12315:     ctx.tb = tb;
                   12316:     ctx.bstate = BS_NONE;
1.1.1.2   root     12317:     /* Restore delay slot state from the tb context.  */
1.1.1.6   root     12318:     ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
                   12319:     restore_cpu_state(env, &ctx);
1.1.1.7   root     12320: #ifdef CONFIG_USER_ONLY
                   12321:         ctx.mem_idx = MIPS_HFLAG_UM;
1.1       root     12322: #else
1.1.1.7   root     12323:         ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
1.1       root     12324: #endif
1.1.1.7   root     12325:     num_insns = 0;
                   12326:     max_insns = tb->cflags & CF_COUNT_MASK;
                   12327:     if (max_insns == 0)
                   12328:         max_insns = CF_COUNT_MASK;
                   12329:     LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
                   12330:     gen_icount_start();
                   12331:     while (ctx.bstate == BS_NONE) {
1.1.1.9   root     12332:         if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
                   12333:             QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
1.1.1.7   root     12334:                 if (bp->pc == ctx.pc) {
1.1.1.6   root     12335:                     save_cpu_state(&ctx, 1);
1.1.1.2   root     12336:                     ctx.bstate = BS_BRANCH;
1.1.1.7   root     12337:                     gen_helper_0i(raise_exception, EXCP_DEBUG);
1.1.1.6   root     12338:                     /* Include the breakpoint location or the tb won't
                   12339:                      * be flushed when it must be.  */
                   12340:                     ctx.pc += 4;
1.1.1.2   root     12341:                     goto done_generating;
                   12342:                 }
                   12343:             }
                   12344:         }
                   12345: 
1.1       root     12346:         if (search_pc) {
                   12347:             j = gen_opc_ptr - gen_opc_buf;
                   12348:             if (lj < j) {
                   12349:                 lj++;
                   12350:                 while (lj < j)
                   12351:                     gen_opc_instr_start[lj++] = 0;
                   12352:             }
1.1.1.2   root     12353:             gen_opc_pc[lj] = ctx.pc;
                   12354:             gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
                   12355:             gen_opc_instr_start[lj] = 1;
1.1.1.7   root     12356:             gen_opc_icount[lj] = num_insns;
1.1       root     12357:         }
1.1.1.7   root     12358:         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
                   12359:             gen_io_start();
1.1.1.12  root     12360: 
                   12361:         is_branch = 0;
                   12362:         if (!(ctx.hflags & MIPS_HFLAG_M16)) {
                   12363:             ctx.opcode = ldl_code(ctx.pc);
                   12364:             insn_bytes = 4;
                   12365:             decode_opc(env, &ctx, &is_branch);
                   12366:         } else if (env->insn_flags & ASE_MICROMIPS) {
                   12367:             ctx.opcode = lduw_code(ctx.pc);
                   12368:             insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
                   12369:         } else if (env->insn_flags & ASE_MIPS16) {
                   12370:             ctx.opcode = lduw_code(ctx.pc);
                   12371:             insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
                   12372:         } else {
                   12373:             generate_exception(&ctx, EXCP_RI);
                   12374:             ctx.bstate = BS_STOP;
                   12375:             break;
                   12376:         }
                   12377:         if (!is_branch) {
                   12378:             handle_delay_slot(env, &ctx, insn_bytes);
                   12379:         }
                   12380:         ctx.pc += insn_bytes;
                   12381: 
1.1.1.7   root     12382:         num_insns++;
1.1.1.2   root     12383: 
1.1.1.9   root     12384:         /* Execute a branch and its delay slot as a single instruction.
                   12385:            This is what GDB expects and is consistent with what the
                   12386:            hardware does (e.g. if a delay slot instruction faults, the
                   12387:            reported PC is the PC of the branch).  */
                   12388:         if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
1.1.1.2   root     12389:             break;
                   12390: 
1.1       root     12391:         if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
                   12392:             break;
1.1.1.2   root     12393: 
1.1.1.7   root     12394:         if (gen_opc_ptr >= gen_opc_end)
                   12395:             break;
                   12396: 
                   12397:         if (num_insns >= max_insns)
                   12398:             break;
1.1.1.8   root     12399: 
                   12400:         if (singlestep)
                   12401:             break;
1.1       root     12402:     }
1.1.1.7   root     12403:     if (tb->cflags & CF_LAST_IO)
                   12404:         gen_io_end();
1.1.1.9   root     12405:     if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
1.1.1.6   root     12406:         save_cpu_state(&ctx, ctx.bstate == BS_NONE);
1.1.1.7   root     12407:         gen_helper_0i(raise_exception, EXCP_DEBUG);
1.1.1.6   root     12408:     } else {
1.1.1.7   root     12409:         switch (ctx.bstate) {
1.1.1.6   root     12410:         case BS_STOP:
                   12411:             gen_goto_tb(&ctx, 0, ctx.pc);
                   12412:             break;
                   12413:         case BS_NONE:
                   12414:             save_cpu_state(&ctx, 0);
                   12415:             gen_goto_tb(&ctx, 0, ctx.pc);
                   12416:             break;
                   12417:         case BS_EXCP:
1.1.1.7   root     12418:             tcg_gen_exit_tb(0);
1.1.1.6   root     12419:             break;
                   12420:         case BS_BRANCH:
                   12421:         default:
                   12422:             break;
1.1.1.7   root     12423:         }
1.1       root     12424:     }
1.1.1.2   root     12425: done_generating:
1.1.1.7   root     12426:     gen_icount_end(tb, num_insns);
1.1       root     12427:     *gen_opc_ptr = INDEX_op_end;
                   12428:     if (search_pc) {
                   12429:         j = gen_opc_ptr - gen_opc_buf;
                   12430:         lj++;
                   12431:         while (lj <= j)
                   12432:             gen_opc_instr_start[lj++] = 0;
                   12433:     } else {
                   12434:         tb->size = ctx.pc - pc_start;
1.1.1.7   root     12435:         tb->icount = num_insns;
1.1       root     12436:     }
                   12437: #ifdef DEBUG_DISAS
1.1.1.7   root     12438:     LOG_DISAS("\n");
                   12439:     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
                   12440:         qemu_log("IN: %s\n", lookup_symbol(pc_start));
                   12441:         log_target_disas(pc_start, ctx.pc - pc_start, 0);
                   12442:         qemu_log("\n");
1.1       root     12443:     }
                   12444: #endif
                   12445: }
                   12446: 
1.1.1.7   root     12447: void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
1.1       root     12448: {
1.1.1.7   root     12449:     gen_intermediate_code_internal(env, tb, 0);
1.1       root     12450: }
                   12451: 
1.1.1.7   root     12452: void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
1.1       root     12453: {
1.1.1.7   root     12454:     gen_intermediate_code_internal(env, tb, 1);
1.1       root     12455: }
                   12456: 
1.1.1.13! root     12457: static void fpu_dump_state(CPUState *env, FILE *f, fprintf_function fpu_fprintf,
1.1.1.7   root     12458:                            int flags)
1.1.1.4   root     12459: {
                   12460:     int i;
1.1.1.6   root     12461:     int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
1.1.1.4   root     12462: 
1.1.1.12  root     12463: #define printfpr(fp)                                                    \
                   12464:     do {                                                                \
                   12465:         if (is_fpu64)                                                   \
                   12466:             fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
                   12467:                         " fd:%13g fs:%13g psu: %13g\n",                 \
                   12468:                         (fp)->w[FP_ENDIAN_IDX], (fp)->d,                \
                   12469:                         (double)(fp)->fd,                               \
                   12470:                         (double)(fp)->fs[FP_ENDIAN_IDX],                \
                   12471:                         (double)(fp)->fs[!FP_ENDIAN_IDX]);              \
                   12472:         else {                                                          \
                   12473:             fpr_t tmp;                                                  \
                   12474:             tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
                   12475:             tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
                   12476:             fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
                   12477:                         " fd:%13g fs:%13g psu:%13g\n",                  \
                   12478:                         tmp.w[FP_ENDIAN_IDX], tmp.d,                    \
                   12479:                         (double)tmp.fd,                                 \
                   12480:                         (double)tmp.fs[FP_ENDIAN_IDX],                  \
                   12481:                         (double)tmp.fs[!FP_ENDIAN_IDX]);                \
                   12482:         }                                                               \
1.1.1.4   root     12483:     } while(0)
                   12484: 
1.1.1.6   root     12485: 
1.1.1.13! root     12486:     fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%02x\n",
        !          12487:                 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
1.1.1.7   root     12488:                 get_float_exception_flags(&env->active_fpu.fp_status));
1.1.1.6   root     12489:     for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
                   12490:         fpu_fprintf(f, "%3s: ", fregnames[i]);
1.1.1.7   root     12491:         printfpr(&env->active_fpu.fpr[i]);
1.1.1.4   root     12492:     }
                   12493: 
                   12494: #undef printfpr
                   12495: }
                   12496: 
1.1.1.6   root     12497: #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
1.1.1.5   root     12498: /* Debug help: The architecture requires 32bit code to maintain proper
1.1.1.7   root     12499:    sign-extended values on 64bit machines.  */
1.1.1.5   root     12500: 
                   12501: #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
                   12502: 
1.1.1.7   root     12503: static void
                   12504: cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
1.1.1.13! root     12505:                                 fprintf_function cpu_fprintf,
1.1.1.7   root     12506:                                 int flags)
1.1.1.5   root     12507: {
                   12508:     int i;
                   12509: 
1.1.1.7   root     12510:     if (!SIGN_EXT_P(env->active_tc.PC))
                   12511:         cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
                   12512:     if (!SIGN_EXT_P(env->active_tc.HI[0]))
                   12513:         cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
                   12514:     if (!SIGN_EXT_P(env->active_tc.LO[0]))
                   12515:         cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
1.1.1.5   root     12516:     if (!SIGN_EXT_P(env->btarget))
1.1.1.6   root     12517:         cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
1.1.1.5   root     12518: 
                   12519:     for (i = 0; i < 32; i++) {
1.1.1.7   root     12520:         if (!SIGN_EXT_P(env->active_tc.gpr[i]))
                   12521:             cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
1.1.1.5   root     12522:     }
                   12523: 
                   12524:     if (!SIGN_EXT_P(env->CP0_EPC))
1.1.1.6   root     12525:         cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
1.1.1.9   root     12526:     if (!SIGN_EXT_P(env->lladdr))
                   12527:         cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
1.1.1.5   root     12528: }
                   12529: #endif
                   12530: 
1.1.1.13! root     12531: void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
1.1       root     12532:                      int flags)
                   12533: {
                   12534:     int i;
1.1.1.6   root     12535: 
1.1.1.12  root     12536:     cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
                   12537:                 " LO=0x" TARGET_FMT_lx " ds %04x "
                   12538:                 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
1.1.1.7   root     12539:                 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
                   12540:                 env->hflags, env->btarget, env->bcond);
1.1       root     12541:     for (i = 0; i < 32; i++) {
                   12542:         if ((i & 3) == 0)
                   12543:             cpu_fprintf(f, "GPR%02d:", i);
1.1.1.7   root     12544:         cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
1.1       root     12545:         if ((i & 3) == 3)
                   12546:             cpu_fprintf(f, "\n");
                   12547:     }
                   12548: 
1.1.1.6   root     12549:     cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
                   12550:                 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
                   12551:     cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
1.1.1.9   root     12552:                 env->CP0_Config0, env->CP0_Config1, env->lladdr);
1.1.1.6   root     12553:     if (env->hflags & MIPS_HFLAG_FPU)
1.1.1.5   root     12554:         fpu_dump_state(env, f, cpu_fprintf, flags);
1.1.1.6   root     12555: #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
1.1.1.5   root     12556:     cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
1.1.1.4   root     12557: #endif
1.1       root     12558: }
                   12559: 
1.1.1.7   root     12560: static void mips_tcg_init(void)
                   12561: {
                   12562:     int i;
                   12563:     static int inited;
                   12564: 
                   12565:     /* Initialize various static tables. */
                   12566:     if (inited)
                   12567:         return;
                   12568: 
                   12569:     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
1.1.1.8   root     12570:     TCGV_UNUSED(cpu_gpr[0]);
                   12571:     for (i = 1; i < 32; i++)
1.1.1.7   root     12572:         cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
                   12573:                                         offsetof(CPUState, active_tc.gpr[i]),
                   12574:                                         regnames[i]);
                   12575:     cpu_PC = tcg_global_mem_new(TCG_AREG0,
                   12576:                                 offsetof(CPUState, active_tc.PC), "PC");
                   12577:     for (i = 0; i < MIPS_DSP_ACC; i++) {
                   12578:         cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
                   12579:                                        offsetof(CPUState, active_tc.HI[i]),
                   12580:                                        regnames_HI[i]);
                   12581:         cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
                   12582:                                        offsetof(CPUState, active_tc.LO[i]),
                   12583:                                        regnames_LO[i]);
                   12584:         cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
                   12585:                                         offsetof(CPUState, active_tc.ACX[i]),
                   12586:                                         regnames_ACX[i]);
                   12587:     }
                   12588:     cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
                   12589:                                      offsetof(CPUState, active_tc.DSPControl),
                   12590:                                      "DSPControl");
1.1.1.8   root     12591:     bcond = tcg_global_mem_new(TCG_AREG0,
                   12592:                                offsetof(CPUState, bcond), "bcond");
1.1.1.7   root     12593:     btarget = tcg_global_mem_new(TCG_AREG0,
                   12594:                                  offsetof(CPUState, btarget), "btarget");
1.1.1.8   root     12595:     hflags = tcg_global_mem_new_i32(TCG_AREG0,
                   12596:                                     offsetof(CPUState, hflags), "hflags");
                   12597: 
1.1.1.7   root     12598:     fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
                   12599:                                       offsetof(CPUState, active_fpu.fcr0),
                   12600:                                       "fcr0");
                   12601:     fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
                   12602:                                        offsetof(CPUState, active_fpu.fcr31),
                   12603:                                        "fcr31");
                   12604: 
                   12605:     /* register helpers */
                   12606: #define GEN_HELPER 2
                   12607: #include "helper.h"
                   12608: 
                   12609:     inited = 1;
                   12610: }
                   12611: 
1.1.1.6   root     12612: #include "translate_init.c"
                   12613: 
                   12614: CPUMIPSState *cpu_mips_init (const char *cpu_model)
1.1       root     12615: {
                   12616:     CPUMIPSState *env;
1.1.1.6   root     12617:     const mips_def_t *def;
1.1       root     12618: 
1.1.1.6   root     12619:     def = cpu_mips_find_by_name(cpu_model);
                   12620:     if (!def)
                   12621:         return NULL;
1.1       root     12622:     env = qemu_mallocz(sizeof(CPUMIPSState));
1.1.1.6   root     12623:     env->cpu_model = def;
1.1.1.9   root     12624:     env->cpu_model_str = cpu_model;
1.1.1.6   root     12625: 
1.1.1.2   root     12626:     cpu_exec_init(env);
1.1.1.9   root     12627: #ifndef CONFIG_USER_ONLY
                   12628:     mmu_init(env, def);
                   12629: #endif
                   12630:     fpu_init(env, def);
                   12631:     mvp_init(env, def);
1.1.1.7   root     12632:     mips_tcg_init();
1.1.1.5   root     12633:     cpu_reset(env);
1.1.1.8   root     12634:     qemu_init_vcpu(env);
1.1.1.5   root     12635:     return env;
                   12636: }
                   12637: 
                   12638: void cpu_reset (CPUMIPSState *env)
                   12639: {
1.1.1.7   root     12640:     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
                   12641:         qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
                   12642:         log_cpu_state(env, 0);
                   12643:     }
                   12644: 
1.1.1.5   root     12645:     memset(env, 0, offsetof(CPUMIPSState, breakpoints));
1.1       root     12646:     tlb_flush(env, 1);
1.1.1.5   root     12647: 
1.1.1.9   root     12648:     /* Reset registers to their default values */
                   12649:     env->CP0_PRid = env->cpu_model->CP0_PRid;
                   12650:     env->CP0_Config0 = env->cpu_model->CP0_Config0;
                   12651: #ifdef TARGET_WORDS_BIGENDIAN
                   12652:     env->CP0_Config0 |= (1 << CP0C0_BE);
                   12653: #endif
                   12654:     env->CP0_Config1 = env->cpu_model->CP0_Config1;
                   12655:     env->CP0_Config2 = env->cpu_model->CP0_Config2;
                   12656:     env->CP0_Config3 = env->cpu_model->CP0_Config3;
                   12657:     env->CP0_Config6 = env->cpu_model->CP0_Config6;
                   12658:     env->CP0_Config7 = env->cpu_model->CP0_Config7;
                   12659:     env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
                   12660:                                  << env->cpu_model->CP0_LLAddr_shift;
                   12661:     env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
                   12662:     env->SYNCI_Step = env->cpu_model->SYNCI_Step;
                   12663:     env->CCRes = env->cpu_model->CCRes;
                   12664:     env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
                   12665:     env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
                   12666:     env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
                   12667:     env->current_tc = 0;
                   12668:     env->SEGBITS = env->cpu_model->SEGBITS;
                   12669:     env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
                   12670: #if defined(TARGET_MIPS64)
                   12671:     if (env->cpu_model->insn_flags & ISA_MIPS3) {
                   12672:         env->SEGMask |= 3ULL << 62;
                   12673:     }
                   12674: #endif
                   12675:     env->PABITS = env->cpu_model->PABITS;
                   12676:     env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
                   12677:     env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
                   12678:     env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
                   12679:     env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
                   12680:     env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
                   12681:     env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
                   12682:     env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
                   12683:     env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
                   12684:     env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
                   12685:     env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
                   12686:     env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
                   12687:     env->insn_flags = env->cpu_model->insn_flags;
                   12688: 
1.1.1.7   root     12689: #if defined(CONFIG_USER_ONLY)
                   12690:     env->hflags = MIPS_HFLAG_UM;
1.1.1.8   root     12691:     /* Enable access to the SYNCI_Step register.  */
                   12692:     env->CP0_HWREna |= (1 << 1);
1.1.1.9   root     12693:     if (env->CP0_Config1 & (1 << CP0C1_FP)) {
                   12694:         env->hflags |= MIPS_HFLAG_FPU;
                   12695:     }
                   12696: #ifdef TARGET_MIPS64
                   12697:     if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
                   12698:         env->hflags |= MIPS_HFLAG_F64;
                   12699:     }
                   12700: #endif
1.1.1.7   root     12701: #else
1.1.1.5   root     12702:     if (env->hflags & MIPS_HFLAG_BMASK) {
                   12703:         /* If the exception was raised from a delay slot,
1.1.1.7   root     12704:            come back to the jump.  */
                   12705:         env->CP0_ErrorEPC = env->active_tc.PC - 4;
1.1.1.5   root     12706:     } else {
1.1.1.7   root     12707:         env->CP0_ErrorEPC = env->active_tc.PC;
1.1.1.5   root     12708:     }
1.1.1.7   root     12709:     env->active_tc.PC = (int32_t)0xBFC00000;
1.1.1.9   root     12710:     env->CP0_Random = env->tlb->nb_tlb - 1;
                   12711:     env->tlb->tlb_in_use = env->tlb->nb_tlb;
1.1       root     12712:     env->CP0_Wired = 0;
1.1.1.13! root     12713:     env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
1.1.1.5   root     12714:     env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
1.1.1.6   root     12715:     /* vectored interrupts not implemented, timer on int 7,
                   12716:        no performance counters. */
                   12717:     env->CP0_IntCtl = 0xe0000000;
                   12718:     {
                   12719:         int i;
                   12720: 
                   12721:         for (i = 0; i < 7; i++) {
                   12722:             env->CP0_WatchLo[i] = 0;
                   12723:             env->CP0_WatchHi[i] = 0x80000000;
                   12724:         }
                   12725:         env->CP0_WatchLo[7] = 0;
                   12726:         env->CP0_WatchHi[7] = 0;
                   12727:     }
1.1       root     12728:     /* Count register increments in debug mode, EJTAG version 1 */
                   12729:     env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
1.1.1.6   root     12730:     env->hflags = MIPS_HFLAG_CP0;
1.1.1.2   root     12731: #endif
1.1.1.9   root     12732: #if defined(TARGET_MIPS64)
                   12733:     if (env->cpu_model->insn_flags & ISA_MIPS3) {
                   12734:         env->hflags |= MIPS_HFLAG_64;
                   12735:     }
                   12736: #endif
1.1.1.7   root     12737:     env->exception_index = EXCP_NONE;
1.1       root     12738: }
1.1.1.7   root     12739: 
                   12740: void gen_pc_load(CPUState *env, TranslationBlock *tb,
                   12741:                 unsigned long searched_pc, int pc_pos, void *puc)
                   12742: {
                   12743:     env->active_tc.PC = gen_opc_pc[pc_pos];
                   12744:     env->hflags &= ~MIPS_HFLAG_BMASK;
                   12745:     env->hflags |= gen_opc_hflags[pc_pos];
                   12746: }

unix.superglobalmegacorp.com

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