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

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 "disas.h"
1.1.1.7   root       31: #include "tcg-op.h"
                     32: #include "qemu-common.h"
                     33: 
                     34: #include "helper.h"
                     35: #define GEN_HELPER 1
                     36: #include "helper.h"
1.1       root       37: 
1.1.1.2   root       38: //#define MIPS_DEBUG_DISAS
1.1.1.5   root       39: //#define MIPS_DEBUG_SIGN_EXTENSIONS
1.1       root       40: 
1.1.1.5   root       41: /* MIPS major opcodes */
                     42: #define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
1.1       root       43: 
                     44: enum {
                     45:     /* indirect opcode tables */
1.1.1.5   root       46:     OPC_SPECIAL  = (0x00 << 26),
                     47:     OPC_REGIMM   = (0x01 << 26),
                     48:     OPC_CP0      = (0x10 << 26),
                     49:     OPC_CP1      = (0x11 << 26),
                     50:     OPC_CP2      = (0x12 << 26),
                     51:     OPC_CP3      = (0x13 << 26),
                     52:     OPC_SPECIAL2 = (0x1C << 26),
                     53:     OPC_SPECIAL3 = (0x1F << 26),
1.1       root       54:     /* arithmetic with immediate */
1.1.1.5   root       55:     OPC_ADDI     = (0x08 << 26),
                     56:     OPC_ADDIU    = (0x09 << 26),
                     57:     OPC_SLTI     = (0x0A << 26),
                     58:     OPC_SLTIU    = (0x0B << 26),
1.1.1.8   root       59:     /* logic with immediate */
1.1.1.5   root       60:     OPC_ANDI     = (0x0C << 26),
                     61:     OPC_ORI      = (0x0D << 26),
                     62:     OPC_XORI     = (0x0E << 26),
                     63:     OPC_LUI      = (0x0F << 26),
1.1.1.8   root       64:     /* arithmetic with immediate */
1.1.1.5   root       65:     OPC_DADDI    = (0x18 << 26),
                     66:     OPC_DADDIU   = (0x19 << 26),
1.1       root       67:     /* Jump and branches */
1.1.1.5   root       68:     OPC_J        = (0x02 << 26),
                     69:     OPC_JAL      = (0x03 << 26),
1.1.1.12  root       70:     OPC_JALS     = OPC_JAL | 0x5,
1.1.1.5   root       71:     OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
                     72:     OPC_BEQL     = (0x14 << 26),
                     73:     OPC_BNE      = (0x05 << 26),
                     74:     OPC_BNEL     = (0x15 << 26),
                     75:     OPC_BLEZ     = (0x06 << 26),
                     76:     OPC_BLEZL    = (0x16 << 26),
                     77:     OPC_BGTZ     = (0x07 << 26),
                     78:     OPC_BGTZL    = (0x17 << 26),
                     79:     OPC_JALX     = (0x1D << 26),  /* MIPS 16 only */
1.1.1.12  root       80:     OPC_JALXS    = OPC_JALX | 0x5,
1.1       root       81:     /* Load and stores */
1.1.1.5   root       82:     OPC_LDL      = (0x1A << 26),
                     83:     OPC_LDR      = (0x1B << 26),
                     84:     OPC_LB       = (0x20 << 26),
                     85:     OPC_LH       = (0x21 << 26),
                     86:     OPC_LWL      = (0x22 << 26),
                     87:     OPC_LW       = (0x23 << 26),
1.1.1.12  root       88:     OPC_LWPC     = OPC_LW | 0x5,
1.1.1.5   root       89:     OPC_LBU      = (0x24 << 26),
                     90:     OPC_LHU      = (0x25 << 26),
                     91:     OPC_LWR      = (0x26 << 26),
                     92:     OPC_LWU      = (0x27 << 26),
                     93:     OPC_SB       = (0x28 << 26),
                     94:     OPC_SH       = (0x29 << 26),
                     95:     OPC_SWL      = (0x2A << 26),
                     96:     OPC_SW       = (0x2B << 26),
                     97:     OPC_SDL      = (0x2C << 26),
                     98:     OPC_SDR      = (0x2D << 26),
                     99:     OPC_SWR      = (0x2E << 26),
                    100:     OPC_LL       = (0x30 << 26),
                    101:     OPC_LLD      = (0x34 << 26),
                    102:     OPC_LD       = (0x37 << 26),
1.1.1.12  root      103:     OPC_LDPC     = OPC_LD | 0x5,
1.1.1.5   root      104:     OPC_SC       = (0x38 << 26),
                    105:     OPC_SCD      = (0x3C << 26),
                    106:     OPC_SD       = (0x3F << 26),
1.1       root      107:     /* Floating point load/store */
1.1.1.5   root      108:     OPC_LWC1     = (0x31 << 26),
                    109:     OPC_LWC2     = (0x32 << 26),
                    110:     OPC_LDC1     = (0x35 << 26),
                    111:     OPC_LDC2     = (0x36 << 26),
                    112:     OPC_SWC1     = (0x39 << 26),
                    113:     OPC_SWC2     = (0x3A << 26),
                    114:     OPC_SDC1     = (0x3D << 26),
                    115:     OPC_SDC2     = (0x3E << 26),
                    116:     /* MDMX ASE specific */
                    117:     OPC_MDMX     = (0x1E << 26),
1.1       root      118:     /* Cache and prefetch */
1.1.1.5   root      119:     OPC_CACHE    = (0x2F << 26),
                    120:     OPC_PREF     = (0x33 << 26),
                    121:     /* Reserved major opcode */
                    122:     OPC_MAJOR3B_RESERVED = (0x3B << 26),
1.1       root      123: };
                    124: 
                    125: /* MIPS special opcodes */
1.1.1.5   root      126: #define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
                    127: 
1.1       root      128: enum {
                    129:     /* Shifts */
1.1.1.5   root      130:     OPC_SLL      = 0x00 | OPC_SPECIAL,
1.1       root      131:     /* NOP is SLL r0, r0, 0   */
                    132:     /* SSNOP is SLL r0, r0, 1 */
1.1.1.5   root      133:     /* EHB is SLL r0, r0, 3 */
                    134:     OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
1.1.1.12  root      135:     OPC_ROTR     = OPC_SRL | (1 << 21),
1.1.1.5   root      136:     OPC_SRA      = 0x03 | OPC_SPECIAL,
                    137:     OPC_SLLV     = 0x04 | OPC_SPECIAL,
1.1.1.6   root      138:     OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
1.1.1.12  root      139:     OPC_ROTRV    = OPC_SRLV | (1 << 6),
1.1.1.5   root      140:     OPC_SRAV     = 0x07 | OPC_SPECIAL,
                    141:     OPC_DSLLV    = 0x14 | OPC_SPECIAL,
                    142:     OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
1.1.1.12  root      143:     OPC_DROTRV   = OPC_DSRLV | (1 << 6),
1.1.1.5   root      144:     OPC_DSRAV    = 0x17 | OPC_SPECIAL,
                    145:     OPC_DSLL     = 0x38 | OPC_SPECIAL,
                    146:     OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
1.1.1.12  root      147:     OPC_DROTR    = OPC_DSRL | (1 << 21),
1.1.1.5   root      148:     OPC_DSRA     = 0x3B | OPC_SPECIAL,
                    149:     OPC_DSLL32   = 0x3C | OPC_SPECIAL,
                    150:     OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
1.1.1.12  root      151:     OPC_DROTR32  = OPC_DSRL32 | (1 << 21),
1.1.1.5   root      152:     OPC_DSRA32   = 0x3F | OPC_SPECIAL,
1.1       root      153:     /* Multiplication / division */
1.1.1.5   root      154:     OPC_MULT     = 0x18 | OPC_SPECIAL,
                    155:     OPC_MULTU    = 0x19 | OPC_SPECIAL,
                    156:     OPC_DIV      = 0x1A | OPC_SPECIAL,
                    157:     OPC_DIVU     = 0x1B | OPC_SPECIAL,
                    158:     OPC_DMULT    = 0x1C | OPC_SPECIAL,
                    159:     OPC_DMULTU   = 0x1D | OPC_SPECIAL,
                    160:     OPC_DDIV     = 0x1E | OPC_SPECIAL,
                    161:     OPC_DDIVU    = 0x1F | OPC_SPECIAL,
1.1       root      162:     /* 2 registers arithmetic / logic */
1.1.1.5   root      163:     OPC_ADD      = 0x20 | OPC_SPECIAL,
                    164:     OPC_ADDU     = 0x21 | OPC_SPECIAL,
                    165:     OPC_SUB      = 0x22 | OPC_SPECIAL,
                    166:     OPC_SUBU     = 0x23 | OPC_SPECIAL,
                    167:     OPC_AND      = 0x24 | OPC_SPECIAL,
                    168:     OPC_OR       = 0x25 | OPC_SPECIAL,
                    169:     OPC_XOR      = 0x26 | OPC_SPECIAL,
                    170:     OPC_NOR      = 0x27 | OPC_SPECIAL,
                    171:     OPC_SLT      = 0x2A | OPC_SPECIAL,
                    172:     OPC_SLTU     = 0x2B | OPC_SPECIAL,
                    173:     OPC_DADD     = 0x2C | OPC_SPECIAL,
                    174:     OPC_DADDU    = 0x2D | OPC_SPECIAL,
                    175:     OPC_DSUB     = 0x2E | OPC_SPECIAL,
                    176:     OPC_DSUBU    = 0x2F | OPC_SPECIAL,
1.1       root      177:     /* Jumps */
1.1.1.5   root      178:     OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
                    179:     OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
1.1.1.12  root      180:     OPC_JALRC    = OPC_JALR | (0x5 << 6),
                    181:     OPC_JALRS    = 0x10 | OPC_SPECIAL | (0x5 << 6),
1.1       root      182:     /* Traps */
1.1.1.5   root      183:     OPC_TGE      = 0x30 | OPC_SPECIAL,
                    184:     OPC_TGEU     = 0x31 | OPC_SPECIAL,
                    185:     OPC_TLT      = 0x32 | OPC_SPECIAL,
                    186:     OPC_TLTU     = 0x33 | OPC_SPECIAL,
                    187:     OPC_TEQ      = 0x34 | OPC_SPECIAL,
                    188:     OPC_TNE      = 0x36 | OPC_SPECIAL,
1.1       root      189:     /* HI / LO registers load & stores */
1.1.1.5   root      190:     OPC_MFHI     = 0x10 | OPC_SPECIAL,
                    191:     OPC_MTHI     = 0x11 | OPC_SPECIAL,
                    192:     OPC_MFLO     = 0x12 | OPC_SPECIAL,
                    193:     OPC_MTLO     = 0x13 | OPC_SPECIAL,
1.1       root      194:     /* Conditional moves */
1.1.1.5   root      195:     OPC_MOVZ     = 0x0A | OPC_SPECIAL,
                    196:     OPC_MOVN     = 0x0B | OPC_SPECIAL,
1.1       root      197: 
1.1.1.5   root      198:     OPC_MOVCI    = 0x01 | OPC_SPECIAL,
1.1       root      199: 
                    200:     /* Special */
1.1.1.9   root      201:     OPC_PMON     = 0x05 | OPC_SPECIAL, /* unofficial */
1.1.1.5   root      202:     OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
                    203:     OPC_BREAK    = 0x0D | OPC_SPECIAL,
1.1.1.9   root      204:     OPC_SPIM     = 0x0E | OPC_SPECIAL, /* unofficial */
1.1.1.5   root      205:     OPC_SYNC     = 0x0F | OPC_SPECIAL,
                    206: 
                    207:     OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
                    208:     OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
                    209:     OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
                    210:     OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
                    211:     OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
                    212:     OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
                    213:     OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
                    214: };
                    215: 
1.1.1.6   root      216: /* Multiplication variants of the vr54xx. */
                    217: #define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
                    218: 
                    219: enum {
                    220:     OPC_VR54XX_MULS    = (0x03 << 6) | OPC_MULT,
                    221:     OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,
                    222:     OPC_VR54XX_MACC    = (0x05 << 6) | OPC_MULT,
                    223:     OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,
                    224:     OPC_VR54XX_MSAC    = (0x07 << 6) | OPC_MULT,
                    225:     OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,
                    226:     OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,
                    227:     OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,
                    228:     OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,
                    229:     OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
                    230:     OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,
                    231:     OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
                    232:     OPC_VR54XX_MSACHI  = (0x0F << 6) | OPC_MULT,
                    233:     OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
                    234: };
                    235: 
1.1.1.5   root      236: /* REGIMM (rt field) opcodes */
                    237: #define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
                    238: 
                    239: enum {
                    240:     OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
                    241:     OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
                    242:     OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
                    243:     OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
                    244:     OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
1.1.1.12  root      245:     OPC_BLTZALS  = OPC_BLTZAL | 0x5, /* microMIPS */
1.1.1.5   root      246:     OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
                    247:     OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
1.1.1.12  root      248:     OPC_BGEZALS  = OPC_BGEZAL | 0x5, /* microMIPS */
1.1.1.5   root      249:     OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
                    250:     OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
                    251:     OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
                    252:     OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
                    253:     OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
                    254:     OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
                    255:     OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
                    256:     OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
1.1       root      257: };
                    258: 
1.1.1.5   root      259: /* Special2 opcodes */
                    260: #define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
                    261: 
1.1       root      262: enum {
1.1.1.5   root      263:     /* Multiply & xxx operations */
                    264:     OPC_MADD     = 0x00 | OPC_SPECIAL2,
                    265:     OPC_MADDU    = 0x01 | OPC_SPECIAL2,
                    266:     OPC_MUL      = 0x02 | OPC_SPECIAL2,
                    267:     OPC_MSUB     = 0x04 | OPC_SPECIAL2,
                    268:     OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
1.1.1.12  root      269:     /* Loongson 2F */
                    270:     OPC_MULT_G_2F   = 0x10 | OPC_SPECIAL2,
                    271:     OPC_DMULT_G_2F  = 0x11 | OPC_SPECIAL2,
                    272:     OPC_MULTU_G_2F  = 0x12 | OPC_SPECIAL2,
                    273:     OPC_DMULTU_G_2F = 0x13 | OPC_SPECIAL2,
                    274:     OPC_DIV_G_2F    = 0x14 | OPC_SPECIAL2,
                    275:     OPC_DDIV_G_2F   = 0x15 | OPC_SPECIAL2,
                    276:     OPC_DIVU_G_2F   = 0x16 | OPC_SPECIAL2,
                    277:     OPC_DDIVU_G_2F  = 0x17 | OPC_SPECIAL2,
                    278:     OPC_MOD_G_2F    = 0x1c | OPC_SPECIAL2,
                    279:     OPC_DMOD_G_2F   = 0x1d | OPC_SPECIAL2,
                    280:     OPC_MODU_G_2F   = 0x1e | OPC_SPECIAL2,
                    281:     OPC_DMODU_G_2F  = 0x1f | OPC_SPECIAL2,
1.1       root      282:     /* Misc */
1.1.1.5   root      283:     OPC_CLZ      = 0x20 | OPC_SPECIAL2,
                    284:     OPC_CLO      = 0x21 | OPC_SPECIAL2,
                    285:     OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
                    286:     OPC_DCLO     = 0x25 | OPC_SPECIAL2,
1.1       root      287:     /* Special */
1.1.1.5   root      288:     OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
                    289: };
                    290: 
                    291: /* Special3 opcodes */
                    292: #define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
                    293: 
                    294: enum {
                    295:     OPC_EXT      = 0x00 | OPC_SPECIAL3,
                    296:     OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
                    297:     OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
                    298:     OPC_DEXT     = 0x03 | OPC_SPECIAL3,
                    299:     OPC_INS      = 0x04 | OPC_SPECIAL3,
                    300:     OPC_DINSM    = 0x05 | OPC_SPECIAL3,
                    301:     OPC_DINSU    = 0x06 | OPC_SPECIAL3,
                    302:     OPC_DINS     = 0x07 | OPC_SPECIAL3,
1.1.1.6   root      303:     OPC_FORK     = 0x08 | OPC_SPECIAL3,
                    304:     OPC_YIELD    = 0x09 | OPC_SPECIAL3,
1.1.1.5   root      305:     OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
                    306:     OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
                    307:     OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
1.1.1.12  root      308: 
                    309:     /* Loongson 2E */
                    310:     OPC_MULT_G_2E   = 0x18 | OPC_SPECIAL3,
                    311:     OPC_MULTU_G_2E  = 0x19 | OPC_SPECIAL3,
                    312:     OPC_DIV_G_2E    = 0x1A | OPC_SPECIAL3,
                    313:     OPC_DIVU_G_2E   = 0x1B | OPC_SPECIAL3,
                    314:     OPC_DMULT_G_2E  = 0x1C | OPC_SPECIAL3,
                    315:     OPC_DMULTU_G_2E = 0x1D | OPC_SPECIAL3,
                    316:     OPC_DDIV_G_2E   = 0x1E | OPC_SPECIAL3,
                    317:     OPC_DDIVU_G_2E  = 0x1F | OPC_SPECIAL3,
                    318:     OPC_MOD_G_2E    = 0x22 | OPC_SPECIAL3,
                    319:     OPC_MODU_G_2E   = 0x23 | OPC_SPECIAL3,
                    320:     OPC_DMOD_G_2E   = 0x26 | OPC_SPECIAL3,
                    321:     OPC_DMODU_G_2E  = 0x27 | OPC_SPECIAL3,
1.1       root      322: };
                    323: 
1.1.1.5   root      324: /* BSHFL opcodes */
                    325: #define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
                    326: 
1.1       root      327: enum {
1.1.1.5   root      328:     OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
                    329:     OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
                    330:     OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
1.1       root      331: };
                    332: 
1.1.1.5   root      333: /* DBSHFL opcodes */
                    334: #define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
                    335: 
1.1       root      336: enum {
1.1.1.5   root      337:     OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
                    338:     OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
1.1       root      339: };
                    340: 
1.1.1.5   root      341: /* Coprocessor 0 (rs field) */
                    342: #define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
                    343: 
1.1.1.4   root      344: enum {
1.1.1.5   root      345:     OPC_MFC0     = (0x00 << 21) | OPC_CP0,
                    346:     OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
                    347:     OPC_MTC0     = (0x04 << 21) | OPC_CP0,
                    348:     OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
1.1.1.6   root      349:     OPC_MFTR     = (0x08 << 21) | OPC_CP0,
1.1.1.5   root      350:     OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
                    351:     OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
1.1.1.6   root      352:     OPC_MTTR     = (0x0C << 21) | OPC_CP0,
1.1.1.5   root      353:     OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
                    354:     OPC_C0       = (0x10 << 21) | OPC_CP0,
                    355:     OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
                    356:     OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,
1.1.1.4   root      357: };
1.1.1.5   root      358: 
                    359: /* MFMC0 opcodes */
1.1.1.6   root      360: #define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
1.1.1.5   root      361: 
                    362: enum {
1.1.1.6   root      363:     OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
                    364:     OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
                    365:     OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
                    366:     OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
1.1.1.5   root      367:     OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
                    368:     OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
                    369: };
                    370: 
                    371: /* Coprocessor 0 (with rs == C0) */
                    372: #define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
                    373: 
                    374: enum {
                    375:     OPC_TLBR     = 0x01 | OPC_C0,
                    376:     OPC_TLBWI    = 0x02 | OPC_C0,
                    377:     OPC_TLBWR    = 0x06 | OPC_C0,
                    378:     OPC_TLBP     = 0x08 | OPC_C0,
                    379:     OPC_RFE      = 0x10 | OPC_C0,
                    380:     OPC_ERET     = 0x18 | OPC_C0,
                    381:     OPC_DERET    = 0x1F | OPC_C0,
                    382:     OPC_WAIT     = 0x20 | OPC_C0,
                    383: };
                    384: 
                    385: /* Coprocessor 1 (rs field) */
                    386: #define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
                    387: 
1.1.1.12  root      388: /* Values for the fmt field in FP instructions */
                    389: enum {
                    390:     /* 0 - 15 are reserved */
                    391:     FMT_S = 16,          /* single fp */
                    392:     FMT_D = 17,          /* double fp */
                    393:     FMT_E = 18,          /* extended fp */
                    394:     FMT_Q = 19,          /* quad fp */
                    395:     FMT_W = 20,          /* 32-bit fixed */
                    396:     FMT_L = 21,          /* 64-bit fixed */
                    397:     FMT_PS = 22,         /* paired single fp */
                    398:     /* 23 - 31 are reserved */
                    399: };
                    400: 
1.1.1.5   root      401: enum {
                    402:     OPC_MFC1     = (0x00 << 21) | OPC_CP1,
                    403:     OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
                    404:     OPC_CFC1     = (0x02 << 21) | OPC_CP1,
1.1.1.6   root      405:     OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
1.1.1.5   root      406:     OPC_MTC1     = (0x04 << 21) | OPC_CP1,
                    407:     OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
                    408:     OPC_CTC1     = (0x06 << 21) | OPC_CP1,
1.1.1.6   root      409:     OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
1.1.1.5   root      410:     OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
1.1.1.6   root      411:     OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
                    412:     OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
1.1.1.12  root      413:     OPC_S_FMT    = (FMT_S << 21) | OPC_CP1,
                    414:     OPC_D_FMT    = (FMT_D << 21) | OPC_CP1,
                    415:     OPC_E_FMT    = (FMT_E << 21) | OPC_CP1,
                    416:     OPC_Q_FMT    = (FMT_Q << 21) | OPC_CP1,
                    417:     OPC_W_FMT    = (FMT_W << 21) | OPC_CP1,
                    418:     OPC_L_FMT    = (FMT_L << 21) | OPC_CP1,
                    419:     OPC_PS_FMT   = (FMT_PS << 21) | OPC_CP1,
1.1.1.5   root      420: };
                    421: 
1.1.1.6   root      422: #define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
                    423: #define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
                    424: 
1.1.1.5   root      425: enum {
                    426:     OPC_BC1F     = (0x00 << 16) | OPC_BC1,
                    427:     OPC_BC1T     = (0x01 << 16) | OPC_BC1,
                    428:     OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
                    429:     OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
                    430: };
                    431: 
1.1.1.6   root      432: enum {
                    433:     OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
                    434:     OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
                    435: };
                    436: 
                    437: enum {
                    438:     OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
                    439:     OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
                    440: };
1.1.1.5   root      441: 
                    442: #define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
1.1.1.6   root      443: 
                    444: enum {
                    445:     OPC_MFC2    = (0x00 << 21) | OPC_CP2,
                    446:     OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
                    447:     OPC_CFC2    = (0x02 << 21) | OPC_CP2,
                    448:     OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
                    449:     OPC_MTC2    = (0x04 << 21) | OPC_CP2,
                    450:     OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
                    451:     OPC_CTC2    = (0x06 << 21) | OPC_CP2,
                    452:     OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
                    453:     OPC_BC2     = (0x08 << 21) | OPC_CP2,
                    454: };
                    455: 
                    456: #define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
                    457: 
                    458: enum {
                    459:     OPC_LWXC1   = 0x00 | OPC_CP3,
                    460:     OPC_LDXC1   = 0x01 | OPC_CP3,
                    461:     OPC_LUXC1   = 0x05 | OPC_CP3,
                    462:     OPC_SWXC1   = 0x08 | OPC_CP3,
                    463:     OPC_SDXC1   = 0x09 | OPC_CP3,
                    464:     OPC_SUXC1   = 0x0D | OPC_CP3,
                    465:     OPC_PREFX   = 0x0F | OPC_CP3,
                    466:     OPC_ALNV_PS = 0x1E | OPC_CP3,
                    467:     OPC_MADD_S  = 0x20 | OPC_CP3,
                    468:     OPC_MADD_D  = 0x21 | OPC_CP3,
                    469:     OPC_MADD_PS = 0x26 | OPC_CP3,
                    470:     OPC_MSUB_S  = 0x28 | OPC_CP3,
                    471:     OPC_MSUB_D  = 0x29 | OPC_CP3,
                    472:     OPC_MSUB_PS = 0x2E | OPC_CP3,
                    473:     OPC_NMADD_S = 0x30 | OPC_CP3,
                    474:     OPC_NMADD_D = 0x31 | OPC_CP3,
                    475:     OPC_NMADD_PS= 0x36 | OPC_CP3,
                    476:     OPC_NMSUB_S = 0x38 | OPC_CP3,
                    477:     OPC_NMSUB_D = 0x39 | OPC_CP3,
                    478:     OPC_NMSUB_PS= 0x3E | OPC_CP3,
                    479: };
                    480: 
1.1.1.7   root      481: /* global register indices */
                    482: static TCGv_ptr cpu_env;
                    483: static TCGv cpu_gpr[32], cpu_PC;
                    484: static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
1.1.1.8   root      485: static TCGv cpu_dspctrl, btarget, bcond;
                    486: static TCGv_i32 hflags;
1.1.1.7   root      487: static TCGv_i32 fpu_fcr0, fpu_fcr31;
                    488: 
1.1.1.12  root      489: static uint32_t gen_opc_hflags[OPC_BUF_SIZE];
                    490: 
1.1.1.7   root      491: #include "gen-icount.h"
                    492: 
                    493: #define gen_helper_0i(name, arg) do {                             \
                    494:     TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
                    495:     gen_helper_##name(helper_tmp);                                \
                    496:     tcg_temp_free_i32(helper_tmp);                                \
                    497:     } while(0)
1.1.1.4   root      498: 
1.1.1.7   root      499: #define gen_helper_1i(name, arg1, arg2) do {                      \
                    500:     TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
                    501:     gen_helper_##name(arg1, helper_tmp);                          \
                    502:     tcg_temp_free_i32(helper_tmp);                                \
                    503:     } while(0)
1.1.1.4   root      504: 
1.1.1.7   root      505: #define gen_helper_2i(name, arg1, arg2, arg3) do {                \
                    506:     TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
                    507:     gen_helper_##name(arg1, arg2, helper_tmp);                    \
                    508:     tcg_temp_free_i32(helper_tmp);                                \
                    509:     } while(0)
1.1.1.4   root      510: 
1.1.1.7   root      511: #define gen_helper_3i(name, arg1, arg2, arg3, arg4) do {          \
                    512:     TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
                    513:     gen_helper_##name(arg1, arg2, arg3, helper_tmp);              \
                    514:     tcg_temp_free_i32(helper_tmp);                                \
                    515:     } while(0)
1.1.1.4   root      516: 
1.1       root      517: typedef struct DisasContext {
                    518:     struct TranslationBlock *tb;
                    519:     target_ulong pc, saved_pc;
                    520:     uint32_t opcode;
1.1.1.9   root      521:     int singlestep_enabled;
1.1       root      522:     /* Routine used to access memory */
                    523:     int mem_idx;
                    524:     uint32_t hflags, saved_hflags;
                    525:     int bstate;
                    526:     target_ulong btarget;
                    527: } DisasContext;
                    528: 
                    529: enum {
                    530:     BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
1.1.1.7   root      531:                       * exception condition */
1.1       root      532:     BS_STOP     = 1, /* We want to stop translation for any reason */
                    533:     BS_BRANCH   = 2, /* We reached a branch condition     */
                    534:     BS_EXCP     = 3, /* We reached an exception condition */
                    535: };
                    536: 
1.1.1.7   root      537: static const char *regnames[] =
                    538:     { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
                    539:       "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
                    540:       "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
                    541:       "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
                    542: 
                    543: static const char *regnames_HI[] =
                    544:     { "HI0", "HI1", "HI2", "HI3", };
                    545: 
                    546: static const char *regnames_LO[] =
                    547:     { "LO0", "LO1", "LO2", "LO3", };
                    548: 
                    549: static const char *regnames_ACX[] =
                    550:     { "ACX0", "ACX1", "ACX2", "ACX3", };
                    551: 
                    552: static const char *fregnames[] =
                    553:     { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
                    554:       "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
                    555:       "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
                    556:       "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
                    557: 
1.1.1.6   root      558: #ifdef MIPS_DEBUG_DISAS
1.1.1.8   root      559: #define MIPS_DEBUG(fmt, ...)                         \
1.1.1.7   root      560:         qemu_log_mask(CPU_LOG_TB_IN_ASM,                \
                    561:                        TARGET_FMT_lx ": %08x " fmt "\n", \
1.1.1.8   root      562:                        ctx->pc, ctx->opcode , ## __VA_ARGS__)
1.1.1.7   root      563: #define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
1.1       root      564: #else
1.1.1.8   root      565: #define MIPS_DEBUG(fmt, ...) do { } while(0)
1.1.1.7   root      566: #define LOG_DISAS(...) do { } while (0)
1.1       root      567: #endif
                    568: 
                    569: #define MIPS_INVAL(op)                                                        \
                    570: do {                                                                          \
                    571:     MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
                    572:                ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
                    573: } while (0)
                    574: 
1.1.1.7   root      575: /* General purpose registers moves. */
                    576: static inline void gen_load_gpr (TCGv t, int reg)
                    577: {
                    578:     if (reg == 0)
                    579:         tcg_gen_movi_tl(t, 0);
                    580:     else
                    581:         tcg_gen_mov_tl(t, cpu_gpr[reg]);
                    582: }
1.1.1.6   root      583: 
1.1.1.7   root      584: static inline void gen_store_gpr (TCGv t, int reg)
                    585: {
                    586:     if (reg != 0)
                    587:         tcg_gen_mov_tl(cpu_gpr[reg], t);
                    588: }
1.1.1.6   root      589: 
1.1.1.7   root      590: /* Moves to/from ACX register.  */
                    591: static inline void gen_load_ACX (TCGv t, int reg)
                    592: {
                    593:     tcg_gen_mov_tl(t, cpu_ACX[reg]);
                    594: }
1.1.1.6   root      595: 
1.1.1.7   root      596: static inline void gen_store_ACX (TCGv t, int reg)
                    597: {
                    598:     tcg_gen_mov_tl(cpu_ACX[reg], t);
                    599: }
1.1       root      600: 
1.1.1.7   root      601: /* Moves to/from shadow registers. */
                    602: static inline void gen_load_srsgpr (int from, int to)
                    603: {
1.1.1.8   root      604:     TCGv t0 = tcg_temp_new();
1.1.1.6   root      605: 
1.1.1.7   root      606:     if (from == 0)
1.1.1.8   root      607:         tcg_gen_movi_tl(t0, 0);
1.1.1.7   root      608:     else {
1.1.1.8   root      609:         TCGv_i32 t2 = tcg_temp_new_i32();
1.1.1.7   root      610:         TCGv_ptr addr = tcg_temp_new_ptr();
1.1.1.6   root      611: 
1.1.1.8   root      612:         tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
                    613:         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
                    614:         tcg_gen_andi_i32(t2, t2, 0xf);
                    615:         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
                    616:         tcg_gen_ext_i32_ptr(addr, t2);
1.1.1.7   root      617:         tcg_gen_add_ptr(addr, cpu_env, addr);
1.1       root      618: 
1.1.1.8   root      619:         tcg_gen_ld_tl(t0, addr, sizeof(target_ulong) * from);
1.1.1.7   root      620:         tcg_temp_free_ptr(addr);
1.1.1.8   root      621:         tcg_temp_free_i32(t2);
1.1.1.7   root      622:     }
1.1.1.8   root      623:     gen_store_gpr(t0, to);
                    624:     tcg_temp_free(t0);
1.1.1.7   root      625: }
1.1       root      626: 
1.1.1.7   root      627: static inline void gen_store_srsgpr (int from, int to)
                    628: {
                    629:     if (to != 0) {
1.1.1.8   root      630:         TCGv t0 = tcg_temp_new();
                    631:         TCGv_i32 t2 = tcg_temp_new_i32();
1.1.1.7   root      632:         TCGv_ptr addr = tcg_temp_new_ptr();
1.1.1.4   root      633: 
1.1.1.8   root      634:         gen_load_gpr(t0, from);
                    635:         tcg_gen_ld_i32(t2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
                    636:         tcg_gen_shri_i32(t2, t2, CP0SRSCtl_PSS);
                    637:         tcg_gen_andi_i32(t2, t2, 0xf);
                    638:         tcg_gen_muli_i32(t2, t2, sizeof(target_ulong) * 32);
                    639:         tcg_gen_ext_i32_ptr(addr, t2);
1.1.1.7   root      640:         tcg_gen_add_ptr(addr, cpu_env, addr);
1.1.1.4   root      641: 
1.1.1.8   root      642:         tcg_gen_st_tl(t0, addr, sizeof(target_ulong) * to);
1.1.1.7   root      643:         tcg_temp_free_ptr(addr);
1.1.1.8   root      644:         tcg_temp_free_i32(t2);
                    645:         tcg_temp_free(t0);
1.1.1.6   root      646:     }
                    647: }
                    648: 
1.1.1.7   root      649: /* Floating point register moves. */
                    650: static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
1.1.1.6   root      651: {
1.1.1.8   root      652:     tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
1.1.1.7   root      653: }
                    654: 
                    655: static inline void gen_store_fpr32 (TCGv_i32 t, int reg)
                    656: {
1.1.1.8   root      657:     tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[FP_ENDIAN_IDX]));
1.1.1.7   root      658: }
                    659: 
1.1.1.8   root      660: static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
1.1.1.7   root      661: {
1.1.1.8   root      662:     tcg_gen_ld_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
1.1.1.6   root      663: }
                    664: 
1.1.1.8   root      665: static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
1.1       root      666: {
1.1.1.8   root      667:     tcg_gen_st_i32(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].w[!FP_ENDIAN_IDX]));
1.1.1.7   root      668: }
                    669: 
1.1.1.8   root      670: static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
1.1.1.7   root      671: {
1.1.1.8   root      672:     if (ctx->hflags & MIPS_HFLAG_F64) {
                    673:         tcg_gen_ld_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
                    674:     } else {
                    675:         TCGv_i32 t0 = tcg_temp_new_i32();
                    676:         TCGv_i32 t1 = tcg_temp_new_i32();
                    677:         gen_load_fpr32(t0, reg & ~1);
                    678:         gen_load_fpr32(t1, reg | 1);
                    679:         tcg_gen_concat_i32_i64(t, t0, t1);
                    680:         tcg_temp_free_i32(t0);
                    681:         tcg_temp_free_i32(t1);
                    682:     }
1.1.1.7   root      683: }
                    684: 
1.1.1.8   root      685: static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
1.1.1.7   root      686: {
1.1.1.8   root      687:     if (ctx->hflags & MIPS_HFLAG_F64) {
                    688:         tcg_gen_st_i64(t, cpu_env, offsetof(CPUState, active_fpu.fpr[reg].d));
                    689:     } else {
                    690:         TCGv_i64 t0 = tcg_temp_new_i64();
                    691:         TCGv_i32 t1 = tcg_temp_new_i32();
                    692:         tcg_gen_trunc_i64_i32(t1, t);
                    693:         gen_store_fpr32(t1, reg & ~1);
                    694:         tcg_gen_shri_i64(t0, t, 32);
                    695:         tcg_gen_trunc_i64_i32(t1, t0);
                    696:         gen_store_fpr32(t1, reg | 1);
                    697:         tcg_temp_free_i32(t1);
                    698:         tcg_temp_free_i64(t0);
                    699:     }
1.1.1.7   root      700: }
                    701: 
1.1.1.8   root      702: static inline int get_fp_bit (int cc)
1.1.1.7   root      703: {
1.1.1.8   root      704:     if (cc)
                    705:         return 24 + cc;
                    706:     else
                    707:         return 23;
1.1.1.7   root      708: }
                    709: 
                    710: /* Tests */
                    711: static inline void gen_save_pc(target_ulong pc)
                    712: {
                    713:     tcg_gen_movi_tl(cpu_PC, pc);
                    714: }
                    715: 
                    716: static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
                    717: {
                    718:     LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1.1       root      719:     if (do_save_pc && ctx->pc != ctx->saved_pc) {
1.1.1.6   root      720:         gen_save_pc(ctx->pc);
1.1       root      721:         ctx->saved_pc = ctx->pc;
                    722:     }
                    723:     if (ctx->hflags != ctx->saved_hflags) {
1.1.1.8   root      724:         tcg_gen_movi_i32(hflags, ctx->hflags);
1.1       root      725:         ctx->saved_hflags = ctx->hflags;
1.1.1.12  root      726:         switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1.1.1.6   root      727:         case MIPS_HFLAG_BR:
                    728:             break;
                    729:         case MIPS_HFLAG_BC:
                    730:         case MIPS_HFLAG_BL:
                    731:         case MIPS_HFLAG_B:
1.1.1.7   root      732:             tcg_gen_movi_tl(btarget, ctx->btarget);
1.1.1.6   root      733:             break;
1.1       root      734:         }
                    735:     }
                    736: }
                    737: 
1.1.1.7   root      738: static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
1.1.1.6   root      739: {
                    740:     ctx->saved_hflags = ctx->hflags;
1.1.1.12  root      741:     switch (ctx->hflags & MIPS_HFLAG_BMASK_BASE) {
1.1.1.6   root      742:     case MIPS_HFLAG_BR:
                    743:         break;
                    744:     case MIPS_HFLAG_BC:
                    745:     case MIPS_HFLAG_BL:
1.1.1.7   root      746:     case MIPS_HFLAG_B:
1.1.1.6   root      747:         ctx->btarget = env->btarget;
                    748:         break;
                    749:     }
                    750: }
                    751: 
1.1.1.7   root      752: static inline void
                    753: generate_exception_err (DisasContext *ctx, int excp, int err)
1.1       root      754: {
1.1.1.7   root      755:     TCGv_i32 texcp = tcg_const_i32(excp);
                    756:     TCGv_i32 terr = tcg_const_i32(err);
1.1       root      757:     save_cpu_state(ctx, 1);
1.1.1.7   root      758:     gen_helper_raise_exception_err(texcp, terr);
                    759:     tcg_temp_free_i32(terr);
                    760:     tcg_temp_free_i32(texcp);
                    761: }
                    762: 
                    763: static inline void
                    764: generate_exception (DisasContext *ctx, int excp)
                    765: {
                    766:     save_cpu_state(ctx, 1);
                    767:     gen_helper_0i(raise_exception, excp);
1.1       root      768: }
                    769: 
1.1.1.7   root      770: /* Addresses computation */
1.1.1.9   root      771: static inline void gen_op_addr_add (DisasContext *ctx, TCGv ret, TCGv arg0, TCGv arg1)
1.1.1.2   root      772: {
1.1.1.9   root      773:     tcg_gen_add_tl(ret, arg0, arg1);
1.1.1.7   root      774: 
                    775: #if defined(TARGET_MIPS64)
                    776:     /* For compatibility with 32-bit code, data reference in user mode
                    777:        with Status_UX = 0 should be casted to 32-bit and sign extended.
                    778:        See the MIPS64 PRA manual, section 4.10. */
                    779:     if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
                    780:         !(ctx->hflags & MIPS_HFLAG_UX)) {
1.1.1.9   root      781:         tcg_gen_ext32s_i64(ret, ret);
1.1.1.7   root      782:     }
                    783: #endif
1.1.1.2   root      784: }
                    785: 
1.1.1.7   root      786: static inline void check_cp0_enabled(DisasContext *ctx)
1.1.1.6   root      787: {
                    788:     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
1.1.1.10  root      789:         generate_exception_err(ctx, EXCP_CpU, 0);
1.1.1.6   root      790: }
                    791: 
1.1.1.7   root      792: static inline void check_cp1_enabled(DisasContext *ctx)
1.1.1.6   root      793: {
                    794:     if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
                    795:         generate_exception_err(ctx, EXCP_CpU, 1);
                    796: }
                    797: 
                    798: /* Verify that the processor is running with COP1X instructions enabled.
                    799:    This is associated with the nabla symbol in the MIPS32 and MIPS64
                    800:    opcode tables.  */
                    801: 
1.1.1.7   root      802: static inline void check_cop1x(DisasContext *ctx)
1.1.1.6   root      803: {
                    804:     if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
                    805:         generate_exception(ctx, EXCP_RI);
                    806: }
                    807: 
                    808: /* Verify that the processor is running with 64-bit floating-point
                    809:    operations enabled.  */
                    810: 
1.1.1.7   root      811: static inline void check_cp1_64bitmode(DisasContext *ctx)
1.1.1.6   root      812: {
                    813:     if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
                    814:         generate_exception(ctx, EXCP_RI);
                    815: }
                    816: 
                    817: /*
                    818:  * Verify if floating point register is valid; an operation is not defined
                    819:  * if bit 0 of any register specification is set and the FR bit in the
                    820:  * Status register equals zero, since the register numbers specify an
                    821:  * even-odd pair of adjacent coprocessor general registers. When the FR bit
                    822:  * in the Status register equals one, both even and odd register numbers
                    823:  * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
                    824:  *
                    825:  * Multiple 64 bit wide registers can be checked by calling
                    826:  * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
                    827:  */
1.1.1.7   root      828: static inline void check_cp1_registers(DisasContext *ctx, int regs)
1.1.1.6   root      829: {
                    830:     if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
                    831:         generate_exception(ctx, EXCP_RI);
                    832: }
                    833: 
                    834: /* This code generates a "reserved instruction" exception if the
                    835:    CPU does not support the instruction set corresponding to flags. */
1.1.1.7   root      836: static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
1.1.1.6   root      837: {
                    838:     if (unlikely(!(env->insn_flags & flags)))
                    839:         generate_exception(ctx, EXCP_RI);
                    840: }
                    841: 
                    842: /* This code generates a "reserved instruction" exception if 64-bit
                    843:    instructions are not enabled. */
1.1.1.7   root      844: static inline void check_mips_64(DisasContext *ctx)
1.1.1.6   root      845: {
                    846:     if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
                    847:         generate_exception(ctx, EXCP_RI);
                    848: }
                    849: 
1.1.1.12  root      850: /* Define small wrappers for gen_load_fpr* so that we have a uniform
                    851:    calling interface for 32 and 64-bit FPRs.  No sense in changing
                    852:    all callers for gen_load_fpr32 when we need the CTX parameter for
                    853:    this one use.  */
                    854: #define gen_ldcmp_fpr32(ctx, x, y) gen_load_fpr32(x, y)
                    855: #define gen_ldcmp_fpr64(ctx, x, y) gen_load_fpr64(ctx, x, y)
                    856: #define FOP_CONDS(type, abs, fmt, ifmt, bits)                                 \
                    857: static inline void gen_cmp ## type ## _ ## fmt(DisasContext *ctx, int n,      \
                    858:                                                int ft, int fs, int cc)        \
                    859: {                                                                             \
                    860:     TCGv_i##bits fp0 = tcg_temp_new_i##bits ();                               \
                    861:     TCGv_i##bits fp1 = tcg_temp_new_i##bits ();                               \
                    862:     switch (ifmt) {                                                           \
                    863:     case FMT_PS:                                                              \
                    864:         check_cp1_64bitmode(ctx);                                             \
                    865:         break;                                                                \
                    866:     case FMT_D:                                                               \
                    867:         if (abs) {                                                            \
                    868:             check_cop1x(ctx);                                                 \
                    869:         }                                                                     \
                    870:         check_cp1_registers(ctx, fs | ft);                                    \
                    871:         break;                                                                \
                    872:     case FMT_S:                                                               \
                    873:         if (abs) {                                                            \
                    874:             check_cop1x(ctx);                                                 \
                    875:         }                                                                     \
                    876:         break;                                                                \
                    877:     }                                                                         \
                    878:     gen_ldcmp_fpr##bits (ctx, fp0, fs);                                       \
                    879:     gen_ldcmp_fpr##bits (ctx, fp1, ft);                                       \
                    880:     switch (n) {                                                              \
                    881:     case  0: gen_helper_2i(cmp ## type ## _ ## fmt ## _f, fp0, fp1, cc);    break;\
                    882:     case  1: gen_helper_2i(cmp ## type ## _ ## fmt ## _un, fp0, fp1, cc);   break;\
                    883:     case  2: gen_helper_2i(cmp ## type ## _ ## fmt ## _eq, fp0, fp1, cc);   break;\
                    884:     case  3: gen_helper_2i(cmp ## type ## _ ## fmt ## _ueq, fp0, fp1, cc);  break;\
                    885:     case  4: gen_helper_2i(cmp ## type ## _ ## fmt ## _olt, fp0, fp1, cc);  break;\
                    886:     case  5: gen_helper_2i(cmp ## type ## _ ## fmt ## _ult, fp0, fp1, cc);  break;\
                    887:     case  6: gen_helper_2i(cmp ## type ## _ ## fmt ## _ole, fp0, fp1, cc);  break;\
                    888:     case  7: gen_helper_2i(cmp ## type ## _ ## fmt ## _ule, fp0, fp1, cc);  break;\
                    889:     case  8: gen_helper_2i(cmp ## type ## _ ## fmt ## _sf, fp0, fp1, cc);   break;\
                    890:     case  9: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngle, fp0, fp1, cc); break;\
                    891:     case 10: gen_helper_2i(cmp ## type ## _ ## fmt ## _seq, fp0, fp1, cc);  break;\
                    892:     case 11: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngl, fp0, fp1, cc);  break;\
                    893:     case 12: gen_helper_2i(cmp ## type ## _ ## fmt ## _lt, fp0, fp1, cc);   break;\
                    894:     case 13: gen_helper_2i(cmp ## type ## _ ## fmt ## _nge, fp0, fp1, cc);  break;\
                    895:     case 14: gen_helper_2i(cmp ## type ## _ ## fmt ## _le, fp0, fp1, cc);   break;\
                    896:     case 15: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngt, fp0, fp1, cc);  break;\
                    897:     default: abort();                                                         \
                    898:     }                                                                         \
                    899:     tcg_temp_free_i##bits (fp0);                                              \
                    900:     tcg_temp_free_i##bits (fp1);                                              \
                    901: }
                    902: 
                    903: FOP_CONDS(, 0, d, FMT_D, 64)
                    904: FOP_CONDS(abs, 1, d, FMT_D, 64)
                    905: FOP_CONDS(, 0, s, FMT_S, 32)
                    906: FOP_CONDS(abs, 1, s, FMT_S, 32)
                    907: FOP_CONDS(, 0, ps, FMT_PS, 64)
                    908: FOP_CONDS(abs, 1, ps, FMT_PS, 64)
                    909: #undef FOP_CONDS
                    910: #undef gen_ldcmp_fpr32
                    911: #undef gen_ldcmp_fpr64
                    912: 
1.1.1.7   root      913: /* load/store instructions. */
1.1.1.8   root      914: #define OP_LD(insn,fname)                                                 \
1.1.1.12  root      915: static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)   \
1.1.1.8   root      916: {                                                                         \
                    917:     tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                        \
1.1.1.7   root      918: }
                    919: OP_LD(lb,ld8s);
                    920: OP_LD(lbu,ld8u);
                    921: OP_LD(lh,ld16s);
                    922: OP_LD(lhu,ld16u);
                    923: OP_LD(lw,ld32s);
                    924: #if defined(TARGET_MIPS64)
                    925: OP_LD(lwu,ld32u);
                    926: OP_LD(ld,ld64);
                    927: #endif
                    928: #undef OP_LD
                    929: 
1.1.1.8   root      930: #define OP_ST(insn,fname)                                                  \
1.1.1.12  root      931: static inline void op_st_##insn(TCGv arg1, TCGv arg2, DisasContext *ctx)   \
1.1.1.8   root      932: {                                                                          \
                    933:     tcg_gen_qemu_##fname(arg1, arg2, ctx->mem_idx);                        \
1.1.1.7   root      934: }
                    935: OP_ST(sb,st8);
                    936: OP_ST(sh,st16);
                    937: OP_ST(sw,st32);
                    938: #if defined(TARGET_MIPS64)
                    939: OP_ST(sd,st64);
                    940: #endif
                    941: #undef OP_ST
                    942: 
1.1.1.9   root      943: #ifdef CONFIG_USER_ONLY
1.1.1.8   root      944: #define OP_LD_ATOMIC(insn,fname)                                           \
1.1.1.12  root      945: static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
1.1.1.8   root      946: {                                                                          \
                    947:     TCGv t0 = tcg_temp_new();                                              \
                    948:     tcg_gen_mov_tl(t0, arg1);                                              \
                    949:     tcg_gen_qemu_##fname(ret, arg1, ctx->mem_idx);                         \
1.1.1.9   root      950:     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, lladdr));                \
1.1.1.8   root      951:     tcg_gen_st_tl(ret, cpu_env, offsetof(CPUState, llval));                \
                    952:     tcg_temp_free(t0);                                                     \
1.1       root      953: }
1.1.1.9   root      954: #else
                    955: #define OP_LD_ATOMIC(insn,fname)                                           \
1.1.1.12  root      956: static inline void op_ld_##insn(TCGv ret, TCGv arg1, DisasContext *ctx)    \
1.1.1.9   root      957: {                                                                          \
                    958:     gen_helper_2i(insn, ret, arg1, ctx->mem_idx);                          \
                    959: }
                    960: #endif
1.1.1.7   root      961: OP_LD_ATOMIC(ll,ld32s);
                    962: #if defined(TARGET_MIPS64)
                    963: OP_LD_ATOMIC(lld,ld64);
1.1       root      964: #endif
1.1.1.7   root      965: #undef OP_LD_ATOMIC
1.1       root      966: 
1.1.1.8   root      967: #ifdef CONFIG_USER_ONLY
                    968: #define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
1.1.1.12  root      969: static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1.1.1.8   root      970: {                                                                            \
                    971:     TCGv t0 = tcg_temp_new();                                                \
                    972:     int l1 = gen_new_label();                                                \
                    973:     int l2 = gen_new_label();                                                \
                    974:                                                                              \
                    975:     tcg_gen_andi_tl(t0, arg2, almask);                                       \
                    976:     tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);                              \
                    977:     tcg_gen_st_tl(arg2, cpu_env, offsetof(CPUState, CP0_BadVAddr));          \
                    978:     generate_exception(ctx, EXCP_AdES);                                      \
                    979:     gen_set_label(l1);                                                       \
1.1.1.9   root      980:     tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, lladdr));                  \
1.1.1.8   root      981:     tcg_gen_brcond_tl(TCG_COND_NE, arg2, t0, l2);                            \
                    982:     tcg_gen_movi_tl(t0, rt | ((almask << 3) & 0x20));                        \
                    983:     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, llreg));                   \
                    984:     tcg_gen_st_tl(arg1, cpu_env, offsetof(CPUState, llnewval));              \
                    985:     gen_helper_0i(raise_exception, EXCP_SC);                                 \
                    986:     gen_set_label(l2);                                                       \
                    987:     tcg_gen_movi_tl(t0, 0);                                                  \
                    988:     gen_store_gpr(t0, rt);                                                   \
                    989:     tcg_temp_free(t0);                                                       \
                    990: }
                    991: #else
                    992: #define OP_ST_ATOMIC(insn,fname,ldname,almask)                               \
1.1.1.12  root      993: static inline void op_st_##insn(TCGv arg1, TCGv arg2, int rt, DisasContext *ctx) \
1.1.1.8   root      994: {                                                                            \
                    995:     TCGv t0 = tcg_temp_new();                                                \
1.1.1.9   root      996:     gen_helper_3i(insn, t0, arg1, arg2, ctx->mem_idx);                       \
1.1.1.8   root      997:     gen_store_gpr(t0, rt);                                                   \
                    998:     tcg_temp_free(t0);                                                       \
1.1.1.7   root      999: }
1.1.1.8   root     1000: #endif
                   1001: OP_ST_ATOMIC(sc,st32,ld32s,0x3);
1.1.1.6   root     1002: #if defined(TARGET_MIPS64)
1.1.1.8   root     1003: OP_ST_ATOMIC(scd,st64,ld64,0x7);
1.1       root     1004: #endif
1.1.1.7   root     1005: #undef OP_ST_ATOMIC
1.1       root     1006: 
1.1.1.12  root     1007: static void gen_base_offset_addr (DisasContext *ctx, TCGv addr,
                   1008:                                   int base, int16_t offset)
1.1       root     1009: {
                   1010:     if (base == 0) {
1.1.1.12  root     1011:         tcg_gen_movi_tl(addr, offset);
1.1       root     1012:     } else if (offset == 0) {
1.1.1.12  root     1013:         gen_load_gpr(addr, base);
1.1       root     1014:     } else {
1.1.1.12  root     1015:         tcg_gen_movi_tl(addr, offset);
                   1016:         gen_op_addr_add(ctx, addr, cpu_gpr[base], addr);
1.1       root     1017:     }
1.1.1.12  root     1018: }
                   1019: 
                   1020: static target_ulong pc_relative_pc (DisasContext *ctx)
                   1021: {
                   1022:     target_ulong pc = ctx->pc;
                   1023: 
                   1024:     if (ctx->hflags & MIPS_HFLAG_BMASK) {
                   1025:         int branch_bytes = ctx->hflags & MIPS_HFLAG_BDS16 ? 2 : 4;
                   1026: 
                   1027:         pc -= branch_bytes;
                   1028:     }
                   1029: 
                   1030:     pc &= ~(target_ulong)3;
                   1031:     return pc;
                   1032: }
                   1033: 
                   1034: /* Load */
                   1035: static void gen_ld (CPUState *env, DisasContext *ctx, uint32_t opc,
                   1036:                     int rt, int base, int16_t offset)
                   1037: {
                   1038:     const char *opn = "ld";
                   1039:     TCGv t0, t1;
                   1040: 
                   1041:     if (rt == 0 && env->insn_flags & (INSN_LOONGSON2E | INSN_LOONGSON2F)) {
                   1042:         /* Loongson CPU uses a load to zero register for prefetch.
                   1043:            We emulate it as a NOP. On other CPU we must perform the
                   1044:            actual memory access. */
                   1045:         MIPS_DEBUG("NOP");
                   1046:         return;
                   1047:     }
                   1048: 
                   1049:     t0 = tcg_temp_new();
                   1050:     t1 = tcg_temp_new();
                   1051:     gen_base_offset_addr(ctx, t0, base, offset);
                   1052: 
1.1       root     1053:     switch (opc) {
1.1.1.6   root     1054: #if defined(TARGET_MIPS64)
                   1055:     case OPC_LWU:
1.1.1.8   root     1056:         save_cpu_state(ctx, 0);
1.1.1.12  root     1057:         op_ld_lwu(t0, t0, ctx);
1.1.1.7   root     1058:         gen_store_gpr(t0, rt);
1.1.1.6   root     1059:         opn = "lwu";
                   1060:         break;
1.1       root     1061:     case OPC_LD:
1.1.1.8   root     1062:         save_cpu_state(ctx, 0);
1.1.1.12  root     1063:         op_ld_ld(t0, t0, ctx);
1.1.1.7   root     1064:         gen_store_gpr(t0, rt);
1.1       root     1065:         opn = "ld";
                   1066:         break;
1.1.1.5   root     1067:     case OPC_LLD:
1.1.1.13  root     1068:         save_cpu_state(ctx, 1);
1.1.1.12  root     1069:         op_ld_lld(t0, t0, ctx);
1.1.1.7   root     1070:         gen_store_gpr(t0, rt);
1.1.1.5   root     1071:         opn = "lld";
                   1072:         break;
1.1       root     1073:     case OPC_LDL:
1.1.1.7   root     1074:         save_cpu_state(ctx, 1);
                   1075:         gen_load_gpr(t1, rt);
1.1.1.8   root     1076:         gen_helper_3i(ldl, t1, t1, t0, ctx->mem_idx);
1.1.1.7   root     1077:         gen_store_gpr(t1, rt);
1.1       root     1078:         opn = "ldl";
                   1079:         break;
                   1080:     case OPC_LDR:
1.1.1.7   root     1081:         save_cpu_state(ctx, 1);
                   1082:         gen_load_gpr(t1, rt);
1.1.1.8   root     1083:         gen_helper_3i(ldr, t1, t1, t0, ctx->mem_idx);
1.1.1.7   root     1084:         gen_store_gpr(t1, rt);
1.1       root     1085:         opn = "ldr";
                   1086:         break;
1.1.1.12  root     1087:     case OPC_LDPC:
1.1.1.13  root     1088:         save_cpu_state(ctx, 0);
1.1.1.12  root     1089:         tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
                   1090:         gen_op_addr_add(ctx, t0, t0, t1);
                   1091:         op_ld_ld(t0, t0, ctx);
                   1092:         gen_store_gpr(t0, rt);
                   1093:         opn = "ldpc";
1.1       root     1094:         break;
                   1095: #endif
1.1.1.12  root     1096:     case OPC_LWPC:
1.1.1.13  root     1097:         save_cpu_state(ctx, 0);
1.1.1.12  root     1098:         tcg_gen_movi_tl(t1, pc_relative_pc(ctx));
                   1099:         gen_op_addr_add(ctx, t0, t0, t1);
                   1100:         op_ld_lw(t0, t0, ctx);
                   1101:         gen_store_gpr(t0, rt);
                   1102:         opn = "lwpc";
                   1103:         break;
1.1       root     1104:     case OPC_LW:
1.1.1.8   root     1105:         save_cpu_state(ctx, 0);
1.1.1.12  root     1106:         op_ld_lw(t0, t0, ctx);
1.1.1.7   root     1107:         gen_store_gpr(t0, rt);
1.1       root     1108:         opn = "lw";
                   1109:         break;
                   1110:     case OPC_LH:
1.1.1.8   root     1111:         save_cpu_state(ctx, 0);
1.1.1.12  root     1112:         op_ld_lh(t0, t0, ctx);
1.1.1.7   root     1113:         gen_store_gpr(t0, rt);
1.1       root     1114:         opn = "lh";
                   1115:         break;
                   1116:     case OPC_LHU:
1.1.1.8   root     1117:         save_cpu_state(ctx, 0);
1.1.1.12  root     1118:         op_ld_lhu(t0, t0, ctx);
1.1.1.7   root     1119:         gen_store_gpr(t0, rt);
1.1       root     1120:         opn = "lhu";
                   1121:         break;
                   1122:     case OPC_LB:
1.1.1.8   root     1123:         save_cpu_state(ctx, 0);
1.1.1.12  root     1124:         op_ld_lb(t0, t0, ctx);
1.1.1.7   root     1125:         gen_store_gpr(t0, rt);
1.1       root     1126:         opn = "lb";
                   1127:         break;
                   1128:     case OPC_LBU:
1.1.1.8   root     1129:         save_cpu_state(ctx, 0);
1.1.1.12  root     1130:         op_ld_lbu(t0, t0, ctx);
1.1.1.7   root     1131:         gen_store_gpr(t0, rt);
1.1       root     1132:         opn = "lbu";
                   1133:         break;
                   1134:     case OPC_LWL:
1.1.1.7   root     1135:         save_cpu_state(ctx, 1);
                   1136:         gen_load_gpr(t1, rt);
1.1.1.8   root     1137:         gen_helper_3i(lwl, t1, t1, t0, ctx->mem_idx);
1.1.1.7   root     1138:         gen_store_gpr(t1, rt);
1.1       root     1139:         opn = "lwl";
                   1140:         break;
                   1141:     case OPC_LWR:
1.1.1.7   root     1142:         save_cpu_state(ctx, 1);
                   1143:         gen_load_gpr(t1, rt);
1.1.1.8   root     1144:         gen_helper_3i(lwr, t1, t1, t0, ctx->mem_idx);
1.1.1.7   root     1145:         gen_store_gpr(t1, rt);
1.1       root     1146:         opn = "lwr";
                   1147:         break;
                   1148:     case OPC_LL:
1.1.1.9   root     1149:         save_cpu_state(ctx, 1);
1.1.1.12  root     1150:         op_ld_ll(t0, t0, ctx);
1.1.1.7   root     1151:         gen_store_gpr(t0, rt);
1.1       root     1152:         opn = "ll";
                   1153:         break;
1.1.1.8   root     1154:     }
1.1.1.13  root     1155:     (void)opn; /* avoid a compiler warning */
1.1.1.8   root     1156:     MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
                   1157:     tcg_temp_free(t0);
                   1158:     tcg_temp_free(t1);
                   1159: }
                   1160: 
1.1.1.12  root     1161: /* Store */
                   1162: static void gen_st (DisasContext *ctx, uint32_t opc, int rt,
                   1163:                     int base, int16_t offset)
                   1164: {
                   1165:     const char *opn = "st";
                   1166:     TCGv t0 = tcg_temp_new();
                   1167:     TCGv t1 = tcg_temp_new();
                   1168: 
                   1169:     gen_base_offset_addr(ctx, t0, base, offset);
                   1170:     gen_load_gpr(t1, rt);
                   1171:     switch (opc) {
                   1172: #if defined(TARGET_MIPS64)
                   1173:     case OPC_SD:
                   1174:         save_cpu_state(ctx, 0);
                   1175:         op_st_sd(t1, t0, ctx);
                   1176:         opn = "sd";
                   1177:         break;
                   1178:     case OPC_SDL:
                   1179:         save_cpu_state(ctx, 1);
                   1180:         gen_helper_2i(sdl, t1, t0, ctx->mem_idx);
                   1181:         opn = "sdl";
                   1182:         break;
                   1183:     case OPC_SDR:
                   1184:         save_cpu_state(ctx, 1);
                   1185:         gen_helper_2i(sdr, t1, t0, ctx->mem_idx);
                   1186:         opn = "sdr";
                   1187:         break;
                   1188: #endif
                   1189:     case OPC_SW:
                   1190:         save_cpu_state(ctx, 0);
                   1191:         op_st_sw(t1, t0, ctx);
                   1192:         opn = "sw";
                   1193:         break;
                   1194:     case OPC_SH:
                   1195:         save_cpu_state(ctx, 0);
                   1196:         op_st_sh(t1, t0, ctx);
                   1197:         opn = "sh";
                   1198:         break;
                   1199:     case OPC_SB:
                   1200:         save_cpu_state(ctx, 0);
                   1201:         op_st_sb(t1, t0, ctx);
                   1202:         opn = "sb";
                   1203:         break;
                   1204:     case OPC_SWL:
                   1205:         save_cpu_state(ctx, 1);
                   1206:         gen_helper_2i(swl, t1, t0, ctx->mem_idx);
                   1207:         opn = "swl";
                   1208:         break;
                   1209:     case OPC_SWR:
                   1210:         save_cpu_state(ctx, 1);
                   1211:         gen_helper_2i(swr, t1, t0, ctx->mem_idx);
                   1212:         opn = "swr";
                   1213:         break;
                   1214:     }
1.1.1.13  root     1215:     (void)opn; /* avoid a compiler warning */
1.1.1.12  root     1216:     MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
                   1217:     tcg_temp_free(t0);
                   1218:     tcg_temp_free(t1);
                   1219: }
                   1220: 
                   1221: 
1.1.1.8   root     1222: /* Store conditional */
                   1223: static void gen_st_cond (DisasContext *ctx, uint32_t opc, int rt,
                   1224:                          int base, int16_t offset)
                   1225: {
                   1226:     const char *opn = "st_cond";
                   1227:     TCGv t0, t1;
                   1228: 
                   1229:     t0 = tcg_temp_local_new();
                   1230: 
1.1.1.12  root     1231:     gen_base_offset_addr(ctx, t0, base, offset);
1.1.1.8   root     1232:     /* Don't do NOP if destination is zero: we must perform the actual
                   1233:        memory access. */
                   1234: 
                   1235:     t1 = tcg_temp_local_new();
                   1236:     gen_load_gpr(t1, rt);
                   1237:     switch (opc) {
                   1238: #if defined(TARGET_MIPS64)
                   1239:     case OPC_SCD:
1.1.1.13  root     1240:         save_cpu_state(ctx, 1);
1.1.1.12  root     1241:         op_st_scd(t1, t0, rt, ctx);
1.1.1.8   root     1242:         opn = "scd";
                   1243:         break;
                   1244: #endif
1.1       root     1245:     case OPC_SC:
1.1.1.9   root     1246:         save_cpu_state(ctx, 1);
1.1.1.12  root     1247:         op_st_sc(t1, t0, rt, ctx);
1.1       root     1248:         opn = "sc";
                   1249:         break;
                   1250:     }
1.1.1.13  root     1251:     (void)opn; /* avoid a compiler warning */
1.1       root     1252:     MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1.1.1.7   root     1253:     tcg_temp_free(t1);
1.1.1.8   root     1254:     tcg_temp_free(t0);
1.1       root     1255: }
                   1256: 
1.1.1.4   root     1257: /* Load and store */
1.1.1.5   root     1258: static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1.1.1.7   root     1259:                           int base, int16_t offset)
1.1.1.4   root     1260: {
1.1.1.6   root     1261:     const char *opn = "flt_ldst";
1.1.1.8   root     1262:     TCGv t0 = tcg_temp_new();
1.1.1.4   root     1263: 
1.1.1.12  root     1264:     gen_base_offset_addr(ctx, t0, base, offset);
1.1.1.4   root     1265:     /* Don't do NOP if destination is zero: we must perform the actual
1.1.1.6   root     1266:        memory access. */
1.1.1.4   root     1267:     switch (opc) {
                   1268:     case OPC_LWC1:
1.1.1.7   root     1269:         {
                   1270:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   1271: 
1.1.1.8   root     1272:             tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
                   1273:             tcg_gen_trunc_tl_i32(fp0, t0);
1.1.1.7   root     1274:             gen_store_fpr32(fp0, ft);
                   1275:             tcg_temp_free_i32(fp0);
                   1276:         }
1.1.1.4   root     1277:         opn = "lwc1";
                   1278:         break;
                   1279:     case OPC_SWC1:
1.1.1.7   root     1280:         {
                   1281:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   1282:             TCGv t1 = tcg_temp_new();
                   1283: 
                   1284:             gen_load_fpr32(fp0, ft);
                   1285:             tcg_gen_extu_i32_tl(t1, fp0);
                   1286:             tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
                   1287:             tcg_temp_free(t1);
                   1288:             tcg_temp_free_i32(fp0);
                   1289:         }
1.1.1.4   root     1290:         opn = "swc1";
                   1291:         break;
                   1292:     case OPC_LDC1:
1.1.1.7   root     1293:         {
                   1294:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   1295: 
                   1296:             tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
                   1297:             gen_store_fpr64(ctx, fp0, ft);
                   1298:             tcg_temp_free_i64(fp0);
                   1299:         }
1.1.1.4   root     1300:         opn = "ldc1";
                   1301:         break;
                   1302:     case OPC_SDC1:
1.1.1.7   root     1303:         {
                   1304:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   1305: 
                   1306:             gen_load_fpr64(ctx, fp0, ft);
                   1307:             tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
                   1308:             tcg_temp_free_i64(fp0);
                   1309:         }
1.1.1.4   root     1310:         opn = "sdc1";
                   1311:         break;
                   1312:     default:
1.1.1.6   root     1313:         MIPS_INVAL(opn);
                   1314:         generate_exception(ctx, EXCP_RI);
1.1.1.7   root     1315:         goto out;
1.1.1.4   root     1316:     }
1.1.1.13  root     1317:     (void)opn; /* avoid a compiler warning */
1.1.1.4   root     1318:     MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1.1.1.7   root     1319:  out:
                   1320:     tcg_temp_free(t0);
1.1.1.4   root     1321: }
1.1.1.5   root     1322: 
1.1.1.12  root     1323: static void gen_cop1_ldst(CPUState *env, DisasContext *ctx,
                   1324:                           uint32_t op, int rt, int rs, int16_t imm)
                   1325: {
                   1326:     if (env->CP0_Config1 & (1 << CP0C1_FP)) {
                   1327:         check_cp1_enabled(ctx);
                   1328:         gen_flt_ldst(ctx, op, rt, rs, imm);
                   1329:     } else {
                   1330:         generate_exception_err(ctx, EXCP_CpU, 1);
                   1331:     }
                   1332: }
                   1333: 
1.1       root     1334: /* Arithmetic with immediate operand */
1.1.1.6   root     1335: static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
                   1336:                            int rt, int rs, int16_t imm)
1.1       root     1337: {
1.1.1.8   root     1338:     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
1.1.1.6   root     1339:     const char *opn = "imm arith";
1.1       root     1340: 
1.1.1.5   root     1341:     if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1.1.1.6   root     1342:         /* If no destination, treat it as a NOP.
                   1343:            For addi, we must generate the overflow exception when needed. */
1.1       root     1344:         MIPS_DEBUG("NOP");
1.1.1.8   root     1345:         return;
1.1       root     1346:     }
                   1347:     switch (opc) {
                   1348:     case OPC_ADDI:
1.1.1.7   root     1349:         {
1.1.1.8   root     1350:             TCGv t0 = tcg_temp_local_new();
                   1351:             TCGv t1 = tcg_temp_new();
                   1352:             TCGv t2 = tcg_temp_new();
1.1.1.7   root     1353:             int l1 = gen_new_label();
                   1354: 
1.1.1.8   root     1355:             gen_load_gpr(t1, rs);
                   1356:             tcg_gen_addi_tl(t0, t1, uimm);
                   1357:             tcg_gen_ext32s_tl(t0, t0);
1.1.1.7   root     1358: 
1.1.1.8   root     1359:             tcg_gen_xori_tl(t1, t1, ~uimm);
                   1360:             tcg_gen_xori_tl(t2, t0, uimm);
                   1361:             tcg_gen_and_tl(t1, t1, t2);
                   1362:             tcg_temp_free(t2);
                   1363:             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
                   1364:             tcg_temp_free(t1);
1.1.1.7   root     1365:             /* operands of same sign, result different sign */
                   1366:             generate_exception(ctx, EXCP_OVERFLOW);
                   1367:             gen_set_label(l1);
                   1368:             tcg_gen_ext32s_tl(t0, t0);
1.1.1.8   root     1369:             gen_store_gpr(t0, rt);
                   1370:             tcg_temp_free(t0);
1.1.1.7   root     1371:         }
1.1       root     1372:         opn = "addi";
                   1373:         break;
                   1374:     case OPC_ADDIU:
1.1.1.8   root     1375:         if (rs != 0) {
                   1376:             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
                   1377:             tcg_gen_ext32s_tl(cpu_gpr[rt], cpu_gpr[rt]);
                   1378:         } else {
                   1379:             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
                   1380:         }
1.1       root     1381:         opn = "addiu";
                   1382:         break;
1.1.1.6   root     1383: #if defined(TARGET_MIPS64)
1.1.1.5   root     1384:     case OPC_DADDI:
1.1.1.7   root     1385:         {
1.1.1.8   root     1386:             TCGv t0 = tcg_temp_local_new();
                   1387:             TCGv t1 = tcg_temp_new();
                   1388:             TCGv t2 = tcg_temp_new();
1.1.1.7   root     1389:             int l1 = gen_new_label();
                   1390: 
1.1.1.8   root     1391:             gen_load_gpr(t1, rs);
                   1392:             tcg_gen_addi_tl(t0, t1, uimm);
1.1.1.7   root     1393: 
1.1.1.8   root     1394:             tcg_gen_xori_tl(t1, t1, ~uimm);
                   1395:             tcg_gen_xori_tl(t2, t0, uimm);
                   1396:             tcg_gen_and_tl(t1, t1, t2);
                   1397:             tcg_temp_free(t2);
                   1398:             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
                   1399:             tcg_temp_free(t1);
1.1.1.7   root     1400:             /* operands of same sign, result different sign */
                   1401:             generate_exception(ctx, EXCP_OVERFLOW);
                   1402:             gen_set_label(l1);
1.1.1.8   root     1403:             gen_store_gpr(t0, rt);
                   1404:             tcg_temp_free(t0);
1.1.1.7   root     1405:         }
1.1.1.5   root     1406:         opn = "daddi";
                   1407:         break;
                   1408:     case OPC_DADDIU:
1.1.1.8   root     1409:         if (rs != 0) {
                   1410:             tcg_gen_addi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
                   1411:         } else {
                   1412:             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
                   1413:         }
1.1.1.5   root     1414:         opn = "daddiu";
                   1415:         break;
                   1416: #endif
1.1.1.8   root     1417:     }
1.1.1.13  root     1418:     (void)opn; /* avoid a compiler warning */
1.1.1.8   root     1419:     MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
                   1420: }
                   1421: 
                   1422: /* Logic with immediate operand */
                   1423: static void gen_logic_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
                   1424: {
                   1425:     target_ulong uimm;
                   1426:     const char *opn = "imm logic";
                   1427: 
                   1428:     if (rt == 0) {
                   1429:         /* If no destination, treat it as a NOP. */
                   1430:         MIPS_DEBUG("NOP");
                   1431:         return;
                   1432:     }
                   1433:     uimm = (uint16_t)imm;
                   1434:     switch (opc) {
1.1       root     1435:     case OPC_ANDI:
1.1.1.8   root     1436:         if (likely(rs != 0))
                   1437:             tcg_gen_andi_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
                   1438:         else
                   1439:             tcg_gen_movi_tl(cpu_gpr[rt], 0);
1.1       root     1440:         opn = "andi";
                   1441:         break;
                   1442:     case OPC_ORI:
1.1.1.8   root     1443:         if (rs != 0)
                   1444:             tcg_gen_ori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
                   1445:         else
                   1446:             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1.1       root     1447:         opn = "ori";
                   1448:         break;
                   1449:     case OPC_XORI:
1.1.1.8   root     1450:         if (likely(rs != 0))
                   1451:             tcg_gen_xori_tl(cpu_gpr[rt], cpu_gpr[rs], uimm);
                   1452:         else
                   1453:             tcg_gen_movi_tl(cpu_gpr[rt], uimm);
1.1       root     1454:         opn = "xori";
                   1455:         break;
                   1456:     case OPC_LUI:
1.1.1.8   root     1457:         tcg_gen_movi_tl(cpu_gpr[rt], imm << 16);
1.1       root     1458:         opn = "lui";
                   1459:         break;
1.1.1.8   root     1460:     }
1.1.1.13  root     1461:     (void)opn; /* avoid a compiler warning */
1.1.1.8   root     1462:     MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
                   1463: }
                   1464: 
                   1465: /* Set on less than with immediate operand */
                   1466: static void gen_slt_imm (CPUState *env, uint32_t opc, int rt, int rs, int16_t imm)
                   1467: {
                   1468:     target_ulong uimm = (target_long)imm; /* Sign extend to 32/64 bits */
                   1469:     const char *opn = "imm arith";
                   1470:     TCGv t0;
                   1471: 
                   1472:     if (rt == 0) {
                   1473:         /* If no destination, treat it as a NOP. */
                   1474:         MIPS_DEBUG("NOP");
                   1475:         return;
                   1476:     }
                   1477:     t0 = tcg_temp_new();
                   1478:     gen_load_gpr(t0, rs);
                   1479:     switch (opc) {
                   1480:     case OPC_SLTI:
1.1.1.12  root     1481:         tcg_gen_setcondi_tl(TCG_COND_LT, cpu_gpr[rt], t0, uimm);
1.1.1.8   root     1482:         opn = "slti";
                   1483:         break;
                   1484:     case OPC_SLTIU:
1.1.1.12  root     1485:         tcg_gen_setcondi_tl(TCG_COND_LTU, cpu_gpr[rt], t0, uimm);
1.1.1.8   root     1486:         opn = "sltiu";
                   1487:         break;
                   1488:     }
1.1.1.13  root     1489:     (void)opn; /* avoid a compiler warning */
1.1.1.8   root     1490:     MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
                   1491:     tcg_temp_free(t0);
                   1492: }
                   1493: 
                   1494: /* Shifts with immediate operand */
                   1495: static void gen_shift_imm(CPUState *env, DisasContext *ctx, uint32_t opc,
                   1496:                           int rt, int rs, int16_t imm)
                   1497: {
                   1498:     target_ulong uimm = ((uint16_t)imm) & 0x1f;
                   1499:     const char *opn = "imm shift";
                   1500:     TCGv t0;
                   1501: 
                   1502:     if (rt == 0) {
                   1503:         /* If no destination, treat it as a NOP. */
                   1504:         MIPS_DEBUG("NOP");
                   1505:         return;
                   1506:     }
                   1507: 
                   1508:     t0 = tcg_temp_new();
                   1509:     gen_load_gpr(t0, rs);
                   1510:     switch (opc) {
1.1       root     1511:     case OPC_SLL:
1.1.1.7   root     1512:         tcg_gen_shli_tl(t0, t0, uimm);
1.1.1.8   root     1513:         tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1.1       root     1514:         opn = "sll";
                   1515:         break;
                   1516:     case OPC_SRA:
1.1.1.8   root     1517:         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1.1       root     1518:         opn = "sra";
                   1519:         break;
                   1520:     case OPC_SRL:
1.1.1.12  root     1521:         if (uimm != 0) {
                   1522:             tcg_gen_ext32u_tl(t0, t0);
                   1523:             tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
                   1524:         } else {
                   1525:             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
                   1526:         }
                   1527:         opn = "srl";
                   1528:         break;
                   1529:     case OPC_ROTR:
                   1530:         if (uimm != 0) {
                   1531:             TCGv_i32 t1 = tcg_temp_new_i32();
1.1.1.7   root     1532: 
1.1.1.12  root     1533:             tcg_gen_trunc_tl_i32(t1, t0);
                   1534:             tcg_gen_rotri_i32(t1, t1, uimm);
                   1535:             tcg_gen_ext_i32_tl(cpu_gpr[rt], t1);
                   1536:             tcg_temp_free_i32(t1);
                   1537:         } else {
                   1538:             tcg_gen_ext32s_tl(cpu_gpr[rt], t0);
1.1.1.6   root     1539:         }
1.1.1.12  root     1540:         opn = "rotr";
1.1.1.5   root     1541:         break;
1.1.1.6   root     1542: #if defined(TARGET_MIPS64)
1.1.1.5   root     1543:     case OPC_DSLL:
1.1.1.8   root     1544:         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm);
1.1.1.5   root     1545:         opn = "dsll";
                   1546:         break;
                   1547:     case OPC_DSRA:
1.1.1.8   root     1548:         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm);
1.1.1.5   root     1549:         opn = "dsra";
                   1550:         break;
                   1551:     case OPC_DSRL:
1.1.1.12  root     1552:         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm);
                   1553:         opn = "dsrl";
                   1554:         break;
                   1555:     case OPC_DROTR:
                   1556:         if (uimm != 0) {
                   1557:             tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm);
                   1558:         } else {
                   1559:             tcg_gen_mov_tl(cpu_gpr[rt], t0);
1.1.1.6   root     1560:         }
1.1.1.12  root     1561:         opn = "drotr";
1.1.1.5   root     1562:         break;
                   1563:     case OPC_DSLL32:
1.1.1.8   root     1564:         tcg_gen_shli_tl(cpu_gpr[rt], t0, uimm + 32);
1.1.1.5   root     1565:         opn = "dsll32";
                   1566:         break;
                   1567:     case OPC_DSRA32:
1.1.1.8   root     1568:         tcg_gen_sari_tl(cpu_gpr[rt], t0, uimm + 32);
1.1.1.5   root     1569:         opn = "dsra32";
                   1570:         break;
                   1571:     case OPC_DSRL32:
1.1.1.12  root     1572:         tcg_gen_shri_tl(cpu_gpr[rt], t0, uimm + 32);
                   1573:         opn = "dsrl32";
                   1574:         break;
                   1575:     case OPC_DROTR32:
                   1576:         tcg_gen_rotri_tl(cpu_gpr[rt], t0, uimm + 32);
                   1577:         opn = "drotr32";
1.1       root     1578:         break;
1.1.1.5   root     1579: #endif
1.1       root     1580:     }
1.1.1.13  root     1581:     (void)opn; /* avoid a compiler warning */
1.1.1.6   root     1582:     MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1.1.1.7   root     1583:     tcg_temp_free(t0);
1.1       root     1584: }
                   1585: 
                   1586: /* Arithmetic */
1.1.1.6   root     1587: static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1.1       root     1588:                        int rd, int rs, int rt)
                   1589: {
1.1.1.6   root     1590:     const char *opn = "arith";
1.1       root     1591: 
1.1.1.5   root     1592:     if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
                   1593:        && opc != OPC_DADD && opc != OPC_DSUB) {
1.1.1.6   root     1594:         /* If no destination, treat it as a NOP.
                   1595:            For add & sub, we must generate the overflow exception when needed. */
1.1       root     1596:         MIPS_DEBUG("NOP");
1.1.1.8   root     1597:         return;
1.1.1.6   root     1598:     }
1.1.1.8   root     1599: 
1.1       root     1600:     switch (opc) {
                   1601:     case OPC_ADD:
1.1.1.7   root     1602:         {
1.1.1.8   root     1603:             TCGv t0 = tcg_temp_local_new();
                   1604:             TCGv t1 = tcg_temp_new();
                   1605:             TCGv t2 = tcg_temp_new();
1.1.1.7   root     1606:             int l1 = gen_new_label();
                   1607: 
1.1.1.8   root     1608:             gen_load_gpr(t1, rs);
                   1609:             gen_load_gpr(t2, rt);
                   1610:             tcg_gen_add_tl(t0, t1, t2);
                   1611:             tcg_gen_ext32s_tl(t0, t0);
                   1612:             tcg_gen_xor_tl(t1, t1, t2);
                   1613:             tcg_gen_xor_tl(t2, t0, t2);
1.1.1.12  root     1614:             tcg_gen_andc_tl(t1, t2, t1);
1.1.1.8   root     1615:             tcg_temp_free(t2);
                   1616:             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
                   1617:             tcg_temp_free(t1);
1.1.1.7   root     1618:             /* operands of same sign, result different sign */
                   1619:             generate_exception(ctx, EXCP_OVERFLOW);
                   1620:             gen_set_label(l1);
1.1.1.8   root     1621:             gen_store_gpr(t0, rd);
                   1622:             tcg_temp_free(t0);
1.1.1.7   root     1623:         }
1.1       root     1624:         opn = "add";
                   1625:         break;
                   1626:     case OPC_ADDU:
1.1.1.8   root     1627:         if (rs != 0 && rt != 0) {
                   1628:             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
                   1629:             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
                   1630:         } else if (rs == 0 && rt != 0) {
                   1631:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
                   1632:         } else if (rs != 0 && rt == 0) {
                   1633:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   1634:         } else {
                   1635:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   1636:         }
1.1       root     1637:         opn = "addu";
                   1638:         break;
                   1639:     case OPC_SUB:
1.1.1.7   root     1640:         {
1.1.1.8   root     1641:             TCGv t0 = tcg_temp_local_new();
                   1642:             TCGv t1 = tcg_temp_new();
                   1643:             TCGv t2 = tcg_temp_new();
1.1.1.7   root     1644:             int l1 = gen_new_label();
                   1645: 
1.1.1.8   root     1646:             gen_load_gpr(t1, rs);
                   1647:             gen_load_gpr(t2, rt);
                   1648:             tcg_gen_sub_tl(t0, t1, t2);
                   1649:             tcg_gen_ext32s_tl(t0, t0);
                   1650:             tcg_gen_xor_tl(t2, t1, t2);
                   1651:             tcg_gen_xor_tl(t1, t0, t1);
                   1652:             tcg_gen_and_tl(t1, t1, t2);
                   1653:             tcg_temp_free(t2);
                   1654:             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
                   1655:             tcg_temp_free(t1);
1.1.1.9   root     1656:             /* operands of different sign, first operand and result different sign */
1.1.1.7   root     1657:             generate_exception(ctx, EXCP_OVERFLOW);
                   1658:             gen_set_label(l1);
1.1.1.8   root     1659:             gen_store_gpr(t0, rd);
                   1660:             tcg_temp_free(t0);
1.1.1.7   root     1661:         }
1.1       root     1662:         opn = "sub";
                   1663:         break;
                   1664:     case OPC_SUBU:
1.1.1.8   root     1665:         if (rs != 0 && rt != 0) {
                   1666:             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
                   1667:             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
                   1668:         } else if (rs == 0 && rt != 0) {
                   1669:             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
                   1670:             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
                   1671:         } else if (rs != 0 && rt == 0) {
                   1672:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   1673:         } else {
                   1674:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   1675:         }
1.1       root     1676:         opn = "subu";
                   1677:         break;
1.1.1.6   root     1678: #if defined(TARGET_MIPS64)
1.1.1.5   root     1679:     case OPC_DADD:
1.1.1.7   root     1680:         {
1.1.1.8   root     1681:             TCGv t0 = tcg_temp_local_new();
                   1682:             TCGv t1 = tcg_temp_new();
                   1683:             TCGv t2 = tcg_temp_new();
1.1.1.7   root     1684:             int l1 = gen_new_label();
                   1685: 
1.1.1.8   root     1686:             gen_load_gpr(t1, rs);
                   1687:             gen_load_gpr(t2, rt);
                   1688:             tcg_gen_add_tl(t0, t1, t2);
                   1689:             tcg_gen_xor_tl(t1, t1, t2);
                   1690:             tcg_gen_xor_tl(t2, t0, t2);
1.1.1.12  root     1691:             tcg_gen_andc_tl(t1, t2, t1);
1.1.1.8   root     1692:             tcg_temp_free(t2);
                   1693:             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
                   1694:             tcg_temp_free(t1);
1.1.1.7   root     1695:             /* operands of same sign, result different sign */
                   1696:             generate_exception(ctx, EXCP_OVERFLOW);
                   1697:             gen_set_label(l1);
1.1.1.8   root     1698:             gen_store_gpr(t0, rd);
                   1699:             tcg_temp_free(t0);
1.1.1.7   root     1700:         }
1.1.1.5   root     1701:         opn = "dadd";
                   1702:         break;
                   1703:     case OPC_DADDU:
1.1.1.8   root     1704:         if (rs != 0 && rt != 0) {
                   1705:             tcg_gen_add_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
                   1706:         } else if (rs == 0 && rt != 0) {
                   1707:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
                   1708:         } else if (rs != 0 && rt == 0) {
                   1709:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   1710:         } else {
                   1711:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   1712:         }
1.1.1.5   root     1713:         opn = "daddu";
                   1714:         break;
                   1715:     case OPC_DSUB:
1.1.1.7   root     1716:         {
1.1.1.8   root     1717:             TCGv t0 = tcg_temp_local_new();
                   1718:             TCGv t1 = tcg_temp_new();
                   1719:             TCGv t2 = tcg_temp_new();
1.1.1.7   root     1720:             int l1 = gen_new_label();
                   1721: 
1.1.1.8   root     1722:             gen_load_gpr(t1, rs);
                   1723:             gen_load_gpr(t2, rt);
                   1724:             tcg_gen_sub_tl(t0, t1, t2);
                   1725:             tcg_gen_xor_tl(t2, t1, t2);
                   1726:             tcg_gen_xor_tl(t1, t0, t1);
                   1727:             tcg_gen_and_tl(t1, t1, t2);
                   1728:             tcg_temp_free(t2);
                   1729:             tcg_gen_brcondi_tl(TCG_COND_GE, t1, 0, l1);
                   1730:             tcg_temp_free(t1);
1.1.1.9   root     1731:             /* operands of different sign, first operand and result different sign */
1.1.1.7   root     1732:             generate_exception(ctx, EXCP_OVERFLOW);
                   1733:             gen_set_label(l1);
1.1.1.8   root     1734:             gen_store_gpr(t0, rd);
                   1735:             tcg_temp_free(t0);
1.1.1.7   root     1736:         }
1.1.1.5   root     1737:         opn = "dsub";
                   1738:         break;
                   1739:     case OPC_DSUBU:
1.1.1.8   root     1740:         if (rs != 0 && rt != 0) {
                   1741:             tcg_gen_sub_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
                   1742:         } else if (rs == 0 && rt != 0) {
                   1743:             tcg_gen_neg_tl(cpu_gpr[rd], cpu_gpr[rt]);
                   1744:         } else if (rs != 0 && rt == 0) {
                   1745:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   1746:         } else {
                   1747:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   1748:         }
1.1.1.5   root     1749:         opn = "dsubu";
                   1750:         break;
                   1751: #endif
1.1.1.8   root     1752:     case OPC_MUL:
                   1753:         if (likely(rs != 0 && rt != 0)) {
                   1754:             tcg_gen_mul_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
                   1755:             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
                   1756:         } else {
                   1757:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   1758:         }
                   1759:         opn = "mul";
1.1       root     1760:         break;
1.1.1.8   root     1761:     }
1.1.1.13  root     1762:     (void)opn; /* avoid a compiler warning */
1.1.1.8   root     1763:     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
                   1764: }
                   1765: 
                   1766: /* Conditional move */
                   1767: static void gen_cond_move (CPUState *env, uint32_t opc, int rd, int rs, int rt)
                   1768: {
                   1769:     const char *opn = "cond move";
                   1770:     int l1;
                   1771: 
                   1772:     if (rd == 0) {
                   1773:         /* If no destination, treat it as a NOP.
                   1774:            For add & sub, we must generate the overflow exception when needed. */
                   1775:         MIPS_DEBUG("NOP");
                   1776:         return;
                   1777:     }
                   1778: 
                   1779:     l1 = gen_new_label();
                   1780:     switch (opc) {
                   1781:     case OPC_MOVN:
                   1782:         if (likely(rt != 0))
                   1783:             tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[rt], 0, l1);
                   1784:         else
                   1785:             tcg_gen_br(l1);
                   1786:         opn = "movn";
1.1       root     1787:         break;
1.1.1.8   root     1788:     case OPC_MOVZ:
                   1789:         if (likely(rt != 0))
                   1790:             tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[rt], 0, l1);
                   1791:         opn = "movz";
                   1792:         break;
                   1793:     }
                   1794:     if (rs != 0)
                   1795:         tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   1796:     else
                   1797:         tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   1798:     gen_set_label(l1);
                   1799: 
1.1.1.13  root     1800:     (void)opn; /* avoid a compiler warning */
1.1.1.8   root     1801:     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
                   1802: }
                   1803: 
                   1804: /* Logic */
                   1805: static void gen_logic (CPUState *env, uint32_t opc, int rd, int rs, int rt)
                   1806: {
                   1807:     const char *opn = "logic";
                   1808: 
                   1809:     if (rd == 0) {
                   1810:         /* If no destination, treat it as a NOP. */
                   1811:         MIPS_DEBUG("NOP");
                   1812:         return;
                   1813:     }
                   1814: 
                   1815:     switch (opc) {
1.1       root     1816:     case OPC_AND:
1.1.1.8   root     1817:         if (likely(rs != 0 && rt != 0)) {
                   1818:             tcg_gen_and_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
                   1819:         } else {
                   1820:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   1821:         }
1.1       root     1822:         opn = "and";
                   1823:         break;
                   1824:     case OPC_NOR:
1.1.1.8   root     1825:         if (rs != 0 && rt != 0) {
                   1826:             tcg_gen_nor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
                   1827:         } else if (rs == 0 && rt != 0) {
                   1828:             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rt]);
                   1829:         } else if (rs != 0 && rt == 0) {
                   1830:             tcg_gen_not_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   1831:         } else {
                   1832:             tcg_gen_movi_tl(cpu_gpr[rd], ~((target_ulong)0));
                   1833:         }
1.1       root     1834:         opn = "nor";
                   1835:         break;
                   1836:     case OPC_OR:
1.1.1.8   root     1837:         if (likely(rs != 0 && rt != 0)) {
                   1838:             tcg_gen_or_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
                   1839:         } else if (rs == 0 && rt != 0) {
                   1840:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
                   1841:         } else if (rs != 0 && rt == 0) {
                   1842:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   1843:         } else {
                   1844:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   1845:         }
1.1       root     1846:         opn = "or";
                   1847:         break;
                   1848:     case OPC_XOR:
1.1.1.8   root     1849:         if (likely(rs != 0 && rt != 0)) {
                   1850:             tcg_gen_xor_tl(cpu_gpr[rd], cpu_gpr[rs], cpu_gpr[rt]);
                   1851:         } else if (rs == 0 && rt != 0) {
                   1852:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rt]);
                   1853:         } else if (rs != 0 && rt == 0) {
                   1854:             tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   1855:         } else {
                   1856:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   1857:         }
1.1       root     1858:         opn = "xor";
                   1859:         break;
1.1.1.8   root     1860:     }
1.1.1.13  root     1861:     (void)opn; /* avoid a compiler warning */
1.1.1.8   root     1862:     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
                   1863: }
                   1864: 
                   1865: /* Set on lower than */
                   1866: static void gen_slt (CPUState *env, uint32_t opc, int rd, int rs, int rt)
                   1867: {
                   1868:     const char *opn = "slt";
                   1869:     TCGv t0, t1;
                   1870: 
                   1871:     if (rd == 0) {
                   1872:         /* If no destination, treat it as a NOP. */
                   1873:         MIPS_DEBUG("NOP");
                   1874:         return;
                   1875:     }
                   1876: 
                   1877:     t0 = tcg_temp_new();
                   1878:     t1 = tcg_temp_new();
                   1879:     gen_load_gpr(t0, rs);
                   1880:     gen_load_gpr(t1, rt);
                   1881:     switch (opc) {
                   1882:     case OPC_SLT:
1.1.1.12  root     1883:         tcg_gen_setcond_tl(TCG_COND_LT, cpu_gpr[rd], t0, t1);
1.1.1.8   root     1884:         opn = "slt";
1.1       root     1885:         break;
1.1.1.8   root     1886:     case OPC_SLTU:
1.1.1.12  root     1887:         tcg_gen_setcond_tl(TCG_COND_LTU, cpu_gpr[rd], t0, t1);
1.1.1.8   root     1888:         opn = "sltu";
                   1889:         break;
                   1890:     }
1.1.1.13  root     1891:     (void)opn; /* avoid a compiler warning */
1.1.1.8   root     1892:     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
                   1893:     tcg_temp_free(t0);
                   1894:     tcg_temp_free(t1);
                   1895: }
1.1.1.7   root     1896: 
1.1.1.8   root     1897: /* Shifts */
                   1898: static void gen_shift (CPUState *env, DisasContext *ctx, uint32_t opc,
                   1899:                        int rd, int rs, int rt)
                   1900: {
                   1901:     const char *opn = "shifts";
                   1902:     TCGv t0, t1;
1.1.1.7   root     1903: 
1.1.1.8   root     1904:     if (rd == 0) {
                   1905:         /* If no destination, treat it as a NOP.
                   1906:            For add & sub, we must generate the overflow exception when needed. */
                   1907:         MIPS_DEBUG("NOP");
                   1908:         return;
                   1909:     }
                   1910: 
                   1911:     t0 = tcg_temp_new();
                   1912:     t1 = tcg_temp_new();
                   1913:     gen_load_gpr(t0, rs);
                   1914:     gen_load_gpr(t1, rt);
                   1915:     switch (opc) {
1.1       root     1916:     case OPC_SLLV:
1.1.1.7   root     1917:         tcg_gen_andi_tl(t0, t0, 0x1f);
                   1918:         tcg_gen_shl_tl(t0, t1, t0);
1.1.1.8   root     1919:         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
1.1       root     1920:         opn = "sllv";
                   1921:         break;
                   1922:     case OPC_SRAV:
1.1.1.7   root     1923:         tcg_gen_andi_tl(t0, t0, 0x1f);
1.1.1.8   root     1924:         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1.1       root     1925:         opn = "srav";
                   1926:         break;
                   1927:     case OPC_SRLV:
1.1.1.12  root     1928:         tcg_gen_ext32u_tl(t1, t1);
                   1929:         tcg_gen_andi_tl(t0, t0, 0x1f);
                   1930:         tcg_gen_shr_tl(t0, t1, t0);
                   1931:         tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
                   1932:         opn = "srlv";
                   1933:         break;
                   1934:     case OPC_ROTRV:
                   1935:         {
                   1936:             TCGv_i32 t2 = tcg_temp_new_i32();
                   1937:             TCGv_i32 t3 = tcg_temp_new_i32();
                   1938: 
                   1939:             tcg_gen_trunc_tl_i32(t2, t0);
                   1940:             tcg_gen_trunc_tl_i32(t3, t1);
                   1941:             tcg_gen_andi_i32(t2, t2, 0x1f);
                   1942:             tcg_gen_rotr_i32(t2, t3, t2);
                   1943:             tcg_gen_ext_i32_tl(cpu_gpr[rd], t2);
                   1944:             tcg_temp_free_i32(t2);
                   1945:             tcg_temp_free_i32(t3);
                   1946:             opn = "rotrv";
1.1.1.6   root     1947:         }
1.1.1.5   root     1948:         break;
1.1.1.6   root     1949: #if defined(TARGET_MIPS64)
1.1.1.5   root     1950:     case OPC_DSLLV:
1.1.1.7   root     1951:         tcg_gen_andi_tl(t0, t0, 0x3f);
1.1.1.8   root     1952:         tcg_gen_shl_tl(cpu_gpr[rd], t1, t0);
1.1.1.5   root     1953:         opn = "dsllv";
                   1954:         break;
                   1955:     case OPC_DSRAV:
1.1.1.7   root     1956:         tcg_gen_andi_tl(t0, t0, 0x3f);
1.1.1.8   root     1957:         tcg_gen_sar_tl(cpu_gpr[rd], t1, t0);
1.1.1.5   root     1958:         opn = "dsrav";
                   1959:         break;
                   1960:     case OPC_DSRLV:
1.1.1.12  root     1961:         tcg_gen_andi_tl(t0, t0, 0x3f);
                   1962:         tcg_gen_shr_tl(cpu_gpr[rd], t1, t0);
                   1963:         opn = "dsrlv";
                   1964:         break;
                   1965:     case OPC_DROTRV:
                   1966:         tcg_gen_andi_tl(t0, t0, 0x3f);
                   1967:         tcg_gen_rotr_tl(cpu_gpr[rd], t1, t0);
                   1968:         opn = "drotrv";
1.1       root     1969:         break;
1.1.1.5   root     1970: #endif
1.1       root     1971:     }
1.1.1.13  root     1972:     (void)opn; /* avoid a compiler warning */
1.1       root     1973:     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1.1.1.7   root     1974:     tcg_temp_free(t0);
                   1975:     tcg_temp_free(t1);
1.1       root     1976: }
                   1977: 
                   1978: /* Arithmetic on HI/LO registers */
1.1.1.5   root     1979: static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1.1       root     1980: {
1.1.1.6   root     1981:     const char *opn = "hilo";
1.1       root     1982: 
                   1983:     if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1.1.1.6   root     1984:         /* Treat as NOP. */
1.1       root     1985:         MIPS_DEBUG("NOP");
1.1.1.8   root     1986:         return;
1.1       root     1987:     }
                   1988:     switch (opc) {
                   1989:     case OPC_MFHI:
1.1.1.8   root     1990:         tcg_gen_mov_tl(cpu_gpr[reg], cpu_HI[0]);
1.1       root     1991:         opn = "mfhi";
                   1992:         break;
                   1993:     case OPC_MFLO:
1.1.1.8   root     1994:         tcg_gen_mov_tl(cpu_gpr[reg], cpu_LO[0]);
1.1       root     1995:         opn = "mflo";
                   1996:         break;
                   1997:     case OPC_MTHI:
1.1.1.8   root     1998:         if (reg != 0)
                   1999:             tcg_gen_mov_tl(cpu_HI[0], cpu_gpr[reg]);
                   2000:         else
                   2001:             tcg_gen_movi_tl(cpu_HI[0], 0);
1.1       root     2002:         opn = "mthi";
                   2003:         break;
                   2004:     case OPC_MTLO:
1.1.1.8   root     2005:         if (reg != 0)
                   2006:             tcg_gen_mov_tl(cpu_LO[0], cpu_gpr[reg]);
                   2007:         else
                   2008:             tcg_gen_movi_tl(cpu_LO[0], 0);
1.1       root     2009:         opn = "mtlo";
                   2010:         break;
                   2011:     }
1.1.1.13  root     2012:     (void)opn; /* avoid a compiler warning */
1.1       root     2013:     MIPS_DEBUG("%s %s", opn, regnames[reg]);
                   2014: }
                   2015: 
1.1.1.5   root     2016: static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1.1       root     2017:                         int rs, int rt)
                   2018: {
1.1.1.6   root     2019:     const char *opn = "mul/div";
1.1.1.8   root     2020:     TCGv t0, t1;
                   2021: 
                   2022:     switch (opc) {
                   2023:     case OPC_DIV:
                   2024:     case OPC_DIVU:
                   2025: #if defined(TARGET_MIPS64)
                   2026:     case OPC_DDIV:
                   2027:     case OPC_DDIVU:
                   2028: #endif
                   2029:         t0 = tcg_temp_local_new();
                   2030:         t1 = tcg_temp_local_new();
                   2031:         break;
                   2032:     default:
                   2033:         t0 = tcg_temp_new();
                   2034:         t1 = tcg_temp_new();
                   2035:         break;
                   2036:     }
1.1       root     2037: 
1.1.1.7   root     2038:     gen_load_gpr(t0, rs);
                   2039:     gen_load_gpr(t1, rt);
1.1       root     2040:     switch (opc) {
                   2041:     case OPC_DIV:
1.1.1.7   root     2042:         {
                   2043:             int l1 = gen_new_label();
1.1.1.8   root     2044:             int l2 = gen_new_label();
1.1.1.7   root     2045: 
1.1.1.8   root     2046:             tcg_gen_ext32s_tl(t0, t0);
                   2047:             tcg_gen_ext32s_tl(t1, t1);
1.1.1.7   root     2048:             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1.1.1.8   root     2049:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
                   2050:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
                   2051: 
                   2052:             tcg_gen_mov_tl(cpu_LO[0], t0);
                   2053:             tcg_gen_movi_tl(cpu_HI[0], 0);
                   2054:             tcg_gen_br(l1);
                   2055:             gen_set_label(l2);
                   2056:             tcg_gen_div_tl(cpu_LO[0], t0, t1);
                   2057:             tcg_gen_rem_tl(cpu_HI[0], t0, t1);
                   2058:             tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
                   2059:             tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
1.1.1.7   root     2060:             gen_set_label(l1);
                   2061:         }
1.1       root     2062:         opn = "div";
                   2063:         break;
                   2064:     case OPC_DIVU:
1.1.1.7   root     2065:         {
                   2066:             int l1 = gen_new_label();
                   2067: 
1.1.1.8   root     2068:             tcg_gen_ext32u_tl(t0, t0);
                   2069:             tcg_gen_ext32u_tl(t1, t1);
1.1.1.7   root     2070:             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1.1.1.8   root     2071:             tcg_gen_divu_tl(cpu_LO[0], t0, t1);
                   2072:             tcg_gen_remu_tl(cpu_HI[0], t0, t1);
                   2073:             tcg_gen_ext32s_tl(cpu_LO[0], cpu_LO[0]);
                   2074:             tcg_gen_ext32s_tl(cpu_HI[0], cpu_HI[0]);
1.1.1.7   root     2075:             gen_set_label(l1);
                   2076:         }
1.1       root     2077:         opn = "divu";
                   2078:         break;
                   2079:     case OPC_MULT:
1.1.1.7   root     2080:         {
1.1.1.8   root     2081:             TCGv_i64 t2 = tcg_temp_new_i64();
                   2082:             TCGv_i64 t3 = tcg_temp_new_i64();
1.1.1.7   root     2083: 
1.1.1.8   root     2084:             tcg_gen_ext_tl_i64(t2, t0);
                   2085:             tcg_gen_ext_tl_i64(t3, t1);
                   2086:             tcg_gen_mul_i64(t2, t2, t3);
                   2087:             tcg_temp_free_i64(t3);
                   2088:             tcg_gen_trunc_i64_tl(t0, t2);
                   2089:             tcg_gen_shri_i64(t2, t2, 32);
                   2090:             tcg_gen_trunc_i64_tl(t1, t2);
                   2091:             tcg_temp_free_i64(t2);
1.1.1.7   root     2092:             tcg_gen_ext32s_tl(cpu_LO[0], t0);
                   2093:             tcg_gen_ext32s_tl(cpu_HI[0], t1);
                   2094:         }
1.1       root     2095:         opn = "mult";
                   2096:         break;
                   2097:     case OPC_MULTU:
1.1.1.7   root     2098:         {
1.1.1.8   root     2099:             TCGv_i64 t2 = tcg_temp_new_i64();
                   2100:             TCGv_i64 t3 = tcg_temp_new_i64();
1.1.1.7   root     2101: 
                   2102:             tcg_gen_ext32u_tl(t0, t0);
                   2103:             tcg_gen_ext32u_tl(t1, t1);
1.1.1.8   root     2104:             tcg_gen_extu_tl_i64(t2, t0);
                   2105:             tcg_gen_extu_tl_i64(t3, t1);
                   2106:             tcg_gen_mul_i64(t2, t2, t3);
                   2107:             tcg_temp_free_i64(t3);
                   2108:             tcg_gen_trunc_i64_tl(t0, t2);
                   2109:             tcg_gen_shri_i64(t2, t2, 32);
                   2110:             tcg_gen_trunc_i64_tl(t1, t2);
                   2111:             tcg_temp_free_i64(t2);
1.1.1.7   root     2112:             tcg_gen_ext32s_tl(cpu_LO[0], t0);
                   2113:             tcg_gen_ext32s_tl(cpu_HI[0], t1);
                   2114:         }
1.1       root     2115:         opn = "multu";
                   2116:         break;
1.1.1.6   root     2117: #if defined(TARGET_MIPS64)
1.1.1.5   root     2118:     case OPC_DDIV:
1.1.1.7   root     2119:         {
                   2120:             int l1 = gen_new_label();
1.1.1.8   root     2121:             int l2 = gen_new_label();
1.1.1.7   root     2122: 
                   2123:             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
1.1.1.8   root     2124:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
                   2125:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
                   2126:             tcg_gen_mov_tl(cpu_LO[0], t0);
                   2127:             tcg_gen_movi_tl(cpu_HI[0], 0);
                   2128:             tcg_gen_br(l1);
                   2129:             gen_set_label(l2);
                   2130:             tcg_gen_div_i64(cpu_LO[0], t0, t1);
                   2131:             tcg_gen_rem_i64(cpu_HI[0], t0, t1);
1.1.1.7   root     2132:             gen_set_label(l1);
                   2133:         }
1.1.1.5   root     2134:         opn = "ddiv";
                   2135:         break;
                   2136:     case OPC_DDIVU:
1.1.1.7   root     2137:         {
                   2138:             int l1 = gen_new_label();
                   2139: 
                   2140:             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
                   2141:             tcg_gen_divu_i64(cpu_LO[0], t0, t1);
                   2142:             tcg_gen_remu_i64(cpu_HI[0], t0, t1);
                   2143:             gen_set_label(l1);
                   2144:         }
1.1.1.5   root     2145:         opn = "ddivu";
                   2146:         break;
                   2147:     case OPC_DMULT:
1.1.1.7   root     2148:         gen_helper_dmult(t0, t1);
1.1.1.5   root     2149:         opn = "dmult";
                   2150:         break;
                   2151:     case OPC_DMULTU:
1.1.1.7   root     2152:         gen_helper_dmultu(t0, t1);
1.1.1.5   root     2153:         opn = "dmultu";
                   2154:         break;
                   2155: #endif
1.1       root     2156:     case OPC_MADD:
1.1.1.7   root     2157:         {
1.1.1.8   root     2158:             TCGv_i64 t2 = tcg_temp_new_i64();
                   2159:             TCGv_i64 t3 = tcg_temp_new_i64();
1.1.1.7   root     2160: 
1.1.1.8   root     2161:             tcg_gen_ext_tl_i64(t2, t0);
                   2162:             tcg_gen_ext_tl_i64(t3, t1);
                   2163:             tcg_gen_mul_i64(t2, t2, t3);
                   2164:             tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
                   2165:             tcg_gen_add_i64(t2, t2, t3);
                   2166:             tcg_temp_free_i64(t3);
                   2167:             tcg_gen_trunc_i64_tl(t0, t2);
                   2168:             tcg_gen_shri_i64(t2, t2, 32);
                   2169:             tcg_gen_trunc_i64_tl(t1, t2);
                   2170:             tcg_temp_free_i64(t2);
1.1.1.7   root     2171:             tcg_gen_ext32s_tl(cpu_LO[0], t0);
1.1.1.8   root     2172:             tcg_gen_ext32s_tl(cpu_HI[0], t1);
1.1.1.7   root     2173:         }
1.1       root     2174:         opn = "madd";
                   2175:         break;
                   2176:     case OPC_MADDU:
1.1.1.7   root     2177:        {
1.1.1.8   root     2178:             TCGv_i64 t2 = tcg_temp_new_i64();
                   2179:             TCGv_i64 t3 = tcg_temp_new_i64();
1.1.1.7   root     2180: 
                   2181:             tcg_gen_ext32u_tl(t0, t0);
                   2182:             tcg_gen_ext32u_tl(t1, t1);
1.1.1.8   root     2183:             tcg_gen_extu_tl_i64(t2, t0);
                   2184:             tcg_gen_extu_tl_i64(t3, t1);
                   2185:             tcg_gen_mul_i64(t2, t2, t3);
                   2186:             tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
                   2187:             tcg_gen_add_i64(t2, t2, t3);
                   2188:             tcg_temp_free_i64(t3);
                   2189:             tcg_gen_trunc_i64_tl(t0, t2);
                   2190:             tcg_gen_shri_i64(t2, t2, 32);
                   2191:             tcg_gen_trunc_i64_tl(t1, t2);
                   2192:             tcg_temp_free_i64(t2);
1.1.1.7   root     2193:             tcg_gen_ext32s_tl(cpu_LO[0], t0);
                   2194:             tcg_gen_ext32s_tl(cpu_HI[0], t1);
                   2195:         }
1.1       root     2196:         opn = "maddu";
                   2197:         break;
                   2198:     case OPC_MSUB:
1.1.1.7   root     2199:         {
1.1.1.8   root     2200:             TCGv_i64 t2 = tcg_temp_new_i64();
                   2201:             TCGv_i64 t3 = tcg_temp_new_i64();
1.1.1.7   root     2202: 
1.1.1.8   root     2203:             tcg_gen_ext_tl_i64(t2, t0);
                   2204:             tcg_gen_ext_tl_i64(t3, t1);
                   2205:             tcg_gen_mul_i64(t2, t2, t3);
                   2206:             tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
                   2207:             tcg_gen_sub_i64(t2, t3, t2);
                   2208:             tcg_temp_free_i64(t3);
                   2209:             tcg_gen_trunc_i64_tl(t0, t2);
                   2210:             tcg_gen_shri_i64(t2, t2, 32);
                   2211:             tcg_gen_trunc_i64_tl(t1, t2);
                   2212:             tcg_temp_free_i64(t2);
1.1.1.7   root     2213:             tcg_gen_ext32s_tl(cpu_LO[0], t0);
                   2214:             tcg_gen_ext32s_tl(cpu_HI[0], t1);
                   2215:         }
1.1       root     2216:         opn = "msub";
                   2217:         break;
                   2218:     case OPC_MSUBU:
1.1.1.7   root     2219:         {
1.1.1.8   root     2220:             TCGv_i64 t2 = tcg_temp_new_i64();
                   2221:             TCGv_i64 t3 = tcg_temp_new_i64();
1.1.1.7   root     2222: 
                   2223:             tcg_gen_ext32u_tl(t0, t0);
                   2224:             tcg_gen_ext32u_tl(t1, t1);
1.1.1.8   root     2225:             tcg_gen_extu_tl_i64(t2, t0);
                   2226:             tcg_gen_extu_tl_i64(t3, t1);
                   2227:             tcg_gen_mul_i64(t2, t2, t3);
                   2228:             tcg_gen_concat_tl_i64(t3, cpu_LO[0], cpu_HI[0]);
                   2229:             tcg_gen_sub_i64(t2, t3, t2);
                   2230:             tcg_temp_free_i64(t3);
                   2231:             tcg_gen_trunc_i64_tl(t0, t2);
                   2232:             tcg_gen_shri_i64(t2, t2, 32);
                   2233:             tcg_gen_trunc_i64_tl(t1, t2);
                   2234:             tcg_temp_free_i64(t2);
1.1.1.7   root     2235:             tcg_gen_ext32s_tl(cpu_LO[0], t0);
                   2236:             tcg_gen_ext32s_tl(cpu_HI[0], t1);
                   2237:         }
1.1       root     2238:         opn = "msubu";
                   2239:         break;
                   2240:     default:
1.1.1.6   root     2241:         MIPS_INVAL(opn);
1.1       root     2242:         generate_exception(ctx, EXCP_RI);
1.1.1.7   root     2243:         goto out;
1.1       root     2244:     }
1.1.1.13  root     2245:     (void)opn; /* avoid a compiler warning */
1.1       root     2246:     MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
1.1.1.7   root     2247:  out:
                   2248:     tcg_temp_free(t0);
                   2249:     tcg_temp_free(t1);
1.1       root     2250: }
                   2251: 
1.1.1.6   root     2252: static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
                   2253:                             int rd, int rs, int rt)
                   2254: {
                   2255:     const char *opn = "mul vr54xx";
1.1.1.8   root     2256:     TCGv t0 = tcg_temp_new();
                   2257:     TCGv t1 = tcg_temp_new();
1.1.1.6   root     2258: 
1.1.1.7   root     2259:     gen_load_gpr(t0, rs);
                   2260:     gen_load_gpr(t1, rt);
1.1.1.6   root     2261: 
                   2262:     switch (opc) {
                   2263:     case OPC_VR54XX_MULS:
1.1.1.7   root     2264:         gen_helper_muls(t0, t0, t1);
1.1.1.6   root     2265:         opn = "muls";
1.1.1.7   root     2266:         break;
1.1.1.6   root     2267:     case OPC_VR54XX_MULSU:
1.1.1.7   root     2268:         gen_helper_mulsu(t0, t0, t1);
1.1.1.6   root     2269:         opn = "mulsu";
1.1.1.7   root     2270:         break;
1.1.1.6   root     2271:     case OPC_VR54XX_MACC:
1.1.1.7   root     2272:         gen_helper_macc(t0, t0, t1);
1.1.1.6   root     2273:         opn = "macc";
1.1.1.7   root     2274:         break;
1.1.1.6   root     2275:     case OPC_VR54XX_MACCU:
1.1.1.7   root     2276:         gen_helper_maccu(t0, t0, t1);
1.1.1.6   root     2277:         opn = "maccu";
1.1.1.7   root     2278:         break;
1.1.1.6   root     2279:     case OPC_VR54XX_MSAC:
1.1.1.7   root     2280:         gen_helper_msac(t0, t0, t1);
1.1.1.6   root     2281:         opn = "msac";
1.1.1.7   root     2282:         break;
1.1.1.6   root     2283:     case OPC_VR54XX_MSACU:
1.1.1.7   root     2284:         gen_helper_msacu(t0, t0, t1);
1.1.1.6   root     2285:         opn = "msacu";
1.1.1.7   root     2286:         break;
1.1.1.6   root     2287:     case OPC_VR54XX_MULHI:
1.1.1.7   root     2288:         gen_helper_mulhi(t0, t0, t1);
1.1.1.6   root     2289:         opn = "mulhi";
1.1.1.7   root     2290:         break;
1.1.1.6   root     2291:     case OPC_VR54XX_MULHIU:
1.1.1.7   root     2292:         gen_helper_mulhiu(t0, t0, t1);
1.1.1.6   root     2293:         opn = "mulhiu";
1.1.1.7   root     2294:         break;
1.1.1.6   root     2295:     case OPC_VR54XX_MULSHI:
1.1.1.7   root     2296:         gen_helper_mulshi(t0, t0, t1);
1.1.1.6   root     2297:         opn = "mulshi";
1.1.1.7   root     2298:         break;
1.1.1.6   root     2299:     case OPC_VR54XX_MULSHIU:
1.1.1.7   root     2300:         gen_helper_mulshiu(t0, t0, t1);
1.1.1.6   root     2301:         opn = "mulshiu";
1.1.1.7   root     2302:         break;
1.1.1.6   root     2303:     case OPC_VR54XX_MACCHI:
1.1.1.7   root     2304:         gen_helper_macchi(t0, t0, t1);
1.1.1.6   root     2305:         opn = "macchi";
1.1.1.7   root     2306:         break;
1.1.1.6   root     2307:     case OPC_VR54XX_MACCHIU:
1.1.1.7   root     2308:         gen_helper_macchiu(t0, t0, t1);
1.1.1.6   root     2309:         opn = "macchiu";
1.1.1.7   root     2310:         break;
1.1.1.6   root     2311:     case OPC_VR54XX_MSACHI:
1.1.1.7   root     2312:         gen_helper_msachi(t0, t0, t1);
1.1.1.6   root     2313:         opn = "msachi";
1.1.1.7   root     2314:         break;
1.1.1.6   root     2315:     case OPC_VR54XX_MSACHIU:
1.1.1.7   root     2316:         gen_helper_msachiu(t0, t0, t1);
1.1.1.6   root     2317:         opn = "msachiu";
1.1.1.7   root     2318:         break;
1.1.1.6   root     2319:     default:
                   2320:         MIPS_INVAL("mul vr54xx");
                   2321:         generate_exception(ctx, EXCP_RI);
1.1.1.7   root     2322:         goto out;
1.1.1.6   root     2323:     }
1.1.1.7   root     2324:     gen_store_gpr(t0, rd);
1.1.1.13  root     2325:     (void)opn; /* avoid a compiler warning */
1.1.1.6   root     2326:     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1.1.1.7   root     2327: 
                   2328:  out:
                   2329:     tcg_temp_free(t0);
                   2330:     tcg_temp_free(t1);
1.1.1.6   root     2331: }
                   2332: 
1.1.1.5   root     2333: static void gen_cl (DisasContext *ctx, uint32_t opc,
1.1       root     2334:                     int rd, int rs)
                   2335: {
1.1.1.6   root     2336:     const char *opn = "CLx";
1.1.1.8   root     2337:     TCGv t0;
1.1.1.7   root     2338: 
1.1       root     2339:     if (rd == 0) {
1.1.1.6   root     2340:         /* Treat as NOP. */
1.1       root     2341:         MIPS_DEBUG("NOP");
1.1.1.8   root     2342:         return;
1.1       root     2343:     }
1.1.1.8   root     2344:     t0 = tcg_temp_new();
1.1.1.7   root     2345:     gen_load_gpr(t0, rs);
1.1       root     2346:     switch (opc) {
                   2347:     case OPC_CLO:
1.1.1.8   root     2348:         gen_helper_clo(cpu_gpr[rd], t0);
1.1       root     2349:         opn = "clo";
                   2350:         break;
                   2351:     case OPC_CLZ:
1.1.1.8   root     2352:         gen_helper_clz(cpu_gpr[rd], t0);
1.1       root     2353:         opn = "clz";
                   2354:         break;
1.1.1.6   root     2355: #if defined(TARGET_MIPS64)
1.1.1.5   root     2356:     case OPC_DCLO:
1.1.1.8   root     2357:         gen_helper_dclo(cpu_gpr[rd], t0);
1.1.1.5   root     2358:         opn = "dclo";
                   2359:         break;
                   2360:     case OPC_DCLZ:
1.1.1.8   root     2361:         gen_helper_dclz(cpu_gpr[rd], t0);
1.1.1.5   root     2362:         opn = "dclz";
                   2363:         break;
                   2364: #endif
1.1       root     2365:     }
1.1.1.13  root     2366:     (void)opn; /* avoid a compiler warning */
1.1       root     2367:     MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
1.1.1.7   root     2368:     tcg_temp_free(t0);
1.1       root     2369: }
                   2370: 
1.1.1.12  root     2371: /* Godson integer instructions */
                   2372: static void gen_loongson_integer (DisasContext *ctx, uint32_t opc,
                   2373:                                 int rd, int rs, int rt)
                   2374: {
                   2375:     const char *opn = "loongson";
                   2376:     TCGv t0, t1;
                   2377: 
                   2378:     if (rd == 0) {
                   2379:         /* Treat as NOP. */
                   2380:         MIPS_DEBUG("NOP");
                   2381:         return;
                   2382:     }
                   2383: 
                   2384:     switch (opc) {
                   2385:     case OPC_MULT_G_2E:
                   2386:     case OPC_MULT_G_2F:
                   2387:     case OPC_MULTU_G_2E:
                   2388:     case OPC_MULTU_G_2F:
                   2389: #if defined(TARGET_MIPS64)
                   2390:     case OPC_DMULT_G_2E:
                   2391:     case OPC_DMULT_G_2F:
                   2392:     case OPC_DMULTU_G_2E:
                   2393:     case OPC_DMULTU_G_2F:
                   2394: #endif
                   2395:         t0 = tcg_temp_new();
                   2396:         t1 = tcg_temp_new();
                   2397:         break;
                   2398:     default:
                   2399:         t0 = tcg_temp_local_new();
                   2400:         t1 = tcg_temp_local_new();
                   2401:         break;
                   2402:     }
                   2403: 
                   2404:     gen_load_gpr(t0, rs);
                   2405:     gen_load_gpr(t1, rt);
                   2406: 
                   2407:     switch (opc) {
                   2408:     case OPC_MULT_G_2E:
                   2409:     case OPC_MULT_G_2F:
                   2410:         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
                   2411:         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
                   2412:         opn = "mult.g";
                   2413:         break;
                   2414:     case OPC_MULTU_G_2E:
                   2415:     case OPC_MULTU_G_2F:
                   2416:         tcg_gen_ext32u_tl(t0, t0);
                   2417:         tcg_gen_ext32u_tl(t1, t1);
                   2418:         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
                   2419:         tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
                   2420:         opn = "multu.g";
                   2421:         break;
                   2422:     case OPC_DIV_G_2E:
                   2423:     case OPC_DIV_G_2F:
                   2424:         {
                   2425:             int l1 = gen_new_label();
                   2426:             int l2 = gen_new_label();
                   2427:             int l3 = gen_new_label();
                   2428:             tcg_gen_ext32s_tl(t0, t0);
                   2429:             tcg_gen_ext32s_tl(t1, t1);
                   2430:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
                   2431:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   2432:             tcg_gen_br(l3);
                   2433:             gen_set_label(l1);
                   2434:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
                   2435:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
                   2436:             tcg_gen_mov_tl(cpu_gpr[rd], t0);
                   2437:             tcg_gen_br(l3);
                   2438:             gen_set_label(l2);
                   2439:             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
                   2440:             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
                   2441:             gen_set_label(l3);
                   2442:         }
                   2443:         opn = "div.g";
                   2444:         break;
                   2445:     case OPC_DIVU_G_2E:
                   2446:     case OPC_DIVU_G_2F:
                   2447:         {
                   2448:             int l1 = gen_new_label();
                   2449:             int l2 = gen_new_label();
                   2450:             tcg_gen_ext32u_tl(t0, t0);
                   2451:             tcg_gen_ext32u_tl(t1, t1);
                   2452:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
                   2453:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   2454:             tcg_gen_br(l2);
                   2455:             gen_set_label(l1);
                   2456:             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
                   2457:             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
                   2458:             gen_set_label(l2);
                   2459:         }
                   2460:         opn = "divu.g";
                   2461:         break;
                   2462:     case OPC_MOD_G_2E:
                   2463:     case OPC_MOD_G_2F:
                   2464:         {
                   2465:             int l1 = gen_new_label();
                   2466:             int l2 = gen_new_label();
                   2467:             int l3 = gen_new_label();
                   2468:             tcg_gen_ext32u_tl(t0, t0);
                   2469:             tcg_gen_ext32u_tl(t1, t1);
                   2470:             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
                   2471:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, INT_MIN, l2);
                   2472:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1, l2);
                   2473:             gen_set_label(l1);
                   2474:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   2475:             tcg_gen_br(l3);
                   2476:             gen_set_label(l2);
                   2477:             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
                   2478:             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
                   2479:             gen_set_label(l3);
                   2480:         }
                   2481:         opn = "mod.g";
                   2482:         break;
                   2483:     case OPC_MODU_G_2E:
                   2484:     case OPC_MODU_G_2F:
                   2485:         {
                   2486:             int l1 = gen_new_label();
                   2487:             int l2 = gen_new_label();
                   2488:             tcg_gen_ext32u_tl(t0, t0);
                   2489:             tcg_gen_ext32u_tl(t1, t1);
                   2490:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
                   2491:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   2492:             tcg_gen_br(l2);
                   2493:             gen_set_label(l1);
                   2494:             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
                   2495:             tcg_gen_ext32s_tl(cpu_gpr[rd], cpu_gpr[rd]);
                   2496:             gen_set_label(l2);
                   2497:         }
                   2498:         opn = "modu.g";
                   2499:         break;
                   2500: #if defined(TARGET_MIPS64)
                   2501:     case OPC_DMULT_G_2E:
                   2502:     case OPC_DMULT_G_2F:
                   2503:         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
                   2504:         opn = "dmult.g";
                   2505:         break;
                   2506:     case OPC_DMULTU_G_2E:
                   2507:     case OPC_DMULTU_G_2F:
                   2508:         tcg_gen_mul_tl(cpu_gpr[rd], t0, t1);
                   2509:         opn = "dmultu.g";
                   2510:         break;
                   2511:     case OPC_DDIV_G_2E:
                   2512:     case OPC_DDIV_G_2F:
                   2513:         {
                   2514:             int l1 = gen_new_label();
                   2515:             int l2 = gen_new_label();
                   2516:             int l3 = gen_new_label();
                   2517:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
                   2518:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   2519:             tcg_gen_br(l3);
                   2520:             gen_set_label(l1);
                   2521:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
                   2522:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
                   2523:             tcg_gen_mov_tl(cpu_gpr[rd], t0);
                   2524:             tcg_gen_br(l3);
                   2525:             gen_set_label(l2);
                   2526:             tcg_gen_div_tl(cpu_gpr[rd], t0, t1);
                   2527:             gen_set_label(l3);
                   2528:         }
                   2529:         opn = "ddiv.g";
                   2530:         break;
                   2531:     case OPC_DDIVU_G_2E:
                   2532:     case OPC_DDIVU_G_2F:
                   2533:         {
                   2534:             int l1 = gen_new_label();
                   2535:             int l2 = gen_new_label();
                   2536:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
                   2537:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   2538:             tcg_gen_br(l2);
                   2539:             gen_set_label(l1);
                   2540:             tcg_gen_divu_tl(cpu_gpr[rd], t0, t1);
                   2541:             gen_set_label(l2);
                   2542:         }
                   2543:         opn = "ddivu.g";
                   2544:         break;
                   2545:     case OPC_DMOD_G_2E:
                   2546:     case OPC_DMOD_G_2F:
                   2547:         {
                   2548:             int l1 = gen_new_label();
                   2549:             int l2 = gen_new_label();
                   2550:             int l3 = gen_new_label();
                   2551:             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
                   2552:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
                   2553:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
                   2554:             gen_set_label(l1);
                   2555:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   2556:             tcg_gen_br(l3);
                   2557:             gen_set_label(l2);
                   2558:             tcg_gen_rem_tl(cpu_gpr[rd], t0, t1);
                   2559:             gen_set_label(l3);
                   2560:         }
                   2561:         opn = "dmod.g";
                   2562:         break;
                   2563:     case OPC_DMODU_G_2E:
                   2564:     case OPC_DMODU_G_2F:
                   2565:         {
                   2566:             int l1 = gen_new_label();
                   2567:             int l2 = gen_new_label();
                   2568:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
                   2569:             tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   2570:             tcg_gen_br(l2);
                   2571:             gen_set_label(l1);
                   2572:             tcg_gen_remu_tl(cpu_gpr[rd], t0, t1);
                   2573:             gen_set_label(l2);
                   2574:         }
                   2575:         opn = "dmodu.g";
                   2576:         break;
                   2577: #endif
                   2578:     }
                   2579: 
1.1.1.13  root     2580:     (void)opn; /* avoid a compiler warning */
1.1.1.12  root     2581:     MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
                   2582:     tcg_temp_free(t0);
                   2583:     tcg_temp_free(t1);
                   2584: }
                   2585: 
                   2586: /* Traps */
1.1.1.5   root     2587: static void gen_trap (DisasContext *ctx, uint32_t opc,
1.1       root     2588:                       int rs, int rt, int16_t imm)
                   2589: {
                   2590:     int cond;
1.1.1.8   root     2591:     TCGv t0 = tcg_temp_new();
                   2592:     TCGv t1 = tcg_temp_new();
1.1       root     2593: 
                   2594:     cond = 0;
                   2595:     /* Load needed operands */
                   2596:     switch (opc) {
                   2597:     case OPC_TEQ:
                   2598:     case OPC_TGE:
                   2599:     case OPC_TGEU:
                   2600:     case OPC_TLT:
                   2601:     case OPC_TLTU:
                   2602:     case OPC_TNE:
                   2603:         /* Compare two registers */
                   2604:         if (rs != rt) {
1.1.1.7   root     2605:             gen_load_gpr(t0, rs);
                   2606:             gen_load_gpr(t1, rt);
1.1       root     2607:             cond = 1;
                   2608:         }
1.1.1.5   root     2609:         break;
1.1       root     2610:     case OPC_TEQI:
                   2611:     case OPC_TGEI:
                   2612:     case OPC_TGEIU:
                   2613:     case OPC_TLTI:
                   2614:     case OPC_TLTIU:
                   2615:     case OPC_TNEI:
                   2616:         /* Compare register to immediate */
                   2617:         if (rs != 0 || imm != 0) {
1.1.1.7   root     2618:             gen_load_gpr(t0, rs);
                   2619:             tcg_gen_movi_tl(t1, (int32_t)imm);
1.1       root     2620:             cond = 1;
                   2621:         }
                   2622:         break;
                   2623:     }
                   2624:     if (cond == 0) {
                   2625:         switch (opc) {
                   2626:         case OPC_TEQ:   /* rs == rs */
                   2627:         case OPC_TEQI:  /* r0 == 0  */
                   2628:         case OPC_TGE:   /* rs >= rs */
                   2629:         case OPC_TGEI:  /* r0 >= 0  */
                   2630:         case OPC_TGEU:  /* rs >= rs unsigned */
                   2631:         case OPC_TGEIU: /* r0 >= 0  unsigned */
                   2632:             /* Always trap */
1.1.1.8   root     2633:             generate_exception(ctx, EXCP_TRAP);
1.1       root     2634:             break;
                   2635:         case OPC_TLT:   /* rs < rs           */
                   2636:         case OPC_TLTI:  /* r0 < 0            */
                   2637:         case OPC_TLTU:  /* rs < rs unsigned  */
                   2638:         case OPC_TLTIU: /* r0 < 0  unsigned  */
                   2639:         case OPC_TNE:   /* rs != rs          */
                   2640:         case OPC_TNEI:  /* r0 != 0           */
1.1.1.6   root     2641:             /* Never trap: treat as NOP. */
1.1.1.8   root     2642:             break;
1.1       root     2643:         }
                   2644:     } else {
1.1.1.8   root     2645:         int l1 = gen_new_label();
                   2646: 
1.1       root     2647:         switch (opc) {
                   2648:         case OPC_TEQ:
                   2649:         case OPC_TEQI:
1.1.1.8   root     2650:             tcg_gen_brcond_tl(TCG_COND_NE, t0, t1, l1);
1.1       root     2651:             break;
                   2652:         case OPC_TGE:
                   2653:         case OPC_TGEI:
1.1.1.8   root     2654:             tcg_gen_brcond_tl(TCG_COND_LT, t0, t1, l1);
1.1       root     2655:             break;
                   2656:         case OPC_TGEU:
                   2657:         case OPC_TGEIU:
1.1.1.8   root     2658:             tcg_gen_brcond_tl(TCG_COND_LTU, t0, t1, l1);
1.1       root     2659:             break;
                   2660:         case OPC_TLT:
                   2661:         case OPC_TLTI:
1.1.1.8   root     2662:             tcg_gen_brcond_tl(TCG_COND_GE, t0, t1, l1);
1.1       root     2663:             break;
                   2664:         case OPC_TLTU:
                   2665:         case OPC_TLTIU:
1.1.1.8   root     2666:             tcg_gen_brcond_tl(TCG_COND_GEU, t0, t1, l1);
1.1       root     2667:             break;
                   2668:         case OPC_TNE:
                   2669:         case OPC_TNEI:
1.1.1.8   root     2670:             tcg_gen_brcond_tl(TCG_COND_EQ, t0, t1, l1);
1.1       root     2671:             break;
                   2672:         }
1.1.1.8   root     2673:         generate_exception(ctx, EXCP_TRAP);
1.1.1.7   root     2674:         gen_set_label(l1);
                   2675:     }
                   2676:     tcg_temp_free(t0);
                   2677:     tcg_temp_free(t1);
1.1       root     2678: }
                   2679: 
1.1.1.7   root     2680: static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1.1.1.2   root     2681: {
                   2682:     TranslationBlock *tb;
                   2683:     tb = ctx->tb;
1.1.1.9   root     2684:     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK) &&
                   2685:         likely(!ctx->singlestep_enabled)) {
1.1.1.7   root     2686:         tcg_gen_goto_tb(n);
1.1.1.6   root     2687:         gen_save_pc(dest);
1.1.1.14! root     2688:         tcg_gen_exit_tb((tcg_target_long)tb + n);
1.1.1.2   root     2689:     } else {
1.1.1.6   root     2690:         gen_save_pc(dest);
1.1.1.9   root     2691:         if (ctx->singlestep_enabled) {
                   2692:             save_cpu_state(ctx, 0);
                   2693:             gen_helper_0i(raise_exception, EXCP_DEBUG);
                   2694:         }
1.1.1.7   root     2695:         tcg_gen_exit_tb(0);
1.1.1.2   root     2696:     }
                   2697: }
                   2698: 
1.1       root     2699: /* Branches (before delay slot) */
1.1.1.5   root     2700: static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1.1.1.12  root     2701:                                 int insn_bytes,
1.1       root     2702:                                 int rs, int rt, int32_t offset)
                   2703: {
1.1.1.7   root     2704:     target_ulong btgt = -1;
1.1.1.6   root     2705:     int blink = 0;
1.1.1.7   root     2706:     int bcond_compute = 0;
1.1.1.8   root     2707:     TCGv t0 = tcg_temp_new();
                   2708:     TCGv t1 = tcg_temp_new();
1.1       root     2709: 
1.1.1.6   root     2710:     if (ctx->hflags & MIPS_HFLAG_BMASK) {
                   2711: #ifdef MIPS_DEBUG_DISAS
1.1.1.7   root     2712:         LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
1.1.1.6   root     2713: #endif
                   2714:         generate_exception(ctx, EXCP_RI);
1.1.1.7   root     2715:         goto out;
1.1.1.6   root     2716:     }
                   2717: 
                   2718:     /* Load needed operands */
                   2719:     switch (opc) {
                   2720:     case OPC_BEQ:
                   2721:     case OPC_BEQL:
                   2722:     case OPC_BNE:
                   2723:     case OPC_BNEL:
1.1       root     2724:         /* Compare two registers */
                   2725:         if (rs != rt) {
1.1.1.7   root     2726:             gen_load_gpr(t0, rs);
                   2727:             gen_load_gpr(t1, rt);
                   2728:             bcond_compute = 1;
1.1       root     2729:         }
1.1.1.12  root     2730:         btgt = ctx->pc + insn_bytes + offset;
1.1       root     2731:         break;
                   2732:     case OPC_BGEZ:
                   2733:     case OPC_BGEZAL:
1.1.1.12  root     2734:     case OPC_BGEZALS:
1.1       root     2735:     case OPC_BGEZALL:
                   2736:     case OPC_BGEZL:
                   2737:     case OPC_BGTZ:
                   2738:     case OPC_BGTZL:
                   2739:     case OPC_BLEZ:
                   2740:     case OPC_BLEZL:
                   2741:     case OPC_BLTZ:
                   2742:     case OPC_BLTZAL:
1.1.1.12  root     2743:     case OPC_BLTZALS:
1.1       root     2744:     case OPC_BLTZALL:
                   2745:     case OPC_BLTZL:
                   2746:         /* Compare to zero */
                   2747:         if (rs != 0) {
1.1.1.7   root     2748:             gen_load_gpr(t0, rs);
                   2749:             bcond_compute = 1;
1.1       root     2750:         }
1.1.1.12  root     2751:         btgt = ctx->pc + insn_bytes + offset;
1.1       root     2752:         break;
                   2753:     case OPC_J:
                   2754:     case OPC_JAL:
1.1.1.12  root     2755:     case OPC_JALX:
                   2756:     case OPC_JALS:
                   2757:     case OPC_JALXS:
1.1       root     2758:         /* Jump to immediate */
1.1.1.12  root     2759:         btgt = ((ctx->pc + insn_bytes) & (int32_t)0xF0000000) | (uint32_t)offset;
1.1       root     2760:         break;
                   2761:     case OPC_JR:
                   2762:     case OPC_JALR:
1.1.1.12  root     2763:     case OPC_JALRC:
                   2764:     case OPC_JALRS:
1.1       root     2765:         /* Jump to register */
1.1.1.5   root     2766:         if (offset != 0 && offset != 16) {
                   2767:             /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
1.1.1.6   root     2768:                others are reserved. */
                   2769:             MIPS_INVAL("jump hint");
1.1       root     2770:             generate_exception(ctx, EXCP_RI);
1.1.1.7   root     2771:             goto out;
1.1       root     2772:         }
1.1.1.7   root     2773:         gen_load_gpr(btarget, rs);
1.1       root     2774:         break;
                   2775:     default:
                   2776:         MIPS_INVAL("branch/jump");
                   2777:         generate_exception(ctx, EXCP_RI);
1.1.1.7   root     2778:         goto out;
1.1       root     2779:     }
1.1.1.7   root     2780:     if (bcond_compute == 0) {
1.1       root     2781:         /* No condition to be computed */
                   2782:         switch (opc) {
                   2783:         case OPC_BEQ:     /* rx == rx        */
                   2784:         case OPC_BEQL:    /* rx == rx likely */
                   2785:         case OPC_BGEZ:    /* 0 >= 0          */
                   2786:         case OPC_BGEZL:   /* 0 >= 0 likely   */
                   2787:         case OPC_BLEZ:    /* 0 <= 0          */
                   2788:         case OPC_BLEZL:   /* 0 <= 0 likely   */
                   2789:             /* Always take */
1.1.1.2   root     2790:             ctx->hflags |= MIPS_HFLAG_B;
1.1       root     2791:             MIPS_DEBUG("balways");
                   2792:             break;
1.1.1.12  root     2793:         case OPC_BGEZALS:
1.1       root     2794:         case OPC_BGEZAL:  /* 0 >= 0          */
                   2795:         case OPC_BGEZALL: /* 0 >= 0 likely   */
1.1.1.12  root     2796:             ctx->hflags |= (opc == OPC_BGEZALS
                   2797:                             ? MIPS_HFLAG_BDS16
                   2798:                             : MIPS_HFLAG_BDS32);
1.1       root     2799:             /* Always take and link */
                   2800:             blink = 31;
1.1.1.2   root     2801:             ctx->hflags |= MIPS_HFLAG_B;
1.1       root     2802:             MIPS_DEBUG("balways and link");
                   2803:             break;
                   2804:         case OPC_BNE:     /* rx != rx        */
                   2805:         case OPC_BGTZ:    /* 0 > 0           */
                   2806:         case OPC_BLTZ:    /* 0 < 0           */
1.1.1.6   root     2807:             /* Treat as NOP. */
1.1       root     2808:             MIPS_DEBUG("bnever (NOP)");
1.1.1.7   root     2809:             goto out;
1.1.1.12  root     2810:         case OPC_BLTZALS:
1.1.1.2   root     2811:         case OPC_BLTZAL:  /* 0 < 0           */
1.1.1.12  root     2812:             ctx->hflags |= (opc == OPC_BLTZALS
                   2813:                             ? MIPS_HFLAG_BDS16
                   2814:                             : MIPS_HFLAG_BDS32);
                   2815:             /* Handle as an unconditional branch to get correct delay
                   2816:                slot checking.  */
                   2817:             blink = 31;
                   2818:             btgt = ctx->pc + (opc == OPC_BLTZALS ? 6 : 8);
                   2819:             ctx->hflags |= MIPS_HFLAG_B;
1.1.1.6   root     2820:             MIPS_DEBUG("bnever and link");
1.1.1.12  root     2821:             break;
1.1.1.2   root     2822:         case OPC_BLTZALL: /* 0 < 0 likely */
1.1.1.8   root     2823:             tcg_gen_movi_tl(cpu_gpr[31], ctx->pc + 8);
1.1.1.6   root     2824:             /* Skip the instruction in the delay slot */
                   2825:             MIPS_DEBUG("bnever, link and skip");
                   2826:             ctx->pc += 4;
1.1.1.7   root     2827:             goto out;
1.1       root     2828:         case OPC_BNEL:    /* rx != rx likely */
                   2829:         case OPC_BGTZL:   /* 0 > 0 likely */
                   2830:         case OPC_BLTZL:   /* 0 < 0 likely */
                   2831:             /* Skip the instruction in the delay slot */
                   2832:             MIPS_DEBUG("bnever and skip");
1.1.1.6   root     2833:             ctx->pc += 4;
1.1.1.7   root     2834:             goto out;
1.1       root     2835:         case OPC_J:
1.1.1.2   root     2836:             ctx->hflags |= MIPS_HFLAG_B;
1.1.1.7   root     2837:             MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
1.1       root     2838:             break;
1.1.1.12  root     2839:         case OPC_JALXS:
                   2840:         case OPC_JALX:
                   2841:             ctx->hflags |= MIPS_HFLAG_BX;
                   2842:             /* Fallthrough */
                   2843:         case OPC_JALS:
1.1       root     2844:         case OPC_JAL:
                   2845:             blink = 31;
1.1.1.2   root     2846:             ctx->hflags |= MIPS_HFLAG_B;
1.1.1.12  root     2847:             ctx->hflags |= ((opc == OPC_JALS || opc == OPC_JALXS)
                   2848:                             ? MIPS_HFLAG_BDS16
                   2849:                             : MIPS_HFLAG_BDS32);
1.1.1.7   root     2850:             MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
1.1       root     2851:             break;
                   2852:         case OPC_JR:
1.1.1.2   root     2853:             ctx->hflags |= MIPS_HFLAG_BR;
1.1.1.12  root     2854:             if (insn_bytes == 4)
                   2855:                 ctx->hflags |= MIPS_HFLAG_BDS32;
1.1       root     2856:             MIPS_DEBUG("jr %s", regnames[rs]);
                   2857:             break;
1.1.1.12  root     2858:         case OPC_JALRS:
1.1       root     2859:         case OPC_JALR:
1.1.1.12  root     2860:         case OPC_JALRC:
1.1       root     2861:             blink = rt;
1.1.1.2   root     2862:             ctx->hflags |= MIPS_HFLAG_BR;
1.1.1.12  root     2863:             ctx->hflags |= (opc == OPC_JALRS
                   2864:                             ? MIPS_HFLAG_BDS16
                   2865:                             : MIPS_HFLAG_BDS32);
1.1       root     2866:             MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
                   2867:             break;
                   2868:         default:
                   2869:             MIPS_INVAL("branch/jump");
                   2870:             generate_exception(ctx, EXCP_RI);
1.1.1.7   root     2871:             goto out;
1.1       root     2872:         }
                   2873:     } else {
                   2874:         switch (opc) {
                   2875:         case OPC_BEQ:
1.1.1.12  root     2876:             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
1.1.1.6   root     2877:             MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
1.1.1.7   root     2878:                        regnames[rs], regnames[rt], btgt);
1.1       root     2879:             goto not_likely;
                   2880:         case OPC_BEQL:
1.1.1.12  root     2881:             tcg_gen_setcond_tl(TCG_COND_EQ, bcond, t0, t1);
1.1.1.6   root     2882:             MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
1.1.1.7   root     2883:                        regnames[rs], regnames[rt], btgt);
1.1       root     2884:             goto likely;
                   2885:         case OPC_BNE:
1.1.1.12  root     2886:             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
1.1.1.6   root     2887:             MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
1.1.1.7   root     2888:                        regnames[rs], regnames[rt], btgt);
1.1       root     2889:             goto not_likely;
                   2890:         case OPC_BNEL:
1.1.1.12  root     2891:             tcg_gen_setcond_tl(TCG_COND_NE, bcond, t0, t1);
1.1.1.6   root     2892:             MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
1.1.1.7   root     2893:                        regnames[rs], regnames[rt], btgt);
1.1       root     2894:             goto likely;
                   2895:         case OPC_BGEZ:
1.1.1.12  root     2896:             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
1.1.1.7   root     2897:             MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2898:             goto not_likely;
                   2899:         case OPC_BGEZL:
1.1.1.12  root     2900:             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
1.1.1.7   root     2901:             MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2902:             goto likely;
1.1.1.12  root     2903:         case OPC_BGEZALS:
1.1       root     2904:         case OPC_BGEZAL:
1.1.1.12  root     2905:             ctx->hflags |= (opc == OPC_BGEZALS
                   2906:                             ? MIPS_HFLAG_BDS16
                   2907:                             : MIPS_HFLAG_BDS32);
                   2908:             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
1.1.1.7   root     2909:             MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2910:             blink = 31;
                   2911:             goto not_likely;
                   2912:         case OPC_BGEZALL:
1.1.1.12  root     2913:             tcg_gen_setcondi_tl(TCG_COND_GE, bcond, t0, 0);
1.1       root     2914:             blink = 31;
1.1.1.7   root     2915:             MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2916:             goto likely;
                   2917:         case OPC_BGTZ:
1.1.1.12  root     2918:             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
1.1.1.7   root     2919:             MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2920:             goto not_likely;
                   2921:         case OPC_BGTZL:
1.1.1.12  root     2922:             tcg_gen_setcondi_tl(TCG_COND_GT, bcond, t0, 0);
1.1.1.7   root     2923:             MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2924:             goto likely;
                   2925:         case OPC_BLEZ:
1.1.1.12  root     2926:             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
1.1.1.7   root     2927:             MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2928:             goto not_likely;
                   2929:         case OPC_BLEZL:
1.1.1.12  root     2930:             tcg_gen_setcondi_tl(TCG_COND_LE, bcond, t0, 0);
1.1.1.7   root     2931:             MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2932:             goto likely;
                   2933:         case OPC_BLTZ:
1.1.1.12  root     2934:             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
1.1.1.7   root     2935:             MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2936:             goto not_likely;
                   2937:         case OPC_BLTZL:
1.1.1.12  root     2938:             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
1.1.1.7   root     2939:             MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2940:             goto likely;
1.1.1.12  root     2941:         case OPC_BLTZALS:
1.1       root     2942:         case OPC_BLTZAL:
1.1.1.12  root     2943:             ctx->hflags |= (opc == OPC_BLTZALS
                   2944:                             ? MIPS_HFLAG_BDS16
                   2945:                             : MIPS_HFLAG_BDS32);
                   2946:             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
1.1       root     2947:             blink = 31;
1.1.1.7   root     2948:             MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2949:         not_likely:
1.1.1.2   root     2950:             ctx->hflags |= MIPS_HFLAG_BC;
1.1       root     2951:             break;
                   2952:         case OPC_BLTZALL:
1.1.1.12  root     2953:             tcg_gen_setcondi_tl(TCG_COND_LT, bcond, t0, 0);
1.1       root     2954:             blink = 31;
1.1.1.7   root     2955:             MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2956:         likely:
1.1.1.2   root     2957:             ctx->hflags |= MIPS_HFLAG_BL;
1.1       root     2958:             break;
1.1.1.6   root     2959:         default:
                   2960:             MIPS_INVAL("conditional branch/jump");
                   2961:             generate_exception(ctx, EXCP_RI);
1.1.1.7   root     2962:             goto out;
1.1       root     2963:         }
                   2964:     }
1.1.1.6   root     2965:     MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
1.1.1.7   root     2966:                blink, ctx->hflags, btgt);
1.1.1.6   root     2967: 
1.1.1.7   root     2968:     ctx->btarget = btgt;
1.1       root     2969:     if (blink > 0) {
1.1.1.12  root     2970:         int post_delay = insn_bytes;
                   2971:         int lowbit = !!(ctx->hflags & MIPS_HFLAG_M16);
                   2972: 
                   2973:         if (opc != OPC_JALRC)
                   2974:             post_delay += ((ctx->hflags & MIPS_HFLAG_BDS16) ? 2 : 4);
                   2975: 
                   2976:         tcg_gen_movi_tl(cpu_gpr[blink], ctx->pc + post_delay + lowbit);
1.1       root     2977:     }
1.1.1.7   root     2978: 
                   2979:  out:
1.1.1.12  root     2980:     if (insn_bytes == 2)
                   2981:         ctx->hflags |= MIPS_HFLAG_B16;
1.1.1.7   root     2982:     tcg_temp_free(t0);
                   2983:     tcg_temp_free(t1);
1.1       root     2984: }
                   2985: 
1.1.1.5   root     2986: /* special3 bitfield operations */
                   2987: static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
1.1.1.7   root     2988:                         int rs, int lsb, int msb)
1.1       root     2989: {
1.1.1.7   root     2990:     TCGv t0 = tcg_temp_new();
                   2991:     TCGv t1 = tcg_temp_new();
                   2992:     target_ulong mask;
                   2993: 
                   2994:     gen_load_gpr(t1, rs);
1.1.1.5   root     2995:     switch (opc) {
                   2996:     case OPC_EXT:
                   2997:         if (lsb + msb > 31)
                   2998:             goto fail;
1.1.1.7   root     2999:         tcg_gen_shri_tl(t0, t1, lsb);
                   3000:         if (msb != 31) {
                   3001:             tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
                   3002:         } else {
                   3003:             tcg_gen_ext32s_tl(t0, t0);
                   3004:         }
1.1.1.5   root     3005:         break;
1.1.1.6   root     3006: #if defined(TARGET_MIPS64)
1.1.1.5   root     3007:     case OPC_DEXTM:
1.1.1.7   root     3008:         tcg_gen_shri_tl(t0, t1, lsb);
                   3009:         if (msb != 31) {
                   3010:             tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
                   3011:         }
1.1.1.5   root     3012:         break;
                   3013:     case OPC_DEXTU:
1.1.1.7   root     3014:         tcg_gen_shri_tl(t0, t1, lsb + 32);
                   3015:         tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
1.1.1.5   root     3016:         break;
                   3017:     case OPC_DEXT:
1.1.1.7   root     3018:         tcg_gen_shri_tl(t0, t1, lsb);
                   3019:         tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
1.1.1.5   root     3020:         break;
1.1.1.6   root     3021: #endif
1.1.1.5   root     3022:     case OPC_INS:
                   3023:         if (lsb > msb)
                   3024:             goto fail;
1.1.1.7   root     3025:         mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
                   3026:         gen_load_gpr(t0, rt);
                   3027:         tcg_gen_andi_tl(t0, t0, ~mask);
                   3028:         tcg_gen_shli_tl(t1, t1, lsb);
                   3029:         tcg_gen_andi_tl(t1, t1, mask);
                   3030:         tcg_gen_or_tl(t0, t0, t1);
                   3031:         tcg_gen_ext32s_tl(t0, t0);
1.1.1.5   root     3032:         break;
1.1.1.6   root     3033: #if defined(TARGET_MIPS64)
1.1.1.5   root     3034:     case OPC_DINSM:
                   3035:         if (lsb > msb)
                   3036:             goto fail;
1.1.1.7   root     3037:         mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
                   3038:         gen_load_gpr(t0, rt);
                   3039:         tcg_gen_andi_tl(t0, t0, ~mask);
                   3040:         tcg_gen_shli_tl(t1, t1, lsb);
                   3041:         tcg_gen_andi_tl(t1, t1, mask);
                   3042:         tcg_gen_or_tl(t0, t0, t1);
1.1.1.5   root     3043:         break;
                   3044:     case OPC_DINSU:
                   3045:         if (lsb > msb)
                   3046:             goto fail;
1.1.1.11  root     3047:         mask = ((1ULL << (msb - lsb + 1)) - 1) << (lsb + 32);
1.1.1.7   root     3048:         gen_load_gpr(t0, rt);
                   3049:         tcg_gen_andi_tl(t0, t0, ~mask);
                   3050:         tcg_gen_shli_tl(t1, t1, lsb + 32);
                   3051:         tcg_gen_andi_tl(t1, t1, mask);
                   3052:         tcg_gen_or_tl(t0, t0, t1);
1.1.1.5   root     3053:         break;
                   3054:     case OPC_DINS:
                   3055:         if (lsb > msb)
                   3056:             goto fail;
1.1.1.7   root     3057:         gen_load_gpr(t0, rt);
                   3058:         mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
                   3059:         gen_load_gpr(t0, rt);
                   3060:         tcg_gen_andi_tl(t0, t0, ~mask);
                   3061:         tcg_gen_shli_tl(t1, t1, lsb);
                   3062:         tcg_gen_andi_tl(t1, t1, mask);
                   3063:         tcg_gen_or_tl(t0, t0, t1);
1.1.1.5   root     3064:         break;
1.1.1.6   root     3065: #endif
1.1.1.5   root     3066:     default:
                   3067: fail:
                   3068:         MIPS_INVAL("bitops");
                   3069:         generate_exception(ctx, EXCP_RI);
1.1.1.7   root     3070:         tcg_temp_free(t0);
                   3071:         tcg_temp_free(t1);
1.1       root     3072:         return;
                   3073:     }
1.1.1.7   root     3074:     gen_store_gpr(t0, rt);
                   3075:     tcg_temp_free(t0);
                   3076:     tcg_temp_free(t1);
                   3077: }
                   3078: 
                   3079: static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
                   3080: {
1.1.1.8   root     3081:     TCGv t0;
1.1.1.7   root     3082: 
1.1.1.8   root     3083:     if (rd == 0) {
                   3084:         /* If no destination, treat it as a NOP. */
                   3085:         MIPS_DEBUG("NOP");
                   3086:         return;
                   3087:     }
                   3088: 
                   3089:     t0 = tcg_temp_new();
                   3090:     gen_load_gpr(t0, rt);
1.1.1.7   root     3091:     switch (op2) {
                   3092:     case OPC_WSBH:
1.1.1.8   root     3093:         {
                   3094:             TCGv t1 = tcg_temp_new();
                   3095: 
                   3096:             tcg_gen_shri_tl(t1, t0, 8);
                   3097:             tcg_gen_andi_tl(t1, t1, 0x00FF00FF);
                   3098:             tcg_gen_shli_tl(t0, t0, 8);
                   3099:             tcg_gen_andi_tl(t0, t0, ~0x00FF00FF);
                   3100:             tcg_gen_or_tl(t0, t0, t1);
                   3101:             tcg_temp_free(t1);
                   3102:             tcg_gen_ext32s_tl(cpu_gpr[rd], t0);
                   3103:         }
1.1.1.7   root     3104:         break;
                   3105:     case OPC_SEB:
1.1.1.8   root     3106:         tcg_gen_ext8s_tl(cpu_gpr[rd], t0);
1.1.1.7   root     3107:         break;
                   3108:     case OPC_SEH:
1.1.1.8   root     3109:         tcg_gen_ext16s_tl(cpu_gpr[rd], t0);
1.1.1.7   root     3110:         break;
                   3111: #if defined(TARGET_MIPS64)
                   3112:     case OPC_DSBH:
1.1.1.8   root     3113:         {
                   3114:             TCGv t1 = tcg_temp_new();
                   3115: 
                   3116:             tcg_gen_shri_tl(t1, t0, 8);
                   3117:             tcg_gen_andi_tl(t1, t1, 0x00FF00FF00FF00FFULL);
                   3118:             tcg_gen_shli_tl(t0, t0, 8);
                   3119:             tcg_gen_andi_tl(t0, t0, ~0x00FF00FF00FF00FFULL);
                   3120:             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
                   3121:             tcg_temp_free(t1);
                   3122:         }
1.1.1.7   root     3123:         break;
                   3124:     case OPC_DSHD:
1.1.1.8   root     3125:         {
                   3126:             TCGv t1 = tcg_temp_new();
                   3127: 
                   3128:             tcg_gen_shri_tl(t1, t0, 16);
                   3129:             tcg_gen_andi_tl(t1, t1, 0x0000FFFF0000FFFFULL);
                   3130:             tcg_gen_shli_tl(t0, t0, 16);
                   3131:             tcg_gen_andi_tl(t0, t0, ~0x0000FFFF0000FFFFULL);
                   3132:             tcg_gen_or_tl(t0, t0, t1);
                   3133:             tcg_gen_shri_tl(t1, t0, 32);
                   3134:             tcg_gen_shli_tl(t0, t0, 32);
                   3135:             tcg_gen_or_tl(cpu_gpr[rd], t0, t1);
                   3136:             tcg_temp_free(t1);
                   3137:         }
1.1.1.7   root     3138:         break;
                   3139: #endif
                   3140:     default:
                   3141:         MIPS_INVAL("bsfhl");
                   3142:         generate_exception(ctx, EXCP_RI);
                   3143:         tcg_temp_free(t0);
                   3144:         return;
                   3145:     }
                   3146:     tcg_temp_free(t0);
1.1.1.5   root     3147: }
1.1.1.4   root     3148: 
1.1.1.7   root     3149: #ifndef CONFIG_USER_ONLY
1.1.1.5   root     3150: /* CP0 (MMU and control) */
1.1.1.8   root     3151: static inline void gen_mfc0_load32 (TCGv arg, target_ulong off)
1.1.1.7   root     3152: {
1.1.1.8   root     3153:     TCGv_i32 t0 = tcg_temp_new_i32();
1.1.1.7   root     3154: 
1.1.1.8   root     3155:     tcg_gen_ld_i32(t0, cpu_env, off);
                   3156:     tcg_gen_ext_i32_tl(arg, t0);
                   3157:     tcg_temp_free_i32(t0);
1.1.1.7   root     3158: }
                   3159: 
1.1.1.8   root     3160: static inline void gen_mfc0_load64 (TCGv arg, target_ulong off)
1.1.1.7   root     3161: {
1.1.1.8   root     3162:     tcg_gen_ld_tl(arg, cpu_env, off);
                   3163:     tcg_gen_ext32s_tl(arg, arg);
1.1.1.7   root     3164: }
                   3165: 
1.1.1.8   root     3166: static inline void gen_mtc0_store32 (TCGv arg, target_ulong off)
1.1.1.7   root     3167: {
1.1.1.8   root     3168:     TCGv_i32 t0 = tcg_temp_new_i32();
1.1.1.7   root     3169: 
1.1.1.8   root     3170:     tcg_gen_trunc_tl_i32(t0, arg);
                   3171:     tcg_gen_st_i32(t0, cpu_env, off);
                   3172:     tcg_temp_free_i32(t0);
1.1.1.7   root     3173: }
                   3174: 
1.1.1.8   root     3175: static inline void gen_mtc0_store64 (TCGv arg, target_ulong off)
1.1.1.7   root     3176: {
1.1.1.8   root     3177:     tcg_gen_ext32s_tl(arg, arg);
                   3178:     tcg_gen_st_tl(arg, cpu_env, off);
1.1.1.7   root     3179: }
                   3180: 
1.1.1.8   root     3181: static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
1.1.1.5   root     3182: {
                   3183:     const char *rn = "invalid";
                   3184: 
1.1.1.6   root     3185:     if (sel != 0)
                   3186:         check_insn(env, ctx, ISA_MIPS32);
                   3187: 
1.1.1.5   root     3188:     switch (reg) {
                   3189:     case 0:
                   3190:         switch (sel) {
                   3191:         case 0:
1.1.1.8   root     3192:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Index));
1.1.1.5   root     3193:             rn = "Index";
                   3194:             break;
                   3195:         case 1:
1.1.1.6   root     3196:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3197:             gen_helper_mfc0_mvpcontrol(arg);
1.1.1.5   root     3198:             rn = "MVPControl";
1.1.1.6   root     3199:             break;
1.1.1.5   root     3200:         case 2:
1.1.1.6   root     3201:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3202:             gen_helper_mfc0_mvpconf0(arg);
1.1.1.5   root     3203:             rn = "MVPConf0";
1.1.1.6   root     3204:             break;
1.1.1.5   root     3205:         case 3:
1.1.1.6   root     3206:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3207:             gen_helper_mfc0_mvpconf1(arg);
1.1.1.5   root     3208:             rn = "MVPConf1";
1.1.1.6   root     3209:             break;
1.1.1.5   root     3210:         default:
                   3211:             goto die;
1.1       root     3212:         }
                   3213:         break;
1.1.1.5   root     3214:     case 1:
                   3215:         switch (sel) {
                   3216:         case 0:
1.1.1.8   root     3217:             gen_helper_mfc0_random(arg);
1.1.1.5   root     3218:             rn = "Random";
1.1.1.6   root     3219:             break;
1.1.1.5   root     3220:         case 1:
1.1.1.6   root     3221:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3222:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEControl));
1.1.1.5   root     3223:             rn = "VPEControl";
1.1.1.6   root     3224:             break;
1.1.1.5   root     3225:         case 2:
1.1.1.6   root     3226:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3227:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf0));
1.1.1.5   root     3228:             rn = "VPEConf0";
1.1.1.6   root     3229:             break;
1.1.1.5   root     3230:         case 3:
1.1.1.6   root     3231:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3232:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf1));
1.1.1.5   root     3233:             rn = "VPEConf1";
1.1.1.6   root     3234:             break;
1.1.1.5   root     3235:         case 4:
1.1.1.6   root     3236:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3237:             gen_mfc0_load64(arg, offsetof(CPUState, CP0_YQMask));
1.1.1.5   root     3238:             rn = "YQMask";
1.1.1.6   root     3239:             break;
1.1.1.5   root     3240:         case 5:
1.1.1.6   root     3241:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3242:             gen_mfc0_load64(arg, offsetof(CPUState, CP0_VPESchedule));
1.1.1.5   root     3243:             rn = "VPESchedule";
1.1.1.6   root     3244:             break;
1.1.1.5   root     3245:         case 6:
1.1.1.6   root     3246:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3247:             gen_mfc0_load64(arg, offsetof(CPUState, CP0_VPEScheFBack));
1.1.1.5   root     3248:             rn = "VPEScheFBack";
1.1.1.6   root     3249:             break;
1.1.1.5   root     3250:         case 7:
1.1.1.6   root     3251:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3252:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEOpt));
1.1.1.5   root     3253:             rn = "VPEOpt";
1.1.1.6   root     3254:             break;
1.1.1.5   root     3255:         default:
                   3256:             goto die;
                   3257:         }
1.1       root     3258:         break;
1.1.1.5   root     3259:     case 2:
                   3260:         switch (sel) {
                   3261:         case 0:
1.1.1.8   root     3262:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo0));
                   3263:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3264:             rn = "EntryLo0";
                   3265:             break;
                   3266:         case 1:
                   3267:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3268:             gen_helper_mfc0_tcstatus(arg);
1.1.1.6   root     3269:             rn = "TCStatus";
                   3270:             break;
                   3271:         case 2:
                   3272:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3273:             gen_helper_mfc0_tcbind(arg);
1.1.1.6   root     3274:             rn = "TCBind";
                   3275:             break;
1.1.1.5   root     3276:         case 3:
1.1.1.6   root     3277:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3278:             gen_helper_mfc0_tcrestart(arg);
1.1.1.6   root     3279:             rn = "TCRestart";
                   3280:             break;
1.1.1.5   root     3281:         case 4:
1.1.1.6   root     3282:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3283:             gen_helper_mfc0_tchalt(arg);
1.1.1.6   root     3284:             rn = "TCHalt";
                   3285:             break;
1.1.1.5   root     3286:         case 5:
1.1.1.6   root     3287:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3288:             gen_helper_mfc0_tccontext(arg);
1.1.1.6   root     3289:             rn = "TCContext";
                   3290:             break;
1.1.1.5   root     3291:         case 6:
1.1.1.6   root     3292:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3293:             gen_helper_mfc0_tcschedule(arg);
1.1.1.6   root     3294:             rn = "TCSchedule";
                   3295:             break;
1.1.1.5   root     3296:         case 7:
1.1.1.6   root     3297:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3298:             gen_helper_mfc0_tcschefback(arg);
1.1.1.6   root     3299:             rn = "TCScheFBack";
                   3300:             break;
1.1.1.5   root     3301:         default:
                   3302:             goto die;
                   3303:         }
1.1       root     3304:         break;
1.1.1.5   root     3305:     case 3:
                   3306:         switch (sel) {
                   3307:         case 0:
1.1.1.8   root     3308:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo1));
                   3309:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3310:             rn = "EntryLo1";
                   3311:             break;
1.1.1.5   root     3312:         default:
                   3313:             goto die;
1.1.1.6   root     3314:         }
1.1       root     3315:         break;
1.1.1.5   root     3316:     case 4:
                   3317:         switch (sel) {
                   3318:         case 0:
1.1.1.8   root     3319:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_Context));
                   3320:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3321:             rn = "Context";
                   3322:             break;
                   3323:         case 1:
1.1.1.8   root     3324: //            gen_helper_mfc0_contextconfig(arg); /* SmartMIPS ASE */
1.1.1.6   root     3325:             rn = "ContextConfig";
                   3326: //            break;
1.1.1.5   root     3327:         default:
                   3328:             goto die;
1.1.1.6   root     3329:         }
1.1       root     3330:         break;
1.1.1.5   root     3331:     case 5:
                   3332:         switch (sel) {
                   3333:         case 0:
1.1.1.8   root     3334:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageMask));
1.1.1.6   root     3335:             rn = "PageMask";
                   3336:             break;
                   3337:         case 1:
                   3338:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3339:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageGrain));
1.1.1.6   root     3340:             rn = "PageGrain";
                   3341:             break;
1.1.1.5   root     3342:         default:
                   3343:             goto die;
1.1.1.6   root     3344:         }
1.1       root     3345:         break;
1.1.1.5   root     3346:     case 6:
                   3347:         switch (sel) {
                   3348:         case 0:
1.1.1.8   root     3349:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Wired));
1.1.1.6   root     3350:             rn = "Wired";
                   3351:             break;
                   3352:         case 1:
                   3353:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3354:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf0));
1.1.1.6   root     3355:             rn = "SRSConf0";
                   3356:             break;
                   3357:         case 2:
                   3358:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3359:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf1));
1.1.1.6   root     3360:             rn = "SRSConf1";
                   3361:             break;
1.1.1.5   root     3362:         case 3:
1.1.1.6   root     3363:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3364:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf2));
1.1.1.6   root     3365:             rn = "SRSConf2";
                   3366:             break;
1.1.1.5   root     3367:         case 4:
1.1.1.6   root     3368:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3369:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf3));
1.1.1.6   root     3370:             rn = "SRSConf3";
                   3371:             break;
1.1.1.5   root     3372:         case 5:
1.1.1.6   root     3373:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3374:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf4));
1.1.1.6   root     3375:             rn = "SRSConf4";
                   3376:             break;
1.1.1.5   root     3377:         default:
                   3378:             goto die;
1.1.1.6   root     3379:         }
1.1       root     3380:         break;
1.1.1.5   root     3381:     case 7:
                   3382:         switch (sel) {
                   3383:         case 0:
1.1.1.6   root     3384:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3385:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_HWREna));
1.1.1.6   root     3386:             rn = "HWREna";
                   3387:             break;
1.1.1.5   root     3388:         default:
                   3389:             goto die;
1.1.1.6   root     3390:         }
1.1       root     3391:         break;
1.1.1.5   root     3392:     case 8:
                   3393:         switch (sel) {
                   3394:         case 0:
1.1.1.8   root     3395:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_BadVAddr));
                   3396:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.7   root     3397:             rn = "BadVAddr";
1.1.1.6   root     3398:             break;
1.1.1.5   root     3399:         default:
                   3400:             goto die;
                   3401:        }
1.1.1.2   root     3402:         break;
1.1.1.5   root     3403:     case 9:
                   3404:         switch (sel) {
                   3405:         case 0:
1.1.1.7   root     3406:             /* Mark as an IO operation because we read the time.  */
                   3407:             if (use_icount)
                   3408:                 gen_io_start();
1.1.1.8   root     3409:             gen_helper_mfc0_count(arg);
1.1.1.7   root     3410:             if (use_icount) {
                   3411:                 gen_io_end();
                   3412:             }
1.1.1.13  root     3413:             /* Break the TB to be able to take timer interrupts immediately
                   3414:                after reading count.  */
                   3415:             ctx->bstate = BS_STOP;
1.1.1.6   root     3416:             rn = "Count";
                   3417:             break;
                   3418:         /* 6,7 are implementation dependent */
1.1.1.5   root     3419:         default:
                   3420:             goto die;
1.1.1.6   root     3421:         }
1.1.1.5   root     3422:         break;
                   3423:     case 10:
                   3424:         switch (sel) {
                   3425:         case 0:
1.1.1.8   root     3426:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryHi));
                   3427:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3428:             rn = "EntryHi";
                   3429:             break;
1.1.1.5   root     3430:         default:
                   3431:             goto die;
1.1.1.6   root     3432:         }
1.1.1.5   root     3433:         break;
                   3434:     case 11:
                   3435:         switch (sel) {
                   3436:         case 0:
1.1.1.8   root     3437:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Compare));
1.1.1.6   root     3438:             rn = "Compare";
                   3439:             break;
                   3440:         /* 6,7 are implementation dependent */
1.1.1.5   root     3441:         default:
                   3442:             goto die;
1.1.1.6   root     3443:         }
1.1.1.5   root     3444:         break;
                   3445:     case 12:
                   3446:         switch (sel) {
                   3447:         case 0:
1.1.1.8   root     3448:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Status));
1.1.1.6   root     3449:             rn = "Status";
                   3450:             break;
                   3451:         case 1:
                   3452:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3453:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_IntCtl));
1.1.1.6   root     3454:             rn = "IntCtl";
                   3455:             break;
                   3456:         case 2:
                   3457:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3458:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSCtl));
1.1.1.6   root     3459:             rn = "SRSCtl";
                   3460:             break;
1.1.1.5   root     3461:         case 3:
1.1.1.6   root     3462:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3463:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSMap));
1.1.1.6   root     3464:             rn = "SRSMap";
                   3465:             break;
1.1.1.5   root     3466:         default:
                   3467:             goto die;
                   3468:        }
                   3469:         break;
                   3470:     case 13:
                   3471:         switch (sel) {
                   3472:         case 0:
1.1.1.8   root     3473:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Cause));
1.1.1.6   root     3474:             rn = "Cause";
                   3475:             break;
1.1.1.5   root     3476:         default:
                   3477:             goto die;
                   3478:        }
                   3479:         break;
                   3480:     case 14:
                   3481:         switch (sel) {
                   3482:         case 0:
1.1.1.8   root     3483:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
                   3484:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3485:             rn = "EPC";
                   3486:             break;
1.1.1.5   root     3487:         default:
                   3488:             goto die;
1.1.1.6   root     3489:         }
1.1.1.5   root     3490:         break;
                   3491:     case 15:
                   3492:         switch (sel) {
                   3493:         case 0:
1.1.1.8   root     3494:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_PRid));
1.1.1.6   root     3495:             rn = "PRid";
                   3496:             break;
                   3497:         case 1:
                   3498:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3499:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_EBase));
1.1.1.6   root     3500:             rn = "EBase";
                   3501:             break;
1.1.1.5   root     3502:         default:
                   3503:             goto die;
                   3504:        }
                   3505:         break;
                   3506:     case 16:
                   3507:         switch (sel) {
                   3508:         case 0:
1.1.1.8   root     3509:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config0));
1.1.1.5   root     3510:             rn = "Config";
                   3511:             break;
                   3512:         case 1:
1.1.1.8   root     3513:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config1));
1.1.1.5   root     3514:             rn = "Config1";
                   3515:             break;
                   3516:         case 2:
1.1.1.8   root     3517:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config2));
1.1.1.5   root     3518:             rn = "Config2";
                   3519:             break;
                   3520:         case 3:
1.1.1.8   root     3521:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config3));
1.1.1.5   root     3522:             rn = "Config3";
                   3523:             break;
1.1.1.6   root     3524:         /* 4,5 are reserved */
                   3525:         /* 6,7 are implementation dependent */
                   3526:         case 6:
1.1.1.8   root     3527:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config6));
1.1.1.6   root     3528:             rn = "Config6";
                   3529:             break;
                   3530:         case 7:
1.1.1.8   root     3531:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config7));
1.1.1.6   root     3532:             rn = "Config7";
                   3533:             break;
1.1.1.5   root     3534:         default:
                   3535:             goto die;
1.1       root     3536:         }
1.1.1.4   root     3537:         break;
1.1.1.5   root     3538:     case 17:
                   3539:         switch (sel) {
                   3540:         case 0:
1.1.1.8   root     3541:             gen_helper_mfc0_lladdr(arg);
1.1.1.6   root     3542:             rn = "LLAddr";
                   3543:             break;
1.1.1.5   root     3544:         default:
                   3545:             goto die;
                   3546:         }
1.1.1.4   root     3547:         break;
1.1.1.5   root     3548:     case 18:
                   3549:         switch (sel) {
1.1.1.6   root     3550:         case 0 ... 7:
1.1.1.8   root     3551:             gen_helper_1i(mfc0_watchlo, arg, sel);
1.1.1.6   root     3552:             rn = "WatchLo";
                   3553:             break;
1.1.1.5   root     3554:         default:
                   3555:             goto die;
                   3556:         }
1.1.1.4   root     3557:         break;
1.1.1.5   root     3558:     case 19:
                   3559:         switch (sel) {
1.1.1.6   root     3560:         case 0 ...7:
1.1.1.8   root     3561:             gen_helper_1i(mfc0_watchhi, arg, sel);
1.1.1.6   root     3562:             rn = "WatchHi";
                   3563:             break;
1.1.1.5   root     3564:         default:
                   3565:             goto die;
                   3566:         }
1.1.1.4   root     3567:         break;
1.1.1.5   root     3568:     case 20:
                   3569:         switch (sel) {
                   3570:         case 0:
1.1.1.6   root     3571: #if defined(TARGET_MIPS64)
                   3572:             check_insn(env, ctx, ISA_MIPS3);
1.1.1.8   root     3573:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_XContext));
                   3574:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3575:             rn = "XContext";
                   3576:             break;
                   3577: #endif
1.1.1.5   root     3578:         default:
                   3579:             goto die;
1.1.1.4   root     3580:         }
                   3581:         break;
1.1.1.5   root     3582:     case 21:
                   3583:        /* Officially reserved, but sel 0 is used for R1x000 framemask */
                   3584:         switch (sel) {
                   3585:         case 0:
1.1.1.8   root     3586:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Framemask));
1.1.1.6   root     3587:             rn = "Framemask";
                   3588:             break;
1.1.1.5   root     3589:         default:
                   3590:             goto die;
1.1.1.4   root     3591:         }
                   3592:         break;
1.1.1.5   root     3593:     case 22:
1.1.1.8   root     3594:         tcg_gen_movi_tl(arg, 0); /* unimplemented */
1.1.1.6   root     3595:         rn = "'Diagnostic"; /* implementation dependent */
                   3596:         break;
1.1.1.5   root     3597:     case 23:
                   3598:         switch (sel) {
                   3599:         case 0:
1.1.1.8   root     3600:             gen_helper_mfc0_debug(arg); /* EJTAG support */
1.1.1.6   root     3601:             rn = "Debug";
                   3602:             break;
                   3603:         case 1:
1.1.1.8   root     3604: //            gen_helper_mfc0_tracecontrol(arg); /* PDtrace support */
1.1.1.6   root     3605:             rn = "TraceControl";
                   3606: //            break;
                   3607:         case 2:
1.1.1.8   root     3608: //            gen_helper_mfc0_tracecontrol2(arg); /* PDtrace support */
1.1.1.6   root     3609:             rn = "TraceControl2";
                   3610: //            break;
1.1.1.5   root     3611:         case 3:
1.1.1.8   root     3612: //            gen_helper_mfc0_usertracedata(arg); /* PDtrace support */
1.1.1.6   root     3613:             rn = "UserTraceData";
                   3614: //            break;
1.1.1.5   root     3615:         case 4:
1.1.1.8   root     3616: //            gen_helper_mfc0_tracebpc(arg); /* PDtrace support */
1.1.1.6   root     3617:             rn = "TraceBPC";
                   3618: //            break;
1.1.1.5   root     3619:         default:
                   3620:             goto die;
1.1.1.4   root     3621:         }
1.1.1.5   root     3622:         break;
                   3623:     case 24:
                   3624:         switch (sel) {
                   3625:         case 0:
1.1.1.7   root     3626:             /* EJTAG support */
1.1.1.8   root     3627:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
                   3628:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3629:             rn = "DEPC";
                   3630:             break;
1.1.1.5   root     3631:         default:
                   3632:             goto die;
                   3633:         }
                   3634:         break;
                   3635:     case 25:
                   3636:         switch (sel) {
                   3637:         case 0:
1.1.1.8   root     3638:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Performance0));
1.1.1.6   root     3639:             rn = "Performance0";
1.1.1.5   root     3640:             break;
                   3641:         case 1:
1.1.1.8   root     3642: //            gen_helper_mfc0_performance1(arg);
1.1.1.6   root     3643:             rn = "Performance1";
                   3644: //            break;
1.1.1.5   root     3645:         case 2:
1.1.1.8   root     3646: //            gen_helper_mfc0_performance2(arg);
1.1.1.6   root     3647:             rn = "Performance2";
                   3648: //            break;
1.1.1.5   root     3649:         case 3:
1.1.1.8   root     3650: //            gen_helper_mfc0_performance3(arg);
1.1.1.6   root     3651:             rn = "Performance3";
                   3652: //            break;
1.1.1.5   root     3653:         case 4:
1.1.1.8   root     3654: //            gen_helper_mfc0_performance4(arg);
1.1.1.6   root     3655:             rn = "Performance4";
                   3656: //            break;
1.1.1.5   root     3657:         case 5:
1.1.1.8   root     3658: //            gen_helper_mfc0_performance5(arg);
1.1.1.6   root     3659:             rn = "Performance5";
                   3660: //            break;
1.1.1.5   root     3661:         case 6:
1.1.1.8   root     3662: //            gen_helper_mfc0_performance6(arg);
1.1.1.6   root     3663:             rn = "Performance6";
                   3664: //            break;
1.1.1.5   root     3665:         case 7:
1.1.1.8   root     3666: //            gen_helper_mfc0_performance7(arg);
1.1.1.6   root     3667:             rn = "Performance7";
                   3668: //            break;
1.1.1.5   root     3669:         default:
                   3670:             goto die;
                   3671:         }
                   3672:         break;
                   3673:     case 26:
1.1.1.8   root     3674:         tcg_gen_movi_tl(arg, 0); /* unimplemented */
1.1.1.7   root     3675:         rn = "ECC";
                   3676:         break;
1.1.1.5   root     3677:     case 27:
                   3678:         switch (sel) {
                   3679:         case 0 ... 3:
1.1.1.8   root     3680:             tcg_gen_movi_tl(arg, 0); /* unimplemented */
1.1.1.6   root     3681:             rn = "CacheErr";
                   3682:             break;
1.1.1.5   root     3683:         default:
                   3684:             goto die;
                   3685:         }
                   3686:         break;
                   3687:     case 28:
                   3688:         switch (sel) {
                   3689:         case 0:
                   3690:         case 2:
                   3691:         case 4:
                   3692:         case 6:
1.1.1.8   root     3693:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagLo));
1.1.1.5   root     3694:             rn = "TagLo";
                   3695:             break;
                   3696:         case 1:
                   3697:         case 3:
                   3698:         case 5:
                   3699:         case 7:
1.1.1.8   root     3700:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataLo));
1.1.1.5   root     3701:             rn = "DataLo";
                   3702:             break;
                   3703:         default:
                   3704:             goto die;
                   3705:         }
                   3706:         break;
                   3707:     case 29:
                   3708:         switch (sel) {
                   3709:         case 0:
                   3710:         case 2:
                   3711:         case 4:
                   3712:         case 6:
1.1.1.8   root     3713:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagHi));
1.1.1.5   root     3714:             rn = "TagHi";
                   3715:             break;
                   3716:         case 1:
                   3717:         case 3:
                   3718:         case 5:
                   3719:         case 7:
1.1.1.8   root     3720:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataHi));
1.1.1.5   root     3721:             rn = "DataHi";
                   3722:             break;
                   3723:         default:
                   3724:             goto die;
                   3725:         }
                   3726:         break;
                   3727:     case 30:
                   3728:         switch (sel) {
                   3729:         case 0:
1.1.1.8   root     3730:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
                   3731:             tcg_gen_ext32s_tl(arg, arg);
1.1.1.6   root     3732:             rn = "ErrorEPC";
                   3733:             break;
1.1.1.5   root     3734:         default:
                   3735:             goto die;
                   3736:         }
                   3737:         break;
                   3738:     case 31:
                   3739:         switch (sel) {
                   3740:         case 0:
1.1.1.7   root     3741:             /* EJTAG support */
1.1.1.8   root     3742:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_DESAVE));
1.1.1.6   root     3743:             rn = "DESAVE";
                   3744:             break;
1.1.1.5   root     3745:         default:
                   3746:             goto die;
                   3747:         }
                   3748:         break;
                   3749:     default:
                   3750:        goto die;
                   3751:     }
1.1.1.13  root     3752:     (void)rn; /* avoid a compiler warning */
1.1.1.7   root     3753:     LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
1.1.1.5   root     3754:     return;
                   3755: 
                   3756: die:
1.1.1.7   root     3757:     LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
1.1.1.5   root     3758:     generate_exception(ctx, EXCP_RI);
                   3759: }
                   3760: 
1.1.1.8   root     3761: static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
1.1.1.5   root     3762: {
                   3763:     const char *rn = "invalid";
                   3764: 
1.1.1.6   root     3765:     if (sel != 0)
                   3766:         check_insn(env, ctx, ISA_MIPS32);
                   3767: 
1.1.1.7   root     3768:     if (use_icount)
                   3769:         gen_io_start();
                   3770: 
1.1.1.5   root     3771:     switch (reg) {
                   3772:     case 0:
                   3773:         switch (sel) {
                   3774:         case 0:
1.1.1.8   root     3775:             gen_helper_mtc0_index(arg);
1.1.1.5   root     3776:             rn = "Index";
                   3777:             break;
                   3778:         case 1:
1.1.1.6   root     3779:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3780:             gen_helper_mtc0_mvpcontrol(arg);
1.1.1.5   root     3781:             rn = "MVPControl";
1.1.1.6   root     3782:             break;
1.1.1.5   root     3783:         case 2:
1.1.1.6   root     3784:             check_insn(env, ctx, ASE_MT);
                   3785:             /* ignored */
1.1.1.5   root     3786:             rn = "MVPConf0";
1.1.1.6   root     3787:             break;
1.1.1.5   root     3788:         case 3:
1.1.1.6   root     3789:             check_insn(env, ctx, ASE_MT);
                   3790:             /* ignored */
1.1.1.5   root     3791:             rn = "MVPConf1";
1.1.1.6   root     3792:             break;
1.1.1.5   root     3793:         default:
                   3794:             goto die;
                   3795:         }
                   3796:         break;
                   3797:     case 1:
                   3798:         switch (sel) {
                   3799:         case 0:
1.1.1.6   root     3800:             /* ignored */
1.1.1.5   root     3801:             rn = "Random";
1.1.1.6   root     3802:             break;
1.1.1.5   root     3803:         case 1:
1.1.1.6   root     3804:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3805:             gen_helper_mtc0_vpecontrol(arg);
1.1.1.5   root     3806:             rn = "VPEControl";
1.1.1.6   root     3807:             break;
1.1.1.5   root     3808:         case 2:
1.1.1.6   root     3809:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3810:             gen_helper_mtc0_vpeconf0(arg);
1.1.1.5   root     3811:             rn = "VPEConf0";
1.1.1.6   root     3812:             break;
1.1.1.5   root     3813:         case 3:
1.1.1.6   root     3814:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3815:             gen_helper_mtc0_vpeconf1(arg);
1.1.1.5   root     3816:             rn = "VPEConf1";
1.1.1.6   root     3817:             break;
1.1.1.5   root     3818:         case 4:
1.1.1.6   root     3819:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3820:             gen_helper_mtc0_yqmask(arg);
1.1.1.5   root     3821:             rn = "YQMask";
1.1.1.6   root     3822:             break;
1.1.1.5   root     3823:         case 5:
1.1.1.6   root     3824:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3825:             gen_mtc0_store64(arg, offsetof(CPUState, CP0_VPESchedule));
1.1.1.5   root     3826:             rn = "VPESchedule";
1.1.1.6   root     3827:             break;
1.1.1.5   root     3828:         case 6:
1.1.1.6   root     3829:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3830:             gen_mtc0_store64(arg, offsetof(CPUState, CP0_VPEScheFBack));
1.1.1.5   root     3831:             rn = "VPEScheFBack";
1.1.1.6   root     3832:             break;
1.1.1.5   root     3833:         case 7:
1.1.1.6   root     3834:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3835:             gen_helper_mtc0_vpeopt(arg);
1.1.1.5   root     3836:             rn = "VPEOpt";
1.1.1.6   root     3837:             break;
1.1.1.5   root     3838:         default:
                   3839:             goto die;
                   3840:         }
                   3841:         break;
                   3842:     case 2:
                   3843:         switch (sel) {
                   3844:         case 0:
1.1.1.8   root     3845:             gen_helper_mtc0_entrylo0(arg);
1.1.1.6   root     3846:             rn = "EntryLo0";
                   3847:             break;
                   3848:         case 1:
                   3849:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3850:             gen_helper_mtc0_tcstatus(arg);
1.1.1.6   root     3851:             rn = "TCStatus";
                   3852:             break;
                   3853:         case 2:
                   3854:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3855:             gen_helper_mtc0_tcbind(arg);
1.1.1.6   root     3856:             rn = "TCBind";
                   3857:             break;
1.1.1.5   root     3858:         case 3:
1.1.1.6   root     3859:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3860:             gen_helper_mtc0_tcrestart(arg);
1.1.1.6   root     3861:             rn = "TCRestart";
                   3862:             break;
1.1.1.5   root     3863:         case 4:
1.1.1.6   root     3864:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3865:             gen_helper_mtc0_tchalt(arg);
1.1.1.6   root     3866:             rn = "TCHalt";
                   3867:             break;
1.1.1.5   root     3868:         case 5:
1.1.1.6   root     3869:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3870:             gen_helper_mtc0_tccontext(arg);
1.1.1.6   root     3871:             rn = "TCContext";
                   3872:             break;
1.1.1.5   root     3873:         case 6:
1.1.1.6   root     3874:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3875:             gen_helper_mtc0_tcschedule(arg);
1.1.1.6   root     3876:             rn = "TCSchedule";
                   3877:             break;
1.1.1.5   root     3878:         case 7:
1.1.1.6   root     3879:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     3880:             gen_helper_mtc0_tcschefback(arg);
1.1.1.6   root     3881:             rn = "TCScheFBack";
                   3882:             break;
1.1.1.5   root     3883:         default:
                   3884:             goto die;
                   3885:         }
                   3886:         break;
                   3887:     case 3:
                   3888:         switch (sel) {
                   3889:         case 0:
1.1.1.8   root     3890:             gen_helper_mtc0_entrylo1(arg);
1.1.1.6   root     3891:             rn = "EntryLo1";
                   3892:             break;
1.1.1.5   root     3893:         default:
                   3894:             goto die;
1.1.1.6   root     3895:         }
1.1.1.5   root     3896:         break;
                   3897:     case 4:
                   3898:         switch (sel) {
                   3899:         case 0:
1.1.1.8   root     3900:             gen_helper_mtc0_context(arg);
1.1.1.6   root     3901:             rn = "Context";
                   3902:             break;
                   3903:         case 1:
1.1.1.8   root     3904: //            gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
1.1.1.6   root     3905:             rn = "ContextConfig";
                   3906: //            break;
1.1.1.5   root     3907:         default:
                   3908:             goto die;
1.1.1.6   root     3909:         }
1.1.1.5   root     3910:         break;
                   3911:     case 5:
                   3912:         switch (sel) {
                   3913:         case 0:
1.1.1.8   root     3914:             gen_helper_mtc0_pagemask(arg);
1.1.1.6   root     3915:             rn = "PageMask";
                   3916:             break;
                   3917:         case 1:
                   3918:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3919:             gen_helper_mtc0_pagegrain(arg);
1.1.1.6   root     3920:             rn = "PageGrain";
                   3921:             break;
1.1.1.5   root     3922:         default:
                   3923:             goto die;
1.1.1.6   root     3924:         }
1.1.1.5   root     3925:         break;
                   3926:     case 6:
                   3927:         switch (sel) {
                   3928:         case 0:
1.1.1.8   root     3929:             gen_helper_mtc0_wired(arg);
1.1.1.6   root     3930:             rn = "Wired";
                   3931:             break;
                   3932:         case 1:
                   3933:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3934:             gen_helper_mtc0_srsconf0(arg);
1.1.1.6   root     3935:             rn = "SRSConf0";
                   3936:             break;
                   3937:         case 2:
                   3938:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3939:             gen_helper_mtc0_srsconf1(arg);
1.1.1.6   root     3940:             rn = "SRSConf1";
                   3941:             break;
1.1.1.5   root     3942:         case 3:
1.1.1.6   root     3943:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3944:             gen_helper_mtc0_srsconf2(arg);
1.1.1.6   root     3945:             rn = "SRSConf2";
                   3946:             break;
1.1.1.5   root     3947:         case 4:
1.1.1.6   root     3948:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3949:             gen_helper_mtc0_srsconf3(arg);
1.1.1.6   root     3950:             rn = "SRSConf3";
                   3951:             break;
1.1.1.5   root     3952:         case 5:
1.1.1.6   root     3953:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3954:             gen_helper_mtc0_srsconf4(arg);
1.1.1.6   root     3955:             rn = "SRSConf4";
                   3956:             break;
1.1.1.5   root     3957:         default:
                   3958:             goto die;
1.1.1.6   root     3959:         }
1.1.1.5   root     3960:         break;
                   3961:     case 7:
                   3962:         switch (sel) {
                   3963:         case 0:
1.1.1.6   root     3964:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     3965:             gen_helper_mtc0_hwrena(arg);
1.1.1.6   root     3966:             rn = "HWREna";
                   3967:             break;
1.1.1.5   root     3968:         default:
                   3969:             goto die;
1.1.1.6   root     3970:         }
1.1.1.5   root     3971:         break;
                   3972:     case 8:
                   3973:         /* ignored */
1.1.1.7   root     3974:         rn = "BadVAddr";
1.1.1.5   root     3975:         break;
                   3976:     case 9:
                   3977:         switch (sel) {
                   3978:         case 0:
1.1.1.8   root     3979:             gen_helper_mtc0_count(arg);
1.1.1.6   root     3980:             rn = "Count";
                   3981:             break;
                   3982:         /* 6,7 are implementation dependent */
1.1.1.5   root     3983:         default:
                   3984:             goto die;
1.1.1.6   root     3985:         }
1.1.1.5   root     3986:         break;
                   3987:     case 10:
                   3988:         switch (sel) {
                   3989:         case 0:
1.1.1.8   root     3990:             gen_helper_mtc0_entryhi(arg);
1.1.1.6   root     3991:             rn = "EntryHi";
                   3992:             break;
1.1.1.5   root     3993:         default:
                   3994:             goto die;
1.1.1.6   root     3995:         }
1.1.1.5   root     3996:         break;
                   3997:     case 11:
                   3998:         switch (sel) {
                   3999:         case 0:
1.1.1.8   root     4000:             gen_helper_mtc0_compare(arg);
1.1.1.6   root     4001:             rn = "Compare";
                   4002:             break;
                   4003:         /* 6,7 are implementation dependent */
1.1.1.5   root     4004:         default:
                   4005:             goto die;
1.1.1.6   root     4006:         }
1.1.1.5   root     4007:         break;
                   4008:     case 12:
                   4009:         switch (sel) {
                   4010:         case 0:
1.1.1.8   root     4011:             save_cpu_state(ctx, 1);
                   4012:             gen_helper_mtc0_status(arg);
1.1.1.6   root     4013:             /* BS_STOP isn't good enough here, hflags may have changed. */
                   4014:             gen_save_pc(ctx->pc + 4);
                   4015:             ctx->bstate = BS_EXCP;
                   4016:             rn = "Status";
                   4017:             break;
                   4018:         case 1:
                   4019:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4020:             gen_helper_mtc0_intctl(arg);
1.1.1.6   root     4021:             /* Stop translation as we may have switched the execution mode */
                   4022:             ctx->bstate = BS_STOP;
                   4023:             rn = "IntCtl";
                   4024:             break;
                   4025:         case 2:
                   4026:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4027:             gen_helper_mtc0_srsctl(arg);
1.1.1.6   root     4028:             /* Stop translation as we may have switched the execution mode */
                   4029:             ctx->bstate = BS_STOP;
                   4030:             rn = "SRSCtl";
                   4031:             break;
1.1.1.5   root     4032:         case 3:
1.1.1.6   root     4033:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4034:             gen_mtc0_store32(arg, offsetof(CPUState, CP0_SRSMap));
1.1.1.6   root     4035:             /* Stop translation as we may have switched the execution mode */
                   4036:             ctx->bstate = BS_STOP;
                   4037:             rn = "SRSMap";
                   4038:             break;
1.1.1.5   root     4039:         default:
                   4040:             goto die;
1.1.1.6   root     4041:         }
1.1.1.5   root     4042:         break;
                   4043:     case 13:
                   4044:         switch (sel) {
                   4045:         case 0:
1.1.1.8   root     4046:             save_cpu_state(ctx, 1);
                   4047:             gen_helper_mtc0_cause(arg);
1.1.1.6   root     4048:             rn = "Cause";
                   4049:             break;
1.1.1.5   root     4050:         default:
                   4051:             goto die;
1.1.1.6   root     4052:         }
1.1.1.5   root     4053:         break;
                   4054:     case 14:
                   4055:         switch (sel) {
                   4056:         case 0:
1.1.1.8   root     4057:             gen_mtc0_store64(arg, offsetof(CPUState, CP0_EPC));
1.1.1.6   root     4058:             rn = "EPC";
                   4059:             break;
1.1.1.5   root     4060:         default:
                   4061:             goto die;
1.1.1.6   root     4062:         }
1.1.1.5   root     4063:         break;
                   4064:     case 15:
                   4065:         switch (sel) {
                   4066:         case 0:
1.1.1.6   root     4067:             /* ignored */
                   4068:             rn = "PRid";
                   4069:             break;
                   4070:         case 1:
                   4071:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4072:             gen_helper_mtc0_ebase(arg);
1.1.1.6   root     4073:             rn = "EBase";
                   4074:             break;
1.1.1.5   root     4075:         default:
                   4076:             goto die;
1.1.1.6   root     4077:         }
1.1.1.5   root     4078:         break;
                   4079:     case 16:
                   4080:         switch (sel) {
                   4081:         case 0:
1.1.1.8   root     4082:             gen_helper_mtc0_config0(arg);
1.1.1.5   root     4083:             rn = "Config";
1.1.1.6   root     4084:             /* Stop translation as we may have switched the execution mode */
                   4085:             ctx->bstate = BS_STOP;
1.1.1.5   root     4086:             break;
                   4087:         case 1:
1.1.1.6   root     4088:             /* ignored, read only */
1.1.1.5   root     4089:             rn = "Config1";
                   4090:             break;
                   4091:         case 2:
1.1.1.8   root     4092:             gen_helper_mtc0_config2(arg);
1.1.1.5   root     4093:             rn = "Config2";
1.1.1.6   root     4094:             /* Stop translation as we may have switched the execution mode */
                   4095:             ctx->bstate = BS_STOP;
1.1.1.5   root     4096:             break;
                   4097:         case 3:
1.1.1.6   root     4098:             /* ignored, read only */
1.1.1.5   root     4099:             rn = "Config3";
                   4100:             break;
1.1.1.6   root     4101:         /* 4,5 are reserved */
                   4102:         /* 6,7 are implementation dependent */
                   4103:         case 6:
                   4104:             /* ignored */
                   4105:             rn = "Config6";
                   4106:             break;
                   4107:         case 7:
                   4108:             /* ignored */
                   4109:             rn = "Config7";
                   4110:             break;
1.1.1.5   root     4111:         default:
                   4112:             rn = "Invalid config selector";
                   4113:             goto die;
                   4114:         }
                   4115:         break;
                   4116:     case 17:
                   4117:         switch (sel) {
                   4118:         case 0:
1.1.1.9   root     4119:             gen_helper_mtc0_lladdr(arg);
1.1.1.6   root     4120:             rn = "LLAddr";
                   4121:             break;
1.1.1.5   root     4122:         default:
                   4123:             goto die;
                   4124:         }
                   4125:         break;
                   4126:     case 18:
                   4127:         switch (sel) {
1.1.1.6   root     4128:         case 0 ... 7:
1.1.1.8   root     4129:             gen_helper_1i(mtc0_watchlo, arg, sel);
1.1.1.6   root     4130:             rn = "WatchLo";
                   4131:             break;
1.1.1.5   root     4132:         default:
                   4133:             goto die;
                   4134:         }
                   4135:         break;
                   4136:     case 19:
                   4137:         switch (sel) {
1.1.1.6   root     4138:         case 0 ... 7:
1.1.1.8   root     4139:             gen_helper_1i(mtc0_watchhi, arg, sel);
1.1.1.6   root     4140:             rn = "WatchHi";
                   4141:             break;
1.1.1.5   root     4142:         default:
                   4143:             goto die;
                   4144:         }
                   4145:         break;
                   4146:     case 20:
                   4147:         switch (sel) {
                   4148:         case 0:
1.1.1.6   root     4149: #if defined(TARGET_MIPS64)
                   4150:             check_insn(env, ctx, ISA_MIPS3);
1.1.1.8   root     4151:             gen_helper_mtc0_xcontext(arg);
1.1.1.6   root     4152:             rn = "XContext";
                   4153:             break;
                   4154: #endif
1.1.1.5   root     4155:         default:
                   4156:             goto die;
                   4157:         }
                   4158:         break;
                   4159:     case 21:
                   4160:        /* Officially reserved, but sel 0 is used for R1x000 framemask */
                   4161:         switch (sel) {
                   4162:         case 0:
1.1.1.8   root     4163:             gen_helper_mtc0_framemask(arg);
1.1.1.6   root     4164:             rn = "Framemask";
                   4165:             break;
1.1.1.5   root     4166:         default:
                   4167:             goto die;
                   4168:         }
                   4169:         break;
                   4170:     case 22:
                   4171:         /* ignored */
                   4172:         rn = "Diagnostic"; /* implementation dependent */
1.1.1.6   root     4173:         break;
1.1.1.5   root     4174:     case 23:
                   4175:         switch (sel) {
                   4176:         case 0:
1.1.1.8   root     4177:             gen_helper_mtc0_debug(arg); /* EJTAG support */
1.1.1.6   root     4178:             /* BS_STOP isn't good enough here, hflags may have changed. */
                   4179:             gen_save_pc(ctx->pc + 4);
                   4180:             ctx->bstate = BS_EXCP;
                   4181:             rn = "Debug";
                   4182:             break;
                   4183:         case 1:
1.1.1.8   root     4184: //            gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
1.1.1.6   root     4185:             rn = "TraceControl";
                   4186:             /* Stop translation as we may have switched the execution mode */
                   4187:             ctx->bstate = BS_STOP;
                   4188: //            break;
                   4189:         case 2:
1.1.1.8   root     4190: //            gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
1.1.1.6   root     4191:             rn = "TraceControl2";
                   4192:             /* Stop translation as we may have switched the execution mode */
                   4193:             ctx->bstate = BS_STOP;
                   4194: //            break;
                   4195:         case 3:
                   4196:             /* Stop translation as we may have switched the execution mode */
                   4197:             ctx->bstate = BS_STOP;
1.1.1.8   root     4198: //            gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
1.1.1.6   root     4199:             rn = "UserTraceData";
                   4200:             /* Stop translation as we may have switched the execution mode */
                   4201:             ctx->bstate = BS_STOP;
                   4202: //            break;
1.1.1.5   root     4203:         case 4:
1.1.1.8   root     4204: //            gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
1.1.1.6   root     4205:             /* Stop translation as we may have switched the execution mode */
                   4206:             ctx->bstate = BS_STOP;
                   4207:             rn = "TraceBPC";
                   4208: //            break;
1.1.1.5   root     4209:         default:
                   4210:             goto die;
                   4211:         }
                   4212:         break;
                   4213:     case 24:
                   4214:         switch (sel) {
                   4215:         case 0:
1.1.1.7   root     4216:             /* EJTAG support */
1.1.1.8   root     4217:             gen_mtc0_store64(arg, offsetof(CPUState, CP0_DEPC));
1.1.1.6   root     4218:             rn = "DEPC";
                   4219:             break;
1.1.1.5   root     4220:         default:
                   4221:             goto die;
                   4222:         }
                   4223:         break;
                   4224:     case 25:
                   4225:         switch (sel) {
                   4226:         case 0:
1.1.1.8   root     4227:             gen_helper_mtc0_performance0(arg);
1.1.1.6   root     4228:             rn = "Performance0";
                   4229:             break;
                   4230:         case 1:
1.1.1.8   root     4231: //            gen_helper_mtc0_performance1(arg);
1.1.1.6   root     4232:             rn = "Performance1";
                   4233: //            break;
                   4234:         case 2:
1.1.1.8   root     4235: //            gen_helper_mtc0_performance2(arg);
1.1.1.6   root     4236:             rn = "Performance2";
                   4237: //            break;
                   4238:         case 3:
1.1.1.8   root     4239: //            gen_helper_mtc0_performance3(arg);
1.1.1.6   root     4240:             rn = "Performance3";
                   4241: //            break;
1.1.1.5   root     4242:         case 4:
1.1.1.8   root     4243: //            gen_helper_mtc0_performance4(arg);
1.1.1.6   root     4244:             rn = "Performance4";
                   4245: //            break;
1.1.1.5   root     4246:         case 5:
1.1.1.8   root     4247: //            gen_helper_mtc0_performance5(arg);
1.1.1.6   root     4248:             rn = "Performance5";
                   4249: //            break;
1.1.1.5   root     4250:         case 6:
1.1.1.8   root     4251: //            gen_helper_mtc0_performance6(arg);
1.1.1.6   root     4252:             rn = "Performance6";
                   4253: //            break;
1.1.1.5   root     4254:         case 7:
1.1.1.8   root     4255: //            gen_helper_mtc0_performance7(arg);
1.1.1.6   root     4256:             rn = "Performance7";
                   4257: //            break;
1.1.1.5   root     4258:         default:
                   4259:             goto die;
                   4260:         }
                   4261:        break;
                   4262:     case 26:
1.1.1.6   root     4263:         /* ignored */
1.1.1.5   root     4264:         rn = "ECC";
1.1.1.6   root     4265:         break;
1.1.1.5   root     4266:     case 27:
                   4267:         switch (sel) {
                   4268:         case 0 ... 3:
1.1.1.6   root     4269:             /* ignored */
                   4270:             rn = "CacheErr";
                   4271:             break;
1.1.1.5   root     4272:         default:
                   4273:             goto die;
                   4274:         }
                   4275:        break;
                   4276:     case 28:
                   4277:         switch (sel) {
                   4278:         case 0:
                   4279:         case 2:
                   4280:         case 4:
                   4281:         case 6:
1.1.1.8   root     4282:             gen_helper_mtc0_taglo(arg);
1.1.1.5   root     4283:             rn = "TagLo";
                   4284:             break;
                   4285:         case 1:
                   4286:         case 3:
                   4287:         case 5:
                   4288:         case 7:
1.1.1.8   root     4289:             gen_helper_mtc0_datalo(arg);
1.1.1.5   root     4290:             rn = "DataLo";
                   4291:             break;
                   4292:         default:
                   4293:             goto die;
                   4294:         }
                   4295:         break;
                   4296:     case 29:
                   4297:         switch (sel) {
                   4298:         case 0:
                   4299:         case 2:
                   4300:         case 4:
                   4301:         case 6:
1.1.1.8   root     4302:             gen_helper_mtc0_taghi(arg);
1.1.1.5   root     4303:             rn = "TagHi";
                   4304:             break;
                   4305:         case 1:
                   4306:         case 3:
                   4307:         case 5:
                   4308:         case 7:
1.1.1.8   root     4309:             gen_helper_mtc0_datahi(arg);
1.1.1.5   root     4310:             rn = "DataHi";
                   4311:             break;
                   4312:         default:
                   4313:             rn = "invalid sel";
                   4314:             goto die;
                   4315:         }
                   4316:        break;
                   4317:     case 30:
                   4318:         switch (sel) {
                   4319:         case 0:
1.1.1.8   root     4320:             gen_mtc0_store64(arg, offsetof(CPUState, CP0_ErrorEPC));
1.1.1.6   root     4321:             rn = "ErrorEPC";
                   4322:             break;
1.1.1.5   root     4323:         default:
                   4324:             goto die;
                   4325:         }
                   4326:         break;
                   4327:     case 31:
                   4328:         switch (sel) {
                   4329:         case 0:
1.1.1.7   root     4330:             /* EJTAG support */
1.1.1.8   root     4331:             gen_mtc0_store32(arg, offsetof(CPUState, CP0_DESAVE));
1.1.1.6   root     4332:             rn = "DESAVE";
                   4333:             break;
1.1.1.5   root     4334:         default:
                   4335:             goto die;
                   4336:         }
1.1.1.6   root     4337:         /* Stop translation as we may have switched the execution mode */
                   4338:         ctx->bstate = BS_STOP;
1.1.1.5   root     4339:         break;
                   4340:     default:
                   4341:        goto die;
                   4342:     }
1.1.1.13  root     4343:     (void)rn; /* avoid a compiler warning */
1.1.1.7   root     4344:     LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
                   4345:     /* For simplicity assume that all writes can cause interrupts.  */
                   4346:     if (use_icount) {
                   4347:         gen_io_end();
                   4348:         ctx->bstate = BS_STOP;
1.1.1.5   root     4349:     }
                   4350:     return;
                   4351: 
                   4352: die:
1.1.1.7   root     4353:     LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
1.1.1.5   root     4354:     generate_exception(ctx, EXCP_RI);
                   4355: }
                   4356: 
1.1.1.6   root     4357: #if defined(TARGET_MIPS64)
1.1.1.8   root     4358: static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
1.1.1.5   root     4359: {
                   4360:     const char *rn = "invalid";
                   4361: 
1.1.1.6   root     4362:     if (sel != 0)
                   4363:         check_insn(env, ctx, ISA_MIPS64);
                   4364: 
1.1.1.5   root     4365:     switch (reg) {
                   4366:     case 0:
                   4367:         switch (sel) {
                   4368:         case 0:
1.1.1.8   root     4369:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Index));
1.1.1.5   root     4370:             rn = "Index";
                   4371:             break;
                   4372:         case 1:
1.1.1.6   root     4373:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4374:             gen_helper_mfc0_mvpcontrol(arg);
1.1.1.5   root     4375:             rn = "MVPControl";
1.1.1.6   root     4376:             break;
1.1.1.5   root     4377:         case 2:
1.1.1.6   root     4378:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4379:             gen_helper_mfc0_mvpconf0(arg);
1.1.1.5   root     4380:             rn = "MVPConf0";
1.1.1.6   root     4381:             break;
1.1.1.5   root     4382:         case 3:
1.1.1.6   root     4383:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4384:             gen_helper_mfc0_mvpconf1(arg);
1.1.1.5   root     4385:             rn = "MVPConf1";
1.1.1.6   root     4386:             break;
1.1.1.5   root     4387:         default:
                   4388:             goto die;
                   4389:         }
                   4390:         break;
                   4391:     case 1:
                   4392:         switch (sel) {
                   4393:         case 0:
1.1.1.8   root     4394:             gen_helper_mfc0_random(arg);
1.1.1.5   root     4395:             rn = "Random";
1.1.1.6   root     4396:             break;
1.1.1.5   root     4397:         case 1:
1.1.1.6   root     4398:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4399:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEControl));
1.1.1.5   root     4400:             rn = "VPEControl";
1.1.1.6   root     4401:             break;
1.1.1.5   root     4402:         case 2:
1.1.1.6   root     4403:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4404:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf0));
1.1.1.5   root     4405:             rn = "VPEConf0";
1.1.1.6   root     4406:             break;
1.1.1.5   root     4407:         case 3:
1.1.1.6   root     4408:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4409:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEConf1));
1.1.1.5   root     4410:             rn = "VPEConf1";
1.1.1.6   root     4411:             break;
1.1.1.5   root     4412:         case 4:
1.1.1.6   root     4413:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4414:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_YQMask));
1.1.1.5   root     4415:             rn = "YQMask";
1.1.1.6   root     4416:             break;
1.1.1.5   root     4417:         case 5:
1.1.1.6   root     4418:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4419:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPESchedule));
1.1.1.5   root     4420:             rn = "VPESchedule";
1.1.1.6   root     4421:             break;
1.1.1.5   root     4422:         case 6:
1.1.1.6   root     4423:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4424:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
1.1.1.5   root     4425:             rn = "VPEScheFBack";
1.1.1.6   root     4426:             break;
1.1.1.5   root     4427:         case 7:
1.1.1.6   root     4428:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4429:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_VPEOpt));
1.1.1.5   root     4430:             rn = "VPEOpt";
1.1.1.6   root     4431:             break;
1.1.1.5   root     4432:         default:
                   4433:             goto die;
                   4434:         }
                   4435:         break;
                   4436:     case 2:
                   4437:         switch (sel) {
                   4438:         case 0:
1.1.1.8   root     4439:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo0));
1.1.1.6   root     4440:             rn = "EntryLo0";
                   4441:             break;
                   4442:         case 1:
                   4443:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4444:             gen_helper_mfc0_tcstatus(arg);
1.1.1.6   root     4445:             rn = "TCStatus";
                   4446:             break;
                   4447:         case 2:
                   4448:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4449:             gen_helper_mfc0_tcbind(arg);
1.1.1.6   root     4450:             rn = "TCBind";
                   4451:             break;
1.1.1.5   root     4452:         case 3:
1.1.1.6   root     4453:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4454:             gen_helper_dmfc0_tcrestart(arg);
1.1.1.6   root     4455:             rn = "TCRestart";
                   4456:             break;
1.1.1.5   root     4457:         case 4:
1.1.1.6   root     4458:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4459:             gen_helper_dmfc0_tchalt(arg);
1.1.1.6   root     4460:             rn = "TCHalt";
                   4461:             break;
1.1.1.5   root     4462:         case 5:
1.1.1.6   root     4463:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4464:             gen_helper_dmfc0_tccontext(arg);
1.1.1.6   root     4465:             rn = "TCContext";
                   4466:             break;
1.1.1.5   root     4467:         case 6:
1.1.1.6   root     4468:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4469:             gen_helper_dmfc0_tcschedule(arg);
1.1.1.6   root     4470:             rn = "TCSchedule";
                   4471:             break;
1.1.1.5   root     4472:         case 7:
1.1.1.6   root     4473:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4474:             gen_helper_dmfc0_tcschefback(arg);
1.1.1.6   root     4475:             rn = "TCScheFBack";
                   4476:             break;
1.1.1.5   root     4477:         default:
                   4478:             goto die;
                   4479:         }
                   4480:         break;
                   4481:     case 3:
                   4482:         switch (sel) {
                   4483:         case 0:
1.1.1.8   root     4484:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryLo1));
1.1.1.6   root     4485:             rn = "EntryLo1";
                   4486:             break;
1.1.1.5   root     4487:         default:
                   4488:             goto die;
1.1.1.6   root     4489:         }
1.1.1.5   root     4490:         break;
                   4491:     case 4:
                   4492:         switch (sel) {
                   4493:         case 0:
1.1.1.8   root     4494:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_Context));
1.1.1.6   root     4495:             rn = "Context";
                   4496:             break;
                   4497:         case 1:
1.1.1.8   root     4498: //            gen_helper_dmfc0_contextconfig(arg); /* SmartMIPS ASE */
1.1.1.6   root     4499:             rn = "ContextConfig";
                   4500: //            break;
1.1.1.5   root     4501:         default:
                   4502:             goto die;
1.1.1.6   root     4503:         }
1.1.1.5   root     4504:         break;
                   4505:     case 5:
                   4506:         switch (sel) {
                   4507:         case 0:
1.1.1.8   root     4508:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageMask));
1.1.1.6   root     4509:             rn = "PageMask";
                   4510:             break;
                   4511:         case 1:
                   4512:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4513:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_PageGrain));
1.1.1.6   root     4514:             rn = "PageGrain";
                   4515:             break;
1.1.1.5   root     4516:         default:
                   4517:             goto die;
1.1.1.6   root     4518:         }
1.1.1.5   root     4519:         break;
                   4520:     case 6:
                   4521:         switch (sel) {
                   4522:         case 0:
1.1.1.8   root     4523:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Wired));
1.1.1.6   root     4524:             rn = "Wired";
                   4525:             break;
                   4526:         case 1:
                   4527:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4528:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf0));
1.1.1.6   root     4529:             rn = "SRSConf0";
                   4530:             break;
                   4531:         case 2:
                   4532:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4533:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf1));
1.1.1.6   root     4534:             rn = "SRSConf1";
                   4535:             break;
1.1.1.5   root     4536:         case 3:
1.1.1.6   root     4537:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4538:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf2));
1.1.1.6   root     4539:             rn = "SRSConf2";
                   4540:             break;
1.1.1.5   root     4541:         case 4:
1.1.1.6   root     4542:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4543:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf3));
1.1.1.6   root     4544:             rn = "SRSConf3";
                   4545:             break;
1.1.1.5   root     4546:         case 5:
1.1.1.6   root     4547:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4548:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSConf4));
1.1.1.6   root     4549:             rn = "SRSConf4";
                   4550:             break;
1.1.1.5   root     4551:         default:
                   4552:             goto die;
1.1.1.6   root     4553:         }
1.1.1.5   root     4554:         break;
                   4555:     case 7:
                   4556:         switch (sel) {
                   4557:         case 0:
1.1.1.6   root     4558:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4559:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_HWREna));
1.1.1.6   root     4560:             rn = "HWREna";
                   4561:             break;
1.1.1.5   root     4562:         default:
                   4563:             goto die;
1.1.1.6   root     4564:         }
1.1.1.5   root     4565:         break;
                   4566:     case 8:
                   4567:         switch (sel) {
                   4568:         case 0:
1.1.1.8   root     4569:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_BadVAddr));
1.1.1.7   root     4570:             rn = "BadVAddr";
1.1.1.6   root     4571:             break;
1.1.1.5   root     4572:         default:
                   4573:             goto die;
1.1.1.6   root     4574:         }
1.1.1.5   root     4575:         break;
                   4576:     case 9:
                   4577:         switch (sel) {
                   4578:         case 0:
1.1.1.7   root     4579:             /* Mark as an IO operation because we read the time.  */
                   4580:             if (use_icount)
                   4581:                 gen_io_start();
1.1.1.8   root     4582:             gen_helper_mfc0_count(arg);
1.1.1.7   root     4583:             if (use_icount) {
                   4584:                 gen_io_end();
                   4585:             }
1.1.1.13  root     4586:             /* Break the TB to be able to take timer interrupts immediately
                   4587:                after reading count.  */
                   4588:             ctx->bstate = BS_STOP;
1.1.1.6   root     4589:             rn = "Count";
                   4590:             break;
                   4591:         /* 6,7 are implementation dependent */
1.1.1.5   root     4592:         default:
                   4593:             goto die;
1.1.1.6   root     4594:         }
1.1.1.5   root     4595:         break;
                   4596:     case 10:
                   4597:         switch (sel) {
                   4598:         case 0:
1.1.1.8   root     4599:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EntryHi));
1.1.1.6   root     4600:             rn = "EntryHi";
                   4601:             break;
1.1.1.5   root     4602:         default:
                   4603:             goto die;
1.1.1.6   root     4604:         }
1.1.1.5   root     4605:         break;
                   4606:     case 11:
                   4607:         switch (sel) {
                   4608:         case 0:
1.1.1.8   root     4609:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Compare));
1.1.1.6   root     4610:             rn = "Compare";
                   4611:             break;
                   4612:         /* 6,7 are implementation dependent */
1.1.1.5   root     4613:         default:
                   4614:             goto die;
1.1.1.6   root     4615:         }
1.1.1.5   root     4616:         break;
                   4617:     case 12:
                   4618:         switch (sel) {
                   4619:         case 0:
1.1.1.8   root     4620:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Status));
1.1.1.6   root     4621:             rn = "Status";
                   4622:             break;
                   4623:         case 1:
                   4624:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4625:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_IntCtl));
1.1.1.6   root     4626:             rn = "IntCtl";
                   4627:             break;
                   4628:         case 2:
                   4629:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4630:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSCtl));
1.1.1.6   root     4631:             rn = "SRSCtl";
                   4632:             break;
1.1.1.5   root     4633:         case 3:
1.1.1.6   root     4634:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4635:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_SRSMap));
1.1.1.6   root     4636:             rn = "SRSMap";
                   4637:             break;
1.1.1.5   root     4638:         default:
                   4639:             goto die;
1.1.1.6   root     4640:         }
1.1.1.5   root     4641:         break;
                   4642:     case 13:
                   4643:         switch (sel) {
                   4644:         case 0:
1.1.1.8   root     4645:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Cause));
1.1.1.6   root     4646:             rn = "Cause";
                   4647:             break;
1.1.1.5   root     4648:         default:
                   4649:             goto die;
1.1.1.6   root     4650:         }
1.1.1.5   root     4651:         break;
                   4652:     case 14:
                   4653:         switch (sel) {
                   4654:         case 0:
1.1.1.8   root     4655:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
1.1.1.6   root     4656:             rn = "EPC";
                   4657:             break;
1.1.1.5   root     4658:         default:
                   4659:             goto die;
1.1.1.6   root     4660:         }
1.1.1.5   root     4661:         break;
                   4662:     case 15:
                   4663:         switch (sel) {
                   4664:         case 0:
1.1.1.8   root     4665:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_PRid));
1.1.1.6   root     4666:             rn = "PRid";
                   4667:             break;
                   4668:         case 1:
                   4669:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     4670:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_EBase));
1.1.1.6   root     4671:             rn = "EBase";
                   4672:             break;
1.1.1.5   root     4673:         default:
                   4674:             goto die;
1.1.1.6   root     4675:         }
1.1.1.5   root     4676:         break;
                   4677:     case 16:
                   4678:         switch (sel) {
                   4679:         case 0:
1.1.1.8   root     4680:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config0));
1.1.1.5   root     4681:             rn = "Config";
                   4682:             break;
                   4683:         case 1:
1.1.1.8   root     4684:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config1));
1.1.1.5   root     4685:             rn = "Config1";
                   4686:             break;
                   4687:         case 2:
1.1.1.8   root     4688:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config2));
1.1.1.5   root     4689:             rn = "Config2";
                   4690:             break;
                   4691:         case 3:
1.1.1.8   root     4692:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config3));
1.1.1.5   root     4693:             rn = "Config3";
                   4694:             break;
                   4695:        /* 6,7 are implementation dependent */
1.1.1.7   root     4696:         case 6:
1.1.1.8   root     4697:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config6));
1.1.1.7   root     4698:             rn = "Config6";
                   4699:             break;
                   4700:         case 7:
1.1.1.8   root     4701:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Config7));
1.1.1.7   root     4702:             rn = "Config7";
                   4703:             break;
1.1.1.5   root     4704:         default:
                   4705:             goto die;
                   4706:         }
                   4707:         break;
                   4708:     case 17:
                   4709:         switch (sel) {
                   4710:         case 0:
1.1.1.8   root     4711:             gen_helper_dmfc0_lladdr(arg);
1.1.1.6   root     4712:             rn = "LLAddr";
                   4713:             break;
1.1.1.5   root     4714:         default:
                   4715:             goto die;
                   4716:         }
                   4717:         break;
                   4718:     case 18:
                   4719:         switch (sel) {
1.1.1.6   root     4720:         case 0 ... 7:
1.1.1.8   root     4721:             gen_helper_1i(dmfc0_watchlo, arg, sel);
1.1.1.6   root     4722:             rn = "WatchLo";
                   4723:             break;
1.1.1.5   root     4724:         default:
                   4725:             goto die;
                   4726:         }
                   4727:         break;
                   4728:     case 19:
                   4729:         switch (sel) {
1.1.1.6   root     4730:         case 0 ... 7:
1.1.1.8   root     4731:             gen_helper_1i(mfc0_watchhi, arg, sel);
1.1.1.6   root     4732:             rn = "WatchHi";
                   4733:             break;
1.1.1.5   root     4734:         default:
                   4735:             goto die;
                   4736:         }
                   4737:         break;
                   4738:     case 20:
                   4739:         switch (sel) {
                   4740:         case 0:
1.1.1.6   root     4741:             check_insn(env, ctx, ISA_MIPS3);
1.1.1.8   root     4742:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_XContext));
1.1.1.6   root     4743:             rn = "XContext";
                   4744:             break;
1.1.1.5   root     4745:         default:
                   4746:             goto die;
                   4747:         }
                   4748:         break;
                   4749:     case 21:
                   4750:        /* Officially reserved, but sel 0 is used for R1x000 framemask */
                   4751:         switch (sel) {
                   4752:         case 0:
1.1.1.8   root     4753:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Framemask));
1.1.1.6   root     4754:             rn = "Framemask";
                   4755:             break;
1.1.1.5   root     4756:         default:
                   4757:             goto die;
                   4758:         }
                   4759:         break;
                   4760:     case 22:
1.1.1.8   root     4761:         tcg_gen_movi_tl(arg, 0); /* unimplemented */
1.1.1.6   root     4762:         rn = "'Diagnostic"; /* implementation dependent */
                   4763:         break;
1.1.1.5   root     4764:     case 23:
                   4765:         switch (sel) {
                   4766:         case 0:
1.1.1.8   root     4767:             gen_helper_mfc0_debug(arg); /* EJTAG support */
1.1.1.6   root     4768:             rn = "Debug";
                   4769:             break;
                   4770:         case 1:
1.1.1.8   root     4771: //            gen_helper_dmfc0_tracecontrol(arg); /* PDtrace support */
1.1.1.6   root     4772:             rn = "TraceControl";
                   4773: //            break;
                   4774:         case 2:
1.1.1.8   root     4775: //            gen_helper_dmfc0_tracecontrol2(arg); /* PDtrace support */
1.1.1.6   root     4776:             rn = "TraceControl2";
                   4777: //            break;
1.1.1.5   root     4778:         case 3:
1.1.1.8   root     4779: //            gen_helper_dmfc0_usertracedata(arg); /* PDtrace support */
1.1.1.6   root     4780:             rn = "UserTraceData";
                   4781: //            break;
1.1.1.5   root     4782:         case 4:
1.1.1.8   root     4783: //            gen_helper_dmfc0_tracebpc(arg); /* PDtrace support */
1.1.1.6   root     4784:             rn = "TraceBPC";
                   4785: //            break;
1.1.1.5   root     4786:         default:
                   4787:             goto die;
                   4788:         }
                   4789:         break;
                   4790:     case 24:
                   4791:         switch (sel) {
                   4792:         case 0:
1.1.1.7   root     4793:             /* EJTAG support */
1.1.1.8   root     4794:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
1.1.1.6   root     4795:             rn = "DEPC";
                   4796:             break;
1.1.1.5   root     4797:         default:
                   4798:             goto die;
                   4799:         }
                   4800:         break;
                   4801:     case 25:
                   4802:         switch (sel) {
                   4803:         case 0:
1.1.1.8   root     4804:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_Performance0));
1.1.1.6   root     4805:             rn = "Performance0";
1.1.1.5   root     4806:             break;
                   4807:         case 1:
1.1.1.8   root     4808: //            gen_helper_dmfc0_performance1(arg);
1.1.1.6   root     4809:             rn = "Performance1";
                   4810: //            break;
1.1.1.5   root     4811:         case 2:
1.1.1.8   root     4812: //            gen_helper_dmfc0_performance2(arg);
1.1.1.6   root     4813:             rn = "Performance2";
                   4814: //            break;
1.1.1.5   root     4815:         case 3:
1.1.1.8   root     4816: //            gen_helper_dmfc0_performance3(arg);
1.1.1.6   root     4817:             rn = "Performance3";
                   4818: //            break;
1.1.1.5   root     4819:         case 4:
1.1.1.8   root     4820: //            gen_helper_dmfc0_performance4(arg);
1.1.1.6   root     4821:             rn = "Performance4";
                   4822: //            break;
1.1.1.5   root     4823:         case 5:
1.1.1.8   root     4824: //            gen_helper_dmfc0_performance5(arg);
1.1.1.6   root     4825:             rn = "Performance5";
                   4826: //            break;
1.1.1.5   root     4827:         case 6:
1.1.1.8   root     4828: //            gen_helper_dmfc0_performance6(arg);
1.1.1.6   root     4829:             rn = "Performance6";
                   4830: //            break;
1.1.1.5   root     4831:         case 7:
1.1.1.8   root     4832: //            gen_helper_dmfc0_performance7(arg);
1.1.1.6   root     4833:             rn = "Performance7";
                   4834: //            break;
1.1.1.5   root     4835:         default:
                   4836:             goto die;
                   4837:         }
                   4838:         break;
                   4839:     case 26:
1.1.1.8   root     4840:         tcg_gen_movi_tl(arg, 0); /* unimplemented */
1.1.1.7   root     4841:         rn = "ECC";
                   4842:         break;
1.1.1.5   root     4843:     case 27:
                   4844:         switch (sel) {
                   4845:         /* ignored */
                   4846:         case 0 ... 3:
1.1.1.8   root     4847:             tcg_gen_movi_tl(arg, 0); /* unimplemented */
1.1.1.6   root     4848:             rn = "CacheErr";
                   4849:             break;
1.1.1.5   root     4850:         default:
                   4851:             goto die;
                   4852:         }
                   4853:         break;
                   4854:     case 28:
                   4855:         switch (sel) {
                   4856:         case 0:
                   4857:         case 2:
                   4858:         case 4:
                   4859:         case 6:
1.1.1.8   root     4860:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagLo));
1.1.1.5   root     4861:             rn = "TagLo";
                   4862:             break;
                   4863:         case 1:
                   4864:         case 3:
                   4865:         case 5:
                   4866:         case 7:
1.1.1.8   root     4867:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataLo));
1.1.1.5   root     4868:             rn = "DataLo";
                   4869:             break;
                   4870:         default:
                   4871:             goto die;
                   4872:         }
                   4873:         break;
                   4874:     case 29:
                   4875:         switch (sel) {
                   4876:         case 0:
                   4877:         case 2:
                   4878:         case 4:
                   4879:         case 6:
1.1.1.8   root     4880:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_TagHi));
1.1.1.5   root     4881:             rn = "TagHi";
                   4882:             break;
                   4883:         case 1:
                   4884:         case 3:
                   4885:         case 5:
                   4886:         case 7:
1.1.1.8   root     4887:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_DataHi));
1.1.1.5   root     4888:             rn = "DataHi";
                   4889:             break;
                   4890:         default:
                   4891:             goto die;
                   4892:         }
                   4893:         break;
                   4894:     case 30:
                   4895:         switch (sel) {
                   4896:         case 0:
1.1.1.8   root     4897:             tcg_gen_ld_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
1.1.1.6   root     4898:             rn = "ErrorEPC";
                   4899:             break;
1.1.1.5   root     4900:         default:
                   4901:             goto die;
                   4902:         }
                   4903:         break;
                   4904:     case 31:
                   4905:         switch (sel) {
                   4906:         case 0:
1.1.1.7   root     4907:             /* EJTAG support */
1.1.1.8   root     4908:             gen_mfc0_load32(arg, offsetof(CPUState, CP0_DESAVE));
1.1.1.6   root     4909:             rn = "DESAVE";
                   4910:             break;
1.1.1.5   root     4911:         default:
                   4912:             goto die;
                   4913:         }
                   4914:         break;
                   4915:     default:
1.1.1.6   root     4916:         goto die;
1.1.1.5   root     4917:     }
1.1.1.13  root     4918:     (void)rn; /* avoid a compiler warning */
1.1.1.7   root     4919:     LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
1.1.1.5   root     4920:     return;
                   4921: 
                   4922: die:
1.1.1.7   root     4923:     LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
1.1.1.5   root     4924:     generate_exception(ctx, EXCP_RI);
                   4925: }
                   4926: 
1.1.1.8   root     4927: static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv arg, int reg, int sel)
1.1.1.5   root     4928: {
                   4929:     const char *rn = "invalid";
                   4930: 
1.1.1.6   root     4931:     if (sel != 0)
                   4932:         check_insn(env, ctx, ISA_MIPS64);
                   4933: 
1.1.1.7   root     4934:     if (use_icount)
                   4935:         gen_io_start();
                   4936: 
1.1.1.5   root     4937:     switch (reg) {
                   4938:     case 0:
                   4939:         switch (sel) {
                   4940:         case 0:
1.1.1.8   root     4941:             gen_helper_mtc0_index(arg);
1.1.1.5   root     4942:             rn = "Index";
                   4943:             break;
                   4944:         case 1:
1.1.1.6   root     4945:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4946:             gen_helper_mtc0_mvpcontrol(arg);
1.1.1.5   root     4947:             rn = "MVPControl";
1.1.1.6   root     4948:             break;
1.1.1.5   root     4949:         case 2:
1.1.1.6   root     4950:             check_insn(env, ctx, ASE_MT);
                   4951:             /* ignored */
1.1.1.5   root     4952:             rn = "MVPConf0";
1.1.1.6   root     4953:             break;
1.1.1.5   root     4954:         case 3:
1.1.1.6   root     4955:             check_insn(env, ctx, ASE_MT);
                   4956:             /* ignored */
1.1.1.5   root     4957:             rn = "MVPConf1";
1.1.1.6   root     4958:             break;
1.1.1.5   root     4959:         default:
                   4960:             goto die;
                   4961:         }
                   4962:         break;
                   4963:     case 1:
                   4964:         switch (sel) {
                   4965:         case 0:
1.1.1.6   root     4966:             /* ignored */
1.1.1.5   root     4967:             rn = "Random";
1.1.1.6   root     4968:             break;
1.1.1.5   root     4969:         case 1:
1.1.1.6   root     4970:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4971:             gen_helper_mtc0_vpecontrol(arg);
1.1.1.5   root     4972:             rn = "VPEControl";
1.1.1.6   root     4973:             break;
1.1.1.5   root     4974:         case 2:
1.1.1.6   root     4975:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4976:             gen_helper_mtc0_vpeconf0(arg);
1.1.1.5   root     4977:             rn = "VPEConf0";
1.1.1.6   root     4978:             break;
1.1.1.5   root     4979:         case 3:
1.1.1.6   root     4980:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4981:             gen_helper_mtc0_vpeconf1(arg);
1.1.1.5   root     4982:             rn = "VPEConf1";
1.1.1.6   root     4983:             break;
1.1.1.5   root     4984:         case 4:
1.1.1.6   root     4985:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4986:             gen_helper_mtc0_yqmask(arg);
1.1.1.5   root     4987:             rn = "YQMask";
1.1.1.6   root     4988:             break;
1.1.1.5   root     4989:         case 5:
1.1.1.6   root     4990:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4991:             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_VPESchedule));
1.1.1.5   root     4992:             rn = "VPESchedule";
1.1.1.6   root     4993:             break;
1.1.1.5   root     4994:         case 6:
1.1.1.6   root     4995:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     4996:             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
1.1.1.5   root     4997:             rn = "VPEScheFBack";
1.1.1.6   root     4998:             break;
1.1.1.5   root     4999:         case 7:
1.1.1.6   root     5000:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     5001:             gen_helper_mtc0_vpeopt(arg);
1.1.1.5   root     5002:             rn = "VPEOpt";
1.1.1.6   root     5003:             break;
1.1.1.5   root     5004:         default:
                   5005:             goto die;
                   5006:         }
                   5007:         break;
                   5008:     case 2:
                   5009:         switch (sel) {
                   5010:         case 0:
1.1.1.8   root     5011:             gen_helper_mtc0_entrylo0(arg);
1.1.1.6   root     5012:             rn = "EntryLo0";
                   5013:             break;
                   5014:         case 1:
                   5015:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     5016:             gen_helper_mtc0_tcstatus(arg);
1.1.1.6   root     5017:             rn = "TCStatus";
                   5018:             break;
                   5019:         case 2:
                   5020:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     5021:             gen_helper_mtc0_tcbind(arg);
1.1.1.6   root     5022:             rn = "TCBind";
                   5023:             break;
1.1.1.5   root     5024:         case 3:
1.1.1.6   root     5025:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     5026:             gen_helper_mtc0_tcrestart(arg);
1.1.1.6   root     5027:             rn = "TCRestart";
                   5028:             break;
1.1.1.5   root     5029:         case 4:
1.1.1.6   root     5030:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     5031:             gen_helper_mtc0_tchalt(arg);
1.1.1.6   root     5032:             rn = "TCHalt";
                   5033:             break;
1.1.1.5   root     5034:         case 5:
1.1.1.6   root     5035:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     5036:             gen_helper_mtc0_tccontext(arg);
1.1.1.6   root     5037:             rn = "TCContext";
                   5038:             break;
1.1.1.5   root     5039:         case 6:
1.1.1.6   root     5040:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     5041:             gen_helper_mtc0_tcschedule(arg);
1.1.1.6   root     5042:             rn = "TCSchedule";
                   5043:             break;
1.1.1.5   root     5044:         case 7:
1.1.1.6   root     5045:             check_insn(env, ctx, ASE_MT);
1.1.1.8   root     5046:             gen_helper_mtc0_tcschefback(arg);
1.1.1.6   root     5047:             rn = "TCScheFBack";
                   5048:             break;
1.1.1.5   root     5049:         default:
                   5050:             goto die;
                   5051:         }
                   5052:         break;
                   5053:     case 3:
                   5054:         switch (sel) {
                   5055:         case 0:
1.1.1.8   root     5056:             gen_helper_mtc0_entrylo1(arg);
1.1.1.6   root     5057:             rn = "EntryLo1";
                   5058:             break;
1.1.1.5   root     5059:         default:
                   5060:             goto die;
1.1.1.6   root     5061:         }
1.1.1.5   root     5062:         break;
                   5063:     case 4:
                   5064:         switch (sel) {
                   5065:         case 0:
1.1.1.8   root     5066:             gen_helper_mtc0_context(arg);
1.1.1.6   root     5067:             rn = "Context";
                   5068:             break;
                   5069:         case 1:
1.1.1.8   root     5070: //           gen_helper_mtc0_contextconfig(arg); /* SmartMIPS ASE */
1.1.1.6   root     5071:             rn = "ContextConfig";
                   5072: //           break;
1.1.1.5   root     5073:         default:
                   5074:             goto die;
1.1.1.6   root     5075:         }
1.1.1.5   root     5076:         break;
                   5077:     case 5:
                   5078:         switch (sel) {
                   5079:         case 0:
1.1.1.8   root     5080:             gen_helper_mtc0_pagemask(arg);
1.1.1.6   root     5081:             rn = "PageMask";
                   5082:             break;
                   5083:         case 1:
                   5084:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5085:             gen_helper_mtc0_pagegrain(arg);
1.1.1.6   root     5086:             rn = "PageGrain";
                   5087:             break;
1.1.1.5   root     5088:         default:
                   5089:             goto die;
1.1.1.6   root     5090:         }
1.1.1.5   root     5091:         break;
                   5092:     case 6:
                   5093:         switch (sel) {
                   5094:         case 0:
1.1.1.8   root     5095:             gen_helper_mtc0_wired(arg);
1.1.1.6   root     5096:             rn = "Wired";
                   5097:             break;
                   5098:         case 1:
                   5099:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5100:             gen_helper_mtc0_srsconf0(arg);
1.1.1.6   root     5101:             rn = "SRSConf0";
                   5102:             break;
                   5103:         case 2:
                   5104:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5105:             gen_helper_mtc0_srsconf1(arg);
1.1.1.6   root     5106:             rn = "SRSConf1";
                   5107:             break;
1.1.1.5   root     5108:         case 3:
1.1.1.6   root     5109:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5110:             gen_helper_mtc0_srsconf2(arg);
1.1.1.6   root     5111:             rn = "SRSConf2";
                   5112:             break;
1.1.1.5   root     5113:         case 4:
1.1.1.6   root     5114:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5115:             gen_helper_mtc0_srsconf3(arg);
1.1.1.6   root     5116:             rn = "SRSConf3";
                   5117:             break;
1.1.1.5   root     5118:         case 5:
1.1.1.6   root     5119:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5120:             gen_helper_mtc0_srsconf4(arg);
1.1.1.6   root     5121:             rn = "SRSConf4";
                   5122:             break;
1.1.1.5   root     5123:         default:
                   5124:             goto die;
1.1.1.6   root     5125:         }
1.1.1.5   root     5126:         break;
                   5127:     case 7:
                   5128:         switch (sel) {
                   5129:         case 0:
1.1.1.6   root     5130:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5131:             gen_helper_mtc0_hwrena(arg);
1.1.1.6   root     5132:             rn = "HWREna";
                   5133:             break;
1.1.1.5   root     5134:         default:
                   5135:             goto die;
1.1.1.6   root     5136:         }
1.1.1.5   root     5137:         break;
                   5138:     case 8:
                   5139:         /* ignored */
1.1.1.7   root     5140:         rn = "BadVAddr";
1.1.1.5   root     5141:         break;
                   5142:     case 9:
                   5143:         switch (sel) {
                   5144:         case 0:
1.1.1.8   root     5145:             gen_helper_mtc0_count(arg);
1.1.1.6   root     5146:             rn = "Count";
                   5147:             break;
                   5148:         /* 6,7 are implementation dependent */
1.1.1.5   root     5149:         default:
                   5150:             goto die;
1.1.1.6   root     5151:         }
                   5152:         /* Stop translation as we may have switched the execution mode */
                   5153:         ctx->bstate = BS_STOP;
1.1.1.5   root     5154:         break;
                   5155:     case 10:
                   5156:         switch (sel) {
                   5157:         case 0:
1.1.1.8   root     5158:             gen_helper_mtc0_entryhi(arg);
1.1.1.6   root     5159:             rn = "EntryHi";
                   5160:             break;
1.1.1.5   root     5161:         default:
                   5162:             goto die;
1.1.1.6   root     5163:         }
1.1.1.5   root     5164:         break;
                   5165:     case 11:
                   5166:         switch (sel) {
                   5167:         case 0:
1.1.1.8   root     5168:             gen_helper_mtc0_compare(arg);
1.1.1.6   root     5169:             rn = "Compare";
                   5170:             break;
                   5171:         /* 6,7 are implementation dependent */
1.1.1.5   root     5172:         default:
                   5173:             goto die;
1.1.1.6   root     5174:         }
                   5175:         /* Stop translation as we may have switched the execution mode */
                   5176:         ctx->bstate = BS_STOP;
1.1.1.5   root     5177:         break;
                   5178:     case 12:
                   5179:         switch (sel) {
                   5180:         case 0:
1.1.1.8   root     5181:             save_cpu_state(ctx, 1);
                   5182:             gen_helper_mtc0_status(arg);
1.1.1.6   root     5183:             /* BS_STOP isn't good enough here, hflags may have changed. */
                   5184:             gen_save_pc(ctx->pc + 4);
                   5185:             ctx->bstate = BS_EXCP;
                   5186:             rn = "Status";
                   5187:             break;
                   5188:         case 1:
                   5189:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5190:             gen_helper_mtc0_intctl(arg);
1.1.1.6   root     5191:             /* Stop translation as we may have switched the execution mode */
                   5192:             ctx->bstate = BS_STOP;
                   5193:             rn = "IntCtl";
                   5194:             break;
                   5195:         case 2:
                   5196:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5197:             gen_helper_mtc0_srsctl(arg);
1.1.1.6   root     5198:             /* Stop translation as we may have switched the execution mode */
                   5199:             ctx->bstate = BS_STOP;
                   5200:             rn = "SRSCtl";
                   5201:             break;
1.1.1.5   root     5202:         case 3:
1.1.1.6   root     5203:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5204:             gen_mtc0_store32(arg, offsetof(CPUState, CP0_SRSMap));
1.1.1.6   root     5205:             /* Stop translation as we may have switched the execution mode */
                   5206:             ctx->bstate = BS_STOP;
                   5207:             rn = "SRSMap";
                   5208:             break;
1.1.1.5   root     5209:         default:
                   5210:             goto die;
1.1.1.6   root     5211:         }
1.1.1.5   root     5212:         break;
                   5213:     case 13:
                   5214:         switch (sel) {
                   5215:         case 0:
1.1.1.8   root     5216:             save_cpu_state(ctx, 1);
1.1.1.12  root     5217:             /* Mark as an IO operation because we may trigger a software
                   5218:                interrupt.  */
                   5219:             if (use_icount) {
                   5220:                 gen_io_start();
                   5221:             }
1.1.1.8   root     5222:             gen_helper_mtc0_cause(arg);
1.1.1.12  root     5223:             if (use_icount) {
                   5224:                 gen_io_end();
                   5225:             }
                   5226:             /* Stop translation as we may have triggered an intetrupt */
                   5227:             ctx->bstate = BS_STOP;
1.1.1.6   root     5228:             rn = "Cause";
                   5229:             break;
1.1.1.5   root     5230:         default:
                   5231:             goto die;
1.1.1.6   root     5232:         }
1.1.1.5   root     5233:         break;
                   5234:     case 14:
                   5235:         switch (sel) {
                   5236:         case 0:
1.1.1.8   root     5237:             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_EPC));
1.1.1.6   root     5238:             rn = "EPC";
                   5239:             break;
1.1.1.5   root     5240:         default:
                   5241:             goto die;
1.1.1.6   root     5242:         }
1.1.1.5   root     5243:         break;
                   5244:     case 15:
                   5245:         switch (sel) {
                   5246:         case 0:
1.1.1.6   root     5247:             /* ignored */
                   5248:             rn = "PRid";
                   5249:             break;
                   5250:         case 1:
                   5251:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.8   root     5252:             gen_helper_mtc0_ebase(arg);
1.1.1.6   root     5253:             rn = "EBase";
                   5254:             break;
1.1.1.5   root     5255:         default:
                   5256:             goto die;
1.1.1.6   root     5257:         }
1.1.1.5   root     5258:         break;
                   5259:     case 16:
                   5260:         switch (sel) {
                   5261:         case 0:
1.1.1.8   root     5262:             gen_helper_mtc0_config0(arg);
1.1.1.5   root     5263:             rn = "Config";
1.1.1.6   root     5264:             /* Stop translation as we may have switched the execution mode */
                   5265:             ctx->bstate = BS_STOP;
1.1.1.5   root     5266:             break;
                   5267:         case 1:
1.1.1.8   root     5268:             /* ignored, read only */
1.1.1.5   root     5269:             rn = "Config1";
                   5270:             break;
                   5271:         case 2:
1.1.1.8   root     5272:             gen_helper_mtc0_config2(arg);
1.1.1.5   root     5273:             rn = "Config2";
1.1.1.6   root     5274:             /* Stop translation as we may have switched the execution mode */
                   5275:             ctx->bstate = BS_STOP;
1.1.1.5   root     5276:             break;
                   5277:         case 3:
1.1.1.6   root     5278:             /* ignored */
1.1.1.5   root     5279:             rn = "Config3";
                   5280:             break;
                   5281:         /* 6,7 are implementation dependent */
                   5282:         default:
                   5283:             rn = "Invalid config selector";
                   5284:             goto die;
                   5285:         }
                   5286:         break;
                   5287:     case 17:
                   5288:         switch (sel) {
                   5289:         case 0:
1.1.1.9   root     5290:             gen_helper_mtc0_lladdr(arg);
1.1.1.6   root     5291:             rn = "LLAddr";
                   5292:             break;
1.1.1.5   root     5293:         default:
                   5294:             goto die;
                   5295:         }
                   5296:         break;
                   5297:     case 18:
                   5298:         switch (sel) {
1.1.1.6   root     5299:         case 0 ... 7:
1.1.1.8   root     5300:             gen_helper_1i(mtc0_watchlo, arg, sel);
1.1.1.6   root     5301:             rn = "WatchLo";
                   5302:             break;
1.1.1.5   root     5303:         default:
                   5304:             goto die;
                   5305:         }
                   5306:         break;
                   5307:     case 19:
                   5308:         switch (sel) {
1.1.1.6   root     5309:         case 0 ... 7:
1.1.1.8   root     5310:             gen_helper_1i(mtc0_watchhi, arg, sel);
1.1.1.6   root     5311:             rn = "WatchHi";
                   5312:             break;
1.1.1.5   root     5313:         default:
                   5314:             goto die;
                   5315:         }
                   5316:         break;
                   5317:     case 20:
                   5318:         switch (sel) {
                   5319:         case 0:
1.1.1.6   root     5320:             check_insn(env, ctx, ISA_MIPS3);
1.1.1.8   root     5321:             gen_helper_mtc0_xcontext(arg);
1.1.1.6   root     5322:             rn = "XContext";
                   5323:             break;
1.1.1.5   root     5324:         default:
                   5325:             goto die;
                   5326:         }
                   5327:         break;
                   5328:     case 21:
                   5329:        /* Officially reserved, but sel 0 is used for R1x000 framemask */
                   5330:         switch (sel) {
                   5331:         case 0:
1.1.1.8   root     5332:             gen_helper_mtc0_framemask(arg);
1.1.1.6   root     5333:             rn = "Framemask";
                   5334:             break;
1.1.1.5   root     5335:         default:
                   5336:             goto die;
                   5337:         }
                   5338:         break;
                   5339:     case 22:
                   5340:         /* ignored */
                   5341:         rn = "Diagnostic"; /* implementation dependent */
1.1.1.6   root     5342:         break;
1.1.1.5   root     5343:     case 23:
                   5344:         switch (sel) {
                   5345:         case 0:
1.1.1.8   root     5346:             gen_helper_mtc0_debug(arg); /* EJTAG support */
1.1.1.6   root     5347:             /* BS_STOP isn't good enough here, hflags may have changed. */
                   5348:             gen_save_pc(ctx->pc + 4);
                   5349:             ctx->bstate = BS_EXCP;
                   5350:             rn = "Debug";
                   5351:             break;
                   5352:         case 1:
1.1.1.8   root     5353: //            gen_helper_mtc0_tracecontrol(arg); /* PDtrace support */
1.1.1.6   root     5354:             /* Stop translation as we may have switched the execution mode */
                   5355:             ctx->bstate = BS_STOP;
                   5356:             rn = "TraceControl";
                   5357: //            break;
                   5358:         case 2:
1.1.1.8   root     5359: //            gen_helper_mtc0_tracecontrol2(arg); /* PDtrace support */
1.1.1.6   root     5360:             /* Stop translation as we may have switched the execution mode */
                   5361:             ctx->bstate = BS_STOP;
                   5362:             rn = "TraceControl2";
                   5363: //            break;
                   5364:         case 3:
1.1.1.8   root     5365: //            gen_helper_mtc0_usertracedata(arg); /* PDtrace support */
1.1.1.6   root     5366:             /* Stop translation as we may have switched the execution mode */
                   5367:             ctx->bstate = BS_STOP;
                   5368:             rn = "UserTraceData";
                   5369: //            break;
1.1.1.5   root     5370:         case 4:
1.1.1.8   root     5371: //            gen_helper_mtc0_tracebpc(arg); /* PDtrace support */
1.1.1.6   root     5372:             /* Stop translation as we may have switched the execution mode */
                   5373:             ctx->bstate = BS_STOP;
                   5374:             rn = "TraceBPC";
                   5375: //            break;
1.1.1.5   root     5376:         default:
                   5377:             goto die;
                   5378:         }
                   5379:         break;
                   5380:     case 24:
                   5381:         switch (sel) {
                   5382:         case 0:
1.1.1.7   root     5383:             /* EJTAG support */
1.1.1.8   root     5384:             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_DEPC));
1.1.1.6   root     5385:             rn = "DEPC";
                   5386:             break;
1.1.1.5   root     5387:         default:
                   5388:             goto die;
                   5389:         }
                   5390:         break;
                   5391:     case 25:
                   5392:         switch (sel) {
                   5393:         case 0:
1.1.1.8   root     5394:             gen_helper_mtc0_performance0(arg);
1.1.1.6   root     5395:             rn = "Performance0";
                   5396:             break;
                   5397:         case 1:
1.1.1.8   root     5398: //            gen_helper_mtc0_performance1(arg);
1.1.1.6   root     5399:             rn = "Performance1";
                   5400: //            break;
                   5401:         case 2:
1.1.1.8   root     5402: //            gen_helper_mtc0_performance2(arg);
1.1.1.6   root     5403:             rn = "Performance2";
                   5404: //            break;
1.1.1.5   root     5405:         case 3:
1.1.1.8   root     5406: //            gen_helper_mtc0_performance3(arg);
1.1.1.6   root     5407:             rn = "Performance3";
                   5408: //            break;
1.1.1.5   root     5409:         case 4:
1.1.1.8   root     5410: //            gen_helper_mtc0_performance4(arg);
1.1.1.6   root     5411:             rn = "Performance4";
                   5412: //            break;
1.1.1.5   root     5413:         case 5:
1.1.1.8   root     5414: //            gen_helper_mtc0_performance5(arg);
1.1.1.6   root     5415:             rn = "Performance5";
                   5416: //            break;
1.1.1.5   root     5417:         case 6:
1.1.1.8   root     5418: //            gen_helper_mtc0_performance6(arg);
1.1.1.6   root     5419:             rn = "Performance6";
                   5420: //            break;
1.1.1.5   root     5421:         case 7:
1.1.1.8   root     5422: //            gen_helper_mtc0_performance7(arg);
1.1.1.6   root     5423:             rn = "Performance7";
                   5424: //            break;
1.1.1.5   root     5425:         default:
                   5426:             goto die;
                   5427:         }
1.1.1.6   root     5428:         break;
1.1.1.5   root     5429:     case 26:
1.1.1.6   root     5430:         /* ignored */
1.1.1.5   root     5431:         rn = "ECC";
1.1.1.6   root     5432:         break;
1.1.1.5   root     5433:     case 27:
                   5434:         switch (sel) {
                   5435:         case 0 ... 3:
1.1.1.6   root     5436:             /* ignored */
                   5437:             rn = "CacheErr";
                   5438:             break;
1.1.1.5   root     5439:         default:
                   5440:             goto die;
                   5441:         }
1.1.1.6   root     5442:         break;
1.1.1.5   root     5443:     case 28:
                   5444:         switch (sel) {
                   5445:         case 0:
                   5446:         case 2:
                   5447:         case 4:
                   5448:         case 6:
1.1.1.8   root     5449:             gen_helper_mtc0_taglo(arg);
1.1.1.5   root     5450:             rn = "TagLo";
                   5451:             break;
                   5452:         case 1:
                   5453:         case 3:
                   5454:         case 5:
                   5455:         case 7:
1.1.1.8   root     5456:             gen_helper_mtc0_datalo(arg);
1.1.1.5   root     5457:             rn = "DataLo";
                   5458:             break;
                   5459:         default:
                   5460:             goto die;
                   5461:         }
                   5462:         break;
                   5463:     case 29:
                   5464:         switch (sel) {
                   5465:         case 0:
                   5466:         case 2:
                   5467:         case 4:
                   5468:         case 6:
1.1.1.8   root     5469:             gen_helper_mtc0_taghi(arg);
1.1.1.5   root     5470:             rn = "TagHi";
                   5471:             break;
                   5472:         case 1:
                   5473:         case 3:
                   5474:         case 5:
                   5475:         case 7:
1.1.1.8   root     5476:             gen_helper_mtc0_datahi(arg);
1.1.1.5   root     5477:             rn = "DataHi";
                   5478:             break;
                   5479:         default:
                   5480:             rn = "invalid sel";
                   5481:             goto die;
                   5482:         }
1.1.1.6   root     5483:         break;
1.1.1.5   root     5484:     case 30:
                   5485:         switch (sel) {
                   5486:         case 0:
1.1.1.8   root     5487:             tcg_gen_st_tl(arg, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
1.1.1.6   root     5488:             rn = "ErrorEPC";
                   5489:             break;
1.1.1.5   root     5490:         default:
                   5491:             goto die;
                   5492:         }
                   5493:         break;
                   5494:     case 31:
                   5495:         switch (sel) {
                   5496:         case 0:
1.1.1.7   root     5497:             /* EJTAG support */
1.1.1.8   root     5498:             gen_mtc0_store32(arg, offsetof(CPUState, CP0_DESAVE));
1.1.1.6   root     5499:             rn = "DESAVE";
                   5500:             break;
1.1.1.5   root     5501:         default:
                   5502:             goto die;
                   5503:         }
1.1.1.6   root     5504:         /* Stop translation as we may have switched the execution mode */
                   5505:         ctx->bstate = BS_STOP;
1.1.1.5   root     5506:         break;
                   5507:     default:
1.1.1.6   root     5508:         goto die;
1.1.1.5   root     5509:     }
1.1.1.13  root     5510:     (void)rn; /* avoid a compiler warning */
1.1.1.7   root     5511:     LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
                   5512:     /* For simplicity assume that all writes can cause interrupts.  */
                   5513:     if (use_icount) {
                   5514:         gen_io_end();
                   5515:         ctx->bstate = BS_STOP;
1.1.1.5   root     5516:     }
                   5517:     return;
                   5518: 
                   5519: die:
1.1.1.7   root     5520:     LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
1.1.1.5   root     5521:     generate_exception(ctx, EXCP_RI);
                   5522: }
1.1.1.6   root     5523: #endif /* TARGET_MIPS64 */
1.1.1.5   root     5524: 
1.1.1.7   root     5525: static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
1.1.1.6   root     5526:                      int u, int sel, int h)
1.1.1.5   root     5527: {
1.1.1.6   root     5528:     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1.1.1.7   root     5529:     TCGv t0 = tcg_temp_local_new();
1.1.1.5   root     5530: 
1.1.1.6   root     5531:     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
1.1.1.7   root     5532:         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
                   5533:          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
                   5534:         tcg_gen_movi_tl(t0, -1);
1.1.1.6   root     5535:     else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
                   5536:              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1.1.1.7   root     5537:         tcg_gen_movi_tl(t0, -1);
1.1.1.6   root     5538:     else if (u == 0) {
                   5539:         switch (rt) {
                   5540:         case 2:
                   5541:             switch (sel) {
                   5542:             case 1:
1.1.1.7   root     5543:                 gen_helper_mftc0_tcstatus(t0);
1.1.1.6   root     5544:                 break;
                   5545:             case 2:
1.1.1.7   root     5546:                 gen_helper_mftc0_tcbind(t0);
1.1.1.6   root     5547:                 break;
                   5548:             case 3:
1.1.1.7   root     5549:                 gen_helper_mftc0_tcrestart(t0);
1.1.1.6   root     5550:                 break;
                   5551:             case 4:
1.1.1.7   root     5552:                 gen_helper_mftc0_tchalt(t0);
1.1.1.6   root     5553:                 break;
                   5554:             case 5:
1.1.1.7   root     5555:                 gen_helper_mftc0_tccontext(t0);
1.1.1.6   root     5556:                 break;
                   5557:             case 6:
1.1.1.7   root     5558:                 gen_helper_mftc0_tcschedule(t0);
1.1.1.6   root     5559:                 break;
                   5560:             case 7:
1.1.1.7   root     5561:                 gen_helper_mftc0_tcschefback(t0);
1.1.1.6   root     5562:                 break;
                   5563:             default:
1.1.1.7   root     5564:                 gen_mfc0(env, ctx, t0, rt, sel);
1.1.1.6   root     5565:                 break;
                   5566:             }
                   5567:             break;
                   5568:         case 10:
                   5569:             switch (sel) {
                   5570:             case 0:
1.1.1.7   root     5571:                 gen_helper_mftc0_entryhi(t0);
1.1.1.6   root     5572:                 break;
                   5573:             default:
1.1.1.7   root     5574:                 gen_mfc0(env, ctx, t0, rt, sel);
1.1.1.6   root     5575:                 break;
                   5576:             }
                   5577:         case 12:
                   5578:             switch (sel) {
                   5579:             case 0:
1.1.1.7   root     5580:                 gen_helper_mftc0_status(t0);
1.1.1.6   root     5581:                 break;
                   5582:             default:
1.1.1.7   root     5583:                 gen_mfc0(env, ctx, t0, rt, sel);
1.1.1.6   root     5584:                 break;
                   5585:             }
                   5586:         case 23:
                   5587:             switch (sel) {
                   5588:             case 0:
1.1.1.7   root     5589:                 gen_helper_mftc0_debug(t0);
1.1.1.6   root     5590:                 break;
                   5591:             default:
1.1.1.7   root     5592:                 gen_mfc0(env, ctx, t0, rt, sel);
1.1.1.6   root     5593:                 break;
                   5594:             }
                   5595:             break;
                   5596:         default:
1.1.1.7   root     5597:             gen_mfc0(env, ctx, t0, rt, sel);
1.1.1.6   root     5598:         }
                   5599:     } else switch (sel) {
                   5600:     /* GPR registers. */
                   5601:     case 0:
1.1.1.7   root     5602:         gen_helper_1i(mftgpr, t0, rt);
1.1.1.6   root     5603:         break;
                   5604:     /* Auxiliary CPU registers */
                   5605:     case 1:
                   5606:         switch (rt) {
                   5607:         case 0:
1.1.1.7   root     5608:             gen_helper_1i(mftlo, t0, 0);
1.1.1.6   root     5609:             break;
                   5610:         case 1:
1.1.1.7   root     5611:             gen_helper_1i(mfthi, t0, 0);
1.1.1.6   root     5612:             break;
                   5613:         case 2:
1.1.1.7   root     5614:             gen_helper_1i(mftacx, t0, 0);
1.1.1.6   root     5615:             break;
                   5616:         case 4:
1.1.1.7   root     5617:             gen_helper_1i(mftlo, t0, 1);
1.1.1.6   root     5618:             break;
                   5619:         case 5:
1.1.1.7   root     5620:             gen_helper_1i(mfthi, t0, 1);
1.1.1.6   root     5621:             break;
                   5622:         case 6:
1.1.1.7   root     5623:             gen_helper_1i(mftacx, t0, 1);
1.1.1.6   root     5624:             break;
                   5625:         case 8:
1.1.1.7   root     5626:             gen_helper_1i(mftlo, t0, 2);
1.1.1.6   root     5627:             break;
                   5628:         case 9:
1.1.1.7   root     5629:             gen_helper_1i(mfthi, t0, 2);
1.1.1.6   root     5630:             break;
                   5631:         case 10:
1.1.1.7   root     5632:             gen_helper_1i(mftacx, t0, 2);
1.1.1.6   root     5633:             break;
                   5634:         case 12:
1.1.1.7   root     5635:             gen_helper_1i(mftlo, t0, 3);
1.1.1.6   root     5636:             break;
                   5637:         case 13:
1.1.1.7   root     5638:             gen_helper_1i(mfthi, t0, 3);
1.1.1.6   root     5639:             break;
                   5640:         case 14:
1.1.1.7   root     5641:             gen_helper_1i(mftacx, t0, 3);
1.1.1.6   root     5642:             break;
                   5643:         case 16:
1.1.1.7   root     5644:             gen_helper_mftdsp(t0);
1.1.1.6   root     5645:             break;
                   5646:         default:
                   5647:             goto die;
                   5648:         }
                   5649:         break;
                   5650:     /* Floating point (COP1). */
                   5651:     case 2:
                   5652:         /* XXX: For now we support only a single FPU context. */
                   5653:         if (h == 0) {
1.1.1.7   root     5654:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   5655: 
                   5656:             gen_load_fpr32(fp0, rt);
                   5657:             tcg_gen_ext_i32_tl(t0, fp0);
                   5658:             tcg_temp_free_i32(fp0);
1.1.1.6   root     5659:         } else {
1.1.1.7   root     5660:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   5661: 
                   5662:             gen_load_fpr32h(fp0, rt);
                   5663:             tcg_gen_ext_i32_tl(t0, fp0);
                   5664:             tcg_temp_free_i32(fp0);
1.1.1.6   root     5665:         }
                   5666:         break;
                   5667:     case 3:
                   5668:         /* XXX: For now we support only a single FPU context. */
1.1.1.7   root     5669:         gen_helper_1i(cfc1, t0, rt);
1.1.1.6   root     5670:         break;
                   5671:     /* COP2: Not implemented. */
                   5672:     case 4:
                   5673:     case 5:
                   5674:         /* fall through */
                   5675:     default:
                   5676:         goto die;
                   5677:     }
1.1.1.7   root     5678:     LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
                   5679:     gen_store_gpr(t0, rd);
                   5680:     tcg_temp_free(t0);
1.1.1.6   root     5681:     return;
                   5682: 
                   5683: die:
1.1.1.7   root     5684:     tcg_temp_free(t0);
                   5685:     LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1.1.1.6   root     5686:     generate_exception(ctx, EXCP_RI);
                   5687: }
                   5688: 
1.1.1.7   root     5689: static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
1.1.1.6   root     5690:                      int u, int sel, int h)
                   5691: {
                   5692:     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1.1.1.7   root     5693:     TCGv t0 = tcg_temp_local_new();
1.1.1.6   root     5694: 
1.1.1.7   root     5695:     gen_load_gpr(t0, rt);
1.1.1.6   root     5696:     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
1.1.1.7   root     5697:         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
                   5698:          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1.1.1.6   root     5699:         /* NOP */ ;
                   5700:     else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
                   5701:              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
                   5702:         /* NOP */ ;
                   5703:     else if (u == 0) {
                   5704:         switch (rd) {
                   5705:         case 2:
                   5706:             switch (sel) {
                   5707:             case 1:
1.1.1.7   root     5708:                 gen_helper_mttc0_tcstatus(t0);
1.1.1.6   root     5709:                 break;
                   5710:             case 2:
1.1.1.7   root     5711:                 gen_helper_mttc0_tcbind(t0);
1.1.1.6   root     5712:                 break;
                   5713:             case 3:
1.1.1.7   root     5714:                 gen_helper_mttc0_tcrestart(t0);
1.1.1.6   root     5715:                 break;
                   5716:             case 4:
1.1.1.7   root     5717:                 gen_helper_mttc0_tchalt(t0);
1.1.1.6   root     5718:                 break;
                   5719:             case 5:
1.1.1.7   root     5720:                 gen_helper_mttc0_tccontext(t0);
1.1.1.6   root     5721:                 break;
                   5722:             case 6:
1.1.1.7   root     5723:                 gen_helper_mttc0_tcschedule(t0);
1.1.1.6   root     5724:                 break;
                   5725:             case 7:
1.1.1.7   root     5726:                 gen_helper_mttc0_tcschefback(t0);
1.1.1.6   root     5727:                 break;
                   5728:             default:
1.1.1.7   root     5729:                 gen_mtc0(env, ctx, t0, rd, sel);
1.1.1.6   root     5730:                 break;
                   5731:             }
                   5732:             break;
                   5733:         case 10:
                   5734:             switch (sel) {
                   5735:             case 0:
1.1.1.7   root     5736:                 gen_helper_mttc0_entryhi(t0);
1.1.1.6   root     5737:                 break;
                   5738:             default:
1.1.1.7   root     5739:                 gen_mtc0(env, ctx, t0, rd, sel);
1.1.1.6   root     5740:                 break;
                   5741:             }
                   5742:         case 12:
                   5743:             switch (sel) {
                   5744:             case 0:
1.1.1.7   root     5745:                 gen_helper_mttc0_status(t0);
1.1.1.6   root     5746:                 break;
                   5747:             default:
1.1.1.7   root     5748:                 gen_mtc0(env, ctx, t0, rd, sel);
1.1.1.6   root     5749:                 break;
                   5750:             }
                   5751:         case 23:
                   5752:             switch (sel) {
                   5753:             case 0:
1.1.1.7   root     5754:                 gen_helper_mttc0_debug(t0);
1.1.1.6   root     5755:                 break;
                   5756:             default:
1.1.1.7   root     5757:                 gen_mtc0(env, ctx, t0, rd, sel);
1.1.1.6   root     5758:                 break;
                   5759:             }
                   5760:             break;
                   5761:         default:
1.1.1.7   root     5762:             gen_mtc0(env, ctx, t0, rd, sel);
1.1.1.6   root     5763:         }
                   5764:     } else switch (sel) {
                   5765:     /* GPR registers. */
                   5766:     case 0:
1.1.1.7   root     5767:         gen_helper_1i(mttgpr, t0, rd);
1.1.1.6   root     5768:         break;
                   5769:     /* Auxiliary CPU registers */
                   5770:     case 1:
                   5771:         switch (rd) {
                   5772:         case 0:
1.1.1.7   root     5773:             gen_helper_1i(mttlo, t0, 0);
1.1.1.6   root     5774:             break;
                   5775:         case 1:
1.1.1.7   root     5776:             gen_helper_1i(mtthi, t0, 0);
1.1.1.6   root     5777:             break;
                   5778:         case 2:
1.1.1.7   root     5779:             gen_helper_1i(mttacx, t0, 0);
1.1.1.6   root     5780:             break;
                   5781:         case 4:
1.1.1.7   root     5782:             gen_helper_1i(mttlo, t0, 1);
1.1.1.6   root     5783:             break;
                   5784:         case 5:
1.1.1.7   root     5785:             gen_helper_1i(mtthi, t0, 1);
1.1.1.6   root     5786:             break;
                   5787:         case 6:
1.1.1.7   root     5788:             gen_helper_1i(mttacx, t0, 1);
1.1.1.6   root     5789:             break;
                   5790:         case 8:
1.1.1.7   root     5791:             gen_helper_1i(mttlo, t0, 2);
1.1.1.6   root     5792:             break;
                   5793:         case 9:
1.1.1.7   root     5794:             gen_helper_1i(mtthi, t0, 2);
1.1.1.6   root     5795:             break;
                   5796:         case 10:
1.1.1.7   root     5797:             gen_helper_1i(mttacx, t0, 2);
1.1.1.6   root     5798:             break;
                   5799:         case 12:
1.1.1.7   root     5800:             gen_helper_1i(mttlo, t0, 3);
1.1.1.6   root     5801:             break;
                   5802:         case 13:
1.1.1.7   root     5803:             gen_helper_1i(mtthi, t0, 3);
1.1.1.6   root     5804:             break;
                   5805:         case 14:
1.1.1.7   root     5806:             gen_helper_1i(mttacx, t0, 3);
1.1.1.6   root     5807:             break;
                   5808:         case 16:
1.1.1.7   root     5809:             gen_helper_mttdsp(t0);
1.1.1.6   root     5810:             break;
                   5811:         default:
                   5812:             goto die;
                   5813:         }
                   5814:         break;
                   5815:     /* Floating point (COP1). */
                   5816:     case 2:
                   5817:         /* XXX: For now we support only a single FPU context. */
                   5818:         if (h == 0) {
1.1.1.7   root     5819:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   5820: 
                   5821:             tcg_gen_trunc_tl_i32(fp0, t0);
                   5822:             gen_store_fpr32(fp0, rd);
                   5823:             tcg_temp_free_i32(fp0);
1.1.1.6   root     5824:         } else {
1.1.1.7   root     5825:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   5826: 
                   5827:             tcg_gen_trunc_tl_i32(fp0, t0);
                   5828:             gen_store_fpr32h(fp0, rd);
                   5829:             tcg_temp_free_i32(fp0);
1.1.1.6   root     5830:         }
                   5831:         break;
                   5832:     case 3:
                   5833:         /* XXX: For now we support only a single FPU context. */
1.1.1.7   root     5834:         gen_helper_1i(ctc1, t0, rd);
1.1.1.6   root     5835:         break;
                   5836:     /* COP2: Not implemented. */
                   5837:     case 4:
                   5838:     case 5:
                   5839:         /* fall through */
                   5840:     default:
                   5841:         goto die;
                   5842:     }
1.1.1.7   root     5843:     LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
                   5844:     tcg_temp_free(t0);
1.1.1.6   root     5845:     return;
                   5846: 
                   5847: die:
1.1.1.7   root     5848:     tcg_temp_free(t0);
                   5849:     LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1.1.1.6   root     5850:     generate_exception(ctx, EXCP_RI);
                   5851: }
                   5852: 
                   5853: static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
                   5854: {
                   5855:     const char *opn = "ldst";
1.1.1.5   root     5856: 
                   5857:     switch (opc) {
                   5858:     case OPC_MFC0:
                   5859:         if (rt == 0) {
1.1.1.6   root     5860:             /* Treat as NOP. */
1.1.1.5   root     5861:             return;
                   5862:         }
1.1.1.8   root     5863:         gen_mfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
1.1.1.5   root     5864:         opn = "mfc0";
                   5865:         break;
                   5866:     case OPC_MTC0:
1.1.1.7   root     5867:         {
1.1.1.8   root     5868:             TCGv t0 = tcg_temp_new();
1.1.1.7   root     5869: 
                   5870:             gen_load_gpr(t0, rt);
                   5871:             gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
                   5872:             tcg_temp_free(t0);
                   5873:         }
1.1.1.5   root     5874:         opn = "mtc0";
                   5875:         break;
1.1.1.6   root     5876: #if defined(TARGET_MIPS64)
1.1.1.5   root     5877:     case OPC_DMFC0:
1.1.1.6   root     5878:         check_insn(env, ctx, ISA_MIPS3);
1.1.1.5   root     5879:         if (rt == 0) {
1.1.1.6   root     5880:             /* Treat as NOP. */
1.1.1.5   root     5881:             return;
                   5882:         }
1.1.1.8   root     5883:         gen_dmfc0(env, ctx, cpu_gpr[rt], rd, ctx->opcode & 0x7);
1.1.1.5   root     5884:         opn = "dmfc0";
                   5885:         break;
                   5886:     case OPC_DMTC0:
1.1.1.6   root     5887:         check_insn(env, ctx, ISA_MIPS3);
1.1.1.7   root     5888:         {
1.1.1.8   root     5889:             TCGv t0 = tcg_temp_new();
1.1.1.7   root     5890: 
                   5891:             gen_load_gpr(t0, rt);
                   5892:             gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
                   5893:             tcg_temp_free(t0);
                   5894:         }
1.1.1.5   root     5895:         opn = "dmtc0";
                   5896:         break;
1.1.1.6   root     5897: #endif
                   5898:     case OPC_MFTR:
                   5899:         check_insn(env, ctx, ASE_MT);
                   5900:         if (rd == 0) {
                   5901:             /* Treat as NOP. */
                   5902:             return;
                   5903:         }
1.1.1.7   root     5904:         gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
1.1.1.6   root     5905:                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
                   5906:         opn = "mftr";
                   5907:         break;
                   5908:     case OPC_MTTR:
                   5909:         check_insn(env, ctx, ASE_MT);
1.1.1.7   root     5910:         gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
1.1.1.6   root     5911:                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
                   5912:         opn = "mttr";
                   5913:         break;
1.1.1.5   root     5914:     case OPC_TLBWI:
                   5915:         opn = "tlbwi";
1.1.1.8   root     5916:         if (!env->tlb->helper_tlbwi)
1.1.1.6   root     5917:             goto die;
1.1.1.7   root     5918:         gen_helper_tlbwi();
1.1.1.5   root     5919:         break;
                   5920:     case OPC_TLBWR:
                   5921:         opn = "tlbwr";
1.1.1.8   root     5922:         if (!env->tlb->helper_tlbwr)
1.1.1.6   root     5923:             goto die;
1.1.1.7   root     5924:         gen_helper_tlbwr();
1.1.1.5   root     5925:         break;
                   5926:     case OPC_TLBP:
                   5927:         opn = "tlbp";
1.1.1.8   root     5928:         if (!env->tlb->helper_tlbp)
1.1.1.6   root     5929:             goto die;
1.1.1.7   root     5930:         gen_helper_tlbp();
1.1.1.5   root     5931:         break;
                   5932:     case OPC_TLBR:
                   5933:         opn = "tlbr";
1.1.1.8   root     5934:         if (!env->tlb->helper_tlbr)
1.1.1.6   root     5935:             goto die;
1.1.1.7   root     5936:         gen_helper_tlbr();
1.1.1.5   root     5937:         break;
                   5938:     case OPC_ERET:
                   5939:         opn = "eret";
1.1.1.6   root     5940:         check_insn(env, ctx, ISA_MIPS2);
1.1.1.7   root     5941:         gen_helper_eret();
1.1.1.5   root     5942:         ctx->bstate = BS_EXCP;
                   5943:         break;
                   5944:     case OPC_DERET:
                   5945:         opn = "deret";
1.1.1.6   root     5946:         check_insn(env, ctx, ISA_MIPS32);
1.1.1.5   root     5947:         if (!(ctx->hflags & MIPS_HFLAG_DM)) {
1.1.1.6   root     5948:             MIPS_INVAL(opn);
1.1.1.5   root     5949:             generate_exception(ctx, EXCP_RI);
                   5950:         } else {
1.1.1.7   root     5951:             gen_helper_deret();
1.1.1.5   root     5952:             ctx->bstate = BS_EXCP;
                   5953:         }
                   5954:         break;
                   5955:     case OPC_WAIT:
                   5956:         opn = "wait";
1.1.1.6   root     5957:         check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
1.1.1.5   root     5958:         /* If we get an exception, we want to restart at next instruction */
                   5959:         ctx->pc += 4;
                   5960:         save_cpu_state(ctx, 1);
                   5961:         ctx->pc -= 4;
1.1.1.7   root     5962:         gen_helper_wait();
1.1.1.5   root     5963:         ctx->bstate = BS_EXCP;
                   5964:         break;
                   5965:     default:
1.1.1.6   root     5966:  die:
                   5967:         MIPS_INVAL(opn);
1.1.1.5   root     5968:         generate_exception(ctx, EXCP_RI);
                   5969:         return;
                   5970:     }
1.1.1.13  root     5971:     (void)opn; /* avoid a compiler warning */
1.1.1.5   root     5972:     MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
                   5973: }
1.1.1.7   root     5974: #endif /* !CONFIG_USER_ONLY */
1.1.1.5   root     5975: 
                   5976: /* CP1 Branches (before delay slot) */
1.1.1.6   root     5977: static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
                   5978:                                  int32_t cc, int32_t offset)
1.1.1.5   root     5979: {
                   5980:     target_ulong btarget;
1.1.1.6   root     5981:     const char *opn = "cp1 cond branch";
1.1.1.7   root     5982:     TCGv_i32 t0 = tcg_temp_new_i32();
1.1.1.6   root     5983: 
                   5984:     if (cc != 0)
                   5985:         check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
1.1.1.5   root     5986: 
                   5987:     btarget = ctx->pc + 4 + offset;
                   5988: 
                   5989:     switch (op) {
                   5990:     case OPC_BC1F:
1.1.1.8   root     5991:         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   5992:         tcg_gen_not_i32(t0, t0);
                   5993:         tcg_gen_andi_i32(t0, t0, 1);
                   5994:         tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.6   root     5995:         opn = "bc1f";
1.1.1.5   root     5996:         goto not_likely;
                   5997:     case OPC_BC1FL:
1.1.1.8   root     5998:         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   5999:         tcg_gen_not_i32(t0, t0);
                   6000:         tcg_gen_andi_i32(t0, t0, 1);
                   6001:         tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.6   root     6002:         opn = "bc1fl";
1.1.1.5   root     6003:         goto likely;
                   6004:     case OPC_BC1T:
1.1.1.8   root     6005:         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   6006:         tcg_gen_andi_i32(t0, t0, 1);
                   6007:         tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.6   root     6008:         opn = "bc1t";
                   6009:         goto not_likely;
1.1.1.5   root     6010:     case OPC_BC1TL:
1.1.1.8   root     6011:         tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   6012:         tcg_gen_andi_i32(t0, t0, 1);
                   6013:         tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.6   root     6014:         opn = "bc1tl";
1.1.1.5   root     6015:     likely:
                   6016:         ctx->hflags |= MIPS_HFLAG_BL;
1.1.1.6   root     6017:         break;
                   6018:     case OPC_BC1FANY2:
1.1.1.7   root     6019:         {
1.1.1.8   root     6020:             TCGv_i32 t1 = tcg_temp_new_i32();
                   6021:             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   6022:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
1.1.1.12  root     6023:             tcg_gen_nor_i32(t0, t0, t1);
1.1.1.8   root     6024:             tcg_temp_free_i32(t1);
                   6025:             tcg_gen_andi_i32(t0, t0, 1);
                   6026:             tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.7   root     6027:         }
1.1.1.6   root     6028:         opn = "bc1any2f";
                   6029:         goto not_likely;
                   6030:     case OPC_BC1TANY2:
1.1.1.7   root     6031:         {
1.1.1.8   root     6032:             TCGv_i32 t1 = tcg_temp_new_i32();
                   6033:             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   6034:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
                   6035:             tcg_gen_or_i32(t0, t0, t1);
                   6036:             tcg_temp_free_i32(t1);
                   6037:             tcg_gen_andi_i32(t0, t0, 1);
                   6038:             tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.7   root     6039:         }
1.1.1.6   root     6040:         opn = "bc1any2t";
                   6041:         goto not_likely;
                   6042:     case OPC_BC1FANY4:
1.1.1.7   root     6043:         {
1.1.1.8   root     6044:             TCGv_i32 t1 = tcg_temp_new_i32();
                   6045:             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   6046:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
                   6047:             tcg_gen_or_i32(t0, t0, t1);
                   6048:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
                   6049:             tcg_gen_or_i32(t0, t0, t1);
                   6050:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
1.1.1.12  root     6051:             tcg_gen_nor_i32(t0, t0, t1);
1.1.1.8   root     6052:             tcg_temp_free_i32(t1);
                   6053:             tcg_gen_andi_i32(t0, t0, 1);
                   6054:             tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.7   root     6055:         }
1.1.1.6   root     6056:         opn = "bc1any4f";
                   6057:         goto not_likely;
                   6058:     case OPC_BC1TANY4:
1.1.1.7   root     6059:         {
1.1.1.8   root     6060:             TCGv_i32 t1 = tcg_temp_new_i32();
                   6061:             tcg_gen_shri_i32(t0, fpu_fcr31, get_fp_bit(cc));
                   6062:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+1));
                   6063:             tcg_gen_or_i32(t0, t0, t1);
                   6064:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+2));
                   6065:             tcg_gen_or_i32(t0, t0, t1);
                   6066:             tcg_gen_shri_i32(t1, fpu_fcr31, get_fp_bit(cc+3));
                   6067:             tcg_gen_or_i32(t0, t0, t1);
                   6068:             tcg_temp_free_i32(t1);
                   6069:             tcg_gen_andi_i32(t0, t0, 1);
                   6070:             tcg_gen_extu_i32_tl(bcond, t0);
1.1.1.7   root     6071:         }
1.1.1.6   root     6072:         opn = "bc1any4t";
                   6073:     not_likely:
                   6074:         ctx->hflags |= MIPS_HFLAG_BC;
1.1.1.5   root     6075:         break;
1.1.1.6   root     6076:     default:
                   6077:         MIPS_INVAL(opn);
                   6078:         generate_exception (ctx, EXCP_RI);
1.1.1.7   root     6079:         goto out;
1.1.1.5   root     6080:     }
1.1.1.13  root     6081:     (void)opn; /* avoid a compiler warning */
1.1.1.6   root     6082:     MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
1.1.1.5   root     6083:                ctx->hflags, btarget);
                   6084:     ctx->btarget = btarget;
1.1.1.7   root     6085: 
                   6086:  out:
                   6087:     tcg_temp_free_i32(t0);
1.1.1.5   root     6088: }
                   6089: 
                   6090: /* Coprocessor 1 (FPU) */
1.1.1.6   root     6091: 
                   6092: #define FOP(func, fmt) (((fmt) << 21) | (func))
                   6093: 
1.1.1.12  root     6094: enum fopcode {
                   6095:     OPC_ADD_S = FOP(0, FMT_S),
                   6096:     OPC_SUB_S = FOP(1, FMT_S),
                   6097:     OPC_MUL_S = FOP(2, FMT_S),
                   6098:     OPC_DIV_S = FOP(3, FMT_S),
                   6099:     OPC_SQRT_S = FOP(4, FMT_S),
                   6100:     OPC_ABS_S = FOP(5, FMT_S),
                   6101:     OPC_MOV_S = FOP(6, FMT_S),
                   6102:     OPC_NEG_S = FOP(7, FMT_S),
                   6103:     OPC_ROUND_L_S = FOP(8, FMT_S),
                   6104:     OPC_TRUNC_L_S = FOP(9, FMT_S),
                   6105:     OPC_CEIL_L_S = FOP(10, FMT_S),
                   6106:     OPC_FLOOR_L_S = FOP(11, FMT_S),
                   6107:     OPC_ROUND_W_S = FOP(12, FMT_S),
                   6108:     OPC_TRUNC_W_S = FOP(13, FMT_S),
                   6109:     OPC_CEIL_W_S = FOP(14, FMT_S),
                   6110:     OPC_FLOOR_W_S = FOP(15, FMT_S),
                   6111:     OPC_MOVCF_S = FOP(17, FMT_S),
                   6112:     OPC_MOVZ_S = FOP(18, FMT_S),
                   6113:     OPC_MOVN_S = FOP(19, FMT_S),
                   6114:     OPC_RECIP_S = FOP(21, FMT_S),
                   6115:     OPC_RSQRT_S = FOP(22, FMT_S),
                   6116:     OPC_RECIP2_S = FOP(28, FMT_S),
                   6117:     OPC_RECIP1_S = FOP(29, FMT_S),
                   6118:     OPC_RSQRT1_S = FOP(30, FMT_S),
                   6119:     OPC_RSQRT2_S = FOP(31, FMT_S),
                   6120:     OPC_CVT_D_S = FOP(33, FMT_S),
                   6121:     OPC_CVT_W_S = FOP(36, FMT_S),
                   6122:     OPC_CVT_L_S = FOP(37, FMT_S),
                   6123:     OPC_CVT_PS_S = FOP(38, FMT_S),
                   6124:     OPC_CMP_F_S = FOP (48, FMT_S),
                   6125:     OPC_CMP_UN_S = FOP (49, FMT_S),
                   6126:     OPC_CMP_EQ_S = FOP (50, FMT_S),
                   6127:     OPC_CMP_UEQ_S = FOP (51, FMT_S),
                   6128:     OPC_CMP_OLT_S = FOP (52, FMT_S),
                   6129:     OPC_CMP_ULT_S = FOP (53, FMT_S),
                   6130:     OPC_CMP_OLE_S = FOP (54, FMT_S),
                   6131:     OPC_CMP_ULE_S = FOP (55, FMT_S),
                   6132:     OPC_CMP_SF_S = FOP (56, FMT_S),
                   6133:     OPC_CMP_NGLE_S = FOP (57, FMT_S),
                   6134:     OPC_CMP_SEQ_S = FOP (58, FMT_S),
                   6135:     OPC_CMP_NGL_S = FOP (59, FMT_S),
                   6136:     OPC_CMP_LT_S = FOP (60, FMT_S),
                   6137:     OPC_CMP_NGE_S = FOP (61, FMT_S),
                   6138:     OPC_CMP_LE_S = FOP (62, FMT_S),
                   6139:     OPC_CMP_NGT_S = FOP (63, FMT_S),
                   6140: 
                   6141:     OPC_ADD_D = FOP(0, FMT_D),
                   6142:     OPC_SUB_D = FOP(1, FMT_D),
                   6143:     OPC_MUL_D = FOP(2, FMT_D),
                   6144:     OPC_DIV_D = FOP(3, FMT_D),
                   6145:     OPC_SQRT_D = FOP(4, FMT_D),
                   6146:     OPC_ABS_D = FOP(5, FMT_D),
                   6147:     OPC_MOV_D = FOP(6, FMT_D),
                   6148:     OPC_NEG_D = FOP(7, FMT_D),
                   6149:     OPC_ROUND_L_D = FOP(8, FMT_D),
                   6150:     OPC_TRUNC_L_D = FOP(9, FMT_D),
                   6151:     OPC_CEIL_L_D = FOP(10, FMT_D),
                   6152:     OPC_FLOOR_L_D = FOP(11, FMT_D),
                   6153:     OPC_ROUND_W_D = FOP(12, FMT_D),
                   6154:     OPC_TRUNC_W_D = FOP(13, FMT_D),
                   6155:     OPC_CEIL_W_D = FOP(14, FMT_D),
                   6156:     OPC_FLOOR_W_D = FOP(15, FMT_D),
                   6157:     OPC_MOVCF_D = FOP(17, FMT_D),
                   6158:     OPC_MOVZ_D = FOP(18, FMT_D),
                   6159:     OPC_MOVN_D = FOP(19, FMT_D),
                   6160:     OPC_RECIP_D = FOP(21, FMT_D),
                   6161:     OPC_RSQRT_D = FOP(22, FMT_D),
                   6162:     OPC_RECIP2_D = FOP(28, FMT_D),
                   6163:     OPC_RECIP1_D = FOP(29, FMT_D),
                   6164:     OPC_RSQRT1_D = FOP(30, FMT_D),
                   6165:     OPC_RSQRT2_D = FOP(31, FMT_D),
                   6166:     OPC_CVT_S_D = FOP(32, FMT_D),
                   6167:     OPC_CVT_W_D = FOP(36, FMT_D),
                   6168:     OPC_CVT_L_D = FOP(37, FMT_D),
                   6169:     OPC_CMP_F_D = FOP (48, FMT_D),
                   6170:     OPC_CMP_UN_D = FOP (49, FMT_D),
                   6171:     OPC_CMP_EQ_D = FOP (50, FMT_D),
                   6172:     OPC_CMP_UEQ_D = FOP (51, FMT_D),
                   6173:     OPC_CMP_OLT_D = FOP (52, FMT_D),
                   6174:     OPC_CMP_ULT_D = FOP (53, FMT_D),
                   6175:     OPC_CMP_OLE_D = FOP (54, FMT_D),
                   6176:     OPC_CMP_ULE_D = FOP (55, FMT_D),
                   6177:     OPC_CMP_SF_D = FOP (56, FMT_D),
                   6178:     OPC_CMP_NGLE_D = FOP (57, FMT_D),
                   6179:     OPC_CMP_SEQ_D = FOP (58, FMT_D),
                   6180:     OPC_CMP_NGL_D = FOP (59, FMT_D),
                   6181:     OPC_CMP_LT_D = FOP (60, FMT_D),
                   6182:     OPC_CMP_NGE_D = FOP (61, FMT_D),
                   6183:     OPC_CMP_LE_D = FOP (62, FMT_D),
                   6184:     OPC_CMP_NGT_D = FOP (63, FMT_D),
                   6185: 
                   6186:     OPC_CVT_S_W = FOP(32, FMT_W),
                   6187:     OPC_CVT_D_W = FOP(33, FMT_W),
                   6188:     OPC_CVT_S_L = FOP(32, FMT_L),
                   6189:     OPC_CVT_D_L = FOP(33, FMT_L),
                   6190:     OPC_CVT_PS_PW = FOP(38, FMT_W),
                   6191: 
                   6192:     OPC_ADD_PS = FOP(0, FMT_PS),
                   6193:     OPC_SUB_PS = FOP(1, FMT_PS),
                   6194:     OPC_MUL_PS = FOP(2, FMT_PS),
                   6195:     OPC_DIV_PS = FOP(3, FMT_PS),
                   6196:     OPC_ABS_PS = FOP(5, FMT_PS),
                   6197:     OPC_MOV_PS = FOP(6, FMT_PS),
                   6198:     OPC_NEG_PS = FOP(7, FMT_PS),
                   6199:     OPC_MOVCF_PS = FOP(17, FMT_PS),
                   6200:     OPC_MOVZ_PS = FOP(18, FMT_PS),
                   6201:     OPC_MOVN_PS = FOP(19, FMT_PS),
                   6202:     OPC_ADDR_PS = FOP(24, FMT_PS),
                   6203:     OPC_MULR_PS = FOP(26, FMT_PS),
                   6204:     OPC_RECIP2_PS = FOP(28, FMT_PS),
                   6205:     OPC_RECIP1_PS = FOP(29, FMT_PS),
                   6206:     OPC_RSQRT1_PS = FOP(30, FMT_PS),
                   6207:     OPC_RSQRT2_PS = FOP(31, FMT_PS),
                   6208: 
                   6209:     OPC_CVT_S_PU = FOP(32, FMT_PS),
                   6210:     OPC_CVT_PW_PS = FOP(36, FMT_PS),
                   6211:     OPC_CVT_S_PL = FOP(40, FMT_PS),
                   6212:     OPC_PLL_PS = FOP(44, FMT_PS),
                   6213:     OPC_PLU_PS = FOP(45, FMT_PS),
                   6214:     OPC_PUL_PS = FOP(46, FMT_PS),
                   6215:     OPC_PUU_PS = FOP(47, FMT_PS),
                   6216:     OPC_CMP_F_PS = FOP (48, FMT_PS),
                   6217:     OPC_CMP_UN_PS = FOP (49, FMT_PS),
                   6218:     OPC_CMP_EQ_PS = FOP (50, FMT_PS),
                   6219:     OPC_CMP_UEQ_PS = FOP (51, FMT_PS),
                   6220:     OPC_CMP_OLT_PS = FOP (52, FMT_PS),
                   6221:     OPC_CMP_ULT_PS = FOP (53, FMT_PS),
                   6222:     OPC_CMP_OLE_PS = FOP (54, FMT_PS),
                   6223:     OPC_CMP_ULE_PS = FOP (55, FMT_PS),
                   6224:     OPC_CMP_SF_PS = FOP (56, FMT_PS),
                   6225:     OPC_CMP_NGLE_PS = FOP (57, FMT_PS),
                   6226:     OPC_CMP_SEQ_PS = FOP (58, FMT_PS),
                   6227:     OPC_CMP_NGL_PS = FOP (59, FMT_PS),
                   6228:     OPC_CMP_LT_PS = FOP (60, FMT_PS),
                   6229:     OPC_CMP_NGE_PS = FOP (61, FMT_PS),
                   6230:     OPC_CMP_LE_PS = FOP (62, FMT_PS),
                   6231:     OPC_CMP_NGT_PS = FOP (63, FMT_PS),
                   6232: };
                   6233: 
1.1.1.5   root     6234: static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
                   6235: {
1.1.1.6   root     6236:     const char *opn = "cp1 move";
1.1.1.8   root     6237:     TCGv t0 = tcg_temp_new();
1.1.1.5   root     6238: 
                   6239:     switch (opc) {
                   6240:     case OPC_MFC1:
1.1.1.7   root     6241:         {
                   6242:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6243: 
                   6244:             gen_load_fpr32(fp0, fs);
                   6245:             tcg_gen_ext_i32_tl(t0, fp0);
                   6246:             tcg_temp_free_i32(fp0);
                   6247:         }
                   6248:         gen_store_gpr(t0, rt);
1.1.1.5   root     6249:         opn = "mfc1";
                   6250:         break;
                   6251:     case OPC_MTC1:
1.1.1.7   root     6252:         gen_load_gpr(t0, rt);
                   6253:         {
                   6254:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6255: 
                   6256:             tcg_gen_trunc_tl_i32(fp0, t0);
                   6257:             gen_store_fpr32(fp0, fs);
                   6258:             tcg_temp_free_i32(fp0);
                   6259:         }
1.1.1.5   root     6260:         opn = "mtc1";
                   6261:         break;
                   6262:     case OPC_CFC1:
1.1.1.7   root     6263:         gen_helper_1i(cfc1, t0, fs);
                   6264:         gen_store_gpr(t0, rt);
1.1.1.5   root     6265:         opn = "cfc1";
                   6266:         break;
                   6267:     case OPC_CTC1:
1.1.1.7   root     6268:         gen_load_gpr(t0, rt);
                   6269:         gen_helper_1i(ctc1, t0, fs);
1.1.1.5   root     6270:         opn = "ctc1";
                   6271:         break;
1.1.1.8   root     6272: #if defined(TARGET_MIPS64)
1.1.1.5   root     6273:     case OPC_DMFC1:
1.1.1.8   root     6274:         gen_load_fpr64(ctx, t0, fs);
1.1.1.7   root     6275:         gen_store_gpr(t0, rt);
1.1.1.6   root     6276:         opn = "dmfc1";
                   6277:         break;
1.1.1.5   root     6278:     case OPC_DMTC1:
1.1.1.7   root     6279:         gen_load_gpr(t0, rt);
1.1.1.8   root     6280:         gen_store_fpr64(ctx, t0, fs);
1.1.1.6   root     6281:         opn = "dmtc1";
                   6282:         break;
1.1.1.8   root     6283: #endif
1.1.1.6   root     6284:     case OPC_MFHC1:
1.1.1.7   root     6285:         {
                   6286:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6287: 
                   6288:             gen_load_fpr32h(fp0, fs);
                   6289:             tcg_gen_ext_i32_tl(t0, fp0);
                   6290:             tcg_temp_free_i32(fp0);
                   6291:         }
                   6292:         gen_store_gpr(t0, rt);
1.1.1.6   root     6293:         opn = "mfhc1";
                   6294:         break;
                   6295:     case OPC_MTHC1:
1.1.1.7   root     6296:         gen_load_gpr(t0, rt);
                   6297:         {
                   6298:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6299: 
                   6300:             tcg_gen_trunc_tl_i32(fp0, t0);
                   6301:             gen_store_fpr32h(fp0, fs);
                   6302:             tcg_temp_free_i32(fp0);
                   6303:         }
1.1.1.6   root     6304:         opn = "mthc1";
                   6305:         break;
1.1.1.5   root     6306:     default:
1.1.1.6   root     6307:         MIPS_INVAL(opn);
                   6308:         generate_exception (ctx, EXCP_RI);
1.1.1.7   root     6309:         goto out;
1.1.1.4   root     6310:     }
1.1.1.13  root     6311:     (void)opn; /* avoid a compiler warning */
1.1.1.4   root     6312:     MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
1.1.1.7   root     6313: 
                   6314:  out:
                   6315:     tcg_temp_free(t0);
1.1.1.4   root     6316: }
                   6317: 
1.1.1.6   root     6318: static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
                   6319: {
1.1.1.8   root     6320:     int l1;
1.1.1.7   root     6321:     TCGCond cond;
1.1.1.8   root     6322:     TCGv_i32 t0;
                   6323: 
                   6324:     if (rd == 0) {
                   6325:         /* Treat as NOP. */
                   6326:         return;
                   6327:     }
1.1.1.7   root     6328: 
                   6329:     if (tf)
                   6330:         cond = TCG_COND_EQ;
                   6331:     else
                   6332:         cond = TCG_COND_NE;
                   6333: 
1.1.1.8   root     6334:     l1 = gen_new_label();
                   6335:     t0 = tcg_temp_new_i32();
                   6336:     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
                   6337:     tcg_gen_brcondi_i32(cond, t0, 0, l1);
                   6338:     tcg_temp_free_i32(t0);
                   6339:     if (rs == 0) {
                   6340:         tcg_gen_movi_tl(cpu_gpr[rd], 0);
                   6341:     } else {
                   6342:         tcg_gen_mov_tl(cpu_gpr[rd], cpu_gpr[rs]);
                   6343:     }
1.1.1.7   root     6344:     gen_set_label(l1);
                   6345: }
                   6346: 
                   6347: static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
                   6348: {
                   6349:     int cond;
1.1.1.8   root     6350:     TCGv_i32 t0 = tcg_temp_new_i32();
1.1.1.7   root     6351:     int l1 = gen_new_label();
                   6352: 
                   6353:     if (tf)
                   6354:         cond = TCG_COND_EQ;
                   6355:     else
                   6356:         cond = TCG_COND_NE;
                   6357: 
1.1.1.8   root     6358:     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
                   6359:     tcg_gen_brcondi_i32(cond, t0, 0, l1);
                   6360:     gen_load_fpr32(t0, fs);
                   6361:     gen_store_fpr32(t0, fd);
1.1.1.7   root     6362:     gen_set_label(l1);
1.1.1.8   root     6363:     tcg_temp_free_i32(t0);
1.1.1.7   root     6364: }
                   6365: 
                   6366: static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
                   6367: {
                   6368:     int cond;
1.1.1.8   root     6369:     TCGv_i32 t0 = tcg_temp_new_i32();
                   6370:     TCGv_i64 fp0;
1.1.1.7   root     6371:     int l1 = gen_new_label();
                   6372: 
                   6373:     if (tf)
                   6374:         cond = TCG_COND_EQ;
                   6375:     else
                   6376:         cond = TCG_COND_NE;
                   6377: 
1.1.1.8   root     6378:     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
                   6379:     tcg_gen_brcondi_i32(cond, t0, 0, l1);
                   6380:     tcg_temp_free_i32(t0);
                   6381:     fp0 = tcg_temp_new_i64();
1.1.1.7   root     6382:     gen_load_fpr64(ctx, fp0, fs);
                   6383:     gen_store_fpr64(ctx, fp0, fd);
                   6384:     tcg_temp_free_i64(fp0);
1.1.1.8   root     6385:     gen_set_label(l1);
1.1.1.7   root     6386: }
                   6387: 
                   6388: static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
                   6389: {
                   6390:     int cond;
1.1.1.8   root     6391:     TCGv_i32 t0 = tcg_temp_new_i32();
1.1.1.7   root     6392:     int l1 = gen_new_label();
                   6393:     int l2 = gen_new_label();
1.1.1.4   root     6394: 
1.1.1.7   root     6395:     if (tf)
                   6396:         cond = TCG_COND_EQ;
1.1.1.6   root     6397:     else
1.1.1.7   root     6398:         cond = TCG_COND_NE;
                   6399: 
1.1.1.8   root     6400:     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc));
                   6401:     tcg_gen_brcondi_i32(cond, t0, 0, l1);
                   6402:     gen_load_fpr32(t0, fs);
                   6403:     gen_store_fpr32(t0, fd);
1.1.1.7   root     6404:     gen_set_label(l1);
                   6405: 
1.1.1.8   root     6406:     tcg_gen_andi_i32(t0, fpu_fcr31, 1 << get_fp_bit(cc+1));
                   6407:     tcg_gen_brcondi_i32(cond, t0, 0, l2);
                   6408:     gen_load_fpr32h(t0, fs);
                   6409:     gen_store_fpr32h(t0, fd);
                   6410:     tcg_temp_free_i32(t0);
1.1.1.7   root     6411:     gen_set_label(l2);
1.1.1.6   root     6412: }
                   6413: 
1.1.1.4   root     6414: 
1.1.1.12  root     6415: static void gen_farith (DisasContext *ctx, enum fopcode op1,
1.1.1.6   root     6416:                         int ft, int fs, int fd, int cc)
1.1.1.4   root     6417: {
1.1.1.6   root     6418:     const char *opn = "farith";
1.1.1.4   root     6419:     const char *condnames[] = {
                   6420:             "c.f",
                   6421:             "c.un",
                   6422:             "c.eq",
                   6423:             "c.ueq",
                   6424:             "c.olt",
                   6425:             "c.ult",
                   6426:             "c.ole",
                   6427:             "c.ule",
                   6428:             "c.sf",
                   6429:             "c.ngle",
                   6430:             "c.seq",
                   6431:             "c.ngl",
                   6432:             "c.lt",
                   6433:             "c.nge",
                   6434:             "c.le",
                   6435:             "c.ngt",
                   6436:     };
1.1.1.6   root     6437:     const char *condnames_abs[] = {
                   6438:             "cabs.f",
                   6439:             "cabs.un",
                   6440:             "cabs.eq",
                   6441:             "cabs.ueq",
                   6442:             "cabs.olt",
                   6443:             "cabs.ult",
                   6444:             "cabs.ole",
                   6445:             "cabs.ule",
                   6446:             "cabs.sf",
                   6447:             "cabs.ngle",
                   6448:             "cabs.seq",
                   6449:             "cabs.ngl",
                   6450:             "cabs.lt",
                   6451:             "cabs.nge",
                   6452:             "cabs.le",
                   6453:             "cabs.ngt",
                   6454:     };
                   6455:     enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
1.1.1.5   root     6456:     uint32_t func = ctx->opcode & 0x3f;
                   6457: 
1.1.1.12  root     6458:     switch (op1) {
                   6459:     case OPC_ADD_S:
1.1.1.7   root     6460:         {
                   6461:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6462:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   6463: 
                   6464:             gen_load_fpr32(fp0, fs);
                   6465:             gen_load_fpr32(fp1, ft);
                   6466:             gen_helper_float_add_s(fp0, fp0, fp1);
                   6467:             tcg_temp_free_i32(fp1);
                   6468:             gen_store_fpr32(fp0, fd);
                   6469:             tcg_temp_free_i32(fp0);
                   6470:         }
1.1.1.6   root     6471:         opn = "add.s";
                   6472:         optype = BINOP;
                   6473:         break;
1.1.1.12  root     6474:     case OPC_SUB_S:
1.1.1.7   root     6475:         {
                   6476:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6477:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   6478: 
                   6479:             gen_load_fpr32(fp0, fs);
                   6480:             gen_load_fpr32(fp1, ft);
                   6481:             gen_helper_float_sub_s(fp0, fp0, fp1);
                   6482:             tcg_temp_free_i32(fp1);
                   6483:             gen_store_fpr32(fp0, fd);
                   6484:             tcg_temp_free_i32(fp0);
                   6485:         }
1.1.1.6   root     6486:         opn = "sub.s";
                   6487:         optype = BINOP;
                   6488:         break;
1.1.1.12  root     6489:     case OPC_MUL_S:
1.1.1.7   root     6490:         {
                   6491:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6492:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   6493: 
                   6494:             gen_load_fpr32(fp0, fs);
                   6495:             gen_load_fpr32(fp1, ft);
                   6496:             gen_helper_float_mul_s(fp0, fp0, fp1);
                   6497:             tcg_temp_free_i32(fp1);
                   6498:             gen_store_fpr32(fp0, fd);
                   6499:             tcg_temp_free_i32(fp0);
                   6500:         }
1.1.1.6   root     6501:         opn = "mul.s";
                   6502:         optype = BINOP;
                   6503:         break;
1.1.1.12  root     6504:     case OPC_DIV_S:
1.1.1.7   root     6505:         {
                   6506:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6507:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   6508: 
                   6509:             gen_load_fpr32(fp0, fs);
                   6510:             gen_load_fpr32(fp1, ft);
                   6511:             gen_helper_float_div_s(fp0, fp0, fp1);
                   6512:             tcg_temp_free_i32(fp1);
                   6513:             gen_store_fpr32(fp0, fd);
                   6514:             tcg_temp_free_i32(fp0);
                   6515:         }
1.1.1.6   root     6516:         opn = "div.s";
                   6517:         optype = BINOP;
                   6518:         break;
1.1.1.12  root     6519:     case OPC_SQRT_S:
1.1.1.7   root     6520:         {
                   6521:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6522: 
                   6523:             gen_load_fpr32(fp0, fs);
                   6524:             gen_helper_float_sqrt_s(fp0, fp0);
                   6525:             gen_store_fpr32(fp0, fd);
                   6526:             tcg_temp_free_i32(fp0);
                   6527:         }
1.1.1.6   root     6528:         opn = "sqrt.s";
                   6529:         break;
1.1.1.12  root     6530:     case OPC_ABS_S:
1.1.1.7   root     6531:         {
                   6532:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6533: 
                   6534:             gen_load_fpr32(fp0, fs);
                   6535:             gen_helper_float_abs_s(fp0, fp0);
                   6536:             gen_store_fpr32(fp0, fd);
                   6537:             tcg_temp_free_i32(fp0);
                   6538:         }
1.1.1.6   root     6539:         opn = "abs.s";
                   6540:         break;
1.1.1.12  root     6541:     case OPC_MOV_S:
1.1.1.7   root     6542:         {
                   6543:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6544: 
                   6545:             gen_load_fpr32(fp0, fs);
                   6546:             gen_store_fpr32(fp0, fd);
                   6547:             tcg_temp_free_i32(fp0);
                   6548:         }
1.1.1.6   root     6549:         opn = "mov.s";
                   6550:         break;
1.1.1.12  root     6551:     case OPC_NEG_S:
1.1.1.7   root     6552:         {
                   6553:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6554: 
                   6555:             gen_load_fpr32(fp0, fs);
                   6556:             gen_helper_float_chs_s(fp0, fp0);
                   6557:             gen_store_fpr32(fp0, fd);
                   6558:             tcg_temp_free_i32(fp0);
                   6559:         }
1.1.1.6   root     6560:         opn = "neg.s";
                   6561:         break;
1.1.1.12  root     6562:     case OPC_ROUND_L_S:
1.1.1.6   root     6563:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6564:         {
                   6565:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   6566:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   6567: 
                   6568:             gen_load_fpr32(fp32, fs);
                   6569:             gen_helper_float_roundl_s(fp64, fp32);
                   6570:             tcg_temp_free_i32(fp32);
                   6571:             gen_store_fpr64(ctx, fp64, fd);
                   6572:             tcg_temp_free_i64(fp64);
                   6573:         }
1.1.1.6   root     6574:         opn = "round.l.s";
                   6575:         break;
1.1.1.12  root     6576:     case OPC_TRUNC_L_S:
1.1.1.6   root     6577:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6578:         {
                   6579:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   6580:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   6581: 
                   6582:             gen_load_fpr32(fp32, fs);
                   6583:             gen_helper_float_truncl_s(fp64, fp32);
                   6584:             tcg_temp_free_i32(fp32);
                   6585:             gen_store_fpr64(ctx, fp64, fd);
                   6586:             tcg_temp_free_i64(fp64);
                   6587:         }
1.1.1.6   root     6588:         opn = "trunc.l.s";
                   6589:         break;
1.1.1.12  root     6590:     case OPC_CEIL_L_S:
1.1.1.6   root     6591:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6592:         {
                   6593:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   6594:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   6595: 
                   6596:             gen_load_fpr32(fp32, fs);
                   6597:             gen_helper_float_ceill_s(fp64, fp32);
                   6598:             tcg_temp_free_i32(fp32);
                   6599:             gen_store_fpr64(ctx, fp64, fd);
                   6600:             tcg_temp_free_i64(fp64);
                   6601:         }
1.1.1.6   root     6602:         opn = "ceil.l.s";
                   6603:         break;
1.1.1.12  root     6604:     case OPC_FLOOR_L_S:
1.1.1.6   root     6605:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6606:         {
                   6607:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   6608:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   6609: 
                   6610:             gen_load_fpr32(fp32, fs);
                   6611:             gen_helper_float_floorl_s(fp64, fp32);
                   6612:             tcg_temp_free_i32(fp32);
                   6613:             gen_store_fpr64(ctx, fp64, fd);
                   6614:             tcg_temp_free_i64(fp64);
                   6615:         }
1.1.1.6   root     6616:         opn = "floor.l.s";
                   6617:         break;
1.1.1.12  root     6618:     case OPC_ROUND_W_S:
1.1.1.7   root     6619:         {
                   6620:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6621: 
                   6622:             gen_load_fpr32(fp0, fs);
                   6623:             gen_helper_float_roundw_s(fp0, fp0);
                   6624:             gen_store_fpr32(fp0, fd);
                   6625:             tcg_temp_free_i32(fp0);
                   6626:         }
1.1.1.6   root     6627:         opn = "round.w.s";
                   6628:         break;
1.1.1.12  root     6629:     case OPC_TRUNC_W_S:
1.1.1.7   root     6630:         {
                   6631:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6632: 
                   6633:             gen_load_fpr32(fp0, fs);
                   6634:             gen_helper_float_truncw_s(fp0, fp0);
                   6635:             gen_store_fpr32(fp0, fd);
                   6636:             tcg_temp_free_i32(fp0);
                   6637:         }
1.1.1.6   root     6638:         opn = "trunc.w.s";
                   6639:         break;
1.1.1.12  root     6640:     case OPC_CEIL_W_S:
1.1.1.7   root     6641:         {
                   6642:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6643: 
                   6644:             gen_load_fpr32(fp0, fs);
                   6645:             gen_helper_float_ceilw_s(fp0, fp0);
                   6646:             gen_store_fpr32(fp0, fd);
                   6647:             tcg_temp_free_i32(fp0);
                   6648:         }
1.1.1.6   root     6649:         opn = "ceil.w.s";
                   6650:         break;
1.1.1.12  root     6651:     case OPC_FLOOR_W_S:
1.1.1.7   root     6652:         {
                   6653:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6654: 
                   6655:             gen_load_fpr32(fp0, fs);
                   6656:             gen_helper_float_floorw_s(fp0, fp0);
                   6657:             gen_store_fpr32(fp0, fd);
                   6658:             tcg_temp_free_i32(fp0);
                   6659:         }
1.1.1.6   root     6660:         opn = "floor.w.s";
                   6661:         break;
1.1.1.12  root     6662:     case OPC_MOVCF_S:
1.1.1.7   root     6663:         gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
1.1.1.6   root     6664:         opn = "movcf.s";
                   6665:         break;
1.1.1.12  root     6666:     case OPC_MOVZ_S:
1.1.1.7   root     6667:         {
                   6668:             int l1 = gen_new_label();
1.1.1.8   root     6669:             TCGv_i32 fp0;
1.1.1.7   root     6670: 
1.1.1.8   root     6671:             if (ft != 0) {
                   6672:                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
                   6673:             }
                   6674:             fp0 = tcg_temp_new_i32();
1.1.1.7   root     6675:             gen_load_fpr32(fp0, fs);
                   6676:             gen_store_fpr32(fp0, fd);
                   6677:             tcg_temp_free_i32(fp0);
                   6678:             gen_set_label(l1);
                   6679:         }
1.1.1.6   root     6680:         opn = "movz.s";
                   6681:         break;
1.1.1.12  root     6682:     case OPC_MOVN_S:
1.1.1.7   root     6683:         {
                   6684:             int l1 = gen_new_label();
1.1.1.8   root     6685:             TCGv_i32 fp0;
1.1.1.7   root     6686: 
1.1.1.8   root     6687:             if (ft != 0) {
                   6688:                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
                   6689:                 fp0 = tcg_temp_new_i32();
                   6690:                 gen_load_fpr32(fp0, fs);
                   6691:                 gen_store_fpr32(fp0, fd);
                   6692:                 tcg_temp_free_i32(fp0);
                   6693:                 gen_set_label(l1);
                   6694:             }
1.1.1.7   root     6695:         }
1.1.1.6   root     6696:         opn = "movn.s";
                   6697:         break;
1.1.1.12  root     6698:     case OPC_RECIP_S:
1.1.1.6   root     6699:         check_cop1x(ctx);
1.1.1.7   root     6700:         {
                   6701:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6702: 
                   6703:             gen_load_fpr32(fp0, fs);
                   6704:             gen_helper_float_recip_s(fp0, fp0);
                   6705:             gen_store_fpr32(fp0, fd);
                   6706:             tcg_temp_free_i32(fp0);
                   6707:         }
1.1.1.6   root     6708:         opn = "recip.s";
                   6709:         break;
1.1.1.12  root     6710:     case OPC_RSQRT_S:
1.1.1.6   root     6711:         check_cop1x(ctx);
1.1.1.7   root     6712:         {
                   6713:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6714: 
                   6715:             gen_load_fpr32(fp0, fs);
                   6716:             gen_helper_float_rsqrt_s(fp0, fp0);
                   6717:             gen_store_fpr32(fp0, fd);
                   6718:             tcg_temp_free_i32(fp0);
                   6719:         }
1.1.1.6   root     6720:         opn = "rsqrt.s";
                   6721:         break;
1.1.1.12  root     6722:     case OPC_RECIP2_S:
1.1.1.6   root     6723:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6724:         {
                   6725:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6726:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   6727: 
                   6728:             gen_load_fpr32(fp0, fs);
                   6729:             gen_load_fpr32(fp1, fd);
                   6730:             gen_helper_float_recip2_s(fp0, fp0, fp1);
                   6731:             tcg_temp_free_i32(fp1);
                   6732:             gen_store_fpr32(fp0, fd);
                   6733:             tcg_temp_free_i32(fp0);
                   6734:         }
1.1.1.6   root     6735:         opn = "recip2.s";
                   6736:         break;
1.1.1.12  root     6737:     case OPC_RECIP1_S:
1.1.1.6   root     6738:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6739:         {
                   6740:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6741: 
                   6742:             gen_load_fpr32(fp0, fs);
                   6743:             gen_helper_float_recip1_s(fp0, fp0);
                   6744:             gen_store_fpr32(fp0, fd);
                   6745:             tcg_temp_free_i32(fp0);
                   6746:         }
1.1.1.6   root     6747:         opn = "recip1.s";
                   6748:         break;
1.1.1.12  root     6749:     case OPC_RSQRT1_S:
1.1.1.6   root     6750:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6751:         {
                   6752:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6753: 
                   6754:             gen_load_fpr32(fp0, fs);
                   6755:             gen_helper_float_rsqrt1_s(fp0, fp0);
                   6756:             gen_store_fpr32(fp0, fd);
                   6757:             tcg_temp_free_i32(fp0);
                   6758:         }
1.1.1.6   root     6759:         opn = "rsqrt1.s";
                   6760:         break;
1.1.1.12  root     6761:     case OPC_RSQRT2_S:
1.1.1.6   root     6762:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6763:         {
                   6764:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6765:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   6766: 
                   6767:             gen_load_fpr32(fp0, fs);
                   6768:             gen_load_fpr32(fp1, ft);
                   6769:             gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
                   6770:             tcg_temp_free_i32(fp1);
                   6771:             gen_store_fpr32(fp0, fd);
                   6772:             tcg_temp_free_i32(fp0);
                   6773:         }
1.1.1.6   root     6774:         opn = "rsqrt2.s";
                   6775:         break;
1.1.1.12  root     6776:     case OPC_CVT_D_S:
1.1.1.6   root     6777:         check_cp1_registers(ctx, fd);
1.1.1.7   root     6778:         {
                   6779:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   6780:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   6781: 
                   6782:             gen_load_fpr32(fp32, fs);
                   6783:             gen_helper_float_cvtd_s(fp64, fp32);
                   6784:             tcg_temp_free_i32(fp32);
                   6785:             gen_store_fpr64(ctx, fp64, fd);
                   6786:             tcg_temp_free_i64(fp64);
                   6787:         }
1.1.1.6   root     6788:         opn = "cvt.d.s";
                   6789:         break;
1.1.1.12  root     6790:     case OPC_CVT_W_S:
1.1.1.7   root     6791:         {
                   6792:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   6793: 
                   6794:             gen_load_fpr32(fp0, fs);
                   6795:             gen_helper_float_cvtw_s(fp0, fp0);
                   6796:             gen_store_fpr32(fp0, fd);
                   6797:             tcg_temp_free_i32(fp0);
                   6798:         }
1.1.1.6   root     6799:         opn = "cvt.w.s";
                   6800:         break;
1.1.1.12  root     6801:     case OPC_CVT_L_S:
1.1.1.6   root     6802:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6803:         {
                   6804:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   6805:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   6806: 
                   6807:             gen_load_fpr32(fp32, fs);
                   6808:             gen_helper_float_cvtl_s(fp64, fp32);
                   6809:             tcg_temp_free_i32(fp32);
                   6810:             gen_store_fpr64(ctx, fp64, fd);
                   6811:             tcg_temp_free_i64(fp64);
                   6812:         }
1.1.1.6   root     6813:         opn = "cvt.l.s";
                   6814:         break;
1.1.1.12  root     6815:     case OPC_CVT_PS_S:
1.1.1.6   root     6816:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6817:         {
                   6818:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   6819:             TCGv_i32 fp32_0 = tcg_temp_new_i32();
                   6820:             TCGv_i32 fp32_1 = tcg_temp_new_i32();
                   6821: 
                   6822:             gen_load_fpr32(fp32_0, fs);
                   6823:             gen_load_fpr32(fp32_1, ft);
                   6824:             tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
                   6825:             tcg_temp_free_i32(fp32_1);
                   6826:             tcg_temp_free_i32(fp32_0);
                   6827:             gen_store_fpr64(ctx, fp64, fd);
                   6828:             tcg_temp_free_i64(fp64);
                   6829:         }
1.1.1.6   root     6830:         opn = "cvt.ps.s";
                   6831:         break;
1.1.1.12  root     6832:     case OPC_CMP_F_S:
                   6833:     case OPC_CMP_UN_S:
                   6834:     case OPC_CMP_EQ_S:
                   6835:     case OPC_CMP_UEQ_S:
                   6836:     case OPC_CMP_OLT_S:
                   6837:     case OPC_CMP_ULT_S:
                   6838:     case OPC_CMP_OLE_S:
                   6839:     case OPC_CMP_ULE_S:
                   6840:     case OPC_CMP_SF_S:
                   6841:     case OPC_CMP_NGLE_S:
                   6842:     case OPC_CMP_SEQ_S:
                   6843:     case OPC_CMP_NGL_S:
                   6844:     case OPC_CMP_LT_S:
                   6845:     case OPC_CMP_NGE_S:
                   6846:     case OPC_CMP_LE_S:
                   6847:     case OPC_CMP_NGT_S:
                   6848:         if (ctx->opcode & (1 << 6)) {
                   6849:             gen_cmpabs_s(ctx, func-48, ft, fs, cc);
                   6850:             opn = condnames_abs[func-48];
                   6851:         } else {
                   6852:             gen_cmp_s(ctx, func-48, ft, fs, cc);
                   6853:             opn = condnames[func-48];
1.1.1.6   root     6854:         }
                   6855:         break;
1.1.1.12  root     6856:     case OPC_ADD_D:
1.1.1.6   root     6857:         check_cp1_registers(ctx, fs | ft | fd);
1.1.1.7   root     6858:         {
                   6859:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6860:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   6861: 
                   6862:             gen_load_fpr64(ctx, fp0, fs);
                   6863:             gen_load_fpr64(ctx, fp1, ft);
                   6864:             gen_helper_float_add_d(fp0, fp0, fp1);
                   6865:             tcg_temp_free_i64(fp1);
                   6866:             gen_store_fpr64(ctx, fp0, fd);
                   6867:             tcg_temp_free_i64(fp0);
                   6868:         }
1.1.1.4   root     6869:         opn = "add.d";
1.1.1.6   root     6870:         optype = BINOP;
1.1.1.4   root     6871:         break;
1.1.1.12  root     6872:     case OPC_SUB_D:
1.1.1.6   root     6873:         check_cp1_registers(ctx, fs | ft | fd);
1.1.1.7   root     6874:         {
                   6875:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6876:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   6877: 
                   6878:             gen_load_fpr64(ctx, fp0, fs);
                   6879:             gen_load_fpr64(ctx, fp1, ft);
                   6880:             gen_helper_float_sub_d(fp0, fp0, fp1);
                   6881:             tcg_temp_free_i64(fp1);
                   6882:             gen_store_fpr64(ctx, fp0, fd);
                   6883:             tcg_temp_free_i64(fp0);
                   6884:         }
1.1.1.4   root     6885:         opn = "sub.d";
1.1.1.6   root     6886:         optype = BINOP;
1.1.1.4   root     6887:         break;
1.1.1.12  root     6888:     case OPC_MUL_D:
1.1.1.6   root     6889:         check_cp1_registers(ctx, fs | ft | fd);
1.1.1.7   root     6890:         {
                   6891:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6892:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   6893: 
                   6894:             gen_load_fpr64(ctx, fp0, fs);
                   6895:             gen_load_fpr64(ctx, fp1, ft);
                   6896:             gen_helper_float_mul_d(fp0, fp0, fp1);
                   6897:             tcg_temp_free_i64(fp1);
                   6898:             gen_store_fpr64(ctx, fp0, fd);
                   6899:             tcg_temp_free_i64(fp0);
                   6900:         }
1.1.1.4   root     6901:         opn = "mul.d";
1.1.1.6   root     6902:         optype = BINOP;
1.1.1.4   root     6903:         break;
1.1.1.12  root     6904:     case OPC_DIV_D:
1.1.1.6   root     6905:         check_cp1_registers(ctx, fs | ft | fd);
1.1.1.7   root     6906:         {
                   6907:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6908:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   6909: 
                   6910:             gen_load_fpr64(ctx, fp0, fs);
                   6911:             gen_load_fpr64(ctx, fp1, ft);
                   6912:             gen_helper_float_div_d(fp0, fp0, fp1);
                   6913:             tcg_temp_free_i64(fp1);
                   6914:             gen_store_fpr64(ctx, fp0, fd);
                   6915:             tcg_temp_free_i64(fp0);
                   6916:         }
1.1.1.4   root     6917:         opn = "div.d";
1.1.1.6   root     6918:         optype = BINOP;
1.1.1.4   root     6919:         break;
1.1.1.12  root     6920:     case OPC_SQRT_D:
1.1.1.6   root     6921:         check_cp1_registers(ctx, fs | fd);
1.1.1.7   root     6922:         {
                   6923:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6924: 
                   6925:             gen_load_fpr64(ctx, fp0, fs);
                   6926:             gen_helper_float_sqrt_d(fp0, fp0);
                   6927:             gen_store_fpr64(ctx, fp0, fd);
                   6928:             tcg_temp_free_i64(fp0);
                   6929:         }
1.1.1.4   root     6930:         opn = "sqrt.d";
                   6931:         break;
1.1.1.12  root     6932:     case OPC_ABS_D:
1.1.1.6   root     6933:         check_cp1_registers(ctx, fs | fd);
1.1.1.7   root     6934:         {
                   6935:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6936: 
                   6937:             gen_load_fpr64(ctx, fp0, fs);
                   6938:             gen_helper_float_abs_d(fp0, fp0);
                   6939:             gen_store_fpr64(ctx, fp0, fd);
                   6940:             tcg_temp_free_i64(fp0);
                   6941:         }
1.1.1.4   root     6942:         opn = "abs.d";
                   6943:         break;
1.1.1.12  root     6944:     case OPC_MOV_D:
1.1.1.6   root     6945:         check_cp1_registers(ctx, fs | fd);
1.1.1.7   root     6946:         {
                   6947:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6948: 
                   6949:             gen_load_fpr64(ctx, fp0, fs);
                   6950:             gen_store_fpr64(ctx, fp0, fd);
                   6951:             tcg_temp_free_i64(fp0);
                   6952:         }
1.1.1.4   root     6953:         opn = "mov.d";
                   6954:         break;
1.1.1.12  root     6955:     case OPC_NEG_D:
1.1.1.6   root     6956:         check_cp1_registers(ctx, fs | fd);
1.1.1.7   root     6957:         {
                   6958:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6959: 
                   6960:             gen_load_fpr64(ctx, fp0, fs);
                   6961:             gen_helper_float_chs_d(fp0, fp0);
                   6962:             gen_store_fpr64(ctx, fp0, fd);
                   6963:             tcg_temp_free_i64(fp0);
                   6964:         }
1.1.1.4   root     6965:         opn = "neg.d";
                   6966:         break;
1.1.1.12  root     6967:     case OPC_ROUND_L_D:
1.1.1.6   root     6968:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6969:         {
                   6970:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6971: 
                   6972:             gen_load_fpr64(ctx, fp0, fs);
                   6973:             gen_helper_float_roundl_d(fp0, fp0);
                   6974:             gen_store_fpr64(ctx, fp0, fd);
                   6975:             tcg_temp_free_i64(fp0);
                   6976:         }
1.1.1.6   root     6977:         opn = "round.l.d";
                   6978:         break;
1.1.1.12  root     6979:     case OPC_TRUNC_L_D:
1.1.1.6   root     6980:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6981:         {
                   6982:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6983: 
                   6984:             gen_load_fpr64(ctx, fp0, fs);
                   6985:             gen_helper_float_truncl_d(fp0, fp0);
                   6986:             gen_store_fpr64(ctx, fp0, fd);
                   6987:             tcg_temp_free_i64(fp0);
                   6988:         }
1.1.1.6   root     6989:         opn = "trunc.l.d";
                   6990:         break;
1.1.1.12  root     6991:     case OPC_CEIL_L_D:
1.1.1.6   root     6992:         check_cp1_64bitmode(ctx);
1.1.1.7   root     6993:         {
                   6994:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   6995: 
                   6996:             gen_load_fpr64(ctx, fp0, fs);
                   6997:             gen_helper_float_ceill_d(fp0, fp0);
                   6998:             gen_store_fpr64(ctx, fp0, fd);
                   6999:             tcg_temp_free_i64(fp0);
                   7000:         }
1.1.1.6   root     7001:         opn = "ceil.l.d";
                   7002:         break;
1.1.1.12  root     7003:     case OPC_FLOOR_L_D:
1.1.1.6   root     7004:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7005:         {
                   7006:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7007: 
                   7008:             gen_load_fpr64(ctx, fp0, fs);
                   7009:             gen_helper_float_floorl_d(fp0, fp0);
                   7010:             gen_store_fpr64(ctx, fp0, fd);
                   7011:             tcg_temp_free_i64(fp0);
                   7012:         }
1.1.1.6   root     7013:         opn = "floor.l.d";
                   7014:         break;
1.1.1.12  root     7015:     case OPC_ROUND_W_D:
1.1.1.6   root     7016:         check_cp1_registers(ctx, fs);
1.1.1.7   root     7017:         {
                   7018:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   7019:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   7020: 
                   7021:             gen_load_fpr64(ctx, fp64, fs);
                   7022:             gen_helper_float_roundw_d(fp32, fp64);
                   7023:             tcg_temp_free_i64(fp64);
                   7024:             gen_store_fpr32(fp32, fd);
                   7025:             tcg_temp_free_i32(fp32);
                   7026:         }
1.1.1.4   root     7027:         opn = "round.w.d";
                   7028:         break;
1.1.1.12  root     7029:     case OPC_TRUNC_W_D:
1.1.1.6   root     7030:         check_cp1_registers(ctx, fs);
1.1.1.7   root     7031:         {
                   7032:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   7033:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   7034: 
                   7035:             gen_load_fpr64(ctx, fp64, fs);
                   7036:             gen_helper_float_truncw_d(fp32, fp64);
                   7037:             tcg_temp_free_i64(fp64);
                   7038:             gen_store_fpr32(fp32, fd);
                   7039:             tcg_temp_free_i32(fp32);
                   7040:         }
1.1.1.4   root     7041:         opn = "trunc.w.d";
                   7042:         break;
1.1.1.12  root     7043:     case OPC_CEIL_W_D:
1.1.1.6   root     7044:         check_cp1_registers(ctx, fs);
1.1.1.7   root     7045:         {
                   7046:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   7047:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   7048: 
                   7049:             gen_load_fpr64(ctx, fp64, fs);
                   7050:             gen_helper_float_ceilw_d(fp32, fp64);
                   7051:             tcg_temp_free_i64(fp64);
                   7052:             gen_store_fpr32(fp32, fd);
                   7053:             tcg_temp_free_i32(fp32);
                   7054:         }
1.1.1.4   root     7055:         opn = "ceil.w.d";
                   7056:         break;
1.1.1.12  root     7057:     case OPC_FLOOR_W_D:
1.1.1.6   root     7058:         check_cp1_registers(ctx, fs);
1.1.1.7   root     7059:         {
                   7060:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   7061:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   7062: 
                   7063:             gen_load_fpr64(ctx, fp64, fs);
                   7064:             gen_helper_float_floorw_d(fp32, fp64);
                   7065:             tcg_temp_free_i64(fp64);
                   7066:             gen_store_fpr32(fp32, fd);
                   7067:             tcg_temp_free_i32(fp32);
                   7068:         }
1.1.1.5   root     7069:         opn = "floor.w.d";
                   7070:         break;
1.1.1.12  root     7071:     case OPC_MOVCF_D:
1.1.1.7   root     7072:         gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
1.1.1.6   root     7073:         opn = "movcf.d";
1.1.1.4   root     7074:         break;
1.1.1.12  root     7075:     case OPC_MOVZ_D:
1.1.1.7   root     7076:         {
                   7077:             int l1 = gen_new_label();
1.1.1.8   root     7078:             TCGv_i64 fp0;
1.1.1.7   root     7079: 
1.1.1.8   root     7080:             if (ft != 0) {
                   7081:                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
                   7082:             }
                   7083:             fp0 = tcg_temp_new_i64();
1.1.1.7   root     7084:             gen_load_fpr64(ctx, fp0, fs);
                   7085:             gen_store_fpr64(ctx, fp0, fd);
                   7086:             tcg_temp_free_i64(fp0);
                   7087:             gen_set_label(l1);
                   7088:         }
1.1.1.6   root     7089:         opn = "movz.d";
                   7090:         break;
1.1.1.12  root     7091:     case OPC_MOVN_D:
1.1.1.7   root     7092:         {
                   7093:             int l1 = gen_new_label();
1.1.1.8   root     7094:             TCGv_i64 fp0;
1.1.1.7   root     7095: 
1.1.1.8   root     7096:             if (ft != 0) {
                   7097:                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
                   7098:                 fp0 = tcg_temp_new_i64();
                   7099:                 gen_load_fpr64(ctx, fp0, fs);
                   7100:                 gen_store_fpr64(ctx, fp0, fd);
                   7101:                 tcg_temp_free_i64(fp0);
                   7102:                 gen_set_label(l1);
                   7103:             }
1.1.1.7   root     7104:         }
1.1.1.6   root     7105:         opn = "movn.d";
                   7106:         break;
1.1.1.12  root     7107:     case OPC_RECIP_D:
1.1.1.6   root     7108:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7109:         {
                   7110:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7111: 
                   7112:             gen_load_fpr64(ctx, fp0, fs);
                   7113:             gen_helper_float_recip_d(fp0, fp0);
                   7114:             gen_store_fpr64(ctx, fp0, fd);
                   7115:             tcg_temp_free_i64(fp0);
                   7116:         }
1.1.1.6   root     7117:         opn = "recip.d";
                   7118:         break;
1.1.1.12  root     7119:     case OPC_RSQRT_D:
1.1.1.6   root     7120:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7121:         {
                   7122:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7123: 
                   7124:             gen_load_fpr64(ctx, fp0, fs);
                   7125:             gen_helper_float_rsqrt_d(fp0, fp0);
                   7126:             gen_store_fpr64(ctx, fp0, fd);
                   7127:             tcg_temp_free_i64(fp0);
                   7128:         }
1.1.1.6   root     7129:         opn = "rsqrt.d";
                   7130:         break;
1.1.1.12  root     7131:     case OPC_RECIP2_D:
1.1.1.6   root     7132:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7133:         {
                   7134:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7135:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7136: 
                   7137:             gen_load_fpr64(ctx, fp0, fs);
                   7138:             gen_load_fpr64(ctx, fp1, ft);
                   7139:             gen_helper_float_recip2_d(fp0, fp0, fp1);
                   7140:             tcg_temp_free_i64(fp1);
                   7141:             gen_store_fpr64(ctx, fp0, fd);
                   7142:             tcg_temp_free_i64(fp0);
                   7143:         }
1.1.1.6   root     7144:         opn = "recip2.d";
                   7145:         break;
1.1.1.12  root     7146:     case OPC_RECIP1_D:
1.1.1.6   root     7147:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7148:         {
                   7149:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7150: 
                   7151:             gen_load_fpr64(ctx, fp0, fs);
                   7152:             gen_helper_float_recip1_d(fp0, fp0);
                   7153:             gen_store_fpr64(ctx, fp0, fd);
                   7154:             tcg_temp_free_i64(fp0);
                   7155:         }
1.1.1.6   root     7156:         opn = "recip1.d";
                   7157:         break;
1.1.1.12  root     7158:     case OPC_RSQRT1_D:
1.1.1.6   root     7159:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7160:         {
                   7161:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7162: 
                   7163:             gen_load_fpr64(ctx, fp0, fs);
                   7164:             gen_helper_float_rsqrt1_d(fp0, fp0);
                   7165:             gen_store_fpr64(ctx, fp0, fd);
                   7166:             tcg_temp_free_i64(fp0);
                   7167:         }
1.1.1.6   root     7168:         opn = "rsqrt1.d";
                   7169:         break;
1.1.1.12  root     7170:     case OPC_RSQRT2_D:
1.1.1.6   root     7171:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7172:         {
                   7173:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7174:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7175: 
                   7176:             gen_load_fpr64(ctx, fp0, fs);
                   7177:             gen_load_fpr64(ctx, fp1, ft);
                   7178:             gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
                   7179:             tcg_temp_free_i64(fp1);
                   7180:             gen_store_fpr64(ctx, fp0, fd);
                   7181:             tcg_temp_free_i64(fp0);
                   7182:         }
1.1.1.6   root     7183:         opn = "rsqrt2.d";
1.1.1.4   root     7184:         break;
1.1.1.12  root     7185:     case OPC_CMP_F_D:
                   7186:     case OPC_CMP_UN_D:
                   7187:     case OPC_CMP_EQ_D:
                   7188:     case OPC_CMP_UEQ_D:
                   7189:     case OPC_CMP_OLT_D:
                   7190:     case OPC_CMP_ULT_D:
                   7191:     case OPC_CMP_OLE_D:
                   7192:     case OPC_CMP_ULE_D:
                   7193:     case OPC_CMP_SF_D:
                   7194:     case OPC_CMP_NGLE_D:
                   7195:     case OPC_CMP_SEQ_D:
                   7196:     case OPC_CMP_NGL_D:
                   7197:     case OPC_CMP_LT_D:
                   7198:     case OPC_CMP_NGE_D:
                   7199:     case OPC_CMP_LE_D:
                   7200:     case OPC_CMP_NGT_D:
                   7201:         if (ctx->opcode & (1 << 6)) {
                   7202:             gen_cmpabs_d(ctx, func-48, ft, fs, cc);
                   7203:             opn = condnames_abs[func-48];
                   7204:         } else {
                   7205:             gen_cmp_d(ctx, func-48, ft, fs, cc);
                   7206:             opn = condnames[func-48];
1.1.1.6   root     7207:         }
                   7208:         break;
1.1.1.12  root     7209:     case OPC_CVT_S_D:
1.1.1.6   root     7210:         check_cp1_registers(ctx, fs);
1.1.1.7   root     7211:         {
                   7212:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   7213:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   7214: 
                   7215:             gen_load_fpr64(ctx, fp64, fs);
                   7216:             gen_helper_float_cvts_d(fp32, fp64);
                   7217:             tcg_temp_free_i64(fp64);
                   7218:             gen_store_fpr32(fp32, fd);
                   7219:             tcg_temp_free_i32(fp32);
                   7220:         }
1.1.1.6   root     7221:         opn = "cvt.s.d";
                   7222:         break;
1.1.1.12  root     7223:     case OPC_CVT_W_D:
1.1.1.6   root     7224:         check_cp1_registers(ctx, fs);
1.1.1.7   root     7225:         {
                   7226:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   7227:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   7228: 
                   7229:             gen_load_fpr64(ctx, fp64, fs);
                   7230:             gen_helper_float_cvtw_d(fp32, fp64);
                   7231:             tcg_temp_free_i64(fp64);
                   7232:             gen_store_fpr32(fp32, fd);
                   7233:             tcg_temp_free_i32(fp32);
                   7234:         }
1.1.1.6   root     7235:         opn = "cvt.w.d";
                   7236:         break;
1.1.1.12  root     7237:     case OPC_CVT_L_D:
1.1.1.6   root     7238:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7239:         {
                   7240:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7241: 
                   7242:             gen_load_fpr64(ctx, fp0, fs);
                   7243:             gen_helper_float_cvtl_d(fp0, fp0);
                   7244:             gen_store_fpr64(ctx, fp0, fd);
                   7245:             tcg_temp_free_i64(fp0);
                   7246:         }
1.1.1.6   root     7247:         opn = "cvt.l.d";
                   7248:         break;
1.1.1.12  root     7249:     case OPC_CVT_S_W:
1.1.1.7   root     7250:         {
                   7251:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7252: 
                   7253:             gen_load_fpr32(fp0, fs);
                   7254:             gen_helper_float_cvts_w(fp0, fp0);
                   7255:             gen_store_fpr32(fp0, fd);
                   7256:             tcg_temp_free_i32(fp0);
                   7257:         }
1.1.1.6   root     7258:         opn = "cvt.s.w";
                   7259:         break;
1.1.1.12  root     7260:     case OPC_CVT_D_W:
1.1.1.6   root     7261:         check_cp1_registers(ctx, fd);
1.1.1.7   root     7262:         {
                   7263:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   7264:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   7265: 
                   7266:             gen_load_fpr32(fp32, fs);
                   7267:             gen_helper_float_cvtd_w(fp64, fp32);
                   7268:             tcg_temp_free_i32(fp32);
                   7269:             gen_store_fpr64(ctx, fp64, fd);
                   7270:             tcg_temp_free_i64(fp64);
                   7271:         }
1.1.1.6   root     7272:         opn = "cvt.d.w";
                   7273:         break;
1.1.1.12  root     7274:     case OPC_CVT_S_L:
1.1.1.6   root     7275:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7276:         {
                   7277:             TCGv_i32 fp32 = tcg_temp_new_i32();
                   7278:             TCGv_i64 fp64 = tcg_temp_new_i64();
                   7279: 
                   7280:             gen_load_fpr64(ctx, fp64, fs);
                   7281:             gen_helper_float_cvts_l(fp32, fp64);
                   7282:             tcg_temp_free_i64(fp64);
                   7283:             gen_store_fpr32(fp32, fd);
                   7284:             tcg_temp_free_i32(fp32);
                   7285:         }
1.1.1.6   root     7286:         opn = "cvt.s.l";
                   7287:         break;
1.1.1.12  root     7288:     case OPC_CVT_D_L:
1.1.1.6   root     7289:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7290:         {
                   7291:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7292: 
                   7293:             gen_load_fpr64(ctx, fp0, fs);
                   7294:             gen_helper_float_cvtd_l(fp0, fp0);
                   7295:             gen_store_fpr64(ctx, fp0, fd);
                   7296:             tcg_temp_free_i64(fp0);
                   7297:         }
1.1.1.6   root     7298:         opn = "cvt.d.l";
                   7299:         break;
1.1.1.12  root     7300:     case OPC_CVT_PS_PW:
1.1.1.6   root     7301:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7302:         {
                   7303:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7304: 
                   7305:             gen_load_fpr64(ctx, fp0, fs);
                   7306:             gen_helper_float_cvtps_pw(fp0, fp0);
                   7307:             gen_store_fpr64(ctx, fp0, fd);
                   7308:             tcg_temp_free_i64(fp0);
                   7309:         }
1.1.1.6   root     7310:         opn = "cvt.ps.pw";
                   7311:         break;
1.1.1.12  root     7312:     case OPC_ADD_PS:
1.1.1.6   root     7313:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7314:         {
                   7315:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7316:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7317: 
                   7318:             gen_load_fpr64(ctx, fp0, fs);
                   7319:             gen_load_fpr64(ctx, fp1, ft);
                   7320:             gen_helper_float_add_ps(fp0, fp0, fp1);
                   7321:             tcg_temp_free_i64(fp1);
                   7322:             gen_store_fpr64(ctx, fp0, fd);
                   7323:             tcg_temp_free_i64(fp0);
                   7324:         }
1.1.1.6   root     7325:         opn = "add.ps";
                   7326:         break;
1.1.1.12  root     7327:     case OPC_SUB_PS:
1.1.1.6   root     7328:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7329:         {
                   7330:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7331:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7332: 
                   7333:             gen_load_fpr64(ctx, fp0, fs);
                   7334:             gen_load_fpr64(ctx, fp1, ft);
                   7335:             gen_helper_float_sub_ps(fp0, fp0, fp1);
                   7336:             tcg_temp_free_i64(fp1);
                   7337:             gen_store_fpr64(ctx, fp0, fd);
                   7338:             tcg_temp_free_i64(fp0);
                   7339:         }
1.1.1.6   root     7340:         opn = "sub.ps";
                   7341:         break;
1.1.1.12  root     7342:     case OPC_MUL_PS:
1.1.1.6   root     7343:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7344:         {
                   7345:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7346:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7347: 
                   7348:             gen_load_fpr64(ctx, fp0, fs);
                   7349:             gen_load_fpr64(ctx, fp1, ft);
                   7350:             gen_helper_float_mul_ps(fp0, fp0, fp1);
                   7351:             tcg_temp_free_i64(fp1);
                   7352:             gen_store_fpr64(ctx, fp0, fd);
                   7353:             tcg_temp_free_i64(fp0);
                   7354:         }
1.1.1.6   root     7355:         opn = "mul.ps";
                   7356:         break;
1.1.1.12  root     7357:     case OPC_ABS_PS:
1.1.1.6   root     7358:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7359:         {
                   7360:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7361: 
                   7362:             gen_load_fpr64(ctx, fp0, fs);
                   7363:             gen_helper_float_abs_ps(fp0, fp0);
                   7364:             gen_store_fpr64(ctx, fp0, fd);
                   7365:             tcg_temp_free_i64(fp0);
                   7366:         }
1.1.1.6   root     7367:         opn = "abs.ps";
                   7368:         break;
1.1.1.12  root     7369:     case OPC_MOV_PS:
1.1.1.6   root     7370:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7371:         {
                   7372:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7373: 
                   7374:             gen_load_fpr64(ctx, fp0, fs);
                   7375:             gen_store_fpr64(ctx, fp0, fd);
                   7376:             tcg_temp_free_i64(fp0);
                   7377:         }
1.1.1.6   root     7378:         opn = "mov.ps";
                   7379:         break;
1.1.1.12  root     7380:     case OPC_NEG_PS:
1.1.1.6   root     7381:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7382:         {
                   7383:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7384: 
                   7385:             gen_load_fpr64(ctx, fp0, fs);
                   7386:             gen_helper_float_chs_ps(fp0, fp0);
                   7387:             gen_store_fpr64(ctx, fp0, fd);
                   7388:             tcg_temp_free_i64(fp0);
                   7389:         }
1.1.1.6   root     7390:         opn = "neg.ps";
                   7391:         break;
1.1.1.12  root     7392:     case OPC_MOVCF_PS:
1.1.1.6   root     7393:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7394:         gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
1.1.1.6   root     7395:         opn = "movcf.ps";
                   7396:         break;
1.1.1.12  root     7397:     case OPC_MOVZ_PS:
1.1.1.6   root     7398:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7399:         {
                   7400:             int l1 = gen_new_label();
1.1.1.8   root     7401:             TCGv_i64 fp0;
1.1.1.7   root     7402: 
1.1.1.8   root     7403:             if (ft != 0)
                   7404:                 tcg_gen_brcondi_tl(TCG_COND_NE, cpu_gpr[ft], 0, l1);
                   7405:             fp0 = tcg_temp_new_i64();
                   7406:             gen_load_fpr64(ctx, fp0, fs);
                   7407:             gen_store_fpr64(ctx, fp0, fd);
                   7408:             tcg_temp_free_i64(fp0);
1.1.1.7   root     7409:             gen_set_label(l1);
                   7410:         }
1.1.1.6   root     7411:         opn = "movz.ps";
                   7412:         break;
1.1.1.12  root     7413:     case OPC_MOVN_PS:
1.1.1.6   root     7414:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7415:         {
                   7416:             int l1 = gen_new_label();
1.1.1.8   root     7417:             TCGv_i64 fp0;
1.1.1.7   root     7418: 
1.1.1.8   root     7419:             if (ft != 0) {
                   7420:                 tcg_gen_brcondi_tl(TCG_COND_EQ, cpu_gpr[ft], 0, l1);
                   7421:                 fp0 = tcg_temp_new_i64();
                   7422:                 gen_load_fpr64(ctx, fp0, fs);
                   7423:                 gen_store_fpr64(ctx, fp0, fd);
                   7424:                 tcg_temp_free_i64(fp0);
                   7425:                 gen_set_label(l1);
                   7426:             }
1.1.1.7   root     7427:         }
1.1.1.6   root     7428:         opn = "movn.ps";
                   7429:         break;
1.1.1.12  root     7430:     case OPC_ADDR_PS:
1.1.1.6   root     7431:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7432:         {
                   7433:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7434:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7435: 
                   7436:             gen_load_fpr64(ctx, fp0, ft);
                   7437:             gen_load_fpr64(ctx, fp1, fs);
                   7438:             gen_helper_float_addr_ps(fp0, fp0, fp1);
                   7439:             tcg_temp_free_i64(fp1);
                   7440:             gen_store_fpr64(ctx, fp0, fd);
                   7441:             tcg_temp_free_i64(fp0);
                   7442:         }
1.1.1.6   root     7443:         opn = "addr.ps";
                   7444:         break;
1.1.1.12  root     7445:     case OPC_MULR_PS:
1.1.1.6   root     7446:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7447:         {
                   7448:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7449:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7450: 
                   7451:             gen_load_fpr64(ctx, fp0, ft);
                   7452:             gen_load_fpr64(ctx, fp1, fs);
                   7453:             gen_helper_float_mulr_ps(fp0, fp0, fp1);
                   7454:             tcg_temp_free_i64(fp1);
                   7455:             gen_store_fpr64(ctx, fp0, fd);
                   7456:             tcg_temp_free_i64(fp0);
                   7457:         }
1.1.1.6   root     7458:         opn = "mulr.ps";
                   7459:         break;
1.1.1.12  root     7460:     case OPC_RECIP2_PS:
1.1.1.6   root     7461:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7462:         {
                   7463:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7464:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7465: 
                   7466:             gen_load_fpr64(ctx, fp0, fs);
                   7467:             gen_load_fpr64(ctx, fp1, fd);
                   7468:             gen_helper_float_recip2_ps(fp0, fp0, fp1);
                   7469:             tcg_temp_free_i64(fp1);
                   7470:             gen_store_fpr64(ctx, fp0, fd);
                   7471:             tcg_temp_free_i64(fp0);
                   7472:         }
1.1.1.6   root     7473:         opn = "recip2.ps";
                   7474:         break;
1.1.1.12  root     7475:     case OPC_RECIP1_PS:
1.1.1.6   root     7476:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7477:         {
                   7478:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7479: 
                   7480:             gen_load_fpr64(ctx, fp0, fs);
                   7481:             gen_helper_float_recip1_ps(fp0, fp0);
                   7482:             gen_store_fpr64(ctx, fp0, fd);
                   7483:             tcg_temp_free_i64(fp0);
                   7484:         }
1.1.1.6   root     7485:         opn = "recip1.ps";
                   7486:         break;
1.1.1.12  root     7487:     case OPC_RSQRT1_PS:
1.1.1.6   root     7488:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7489:         {
                   7490:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7491: 
                   7492:             gen_load_fpr64(ctx, fp0, fs);
                   7493:             gen_helper_float_rsqrt1_ps(fp0, fp0);
                   7494:             gen_store_fpr64(ctx, fp0, fd);
                   7495:             tcg_temp_free_i64(fp0);
                   7496:         }
1.1.1.6   root     7497:         opn = "rsqrt1.ps";
                   7498:         break;
1.1.1.12  root     7499:     case OPC_RSQRT2_PS:
1.1.1.6   root     7500:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7501:         {
                   7502:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7503:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7504: 
                   7505:             gen_load_fpr64(ctx, fp0, fs);
                   7506:             gen_load_fpr64(ctx, fp1, ft);
                   7507:             gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
                   7508:             tcg_temp_free_i64(fp1);
                   7509:             gen_store_fpr64(ctx, fp0, fd);
                   7510:             tcg_temp_free_i64(fp0);
                   7511:         }
1.1.1.6   root     7512:         opn = "rsqrt2.ps";
                   7513:         break;
1.1.1.12  root     7514:     case OPC_CVT_S_PU:
1.1.1.6   root     7515:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7516:         {
                   7517:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7518: 
                   7519:             gen_load_fpr32h(fp0, fs);
                   7520:             gen_helper_float_cvts_pu(fp0, fp0);
                   7521:             gen_store_fpr32(fp0, fd);
                   7522:             tcg_temp_free_i32(fp0);
                   7523:         }
1.1.1.6   root     7524:         opn = "cvt.s.pu";
                   7525:         break;
1.1.1.12  root     7526:     case OPC_CVT_PW_PS:
1.1.1.6   root     7527:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7528:         {
                   7529:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7530: 
                   7531:             gen_load_fpr64(ctx, fp0, fs);
                   7532:             gen_helper_float_cvtpw_ps(fp0, fp0);
                   7533:             gen_store_fpr64(ctx, fp0, fd);
                   7534:             tcg_temp_free_i64(fp0);
                   7535:         }
1.1.1.6   root     7536:         opn = "cvt.pw.ps";
1.1.1.4   root     7537:         break;
1.1.1.12  root     7538:     case OPC_CVT_S_PL:
1.1.1.6   root     7539:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7540:         {
                   7541:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7542: 
                   7543:             gen_load_fpr32(fp0, fs);
                   7544:             gen_helper_float_cvts_pl(fp0, fp0);
                   7545:             gen_store_fpr32(fp0, fd);
                   7546:             tcg_temp_free_i32(fp0);
                   7547:         }
1.1.1.6   root     7548:         opn = "cvt.s.pl";
1.1.1.4   root     7549:         break;
1.1.1.12  root     7550:     case OPC_PLL_PS:
1.1.1.6   root     7551:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7552:         {
                   7553:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7554:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   7555: 
                   7556:             gen_load_fpr32(fp0, fs);
                   7557:             gen_load_fpr32(fp1, ft);
                   7558:             gen_store_fpr32h(fp0, fd);
                   7559:             gen_store_fpr32(fp1, fd);
                   7560:             tcg_temp_free_i32(fp0);
                   7561:             tcg_temp_free_i32(fp1);
                   7562:         }
1.1.1.6   root     7563:         opn = "pll.ps";
1.1.1.4   root     7564:         break;
1.1.1.12  root     7565:     case OPC_PLU_PS:
1.1.1.6   root     7566:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7567:         {
                   7568:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7569:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   7570: 
                   7571:             gen_load_fpr32(fp0, fs);
                   7572:             gen_load_fpr32h(fp1, ft);
                   7573:             gen_store_fpr32(fp1, fd);
                   7574:             gen_store_fpr32h(fp0, fd);
                   7575:             tcg_temp_free_i32(fp0);
                   7576:             tcg_temp_free_i32(fp1);
                   7577:         }
1.1.1.6   root     7578:         opn = "plu.ps";
                   7579:         break;
1.1.1.12  root     7580:     case OPC_PUL_PS:
1.1.1.6   root     7581:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7582:         {
                   7583:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7584:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   7585: 
                   7586:             gen_load_fpr32h(fp0, fs);
                   7587:             gen_load_fpr32(fp1, ft);
                   7588:             gen_store_fpr32(fp1, fd);
                   7589:             gen_store_fpr32h(fp0, fd);
                   7590:             tcg_temp_free_i32(fp0);
                   7591:             tcg_temp_free_i32(fp1);
                   7592:         }
1.1.1.6   root     7593:         opn = "pul.ps";
1.1.1.4   root     7594:         break;
1.1.1.12  root     7595:     case OPC_PUU_PS:
1.1.1.6   root     7596:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7597:         {
                   7598:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7599:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   7600: 
                   7601:             gen_load_fpr32h(fp0, fs);
                   7602:             gen_load_fpr32h(fp1, ft);
                   7603:             gen_store_fpr32(fp1, fd);
                   7604:             gen_store_fpr32h(fp0, fd);
                   7605:             tcg_temp_free_i32(fp0);
                   7606:             tcg_temp_free_i32(fp1);
                   7607:         }
1.1.1.6   root     7608:         opn = "puu.ps";
                   7609:         break;
1.1.1.12  root     7610:     case OPC_CMP_F_PS:
                   7611:     case OPC_CMP_UN_PS:
                   7612:     case OPC_CMP_EQ_PS:
                   7613:     case OPC_CMP_UEQ_PS:
                   7614:     case OPC_CMP_OLT_PS:
                   7615:     case OPC_CMP_ULT_PS:
                   7616:     case OPC_CMP_OLE_PS:
                   7617:     case OPC_CMP_ULE_PS:
                   7618:     case OPC_CMP_SF_PS:
                   7619:     case OPC_CMP_NGLE_PS:
                   7620:     case OPC_CMP_SEQ_PS:
                   7621:     case OPC_CMP_NGL_PS:
                   7622:     case OPC_CMP_LT_PS:
                   7623:     case OPC_CMP_NGE_PS:
                   7624:     case OPC_CMP_LE_PS:
                   7625:     case OPC_CMP_NGT_PS:
                   7626:         if (ctx->opcode & (1 << 6)) {
                   7627:             gen_cmpabs_ps(ctx, func-48, ft, fs, cc);
                   7628:             opn = condnames_abs[func-48];
                   7629:         } else {
                   7630:             gen_cmp_ps(ctx, func-48, ft, fs, cc);
                   7631:             opn = condnames[func-48];
1.1.1.6   root     7632:         }
1.1.1.4   root     7633:         break;
1.1.1.6   root     7634:     default:
                   7635:         MIPS_INVAL(opn);
                   7636:         generate_exception (ctx, EXCP_RI);
                   7637:         return;
                   7638:     }
1.1.1.13  root     7639:     (void)opn; /* avoid a compiler warning */
1.1.1.6   root     7640:     switch (optype) {
                   7641:     case BINOP:
                   7642:         MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
                   7643:         break;
                   7644:     case CMPOP:
                   7645:         MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
                   7646:         break;
                   7647:     default:
                   7648:         MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
                   7649:         break;
                   7650:     }
                   7651: }
                   7652: 
                   7653: /* Coprocessor 3 (FPU) */
                   7654: static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
                   7655:                            int fd, int fs, int base, int index)
                   7656: {
                   7657:     const char *opn = "extended float load/store";
                   7658:     int store = 0;
1.1.1.8   root     7659:     TCGv t0 = tcg_temp_new();
1.1.1.6   root     7660: 
                   7661:     if (base == 0) {
1.1.1.7   root     7662:         gen_load_gpr(t0, index);
1.1.1.6   root     7663:     } else if (index == 0) {
1.1.1.7   root     7664:         gen_load_gpr(t0, base);
1.1.1.6   root     7665:     } else {
1.1.1.7   root     7666:         gen_load_gpr(t0, index);
1.1.1.9   root     7667:         gen_op_addr_add(ctx, t0, cpu_gpr[base], t0);
1.1.1.6   root     7668:     }
                   7669:     /* Don't do NOP if destination is zero: we must perform the actual
                   7670:        memory access. */
1.1.1.8   root     7671:     save_cpu_state(ctx, 0);
1.1.1.6   root     7672:     switch (opc) {
                   7673:     case OPC_LWXC1:
                   7674:         check_cop1x(ctx);
1.1.1.7   root     7675:         {
                   7676:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7677: 
1.1.1.8   root     7678:             tcg_gen_qemu_ld32s(t0, t0, ctx->mem_idx);
                   7679:             tcg_gen_trunc_tl_i32(fp0, t0);
1.1.1.7   root     7680:             gen_store_fpr32(fp0, fd);
                   7681:             tcg_temp_free_i32(fp0);
                   7682:         }
1.1.1.6   root     7683:         opn = "lwxc1";
                   7684:         break;
                   7685:     case OPC_LDXC1:
                   7686:         check_cop1x(ctx);
                   7687:         check_cp1_registers(ctx, fd);
1.1.1.7   root     7688:         {
                   7689:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7690: 
                   7691:             tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
                   7692:             gen_store_fpr64(ctx, fp0, fd);
                   7693:             tcg_temp_free_i64(fp0);
                   7694:         }
1.1.1.6   root     7695:         opn = "ldxc1";
                   7696:         break;
                   7697:     case OPC_LUXC1:
                   7698:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7699:         tcg_gen_andi_tl(t0, t0, ~0x7);
                   7700:         {
                   7701:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7702: 
                   7703:             tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
                   7704:             gen_store_fpr64(ctx, fp0, fd);
                   7705:             tcg_temp_free_i64(fp0);
                   7706:         }
1.1.1.6   root     7707:         opn = "luxc1";
                   7708:         break;
                   7709:     case OPC_SWXC1:
                   7710:         check_cop1x(ctx);
1.1.1.7   root     7711:         {
                   7712:             TCGv_i32 fp0 = tcg_temp_new_i32();
1.1.1.8   root     7713:             TCGv t1 = tcg_temp_new();
1.1.1.7   root     7714: 
                   7715:             gen_load_fpr32(fp0, fs);
                   7716:             tcg_gen_extu_i32_tl(t1, fp0);
                   7717:             tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
                   7718:             tcg_temp_free_i32(fp0);
1.1.1.8   root     7719:             tcg_temp_free(t1);
1.1.1.7   root     7720:         }
1.1.1.6   root     7721:         opn = "swxc1";
                   7722:         store = 1;
1.1.1.4   root     7723:         break;
1.1.1.6   root     7724:     case OPC_SDXC1:
                   7725:         check_cop1x(ctx);
                   7726:         check_cp1_registers(ctx, fs);
1.1.1.7   root     7727:         {
                   7728:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7729: 
                   7730:             gen_load_fpr64(ctx, fp0, fs);
                   7731:             tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
                   7732:             tcg_temp_free_i64(fp0);
                   7733:         }
1.1.1.6   root     7734:         opn = "sdxc1";
                   7735:         store = 1;
                   7736:         break;
                   7737:     case OPC_SUXC1:
                   7738:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7739:         tcg_gen_andi_tl(t0, t0, ~0x7);
                   7740:         {
                   7741:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7742: 
                   7743:             gen_load_fpr64(ctx, fp0, fs);
                   7744:             tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
                   7745:             tcg_temp_free_i64(fp0);
                   7746:         }
1.1.1.6   root     7747:         opn = "suxc1";
                   7748:         store = 1;
                   7749:         break;
                   7750:     }
1.1.1.7   root     7751:     tcg_temp_free(t0);
1.1.1.13  root     7752:     (void)opn; (void)store; /* avoid compiler warnings */
1.1.1.6   root     7753:     MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
                   7754:                regnames[index], regnames[base]);
                   7755: }
                   7756: 
                   7757: static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
                   7758:                             int fd, int fr, int fs, int ft)
                   7759: {
                   7760:     const char *opn = "flt3_arith";
                   7761: 
                   7762:     switch (opc) {
                   7763:     case OPC_ALNV_PS:
                   7764:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7765:         {
                   7766:             TCGv t0 = tcg_temp_local_new();
1.1.1.8   root     7767:             TCGv_i32 fp = tcg_temp_new_i32();
                   7768:             TCGv_i32 fph = tcg_temp_new_i32();
1.1.1.7   root     7769:             int l1 = gen_new_label();
                   7770:             int l2 = gen_new_label();
                   7771: 
                   7772:             gen_load_gpr(t0, fr);
                   7773:             tcg_gen_andi_tl(t0, t0, 0x7);
                   7774: 
                   7775:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
1.1.1.8   root     7776:             gen_load_fpr32(fp, fs);
                   7777:             gen_load_fpr32h(fph, fs);
                   7778:             gen_store_fpr32(fp, fd);
                   7779:             gen_store_fpr32h(fph, fd);
1.1.1.7   root     7780:             tcg_gen_br(l2);
                   7781:             gen_set_label(l1);
                   7782:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
                   7783:             tcg_temp_free(t0);
                   7784: #ifdef TARGET_WORDS_BIGENDIAN
1.1.1.8   root     7785:             gen_load_fpr32(fp, fs);
                   7786:             gen_load_fpr32h(fph, ft);
                   7787:             gen_store_fpr32h(fp, fd);
                   7788:             gen_store_fpr32(fph, fd);
1.1.1.7   root     7789: #else
1.1.1.8   root     7790:             gen_load_fpr32h(fph, fs);
                   7791:             gen_load_fpr32(fp, ft);
                   7792:             gen_store_fpr32(fph, fd);
                   7793:             gen_store_fpr32h(fp, fd);
1.1.1.7   root     7794: #endif
                   7795:             gen_set_label(l2);
1.1.1.8   root     7796:             tcg_temp_free_i32(fp);
                   7797:             tcg_temp_free_i32(fph);
1.1.1.7   root     7798:         }
1.1.1.6   root     7799:         opn = "alnv.ps";
                   7800:         break;
                   7801:     case OPC_MADD_S:
                   7802:         check_cop1x(ctx);
1.1.1.7   root     7803:         {
                   7804:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7805:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   7806:             TCGv_i32 fp2 = tcg_temp_new_i32();
                   7807: 
                   7808:             gen_load_fpr32(fp0, fs);
                   7809:             gen_load_fpr32(fp1, ft);
                   7810:             gen_load_fpr32(fp2, fr);
                   7811:             gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
                   7812:             tcg_temp_free_i32(fp0);
                   7813:             tcg_temp_free_i32(fp1);
                   7814:             gen_store_fpr32(fp2, fd);
                   7815:             tcg_temp_free_i32(fp2);
                   7816:         }
1.1.1.6   root     7817:         opn = "madd.s";
1.1.1.4   root     7818:         break;
1.1.1.6   root     7819:     case OPC_MADD_D:
                   7820:         check_cop1x(ctx);
                   7821:         check_cp1_registers(ctx, fd | fs | ft | fr);
1.1.1.7   root     7822:         {
                   7823:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7824:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7825:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   7826: 
                   7827:             gen_load_fpr64(ctx, fp0, fs);
                   7828:             gen_load_fpr64(ctx, fp1, ft);
                   7829:             gen_load_fpr64(ctx, fp2, fr);
                   7830:             gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
                   7831:             tcg_temp_free_i64(fp0);
                   7832:             tcg_temp_free_i64(fp1);
                   7833:             gen_store_fpr64(ctx, fp2, fd);
                   7834:             tcg_temp_free_i64(fp2);
                   7835:         }
1.1.1.6   root     7836:         opn = "madd.d";
                   7837:         break;
                   7838:     case OPC_MADD_PS:
                   7839:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7840:         {
                   7841:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7842:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7843:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   7844: 
                   7845:             gen_load_fpr64(ctx, fp0, fs);
                   7846:             gen_load_fpr64(ctx, fp1, ft);
                   7847:             gen_load_fpr64(ctx, fp2, fr);
                   7848:             gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
                   7849:             tcg_temp_free_i64(fp0);
                   7850:             tcg_temp_free_i64(fp1);
                   7851:             gen_store_fpr64(ctx, fp2, fd);
                   7852:             tcg_temp_free_i64(fp2);
                   7853:         }
1.1.1.6   root     7854:         opn = "madd.ps";
1.1.1.4   root     7855:         break;
1.1.1.6   root     7856:     case OPC_MSUB_S:
                   7857:         check_cop1x(ctx);
1.1.1.7   root     7858:         {
                   7859:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7860:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   7861:             TCGv_i32 fp2 = tcg_temp_new_i32();
                   7862: 
                   7863:             gen_load_fpr32(fp0, fs);
                   7864:             gen_load_fpr32(fp1, ft);
                   7865:             gen_load_fpr32(fp2, fr);
                   7866:             gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
                   7867:             tcg_temp_free_i32(fp0);
                   7868:             tcg_temp_free_i32(fp1);
                   7869:             gen_store_fpr32(fp2, fd);
                   7870:             tcg_temp_free_i32(fp2);
                   7871:         }
1.1.1.6   root     7872:         opn = "msub.s";
1.1.1.4   root     7873:         break;
1.1.1.6   root     7874:     case OPC_MSUB_D:
                   7875:         check_cop1x(ctx);
                   7876:         check_cp1_registers(ctx, fd | fs | ft | fr);
1.1.1.7   root     7877:         {
                   7878:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7879:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7880:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   7881: 
                   7882:             gen_load_fpr64(ctx, fp0, fs);
                   7883:             gen_load_fpr64(ctx, fp1, ft);
                   7884:             gen_load_fpr64(ctx, fp2, fr);
                   7885:             gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
                   7886:             tcg_temp_free_i64(fp0);
                   7887:             tcg_temp_free_i64(fp1);
                   7888:             gen_store_fpr64(ctx, fp2, fd);
                   7889:             tcg_temp_free_i64(fp2);
                   7890:         }
1.1.1.6   root     7891:         opn = "msub.d";
                   7892:         break;
                   7893:     case OPC_MSUB_PS:
                   7894:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7895:         {
                   7896:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7897:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7898:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   7899: 
                   7900:             gen_load_fpr64(ctx, fp0, fs);
                   7901:             gen_load_fpr64(ctx, fp1, ft);
                   7902:             gen_load_fpr64(ctx, fp2, fr);
                   7903:             gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
                   7904:             tcg_temp_free_i64(fp0);
                   7905:             tcg_temp_free_i64(fp1);
                   7906:             gen_store_fpr64(ctx, fp2, fd);
                   7907:             tcg_temp_free_i64(fp2);
                   7908:         }
1.1.1.6   root     7909:         opn = "msub.ps";
1.1.1.4   root     7910:         break;
1.1.1.6   root     7911:     case OPC_NMADD_S:
                   7912:         check_cop1x(ctx);
1.1.1.7   root     7913:         {
                   7914:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7915:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   7916:             TCGv_i32 fp2 = tcg_temp_new_i32();
                   7917: 
                   7918:             gen_load_fpr32(fp0, fs);
                   7919:             gen_load_fpr32(fp1, ft);
                   7920:             gen_load_fpr32(fp2, fr);
                   7921:             gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
                   7922:             tcg_temp_free_i32(fp0);
                   7923:             tcg_temp_free_i32(fp1);
                   7924:             gen_store_fpr32(fp2, fd);
                   7925:             tcg_temp_free_i32(fp2);
                   7926:         }
1.1.1.6   root     7927:         opn = "nmadd.s";
1.1.1.4   root     7928:         break;
1.1.1.6   root     7929:     case OPC_NMADD_D:
                   7930:         check_cop1x(ctx);
                   7931:         check_cp1_registers(ctx, fd | fs | ft | fr);
1.1.1.7   root     7932:         {
                   7933:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7934:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7935:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   7936: 
                   7937:             gen_load_fpr64(ctx, fp0, fs);
                   7938:             gen_load_fpr64(ctx, fp1, ft);
                   7939:             gen_load_fpr64(ctx, fp2, fr);
                   7940:             gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
                   7941:             tcg_temp_free_i64(fp0);
                   7942:             tcg_temp_free_i64(fp1);
                   7943:             gen_store_fpr64(ctx, fp2, fd);
                   7944:             tcg_temp_free_i64(fp2);
                   7945:         }
1.1.1.6   root     7946:         opn = "nmadd.d";
1.1.1.5   root     7947:         break;
1.1.1.6   root     7948:     case OPC_NMADD_PS:
                   7949:         check_cp1_64bitmode(ctx);
1.1.1.7   root     7950:         {
                   7951:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7952:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7953:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   7954: 
                   7955:             gen_load_fpr64(ctx, fp0, fs);
                   7956:             gen_load_fpr64(ctx, fp1, ft);
                   7957:             gen_load_fpr64(ctx, fp2, fr);
                   7958:             gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
                   7959:             tcg_temp_free_i64(fp0);
                   7960:             tcg_temp_free_i64(fp1);
                   7961:             gen_store_fpr64(ctx, fp2, fd);
                   7962:             tcg_temp_free_i64(fp2);
                   7963:         }
1.1.1.6   root     7964:         opn = "nmadd.ps";
1.1.1.4   root     7965:         break;
1.1.1.6   root     7966:     case OPC_NMSUB_S:
                   7967:         check_cop1x(ctx);
1.1.1.7   root     7968:         {
                   7969:             TCGv_i32 fp0 = tcg_temp_new_i32();
                   7970:             TCGv_i32 fp1 = tcg_temp_new_i32();
                   7971:             TCGv_i32 fp2 = tcg_temp_new_i32();
                   7972: 
                   7973:             gen_load_fpr32(fp0, fs);
                   7974:             gen_load_fpr32(fp1, ft);
                   7975:             gen_load_fpr32(fp2, fr);
                   7976:             gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
                   7977:             tcg_temp_free_i32(fp0);
                   7978:             tcg_temp_free_i32(fp1);
                   7979:             gen_store_fpr32(fp2, fd);
                   7980:             tcg_temp_free_i32(fp2);
                   7981:         }
1.1.1.6   root     7982:         opn = "nmsub.s";
1.1.1.4   root     7983:         break;
1.1.1.6   root     7984:     case OPC_NMSUB_D:
                   7985:         check_cop1x(ctx);
                   7986:         check_cp1_registers(ctx, fd | fs | ft | fr);
1.1.1.7   root     7987:         {
                   7988:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   7989:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   7990:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   7991: 
                   7992:             gen_load_fpr64(ctx, fp0, fs);
                   7993:             gen_load_fpr64(ctx, fp1, ft);
                   7994:             gen_load_fpr64(ctx, fp2, fr);
                   7995:             gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
                   7996:             tcg_temp_free_i64(fp0);
                   7997:             tcg_temp_free_i64(fp1);
                   7998:             gen_store_fpr64(ctx, fp2, fd);
                   7999:             tcg_temp_free_i64(fp2);
                   8000:         }
1.1.1.6   root     8001:         opn = "nmsub.d";
1.1.1.4   root     8002:         break;
1.1.1.6   root     8003:     case OPC_NMSUB_PS:
                   8004:         check_cp1_64bitmode(ctx);
1.1.1.7   root     8005:         {
                   8006:             TCGv_i64 fp0 = tcg_temp_new_i64();
                   8007:             TCGv_i64 fp1 = tcg_temp_new_i64();
                   8008:             TCGv_i64 fp2 = tcg_temp_new_i64();
                   8009: 
                   8010:             gen_load_fpr64(ctx, fp0, fs);
                   8011:             gen_load_fpr64(ctx, fp1, ft);
                   8012:             gen_load_fpr64(ctx, fp2, fr);
                   8013:             gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
                   8014:             tcg_temp_free_i64(fp0);
                   8015:             tcg_temp_free_i64(fp1);
                   8016:             gen_store_fpr64(ctx, fp2, fd);
                   8017:             tcg_temp_free_i64(fp2);
                   8018:         }
1.1.1.6   root     8019:         opn = "nmsub.ps";
1.1.1.4   root     8020:         break;
1.1.1.6   root     8021:     default:
                   8022:         MIPS_INVAL(opn);
                   8023:         generate_exception (ctx, EXCP_RI);
1.1.1.4   root     8024:         return;
                   8025:     }
1.1.1.13  root     8026:     (void)opn; /* avoid a compiler warning */
1.1.1.6   root     8027:     MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
                   8028:                fregnames[fs], fregnames[ft]);
1.1       root     8029: }
                   8030: 
1.1.1.12  root     8031: static void
                   8032: gen_rdhwr (CPUState *env, DisasContext *ctx, int rt, int rd)
                   8033: {
                   8034:     TCGv t0;
1.1       root     8035: 
1.1.1.12  root     8036:     check_insn(env, ctx, ISA_MIPS32R2);
                   8037:     t0 = tcg_temp_new();
1.1       root     8038: 
1.1.1.12  root     8039:     switch (rd) {
                   8040:     case 0:
                   8041:         save_cpu_state(ctx, 1);
                   8042:         gen_helper_rdhwr_cpunum(t0);
                   8043:         gen_store_gpr(t0, rt);
                   8044:         break;
                   8045:     case 1:
                   8046:         save_cpu_state(ctx, 1);
                   8047:         gen_helper_rdhwr_synci_step(t0);
                   8048:         gen_store_gpr(t0, rt);
                   8049:         break;
                   8050:     case 2:
                   8051:         save_cpu_state(ctx, 1);
                   8052:         gen_helper_rdhwr_cc(t0);
                   8053:         gen_store_gpr(t0, rt);
                   8054:         break;
                   8055:     case 3:
                   8056:         save_cpu_state(ctx, 1);
                   8057:         gen_helper_rdhwr_ccres(t0);
                   8058:         gen_store_gpr(t0, rt);
                   8059:         break;
                   8060:     case 29:
                   8061: #if defined(CONFIG_USER_ONLY)
                   8062:         tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
                   8063:         gen_store_gpr(t0, rt);
                   8064:         break;
                   8065: #else
                   8066:         /* XXX: Some CPUs implement this in hardware.
                   8067:            Not supported yet. */
1.1       root     8068: #endif
1.1.1.12  root     8069:     default:            /* Invalid */
                   8070:         MIPS_INVAL("rdhwr");
                   8071:         generate_exception(ctx, EXCP_RI);
                   8072:         break;
1.1.1.4   root     8073:     }
1.1.1.12  root     8074:     tcg_temp_free(t0);
                   8075: }
1.1.1.4   root     8076: 
1.1.1.12  root     8077: static void handle_delay_slot (CPUState *env, DisasContext *ctx,
                   8078:                                int insn_bytes)
                   8079: {
                   8080:     if (ctx->hflags & MIPS_HFLAG_BMASK) {
                   8081:         int proc_hflags = ctx->hflags & MIPS_HFLAG_BMASK;
                   8082:         /* Branches completion */
                   8083:         ctx->hflags &= ~MIPS_HFLAG_BMASK;
                   8084:         ctx->bstate = BS_BRANCH;
                   8085:         save_cpu_state(ctx, 0);
                   8086:         /* FIXME: Need to clear can_do_io.  */
                   8087:         switch (proc_hflags & MIPS_HFLAG_BMASK_BASE) {
                   8088:         case MIPS_HFLAG_B:
                   8089:             /* unconditional branch */
                   8090:             MIPS_DEBUG("unconditional branch");
                   8091:             if (proc_hflags & MIPS_HFLAG_BX) {
                   8092:                 tcg_gen_xori_i32(hflags, hflags, MIPS_HFLAG_M16);
                   8093:             }
                   8094:             gen_goto_tb(ctx, 0, ctx->btarget);
                   8095:             break;
                   8096:         case MIPS_HFLAG_BL:
                   8097:             /* blikely taken case */
                   8098:             MIPS_DEBUG("blikely branch taken");
                   8099:             gen_goto_tb(ctx, 0, ctx->btarget);
                   8100:             break;
                   8101:         case MIPS_HFLAG_BC:
                   8102:             /* Conditional branch */
                   8103:             MIPS_DEBUG("conditional branch");
                   8104:             {
                   8105:                 int l1 = gen_new_label();
1.1.1.7   root     8106: 
1.1.1.12  root     8107:                 tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
                   8108:                 gen_goto_tb(ctx, 1, ctx->pc + insn_bytes);
                   8109:                 gen_set_label(l1);
                   8110:                 gen_goto_tb(ctx, 0, ctx->btarget);
                   8111:             }
                   8112:             break;
                   8113:         case MIPS_HFLAG_BR:
                   8114:             /* unconditional branch to register */
                   8115:             MIPS_DEBUG("branch to register");
                   8116:             if (env->insn_flags & (ASE_MIPS16 | ASE_MICROMIPS)) {
                   8117:                 TCGv t0 = tcg_temp_new();
                   8118:                 TCGv_i32 t1 = tcg_temp_new_i32();
                   8119: 
                   8120:                 tcg_gen_andi_tl(t0, btarget, 0x1);
                   8121:                 tcg_gen_trunc_tl_i32(t1, t0);
                   8122:                 tcg_temp_free(t0);
                   8123:                 tcg_gen_andi_i32(hflags, hflags, ~(uint32_t)MIPS_HFLAG_M16);
                   8124:                 tcg_gen_shli_i32(t1, t1, MIPS_HFLAG_M16_SHIFT);
                   8125:                 tcg_gen_or_i32(hflags, hflags, t1);
                   8126:                 tcg_temp_free_i32(t1);
                   8127: 
                   8128:                 tcg_gen_andi_tl(cpu_PC, btarget, ~(target_ulong)0x1);
                   8129:             } else {
                   8130:                 tcg_gen_mov_tl(cpu_PC, btarget);
                   8131:             }
                   8132:             if (ctx->singlestep_enabled) {
                   8133:                 save_cpu_state(ctx, 0);
                   8134:                 gen_helper_0i(raise_exception, EXCP_DEBUG);
                   8135:             }
                   8136:             tcg_gen_exit_tb(0);
                   8137:             break;
                   8138:         default:
                   8139:             MIPS_DEBUG("unknown branch");
                   8140:             break;
                   8141:         }
                   8142:     }
                   8143: }
                   8144: 
                   8145: /* ISA extensions (ASEs) */
                   8146: /* MIPS16 extension to MIPS32 */
                   8147: 
                   8148: /* MIPS16 major opcodes */
                   8149: enum {
                   8150:   M16_OPC_ADDIUSP = 0x00,
                   8151:   M16_OPC_ADDIUPC = 0x01,
                   8152:   M16_OPC_B = 0x02,
                   8153:   M16_OPC_JAL = 0x03,
                   8154:   M16_OPC_BEQZ = 0x04,
                   8155:   M16_OPC_BNEQZ = 0x05,
                   8156:   M16_OPC_SHIFT = 0x06,
                   8157:   M16_OPC_LD = 0x07,
                   8158:   M16_OPC_RRIA = 0x08,
                   8159:   M16_OPC_ADDIU8 = 0x09,
                   8160:   M16_OPC_SLTI = 0x0a,
                   8161:   M16_OPC_SLTIU = 0x0b,
                   8162:   M16_OPC_I8 = 0x0c,
                   8163:   M16_OPC_LI = 0x0d,
                   8164:   M16_OPC_CMPI = 0x0e,
                   8165:   M16_OPC_SD = 0x0f,
                   8166:   M16_OPC_LB = 0x10,
                   8167:   M16_OPC_LH = 0x11,
                   8168:   M16_OPC_LWSP = 0x12,
                   8169:   M16_OPC_LW = 0x13,
                   8170:   M16_OPC_LBU = 0x14,
                   8171:   M16_OPC_LHU = 0x15,
                   8172:   M16_OPC_LWPC = 0x16,
                   8173:   M16_OPC_LWU = 0x17,
                   8174:   M16_OPC_SB = 0x18,
                   8175:   M16_OPC_SH = 0x19,
                   8176:   M16_OPC_SWSP = 0x1a,
                   8177:   M16_OPC_SW = 0x1b,
                   8178:   M16_OPC_RRR = 0x1c,
                   8179:   M16_OPC_RR = 0x1d,
                   8180:   M16_OPC_EXTEND = 0x1e,
                   8181:   M16_OPC_I64 = 0x1f
                   8182: };
                   8183: 
                   8184: /* I8 funct field */
                   8185: enum {
                   8186:   I8_BTEQZ = 0x0,
                   8187:   I8_BTNEZ = 0x1,
                   8188:   I8_SWRASP = 0x2,
                   8189:   I8_ADJSP = 0x3,
                   8190:   I8_SVRS = 0x4,
                   8191:   I8_MOV32R = 0x5,
                   8192:   I8_MOVR32 = 0x7
                   8193: };
                   8194: 
                   8195: /* RRR f field */
                   8196: enum {
                   8197:   RRR_DADDU = 0x0,
                   8198:   RRR_ADDU = 0x1,
                   8199:   RRR_DSUBU = 0x2,
                   8200:   RRR_SUBU = 0x3
                   8201: };
                   8202: 
                   8203: /* RR funct field */
                   8204: enum {
                   8205:   RR_JR = 0x00,
                   8206:   RR_SDBBP = 0x01,
                   8207:   RR_SLT = 0x02,
                   8208:   RR_SLTU = 0x03,
                   8209:   RR_SLLV = 0x04,
                   8210:   RR_BREAK = 0x05,
                   8211:   RR_SRLV = 0x06,
                   8212:   RR_SRAV = 0x07,
                   8213:   RR_DSRL = 0x08,
                   8214:   RR_CMP = 0x0a,
                   8215:   RR_NEG = 0x0b,
                   8216:   RR_AND = 0x0c,
                   8217:   RR_OR = 0x0d,
                   8218:   RR_XOR = 0x0e,
                   8219:   RR_NOT = 0x0f,
                   8220:   RR_MFHI = 0x10,
                   8221:   RR_CNVT = 0x11,
                   8222:   RR_MFLO = 0x12,
                   8223:   RR_DSRA = 0x13,
                   8224:   RR_DSLLV = 0x14,
                   8225:   RR_DSRLV = 0x16,
                   8226:   RR_DSRAV = 0x17,
                   8227:   RR_MULT = 0x18,
                   8228:   RR_MULTU = 0x19,
                   8229:   RR_DIV = 0x1a,
                   8230:   RR_DIVU = 0x1b,
                   8231:   RR_DMULT = 0x1c,
                   8232:   RR_DMULTU = 0x1d,
                   8233:   RR_DDIV = 0x1e,
                   8234:   RR_DDIVU = 0x1f
                   8235: };
                   8236: 
                   8237: /* I64 funct field */
                   8238: enum {
                   8239:   I64_LDSP = 0x0,
                   8240:   I64_SDSP = 0x1,
                   8241:   I64_SDRASP = 0x2,
                   8242:   I64_DADJSP = 0x3,
                   8243:   I64_LDPC = 0x4,
                   8244:   I64_DADDIU5 = 0x5,
                   8245:   I64_DADDIUPC = 0x6,
                   8246:   I64_DADDIUSP = 0x7
                   8247: };
                   8248: 
                   8249: /* RR ry field for CNVT */
                   8250: enum {
                   8251:   RR_RY_CNVT_ZEB = 0x0,
                   8252:   RR_RY_CNVT_ZEH = 0x1,
                   8253:   RR_RY_CNVT_ZEW = 0x2,
                   8254:   RR_RY_CNVT_SEB = 0x4,
                   8255:   RR_RY_CNVT_SEH = 0x5,
                   8256:   RR_RY_CNVT_SEW = 0x6,
                   8257: };
                   8258: 
                   8259: static int xlat (int r)
                   8260: {
                   8261:   static int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
                   8262: 
                   8263:   return map[r];
                   8264: }
                   8265: 
                   8266: static void gen_mips16_save (DisasContext *ctx,
                   8267:                              int xsregs, int aregs,
                   8268:                              int do_ra, int do_s0, int do_s1,
                   8269:                              int framesize)
                   8270: {
                   8271:     TCGv t0 = tcg_temp_new();
                   8272:     TCGv t1 = tcg_temp_new();
                   8273:     int args, astatic;
                   8274: 
                   8275:     switch (aregs) {
                   8276:     case 0:
                   8277:     case 1:
                   8278:     case 2:
                   8279:     case 3:
                   8280:     case 11:
                   8281:         args = 0;
                   8282:         break;
                   8283:     case 4:
                   8284:     case 5:
                   8285:     case 6:
                   8286:     case 7:
                   8287:         args = 1;
                   8288:         break;
                   8289:     case 8:
                   8290:     case 9:
                   8291:     case 10:
                   8292:         args = 2;
                   8293:         break;
                   8294:     case 12:
                   8295:     case 13:
                   8296:         args = 3;
                   8297:         break;
                   8298:     case 14:
                   8299:         args = 4;
                   8300:         break;
                   8301:     default:
                   8302:         generate_exception(ctx, EXCP_RI);
                   8303:         return;
                   8304:     }
                   8305: 
                   8306:     switch (args) {
                   8307:     case 4:
                   8308:         gen_base_offset_addr(ctx, t0, 29, 12);
                   8309:         gen_load_gpr(t1, 7);
                   8310:         op_st_sw(t1, t0, ctx);
                   8311:         /* Fall through */
                   8312:     case 3:
                   8313:         gen_base_offset_addr(ctx, t0, 29, 8);
                   8314:         gen_load_gpr(t1, 6);
                   8315:         op_st_sw(t1, t0, ctx);
                   8316:         /* Fall through */
                   8317:     case 2:
                   8318:         gen_base_offset_addr(ctx, t0, 29, 4);
                   8319:         gen_load_gpr(t1, 5);
                   8320:         op_st_sw(t1, t0, ctx);
                   8321:         /* Fall through */
                   8322:     case 1:
                   8323:         gen_base_offset_addr(ctx, t0, 29, 0);
                   8324:         gen_load_gpr(t1, 4);
                   8325:         op_st_sw(t1, t0, ctx);
                   8326:     }
                   8327: 
                   8328:     gen_load_gpr(t0, 29);
                   8329: 
                   8330: #define DECR_AND_STORE(reg) do {                \
                   8331:         tcg_gen_subi_tl(t0, t0, 4);             \
                   8332:         gen_load_gpr(t1, reg);                  \
                   8333:         op_st_sw(t1, t0, ctx);                  \
                   8334:     } while (0)
                   8335: 
                   8336:     if (do_ra) {
                   8337:         DECR_AND_STORE(31);
                   8338:     }
                   8339: 
                   8340:     switch (xsregs) {
                   8341:     case 7:
                   8342:         DECR_AND_STORE(30);
                   8343:         /* Fall through */
                   8344:     case 6:
                   8345:         DECR_AND_STORE(23);
                   8346:         /* Fall through */
                   8347:     case 5:
                   8348:         DECR_AND_STORE(22);
                   8349:         /* Fall through */
                   8350:     case 4:
                   8351:         DECR_AND_STORE(21);
                   8352:         /* Fall through */
                   8353:     case 3:
                   8354:         DECR_AND_STORE(20);
                   8355:         /* Fall through */
                   8356:     case 2:
                   8357:         DECR_AND_STORE(19);
                   8358:         /* Fall through */
                   8359:     case 1:
                   8360:         DECR_AND_STORE(18);
                   8361:     }
                   8362: 
                   8363:     if (do_s1) {
                   8364:         DECR_AND_STORE(17);
                   8365:     }
                   8366:     if (do_s0) {
                   8367:         DECR_AND_STORE(16);
                   8368:     }
                   8369: 
                   8370:     switch (aregs) {
                   8371:     case 0:
                   8372:     case 4:
                   8373:     case 8:
                   8374:     case 12:
                   8375:     case 14:
                   8376:         astatic = 0;
                   8377:         break;
                   8378:     case 1:
                   8379:     case 5:
                   8380:     case 9:
                   8381:     case 13:
                   8382:         astatic = 1;
                   8383:         break;
                   8384:     case 2:
                   8385:     case 6:
                   8386:     case 10:
                   8387:         astatic = 2;
                   8388:         break;
                   8389:     case 3:
                   8390:     case 7:
                   8391:         astatic = 3;
                   8392:         break;
                   8393:     case 11:
                   8394:         astatic = 4;
                   8395:         break;
                   8396:     default:
                   8397:         generate_exception(ctx, EXCP_RI);
                   8398:         return;
                   8399:     }
                   8400: 
                   8401:     if (astatic > 0) {
                   8402:         DECR_AND_STORE(7);
                   8403:         if (astatic > 1) {
                   8404:             DECR_AND_STORE(6);
                   8405:             if (astatic > 2) {
                   8406:                 DECR_AND_STORE(5);
                   8407:                 if (astatic > 3) {
                   8408:                     DECR_AND_STORE(4);
                   8409:                 }
                   8410:             }
                   8411:         }
                   8412:     }
                   8413: #undef DECR_AND_STORE
                   8414: 
                   8415:     tcg_gen_subi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
                   8416:     tcg_temp_free(t0);
                   8417:     tcg_temp_free(t1);
                   8418: }
                   8419: 
                   8420: static void gen_mips16_restore (DisasContext *ctx,
                   8421:                                 int xsregs, int aregs,
                   8422:                                 int do_ra, int do_s0, int do_s1,
                   8423:                                 int framesize)
                   8424: {
                   8425:     int astatic;
                   8426:     TCGv t0 = tcg_temp_new();
                   8427:     TCGv t1 = tcg_temp_new();
                   8428: 
                   8429:     tcg_gen_addi_tl(t0, cpu_gpr[29], framesize);
                   8430: 
                   8431: #define DECR_AND_LOAD(reg) do {                 \
                   8432:         tcg_gen_subi_tl(t0, t0, 4);             \
                   8433:         op_ld_lw(t1, t0, ctx);                  \
                   8434:         gen_store_gpr(t1, reg);                 \
                   8435:     } while (0)
                   8436: 
                   8437:     if (do_ra) {
                   8438:         DECR_AND_LOAD(31);
                   8439:     }
                   8440: 
                   8441:     switch (xsregs) {
                   8442:     case 7:
                   8443:         DECR_AND_LOAD(30);
                   8444:         /* Fall through */
                   8445:     case 6:
                   8446:         DECR_AND_LOAD(23);
                   8447:         /* Fall through */
                   8448:     case 5:
                   8449:         DECR_AND_LOAD(22);
                   8450:         /* Fall through */
                   8451:     case 4:
                   8452:         DECR_AND_LOAD(21);
                   8453:         /* Fall through */
                   8454:     case 3:
                   8455:         DECR_AND_LOAD(20);
                   8456:         /* Fall through */
                   8457:     case 2:
                   8458:         DECR_AND_LOAD(19);
                   8459:         /* Fall through */
                   8460:     case 1:
                   8461:         DECR_AND_LOAD(18);
                   8462:     }
                   8463: 
                   8464:     if (do_s1) {
                   8465:         DECR_AND_LOAD(17);
                   8466:     }
                   8467:     if (do_s0) {
                   8468:         DECR_AND_LOAD(16);
                   8469:     }
                   8470: 
                   8471:     switch (aregs) {
                   8472:     case 0:
                   8473:     case 4:
                   8474:     case 8:
                   8475:     case 12:
                   8476:     case 14:
                   8477:         astatic = 0;
                   8478:         break;
                   8479:     case 1:
                   8480:     case 5:
                   8481:     case 9:
                   8482:     case 13:
                   8483:         astatic = 1;
                   8484:         break;
                   8485:     case 2:
                   8486:     case 6:
                   8487:     case 10:
                   8488:         astatic = 2;
                   8489:         break;
                   8490:     case 3:
                   8491:     case 7:
                   8492:         astatic = 3;
                   8493:         break;
                   8494:     case 11:
                   8495:         astatic = 4;
                   8496:         break;
                   8497:     default:
                   8498:         generate_exception(ctx, EXCP_RI);
                   8499:         return;
                   8500:     }
                   8501: 
                   8502:     if (astatic > 0) {
                   8503:         DECR_AND_LOAD(7);
                   8504:         if (astatic > 1) {
                   8505:             DECR_AND_LOAD(6);
                   8506:             if (astatic > 2) {
                   8507:                 DECR_AND_LOAD(5);
                   8508:                 if (astatic > 3) {
                   8509:                     DECR_AND_LOAD(4);
                   8510:                 }
                   8511:             }
                   8512:         }
                   8513:     }
                   8514: #undef DECR_AND_LOAD
                   8515: 
                   8516:     tcg_gen_addi_tl(cpu_gpr[29], cpu_gpr[29], framesize);
                   8517:     tcg_temp_free(t0);
                   8518:     tcg_temp_free(t1);
                   8519: }
                   8520: 
                   8521: static void gen_addiupc (DisasContext *ctx, int rx, int imm,
                   8522:                          int is_64_bit, int extended)
                   8523: {
                   8524:     TCGv t0;
                   8525: 
                   8526:     if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
                   8527:         generate_exception(ctx, EXCP_RI);
                   8528:         return;
                   8529:     }
                   8530: 
                   8531:     t0 = tcg_temp_new();
                   8532: 
                   8533:     tcg_gen_movi_tl(t0, pc_relative_pc(ctx));
                   8534:     tcg_gen_addi_tl(cpu_gpr[rx], t0, imm);
                   8535:     if (!is_64_bit) {
                   8536:         tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
                   8537:     }
                   8538: 
                   8539:     tcg_temp_free(t0);
                   8540: }
                   8541: 
                   8542: #if defined(TARGET_MIPS64)
                   8543: static void decode_i64_mips16 (CPUState *env, DisasContext *ctx,
                   8544:                                int ry, int funct, int16_t offset,
                   8545:                                int extended)
                   8546: {
                   8547:     switch (funct) {
                   8548:     case I64_LDSP:
                   8549:         check_mips_64(ctx);
                   8550:         offset = extended ? offset : offset << 3;
                   8551:         gen_ld(env, ctx, OPC_LD, ry, 29, offset);
                   8552:         break;
                   8553:     case I64_SDSP:
                   8554:         check_mips_64(ctx);
                   8555:         offset = extended ? offset : offset << 3;
                   8556:         gen_st(ctx, OPC_SD, ry, 29, offset);
                   8557:         break;
                   8558:     case I64_SDRASP:
                   8559:         check_mips_64(ctx);
                   8560:         offset = extended ? offset : (ctx->opcode & 0xff) << 3;
                   8561:         gen_st(ctx, OPC_SD, 31, 29, offset);
                   8562:         break;
                   8563:     case I64_DADJSP:
                   8564:         check_mips_64(ctx);
                   8565:         offset = extended ? offset : ((int8_t)ctx->opcode) << 3;
                   8566:         gen_arith_imm(env, ctx, OPC_DADDIU, 29, 29, offset);
                   8567:         break;
                   8568:     case I64_LDPC:
                   8569:         if (extended && (ctx->hflags & MIPS_HFLAG_BMASK)) {
                   8570:             generate_exception(ctx, EXCP_RI);
                   8571:         } else {
                   8572:             offset = extended ? offset : offset << 3;
                   8573:             gen_ld(env, ctx, OPC_LDPC, ry, 0, offset);
                   8574:         }
                   8575:         break;
                   8576:     case I64_DADDIU5:
                   8577:         check_mips_64(ctx);
                   8578:         offset = extended ? offset : ((int8_t)(offset << 3)) >> 3;
                   8579:         gen_arith_imm(env, ctx, OPC_DADDIU, ry, ry, offset);
                   8580:         break;
                   8581:     case I64_DADDIUPC:
                   8582:         check_mips_64(ctx);
                   8583:         offset = extended ? offset : offset << 2;
                   8584:         gen_addiupc(ctx, ry, offset, 1, extended);
                   8585:         break;
                   8586:     case I64_DADDIUSP:
                   8587:         check_mips_64(ctx);
                   8588:         offset = extended ? offset : offset << 2;
                   8589:         gen_arith_imm(env, ctx, OPC_DADDIU, ry, 29, offset);
                   8590:         break;
                   8591:     }
                   8592: }
                   8593: #endif
                   8594: 
                   8595: static int decode_extended_mips16_opc (CPUState *env, DisasContext *ctx,
                   8596:                                        int *is_branch)
                   8597: {
                   8598:     int extend = lduw_code(ctx->pc + 2);
                   8599:     int op, rx, ry, funct, sa;
                   8600:     int16_t imm, offset;
                   8601: 
                   8602:     ctx->opcode = (ctx->opcode << 16) | extend;
                   8603:     op = (ctx->opcode >> 11) & 0x1f;
                   8604:     sa = (ctx->opcode >> 22) & 0x1f;
                   8605:     funct = (ctx->opcode >> 8) & 0x7;
                   8606:     rx = xlat((ctx->opcode >> 8) & 0x7);
                   8607:     ry = xlat((ctx->opcode >> 5) & 0x7);
                   8608:     offset = imm = (int16_t) (((ctx->opcode >> 16) & 0x1f) << 11
                   8609:                               | ((ctx->opcode >> 21) & 0x3f) << 5
                   8610:                               | (ctx->opcode & 0x1f));
                   8611: 
                   8612:     /* The extended opcodes cleverly reuse the opcodes from their 16-bit
                   8613:        counterparts.  */
                   8614:     switch (op) {
                   8615:     case M16_OPC_ADDIUSP:
                   8616:         gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
                   8617:         break;
                   8618:     case M16_OPC_ADDIUPC:
                   8619:         gen_addiupc(ctx, rx, imm, 0, 1);
                   8620:         break;
                   8621:     case M16_OPC_B:
                   8622:         gen_compute_branch(ctx, OPC_BEQ, 4, 0, 0, offset << 1);
                   8623:         /* No delay slot, so just process as a normal instruction */
                   8624:         break;
                   8625:     case M16_OPC_BEQZ:
                   8626:         gen_compute_branch(ctx, OPC_BEQ, 4, rx, 0, offset << 1);
                   8627:         /* No delay slot, so just process as a normal instruction */
                   8628:         break;
                   8629:     case M16_OPC_BNEQZ:
                   8630:         gen_compute_branch(ctx, OPC_BNE, 4, rx, 0, offset << 1);
                   8631:         /* No delay slot, so just process as a normal instruction */
                   8632:         break;
                   8633:     case M16_OPC_SHIFT:
                   8634:         switch (ctx->opcode & 0x3) {
                   8635:         case 0x0:
                   8636:             gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
                   8637:             break;
                   8638:         case 0x1:
                   8639: #if defined(TARGET_MIPS64)
                   8640:             check_mips_64(ctx);
                   8641:             gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
                   8642: #else
                   8643:             generate_exception(ctx, EXCP_RI);
                   8644: #endif
                   8645:             break;
                   8646:         case 0x2:
                   8647:             gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
                   8648:             break;
                   8649:         case 0x3:
                   8650:             gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
                   8651:             break;
                   8652:         }
                   8653:         break;
                   8654: #if defined(TARGET_MIPS64)
                   8655:     case M16_OPC_LD:
                   8656:             check_mips_64(ctx);
                   8657:         gen_ld(env, ctx, OPC_LD, ry, rx, offset);
                   8658:         break;
                   8659: #endif
                   8660:     case M16_OPC_RRIA:
                   8661:         imm = ctx->opcode & 0xf;
                   8662:         imm = imm | ((ctx->opcode >> 20) & 0x7f) << 4;
                   8663:         imm = imm | ((ctx->opcode >> 16) & 0xf) << 11;
                   8664:         imm = (int16_t) (imm << 1) >> 1;
                   8665:         if ((ctx->opcode >> 4) & 0x1) {
                   8666: #if defined(TARGET_MIPS64)
                   8667:             check_mips_64(ctx);
                   8668:             gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
                   8669: #else
                   8670:             generate_exception(ctx, EXCP_RI);
                   8671: #endif
                   8672:         } else {
                   8673:             gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
                   8674:         }
                   8675:         break;
                   8676:     case M16_OPC_ADDIU8:
                   8677:         gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
                   8678:         break;
                   8679:     case M16_OPC_SLTI:
                   8680:         gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
                   8681:         break;
                   8682:     case M16_OPC_SLTIU:
                   8683:         gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
                   8684:         break;
                   8685:     case M16_OPC_I8:
                   8686:         switch (funct) {
                   8687:         case I8_BTEQZ:
                   8688:             gen_compute_branch(ctx, OPC_BEQ, 4, 24, 0, offset << 1);
                   8689:             break;
                   8690:         case I8_BTNEZ:
                   8691:             gen_compute_branch(ctx, OPC_BNE, 4, 24, 0, offset << 1);
                   8692:             break;
                   8693:         case I8_SWRASP:
                   8694:             gen_st(ctx, OPC_SW, 31, 29, imm);
                   8695:             break;
                   8696:         case I8_ADJSP:
                   8697:             gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm);
                   8698:             break;
                   8699:         case I8_SVRS:
                   8700:             {
                   8701:                 int xsregs = (ctx->opcode >> 24) & 0x7;
                   8702:                 int aregs = (ctx->opcode >> 16) & 0xf;
                   8703:                 int do_ra = (ctx->opcode >> 6) & 0x1;
                   8704:                 int do_s0 = (ctx->opcode >> 5) & 0x1;
                   8705:                 int do_s1 = (ctx->opcode >> 4) & 0x1;
                   8706:                 int framesize = (((ctx->opcode >> 20) & 0xf) << 4
                   8707:                                  | (ctx->opcode & 0xf)) << 3;
                   8708: 
                   8709:                 if (ctx->opcode & (1 << 7)) {
                   8710:                     gen_mips16_save(ctx, xsregs, aregs,
                   8711:                                     do_ra, do_s0, do_s1,
                   8712:                                     framesize);
                   8713:                 } else {
                   8714:                     gen_mips16_restore(ctx, xsregs, aregs,
                   8715:                                        do_ra, do_s0, do_s1,
                   8716:                                        framesize);
                   8717:                 }
                   8718:             }
                   8719:             break;
                   8720:         default:
                   8721:             generate_exception(ctx, EXCP_RI);
                   8722:             break;
                   8723:         }
                   8724:         break;
                   8725:     case M16_OPC_LI:
                   8726:         tcg_gen_movi_tl(cpu_gpr[rx], (uint16_t) imm);
                   8727:         break;
                   8728:     case M16_OPC_CMPI:
                   8729:         tcg_gen_xori_tl(cpu_gpr[24], cpu_gpr[rx], (uint16_t) imm);
                   8730:         break;
                   8731: #if defined(TARGET_MIPS64)
                   8732:     case M16_OPC_SD:
                   8733:         gen_st(ctx, OPC_SD, ry, rx, offset);
                   8734:         break;
                   8735: #endif
                   8736:     case M16_OPC_LB:
                   8737:         gen_ld(env, ctx, OPC_LB, ry, rx, offset);
                   8738:         break;
                   8739:     case M16_OPC_LH:
                   8740:         gen_ld(env, ctx, OPC_LH, ry, rx, offset);
                   8741:         break;
                   8742:     case M16_OPC_LWSP:
                   8743:         gen_ld(env, ctx, OPC_LW, rx, 29, offset);
                   8744:         break;
                   8745:     case M16_OPC_LW:
                   8746:         gen_ld(env, ctx, OPC_LW, ry, rx, offset);
                   8747:         break;
                   8748:     case M16_OPC_LBU:
                   8749:         gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
                   8750:         break;
                   8751:     case M16_OPC_LHU:
                   8752:         gen_ld(env, ctx, OPC_LHU, ry, rx, offset);
                   8753:         break;
                   8754:     case M16_OPC_LWPC:
                   8755:         gen_ld(env, ctx, OPC_LWPC, rx, 0, offset);
                   8756:         break;
                   8757: #if defined(TARGET_MIPS64)
                   8758:     case M16_OPC_LWU:
                   8759:         gen_ld(env, ctx, OPC_LWU, ry, rx, offset);
                   8760:         break;
                   8761: #endif
                   8762:     case M16_OPC_SB:
                   8763:         gen_st(ctx, OPC_SB, ry, rx, offset);
                   8764:         break;
                   8765:     case M16_OPC_SH:
                   8766:         gen_st(ctx, OPC_SH, ry, rx, offset);
                   8767:         break;
                   8768:     case M16_OPC_SWSP:
                   8769:         gen_st(ctx, OPC_SW, rx, 29, offset);
                   8770:         break;
                   8771:     case M16_OPC_SW:
                   8772:         gen_st(ctx, OPC_SW, ry, rx, offset);
                   8773:         break;
                   8774: #if defined(TARGET_MIPS64)
                   8775:     case M16_OPC_I64:
                   8776:         decode_i64_mips16(env, ctx, ry, funct, offset, 1);
                   8777:         break;
                   8778: #endif
                   8779:     default:
                   8780:         generate_exception(ctx, EXCP_RI);
                   8781:         break;
                   8782:     }
                   8783: 
                   8784:     return 4;
                   8785: }
                   8786: 
                   8787: static int decode_mips16_opc (CPUState *env, DisasContext *ctx,
                   8788:                               int *is_branch)
                   8789: {
                   8790:     int rx, ry;
                   8791:     int sa;
                   8792:     int op, cnvt_op, op1, offset;
                   8793:     int funct;
                   8794:     int n_bytes;
                   8795: 
                   8796:     op = (ctx->opcode >> 11) & 0x1f;
                   8797:     sa = (ctx->opcode >> 2) & 0x7;
                   8798:     sa = sa == 0 ? 8 : sa;
                   8799:     rx = xlat((ctx->opcode >> 8) & 0x7);
                   8800:     cnvt_op = (ctx->opcode >> 5) & 0x7;
                   8801:     ry = xlat((ctx->opcode >> 5) & 0x7);
                   8802:     op1 = offset = ctx->opcode & 0x1f;
                   8803: 
                   8804:     n_bytes = 2;
                   8805: 
                   8806:     switch (op) {
                   8807:     case M16_OPC_ADDIUSP:
                   8808:         {
                   8809:             int16_t imm = ((uint8_t) ctx->opcode) << 2;
                   8810: 
                   8811:             gen_arith_imm(env, ctx, OPC_ADDIU, rx, 29, imm);
                   8812:         }
                   8813:         break;
                   8814:     case M16_OPC_ADDIUPC:
                   8815:         gen_addiupc(ctx, rx, ((uint8_t) ctx->opcode) << 2, 0, 0);
                   8816:         break;
                   8817:     case M16_OPC_B:
                   8818:         offset = (ctx->opcode & 0x7ff) << 1;
                   8819:         offset = (int16_t)(offset << 4) >> 4;
                   8820:         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0, offset);
                   8821:         /* No delay slot, so just process as a normal instruction */
                   8822:         break;
                   8823:     case M16_OPC_JAL:
                   8824:         offset = lduw_code(ctx->pc + 2);
                   8825:         offset = (((ctx->opcode & 0x1f) << 21)
                   8826:                   | ((ctx->opcode >> 5) & 0x1f) << 16
                   8827:                   | offset) << 2;
                   8828:         op = ((ctx->opcode >> 10) & 0x1) ? OPC_JALXS : OPC_JALS;
                   8829:         gen_compute_branch(ctx, op, 4, rx, ry, offset);
                   8830:         n_bytes = 4;
                   8831:         *is_branch = 1;
                   8832:         break;
                   8833:     case M16_OPC_BEQZ:
                   8834:         gen_compute_branch(ctx, OPC_BEQ, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
                   8835:         /* No delay slot, so just process as a normal instruction */
                   8836:         break;
                   8837:     case M16_OPC_BNEQZ:
                   8838:         gen_compute_branch(ctx, OPC_BNE, 2, rx, 0, ((int8_t)ctx->opcode) << 1);
                   8839:         /* No delay slot, so just process as a normal instruction */
                   8840:         break;
                   8841:     case M16_OPC_SHIFT:
                   8842:         switch (ctx->opcode & 0x3) {
                   8843:         case 0x0:
                   8844:             gen_shift_imm(env, ctx, OPC_SLL, rx, ry, sa);
                   8845:             break;
                   8846:         case 0x1:
                   8847: #if defined(TARGET_MIPS64)
                   8848:             check_mips_64(ctx);
                   8849:             gen_shift_imm(env, ctx, OPC_DSLL, rx, ry, sa);
                   8850: #else
                   8851:             generate_exception(ctx, EXCP_RI);
                   8852: #endif
                   8853:             break;
                   8854:         case 0x2:
                   8855:             gen_shift_imm(env, ctx, OPC_SRL, rx, ry, sa);
                   8856:             break;
                   8857:         case 0x3:
                   8858:             gen_shift_imm(env, ctx, OPC_SRA, rx, ry, sa);
                   8859:             break;
                   8860:         }
                   8861:         break;
                   8862: #if defined(TARGET_MIPS64)
                   8863:     case M16_OPC_LD:
                   8864:         check_mips_64(ctx);
                   8865:         gen_ld(env, ctx, OPC_LD, ry, rx, offset << 3);
                   8866:         break;
                   8867: #endif
                   8868:     case M16_OPC_RRIA:
                   8869:         {
                   8870:             int16_t imm = (int8_t)((ctx->opcode & 0xf) << 4) >> 4;
                   8871: 
                   8872:             if ((ctx->opcode >> 4) & 1) {
                   8873: #if defined(TARGET_MIPS64)
                   8874:                 check_mips_64(ctx);
                   8875:                 gen_arith_imm(env, ctx, OPC_DADDIU, ry, rx, imm);
                   8876: #else
                   8877:                 generate_exception(ctx, EXCP_RI);
                   8878: #endif
                   8879:             } else {
                   8880:                 gen_arith_imm(env, ctx, OPC_ADDIU, ry, rx, imm);
                   8881:             }
                   8882:         }
                   8883:         break;
                   8884:     case M16_OPC_ADDIU8:
                   8885:         {
                   8886:             int16_t imm = (int8_t) ctx->opcode;
                   8887: 
                   8888:             gen_arith_imm(env, ctx, OPC_ADDIU, rx, rx, imm);
                   8889:         }
                   8890:         break;
                   8891:     case M16_OPC_SLTI:
                   8892:         {
                   8893:             int16_t imm = (uint8_t) ctx->opcode;
                   8894: 
                   8895:             gen_slt_imm(env, OPC_SLTI, 24, rx, imm);
                   8896:         }
                   8897:         break;
                   8898:     case M16_OPC_SLTIU:
                   8899:         {
                   8900:             int16_t imm = (uint8_t) ctx->opcode;
                   8901: 
                   8902:             gen_slt_imm(env, OPC_SLTIU, 24, rx, imm);
                   8903:         }
                   8904:         break;
                   8905:     case M16_OPC_I8:
                   8906:         {
                   8907:             int reg32;
                   8908: 
                   8909:             funct = (ctx->opcode >> 8) & 0x7;
                   8910:             switch (funct) {
                   8911:             case I8_BTEQZ:
                   8912:                 gen_compute_branch(ctx, OPC_BEQ, 2, 24, 0,
                   8913:                                    ((int8_t)ctx->opcode) << 1);
                   8914:                 break;
                   8915:             case I8_BTNEZ:
                   8916:                 gen_compute_branch(ctx, OPC_BNE, 2, 24, 0,
                   8917:                                    ((int8_t)ctx->opcode) << 1);
                   8918:                 break;
                   8919:             case I8_SWRASP:
                   8920:                 gen_st(ctx, OPC_SW, 31, 29, (ctx->opcode & 0xff) << 2);
                   8921:                 break;
                   8922:             case I8_ADJSP:
                   8923:                 gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29,
                   8924:                               ((int8_t)ctx->opcode) << 3);
                   8925:                 break;
                   8926:             case I8_SVRS:
                   8927:                 {
                   8928:                     int do_ra = ctx->opcode & (1 << 6);
                   8929:                     int do_s0 = ctx->opcode & (1 << 5);
                   8930:                     int do_s1 = ctx->opcode & (1 << 4);
                   8931:                     int framesize = ctx->opcode & 0xf;
                   8932: 
                   8933:                     if (framesize == 0) {
                   8934:                         framesize = 128;
                   8935:                     } else {
                   8936:                         framesize = framesize << 3;
                   8937:                     }
                   8938: 
                   8939:                     if (ctx->opcode & (1 << 7)) {
                   8940:                         gen_mips16_save(ctx, 0, 0,
                   8941:                                         do_ra, do_s0, do_s1, framesize);
                   8942:                     } else {
                   8943:                         gen_mips16_restore(ctx, 0, 0,
                   8944:                                            do_ra, do_s0, do_s1, framesize);
                   8945:                     }
                   8946:                 }
                   8947:                 break;
                   8948:             case I8_MOV32R:
                   8949:                 {
                   8950:                     int rz = xlat(ctx->opcode & 0x7);
                   8951: 
                   8952:                     reg32 = (((ctx->opcode >> 3) & 0x3) << 3) |
                   8953:                         ((ctx->opcode >> 5) & 0x7);
                   8954:                     gen_arith(env, ctx, OPC_ADDU, reg32, rz, 0);
                   8955:                 }
                   8956:                 break;
                   8957:             case I8_MOVR32:
                   8958:                 reg32 = ctx->opcode & 0x1f;
                   8959:                 gen_arith(env, ctx, OPC_ADDU, ry, reg32, 0);
                   8960:                 break;
                   8961:             default:
                   8962:                 generate_exception(ctx, EXCP_RI);
                   8963:                 break;
                   8964:             }
                   8965:         }
                   8966:         break;
                   8967:     case M16_OPC_LI:
                   8968:         {
                   8969:             int16_t imm = (uint8_t) ctx->opcode;
                   8970: 
                   8971:             gen_arith_imm(env, ctx, OPC_ADDIU, rx, 0, imm);
                   8972:         }
                   8973:         break;
                   8974:     case M16_OPC_CMPI:
                   8975:         {
                   8976:             int16_t imm = (uint8_t) ctx->opcode;
                   8977: 
                   8978:             gen_logic_imm(env, OPC_XORI, 24, rx, imm);
                   8979:         }
                   8980:         break;
                   8981: #if defined(TARGET_MIPS64)
                   8982:     case M16_OPC_SD:
                   8983:         check_mips_64(ctx);
                   8984:         gen_st(ctx, OPC_SD, ry, rx, offset << 3);
                   8985:         break;
                   8986: #endif
                   8987:     case M16_OPC_LB:
                   8988:         gen_ld(env, ctx, OPC_LB, ry, rx, offset);
                   8989:         break;
                   8990:     case M16_OPC_LH:
                   8991:         gen_ld(env, ctx, OPC_LH, ry, rx, offset << 1);
                   8992:         break;
                   8993:     case M16_OPC_LWSP:
                   8994:         gen_ld(env, ctx, OPC_LW, rx, 29, ((uint8_t)ctx->opcode) << 2);
                   8995:         break;
                   8996:     case M16_OPC_LW:
                   8997:         gen_ld(env, ctx, OPC_LW, ry, rx, offset << 2);
                   8998:         break;
                   8999:     case M16_OPC_LBU:
                   9000:         gen_ld(env, ctx, OPC_LBU, ry, rx, offset);
                   9001:         break;
                   9002:     case M16_OPC_LHU:
                   9003:         gen_ld(env, ctx, OPC_LHU, ry, rx, offset << 1);
                   9004:         break;
                   9005:     case M16_OPC_LWPC:
                   9006:         gen_ld(env, ctx, OPC_LWPC, rx, 0, ((uint8_t)ctx->opcode) << 2);
                   9007:         break;
                   9008: #if defined (TARGET_MIPS64)
                   9009:     case M16_OPC_LWU:
                   9010:         check_mips_64(ctx);
                   9011:         gen_ld(env, ctx, OPC_LWU, ry, rx, offset << 2);
                   9012:         break;
                   9013: #endif
                   9014:     case M16_OPC_SB:
                   9015:         gen_st(ctx, OPC_SB, ry, rx, offset);
                   9016:         break;
                   9017:     case M16_OPC_SH:
                   9018:         gen_st(ctx, OPC_SH, ry, rx, offset << 1);
                   9019:         break;
                   9020:     case M16_OPC_SWSP:
                   9021:         gen_st(ctx, OPC_SW, rx, 29, ((uint8_t)ctx->opcode) << 2);
                   9022:         break;
                   9023:     case M16_OPC_SW:
                   9024:         gen_st(ctx, OPC_SW, ry, rx, offset << 2);
                   9025:         break;
                   9026:     case M16_OPC_RRR:
                   9027:         {
                   9028:             int rz = xlat((ctx->opcode >> 2) & 0x7);
                   9029:             int mips32_op;
                   9030: 
                   9031:             switch (ctx->opcode & 0x3) {
                   9032:             case RRR_ADDU:
                   9033:                 mips32_op = OPC_ADDU;
                   9034:                 break;
                   9035:             case RRR_SUBU:
                   9036:                 mips32_op = OPC_SUBU;
                   9037:                 break;
                   9038: #if defined(TARGET_MIPS64)
                   9039:             case RRR_DADDU:
                   9040:                 mips32_op = OPC_DADDU;
                   9041:                 check_mips_64(ctx);
                   9042:                 break;
                   9043:             case RRR_DSUBU:
                   9044:                 mips32_op = OPC_DSUBU;
                   9045:                 check_mips_64(ctx);
                   9046:                 break;
                   9047: #endif
                   9048:             default:
                   9049:                 generate_exception(ctx, EXCP_RI);
                   9050:                 goto done;
                   9051:             }
                   9052: 
                   9053:             gen_arith(env, ctx, mips32_op, rz, rx, ry);
                   9054:         done:
                   9055:             ;
                   9056:         }
                   9057:         break;
                   9058:     case M16_OPC_RR:
                   9059:         switch (op1) {
                   9060:         case RR_JR:
                   9061:             {
                   9062:                 int nd = (ctx->opcode >> 7) & 0x1;
                   9063:                 int link = (ctx->opcode >> 6) & 0x1;
                   9064:                 int ra = (ctx->opcode >> 5) & 0x1;
                   9065: 
                   9066:                 if (link) {
                   9067:                     op = nd ? OPC_JALRC : OPC_JALRS;
                   9068:                 } else {
                   9069:                     op = OPC_JR;
                   9070:                 }
                   9071: 
                   9072:                 gen_compute_branch(ctx, op, 2, ra ? 31 : rx, 31, 0);
                   9073:                 if (!nd) {
                   9074:                     *is_branch = 1;
                   9075:                 }
                   9076:             }
                   9077:             break;
                   9078:         case RR_SDBBP:
                   9079:             /* XXX: not clear which exception should be raised
                   9080:              *      when in debug mode...
                   9081:              */
                   9082:             check_insn(env, ctx, ISA_MIPS32);
                   9083:             if (!(ctx->hflags & MIPS_HFLAG_DM)) {
                   9084:                 generate_exception(ctx, EXCP_DBp);
                   9085:             } else {
                   9086:                 generate_exception(ctx, EXCP_DBp);
                   9087:             }
                   9088:             break;
                   9089:         case RR_SLT:
                   9090:             gen_slt(env, OPC_SLT, 24, rx, ry);
                   9091:             break;
                   9092:         case RR_SLTU:
                   9093:             gen_slt(env, OPC_SLTU, 24, rx, ry);
                   9094:             break;
                   9095:         case RR_BREAK:
                   9096:             generate_exception(ctx, EXCP_BREAK);
                   9097:             break;
                   9098:         case RR_SLLV:
                   9099:             gen_shift(env, ctx, OPC_SLLV, ry, rx, ry);
                   9100:             break;
                   9101:         case RR_SRLV:
                   9102:             gen_shift(env, ctx, OPC_SRLV, ry, rx, ry);
                   9103:             break;
                   9104:         case RR_SRAV:
                   9105:             gen_shift(env, ctx, OPC_SRAV, ry, rx, ry);
                   9106:             break;
                   9107: #if defined (TARGET_MIPS64)
                   9108:         case RR_DSRL:
                   9109:             check_mips_64(ctx);
                   9110:             gen_shift_imm(env, ctx, OPC_DSRL, ry, ry, sa);
                   9111:             break;
                   9112: #endif
                   9113:         case RR_CMP:
                   9114:             gen_logic(env, OPC_XOR, 24, rx, ry);
                   9115:             break;
                   9116:         case RR_NEG:
                   9117:             gen_arith(env, ctx, OPC_SUBU, rx, 0, ry);
                   9118:             break;
                   9119:         case RR_AND:
                   9120:             gen_logic(env, OPC_AND, rx, rx, ry);
                   9121:             break;
                   9122:         case RR_OR:
                   9123:             gen_logic(env, OPC_OR, rx, rx, ry);
                   9124:             break;
                   9125:         case RR_XOR:
                   9126:             gen_logic(env, OPC_XOR, rx, rx, ry);
                   9127:             break;
                   9128:         case RR_NOT:
                   9129:             gen_logic(env, OPC_NOR, rx, ry, 0);
                   9130:             break;
                   9131:         case RR_MFHI:
                   9132:             gen_HILO(ctx, OPC_MFHI, rx);
                   9133:             break;
                   9134:         case RR_CNVT:
                   9135:             switch (cnvt_op) {
                   9136:             case RR_RY_CNVT_ZEB:
                   9137:                 tcg_gen_ext8u_tl(cpu_gpr[rx], cpu_gpr[rx]);
                   9138:                 break;
                   9139:             case RR_RY_CNVT_ZEH:
                   9140:                 tcg_gen_ext16u_tl(cpu_gpr[rx], cpu_gpr[rx]);
                   9141:                 break;
                   9142:             case RR_RY_CNVT_SEB:
                   9143:                 tcg_gen_ext8s_tl(cpu_gpr[rx], cpu_gpr[rx]);
                   9144:                 break;
                   9145:             case RR_RY_CNVT_SEH:
                   9146:                 tcg_gen_ext16s_tl(cpu_gpr[rx], cpu_gpr[rx]);
                   9147:                 break;
                   9148: #if defined (TARGET_MIPS64)
                   9149:             case RR_RY_CNVT_ZEW:
                   9150:                 check_mips_64(ctx);
                   9151:                 tcg_gen_ext32u_tl(cpu_gpr[rx], cpu_gpr[rx]);
                   9152:                 break;
                   9153:             case RR_RY_CNVT_SEW:
                   9154:                 check_mips_64(ctx);
                   9155:                 tcg_gen_ext32s_tl(cpu_gpr[rx], cpu_gpr[rx]);
                   9156:                 break;
                   9157: #endif
                   9158:             default:
                   9159:                 generate_exception(ctx, EXCP_RI);
                   9160:                 break;
                   9161:             }
                   9162:             break;
                   9163:         case RR_MFLO:
                   9164:             gen_HILO(ctx, OPC_MFLO, rx);
                   9165:             break;
                   9166: #if defined (TARGET_MIPS64)
                   9167:         case RR_DSRA:
                   9168:             check_mips_64(ctx);
                   9169:             gen_shift_imm(env, ctx, OPC_DSRA, ry, ry, sa);
                   9170:             break;
                   9171:         case RR_DSLLV:
                   9172:             check_mips_64(ctx);
                   9173:             gen_shift(env, ctx, OPC_DSLLV, ry, rx, ry);
                   9174:             break;
                   9175:         case RR_DSRLV:
                   9176:             check_mips_64(ctx);
                   9177:             gen_shift(env, ctx, OPC_DSRLV, ry, rx, ry);
                   9178:             break;
                   9179:         case RR_DSRAV:
                   9180:             check_mips_64(ctx);
                   9181:             gen_shift(env, ctx, OPC_DSRAV, ry, rx, ry);
                   9182:             break;
                   9183: #endif
                   9184:         case RR_MULT:
                   9185:             gen_muldiv(ctx, OPC_MULT, rx, ry);
                   9186:             break;
                   9187:         case RR_MULTU:
                   9188:             gen_muldiv(ctx, OPC_MULTU, rx, ry);
                   9189:             break;
                   9190:         case RR_DIV:
                   9191:             gen_muldiv(ctx, OPC_DIV, rx, ry);
                   9192:             break;
                   9193:         case RR_DIVU:
                   9194:             gen_muldiv(ctx, OPC_DIVU, rx, ry);
                   9195:             break;
                   9196: #if defined (TARGET_MIPS64)
                   9197:         case RR_DMULT:
                   9198:             check_mips_64(ctx);
                   9199:             gen_muldiv(ctx, OPC_DMULT, rx, ry);
                   9200:             break;
                   9201:         case RR_DMULTU:
                   9202:             check_mips_64(ctx);
                   9203:             gen_muldiv(ctx, OPC_DMULTU, rx, ry);
                   9204:             break;
                   9205:         case RR_DDIV:
                   9206:             check_mips_64(ctx);
                   9207:             gen_muldiv(ctx, OPC_DDIV, rx, ry);
                   9208:             break;
                   9209:         case RR_DDIVU:
                   9210:             check_mips_64(ctx);
                   9211:             gen_muldiv(ctx, OPC_DDIVU, rx, ry);
                   9212:             break;
                   9213: #endif
                   9214:         default:
                   9215:             generate_exception(ctx, EXCP_RI);
                   9216:             break;
                   9217:         }
                   9218:         break;
                   9219:     case M16_OPC_EXTEND:
                   9220:         decode_extended_mips16_opc(env, ctx, is_branch);
                   9221:         n_bytes = 4;
                   9222:         break;
                   9223: #if defined(TARGET_MIPS64)
                   9224:     case M16_OPC_I64:
                   9225:         funct = (ctx->opcode >> 8) & 0x7;
                   9226:         decode_i64_mips16(env, ctx, ry, funct, offset, 0);
                   9227:         break;
                   9228: #endif
                   9229:     default:
                   9230:         generate_exception(ctx, EXCP_RI);
                   9231:         break;
                   9232:     }
                   9233: 
                   9234:     return n_bytes;
                   9235: }
                   9236: 
                   9237: /* microMIPS extension to MIPS32 */
                   9238: 
                   9239: /* microMIPS32 major opcodes */
                   9240: 
                   9241: enum {
                   9242:     POOL32A = 0x00,
                   9243:     POOL16A = 0x01,
                   9244:     LBU16 = 0x02,
                   9245:     MOVE16 = 0x03,
                   9246:     ADDI32 = 0x04,
                   9247:     LBU32 = 0x05,
                   9248:     SB32 = 0x06,
                   9249:     LB32 = 0x07,
                   9250: 
                   9251:     POOL32B = 0x08,
                   9252:     POOL16B = 0x09,
                   9253:     LHU16 = 0x0a,
                   9254:     ANDI16 = 0x0b,
                   9255:     ADDIU32 = 0x0c,
                   9256:     LHU32 = 0x0d,
                   9257:     SH32 = 0x0e,
                   9258:     LH32 = 0x0f,
                   9259: 
                   9260:     POOL32I = 0x10,
                   9261:     POOL16C = 0x11,
                   9262:     LWSP16 = 0x12,
                   9263:     POOL16D = 0x13,
                   9264:     ORI32 = 0x14,
                   9265:     POOL32F = 0x15,
                   9266:     POOL32S = 0x16,
                   9267:     DADDIU32 = 0x17,
                   9268: 
                   9269:     POOL32C = 0x18,
                   9270:     LWGP16 = 0x19,
                   9271:     LW16 = 0x1a,
                   9272:     POOL16E = 0x1b,
                   9273:     XORI32 = 0x1c,
                   9274:     JALS32 = 0x1d,
                   9275:     ADDIUPC = 0x1e,
                   9276:     POOL48A = 0x1f,
                   9277: 
                   9278:     /* 0x20 is reserved */
                   9279:     RES_20 = 0x20,
                   9280:     POOL16F = 0x21,
                   9281:     SB16 = 0x22,
                   9282:     BEQZ16 = 0x23,
                   9283:     SLTI32 = 0x24,
                   9284:     BEQ32 = 0x25,
                   9285:     SWC132 = 0x26,
                   9286:     LWC132 = 0x27,
                   9287: 
                   9288:     /* 0x28 and 0x29 are reserved */
                   9289:     RES_28 = 0x28,
                   9290:     RES_29 = 0x29,
                   9291:     SH16 = 0x2a,
                   9292:     BNEZ16 = 0x2b,
                   9293:     SLTIU32 = 0x2c,
                   9294:     BNE32 = 0x2d,
                   9295:     SDC132 = 0x2e,
                   9296:     LDC132 = 0x2f,
                   9297: 
                   9298:     /* 0x30 and 0x31 are reserved */
                   9299:     RES_30 = 0x30,
                   9300:     RES_31 = 0x31,
                   9301:     SWSP16 = 0x32,
                   9302:     B16 = 0x33,
                   9303:     ANDI32 = 0x34,
                   9304:     J32 = 0x35,
                   9305:     SD32 = 0x36,
                   9306:     LD32 = 0x37,
                   9307: 
                   9308:     /* 0x38 and 0x39 are reserved */
                   9309:     RES_38 = 0x38,
                   9310:     RES_39 = 0x39,
                   9311:     SW16 = 0x3a,
                   9312:     LI16 = 0x3b,
                   9313:     JALX32 = 0x3c,
                   9314:     JAL32 = 0x3d,
                   9315:     SW32 = 0x3e,
                   9316:     LW32 = 0x3f
                   9317: };
                   9318: 
                   9319: /* POOL32A encoding of minor opcode field */
                   9320: 
                   9321: enum {
                   9322:     /* These opcodes are distinguished only by bits 9..6; those bits are
                   9323:      * what are recorded below. */
                   9324:     SLL32 = 0x0,
                   9325:     SRL32 = 0x1,
                   9326:     SRA = 0x2,
                   9327:     ROTR = 0x3,
                   9328: 
                   9329:     SLLV = 0x0,
                   9330:     SRLV = 0x1,
                   9331:     SRAV = 0x2,
                   9332:     ROTRV = 0x3,
                   9333:     ADD = 0x4,
                   9334:     ADDU32 = 0x5,
                   9335:     SUB = 0x6,
                   9336:     SUBU32 = 0x7,
                   9337:     MUL = 0x8,
                   9338:     AND = 0x9,
                   9339:     OR32 = 0xa,
                   9340:     NOR = 0xb,
                   9341:     XOR32 = 0xc,
                   9342:     SLT = 0xd,
                   9343:     SLTU = 0xe,
                   9344: 
                   9345:     MOVN = 0x0,
                   9346:     MOVZ = 0x1,
                   9347:     LWXS = 0x4,
                   9348: 
                   9349:     /* The following can be distinguished by their lower 6 bits. */
                   9350:     INS = 0x0c,
                   9351:     EXT = 0x2c,
                   9352:     POOL32AXF = 0x3c
                   9353: };
                   9354: 
                   9355: /* POOL32AXF encoding of minor opcode field extension */
                   9356: 
                   9357: enum {
                   9358:     /* bits 11..6 */
                   9359:     TEQ = 0x00,
                   9360:     TGE = 0x08,
                   9361:     TGEU = 0x10,
                   9362:     TLT = 0x20,
                   9363:     TLTU = 0x28,
                   9364:     TNE = 0x30,
                   9365: 
                   9366:     MFC0 = 0x03,
                   9367:     MTC0 = 0x0b,
                   9368: 
                   9369:     /* bits 13..12 for 0x01 */
                   9370:     MFHI_ACC = 0x0,
                   9371:     MFLO_ACC = 0x1,
                   9372:     MTHI_ACC = 0x2,
                   9373:     MTLO_ACC = 0x3,
                   9374: 
                   9375:     /* bits 13..12 for 0x2a */
                   9376:     MADD_ACC = 0x0,
                   9377:     MADDU_ACC = 0x1,
                   9378:     MSUB_ACC = 0x2,
                   9379:     MSUBU_ACC = 0x3,
                   9380: 
                   9381:     /* bits 13..12 for 0x32 */
                   9382:     MULT_ACC = 0x0,
                   9383:     MULTU_ACC = 0x0,
                   9384: 
                   9385:     /* bits 15..12 for 0x2c */
                   9386:     SEB = 0x2,
                   9387:     SEH = 0x3,
                   9388:     CLO = 0x4,
                   9389:     CLZ = 0x5,
                   9390:     RDHWR = 0x6,
                   9391:     WSBH = 0x7,
                   9392:     MULT = 0x8,
                   9393:     MULTU = 0x9,
                   9394:     DIV = 0xa,
                   9395:     DIVU = 0xb,
                   9396:     MADD = 0xc,
                   9397:     MADDU = 0xd,
                   9398:     MSUB = 0xe,
                   9399:     MSUBU = 0xf,
                   9400: 
                   9401:     /* bits 15..12 for 0x34 */
                   9402:     MFC2 = 0x4,
                   9403:     MTC2 = 0x5,
                   9404:     MFHC2 = 0x8,
                   9405:     MTHC2 = 0x9,
                   9406:     CFC2 = 0xc,
                   9407:     CTC2 = 0xd,
                   9408: 
                   9409:     /* bits 15..12 for 0x3c */
                   9410:     JALR = 0x0,
                   9411:     JR = 0x0,                   /* alias */
                   9412:     JALR_HB = 0x1,
                   9413:     JALRS = 0x4,
                   9414:     JALRS_HB = 0x5,
                   9415: 
                   9416:     /* bits 15..12 for 0x05 */
                   9417:     RDPGPR = 0xe,
                   9418:     WRPGPR = 0xf,
                   9419: 
                   9420:     /* bits 15..12 for 0x0d */
                   9421:     TLBP = 0x0,
                   9422:     TLBR = 0x1,
                   9423:     TLBWI = 0x2,
                   9424:     TLBWR = 0x3,
                   9425:     WAIT = 0x9,
                   9426:     IRET = 0xd,
                   9427:     DERET = 0xe,
                   9428:     ERET = 0xf,
                   9429: 
                   9430:     /* bits 15..12 for 0x15 */
                   9431:     DMT = 0x0,
                   9432:     DVPE = 0x1,
                   9433:     EMT = 0x2,
                   9434:     EVPE = 0x3,
                   9435: 
                   9436:     /* bits 15..12 for 0x1d */
                   9437:     DI = 0x4,
                   9438:     EI = 0x5,
                   9439: 
                   9440:     /* bits 15..12 for 0x2d */
                   9441:     SYNC = 0x6,
                   9442:     SYSCALL = 0x8,
                   9443:     SDBBP = 0xd,
                   9444: 
                   9445:     /* bits 15..12 for 0x35 */
                   9446:     MFHI32 = 0x0,
                   9447:     MFLO32 = 0x1,
                   9448:     MTHI32 = 0x2,
                   9449:     MTLO32 = 0x3,
                   9450: };
                   9451: 
                   9452: /* POOL32B encoding of minor opcode field (bits 15..12) */
                   9453: 
                   9454: enum {
                   9455:     LWC2 = 0x0,
                   9456:     LWP = 0x1,
                   9457:     LDP = 0x4,
                   9458:     LWM32 = 0x5,
                   9459:     CACHE = 0x6,
                   9460:     LDM = 0x7,
                   9461:     SWC2 = 0x8,
                   9462:     SWP = 0x9,
                   9463:     SDP = 0xc,
                   9464:     SWM32 = 0xd,
                   9465:     SDM = 0xf
                   9466: };
                   9467: 
                   9468: /* POOL32C encoding of minor opcode field (bits 15..12) */
                   9469: 
                   9470: enum {
                   9471:     LWL = 0x0,
                   9472:     SWL = 0x8,
                   9473:     LWR = 0x1,
                   9474:     SWR = 0x9,
                   9475:     PREF = 0x2,
                   9476:     /* 0xa is reserved */
                   9477:     LL = 0x3,
                   9478:     SC = 0xb,
                   9479:     LDL = 0x4,
                   9480:     SDL = 0xc,
                   9481:     LDR = 0x5,
                   9482:     SDR = 0xd,
                   9483:     /* 0x6 is reserved */
                   9484:     LWU = 0xe,
                   9485:     LLD = 0x7,
                   9486:     SCD = 0xf
                   9487: };
                   9488: 
                   9489: /* POOL32F encoding of minor opcode field (bits 5..0) */
                   9490: 
                   9491: enum {
                   9492:     /* These are the bit 7..6 values */
                   9493:     ADD_FMT = 0x0,
                   9494:     MOVN_FMT = 0x0,
                   9495: 
                   9496:     SUB_FMT = 0x1,
                   9497:     MOVZ_FMT = 0x1,
                   9498: 
                   9499:     MUL_FMT = 0x2,
                   9500: 
                   9501:     DIV_FMT = 0x3,
                   9502: 
                   9503:     /* These are the bit 8..6 values */
                   9504:     RSQRT2_FMT = 0x0,
                   9505:     MOVF_FMT = 0x0,
                   9506: 
                   9507:     LWXC1 = 0x1,
                   9508:     MOVT_FMT = 0x1,
                   9509: 
                   9510:     PLL_PS = 0x2,
                   9511:     SWXC1 = 0x2,
                   9512: 
                   9513:     PLU_PS = 0x3,
                   9514:     LDXC1 = 0x3,
                   9515: 
                   9516:     PUL_PS = 0x4,
                   9517:     SDXC1 = 0x4,
                   9518:     RECIP2_FMT = 0x4,
                   9519: 
                   9520:     PUU_PS = 0x5,
                   9521:     LUXC1 = 0x5,
                   9522: 
                   9523:     CVT_PS_S = 0x6,
                   9524:     SUXC1 = 0x6,
                   9525:     ADDR_PS = 0x6,
                   9526:     PREFX = 0x6,
                   9527: 
                   9528:     MULR_PS = 0x7,
                   9529: 
                   9530:     MADD_S = 0x01,
                   9531:     MADD_D = 0x09,
                   9532:     MADD_PS = 0x11,
                   9533:     ALNV_PS = 0x19,
                   9534:     MSUB_S = 0x21,
                   9535:     MSUB_D = 0x29,
                   9536:     MSUB_PS = 0x31,
                   9537: 
                   9538:     NMADD_S = 0x02,
                   9539:     NMADD_D = 0x0a,
                   9540:     NMADD_PS = 0x12,
                   9541:     NMSUB_S = 0x22,
                   9542:     NMSUB_D = 0x2a,
                   9543:     NMSUB_PS = 0x32,
                   9544: 
                   9545:     POOL32FXF = 0x3b,
                   9546: 
                   9547:     CABS_COND_FMT = 0x1c,              /* MIPS3D */
                   9548:     C_COND_FMT = 0x3c
                   9549: };
                   9550: 
                   9551: /* POOL32Fxf encoding of minor opcode extension field */
                   9552: 
                   9553: enum {
                   9554:     CVT_L = 0x04,
                   9555:     RSQRT_FMT = 0x08,
                   9556:     FLOOR_L = 0x0c,
                   9557:     CVT_PW_PS = 0x1c,
                   9558:     CVT_W = 0x24,
                   9559:     SQRT_FMT = 0x28,
                   9560:     FLOOR_W = 0x2c,
                   9561:     CVT_PS_PW = 0x3c,
                   9562:     CFC1 = 0x40,
                   9563:     RECIP_FMT = 0x48,
                   9564:     CEIL_L = 0x4c,
                   9565:     CTC1 = 0x60,
                   9566:     CEIL_W = 0x6c,
                   9567:     MFC1 = 0x80,
                   9568:     CVT_S_PL = 0x84,
                   9569:     TRUNC_L = 0x8c,
                   9570:     MTC1 = 0xa0,
                   9571:     CVT_S_PU = 0xa4,
                   9572:     TRUNC_W = 0xac,
                   9573:     MFHC1 = 0xc0,
                   9574:     ROUND_L = 0xcc,
                   9575:     MTHC1 = 0xe0,
                   9576:     ROUND_W = 0xec,
                   9577: 
                   9578:     MOV_FMT = 0x01,
                   9579:     MOVF = 0x05,
                   9580:     ABS_FMT = 0x0d,
                   9581:     RSQRT1_FMT = 0x1d,
                   9582:     MOVT = 0x25,
                   9583:     NEG_FMT = 0x2d,
                   9584:     CVT_D = 0x4d,
                   9585:     RECIP1_FMT = 0x5d,
                   9586:     CVT_S = 0x6d
                   9587: };
                   9588: 
                   9589: /* POOL32I encoding of minor opcode field (bits 25..21) */
                   9590: 
                   9591: enum {
                   9592:     BLTZ = 0x00,
                   9593:     BLTZAL = 0x01,
                   9594:     BGEZ = 0x02,
                   9595:     BGEZAL = 0x03,
                   9596:     BLEZ = 0x04,
                   9597:     BNEZC = 0x05,
                   9598:     BGTZ = 0x06,
                   9599:     BEQZC = 0x07,
                   9600:     TLTI = 0x08,
                   9601:     TGEI = 0x09,
                   9602:     TLTIU = 0x0a,
                   9603:     TGEIU = 0x0b,
                   9604:     TNEI = 0x0c,
                   9605:     LUI = 0x0d,
                   9606:     TEQI = 0x0e,
                   9607:     SYNCI = 0x10,
                   9608:     BLTZALS = 0x11,
                   9609:     BGEZALS = 0x13,
                   9610:     BC2F = 0x14,
                   9611:     BC2T = 0x15,
                   9612:     BPOSGE64 = 0x1a,
                   9613:     BPOSGE32 = 0x1b,
                   9614:     /* These overlap and are distinguished by bit16 of the instruction */
                   9615:     BC1F = 0x1c,
                   9616:     BC1T = 0x1d,
                   9617:     BC1ANY2F = 0x1c,
                   9618:     BC1ANY2T = 0x1d,
                   9619:     BC1ANY4F = 0x1e,
                   9620:     BC1ANY4T = 0x1f
                   9621: };
                   9622: 
                   9623: /* POOL16A encoding of minor opcode field */
                   9624: 
                   9625: enum {
                   9626:     ADDU16 = 0x0,
                   9627:     SUBU16 = 0x1
                   9628: };
                   9629: 
                   9630: /* POOL16B encoding of minor opcode field */
                   9631: 
                   9632: enum {
                   9633:     SLL16 = 0x0,
                   9634:     SRL16 = 0x1
                   9635: };
                   9636: 
                   9637: /* POOL16C encoding of minor opcode field */
                   9638: 
                   9639: enum {
                   9640:     NOT16 = 0x00,
                   9641:     XOR16 = 0x04,
                   9642:     AND16 = 0x08,
                   9643:     OR16 = 0x0c,
                   9644:     LWM16 = 0x10,
                   9645:     SWM16 = 0x14,
                   9646:     JR16 = 0x18,
                   9647:     JRC16 = 0x1a,
                   9648:     JALR16 = 0x1c,
                   9649:     JALR16S = 0x1e,
                   9650:     MFHI16 = 0x20,
                   9651:     MFLO16 = 0x24,
                   9652:     BREAK16 = 0x28,
                   9653:     SDBBP16 = 0x2c,
                   9654:     JRADDIUSP = 0x30
                   9655: };
                   9656: 
                   9657: /* POOL16D encoding of minor opcode field */
                   9658: 
                   9659: enum {
                   9660:     ADDIUS5 = 0x0,
                   9661:     ADDIUSP = 0x1
                   9662: };
                   9663: 
                   9664: /* POOL16E encoding of minor opcode field */
                   9665: 
                   9666: enum {
                   9667:     ADDIUR2 = 0x0,
                   9668:     ADDIUR1SP = 0x1
                   9669: };
                   9670: 
                   9671: static int mmreg (int r)
                   9672: {
                   9673:     static const int map[] = { 16, 17, 2, 3, 4, 5, 6, 7 };
                   9674: 
                   9675:     return map[r];
                   9676: }
                   9677: 
                   9678: /* Used for 16-bit store instructions.  */
                   9679: static int mmreg2 (int r)
                   9680: {
                   9681:     static const int map[] = { 0, 17, 2, 3, 4, 5, 6, 7 };
                   9682: 
                   9683:     return map[r];
                   9684: }
                   9685: 
                   9686: #define uMIPS_RD(op) ((op >> 7) & 0x7)
                   9687: #define uMIPS_RS(op) ((op >> 4) & 0x7)
                   9688: #define uMIPS_RS2(op) uMIPS_RS(op)
                   9689: #define uMIPS_RS1(op) ((op >> 1) & 0x7)
                   9690: #define uMIPS_RD5(op) ((op >> 5) & 0x1f)
                   9691: #define uMIPS_RS5(op) (op & 0x1f)
                   9692: 
                   9693: /* Signed immediate */
                   9694: #define SIMM(op, start, width)                                          \
                   9695:     ((int32_t)(((op >> start) & ((~0U) >> (32-width)))                 \
                   9696:                << (32-width))                                           \
                   9697:      >> (32-width))
                   9698: /* Zero-extended immediate */
                   9699: #define ZIMM(op, start, width) ((op >> start) & ((~0U) >> (32-width)))
                   9700: 
                   9701: static void gen_addiur1sp (CPUState *env, DisasContext *ctx)
                   9702: {
                   9703:     int rd = mmreg(uMIPS_RD(ctx->opcode));
                   9704: 
                   9705:     gen_arith_imm(env, ctx, OPC_ADDIU, rd, 29, ((ctx->opcode >> 1) & 0x3f) << 2);
                   9706: }
                   9707: 
                   9708: static void gen_addiur2 (CPUState *env, DisasContext *ctx)
                   9709: {
                   9710:     static const int decoded_imm[] = { 1, 4, 8, 12, 16, 20, 24, -1 };
                   9711:     int rd = mmreg(uMIPS_RD(ctx->opcode));
                   9712:     int rs = mmreg(uMIPS_RS(ctx->opcode));
                   9713: 
                   9714:     gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, decoded_imm[ZIMM(ctx->opcode, 1, 3)]);
                   9715: }
                   9716: 
                   9717: static void gen_addiusp (CPUState *env, DisasContext *ctx)
                   9718: {
                   9719:     int encoded = ZIMM(ctx->opcode, 1, 9);
                   9720:     int decoded;
                   9721: 
                   9722:     if (encoded <= 1) {
                   9723:         decoded = 256 + encoded;
                   9724:     } else if (encoded <= 255) {
                   9725:         decoded = encoded;
                   9726:     } else if (encoded <= 509) {
                   9727:         decoded = encoded - 512;
                   9728:     } else {
                   9729:         decoded = encoded - 768;
                   9730:     }
                   9731: 
                   9732:     gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, decoded << 2);
                   9733: }
                   9734: 
                   9735: static void gen_addius5 (CPUState *env, DisasContext *ctx)
                   9736: {
                   9737:     int imm = SIMM(ctx->opcode, 1, 4);
                   9738:     int rd = (ctx->opcode >> 5) & 0x1f;
                   9739: 
                   9740:     gen_arith_imm(env, ctx, OPC_ADDIU, rd, rd, imm);
                   9741: }
                   9742: 
                   9743: static void gen_andi16 (CPUState *env, DisasContext *ctx)
                   9744: {
                   9745:     static const int decoded_imm[] = { 128, 1, 2, 3, 4, 7, 8, 15, 16,
                   9746:                                  31, 32, 63, 64, 255, 32768, 65535 };
                   9747:     int rd = mmreg(uMIPS_RD(ctx->opcode));
                   9748:     int rs = mmreg(uMIPS_RS(ctx->opcode));
                   9749:     int encoded = ZIMM(ctx->opcode, 0, 4);
                   9750: 
                   9751:     gen_logic_imm(env, OPC_ANDI, rd, rs, decoded_imm[encoded]);
                   9752: }
                   9753: 
                   9754: static void gen_ldst_multiple (DisasContext *ctx, uint32_t opc, int reglist,
                   9755:                                int base, int16_t offset)
                   9756: {
                   9757:     TCGv t0, t1;
                   9758:     TCGv_i32 t2;
                   9759: 
                   9760:     if (ctx->hflags & MIPS_HFLAG_BMASK) {
                   9761:         generate_exception(ctx, EXCP_RI);
                   9762:         return;
                   9763:     }
                   9764: 
                   9765:     t0 = tcg_temp_new();
                   9766: 
                   9767:     gen_base_offset_addr(ctx, t0, base, offset);
                   9768: 
                   9769:     t1 = tcg_const_tl(reglist);
                   9770:     t2 = tcg_const_i32(ctx->mem_idx);
                   9771: 
                   9772:     save_cpu_state(ctx, 1);
                   9773:     switch (opc) {
                   9774:     case LWM32:
                   9775:         gen_helper_lwm(t0, t1, t2);
                   9776:         break;
                   9777:     case SWM32:
                   9778:         gen_helper_swm(t0, t1, t2);
                   9779:         break;
                   9780: #ifdef TARGET_MIPS64
                   9781:     case LDM:
                   9782:         gen_helper_ldm(t0, t1, t2);
                   9783:         break;
                   9784:     case SDM:
                   9785:         gen_helper_sdm(t0, t1, t2);
                   9786:         break;
                   9787: #endif
                   9788:     }
                   9789:     MIPS_DEBUG("%s, %x, %d(%s)", opn, reglist, offset, regnames[base]);
                   9790:     tcg_temp_free(t0);
                   9791:     tcg_temp_free(t1);
                   9792:     tcg_temp_free_i32(t2);
                   9793: }
                   9794: 
                   9795: 
                   9796: static void gen_pool16c_insn (CPUState *env, DisasContext *ctx, int *is_branch)
                   9797: {
                   9798:     int rd = mmreg((ctx->opcode >> 3) & 0x7);
                   9799:     int rs = mmreg(ctx->opcode & 0x7);
                   9800:     int opc;
                   9801: 
                   9802:     switch (((ctx->opcode) >> 4) & 0x3f) {
                   9803:     case NOT16 + 0:
                   9804:     case NOT16 + 1:
                   9805:     case NOT16 + 2:
                   9806:     case NOT16 + 3:
                   9807:         gen_logic(env, OPC_NOR, rd, rs, 0);
                   9808:         break;
                   9809:     case XOR16 + 0:
                   9810:     case XOR16 + 1:
                   9811:     case XOR16 + 2:
                   9812:     case XOR16 + 3:
                   9813:         gen_logic(env, OPC_XOR, rd, rd, rs);
                   9814:         break;
                   9815:     case AND16 + 0:
                   9816:     case AND16 + 1:
                   9817:     case AND16 + 2:
                   9818:     case AND16 + 3:
                   9819:         gen_logic(env, OPC_AND, rd, rd, rs);
                   9820:         break;
                   9821:     case OR16 + 0:
                   9822:     case OR16 + 1:
                   9823:     case OR16 + 2:
                   9824:     case OR16 + 3:
                   9825:         gen_logic(env, OPC_OR, rd, rd, rs);
                   9826:         break;
                   9827:     case LWM16 + 0:
                   9828:     case LWM16 + 1:
                   9829:     case LWM16 + 2:
                   9830:     case LWM16 + 3:
                   9831:         {
                   9832:             static const int lwm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
                   9833:             int offset = ZIMM(ctx->opcode, 0, 4);
                   9834: 
                   9835:             gen_ldst_multiple(ctx, LWM32, lwm_convert[(ctx->opcode >> 4) & 0x3],
                   9836:                               29, offset << 2);
                   9837:         }
                   9838:         break;
                   9839:     case SWM16 + 0:
                   9840:     case SWM16 + 1:
                   9841:     case SWM16 + 2:
                   9842:     case SWM16 + 3:
                   9843:         {
                   9844:             static const int swm_convert[] = { 0x11, 0x12, 0x13, 0x14 };
                   9845:             int offset = ZIMM(ctx->opcode, 0, 4);
                   9846: 
                   9847:             gen_ldst_multiple(ctx, SWM32, swm_convert[(ctx->opcode >> 4) & 0x3],
                   9848:                               29, offset << 2);
                   9849:         }
                   9850:         break;
                   9851:     case JR16 + 0:
                   9852:     case JR16 + 1:
                   9853:         {
                   9854:             int reg = ctx->opcode & 0x1f;
                   9855: 
                   9856:             gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
                   9857:         }
                   9858:         *is_branch = 1;
                   9859:         break;
                   9860:     case JRC16 + 0:
                   9861:     case JRC16 + 1:
                   9862:         {
                   9863:             int reg = ctx->opcode & 0x1f;
                   9864: 
                   9865:             gen_compute_branch(ctx, OPC_JR, 2, reg, 0, 0);
                   9866:             /* Let normal delay slot handling in our caller take us
                   9867:                to the branch target.  */
                   9868:         }
                   9869:         break;
                   9870:     case JALR16 + 0:
                   9871:     case JALR16 + 1:
                   9872:         opc = OPC_JALR;
                   9873:         goto do_jalr;
                   9874:     case JALR16S + 0:
                   9875:     case JALR16S + 1:
                   9876:         opc = OPC_JALRS;
                   9877:     do_jalr:
                   9878:         {
                   9879:             int reg = ctx->opcode & 0x1f;
                   9880: 
                   9881:             gen_compute_branch(ctx, opc, 2, reg, 31, 0);
                   9882:         }
                   9883:         *is_branch = 1;
                   9884:         break;
                   9885:     case MFHI16 + 0:
                   9886:     case MFHI16 + 1:
                   9887:         gen_HILO(ctx, OPC_MFHI, uMIPS_RS5(ctx->opcode));
                   9888:         break;
                   9889:     case MFLO16 + 0:
                   9890:     case MFLO16 + 1:
                   9891:         gen_HILO(ctx, OPC_MFLO, uMIPS_RS5(ctx->opcode));
                   9892:         break;
                   9893:     case BREAK16:
                   9894:         generate_exception(ctx, EXCP_BREAK);
                   9895:         break;
                   9896:     case SDBBP16:
                   9897:         /* XXX: not clear which exception should be raised
                   9898:          *      when in debug mode...
                   9899:          */
                   9900:         check_insn(env, ctx, ISA_MIPS32);
                   9901:         if (!(ctx->hflags & MIPS_HFLAG_DM)) {
                   9902:             generate_exception(ctx, EXCP_DBp);
                   9903:         } else {
                   9904:             generate_exception(ctx, EXCP_DBp);
                   9905:         }
                   9906:         break;
                   9907:     case JRADDIUSP + 0:
                   9908:     case JRADDIUSP + 1:
                   9909:         {
                   9910:             int imm = ZIMM(ctx->opcode, 0, 5);
                   9911: 
                   9912:             gen_compute_branch(ctx, OPC_JR, 2, 31, 0, 0);
                   9913:             gen_arith_imm(env, ctx, OPC_ADDIU, 29, 29, imm << 2);
                   9914:             /* Let normal delay slot handling in our caller take us
                   9915:                to the branch target.  */
                   9916:         }
                   9917:         break;
                   9918:     default:
                   9919:         generate_exception(ctx, EXCP_RI);
                   9920:         break;
                   9921:     }
                   9922: }
                   9923: 
                   9924: static void gen_ldxs (DisasContext *ctx, int base, int index, int rd)
                   9925: {
                   9926:     TCGv t0 = tcg_temp_new();
                   9927:     TCGv t1 = tcg_temp_new();
                   9928: 
                   9929:     gen_load_gpr(t0, base);
                   9930: 
                   9931:     if (index != 0) {
                   9932:         gen_load_gpr(t1, index);
                   9933:         tcg_gen_shli_tl(t1, t1, 2);
                   9934:         gen_op_addr_add(ctx, t0, t1, t0);
                   9935:     }
                   9936: 
                   9937:     save_cpu_state(ctx, 0);
                   9938:     op_ld_lw(t1, t0, ctx);
                   9939:     gen_store_gpr(t1, rd);
                   9940: 
                   9941:     tcg_temp_free(t0);
                   9942:     tcg_temp_free(t1);
                   9943: }
                   9944: 
                   9945: static void gen_ldst_pair (DisasContext *ctx, uint32_t opc, int rd,
                   9946:                            int base, int16_t offset)
                   9947: {
                   9948:     const char *opn = "ldst_pair";
                   9949:     TCGv t0, t1;
                   9950: 
                   9951:     if (ctx->hflags & MIPS_HFLAG_BMASK || rd == 31 || rd == base) {
                   9952:         generate_exception(ctx, EXCP_RI);
                   9953:         return;
                   9954:     }
                   9955: 
                   9956:     t0 = tcg_temp_new();
                   9957:     t1 = tcg_temp_new();
                   9958: 
                   9959:     gen_base_offset_addr(ctx, t0, base, offset);
                   9960: 
                   9961:     switch (opc) {
                   9962:     case LWP:
                   9963:         save_cpu_state(ctx, 0);
                   9964:         op_ld_lw(t1, t0, ctx);
                   9965:         gen_store_gpr(t1, rd);
                   9966:         tcg_gen_movi_tl(t1, 4);
                   9967:         gen_op_addr_add(ctx, t0, t0, t1);
                   9968:         op_ld_lw(t1, t0, ctx);
                   9969:         gen_store_gpr(t1, rd+1);
                   9970:         opn = "lwp";
                   9971:         break;
                   9972:     case SWP:
1.1.1.13  root     9973:         save_cpu_state(ctx, 0);
1.1.1.12  root     9974:         gen_load_gpr(t1, rd);
                   9975:         op_st_sw(t1, t0, ctx);
                   9976:         tcg_gen_movi_tl(t1, 4);
                   9977:         gen_op_addr_add(ctx, t0, t0, t1);
                   9978:         gen_load_gpr(t1, rd+1);
                   9979:         op_st_sw(t1, t0, ctx);
                   9980:         opn = "swp";
                   9981:         break;
                   9982: #ifdef TARGET_MIPS64
                   9983:     case LDP:
                   9984:         save_cpu_state(ctx, 0);
                   9985:         op_ld_ld(t1, t0, ctx);
                   9986:         gen_store_gpr(t1, rd);
                   9987:         tcg_gen_movi_tl(t1, 8);
                   9988:         gen_op_addr_add(ctx, t0, t0, t1);
                   9989:         op_ld_ld(t1, t0, ctx);
                   9990:         gen_store_gpr(t1, rd+1);
                   9991:         opn = "ldp";
                   9992:         break;
                   9993:     case SDP:
1.1.1.13  root     9994:         save_cpu_state(ctx, 0);
1.1.1.12  root     9995:         gen_load_gpr(t1, rd);
                   9996:         op_st_sd(t1, t0, ctx);
                   9997:         tcg_gen_movi_tl(t1, 8);
                   9998:         gen_op_addr_add(ctx, t0, t0, t1);
                   9999:         gen_load_gpr(t1, rd+1);
                   10000:         op_st_sd(t1, t0, ctx);
                   10001:         opn = "sdp";
                   10002:         break;
                   10003: #endif
                   10004:     }
1.1.1.13  root     10005:     (void)opn; /* avoid a compiler warning */
1.1.1.12  root     10006:     MIPS_DEBUG("%s, %s, %d(%s)", opn, regnames[rd], offset, regnames[base]);
                   10007:     tcg_temp_free(t0);
                   10008:     tcg_temp_free(t1);
                   10009: }
                   10010: 
                   10011: static void gen_pool32axf (CPUState *env, DisasContext *ctx, int rt, int rs,
                   10012:                            int *is_branch)
                   10013: {
                   10014:     int extension = (ctx->opcode >> 6) & 0x3f;
                   10015:     int minor = (ctx->opcode >> 12) & 0xf;
                   10016:     uint32_t mips32_op;
                   10017: 
                   10018:     switch (extension) {
                   10019:     case TEQ:
                   10020:         mips32_op = OPC_TEQ;
                   10021:         goto do_trap;
                   10022:     case TGE:
                   10023:         mips32_op = OPC_TGE;
                   10024:         goto do_trap;
                   10025:     case TGEU:
                   10026:         mips32_op = OPC_TGEU;
                   10027:         goto do_trap;
                   10028:     case TLT:
                   10029:         mips32_op = OPC_TLT;
                   10030:         goto do_trap;
                   10031:     case TLTU:
                   10032:         mips32_op = OPC_TLTU;
                   10033:         goto do_trap;
                   10034:     case TNE:
                   10035:         mips32_op = OPC_TNE;
                   10036:     do_trap:
                   10037:         gen_trap(ctx, mips32_op, rs, rt, -1);
                   10038:         break;
                   10039: #ifndef CONFIG_USER_ONLY
                   10040:     case MFC0:
                   10041:     case MFC0 + 32:
                   10042:         if (rt == 0) {
                   10043:             /* Treat as NOP. */
                   10044:             break;
                   10045:         }
                   10046:         gen_mfc0(env, ctx, cpu_gpr[rt], rs, (ctx->opcode >> 11) & 0x7);
                   10047:         break;
                   10048:     case MTC0:
                   10049:     case MTC0 + 32:
                   10050:         {
                   10051:             TCGv t0 = tcg_temp_new();
                   10052: 
                   10053:             gen_load_gpr(t0, rt);
                   10054:             gen_mtc0(env, ctx, t0, rs, (ctx->opcode >> 11) & 0x7);
                   10055:             tcg_temp_free(t0);
                   10056:         }
                   10057:         break;
                   10058: #endif
                   10059:     case 0x2c:
                   10060:         switch (minor) {
                   10061:         case SEB:
                   10062:             gen_bshfl(ctx, OPC_SEB, rs, rt);
                   10063:             break;
                   10064:         case SEH:
                   10065:             gen_bshfl(ctx, OPC_SEH, rs, rt);
                   10066:             break;
                   10067:         case CLO:
                   10068:             mips32_op = OPC_CLO;
                   10069:             goto do_cl;
                   10070:         case CLZ:
                   10071:             mips32_op = OPC_CLZ;
                   10072:         do_cl:
                   10073:             check_insn(env, ctx, ISA_MIPS32);
                   10074:             gen_cl(ctx, mips32_op, rt, rs);
                   10075:             break;
                   10076:         case RDHWR:
                   10077:             gen_rdhwr(env, ctx, rt, rs);
                   10078:             break;
                   10079:         case WSBH:
                   10080:             gen_bshfl(ctx, OPC_WSBH, rs, rt);
                   10081:             break;
                   10082:         case MULT:
                   10083:             mips32_op = OPC_MULT;
                   10084:             goto do_muldiv;
                   10085:         case MULTU:
                   10086:             mips32_op = OPC_MULTU;
                   10087:             goto do_muldiv;
                   10088:         case DIV:
                   10089:             mips32_op = OPC_DIV;
                   10090:             goto do_muldiv;
                   10091:         case DIVU:
                   10092:             mips32_op = OPC_DIVU;
                   10093:             goto do_muldiv;
                   10094:         case MADD:
                   10095:             mips32_op = OPC_MADD;
                   10096:             goto do_muldiv;
                   10097:         case MADDU:
                   10098:             mips32_op = OPC_MADDU;
                   10099:             goto do_muldiv;
                   10100:         case MSUB:
                   10101:             mips32_op = OPC_MSUB;
                   10102:             goto do_muldiv;
                   10103:         case MSUBU:
                   10104:             mips32_op = OPC_MSUBU;
                   10105:         do_muldiv:
                   10106:             check_insn(env, ctx, ISA_MIPS32);
                   10107:             gen_muldiv(ctx, mips32_op, rs, rt);
                   10108:             break;
                   10109:         default:
                   10110:             goto pool32axf_invalid;
                   10111:         }
                   10112:         break;
                   10113:     case 0x34:
                   10114:         switch (minor) {
                   10115:         case MFC2:
                   10116:         case MTC2:
                   10117:         case MFHC2:
                   10118:         case MTHC2:
                   10119:         case CFC2:
                   10120:         case CTC2:
                   10121:             generate_exception_err(ctx, EXCP_CpU, 2);
                   10122:             break;
                   10123:         default:
                   10124:             goto pool32axf_invalid;
                   10125:         }
                   10126:         break;
                   10127:     case 0x3c:
                   10128:         switch (minor) {
                   10129:         case JALR:
                   10130:         case JALR_HB:
                   10131:             gen_compute_branch (ctx, OPC_JALR, 4, rs, rt, 0);
                   10132:             *is_branch = 1;
                   10133:             break;
                   10134:         case JALRS:
                   10135:         case JALRS_HB:
                   10136:             gen_compute_branch (ctx, OPC_JALRS, 4, rs, rt, 0);
                   10137:             *is_branch = 1;
                   10138:             break;
                   10139:         default:
                   10140:             goto pool32axf_invalid;
                   10141:         }
                   10142:         break;
                   10143:     case 0x05:
                   10144:         switch (minor) {
                   10145:         case RDPGPR:
                   10146:             check_insn(env, ctx, ISA_MIPS32R2);
                   10147:             gen_load_srsgpr(rt, rs);
                   10148:             break;
                   10149:         case WRPGPR:
                   10150:             check_insn(env, ctx, ISA_MIPS32R2);
                   10151:             gen_store_srsgpr(rt, rs);
                   10152:             break;
                   10153:         default:
                   10154:             goto pool32axf_invalid;
                   10155:         }
                   10156:         break;
                   10157: #ifndef CONFIG_USER_ONLY
                   10158:     case 0x0d:
                   10159:         switch (minor) {
                   10160:         case TLBP:
                   10161:             mips32_op = OPC_TLBP;
                   10162:             goto do_cp0;
                   10163:         case TLBR:
                   10164:             mips32_op = OPC_TLBR;
                   10165:             goto do_cp0;
                   10166:         case TLBWI:
                   10167:             mips32_op = OPC_TLBWI;
                   10168:             goto do_cp0;
                   10169:         case TLBWR:
                   10170:             mips32_op = OPC_TLBWR;
                   10171:             goto do_cp0;
                   10172:         case WAIT:
                   10173:             mips32_op = OPC_WAIT;
                   10174:             goto do_cp0;
                   10175:         case DERET:
                   10176:             mips32_op = OPC_DERET;
                   10177:             goto do_cp0;
                   10178:         case ERET:
                   10179:             mips32_op = OPC_ERET;
                   10180:         do_cp0:
                   10181:             gen_cp0(env, ctx, mips32_op, rt, rs);
                   10182:             break;
                   10183:         default:
                   10184:             goto pool32axf_invalid;
                   10185:         }
                   10186:         break;
                   10187:     case 0x1d:
                   10188:         switch (minor) {
                   10189:         case DI:
                   10190:             {
                   10191:                 TCGv t0 = tcg_temp_new();
                   10192: 
                   10193:                 save_cpu_state(ctx, 1);
                   10194:                 gen_helper_di(t0);
                   10195:                 gen_store_gpr(t0, rs);
                   10196:                 /* Stop translation as we may have switched the execution mode */
                   10197:                 ctx->bstate = BS_STOP;
                   10198:                 tcg_temp_free(t0);
                   10199:             }
                   10200:             break;
                   10201:         case EI:
                   10202:             {
                   10203:                 TCGv t0 = tcg_temp_new();
                   10204: 
                   10205:                 save_cpu_state(ctx, 1);
                   10206:                 gen_helper_ei(t0);
                   10207:                 gen_store_gpr(t0, rs);
                   10208:                 /* Stop translation as we may have switched the execution mode */
                   10209:                 ctx->bstate = BS_STOP;
                   10210:                 tcg_temp_free(t0);
                   10211:             }
                   10212:             break;
                   10213:         default:
                   10214:             goto pool32axf_invalid;
                   10215:         }
                   10216:         break;
                   10217: #endif
                   10218:     case 0x2d:
                   10219:         switch (minor) {
                   10220:         case SYNC:
                   10221:             /* NOP */
                   10222:             break;
                   10223:         case SYSCALL:
                   10224:             generate_exception(ctx, EXCP_SYSCALL);
                   10225:             ctx->bstate = BS_STOP;
                   10226:             break;
                   10227:         case SDBBP:
                   10228:             check_insn(env, ctx, ISA_MIPS32);
                   10229:             if (!(ctx->hflags & MIPS_HFLAG_DM)) {
                   10230:                 generate_exception(ctx, EXCP_DBp);
                   10231:             } else {
                   10232:                 generate_exception(ctx, EXCP_DBp);
                   10233:             }
                   10234:             break;
                   10235:         default:
                   10236:             goto pool32axf_invalid;
                   10237:         }
                   10238:         break;
                   10239:     case 0x35:
                   10240:         switch (minor) {
                   10241:         case MFHI32:
                   10242:             gen_HILO(ctx, OPC_MFHI, rs);
                   10243:             break;
                   10244:         case MFLO32:
                   10245:             gen_HILO(ctx, OPC_MFLO, rs);
                   10246:             break;
                   10247:         case MTHI32:
                   10248:             gen_HILO(ctx, OPC_MTHI, rs);
                   10249:             break;
                   10250:         case MTLO32:
                   10251:             gen_HILO(ctx, OPC_MTLO, rs);
                   10252:             break;
                   10253:         default:
                   10254:             goto pool32axf_invalid;
                   10255:         }
                   10256:         break;
                   10257:     default:
                   10258:     pool32axf_invalid:
                   10259:         MIPS_INVAL("pool32axf");
                   10260:         generate_exception(ctx, EXCP_RI);
                   10261:         break;
                   10262:     }
                   10263: }
                   10264: 
                   10265: /* Values for microMIPS fmt field.  Variable-width, depending on which
                   10266:    formats the instruction supports.  */
                   10267: 
                   10268: enum {
                   10269:     FMT_SD_S = 0,
                   10270:     FMT_SD_D = 1,
                   10271: 
                   10272:     FMT_SDPS_S = 0,
                   10273:     FMT_SDPS_D = 1,
                   10274:     FMT_SDPS_PS = 2,
                   10275: 
                   10276:     FMT_SWL_S = 0,
                   10277:     FMT_SWL_W = 1,
                   10278:     FMT_SWL_L = 2,
                   10279: 
                   10280:     FMT_DWL_D = 0,
                   10281:     FMT_DWL_W = 1,
                   10282:     FMT_DWL_L = 2
                   10283: };
                   10284: 
                   10285: static void gen_pool32fxf (CPUState *env, DisasContext *ctx, int rt, int rs)
                   10286: {
                   10287:     int extension = (ctx->opcode >> 6) & 0x3ff;
                   10288:     uint32_t mips32_op;
                   10289: 
                   10290: #define FLOAT_1BIT_FMT(opc, fmt) (fmt << 8) | opc
                   10291: #define FLOAT_2BIT_FMT(opc, fmt) (fmt << 7) | opc
                   10292: #define COND_FLOAT_MOV(opc, cond) (cond << 7) | opc
                   10293: 
                   10294:     switch (extension) {
                   10295:     case FLOAT_1BIT_FMT(CFC1, 0):
                   10296:         mips32_op = OPC_CFC1;
                   10297:         goto do_cp1;
                   10298:     case FLOAT_1BIT_FMT(CTC1, 0):
                   10299:         mips32_op = OPC_CTC1;
                   10300:         goto do_cp1;
                   10301:     case FLOAT_1BIT_FMT(MFC1, 0):
                   10302:         mips32_op = OPC_MFC1;
                   10303:         goto do_cp1;
                   10304:     case FLOAT_1BIT_FMT(MTC1, 0):
                   10305:         mips32_op = OPC_MTC1;
                   10306:         goto do_cp1;
                   10307:     case FLOAT_1BIT_FMT(MFHC1, 0):
                   10308:         mips32_op = OPC_MFHC1;
                   10309:         goto do_cp1;
                   10310:     case FLOAT_1BIT_FMT(MTHC1, 0):
                   10311:         mips32_op = OPC_MTHC1;
                   10312:     do_cp1:
                   10313:         gen_cp1(ctx, mips32_op, rt, rs);
                   10314:         break;
                   10315: 
                   10316:         /* Reciprocal square root */
                   10317:     case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_S):
                   10318:         mips32_op = OPC_RSQRT_S;
                   10319:         goto do_unaryfp;
                   10320:     case FLOAT_1BIT_FMT(RSQRT_FMT, FMT_SD_D):
                   10321:         mips32_op = OPC_RSQRT_D;
                   10322:         goto do_unaryfp;
                   10323: 
                   10324:         /* Square root */
                   10325:     case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_S):
                   10326:         mips32_op = OPC_SQRT_S;
                   10327:         goto do_unaryfp;
                   10328:     case FLOAT_1BIT_FMT(SQRT_FMT, FMT_SD_D):
                   10329:         mips32_op = OPC_SQRT_D;
                   10330:         goto do_unaryfp;
                   10331: 
                   10332:         /* Reciprocal */
                   10333:     case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_S):
                   10334:         mips32_op = OPC_RECIP_S;
                   10335:         goto do_unaryfp;
                   10336:     case FLOAT_1BIT_FMT(RECIP_FMT, FMT_SD_D):
                   10337:         mips32_op = OPC_RECIP_D;
                   10338:         goto do_unaryfp;
                   10339: 
                   10340:         /* Floor */
                   10341:     case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_S):
                   10342:         mips32_op = OPC_FLOOR_L_S;
                   10343:         goto do_unaryfp;
                   10344:     case FLOAT_1BIT_FMT(FLOOR_L, FMT_SD_D):
                   10345:         mips32_op = OPC_FLOOR_L_D;
                   10346:         goto do_unaryfp;
                   10347:     case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_S):
                   10348:         mips32_op = OPC_FLOOR_W_S;
                   10349:         goto do_unaryfp;
                   10350:     case FLOAT_1BIT_FMT(FLOOR_W, FMT_SD_D):
                   10351:         mips32_op = OPC_FLOOR_W_D;
                   10352:         goto do_unaryfp;
                   10353: 
                   10354:         /* Ceiling */
                   10355:     case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_S):
                   10356:         mips32_op = OPC_CEIL_L_S;
                   10357:         goto do_unaryfp;
                   10358:     case FLOAT_1BIT_FMT(CEIL_L, FMT_SD_D):
                   10359:         mips32_op = OPC_CEIL_L_D;
                   10360:         goto do_unaryfp;
                   10361:     case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_S):
                   10362:         mips32_op = OPC_CEIL_W_S;
                   10363:         goto do_unaryfp;
                   10364:     case FLOAT_1BIT_FMT(CEIL_W, FMT_SD_D):
                   10365:         mips32_op = OPC_CEIL_W_D;
                   10366:         goto do_unaryfp;
                   10367: 
                   10368:         /* Truncation */
                   10369:     case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_S):
                   10370:         mips32_op = OPC_TRUNC_L_S;
                   10371:         goto do_unaryfp;
                   10372:     case FLOAT_1BIT_FMT(TRUNC_L, FMT_SD_D):
                   10373:         mips32_op = OPC_TRUNC_L_D;
                   10374:         goto do_unaryfp;
                   10375:     case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_S):
                   10376:         mips32_op = OPC_TRUNC_W_S;
                   10377:         goto do_unaryfp;
                   10378:     case FLOAT_1BIT_FMT(TRUNC_W, FMT_SD_D):
                   10379:         mips32_op = OPC_TRUNC_W_D;
                   10380:         goto do_unaryfp;
                   10381: 
                   10382:         /* Round */
                   10383:     case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_S):
                   10384:         mips32_op = OPC_ROUND_L_S;
                   10385:         goto do_unaryfp;
                   10386:     case FLOAT_1BIT_FMT(ROUND_L, FMT_SD_D):
                   10387:         mips32_op = OPC_ROUND_L_D;
                   10388:         goto do_unaryfp;
                   10389:     case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_S):
                   10390:         mips32_op = OPC_ROUND_W_S;
                   10391:         goto do_unaryfp;
                   10392:     case FLOAT_1BIT_FMT(ROUND_W, FMT_SD_D):
                   10393:         mips32_op = OPC_ROUND_W_D;
                   10394:         goto do_unaryfp;
                   10395: 
                   10396:         /* Integer to floating-point conversion */
                   10397:     case FLOAT_1BIT_FMT(CVT_L, FMT_SD_S):
                   10398:         mips32_op = OPC_CVT_L_S;
                   10399:         goto do_unaryfp;
                   10400:     case FLOAT_1BIT_FMT(CVT_L, FMT_SD_D):
                   10401:         mips32_op = OPC_CVT_L_D;
                   10402:         goto do_unaryfp;
                   10403:     case FLOAT_1BIT_FMT(CVT_W, FMT_SD_S):
                   10404:         mips32_op = OPC_CVT_W_S;
                   10405:         goto do_unaryfp;
                   10406:     case FLOAT_1BIT_FMT(CVT_W, FMT_SD_D):
                   10407:         mips32_op = OPC_CVT_W_D;
                   10408:         goto do_unaryfp;
                   10409: 
                   10410:         /* Paired-foo conversions */
                   10411:     case FLOAT_1BIT_FMT(CVT_S_PL, 0):
                   10412:         mips32_op = OPC_CVT_S_PL;
                   10413:         goto do_unaryfp;
                   10414:     case FLOAT_1BIT_FMT(CVT_S_PU, 0):
                   10415:         mips32_op = OPC_CVT_S_PU;
                   10416:         goto do_unaryfp;
                   10417:     case FLOAT_1BIT_FMT(CVT_PW_PS, 0):
                   10418:         mips32_op = OPC_CVT_PW_PS;
                   10419:         goto do_unaryfp;
                   10420:     case FLOAT_1BIT_FMT(CVT_PS_PW, 0):
                   10421:         mips32_op = OPC_CVT_PS_PW;
                   10422:         goto do_unaryfp;
                   10423: 
                   10424:         /* Floating-point moves */
                   10425:     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_S):
                   10426:         mips32_op = OPC_MOV_S;
                   10427:         goto do_unaryfp;
                   10428:     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_D):
                   10429:         mips32_op = OPC_MOV_D;
                   10430:         goto do_unaryfp;
                   10431:     case FLOAT_2BIT_FMT(MOV_FMT, FMT_SDPS_PS):
                   10432:         mips32_op = OPC_MOV_PS;
                   10433:         goto do_unaryfp;
                   10434: 
                   10435:         /* Absolute value */
                   10436:     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_S):
                   10437:         mips32_op = OPC_ABS_S;
                   10438:         goto do_unaryfp;
                   10439:     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_D):
                   10440:         mips32_op = OPC_ABS_D;
                   10441:         goto do_unaryfp;
                   10442:     case FLOAT_2BIT_FMT(ABS_FMT, FMT_SDPS_PS):
                   10443:         mips32_op = OPC_ABS_PS;
                   10444:         goto do_unaryfp;
                   10445: 
                   10446:         /* Negation */
                   10447:     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_S):
                   10448:         mips32_op = OPC_NEG_S;
                   10449:         goto do_unaryfp;
                   10450:     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_D):
                   10451:         mips32_op = OPC_NEG_D;
                   10452:         goto do_unaryfp;
                   10453:     case FLOAT_2BIT_FMT(NEG_FMT, FMT_SDPS_PS):
                   10454:         mips32_op = OPC_NEG_PS;
                   10455:         goto do_unaryfp;
                   10456: 
                   10457:         /* Reciprocal square root step */
                   10458:     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_S):
                   10459:         mips32_op = OPC_RSQRT1_S;
                   10460:         goto do_unaryfp;
                   10461:     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_D):
                   10462:         mips32_op = OPC_RSQRT1_D;
                   10463:         goto do_unaryfp;
                   10464:     case FLOAT_2BIT_FMT(RSQRT1_FMT, FMT_SDPS_PS):
                   10465:         mips32_op = OPC_RSQRT1_PS;
                   10466:         goto do_unaryfp;
                   10467: 
                   10468:         /* Reciprocal step */
                   10469:     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_S):
                   10470:         mips32_op = OPC_RECIP1_S;
                   10471:         goto do_unaryfp;
                   10472:     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_D):
                   10473:         mips32_op = OPC_RECIP1_S;
                   10474:         goto do_unaryfp;
                   10475:     case FLOAT_2BIT_FMT(RECIP1_FMT, FMT_SDPS_PS):
                   10476:         mips32_op = OPC_RECIP1_PS;
                   10477:         goto do_unaryfp;
                   10478: 
                   10479:         /* Conversions from double */
                   10480:     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_S):
                   10481:         mips32_op = OPC_CVT_D_S;
                   10482:         goto do_unaryfp;
                   10483:     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_W):
                   10484:         mips32_op = OPC_CVT_D_W;
                   10485:         goto do_unaryfp;
                   10486:     case FLOAT_2BIT_FMT(CVT_D, FMT_SWL_L):
                   10487:         mips32_op = OPC_CVT_D_L;
                   10488:         goto do_unaryfp;
                   10489: 
                   10490:         /* Conversions from single */
                   10491:     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_D):
                   10492:         mips32_op = OPC_CVT_S_D;
                   10493:         goto do_unaryfp;
                   10494:     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_W):
                   10495:         mips32_op = OPC_CVT_S_W;
                   10496:         goto do_unaryfp;
                   10497:     case FLOAT_2BIT_FMT(CVT_S, FMT_DWL_L):
                   10498:         mips32_op = OPC_CVT_S_L;
                   10499:     do_unaryfp:
                   10500:         gen_farith(ctx, mips32_op, -1, rs, rt, 0);
                   10501:         break;
                   10502: 
                   10503:         /* Conditional moves on floating-point codes */
                   10504:     case COND_FLOAT_MOV(MOVT, 0):
                   10505:     case COND_FLOAT_MOV(MOVT, 1):
                   10506:     case COND_FLOAT_MOV(MOVT, 2):
                   10507:     case COND_FLOAT_MOV(MOVT, 3):
                   10508:     case COND_FLOAT_MOV(MOVT, 4):
                   10509:     case COND_FLOAT_MOV(MOVT, 5):
                   10510:     case COND_FLOAT_MOV(MOVT, 6):
                   10511:     case COND_FLOAT_MOV(MOVT, 7):
                   10512:         gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 1);
                   10513:         break;
                   10514:     case COND_FLOAT_MOV(MOVF, 0):
                   10515:     case COND_FLOAT_MOV(MOVF, 1):
                   10516:     case COND_FLOAT_MOV(MOVF, 2):
                   10517:     case COND_FLOAT_MOV(MOVF, 3):
                   10518:     case COND_FLOAT_MOV(MOVF, 4):
                   10519:     case COND_FLOAT_MOV(MOVF, 5):
                   10520:     case COND_FLOAT_MOV(MOVF, 6):
                   10521:     case COND_FLOAT_MOV(MOVF, 7):
                   10522:         gen_movci(ctx, rt, rs, (ctx->opcode >> 13) & 0x7, 0);
                   10523:         break;
                   10524:     default:
                   10525:         MIPS_INVAL("pool32fxf");
                   10526:         generate_exception(ctx, EXCP_RI);
                   10527:         break;
                   10528:     }
                   10529: }
                   10530: 
                   10531: static void decode_micromips32_opc (CPUState *env, DisasContext *ctx,
                   10532:                                     uint16_t insn_hw1, int *is_branch)
                   10533: {
                   10534:     int32_t offset;
                   10535:     uint16_t insn;
                   10536:     int rt, rs, rd, rr;
                   10537:     int16_t imm;
                   10538:     uint32_t op, minor, mips32_op;
                   10539:     uint32_t cond, fmt, cc;
                   10540: 
                   10541:     insn = lduw_code(ctx->pc + 2);
                   10542:     ctx->opcode = (ctx->opcode << 16) | insn;
                   10543: 
                   10544:     rt = (ctx->opcode >> 21) & 0x1f;
                   10545:     rs = (ctx->opcode >> 16) & 0x1f;
                   10546:     rd = (ctx->opcode >> 11) & 0x1f;
                   10547:     rr = (ctx->opcode >> 6) & 0x1f;
                   10548:     imm = (int16_t) ctx->opcode;
                   10549: 
                   10550:     op = (ctx->opcode >> 26) & 0x3f;
                   10551:     switch (op) {
                   10552:     case POOL32A:
                   10553:         minor = ctx->opcode & 0x3f;
                   10554:         switch (minor) {
                   10555:         case 0x00:
                   10556:             minor = (ctx->opcode >> 6) & 0xf;
                   10557:             switch (minor) {
                   10558:             case SLL32:
                   10559:                 mips32_op = OPC_SLL;
                   10560:                 goto do_shifti;
                   10561:             case SRA:
                   10562:                 mips32_op = OPC_SRA;
                   10563:                 goto do_shifti;
                   10564:             case SRL32:
                   10565:                 mips32_op = OPC_SRL;
                   10566:                 goto do_shifti;
                   10567:             case ROTR:
                   10568:                 mips32_op = OPC_ROTR;
                   10569:             do_shifti:
                   10570:                 gen_shift_imm(env, ctx, mips32_op, rt, rs, rd);
                   10571:                 break;
                   10572:             default:
                   10573:                 goto pool32a_invalid;
                   10574:             }
                   10575:             break;
                   10576:         case 0x10:
                   10577:             minor = (ctx->opcode >> 6) & 0xf;
                   10578:             switch (minor) {
                   10579:                 /* Arithmetic */
                   10580:             case ADD:
                   10581:                 mips32_op = OPC_ADD;
                   10582:                 goto do_arith;
                   10583:             case ADDU32:
                   10584:                 mips32_op = OPC_ADDU;
                   10585:                 goto do_arith;
                   10586:             case SUB:
                   10587:                 mips32_op = OPC_SUB;
                   10588:                 goto do_arith;
                   10589:             case SUBU32:
                   10590:                 mips32_op = OPC_SUBU;
                   10591:                 goto do_arith;
                   10592:             case MUL:
                   10593:                 mips32_op = OPC_MUL;
                   10594:             do_arith:
                   10595:                 gen_arith(env, ctx, mips32_op, rd, rs, rt);
                   10596:                 break;
                   10597:                 /* Shifts */
                   10598:             case SLLV:
                   10599:                 mips32_op = OPC_SLLV;
                   10600:                 goto do_shift;
                   10601:             case SRLV:
                   10602:                 mips32_op = OPC_SRLV;
                   10603:                 goto do_shift;
                   10604:             case SRAV:
                   10605:                 mips32_op = OPC_SRAV;
                   10606:                 goto do_shift;
                   10607:             case ROTRV:
                   10608:                 mips32_op = OPC_ROTRV;
                   10609:             do_shift:
                   10610:                 gen_shift(env, ctx, mips32_op, rd, rs, rt);
                   10611:                 break;
                   10612:                 /* Logical operations */
                   10613:             case AND:
                   10614:                 mips32_op = OPC_AND;
                   10615:                 goto do_logic;
                   10616:             case OR32:
                   10617:                 mips32_op = OPC_OR;
                   10618:                 goto do_logic;
                   10619:             case NOR:
                   10620:                 mips32_op = OPC_NOR;
                   10621:                 goto do_logic;
                   10622:             case XOR32:
                   10623:                 mips32_op = OPC_XOR;
                   10624:             do_logic:
                   10625:                 gen_logic(env, mips32_op, rd, rs, rt);
                   10626:                 break;
                   10627:                 /* Set less than */
                   10628:             case SLT:
                   10629:                 mips32_op = OPC_SLT;
                   10630:                 goto do_slt;
                   10631:             case SLTU:
                   10632:                 mips32_op = OPC_SLTU;
                   10633:             do_slt:
                   10634:                 gen_slt(env, mips32_op, rd, rs, rt);
                   10635:                 break;
                   10636:             default:
                   10637:                 goto pool32a_invalid;
                   10638:             }
                   10639:             break;
                   10640:         case 0x18:
                   10641:             minor = (ctx->opcode >> 6) & 0xf;
                   10642:             switch (minor) {
                   10643:                 /* Conditional moves */
                   10644:             case MOVN:
                   10645:                 mips32_op = OPC_MOVN;
                   10646:                 goto do_cmov;
                   10647:             case MOVZ:
                   10648:                 mips32_op = OPC_MOVZ;
                   10649:             do_cmov:
                   10650:                 gen_cond_move(env, mips32_op, rd, rs, rt);
                   10651:                 break;
                   10652:             case LWXS:
                   10653:                 gen_ldxs(ctx, rs, rt, rd);
                   10654:                 break;
                   10655:             default:
                   10656:                 goto pool32a_invalid;
                   10657:             }
                   10658:             break;
                   10659:         case INS:
                   10660:             gen_bitops(ctx, OPC_INS, rt, rs, rr, rd);
                   10661:             return;
                   10662:         case EXT:
                   10663:             gen_bitops(ctx, OPC_EXT, rt, rs, rr, rd);
                   10664:             return;
                   10665:         case POOL32AXF:
                   10666:             gen_pool32axf(env, ctx, rt, rs, is_branch);
                   10667:             break;
                   10668:         case 0x07:
                   10669:             generate_exception(ctx, EXCP_BREAK);
                   10670:             break;
                   10671:         default:
                   10672:         pool32a_invalid:
                   10673:                 MIPS_INVAL("pool32a");
                   10674:                 generate_exception(ctx, EXCP_RI);
                   10675:                 break;
                   10676:         }
                   10677:         break;
                   10678:     case POOL32B:
                   10679:         minor = (ctx->opcode >> 12) & 0xf;
                   10680:         switch (minor) {
                   10681:         case CACHE:
                   10682:             /* Treat as no-op. */
                   10683:             break;
                   10684:         case LWC2:
                   10685:         case SWC2:
                   10686:             /* COP2: Not implemented. */
                   10687:             generate_exception_err(ctx, EXCP_CpU, 2);
                   10688:             break;
                   10689:         case LWP:
                   10690:         case SWP:
                   10691: #ifdef TARGET_MIPS64
                   10692:         case LDP:
                   10693:         case SDP:
                   10694: #endif
                   10695:             gen_ldst_pair(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
                   10696:             break;
                   10697:         case LWM32:
                   10698:         case SWM32:
                   10699: #ifdef TARGET_MIPS64
                   10700:         case LDM:
                   10701:         case SDM:
                   10702: #endif
                   10703:             gen_ldst_multiple(ctx, minor, rt, rs, SIMM(ctx->opcode, 0, 12));
                   10704:             break;
                   10705:         default:
                   10706:             MIPS_INVAL("pool32b");
                   10707:             generate_exception(ctx, EXCP_RI);
                   10708:             break;
                   10709:         }
                   10710:         break;
                   10711:     case POOL32F:
                   10712:         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
                   10713:             minor = ctx->opcode & 0x3f;
                   10714:             check_cp1_enabled(ctx);
                   10715:             switch (minor) {
                   10716:             case ALNV_PS:
                   10717:                 mips32_op = OPC_ALNV_PS;
                   10718:                 goto do_madd;
                   10719:             case MADD_S:
                   10720:                 mips32_op = OPC_MADD_S;
                   10721:                 goto do_madd;
                   10722:             case MADD_D:
                   10723:                 mips32_op = OPC_MADD_D;
                   10724:                 goto do_madd;
                   10725:             case MADD_PS:
                   10726:                 mips32_op = OPC_MADD_PS;
                   10727:                 goto do_madd;
                   10728:             case MSUB_S:
                   10729:                 mips32_op = OPC_MSUB_S;
                   10730:                 goto do_madd;
                   10731:             case MSUB_D:
                   10732:                 mips32_op = OPC_MSUB_D;
                   10733:                 goto do_madd;
                   10734:             case MSUB_PS:
                   10735:                 mips32_op = OPC_MSUB_PS;
                   10736:                 goto do_madd;
                   10737:             case NMADD_S:
                   10738:                 mips32_op = OPC_NMADD_S;
                   10739:                 goto do_madd;
                   10740:             case NMADD_D:
                   10741:                 mips32_op = OPC_NMADD_D;
                   10742:                 goto do_madd;
                   10743:             case NMADD_PS:
                   10744:                 mips32_op = OPC_NMADD_PS;
                   10745:                 goto do_madd;
                   10746:             case NMSUB_S:
                   10747:                 mips32_op = OPC_NMSUB_S;
                   10748:                 goto do_madd;
                   10749:             case NMSUB_D:
                   10750:                 mips32_op = OPC_NMSUB_D;
                   10751:                 goto do_madd;
                   10752:             case NMSUB_PS:
                   10753:                 mips32_op = OPC_NMSUB_PS;
                   10754:             do_madd:
                   10755:                 gen_flt3_arith(ctx, mips32_op, rd, rr, rs, rt);
                   10756:                 break;
                   10757:             case CABS_COND_FMT:
                   10758:                 cond = (ctx->opcode >> 6) & 0xf;
                   10759:                 cc = (ctx->opcode >> 13) & 0x7;
                   10760:                 fmt = (ctx->opcode >> 10) & 0x3;
                   10761:                 switch (fmt) {
                   10762:                 case 0x0:
                   10763:                     gen_cmpabs_s(ctx, cond, rt, rs, cc);
                   10764:                     break;
                   10765:                 case 0x1:
                   10766:                     gen_cmpabs_d(ctx, cond, rt, rs, cc);
                   10767:                     break;
                   10768:                 case 0x2:
                   10769:                     gen_cmpabs_ps(ctx, cond, rt, rs, cc);
                   10770:                     break;
                   10771:                 default:
                   10772:                     goto pool32f_invalid;
                   10773:                 }
                   10774:                 break;
                   10775:             case C_COND_FMT:
                   10776:                 cond = (ctx->opcode >> 6) & 0xf;
                   10777:                 cc = (ctx->opcode >> 13) & 0x7;
                   10778:                 fmt = (ctx->opcode >> 10) & 0x3;
                   10779:                 switch (fmt) {
                   10780:                 case 0x0:
                   10781:                     gen_cmp_s(ctx, cond, rt, rs, cc);
                   10782:                     break;
                   10783:                 case 0x1:
                   10784:                     gen_cmp_d(ctx, cond, rt, rs, cc);
                   10785:                     break;
                   10786:                 case 0x2:
                   10787:                     gen_cmp_ps(ctx, cond, rt, rs, cc);
                   10788:                     break;
                   10789:                 default:
                   10790:                     goto pool32f_invalid;
                   10791:                 }
                   10792:                 break;
                   10793:             case POOL32FXF:
                   10794:                 gen_pool32fxf(env, ctx, rt, rs);
                   10795:                 break;
                   10796:             case 0x00:
                   10797:                 /* PLL foo */
                   10798:                 switch ((ctx->opcode >> 6) & 0x7) {
                   10799:                 case PLL_PS:
                   10800:                     mips32_op = OPC_PLL_PS;
                   10801:                     goto do_ps;
                   10802:                 case PLU_PS:
                   10803:                     mips32_op = OPC_PLU_PS;
                   10804:                     goto do_ps;
                   10805:                 case PUL_PS:
                   10806:                     mips32_op = OPC_PUL_PS;
                   10807:                     goto do_ps;
                   10808:                 case PUU_PS:
                   10809:                     mips32_op = OPC_PUU_PS;
                   10810:                     goto do_ps;
                   10811:                 case CVT_PS_S:
                   10812:                     mips32_op = OPC_CVT_PS_S;
                   10813:                 do_ps:
                   10814:                     gen_farith(ctx, mips32_op, rt, rs, rd, 0);
                   10815:                     break;
                   10816:                 default:
                   10817:                     goto pool32f_invalid;
                   10818:                 }
                   10819:                 break;
                   10820:             case 0x08:
                   10821:                 /* [LS][WDU]XC1 */
                   10822:                 switch ((ctx->opcode >> 6) & 0x7) {
                   10823:                 case LWXC1:
                   10824:                     mips32_op = OPC_LWXC1;
                   10825:                     goto do_ldst_cp1;
                   10826:                 case SWXC1:
                   10827:                     mips32_op = OPC_SWXC1;
                   10828:                     goto do_ldst_cp1;
                   10829:                 case LDXC1:
                   10830:                     mips32_op = OPC_LDXC1;
                   10831:                     goto do_ldst_cp1;
                   10832:                 case SDXC1:
                   10833:                     mips32_op = OPC_SDXC1;
                   10834:                     goto do_ldst_cp1;
                   10835:                 case LUXC1:
                   10836:                     mips32_op = OPC_LUXC1;
                   10837:                     goto do_ldst_cp1;
                   10838:                 case SUXC1:
                   10839:                     mips32_op = OPC_SUXC1;
                   10840:                 do_ldst_cp1:
                   10841:                     gen_flt3_ldst(ctx, mips32_op, rd, rd, rt, rs);
                   10842:                     break;
                   10843:                 default:
                   10844:                     goto pool32f_invalid;
                   10845:                 }
                   10846:                 break;
                   10847:             case 0x18:
                   10848:                 /* 3D insns */
                   10849:                 fmt = (ctx->opcode >> 9) & 0x3;
                   10850:                 switch ((ctx->opcode >> 6) & 0x7) {
                   10851:                 case RSQRT2_FMT:
                   10852:                     switch (fmt) {
                   10853:                     case FMT_SDPS_S:
                   10854:                         mips32_op = OPC_RSQRT2_S;
                   10855:                         goto do_3d;
                   10856:                     case FMT_SDPS_D:
                   10857:                         mips32_op = OPC_RSQRT2_D;
                   10858:                         goto do_3d;
                   10859:                     case FMT_SDPS_PS:
                   10860:                         mips32_op = OPC_RSQRT2_PS;
                   10861:                         goto do_3d;
                   10862:                     default:
                   10863:                         goto pool32f_invalid;
                   10864:                     }
                   10865:                     break;
                   10866:                 case RECIP2_FMT:
                   10867:                     switch (fmt) {
                   10868:                     case FMT_SDPS_S:
                   10869:                         mips32_op = OPC_RECIP2_S;
                   10870:                         goto do_3d;
                   10871:                     case FMT_SDPS_D:
                   10872:                         mips32_op = OPC_RECIP2_D;
                   10873:                         goto do_3d;
                   10874:                     case FMT_SDPS_PS:
                   10875:                         mips32_op = OPC_RECIP2_PS;
                   10876:                         goto do_3d;
                   10877:                     default:
                   10878:                         goto pool32f_invalid;
                   10879:                     }
                   10880:                     break;
                   10881:                 case ADDR_PS:
                   10882:                     mips32_op = OPC_ADDR_PS;
                   10883:                     goto do_3d;
                   10884:                 case MULR_PS:
                   10885:                     mips32_op = OPC_MULR_PS;
                   10886:                 do_3d:
                   10887:                     gen_farith(ctx, mips32_op, rt, rs, rd, 0);
                   10888:                     break;
                   10889:                 default:
                   10890:                     goto pool32f_invalid;
                   10891:                 }
                   10892:                 break;
                   10893:             case 0x20:
                   10894:                 /* MOV[FT].fmt and PREFX */
                   10895:                 cc = (ctx->opcode >> 13) & 0x7;
                   10896:                 fmt = (ctx->opcode >> 9) & 0x3;
                   10897:                 switch ((ctx->opcode >> 6) & 0x7) {
                   10898:                 case MOVF_FMT:
                   10899:                     switch (fmt) {
                   10900:                     case FMT_SDPS_S:
                   10901:                         gen_movcf_s(rs, rt, cc, 0);
                   10902:                         break;
                   10903:                     case FMT_SDPS_D:
                   10904:                         gen_movcf_d(ctx, rs, rt, cc, 0);
                   10905:                         break;
                   10906:                     case FMT_SDPS_PS:
                   10907:                         gen_movcf_ps(rs, rt, cc, 0);
                   10908:                         break;
                   10909:                     default:
                   10910:                         goto pool32f_invalid;
                   10911:                     }
                   10912:                     break;
                   10913:                 case MOVT_FMT:
                   10914:                     switch (fmt) {
                   10915:                     case FMT_SDPS_S:
                   10916:                         gen_movcf_s(rs, rt, cc, 1);
                   10917:                         break;
                   10918:                     case FMT_SDPS_D:
                   10919:                         gen_movcf_d(ctx, rs, rt, cc, 1);
                   10920:                         break;
                   10921:                     case FMT_SDPS_PS:
                   10922:                         gen_movcf_ps(rs, rt, cc, 1);
                   10923:                         break;
                   10924:                     default:
                   10925:                         goto pool32f_invalid;
                   10926:                     }
                   10927:                     break;
                   10928:                 case PREFX:
                   10929:                     break;
                   10930:                 default:
                   10931:                     goto pool32f_invalid;
                   10932:                 }
                   10933:                 break;
                   10934: #define FINSN_3ARG_SDPS(prfx)                           \
                   10935:                 switch ((ctx->opcode >> 8) & 0x3) {     \
                   10936:                 case FMT_SDPS_S:                        \
                   10937:                     mips32_op = OPC_##prfx##_S;         \
                   10938:                     goto do_fpop;                       \
                   10939:                 case FMT_SDPS_D:                        \
                   10940:                     mips32_op = OPC_##prfx##_D;         \
                   10941:                     goto do_fpop;                       \
                   10942:                 case FMT_SDPS_PS:                       \
                   10943:                     mips32_op = OPC_##prfx##_PS;        \
                   10944:                     goto do_fpop;                       \
                   10945:                 default:                                \
                   10946:                     goto pool32f_invalid;               \
                   10947:                 }
                   10948:             case 0x30:
                   10949:                 /* regular FP ops */
                   10950:                 switch ((ctx->opcode >> 6) & 0x3) {
                   10951:                 case ADD_FMT:
                   10952:                     FINSN_3ARG_SDPS(ADD);
                   10953:                     break;
                   10954:                 case SUB_FMT:
                   10955:                     FINSN_3ARG_SDPS(SUB);
                   10956:                     break;
                   10957:                 case MUL_FMT:
                   10958:                     FINSN_3ARG_SDPS(MUL);
                   10959:                     break;
                   10960:                 case DIV_FMT:
                   10961:                     fmt = (ctx->opcode >> 8) & 0x3;
                   10962:                     if (fmt == 1) {
                   10963:                         mips32_op = OPC_DIV_D;
                   10964:                     } else if (fmt == 0) {
                   10965:                         mips32_op = OPC_DIV_S;
                   10966:                     } else {
                   10967:                         goto pool32f_invalid;
                   10968:                     }
                   10969:                     goto do_fpop;
                   10970:                 default:
                   10971:                     goto pool32f_invalid;
                   10972:                 }
                   10973:                 break;
                   10974:             case 0x38:
                   10975:                 /* cmovs */
                   10976:                 switch ((ctx->opcode >> 6) & 0x3) {
                   10977:                 case MOVN_FMT:
                   10978:                     FINSN_3ARG_SDPS(MOVN);
                   10979:                     break;
                   10980:                 case MOVZ_FMT:
                   10981:                     FINSN_3ARG_SDPS(MOVZ);
                   10982:                     break;
                   10983:                 default:
                   10984:                     goto pool32f_invalid;
                   10985:                 }
                   10986:                 break;
                   10987:             do_fpop:
                   10988:                 gen_farith(ctx, mips32_op, rt, rs, rd, 0);
                   10989:                 break;
                   10990:             default:
                   10991:             pool32f_invalid:
                   10992:                 MIPS_INVAL("pool32f");
                   10993:                 generate_exception(ctx, EXCP_RI);
                   10994:                 break;
                   10995:             }
                   10996:         } else {
                   10997:             generate_exception_err(ctx, EXCP_CpU, 1);
                   10998:         }
                   10999:         break;
                   11000:     case POOL32I:
                   11001:         minor = (ctx->opcode >> 21) & 0x1f;
                   11002:         switch (minor) {
                   11003:         case BLTZ:
                   11004:             mips32_op = OPC_BLTZ;
                   11005:             goto do_branch;
                   11006:         case BLTZAL:
                   11007:             mips32_op = OPC_BLTZAL;
                   11008:             goto do_branch;
                   11009:         case BLTZALS:
                   11010:             mips32_op = OPC_BLTZALS;
                   11011:             goto do_branch;
                   11012:         case BGEZ:
                   11013:             mips32_op = OPC_BGEZ;
                   11014:             goto do_branch;
                   11015:         case BGEZAL:
                   11016:             mips32_op = OPC_BGEZAL;
                   11017:             goto do_branch;
                   11018:         case BGEZALS:
                   11019:             mips32_op = OPC_BGEZALS;
                   11020:             goto do_branch;
                   11021:         case BLEZ:
                   11022:             mips32_op = OPC_BLEZ;
                   11023:             goto do_branch;
                   11024:         case BGTZ:
                   11025:             mips32_op = OPC_BGTZ;
                   11026:         do_branch:
                   11027:             gen_compute_branch(ctx, mips32_op, 4, rs, -1, imm << 1);
                   11028:             *is_branch = 1;
                   11029:             break;
                   11030: 
                   11031:             /* Traps */
                   11032:         case TLTI:
                   11033:             mips32_op = OPC_TLTI;
                   11034:             goto do_trapi;
                   11035:         case TGEI:
                   11036:             mips32_op = OPC_TGEI;
                   11037:             goto do_trapi;
                   11038:         case TLTIU:
                   11039:             mips32_op = OPC_TLTIU;
                   11040:             goto do_trapi;
                   11041:         case TGEIU:
                   11042:             mips32_op = OPC_TGEIU;
                   11043:             goto do_trapi;
                   11044:         case TNEI:
                   11045:             mips32_op = OPC_TNEI;
                   11046:             goto do_trapi;
                   11047:         case TEQI:
                   11048:             mips32_op = OPC_TEQI;
                   11049:         do_trapi:
                   11050:             gen_trap(ctx, mips32_op, rs, -1, imm);
                   11051:             break;
                   11052: 
                   11053:         case BNEZC:
                   11054:         case BEQZC:
                   11055:             gen_compute_branch(ctx, minor == BNEZC ? OPC_BNE : OPC_BEQ,
                   11056:                                4, rs, 0, imm << 1);
                   11057:             /* Compact branches don't have a delay slot, so just let
                   11058:                the normal delay slot handling take us to the branch
                   11059:                target. */
                   11060:             break;
                   11061:         case LUI:
                   11062:             gen_logic_imm(env, OPC_LUI, rs, -1, imm);
                   11063:             break;
                   11064:         case SYNCI:
                   11065:             break;
                   11066:         case BC2F:
                   11067:         case BC2T:
                   11068:             /* COP2: Not implemented. */
                   11069:             generate_exception_err(ctx, EXCP_CpU, 2);
                   11070:             break;
                   11071:         case BC1F:
                   11072:             mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1FANY2 : OPC_BC1F;
                   11073:             goto do_cp1branch;
                   11074:         case BC1T:
                   11075:             mips32_op = (ctx->opcode & (1 << 16)) ? OPC_BC1TANY2 : OPC_BC1T;
                   11076:             goto do_cp1branch;
                   11077:         case BC1ANY4F:
                   11078:             mips32_op = OPC_BC1FANY4;
                   11079:             goto do_cp1mips3d;
                   11080:         case BC1ANY4T:
                   11081:             mips32_op = OPC_BC1TANY4;
                   11082:         do_cp1mips3d:
                   11083:             check_cop1x(ctx);
                   11084:             check_insn(env, ctx, ASE_MIPS3D);
                   11085:             /* Fall through */
                   11086:         do_cp1branch:
                   11087:             gen_compute_branch1(env, ctx, mips32_op,
                   11088:                                 (ctx->opcode >> 18) & 0x7, imm << 1);
                   11089:             *is_branch = 1;
                   11090:             break;
                   11091:         case BPOSGE64:
                   11092:         case BPOSGE32:
                   11093:             /* MIPS DSP: not implemented */
                   11094:             /* Fall through */
                   11095:         default:
                   11096:             MIPS_INVAL("pool32i");
                   11097:             generate_exception(ctx, EXCP_RI);
                   11098:             break;
                   11099:         }
                   11100:         break;
                   11101:     case POOL32C:
                   11102:         minor = (ctx->opcode >> 12) & 0xf;
                   11103:         switch (minor) {
                   11104:         case LWL:
                   11105:             mips32_op = OPC_LWL;
                   11106:             goto do_ld_lr;
                   11107:         case SWL:
                   11108:             mips32_op = OPC_SWL;
                   11109:             goto do_st_lr;
                   11110:         case LWR:
                   11111:             mips32_op = OPC_LWR;
                   11112:             goto do_ld_lr;
                   11113:         case SWR:
                   11114:             mips32_op = OPC_SWR;
                   11115:             goto do_st_lr;
                   11116: #if defined(TARGET_MIPS64)
                   11117:         case LDL:
                   11118:             mips32_op = OPC_LDL;
                   11119:             goto do_ld_lr;
                   11120:         case SDL:
                   11121:             mips32_op = OPC_SDL;
                   11122:             goto do_st_lr;
                   11123:         case LDR:
                   11124:             mips32_op = OPC_LDR;
                   11125:             goto do_ld_lr;
                   11126:         case SDR:
                   11127:             mips32_op = OPC_SDR;
                   11128:             goto do_st_lr;
                   11129:         case LWU:
                   11130:             mips32_op = OPC_LWU;
                   11131:             goto do_ld_lr;
                   11132:         case LLD:
                   11133:             mips32_op = OPC_LLD;
                   11134:             goto do_ld_lr;
                   11135: #endif
                   11136:         case LL:
                   11137:             mips32_op = OPC_LL;
                   11138:             goto do_ld_lr;
                   11139:         do_ld_lr:
                   11140:             gen_ld(env, ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
                   11141:             break;
                   11142:         do_st_lr:
                   11143:             gen_st(ctx, mips32_op, rt, rs, SIMM(ctx->opcode, 0, 12));
                   11144:             break;
                   11145:         case SC:
                   11146:             gen_st_cond(ctx, OPC_SC, rt, rs, SIMM(ctx->opcode, 0, 12));
                   11147:             break;
                   11148: #if defined(TARGET_MIPS64)
                   11149:         case SCD:
                   11150:             gen_st_cond(ctx, OPC_SCD, rt, rs, SIMM(ctx->opcode, 0, 12));
                   11151:             break;
                   11152: #endif
                   11153:         case PREF:
                   11154:             /* Treat as no-op */
                   11155:             break;
                   11156:         default:
                   11157:             MIPS_INVAL("pool32c");
                   11158:             generate_exception(ctx, EXCP_RI);
                   11159:             break;
                   11160:         }
                   11161:         break;
                   11162:     case ADDI32:
                   11163:         mips32_op = OPC_ADDI;
                   11164:         goto do_addi;
                   11165:     case ADDIU32:
                   11166:         mips32_op = OPC_ADDIU;
                   11167:     do_addi:
                   11168:         gen_arith_imm(env, ctx, mips32_op, rt, rs, imm);
                   11169:         break;
                   11170: 
                   11171:         /* Logical operations */
                   11172:     case ORI32:
                   11173:         mips32_op = OPC_ORI;
                   11174:         goto do_logici;
                   11175:     case XORI32:
                   11176:         mips32_op = OPC_XORI;
                   11177:         goto do_logici;
                   11178:     case ANDI32:
                   11179:         mips32_op = OPC_ANDI;
                   11180:     do_logici:
                   11181:         gen_logic_imm(env, mips32_op, rt, rs, imm);
                   11182:         break;
                   11183: 
                   11184:         /* Set less than immediate */
                   11185:     case SLTI32:
                   11186:         mips32_op = OPC_SLTI;
                   11187:         goto do_slti;
                   11188:     case SLTIU32:
                   11189:         mips32_op = OPC_SLTIU;
                   11190:     do_slti:
                   11191:         gen_slt_imm(env, mips32_op, rt, rs, imm);
                   11192:         break;
                   11193:     case JALX32:
                   11194:         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
                   11195:         gen_compute_branch(ctx, OPC_JALX, 4, rt, rs, offset);
                   11196:         *is_branch = 1;
                   11197:         break;
                   11198:     case JALS32:
                   11199:         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 1;
                   11200:         gen_compute_branch(ctx, OPC_JALS, 4, rt, rs, offset);
                   11201:         *is_branch = 1;
                   11202:         break;
                   11203:     case BEQ32:
                   11204:         gen_compute_branch(ctx, OPC_BEQ, 4, rt, rs, imm << 1);
                   11205:         *is_branch = 1;
                   11206:         break;
                   11207:     case BNE32:
                   11208:         gen_compute_branch(ctx, OPC_BNE, 4, rt, rs, imm << 1);
                   11209:         *is_branch = 1;
                   11210:         break;
                   11211:     case J32:
                   11212:         gen_compute_branch(ctx, OPC_J, 4, rt, rs,
                   11213:                            (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
                   11214:         *is_branch = 1;
                   11215:         break;
                   11216:     case JAL32:
                   11217:         gen_compute_branch(ctx, OPC_JAL, 4, rt, rs,
                   11218:                            (int32_t)(ctx->opcode & 0x3FFFFFF) << 1);
                   11219:         *is_branch = 1;
                   11220:         break;
                   11221:         /* Floating point (COP1) */
                   11222:     case LWC132:
                   11223:         mips32_op = OPC_LWC1;
                   11224:         goto do_cop1;
                   11225:     case LDC132:
                   11226:         mips32_op = OPC_LDC1;
                   11227:         goto do_cop1;
                   11228:     case SWC132:
                   11229:         mips32_op = OPC_SWC1;
                   11230:         goto do_cop1;
                   11231:     case SDC132:
                   11232:         mips32_op = OPC_SDC1;
                   11233:     do_cop1:
                   11234:         gen_cop1_ldst(env, ctx, mips32_op, rt, rs, imm);
                   11235:         break;
                   11236:     case ADDIUPC:
                   11237:         {
                   11238:             int reg = mmreg(ZIMM(ctx->opcode, 23, 3));
                   11239:             int offset = SIMM(ctx->opcode, 0, 23) << 2;
                   11240: 
                   11241:             gen_addiupc(ctx, reg, offset, 0, 0);
                   11242:         }
                   11243:         break;
                   11244:         /* Loads and stores */
                   11245:     case LB32:
                   11246:         mips32_op = OPC_LB;
                   11247:         goto do_ld;
                   11248:     case LBU32:
                   11249:         mips32_op = OPC_LBU;
                   11250:         goto do_ld;
                   11251:     case LH32:
                   11252:         mips32_op = OPC_LH;
                   11253:         goto do_ld;
                   11254:     case LHU32:
                   11255:         mips32_op = OPC_LHU;
                   11256:         goto do_ld;
                   11257:     case LW32:
                   11258:         mips32_op = OPC_LW;
                   11259:         goto do_ld;
                   11260: #ifdef TARGET_MIPS64
                   11261:     case LD32:
                   11262:         mips32_op = OPC_LD;
                   11263:         goto do_ld;
                   11264:     case SD32:
                   11265:         mips32_op = OPC_SD;
                   11266:         goto do_st;
                   11267: #endif
                   11268:     case SB32:
                   11269:         mips32_op = OPC_SB;
                   11270:         goto do_st;
                   11271:     case SH32:
                   11272:         mips32_op = OPC_SH;
                   11273:         goto do_st;
                   11274:     case SW32:
                   11275:         mips32_op = OPC_SW;
                   11276:         goto do_st;
                   11277:     do_ld:
                   11278:         gen_ld(env, ctx, mips32_op, rt, rs, imm);
                   11279:         break;
                   11280:     do_st:
                   11281:         gen_st(ctx, mips32_op, rt, rs, imm);
                   11282:         break;
                   11283:     default:
                   11284:         generate_exception(ctx, EXCP_RI);
                   11285:         break;
                   11286:     }
                   11287: }
                   11288: 
                   11289: static int decode_micromips_opc (CPUState *env, DisasContext *ctx, int *is_branch)
                   11290: {
                   11291:     uint32_t op;
                   11292: 
                   11293:     /* make sure instructions are on a halfword boundary */
                   11294:     if (ctx->pc & 0x1) {
                   11295:         env->CP0_BadVAddr = ctx->pc;
                   11296:         generate_exception(ctx, EXCP_AdEL);
                   11297:         ctx->bstate = BS_STOP;
                   11298:         return 2;
                   11299:     }
                   11300: 
                   11301:     op = (ctx->opcode >> 10) & 0x3f;
                   11302:     /* Enforce properly-sized instructions in a delay slot */
                   11303:     if (ctx->hflags & MIPS_HFLAG_BMASK) {
                   11304:         int bits = ctx->hflags & MIPS_HFLAG_BMASK_EXT;
                   11305: 
                   11306:         switch (op) {
                   11307:         case POOL32A:
                   11308:         case POOL32B:
                   11309:         case POOL32I:
                   11310:         case POOL32C:
                   11311:         case ADDI32:
                   11312:         case ADDIU32:
                   11313:         case ORI32:
                   11314:         case XORI32:
                   11315:         case SLTI32:
                   11316:         case SLTIU32:
                   11317:         case ANDI32:
                   11318:         case JALX32:
                   11319:         case LBU32:
                   11320:         case LHU32:
                   11321:         case POOL32F:
                   11322:         case JALS32:
                   11323:         case BEQ32:
                   11324:         case BNE32:
                   11325:         case J32:
                   11326:         case JAL32:
                   11327:         case SB32:
                   11328:         case SH32:
                   11329:         case POOL32S:
                   11330:         case ADDIUPC:
                   11331:         case SWC132:
                   11332:         case SDC132:
                   11333:         case SD32:
                   11334:         case SW32:
                   11335:         case LB32:
                   11336:         case LH32:
                   11337:         case DADDIU32:
                   11338:         case POOL48A:           /* ??? */
                   11339:         case LWC132:
                   11340:         case LDC132:
                   11341:         case LD32:
                   11342:         case LW32:
                   11343:             if (bits & MIPS_HFLAG_BDS16) {
                   11344:                 generate_exception(ctx, EXCP_RI);
                   11345:                 /* Just stop translation; the user is confused.  */
                   11346:                 ctx->bstate = BS_STOP;
                   11347:                 return 2;
                   11348:             }
                   11349:             break;
                   11350:         case POOL16A:
                   11351:         case POOL16B:
                   11352:         case POOL16C:
                   11353:         case LWGP16:
                   11354:         case POOL16F:
                   11355:         case LBU16:
                   11356:         case LHU16:
                   11357:         case LWSP16:
                   11358:         case LW16:
                   11359:         case SB16:
                   11360:         case SH16:
                   11361:         case SWSP16:
                   11362:         case SW16:
                   11363:         case MOVE16:
                   11364:         case ANDI16:
                   11365:         case POOL16D:
                   11366:         case POOL16E:
                   11367:         case BEQZ16:
                   11368:         case BNEZ16:
                   11369:         case B16:
                   11370:         case LI16:
                   11371:             if (bits & MIPS_HFLAG_BDS32) {
                   11372:                 generate_exception(ctx, EXCP_RI);
                   11373:                 /* Just stop translation; the user is confused.  */
                   11374:                 ctx->bstate = BS_STOP;
                   11375:                 return 2;
                   11376:             }
                   11377:             break;
                   11378:         default:
                   11379:             break;
                   11380:         }
                   11381:     }
                   11382:     switch (op) {
                   11383:     case POOL16A:
                   11384:         {
                   11385:             int rd = mmreg(uMIPS_RD(ctx->opcode));
                   11386:             int rs1 = mmreg(uMIPS_RS1(ctx->opcode));
                   11387:             int rs2 = mmreg(uMIPS_RS2(ctx->opcode));
                   11388:             uint32_t opc = 0;
                   11389: 
                   11390:             switch (ctx->opcode & 0x1) {
                   11391:             case ADDU16:
                   11392:                 opc = OPC_ADDU;
                   11393:                 break;
                   11394:             case SUBU16:
                   11395:                 opc = OPC_SUBU;
                   11396:                 break;
                   11397:             }
                   11398: 
                   11399:             gen_arith(env, ctx, opc, rd, rs1, rs2);
                   11400:         }
                   11401:         break;
                   11402:     case POOL16B:
                   11403:         {
                   11404:             int rd = mmreg(uMIPS_RD(ctx->opcode));
                   11405:             int rs = mmreg(uMIPS_RS(ctx->opcode));
                   11406:             int amount = (ctx->opcode >> 1) & 0x7;
                   11407:             uint32_t opc = 0;
                   11408:             amount = amount == 0 ? 8 : amount;
                   11409: 
                   11410:             switch (ctx->opcode & 0x1) {
                   11411:             case SLL16:
                   11412:                 opc = OPC_SLL;
                   11413:                 break;
                   11414:             case SRL16:
                   11415:                 opc = OPC_SRL;
                   11416:                 break;
                   11417:             }
                   11418: 
                   11419:             gen_shift_imm(env, ctx, opc, rd, rs, amount);
                   11420:         }
                   11421:         break;
                   11422:     case POOL16C:
                   11423:         gen_pool16c_insn(env, ctx, is_branch);
                   11424:         break;
                   11425:     case LWGP16:
                   11426:         {
                   11427:             int rd = mmreg(uMIPS_RD(ctx->opcode));
                   11428:             int rb = 28;            /* GP */
                   11429:             int16_t offset = SIMM(ctx->opcode, 0, 7) << 2;
                   11430: 
                   11431:             gen_ld(env, ctx, OPC_LW, rd, rb, offset);
                   11432:         }
                   11433:         break;
                   11434:     case POOL16F:
                   11435:         if (ctx->opcode & 1) {
                   11436:             generate_exception(ctx, EXCP_RI);
                   11437:         } else {
                   11438:             /* MOVEP */
                   11439:             int enc_dest = uMIPS_RD(ctx->opcode);
                   11440:             int enc_rt = uMIPS_RS2(ctx->opcode);
                   11441:             int enc_rs = uMIPS_RS1(ctx->opcode);
                   11442:             int rd, rs, re, rt;
                   11443:             static const int rd_enc[] = { 5, 5, 6, 4, 4, 4, 4, 4 };
                   11444:             static const int re_enc[] = { 6, 7, 7, 21, 22, 5, 6, 7 };
                   11445:             static const int rs_rt_enc[] = { 0, 17, 2, 3, 16, 18, 19, 20 };
                   11446: 
                   11447:             rd = rd_enc[enc_dest];
                   11448:             re = re_enc[enc_dest];
                   11449:             rs = rs_rt_enc[enc_rs];
                   11450:             rt = rs_rt_enc[enc_rt];
                   11451: 
                   11452:             gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
                   11453:             gen_arith_imm(env, ctx, OPC_ADDIU, re, rt, 0);
                   11454:         }
                   11455:         break;
                   11456:     case LBU16:
                   11457:         {
                   11458:             int rd = mmreg(uMIPS_RD(ctx->opcode));
                   11459:             int rb = mmreg(uMIPS_RS(ctx->opcode));
                   11460:             int16_t offset = ZIMM(ctx->opcode, 0, 4);
                   11461:             offset = (offset == 0xf ? -1 : offset);
                   11462: 
                   11463:             gen_ld(env, ctx, OPC_LBU, rd, rb, offset);
                   11464:         }
                   11465:         break;
                   11466:     case LHU16:
                   11467:         {
                   11468:             int rd = mmreg(uMIPS_RD(ctx->opcode));
                   11469:             int rb = mmreg(uMIPS_RS(ctx->opcode));
                   11470:             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
                   11471: 
                   11472:             gen_ld(env, ctx, OPC_LHU, rd, rb, offset);
                   11473:         }
                   11474:         break;
                   11475:     case LWSP16:
                   11476:         {
                   11477:             int rd = (ctx->opcode >> 5) & 0x1f;
                   11478:             int rb = 29;            /* SP */
                   11479:             int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
                   11480: 
                   11481:             gen_ld(env, ctx, OPC_LW, rd, rb, offset);
                   11482:         }
                   11483:         break;
                   11484:     case LW16:
                   11485:         {
                   11486:             int rd = mmreg(uMIPS_RD(ctx->opcode));
                   11487:             int rb = mmreg(uMIPS_RS(ctx->opcode));
                   11488:             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
                   11489: 
                   11490:             gen_ld(env, ctx, OPC_LW, rd, rb, offset);
                   11491:         }
                   11492:         break;
                   11493:     case SB16:
                   11494:         {
                   11495:             int rd = mmreg2(uMIPS_RD(ctx->opcode));
                   11496:             int rb = mmreg(uMIPS_RS(ctx->opcode));
                   11497:             int16_t offset = ZIMM(ctx->opcode, 0, 4);
                   11498: 
                   11499:             gen_st(ctx, OPC_SB, rd, rb, offset);
                   11500:         }
                   11501:         break;
                   11502:     case SH16:
                   11503:         {
                   11504:             int rd = mmreg2(uMIPS_RD(ctx->opcode));
                   11505:             int rb = mmreg(uMIPS_RS(ctx->opcode));
                   11506:             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 1;
                   11507: 
                   11508:             gen_st(ctx, OPC_SH, rd, rb, offset);
                   11509:         }
                   11510:         break;
                   11511:     case SWSP16:
                   11512:         {
                   11513:             int rd = (ctx->opcode >> 5) & 0x1f;
                   11514:             int rb = 29;            /* SP */
                   11515:             int16_t offset = ZIMM(ctx->opcode, 0, 5) << 2;
                   11516: 
                   11517:             gen_st(ctx, OPC_SW, rd, rb, offset);
                   11518:         }
                   11519:         break;
                   11520:     case SW16:
                   11521:         {
                   11522:             int rd = mmreg2(uMIPS_RD(ctx->opcode));
                   11523:             int rb = mmreg(uMIPS_RS(ctx->opcode));
                   11524:             int16_t offset = ZIMM(ctx->opcode, 0, 4) << 2;
                   11525: 
                   11526:             gen_st(ctx, OPC_SW, rd, rb, offset);
                   11527:         }
                   11528:         break;
                   11529:     case MOVE16:
                   11530:         {
                   11531:             int rd = uMIPS_RD5(ctx->opcode);
                   11532:             int rs = uMIPS_RS5(ctx->opcode);
                   11533: 
                   11534:             gen_arith_imm(env, ctx, OPC_ADDIU, rd, rs, 0);
                   11535:         }
                   11536:         break;
                   11537:     case ANDI16:
                   11538:         gen_andi16(env, ctx);
                   11539:         break;
                   11540:     case POOL16D:
                   11541:         switch (ctx->opcode & 0x1) {
                   11542:         case ADDIUS5:
                   11543:             gen_addius5(env, ctx);
                   11544:             break;
                   11545:         case ADDIUSP:
                   11546:             gen_addiusp(env, ctx);
                   11547:             break;
                   11548:         }
                   11549:         break;
                   11550:     case POOL16E:
                   11551:         switch (ctx->opcode & 0x1) {
                   11552:         case ADDIUR2:
                   11553:             gen_addiur2(env, ctx);
                   11554:             break;
                   11555:         case ADDIUR1SP:
                   11556:             gen_addiur1sp(env, ctx);
                   11557:             break;
                   11558:         }
                   11559:         break;
                   11560:     case B16:
                   11561:         gen_compute_branch(ctx, OPC_BEQ, 2, 0, 0,
                   11562:                            SIMM(ctx->opcode, 0, 10) << 1);
                   11563:         *is_branch = 1;
                   11564:         break;
                   11565:     case BNEZ16:
                   11566:     case BEQZ16:
                   11567:         gen_compute_branch(ctx, op == BNEZ16 ? OPC_BNE : OPC_BEQ, 2,
                   11568:                            mmreg(uMIPS_RD(ctx->opcode)),
                   11569:                            0, SIMM(ctx->opcode, 0, 7) << 1);
                   11570:         *is_branch = 1;
                   11571:         break;
                   11572:     case LI16:
                   11573:         {
                   11574:             int reg = mmreg(uMIPS_RD(ctx->opcode));
                   11575:             int imm = ZIMM(ctx->opcode, 0, 7);
                   11576: 
                   11577:             imm = (imm == 0x7f ? -1 : imm);
                   11578:             tcg_gen_movi_tl(cpu_gpr[reg], imm);
                   11579:         }
                   11580:         break;
                   11581:     case RES_20:
                   11582:     case RES_28:
                   11583:     case RES_29:
                   11584:     case RES_30:
                   11585:     case RES_31:
                   11586:     case RES_38:
                   11587:     case RES_39:
                   11588:         generate_exception(ctx, EXCP_RI);
                   11589:         break;
                   11590:     default:
                   11591:         decode_micromips32_opc (env, ctx, op, is_branch);
                   11592:         return 4;
                   11593:     }
                   11594: 
                   11595:     return 2;
                   11596: }
                   11597: 
                   11598: /* SmartMIPS extension to MIPS32 */
                   11599: 
                   11600: #if defined(TARGET_MIPS64)
                   11601: 
                   11602: /* MDMX extension to MIPS64 */
                   11603: 
                   11604: #endif
                   11605: 
                   11606: static void decode_opc (CPUState *env, DisasContext *ctx, int *is_branch)
                   11607: {
                   11608:     int32_t offset;
                   11609:     int rs, rt, rd, sa;
                   11610:     uint32_t op, op1, op2;
                   11611:     int16_t imm;
                   11612: 
                   11613:     /* make sure instructions are on a word boundary */
                   11614:     if (ctx->pc & 0x3) {
                   11615:         env->CP0_BadVAddr = ctx->pc;
                   11616:         generate_exception(ctx, EXCP_AdEL);
                   11617:         return;
                   11618:     }
                   11619: 
                   11620:     /* Handle blikely not taken case */
                   11621:     if ((ctx->hflags & MIPS_HFLAG_BMASK_BASE) == MIPS_HFLAG_BL) {
                   11622:         int l1 = gen_new_label();
                   11623: 
                   11624:         MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
1.1.1.8   root     11625:         tcg_gen_brcondi_tl(TCG_COND_NE, bcond, 0, l1);
                   11626:         tcg_gen_movi_i32(hflags, ctx->hflags & ~MIPS_HFLAG_BMASK);
1.1.1.6   root     11627:         gen_goto_tb(ctx, 1, ctx->pc + 4);
                   11628:         gen_set_label(l1);
1.1       root     11629:     }
1.1.1.9   root     11630: 
                   11631:     if (unlikely(qemu_loglevel_mask(CPU_LOG_TB_OP)))
                   11632:         tcg_gen_debug_insn_start(ctx->pc);
                   11633: 
1.1.1.5   root     11634:     op = MASK_OP_MAJOR(ctx->opcode);
                   11635:     rs = (ctx->opcode >> 21) & 0x1f;
                   11636:     rt = (ctx->opcode >> 16) & 0x1f;
                   11637:     rd = (ctx->opcode >> 11) & 0x1f;
                   11638:     sa = (ctx->opcode >> 6) & 0x1f;
1.1       root     11639:     imm = (int16_t)ctx->opcode;
                   11640:     switch (op) {
1.1.1.5   root     11641:     case OPC_SPECIAL:
                   11642:         op1 = MASK_SPECIAL(ctx->opcode);
1.1       root     11643:         switch (op1) {
1.1.1.8   root     11644:         case OPC_SLL:          /* Shift with immediate */
                   11645:         case OPC_SRA:
                   11646:             gen_shift_imm(env, ctx, op1, rd, rt, sa);
1.1.1.5   root     11647:             break;
1.1.1.12  root     11648:         case OPC_SRL:
                   11649:             switch ((ctx->opcode >> 21) & 0x1f) {
                   11650:             case 1:
                   11651:                 /* rotr is decoded as srl on non-R2 CPUs */
                   11652:                 if (env->insn_flags & ISA_MIPS32R2) {
                   11653:                     op1 = OPC_ROTR;
                   11654:                 }
                   11655:                 /* Fallthrough */
                   11656:             case 0:
                   11657:                 gen_shift_imm(env, ctx, op1, rd, rt, sa);
                   11658:                 break;
                   11659:             default:
                   11660:                 generate_exception(ctx, EXCP_RI);
                   11661:                 break;
                   11662:             }
                   11663:             break;
1.1.1.8   root     11664:         case OPC_MOVN:         /* Conditional move */
                   11665:         case OPC_MOVZ:
1.1.1.12  root     11666:             check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32 |
                   11667:                                  INSN_LOONGSON2E | INSN_LOONGSON2F);
1.1.1.8   root     11668:             gen_cond_move(env, op1, rd, rs, rt);
                   11669:             break;
                   11670:         case OPC_ADD ... OPC_SUBU:
1.1.1.6   root     11671:             gen_arith(env, ctx, op1, rd, rs, rt);
1.1       root     11672:             break;
1.1.1.8   root     11673:         case OPC_SLLV:         /* Shifts */
                   11674:         case OPC_SRAV:
                   11675:             gen_shift(env, ctx, op1, rd, rs, rt);
                   11676:             break;
1.1.1.12  root     11677:         case OPC_SRLV:
                   11678:             switch ((ctx->opcode >> 6) & 0x1f) {
                   11679:             case 1:
                   11680:                 /* rotrv is decoded as srlv on non-R2 CPUs */
                   11681:                 if (env->insn_flags & ISA_MIPS32R2) {
                   11682:                     op1 = OPC_ROTRV;
                   11683:                 }
                   11684:                 /* Fallthrough */
                   11685:             case 0:
                   11686:                 gen_shift(env, ctx, op1, rd, rs, rt);
                   11687:                 break;
                   11688:             default:
                   11689:                 generate_exception(ctx, EXCP_RI);
                   11690:                 break;
                   11691:             }
                   11692:             break;
1.1.1.8   root     11693:         case OPC_SLT:          /* Set on less than */
                   11694:         case OPC_SLTU:
                   11695:             gen_slt(env, op1, rd, rs, rt);
                   11696:             break;
                   11697:         case OPC_AND:          /* Logic*/
                   11698:         case OPC_OR:
                   11699:         case OPC_NOR:
                   11700:         case OPC_XOR:
                   11701:             gen_logic(env, op1, rd, rs, rt);
                   11702:             break;
1.1.1.5   root     11703:         case OPC_MULT ... OPC_DIVU:
1.1.1.6   root     11704:             if (sa) {
                   11705:                 check_insn(env, ctx, INSN_VR54XX);
                   11706:                 op1 = MASK_MUL_VR54XX(ctx->opcode);
                   11707:                 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
                   11708:             } else
                   11709:                 gen_muldiv(ctx, op1, rs, rt);
1.1       root     11710:             break;
1.1.1.5   root     11711:         case OPC_JR ... OPC_JALR:
1.1.1.12  root     11712:             gen_compute_branch(ctx, op1, 4, rs, rd, sa);
                   11713:             *is_branch = 1;
                   11714:             break;
1.1.1.5   root     11715:         case OPC_TGE ... OPC_TEQ: /* Traps */
                   11716:         case OPC_TNE:
                   11717:             gen_trap(ctx, op1, rs, rt, -1);
                   11718:             break;
                   11719:         case OPC_MFHI:          /* Move from HI/LO */
                   11720:         case OPC_MFLO:
                   11721:             gen_HILO(ctx, op1, rd);
1.1       root     11722:             break;
1.1.1.5   root     11723:         case OPC_MTHI:
                   11724:         case OPC_MTLO:          /* Move to HI/LO */
                   11725:             gen_HILO(ctx, op1, rs);
                   11726:             break;
1.1.1.6   root     11727:         case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
                   11728: #ifdef MIPS_STRICT_STANDARD
                   11729:             MIPS_INVAL("PMON / selsl");
                   11730:             generate_exception(ctx, EXCP_RI);
                   11731: #else
1.1.1.7   root     11732:             gen_helper_0i(pmon, sa);
1.1.1.6   root     11733: #endif
1.1.1.5   root     11734:             break;
                   11735:         case OPC_SYSCALL:
1.1       root     11736:             generate_exception(ctx, EXCP_SYSCALL);
1.1.1.8   root     11737:             ctx->bstate = BS_STOP;
1.1       root     11738:             break;
1.1.1.5   root     11739:         case OPC_BREAK:
1.1       root     11740:             generate_exception(ctx, EXCP_BREAK);
                   11741:             break;
1.1.1.6   root     11742:         case OPC_SPIM:
                   11743: #ifdef MIPS_STRICT_STANDARD
                   11744:             MIPS_INVAL("SPIM");
                   11745:             generate_exception(ctx, EXCP_RI);
                   11746: #else
1.1.1.5   root     11747:            /* Implemented as RI exception for now. */
                   11748:             MIPS_INVAL("spim (unofficial)");
                   11749:             generate_exception(ctx, EXCP_RI);
1.1.1.6   root     11750: #endif
1.1       root     11751:             break;
1.1.1.5   root     11752:         case OPC_SYNC:
1.1.1.6   root     11753:             /* Treat as NOP. */
1.1       root     11754:             break;
1.1.1.2   root     11755: 
1.1.1.5   root     11756:         case OPC_MOVCI:
1.1.1.6   root     11757:             check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
                   11758:             if (env->CP0_Config1 & (1 << CP0C1_FP)) {
                   11759:                 check_cp1_enabled(ctx);
                   11760:                 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
                   11761:                           (ctx->opcode >> 16) & 1);
                   11762:             } else {
                   11763:                 generate_exception_err(ctx, EXCP_CpU, 1);
                   11764:             }
1.1.1.2   root     11765:             break;
                   11766: 
1.1.1.6   root     11767: #if defined(TARGET_MIPS64)
1.1.1.5   root     11768:        /* MIPS64 specific opcodes */
                   11769:         case OPC_DSLL:
1.1.1.8   root     11770:         case OPC_DSRA:
1.1.1.5   root     11771:         case OPC_DSLL32:
1.1.1.8   root     11772:         case OPC_DSRA32:
1.1.1.6   root     11773:             check_insn(env, ctx, ISA_MIPS3);
                   11774:             check_mips_64(ctx);
1.1.1.8   root     11775:             gen_shift_imm(env, ctx, op1, rd, rt, sa);
1.1.1.5   root     11776:             break;
1.1.1.12  root     11777:         case OPC_DSRL:
                   11778:             switch ((ctx->opcode >> 21) & 0x1f) {
                   11779:             case 1:
                   11780:                 /* drotr is decoded as dsrl on non-R2 CPUs */
                   11781:                 if (env->insn_flags & ISA_MIPS32R2) {
                   11782:                     op1 = OPC_DROTR;
                   11783:                 }
                   11784:                 /* Fallthrough */
                   11785:             case 0:
                   11786:                 check_insn(env, ctx, ISA_MIPS3);
                   11787:                 check_mips_64(ctx);
                   11788:                 gen_shift_imm(env, ctx, op1, rd, rt, sa);
                   11789:                 break;
                   11790:             default:
                   11791:                 generate_exception(ctx, EXCP_RI);
                   11792:                 break;
                   11793:             }
                   11794:             break;
                   11795:         case OPC_DSRL32:
                   11796:             switch ((ctx->opcode >> 21) & 0x1f) {
                   11797:             case 1:
                   11798:                 /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
                   11799:                 if (env->insn_flags & ISA_MIPS32R2) {
                   11800:                     op1 = OPC_DROTR32;
                   11801:                 }
                   11802:                 /* Fallthrough */
                   11803:             case 0:
                   11804:                 check_insn(env, ctx, ISA_MIPS3);
                   11805:                 check_mips_64(ctx);
                   11806:                 gen_shift_imm(env, ctx, op1, rd, rt, sa);
                   11807:                 break;
                   11808:             default:
                   11809:                 generate_exception(ctx, EXCP_RI);
                   11810:                 break;
                   11811:             }
                   11812:             break;
1.1.1.5   root     11813:         case OPC_DADD ... OPC_DSUBU:
1.1.1.6   root     11814:             check_insn(env, ctx, ISA_MIPS3);
                   11815:             check_mips_64(ctx);
                   11816:             gen_arith(env, ctx, op1, rd, rs, rt);
1.1.1.5   root     11817:             break;
1.1.1.8   root     11818:         case OPC_DSLLV:
                   11819:         case OPC_DSRAV:
                   11820:             check_insn(env, ctx, ISA_MIPS3);
                   11821:             check_mips_64(ctx);
                   11822:             gen_shift(env, ctx, op1, rd, rs, rt);
                   11823:             break;
1.1.1.12  root     11824:         case OPC_DSRLV:
                   11825:             switch ((ctx->opcode >> 6) & 0x1f) {
                   11826:             case 1:
                   11827:                 /* drotrv is decoded as dsrlv on non-R2 CPUs */
                   11828:                 if (env->insn_flags & ISA_MIPS32R2) {
                   11829:                     op1 = OPC_DROTRV;
                   11830:                 }
                   11831:                 /* Fallthrough */
                   11832:             case 0:
                   11833:                 check_insn(env, ctx, ISA_MIPS3);
                   11834:                 check_mips_64(ctx);
                   11835:                 gen_shift(env, ctx, op1, rd, rs, rt);
                   11836:                 break;
                   11837:             default:
                   11838:                 generate_exception(ctx, EXCP_RI);
                   11839:                 break;
                   11840:             }
                   11841:             break;
1.1.1.5   root     11842:         case OPC_DMULT ... OPC_DDIVU:
1.1.1.6   root     11843:             check_insn(env, ctx, ISA_MIPS3);
                   11844:             check_mips_64(ctx);
1.1.1.5   root     11845:             gen_muldiv(ctx, op1, rs, rt);
                   11846:             break;
1.1       root     11847: #endif
                   11848:         default:            /* Invalid */
                   11849:             MIPS_INVAL("special");
                   11850:             generate_exception(ctx, EXCP_RI);
                   11851:             break;
                   11852:         }
                   11853:         break;
1.1.1.5   root     11854:     case OPC_SPECIAL2:
                   11855:         op1 = MASK_SPECIAL2(ctx->opcode);
1.1       root     11856:         switch (op1) {
1.1.1.5   root     11857:         case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
                   11858:         case OPC_MSUB ... OPC_MSUBU:
1.1.1.6   root     11859:             check_insn(env, ctx, ISA_MIPS32);
1.1.1.5   root     11860:             gen_muldiv(ctx, op1, rs, rt);
1.1       root     11861:             break;
1.1.1.5   root     11862:         case OPC_MUL:
1.1.1.6   root     11863:             gen_arith(env, ctx, op1, rd, rs, rt);
1.1       root     11864:             break;
1.1.1.8   root     11865:         case OPC_CLO:
                   11866:         case OPC_CLZ:
1.1.1.6   root     11867:             check_insn(env, ctx, ISA_MIPS32);
1.1.1.5   root     11868:             gen_cl(ctx, op1, rd, rs);
1.1       root     11869:             break;
1.1.1.5   root     11870:         case OPC_SDBBP:
1.1       root     11871:             /* XXX: not clear which exception should be raised
                   11872:              *      when in debug mode...
                   11873:              */
1.1.1.6   root     11874:             check_insn(env, ctx, ISA_MIPS32);
1.1       root     11875:             if (!(ctx->hflags & MIPS_HFLAG_DM)) {
                   11876:                 generate_exception(ctx, EXCP_DBp);
                   11877:             } else {
                   11878:                 generate_exception(ctx, EXCP_DBp);
                   11879:             }
1.1.1.6   root     11880:             /* Treat as NOP. */
1.1       root     11881:             break;
1.1.1.12  root     11882:         case OPC_DIV_G_2F:
                   11883:         case OPC_DIVU_G_2F:
                   11884:         case OPC_MULT_G_2F:
                   11885:         case OPC_MULTU_G_2F:
                   11886:         case OPC_MOD_G_2F:
                   11887:         case OPC_MODU_G_2F:
                   11888:             check_insn(env, ctx, INSN_LOONGSON2F);
                   11889:             gen_loongson_integer(ctx, op1, rd, rs, rt);
                   11890:             break;
1.1.1.6   root     11891: #if defined(TARGET_MIPS64)
1.1.1.8   root     11892:         case OPC_DCLO:
                   11893:         case OPC_DCLZ:
1.1.1.6   root     11894:             check_insn(env, ctx, ISA_MIPS64);
                   11895:             check_mips_64(ctx);
1.1.1.5   root     11896:             gen_cl(ctx, op1, rd, rs);
                   11897:             break;
1.1.1.12  root     11898:         case OPC_DMULT_G_2F:
                   11899:         case OPC_DMULTU_G_2F:
                   11900:         case OPC_DDIV_G_2F:
                   11901:         case OPC_DDIVU_G_2F:
                   11902:         case OPC_DMOD_G_2F:
                   11903:         case OPC_DMODU_G_2F:
                   11904:             check_insn(env, ctx, INSN_LOONGSON2F);
                   11905:             gen_loongson_integer(ctx, op1, rd, rs, rt);
                   11906:             break;
1.1.1.5   root     11907: #endif
1.1       root     11908:         default:            /* Invalid */
                   11909:             MIPS_INVAL("special2");
                   11910:             generate_exception(ctx, EXCP_RI);
                   11911:             break;
                   11912:         }
                   11913:         break;
1.1.1.5   root     11914:     case OPC_SPECIAL3:
1.1.1.7   root     11915:         op1 = MASK_SPECIAL3(ctx->opcode);
                   11916:         switch (op1) {
                   11917:         case OPC_EXT:
                   11918:         case OPC_INS:
                   11919:             check_insn(env, ctx, ISA_MIPS32R2);
                   11920:             gen_bitops(ctx, op1, rt, rs, sa, rd);
                   11921:             break;
                   11922:         case OPC_BSHFL:
                   11923:             check_insn(env, ctx, ISA_MIPS32R2);
                   11924:             op2 = MASK_BSHFL(ctx->opcode);
                   11925:             gen_bshfl(ctx, op2, rt, rd);
1.1.1.6   root     11926:             break;
                   11927:         case OPC_RDHWR:
1.1.1.12  root     11928:             gen_rdhwr(env, ctx, rt, rd);
1.1.1.6   root     11929:             break;
                   11930:         case OPC_FORK:
                   11931:             check_insn(env, ctx, ASE_MT);
1.1.1.7   root     11932:             {
1.1.1.8   root     11933:                 TCGv t0 = tcg_temp_new();
                   11934:                 TCGv t1 = tcg_temp_new();
1.1.1.7   root     11935: 
                   11936:                 gen_load_gpr(t0, rt);
                   11937:                 gen_load_gpr(t1, rs);
                   11938:                 gen_helper_fork(t0, t1);
                   11939:                 tcg_temp_free(t0);
                   11940:                 tcg_temp_free(t1);
                   11941:             }
1.1.1.6   root     11942:             break;
                   11943:         case OPC_YIELD:
                   11944:             check_insn(env, ctx, ASE_MT);
1.1.1.7   root     11945:             {
1.1.1.8   root     11946:                 TCGv t0 = tcg_temp_new();
1.1.1.7   root     11947: 
1.1.1.8   root     11948:                 save_cpu_state(ctx, 1);
1.1.1.7   root     11949:                 gen_load_gpr(t0, rs);
                   11950:                 gen_helper_yield(t0, t0);
                   11951:                 gen_store_gpr(t0, rd);
                   11952:                 tcg_temp_free(t0);
                   11953:             }
1.1.1.6   root     11954:             break;
1.1.1.12  root     11955:         case OPC_DIV_G_2E ... OPC_DIVU_G_2E:
                   11956:         case OPC_MULT_G_2E ... OPC_MULTU_G_2E:
                   11957:         case OPC_MOD_G_2E ... OPC_MODU_G_2E:
                   11958:             check_insn(env, ctx, INSN_LOONGSON2E);
                   11959:             gen_loongson_integer(ctx, op1, rd, rs, rt);
                   11960:             break;
1.1.1.6   root     11961: #if defined(TARGET_MIPS64)
                   11962:         case OPC_DEXTM ... OPC_DEXT:
                   11963:         case OPC_DINSM ... OPC_DINS:
                   11964:             check_insn(env, ctx, ISA_MIPS64R2);
                   11965:             check_mips_64(ctx);
1.1.1.5   root     11966:             gen_bitops(ctx, op1, rt, rs, sa, rd);
                   11967:             break;
1.1.1.6   root     11968:         case OPC_DBSHFL:
                   11969:             check_insn(env, ctx, ISA_MIPS64R2);
                   11970:             check_mips_64(ctx);
                   11971:             op2 = MASK_DBSHFL(ctx->opcode);
1.1.1.7   root     11972:             gen_bshfl(ctx, op2, rt, rd);
1.1.1.6   root     11973:             break;
1.1.1.12  root     11974:         case OPC_DDIV_G_2E ... OPC_DDIVU_G_2E:
                   11975:         case OPC_DMULT_G_2E ... OPC_DMULTU_G_2E:
                   11976:         case OPC_DMOD_G_2E ... OPC_DMODU_G_2E:
                   11977:             check_insn(env, ctx, INSN_LOONGSON2E);
                   11978:             gen_loongson_integer(ctx, op1, rd, rs, rt);
                   11979:             break;
1.1.1.5   root     11980: #endif
                   11981:         default:            /* Invalid */
                   11982:             MIPS_INVAL("special3");
                   11983:             generate_exception(ctx, EXCP_RI);
                   11984:             break;
                   11985:         }
                   11986:         break;
                   11987:     case OPC_REGIMM:
                   11988:         op1 = MASK_REGIMM(ctx->opcode);
1.1       root     11989:         switch (op1) {
1.1.1.5   root     11990:         case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
                   11991:         case OPC_BLTZAL ... OPC_BGEZALL:
1.1.1.12  root     11992:             gen_compute_branch(ctx, op1, 4, rs, -1, imm << 2);
                   11993:             *is_branch = 1;
                   11994:             break;
1.1.1.5   root     11995:         case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
                   11996:         case OPC_TNEI:
                   11997:             gen_trap(ctx, op1, rs, -1, imm);
                   11998:             break;
                   11999:         case OPC_SYNCI:
1.1.1.6   root     12000:             check_insn(env, ctx, ISA_MIPS32R2);
                   12001:             /* Treat as NOP. */
1.1       root     12002:             break;
                   12003:         default:            /* Invalid */
1.1.1.6   root     12004:             MIPS_INVAL("regimm");
1.1       root     12005:             generate_exception(ctx, EXCP_RI);
                   12006:             break;
                   12007:         }
                   12008:         break;
1.1.1.5   root     12009:     case OPC_CP0:
1.1.1.6   root     12010:         check_cp0_enabled(ctx);
1.1.1.5   root     12011:         op1 = MASK_CP0(ctx->opcode);
1.1       root     12012:         switch (op1) {
1.1.1.5   root     12013:         case OPC_MFC0:
                   12014:         case OPC_MTC0:
1.1.1.6   root     12015:         case OPC_MFTR:
                   12016:         case OPC_MTTR:
                   12017: #if defined(TARGET_MIPS64)
1.1.1.5   root     12018:         case OPC_DMFC0:
                   12019:         case OPC_DMTC0:
                   12020: #endif
1.1.1.7   root     12021: #ifndef CONFIG_USER_ONLY
1.1.1.6   root     12022:             gen_cp0(env, ctx, op1, rt, rd);
1.1.1.7   root     12023: #endif /* !CONFIG_USER_ONLY */
1.1.1.5   root     12024:             break;
                   12025:         case OPC_C0_FIRST ... OPC_C0_LAST:
1.1.1.7   root     12026: #ifndef CONFIG_USER_ONLY
1.1.1.6   root     12027:             gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
1.1.1.7   root     12028: #endif /* !CONFIG_USER_ONLY */
1.1.1.5   root     12029:             break;
                   12030:         case OPC_MFMC0:
1.1.1.7   root     12031: #ifndef CONFIG_USER_ONLY
                   12032:             {
1.1.1.8   root     12033:                 TCGv t0 = tcg_temp_new();
1.1.1.7   root     12034: 
                   12035:                 op2 = MASK_MFMC0(ctx->opcode);
                   12036:                 switch (op2) {
                   12037:                 case OPC_DMT:
                   12038:                     check_insn(env, ctx, ASE_MT);
1.1.1.13  root     12039:                     gen_helper_dmt(t0);
1.1.1.8   root     12040:                     gen_store_gpr(t0, rt);
1.1.1.7   root     12041:                     break;
                   12042:                 case OPC_EMT:
                   12043:                     check_insn(env, ctx, ASE_MT);
1.1.1.13  root     12044:                     gen_helper_emt(t0);
1.1.1.8   root     12045:                     gen_store_gpr(t0, rt);
1.1.1.7   root     12046:                     break;
                   12047:                 case OPC_DVPE:
                   12048:                     check_insn(env, ctx, ASE_MT);
1.1.1.13  root     12049:                     gen_helper_dvpe(t0);
1.1.1.8   root     12050:                     gen_store_gpr(t0, rt);
1.1.1.7   root     12051:                     break;
                   12052:                 case OPC_EVPE:
                   12053:                     check_insn(env, ctx, ASE_MT);
1.1.1.13  root     12054:                     gen_helper_evpe(t0);
1.1.1.8   root     12055:                     gen_store_gpr(t0, rt);
1.1.1.7   root     12056:                     break;
                   12057:                 case OPC_DI:
                   12058:                     check_insn(env, ctx, ISA_MIPS32R2);
                   12059:                     save_cpu_state(ctx, 1);
                   12060:                     gen_helper_di(t0);
1.1.1.8   root     12061:                     gen_store_gpr(t0, rt);
1.1.1.7   root     12062:                     /* Stop translation as we may have switched the execution mode */
                   12063:                     ctx->bstate = BS_STOP;
                   12064:                     break;
                   12065:                 case OPC_EI:
                   12066:                     check_insn(env, ctx, ISA_MIPS32R2);
                   12067:                     save_cpu_state(ctx, 1);
                   12068:                     gen_helper_ei(t0);
1.1.1.8   root     12069:                     gen_store_gpr(t0, rt);
1.1.1.7   root     12070:                     /* Stop translation as we may have switched the execution mode */
                   12071:                     ctx->bstate = BS_STOP;
                   12072:                     break;
                   12073:                 default:            /* Invalid */
                   12074:                     MIPS_INVAL("mfmc0");
                   12075:                     generate_exception(ctx, EXCP_RI);
                   12076:                     break;
                   12077:                 }
                   12078:                 tcg_temp_free(t0);
1.1.1.5   root     12079:             }
1.1.1.7   root     12080: #endif /* !CONFIG_USER_ONLY */
1.1       root     12081:             break;
1.1.1.5   root     12082:         case OPC_RDPGPR:
1.1.1.6   root     12083:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7   root     12084:             gen_load_srsgpr(rt, rd);
1.1.1.6   root     12085:             break;
1.1.1.5   root     12086:         case OPC_WRPGPR:
1.1.1.6   root     12087:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7   root     12088:             gen_store_srsgpr(rt, rd);
1.1.1.6   root     12089:             break;
1.1       root     12090:         default:
1.1.1.6   root     12091:             MIPS_INVAL("cp0");
1.1.1.5   root     12092:             generate_exception(ctx, EXCP_RI);
1.1       root     12093:             break;
                   12094:         }
                   12095:         break;
1.1.1.8   root     12096:     case OPC_ADDI: /* Arithmetic with immediate opcode */
                   12097:     case OPC_ADDIU:
1.1.1.6   root     12098:          gen_arith_imm(env, ctx, op, rt, rs, imm);
1.1.1.5   root     12099:          break;
1.1.1.8   root     12100:     case OPC_SLTI: /* Set on less than with immediate opcode */
                   12101:     case OPC_SLTIU:
                   12102:          gen_slt_imm(env, op, rt, rs, imm);
                   12103:          break;
                   12104:     case OPC_ANDI: /* Arithmetic with immediate opcode */
                   12105:     case OPC_LUI:
                   12106:     case OPC_ORI:
                   12107:     case OPC_XORI:
                   12108:          gen_logic_imm(env, op, rt, rs, imm);
                   12109:          break;
1.1.1.5   root     12110:     case OPC_J ... OPC_JAL: /* Jump */
                   12111:          offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
1.1.1.12  root     12112:          gen_compute_branch(ctx, op, 4, rs, rt, offset);
                   12113:          *is_branch = 1;
                   12114:          break;
1.1.1.5   root     12115:     case OPC_BEQ ... OPC_BGTZ: /* Branch */
                   12116:     case OPC_BEQL ... OPC_BGTZL:
1.1.1.12  root     12117:          gen_compute_branch(ctx, op, 4, rs, rt, imm << 2);
                   12118:          *is_branch = 1;
                   12119:          break;
1.1.1.5   root     12120:     case OPC_LB ... OPC_LWR: /* Load and stores */
1.1.1.12  root     12121:     case OPC_LL:
                   12122:          gen_ld(env, ctx, op, rt, rs, imm);
                   12123:          break;
1.1.1.5   root     12124:     case OPC_SB ... OPC_SW:
                   12125:     case OPC_SWR:
1.1.1.12  root     12126:          gen_st(ctx, op, rt, rs, imm);
1.1.1.5   root     12127:          break;
1.1.1.8   root     12128:     case OPC_SC:
                   12129:          gen_st_cond(ctx, op, rt, rs, imm);
                   12130:          break;
1.1.1.5   root     12131:     case OPC_CACHE:
1.1.1.6   root     12132:         check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
                   12133:         /* Treat as NOP. */
                   12134:         break;
1.1.1.5   root     12135:     case OPC_PREF:
1.1.1.6   root     12136:         check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
                   12137:         /* Treat as NOP. */
1.1       root     12138:         break;
1.1.1.2   root     12139: 
1.1.1.6   root     12140:     /* Floating point (COP1). */
1.1.1.5   root     12141:     case OPC_LWC1:
                   12142:     case OPC_LDC1:
                   12143:     case OPC_SWC1:
                   12144:     case OPC_SDC1:
1.1.1.12  root     12145:         gen_cop1_ldst(env, ctx, op, rt, rs, imm);
1.1.1.4   root     12146:         break;
                   12147: 
1.1.1.5   root     12148:     case OPC_CP1:
1.1.1.6   root     12149:         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
                   12150:             check_cp1_enabled(ctx);
                   12151:             op1 = MASK_CP1(ctx->opcode);
                   12152:             switch (op1) {
                   12153:             case OPC_MFHC1:
                   12154:             case OPC_MTHC1:
                   12155:                 check_insn(env, ctx, ISA_MIPS32R2);
                   12156:             case OPC_MFC1:
                   12157:             case OPC_CFC1:
                   12158:             case OPC_MTC1:
                   12159:             case OPC_CTC1:
                   12160:                 gen_cp1(ctx, op1, rt, rd);
                   12161:                 break;
                   12162: #if defined(TARGET_MIPS64)
                   12163:             case OPC_DMFC1:
                   12164:             case OPC_DMTC1:
                   12165:                 check_insn(env, ctx, ISA_MIPS3);
                   12166:                 gen_cp1(ctx, op1, rt, rd);
                   12167:                 break;
1.1.1.5   root     12168: #endif
1.1.1.6   root     12169:             case OPC_BC1ANY2:
                   12170:             case OPC_BC1ANY4:
                   12171:                 check_cop1x(ctx);
                   12172:                 check_insn(env, ctx, ASE_MIPS3D);
                   12173:                 /* fall through */
                   12174:             case OPC_BC1:
                   12175:                 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
                   12176:                                     (rt >> 2) & 0x7, imm << 2);
1.1.1.12  root     12177:                 *is_branch = 1;
                   12178:                 break;
1.1.1.6   root     12179:             case OPC_S_FMT:
                   12180:             case OPC_D_FMT:
                   12181:             case OPC_W_FMT:
                   12182:             case OPC_L_FMT:
                   12183:             case OPC_PS_FMT:
1.1.1.12  root     12184:                 gen_farith(ctx, ctx->opcode & FOP(0x3f, 0x1f), rt, rd, sa,
1.1.1.6   root     12185:                            (imm >> 8) & 0x7);
                   12186:                 break;
                   12187:             default:
                   12188:                 MIPS_INVAL("cp1");
                   12189:                 generate_exception (ctx, EXCP_RI);
                   12190:                 break;
                   12191:             }
                   12192:         } else {
                   12193:             generate_exception_err(ctx, EXCP_CpU, 1);
1.1.1.4   root     12194:         }
1.1.1.2   root     12195:         break;
                   12196: 
                   12197:     /* COP2.  */
1.1.1.5   root     12198:     case OPC_LWC2:
                   12199:     case OPC_LDC2:
                   12200:     case OPC_SWC2:
                   12201:     case OPC_SDC2:
                   12202:     case OPC_CP2:
                   12203:         /* COP2: Not implemented. */
1.1.1.2   root     12204:         generate_exception_err(ctx, EXCP_CpU, 2);
                   12205:         break;
                   12206: 
1.1.1.5   root     12207:     case OPC_CP3:
1.1.1.6   root     12208:         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
                   12209:             check_cp1_enabled(ctx);
                   12210:             op1 = MASK_CP3(ctx->opcode);
                   12211:             switch (op1) {
                   12212:             case OPC_LWXC1:
                   12213:             case OPC_LDXC1:
                   12214:             case OPC_LUXC1:
                   12215:             case OPC_SWXC1:
                   12216:             case OPC_SDXC1:
                   12217:             case OPC_SUXC1:
                   12218:                 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
                   12219:                 break;
                   12220:             case OPC_PREFX:
                   12221:                 /* Treat as NOP. */
                   12222:                 break;
                   12223:             case OPC_ALNV_PS:
                   12224:             case OPC_MADD_S:
                   12225:             case OPC_MADD_D:
                   12226:             case OPC_MADD_PS:
                   12227:             case OPC_MSUB_S:
                   12228:             case OPC_MSUB_D:
                   12229:             case OPC_MSUB_PS:
                   12230:             case OPC_NMADD_S:
                   12231:             case OPC_NMADD_D:
                   12232:             case OPC_NMADD_PS:
                   12233:             case OPC_NMSUB_S:
                   12234:             case OPC_NMSUB_D:
                   12235:             case OPC_NMSUB_PS:
                   12236:                 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
                   12237:                 break;
                   12238:             default:
                   12239:                 MIPS_INVAL("cp3");
                   12240:                 generate_exception (ctx, EXCP_RI);
                   12241:                 break;
                   12242:             }
                   12243:         } else {
                   12244:             generate_exception_err(ctx, EXCP_CpU, 1);
1.1.1.5   root     12245:         }
1.1.1.2   root     12246:         break;
                   12247: 
1.1.1.6   root     12248: #if defined(TARGET_MIPS64)
1.1.1.5   root     12249:     /* MIPS64 opcodes */
                   12250:     case OPC_LWU:
                   12251:     case OPC_LDL ... OPC_LDR:
                   12252:     case OPC_LLD:
                   12253:     case OPC_LD:
1.1.1.12  root     12254:         check_insn(env, ctx, ISA_MIPS3);
                   12255:         check_mips_64(ctx);
                   12256:         gen_ld(env, ctx, op, rt, rs, imm);
                   12257:         break;
                   12258:     case OPC_SDL ... OPC_SDR:
1.1.1.5   root     12259:     case OPC_SD:
1.1.1.6   root     12260:         check_insn(env, ctx, ISA_MIPS3);
                   12261:         check_mips_64(ctx);
1.1.1.12  root     12262:         gen_st(ctx, op, rt, rs, imm);
1.1.1.5   root     12263:         break;
1.1.1.8   root     12264:     case OPC_SCD:
                   12265:         check_insn(env, ctx, ISA_MIPS3);
                   12266:         check_mips_64(ctx);
                   12267:         gen_st_cond(ctx, op, rt, rs, imm);
                   12268:         break;
                   12269:     case OPC_DADDI:
                   12270:     case OPC_DADDIU:
1.1.1.6   root     12271:         check_insn(env, ctx, ISA_MIPS3);
                   12272:         check_mips_64(ctx);
                   12273:         gen_arith_imm(env, ctx, op, rt, rs, imm);
1.1.1.5   root     12274:         break;
                   12275: #endif
                   12276:     case OPC_JALX:
1.1.1.12  root     12277:         check_insn(env, ctx, ASE_MIPS16 | ASE_MICROMIPS);
                   12278:         offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
                   12279:         gen_compute_branch(ctx, op, 4, rs, rt, offset);
                   12280:         *is_branch = 1;
                   12281:         break;
1.1.1.5   root     12282:     case OPC_MDMX:
1.1.1.6   root     12283:         check_insn(env, ctx, ASE_MDMX);
1.1.1.5   root     12284:         /* MDMX: Not implemented. */
1.1       root     12285:     default:            /* Invalid */
1.1.1.6   root     12286:         MIPS_INVAL("major opcode");
1.1       root     12287:         generate_exception(ctx, EXCP_RI);
                   12288:         break;
                   12289:     }
                   12290: }
                   12291: 
1.1.1.7   root     12292: static inline void
1.1.1.6   root     12293: gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
                   12294:                                 int search_pc)
1.1       root     12295: {
1.1.1.6   root     12296:     DisasContext ctx;
1.1       root     12297:     target_ulong pc_start;
                   12298:     uint16_t *gen_opc_end;
1.1.1.7   root     12299:     CPUBreakpoint *bp;
1.1       root     12300:     int j, lj = -1;
1.1.1.7   root     12301:     int num_insns;
                   12302:     int max_insns;
1.1.1.12  root     12303:     int insn_bytes;
                   12304:     int is_branch;
1.1       root     12305: 
1.1.1.7   root     12306:     if (search_pc)
                   12307:         qemu_log("search pc %d\n", search_pc);
1.1.1.2   root     12308: 
1.1       root     12309:     pc_start = tb->pc;
1.1.1.9   root     12310:     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE;
1.1       root     12311:     ctx.pc = pc_start;
1.1.1.2   root     12312:     ctx.saved_pc = -1;
1.1.1.9   root     12313:     ctx.singlestep_enabled = env->singlestep_enabled;
1.1       root     12314:     ctx.tb = tb;
                   12315:     ctx.bstate = BS_NONE;
1.1.1.2   root     12316:     /* Restore delay slot state from the tb context.  */
1.1.1.6   root     12317:     ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
                   12318:     restore_cpu_state(env, &ctx);
1.1.1.7   root     12319: #ifdef CONFIG_USER_ONLY
                   12320:         ctx.mem_idx = MIPS_HFLAG_UM;
1.1       root     12321: #else
1.1.1.7   root     12322:         ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
1.1       root     12323: #endif
1.1.1.7   root     12324:     num_insns = 0;
                   12325:     max_insns = tb->cflags & CF_COUNT_MASK;
                   12326:     if (max_insns == 0)
                   12327:         max_insns = CF_COUNT_MASK;
                   12328:     LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
                   12329:     gen_icount_start();
                   12330:     while (ctx.bstate == BS_NONE) {
1.1.1.9   root     12331:         if (unlikely(!QTAILQ_EMPTY(&env->breakpoints))) {
                   12332:             QTAILQ_FOREACH(bp, &env->breakpoints, entry) {
1.1.1.7   root     12333:                 if (bp->pc == ctx.pc) {
1.1.1.6   root     12334:                     save_cpu_state(&ctx, 1);
1.1.1.2   root     12335:                     ctx.bstate = BS_BRANCH;
1.1.1.7   root     12336:                     gen_helper_0i(raise_exception, EXCP_DEBUG);
1.1.1.6   root     12337:                     /* Include the breakpoint location or the tb won't
                   12338:                      * be flushed when it must be.  */
                   12339:                     ctx.pc += 4;
1.1.1.2   root     12340:                     goto done_generating;
                   12341:                 }
                   12342:             }
                   12343:         }
                   12344: 
1.1       root     12345:         if (search_pc) {
                   12346:             j = gen_opc_ptr - gen_opc_buf;
                   12347:             if (lj < j) {
                   12348:                 lj++;
                   12349:                 while (lj < j)
                   12350:                     gen_opc_instr_start[lj++] = 0;
                   12351:             }
1.1.1.2   root     12352:             gen_opc_pc[lj] = ctx.pc;
                   12353:             gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
                   12354:             gen_opc_instr_start[lj] = 1;
1.1.1.7   root     12355:             gen_opc_icount[lj] = num_insns;
1.1       root     12356:         }
1.1.1.7   root     12357:         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
                   12358:             gen_io_start();
1.1.1.12  root     12359: 
                   12360:         is_branch = 0;
                   12361:         if (!(ctx.hflags & MIPS_HFLAG_M16)) {
                   12362:             ctx.opcode = ldl_code(ctx.pc);
                   12363:             insn_bytes = 4;
                   12364:             decode_opc(env, &ctx, &is_branch);
                   12365:         } else if (env->insn_flags & ASE_MICROMIPS) {
                   12366:             ctx.opcode = lduw_code(ctx.pc);
                   12367:             insn_bytes = decode_micromips_opc(env, &ctx, &is_branch);
                   12368:         } else if (env->insn_flags & ASE_MIPS16) {
                   12369:             ctx.opcode = lduw_code(ctx.pc);
                   12370:             insn_bytes = decode_mips16_opc(env, &ctx, &is_branch);
                   12371:         } else {
                   12372:             generate_exception(&ctx, EXCP_RI);
                   12373:             ctx.bstate = BS_STOP;
                   12374:             break;
                   12375:         }
                   12376:         if (!is_branch) {
                   12377:             handle_delay_slot(env, &ctx, insn_bytes);
                   12378:         }
                   12379:         ctx.pc += insn_bytes;
                   12380: 
1.1.1.7   root     12381:         num_insns++;
1.1.1.2   root     12382: 
1.1.1.9   root     12383:         /* Execute a branch and its delay slot as a single instruction.
                   12384:            This is what GDB expects and is consistent with what the
                   12385:            hardware does (e.g. if a delay slot instruction faults, the
                   12386:            reported PC is the PC of the branch).  */
                   12387:         if (env->singlestep_enabled && (ctx.hflags & MIPS_HFLAG_BMASK) == 0)
1.1.1.2   root     12388:             break;
                   12389: 
1.1       root     12390:         if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
                   12391:             break;
1.1.1.2   root     12392: 
1.1.1.7   root     12393:         if (gen_opc_ptr >= gen_opc_end)
                   12394:             break;
                   12395: 
                   12396:         if (num_insns >= max_insns)
                   12397:             break;
1.1.1.8   root     12398: 
                   12399:         if (singlestep)
                   12400:             break;
1.1       root     12401:     }
1.1.1.7   root     12402:     if (tb->cflags & CF_LAST_IO)
                   12403:         gen_io_end();
1.1.1.9   root     12404:     if (env->singlestep_enabled && ctx.bstate != BS_BRANCH) {
1.1.1.6   root     12405:         save_cpu_state(&ctx, ctx.bstate == BS_NONE);
1.1.1.7   root     12406:         gen_helper_0i(raise_exception, EXCP_DEBUG);
1.1.1.6   root     12407:     } else {
1.1.1.7   root     12408:         switch (ctx.bstate) {
1.1.1.6   root     12409:         case BS_STOP:
                   12410:             gen_goto_tb(&ctx, 0, ctx.pc);
                   12411:             break;
                   12412:         case BS_NONE:
                   12413:             save_cpu_state(&ctx, 0);
                   12414:             gen_goto_tb(&ctx, 0, ctx.pc);
                   12415:             break;
                   12416:         case BS_EXCP:
1.1.1.7   root     12417:             tcg_gen_exit_tb(0);
1.1.1.6   root     12418:             break;
                   12419:         case BS_BRANCH:
                   12420:         default:
                   12421:             break;
1.1.1.7   root     12422:         }
1.1       root     12423:     }
1.1.1.2   root     12424: done_generating:
1.1.1.7   root     12425:     gen_icount_end(tb, num_insns);
1.1       root     12426:     *gen_opc_ptr = INDEX_op_end;
                   12427:     if (search_pc) {
                   12428:         j = gen_opc_ptr - gen_opc_buf;
                   12429:         lj++;
                   12430:         while (lj <= j)
                   12431:             gen_opc_instr_start[lj++] = 0;
                   12432:     } else {
                   12433:         tb->size = ctx.pc - pc_start;
1.1.1.7   root     12434:         tb->icount = num_insns;
1.1       root     12435:     }
                   12436: #ifdef DEBUG_DISAS
1.1.1.7   root     12437:     LOG_DISAS("\n");
                   12438:     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
                   12439:         qemu_log("IN: %s\n", lookup_symbol(pc_start));
                   12440:         log_target_disas(pc_start, ctx.pc - pc_start, 0);
                   12441:         qemu_log("\n");
1.1       root     12442:     }
                   12443: #endif
                   12444: }
                   12445: 
1.1.1.7   root     12446: void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
1.1       root     12447: {
1.1.1.7   root     12448:     gen_intermediate_code_internal(env, tb, 0);
1.1       root     12449: }
                   12450: 
1.1.1.7   root     12451: void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
1.1       root     12452: {
1.1.1.7   root     12453:     gen_intermediate_code_internal(env, tb, 1);
1.1       root     12454: }
                   12455: 
1.1.1.13  root     12456: static void fpu_dump_state(CPUState *env, FILE *f, fprintf_function fpu_fprintf,
1.1.1.7   root     12457:                            int flags)
1.1.1.4   root     12458: {
                   12459:     int i;
1.1.1.6   root     12460:     int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
1.1.1.4   root     12461: 
1.1.1.12  root     12462: #define printfpr(fp)                                                    \
                   12463:     do {                                                                \
                   12464:         if (is_fpu64)                                                   \
                   12465:             fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
                   12466:                         " fd:%13g fs:%13g psu: %13g\n",                 \
                   12467:                         (fp)->w[FP_ENDIAN_IDX], (fp)->d,                \
                   12468:                         (double)(fp)->fd,                               \
                   12469:                         (double)(fp)->fs[FP_ENDIAN_IDX],                \
                   12470:                         (double)(fp)->fs[!FP_ENDIAN_IDX]);              \
                   12471:         else {                                                          \
                   12472:             fpr_t tmp;                                                  \
                   12473:             tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];              \
                   12474:             tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];       \
                   12475:             fpu_fprintf(f, "w:%08x d:%016" PRIx64                       \
                   12476:                         " fd:%13g fs:%13g psu:%13g\n",                  \
                   12477:                         tmp.w[FP_ENDIAN_IDX], tmp.d,                    \
                   12478:                         (double)tmp.fd,                                 \
                   12479:                         (double)tmp.fs[FP_ENDIAN_IDX],                  \
                   12480:                         (double)tmp.fs[!FP_ENDIAN_IDX]);                \
                   12481:         }                                                               \
1.1.1.4   root     12482:     } while(0)
                   12483: 
1.1.1.6   root     12484: 
1.1.1.13  root     12485:     fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%02x\n",
                   12486:                 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64,
1.1.1.7   root     12487:                 get_float_exception_flags(&env->active_fpu.fp_status));
1.1.1.6   root     12488:     for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
                   12489:         fpu_fprintf(f, "%3s: ", fregnames[i]);
1.1.1.7   root     12490:         printfpr(&env->active_fpu.fpr[i]);
1.1.1.4   root     12491:     }
                   12492: 
                   12493: #undef printfpr
                   12494: }
                   12495: 
1.1.1.6   root     12496: #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
1.1.1.5   root     12497: /* Debug help: The architecture requires 32bit code to maintain proper
1.1.1.7   root     12498:    sign-extended values on 64bit machines.  */
1.1.1.5   root     12499: 
                   12500: #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
                   12501: 
1.1.1.7   root     12502: static void
                   12503: cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
1.1.1.13  root     12504:                                 fprintf_function cpu_fprintf,
1.1.1.7   root     12505:                                 int flags)
1.1.1.5   root     12506: {
                   12507:     int i;
                   12508: 
1.1.1.7   root     12509:     if (!SIGN_EXT_P(env->active_tc.PC))
                   12510:         cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
                   12511:     if (!SIGN_EXT_P(env->active_tc.HI[0]))
                   12512:         cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
                   12513:     if (!SIGN_EXT_P(env->active_tc.LO[0]))
                   12514:         cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
1.1.1.5   root     12515:     if (!SIGN_EXT_P(env->btarget))
1.1.1.6   root     12516:         cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
1.1.1.5   root     12517: 
                   12518:     for (i = 0; i < 32; i++) {
1.1.1.7   root     12519:         if (!SIGN_EXT_P(env->active_tc.gpr[i]))
                   12520:             cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
1.1.1.5   root     12521:     }
                   12522: 
                   12523:     if (!SIGN_EXT_P(env->CP0_EPC))
1.1.1.6   root     12524:         cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
1.1.1.9   root     12525:     if (!SIGN_EXT_P(env->lladdr))
                   12526:         cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->lladdr);
1.1.1.5   root     12527: }
                   12528: #endif
                   12529: 
1.1.1.13  root     12530: void cpu_dump_state (CPUState *env, FILE *f, fprintf_function cpu_fprintf,
1.1       root     12531:                      int flags)
                   12532: {
                   12533:     int i;
1.1.1.6   root     12534: 
1.1.1.12  root     12535:     cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx
                   12536:                 " LO=0x" TARGET_FMT_lx " ds %04x "
                   12537:                 TARGET_FMT_lx " " TARGET_FMT_ld "\n",
1.1.1.7   root     12538:                 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
                   12539:                 env->hflags, env->btarget, env->bcond);
1.1       root     12540:     for (i = 0; i < 32; i++) {
                   12541:         if ((i & 3) == 0)
                   12542:             cpu_fprintf(f, "GPR%02d:", i);
1.1.1.7   root     12543:         cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
1.1       root     12544:         if ((i & 3) == 3)
                   12545:             cpu_fprintf(f, "\n");
                   12546:     }
                   12547: 
1.1.1.6   root     12548:     cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
                   12549:                 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
                   12550:     cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
1.1.1.9   root     12551:                 env->CP0_Config0, env->CP0_Config1, env->lladdr);
1.1.1.6   root     12552:     if (env->hflags & MIPS_HFLAG_FPU)
1.1.1.5   root     12553:         fpu_dump_state(env, f, cpu_fprintf, flags);
1.1.1.6   root     12554: #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
1.1.1.5   root     12555:     cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
1.1.1.4   root     12556: #endif
1.1       root     12557: }
                   12558: 
1.1.1.7   root     12559: static void mips_tcg_init(void)
                   12560: {
                   12561:     int i;
                   12562:     static int inited;
                   12563: 
                   12564:     /* Initialize various static tables. */
                   12565:     if (inited)
                   12566:         return;
                   12567: 
                   12568:     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
1.1.1.8   root     12569:     TCGV_UNUSED(cpu_gpr[0]);
                   12570:     for (i = 1; i < 32; i++)
1.1.1.7   root     12571:         cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
                   12572:                                         offsetof(CPUState, active_tc.gpr[i]),
                   12573:                                         regnames[i]);
                   12574:     cpu_PC = tcg_global_mem_new(TCG_AREG0,
                   12575:                                 offsetof(CPUState, active_tc.PC), "PC");
                   12576:     for (i = 0; i < MIPS_DSP_ACC; i++) {
                   12577:         cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
                   12578:                                        offsetof(CPUState, active_tc.HI[i]),
                   12579:                                        regnames_HI[i]);
                   12580:         cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
                   12581:                                        offsetof(CPUState, active_tc.LO[i]),
                   12582:                                        regnames_LO[i]);
                   12583:         cpu_ACX[i] = tcg_global_mem_new(TCG_AREG0,
                   12584:                                         offsetof(CPUState, active_tc.ACX[i]),
                   12585:                                         regnames_ACX[i]);
                   12586:     }
                   12587:     cpu_dspctrl = tcg_global_mem_new(TCG_AREG0,
                   12588:                                      offsetof(CPUState, active_tc.DSPControl),
                   12589:                                      "DSPControl");
1.1.1.8   root     12590:     bcond = tcg_global_mem_new(TCG_AREG0,
                   12591:                                offsetof(CPUState, bcond), "bcond");
1.1.1.7   root     12592:     btarget = tcg_global_mem_new(TCG_AREG0,
                   12593:                                  offsetof(CPUState, btarget), "btarget");
1.1.1.8   root     12594:     hflags = tcg_global_mem_new_i32(TCG_AREG0,
                   12595:                                     offsetof(CPUState, hflags), "hflags");
                   12596: 
1.1.1.7   root     12597:     fpu_fcr0 = tcg_global_mem_new_i32(TCG_AREG0,
                   12598:                                       offsetof(CPUState, active_fpu.fcr0),
                   12599:                                       "fcr0");
                   12600:     fpu_fcr31 = tcg_global_mem_new_i32(TCG_AREG0,
                   12601:                                        offsetof(CPUState, active_fpu.fcr31),
                   12602:                                        "fcr31");
                   12603: 
                   12604:     /* register helpers */
                   12605: #define GEN_HELPER 2
                   12606: #include "helper.h"
                   12607: 
                   12608:     inited = 1;
                   12609: }
                   12610: 
1.1.1.6   root     12611: #include "translate_init.c"
                   12612: 
                   12613: CPUMIPSState *cpu_mips_init (const char *cpu_model)
1.1       root     12614: {
                   12615:     CPUMIPSState *env;
1.1.1.6   root     12616:     const mips_def_t *def;
1.1       root     12617: 
1.1.1.6   root     12618:     def = cpu_mips_find_by_name(cpu_model);
                   12619:     if (!def)
                   12620:         return NULL;
1.1       root     12621:     env = qemu_mallocz(sizeof(CPUMIPSState));
1.1.1.6   root     12622:     env->cpu_model = def;
1.1.1.9   root     12623:     env->cpu_model_str = cpu_model;
1.1.1.6   root     12624: 
1.1.1.2   root     12625:     cpu_exec_init(env);
1.1.1.9   root     12626: #ifndef CONFIG_USER_ONLY
                   12627:     mmu_init(env, def);
                   12628: #endif
                   12629:     fpu_init(env, def);
                   12630:     mvp_init(env, def);
1.1.1.7   root     12631:     mips_tcg_init();
1.1.1.5   root     12632:     cpu_reset(env);
1.1.1.8   root     12633:     qemu_init_vcpu(env);
1.1.1.5   root     12634:     return env;
                   12635: }
                   12636: 
                   12637: void cpu_reset (CPUMIPSState *env)
                   12638: {
1.1.1.7   root     12639:     if (qemu_loglevel_mask(CPU_LOG_RESET)) {
                   12640:         qemu_log("CPU Reset (CPU %d)\n", env->cpu_index);
                   12641:         log_cpu_state(env, 0);
                   12642:     }
                   12643: 
1.1.1.5   root     12644:     memset(env, 0, offsetof(CPUMIPSState, breakpoints));
1.1       root     12645:     tlb_flush(env, 1);
1.1.1.5   root     12646: 
1.1.1.9   root     12647:     /* Reset registers to their default values */
                   12648:     env->CP0_PRid = env->cpu_model->CP0_PRid;
                   12649:     env->CP0_Config0 = env->cpu_model->CP0_Config0;
                   12650: #ifdef TARGET_WORDS_BIGENDIAN
                   12651:     env->CP0_Config0 |= (1 << CP0C0_BE);
                   12652: #endif
                   12653:     env->CP0_Config1 = env->cpu_model->CP0_Config1;
                   12654:     env->CP0_Config2 = env->cpu_model->CP0_Config2;
                   12655:     env->CP0_Config3 = env->cpu_model->CP0_Config3;
                   12656:     env->CP0_Config6 = env->cpu_model->CP0_Config6;
                   12657:     env->CP0_Config7 = env->cpu_model->CP0_Config7;
                   12658:     env->CP0_LLAddr_rw_bitmask = env->cpu_model->CP0_LLAddr_rw_bitmask
                   12659:                                  << env->cpu_model->CP0_LLAddr_shift;
                   12660:     env->CP0_LLAddr_shift = env->cpu_model->CP0_LLAddr_shift;
                   12661:     env->SYNCI_Step = env->cpu_model->SYNCI_Step;
                   12662:     env->CCRes = env->cpu_model->CCRes;
                   12663:     env->CP0_Status_rw_bitmask = env->cpu_model->CP0_Status_rw_bitmask;
                   12664:     env->CP0_TCStatus_rw_bitmask = env->cpu_model->CP0_TCStatus_rw_bitmask;
                   12665:     env->CP0_SRSCtl = env->cpu_model->CP0_SRSCtl;
                   12666:     env->current_tc = 0;
                   12667:     env->SEGBITS = env->cpu_model->SEGBITS;
                   12668:     env->SEGMask = (target_ulong)((1ULL << env->cpu_model->SEGBITS) - 1);
                   12669: #if defined(TARGET_MIPS64)
                   12670:     if (env->cpu_model->insn_flags & ISA_MIPS3) {
                   12671:         env->SEGMask |= 3ULL << 62;
                   12672:     }
                   12673: #endif
                   12674:     env->PABITS = env->cpu_model->PABITS;
                   12675:     env->PAMask = (target_ulong)((1ULL << env->cpu_model->PABITS) - 1);
                   12676:     env->CP0_SRSConf0_rw_bitmask = env->cpu_model->CP0_SRSConf0_rw_bitmask;
                   12677:     env->CP0_SRSConf0 = env->cpu_model->CP0_SRSConf0;
                   12678:     env->CP0_SRSConf1_rw_bitmask = env->cpu_model->CP0_SRSConf1_rw_bitmask;
                   12679:     env->CP0_SRSConf1 = env->cpu_model->CP0_SRSConf1;
                   12680:     env->CP0_SRSConf2_rw_bitmask = env->cpu_model->CP0_SRSConf2_rw_bitmask;
                   12681:     env->CP0_SRSConf2 = env->cpu_model->CP0_SRSConf2;
                   12682:     env->CP0_SRSConf3_rw_bitmask = env->cpu_model->CP0_SRSConf3_rw_bitmask;
                   12683:     env->CP0_SRSConf3 = env->cpu_model->CP0_SRSConf3;
                   12684:     env->CP0_SRSConf4_rw_bitmask = env->cpu_model->CP0_SRSConf4_rw_bitmask;
                   12685:     env->CP0_SRSConf4 = env->cpu_model->CP0_SRSConf4;
                   12686:     env->insn_flags = env->cpu_model->insn_flags;
                   12687: 
1.1.1.7   root     12688: #if defined(CONFIG_USER_ONLY)
                   12689:     env->hflags = MIPS_HFLAG_UM;
1.1.1.8   root     12690:     /* Enable access to the SYNCI_Step register.  */
                   12691:     env->CP0_HWREna |= (1 << 1);
1.1.1.9   root     12692:     if (env->CP0_Config1 & (1 << CP0C1_FP)) {
                   12693:         env->hflags |= MIPS_HFLAG_FPU;
                   12694:     }
                   12695: #ifdef TARGET_MIPS64
                   12696:     if (env->active_fpu.fcr0 & (1 << FCR0_F64)) {
                   12697:         env->hflags |= MIPS_HFLAG_F64;
                   12698:     }
                   12699: #endif
1.1.1.7   root     12700: #else
1.1.1.5   root     12701:     if (env->hflags & MIPS_HFLAG_BMASK) {
                   12702:         /* If the exception was raised from a delay slot,
1.1.1.7   root     12703:            come back to the jump.  */
                   12704:         env->CP0_ErrorEPC = env->active_tc.PC - 4;
1.1.1.5   root     12705:     } else {
1.1.1.7   root     12706:         env->CP0_ErrorEPC = env->active_tc.PC;
1.1.1.5   root     12707:     }
1.1.1.7   root     12708:     env->active_tc.PC = (int32_t)0xBFC00000;
1.1.1.9   root     12709:     env->CP0_Random = env->tlb->nb_tlb - 1;
                   12710:     env->tlb->tlb_in_use = env->tlb->nb_tlb;
1.1       root     12711:     env->CP0_Wired = 0;
1.1.1.13  root     12712:     env->CP0_EBase = 0x80000000 | (env->cpu_index & 0x3FF);
1.1.1.5   root     12713:     env->CP0_Status = (1 << CP0St_BEV) | (1 << CP0St_ERL);
1.1.1.6   root     12714:     /* vectored interrupts not implemented, timer on int 7,
                   12715:        no performance counters. */
                   12716:     env->CP0_IntCtl = 0xe0000000;
                   12717:     {
                   12718:         int i;
                   12719: 
                   12720:         for (i = 0; i < 7; i++) {
                   12721:             env->CP0_WatchLo[i] = 0;
                   12722:             env->CP0_WatchHi[i] = 0x80000000;
                   12723:         }
                   12724:         env->CP0_WatchLo[7] = 0;
                   12725:         env->CP0_WatchHi[7] = 0;
                   12726:     }
1.1       root     12727:     /* Count register increments in debug mode, EJTAG version 1 */
                   12728:     env->CP0_Debug = (1 << CP0DB_CNT) | (0x1 << CP0DB_VER);
1.1.1.6   root     12729:     env->hflags = MIPS_HFLAG_CP0;
1.1.1.2   root     12730: #endif
1.1.1.9   root     12731: #if defined(TARGET_MIPS64)
                   12732:     if (env->cpu_model->insn_flags & ISA_MIPS3) {
                   12733:         env->hflags |= MIPS_HFLAG_64;
                   12734:     }
                   12735: #endif
1.1.1.7   root     12736:     env->exception_index = EXCP_NONE;
1.1       root     12737: }
1.1.1.7   root     12738: 
1.1.1.14! root     12739: void restore_state_to_opc(CPUState *env, TranslationBlock *tb, int pc_pos)
1.1.1.7   root     12740: {
                   12741:     env->active_tc.PC = gen_opc_pc[pc_pos];
                   12742:     env->hflags &= ~MIPS_HFLAG_BMASK;
                   12743:     env->hflags |= gen_opc_hflags[pc_pos];
                   12744: }

unix.superglobalmegacorp.com

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