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

1.1       root        1: /*
                      2:  *  MIPS32 emulation for qemu: main translation routines.
1.1.1.6   root        3:  *
1.1       root        4:  *  Copyright (c) 2004-2005 Jocelyn Mayer
1.1.1.4   root        5:  *  Copyright (c) 2006 Marius Groeger (FPU operations)
1.1.1.5   root        6:  *  Copyright (c) 2006 Thiemo Seufer (MIPS32R2 support)
1.1       root        7:  *
                      8:  * This library is free software; you can redistribute it and/or
                      9:  * modify it under the terms of the GNU Lesser General Public
                     10:  * License as published by the Free Software Foundation; either
                     11:  * version 2 of the License, or (at your option) any later version.
                     12:  *
                     13:  * This library is distributed in the hope that it will be useful,
                     14:  * but WITHOUT ANY WARRANTY; without even the implied warranty of
                     15:  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
                     16:  * Lesser General Public License for more details.
                     17:  *
                     18:  * You should have received a copy of the GNU Lesser General Public
                     19:  * License along with this library; if not, write to the Free Software
1.1.1.7 ! root       20:  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA  02110-1301 USA
1.1       root       21:  */
                     22: 
                     23: #include <stdarg.h>
                     24: #include <stdlib.h>
                     25: #include <stdio.h>
                     26: #include <string.h>
                     27: #include <inttypes.h>
                     28: 
                     29: #include "cpu.h"
                     30: #include "exec-all.h"
                     31: #include "disas.h"
1.1.1.7 ! root       32: #include "tcg-op.h"
        !            33: #include "qemu-common.h"
        !            34: 
        !            35: #include "helper.h"
        !            36: #define GEN_HELPER 1
        !            37: #include "helper.h"
1.1       root       38: 
1.1.1.2   root       39: //#define MIPS_DEBUG_DISAS
1.1.1.5   root       40: //#define MIPS_DEBUG_SIGN_EXTENSIONS
1.1       root       41: //#define MIPS_SINGLE_STEP
                     42: 
1.1.1.5   root       43: /* MIPS major opcodes */
                     44: #define MASK_OP_MAJOR(op)  (op & (0x3F << 26))
1.1       root       45: 
                     46: enum {
                     47:     /* indirect opcode tables */
1.1.1.5   root       48:     OPC_SPECIAL  = (0x00 << 26),
                     49:     OPC_REGIMM   = (0x01 << 26),
                     50:     OPC_CP0      = (0x10 << 26),
                     51:     OPC_CP1      = (0x11 << 26),
                     52:     OPC_CP2      = (0x12 << 26),
                     53:     OPC_CP3      = (0x13 << 26),
                     54:     OPC_SPECIAL2 = (0x1C << 26),
                     55:     OPC_SPECIAL3 = (0x1F << 26),
1.1       root       56:     /* arithmetic with immediate */
1.1.1.5   root       57:     OPC_ADDI     = (0x08 << 26),
                     58:     OPC_ADDIU    = (0x09 << 26),
                     59:     OPC_SLTI     = (0x0A << 26),
                     60:     OPC_SLTIU    = (0x0B << 26),
                     61:     OPC_ANDI     = (0x0C << 26),
                     62:     OPC_ORI      = (0x0D << 26),
                     63:     OPC_XORI     = (0x0E << 26),
                     64:     OPC_LUI      = (0x0F << 26),
                     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),
                     70:     OPC_BEQ      = (0x04 << 26),  /* Unconditional if rs = rt = 0 (B) */
                     71:     OPC_BEQL     = (0x14 << 26),
                     72:     OPC_BNE      = (0x05 << 26),
                     73:     OPC_BNEL     = (0x15 << 26),
                     74:     OPC_BLEZ     = (0x06 << 26),
                     75:     OPC_BLEZL    = (0x16 << 26),
                     76:     OPC_BGTZ     = (0x07 << 26),
                     77:     OPC_BGTZL    = (0x17 << 26),
                     78:     OPC_JALX     = (0x1D << 26),  /* MIPS 16 only */
1.1       root       79:     /* Load and stores */
1.1.1.5   root       80:     OPC_LDL      = (0x1A << 26),
                     81:     OPC_LDR      = (0x1B << 26),
                     82:     OPC_LB       = (0x20 << 26),
                     83:     OPC_LH       = (0x21 << 26),
                     84:     OPC_LWL      = (0x22 << 26),
                     85:     OPC_LW       = (0x23 << 26),
                     86:     OPC_LBU      = (0x24 << 26),
                     87:     OPC_LHU      = (0x25 << 26),
                     88:     OPC_LWR      = (0x26 << 26),
                     89:     OPC_LWU      = (0x27 << 26),
                     90:     OPC_SB       = (0x28 << 26),
                     91:     OPC_SH       = (0x29 << 26),
                     92:     OPC_SWL      = (0x2A << 26),
                     93:     OPC_SW       = (0x2B << 26),
                     94:     OPC_SDL      = (0x2C << 26),
                     95:     OPC_SDR      = (0x2D << 26),
                     96:     OPC_SWR      = (0x2E << 26),
                     97:     OPC_LL       = (0x30 << 26),
                     98:     OPC_LLD      = (0x34 << 26),
                     99:     OPC_LD       = (0x37 << 26),
                    100:     OPC_SC       = (0x38 << 26),
                    101:     OPC_SCD      = (0x3C << 26),
                    102:     OPC_SD       = (0x3F << 26),
1.1       root      103:     /* Floating point load/store */
1.1.1.5   root      104:     OPC_LWC1     = (0x31 << 26),
                    105:     OPC_LWC2     = (0x32 << 26),
                    106:     OPC_LDC1     = (0x35 << 26),
                    107:     OPC_LDC2     = (0x36 << 26),
                    108:     OPC_SWC1     = (0x39 << 26),
                    109:     OPC_SWC2     = (0x3A << 26),
                    110:     OPC_SDC1     = (0x3D << 26),
                    111:     OPC_SDC2     = (0x3E << 26),
                    112:     /* MDMX ASE specific */
                    113:     OPC_MDMX     = (0x1E << 26),
1.1       root      114:     /* Cache and prefetch */
1.1.1.5   root      115:     OPC_CACHE    = (0x2F << 26),
                    116:     OPC_PREF     = (0x33 << 26),
                    117:     /* Reserved major opcode */
                    118:     OPC_MAJOR3B_RESERVED = (0x3B << 26),
1.1       root      119: };
                    120: 
                    121: /* MIPS special opcodes */
1.1.1.5   root      122: #define MASK_SPECIAL(op)   MASK_OP_MAJOR(op) | (op & 0x3F)
                    123: 
1.1       root      124: enum {
                    125:     /* Shifts */
1.1.1.5   root      126:     OPC_SLL      = 0x00 | OPC_SPECIAL,
1.1       root      127:     /* NOP is SLL r0, r0, 0   */
                    128:     /* SSNOP is SLL r0, r0, 1 */
1.1.1.5   root      129:     /* EHB is SLL r0, r0, 3 */
                    130:     OPC_SRL      = 0x02 | OPC_SPECIAL, /* also ROTR */
                    131:     OPC_SRA      = 0x03 | OPC_SPECIAL,
                    132:     OPC_SLLV     = 0x04 | OPC_SPECIAL,
1.1.1.6   root      133:     OPC_SRLV     = 0x06 | OPC_SPECIAL, /* also ROTRV */
1.1.1.5   root      134:     OPC_SRAV     = 0x07 | OPC_SPECIAL,
                    135:     OPC_DSLLV    = 0x14 | OPC_SPECIAL,
                    136:     OPC_DSRLV    = 0x16 | OPC_SPECIAL, /* also DROTRV */
                    137:     OPC_DSRAV    = 0x17 | OPC_SPECIAL,
                    138:     OPC_DSLL     = 0x38 | OPC_SPECIAL,
                    139:     OPC_DSRL     = 0x3A | OPC_SPECIAL, /* also DROTR */
                    140:     OPC_DSRA     = 0x3B | OPC_SPECIAL,
                    141:     OPC_DSLL32   = 0x3C | OPC_SPECIAL,
                    142:     OPC_DSRL32   = 0x3E | OPC_SPECIAL, /* also DROTR32 */
                    143:     OPC_DSRA32   = 0x3F | OPC_SPECIAL,
1.1       root      144:     /* Multiplication / division */
1.1.1.5   root      145:     OPC_MULT     = 0x18 | OPC_SPECIAL,
                    146:     OPC_MULTU    = 0x19 | OPC_SPECIAL,
                    147:     OPC_DIV      = 0x1A | OPC_SPECIAL,
                    148:     OPC_DIVU     = 0x1B | OPC_SPECIAL,
                    149:     OPC_DMULT    = 0x1C | OPC_SPECIAL,
                    150:     OPC_DMULTU   = 0x1D | OPC_SPECIAL,
                    151:     OPC_DDIV     = 0x1E | OPC_SPECIAL,
                    152:     OPC_DDIVU    = 0x1F | OPC_SPECIAL,
1.1       root      153:     /* 2 registers arithmetic / logic */
1.1.1.5   root      154:     OPC_ADD      = 0x20 | OPC_SPECIAL,
                    155:     OPC_ADDU     = 0x21 | OPC_SPECIAL,
                    156:     OPC_SUB      = 0x22 | OPC_SPECIAL,
                    157:     OPC_SUBU     = 0x23 | OPC_SPECIAL,
                    158:     OPC_AND      = 0x24 | OPC_SPECIAL,
                    159:     OPC_OR       = 0x25 | OPC_SPECIAL,
                    160:     OPC_XOR      = 0x26 | OPC_SPECIAL,
                    161:     OPC_NOR      = 0x27 | OPC_SPECIAL,
                    162:     OPC_SLT      = 0x2A | OPC_SPECIAL,
                    163:     OPC_SLTU     = 0x2B | OPC_SPECIAL,
                    164:     OPC_DADD     = 0x2C | OPC_SPECIAL,
                    165:     OPC_DADDU    = 0x2D | OPC_SPECIAL,
                    166:     OPC_DSUB     = 0x2E | OPC_SPECIAL,
                    167:     OPC_DSUBU    = 0x2F | OPC_SPECIAL,
1.1       root      168:     /* Jumps */
1.1.1.5   root      169:     OPC_JR       = 0x08 | OPC_SPECIAL, /* Also JR.HB */
                    170:     OPC_JALR     = 0x09 | OPC_SPECIAL, /* Also JALR.HB */
1.1       root      171:     /* Traps */
1.1.1.5   root      172:     OPC_TGE      = 0x30 | OPC_SPECIAL,
                    173:     OPC_TGEU     = 0x31 | OPC_SPECIAL,
                    174:     OPC_TLT      = 0x32 | OPC_SPECIAL,
                    175:     OPC_TLTU     = 0x33 | OPC_SPECIAL,
                    176:     OPC_TEQ      = 0x34 | OPC_SPECIAL,
                    177:     OPC_TNE      = 0x36 | OPC_SPECIAL,
1.1       root      178:     /* HI / LO registers load & stores */
1.1.1.5   root      179:     OPC_MFHI     = 0x10 | OPC_SPECIAL,
                    180:     OPC_MTHI     = 0x11 | OPC_SPECIAL,
                    181:     OPC_MFLO     = 0x12 | OPC_SPECIAL,
                    182:     OPC_MTLO     = 0x13 | OPC_SPECIAL,
1.1       root      183:     /* Conditional moves */
1.1.1.5   root      184:     OPC_MOVZ     = 0x0A | OPC_SPECIAL,
                    185:     OPC_MOVN     = 0x0B | OPC_SPECIAL,
1.1       root      186: 
1.1.1.5   root      187:     OPC_MOVCI    = 0x01 | OPC_SPECIAL,
1.1       root      188: 
                    189:     /* Special */
1.1.1.5   root      190:     OPC_PMON     = 0x05 | OPC_SPECIAL, /* inofficial */
                    191:     OPC_SYSCALL  = 0x0C | OPC_SPECIAL,
                    192:     OPC_BREAK    = 0x0D | OPC_SPECIAL,
                    193:     OPC_SPIM     = 0x0E | OPC_SPECIAL, /* inofficial */
                    194:     OPC_SYNC     = 0x0F | OPC_SPECIAL,
                    195: 
                    196:     OPC_SPECIAL15_RESERVED = 0x15 | OPC_SPECIAL,
                    197:     OPC_SPECIAL28_RESERVED = 0x28 | OPC_SPECIAL,
                    198:     OPC_SPECIAL29_RESERVED = 0x29 | OPC_SPECIAL,
                    199:     OPC_SPECIAL35_RESERVED = 0x35 | OPC_SPECIAL,
                    200:     OPC_SPECIAL37_RESERVED = 0x37 | OPC_SPECIAL,
                    201:     OPC_SPECIAL39_RESERVED = 0x39 | OPC_SPECIAL,
                    202:     OPC_SPECIAL3D_RESERVED = 0x3D | OPC_SPECIAL,
                    203: };
                    204: 
1.1.1.6   root      205: /* Multiplication variants of the vr54xx. */
                    206: #define MASK_MUL_VR54XX(op)   MASK_SPECIAL(op) | (op & (0x1F << 6))
                    207: 
                    208: enum {
                    209:     OPC_VR54XX_MULS    = (0x03 << 6) | OPC_MULT,
                    210:     OPC_VR54XX_MULSU   = (0x03 << 6) | OPC_MULTU,
                    211:     OPC_VR54XX_MACC    = (0x05 << 6) | OPC_MULT,
                    212:     OPC_VR54XX_MACCU   = (0x05 << 6) | OPC_MULTU,
                    213:     OPC_VR54XX_MSAC    = (0x07 << 6) | OPC_MULT,
                    214:     OPC_VR54XX_MSACU   = (0x07 << 6) | OPC_MULTU,
                    215:     OPC_VR54XX_MULHI   = (0x09 << 6) | OPC_MULT,
                    216:     OPC_VR54XX_MULHIU  = (0x09 << 6) | OPC_MULTU,
                    217:     OPC_VR54XX_MULSHI  = (0x0B << 6) | OPC_MULT,
                    218:     OPC_VR54XX_MULSHIU = (0x0B << 6) | OPC_MULTU,
                    219:     OPC_VR54XX_MACCHI  = (0x0D << 6) | OPC_MULT,
                    220:     OPC_VR54XX_MACCHIU = (0x0D << 6) | OPC_MULTU,
                    221:     OPC_VR54XX_MSACHI  = (0x0F << 6) | OPC_MULT,
                    222:     OPC_VR54XX_MSACHIU = (0x0F << 6) | OPC_MULTU,
                    223: };
                    224: 
1.1.1.5   root      225: /* REGIMM (rt field) opcodes */
                    226: #define MASK_REGIMM(op)    MASK_OP_MAJOR(op) | (op & (0x1F << 16))
                    227: 
                    228: enum {
                    229:     OPC_BLTZ     = (0x00 << 16) | OPC_REGIMM,
                    230:     OPC_BLTZL    = (0x02 << 16) | OPC_REGIMM,
                    231:     OPC_BGEZ     = (0x01 << 16) | OPC_REGIMM,
                    232:     OPC_BGEZL    = (0x03 << 16) | OPC_REGIMM,
                    233:     OPC_BLTZAL   = (0x10 << 16) | OPC_REGIMM,
                    234:     OPC_BLTZALL  = (0x12 << 16) | OPC_REGIMM,
                    235:     OPC_BGEZAL   = (0x11 << 16) | OPC_REGIMM,
                    236:     OPC_BGEZALL  = (0x13 << 16) | OPC_REGIMM,
                    237:     OPC_TGEI     = (0x08 << 16) | OPC_REGIMM,
                    238:     OPC_TGEIU    = (0x09 << 16) | OPC_REGIMM,
                    239:     OPC_TLTI     = (0x0A << 16) | OPC_REGIMM,
                    240:     OPC_TLTIU    = (0x0B << 16) | OPC_REGIMM,
                    241:     OPC_TEQI     = (0x0C << 16) | OPC_REGIMM,
                    242:     OPC_TNEI     = (0x0E << 16) | OPC_REGIMM,
                    243:     OPC_SYNCI    = (0x1F << 16) | OPC_REGIMM,
1.1       root      244: };
                    245: 
1.1.1.5   root      246: /* Special2 opcodes */
                    247: #define MASK_SPECIAL2(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
                    248: 
1.1       root      249: enum {
1.1.1.5   root      250:     /* Multiply & xxx operations */
                    251:     OPC_MADD     = 0x00 | OPC_SPECIAL2,
                    252:     OPC_MADDU    = 0x01 | OPC_SPECIAL2,
                    253:     OPC_MUL      = 0x02 | OPC_SPECIAL2,
                    254:     OPC_MSUB     = 0x04 | OPC_SPECIAL2,
                    255:     OPC_MSUBU    = 0x05 | OPC_SPECIAL2,
1.1       root      256:     /* Misc */
1.1.1.5   root      257:     OPC_CLZ      = 0x20 | OPC_SPECIAL2,
                    258:     OPC_CLO      = 0x21 | OPC_SPECIAL2,
                    259:     OPC_DCLZ     = 0x24 | OPC_SPECIAL2,
                    260:     OPC_DCLO     = 0x25 | OPC_SPECIAL2,
1.1       root      261:     /* Special */
1.1.1.5   root      262:     OPC_SDBBP    = 0x3F | OPC_SPECIAL2,
                    263: };
                    264: 
                    265: /* Special3 opcodes */
                    266: #define MASK_SPECIAL3(op)  MASK_OP_MAJOR(op) | (op & 0x3F)
                    267: 
                    268: enum {
                    269:     OPC_EXT      = 0x00 | OPC_SPECIAL3,
                    270:     OPC_DEXTM    = 0x01 | OPC_SPECIAL3,
                    271:     OPC_DEXTU    = 0x02 | OPC_SPECIAL3,
                    272:     OPC_DEXT     = 0x03 | OPC_SPECIAL3,
                    273:     OPC_INS      = 0x04 | OPC_SPECIAL3,
                    274:     OPC_DINSM    = 0x05 | OPC_SPECIAL3,
                    275:     OPC_DINSU    = 0x06 | OPC_SPECIAL3,
                    276:     OPC_DINS     = 0x07 | OPC_SPECIAL3,
1.1.1.6   root      277:     OPC_FORK     = 0x08 | OPC_SPECIAL3,
                    278:     OPC_YIELD    = 0x09 | OPC_SPECIAL3,
1.1.1.5   root      279:     OPC_BSHFL    = 0x20 | OPC_SPECIAL3,
                    280:     OPC_DBSHFL   = 0x24 | OPC_SPECIAL3,
                    281:     OPC_RDHWR    = 0x3B | OPC_SPECIAL3,
1.1       root      282: };
                    283: 
1.1.1.5   root      284: /* BSHFL opcodes */
                    285: #define MASK_BSHFL(op)     MASK_SPECIAL3(op) | (op & (0x1F << 6))
                    286: 
1.1       root      287: enum {
1.1.1.5   root      288:     OPC_WSBH     = (0x02 << 6) | OPC_BSHFL,
                    289:     OPC_SEB      = (0x10 << 6) | OPC_BSHFL,
                    290:     OPC_SEH      = (0x18 << 6) | OPC_BSHFL,
1.1       root      291: };
                    292: 
1.1.1.5   root      293: /* DBSHFL opcodes */
                    294: #define MASK_DBSHFL(op)    MASK_SPECIAL3(op) | (op & (0x1F << 6))
                    295: 
1.1       root      296: enum {
1.1.1.5   root      297:     OPC_DSBH     = (0x02 << 6) | OPC_DBSHFL,
                    298:     OPC_DSHD     = (0x05 << 6) | OPC_DBSHFL,
1.1       root      299: };
                    300: 
1.1.1.5   root      301: /* Coprocessor 0 (rs field) */
                    302: #define MASK_CP0(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
                    303: 
1.1.1.4   root      304: enum {
1.1.1.5   root      305:     OPC_MFC0     = (0x00 << 21) | OPC_CP0,
                    306:     OPC_DMFC0    = (0x01 << 21) | OPC_CP0,
                    307:     OPC_MTC0     = (0x04 << 21) | OPC_CP0,
                    308:     OPC_DMTC0    = (0x05 << 21) | OPC_CP0,
1.1.1.6   root      309:     OPC_MFTR     = (0x08 << 21) | OPC_CP0,
1.1.1.5   root      310:     OPC_RDPGPR   = (0x0A << 21) | OPC_CP0,
                    311:     OPC_MFMC0    = (0x0B << 21) | OPC_CP0,
1.1.1.6   root      312:     OPC_MTTR     = (0x0C << 21) | OPC_CP0,
1.1.1.5   root      313:     OPC_WRPGPR   = (0x0E << 21) | OPC_CP0,
                    314:     OPC_C0       = (0x10 << 21) | OPC_CP0,
                    315:     OPC_C0_FIRST = (0x10 << 21) | OPC_CP0,
                    316:     OPC_C0_LAST  = (0x1F << 21) | OPC_CP0,
1.1.1.4   root      317: };
1.1.1.5   root      318: 
                    319: /* MFMC0 opcodes */
1.1.1.6   root      320: #define MASK_MFMC0(op)     MASK_CP0(op) | (op & 0xFFFF)
1.1.1.5   root      321: 
                    322: enum {
1.1.1.6   root      323:     OPC_DMT      = 0x01 | (0 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
                    324:     OPC_EMT      = 0x01 | (1 << 5) | (0x0F << 6) | (0x01 << 11) | OPC_MFMC0,
                    325:     OPC_DVPE     = 0x01 | (0 << 5) | OPC_MFMC0,
                    326:     OPC_EVPE     = 0x01 | (1 << 5) | OPC_MFMC0,
1.1.1.5   root      327:     OPC_DI       = (0 << 5) | (0x0C << 11) | OPC_MFMC0,
                    328:     OPC_EI       = (1 << 5) | (0x0C << 11) | OPC_MFMC0,
                    329: };
                    330: 
                    331: /* Coprocessor 0 (with rs == C0) */
                    332: #define MASK_C0(op)        MASK_CP0(op) | (op & 0x3F)
                    333: 
                    334: enum {
                    335:     OPC_TLBR     = 0x01 | OPC_C0,
                    336:     OPC_TLBWI    = 0x02 | OPC_C0,
                    337:     OPC_TLBWR    = 0x06 | OPC_C0,
                    338:     OPC_TLBP     = 0x08 | OPC_C0,
                    339:     OPC_RFE      = 0x10 | OPC_C0,
                    340:     OPC_ERET     = 0x18 | OPC_C0,
                    341:     OPC_DERET    = 0x1F | OPC_C0,
                    342:     OPC_WAIT     = 0x20 | OPC_C0,
                    343: };
                    344: 
                    345: /* Coprocessor 1 (rs field) */
                    346: #define MASK_CP1(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
                    347: 
                    348: enum {
                    349:     OPC_MFC1     = (0x00 << 21) | OPC_CP1,
                    350:     OPC_DMFC1    = (0x01 << 21) | OPC_CP1,
                    351:     OPC_CFC1     = (0x02 << 21) | OPC_CP1,
1.1.1.6   root      352:     OPC_MFHC1    = (0x03 << 21) | OPC_CP1,
1.1.1.5   root      353:     OPC_MTC1     = (0x04 << 21) | OPC_CP1,
                    354:     OPC_DMTC1    = (0x05 << 21) | OPC_CP1,
                    355:     OPC_CTC1     = (0x06 << 21) | OPC_CP1,
1.1.1.6   root      356:     OPC_MTHC1    = (0x07 << 21) | OPC_CP1,
1.1.1.5   root      357:     OPC_BC1      = (0x08 << 21) | OPC_CP1, /* bc */
1.1.1.6   root      358:     OPC_BC1ANY2  = (0x09 << 21) | OPC_CP1,
                    359:     OPC_BC1ANY4  = (0x0A << 21) | OPC_CP1,
1.1.1.5   root      360:     OPC_S_FMT    = (0x10 << 21) | OPC_CP1, /* 16: fmt=single fp */
                    361:     OPC_D_FMT    = (0x11 << 21) | OPC_CP1, /* 17: fmt=double fp */
                    362:     OPC_E_FMT    = (0x12 << 21) | OPC_CP1, /* 18: fmt=extended fp */
                    363:     OPC_Q_FMT    = (0x13 << 21) | OPC_CP1, /* 19: fmt=quad fp */
                    364:     OPC_W_FMT    = (0x14 << 21) | OPC_CP1, /* 20: fmt=32bit fixed */
                    365:     OPC_L_FMT    = (0x15 << 21) | OPC_CP1, /* 21: fmt=64bit fixed */
1.1.1.6   root      366:     OPC_PS_FMT   = (0x16 << 21) | OPC_CP1, /* 22: fmt=paired single fp */
1.1.1.5   root      367: };
                    368: 
1.1.1.6   root      369: #define MASK_CP1_FUNC(op)       MASK_CP1(op) | (op & 0x3F)
                    370: #define MASK_BC1(op)            MASK_CP1(op) | (op & (0x3 << 16))
                    371: 
1.1.1.5   root      372: enum {
                    373:     OPC_BC1F     = (0x00 << 16) | OPC_BC1,
                    374:     OPC_BC1T     = (0x01 << 16) | OPC_BC1,
                    375:     OPC_BC1FL    = (0x02 << 16) | OPC_BC1,
                    376:     OPC_BC1TL    = (0x03 << 16) | OPC_BC1,
                    377: };
                    378: 
1.1.1.6   root      379: enum {
                    380:     OPC_BC1FANY2     = (0x00 << 16) | OPC_BC1ANY2,
                    381:     OPC_BC1TANY2     = (0x01 << 16) | OPC_BC1ANY2,
                    382: };
                    383: 
                    384: enum {
                    385:     OPC_BC1FANY4     = (0x00 << 16) | OPC_BC1ANY4,
                    386:     OPC_BC1TANY4     = (0x01 << 16) | OPC_BC1ANY4,
                    387: };
1.1.1.5   root      388: 
                    389: #define MASK_CP2(op)       MASK_OP_MAJOR(op) | (op & (0x1F << 21))
1.1.1.6   root      390: 
                    391: enum {
                    392:     OPC_MFC2    = (0x00 << 21) | OPC_CP2,
                    393:     OPC_DMFC2   = (0x01 << 21) | OPC_CP2,
                    394:     OPC_CFC2    = (0x02 << 21) | OPC_CP2,
                    395:     OPC_MFHC2   = (0x03 << 21) | OPC_CP2,
                    396:     OPC_MTC2    = (0x04 << 21) | OPC_CP2,
                    397:     OPC_DMTC2   = (0x05 << 21) | OPC_CP2,
                    398:     OPC_CTC2    = (0x06 << 21) | OPC_CP2,
                    399:     OPC_MTHC2   = (0x07 << 21) | OPC_CP2,
                    400:     OPC_BC2     = (0x08 << 21) | OPC_CP2,
                    401: };
                    402: 
                    403: #define MASK_CP3(op)       MASK_OP_MAJOR(op) | (op & 0x3F)
                    404: 
                    405: enum {
                    406:     OPC_LWXC1   = 0x00 | OPC_CP3,
                    407:     OPC_LDXC1   = 0x01 | OPC_CP3,
                    408:     OPC_LUXC1   = 0x05 | OPC_CP3,
                    409:     OPC_SWXC1   = 0x08 | OPC_CP3,
                    410:     OPC_SDXC1   = 0x09 | OPC_CP3,
                    411:     OPC_SUXC1   = 0x0D | OPC_CP3,
                    412:     OPC_PREFX   = 0x0F | OPC_CP3,
                    413:     OPC_ALNV_PS = 0x1E | OPC_CP3,
                    414:     OPC_MADD_S  = 0x20 | OPC_CP3,
                    415:     OPC_MADD_D  = 0x21 | OPC_CP3,
                    416:     OPC_MADD_PS = 0x26 | OPC_CP3,
                    417:     OPC_MSUB_S  = 0x28 | OPC_CP3,
                    418:     OPC_MSUB_D  = 0x29 | OPC_CP3,
                    419:     OPC_MSUB_PS = 0x2E | OPC_CP3,
                    420:     OPC_NMADD_S = 0x30 | OPC_CP3,
                    421:     OPC_NMADD_D = 0x31 | OPC_CP3,
                    422:     OPC_NMADD_PS= 0x36 | OPC_CP3,
                    423:     OPC_NMSUB_S = 0x38 | OPC_CP3,
                    424:     OPC_NMSUB_D = 0x39 | OPC_CP3,
                    425:     OPC_NMSUB_PS= 0x3E | OPC_CP3,
                    426: };
                    427: 
1.1.1.7 ! root      428: /* global register indices */
        !           429: static TCGv_ptr cpu_env;
        !           430: static TCGv cpu_gpr[32], cpu_PC;
        !           431: static TCGv cpu_HI[MIPS_DSP_ACC], cpu_LO[MIPS_DSP_ACC], cpu_ACX[MIPS_DSP_ACC];
        !           432: static TCGv cpu_dspctrl, btarget;
        !           433: static TCGv_i32 bcond;
        !           434: static TCGv_i32 fpu_fpr32[32], fpu_fpr32h[32];
        !           435: static TCGv_i64 fpu_fpr64[32];
        !           436: static TCGv_i32 fpu_fcr0, fpu_fcr31;
        !           437: 
        !           438: #include "gen-icount.h"
        !           439: 
        !           440: #define gen_helper_0i(name, arg) do {                             \
        !           441:     TCGv_i32 helper_tmp = tcg_const_i32(arg);                     \
        !           442:     gen_helper_##name(helper_tmp);                                \
        !           443:     tcg_temp_free_i32(helper_tmp);                                \
        !           444:     } while(0)
1.1.1.4   root      445: 
1.1.1.7 ! root      446: #define gen_helper_1i(name, arg1, arg2) do {                      \
        !           447:     TCGv_i32 helper_tmp = tcg_const_i32(arg2);                    \
        !           448:     gen_helper_##name(arg1, helper_tmp);                          \
        !           449:     tcg_temp_free_i32(helper_tmp);                                \
        !           450:     } while(0)
1.1.1.4   root      451: 
1.1.1.7 ! root      452: #define gen_helper_2i(name, arg1, arg2, arg3) do {                \
        !           453:     TCGv_i32 helper_tmp = tcg_const_i32(arg3);                    \
        !           454:     gen_helper_##name(arg1, arg2, helper_tmp);                    \
        !           455:     tcg_temp_free_i32(helper_tmp);                                \
        !           456:     } while(0)
1.1.1.4   root      457: 
1.1.1.7 ! root      458: #define gen_helper_3i(name, arg1, arg2, arg3, arg4) do {          \
        !           459:     TCGv_i32 helper_tmp = tcg_const_i32(arg4);                    \
        !           460:     gen_helper_##name(arg1, arg2, arg3, helper_tmp);              \
        !           461:     tcg_temp_free_i32(helper_tmp);                                \
        !           462:     } while(0)
1.1.1.4   root      463: 
1.1       root      464: typedef struct DisasContext {
                    465:     struct TranslationBlock *tb;
                    466:     target_ulong pc, saved_pc;
                    467:     uint32_t opcode;
                    468:     /* Routine used to access memory */
                    469:     int mem_idx;
                    470:     uint32_t hflags, saved_hflags;
                    471:     int bstate;
                    472:     target_ulong btarget;
                    473: } DisasContext;
                    474: 
                    475: enum {
                    476:     BS_NONE     = 0, /* We go out of the TB without reaching a branch or an
1.1.1.7 ! root      477:                       * exception condition */
1.1       root      478:     BS_STOP     = 1, /* We want to stop translation for any reason */
                    479:     BS_BRANCH   = 2, /* We reached a branch condition     */
                    480:     BS_EXCP     = 3, /* We reached an exception condition */
                    481: };
                    482: 
1.1.1.7 ! root      483: static const char *regnames[] =
        !           484:     { "r0", "at", "v0", "v1", "a0", "a1", "a2", "a3",
        !           485:       "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
        !           486:       "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
        !           487:       "t8", "t9", "k0", "k1", "gp", "sp", "s8", "ra", };
        !           488: 
        !           489: static const char *regnames_HI[] =
        !           490:     { "HI0", "HI1", "HI2", "HI3", };
        !           491: 
        !           492: static const char *regnames_LO[] =
        !           493:     { "LO0", "LO1", "LO2", "LO3", };
        !           494: 
        !           495: static const char *regnames_ACX[] =
        !           496:     { "ACX0", "ACX1", "ACX2", "ACX3", };
        !           497: 
        !           498: static const char *fregnames[] =
        !           499:     { "f0",  "f1",  "f2",  "f3",  "f4",  "f5",  "f6",  "f7",
        !           500:       "f8",  "f9",  "f10", "f11", "f12", "f13", "f14", "f15",
        !           501:       "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
        !           502:       "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31", };
        !           503: 
        !           504: static const char *fregnames_64[] =
        !           505:     { "F0",  "F1",  "F2",  "F3",  "F4",  "F5",  "F6",  "F7",
        !           506:       "F8",  "F9",  "F10", "F11", "F12", "F13", "F14", "F15",
        !           507:       "F16", "F17", "F18", "F19", "F20", "F21", "F22", "F23",
        !           508:       "F24", "F25", "F26", "F27", "F28", "F29", "F30", "F31", };
        !           509: 
        !           510: static const char *fregnames_h[] =
        !           511:     { "h0",  "h1",  "h2",  "h3",  "h4",  "h5",  "h6",  "h7",
        !           512:       "h8",  "h9",  "h10", "h11", "h12", "h13", "h14", "h15",
        !           513:       "h16", "h17", "h18", "h19", "h20", "h21", "h22", "h23",
        !           514:       "h24", "h25", "h26", "h27", "h28", "h29", "h30", "h31", };
        !           515: 
1.1.1.6   root      516: #ifdef MIPS_DEBUG_DISAS
1.1.1.7 ! root      517: #define MIPS_DEBUG(fmt, args...)                         \
        !           518:         qemu_log_mask(CPU_LOG_TB_IN_ASM,                \
        !           519:                        TARGET_FMT_lx ": %08x " fmt "\n", \
        !           520:                        ctx->pc, ctx->opcode , ##args)
        !           521: #define LOG_DISAS(...) qemu_log_mask(CPU_LOG_TB_IN_ASM, ## __VA_ARGS__)
1.1       root      522: #else
                    523: #define MIPS_DEBUG(fmt, args...) do { } while(0)
1.1.1.7 ! root      524: #define LOG_DISAS(...) do { } while (0)
1.1       root      525: #endif
                    526: 
                    527: #define MIPS_INVAL(op)                                                        \
                    528: do {                                                                          \
                    529:     MIPS_DEBUG("Invalid %s %03x %03x %03x", op, ctx->opcode >> 26,            \
                    530:                ctx->opcode & 0x3F, ((ctx->opcode >> 16) & 0x1F));             \
                    531: } while (0)
                    532: 
1.1.1.7 ! root      533: /* General purpose registers moves. */
        !           534: static inline void gen_load_gpr (TCGv t, int reg)
        !           535: {
        !           536:     if (reg == 0)
        !           537:         tcg_gen_movi_tl(t, 0);
        !           538:     else
        !           539:         tcg_gen_mov_tl(t, cpu_gpr[reg]);
        !           540: }
1.1.1.6   root      541: 
1.1.1.7 ! root      542: static inline void gen_store_gpr (TCGv t, int reg)
        !           543: {
        !           544:     if (reg != 0)
        !           545:         tcg_gen_mov_tl(cpu_gpr[reg], t);
        !           546: }
1.1.1.6   root      547: 
1.1.1.7 ! root      548: /* Moves to/from ACX register.  */
        !           549: static inline void gen_load_ACX (TCGv t, int reg)
        !           550: {
        !           551:     tcg_gen_mov_tl(t, cpu_ACX[reg]);
        !           552: }
1.1.1.6   root      553: 
1.1.1.7 ! root      554: static inline void gen_store_ACX (TCGv t, int reg)
        !           555: {
        !           556:     tcg_gen_mov_tl(cpu_ACX[reg], t);
        !           557: }
1.1       root      558: 
1.1.1.7 ! root      559: /* Moves to/from shadow registers. */
        !           560: static inline void gen_load_srsgpr (int from, int to)
        !           561: {
        !           562:     TCGv r_tmp1 = tcg_temp_new();
1.1.1.6   root      563: 
1.1.1.7 ! root      564:     if (from == 0)
        !           565:         tcg_gen_movi_tl(r_tmp1, 0);
        !           566:     else {
        !           567:         TCGv_i32 r_tmp2 = tcg_temp_new_i32();
        !           568:         TCGv_ptr addr = tcg_temp_new_ptr();
1.1.1.6   root      569: 
1.1.1.7 ! root      570:         tcg_gen_ld_i32(r_tmp2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
        !           571:         tcg_gen_shri_i32(r_tmp2, r_tmp2, CP0SRSCtl_PSS);
        !           572:         tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xf);
        !           573:         tcg_gen_muli_i32(r_tmp2, r_tmp2, sizeof(target_ulong) * 32);
        !           574:         tcg_gen_ext_i32_ptr(addr, r_tmp2);
        !           575:         tcg_gen_add_ptr(addr, cpu_env, addr);
1.1       root      576: 
1.1.1.7 ! root      577:         tcg_gen_ld_tl(r_tmp1, addr, sizeof(target_ulong) * from);
        !           578:         tcg_temp_free_ptr(addr);
        !           579:         tcg_temp_free_i32(r_tmp2);
        !           580:     }
        !           581:     gen_store_gpr(r_tmp1, to);
        !           582:     tcg_temp_free(r_tmp1);
        !           583: }
1.1       root      584: 
1.1.1.7 ! root      585: static inline void gen_store_srsgpr (int from, int to)
        !           586: {
        !           587:     if (to != 0) {
        !           588:         TCGv r_tmp1 = tcg_temp_new();
        !           589:         TCGv_i32 r_tmp2 = tcg_temp_new_i32();
        !           590:         TCGv_ptr addr = tcg_temp_new_ptr();
1.1.1.4   root      591: 
1.1.1.7 ! root      592:         gen_load_gpr(r_tmp1, from);
        !           593:         tcg_gen_ld_i32(r_tmp2, cpu_env, offsetof(CPUState, CP0_SRSCtl));
        !           594:         tcg_gen_shri_i32(r_tmp2, r_tmp2, CP0SRSCtl_PSS);
        !           595:         tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xf);
        !           596:         tcg_gen_muli_i32(r_tmp2, r_tmp2, sizeof(target_ulong) * 32);
        !           597:         tcg_gen_ext_i32_ptr(addr, r_tmp2);
        !           598:         tcg_gen_add_ptr(addr, cpu_env, addr);
1.1.1.4   root      599: 
1.1.1.7 ! root      600:         tcg_gen_st_tl(r_tmp1, addr, sizeof(target_ulong) * to);
        !           601:         tcg_temp_free_ptr(addr);
        !           602:         tcg_temp_free_i32(r_tmp2);
        !           603:         tcg_temp_free(r_tmp1);
1.1.1.6   root      604:     }
                    605: }
                    606: 
1.1.1.7 ! root      607: /* Floating point register moves. */
        !           608: static inline void gen_load_fpr32 (TCGv_i32 t, int reg)
1.1.1.6   root      609: {
1.1.1.7 ! root      610:     tcg_gen_mov_i32(t, fpu_fpr32[reg]);
        !           611: }
        !           612: 
        !           613: static inline void gen_store_fpr32 (TCGv_i32 t, int reg)
        !           614: {
        !           615:     tcg_gen_mov_i32(fpu_fpr32[reg], t);
        !           616: }
        !           617: 
        !           618: static inline void gen_load_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
        !           619: {
        !           620:     if (ctx->hflags & MIPS_HFLAG_F64)
        !           621:         tcg_gen_mov_i64(t, fpu_fpr64[reg]);
        !           622:     else {
        !           623:         tcg_gen_concat_i32_i64(t, fpu_fpr32[reg & ~1], fpu_fpr32[reg | 1]);
1.1.1.6   root      624:     }
                    625: }
                    626: 
1.1.1.7 ! root      627: static inline void gen_store_fpr64 (DisasContext *ctx, TCGv_i64 t, int reg)
1.1       root      628: {
1.1.1.7 ! root      629:     if (ctx->hflags & MIPS_HFLAG_F64)
        !           630:         tcg_gen_mov_i64(fpu_fpr64[reg], t);
        !           631:     else {
        !           632:         tcg_gen_trunc_i64_i32(fpu_fpr32[reg & ~1], t);
        !           633:         tcg_gen_shri_i64(t, t, 32);
        !           634:         tcg_gen_trunc_i64_i32(fpu_fpr32[reg | 1], t);
1.1       root      635:     }
1.1.1.7 ! root      636: }
        !           637: 
        !           638: static inline void gen_load_fpr32h (TCGv_i32 t, int reg)
        !           639: {
        !           640:     tcg_gen_mov_i32(t, fpu_fpr32h[reg]);
        !           641: }
        !           642: 
        !           643: static inline void gen_store_fpr32h (TCGv_i32 t, int reg)
        !           644: {
        !           645:     tcg_gen_mov_i32(fpu_fpr32h[reg], t);
        !           646: }
        !           647: 
        !           648: static inline void get_fp_cond (TCGv_i32 t)
        !           649: {
        !           650:     TCGv_i32 r_tmp1 = tcg_temp_new_i32();
        !           651:     TCGv_i32 r_tmp2 = tcg_temp_new_i32();
        !           652: 
        !           653:     tcg_gen_shri_i32(r_tmp2, fpu_fcr31, 24);
        !           654:     tcg_gen_andi_i32(r_tmp2, r_tmp2, 0xfe);
        !           655:     tcg_gen_shri_i32(r_tmp1, fpu_fcr31, 23);
        !           656:     tcg_gen_andi_i32(r_tmp1, r_tmp1, 0x1);
        !           657:     tcg_gen_or_i32(t, r_tmp1, r_tmp2);
        !           658:     tcg_temp_free_i32(r_tmp1);
        !           659:     tcg_temp_free_i32(r_tmp2);
        !           660: }
        !           661: 
        !           662: #define FOP_CONDS(type, fmt, bits)                                            \
        !           663: static inline void gen_cmp ## type ## _ ## fmt(int n, TCGv_i##bits a,         \
        !           664:                                                TCGv_i##bits b, int cc)        \
        !           665: {                                                                             \
        !           666:     switch (n) {                                                              \
        !           667:     case  0: gen_helper_2i(cmp ## type ## _ ## fmt ## _f, a, b, cc);    break;\
        !           668:     case  1: gen_helper_2i(cmp ## type ## _ ## fmt ## _un, a, b, cc);   break;\
        !           669:     case  2: gen_helper_2i(cmp ## type ## _ ## fmt ## _eq, a, b, cc);   break;\
        !           670:     case  3: gen_helper_2i(cmp ## type ## _ ## fmt ## _ueq, a, b, cc);  break;\
        !           671:     case  4: gen_helper_2i(cmp ## type ## _ ## fmt ## _olt, a, b, cc);  break;\
        !           672:     case  5: gen_helper_2i(cmp ## type ## _ ## fmt ## _ult, a, b, cc);  break;\
        !           673:     case  6: gen_helper_2i(cmp ## type ## _ ## fmt ## _ole, a, b, cc);  break;\
        !           674:     case  7: gen_helper_2i(cmp ## type ## _ ## fmt ## _ule, a, b, cc);  break;\
        !           675:     case  8: gen_helper_2i(cmp ## type ## _ ## fmt ## _sf, a, b, cc);   break;\
        !           676:     case  9: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngle, a, b, cc); break;\
        !           677:     case 10: gen_helper_2i(cmp ## type ## _ ## fmt ## _seq, a, b, cc);  break;\
        !           678:     case 11: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngl, a, b, cc);  break;\
        !           679:     case 12: gen_helper_2i(cmp ## type ## _ ## fmt ## _lt, a, b, cc);   break;\
        !           680:     case 13: gen_helper_2i(cmp ## type ## _ ## fmt ## _nge, a, b, cc);  break;\
        !           681:     case 14: gen_helper_2i(cmp ## type ## _ ## fmt ## _le, a, b, cc);   break;\
        !           682:     case 15: gen_helper_2i(cmp ## type ## _ ## fmt ## _ngt, a, b, cc);  break;\
        !           683:     default: abort();                                                         \
        !           684:     }                                                                         \
        !           685: }
        !           686: 
        !           687: FOP_CONDS(, d, 64)
        !           688: FOP_CONDS(abs, d, 64)
        !           689: FOP_CONDS(, s, 32)
        !           690: FOP_CONDS(abs, s, 32)
        !           691: FOP_CONDS(, ps, 64)
        !           692: FOP_CONDS(abs, ps, 64)
        !           693: #undef FOP_CONDS
        !           694: 
        !           695: /* Tests */
        !           696: #define OP_COND(name, cond)                                   \
        !           697: static inline void glue(gen_op_, name) (TCGv t0, TCGv t1)     \
        !           698: {                                                             \
        !           699:     int l1 = gen_new_label();                                 \
        !           700:     int l2 = gen_new_label();                                 \
        !           701:                                                               \
        !           702:     tcg_gen_brcond_tl(cond, t0, t1, l1);                      \
        !           703:     tcg_gen_movi_tl(t0, 0);                                   \
        !           704:     tcg_gen_br(l2);                                           \
        !           705:     gen_set_label(l1);                                        \
        !           706:     tcg_gen_movi_tl(t0, 1);                                   \
        !           707:     gen_set_label(l2);                                        \
        !           708: }
        !           709: OP_COND(eq, TCG_COND_EQ);
        !           710: OP_COND(ne, TCG_COND_NE);
        !           711: OP_COND(ge, TCG_COND_GE);
        !           712: OP_COND(geu, TCG_COND_GEU);
        !           713: OP_COND(lt, TCG_COND_LT);
        !           714: OP_COND(ltu, TCG_COND_LTU);
        !           715: #undef OP_COND
        !           716: 
        !           717: #define OP_CONDI(name, cond)                                  \
        !           718: static inline void glue(gen_op_, name) (TCGv t, target_ulong val) \
        !           719: {                                                             \
        !           720:     int l1 = gen_new_label();                                 \
        !           721:     int l2 = gen_new_label();                                 \
        !           722:                                                               \
        !           723:     tcg_gen_brcondi_tl(cond, t, val, l1);                     \
        !           724:     tcg_gen_movi_tl(t, 0);                                    \
        !           725:     tcg_gen_br(l2);                                           \
        !           726:     gen_set_label(l1);                                        \
        !           727:     tcg_gen_movi_tl(t, 1);                                    \
        !           728:     gen_set_label(l2);                                        \
        !           729: }
        !           730: OP_CONDI(lti, TCG_COND_LT);
        !           731: OP_CONDI(ltiu, TCG_COND_LTU);
        !           732: #undef OP_CONDI
        !           733: 
        !           734: #define OP_CONDZ(name, cond)                                  \
        !           735: static inline void glue(gen_op_, name) (TCGv t)               \
        !           736: {                                                             \
        !           737:     int l1 = gen_new_label();                                 \
        !           738:     int l2 = gen_new_label();                                 \
        !           739:                                                               \
        !           740:     tcg_gen_brcondi_tl(cond, t, 0, l1);                       \
        !           741:     tcg_gen_movi_tl(t, 0);                                    \
        !           742:     tcg_gen_br(l2);                                           \
        !           743:     gen_set_label(l1);                                        \
        !           744:     tcg_gen_movi_tl(t, 1);                                    \
        !           745:     gen_set_label(l2);                                        \
        !           746: }
        !           747: OP_CONDZ(gez, TCG_COND_GE);
        !           748: OP_CONDZ(gtz, TCG_COND_GT);
        !           749: OP_CONDZ(lez, TCG_COND_LE);
        !           750: OP_CONDZ(ltz, TCG_COND_LT);
        !           751: #undef OP_CONDZ
        !           752: 
        !           753: static inline void gen_save_pc(target_ulong pc)
        !           754: {
        !           755:     tcg_gen_movi_tl(cpu_PC, pc);
        !           756: }
        !           757: 
        !           758: static inline void save_cpu_state (DisasContext *ctx, int do_save_pc)
        !           759: {
        !           760:     LOG_DISAS("hflags %08x saved %08x\n", ctx->hflags, ctx->saved_hflags);
1.1       root      761:     if (do_save_pc && ctx->pc != ctx->saved_pc) {
1.1.1.6   root      762:         gen_save_pc(ctx->pc);
1.1       root      763:         ctx->saved_pc = ctx->pc;
                    764:     }
                    765:     if (ctx->hflags != ctx->saved_hflags) {
1.1.1.7 ! root      766:         TCGv_i32 r_tmp = tcg_temp_new_i32();
        !           767: 
        !           768:         tcg_gen_movi_i32(r_tmp, ctx->hflags);
        !           769:         tcg_gen_st_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
        !           770:         tcg_temp_free_i32(r_tmp);
1.1       root      771:         ctx->saved_hflags = ctx->hflags;
1.1.1.6   root      772:         switch (ctx->hflags & MIPS_HFLAG_BMASK) {
                    773:         case MIPS_HFLAG_BR:
                    774:             break;
                    775:         case MIPS_HFLAG_BC:
                    776:         case MIPS_HFLAG_BL:
                    777:         case MIPS_HFLAG_B:
1.1.1.7 ! root      778:             tcg_gen_movi_tl(btarget, ctx->btarget);
1.1.1.6   root      779:             break;
1.1       root      780:         }
                    781:     }
                    782: }
                    783: 
1.1.1.7 ! root      784: static inline void restore_cpu_state (CPUState *env, DisasContext *ctx)
1.1.1.6   root      785: {
                    786:     ctx->saved_hflags = ctx->hflags;
                    787:     switch (ctx->hflags & MIPS_HFLAG_BMASK) {
                    788:     case MIPS_HFLAG_BR:
                    789:         break;
                    790:     case MIPS_HFLAG_BC:
                    791:     case MIPS_HFLAG_BL:
1.1.1.7 ! root      792:     case MIPS_HFLAG_B:
1.1.1.6   root      793:         ctx->btarget = env->btarget;
                    794:         break;
                    795:     }
                    796: }
                    797: 
1.1.1.7 ! root      798: static inline void
        !           799: generate_exception_err (DisasContext *ctx, int excp, int err)
1.1       root      800: {
1.1.1.7 ! root      801:     TCGv_i32 texcp = tcg_const_i32(excp);
        !           802:     TCGv_i32 terr = tcg_const_i32(err);
1.1       root      803:     save_cpu_state(ctx, 1);
1.1.1.7 ! root      804:     gen_helper_raise_exception_err(texcp, terr);
        !           805:     tcg_temp_free_i32(terr);
        !           806:     tcg_temp_free_i32(texcp);
        !           807:     gen_helper_interrupt_restart();
        !           808:     tcg_gen_exit_tb(0);
        !           809: }
        !           810: 
        !           811: static inline void
        !           812: generate_exception (DisasContext *ctx, int excp)
        !           813: {
        !           814:     save_cpu_state(ctx, 1);
        !           815:     gen_helper_0i(raise_exception, excp);
        !           816:     gen_helper_interrupt_restart();
        !           817:     tcg_gen_exit_tb(0);
1.1       root      818: }
                    819: 
1.1.1.7 ! root      820: /* Addresses computation */
        !           821: static inline void gen_op_addr_add (DisasContext *ctx, TCGv t0, TCGv t1)
1.1.1.2   root      822: {
1.1.1.7 ! root      823:     tcg_gen_add_tl(t0, t0, t1);
        !           824: 
        !           825: #if defined(TARGET_MIPS64)
        !           826:     /* For compatibility with 32-bit code, data reference in user mode
        !           827:        with Status_UX = 0 should be casted to 32-bit and sign extended.
        !           828:        See the MIPS64 PRA manual, section 4.10. */
        !           829:     if (((ctx->hflags & MIPS_HFLAG_KSU) == MIPS_HFLAG_UM) &&
        !           830:         !(ctx->hflags & MIPS_HFLAG_UX)) {
        !           831:         tcg_gen_ext32s_i64(t0, t0);
        !           832:     }
        !           833: #endif
1.1.1.2   root      834: }
                    835: 
1.1.1.7 ! root      836: static inline void check_cp0_enabled(DisasContext *ctx)
1.1.1.6   root      837: {
                    838:     if (unlikely(!(ctx->hflags & MIPS_HFLAG_CP0)))
                    839:         generate_exception_err(ctx, EXCP_CpU, 1);
                    840: }
                    841: 
1.1.1.7 ! root      842: static inline void check_cp1_enabled(DisasContext *ctx)
1.1.1.6   root      843: {
                    844:     if (unlikely(!(ctx->hflags & MIPS_HFLAG_FPU)))
                    845:         generate_exception_err(ctx, EXCP_CpU, 1);
                    846: }
                    847: 
                    848: /* Verify that the processor is running with COP1X instructions enabled.
                    849:    This is associated with the nabla symbol in the MIPS32 and MIPS64
                    850:    opcode tables.  */
                    851: 
1.1.1.7 ! root      852: static inline void check_cop1x(DisasContext *ctx)
1.1.1.6   root      853: {
                    854:     if (unlikely(!(ctx->hflags & MIPS_HFLAG_COP1X)))
                    855:         generate_exception(ctx, EXCP_RI);
                    856: }
                    857: 
                    858: /* Verify that the processor is running with 64-bit floating-point
                    859:    operations enabled.  */
                    860: 
1.1.1.7 ! root      861: static inline void check_cp1_64bitmode(DisasContext *ctx)
1.1.1.6   root      862: {
                    863:     if (unlikely(~ctx->hflags & (MIPS_HFLAG_F64 | MIPS_HFLAG_COP1X)))
                    864:         generate_exception(ctx, EXCP_RI);
                    865: }
                    866: 
                    867: /*
                    868:  * Verify if floating point register is valid; an operation is not defined
                    869:  * if bit 0 of any register specification is set and the FR bit in the
                    870:  * Status register equals zero, since the register numbers specify an
                    871:  * even-odd pair of adjacent coprocessor general registers. When the FR bit
                    872:  * in the Status register equals one, both even and odd register numbers
                    873:  * are valid. This limitation exists only for 64 bit wide (d,l,ps) registers.
                    874:  *
                    875:  * Multiple 64 bit wide registers can be checked by calling
                    876:  * gen_op_cp1_registers(freg1 | freg2 | ... | fregN);
                    877:  */
1.1.1.7 ! root      878: static inline void check_cp1_registers(DisasContext *ctx, int regs)
1.1.1.6   root      879: {
                    880:     if (unlikely(!(ctx->hflags & MIPS_HFLAG_F64) && (regs & 1)))
                    881:         generate_exception(ctx, EXCP_RI);
                    882: }
                    883: 
                    884: /* This code generates a "reserved instruction" exception if the
                    885:    CPU does not support the instruction set corresponding to flags. */
1.1.1.7 ! root      886: static inline void check_insn(CPUState *env, DisasContext *ctx, int flags)
1.1.1.6   root      887: {
                    888:     if (unlikely(!(env->insn_flags & flags)))
                    889:         generate_exception(ctx, EXCP_RI);
                    890: }
                    891: 
                    892: /* This code generates a "reserved instruction" exception if 64-bit
                    893:    instructions are not enabled. */
1.1.1.7 ! root      894: static inline void check_mips_64(DisasContext *ctx)
1.1.1.6   root      895: {
                    896:     if (unlikely(!(ctx->hflags & MIPS_HFLAG_64)))
                    897:         generate_exception(ctx, EXCP_RI);
                    898: }
                    899: 
1.1.1.7 ! root      900: /* load/store instructions. */
        !           901: #define OP_LD(insn,fname)                                        \
        !           902: static inline void op_ldst_##insn(TCGv t0, DisasContext *ctx)    \
        !           903: {                                                                \
        !           904:     tcg_gen_qemu_##fname(t0, t0, ctx->mem_idx);                  \
        !           905: }
        !           906: OP_LD(lb,ld8s);
        !           907: OP_LD(lbu,ld8u);
        !           908: OP_LD(lh,ld16s);
        !           909: OP_LD(lhu,ld16u);
        !           910: OP_LD(lw,ld32s);
        !           911: #if defined(TARGET_MIPS64)
        !           912: OP_LD(lwu,ld32u);
        !           913: OP_LD(ld,ld64);
        !           914: #endif
        !           915: #undef OP_LD
        !           916: 
        !           917: #define OP_ST(insn,fname)                                        \
        !           918: static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx) \
        !           919: {                                                                \
        !           920:     tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx);                  \
        !           921: }
        !           922: OP_ST(sb,st8);
        !           923: OP_ST(sh,st16);
        !           924: OP_ST(sw,st32);
        !           925: #if defined(TARGET_MIPS64)
        !           926: OP_ST(sd,st64);
        !           927: #endif
        !           928: #undef OP_ST
        !           929: 
        !           930: #define OP_LD_ATOMIC(insn,fname)                                        \
        !           931: static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx)  \
        !           932: {                                                                       \
        !           933:     tcg_gen_mov_tl(t1, t0);                                             \
        !           934:     tcg_gen_qemu_##fname(t0, t0, ctx->mem_idx);                         \
        !           935:     tcg_gen_st_tl(t1, cpu_env, offsetof(CPUState, CP0_LLAddr));         \
1.1       root      936: }
1.1.1.7 ! root      937: OP_LD_ATOMIC(ll,ld32s);
        !           938: #if defined(TARGET_MIPS64)
        !           939: OP_LD_ATOMIC(lld,ld64);
1.1       root      940: #endif
1.1.1.7 ! root      941: #undef OP_LD_ATOMIC
1.1       root      942: 
1.1.1.7 ! root      943: #define OP_ST_ATOMIC(insn,fname,almask)                                 \
        !           944: static inline void op_ldst_##insn(TCGv t0, TCGv t1, DisasContext *ctx)  \
        !           945: {                                                                       \
        !           946:     TCGv r_tmp = tcg_temp_local_new();                       \
        !           947:     int l1 = gen_new_label();                                           \
        !           948:     int l2 = gen_new_label();                                           \
        !           949:     int l3 = gen_new_label();                                           \
        !           950:                                                                         \
        !           951:     tcg_gen_andi_tl(r_tmp, t0, almask);                                 \
        !           952:     tcg_gen_brcondi_tl(TCG_COND_EQ, r_tmp, 0, l1);                      \
        !           953:     tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_BadVAddr));       \
        !           954:     generate_exception(ctx, EXCP_AdES);                                 \
        !           955:     gen_set_label(l1);                                                  \
        !           956:     tcg_gen_ld_tl(r_tmp, cpu_env, offsetof(CPUState, CP0_LLAddr));      \
        !           957:     tcg_gen_brcond_tl(TCG_COND_NE, t0, r_tmp, l2);                      \
        !           958:     tcg_gen_qemu_##fname(t1, t0, ctx->mem_idx);                         \
        !           959:     tcg_gen_movi_tl(t0, 1);                                             \
        !           960:     tcg_gen_br(l3);                                                     \
        !           961:     gen_set_label(l2);                                                  \
        !           962:     tcg_gen_movi_tl(t0, 0);                                             \
        !           963:     gen_set_label(l3);                                                  \
        !           964:     tcg_temp_free(r_tmp);                                               \
        !           965: }
        !           966: OP_ST_ATOMIC(sc,st32,0x3);
1.1.1.6   root      967: #if defined(TARGET_MIPS64)
1.1.1.7 ! root      968: OP_ST_ATOMIC(scd,st64,0x7);
1.1       root      969: #endif
1.1.1.7 ! root      970: #undef OP_ST_ATOMIC
1.1       root      971: 
                    972: /* Load and store */
1.1.1.5   root      973: static void gen_ldst (DisasContext *ctx, uint32_t opc, int rt,
1.1       root      974:                       int base, int16_t offset)
                    975: {
1.1.1.6   root      976:     const char *opn = "ldst";
1.1.1.7 ! root      977:     TCGv t0 = tcg_temp_local_new();
        !           978:     TCGv t1 = tcg_temp_local_new();
1.1       root      979: 
                    980:     if (base == 0) {
1.1.1.7 ! root      981:         tcg_gen_movi_tl(t0, offset);
1.1       root      982:     } else if (offset == 0) {
1.1.1.7 ! root      983:         gen_load_gpr(t0, base);
1.1       root      984:     } else {
1.1.1.7 ! root      985:         tcg_gen_movi_tl(t0, offset);
        !           986:         gen_op_addr_add(ctx, t0, cpu_gpr[base]);
1.1       root      987:     }
                    988:     /* Don't do NOP if destination is zero: we must perform the actual
1.1.1.6   root      989:        memory access. */
1.1       root      990:     switch (opc) {
1.1.1.6   root      991: #if defined(TARGET_MIPS64)
                    992:     case OPC_LWU:
1.1.1.7 ! root      993:         op_ldst_lwu(t0, ctx);
        !           994:         gen_store_gpr(t0, rt);
1.1.1.6   root      995:         opn = "lwu";
                    996:         break;
1.1       root      997:     case OPC_LD:
1.1.1.7 ! root      998:         op_ldst_ld(t0, ctx);
        !           999:         gen_store_gpr(t0, rt);
1.1       root     1000:         opn = "ld";
                   1001:         break;
1.1.1.5   root     1002:     case OPC_LLD:
1.1.1.7 ! root     1003:         op_ldst_lld(t0, t1, ctx);
        !          1004:         gen_store_gpr(t0, rt);
1.1.1.5   root     1005:         opn = "lld";
                   1006:         break;
1.1       root     1007:     case OPC_SD:
1.1.1.7 ! root     1008:         gen_load_gpr(t1, rt);
        !          1009:         op_ldst_sd(t0, t1, ctx);
1.1       root     1010:         opn = "sd";
                   1011:         break;
1.1.1.5   root     1012:     case OPC_SCD:
1.1.1.6   root     1013:         save_cpu_state(ctx, 1);
1.1.1.7 ! root     1014:         gen_load_gpr(t1, rt);
        !          1015:         op_ldst_scd(t0, t1, ctx);
        !          1016:         gen_store_gpr(t0, rt);
1.1.1.5   root     1017:         opn = "scd";
                   1018:         break;
1.1       root     1019:     case OPC_LDL:
1.1.1.7 ! root     1020:         save_cpu_state(ctx, 1);
        !          1021:         gen_load_gpr(t1, rt);
        !          1022:         gen_helper_3i(ldl, t1, t0, t1, ctx->mem_idx);
        !          1023:         gen_store_gpr(t1, rt);
1.1       root     1024:         opn = "ldl";
                   1025:         break;
                   1026:     case OPC_SDL:
1.1.1.7 ! root     1027:         save_cpu_state(ctx, 1);
        !          1028:         gen_load_gpr(t1, rt);
        !          1029:         gen_helper_2i(sdl, t0, t1, ctx->mem_idx);
1.1       root     1030:         opn = "sdl";
                   1031:         break;
                   1032:     case OPC_LDR:
1.1.1.7 ! root     1033:         save_cpu_state(ctx, 1);
        !          1034:         gen_load_gpr(t1, rt);
        !          1035:         gen_helper_3i(ldr, t1, t0, t1, ctx->mem_idx);
        !          1036:         gen_store_gpr(t1, rt);
1.1       root     1037:         opn = "ldr";
                   1038:         break;
                   1039:     case OPC_SDR:
1.1.1.7 ! root     1040:         save_cpu_state(ctx, 1);
        !          1041:         gen_load_gpr(t1, rt);
        !          1042:         gen_helper_2i(sdr, t0, t1, ctx->mem_idx);
1.1       root     1043:         opn = "sdr";
                   1044:         break;
                   1045: #endif
                   1046:     case OPC_LW:
1.1.1.7 ! root     1047:         op_ldst_lw(t0, ctx);
        !          1048:         gen_store_gpr(t0, rt);
1.1       root     1049:         opn = "lw";
                   1050:         break;
                   1051:     case OPC_SW:
1.1.1.7 ! root     1052:         gen_load_gpr(t1, rt);
        !          1053:         op_ldst_sw(t0, t1, ctx);
1.1       root     1054:         opn = "sw";
                   1055:         break;
                   1056:     case OPC_LH:
1.1.1.7 ! root     1057:         op_ldst_lh(t0, ctx);
        !          1058:         gen_store_gpr(t0, rt);
1.1       root     1059:         opn = "lh";
                   1060:         break;
                   1061:     case OPC_SH:
1.1.1.7 ! root     1062:         gen_load_gpr(t1, rt);
        !          1063:         op_ldst_sh(t0, t1, ctx);
1.1       root     1064:         opn = "sh";
                   1065:         break;
                   1066:     case OPC_LHU:
1.1.1.7 ! root     1067:         op_ldst_lhu(t0, ctx);
        !          1068:         gen_store_gpr(t0, rt);
1.1       root     1069:         opn = "lhu";
                   1070:         break;
                   1071:     case OPC_LB:
1.1.1.7 ! root     1072:         op_ldst_lb(t0, ctx);
        !          1073:         gen_store_gpr(t0, rt);
1.1       root     1074:         opn = "lb";
                   1075:         break;
                   1076:     case OPC_SB:
1.1.1.7 ! root     1077:         gen_load_gpr(t1, rt);
        !          1078:         op_ldst_sb(t0, t1, ctx);
1.1       root     1079:         opn = "sb";
                   1080:         break;
                   1081:     case OPC_LBU:
1.1.1.7 ! root     1082:         op_ldst_lbu(t0, ctx);
        !          1083:         gen_store_gpr(t0, rt);
1.1       root     1084:         opn = "lbu";
                   1085:         break;
                   1086:     case OPC_LWL:
1.1.1.7 ! root     1087:         save_cpu_state(ctx, 1);
        !          1088:         gen_load_gpr(t1, rt);
        !          1089:         gen_helper_3i(lwl, t1, t0, t1, ctx->mem_idx);
        !          1090:         gen_store_gpr(t1, rt);
1.1       root     1091:         opn = "lwl";
                   1092:         break;
                   1093:     case OPC_SWL:
1.1.1.7 ! root     1094:         save_cpu_state(ctx, 1);
        !          1095:         gen_load_gpr(t1, rt);
        !          1096:         gen_helper_2i(swl, t0, t1, ctx->mem_idx);
1.1       root     1097:         opn = "swr";
                   1098:         break;
                   1099:     case OPC_LWR:
1.1.1.7 ! root     1100:         save_cpu_state(ctx, 1);
        !          1101:         gen_load_gpr(t1, rt);
        !          1102:         gen_helper_3i(lwr, t1, t0, t1, ctx->mem_idx);
        !          1103:         gen_store_gpr(t1, rt);
1.1       root     1104:         opn = "lwr";
                   1105:         break;
                   1106:     case OPC_SWR:
1.1.1.7 ! root     1107:         save_cpu_state(ctx, 1);
        !          1108:         gen_load_gpr(t1, rt);
        !          1109:         gen_helper_2i(swr, t0, t1, ctx->mem_idx);
1.1       root     1110:         opn = "swr";
                   1111:         break;
                   1112:     case OPC_LL:
1.1.1.7 ! root     1113:         op_ldst_ll(t0, t1, ctx);
        !          1114:         gen_store_gpr(t0, rt);
1.1       root     1115:         opn = "ll";
                   1116:         break;
                   1117:     case OPC_SC:
1.1.1.6   root     1118:         save_cpu_state(ctx, 1);
1.1.1.7 ! root     1119:         gen_load_gpr(t1, rt);
        !          1120:         op_ldst_sc(t0, t1, ctx);
        !          1121:         gen_store_gpr(t0, rt);
1.1       root     1122:         opn = "sc";
                   1123:         break;
                   1124:     default:
1.1.1.6   root     1125:         MIPS_INVAL(opn);
1.1       root     1126:         generate_exception(ctx, EXCP_RI);
1.1.1.7 ! root     1127:         goto out;
1.1       root     1128:     }
                   1129:     MIPS_DEBUG("%s %s, %d(%s)", opn, regnames[rt], offset, regnames[base]);
1.1.1.7 ! root     1130:  out:
        !          1131:     tcg_temp_free(t0);
        !          1132:     tcg_temp_free(t1);
1.1       root     1133: }
                   1134: 
1.1.1.4   root     1135: /* Load and store */
1.1.1.5   root     1136: static void gen_flt_ldst (DisasContext *ctx, uint32_t opc, int ft,
1.1.1.7 ! root     1137:                           int base, int16_t offset)
1.1.1.4   root     1138: {
1.1.1.6   root     1139:     const char *opn = "flt_ldst";
1.1.1.7 ! root     1140:     TCGv t0 = tcg_temp_local_new();
1.1.1.4   root     1141: 
                   1142:     if (base == 0) {
1.1.1.7 ! root     1143:         tcg_gen_movi_tl(t0, offset);
1.1.1.4   root     1144:     } else if (offset == 0) {
1.1.1.7 ! root     1145:         gen_load_gpr(t0, base);
1.1.1.4   root     1146:     } else {
1.1.1.7 ! root     1147:         tcg_gen_movi_tl(t0, offset);
        !          1148:         gen_op_addr_add(ctx, t0, cpu_gpr[base]);
1.1.1.4   root     1149:     }
                   1150:     /* Don't do NOP if destination is zero: we must perform the actual
1.1.1.6   root     1151:        memory access. */
1.1.1.4   root     1152:     switch (opc) {
                   1153:     case OPC_LWC1:
1.1.1.7 ! root     1154:         {
        !          1155:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          1156:             TCGv t1 = tcg_temp_new();
        !          1157: 
        !          1158:             tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
        !          1159:             tcg_gen_trunc_tl_i32(fp0, t1);
        !          1160:             gen_store_fpr32(fp0, ft);
        !          1161:             tcg_temp_free(t1);
        !          1162:             tcg_temp_free_i32(fp0);
        !          1163:         }
1.1.1.4   root     1164:         opn = "lwc1";
                   1165:         break;
                   1166:     case OPC_SWC1:
1.1.1.7 ! root     1167:         {
        !          1168:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          1169:             TCGv t1 = tcg_temp_new();
        !          1170: 
        !          1171:             gen_load_fpr32(fp0, ft);
        !          1172:             tcg_gen_extu_i32_tl(t1, fp0);
        !          1173:             tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
        !          1174:             tcg_temp_free(t1);
        !          1175:             tcg_temp_free_i32(fp0);
        !          1176:         }
1.1.1.4   root     1177:         opn = "swc1";
                   1178:         break;
                   1179:     case OPC_LDC1:
1.1.1.7 ! root     1180:         {
        !          1181:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          1182: 
        !          1183:             tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
        !          1184:             gen_store_fpr64(ctx, fp0, ft);
        !          1185:             tcg_temp_free_i64(fp0);
        !          1186:         }
1.1.1.4   root     1187:         opn = "ldc1";
                   1188:         break;
                   1189:     case OPC_SDC1:
1.1.1.7 ! root     1190:         {
        !          1191:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          1192: 
        !          1193:             gen_load_fpr64(ctx, fp0, ft);
        !          1194:             tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
        !          1195:             tcg_temp_free_i64(fp0);
        !          1196:         }
1.1.1.4   root     1197:         opn = "sdc1";
                   1198:         break;
                   1199:     default:
1.1.1.6   root     1200:         MIPS_INVAL(opn);
                   1201:         generate_exception(ctx, EXCP_RI);
1.1.1.7 ! root     1202:         goto out;
1.1.1.4   root     1203:     }
                   1204:     MIPS_DEBUG("%s %s, %d(%s)", opn, fregnames[ft], offset, regnames[base]);
1.1.1.7 ! root     1205:  out:
        !          1206:     tcg_temp_free(t0);
1.1.1.4   root     1207: }
1.1.1.5   root     1208: 
1.1       root     1209: /* Arithmetic with immediate operand */
1.1.1.6   root     1210: static void gen_arith_imm (CPUState *env, DisasContext *ctx, uint32_t opc,
                   1211:                            int rt, int rs, int16_t imm)
1.1       root     1212: {
1.1.1.6   root     1213:     target_ulong uimm;
                   1214:     const char *opn = "imm arith";
1.1.1.7 ! root     1215:     TCGv t0 = tcg_temp_local_new();
1.1       root     1216: 
1.1.1.5   root     1217:     if (rt == 0 && opc != OPC_ADDI && opc != OPC_DADDI) {
1.1.1.6   root     1218:         /* If no destination, treat it as a NOP.
                   1219:            For addi, we must generate the overflow exception when needed. */
1.1       root     1220:         MIPS_DEBUG("NOP");
1.1.1.7 ! root     1221:         goto out;
1.1       root     1222:     }
1.1.1.6   root     1223:     uimm = (uint16_t)imm;
                   1224:     switch (opc) {
                   1225:     case OPC_ADDI:
                   1226:     case OPC_ADDIU:
                   1227: #if defined(TARGET_MIPS64)
                   1228:     case OPC_DADDI:
                   1229:     case OPC_DADDIU:
                   1230: #endif
                   1231:     case OPC_SLTI:
                   1232:     case OPC_SLTIU:
                   1233:         uimm = (target_long)imm; /* Sign extend to 32/64 bits */
                   1234:         /* Fall through. */
                   1235:     case OPC_ANDI:
                   1236:     case OPC_ORI:
                   1237:     case OPC_XORI:
1.1.1.7 ! root     1238:         gen_load_gpr(t0, rs);
1.1.1.6   root     1239:         break;
                   1240:     case OPC_LUI:
1.1.1.7 ! root     1241:         tcg_gen_movi_tl(t0, imm << 16);
1.1.1.6   root     1242:         break;
                   1243:     case OPC_SLL:
                   1244:     case OPC_SRA:
                   1245:     case OPC_SRL:
                   1246: #if defined(TARGET_MIPS64)
                   1247:     case OPC_DSLL:
                   1248:     case OPC_DSRA:
                   1249:     case OPC_DSRL:
                   1250:     case OPC_DSLL32:
                   1251:     case OPC_DSRA32:
                   1252:     case OPC_DSRL32:
                   1253: #endif
                   1254:         uimm &= 0x1f;
1.1.1.7 ! root     1255:         gen_load_gpr(t0, rs);
1.1.1.6   root     1256:         break;
1.1       root     1257:     }
                   1258:     switch (opc) {
                   1259:     case OPC_ADDI:
1.1.1.7 ! root     1260:         {
        !          1261:             TCGv r_tmp1 = tcg_temp_new();
        !          1262:             TCGv r_tmp2 = tcg_temp_new();
        !          1263:             int l1 = gen_new_label();
        !          1264: 
        !          1265:             save_cpu_state(ctx, 1);
        !          1266:             tcg_gen_ext32s_tl(r_tmp1, t0);
        !          1267:             tcg_gen_addi_tl(t0, r_tmp1, uimm);
        !          1268: 
        !          1269:             tcg_gen_xori_tl(r_tmp1, r_tmp1, ~uimm);
        !          1270:             tcg_gen_xori_tl(r_tmp2, t0, uimm);
        !          1271:             tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
        !          1272:             tcg_temp_free(r_tmp2);
        !          1273:             tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
        !          1274:             /* operands of same sign, result different sign */
        !          1275:             generate_exception(ctx, EXCP_OVERFLOW);
        !          1276:             gen_set_label(l1);
        !          1277:             tcg_temp_free(r_tmp1);
        !          1278: 
        !          1279:             tcg_gen_ext32s_tl(t0, t0);
        !          1280:         }
1.1       root     1281:         opn = "addi";
                   1282:         break;
                   1283:     case OPC_ADDIU:
1.1.1.7 ! root     1284:         tcg_gen_addi_tl(t0, t0, uimm);
        !          1285:         tcg_gen_ext32s_tl(t0, t0);
1.1       root     1286:         opn = "addiu";
                   1287:         break;
1.1.1.6   root     1288: #if defined(TARGET_MIPS64)
1.1.1.5   root     1289:     case OPC_DADDI:
1.1.1.7 ! root     1290:         {
        !          1291:             TCGv r_tmp1 = tcg_temp_new();
        !          1292:             TCGv r_tmp2 = tcg_temp_new();
        !          1293:             int l1 = gen_new_label();
        !          1294: 
        !          1295:             save_cpu_state(ctx, 1);
        !          1296:             tcg_gen_mov_tl(r_tmp1, t0);
        !          1297:             tcg_gen_addi_tl(t0, t0, uimm);
        !          1298: 
        !          1299:             tcg_gen_xori_tl(r_tmp1, r_tmp1, ~uimm);
        !          1300:             tcg_gen_xori_tl(r_tmp2, t0, uimm);
        !          1301:             tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
        !          1302:             tcg_temp_free(r_tmp2);
        !          1303:             tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
        !          1304:             /* operands of same sign, result different sign */
        !          1305:             generate_exception(ctx, EXCP_OVERFLOW);
        !          1306:             gen_set_label(l1);
        !          1307:             tcg_temp_free(r_tmp1);
        !          1308:         }
1.1.1.5   root     1309:         opn = "daddi";
                   1310:         break;
                   1311:     case OPC_DADDIU:
1.1.1.7 ! root     1312:         tcg_gen_addi_tl(t0, t0, uimm);
1.1.1.5   root     1313:         opn = "daddiu";
                   1314:         break;
                   1315: #endif
1.1       root     1316:     case OPC_SLTI:
1.1.1.7 ! root     1317:         gen_op_lti(t0, uimm);
1.1       root     1318:         opn = "slti";
                   1319:         break;
                   1320:     case OPC_SLTIU:
1.1.1.7 ! root     1321:         gen_op_ltiu(t0, uimm);
1.1       root     1322:         opn = "sltiu";
                   1323:         break;
                   1324:     case OPC_ANDI:
1.1.1.7 ! root     1325:         tcg_gen_andi_tl(t0, t0, uimm);
1.1       root     1326:         opn = "andi";
                   1327:         break;
                   1328:     case OPC_ORI:
1.1.1.7 ! root     1329:         tcg_gen_ori_tl(t0, t0, uimm);
1.1       root     1330:         opn = "ori";
                   1331:         break;
                   1332:     case OPC_XORI:
1.1.1.7 ! root     1333:         tcg_gen_xori_tl(t0, t0, uimm);
1.1       root     1334:         opn = "xori";
                   1335:         break;
                   1336:     case OPC_LUI:
                   1337:         opn = "lui";
                   1338:         break;
                   1339:     case OPC_SLL:
1.1.1.7 ! root     1340:         tcg_gen_shli_tl(t0, t0, uimm);
        !          1341:         tcg_gen_ext32s_tl(t0, t0);
1.1       root     1342:         opn = "sll";
                   1343:         break;
                   1344:     case OPC_SRA:
1.1.1.7 ! root     1345:         tcg_gen_ext32s_tl(t0, t0);
        !          1346:         tcg_gen_sari_tl(t0, t0, uimm);
1.1       root     1347:         opn = "sra";
                   1348:         break;
                   1349:     case OPC_SRL:
1.1.1.6   root     1350:         switch ((ctx->opcode >> 21) & 0x1f) {
                   1351:         case 0:
1.1.1.7 ! root     1352:             if (uimm != 0) {
        !          1353:                 tcg_gen_ext32u_tl(t0, t0);
        !          1354:                 tcg_gen_shri_tl(t0, t0, uimm);
        !          1355:             } else {
        !          1356:                 tcg_gen_ext32s_tl(t0, t0);
        !          1357:             }
1.1.1.5   root     1358:             opn = "srl";
1.1.1.6   root     1359:             break;
                   1360:         case 1:
                   1361:             /* rotr is decoded as srl on non-R2 CPUs */
                   1362:             if (env->insn_flags & ISA_MIPS32R2) {
1.1.1.7 ! root     1363:                 if (uimm != 0) {
        !          1364:                     TCGv_i32 r_tmp1 = tcg_temp_new_i32();
        !          1365: 
        !          1366:                     tcg_gen_trunc_tl_i32(r_tmp1, t0);
        !          1367:                     tcg_gen_rotri_i32(r_tmp1, r_tmp1, uimm);
        !          1368:                     tcg_gen_ext_i32_tl(t0, r_tmp1);
        !          1369:                     tcg_temp_free_i32(r_tmp1);
        !          1370:                 }
1.1.1.6   root     1371:                 opn = "rotr";
                   1372:             } else {
1.1.1.7 ! root     1373:                 if (uimm != 0) {
        !          1374:                     tcg_gen_ext32u_tl(t0, t0);
        !          1375:                     tcg_gen_shri_tl(t0, t0, uimm);
        !          1376:                 } else {
        !          1377:                     tcg_gen_ext32s_tl(t0, t0);
        !          1378:                 }
1.1.1.6   root     1379:                 opn = "srl";
                   1380:             }
                   1381:             break;
                   1382:         default:
                   1383:             MIPS_INVAL("invalid srl flag");
                   1384:             generate_exception(ctx, EXCP_RI);
                   1385:             break;
                   1386:         }
1.1.1.5   root     1387:         break;
1.1.1.6   root     1388: #if defined(TARGET_MIPS64)
1.1.1.5   root     1389:     case OPC_DSLL:
1.1.1.7 ! root     1390:         tcg_gen_shli_tl(t0, t0, uimm);
1.1.1.5   root     1391:         opn = "dsll";
                   1392:         break;
                   1393:     case OPC_DSRA:
1.1.1.7 ! root     1394:         tcg_gen_sari_tl(t0, t0, uimm);
1.1.1.5   root     1395:         opn = "dsra";
                   1396:         break;
                   1397:     case OPC_DSRL:
1.1.1.6   root     1398:         switch ((ctx->opcode >> 21) & 0x1f) {
                   1399:         case 0:
1.1.1.7 ! root     1400:             tcg_gen_shri_tl(t0, t0, uimm);
1.1.1.5   root     1401:             opn = "dsrl";
1.1.1.6   root     1402:             break;
                   1403:         case 1:
                   1404:             /* drotr is decoded as dsrl on non-R2 CPUs */
                   1405:             if (env->insn_flags & ISA_MIPS32R2) {
1.1.1.7 ! root     1406:                 if (uimm != 0) {
        !          1407:                     tcg_gen_rotri_tl(t0, t0, uimm);
        !          1408:                 }
1.1.1.6   root     1409:                 opn = "drotr";
                   1410:             } else {
1.1.1.7 ! root     1411:                 tcg_gen_shri_tl(t0, t0, uimm);
1.1.1.6   root     1412:                 opn = "dsrl";
                   1413:             }
                   1414:             break;
                   1415:         default:
                   1416:             MIPS_INVAL("invalid dsrl flag");
                   1417:             generate_exception(ctx, EXCP_RI);
                   1418:             break;
                   1419:         }
1.1.1.5   root     1420:         break;
                   1421:     case OPC_DSLL32:
1.1.1.7 ! root     1422:         tcg_gen_shli_tl(t0, t0, uimm + 32);
1.1.1.5   root     1423:         opn = "dsll32";
                   1424:         break;
                   1425:     case OPC_DSRA32:
1.1.1.7 ! root     1426:         tcg_gen_sari_tl(t0, t0, uimm + 32);
1.1.1.5   root     1427:         opn = "dsra32";
                   1428:         break;
                   1429:     case OPC_DSRL32:
1.1.1.6   root     1430:         switch ((ctx->opcode >> 21) & 0x1f) {
                   1431:         case 0:
1.1.1.7 ! root     1432:             tcg_gen_shri_tl(t0, t0, uimm + 32);
1.1.1.5   root     1433:             opn = "dsrl32";
1.1.1.6   root     1434:             break;
                   1435:         case 1:
                   1436:             /* drotr32 is decoded as dsrl32 on non-R2 CPUs */
                   1437:             if (env->insn_flags & ISA_MIPS32R2) {
1.1.1.7 ! root     1438:                 tcg_gen_rotri_tl(t0, t0, uimm + 32);
1.1.1.6   root     1439:                 opn = "drotr32";
                   1440:             } else {
1.1.1.7 ! root     1441:                 tcg_gen_shri_tl(t0, t0, uimm + 32);
1.1.1.6   root     1442:                 opn = "dsrl32";
                   1443:             }
                   1444:             break;
                   1445:         default:
                   1446:             MIPS_INVAL("invalid dsrl32 flag");
                   1447:             generate_exception(ctx, EXCP_RI);
                   1448:             break;
                   1449:         }
1.1       root     1450:         break;
1.1.1.5   root     1451: #endif
1.1       root     1452:     default:
1.1.1.6   root     1453:         MIPS_INVAL(opn);
1.1       root     1454:         generate_exception(ctx, EXCP_RI);
1.1.1.7 ! root     1455:         goto out;
1.1       root     1456:     }
1.1.1.7 ! root     1457:     gen_store_gpr(t0, rt);
1.1.1.6   root     1458:     MIPS_DEBUG("%s %s, %s, " TARGET_FMT_lx, opn, regnames[rt], regnames[rs], uimm);
1.1.1.7 ! root     1459:  out:
        !          1460:     tcg_temp_free(t0);
1.1       root     1461: }
                   1462: 
                   1463: /* Arithmetic */
1.1.1.6   root     1464: static void gen_arith (CPUState *env, DisasContext *ctx, uint32_t opc,
1.1       root     1465:                        int rd, int rs, int rt)
                   1466: {
1.1.1.6   root     1467:     const char *opn = "arith";
1.1.1.7 ! root     1468:     TCGv t0 = tcg_temp_local_new();
        !          1469:     TCGv t1 = tcg_temp_local_new();
1.1       root     1470: 
1.1.1.5   root     1471:     if (rd == 0 && opc != OPC_ADD && opc != OPC_SUB
                   1472:        && opc != OPC_DADD && opc != OPC_DSUB) {
1.1.1.6   root     1473:         /* If no destination, treat it as a NOP.
                   1474:            For add & sub, we must generate the overflow exception when needed. */
1.1       root     1475:         MIPS_DEBUG("NOP");
1.1.1.7 ! root     1476:         goto out;
1.1       root     1477:     }
1.1.1.7 ! root     1478:     gen_load_gpr(t0, rs);
1.1.1.6   root     1479:     /* Specialcase the conventional move operation. */
                   1480:     if (rt == 0 && (opc == OPC_ADDU || opc == OPC_DADDU
                   1481:                     || opc == OPC_SUBU || opc == OPC_DSUBU)) {
1.1.1.7 ! root     1482:         gen_store_gpr(t0, rd);
        !          1483:         goto out;
1.1.1.6   root     1484:     }
1.1.1.7 ! root     1485:     gen_load_gpr(t1, rt);
1.1       root     1486:     switch (opc) {
                   1487:     case OPC_ADD:
1.1.1.7 ! root     1488:         {
        !          1489:             TCGv r_tmp1 = tcg_temp_new();
        !          1490:             TCGv r_tmp2 = tcg_temp_new();
        !          1491:             int l1 = gen_new_label();
        !          1492: 
        !          1493:             save_cpu_state(ctx, 1);
        !          1494:             tcg_gen_ext32s_tl(r_tmp1, t0);
        !          1495:             tcg_gen_ext32s_tl(r_tmp2, t1);
        !          1496:             tcg_gen_add_tl(t0, r_tmp1, r_tmp2);
        !          1497: 
        !          1498:             tcg_gen_xor_tl(r_tmp1, r_tmp1, t1);
        !          1499:             tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
        !          1500:             tcg_gen_xor_tl(r_tmp2, t0, t1);
        !          1501:             tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
        !          1502:             tcg_temp_free(r_tmp2);
        !          1503:             tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
        !          1504:             /* operands of same sign, result different sign */
        !          1505:             generate_exception(ctx, EXCP_OVERFLOW);
        !          1506:             gen_set_label(l1);
        !          1507:             tcg_temp_free(r_tmp1);
        !          1508: 
        !          1509:             tcg_gen_ext32s_tl(t0, t0);
        !          1510:         }
1.1       root     1511:         opn = "add";
                   1512:         break;
                   1513:     case OPC_ADDU:
1.1.1.7 ! root     1514:         tcg_gen_add_tl(t0, t0, t1);
        !          1515:         tcg_gen_ext32s_tl(t0, t0);
1.1       root     1516:         opn = "addu";
                   1517:         break;
                   1518:     case OPC_SUB:
1.1.1.7 ! root     1519:         {
        !          1520:             TCGv r_tmp1 = tcg_temp_new();
        !          1521:             TCGv r_tmp2 = tcg_temp_new();
        !          1522:             int l1 = gen_new_label();
        !          1523: 
        !          1524:             save_cpu_state(ctx, 1);
        !          1525:             tcg_gen_ext32s_tl(r_tmp1, t0);
        !          1526:             tcg_gen_ext32s_tl(r_tmp2, t1);
        !          1527:             tcg_gen_sub_tl(t0, r_tmp1, r_tmp2);
        !          1528: 
        !          1529:             tcg_gen_xor_tl(r_tmp2, r_tmp1, t1);
        !          1530:             tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
        !          1531:             tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
        !          1532:             tcg_temp_free(r_tmp2);
        !          1533:             tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
        !          1534:             /* operands of different sign, first operand and result different sign */
        !          1535:             generate_exception(ctx, EXCP_OVERFLOW);
        !          1536:             gen_set_label(l1);
        !          1537:             tcg_temp_free(r_tmp1);
        !          1538: 
        !          1539:             tcg_gen_ext32s_tl(t0, t0);
        !          1540:         }
1.1       root     1541:         opn = "sub";
                   1542:         break;
                   1543:     case OPC_SUBU:
1.1.1.7 ! root     1544:         tcg_gen_sub_tl(t0, t0, t1);
        !          1545:         tcg_gen_ext32s_tl(t0, t0);
1.1       root     1546:         opn = "subu";
                   1547:         break;
1.1.1.6   root     1548: #if defined(TARGET_MIPS64)
1.1.1.5   root     1549:     case OPC_DADD:
1.1.1.7 ! root     1550:         {
        !          1551:             TCGv r_tmp1 = tcg_temp_new();
        !          1552:             TCGv r_tmp2 = tcg_temp_new();
        !          1553:             int l1 = gen_new_label();
        !          1554: 
        !          1555:             save_cpu_state(ctx, 1);
        !          1556:             tcg_gen_mov_tl(r_tmp1, t0);
        !          1557:             tcg_gen_add_tl(t0, t0, t1);
        !          1558: 
        !          1559:             tcg_gen_xor_tl(r_tmp1, r_tmp1, t1);
        !          1560:             tcg_gen_xori_tl(r_tmp1, r_tmp1, -1);
        !          1561:             tcg_gen_xor_tl(r_tmp2, t0, t1);
        !          1562:             tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
        !          1563:             tcg_temp_free(r_tmp2);
        !          1564:             tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
        !          1565:             /* operands of same sign, result different sign */
        !          1566:             generate_exception(ctx, EXCP_OVERFLOW);
        !          1567:             gen_set_label(l1);
        !          1568:             tcg_temp_free(r_tmp1);
        !          1569:         }
1.1.1.5   root     1570:         opn = "dadd";
                   1571:         break;
                   1572:     case OPC_DADDU:
1.1.1.7 ! root     1573:         tcg_gen_add_tl(t0, t0, t1);
1.1.1.5   root     1574:         opn = "daddu";
                   1575:         break;
                   1576:     case OPC_DSUB:
1.1.1.7 ! root     1577:         {
        !          1578:             TCGv r_tmp1 = tcg_temp_new();
        !          1579:             TCGv r_tmp2 = tcg_temp_new();
        !          1580:             int l1 = gen_new_label();
        !          1581: 
        !          1582:             save_cpu_state(ctx, 1);
        !          1583:             tcg_gen_mov_tl(r_tmp1, t0);
        !          1584:             tcg_gen_sub_tl(t0, t0, t1);
        !          1585: 
        !          1586:             tcg_gen_xor_tl(r_tmp2, r_tmp1, t1);
        !          1587:             tcg_gen_xor_tl(r_tmp1, r_tmp1, t0);
        !          1588:             tcg_gen_and_tl(r_tmp1, r_tmp1, r_tmp2);
        !          1589:             tcg_temp_free(r_tmp2);
        !          1590:             tcg_gen_brcondi_tl(TCG_COND_GE, r_tmp1, 0, l1);
        !          1591:             /* operands of different sign, first operand and result different sign */
        !          1592:             generate_exception(ctx, EXCP_OVERFLOW);
        !          1593:             gen_set_label(l1);
        !          1594:             tcg_temp_free(r_tmp1);
        !          1595:         }
1.1.1.5   root     1596:         opn = "dsub";
                   1597:         break;
                   1598:     case OPC_DSUBU:
1.1.1.7 ! root     1599:         tcg_gen_sub_tl(t0, t0, t1);
1.1.1.5   root     1600:         opn = "dsubu";
                   1601:         break;
                   1602: #endif
1.1       root     1603:     case OPC_SLT:
1.1.1.7 ! root     1604:         gen_op_lt(t0, t1);
1.1       root     1605:         opn = "slt";
                   1606:         break;
                   1607:     case OPC_SLTU:
1.1.1.7 ! root     1608:         gen_op_ltu(t0, t1);
1.1       root     1609:         opn = "sltu";
                   1610:         break;
                   1611:     case OPC_AND:
1.1.1.7 ! root     1612:         tcg_gen_and_tl(t0, t0, t1);
1.1       root     1613:         opn = "and";
                   1614:         break;
                   1615:     case OPC_NOR:
1.1.1.7 ! root     1616:         tcg_gen_or_tl(t0, t0, t1);
        !          1617:         tcg_gen_not_tl(t0, t0);
1.1       root     1618:         opn = "nor";
                   1619:         break;
                   1620:     case OPC_OR:
1.1.1.7 ! root     1621:         tcg_gen_or_tl(t0, t0, t1);
1.1       root     1622:         opn = "or";
                   1623:         break;
                   1624:     case OPC_XOR:
1.1.1.7 ! root     1625:         tcg_gen_xor_tl(t0, t0, t1);
1.1       root     1626:         opn = "xor";
                   1627:         break;
                   1628:     case OPC_MUL:
1.1.1.7 ! root     1629:         tcg_gen_mul_tl(t0, t0, t1);
        !          1630:         tcg_gen_ext32s_tl(t0, t0);
1.1       root     1631:         opn = "mul";
                   1632:         break;
                   1633:     case OPC_MOVN:
1.1.1.7 ! root     1634:         {
        !          1635:             int l1 = gen_new_label();
        !          1636: 
        !          1637:             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
        !          1638:             gen_store_gpr(t0, rd);
        !          1639:             gen_set_label(l1);
        !          1640:         }
1.1       root     1641:         opn = "movn";
                   1642:         goto print;
                   1643:     case OPC_MOVZ:
1.1.1.7 ! root     1644:         {
        !          1645:             int l1 = gen_new_label();
        !          1646: 
        !          1647:             tcg_gen_brcondi_tl(TCG_COND_NE, t1, 0, l1);
        !          1648:             gen_store_gpr(t0, rd);
        !          1649:             gen_set_label(l1);
        !          1650:         }
1.1       root     1651:         opn = "movz";
                   1652:         goto print;
                   1653:     case OPC_SLLV:
1.1.1.7 ! root     1654:         tcg_gen_andi_tl(t0, t0, 0x1f);
        !          1655:         tcg_gen_shl_tl(t0, t1, t0);
        !          1656:         tcg_gen_ext32s_tl(t0, t0);
1.1       root     1657:         opn = "sllv";
                   1658:         break;
                   1659:     case OPC_SRAV:
1.1.1.7 ! root     1660:         tcg_gen_ext32s_tl(t1, t1);
        !          1661:         tcg_gen_andi_tl(t0, t0, 0x1f);
        !          1662:         tcg_gen_sar_tl(t0, t1, t0);
1.1       root     1663:         opn = "srav";
                   1664:         break;
                   1665:     case OPC_SRLV:
1.1.1.6   root     1666:         switch ((ctx->opcode >> 6) & 0x1f) {
                   1667:         case 0:
1.1.1.7 ! root     1668:             tcg_gen_ext32u_tl(t1, t1);
        !          1669:             tcg_gen_andi_tl(t0, t0, 0x1f);
        !          1670:             tcg_gen_shr_tl(t0, t1, t0);
        !          1671:             tcg_gen_ext32s_tl(t0, t0);
1.1.1.5   root     1672:             opn = "srlv";
1.1.1.6   root     1673:             break;
                   1674:         case 1:
                   1675:             /* rotrv is decoded as srlv on non-R2 CPUs */
                   1676:             if (env->insn_flags & ISA_MIPS32R2) {
1.1.1.7 ! root     1677:                 int l1 = gen_new_label();
        !          1678:                 int l2 = gen_new_label();
        !          1679: 
        !          1680:                 tcg_gen_andi_tl(t0, t0, 0x1f);
        !          1681:                 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
        !          1682:                 {
        !          1683:                     TCGv_i32 r_tmp1 = tcg_temp_new_i32();
        !          1684:                     TCGv_i32 r_tmp2 = tcg_temp_new_i32();
        !          1685: 
        !          1686:                     tcg_gen_trunc_tl_i32(r_tmp1, t0);
        !          1687:                     tcg_gen_trunc_tl_i32(r_tmp2, t1);
        !          1688:                     tcg_gen_rotr_i32(r_tmp1, r_tmp1, r_tmp2);
        !          1689:                     tcg_temp_free_i32(r_tmp1);
        !          1690:                     tcg_temp_free_i32(r_tmp2);
        !          1691:                     tcg_gen_br(l2);
        !          1692:                 }
        !          1693:                 gen_set_label(l1);
        !          1694:                 tcg_gen_mov_tl(t0, t1);
        !          1695:                 gen_set_label(l2);
1.1.1.6   root     1696:                 opn = "rotrv";
                   1697:             } else {
1.1.1.7 ! root     1698:                 tcg_gen_ext32u_tl(t1, t1);
        !          1699:                 tcg_gen_andi_tl(t0, t0, 0x1f);
        !          1700:                 tcg_gen_shr_tl(t0, t1, t0);
        !          1701:                 tcg_gen_ext32s_tl(t0, t0);
1.1.1.6   root     1702:                 opn = "srlv";
                   1703:             }
                   1704:             break;
                   1705:         default:
                   1706:             MIPS_INVAL("invalid srlv flag");
                   1707:             generate_exception(ctx, EXCP_RI);
                   1708:             break;
                   1709:         }
1.1.1.5   root     1710:         break;
1.1.1.6   root     1711: #if defined(TARGET_MIPS64)
1.1.1.5   root     1712:     case OPC_DSLLV:
1.1.1.7 ! root     1713:         tcg_gen_andi_tl(t0, t0, 0x3f);
        !          1714:         tcg_gen_shl_tl(t0, t1, t0);
1.1.1.5   root     1715:         opn = "dsllv";
                   1716:         break;
                   1717:     case OPC_DSRAV:
1.1.1.7 ! root     1718:         tcg_gen_andi_tl(t0, t0, 0x3f);
        !          1719:         tcg_gen_sar_tl(t0, t1, t0);
1.1.1.5   root     1720:         opn = "dsrav";
                   1721:         break;
                   1722:     case OPC_DSRLV:
1.1.1.6   root     1723:         switch ((ctx->opcode >> 6) & 0x1f) {
                   1724:         case 0:
1.1.1.7 ! root     1725:             tcg_gen_andi_tl(t0, t0, 0x3f);
        !          1726:             tcg_gen_shr_tl(t0, t1, t0);
1.1.1.5   root     1727:             opn = "dsrlv";
1.1.1.6   root     1728:             break;
                   1729:         case 1:
                   1730:             /* drotrv is decoded as dsrlv on non-R2 CPUs */
                   1731:             if (env->insn_flags & ISA_MIPS32R2) {
1.1.1.7 ! root     1732:                 int l1 = gen_new_label();
        !          1733:                 int l2 = gen_new_label();
        !          1734: 
        !          1735:                 tcg_gen_andi_tl(t0, t0, 0x3f);
        !          1736:                 tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
        !          1737:                 {
        !          1738:                     tcg_gen_rotr_tl(t0, t1, t0);
        !          1739:                     tcg_gen_br(l2);
        !          1740:                 }
        !          1741:                 gen_set_label(l1);
        !          1742:                 tcg_gen_mov_tl(t0, t1);
        !          1743:                 gen_set_label(l2);
1.1.1.6   root     1744:                 opn = "drotrv";
                   1745:             } else {
1.1.1.7 ! root     1746:                 tcg_gen_andi_tl(t0, t0, 0x3f);
        !          1747:                 tcg_gen_shr_tl(t0, t1, t0);
1.1.1.6   root     1748:                 opn = "dsrlv";
                   1749:             }
                   1750:             break;
                   1751:         default:
                   1752:             MIPS_INVAL("invalid dsrlv flag");
                   1753:             generate_exception(ctx, EXCP_RI);
                   1754:             break;
                   1755:         }
1.1       root     1756:         break;
1.1.1.5   root     1757: #endif
1.1       root     1758:     default:
1.1.1.6   root     1759:         MIPS_INVAL(opn);
1.1       root     1760:         generate_exception(ctx, EXCP_RI);
1.1.1.7 ! root     1761:         goto out;
1.1       root     1762:     }
1.1.1.7 ! root     1763:     gen_store_gpr(t0, rd);
1.1       root     1764:  print:
                   1765:     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1.1.1.7 ! root     1766:  out:
        !          1767:     tcg_temp_free(t0);
        !          1768:     tcg_temp_free(t1);
1.1       root     1769: }
                   1770: 
                   1771: /* Arithmetic on HI/LO registers */
1.1.1.5   root     1772: static void gen_HILO (DisasContext *ctx, uint32_t opc, int reg)
1.1       root     1773: {
1.1.1.6   root     1774:     const char *opn = "hilo";
1.1.1.7 ! root     1775:     TCGv t0 = tcg_temp_local_new();
1.1       root     1776: 
                   1777:     if (reg == 0 && (opc == OPC_MFHI || opc == OPC_MFLO)) {
1.1.1.6   root     1778:         /* Treat as NOP. */
1.1       root     1779:         MIPS_DEBUG("NOP");
1.1.1.7 ! root     1780:         goto out;
1.1       root     1781:     }
                   1782:     switch (opc) {
                   1783:     case OPC_MFHI:
1.1.1.7 ! root     1784:         tcg_gen_mov_tl(t0, cpu_HI[0]);
        !          1785:         gen_store_gpr(t0, reg);
1.1       root     1786:         opn = "mfhi";
                   1787:         break;
                   1788:     case OPC_MFLO:
1.1.1.7 ! root     1789:         tcg_gen_mov_tl(t0, cpu_LO[0]);
        !          1790:         gen_store_gpr(t0, reg);
1.1       root     1791:         opn = "mflo";
                   1792:         break;
                   1793:     case OPC_MTHI:
1.1.1.7 ! root     1794:         gen_load_gpr(t0, reg);
        !          1795:         tcg_gen_mov_tl(cpu_HI[0], t0);
1.1       root     1796:         opn = "mthi";
                   1797:         break;
                   1798:     case OPC_MTLO:
1.1.1.7 ! root     1799:         gen_load_gpr(t0, reg);
        !          1800:         tcg_gen_mov_tl(cpu_LO[0], t0);
1.1       root     1801:         opn = "mtlo";
                   1802:         break;
                   1803:     default:
1.1.1.6   root     1804:         MIPS_INVAL(opn);
1.1       root     1805:         generate_exception(ctx, EXCP_RI);
1.1.1.7 ! root     1806:         goto out;
1.1       root     1807:     }
                   1808:     MIPS_DEBUG("%s %s", opn, regnames[reg]);
1.1.1.7 ! root     1809:  out:
        !          1810:     tcg_temp_free(t0);
1.1       root     1811: }
                   1812: 
1.1.1.5   root     1813: static void gen_muldiv (DisasContext *ctx, uint32_t opc,
1.1       root     1814:                         int rs, int rt)
                   1815: {
1.1.1.6   root     1816:     const char *opn = "mul/div";
1.1.1.7 ! root     1817:     TCGv t0 = tcg_temp_local_new();
        !          1818:     TCGv t1 = tcg_temp_local_new();
1.1       root     1819: 
1.1.1.7 ! root     1820:     gen_load_gpr(t0, rs);
        !          1821:     gen_load_gpr(t1, rt);
1.1       root     1822:     switch (opc) {
                   1823:     case OPC_DIV:
1.1.1.7 ! root     1824:         {
        !          1825:             int l1 = gen_new_label();
        !          1826: 
        !          1827:             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
        !          1828:             {
        !          1829:                 int l2 = gen_new_label();
        !          1830:                 TCGv_i32 r_tmp1 = tcg_temp_local_new_i32();
        !          1831:                 TCGv_i32 r_tmp2 = tcg_temp_local_new_i32();
        !          1832:                 TCGv_i32 r_tmp3 = tcg_temp_local_new_i32();
        !          1833: 
        !          1834:                 tcg_gen_trunc_tl_i32(r_tmp1, t0);
        !          1835:                 tcg_gen_trunc_tl_i32(r_tmp2, t1);
        !          1836:                 tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp1, -1 << 31, l2);
        !          1837:                 tcg_gen_brcondi_i32(TCG_COND_NE, r_tmp2, -1, l2);
        !          1838:                 tcg_gen_ext32s_tl(cpu_LO[0], t0);
        !          1839:                 tcg_gen_movi_tl(cpu_HI[0], 0);
        !          1840:                 tcg_gen_br(l1);
        !          1841:                 gen_set_label(l2);
        !          1842:                 tcg_gen_div_i32(r_tmp3, r_tmp1, r_tmp2);
        !          1843:                 tcg_gen_rem_i32(r_tmp2, r_tmp1, r_tmp2);
        !          1844:                 tcg_gen_ext_i32_tl(cpu_LO[0], r_tmp3);
        !          1845:                 tcg_gen_ext_i32_tl(cpu_HI[0], r_tmp2);
        !          1846:                 tcg_temp_free_i32(r_tmp1);
        !          1847:                 tcg_temp_free_i32(r_tmp2);
        !          1848:                 tcg_temp_free_i32(r_tmp3);
        !          1849:             }
        !          1850:             gen_set_label(l1);
        !          1851:         }
1.1       root     1852:         opn = "div";
                   1853:         break;
                   1854:     case OPC_DIVU:
1.1.1.7 ! root     1855:         {
        !          1856:             int l1 = gen_new_label();
        !          1857: 
        !          1858:             tcg_gen_ext32s_tl(t1, t1);
        !          1859:             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
        !          1860:             {
        !          1861:                 TCGv_i32 r_tmp1 = tcg_temp_new_i32();
        !          1862:                 TCGv_i32 r_tmp2 = tcg_temp_new_i32();
        !          1863:                 TCGv_i32 r_tmp3 = tcg_temp_new_i32();
        !          1864: 
        !          1865:                 tcg_gen_trunc_tl_i32(r_tmp1, t0);
        !          1866:                 tcg_gen_trunc_tl_i32(r_tmp2, t1);
        !          1867:                 tcg_gen_divu_i32(r_tmp3, r_tmp1, r_tmp2);
        !          1868:                 tcg_gen_remu_i32(r_tmp1, r_tmp1, r_tmp2);
        !          1869:                 tcg_gen_ext_i32_tl(cpu_LO[0], r_tmp3);
        !          1870:                 tcg_gen_ext_i32_tl(cpu_HI[0], r_tmp1);
        !          1871:                 tcg_temp_free_i32(r_tmp1);
        !          1872:                 tcg_temp_free_i32(r_tmp2);
        !          1873:                 tcg_temp_free_i32(r_tmp3);
        !          1874:             }
        !          1875:             gen_set_label(l1);
        !          1876:         }
1.1       root     1877:         opn = "divu";
                   1878:         break;
                   1879:     case OPC_MULT:
1.1.1.7 ! root     1880:         {
        !          1881:             TCGv_i64 r_tmp1 = tcg_temp_new_i64();
        !          1882:             TCGv_i64 r_tmp2 = tcg_temp_new_i64();
        !          1883: 
        !          1884:             tcg_gen_ext_tl_i64(r_tmp1, t0);
        !          1885:             tcg_gen_ext_tl_i64(r_tmp2, t1);
        !          1886:             tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
        !          1887:             tcg_temp_free_i64(r_tmp2);
        !          1888:             tcg_gen_trunc_i64_tl(t0, r_tmp1);
        !          1889:             tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
        !          1890:             tcg_gen_trunc_i64_tl(t1, r_tmp1);
        !          1891:             tcg_temp_free_i64(r_tmp1);
        !          1892:             tcg_gen_ext32s_tl(cpu_LO[0], t0);
        !          1893:             tcg_gen_ext32s_tl(cpu_HI[0], t1);
        !          1894:         }
1.1       root     1895:         opn = "mult";
                   1896:         break;
                   1897:     case OPC_MULTU:
1.1.1.7 ! root     1898:         {
        !          1899:             TCGv_i64 r_tmp1 = tcg_temp_new_i64();
        !          1900:             TCGv_i64 r_tmp2 = tcg_temp_new_i64();
        !          1901: 
        !          1902:             tcg_gen_ext32u_tl(t0, t0);
        !          1903:             tcg_gen_ext32u_tl(t1, t1);
        !          1904:             tcg_gen_extu_tl_i64(r_tmp1, t0);
        !          1905:             tcg_gen_extu_tl_i64(r_tmp2, t1);
        !          1906:             tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
        !          1907:             tcg_temp_free_i64(r_tmp2);
        !          1908:             tcg_gen_trunc_i64_tl(t0, r_tmp1);
        !          1909:             tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
        !          1910:             tcg_gen_trunc_i64_tl(t1, r_tmp1);
        !          1911:             tcg_temp_free_i64(r_tmp1);
        !          1912:             tcg_gen_ext32s_tl(cpu_LO[0], t0);
        !          1913:             tcg_gen_ext32s_tl(cpu_HI[0], t1);
        !          1914:         }
1.1       root     1915:         opn = "multu";
                   1916:         break;
1.1.1.6   root     1917: #if defined(TARGET_MIPS64)
1.1.1.5   root     1918:     case OPC_DDIV:
1.1.1.7 ! root     1919:         {
        !          1920:             int l1 = gen_new_label();
        !          1921: 
        !          1922:             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
        !          1923:             {
        !          1924:                 int l2 = gen_new_label();
        !          1925: 
        !          1926:                 tcg_gen_brcondi_tl(TCG_COND_NE, t0, -1LL << 63, l2);
        !          1927:                 tcg_gen_brcondi_tl(TCG_COND_NE, t1, -1LL, l2);
        !          1928:                 tcg_gen_mov_tl(cpu_LO[0], t0);
        !          1929:                 tcg_gen_movi_tl(cpu_HI[0], 0);
        !          1930:                 tcg_gen_br(l1);
        !          1931:                 gen_set_label(l2);
        !          1932:                 tcg_gen_div_i64(cpu_LO[0], t0, t1);
        !          1933:                 tcg_gen_rem_i64(cpu_HI[0], t0, t1);
        !          1934:             }
        !          1935:             gen_set_label(l1);
        !          1936:         }
1.1.1.5   root     1937:         opn = "ddiv";
                   1938:         break;
                   1939:     case OPC_DDIVU:
1.1.1.7 ! root     1940:         {
        !          1941:             int l1 = gen_new_label();
        !          1942: 
        !          1943:             tcg_gen_brcondi_tl(TCG_COND_EQ, t1, 0, l1);
        !          1944:             tcg_gen_divu_i64(cpu_LO[0], t0, t1);
        !          1945:             tcg_gen_remu_i64(cpu_HI[0], t0, t1);
        !          1946:             gen_set_label(l1);
        !          1947:         }
1.1.1.5   root     1948:         opn = "ddivu";
                   1949:         break;
                   1950:     case OPC_DMULT:
1.1.1.7 ! root     1951:         gen_helper_dmult(t0, t1);
1.1.1.5   root     1952:         opn = "dmult";
                   1953:         break;
                   1954:     case OPC_DMULTU:
1.1.1.7 ! root     1955:         gen_helper_dmultu(t0, t1);
1.1.1.5   root     1956:         opn = "dmultu";
                   1957:         break;
                   1958: #endif
1.1       root     1959:     case OPC_MADD:
1.1.1.7 ! root     1960:         {
        !          1961:             TCGv_i64 r_tmp1 = tcg_temp_new_i64();
        !          1962:             TCGv_i64 r_tmp2 = tcg_temp_new_i64();
        !          1963: 
        !          1964:             tcg_gen_ext_tl_i64(r_tmp1, t0);
        !          1965:             tcg_gen_ext_tl_i64(r_tmp2, t1);
        !          1966:             tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
        !          1967:             tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
        !          1968:             tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2);
        !          1969:             tcg_temp_free_i64(r_tmp2);
        !          1970:             tcg_gen_trunc_i64_tl(t0, r_tmp1);
        !          1971:             tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
        !          1972:             tcg_gen_trunc_i64_tl(t1, r_tmp1);
        !          1973:             tcg_temp_free_i64(r_tmp1);
        !          1974:             tcg_gen_ext32s_tl(cpu_LO[0], t0);
        !          1975:             tcg_gen_ext32s_tl(cpu_LO[1], t1);
        !          1976:         }
1.1       root     1977:         opn = "madd";
                   1978:         break;
                   1979:     case OPC_MADDU:
1.1.1.7 ! root     1980:        {
        !          1981:             TCGv_i64 r_tmp1 = tcg_temp_new_i64();
        !          1982:             TCGv_i64 r_tmp2 = tcg_temp_new_i64();
        !          1983: 
        !          1984:             tcg_gen_ext32u_tl(t0, t0);
        !          1985:             tcg_gen_ext32u_tl(t1, t1);
        !          1986:             tcg_gen_extu_tl_i64(r_tmp1, t0);
        !          1987:             tcg_gen_extu_tl_i64(r_tmp2, t1);
        !          1988:             tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
        !          1989:             tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
        !          1990:             tcg_gen_add_i64(r_tmp1, r_tmp1, r_tmp2);
        !          1991:             tcg_temp_free_i64(r_tmp2);
        !          1992:             tcg_gen_trunc_i64_tl(t0, r_tmp1);
        !          1993:             tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
        !          1994:             tcg_gen_trunc_i64_tl(t1, r_tmp1);
        !          1995:             tcg_temp_free_i64(r_tmp1);
        !          1996:             tcg_gen_ext32s_tl(cpu_LO[0], t0);
        !          1997:             tcg_gen_ext32s_tl(cpu_HI[0], t1);
        !          1998:         }
1.1       root     1999:         opn = "maddu";
                   2000:         break;
                   2001:     case OPC_MSUB:
1.1.1.7 ! root     2002:         {
        !          2003:             TCGv_i64 r_tmp1 = tcg_temp_new_i64();
        !          2004:             TCGv_i64 r_tmp2 = tcg_temp_new_i64();
        !          2005: 
        !          2006:             tcg_gen_ext_tl_i64(r_tmp1, t0);
        !          2007:             tcg_gen_ext_tl_i64(r_tmp2, t1);
        !          2008:             tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
        !          2009:             tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
        !          2010:             tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2);
        !          2011:             tcg_temp_free_i64(r_tmp2);
        !          2012:             tcg_gen_trunc_i64_tl(t0, r_tmp1);
        !          2013:             tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
        !          2014:             tcg_gen_trunc_i64_tl(t1, r_tmp1);
        !          2015:             tcg_temp_free_i64(r_tmp1);
        !          2016:             tcg_gen_ext32s_tl(cpu_LO[0], t0);
        !          2017:             tcg_gen_ext32s_tl(cpu_HI[0], t1);
        !          2018:         }
1.1       root     2019:         opn = "msub";
                   2020:         break;
                   2021:     case OPC_MSUBU:
1.1.1.7 ! root     2022:         {
        !          2023:             TCGv_i64 r_tmp1 = tcg_temp_new_i64();
        !          2024:             TCGv_i64 r_tmp2 = tcg_temp_new_i64();
        !          2025: 
        !          2026:             tcg_gen_ext32u_tl(t0, t0);
        !          2027:             tcg_gen_ext32u_tl(t1, t1);
        !          2028:             tcg_gen_extu_tl_i64(r_tmp1, t0);
        !          2029:             tcg_gen_extu_tl_i64(r_tmp2, t1);
        !          2030:             tcg_gen_mul_i64(r_tmp1, r_tmp1, r_tmp2);
        !          2031:             tcg_gen_concat_tl_i64(r_tmp2, cpu_LO[0], cpu_HI[0]);
        !          2032:             tcg_gen_sub_i64(r_tmp1, r_tmp1, r_tmp2);
        !          2033:             tcg_temp_free_i64(r_tmp2);
        !          2034:             tcg_gen_trunc_i64_tl(t0, r_tmp1);
        !          2035:             tcg_gen_shri_i64(r_tmp1, r_tmp1, 32);
        !          2036:             tcg_gen_trunc_i64_tl(t1, r_tmp1);
        !          2037:             tcg_temp_free_i64(r_tmp1);
        !          2038:             tcg_gen_ext32s_tl(cpu_LO[0], t0);
        !          2039:             tcg_gen_ext32s_tl(cpu_HI[0], t1);
        !          2040:         }
1.1       root     2041:         opn = "msubu";
                   2042:         break;
                   2043:     default:
1.1.1.6   root     2044:         MIPS_INVAL(opn);
1.1       root     2045:         generate_exception(ctx, EXCP_RI);
1.1.1.7 ! root     2046:         goto out;
1.1       root     2047:     }
                   2048:     MIPS_DEBUG("%s %s %s", opn, regnames[rs], regnames[rt]);
1.1.1.7 ! root     2049:  out:
        !          2050:     tcg_temp_free(t0);
        !          2051:     tcg_temp_free(t1);
1.1       root     2052: }
                   2053: 
1.1.1.6   root     2054: static void gen_mul_vr54xx (DisasContext *ctx, uint32_t opc,
                   2055:                             int rd, int rs, int rt)
                   2056: {
                   2057:     const char *opn = "mul vr54xx";
1.1.1.7 ! root     2058:     TCGv t0 = tcg_temp_local_new();
        !          2059:     TCGv t1 = tcg_temp_local_new();
1.1.1.6   root     2060: 
1.1.1.7 ! root     2061:     gen_load_gpr(t0, rs);
        !          2062:     gen_load_gpr(t1, rt);
1.1.1.6   root     2063: 
                   2064:     switch (opc) {
                   2065:     case OPC_VR54XX_MULS:
1.1.1.7 ! root     2066:         gen_helper_muls(t0, t0, t1);
1.1.1.6   root     2067:         opn = "muls";
1.1.1.7 ! root     2068:         break;
1.1.1.6   root     2069:     case OPC_VR54XX_MULSU:
1.1.1.7 ! root     2070:         gen_helper_mulsu(t0, t0, t1);
1.1.1.6   root     2071:         opn = "mulsu";
1.1.1.7 ! root     2072:         break;
1.1.1.6   root     2073:     case OPC_VR54XX_MACC:
1.1.1.7 ! root     2074:         gen_helper_macc(t0, t0, t1);
1.1.1.6   root     2075:         opn = "macc";
1.1.1.7 ! root     2076:         break;
1.1.1.6   root     2077:     case OPC_VR54XX_MACCU:
1.1.1.7 ! root     2078:         gen_helper_maccu(t0, t0, t1);
1.1.1.6   root     2079:         opn = "maccu";
1.1.1.7 ! root     2080:         break;
1.1.1.6   root     2081:     case OPC_VR54XX_MSAC:
1.1.1.7 ! root     2082:         gen_helper_msac(t0, t0, t1);
1.1.1.6   root     2083:         opn = "msac";
1.1.1.7 ! root     2084:         break;
1.1.1.6   root     2085:     case OPC_VR54XX_MSACU:
1.1.1.7 ! root     2086:         gen_helper_msacu(t0, t0, t1);
1.1.1.6   root     2087:         opn = "msacu";
1.1.1.7 ! root     2088:         break;
1.1.1.6   root     2089:     case OPC_VR54XX_MULHI:
1.1.1.7 ! root     2090:         gen_helper_mulhi(t0, t0, t1);
1.1.1.6   root     2091:         opn = "mulhi";
1.1.1.7 ! root     2092:         break;
1.1.1.6   root     2093:     case OPC_VR54XX_MULHIU:
1.1.1.7 ! root     2094:         gen_helper_mulhiu(t0, t0, t1);
1.1.1.6   root     2095:         opn = "mulhiu";
1.1.1.7 ! root     2096:         break;
1.1.1.6   root     2097:     case OPC_VR54XX_MULSHI:
1.1.1.7 ! root     2098:         gen_helper_mulshi(t0, t0, t1);
1.1.1.6   root     2099:         opn = "mulshi";
1.1.1.7 ! root     2100:         break;
1.1.1.6   root     2101:     case OPC_VR54XX_MULSHIU:
1.1.1.7 ! root     2102:         gen_helper_mulshiu(t0, t0, t1);
1.1.1.6   root     2103:         opn = "mulshiu";
1.1.1.7 ! root     2104:         break;
1.1.1.6   root     2105:     case OPC_VR54XX_MACCHI:
1.1.1.7 ! root     2106:         gen_helper_macchi(t0, t0, t1);
1.1.1.6   root     2107:         opn = "macchi";
1.1.1.7 ! root     2108:         break;
1.1.1.6   root     2109:     case OPC_VR54XX_MACCHIU:
1.1.1.7 ! root     2110:         gen_helper_macchiu(t0, t0, t1);
1.1.1.6   root     2111:         opn = "macchiu";
1.1.1.7 ! root     2112:         break;
1.1.1.6   root     2113:     case OPC_VR54XX_MSACHI:
1.1.1.7 ! root     2114:         gen_helper_msachi(t0, t0, t1);
1.1.1.6   root     2115:         opn = "msachi";
1.1.1.7 ! root     2116:         break;
1.1.1.6   root     2117:     case OPC_VR54XX_MSACHIU:
1.1.1.7 ! root     2118:         gen_helper_msachiu(t0, t0, t1);
1.1.1.6   root     2119:         opn = "msachiu";
1.1.1.7 ! root     2120:         break;
1.1.1.6   root     2121:     default:
                   2122:         MIPS_INVAL("mul vr54xx");
                   2123:         generate_exception(ctx, EXCP_RI);
1.1.1.7 ! root     2124:         goto out;
1.1.1.6   root     2125:     }
1.1.1.7 ! root     2126:     gen_store_gpr(t0, rd);
1.1.1.6   root     2127:     MIPS_DEBUG("%s %s, %s, %s", opn, regnames[rd], regnames[rs], regnames[rt]);
1.1.1.7 ! root     2128: 
        !          2129:  out:
        !          2130:     tcg_temp_free(t0);
        !          2131:     tcg_temp_free(t1);
1.1.1.6   root     2132: }
                   2133: 
1.1.1.5   root     2134: static void gen_cl (DisasContext *ctx, uint32_t opc,
1.1       root     2135:                     int rd, int rs)
                   2136: {
1.1.1.6   root     2137:     const char *opn = "CLx";
1.1.1.7 ! root     2138:     TCGv t0 = tcg_temp_local_new();
        !          2139: 
1.1       root     2140:     if (rd == 0) {
1.1.1.6   root     2141:         /* Treat as NOP. */
1.1       root     2142:         MIPS_DEBUG("NOP");
1.1.1.7 ! root     2143:         goto out;
1.1       root     2144:     }
1.1.1.7 ! root     2145:     gen_load_gpr(t0, rs);
1.1       root     2146:     switch (opc) {
                   2147:     case OPC_CLO:
1.1.1.7 ! root     2148:         gen_helper_clo(t0, t0);
1.1       root     2149:         opn = "clo";
                   2150:         break;
                   2151:     case OPC_CLZ:
1.1.1.7 ! root     2152:         gen_helper_clz(t0, t0);
1.1       root     2153:         opn = "clz";
                   2154:         break;
1.1.1.6   root     2155: #if defined(TARGET_MIPS64)
1.1.1.5   root     2156:     case OPC_DCLO:
1.1.1.7 ! root     2157:         gen_helper_dclo(t0, t0);
1.1.1.5   root     2158:         opn = "dclo";
                   2159:         break;
                   2160:     case OPC_DCLZ:
1.1.1.7 ! root     2161:         gen_helper_dclz(t0, t0);
1.1.1.5   root     2162:         opn = "dclz";
                   2163:         break;
                   2164: #endif
1.1       root     2165:     default:
1.1.1.6   root     2166:         MIPS_INVAL(opn);
1.1       root     2167:         generate_exception(ctx, EXCP_RI);
1.1.1.7 ! root     2168:         goto out;
1.1       root     2169:     }
1.1.1.7 ! root     2170:     gen_store_gpr(t0, rd);
1.1       root     2171:     MIPS_DEBUG("%s %s, %s", opn, regnames[rd], regnames[rs]);
1.1.1.7 ! root     2172: 
        !          2173:  out:
        !          2174:     tcg_temp_free(t0);
1.1       root     2175: }
                   2176: 
                   2177: /* Traps */
1.1.1.5   root     2178: static void gen_trap (DisasContext *ctx, uint32_t opc,
1.1       root     2179:                       int rs, int rt, int16_t imm)
                   2180: {
                   2181:     int cond;
1.1.1.7 ! root     2182:     TCGv t0 = tcg_temp_local_new();
        !          2183:     TCGv t1 = tcg_temp_local_new();
1.1       root     2184: 
                   2185:     cond = 0;
                   2186:     /* Load needed operands */
                   2187:     switch (opc) {
                   2188:     case OPC_TEQ:
                   2189:     case OPC_TGE:
                   2190:     case OPC_TGEU:
                   2191:     case OPC_TLT:
                   2192:     case OPC_TLTU:
                   2193:     case OPC_TNE:
                   2194:         /* Compare two registers */
                   2195:         if (rs != rt) {
1.1.1.7 ! root     2196:             gen_load_gpr(t0, rs);
        !          2197:             gen_load_gpr(t1, rt);
1.1       root     2198:             cond = 1;
                   2199:         }
1.1.1.5   root     2200:         break;
1.1       root     2201:     case OPC_TEQI:
                   2202:     case OPC_TGEI:
                   2203:     case OPC_TGEIU:
                   2204:     case OPC_TLTI:
                   2205:     case OPC_TLTIU:
                   2206:     case OPC_TNEI:
                   2207:         /* Compare register to immediate */
                   2208:         if (rs != 0 || imm != 0) {
1.1.1.7 ! root     2209:             gen_load_gpr(t0, rs);
        !          2210:             tcg_gen_movi_tl(t1, (int32_t)imm);
1.1       root     2211:             cond = 1;
                   2212:         }
                   2213:         break;
                   2214:     }
                   2215:     if (cond == 0) {
                   2216:         switch (opc) {
                   2217:         case OPC_TEQ:   /* rs == rs */
                   2218:         case OPC_TEQI:  /* r0 == 0  */
                   2219:         case OPC_TGE:   /* rs >= rs */
                   2220:         case OPC_TGEI:  /* r0 >= 0  */
                   2221:         case OPC_TGEU:  /* rs >= rs unsigned */
                   2222:         case OPC_TGEIU: /* r0 >= 0  unsigned */
                   2223:             /* Always trap */
1.1.1.7 ! root     2224:             tcg_gen_movi_tl(t0, 1);
1.1       root     2225:             break;
                   2226:         case OPC_TLT:   /* rs < rs           */
                   2227:         case OPC_TLTI:  /* r0 < 0            */
                   2228:         case OPC_TLTU:  /* rs < rs unsigned  */
                   2229:         case OPC_TLTIU: /* r0 < 0  unsigned  */
                   2230:         case OPC_TNE:   /* rs != rs          */
                   2231:         case OPC_TNEI:  /* r0 != 0           */
1.1.1.6   root     2232:             /* Never trap: treat as NOP. */
1.1.1.7 ! root     2233:             goto out;
1.1       root     2234:         default:
1.1.1.6   root     2235:             MIPS_INVAL("trap");
1.1       root     2236:             generate_exception(ctx, EXCP_RI);
1.1.1.7 ! root     2237:             goto out;
1.1       root     2238:         }
                   2239:     } else {
                   2240:         switch (opc) {
                   2241:         case OPC_TEQ:
                   2242:         case OPC_TEQI:
1.1.1.7 ! root     2243:             gen_op_eq(t0, t1);
1.1       root     2244:             break;
                   2245:         case OPC_TGE:
                   2246:         case OPC_TGEI:
1.1.1.7 ! root     2247:             gen_op_ge(t0, t1);
1.1       root     2248:             break;
                   2249:         case OPC_TGEU:
                   2250:         case OPC_TGEIU:
1.1.1.7 ! root     2251:             gen_op_geu(t0, t1);
1.1       root     2252:             break;
                   2253:         case OPC_TLT:
                   2254:         case OPC_TLTI:
1.1.1.7 ! root     2255:             gen_op_lt(t0, t1);
1.1       root     2256:             break;
                   2257:         case OPC_TLTU:
                   2258:         case OPC_TLTIU:
1.1.1.7 ! root     2259:             gen_op_ltu(t0, t1);
1.1       root     2260:             break;
                   2261:         case OPC_TNE:
                   2262:         case OPC_TNEI:
1.1.1.7 ! root     2263:             gen_op_ne(t0, t1);
1.1       root     2264:             break;
                   2265:         default:
1.1.1.6   root     2266:             MIPS_INVAL("trap");
1.1       root     2267:             generate_exception(ctx, EXCP_RI);
1.1.1.7 ! root     2268:             goto out;
1.1       root     2269:         }
                   2270:     }
                   2271:     save_cpu_state(ctx, 1);
1.1.1.7 ! root     2272:     {
        !          2273:         int l1 = gen_new_label();
        !          2274: 
        !          2275:         tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
        !          2276:         gen_helper_0i(raise_exception, EXCP_TRAP);
        !          2277:         gen_set_label(l1);
        !          2278:     }
1.1       root     2279:     ctx->bstate = BS_STOP;
1.1.1.7 ! root     2280:  out:
        !          2281:     tcg_temp_free(t0);
        !          2282:     tcg_temp_free(t1);
1.1       root     2283: }
                   2284: 
1.1.1.7 ! root     2285: static inline void gen_goto_tb(DisasContext *ctx, int n, target_ulong dest)
1.1.1.2   root     2286: {
                   2287:     TranslationBlock *tb;
                   2288:     tb = ctx->tb;
                   2289:     if ((tb->pc & TARGET_PAGE_MASK) == (dest & TARGET_PAGE_MASK)) {
1.1.1.7 ! root     2290:         tcg_gen_goto_tb(n);
1.1.1.6   root     2291:         gen_save_pc(dest);
1.1.1.7 ! root     2292:         tcg_gen_exit_tb((long)tb + n);
1.1.1.2   root     2293:     } else {
1.1.1.6   root     2294:         gen_save_pc(dest);
1.1.1.7 ! root     2295:         tcg_gen_exit_tb(0);
1.1.1.2   root     2296:     }
                   2297: }
                   2298: 
1.1       root     2299: /* Branches (before delay slot) */
1.1.1.5   root     2300: static void gen_compute_branch (DisasContext *ctx, uint32_t opc,
1.1       root     2301:                                 int rs, int rt, int32_t offset)
                   2302: {
1.1.1.7 ! root     2303:     target_ulong btgt = -1;
1.1.1.6   root     2304:     int blink = 0;
1.1.1.7 ! root     2305:     int bcond_compute = 0;
        !          2306:     TCGv t0 = tcg_temp_local_new();
        !          2307:     TCGv t1 = tcg_temp_local_new();
1.1       root     2308: 
1.1.1.6   root     2309:     if (ctx->hflags & MIPS_HFLAG_BMASK) {
                   2310: #ifdef MIPS_DEBUG_DISAS
1.1.1.7 ! root     2311:         LOG_DISAS("Branch in delay slot at PC 0x" TARGET_FMT_lx "\n", ctx->pc);
1.1.1.6   root     2312: #endif
                   2313:         generate_exception(ctx, EXCP_RI);
1.1.1.7 ! root     2314:         goto out;
1.1.1.6   root     2315:     }
                   2316: 
                   2317:     /* Load needed operands */
                   2318:     switch (opc) {
                   2319:     case OPC_BEQ:
                   2320:     case OPC_BEQL:
                   2321:     case OPC_BNE:
                   2322:     case OPC_BNEL:
1.1       root     2323:         /* Compare two registers */
                   2324:         if (rs != rt) {
1.1.1.7 ! root     2325:             gen_load_gpr(t0, rs);
        !          2326:             gen_load_gpr(t1, rt);
        !          2327:             bcond_compute = 1;
1.1       root     2328:         }
1.1.1.7 ! root     2329:         btgt = ctx->pc + 4 + offset;
1.1       root     2330:         break;
                   2331:     case OPC_BGEZ:
                   2332:     case OPC_BGEZAL:
                   2333:     case OPC_BGEZALL:
                   2334:     case OPC_BGEZL:
                   2335:     case OPC_BGTZ:
                   2336:     case OPC_BGTZL:
                   2337:     case OPC_BLEZ:
                   2338:     case OPC_BLEZL:
                   2339:     case OPC_BLTZ:
                   2340:     case OPC_BLTZAL:
                   2341:     case OPC_BLTZALL:
                   2342:     case OPC_BLTZL:
                   2343:         /* Compare to zero */
                   2344:         if (rs != 0) {
1.1.1.7 ! root     2345:             gen_load_gpr(t0, rs);
        !          2346:             bcond_compute = 1;
1.1       root     2347:         }
1.1.1.7 ! root     2348:         btgt = ctx->pc + 4 + offset;
1.1       root     2349:         break;
                   2350:     case OPC_J:
                   2351:     case OPC_JAL:
                   2352:         /* Jump to immediate */
1.1.1.7 ! root     2353:         btgt = ((ctx->pc + 4) & (int32_t)0xF0000000) | (uint32_t)offset;
1.1       root     2354:         break;
                   2355:     case OPC_JR:
                   2356:     case OPC_JALR:
                   2357:         /* Jump to register */
1.1.1.5   root     2358:         if (offset != 0 && offset != 16) {
                   2359:             /* Hint = 0 is JR/JALR, hint 16 is JR.HB/JALR.HB, the
1.1.1.6   root     2360:                others are reserved. */
                   2361:             MIPS_INVAL("jump hint");
1.1       root     2362:             generate_exception(ctx, EXCP_RI);
1.1.1.7 ! root     2363:             goto out;
1.1       root     2364:         }
1.1.1.7 ! root     2365:         gen_load_gpr(btarget, rs);
1.1       root     2366:         break;
                   2367:     default:
                   2368:         MIPS_INVAL("branch/jump");
                   2369:         generate_exception(ctx, EXCP_RI);
1.1.1.7 ! root     2370:         goto out;
1.1       root     2371:     }
1.1.1.7 ! root     2372:     if (bcond_compute == 0) {
1.1       root     2373:         /* No condition to be computed */
                   2374:         switch (opc) {
                   2375:         case OPC_BEQ:     /* rx == rx        */
                   2376:         case OPC_BEQL:    /* rx == rx likely */
                   2377:         case OPC_BGEZ:    /* 0 >= 0          */
                   2378:         case OPC_BGEZL:   /* 0 >= 0 likely   */
                   2379:         case OPC_BLEZ:    /* 0 <= 0          */
                   2380:         case OPC_BLEZL:   /* 0 <= 0 likely   */
                   2381:             /* Always take */
1.1.1.2   root     2382:             ctx->hflags |= MIPS_HFLAG_B;
1.1       root     2383:             MIPS_DEBUG("balways");
                   2384:             break;
                   2385:         case OPC_BGEZAL:  /* 0 >= 0          */
                   2386:         case OPC_BGEZALL: /* 0 >= 0 likely   */
                   2387:             /* Always take and link */
                   2388:             blink = 31;
1.1.1.2   root     2389:             ctx->hflags |= MIPS_HFLAG_B;
1.1       root     2390:             MIPS_DEBUG("balways and link");
                   2391:             break;
                   2392:         case OPC_BNE:     /* rx != rx        */
                   2393:         case OPC_BGTZ:    /* 0 > 0           */
                   2394:         case OPC_BLTZ:    /* 0 < 0           */
1.1.1.6   root     2395:             /* Treat as NOP. */
1.1       root     2396:             MIPS_DEBUG("bnever (NOP)");
1.1.1.7 ! root     2397:             goto out;
1.1.1.2   root     2398:         case OPC_BLTZAL:  /* 0 < 0           */
1.1.1.7 ! root     2399:             tcg_gen_movi_tl(t0, ctx->pc + 8);
        !          2400:             gen_store_gpr(t0, 31);
1.1.1.6   root     2401:             MIPS_DEBUG("bnever and link");
1.1.1.7 ! root     2402:             goto out;
1.1.1.2   root     2403:         case OPC_BLTZALL: /* 0 < 0 likely */
1.1.1.7 ! root     2404:             tcg_gen_movi_tl(t0, ctx->pc + 8);
        !          2405:             gen_store_gpr(t0, 31);
1.1.1.6   root     2406:             /* Skip the instruction in the delay slot */
                   2407:             MIPS_DEBUG("bnever, link and skip");
                   2408:             ctx->pc += 4;
1.1.1.7 ! root     2409:             goto out;
1.1       root     2410:         case OPC_BNEL:    /* rx != rx likely */
                   2411:         case OPC_BGTZL:   /* 0 > 0 likely */
                   2412:         case OPC_BLTZL:   /* 0 < 0 likely */
                   2413:             /* Skip the instruction in the delay slot */
                   2414:             MIPS_DEBUG("bnever and skip");
1.1.1.6   root     2415:             ctx->pc += 4;
1.1.1.7 ! root     2416:             goto out;
1.1       root     2417:         case OPC_J:
1.1.1.2   root     2418:             ctx->hflags |= MIPS_HFLAG_B;
1.1.1.7 ! root     2419:             MIPS_DEBUG("j " TARGET_FMT_lx, btgt);
1.1       root     2420:             break;
                   2421:         case OPC_JAL:
                   2422:             blink = 31;
1.1.1.2   root     2423:             ctx->hflags |= MIPS_HFLAG_B;
1.1.1.7 ! root     2424:             MIPS_DEBUG("jal " TARGET_FMT_lx, btgt);
1.1       root     2425:             break;
                   2426:         case OPC_JR:
1.1.1.2   root     2427:             ctx->hflags |= MIPS_HFLAG_BR;
1.1       root     2428:             MIPS_DEBUG("jr %s", regnames[rs]);
                   2429:             break;
                   2430:         case OPC_JALR:
                   2431:             blink = rt;
1.1.1.2   root     2432:             ctx->hflags |= MIPS_HFLAG_BR;
1.1       root     2433:             MIPS_DEBUG("jalr %s, %s", regnames[rt], regnames[rs]);
                   2434:             break;
                   2435:         default:
                   2436:             MIPS_INVAL("branch/jump");
                   2437:             generate_exception(ctx, EXCP_RI);
1.1.1.7 ! root     2438:             goto out;
1.1       root     2439:         }
                   2440:     } else {
                   2441:         switch (opc) {
                   2442:         case OPC_BEQ:
1.1.1.7 ! root     2443:             gen_op_eq(t0, t1);
1.1.1.6   root     2444:             MIPS_DEBUG("beq %s, %s, " TARGET_FMT_lx,
1.1.1.7 ! root     2445:                        regnames[rs], regnames[rt], btgt);
1.1       root     2446:             goto not_likely;
                   2447:         case OPC_BEQL:
1.1.1.7 ! root     2448:             gen_op_eq(t0, t1);
1.1.1.6   root     2449:             MIPS_DEBUG("beql %s, %s, " TARGET_FMT_lx,
1.1.1.7 ! root     2450:                        regnames[rs], regnames[rt], btgt);
1.1       root     2451:             goto likely;
                   2452:         case OPC_BNE:
1.1.1.7 ! root     2453:             gen_op_ne(t0, t1);
1.1.1.6   root     2454:             MIPS_DEBUG("bne %s, %s, " TARGET_FMT_lx,
1.1.1.7 ! root     2455:                        regnames[rs], regnames[rt], btgt);
1.1       root     2456:             goto not_likely;
                   2457:         case OPC_BNEL:
1.1.1.7 ! root     2458:             gen_op_ne(t0, t1);
1.1.1.6   root     2459:             MIPS_DEBUG("bnel %s, %s, " TARGET_FMT_lx,
1.1.1.7 ! root     2460:                        regnames[rs], regnames[rt], btgt);
1.1       root     2461:             goto likely;
                   2462:         case OPC_BGEZ:
1.1.1.7 ! root     2463:             gen_op_gez(t0);
        !          2464:             MIPS_DEBUG("bgez %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2465:             goto not_likely;
                   2466:         case OPC_BGEZL:
1.1.1.7 ! root     2467:             gen_op_gez(t0);
        !          2468:             MIPS_DEBUG("bgezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2469:             goto likely;
                   2470:         case OPC_BGEZAL:
1.1.1.7 ! root     2471:             gen_op_gez(t0);
        !          2472:             MIPS_DEBUG("bgezal %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2473:             blink = 31;
                   2474:             goto not_likely;
                   2475:         case OPC_BGEZALL:
1.1.1.7 ! root     2476:             gen_op_gez(t0);
1.1       root     2477:             blink = 31;
1.1.1.7 ! root     2478:             MIPS_DEBUG("bgezall %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2479:             goto likely;
                   2480:         case OPC_BGTZ:
1.1.1.7 ! root     2481:             gen_op_gtz(t0);
        !          2482:             MIPS_DEBUG("bgtz %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2483:             goto not_likely;
                   2484:         case OPC_BGTZL:
1.1.1.7 ! root     2485:             gen_op_gtz(t0);
        !          2486:             MIPS_DEBUG("bgtzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2487:             goto likely;
                   2488:         case OPC_BLEZ:
1.1.1.7 ! root     2489:             gen_op_lez(t0);
        !          2490:             MIPS_DEBUG("blez %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2491:             goto not_likely;
                   2492:         case OPC_BLEZL:
1.1.1.7 ! root     2493:             gen_op_lez(t0);
        !          2494:             MIPS_DEBUG("blezl %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2495:             goto likely;
                   2496:         case OPC_BLTZ:
1.1.1.7 ! root     2497:             gen_op_ltz(t0);
        !          2498:             MIPS_DEBUG("bltz %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2499:             goto not_likely;
                   2500:         case OPC_BLTZL:
1.1.1.7 ! root     2501:             gen_op_ltz(t0);
        !          2502:             MIPS_DEBUG("bltzl %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2503:             goto likely;
                   2504:         case OPC_BLTZAL:
1.1.1.7 ! root     2505:             gen_op_ltz(t0);
1.1       root     2506:             blink = 31;
1.1.1.7 ! root     2507:             MIPS_DEBUG("bltzal %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2508:         not_likely:
1.1.1.2   root     2509:             ctx->hflags |= MIPS_HFLAG_BC;
1.1.1.7 ! root     2510:             tcg_gen_trunc_tl_i32(bcond, t0);
1.1       root     2511:             break;
                   2512:         case OPC_BLTZALL:
1.1.1.7 ! root     2513:             gen_op_ltz(t0);
1.1       root     2514:             blink = 31;
1.1.1.7 ! root     2515:             MIPS_DEBUG("bltzall %s, " TARGET_FMT_lx, regnames[rs], btgt);
1.1       root     2516:         likely:
1.1.1.2   root     2517:             ctx->hflags |= MIPS_HFLAG_BL;
1.1.1.7 ! root     2518:             tcg_gen_trunc_tl_i32(bcond, t0);
1.1       root     2519:             break;
1.1.1.6   root     2520:         default:
                   2521:             MIPS_INVAL("conditional branch/jump");
                   2522:             generate_exception(ctx, EXCP_RI);
1.1.1.7 ! root     2523:             goto out;
1.1       root     2524:         }
                   2525:     }
1.1.1.6   root     2526:     MIPS_DEBUG("enter ds: link %d cond %02x target " TARGET_FMT_lx,
1.1.1.7 ! root     2527:                blink, ctx->hflags, btgt);
1.1.1.6   root     2528: 
1.1.1.7 ! root     2529:     ctx->btarget = btgt;
1.1       root     2530:     if (blink > 0) {
1.1.1.7 ! root     2531:         tcg_gen_movi_tl(t0, ctx->pc + 8);
        !          2532:         gen_store_gpr(t0, blink);
1.1       root     2533:     }
1.1.1.7 ! root     2534: 
        !          2535:  out:
        !          2536:     tcg_temp_free(t0);
        !          2537:     tcg_temp_free(t1);
1.1       root     2538: }
                   2539: 
1.1.1.5   root     2540: /* special3 bitfield operations */
                   2541: static void gen_bitops (DisasContext *ctx, uint32_t opc, int rt,
1.1.1.7 ! root     2542:                         int rs, int lsb, int msb)
1.1       root     2543: {
1.1.1.7 ! root     2544:     TCGv t0 = tcg_temp_new();
        !          2545:     TCGv t1 = tcg_temp_new();
        !          2546:     target_ulong mask;
        !          2547: 
        !          2548:     gen_load_gpr(t1, rs);
1.1.1.5   root     2549:     switch (opc) {
                   2550:     case OPC_EXT:
                   2551:         if (lsb + msb > 31)
                   2552:             goto fail;
1.1.1.7 ! root     2553:         tcg_gen_shri_tl(t0, t1, lsb);
        !          2554:         if (msb != 31) {
        !          2555:             tcg_gen_andi_tl(t0, t0, (1 << (msb + 1)) - 1);
        !          2556:         } else {
        !          2557:             tcg_gen_ext32s_tl(t0, t0);
        !          2558:         }
1.1.1.5   root     2559:         break;
1.1.1.6   root     2560: #if defined(TARGET_MIPS64)
1.1.1.5   root     2561:     case OPC_DEXTM:
1.1.1.7 ! root     2562:         tcg_gen_shri_tl(t0, t1, lsb);
        !          2563:         if (msb != 31) {
        !          2564:             tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1 + 32)) - 1);
        !          2565:         }
1.1.1.5   root     2566:         break;
                   2567:     case OPC_DEXTU:
1.1.1.7 ! root     2568:         tcg_gen_shri_tl(t0, t1, lsb + 32);
        !          2569:         tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
1.1.1.5   root     2570:         break;
                   2571:     case OPC_DEXT:
1.1.1.7 ! root     2572:         tcg_gen_shri_tl(t0, t1, lsb);
        !          2573:         tcg_gen_andi_tl(t0, t0, (1ULL << (msb + 1)) - 1);
1.1.1.5   root     2574:         break;
1.1.1.6   root     2575: #endif
1.1.1.5   root     2576:     case OPC_INS:
                   2577:         if (lsb > msb)
                   2578:             goto fail;
1.1.1.7 ! root     2579:         mask = ((msb - lsb + 1 < 32) ? ((1 << (msb - lsb + 1)) - 1) : ~0) << lsb;
        !          2580:         gen_load_gpr(t0, rt);
        !          2581:         tcg_gen_andi_tl(t0, t0, ~mask);
        !          2582:         tcg_gen_shli_tl(t1, t1, lsb);
        !          2583:         tcg_gen_andi_tl(t1, t1, mask);
        !          2584:         tcg_gen_or_tl(t0, t0, t1);
        !          2585:         tcg_gen_ext32s_tl(t0, t0);
1.1.1.5   root     2586:         break;
1.1.1.6   root     2587: #if defined(TARGET_MIPS64)
1.1.1.5   root     2588:     case OPC_DINSM:
                   2589:         if (lsb > msb)
                   2590:             goto fail;
1.1.1.7 ! root     2591:         mask = ((msb - lsb + 1 + 32 < 64) ? ((1ULL << (msb - lsb + 1 + 32)) - 1) : ~0ULL) << lsb;
        !          2592:         gen_load_gpr(t0, rt);
        !          2593:         tcg_gen_andi_tl(t0, t0, ~mask);
        !          2594:         tcg_gen_shli_tl(t1, t1, lsb);
        !          2595:         tcg_gen_andi_tl(t1, t1, mask);
        !          2596:         tcg_gen_or_tl(t0, t0, t1);
1.1.1.5   root     2597:         break;
                   2598:     case OPC_DINSU:
                   2599:         if (lsb > msb)
                   2600:             goto fail;
1.1.1.7 ! root     2601:         mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
        !          2602:         gen_load_gpr(t0, rt);
        !          2603:         tcg_gen_andi_tl(t0, t0, ~mask);
        !          2604:         tcg_gen_shli_tl(t1, t1, lsb + 32);
        !          2605:         tcg_gen_andi_tl(t1, t1, mask);
        !          2606:         tcg_gen_or_tl(t0, t0, t1);
1.1.1.5   root     2607:         break;
                   2608:     case OPC_DINS:
                   2609:         if (lsb > msb)
                   2610:             goto fail;
1.1.1.7 ! root     2611:         gen_load_gpr(t0, rt);
        !          2612:         mask = ((1ULL << (msb - lsb + 1)) - 1) << lsb;
        !          2613:         gen_load_gpr(t0, rt);
        !          2614:         tcg_gen_andi_tl(t0, t0, ~mask);
        !          2615:         tcg_gen_shli_tl(t1, t1, lsb);
        !          2616:         tcg_gen_andi_tl(t1, t1, mask);
        !          2617:         tcg_gen_or_tl(t0, t0, t1);
1.1.1.5   root     2618:         break;
1.1.1.6   root     2619: #endif
1.1.1.5   root     2620:     default:
                   2621: fail:
                   2622:         MIPS_INVAL("bitops");
                   2623:         generate_exception(ctx, EXCP_RI);
1.1.1.7 ! root     2624:         tcg_temp_free(t0);
        !          2625:         tcg_temp_free(t1);
1.1       root     2626:         return;
                   2627:     }
1.1.1.7 ! root     2628:     gen_store_gpr(t0, rt);
        !          2629:     tcg_temp_free(t0);
        !          2630:     tcg_temp_free(t1);
        !          2631: }
        !          2632: 
        !          2633: static void gen_bshfl (DisasContext *ctx, uint32_t op2, int rt, int rd)
        !          2634: {
        !          2635:     TCGv t0 = tcg_temp_new();
        !          2636:     TCGv t1 = tcg_temp_new();
        !          2637: 
        !          2638:     gen_load_gpr(t1, rt);
        !          2639:     switch (op2) {
        !          2640:     case OPC_WSBH:
        !          2641:         tcg_gen_shri_tl(t0, t1, 8);
        !          2642:         tcg_gen_andi_tl(t0, t0, 0x00FF00FF);
        !          2643:         tcg_gen_shli_tl(t1, t1, 8);
        !          2644:         tcg_gen_andi_tl(t1, t1, ~0x00FF00FF);
        !          2645:         tcg_gen_or_tl(t0, t0, t1);
        !          2646:         tcg_gen_ext32s_tl(t0, t0);
        !          2647:         break;
        !          2648:     case OPC_SEB:
        !          2649:         tcg_gen_ext8s_tl(t0, t1);
        !          2650:         break;
        !          2651:     case OPC_SEH:
        !          2652:         tcg_gen_ext16s_tl(t0, t1);
        !          2653:         break;
        !          2654: #if defined(TARGET_MIPS64)
        !          2655:     case OPC_DSBH:
        !          2656:         gen_load_gpr(t1, rt);
        !          2657:         tcg_gen_shri_tl(t0, t1, 8);
        !          2658:         tcg_gen_andi_tl(t0, t0, 0x00FF00FF00FF00FFULL);
        !          2659:         tcg_gen_shli_tl(t1, t1, 8);
        !          2660:         tcg_gen_andi_tl(t1, t1, ~0x00FF00FF00FF00FFULL);
        !          2661:         tcg_gen_or_tl(t0, t0, t1);
        !          2662:         break;
        !          2663:     case OPC_DSHD:
        !          2664:         gen_load_gpr(t1, rt);
        !          2665:         tcg_gen_shri_tl(t0, t1, 16);
        !          2666:         tcg_gen_andi_tl(t0, t0, 0x0000FFFF0000FFFFULL);
        !          2667:         tcg_gen_shli_tl(t1, t1, 16);
        !          2668:         tcg_gen_andi_tl(t1, t1, ~0x0000FFFF0000FFFFULL);
        !          2669:         tcg_gen_or_tl(t1, t0, t1);
        !          2670:         tcg_gen_shri_tl(t0, t1, 32);
        !          2671:         tcg_gen_shli_tl(t1, t1, 32);
        !          2672:         tcg_gen_or_tl(t0, t0, t1);
        !          2673:         break;
        !          2674: #endif
        !          2675:     default:
        !          2676:         MIPS_INVAL("bsfhl");
        !          2677:         generate_exception(ctx, EXCP_RI);
        !          2678:         tcg_temp_free(t0);
        !          2679:         tcg_temp_free(t1);
        !          2680:         return;
        !          2681:     }
        !          2682:     gen_store_gpr(t0, rd);
        !          2683:     tcg_temp_free(t0);
        !          2684:     tcg_temp_free(t1);
1.1.1.5   root     2685: }
1.1.1.4   root     2686: 
1.1.1.7 ! root     2687: #ifndef CONFIG_USER_ONLY
1.1.1.5   root     2688: /* CP0 (MMU and control) */
1.1.1.7 ! root     2689: static inline void gen_mfc0_load32 (TCGv t, target_ulong off)
        !          2690: {
        !          2691:     TCGv_i32 r_tmp = tcg_temp_new_i32();
        !          2692: 
        !          2693:     tcg_gen_ld_i32(r_tmp, cpu_env, off);
        !          2694:     tcg_gen_ext_i32_tl(t, r_tmp);
        !          2695:     tcg_temp_free_i32(r_tmp);
        !          2696: }
        !          2697: 
        !          2698: static inline void gen_mfc0_load64 (TCGv t, target_ulong off)
        !          2699: {
        !          2700:     tcg_gen_ld_tl(t, cpu_env, off);
        !          2701:     tcg_gen_ext32s_tl(t, t);
        !          2702: }
        !          2703: 
        !          2704: static inline void gen_mtc0_store32 (TCGv t, target_ulong off)
        !          2705: {
        !          2706:     TCGv_i32 r_tmp = tcg_temp_new_i32();
        !          2707: 
        !          2708:     tcg_gen_trunc_tl_i32(r_tmp, t);
        !          2709:     tcg_gen_st_i32(r_tmp, cpu_env, off);
        !          2710:     tcg_temp_free_i32(r_tmp);
        !          2711: }
        !          2712: 
        !          2713: static inline void gen_mtc0_store64 (TCGv t, target_ulong off)
        !          2714: {
        !          2715:     tcg_gen_ext32s_tl(t, t);
        !          2716:     tcg_gen_st_tl(t, cpu_env, off);
        !          2717: }
        !          2718: 
        !          2719: static void gen_mfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
1.1.1.5   root     2720: {
                   2721:     const char *rn = "invalid";
                   2722: 
1.1.1.6   root     2723:     if (sel != 0)
                   2724:         check_insn(env, ctx, ISA_MIPS32);
                   2725: 
1.1.1.5   root     2726:     switch (reg) {
                   2727:     case 0:
                   2728:         switch (sel) {
                   2729:         case 0:
1.1.1.7 ! root     2730:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_Index));
1.1.1.5   root     2731:             rn = "Index";
                   2732:             break;
                   2733:         case 1:
1.1.1.6   root     2734:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     2735:             gen_helper_mfc0_mvpcontrol(t0);
1.1.1.5   root     2736:             rn = "MVPControl";
1.1.1.6   root     2737:             break;
1.1.1.5   root     2738:         case 2:
1.1.1.6   root     2739:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     2740:             gen_helper_mfc0_mvpconf0(t0);
1.1.1.5   root     2741:             rn = "MVPConf0";
1.1.1.6   root     2742:             break;
1.1.1.5   root     2743:         case 3:
1.1.1.6   root     2744:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     2745:             gen_helper_mfc0_mvpconf1(t0);
1.1.1.5   root     2746:             rn = "MVPConf1";
1.1.1.6   root     2747:             break;
1.1.1.5   root     2748:         default:
                   2749:             goto die;
1.1       root     2750:         }
                   2751:         break;
1.1.1.5   root     2752:     case 1:
                   2753:         switch (sel) {
                   2754:         case 0:
1.1.1.7 ! root     2755:             gen_helper_mfc0_random(t0);
1.1.1.5   root     2756:             rn = "Random";
1.1.1.6   root     2757:             break;
1.1.1.5   root     2758:         case 1:
1.1.1.6   root     2759:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     2760:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEControl));
1.1.1.5   root     2761:             rn = "VPEControl";
1.1.1.6   root     2762:             break;
1.1.1.5   root     2763:         case 2:
1.1.1.6   root     2764:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     2765:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf0));
1.1.1.5   root     2766:             rn = "VPEConf0";
1.1.1.6   root     2767:             break;
1.1.1.5   root     2768:         case 3:
1.1.1.6   root     2769:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     2770:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf1));
1.1.1.5   root     2771:             rn = "VPEConf1";
1.1.1.6   root     2772:             break;
1.1.1.5   root     2773:         case 4:
1.1.1.6   root     2774:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     2775:             gen_mfc0_load64(t0, offsetof(CPUState, CP0_YQMask));
1.1.1.5   root     2776:             rn = "YQMask";
1.1.1.6   root     2777:             break;
1.1.1.5   root     2778:         case 5:
1.1.1.6   root     2779:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     2780:             gen_mfc0_load64(t0, offsetof(CPUState, CP0_VPESchedule));
1.1.1.5   root     2781:             rn = "VPESchedule";
1.1.1.6   root     2782:             break;
1.1.1.5   root     2783:         case 6:
1.1.1.6   root     2784:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     2785:             gen_mfc0_load64(t0, offsetof(CPUState, CP0_VPEScheFBack));
1.1.1.5   root     2786:             rn = "VPEScheFBack";
1.1.1.6   root     2787:             break;
1.1.1.5   root     2788:         case 7:
1.1.1.6   root     2789:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     2790:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEOpt));
1.1.1.5   root     2791:             rn = "VPEOpt";
1.1.1.6   root     2792:             break;
1.1.1.5   root     2793:         default:
                   2794:             goto die;
                   2795:         }
1.1       root     2796:         break;
1.1.1.5   root     2797:     case 2:
                   2798:         switch (sel) {
                   2799:         case 0:
1.1.1.7 ! root     2800:             tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo0));
        !          2801:             tcg_gen_ext32s_tl(t0, t0);
1.1.1.6   root     2802:             rn = "EntryLo0";
                   2803:             break;
                   2804:         case 1:
                   2805:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     2806:             gen_helper_mfc0_tcstatus(t0);
1.1.1.6   root     2807:             rn = "TCStatus";
                   2808:             break;
                   2809:         case 2:
                   2810:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     2811:             gen_helper_mfc0_tcbind(t0);
1.1.1.6   root     2812:             rn = "TCBind";
                   2813:             break;
1.1.1.5   root     2814:         case 3:
1.1.1.6   root     2815:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     2816:             gen_helper_mfc0_tcrestart(t0);
1.1.1.6   root     2817:             rn = "TCRestart";
                   2818:             break;
1.1.1.5   root     2819:         case 4:
1.1.1.6   root     2820:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     2821:             gen_helper_mfc0_tchalt(t0);
1.1.1.6   root     2822:             rn = "TCHalt";
                   2823:             break;
1.1.1.5   root     2824:         case 5:
1.1.1.6   root     2825:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     2826:             gen_helper_mfc0_tccontext(t0);
1.1.1.6   root     2827:             rn = "TCContext";
                   2828:             break;
1.1.1.5   root     2829:         case 6:
1.1.1.6   root     2830:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     2831:             gen_helper_mfc0_tcschedule(t0);
1.1.1.6   root     2832:             rn = "TCSchedule";
                   2833:             break;
1.1.1.5   root     2834:         case 7:
1.1.1.6   root     2835:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     2836:             gen_helper_mfc0_tcschefback(t0);
1.1.1.6   root     2837:             rn = "TCScheFBack";
                   2838:             break;
1.1.1.5   root     2839:         default:
                   2840:             goto die;
                   2841:         }
1.1       root     2842:         break;
1.1.1.5   root     2843:     case 3:
                   2844:         switch (sel) {
                   2845:         case 0:
1.1.1.7 ! root     2846:             tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo1));
        !          2847:             tcg_gen_ext32s_tl(t0, t0);
1.1.1.6   root     2848:             rn = "EntryLo1";
                   2849:             break;
1.1.1.5   root     2850:         default:
                   2851:             goto die;
1.1.1.6   root     2852:         }
1.1       root     2853:         break;
1.1.1.5   root     2854:     case 4:
                   2855:         switch (sel) {
                   2856:         case 0:
1.1.1.7 ! root     2857:             tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_Context));
        !          2858:             tcg_gen_ext32s_tl(t0, t0);
1.1.1.6   root     2859:             rn = "Context";
                   2860:             break;
                   2861:         case 1:
1.1.1.7 ! root     2862: //            gen_helper_mfc0_contextconfig(t0); /* SmartMIPS ASE */
1.1.1.6   root     2863:             rn = "ContextConfig";
                   2864: //            break;
1.1.1.5   root     2865:         default:
                   2866:             goto die;
1.1.1.6   root     2867:         }
1.1       root     2868:         break;
1.1.1.5   root     2869:     case 5:
                   2870:         switch (sel) {
                   2871:         case 0:
1.1.1.7 ! root     2872:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageMask));
1.1.1.6   root     2873:             rn = "PageMask";
                   2874:             break;
                   2875:         case 1:
                   2876:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     2877:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageGrain));
1.1.1.6   root     2878:             rn = "PageGrain";
                   2879:             break;
1.1.1.5   root     2880:         default:
                   2881:             goto die;
1.1.1.6   root     2882:         }
1.1       root     2883:         break;
1.1.1.5   root     2884:     case 6:
                   2885:         switch (sel) {
                   2886:         case 0:
1.1.1.7 ! root     2887:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_Wired));
1.1.1.6   root     2888:             rn = "Wired";
                   2889:             break;
                   2890:         case 1:
                   2891:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     2892:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf0));
1.1.1.6   root     2893:             rn = "SRSConf0";
                   2894:             break;
                   2895:         case 2:
                   2896:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     2897:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf1));
1.1.1.6   root     2898:             rn = "SRSConf1";
                   2899:             break;
1.1.1.5   root     2900:         case 3:
1.1.1.6   root     2901:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     2902:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf2));
1.1.1.6   root     2903:             rn = "SRSConf2";
                   2904:             break;
1.1.1.5   root     2905:         case 4:
1.1.1.6   root     2906:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     2907:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf3));
1.1.1.6   root     2908:             rn = "SRSConf3";
                   2909:             break;
1.1.1.5   root     2910:         case 5:
1.1.1.6   root     2911:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     2912:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf4));
1.1.1.6   root     2913:             rn = "SRSConf4";
                   2914:             break;
1.1.1.5   root     2915:         default:
                   2916:             goto die;
1.1.1.6   root     2917:         }
1.1       root     2918:         break;
1.1.1.5   root     2919:     case 7:
                   2920:         switch (sel) {
                   2921:         case 0:
1.1.1.6   root     2922:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     2923:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_HWREna));
1.1.1.6   root     2924:             rn = "HWREna";
                   2925:             break;
1.1.1.5   root     2926:         default:
                   2927:             goto die;
1.1.1.6   root     2928:         }
1.1       root     2929:         break;
1.1.1.5   root     2930:     case 8:
                   2931:         switch (sel) {
                   2932:         case 0:
1.1.1.7 ! root     2933:             tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_BadVAddr));
        !          2934:             tcg_gen_ext32s_tl(t0, t0);
        !          2935:             rn = "BadVAddr";
1.1.1.6   root     2936:             break;
1.1.1.5   root     2937:         default:
                   2938:             goto die;
                   2939:        }
1.1.1.2   root     2940:         break;
1.1.1.5   root     2941:     case 9:
                   2942:         switch (sel) {
                   2943:         case 0:
1.1.1.7 ! root     2944:             /* Mark as an IO operation because we read the time.  */
        !          2945:             if (use_icount)
        !          2946:                 gen_io_start();
        !          2947:             gen_helper_mfc0_count(t0);
        !          2948:             if (use_icount) {
        !          2949:                 gen_io_end();
        !          2950:                 ctx->bstate = BS_STOP;
        !          2951:             }
1.1.1.6   root     2952:             rn = "Count";
                   2953:             break;
                   2954:         /* 6,7 are implementation dependent */
1.1.1.5   root     2955:         default:
                   2956:             goto die;
1.1.1.6   root     2957:         }
1.1.1.5   root     2958:         break;
                   2959:     case 10:
                   2960:         switch (sel) {
                   2961:         case 0:
1.1.1.7 ! root     2962:             tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryHi));
        !          2963:             tcg_gen_ext32s_tl(t0, t0);
1.1.1.6   root     2964:             rn = "EntryHi";
                   2965:             break;
1.1.1.5   root     2966:         default:
                   2967:             goto die;
1.1.1.6   root     2968:         }
1.1.1.5   root     2969:         break;
                   2970:     case 11:
                   2971:         switch (sel) {
                   2972:         case 0:
1.1.1.7 ! root     2973:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_Compare));
1.1.1.6   root     2974:             rn = "Compare";
                   2975:             break;
                   2976:         /* 6,7 are implementation dependent */
1.1.1.5   root     2977:         default:
                   2978:             goto die;
1.1.1.6   root     2979:         }
1.1.1.5   root     2980:         break;
                   2981:     case 12:
                   2982:         switch (sel) {
                   2983:         case 0:
1.1.1.7 ! root     2984:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_Status));
1.1.1.6   root     2985:             rn = "Status";
                   2986:             break;
                   2987:         case 1:
                   2988:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     2989:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_IntCtl));
1.1.1.6   root     2990:             rn = "IntCtl";
                   2991:             break;
                   2992:         case 2:
                   2993:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     2994:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSCtl));
1.1.1.6   root     2995:             rn = "SRSCtl";
                   2996:             break;
1.1.1.5   root     2997:         case 3:
1.1.1.6   root     2998:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     2999:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSMap));
1.1.1.6   root     3000:             rn = "SRSMap";
                   3001:             break;
1.1.1.5   root     3002:         default:
                   3003:             goto die;
                   3004:        }
                   3005:         break;
                   3006:     case 13:
                   3007:         switch (sel) {
                   3008:         case 0:
1.1.1.7 ! root     3009:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_Cause));
1.1.1.6   root     3010:             rn = "Cause";
                   3011:             break;
1.1.1.5   root     3012:         default:
                   3013:             goto die;
                   3014:        }
                   3015:         break;
                   3016:     case 14:
                   3017:         switch (sel) {
                   3018:         case 0:
1.1.1.7 ! root     3019:             tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EPC));
        !          3020:             tcg_gen_ext32s_tl(t0, t0);
1.1.1.6   root     3021:             rn = "EPC";
                   3022:             break;
1.1.1.5   root     3023:         default:
                   3024:             goto die;
1.1.1.6   root     3025:         }
1.1.1.5   root     3026:         break;
                   3027:     case 15:
                   3028:         switch (sel) {
                   3029:         case 0:
1.1.1.7 ! root     3030:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_PRid));
1.1.1.6   root     3031:             rn = "PRid";
                   3032:             break;
                   3033:         case 1:
                   3034:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     3035:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_EBase));
1.1.1.6   root     3036:             rn = "EBase";
                   3037:             break;
1.1.1.5   root     3038:         default:
                   3039:             goto die;
                   3040:        }
                   3041:         break;
                   3042:     case 16:
                   3043:         switch (sel) {
                   3044:         case 0:
1.1.1.7 ! root     3045:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config0));
1.1.1.5   root     3046:             rn = "Config";
                   3047:             break;
                   3048:         case 1:
1.1.1.7 ! root     3049:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config1));
1.1.1.5   root     3050:             rn = "Config1";
                   3051:             break;
                   3052:         case 2:
1.1.1.7 ! root     3053:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config2));
1.1.1.5   root     3054:             rn = "Config2";
                   3055:             break;
                   3056:         case 3:
1.1.1.7 ! root     3057:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config3));
1.1.1.5   root     3058:             rn = "Config3";
                   3059:             break;
1.1.1.6   root     3060:         /* 4,5 are reserved */
                   3061:         /* 6,7 are implementation dependent */
                   3062:         case 6:
1.1.1.7 ! root     3063:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config6));
1.1.1.6   root     3064:             rn = "Config6";
                   3065:             break;
                   3066:         case 7:
1.1.1.7 ! root     3067:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config7));
1.1.1.6   root     3068:             rn = "Config7";
                   3069:             break;
1.1.1.5   root     3070:         default:
                   3071:             goto die;
1.1       root     3072:         }
1.1.1.4   root     3073:         break;
1.1.1.5   root     3074:     case 17:
                   3075:         switch (sel) {
                   3076:         case 0:
1.1.1.7 ! root     3077:             gen_helper_mfc0_lladdr(t0);
1.1.1.6   root     3078:             rn = "LLAddr";
                   3079:             break;
1.1.1.5   root     3080:         default:
                   3081:             goto die;
                   3082:         }
1.1.1.4   root     3083:         break;
1.1.1.5   root     3084:     case 18:
                   3085:         switch (sel) {
1.1.1.6   root     3086:         case 0 ... 7:
1.1.1.7 ! root     3087:             gen_helper_1i(mfc0_watchlo, t0, sel);
1.1.1.6   root     3088:             rn = "WatchLo";
                   3089:             break;
1.1.1.5   root     3090:         default:
                   3091:             goto die;
                   3092:         }
1.1.1.4   root     3093:         break;
1.1.1.5   root     3094:     case 19:
                   3095:         switch (sel) {
1.1.1.6   root     3096:         case 0 ...7:
1.1.1.7 ! root     3097:             gen_helper_1i(mfc0_watchhi, t0, sel);
1.1.1.6   root     3098:             rn = "WatchHi";
                   3099:             break;
1.1.1.5   root     3100:         default:
                   3101:             goto die;
                   3102:         }
1.1.1.4   root     3103:         break;
1.1.1.5   root     3104:     case 20:
                   3105:         switch (sel) {
                   3106:         case 0:
1.1.1.6   root     3107: #if defined(TARGET_MIPS64)
                   3108:             check_insn(env, ctx, ISA_MIPS3);
1.1.1.7 ! root     3109:             tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_XContext));
        !          3110:             tcg_gen_ext32s_tl(t0, t0);
1.1.1.6   root     3111:             rn = "XContext";
                   3112:             break;
                   3113: #endif
1.1.1.5   root     3114:         default:
                   3115:             goto die;
1.1.1.4   root     3116:         }
                   3117:         break;
1.1.1.5   root     3118:     case 21:
                   3119:        /* Officially reserved, but sel 0 is used for R1x000 framemask */
                   3120:         switch (sel) {
                   3121:         case 0:
1.1.1.7 ! root     3122:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_Framemask));
1.1.1.6   root     3123:             rn = "Framemask";
                   3124:             break;
1.1.1.5   root     3125:         default:
                   3126:             goto die;
1.1.1.4   root     3127:         }
                   3128:         break;
1.1.1.5   root     3129:     case 22:
1.1.1.7 ! root     3130:         tcg_gen_movi_tl(t0, 0); /* unimplemented */
1.1.1.6   root     3131:         rn = "'Diagnostic"; /* implementation dependent */
                   3132:         break;
1.1.1.5   root     3133:     case 23:
                   3134:         switch (sel) {
                   3135:         case 0:
1.1.1.7 ! root     3136:             gen_helper_mfc0_debug(t0); /* EJTAG support */
1.1.1.6   root     3137:             rn = "Debug";
                   3138:             break;
                   3139:         case 1:
1.1.1.7 ! root     3140: //            gen_helper_mfc0_tracecontrol(t0); /* PDtrace support */
1.1.1.6   root     3141:             rn = "TraceControl";
                   3142: //            break;
                   3143:         case 2:
1.1.1.7 ! root     3144: //            gen_helper_mfc0_tracecontrol2(t0); /* PDtrace support */
1.1.1.6   root     3145:             rn = "TraceControl2";
                   3146: //            break;
1.1.1.5   root     3147:         case 3:
1.1.1.7 ! root     3148: //            gen_helper_mfc0_usertracedata(t0); /* PDtrace support */
1.1.1.6   root     3149:             rn = "UserTraceData";
                   3150: //            break;
1.1.1.5   root     3151:         case 4:
1.1.1.7 ! root     3152: //            gen_helper_mfc0_tracebpc(t0); /* PDtrace support */
1.1.1.6   root     3153:             rn = "TraceBPC";
                   3154: //            break;
1.1.1.5   root     3155:         default:
                   3156:             goto die;
1.1.1.4   root     3157:         }
1.1.1.5   root     3158:         break;
                   3159:     case 24:
                   3160:         switch (sel) {
                   3161:         case 0:
1.1.1.7 ! root     3162:             /* EJTAG support */
        !          3163:             tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_DEPC));
        !          3164:             tcg_gen_ext32s_tl(t0, t0);
1.1.1.6   root     3165:             rn = "DEPC";
                   3166:             break;
1.1.1.5   root     3167:         default:
                   3168:             goto die;
                   3169:         }
                   3170:         break;
                   3171:     case 25:
                   3172:         switch (sel) {
                   3173:         case 0:
1.1.1.7 ! root     3174:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_Performance0));
1.1.1.6   root     3175:             rn = "Performance0";
1.1.1.5   root     3176:             break;
                   3177:         case 1:
1.1.1.7 ! root     3178: //            gen_helper_mfc0_performance1(t0);
1.1.1.6   root     3179:             rn = "Performance1";
                   3180: //            break;
1.1.1.5   root     3181:         case 2:
1.1.1.7 ! root     3182: //            gen_helper_mfc0_performance2(t0);
1.1.1.6   root     3183:             rn = "Performance2";
                   3184: //            break;
1.1.1.5   root     3185:         case 3:
1.1.1.7 ! root     3186: //            gen_helper_mfc0_performance3(t0);
1.1.1.6   root     3187:             rn = "Performance3";
                   3188: //            break;
1.1.1.5   root     3189:         case 4:
1.1.1.7 ! root     3190: //            gen_helper_mfc0_performance4(t0);
1.1.1.6   root     3191:             rn = "Performance4";
                   3192: //            break;
1.1.1.5   root     3193:         case 5:
1.1.1.7 ! root     3194: //            gen_helper_mfc0_performance5(t0);
1.1.1.6   root     3195:             rn = "Performance5";
                   3196: //            break;
1.1.1.5   root     3197:         case 6:
1.1.1.7 ! root     3198: //            gen_helper_mfc0_performance6(t0);
1.1.1.6   root     3199:             rn = "Performance6";
                   3200: //            break;
1.1.1.5   root     3201:         case 7:
1.1.1.7 ! root     3202: //            gen_helper_mfc0_performance7(t0);
1.1.1.6   root     3203:             rn = "Performance7";
                   3204: //            break;
1.1.1.5   root     3205:         default:
                   3206:             goto die;
                   3207:         }
                   3208:         break;
                   3209:     case 26:
1.1.1.7 ! root     3210:         tcg_gen_movi_tl(t0, 0); /* unimplemented */
        !          3211:         rn = "ECC";
        !          3212:         break;
1.1.1.5   root     3213:     case 27:
                   3214:         switch (sel) {
                   3215:         case 0 ... 3:
1.1.1.7 ! root     3216:             tcg_gen_movi_tl(t0, 0); /* unimplemented */
1.1.1.6   root     3217:             rn = "CacheErr";
                   3218:             break;
1.1.1.5   root     3219:         default:
                   3220:             goto die;
                   3221:         }
                   3222:         break;
                   3223:     case 28:
                   3224:         switch (sel) {
                   3225:         case 0:
                   3226:         case 2:
                   3227:         case 4:
                   3228:         case 6:
1.1.1.7 ! root     3229:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagLo));
1.1.1.5   root     3230:             rn = "TagLo";
                   3231:             break;
                   3232:         case 1:
                   3233:         case 3:
                   3234:         case 5:
                   3235:         case 7:
1.1.1.7 ! root     3236:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataLo));
1.1.1.5   root     3237:             rn = "DataLo";
                   3238:             break;
                   3239:         default:
                   3240:             goto die;
                   3241:         }
                   3242:         break;
                   3243:     case 29:
                   3244:         switch (sel) {
                   3245:         case 0:
                   3246:         case 2:
                   3247:         case 4:
                   3248:         case 6:
1.1.1.7 ! root     3249:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagHi));
1.1.1.5   root     3250:             rn = "TagHi";
                   3251:             break;
                   3252:         case 1:
                   3253:         case 3:
                   3254:         case 5:
                   3255:         case 7:
1.1.1.7 ! root     3256:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataHi));
1.1.1.5   root     3257:             rn = "DataHi";
                   3258:             break;
                   3259:         default:
                   3260:             goto die;
                   3261:         }
                   3262:         break;
                   3263:     case 30:
                   3264:         switch (sel) {
                   3265:         case 0:
1.1.1.7 ! root     3266:             tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
        !          3267:             tcg_gen_ext32s_tl(t0, t0);
1.1.1.6   root     3268:             rn = "ErrorEPC";
                   3269:             break;
1.1.1.5   root     3270:         default:
                   3271:             goto die;
                   3272:         }
                   3273:         break;
                   3274:     case 31:
                   3275:         switch (sel) {
                   3276:         case 0:
1.1.1.7 ! root     3277:             /* EJTAG support */
        !          3278:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_DESAVE));
1.1.1.6   root     3279:             rn = "DESAVE";
                   3280:             break;
1.1.1.5   root     3281:         default:
                   3282:             goto die;
                   3283:         }
                   3284:         break;
                   3285:     default:
                   3286:        goto die;
                   3287:     }
1.1.1.7 ! root     3288:     LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
1.1.1.5   root     3289:     return;
                   3290: 
                   3291: die:
1.1.1.7 ! root     3292:     LOG_DISAS("mfc0 %s (reg %d sel %d)\n", rn, reg, sel);
1.1.1.5   root     3293:     generate_exception(ctx, EXCP_RI);
                   3294: }
                   3295: 
1.1.1.7 ! root     3296: static void gen_mtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
1.1.1.5   root     3297: {
                   3298:     const char *rn = "invalid";
                   3299: 
1.1.1.6   root     3300:     if (sel != 0)
                   3301:         check_insn(env, ctx, ISA_MIPS32);
                   3302: 
1.1.1.7 ! root     3303:     if (use_icount)
        !          3304:         gen_io_start();
        !          3305: 
1.1.1.5   root     3306:     switch (reg) {
                   3307:     case 0:
                   3308:         switch (sel) {
                   3309:         case 0:
1.1.1.7 ! root     3310:             gen_helper_mtc0_index(t0);
1.1.1.5   root     3311:             rn = "Index";
                   3312:             break;
                   3313:         case 1:
1.1.1.6   root     3314:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     3315:             gen_helper_mtc0_mvpcontrol(t0);
1.1.1.5   root     3316:             rn = "MVPControl";
1.1.1.6   root     3317:             break;
1.1.1.5   root     3318:         case 2:
1.1.1.6   root     3319:             check_insn(env, ctx, ASE_MT);
                   3320:             /* ignored */
1.1.1.5   root     3321:             rn = "MVPConf0";
1.1.1.6   root     3322:             break;
1.1.1.5   root     3323:         case 3:
1.1.1.6   root     3324:             check_insn(env, ctx, ASE_MT);
                   3325:             /* ignored */
1.1.1.5   root     3326:             rn = "MVPConf1";
1.1.1.6   root     3327:             break;
1.1.1.5   root     3328:         default:
                   3329:             goto die;
                   3330:         }
                   3331:         break;
                   3332:     case 1:
                   3333:         switch (sel) {
                   3334:         case 0:
1.1.1.6   root     3335:             /* ignored */
1.1.1.5   root     3336:             rn = "Random";
1.1.1.6   root     3337:             break;
1.1.1.5   root     3338:         case 1:
1.1.1.6   root     3339:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     3340:             gen_helper_mtc0_vpecontrol(t0);
1.1.1.5   root     3341:             rn = "VPEControl";
1.1.1.6   root     3342:             break;
1.1.1.5   root     3343:         case 2:
1.1.1.6   root     3344:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     3345:             gen_helper_mtc0_vpeconf0(t0);
1.1.1.5   root     3346:             rn = "VPEConf0";
1.1.1.6   root     3347:             break;
1.1.1.5   root     3348:         case 3:
1.1.1.6   root     3349:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     3350:             gen_helper_mtc0_vpeconf1(t0);
1.1.1.5   root     3351:             rn = "VPEConf1";
1.1.1.6   root     3352:             break;
1.1.1.5   root     3353:         case 4:
1.1.1.6   root     3354:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     3355:             gen_helper_mtc0_yqmask(t0);
1.1.1.5   root     3356:             rn = "YQMask";
1.1.1.6   root     3357:             break;
1.1.1.5   root     3358:         case 5:
1.1.1.6   root     3359:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     3360:             gen_mtc0_store64(t0, offsetof(CPUState, CP0_VPESchedule));
1.1.1.5   root     3361:             rn = "VPESchedule";
1.1.1.6   root     3362:             break;
1.1.1.5   root     3363:         case 6:
1.1.1.6   root     3364:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     3365:             gen_mtc0_store64(t0, offsetof(CPUState, CP0_VPEScheFBack));
1.1.1.5   root     3366:             rn = "VPEScheFBack";
1.1.1.6   root     3367:             break;
1.1.1.5   root     3368:         case 7:
1.1.1.6   root     3369:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     3370:             gen_helper_mtc0_vpeopt(t0);
1.1.1.5   root     3371:             rn = "VPEOpt";
1.1.1.6   root     3372:             break;
1.1.1.5   root     3373:         default:
                   3374:             goto die;
                   3375:         }
                   3376:         break;
                   3377:     case 2:
                   3378:         switch (sel) {
                   3379:         case 0:
1.1.1.7 ! root     3380:             gen_helper_mtc0_entrylo0(t0);
1.1.1.6   root     3381:             rn = "EntryLo0";
                   3382:             break;
                   3383:         case 1:
                   3384:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     3385:             gen_helper_mtc0_tcstatus(t0);
1.1.1.6   root     3386:             rn = "TCStatus";
                   3387:             break;
                   3388:         case 2:
                   3389:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     3390:             gen_helper_mtc0_tcbind(t0);
1.1.1.6   root     3391:             rn = "TCBind";
                   3392:             break;
1.1.1.5   root     3393:         case 3:
1.1.1.6   root     3394:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     3395:             gen_helper_mtc0_tcrestart(t0);
1.1.1.6   root     3396:             rn = "TCRestart";
                   3397:             break;
1.1.1.5   root     3398:         case 4:
1.1.1.6   root     3399:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     3400:             gen_helper_mtc0_tchalt(t0);
1.1.1.6   root     3401:             rn = "TCHalt";
                   3402:             break;
1.1.1.5   root     3403:         case 5:
1.1.1.6   root     3404:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     3405:             gen_helper_mtc0_tccontext(t0);
1.1.1.6   root     3406:             rn = "TCContext";
                   3407:             break;
1.1.1.5   root     3408:         case 6:
1.1.1.6   root     3409:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     3410:             gen_helper_mtc0_tcschedule(t0);
1.1.1.6   root     3411:             rn = "TCSchedule";
                   3412:             break;
1.1.1.5   root     3413:         case 7:
1.1.1.6   root     3414:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     3415:             gen_helper_mtc0_tcschefback(t0);
1.1.1.6   root     3416:             rn = "TCScheFBack";
                   3417:             break;
1.1.1.5   root     3418:         default:
                   3419:             goto die;
                   3420:         }
                   3421:         break;
                   3422:     case 3:
                   3423:         switch (sel) {
                   3424:         case 0:
1.1.1.7 ! root     3425:             gen_helper_mtc0_entrylo1(t0);
1.1.1.6   root     3426:             rn = "EntryLo1";
                   3427:             break;
1.1.1.5   root     3428:         default:
                   3429:             goto die;
1.1.1.6   root     3430:         }
1.1.1.5   root     3431:         break;
                   3432:     case 4:
                   3433:         switch (sel) {
                   3434:         case 0:
1.1.1.7 ! root     3435:             gen_helper_mtc0_context(t0);
1.1.1.6   root     3436:             rn = "Context";
                   3437:             break;
                   3438:         case 1:
1.1.1.7 ! root     3439: //            gen_helper_mtc0_contextconfig(t0); /* SmartMIPS ASE */
1.1.1.6   root     3440:             rn = "ContextConfig";
                   3441: //            break;
1.1.1.5   root     3442:         default:
                   3443:             goto die;
1.1.1.6   root     3444:         }
1.1.1.5   root     3445:         break;
                   3446:     case 5:
                   3447:         switch (sel) {
                   3448:         case 0:
1.1.1.7 ! root     3449:             gen_helper_mtc0_pagemask(t0);
1.1.1.6   root     3450:             rn = "PageMask";
                   3451:             break;
                   3452:         case 1:
                   3453:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     3454:             gen_helper_mtc0_pagegrain(t0);
1.1.1.6   root     3455:             rn = "PageGrain";
                   3456:             break;
1.1.1.5   root     3457:         default:
                   3458:             goto die;
1.1.1.6   root     3459:         }
1.1.1.5   root     3460:         break;
                   3461:     case 6:
                   3462:         switch (sel) {
                   3463:         case 0:
1.1.1.7 ! root     3464:             gen_helper_mtc0_wired(t0);
1.1.1.6   root     3465:             rn = "Wired";
                   3466:             break;
                   3467:         case 1:
                   3468:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     3469:             gen_helper_mtc0_srsconf0(t0);
1.1.1.6   root     3470:             rn = "SRSConf0";
                   3471:             break;
                   3472:         case 2:
                   3473:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     3474:             gen_helper_mtc0_srsconf1(t0);
1.1.1.6   root     3475:             rn = "SRSConf1";
                   3476:             break;
1.1.1.5   root     3477:         case 3:
1.1.1.6   root     3478:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     3479:             gen_helper_mtc0_srsconf2(t0);
1.1.1.6   root     3480:             rn = "SRSConf2";
                   3481:             break;
1.1.1.5   root     3482:         case 4:
1.1.1.6   root     3483:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     3484:             gen_helper_mtc0_srsconf3(t0);
1.1.1.6   root     3485:             rn = "SRSConf3";
                   3486:             break;
1.1.1.5   root     3487:         case 5:
1.1.1.6   root     3488:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     3489:             gen_helper_mtc0_srsconf4(t0);
1.1.1.6   root     3490:             rn = "SRSConf4";
                   3491:             break;
1.1.1.5   root     3492:         default:
                   3493:             goto die;
1.1.1.6   root     3494:         }
1.1.1.5   root     3495:         break;
                   3496:     case 7:
                   3497:         switch (sel) {
                   3498:         case 0:
1.1.1.6   root     3499:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     3500:             gen_helper_mtc0_hwrena(t0);
1.1.1.6   root     3501:             rn = "HWREna";
                   3502:             break;
1.1.1.5   root     3503:         default:
                   3504:             goto die;
1.1.1.6   root     3505:         }
1.1.1.5   root     3506:         break;
                   3507:     case 8:
                   3508:         /* ignored */
1.1.1.7 ! root     3509:         rn = "BadVAddr";
1.1.1.5   root     3510:         break;
                   3511:     case 9:
                   3512:         switch (sel) {
                   3513:         case 0:
1.1.1.7 ! root     3514:             gen_helper_mtc0_count(t0);
1.1.1.6   root     3515:             rn = "Count";
                   3516:             break;
                   3517:         /* 6,7 are implementation dependent */
1.1.1.5   root     3518:         default:
                   3519:             goto die;
1.1.1.6   root     3520:         }
                   3521:         /* Stop translation as we may have switched the execution mode */
                   3522:         ctx->bstate = BS_STOP;
1.1.1.5   root     3523:         break;
                   3524:     case 10:
                   3525:         switch (sel) {
                   3526:         case 0:
1.1.1.7 ! root     3527:             gen_helper_mtc0_entryhi(t0);
1.1.1.6   root     3528:             rn = "EntryHi";
                   3529:             break;
1.1.1.5   root     3530:         default:
                   3531:             goto die;
1.1.1.6   root     3532:         }
1.1.1.5   root     3533:         break;
                   3534:     case 11:
                   3535:         switch (sel) {
                   3536:         case 0:
1.1.1.7 ! root     3537:             gen_helper_mtc0_compare(t0);
1.1.1.6   root     3538:             rn = "Compare";
                   3539:             break;
                   3540:         /* 6,7 are implementation dependent */
1.1.1.5   root     3541:         default:
                   3542:             goto die;
1.1.1.6   root     3543:         }
                   3544:         /* Stop translation as we may have switched the execution mode */
                   3545:         ctx->bstate = BS_STOP;
1.1.1.5   root     3546:         break;
                   3547:     case 12:
                   3548:         switch (sel) {
                   3549:         case 0:
1.1.1.7 ! root     3550:             gen_helper_mtc0_status(t0);
1.1.1.6   root     3551:             /* BS_STOP isn't good enough here, hflags may have changed. */
                   3552:             gen_save_pc(ctx->pc + 4);
                   3553:             ctx->bstate = BS_EXCP;
                   3554:             rn = "Status";
                   3555:             break;
                   3556:         case 1:
                   3557:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     3558:             gen_helper_mtc0_intctl(t0);
1.1.1.6   root     3559:             /* Stop translation as we may have switched the execution mode */
                   3560:             ctx->bstate = BS_STOP;
                   3561:             rn = "IntCtl";
                   3562:             break;
                   3563:         case 2:
                   3564:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     3565:             gen_helper_mtc0_srsctl(t0);
1.1.1.6   root     3566:             /* Stop translation as we may have switched the execution mode */
                   3567:             ctx->bstate = BS_STOP;
                   3568:             rn = "SRSCtl";
                   3569:             break;
1.1.1.5   root     3570:         case 3:
1.1.1.6   root     3571:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     3572:             gen_mtc0_store32(t0, offsetof(CPUState, CP0_SRSMap));
1.1.1.6   root     3573:             /* Stop translation as we may have switched the execution mode */
                   3574:             ctx->bstate = BS_STOP;
                   3575:             rn = "SRSMap";
                   3576:             break;
1.1.1.5   root     3577:         default:
                   3578:             goto die;
1.1.1.6   root     3579:         }
1.1.1.5   root     3580:         break;
                   3581:     case 13:
                   3582:         switch (sel) {
                   3583:         case 0:
1.1.1.7 ! root     3584:             gen_helper_mtc0_cause(t0);
1.1.1.6   root     3585:             rn = "Cause";
                   3586:             break;
1.1.1.5   root     3587:         default:
                   3588:             goto die;
1.1.1.6   root     3589:         }
                   3590:         /* Stop translation as we may have switched the execution mode */
                   3591:         ctx->bstate = BS_STOP;
1.1.1.5   root     3592:         break;
                   3593:     case 14:
                   3594:         switch (sel) {
                   3595:         case 0:
1.1.1.7 ! root     3596:             gen_mtc0_store64(t0, offsetof(CPUState, CP0_EPC));
1.1.1.6   root     3597:             rn = "EPC";
                   3598:             break;
1.1.1.5   root     3599:         default:
                   3600:             goto die;
1.1.1.6   root     3601:         }
1.1.1.5   root     3602:         break;
                   3603:     case 15:
                   3604:         switch (sel) {
                   3605:         case 0:
1.1.1.6   root     3606:             /* ignored */
                   3607:             rn = "PRid";
                   3608:             break;
                   3609:         case 1:
                   3610:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     3611:             gen_helper_mtc0_ebase(t0);
1.1.1.6   root     3612:             rn = "EBase";
                   3613:             break;
1.1.1.5   root     3614:         default:
                   3615:             goto die;
1.1.1.6   root     3616:         }
1.1.1.5   root     3617:         break;
                   3618:     case 16:
                   3619:         switch (sel) {
                   3620:         case 0:
1.1.1.7 ! root     3621:             gen_helper_mtc0_config0(t0);
1.1.1.5   root     3622:             rn = "Config";
1.1.1.6   root     3623:             /* Stop translation as we may have switched the execution mode */
                   3624:             ctx->bstate = BS_STOP;
1.1.1.5   root     3625:             break;
                   3626:         case 1:
1.1.1.6   root     3627:             /* ignored, read only */
1.1.1.5   root     3628:             rn = "Config1";
                   3629:             break;
                   3630:         case 2:
1.1.1.7 ! root     3631:             gen_helper_mtc0_config2(t0);
1.1.1.5   root     3632:             rn = "Config2";
1.1.1.6   root     3633:             /* Stop translation as we may have switched the execution mode */
                   3634:             ctx->bstate = BS_STOP;
1.1.1.5   root     3635:             break;
                   3636:         case 3:
1.1.1.6   root     3637:             /* ignored, read only */
1.1.1.5   root     3638:             rn = "Config3";
                   3639:             break;
1.1.1.6   root     3640:         /* 4,5 are reserved */
                   3641:         /* 6,7 are implementation dependent */
                   3642:         case 6:
                   3643:             /* ignored */
                   3644:             rn = "Config6";
                   3645:             break;
                   3646:         case 7:
                   3647:             /* ignored */
                   3648:             rn = "Config7";
                   3649:             break;
1.1.1.5   root     3650:         default:
                   3651:             rn = "Invalid config selector";
                   3652:             goto die;
                   3653:         }
                   3654:         break;
                   3655:     case 17:
                   3656:         switch (sel) {
                   3657:         case 0:
1.1.1.6   root     3658:             /* ignored */
                   3659:             rn = "LLAddr";
                   3660:             break;
1.1.1.5   root     3661:         default:
                   3662:             goto die;
                   3663:         }
                   3664:         break;
                   3665:     case 18:
                   3666:         switch (sel) {
1.1.1.6   root     3667:         case 0 ... 7:
1.1.1.7 ! root     3668:             gen_helper_1i(mtc0_watchlo, t0, sel);
1.1.1.6   root     3669:             rn = "WatchLo";
                   3670:             break;
1.1.1.5   root     3671:         default:
                   3672:             goto die;
                   3673:         }
                   3674:         break;
                   3675:     case 19:
                   3676:         switch (sel) {
1.1.1.6   root     3677:         case 0 ... 7:
1.1.1.7 ! root     3678:             gen_helper_1i(mtc0_watchhi, t0, sel);
1.1.1.6   root     3679:             rn = "WatchHi";
                   3680:             break;
1.1.1.5   root     3681:         default:
                   3682:             goto die;
                   3683:         }
                   3684:         break;
                   3685:     case 20:
                   3686:         switch (sel) {
                   3687:         case 0:
1.1.1.6   root     3688: #if defined(TARGET_MIPS64)
                   3689:             check_insn(env, ctx, ISA_MIPS3);
1.1.1.7 ! root     3690:             gen_helper_mtc0_xcontext(t0);
1.1.1.6   root     3691:             rn = "XContext";
                   3692:             break;
                   3693: #endif
1.1.1.5   root     3694:         default:
                   3695:             goto die;
                   3696:         }
                   3697:         break;
                   3698:     case 21:
                   3699:        /* Officially reserved, but sel 0 is used for R1x000 framemask */
                   3700:         switch (sel) {
                   3701:         case 0:
1.1.1.7 ! root     3702:             gen_helper_mtc0_framemask(t0);
1.1.1.6   root     3703:             rn = "Framemask";
                   3704:             break;
1.1.1.5   root     3705:         default:
                   3706:             goto die;
                   3707:         }
                   3708:         break;
                   3709:     case 22:
                   3710:         /* ignored */
                   3711:         rn = "Diagnostic"; /* implementation dependent */
1.1.1.6   root     3712:         break;
1.1.1.5   root     3713:     case 23:
                   3714:         switch (sel) {
                   3715:         case 0:
1.1.1.7 ! root     3716:             gen_helper_mtc0_debug(t0); /* EJTAG support */
1.1.1.6   root     3717:             /* BS_STOP isn't good enough here, hflags may have changed. */
                   3718:             gen_save_pc(ctx->pc + 4);
                   3719:             ctx->bstate = BS_EXCP;
                   3720:             rn = "Debug";
                   3721:             break;
                   3722:         case 1:
1.1.1.7 ! root     3723: //            gen_helper_mtc0_tracecontrol(t0); /* PDtrace support */
1.1.1.6   root     3724:             rn = "TraceControl";
                   3725:             /* Stop translation as we may have switched the execution mode */
                   3726:             ctx->bstate = BS_STOP;
                   3727: //            break;
                   3728:         case 2:
1.1.1.7 ! root     3729: //            gen_helper_mtc0_tracecontrol2(t0); /* PDtrace support */
1.1.1.6   root     3730:             rn = "TraceControl2";
                   3731:             /* Stop translation as we may have switched the execution mode */
                   3732:             ctx->bstate = BS_STOP;
                   3733: //            break;
                   3734:         case 3:
                   3735:             /* Stop translation as we may have switched the execution mode */
                   3736:             ctx->bstate = BS_STOP;
1.1.1.7 ! root     3737: //            gen_helper_mtc0_usertracedata(t0); /* PDtrace support */
1.1.1.6   root     3738:             rn = "UserTraceData";
                   3739:             /* Stop translation as we may have switched the execution mode */
                   3740:             ctx->bstate = BS_STOP;
                   3741: //            break;
1.1.1.5   root     3742:         case 4:
1.1.1.7 ! root     3743: //            gen_helper_mtc0_tracebpc(t0); /* PDtrace support */
1.1.1.6   root     3744:             /* Stop translation as we may have switched the execution mode */
                   3745:             ctx->bstate = BS_STOP;
                   3746:             rn = "TraceBPC";
                   3747: //            break;
1.1.1.5   root     3748:         default:
                   3749:             goto die;
                   3750:         }
                   3751:         break;
                   3752:     case 24:
                   3753:         switch (sel) {
                   3754:         case 0:
1.1.1.7 ! root     3755:             /* EJTAG support */
        !          3756:             gen_mtc0_store64(t0, offsetof(CPUState, CP0_DEPC));
1.1.1.6   root     3757:             rn = "DEPC";
                   3758:             break;
1.1.1.5   root     3759:         default:
                   3760:             goto die;
                   3761:         }
                   3762:         break;
                   3763:     case 25:
                   3764:         switch (sel) {
                   3765:         case 0:
1.1.1.7 ! root     3766:             gen_helper_mtc0_performance0(t0);
1.1.1.6   root     3767:             rn = "Performance0";
                   3768:             break;
                   3769:         case 1:
1.1.1.7 ! root     3770: //            gen_helper_mtc0_performance1(t0);
1.1.1.6   root     3771:             rn = "Performance1";
                   3772: //            break;
                   3773:         case 2:
1.1.1.7 ! root     3774: //            gen_helper_mtc0_performance2(t0);
1.1.1.6   root     3775:             rn = "Performance2";
                   3776: //            break;
                   3777:         case 3:
1.1.1.7 ! root     3778: //            gen_helper_mtc0_performance3(t0);
1.1.1.6   root     3779:             rn = "Performance3";
                   3780: //            break;
1.1.1.5   root     3781:         case 4:
1.1.1.7 ! root     3782: //            gen_helper_mtc0_performance4(t0);
1.1.1.6   root     3783:             rn = "Performance4";
                   3784: //            break;
1.1.1.5   root     3785:         case 5:
1.1.1.7 ! root     3786: //            gen_helper_mtc0_performance5(t0);
1.1.1.6   root     3787:             rn = "Performance5";
                   3788: //            break;
1.1.1.5   root     3789:         case 6:
1.1.1.7 ! root     3790: //            gen_helper_mtc0_performance6(t0);
1.1.1.6   root     3791:             rn = "Performance6";
                   3792: //            break;
1.1.1.5   root     3793:         case 7:
1.1.1.7 ! root     3794: //            gen_helper_mtc0_performance7(t0);
1.1.1.6   root     3795:             rn = "Performance7";
                   3796: //            break;
1.1.1.5   root     3797:         default:
                   3798:             goto die;
                   3799:         }
                   3800:        break;
                   3801:     case 26:
1.1.1.6   root     3802:         /* ignored */
1.1.1.5   root     3803:         rn = "ECC";
1.1.1.6   root     3804:         break;
1.1.1.5   root     3805:     case 27:
                   3806:         switch (sel) {
                   3807:         case 0 ... 3:
1.1.1.6   root     3808:             /* ignored */
                   3809:             rn = "CacheErr";
                   3810:             break;
1.1.1.5   root     3811:         default:
                   3812:             goto die;
                   3813:         }
                   3814:        break;
                   3815:     case 28:
                   3816:         switch (sel) {
                   3817:         case 0:
                   3818:         case 2:
                   3819:         case 4:
                   3820:         case 6:
1.1.1.7 ! root     3821:             gen_helper_mtc0_taglo(t0);
1.1.1.5   root     3822:             rn = "TagLo";
                   3823:             break;
                   3824:         case 1:
                   3825:         case 3:
                   3826:         case 5:
                   3827:         case 7:
1.1.1.7 ! root     3828:             gen_helper_mtc0_datalo(t0);
1.1.1.5   root     3829:             rn = "DataLo";
                   3830:             break;
                   3831:         default:
                   3832:             goto die;
                   3833:         }
                   3834:         break;
                   3835:     case 29:
                   3836:         switch (sel) {
                   3837:         case 0:
                   3838:         case 2:
                   3839:         case 4:
                   3840:         case 6:
1.1.1.7 ! root     3841:             gen_helper_mtc0_taghi(t0);
1.1.1.5   root     3842:             rn = "TagHi";
                   3843:             break;
                   3844:         case 1:
                   3845:         case 3:
                   3846:         case 5:
                   3847:         case 7:
1.1.1.7 ! root     3848:             gen_helper_mtc0_datahi(t0);
1.1.1.5   root     3849:             rn = "DataHi";
                   3850:             break;
                   3851:         default:
                   3852:             rn = "invalid sel";
                   3853:             goto die;
                   3854:         }
                   3855:        break;
                   3856:     case 30:
                   3857:         switch (sel) {
                   3858:         case 0:
1.1.1.7 ! root     3859:             gen_mtc0_store64(t0, offsetof(CPUState, CP0_ErrorEPC));
1.1.1.6   root     3860:             rn = "ErrorEPC";
                   3861:             break;
1.1.1.5   root     3862:         default:
                   3863:             goto die;
                   3864:         }
                   3865:         break;
                   3866:     case 31:
                   3867:         switch (sel) {
                   3868:         case 0:
1.1.1.7 ! root     3869:             /* EJTAG support */
        !          3870:             gen_mtc0_store32(t0, offsetof(CPUState, CP0_DESAVE));
1.1.1.6   root     3871:             rn = "DESAVE";
                   3872:             break;
1.1.1.5   root     3873:         default:
                   3874:             goto die;
                   3875:         }
1.1.1.6   root     3876:         /* Stop translation as we may have switched the execution mode */
                   3877:         ctx->bstate = BS_STOP;
1.1.1.5   root     3878:         break;
                   3879:     default:
                   3880:        goto die;
                   3881:     }
1.1.1.7 ! root     3882:     LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
        !          3883:     /* For simplicity assume that all writes can cause interrupts.  */
        !          3884:     if (use_icount) {
        !          3885:         gen_io_end();
        !          3886:         ctx->bstate = BS_STOP;
1.1.1.5   root     3887:     }
                   3888:     return;
                   3889: 
                   3890: die:
1.1.1.7 ! root     3891:     LOG_DISAS("mtc0 %s (reg %d sel %d)\n", rn, reg, sel);
1.1.1.5   root     3892:     generate_exception(ctx, EXCP_RI);
                   3893: }
                   3894: 
1.1.1.6   root     3895: #if defined(TARGET_MIPS64)
1.1.1.7 ! root     3896: static void gen_dmfc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
1.1.1.5   root     3897: {
                   3898:     const char *rn = "invalid";
                   3899: 
1.1.1.6   root     3900:     if (sel != 0)
                   3901:         check_insn(env, ctx, ISA_MIPS64);
                   3902: 
1.1.1.5   root     3903:     switch (reg) {
                   3904:     case 0:
                   3905:         switch (sel) {
                   3906:         case 0:
1.1.1.7 ! root     3907:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_Index));
1.1.1.5   root     3908:             rn = "Index";
                   3909:             break;
                   3910:         case 1:
1.1.1.6   root     3911:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     3912:             gen_helper_mfc0_mvpcontrol(t0);
1.1.1.5   root     3913:             rn = "MVPControl";
1.1.1.6   root     3914:             break;
1.1.1.5   root     3915:         case 2:
1.1.1.6   root     3916:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     3917:             gen_helper_mfc0_mvpconf0(t0);
1.1.1.5   root     3918:             rn = "MVPConf0";
1.1.1.6   root     3919:             break;
1.1.1.5   root     3920:         case 3:
1.1.1.6   root     3921:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     3922:             gen_helper_mfc0_mvpconf1(t0);
1.1.1.5   root     3923:             rn = "MVPConf1";
1.1.1.6   root     3924:             break;
1.1.1.5   root     3925:         default:
                   3926:             goto die;
                   3927:         }
                   3928:         break;
                   3929:     case 1:
                   3930:         switch (sel) {
                   3931:         case 0:
1.1.1.7 ! root     3932:             gen_helper_mfc0_random(t0);
1.1.1.5   root     3933:             rn = "Random";
1.1.1.6   root     3934:             break;
1.1.1.5   root     3935:         case 1:
1.1.1.6   root     3936:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     3937:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEControl));
1.1.1.5   root     3938:             rn = "VPEControl";
1.1.1.6   root     3939:             break;
1.1.1.5   root     3940:         case 2:
1.1.1.6   root     3941:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     3942:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf0));
1.1.1.5   root     3943:             rn = "VPEConf0";
1.1.1.6   root     3944:             break;
1.1.1.5   root     3945:         case 3:
1.1.1.6   root     3946:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     3947:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEConf1));
1.1.1.5   root     3948:             rn = "VPEConf1";
1.1.1.6   root     3949:             break;
1.1.1.5   root     3950:         case 4:
1.1.1.6   root     3951:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     3952:             tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_YQMask));
1.1.1.5   root     3953:             rn = "YQMask";
1.1.1.6   root     3954:             break;
1.1.1.5   root     3955:         case 5:
1.1.1.6   root     3956:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     3957:             tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_VPESchedule));
1.1.1.5   root     3958:             rn = "VPESchedule";
1.1.1.6   root     3959:             break;
1.1.1.5   root     3960:         case 6:
1.1.1.6   root     3961:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     3962:             tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
1.1.1.5   root     3963:             rn = "VPEScheFBack";
1.1.1.6   root     3964:             break;
1.1.1.5   root     3965:         case 7:
1.1.1.6   root     3966:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     3967:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_VPEOpt));
1.1.1.5   root     3968:             rn = "VPEOpt";
1.1.1.6   root     3969:             break;
1.1.1.5   root     3970:         default:
                   3971:             goto die;
                   3972:         }
                   3973:         break;
                   3974:     case 2:
                   3975:         switch (sel) {
                   3976:         case 0:
1.1.1.7 ! root     3977:             tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo0));
1.1.1.6   root     3978:             rn = "EntryLo0";
                   3979:             break;
                   3980:         case 1:
                   3981:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     3982:             gen_helper_mfc0_tcstatus(t0);
1.1.1.6   root     3983:             rn = "TCStatus";
                   3984:             break;
                   3985:         case 2:
                   3986:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     3987:             gen_helper_mfc0_tcbind(t0);
1.1.1.6   root     3988:             rn = "TCBind";
                   3989:             break;
1.1.1.5   root     3990:         case 3:
1.1.1.6   root     3991:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     3992:             gen_helper_dmfc0_tcrestart(t0);
1.1.1.6   root     3993:             rn = "TCRestart";
                   3994:             break;
1.1.1.5   root     3995:         case 4:
1.1.1.6   root     3996:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     3997:             gen_helper_dmfc0_tchalt(t0);
1.1.1.6   root     3998:             rn = "TCHalt";
                   3999:             break;
1.1.1.5   root     4000:         case 5:
1.1.1.6   root     4001:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     4002:             gen_helper_dmfc0_tccontext(t0);
1.1.1.6   root     4003:             rn = "TCContext";
                   4004:             break;
1.1.1.5   root     4005:         case 6:
1.1.1.6   root     4006:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     4007:             gen_helper_dmfc0_tcschedule(t0);
1.1.1.6   root     4008:             rn = "TCSchedule";
                   4009:             break;
1.1.1.5   root     4010:         case 7:
1.1.1.6   root     4011:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     4012:             gen_helper_dmfc0_tcschefback(t0);
1.1.1.6   root     4013:             rn = "TCScheFBack";
                   4014:             break;
1.1.1.5   root     4015:         default:
                   4016:             goto die;
                   4017:         }
                   4018:         break;
                   4019:     case 3:
                   4020:         switch (sel) {
                   4021:         case 0:
1.1.1.7 ! root     4022:             tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryLo1));
1.1.1.6   root     4023:             rn = "EntryLo1";
                   4024:             break;
1.1.1.5   root     4025:         default:
                   4026:             goto die;
1.1.1.6   root     4027:         }
1.1.1.5   root     4028:         break;
                   4029:     case 4:
                   4030:         switch (sel) {
                   4031:         case 0:
1.1.1.7 ! root     4032:             tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_Context));
1.1.1.6   root     4033:             rn = "Context";
                   4034:             break;
                   4035:         case 1:
1.1.1.7 ! root     4036: //            gen_helper_dmfc0_contextconfig(t0); /* SmartMIPS ASE */
1.1.1.6   root     4037:             rn = "ContextConfig";
                   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 5:
                   4044:         switch (sel) {
                   4045:         case 0:
1.1.1.7 ! root     4046:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageMask));
1.1.1.6   root     4047:             rn = "PageMask";
                   4048:             break;
                   4049:         case 1:
                   4050:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     4051:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_PageGrain));
1.1.1.6   root     4052:             rn = "PageGrain";
                   4053:             break;
1.1.1.5   root     4054:         default:
                   4055:             goto die;
1.1.1.6   root     4056:         }
1.1.1.5   root     4057:         break;
                   4058:     case 6:
                   4059:         switch (sel) {
                   4060:         case 0:
1.1.1.7 ! root     4061:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_Wired));
1.1.1.6   root     4062:             rn = "Wired";
                   4063:             break;
                   4064:         case 1:
                   4065:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     4066:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf0));
1.1.1.6   root     4067:             rn = "SRSConf0";
                   4068:             break;
                   4069:         case 2:
                   4070:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     4071:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf1));
1.1.1.6   root     4072:             rn = "SRSConf1";
                   4073:             break;
1.1.1.5   root     4074:         case 3:
1.1.1.6   root     4075:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     4076:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf2));
1.1.1.6   root     4077:             rn = "SRSConf2";
                   4078:             break;
1.1.1.5   root     4079:         case 4:
1.1.1.6   root     4080:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     4081:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf3));
1.1.1.6   root     4082:             rn = "SRSConf3";
                   4083:             break;
1.1.1.5   root     4084:         case 5:
1.1.1.6   root     4085:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     4086:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSConf4));
1.1.1.6   root     4087:             rn = "SRSConf4";
                   4088:             break;
1.1.1.5   root     4089:         default:
                   4090:             goto die;
1.1.1.6   root     4091:         }
1.1.1.5   root     4092:         break;
                   4093:     case 7:
                   4094:         switch (sel) {
                   4095:         case 0:
1.1.1.6   root     4096:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     4097:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_HWREna));
1.1.1.6   root     4098:             rn = "HWREna";
                   4099:             break;
1.1.1.5   root     4100:         default:
                   4101:             goto die;
1.1.1.6   root     4102:         }
1.1.1.5   root     4103:         break;
                   4104:     case 8:
                   4105:         switch (sel) {
                   4106:         case 0:
1.1.1.7 ! root     4107:             tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_BadVAddr));
        !          4108:             rn = "BadVAddr";
1.1.1.6   root     4109:             break;
1.1.1.5   root     4110:         default:
                   4111:             goto die;
1.1.1.6   root     4112:         }
1.1.1.5   root     4113:         break;
                   4114:     case 9:
                   4115:         switch (sel) {
                   4116:         case 0:
1.1.1.7 ! root     4117:             /* Mark as an IO operation because we read the time.  */
        !          4118:             if (use_icount)
        !          4119:                 gen_io_start();
        !          4120:             gen_helper_mfc0_count(t0);
        !          4121:             if (use_icount) {
        !          4122:                 gen_io_end();
        !          4123:                 ctx->bstate = BS_STOP;
        !          4124:             }
1.1.1.6   root     4125:             rn = "Count";
                   4126:             break;
                   4127:         /* 6,7 are implementation dependent */
1.1.1.5   root     4128:         default:
                   4129:             goto die;
1.1.1.6   root     4130:         }
1.1.1.5   root     4131:         break;
                   4132:     case 10:
                   4133:         switch (sel) {
                   4134:         case 0:
1.1.1.7 ! root     4135:             tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EntryHi));
1.1.1.6   root     4136:             rn = "EntryHi";
                   4137:             break;
1.1.1.5   root     4138:         default:
                   4139:             goto die;
1.1.1.6   root     4140:         }
1.1.1.5   root     4141:         break;
                   4142:     case 11:
                   4143:         switch (sel) {
                   4144:         case 0:
1.1.1.7 ! root     4145:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_Compare));
1.1.1.6   root     4146:             rn = "Compare";
                   4147:             break;
                   4148:         /* 6,7 are implementation dependent */
1.1.1.5   root     4149:         default:
                   4150:             goto die;
1.1.1.6   root     4151:         }
1.1.1.5   root     4152:         break;
                   4153:     case 12:
                   4154:         switch (sel) {
                   4155:         case 0:
1.1.1.7 ! root     4156:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_Status));
1.1.1.6   root     4157:             rn = "Status";
                   4158:             break;
                   4159:         case 1:
                   4160:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     4161:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_IntCtl));
1.1.1.6   root     4162:             rn = "IntCtl";
                   4163:             break;
                   4164:         case 2:
                   4165:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     4166:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSCtl));
1.1.1.6   root     4167:             rn = "SRSCtl";
                   4168:             break;
1.1.1.5   root     4169:         case 3:
1.1.1.6   root     4170:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     4171:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_SRSMap));
1.1.1.6   root     4172:             rn = "SRSMap";
                   4173:             break;
1.1.1.5   root     4174:         default:
                   4175:             goto die;
1.1.1.6   root     4176:         }
1.1.1.5   root     4177:         break;
                   4178:     case 13:
                   4179:         switch (sel) {
                   4180:         case 0:
1.1.1.7 ! root     4181:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_Cause));
1.1.1.6   root     4182:             rn = "Cause";
                   4183:             break;
1.1.1.5   root     4184:         default:
                   4185:             goto die;
1.1.1.6   root     4186:         }
1.1.1.5   root     4187:         break;
                   4188:     case 14:
                   4189:         switch (sel) {
                   4190:         case 0:
1.1.1.7 ! root     4191:             tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_EPC));
1.1.1.6   root     4192:             rn = "EPC";
                   4193:             break;
1.1.1.5   root     4194:         default:
                   4195:             goto die;
1.1.1.6   root     4196:         }
1.1.1.5   root     4197:         break;
                   4198:     case 15:
                   4199:         switch (sel) {
                   4200:         case 0:
1.1.1.7 ! root     4201:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_PRid));
1.1.1.6   root     4202:             rn = "PRid";
                   4203:             break;
                   4204:         case 1:
                   4205:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     4206:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_EBase));
1.1.1.6   root     4207:             rn = "EBase";
                   4208:             break;
1.1.1.5   root     4209:         default:
                   4210:             goto die;
1.1.1.6   root     4211:         }
1.1.1.5   root     4212:         break;
                   4213:     case 16:
                   4214:         switch (sel) {
                   4215:         case 0:
1.1.1.7 ! root     4216:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config0));
1.1.1.5   root     4217:             rn = "Config";
                   4218:             break;
                   4219:         case 1:
1.1.1.7 ! root     4220:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config1));
1.1.1.5   root     4221:             rn = "Config1";
                   4222:             break;
                   4223:         case 2:
1.1.1.7 ! root     4224:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config2));
1.1.1.5   root     4225:             rn = "Config2";
                   4226:             break;
                   4227:         case 3:
1.1.1.7 ! root     4228:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config3));
1.1.1.5   root     4229:             rn = "Config3";
                   4230:             break;
                   4231:        /* 6,7 are implementation dependent */
1.1.1.7 ! root     4232:         case 6:
        !          4233:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config6));
        !          4234:             rn = "Config6";
        !          4235:             break;
        !          4236:         case 7:
        !          4237:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_Config7));
        !          4238:             rn = "Config7";
        !          4239:             break;
1.1.1.5   root     4240:         default:
                   4241:             goto die;
                   4242:         }
                   4243:         break;
                   4244:     case 17:
                   4245:         switch (sel) {
                   4246:         case 0:
1.1.1.7 ! root     4247:             gen_helper_dmfc0_lladdr(t0);
1.1.1.6   root     4248:             rn = "LLAddr";
                   4249:             break;
1.1.1.5   root     4250:         default:
                   4251:             goto die;
                   4252:         }
                   4253:         break;
                   4254:     case 18:
                   4255:         switch (sel) {
1.1.1.6   root     4256:         case 0 ... 7:
1.1.1.7 ! root     4257:             gen_helper_1i(dmfc0_watchlo, t0, sel);
1.1.1.6   root     4258:             rn = "WatchLo";
                   4259:             break;
1.1.1.5   root     4260:         default:
                   4261:             goto die;
                   4262:         }
                   4263:         break;
                   4264:     case 19:
                   4265:         switch (sel) {
1.1.1.6   root     4266:         case 0 ... 7:
1.1.1.7 ! root     4267:             gen_helper_1i(mfc0_watchhi, t0, sel);
1.1.1.6   root     4268:             rn = "WatchHi";
                   4269:             break;
1.1.1.5   root     4270:         default:
                   4271:             goto die;
                   4272:         }
                   4273:         break;
                   4274:     case 20:
                   4275:         switch (sel) {
                   4276:         case 0:
1.1.1.6   root     4277:             check_insn(env, ctx, ISA_MIPS3);
1.1.1.7 ! root     4278:             tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_XContext));
1.1.1.6   root     4279:             rn = "XContext";
                   4280:             break;
1.1.1.5   root     4281:         default:
                   4282:             goto die;
                   4283:         }
                   4284:         break;
                   4285:     case 21:
                   4286:        /* Officially reserved, but sel 0 is used for R1x000 framemask */
                   4287:         switch (sel) {
                   4288:         case 0:
1.1.1.7 ! root     4289:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_Framemask));
1.1.1.6   root     4290:             rn = "Framemask";
                   4291:             break;
1.1.1.5   root     4292:         default:
                   4293:             goto die;
                   4294:         }
                   4295:         break;
                   4296:     case 22:
1.1.1.7 ! root     4297:         tcg_gen_movi_tl(t0, 0); /* unimplemented */
1.1.1.6   root     4298:         rn = "'Diagnostic"; /* implementation dependent */
                   4299:         break;
1.1.1.5   root     4300:     case 23:
                   4301:         switch (sel) {
                   4302:         case 0:
1.1.1.7 ! root     4303:             gen_helper_mfc0_debug(t0); /* EJTAG support */
1.1.1.6   root     4304:             rn = "Debug";
                   4305:             break;
                   4306:         case 1:
1.1.1.7 ! root     4307: //            gen_helper_dmfc0_tracecontrol(t0); /* PDtrace support */
1.1.1.6   root     4308:             rn = "TraceControl";
                   4309: //            break;
                   4310:         case 2:
1.1.1.7 ! root     4311: //            gen_helper_dmfc0_tracecontrol2(t0); /* PDtrace support */
1.1.1.6   root     4312:             rn = "TraceControl2";
                   4313: //            break;
1.1.1.5   root     4314:         case 3:
1.1.1.7 ! root     4315: //            gen_helper_dmfc0_usertracedata(t0); /* PDtrace support */
1.1.1.6   root     4316:             rn = "UserTraceData";
                   4317: //            break;
1.1.1.5   root     4318:         case 4:
1.1.1.7 ! root     4319: //            gen_helper_dmfc0_tracebpc(t0); /* PDtrace support */
1.1.1.6   root     4320:             rn = "TraceBPC";
                   4321: //            break;
1.1.1.5   root     4322:         default:
                   4323:             goto die;
                   4324:         }
                   4325:         break;
                   4326:     case 24:
                   4327:         switch (sel) {
                   4328:         case 0:
1.1.1.7 ! root     4329:             /* EJTAG support */
        !          4330:             tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_DEPC));
1.1.1.6   root     4331:             rn = "DEPC";
                   4332:             break;
1.1.1.5   root     4333:         default:
                   4334:             goto die;
                   4335:         }
                   4336:         break;
                   4337:     case 25:
                   4338:         switch (sel) {
                   4339:         case 0:
1.1.1.7 ! root     4340:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_Performance0));
1.1.1.6   root     4341:             rn = "Performance0";
1.1.1.5   root     4342:             break;
                   4343:         case 1:
1.1.1.7 ! root     4344: //            gen_helper_dmfc0_performance1(t0);
1.1.1.6   root     4345:             rn = "Performance1";
                   4346: //            break;
1.1.1.5   root     4347:         case 2:
1.1.1.7 ! root     4348: //            gen_helper_dmfc0_performance2(t0);
1.1.1.6   root     4349:             rn = "Performance2";
                   4350: //            break;
1.1.1.5   root     4351:         case 3:
1.1.1.7 ! root     4352: //            gen_helper_dmfc0_performance3(t0);
1.1.1.6   root     4353:             rn = "Performance3";
                   4354: //            break;
1.1.1.5   root     4355:         case 4:
1.1.1.7 ! root     4356: //            gen_helper_dmfc0_performance4(t0);
1.1.1.6   root     4357:             rn = "Performance4";
                   4358: //            break;
1.1.1.5   root     4359:         case 5:
1.1.1.7 ! root     4360: //            gen_helper_dmfc0_performance5(t0);
1.1.1.6   root     4361:             rn = "Performance5";
                   4362: //            break;
1.1.1.5   root     4363:         case 6:
1.1.1.7 ! root     4364: //            gen_helper_dmfc0_performance6(t0);
1.1.1.6   root     4365:             rn = "Performance6";
                   4366: //            break;
1.1.1.5   root     4367:         case 7:
1.1.1.7 ! root     4368: //            gen_helper_dmfc0_performance7(t0);
1.1.1.6   root     4369:             rn = "Performance7";
                   4370: //            break;
1.1.1.5   root     4371:         default:
                   4372:             goto die;
                   4373:         }
                   4374:         break;
                   4375:     case 26:
1.1.1.7 ! root     4376:         tcg_gen_movi_tl(t0, 0); /* unimplemented */
        !          4377:         rn = "ECC";
        !          4378:         break;
1.1.1.5   root     4379:     case 27:
                   4380:         switch (sel) {
                   4381:         /* ignored */
                   4382:         case 0 ... 3:
1.1.1.7 ! root     4383:             tcg_gen_movi_tl(t0, 0); /* unimplemented */
1.1.1.6   root     4384:             rn = "CacheErr";
                   4385:             break;
1.1.1.5   root     4386:         default:
                   4387:             goto die;
                   4388:         }
                   4389:         break;
                   4390:     case 28:
                   4391:         switch (sel) {
                   4392:         case 0:
                   4393:         case 2:
                   4394:         case 4:
                   4395:         case 6:
1.1.1.7 ! root     4396:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagLo));
1.1.1.5   root     4397:             rn = "TagLo";
                   4398:             break;
                   4399:         case 1:
                   4400:         case 3:
                   4401:         case 5:
                   4402:         case 7:
1.1.1.7 ! root     4403:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataLo));
1.1.1.5   root     4404:             rn = "DataLo";
                   4405:             break;
                   4406:         default:
                   4407:             goto die;
                   4408:         }
                   4409:         break;
                   4410:     case 29:
                   4411:         switch (sel) {
                   4412:         case 0:
                   4413:         case 2:
                   4414:         case 4:
                   4415:         case 6:
1.1.1.7 ! root     4416:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_TagHi));
1.1.1.5   root     4417:             rn = "TagHi";
                   4418:             break;
                   4419:         case 1:
                   4420:         case 3:
                   4421:         case 5:
                   4422:         case 7:
1.1.1.7 ! root     4423:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_DataHi));
1.1.1.5   root     4424:             rn = "DataHi";
                   4425:             break;
                   4426:         default:
                   4427:             goto die;
                   4428:         }
                   4429:         break;
                   4430:     case 30:
                   4431:         switch (sel) {
                   4432:         case 0:
1.1.1.7 ! root     4433:             tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
1.1.1.6   root     4434:             rn = "ErrorEPC";
                   4435:             break;
1.1.1.5   root     4436:         default:
                   4437:             goto die;
                   4438:         }
                   4439:         break;
                   4440:     case 31:
                   4441:         switch (sel) {
                   4442:         case 0:
1.1.1.7 ! root     4443:             /* EJTAG support */
        !          4444:             gen_mfc0_load32(t0, offsetof(CPUState, CP0_DESAVE));
1.1.1.6   root     4445:             rn = "DESAVE";
                   4446:             break;
1.1.1.5   root     4447:         default:
                   4448:             goto die;
                   4449:         }
                   4450:         break;
                   4451:     default:
1.1.1.6   root     4452:         goto die;
1.1.1.5   root     4453:     }
1.1.1.7 ! root     4454:     LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
1.1.1.5   root     4455:     return;
                   4456: 
                   4457: die:
1.1.1.7 ! root     4458:     LOG_DISAS("dmfc0 %s (reg %d sel %d)\n", rn, reg, sel);
1.1.1.5   root     4459:     generate_exception(ctx, EXCP_RI);
                   4460: }
                   4461: 
1.1.1.7 ! root     4462: static void gen_dmtc0 (CPUState *env, DisasContext *ctx, TCGv t0, int reg, int sel)
1.1.1.5   root     4463: {
                   4464:     const char *rn = "invalid";
                   4465: 
1.1.1.6   root     4466:     if (sel != 0)
                   4467:         check_insn(env, ctx, ISA_MIPS64);
                   4468: 
1.1.1.7 ! root     4469:     if (use_icount)
        !          4470:         gen_io_start();
        !          4471: 
1.1.1.5   root     4472:     switch (reg) {
                   4473:     case 0:
                   4474:         switch (sel) {
                   4475:         case 0:
1.1.1.7 ! root     4476:             gen_helper_mtc0_index(t0);
1.1.1.5   root     4477:             rn = "Index";
                   4478:             break;
                   4479:         case 1:
1.1.1.6   root     4480:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     4481:             gen_helper_mtc0_mvpcontrol(t0);
1.1.1.5   root     4482:             rn = "MVPControl";
1.1.1.6   root     4483:             break;
1.1.1.5   root     4484:         case 2:
1.1.1.6   root     4485:             check_insn(env, ctx, ASE_MT);
                   4486:             /* ignored */
1.1.1.5   root     4487:             rn = "MVPConf0";
1.1.1.6   root     4488:             break;
1.1.1.5   root     4489:         case 3:
1.1.1.6   root     4490:             check_insn(env, ctx, ASE_MT);
                   4491:             /* ignored */
1.1.1.5   root     4492:             rn = "MVPConf1";
1.1.1.6   root     4493:             break;
1.1.1.5   root     4494:         default:
                   4495:             goto die;
                   4496:         }
                   4497:         break;
                   4498:     case 1:
                   4499:         switch (sel) {
                   4500:         case 0:
1.1.1.6   root     4501:             /* ignored */
1.1.1.5   root     4502:             rn = "Random";
1.1.1.6   root     4503:             break;
1.1.1.5   root     4504:         case 1:
1.1.1.6   root     4505:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     4506:             gen_helper_mtc0_vpecontrol(t0);
1.1.1.5   root     4507:             rn = "VPEControl";
1.1.1.6   root     4508:             break;
1.1.1.5   root     4509:         case 2:
1.1.1.6   root     4510:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     4511:             gen_helper_mtc0_vpeconf0(t0);
1.1.1.5   root     4512:             rn = "VPEConf0";
1.1.1.6   root     4513:             break;
1.1.1.5   root     4514:         case 3:
1.1.1.6   root     4515:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     4516:             gen_helper_mtc0_vpeconf1(t0);
1.1.1.5   root     4517:             rn = "VPEConf1";
1.1.1.6   root     4518:             break;
1.1.1.5   root     4519:         case 4:
1.1.1.6   root     4520:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     4521:             gen_helper_mtc0_yqmask(t0);
1.1.1.5   root     4522:             rn = "YQMask";
1.1.1.6   root     4523:             break;
1.1.1.5   root     4524:         case 5:
1.1.1.6   root     4525:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     4526:             tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_VPESchedule));
1.1.1.5   root     4527:             rn = "VPESchedule";
1.1.1.6   root     4528:             break;
1.1.1.5   root     4529:         case 6:
1.1.1.6   root     4530:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     4531:             tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_VPEScheFBack));
1.1.1.5   root     4532:             rn = "VPEScheFBack";
1.1.1.6   root     4533:             break;
1.1.1.5   root     4534:         case 7:
1.1.1.6   root     4535:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     4536:             gen_helper_mtc0_vpeopt(t0);
1.1.1.5   root     4537:             rn = "VPEOpt";
1.1.1.6   root     4538:             break;
1.1.1.5   root     4539:         default:
                   4540:             goto die;
                   4541:         }
                   4542:         break;
                   4543:     case 2:
                   4544:         switch (sel) {
                   4545:         case 0:
1.1.1.7 ! root     4546:             gen_helper_mtc0_entrylo0(t0);
1.1.1.6   root     4547:             rn = "EntryLo0";
                   4548:             break;
                   4549:         case 1:
                   4550:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     4551:             gen_helper_mtc0_tcstatus(t0);
1.1.1.6   root     4552:             rn = "TCStatus";
                   4553:             break;
                   4554:         case 2:
                   4555:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     4556:             gen_helper_mtc0_tcbind(t0);
1.1.1.6   root     4557:             rn = "TCBind";
                   4558:             break;
1.1.1.5   root     4559:         case 3:
1.1.1.6   root     4560:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     4561:             gen_helper_mtc0_tcrestart(t0);
1.1.1.6   root     4562:             rn = "TCRestart";
                   4563:             break;
1.1.1.5   root     4564:         case 4:
1.1.1.6   root     4565:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     4566:             gen_helper_mtc0_tchalt(t0);
1.1.1.6   root     4567:             rn = "TCHalt";
                   4568:             break;
1.1.1.5   root     4569:         case 5:
1.1.1.6   root     4570:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     4571:             gen_helper_mtc0_tccontext(t0);
1.1.1.6   root     4572:             rn = "TCContext";
                   4573:             break;
1.1.1.5   root     4574:         case 6:
1.1.1.6   root     4575:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     4576:             gen_helper_mtc0_tcschedule(t0);
1.1.1.6   root     4577:             rn = "TCSchedule";
                   4578:             break;
1.1.1.5   root     4579:         case 7:
1.1.1.6   root     4580:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     4581:             gen_helper_mtc0_tcschefback(t0);
1.1.1.6   root     4582:             rn = "TCScheFBack";
                   4583:             break;
1.1.1.5   root     4584:         default:
                   4585:             goto die;
                   4586:         }
                   4587:         break;
                   4588:     case 3:
                   4589:         switch (sel) {
                   4590:         case 0:
1.1.1.7 ! root     4591:             gen_helper_mtc0_entrylo1(t0);
1.1.1.6   root     4592:             rn = "EntryLo1";
                   4593:             break;
1.1.1.5   root     4594:         default:
                   4595:             goto die;
1.1.1.6   root     4596:         }
1.1.1.5   root     4597:         break;
                   4598:     case 4:
                   4599:         switch (sel) {
                   4600:         case 0:
1.1.1.7 ! root     4601:             gen_helper_mtc0_context(t0);
1.1.1.6   root     4602:             rn = "Context";
                   4603:             break;
                   4604:         case 1:
1.1.1.7 ! root     4605: //           gen_helper_mtc0_contextconfig(t0); /* SmartMIPS ASE */
1.1.1.6   root     4606:             rn = "ContextConfig";
                   4607: //           break;
1.1.1.5   root     4608:         default:
                   4609:             goto die;
1.1.1.6   root     4610:         }
1.1.1.5   root     4611:         break;
                   4612:     case 5:
                   4613:         switch (sel) {
                   4614:         case 0:
1.1.1.7 ! root     4615:             gen_helper_mtc0_pagemask(t0);
1.1.1.6   root     4616:             rn = "PageMask";
                   4617:             break;
                   4618:         case 1:
                   4619:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     4620:             gen_helper_mtc0_pagegrain(t0);
1.1.1.6   root     4621:             rn = "PageGrain";
                   4622:             break;
1.1.1.5   root     4623:         default:
                   4624:             goto die;
1.1.1.6   root     4625:         }
1.1.1.5   root     4626:         break;
                   4627:     case 6:
                   4628:         switch (sel) {
                   4629:         case 0:
1.1.1.7 ! root     4630:             gen_helper_mtc0_wired(t0);
1.1.1.6   root     4631:             rn = "Wired";
                   4632:             break;
                   4633:         case 1:
                   4634:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     4635:             gen_helper_mtc0_srsconf0(t0);
1.1.1.6   root     4636:             rn = "SRSConf0";
                   4637:             break;
                   4638:         case 2:
                   4639:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     4640:             gen_helper_mtc0_srsconf1(t0);
1.1.1.6   root     4641:             rn = "SRSConf1";
                   4642:             break;
1.1.1.5   root     4643:         case 3:
1.1.1.6   root     4644:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     4645:             gen_helper_mtc0_srsconf2(t0);
1.1.1.6   root     4646:             rn = "SRSConf2";
                   4647:             break;
1.1.1.5   root     4648:         case 4:
1.1.1.6   root     4649:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     4650:             gen_helper_mtc0_srsconf3(t0);
1.1.1.6   root     4651:             rn = "SRSConf3";
                   4652:             break;
1.1.1.5   root     4653:         case 5:
1.1.1.6   root     4654:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     4655:             gen_helper_mtc0_srsconf4(t0);
1.1.1.6   root     4656:             rn = "SRSConf4";
                   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 7:
                   4663:         switch (sel) {
                   4664:         case 0:
1.1.1.6   root     4665:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     4666:             gen_helper_mtc0_hwrena(t0);
1.1.1.6   root     4667:             rn = "HWREna";
                   4668:             break;
1.1.1.5   root     4669:         default:
                   4670:             goto die;
1.1.1.6   root     4671:         }
1.1.1.5   root     4672:         break;
                   4673:     case 8:
                   4674:         /* ignored */
1.1.1.7 ! root     4675:         rn = "BadVAddr";
1.1.1.5   root     4676:         break;
                   4677:     case 9:
                   4678:         switch (sel) {
                   4679:         case 0:
1.1.1.7 ! root     4680:             gen_helper_mtc0_count(t0);
1.1.1.6   root     4681:             rn = "Count";
                   4682:             break;
                   4683:         /* 6,7 are implementation dependent */
1.1.1.5   root     4684:         default:
                   4685:             goto die;
1.1.1.6   root     4686:         }
                   4687:         /* Stop translation as we may have switched the execution mode */
                   4688:         ctx->bstate = BS_STOP;
1.1.1.5   root     4689:         break;
                   4690:     case 10:
                   4691:         switch (sel) {
                   4692:         case 0:
1.1.1.7 ! root     4693:             gen_helper_mtc0_entryhi(t0);
1.1.1.6   root     4694:             rn = "EntryHi";
                   4695:             break;
1.1.1.5   root     4696:         default:
                   4697:             goto die;
1.1.1.6   root     4698:         }
1.1.1.5   root     4699:         break;
                   4700:     case 11:
                   4701:         switch (sel) {
                   4702:         case 0:
1.1.1.7 ! root     4703:             gen_helper_mtc0_compare(t0);
1.1.1.6   root     4704:             rn = "Compare";
                   4705:             break;
                   4706:         /* 6,7 are implementation dependent */
1.1.1.5   root     4707:         default:
                   4708:             goto die;
1.1.1.6   root     4709:         }
                   4710:         /* Stop translation as we may have switched the execution mode */
                   4711:         ctx->bstate = BS_STOP;
1.1.1.5   root     4712:         break;
                   4713:     case 12:
                   4714:         switch (sel) {
                   4715:         case 0:
1.1.1.7 ! root     4716:             gen_helper_mtc0_status(t0);
1.1.1.6   root     4717:             /* BS_STOP isn't good enough here, hflags may have changed. */
                   4718:             gen_save_pc(ctx->pc + 4);
                   4719:             ctx->bstate = BS_EXCP;
                   4720:             rn = "Status";
                   4721:             break;
                   4722:         case 1:
                   4723:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     4724:             gen_helper_mtc0_intctl(t0);
1.1.1.6   root     4725:             /* Stop translation as we may have switched the execution mode */
                   4726:             ctx->bstate = BS_STOP;
                   4727:             rn = "IntCtl";
                   4728:             break;
                   4729:         case 2:
                   4730:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     4731:             gen_helper_mtc0_srsctl(t0);
1.1.1.6   root     4732:             /* Stop translation as we may have switched the execution mode */
                   4733:             ctx->bstate = BS_STOP;
                   4734:             rn = "SRSCtl";
                   4735:             break;
1.1.1.5   root     4736:         case 3:
1.1.1.6   root     4737:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     4738:             gen_mtc0_store32(t0, offsetof(CPUState, CP0_SRSMap));
1.1.1.6   root     4739:             /* Stop translation as we may have switched the execution mode */
                   4740:             ctx->bstate = BS_STOP;
                   4741:             rn = "SRSMap";
                   4742:             break;
1.1.1.5   root     4743:         default:
                   4744:             goto die;
1.1.1.6   root     4745:         }
1.1.1.5   root     4746:         break;
                   4747:     case 13:
                   4748:         switch (sel) {
                   4749:         case 0:
1.1.1.7 ! root     4750:             gen_helper_mtc0_cause(t0);
1.1.1.6   root     4751:             rn = "Cause";
                   4752:             break;
1.1.1.5   root     4753:         default:
                   4754:             goto die;
1.1.1.6   root     4755:         }
                   4756:         /* Stop translation as we may have switched the execution mode */
                   4757:         ctx->bstate = BS_STOP;
1.1.1.5   root     4758:         break;
                   4759:     case 14:
                   4760:         switch (sel) {
                   4761:         case 0:
1.1.1.7 ! root     4762:             tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_EPC));
1.1.1.6   root     4763:             rn = "EPC";
                   4764:             break;
1.1.1.5   root     4765:         default:
                   4766:             goto die;
1.1.1.6   root     4767:         }
1.1.1.5   root     4768:         break;
                   4769:     case 15:
                   4770:         switch (sel) {
                   4771:         case 0:
1.1.1.6   root     4772:             /* ignored */
                   4773:             rn = "PRid";
                   4774:             break;
                   4775:         case 1:
                   4776:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     4777:             gen_helper_mtc0_ebase(t0);
1.1.1.6   root     4778:             rn = "EBase";
                   4779:             break;
1.1.1.5   root     4780:         default:
                   4781:             goto die;
1.1.1.6   root     4782:         }
1.1.1.5   root     4783:         break;
                   4784:     case 16:
                   4785:         switch (sel) {
                   4786:         case 0:
1.1.1.7 ! root     4787:             gen_helper_mtc0_config0(t0);
1.1.1.5   root     4788:             rn = "Config";
1.1.1.6   root     4789:             /* Stop translation as we may have switched the execution mode */
                   4790:             ctx->bstate = BS_STOP;
1.1.1.5   root     4791:             break;
                   4792:         case 1:
1.1.1.6   root     4793:             /* ignored */
1.1.1.5   root     4794:             rn = "Config1";
                   4795:             break;
                   4796:         case 2:
1.1.1.7 ! root     4797:             gen_helper_mtc0_config2(t0);
1.1.1.5   root     4798:             rn = "Config2";
1.1.1.6   root     4799:             /* Stop translation as we may have switched the execution mode */
                   4800:             ctx->bstate = BS_STOP;
1.1.1.5   root     4801:             break;
                   4802:         case 3:
1.1.1.6   root     4803:             /* ignored */
1.1.1.5   root     4804:             rn = "Config3";
                   4805:             break;
                   4806:         /* 6,7 are implementation dependent */
                   4807:         default:
                   4808:             rn = "Invalid config selector";
                   4809:             goto die;
                   4810:         }
                   4811:         break;
                   4812:     case 17:
                   4813:         switch (sel) {
                   4814:         case 0:
1.1.1.6   root     4815:             /* ignored */
                   4816:             rn = "LLAddr";
                   4817:             break;
1.1.1.5   root     4818:         default:
                   4819:             goto die;
                   4820:         }
                   4821:         break;
                   4822:     case 18:
                   4823:         switch (sel) {
1.1.1.6   root     4824:         case 0 ... 7:
1.1.1.7 ! root     4825:             gen_helper_1i(mtc0_watchlo, t0, sel);
1.1.1.6   root     4826:             rn = "WatchLo";
                   4827:             break;
1.1.1.5   root     4828:         default:
                   4829:             goto die;
                   4830:         }
                   4831:         break;
                   4832:     case 19:
                   4833:         switch (sel) {
1.1.1.6   root     4834:         case 0 ... 7:
1.1.1.7 ! root     4835:             gen_helper_1i(mtc0_watchhi, t0, sel);
1.1.1.6   root     4836:             rn = "WatchHi";
                   4837:             break;
1.1.1.5   root     4838:         default:
                   4839:             goto die;
                   4840:         }
                   4841:         break;
                   4842:     case 20:
                   4843:         switch (sel) {
                   4844:         case 0:
1.1.1.6   root     4845:             check_insn(env, ctx, ISA_MIPS3);
1.1.1.7 ! root     4846:             gen_helper_mtc0_xcontext(t0);
1.1.1.6   root     4847:             rn = "XContext";
                   4848:             break;
1.1.1.5   root     4849:         default:
                   4850:             goto die;
                   4851:         }
                   4852:         break;
                   4853:     case 21:
                   4854:        /* Officially reserved, but sel 0 is used for R1x000 framemask */
                   4855:         switch (sel) {
                   4856:         case 0:
1.1.1.7 ! root     4857:             gen_helper_mtc0_framemask(t0);
1.1.1.6   root     4858:             rn = "Framemask";
                   4859:             break;
1.1.1.5   root     4860:         default:
                   4861:             goto die;
                   4862:         }
                   4863:         break;
                   4864:     case 22:
                   4865:         /* ignored */
                   4866:         rn = "Diagnostic"; /* implementation dependent */
1.1.1.6   root     4867:         break;
1.1.1.5   root     4868:     case 23:
                   4869:         switch (sel) {
                   4870:         case 0:
1.1.1.7 ! root     4871:             gen_helper_mtc0_debug(t0); /* EJTAG support */
1.1.1.6   root     4872:             /* BS_STOP isn't good enough here, hflags may have changed. */
                   4873:             gen_save_pc(ctx->pc + 4);
                   4874:             ctx->bstate = BS_EXCP;
                   4875:             rn = "Debug";
                   4876:             break;
                   4877:         case 1:
1.1.1.7 ! root     4878: //            gen_helper_mtc0_tracecontrol(t0); /* PDtrace support */
1.1.1.6   root     4879:             /* Stop translation as we may have switched the execution mode */
                   4880:             ctx->bstate = BS_STOP;
                   4881:             rn = "TraceControl";
                   4882: //            break;
                   4883:         case 2:
1.1.1.7 ! root     4884: //            gen_helper_mtc0_tracecontrol2(t0); /* PDtrace support */
1.1.1.6   root     4885:             /* Stop translation as we may have switched the execution mode */
                   4886:             ctx->bstate = BS_STOP;
                   4887:             rn = "TraceControl2";
                   4888: //            break;
                   4889:         case 3:
1.1.1.7 ! root     4890: //            gen_helper_mtc0_usertracedata(t0); /* PDtrace support */
1.1.1.6   root     4891:             /* Stop translation as we may have switched the execution mode */
                   4892:             ctx->bstate = BS_STOP;
                   4893:             rn = "UserTraceData";
                   4894: //            break;
1.1.1.5   root     4895:         case 4:
1.1.1.7 ! root     4896: //            gen_helper_mtc0_tracebpc(t0); /* PDtrace support */
1.1.1.6   root     4897:             /* Stop translation as we may have switched the execution mode */
                   4898:             ctx->bstate = BS_STOP;
                   4899:             rn = "TraceBPC";
                   4900: //            break;
1.1.1.5   root     4901:         default:
                   4902:             goto die;
                   4903:         }
                   4904:         break;
                   4905:     case 24:
                   4906:         switch (sel) {
                   4907:         case 0:
1.1.1.7 ! root     4908:             /* EJTAG support */
        !          4909:             tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_DEPC));
1.1.1.6   root     4910:             rn = "DEPC";
                   4911:             break;
1.1.1.5   root     4912:         default:
                   4913:             goto die;
                   4914:         }
                   4915:         break;
                   4916:     case 25:
                   4917:         switch (sel) {
                   4918:         case 0:
1.1.1.7 ! root     4919:             gen_helper_mtc0_performance0(t0);
1.1.1.6   root     4920:             rn = "Performance0";
                   4921:             break;
                   4922:         case 1:
1.1.1.7 ! root     4923: //            gen_helper_mtc0_performance1(t0);
1.1.1.6   root     4924:             rn = "Performance1";
                   4925: //            break;
                   4926:         case 2:
1.1.1.7 ! root     4927: //            gen_helper_mtc0_performance2(t0);
1.1.1.6   root     4928:             rn = "Performance2";
                   4929: //            break;
1.1.1.5   root     4930:         case 3:
1.1.1.7 ! root     4931: //            gen_helper_mtc0_performance3(t0);
1.1.1.6   root     4932:             rn = "Performance3";
                   4933: //            break;
1.1.1.5   root     4934:         case 4:
1.1.1.7 ! root     4935: //            gen_helper_mtc0_performance4(t0);
1.1.1.6   root     4936:             rn = "Performance4";
                   4937: //            break;
1.1.1.5   root     4938:         case 5:
1.1.1.7 ! root     4939: //            gen_helper_mtc0_performance5(t0);
1.1.1.6   root     4940:             rn = "Performance5";
                   4941: //            break;
1.1.1.5   root     4942:         case 6:
1.1.1.7 ! root     4943: //            gen_helper_mtc0_performance6(t0);
1.1.1.6   root     4944:             rn = "Performance6";
                   4945: //            break;
1.1.1.5   root     4946:         case 7:
1.1.1.7 ! root     4947: //            gen_helper_mtc0_performance7(t0);
1.1.1.6   root     4948:             rn = "Performance7";
                   4949: //            break;
1.1.1.5   root     4950:         default:
                   4951:             goto die;
                   4952:         }
1.1.1.6   root     4953:         break;
1.1.1.5   root     4954:     case 26:
1.1.1.6   root     4955:         /* ignored */
1.1.1.5   root     4956:         rn = "ECC";
1.1.1.6   root     4957:         break;
1.1.1.5   root     4958:     case 27:
                   4959:         switch (sel) {
                   4960:         case 0 ... 3:
1.1.1.6   root     4961:             /* ignored */
                   4962:             rn = "CacheErr";
                   4963:             break;
1.1.1.5   root     4964:         default:
                   4965:             goto die;
                   4966:         }
1.1.1.6   root     4967:         break;
1.1.1.5   root     4968:     case 28:
                   4969:         switch (sel) {
                   4970:         case 0:
                   4971:         case 2:
                   4972:         case 4:
                   4973:         case 6:
1.1.1.7 ! root     4974:             gen_helper_mtc0_taglo(t0);
1.1.1.5   root     4975:             rn = "TagLo";
                   4976:             break;
                   4977:         case 1:
                   4978:         case 3:
                   4979:         case 5:
                   4980:         case 7:
1.1.1.7 ! root     4981:             gen_helper_mtc0_datalo(t0);
1.1.1.5   root     4982:             rn = "DataLo";
                   4983:             break;
                   4984:         default:
                   4985:             goto die;
                   4986:         }
                   4987:         break;
                   4988:     case 29:
                   4989:         switch (sel) {
                   4990:         case 0:
                   4991:         case 2:
                   4992:         case 4:
                   4993:         case 6:
1.1.1.7 ! root     4994:             gen_helper_mtc0_taghi(t0);
1.1.1.5   root     4995:             rn = "TagHi";
                   4996:             break;
                   4997:         case 1:
                   4998:         case 3:
                   4999:         case 5:
                   5000:         case 7:
1.1.1.7 ! root     5001:             gen_helper_mtc0_datahi(t0);
1.1.1.5   root     5002:             rn = "DataHi";
                   5003:             break;
                   5004:         default:
                   5005:             rn = "invalid sel";
                   5006:             goto die;
                   5007:         }
1.1.1.6   root     5008:         break;
1.1.1.5   root     5009:     case 30:
                   5010:         switch (sel) {
                   5011:         case 0:
1.1.1.7 ! root     5012:             tcg_gen_st_tl(t0, cpu_env, offsetof(CPUState, CP0_ErrorEPC));
1.1.1.6   root     5013:             rn = "ErrorEPC";
                   5014:             break;
1.1.1.5   root     5015:         default:
                   5016:             goto die;
                   5017:         }
                   5018:         break;
                   5019:     case 31:
                   5020:         switch (sel) {
                   5021:         case 0:
1.1.1.7 ! root     5022:             /* EJTAG support */
        !          5023:             gen_mtc0_store32(t0, offsetof(CPUState, CP0_DESAVE));
1.1.1.6   root     5024:             rn = "DESAVE";
                   5025:             break;
1.1.1.5   root     5026:         default:
                   5027:             goto die;
                   5028:         }
1.1.1.6   root     5029:         /* Stop translation as we may have switched the execution mode */
                   5030:         ctx->bstate = BS_STOP;
1.1.1.5   root     5031:         break;
                   5032:     default:
1.1.1.6   root     5033:         goto die;
1.1.1.5   root     5034:     }
1.1.1.7 ! root     5035:     LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
        !          5036:     /* For simplicity assume that all writes can cause interrupts.  */
        !          5037:     if (use_icount) {
        !          5038:         gen_io_end();
        !          5039:         ctx->bstate = BS_STOP;
1.1.1.5   root     5040:     }
                   5041:     return;
                   5042: 
                   5043: die:
1.1.1.7 ! root     5044:     LOG_DISAS("dmtc0 %s (reg %d sel %d)\n", rn, reg, sel);
1.1.1.5   root     5045:     generate_exception(ctx, EXCP_RI);
                   5046: }
1.1.1.6   root     5047: #endif /* TARGET_MIPS64 */
1.1.1.5   root     5048: 
1.1.1.7 ! root     5049: static void gen_mftr(CPUState *env, DisasContext *ctx, int rt, int rd,
1.1.1.6   root     5050:                      int u, int sel, int h)
1.1.1.5   root     5051: {
1.1.1.6   root     5052:     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1.1.1.7 ! root     5053:     TCGv t0 = tcg_temp_local_new();
1.1.1.5   root     5054: 
1.1.1.6   root     5055:     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
1.1.1.7 ! root     5056:         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
        !          5057:          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
        !          5058:         tcg_gen_movi_tl(t0, -1);
1.1.1.6   root     5059:     else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
                   5060:              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
1.1.1.7 ! root     5061:         tcg_gen_movi_tl(t0, -1);
1.1.1.6   root     5062:     else if (u == 0) {
                   5063:         switch (rt) {
                   5064:         case 2:
                   5065:             switch (sel) {
                   5066:             case 1:
1.1.1.7 ! root     5067:                 gen_helper_mftc0_tcstatus(t0);
1.1.1.6   root     5068:                 break;
                   5069:             case 2:
1.1.1.7 ! root     5070:                 gen_helper_mftc0_tcbind(t0);
1.1.1.6   root     5071:                 break;
                   5072:             case 3:
1.1.1.7 ! root     5073:                 gen_helper_mftc0_tcrestart(t0);
1.1.1.6   root     5074:                 break;
                   5075:             case 4:
1.1.1.7 ! root     5076:                 gen_helper_mftc0_tchalt(t0);
1.1.1.6   root     5077:                 break;
                   5078:             case 5:
1.1.1.7 ! root     5079:                 gen_helper_mftc0_tccontext(t0);
1.1.1.6   root     5080:                 break;
                   5081:             case 6:
1.1.1.7 ! root     5082:                 gen_helper_mftc0_tcschedule(t0);
1.1.1.6   root     5083:                 break;
                   5084:             case 7:
1.1.1.7 ! root     5085:                 gen_helper_mftc0_tcschefback(t0);
1.1.1.6   root     5086:                 break;
                   5087:             default:
1.1.1.7 ! root     5088:                 gen_mfc0(env, ctx, t0, rt, sel);
1.1.1.6   root     5089:                 break;
                   5090:             }
                   5091:             break;
                   5092:         case 10:
                   5093:             switch (sel) {
                   5094:             case 0:
1.1.1.7 ! root     5095:                 gen_helper_mftc0_entryhi(t0);
1.1.1.6   root     5096:                 break;
                   5097:             default:
1.1.1.7 ! root     5098:                 gen_mfc0(env, ctx, t0, rt, sel);
1.1.1.6   root     5099:                 break;
                   5100:             }
                   5101:         case 12:
                   5102:             switch (sel) {
                   5103:             case 0:
1.1.1.7 ! root     5104:                 gen_helper_mftc0_status(t0);
1.1.1.6   root     5105:                 break;
                   5106:             default:
1.1.1.7 ! root     5107:                 gen_mfc0(env, ctx, t0, rt, sel);
1.1.1.6   root     5108:                 break;
                   5109:             }
                   5110:         case 23:
                   5111:             switch (sel) {
                   5112:             case 0:
1.1.1.7 ! root     5113:                 gen_helper_mftc0_debug(t0);
1.1.1.6   root     5114:                 break;
                   5115:             default:
1.1.1.7 ! root     5116:                 gen_mfc0(env, ctx, t0, rt, sel);
1.1.1.6   root     5117:                 break;
                   5118:             }
                   5119:             break;
                   5120:         default:
1.1.1.7 ! root     5121:             gen_mfc0(env, ctx, t0, rt, sel);
1.1.1.6   root     5122:         }
                   5123:     } else switch (sel) {
                   5124:     /* GPR registers. */
                   5125:     case 0:
1.1.1.7 ! root     5126:         gen_helper_1i(mftgpr, t0, rt);
1.1.1.6   root     5127:         break;
                   5128:     /* Auxiliary CPU registers */
                   5129:     case 1:
                   5130:         switch (rt) {
                   5131:         case 0:
1.1.1.7 ! root     5132:             gen_helper_1i(mftlo, t0, 0);
1.1.1.6   root     5133:             break;
                   5134:         case 1:
1.1.1.7 ! root     5135:             gen_helper_1i(mfthi, t0, 0);
1.1.1.6   root     5136:             break;
                   5137:         case 2:
1.1.1.7 ! root     5138:             gen_helper_1i(mftacx, t0, 0);
1.1.1.6   root     5139:             break;
                   5140:         case 4:
1.1.1.7 ! root     5141:             gen_helper_1i(mftlo, t0, 1);
1.1.1.6   root     5142:             break;
                   5143:         case 5:
1.1.1.7 ! root     5144:             gen_helper_1i(mfthi, t0, 1);
1.1.1.6   root     5145:             break;
                   5146:         case 6:
1.1.1.7 ! root     5147:             gen_helper_1i(mftacx, t0, 1);
1.1.1.6   root     5148:             break;
                   5149:         case 8:
1.1.1.7 ! root     5150:             gen_helper_1i(mftlo, t0, 2);
1.1.1.6   root     5151:             break;
                   5152:         case 9:
1.1.1.7 ! root     5153:             gen_helper_1i(mfthi, t0, 2);
1.1.1.6   root     5154:             break;
                   5155:         case 10:
1.1.1.7 ! root     5156:             gen_helper_1i(mftacx, t0, 2);
1.1.1.6   root     5157:             break;
                   5158:         case 12:
1.1.1.7 ! root     5159:             gen_helper_1i(mftlo, t0, 3);
1.1.1.6   root     5160:             break;
                   5161:         case 13:
1.1.1.7 ! root     5162:             gen_helper_1i(mfthi, t0, 3);
1.1.1.6   root     5163:             break;
                   5164:         case 14:
1.1.1.7 ! root     5165:             gen_helper_1i(mftacx, t0, 3);
1.1.1.6   root     5166:             break;
                   5167:         case 16:
1.1.1.7 ! root     5168:             gen_helper_mftdsp(t0);
1.1.1.6   root     5169:             break;
                   5170:         default:
                   5171:             goto die;
                   5172:         }
                   5173:         break;
                   5174:     /* Floating point (COP1). */
                   5175:     case 2:
                   5176:         /* XXX: For now we support only a single FPU context. */
                   5177:         if (h == 0) {
1.1.1.7 ! root     5178:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          5179: 
        !          5180:             gen_load_fpr32(fp0, rt);
        !          5181:             tcg_gen_ext_i32_tl(t0, fp0);
        !          5182:             tcg_temp_free_i32(fp0);
1.1.1.6   root     5183:         } else {
1.1.1.7 ! root     5184:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          5185: 
        !          5186:             gen_load_fpr32h(fp0, rt);
        !          5187:             tcg_gen_ext_i32_tl(t0, fp0);
        !          5188:             tcg_temp_free_i32(fp0);
1.1.1.6   root     5189:         }
                   5190:         break;
                   5191:     case 3:
                   5192:         /* XXX: For now we support only a single FPU context. */
1.1.1.7 ! root     5193:         gen_helper_1i(cfc1, t0, rt);
1.1.1.6   root     5194:         break;
                   5195:     /* COP2: Not implemented. */
                   5196:     case 4:
                   5197:     case 5:
                   5198:         /* fall through */
                   5199:     default:
                   5200:         goto die;
                   5201:     }
1.1.1.7 ! root     5202:     LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
        !          5203:     gen_store_gpr(t0, rd);
        !          5204:     tcg_temp_free(t0);
1.1.1.6   root     5205:     return;
                   5206: 
                   5207: die:
1.1.1.7 ! root     5208:     tcg_temp_free(t0);
        !          5209:     LOG_DISAS("mftr (reg %d u %d sel %d h %d)\n", rt, u, sel, h);
1.1.1.6   root     5210:     generate_exception(ctx, EXCP_RI);
                   5211: }
                   5212: 
1.1.1.7 ! root     5213: static void gen_mttr(CPUState *env, DisasContext *ctx, int rd, int rt,
1.1.1.6   root     5214:                      int u, int sel, int h)
                   5215: {
                   5216:     int other_tc = env->CP0_VPEControl & (0xff << CP0VPECo_TargTC);
1.1.1.7 ! root     5217:     TCGv t0 = tcg_temp_local_new();
1.1.1.6   root     5218: 
1.1.1.7 ! root     5219:     gen_load_gpr(t0, rt);
1.1.1.6   root     5220:     if ((env->CP0_VPEConf0 & (1 << CP0VPEC0_MVP)) == 0 &&
1.1.1.7 ! root     5221:         ((env->tcs[other_tc].CP0_TCBind & (0xf << CP0TCBd_CurVPE)) !=
        !          5222:          (env->active_tc.CP0_TCBind & (0xf << CP0TCBd_CurVPE))))
1.1.1.6   root     5223:         /* NOP */ ;
                   5224:     else if ((env->CP0_VPEControl & (0xff << CP0VPECo_TargTC)) >
                   5225:              (env->mvp->CP0_MVPConf0 & (0xff << CP0MVPC0_PTC)))
                   5226:         /* NOP */ ;
                   5227:     else if (u == 0) {
                   5228:         switch (rd) {
                   5229:         case 2:
                   5230:             switch (sel) {
                   5231:             case 1:
1.1.1.7 ! root     5232:                 gen_helper_mttc0_tcstatus(t0);
1.1.1.6   root     5233:                 break;
                   5234:             case 2:
1.1.1.7 ! root     5235:                 gen_helper_mttc0_tcbind(t0);
1.1.1.6   root     5236:                 break;
                   5237:             case 3:
1.1.1.7 ! root     5238:                 gen_helper_mttc0_tcrestart(t0);
1.1.1.6   root     5239:                 break;
                   5240:             case 4:
1.1.1.7 ! root     5241:                 gen_helper_mttc0_tchalt(t0);
1.1.1.6   root     5242:                 break;
                   5243:             case 5:
1.1.1.7 ! root     5244:                 gen_helper_mttc0_tccontext(t0);
1.1.1.6   root     5245:                 break;
                   5246:             case 6:
1.1.1.7 ! root     5247:                 gen_helper_mttc0_tcschedule(t0);
1.1.1.6   root     5248:                 break;
                   5249:             case 7:
1.1.1.7 ! root     5250:                 gen_helper_mttc0_tcschefback(t0);
1.1.1.6   root     5251:                 break;
                   5252:             default:
1.1.1.7 ! root     5253:                 gen_mtc0(env, ctx, t0, rd, sel);
1.1.1.6   root     5254:                 break;
                   5255:             }
                   5256:             break;
                   5257:         case 10:
                   5258:             switch (sel) {
                   5259:             case 0:
1.1.1.7 ! root     5260:                 gen_helper_mttc0_entryhi(t0);
1.1.1.6   root     5261:                 break;
                   5262:             default:
1.1.1.7 ! root     5263:                 gen_mtc0(env, ctx, t0, rd, sel);
1.1.1.6   root     5264:                 break;
                   5265:             }
                   5266:         case 12:
                   5267:             switch (sel) {
                   5268:             case 0:
1.1.1.7 ! root     5269:                 gen_helper_mttc0_status(t0);
1.1.1.6   root     5270:                 break;
                   5271:             default:
1.1.1.7 ! root     5272:                 gen_mtc0(env, ctx, t0, rd, sel);
1.1.1.6   root     5273:                 break;
                   5274:             }
                   5275:         case 23:
                   5276:             switch (sel) {
                   5277:             case 0:
1.1.1.7 ! root     5278:                 gen_helper_mttc0_debug(t0);
1.1.1.6   root     5279:                 break;
                   5280:             default:
1.1.1.7 ! root     5281:                 gen_mtc0(env, ctx, t0, rd, sel);
1.1.1.6   root     5282:                 break;
                   5283:             }
                   5284:             break;
                   5285:         default:
1.1.1.7 ! root     5286:             gen_mtc0(env, ctx, t0, rd, sel);
1.1.1.6   root     5287:         }
                   5288:     } else switch (sel) {
                   5289:     /* GPR registers. */
                   5290:     case 0:
1.1.1.7 ! root     5291:         gen_helper_1i(mttgpr, t0, rd);
1.1.1.6   root     5292:         break;
                   5293:     /* Auxiliary CPU registers */
                   5294:     case 1:
                   5295:         switch (rd) {
                   5296:         case 0:
1.1.1.7 ! root     5297:             gen_helper_1i(mttlo, t0, 0);
1.1.1.6   root     5298:             break;
                   5299:         case 1:
1.1.1.7 ! root     5300:             gen_helper_1i(mtthi, t0, 0);
1.1.1.6   root     5301:             break;
                   5302:         case 2:
1.1.1.7 ! root     5303:             gen_helper_1i(mttacx, t0, 0);
1.1.1.6   root     5304:             break;
                   5305:         case 4:
1.1.1.7 ! root     5306:             gen_helper_1i(mttlo, t0, 1);
1.1.1.6   root     5307:             break;
                   5308:         case 5:
1.1.1.7 ! root     5309:             gen_helper_1i(mtthi, t0, 1);
1.1.1.6   root     5310:             break;
                   5311:         case 6:
1.1.1.7 ! root     5312:             gen_helper_1i(mttacx, t0, 1);
1.1.1.6   root     5313:             break;
                   5314:         case 8:
1.1.1.7 ! root     5315:             gen_helper_1i(mttlo, t0, 2);
1.1.1.6   root     5316:             break;
                   5317:         case 9:
1.1.1.7 ! root     5318:             gen_helper_1i(mtthi, t0, 2);
1.1.1.6   root     5319:             break;
                   5320:         case 10:
1.1.1.7 ! root     5321:             gen_helper_1i(mttacx, t0, 2);
1.1.1.6   root     5322:             break;
                   5323:         case 12:
1.1.1.7 ! root     5324:             gen_helper_1i(mttlo, t0, 3);
1.1.1.6   root     5325:             break;
                   5326:         case 13:
1.1.1.7 ! root     5327:             gen_helper_1i(mtthi, t0, 3);
1.1.1.6   root     5328:             break;
                   5329:         case 14:
1.1.1.7 ! root     5330:             gen_helper_1i(mttacx, t0, 3);
1.1.1.6   root     5331:             break;
                   5332:         case 16:
1.1.1.7 ! root     5333:             gen_helper_mttdsp(t0);
1.1.1.6   root     5334:             break;
                   5335:         default:
                   5336:             goto die;
                   5337:         }
                   5338:         break;
                   5339:     /* Floating point (COP1). */
                   5340:     case 2:
                   5341:         /* XXX: For now we support only a single FPU context. */
                   5342:         if (h == 0) {
1.1.1.7 ! root     5343:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          5344: 
        !          5345:             tcg_gen_trunc_tl_i32(fp0, t0);
        !          5346:             gen_store_fpr32(fp0, rd);
        !          5347:             tcg_temp_free_i32(fp0);
1.1.1.6   root     5348:         } else {
1.1.1.7 ! root     5349:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          5350: 
        !          5351:             tcg_gen_trunc_tl_i32(fp0, t0);
        !          5352:             gen_store_fpr32h(fp0, rd);
        !          5353:             tcg_temp_free_i32(fp0);
1.1.1.6   root     5354:         }
                   5355:         break;
                   5356:     case 3:
                   5357:         /* XXX: For now we support only a single FPU context. */
1.1.1.7 ! root     5358:         gen_helper_1i(ctc1, t0, rd);
1.1.1.6   root     5359:         break;
                   5360:     /* COP2: Not implemented. */
                   5361:     case 4:
                   5362:     case 5:
                   5363:         /* fall through */
                   5364:     default:
                   5365:         goto die;
                   5366:     }
1.1.1.7 ! root     5367:     LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
        !          5368:     tcg_temp_free(t0);
1.1.1.6   root     5369:     return;
                   5370: 
                   5371: die:
1.1.1.7 ! root     5372:     tcg_temp_free(t0);
        !          5373:     LOG_DISAS("mttr (reg %d u %d sel %d h %d)\n", rd, u, sel, h);
1.1.1.6   root     5374:     generate_exception(ctx, EXCP_RI);
                   5375: }
                   5376: 
                   5377: static void gen_cp0 (CPUState *env, DisasContext *ctx, uint32_t opc, int rt, int rd)
                   5378: {
                   5379:     const char *opn = "ldst";
1.1.1.5   root     5380: 
                   5381:     switch (opc) {
                   5382:     case OPC_MFC0:
                   5383:         if (rt == 0) {
1.1.1.6   root     5384:             /* Treat as NOP. */
1.1.1.5   root     5385:             return;
                   5386:         }
1.1.1.7 ! root     5387:         {
        !          5388:             TCGv t0 = tcg_temp_local_new();
        !          5389: 
        !          5390:             gen_mfc0(env, ctx, t0, rd, ctx->opcode & 0x7);
        !          5391:             gen_store_gpr(t0, rt);
        !          5392:             tcg_temp_free(t0);
        !          5393:         }
1.1.1.5   root     5394:         opn = "mfc0";
                   5395:         break;
                   5396:     case OPC_MTC0:
1.1.1.7 ! root     5397:         {
        !          5398:             TCGv t0 = tcg_temp_local_new();
        !          5399: 
        !          5400:             gen_load_gpr(t0, rt);
        !          5401:             save_cpu_state(ctx, 1);
        !          5402:             gen_mtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
        !          5403:             tcg_temp_free(t0);
        !          5404:         }
1.1.1.5   root     5405:         opn = "mtc0";
                   5406:         break;
1.1.1.6   root     5407: #if defined(TARGET_MIPS64)
1.1.1.5   root     5408:     case OPC_DMFC0:
1.1.1.6   root     5409:         check_insn(env, ctx, ISA_MIPS3);
1.1.1.5   root     5410:         if (rt == 0) {
1.1.1.6   root     5411:             /* Treat as NOP. */
1.1.1.5   root     5412:             return;
                   5413:         }
1.1.1.7 ! root     5414:         {
        !          5415:             TCGv t0 = tcg_temp_local_new();
        !          5416: 
        !          5417:             gen_dmfc0(env, ctx, t0, rd, ctx->opcode & 0x7);
        !          5418:             gen_store_gpr(t0, rt);
        !          5419:             tcg_temp_free(t0);
        !          5420:         }
1.1.1.5   root     5421:         opn = "dmfc0";
                   5422:         break;
                   5423:     case OPC_DMTC0:
1.1.1.6   root     5424:         check_insn(env, ctx, ISA_MIPS3);
1.1.1.7 ! root     5425:         {
        !          5426:             TCGv t0 = tcg_temp_local_new();
        !          5427: 
        !          5428:             gen_load_gpr(t0, rt);
        !          5429:             save_cpu_state(ctx, 1);
        !          5430:             gen_dmtc0(env, ctx, t0, rd, ctx->opcode & 0x7);
        !          5431:             tcg_temp_free(t0);
        !          5432:         }
1.1.1.5   root     5433:         opn = "dmtc0";
                   5434:         break;
1.1.1.6   root     5435: #endif
                   5436:     case OPC_MFTR:
                   5437:         check_insn(env, ctx, ASE_MT);
                   5438:         if (rd == 0) {
                   5439:             /* Treat as NOP. */
                   5440:             return;
                   5441:         }
1.1.1.7 ! root     5442:         gen_mftr(env, ctx, rt, rd, (ctx->opcode >> 5) & 1,
1.1.1.6   root     5443:                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
                   5444:         opn = "mftr";
                   5445:         break;
                   5446:     case OPC_MTTR:
                   5447:         check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     5448:         gen_mttr(env, ctx, rd, rt, (ctx->opcode >> 5) & 1,
1.1.1.6   root     5449:                  ctx->opcode & 0x7, (ctx->opcode >> 4) & 1);
                   5450:         opn = "mttr";
                   5451:         break;
1.1.1.5   root     5452:     case OPC_TLBWI:
                   5453:         opn = "tlbwi";
1.1.1.6   root     5454:         if (!env->tlb->do_tlbwi)
                   5455:             goto die;
1.1.1.7 ! root     5456:         gen_helper_tlbwi();
1.1.1.5   root     5457:         break;
                   5458:     case OPC_TLBWR:
                   5459:         opn = "tlbwr";
1.1.1.6   root     5460:         if (!env->tlb->do_tlbwr)
                   5461:             goto die;
1.1.1.7 ! root     5462:         gen_helper_tlbwr();
1.1.1.5   root     5463:         break;
                   5464:     case OPC_TLBP:
                   5465:         opn = "tlbp";
1.1.1.6   root     5466:         if (!env->tlb->do_tlbp)
                   5467:             goto die;
1.1.1.7 ! root     5468:         gen_helper_tlbp();
1.1.1.5   root     5469:         break;
                   5470:     case OPC_TLBR:
                   5471:         opn = "tlbr";
1.1.1.6   root     5472:         if (!env->tlb->do_tlbr)
                   5473:             goto die;
1.1.1.7 ! root     5474:         gen_helper_tlbr();
1.1.1.5   root     5475:         break;
                   5476:     case OPC_ERET:
                   5477:         opn = "eret";
1.1.1.6   root     5478:         check_insn(env, ctx, ISA_MIPS2);
                   5479:         save_cpu_state(ctx, 1);
1.1.1.7 ! root     5480:         gen_helper_eret();
1.1.1.5   root     5481:         ctx->bstate = BS_EXCP;
                   5482:         break;
                   5483:     case OPC_DERET:
                   5484:         opn = "deret";
1.1.1.6   root     5485:         check_insn(env, ctx, ISA_MIPS32);
1.1.1.5   root     5486:         if (!(ctx->hflags & MIPS_HFLAG_DM)) {
1.1.1.6   root     5487:             MIPS_INVAL(opn);
1.1.1.5   root     5488:             generate_exception(ctx, EXCP_RI);
                   5489:         } else {
1.1.1.6   root     5490:             save_cpu_state(ctx, 1);
1.1.1.7 ! root     5491:             gen_helper_deret();
1.1.1.5   root     5492:             ctx->bstate = BS_EXCP;
                   5493:         }
                   5494:         break;
                   5495:     case OPC_WAIT:
                   5496:         opn = "wait";
1.1.1.6   root     5497:         check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
1.1.1.5   root     5498:         /* If we get an exception, we want to restart at next instruction */
                   5499:         ctx->pc += 4;
                   5500:         save_cpu_state(ctx, 1);
                   5501:         ctx->pc -= 4;
1.1.1.7 ! root     5502:         gen_helper_wait();
1.1.1.5   root     5503:         ctx->bstate = BS_EXCP;
                   5504:         break;
                   5505:     default:
1.1.1.6   root     5506:  die:
                   5507:         MIPS_INVAL(opn);
1.1.1.5   root     5508:         generate_exception(ctx, EXCP_RI);
                   5509:         return;
                   5510:     }
                   5511:     MIPS_DEBUG("%s %s %d", opn, regnames[rt], rd);
                   5512: }
1.1.1.7 ! root     5513: #endif /* !CONFIG_USER_ONLY */
1.1.1.5   root     5514: 
                   5515: /* CP1 Branches (before delay slot) */
1.1.1.6   root     5516: static void gen_compute_branch1 (CPUState *env, DisasContext *ctx, uint32_t op,
                   5517:                                  int32_t cc, int32_t offset)
1.1.1.5   root     5518: {
                   5519:     target_ulong btarget;
1.1.1.6   root     5520:     const char *opn = "cp1 cond branch";
1.1.1.7 ! root     5521:     TCGv_i32 t0 = tcg_temp_new_i32();
1.1.1.6   root     5522: 
                   5523:     if (cc != 0)
                   5524:         check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
1.1.1.5   root     5525: 
                   5526:     btarget = ctx->pc + 4 + offset;
                   5527: 
                   5528:     switch (op) {
                   5529:     case OPC_BC1F:
1.1.1.7 ! root     5530:         {
        !          5531:             int l1 = gen_new_label();
        !          5532:             int l2 = gen_new_label();
        !          5533: 
        !          5534:             get_fp_cond(t0);
        !          5535:             tcg_gen_andi_i32(t0, t0, 0x1 << cc);
        !          5536:             tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
        !          5537:             tcg_gen_movi_i32(bcond, 0);
        !          5538:             tcg_gen_br(l2);
        !          5539:             gen_set_label(l1);
        !          5540:             tcg_gen_movi_i32(bcond, 1);
        !          5541:             gen_set_label(l2);
        !          5542:         }
1.1.1.6   root     5543:         opn = "bc1f";
1.1.1.5   root     5544:         goto not_likely;
                   5545:     case OPC_BC1FL:
1.1.1.7 ! root     5546:         {
        !          5547:             int l1 = gen_new_label();
        !          5548:             int l2 = gen_new_label();
        !          5549: 
        !          5550:             get_fp_cond(t0);
        !          5551:             tcg_gen_andi_i32(t0, t0, 0x1 << cc);
        !          5552:             tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
        !          5553:             tcg_gen_movi_i32(bcond, 0);
        !          5554:             tcg_gen_br(l2);
        !          5555:             gen_set_label(l1);
        !          5556:             tcg_gen_movi_i32(bcond, 1);
        !          5557:             gen_set_label(l2);
        !          5558:         }
1.1.1.6   root     5559:         opn = "bc1fl";
1.1.1.5   root     5560:         goto likely;
                   5561:     case OPC_BC1T:
1.1.1.7 ! root     5562:         {
        !          5563:             int l1 = gen_new_label();
        !          5564:             int l2 = gen_new_label();
        !          5565: 
        !          5566:             get_fp_cond(t0);
        !          5567:             tcg_gen_andi_i32(t0, t0, 0x1 << cc);
        !          5568:             tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
        !          5569:             tcg_gen_movi_i32(bcond, 0);
        !          5570:             tcg_gen_br(l2);
        !          5571:             gen_set_label(l1);
        !          5572:             tcg_gen_movi_i32(bcond, 1);
        !          5573:             gen_set_label(l2);
        !          5574:         }
1.1.1.6   root     5575:         opn = "bc1t";
                   5576:         goto not_likely;
1.1.1.5   root     5577:     case OPC_BC1TL:
1.1.1.7 ! root     5578:         {
        !          5579:             int l1 = gen_new_label();
        !          5580:             int l2 = gen_new_label();
        !          5581: 
        !          5582:             get_fp_cond(t0);
        !          5583:             tcg_gen_andi_i32(t0, t0, 0x1 << cc);
        !          5584:             tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
        !          5585:             tcg_gen_movi_i32(bcond, 0);
        !          5586:             tcg_gen_br(l2);
        !          5587:             gen_set_label(l1);
        !          5588:             tcg_gen_movi_i32(bcond, 1);
        !          5589:             gen_set_label(l2);
        !          5590:         }
1.1.1.6   root     5591:         opn = "bc1tl";
1.1.1.5   root     5592:     likely:
                   5593:         ctx->hflags |= MIPS_HFLAG_BL;
1.1.1.6   root     5594:         break;
                   5595:     case OPC_BC1FANY2:
1.1.1.7 ! root     5596:         {
        !          5597:             int l1 = gen_new_label();
        !          5598:             int l2 = gen_new_label();
        !          5599: 
        !          5600:             get_fp_cond(t0);
        !          5601:             tcg_gen_andi_i32(t0, t0, 0x3 << cc);
        !          5602:             tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
        !          5603:             tcg_gen_movi_i32(bcond, 0);
        !          5604:             tcg_gen_br(l2);
        !          5605:             gen_set_label(l1);
        !          5606:             tcg_gen_movi_i32(bcond, 1);
        !          5607:             gen_set_label(l2);
        !          5608:         }
1.1.1.6   root     5609:         opn = "bc1any2f";
                   5610:         goto not_likely;
                   5611:     case OPC_BC1TANY2:
1.1.1.7 ! root     5612:         {
        !          5613:             int l1 = gen_new_label();
        !          5614:             int l2 = gen_new_label();
        !          5615: 
        !          5616:             get_fp_cond(t0);
        !          5617:             tcg_gen_andi_i32(t0, t0, 0x3 << cc);
        !          5618:             tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
        !          5619:             tcg_gen_movi_i32(bcond, 0);
        !          5620:             tcg_gen_br(l2);
        !          5621:             gen_set_label(l1);
        !          5622:             tcg_gen_movi_i32(bcond, 1);
        !          5623:             gen_set_label(l2);
        !          5624:         }
1.1.1.6   root     5625:         opn = "bc1any2t";
                   5626:         goto not_likely;
                   5627:     case OPC_BC1FANY4:
1.1.1.7 ! root     5628:         {
        !          5629:             int l1 = gen_new_label();
        !          5630:             int l2 = gen_new_label();
        !          5631: 
        !          5632:             get_fp_cond(t0);
        !          5633:             tcg_gen_andi_i32(t0, t0, 0xf << cc);
        !          5634:             tcg_gen_brcondi_i32(TCG_COND_EQ, t0, 0, l1);
        !          5635:             tcg_gen_movi_i32(bcond, 0);
        !          5636:             tcg_gen_br(l2);
        !          5637:             gen_set_label(l1);
        !          5638:             tcg_gen_movi_i32(bcond, 1);
        !          5639:             gen_set_label(l2);
        !          5640:         }
1.1.1.6   root     5641:         opn = "bc1any4f";
                   5642:         goto not_likely;
                   5643:     case OPC_BC1TANY4:
1.1.1.7 ! root     5644:         {
        !          5645:             int l1 = gen_new_label();
        !          5646:             int l2 = gen_new_label();
        !          5647: 
        !          5648:             get_fp_cond(t0);
        !          5649:             tcg_gen_andi_i32(t0, t0, 0xf << cc);
        !          5650:             tcg_gen_brcondi_i32(TCG_COND_NE, t0, 0, l1);
        !          5651:             tcg_gen_movi_i32(bcond, 0);
        !          5652:             tcg_gen_br(l2);
        !          5653:             gen_set_label(l1);
        !          5654:             tcg_gen_movi_i32(bcond, 1);
        !          5655:             gen_set_label(l2);
        !          5656:         }
1.1.1.6   root     5657:         opn = "bc1any4t";
                   5658:     not_likely:
                   5659:         ctx->hflags |= MIPS_HFLAG_BC;
1.1.1.5   root     5660:         break;
1.1.1.6   root     5661:     default:
                   5662:         MIPS_INVAL(opn);
                   5663:         generate_exception (ctx, EXCP_RI);
1.1.1.7 ! root     5664:         goto out;
1.1.1.5   root     5665:     }
1.1.1.6   root     5666:     MIPS_DEBUG("%s: cond %02x target " TARGET_FMT_lx, opn,
1.1.1.5   root     5667:                ctx->hflags, btarget);
                   5668:     ctx->btarget = btarget;
1.1.1.7 ! root     5669: 
        !          5670:  out:
        !          5671:     tcg_temp_free_i32(t0);
1.1.1.5   root     5672: }
                   5673: 
                   5674: /* Coprocessor 1 (FPU) */
1.1.1.6   root     5675: 
                   5676: #define FOP(func, fmt) (((fmt) << 21) | (func))
                   5677: 
1.1.1.5   root     5678: static void gen_cp1 (DisasContext *ctx, uint32_t opc, int rt, int fs)
                   5679: {
1.1.1.6   root     5680:     const char *opn = "cp1 move";
1.1.1.7 ! root     5681:     TCGv t0 = tcg_temp_local_new();
1.1.1.5   root     5682: 
                   5683:     switch (opc) {
                   5684:     case OPC_MFC1:
1.1.1.7 ! root     5685:         {
        !          5686:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          5687: 
        !          5688:             gen_load_fpr32(fp0, fs);
        !          5689:             tcg_gen_ext_i32_tl(t0, fp0);
        !          5690:             tcg_temp_free_i32(fp0);
        !          5691:         }
        !          5692:         gen_store_gpr(t0, rt);
1.1.1.5   root     5693:         opn = "mfc1";
                   5694:         break;
                   5695:     case OPC_MTC1:
1.1.1.7 ! root     5696:         gen_load_gpr(t0, rt);
        !          5697:         {
        !          5698:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          5699: 
        !          5700:             tcg_gen_trunc_tl_i32(fp0, t0);
        !          5701:             gen_store_fpr32(fp0, fs);
        !          5702:             tcg_temp_free_i32(fp0);
        !          5703:         }
1.1.1.5   root     5704:         opn = "mtc1";
                   5705:         break;
                   5706:     case OPC_CFC1:
1.1.1.7 ! root     5707:         gen_helper_1i(cfc1, t0, fs);
        !          5708:         gen_store_gpr(t0, rt);
1.1.1.5   root     5709:         opn = "cfc1";
                   5710:         break;
                   5711:     case OPC_CTC1:
1.1.1.7 ! root     5712:         gen_load_gpr(t0, rt);
        !          5713:         gen_helper_1i(ctc1, t0, fs);
1.1.1.5   root     5714:         opn = "ctc1";
                   5715:         break;
                   5716:     case OPC_DMFC1:
1.1.1.7 ! root     5717:         {
        !          5718:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          5719: 
        !          5720:             gen_load_fpr64(ctx, fp0, fs);
        !          5721:             tcg_gen_trunc_i64_tl(t0, fp0);
        !          5722:             tcg_temp_free_i64(fp0);
        !          5723:         }
        !          5724:         gen_store_gpr(t0, rt);
1.1.1.6   root     5725:         opn = "dmfc1";
                   5726:         break;
1.1.1.5   root     5727:     case OPC_DMTC1:
1.1.1.7 ! root     5728:         gen_load_gpr(t0, rt);
        !          5729:         {
        !          5730:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          5731: 
        !          5732:             tcg_gen_extu_tl_i64(fp0, t0);
        !          5733:             gen_store_fpr64(ctx, fp0, fs);
        !          5734:             tcg_temp_free_i64(fp0);
        !          5735:         }
1.1.1.6   root     5736:         opn = "dmtc1";
                   5737:         break;
                   5738:     case OPC_MFHC1:
1.1.1.7 ! root     5739:         {
        !          5740:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          5741: 
        !          5742:             gen_load_fpr32h(fp0, fs);
        !          5743:             tcg_gen_ext_i32_tl(t0, fp0);
        !          5744:             tcg_temp_free_i32(fp0);
        !          5745:         }
        !          5746:         gen_store_gpr(t0, rt);
1.1.1.6   root     5747:         opn = "mfhc1";
                   5748:         break;
                   5749:     case OPC_MTHC1:
1.1.1.7 ! root     5750:         gen_load_gpr(t0, rt);
        !          5751:         {
        !          5752:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          5753: 
        !          5754:             tcg_gen_trunc_tl_i32(fp0, t0);
        !          5755:             gen_store_fpr32h(fp0, fs);
        !          5756:             tcg_temp_free_i32(fp0);
        !          5757:         }
1.1.1.6   root     5758:         opn = "mthc1";
                   5759:         break;
1.1.1.5   root     5760:     default:
1.1.1.6   root     5761:         MIPS_INVAL(opn);
                   5762:         generate_exception (ctx, EXCP_RI);
1.1.1.7 ! root     5763:         goto out;
1.1.1.4   root     5764:     }
                   5765:     MIPS_DEBUG("%s %s %s", opn, regnames[rt], fregnames[fs]);
1.1.1.7 ! root     5766: 
        !          5767:  out:
        !          5768:     tcg_temp_free(t0);
1.1.1.4   root     5769: }
                   5770: 
1.1.1.6   root     5771: static void gen_movci (DisasContext *ctx, int rd, int rs, int cc, int tf)
                   5772: {
1.1.1.7 ! root     5773:     int l1 = gen_new_label();
1.1.1.6   root     5774:     uint32_t ccbit;
1.1.1.7 ! root     5775:     TCGCond cond;
        !          5776:     TCGv t0 = tcg_temp_local_new();
        !          5777:     TCGv_i32 r_tmp = tcg_temp_new_i32();
        !          5778: 
        !          5779:     if (cc)
        !          5780:         ccbit = 1 << (24 + cc);
        !          5781:     else
        !          5782:         ccbit = 1 << 23;
        !          5783:     if (tf)
        !          5784:         cond = TCG_COND_EQ;
        !          5785:     else
        !          5786:         cond = TCG_COND_NE;
        !          5787: 
        !          5788:     gen_load_gpr(t0, rd);
        !          5789:     tcg_gen_andi_i32(r_tmp, fpu_fcr31, ccbit);
        !          5790:     tcg_gen_brcondi_i32(cond, r_tmp, 0, l1);
        !          5791:     tcg_temp_free_i32(r_tmp);
        !          5792:     gen_load_gpr(t0, rs);
        !          5793:     gen_set_label(l1);
        !          5794:     gen_store_gpr(t0, rd);
        !          5795:     tcg_temp_free(t0);
        !          5796: }
        !          5797: 
        !          5798: static inline void gen_movcf_s (int fs, int fd, int cc, int tf)
        !          5799: {
        !          5800:     uint32_t ccbit;
        !          5801:     int cond;
        !          5802:     TCGv_i32 r_tmp1 = tcg_temp_new_i32();
        !          5803:     TCGv_i32 fp0 = tcg_temp_local_new_i32();
        !          5804:     int l1 = gen_new_label();
        !          5805: 
        !          5806:     if (cc)
        !          5807:         ccbit = 1 << (24 + cc);
        !          5808:     else
        !          5809:         ccbit = 1 << 23;
        !          5810: 
        !          5811:     if (tf)
        !          5812:         cond = TCG_COND_EQ;
        !          5813:     else
        !          5814:         cond = TCG_COND_NE;
        !          5815: 
        !          5816:     gen_load_fpr32(fp0, fd);
        !          5817:     tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
        !          5818:     tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
        !          5819:     tcg_temp_free_i32(r_tmp1);
        !          5820:     gen_load_fpr32(fp0, fs);
        !          5821:     gen_set_label(l1);
        !          5822:     gen_store_fpr32(fp0, fd);
        !          5823:     tcg_temp_free_i32(fp0);
        !          5824: }
        !          5825: 
        !          5826: static inline void gen_movcf_d (DisasContext *ctx, int fs, int fd, int cc, int tf)
        !          5827: {
        !          5828:     uint32_t ccbit;
        !          5829:     int cond;
        !          5830:     TCGv_i32 r_tmp1 = tcg_temp_new_i32();
        !          5831:     TCGv_i64 fp0 = tcg_temp_local_new_i64();
        !          5832:     int l1 = gen_new_label();
        !          5833: 
        !          5834:     if (cc)
        !          5835:         ccbit = 1 << (24 + cc);
        !          5836:     else
        !          5837:         ccbit = 1 << 23;
        !          5838: 
        !          5839:     if (tf)
        !          5840:         cond = TCG_COND_EQ;
        !          5841:     else
        !          5842:         cond = TCG_COND_NE;
        !          5843: 
        !          5844:     gen_load_fpr64(ctx, fp0, fd);
        !          5845:     tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit);
        !          5846:     tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
        !          5847:     tcg_temp_free_i32(r_tmp1);
        !          5848:     gen_load_fpr64(ctx, fp0, fs);
        !          5849:     gen_set_label(l1);
        !          5850:     gen_store_fpr64(ctx, fp0, fd);
        !          5851:     tcg_temp_free_i64(fp0);
        !          5852: }
        !          5853: 
        !          5854: static inline void gen_movcf_ps (int fs, int fd, int cc, int tf)
        !          5855: {
        !          5856:     uint32_t ccbit1, ccbit2;
        !          5857:     int cond;
        !          5858:     TCGv_i32 r_tmp1 = tcg_temp_new_i32();
        !          5859:     TCGv_i32 fp0 = tcg_temp_local_new_i32();
        !          5860:     int l1 = gen_new_label();
        !          5861:     int l2 = gen_new_label();
1.1.1.4   root     5862: 
1.1.1.6   root     5863:     if (cc) {
1.1.1.7 ! root     5864:         ccbit1 = 1 << (24 + cc);
        !          5865:         ccbit2 = 1 << (25 + cc);
        !          5866:     } else {
        !          5867:         ccbit1 = 1 << 23;
        !          5868:         ccbit2 = 1 << 25;
        !          5869:     }
        !          5870: 
        !          5871:     if (tf)
        !          5872:         cond = TCG_COND_EQ;
1.1.1.6   root     5873:     else
1.1.1.7 ! root     5874:         cond = TCG_COND_NE;
        !          5875: 
        !          5876:     gen_load_fpr32(fp0, fd);
        !          5877:     tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit1);
        !          5878:     tcg_gen_brcondi_i32(cond, r_tmp1, 0, l1);
        !          5879:     gen_load_fpr32(fp0, fs);
        !          5880:     gen_set_label(l1);
        !          5881:     gen_store_fpr32(fp0, fd);
        !          5882: 
        !          5883:     gen_load_fpr32h(fp0, fd);
        !          5884:     tcg_gen_andi_i32(r_tmp1, fpu_fcr31, ccbit2);
        !          5885:     tcg_gen_brcondi_i32(cond, r_tmp1, 0, l2);
        !          5886:     gen_load_fpr32h(fp0, fs);
        !          5887:     gen_set_label(l2);
        !          5888:     gen_store_fpr32h(fp0, fd);
        !          5889: 
        !          5890:     tcg_temp_free_i32(r_tmp1);
        !          5891:     tcg_temp_free_i32(fp0);
1.1.1.6   root     5892: }
                   5893: 
1.1.1.4   root     5894: 
1.1.1.6   root     5895: static void gen_farith (DisasContext *ctx, uint32_t op1,
                   5896:                         int ft, int fs, int fd, int cc)
1.1.1.4   root     5897: {
1.1.1.6   root     5898:     const char *opn = "farith";
1.1.1.4   root     5899:     const char *condnames[] = {
                   5900:             "c.f",
                   5901:             "c.un",
                   5902:             "c.eq",
                   5903:             "c.ueq",
                   5904:             "c.olt",
                   5905:             "c.ult",
                   5906:             "c.ole",
                   5907:             "c.ule",
                   5908:             "c.sf",
                   5909:             "c.ngle",
                   5910:             "c.seq",
                   5911:             "c.ngl",
                   5912:             "c.lt",
                   5913:             "c.nge",
                   5914:             "c.le",
                   5915:             "c.ngt",
                   5916:     };
1.1.1.6   root     5917:     const char *condnames_abs[] = {
                   5918:             "cabs.f",
                   5919:             "cabs.un",
                   5920:             "cabs.eq",
                   5921:             "cabs.ueq",
                   5922:             "cabs.olt",
                   5923:             "cabs.ult",
                   5924:             "cabs.ole",
                   5925:             "cabs.ule",
                   5926:             "cabs.sf",
                   5927:             "cabs.ngle",
                   5928:             "cabs.seq",
                   5929:             "cabs.ngl",
                   5930:             "cabs.lt",
                   5931:             "cabs.nge",
                   5932:             "cabs.le",
                   5933:             "cabs.ngt",
                   5934:     };
                   5935:     enum { BINOP, CMPOP, OTHEROP } optype = OTHEROP;
1.1.1.5   root     5936:     uint32_t func = ctx->opcode & 0x3f;
                   5937: 
1.1.1.4   root     5938:     switch (ctx->opcode & FOP(0x3f, 0x1f)) {
1.1.1.6   root     5939:     case FOP(0, 16):
1.1.1.7 ! root     5940:         {
        !          5941:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          5942:             TCGv_i32 fp1 = tcg_temp_new_i32();
        !          5943: 
        !          5944:             gen_load_fpr32(fp0, fs);
        !          5945:             gen_load_fpr32(fp1, ft);
        !          5946:             gen_helper_float_add_s(fp0, fp0, fp1);
        !          5947:             tcg_temp_free_i32(fp1);
        !          5948:             gen_store_fpr32(fp0, fd);
        !          5949:             tcg_temp_free_i32(fp0);
        !          5950:         }
1.1.1.6   root     5951:         opn = "add.s";
                   5952:         optype = BINOP;
                   5953:         break;
                   5954:     case FOP(1, 16):
1.1.1.7 ! root     5955:         {
        !          5956:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          5957:             TCGv_i32 fp1 = tcg_temp_new_i32();
        !          5958: 
        !          5959:             gen_load_fpr32(fp0, fs);
        !          5960:             gen_load_fpr32(fp1, ft);
        !          5961:             gen_helper_float_sub_s(fp0, fp0, fp1);
        !          5962:             tcg_temp_free_i32(fp1);
        !          5963:             gen_store_fpr32(fp0, fd);
        !          5964:             tcg_temp_free_i32(fp0);
        !          5965:         }
1.1.1.6   root     5966:         opn = "sub.s";
                   5967:         optype = BINOP;
                   5968:         break;
                   5969:     case FOP(2, 16):
1.1.1.7 ! root     5970:         {
        !          5971:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          5972:             TCGv_i32 fp1 = tcg_temp_new_i32();
        !          5973: 
        !          5974:             gen_load_fpr32(fp0, fs);
        !          5975:             gen_load_fpr32(fp1, ft);
        !          5976:             gen_helper_float_mul_s(fp0, fp0, fp1);
        !          5977:             tcg_temp_free_i32(fp1);
        !          5978:             gen_store_fpr32(fp0, fd);
        !          5979:             tcg_temp_free_i32(fp0);
        !          5980:         }
1.1.1.6   root     5981:         opn = "mul.s";
                   5982:         optype = BINOP;
                   5983:         break;
                   5984:     case FOP(3, 16):
1.1.1.7 ! root     5985:         {
        !          5986:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          5987:             TCGv_i32 fp1 = tcg_temp_new_i32();
        !          5988: 
        !          5989:             gen_load_fpr32(fp0, fs);
        !          5990:             gen_load_fpr32(fp1, ft);
        !          5991:             gen_helper_float_div_s(fp0, fp0, fp1);
        !          5992:             tcg_temp_free_i32(fp1);
        !          5993:             gen_store_fpr32(fp0, fd);
        !          5994:             tcg_temp_free_i32(fp0);
        !          5995:         }
1.1.1.6   root     5996:         opn = "div.s";
                   5997:         optype = BINOP;
                   5998:         break;
                   5999:     case FOP(4, 16):
1.1.1.7 ! root     6000:         {
        !          6001:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          6002: 
        !          6003:             gen_load_fpr32(fp0, fs);
        !          6004:             gen_helper_float_sqrt_s(fp0, fp0);
        !          6005:             gen_store_fpr32(fp0, fd);
        !          6006:             tcg_temp_free_i32(fp0);
        !          6007:         }
1.1.1.6   root     6008:         opn = "sqrt.s";
                   6009:         break;
                   6010:     case FOP(5, 16):
1.1.1.7 ! root     6011:         {
        !          6012:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          6013: 
        !          6014:             gen_load_fpr32(fp0, fs);
        !          6015:             gen_helper_float_abs_s(fp0, fp0);
        !          6016:             gen_store_fpr32(fp0, fd);
        !          6017:             tcg_temp_free_i32(fp0);
        !          6018:         }
1.1.1.6   root     6019:         opn = "abs.s";
                   6020:         break;
                   6021:     case FOP(6, 16):
1.1.1.7 ! root     6022:         {
        !          6023:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          6024: 
        !          6025:             gen_load_fpr32(fp0, fs);
        !          6026:             gen_store_fpr32(fp0, fd);
        !          6027:             tcg_temp_free_i32(fp0);
        !          6028:         }
1.1.1.6   root     6029:         opn = "mov.s";
                   6030:         break;
                   6031:     case FOP(7, 16):
1.1.1.7 ! root     6032:         {
        !          6033:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          6034: 
        !          6035:             gen_load_fpr32(fp0, fs);
        !          6036:             gen_helper_float_chs_s(fp0, fp0);
        !          6037:             gen_store_fpr32(fp0, fd);
        !          6038:             tcg_temp_free_i32(fp0);
        !          6039:         }
1.1.1.6   root     6040:         opn = "neg.s";
                   6041:         break;
                   6042:     case FOP(8, 16):
                   6043:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6044:         {
        !          6045:             TCGv_i32 fp32 = tcg_temp_new_i32();
        !          6046:             TCGv_i64 fp64 = tcg_temp_new_i64();
        !          6047: 
        !          6048:             gen_load_fpr32(fp32, fs);
        !          6049:             gen_helper_float_roundl_s(fp64, fp32);
        !          6050:             tcg_temp_free_i32(fp32);
        !          6051:             gen_store_fpr64(ctx, fp64, fd);
        !          6052:             tcg_temp_free_i64(fp64);
        !          6053:         }
1.1.1.6   root     6054:         opn = "round.l.s";
                   6055:         break;
                   6056:     case FOP(9, 16):
                   6057:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6058:         {
        !          6059:             TCGv_i32 fp32 = tcg_temp_new_i32();
        !          6060:             TCGv_i64 fp64 = tcg_temp_new_i64();
        !          6061: 
        !          6062:             gen_load_fpr32(fp32, fs);
        !          6063:             gen_helper_float_truncl_s(fp64, fp32);
        !          6064:             tcg_temp_free_i32(fp32);
        !          6065:             gen_store_fpr64(ctx, fp64, fd);
        !          6066:             tcg_temp_free_i64(fp64);
        !          6067:         }
1.1.1.6   root     6068:         opn = "trunc.l.s";
                   6069:         break;
                   6070:     case FOP(10, 16):
                   6071:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6072:         {
        !          6073:             TCGv_i32 fp32 = tcg_temp_new_i32();
        !          6074:             TCGv_i64 fp64 = tcg_temp_new_i64();
        !          6075: 
        !          6076:             gen_load_fpr32(fp32, fs);
        !          6077:             gen_helper_float_ceill_s(fp64, fp32);
        !          6078:             tcg_temp_free_i32(fp32);
        !          6079:             gen_store_fpr64(ctx, fp64, fd);
        !          6080:             tcg_temp_free_i64(fp64);
        !          6081:         }
1.1.1.6   root     6082:         opn = "ceil.l.s";
                   6083:         break;
                   6084:     case FOP(11, 16):
                   6085:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6086:         {
        !          6087:             TCGv_i32 fp32 = tcg_temp_new_i32();
        !          6088:             TCGv_i64 fp64 = tcg_temp_new_i64();
        !          6089: 
        !          6090:             gen_load_fpr32(fp32, fs);
        !          6091:             gen_helper_float_floorl_s(fp64, fp32);
        !          6092:             tcg_temp_free_i32(fp32);
        !          6093:             gen_store_fpr64(ctx, fp64, fd);
        !          6094:             tcg_temp_free_i64(fp64);
        !          6095:         }
1.1.1.6   root     6096:         opn = "floor.l.s";
                   6097:         break;
                   6098:     case FOP(12, 16):
1.1.1.7 ! root     6099:         {
        !          6100:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          6101: 
        !          6102:             gen_load_fpr32(fp0, fs);
        !          6103:             gen_helper_float_roundw_s(fp0, fp0);
        !          6104:             gen_store_fpr32(fp0, fd);
        !          6105:             tcg_temp_free_i32(fp0);
        !          6106:         }
1.1.1.6   root     6107:         opn = "round.w.s";
                   6108:         break;
                   6109:     case FOP(13, 16):
1.1.1.7 ! root     6110:         {
        !          6111:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          6112: 
        !          6113:             gen_load_fpr32(fp0, fs);
        !          6114:             gen_helper_float_truncw_s(fp0, fp0);
        !          6115:             gen_store_fpr32(fp0, fd);
        !          6116:             tcg_temp_free_i32(fp0);
        !          6117:         }
1.1.1.6   root     6118:         opn = "trunc.w.s";
                   6119:         break;
                   6120:     case FOP(14, 16):
1.1.1.7 ! root     6121:         {
        !          6122:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          6123: 
        !          6124:             gen_load_fpr32(fp0, fs);
        !          6125:             gen_helper_float_ceilw_s(fp0, fp0);
        !          6126:             gen_store_fpr32(fp0, fd);
        !          6127:             tcg_temp_free_i32(fp0);
        !          6128:         }
1.1.1.6   root     6129:         opn = "ceil.w.s";
                   6130:         break;
                   6131:     case FOP(15, 16):
1.1.1.7 ! root     6132:         {
        !          6133:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          6134: 
        !          6135:             gen_load_fpr32(fp0, fs);
        !          6136:             gen_helper_float_floorw_s(fp0, fp0);
        !          6137:             gen_store_fpr32(fp0, fd);
        !          6138:             tcg_temp_free_i32(fp0);
        !          6139:         }
1.1.1.6   root     6140:         opn = "floor.w.s";
                   6141:         break;
                   6142:     case FOP(17, 16):
1.1.1.7 ! root     6143:         gen_movcf_s(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
1.1.1.6   root     6144:         opn = "movcf.s";
                   6145:         break;
                   6146:     case FOP(18, 16):
1.1.1.7 ! root     6147:         {
        !          6148:             int l1 = gen_new_label();
        !          6149:             TCGv t0 = tcg_temp_new();
        !          6150:             TCGv_i32 fp0 = tcg_temp_local_new_i32();
        !          6151: 
        !          6152:             gen_load_gpr(t0, ft);
        !          6153:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
        !          6154:             gen_load_fpr32(fp0, fs);
        !          6155:             gen_store_fpr32(fp0, fd);
        !          6156:             tcg_temp_free_i32(fp0);
        !          6157:             gen_set_label(l1);
        !          6158:             tcg_temp_free(t0);
        !          6159:         }
1.1.1.6   root     6160:         opn = "movz.s";
                   6161:         break;
                   6162:     case FOP(19, 16):
1.1.1.7 ! root     6163:         {
        !          6164:             int l1 = gen_new_label();
        !          6165:             TCGv t0 = tcg_temp_new();
        !          6166:             TCGv_i32 fp0 = tcg_temp_local_new_i32();
        !          6167: 
        !          6168:             gen_load_gpr(t0, ft);
        !          6169:             tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
        !          6170:             gen_load_fpr32(fp0, fs);
        !          6171:             gen_store_fpr32(fp0, fd);
        !          6172:             tcg_temp_free_i32(fp0);
        !          6173:             gen_set_label(l1);
        !          6174:             tcg_temp_free(t0);
        !          6175:         }
1.1.1.6   root     6176:         opn = "movn.s";
                   6177:         break;
                   6178:     case FOP(21, 16):
                   6179:         check_cop1x(ctx);
1.1.1.7 ! root     6180:         {
        !          6181:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          6182: 
        !          6183:             gen_load_fpr32(fp0, fs);
        !          6184:             gen_helper_float_recip_s(fp0, fp0);
        !          6185:             gen_store_fpr32(fp0, fd);
        !          6186:             tcg_temp_free_i32(fp0);
        !          6187:         }
1.1.1.6   root     6188:         opn = "recip.s";
                   6189:         break;
                   6190:     case FOP(22, 16):
                   6191:         check_cop1x(ctx);
1.1.1.7 ! root     6192:         {
        !          6193:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          6194: 
        !          6195:             gen_load_fpr32(fp0, fs);
        !          6196:             gen_helper_float_rsqrt_s(fp0, fp0);
        !          6197:             gen_store_fpr32(fp0, fd);
        !          6198:             tcg_temp_free_i32(fp0);
        !          6199:         }
1.1.1.6   root     6200:         opn = "rsqrt.s";
                   6201:         break;
                   6202:     case FOP(28, 16):
                   6203:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6204:         {
        !          6205:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          6206:             TCGv_i32 fp1 = tcg_temp_new_i32();
        !          6207: 
        !          6208:             gen_load_fpr32(fp0, fs);
        !          6209:             gen_load_fpr32(fp1, fd);
        !          6210:             gen_helper_float_recip2_s(fp0, fp0, fp1);
        !          6211:             tcg_temp_free_i32(fp1);
        !          6212:             gen_store_fpr32(fp0, fd);
        !          6213:             tcg_temp_free_i32(fp0);
        !          6214:         }
1.1.1.6   root     6215:         opn = "recip2.s";
                   6216:         break;
                   6217:     case FOP(29, 16):
                   6218:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6219:         {
        !          6220:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          6221: 
        !          6222:             gen_load_fpr32(fp0, fs);
        !          6223:             gen_helper_float_recip1_s(fp0, fp0);
        !          6224:             gen_store_fpr32(fp0, fd);
        !          6225:             tcg_temp_free_i32(fp0);
        !          6226:         }
1.1.1.6   root     6227:         opn = "recip1.s";
                   6228:         break;
                   6229:     case FOP(30, 16):
                   6230:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6231:         {
        !          6232:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          6233: 
        !          6234:             gen_load_fpr32(fp0, fs);
        !          6235:             gen_helper_float_rsqrt1_s(fp0, fp0);
        !          6236:             gen_store_fpr32(fp0, fd);
        !          6237:             tcg_temp_free_i32(fp0);
        !          6238:         }
1.1.1.6   root     6239:         opn = "rsqrt1.s";
                   6240:         break;
                   6241:     case FOP(31, 16):
                   6242:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6243:         {
        !          6244:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          6245:             TCGv_i32 fp1 = tcg_temp_new_i32();
        !          6246: 
        !          6247:             gen_load_fpr32(fp0, fs);
        !          6248:             gen_load_fpr32(fp1, ft);
        !          6249:             gen_helper_float_rsqrt2_s(fp0, fp0, fp1);
        !          6250:             tcg_temp_free_i32(fp1);
        !          6251:             gen_store_fpr32(fp0, fd);
        !          6252:             tcg_temp_free_i32(fp0);
        !          6253:         }
1.1.1.6   root     6254:         opn = "rsqrt2.s";
                   6255:         break;
                   6256:     case FOP(33, 16):
                   6257:         check_cp1_registers(ctx, fd);
1.1.1.7 ! root     6258:         {
        !          6259:             TCGv_i32 fp32 = tcg_temp_new_i32();
        !          6260:             TCGv_i64 fp64 = tcg_temp_new_i64();
        !          6261: 
        !          6262:             gen_load_fpr32(fp32, fs);
        !          6263:             gen_helper_float_cvtd_s(fp64, fp32);
        !          6264:             tcg_temp_free_i32(fp32);
        !          6265:             gen_store_fpr64(ctx, fp64, fd);
        !          6266:             tcg_temp_free_i64(fp64);
        !          6267:         }
1.1.1.6   root     6268:         opn = "cvt.d.s";
                   6269:         break;
                   6270:     case FOP(36, 16):
1.1.1.7 ! root     6271:         {
        !          6272:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          6273: 
        !          6274:             gen_load_fpr32(fp0, fs);
        !          6275:             gen_helper_float_cvtw_s(fp0, fp0);
        !          6276:             gen_store_fpr32(fp0, fd);
        !          6277:             tcg_temp_free_i32(fp0);
        !          6278:         }
1.1.1.6   root     6279:         opn = "cvt.w.s";
                   6280:         break;
                   6281:     case FOP(37, 16):
                   6282:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6283:         {
        !          6284:             TCGv_i32 fp32 = tcg_temp_new_i32();
        !          6285:             TCGv_i64 fp64 = tcg_temp_new_i64();
        !          6286: 
        !          6287:             gen_load_fpr32(fp32, fs);
        !          6288:             gen_helper_float_cvtl_s(fp64, fp32);
        !          6289:             tcg_temp_free_i32(fp32);
        !          6290:             gen_store_fpr64(ctx, fp64, fd);
        !          6291:             tcg_temp_free_i64(fp64);
        !          6292:         }
1.1.1.6   root     6293:         opn = "cvt.l.s";
                   6294:         break;
                   6295:     case FOP(38, 16):
                   6296:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6297:         {
        !          6298:             TCGv_i64 fp64 = tcg_temp_new_i64();
        !          6299:             TCGv_i32 fp32_0 = tcg_temp_new_i32();
        !          6300:             TCGv_i32 fp32_1 = tcg_temp_new_i32();
        !          6301: 
        !          6302:             gen_load_fpr32(fp32_0, fs);
        !          6303:             gen_load_fpr32(fp32_1, ft);
        !          6304:             tcg_gen_concat_i32_i64(fp64, fp32_0, fp32_1);
        !          6305:             tcg_temp_free_i32(fp32_1);
        !          6306:             tcg_temp_free_i32(fp32_0);
        !          6307:             gen_store_fpr64(ctx, fp64, fd);
        !          6308:             tcg_temp_free_i64(fp64);
        !          6309:         }
1.1.1.6   root     6310:         opn = "cvt.ps.s";
                   6311:         break;
                   6312:     case FOP(48, 16):
                   6313:     case FOP(49, 16):
                   6314:     case FOP(50, 16):
                   6315:     case FOP(51, 16):
                   6316:     case FOP(52, 16):
                   6317:     case FOP(53, 16):
                   6318:     case FOP(54, 16):
                   6319:     case FOP(55, 16):
                   6320:     case FOP(56, 16):
                   6321:     case FOP(57, 16):
                   6322:     case FOP(58, 16):
                   6323:     case FOP(59, 16):
                   6324:     case FOP(60, 16):
                   6325:     case FOP(61, 16):
                   6326:     case FOP(62, 16):
                   6327:     case FOP(63, 16):
1.1.1.7 ! root     6328:         {
        !          6329:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          6330:             TCGv_i32 fp1 = tcg_temp_new_i32();
        !          6331: 
        !          6332:             gen_load_fpr32(fp0, fs);
        !          6333:             gen_load_fpr32(fp1, ft);
        !          6334:             if (ctx->opcode & (1 << 6)) {
        !          6335:                 check_cop1x(ctx);
        !          6336:                 gen_cmpabs_s(func-48, fp0, fp1, cc);
        !          6337:                 opn = condnames_abs[func-48];
        !          6338:             } else {
        !          6339:                 gen_cmp_s(func-48, fp0, fp1, cc);
        !          6340:                 opn = condnames[func-48];
        !          6341:             }
        !          6342:             tcg_temp_free_i32(fp0);
        !          6343:             tcg_temp_free_i32(fp1);
1.1.1.6   root     6344:         }
                   6345:         break;
1.1.1.4   root     6346:     case FOP(0, 17):
1.1.1.6   root     6347:         check_cp1_registers(ctx, fs | ft | fd);
1.1.1.7 ! root     6348:         {
        !          6349:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6350:             TCGv_i64 fp1 = tcg_temp_new_i64();
        !          6351: 
        !          6352:             gen_load_fpr64(ctx, fp0, fs);
        !          6353:             gen_load_fpr64(ctx, fp1, ft);
        !          6354:             gen_helper_float_add_d(fp0, fp0, fp1);
        !          6355:             tcg_temp_free_i64(fp1);
        !          6356:             gen_store_fpr64(ctx, fp0, fd);
        !          6357:             tcg_temp_free_i64(fp0);
        !          6358:         }
1.1.1.4   root     6359:         opn = "add.d";
1.1.1.6   root     6360:         optype = BINOP;
1.1.1.4   root     6361:         break;
                   6362:     case FOP(1, 17):
1.1.1.6   root     6363:         check_cp1_registers(ctx, fs | ft | fd);
1.1.1.7 ! root     6364:         {
        !          6365:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6366:             TCGv_i64 fp1 = tcg_temp_new_i64();
        !          6367: 
        !          6368:             gen_load_fpr64(ctx, fp0, fs);
        !          6369:             gen_load_fpr64(ctx, fp1, ft);
        !          6370:             gen_helper_float_sub_d(fp0, fp0, fp1);
        !          6371:             tcg_temp_free_i64(fp1);
        !          6372:             gen_store_fpr64(ctx, fp0, fd);
        !          6373:             tcg_temp_free_i64(fp0);
        !          6374:         }
1.1.1.4   root     6375:         opn = "sub.d";
1.1.1.6   root     6376:         optype = BINOP;
1.1.1.4   root     6377:         break;
                   6378:     case FOP(2, 17):
1.1.1.6   root     6379:         check_cp1_registers(ctx, fs | ft | fd);
1.1.1.7 ! root     6380:         {
        !          6381:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6382:             TCGv_i64 fp1 = tcg_temp_new_i64();
        !          6383: 
        !          6384:             gen_load_fpr64(ctx, fp0, fs);
        !          6385:             gen_load_fpr64(ctx, fp1, ft);
        !          6386:             gen_helper_float_mul_d(fp0, fp0, fp1);
        !          6387:             tcg_temp_free_i64(fp1);
        !          6388:             gen_store_fpr64(ctx, fp0, fd);
        !          6389:             tcg_temp_free_i64(fp0);
        !          6390:         }
1.1.1.4   root     6391:         opn = "mul.d";
1.1.1.6   root     6392:         optype = BINOP;
1.1.1.4   root     6393:         break;
                   6394:     case FOP(3, 17):
1.1.1.6   root     6395:         check_cp1_registers(ctx, fs | ft | fd);
1.1.1.7 ! root     6396:         {
        !          6397:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6398:             TCGv_i64 fp1 = tcg_temp_new_i64();
        !          6399: 
        !          6400:             gen_load_fpr64(ctx, fp0, fs);
        !          6401:             gen_load_fpr64(ctx, fp1, ft);
        !          6402:             gen_helper_float_div_d(fp0, fp0, fp1);
        !          6403:             tcg_temp_free_i64(fp1);
        !          6404:             gen_store_fpr64(ctx, fp0, fd);
        !          6405:             tcg_temp_free_i64(fp0);
        !          6406:         }
1.1.1.4   root     6407:         opn = "div.d";
1.1.1.6   root     6408:         optype = BINOP;
1.1.1.4   root     6409:         break;
                   6410:     case FOP(4, 17):
1.1.1.6   root     6411:         check_cp1_registers(ctx, fs | fd);
1.1.1.7 ! root     6412:         {
        !          6413:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6414: 
        !          6415:             gen_load_fpr64(ctx, fp0, fs);
        !          6416:             gen_helper_float_sqrt_d(fp0, fp0);
        !          6417:             gen_store_fpr64(ctx, fp0, fd);
        !          6418:             tcg_temp_free_i64(fp0);
        !          6419:         }
1.1.1.4   root     6420:         opn = "sqrt.d";
                   6421:         break;
                   6422:     case FOP(5, 17):
1.1.1.6   root     6423:         check_cp1_registers(ctx, fs | fd);
1.1.1.7 ! root     6424:         {
        !          6425:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6426: 
        !          6427:             gen_load_fpr64(ctx, fp0, fs);
        !          6428:             gen_helper_float_abs_d(fp0, fp0);
        !          6429:             gen_store_fpr64(ctx, fp0, fd);
        !          6430:             tcg_temp_free_i64(fp0);
        !          6431:         }
1.1.1.4   root     6432:         opn = "abs.d";
                   6433:         break;
                   6434:     case FOP(6, 17):
1.1.1.6   root     6435:         check_cp1_registers(ctx, fs | fd);
1.1.1.7 ! root     6436:         {
        !          6437:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6438: 
        !          6439:             gen_load_fpr64(ctx, fp0, fs);
        !          6440:             gen_store_fpr64(ctx, fp0, fd);
        !          6441:             tcg_temp_free_i64(fp0);
        !          6442:         }
1.1.1.4   root     6443:         opn = "mov.d";
                   6444:         break;
                   6445:     case FOP(7, 17):
1.1.1.6   root     6446:         check_cp1_registers(ctx, fs | fd);
1.1.1.7 ! root     6447:         {
        !          6448:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6449: 
        !          6450:             gen_load_fpr64(ctx, fp0, fs);
        !          6451:             gen_helper_float_chs_d(fp0, fp0);
        !          6452:             gen_store_fpr64(ctx, fp0, fd);
        !          6453:             tcg_temp_free_i64(fp0);
        !          6454:         }
1.1.1.4   root     6455:         opn = "neg.d";
                   6456:         break;
1.1.1.6   root     6457:     case FOP(8, 17):
                   6458:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6459:         {
        !          6460:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6461: 
        !          6462:             gen_load_fpr64(ctx, fp0, fs);
        !          6463:             gen_helper_float_roundl_d(fp0, fp0);
        !          6464:             gen_store_fpr64(ctx, fp0, fd);
        !          6465:             tcg_temp_free_i64(fp0);
        !          6466:         }
1.1.1.6   root     6467:         opn = "round.l.d";
                   6468:         break;
                   6469:     case FOP(9, 17):
                   6470:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6471:         {
        !          6472:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6473: 
        !          6474:             gen_load_fpr64(ctx, fp0, fs);
        !          6475:             gen_helper_float_truncl_d(fp0, fp0);
        !          6476:             gen_store_fpr64(ctx, fp0, fd);
        !          6477:             tcg_temp_free_i64(fp0);
        !          6478:         }
1.1.1.6   root     6479:         opn = "trunc.l.d";
                   6480:         break;
                   6481:     case FOP(10, 17):
                   6482:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6483:         {
        !          6484:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6485: 
        !          6486:             gen_load_fpr64(ctx, fp0, fs);
        !          6487:             gen_helper_float_ceill_d(fp0, fp0);
        !          6488:             gen_store_fpr64(ctx, fp0, fd);
        !          6489:             tcg_temp_free_i64(fp0);
        !          6490:         }
1.1.1.6   root     6491:         opn = "ceil.l.d";
                   6492:         break;
                   6493:     case FOP(11, 17):
                   6494:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6495:         {
        !          6496:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6497: 
        !          6498:             gen_load_fpr64(ctx, fp0, fs);
        !          6499:             gen_helper_float_floorl_d(fp0, fp0);
        !          6500:             gen_store_fpr64(ctx, fp0, fd);
        !          6501:             tcg_temp_free_i64(fp0);
        !          6502:         }
1.1.1.6   root     6503:         opn = "floor.l.d";
                   6504:         break;
1.1.1.4   root     6505:     case FOP(12, 17):
1.1.1.6   root     6506:         check_cp1_registers(ctx, fs);
1.1.1.7 ! root     6507:         {
        !          6508:             TCGv_i32 fp32 = tcg_temp_new_i32();
        !          6509:             TCGv_i64 fp64 = tcg_temp_new_i64();
        !          6510: 
        !          6511:             gen_load_fpr64(ctx, fp64, fs);
        !          6512:             gen_helper_float_roundw_d(fp32, fp64);
        !          6513:             tcg_temp_free_i64(fp64);
        !          6514:             gen_store_fpr32(fp32, fd);
        !          6515:             tcg_temp_free_i32(fp32);
        !          6516:         }
1.1.1.4   root     6517:         opn = "round.w.d";
                   6518:         break;
                   6519:     case FOP(13, 17):
1.1.1.6   root     6520:         check_cp1_registers(ctx, fs);
1.1.1.7 ! root     6521:         {
        !          6522:             TCGv_i32 fp32 = tcg_temp_new_i32();
        !          6523:             TCGv_i64 fp64 = tcg_temp_new_i64();
        !          6524: 
        !          6525:             gen_load_fpr64(ctx, fp64, fs);
        !          6526:             gen_helper_float_truncw_d(fp32, fp64);
        !          6527:             tcg_temp_free_i64(fp64);
        !          6528:             gen_store_fpr32(fp32, fd);
        !          6529:             tcg_temp_free_i32(fp32);
        !          6530:         }
1.1.1.4   root     6531:         opn = "trunc.w.d";
                   6532:         break;
                   6533:     case FOP(14, 17):
1.1.1.6   root     6534:         check_cp1_registers(ctx, fs);
1.1.1.7 ! root     6535:         {
        !          6536:             TCGv_i32 fp32 = tcg_temp_new_i32();
        !          6537:             TCGv_i64 fp64 = tcg_temp_new_i64();
        !          6538: 
        !          6539:             gen_load_fpr64(ctx, fp64, fs);
        !          6540:             gen_helper_float_ceilw_d(fp32, fp64);
        !          6541:             tcg_temp_free_i64(fp64);
        !          6542:             gen_store_fpr32(fp32, fd);
        !          6543:             tcg_temp_free_i32(fp32);
        !          6544:         }
1.1.1.4   root     6545:         opn = "ceil.w.d";
                   6546:         break;
                   6547:     case FOP(15, 17):
1.1.1.6   root     6548:         check_cp1_registers(ctx, fs);
1.1.1.7 ! root     6549:         {
        !          6550:             TCGv_i32 fp32 = tcg_temp_new_i32();
        !          6551:             TCGv_i64 fp64 = tcg_temp_new_i64();
        !          6552: 
        !          6553:             gen_load_fpr64(ctx, fp64, fs);
        !          6554:             gen_helper_float_floorw_d(fp32, fp64);
        !          6555:             tcg_temp_free_i64(fp64);
        !          6556:             gen_store_fpr32(fp32, fd);
        !          6557:             tcg_temp_free_i32(fp32);
        !          6558:         }
1.1.1.5   root     6559:         opn = "floor.w.d";
                   6560:         break;
1.1.1.6   root     6561:     case FOP(17, 17):
1.1.1.7 ! root     6562:         gen_movcf_d(ctx, fs, fd, (ft >> 2) & 0x7, ft & 0x1);
1.1.1.6   root     6563:         opn = "movcf.d";
1.1.1.4   root     6564:         break;
1.1.1.6   root     6565:     case FOP(18, 17):
1.1.1.7 ! root     6566:         {
        !          6567:             int l1 = gen_new_label();
        !          6568:             TCGv t0 = tcg_temp_new();
        !          6569:             TCGv_i64 fp0 = tcg_temp_local_new_i64();
        !          6570: 
        !          6571:             gen_load_gpr(t0, ft);
        !          6572:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
        !          6573:             gen_load_fpr64(ctx, fp0, fs);
        !          6574:             gen_store_fpr64(ctx, fp0, fd);
        !          6575:             tcg_temp_free_i64(fp0);
        !          6576:             gen_set_label(l1);
        !          6577:             tcg_temp_free(t0);
        !          6578:         }
1.1.1.6   root     6579:         opn = "movz.d";
                   6580:         break;
                   6581:     case FOP(19, 17):
1.1.1.7 ! root     6582:         {
        !          6583:             int l1 = gen_new_label();
        !          6584:             TCGv t0 = tcg_temp_new();
        !          6585:             TCGv_i64 fp0 = tcg_temp_local_new_i64();
        !          6586: 
        !          6587:             gen_load_gpr(t0, ft);
        !          6588:             tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
        !          6589:             gen_load_fpr64(ctx, fp0, fs);
        !          6590:             gen_store_fpr64(ctx, fp0, fd);
        !          6591:             tcg_temp_free_i64(fp0);
        !          6592:             gen_set_label(l1);
        !          6593:             tcg_temp_free(t0);
        !          6594:         }
1.1.1.6   root     6595:         opn = "movn.d";
                   6596:         break;
                   6597:     case FOP(21, 17):
                   6598:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6599:         {
        !          6600:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6601: 
        !          6602:             gen_load_fpr64(ctx, fp0, fs);
        !          6603:             gen_helper_float_recip_d(fp0, fp0);
        !          6604:             gen_store_fpr64(ctx, fp0, fd);
        !          6605:             tcg_temp_free_i64(fp0);
        !          6606:         }
1.1.1.6   root     6607:         opn = "recip.d";
                   6608:         break;
                   6609:     case FOP(22, 17):
                   6610:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6611:         {
        !          6612:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6613: 
        !          6614:             gen_load_fpr64(ctx, fp0, fs);
        !          6615:             gen_helper_float_rsqrt_d(fp0, fp0);
        !          6616:             gen_store_fpr64(ctx, fp0, fd);
        !          6617:             tcg_temp_free_i64(fp0);
        !          6618:         }
1.1.1.6   root     6619:         opn = "rsqrt.d";
                   6620:         break;
                   6621:     case FOP(28, 17):
                   6622:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6623:         {
        !          6624:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6625:             TCGv_i64 fp1 = tcg_temp_new_i64();
        !          6626: 
        !          6627:             gen_load_fpr64(ctx, fp0, fs);
        !          6628:             gen_load_fpr64(ctx, fp1, ft);
        !          6629:             gen_helper_float_recip2_d(fp0, fp0, fp1);
        !          6630:             tcg_temp_free_i64(fp1);
        !          6631:             gen_store_fpr64(ctx, fp0, fd);
        !          6632:             tcg_temp_free_i64(fp0);
        !          6633:         }
1.1.1.6   root     6634:         opn = "recip2.d";
                   6635:         break;
                   6636:     case FOP(29, 17):
                   6637:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6638:         {
        !          6639:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6640: 
        !          6641:             gen_load_fpr64(ctx, fp0, fs);
        !          6642:             gen_helper_float_recip1_d(fp0, fp0);
        !          6643:             gen_store_fpr64(ctx, fp0, fd);
        !          6644:             tcg_temp_free_i64(fp0);
        !          6645:         }
1.1.1.6   root     6646:         opn = "recip1.d";
                   6647:         break;
                   6648:     case FOP(30, 17):
                   6649:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6650:         {
        !          6651:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6652: 
        !          6653:             gen_load_fpr64(ctx, fp0, fs);
        !          6654:             gen_helper_float_rsqrt1_d(fp0, fp0);
        !          6655:             gen_store_fpr64(ctx, fp0, fd);
        !          6656:             tcg_temp_free_i64(fp0);
        !          6657:         }
1.1.1.6   root     6658:         opn = "rsqrt1.d";
                   6659:         break;
                   6660:     case FOP(31, 17):
                   6661:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6662:         {
        !          6663:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6664:             TCGv_i64 fp1 = tcg_temp_new_i64();
        !          6665: 
        !          6666:             gen_load_fpr64(ctx, fp0, fs);
        !          6667:             gen_load_fpr64(ctx, fp1, ft);
        !          6668:             gen_helper_float_rsqrt2_d(fp0, fp0, fp1);
        !          6669:             tcg_temp_free_i64(fp1);
        !          6670:             gen_store_fpr64(ctx, fp0, fd);
        !          6671:             tcg_temp_free_i64(fp0);
        !          6672:         }
1.1.1.6   root     6673:         opn = "rsqrt2.d";
1.1.1.4   root     6674:         break;
                   6675:     case FOP(48, 17):
                   6676:     case FOP(49, 17):
                   6677:     case FOP(50, 17):
                   6678:     case FOP(51, 17):
                   6679:     case FOP(52, 17):
                   6680:     case FOP(53, 17):
                   6681:     case FOP(54, 17):
                   6682:     case FOP(55, 17):
                   6683:     case FOP(56, 17):
                   6684:     case FOP(57, 17):
                   6685:     case FOP(58, 17):
                   6686:     case FOP(59, 17):
                   6687:     case FOP(60, 17):
                   6688:     case FOP(61, 17):
                   6689:     case FOP(62, 17):
                   6690:     case FOP(63, 17):
1.1.1.7 ! root     6691:         {
        !          6692:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6693:             TCGv_i64 fp1 = tcg_temp_new_i64();
        !          6694: 
        !          6695:             gen_load_fpr64(ctx, fp0, fs);
        !          6696:             gen_load_fpr64(ctx, fp1, ft);
        !          6697:             if (ctx->opcode & (1 << 6)) {
        !          6698:                 check_cop1x(ctx);
        !          6699:                 check_cp1_registers(ctx, fs | ft);
        !          6700:                 gen_cmpabs_d(func-48, fp0, fp1, cc);
        !          6701:                 opn = condnames_abs[func-48];
        !          6702:             } else {
        !          6703:                 check_cp1_registers(ctx, fs | ft);
        !          6704:                 gen_cmp_d(func-48, fp0, fp1, cc);
        !          6705:                 opn = condnames[func-48];
        !          6706:             }
        !          6707:             tcg_temp_free_i64(fp0);
        !          6708:             tcg_temp_free_i64(fp1);
1.1.1.6   root     6709:         }
                   6710:         break;
                   6711:     case FOP(32, 17):
                   6712:         check_cp1_registers(ctx, fs);
1.1.1.7 ! root     6713:         {
        !          6714:             TCGv_i32 fp32 = tcg_temp_new_i32();
        !          6715:             TCGv_i64 fp64 = tcg_temp_new_i64();
        !          6716: 
        !          6717:             gen_load_fpr64(ctx, fp64, fs);
        !          6718:             gen_helper_float_cvts_d(fp32, fp64);
        !          6719:             tcg_temp_free_i64(fp64);
        !          6720:             gen_store_fpr32(fp32, fd);
        !          6721:             tcg_temp_free_i32(fp32);
        !          6722:         }
1.1.1.6   root     6723:         opn = "cvt.s.d";
                   6724:         break;
                   6725:     case FOP(36, 17):
                   6726:         check_cp1_registers(ctx, fs);
1.1.1.7 ! root     6727:         {
        !          6728:             TCGv_i32 fp32 = tcg_temp_new_i32();
        !          6729:             TCGv_i64 fp64 = tcg_temp_new_i64();
        !          6730: 
        !          6731:             gen_load_fpr64(ctx, fp64, fs);
        !          6732:             gen_helper_float_cvtw_d(fp32, fp64);
        !          6733:             tcg_temp_free_i64(fp64);
        !          6734:             gen_store_fpr32(fp32, fd);
        !          6735:             tcg_temp_free_i32(fp32);
        !          6736:         }
1.1.1.6   root     6737:         opn = "cvt.w.d";
                   6738:         break;
                   6739:     case FOP(37, 17):
                   6740:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6741:         {
        !          6742:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6743: 
        !          6744:             gen_load_fpr64(ctx, fp0, fs);
        !          6745:             gen_helper_float_cvtl_d(fp0, fp0);
        !          6746:             gen_store_fpr64(ctx, fp0, fd);
        !          6747:             tcg_temp_free_i64(fp0);
        !          6748:         }
1.1.1.6   root     6749:         opn = "cvt.l.d";
                   6750:         break;
                   6751:     case FOP(32, 20):
1.1.1.7 ! root     6752:         {
        !          6753:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          6754: 
        !          6755:             gen_load_fpr32(fp0, fs);
        !          6756:             gen_helper_float_cvts_w(fp0, fp0);
        !          6757:             gen_store_fpr32(fp0, fd);
        !          6758:             tcg_temp_free_i32(fp0);
        !          6759:         }
1.1.1.6   root     6760:         opn = "cvt.s.w";
                   6761:         break;
                   6762:     case FOP(33, 20):
                   6763:         check_cp1_registers(ctx, fd);
1.1.1.7 ! root     6764:         {
        !          6765:             TCGv_i32 fp32 = tcg_temp_new_i32();
        !          6766:             TCGv_i64 fp64 = tcg_temp_new_i64();
        !          6767: 
        !          6768:             gen_load_fpr32(fp32, fs);
        !          6769:             gen_helper_float_cvtd_w(fp64, fp32);
        !          6770:             tcg_temp_free_i32(fp32);
        !          6771:             gen_store_fpr64(ctx, fp64, fd);
        !          6772:             tcg_temp_free_i64(fp64);
        !          6773:         }
1.1.1.6   root     6774:         opn = "cvt.d.w";
                   6775:         break;
                   6776:     case FOP(32, 21):
                   6777:         check_cp1_64bitmode(ctx);
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_fpr64(ctx, fp64, fs);
        !          6783:             gen_helper_float_cvts_l(fp32, fp64);
        !          6784:             tcg_temp_free_i64(fp64);
        !          6785:             gen_store_fpr32(fp32, fd);
        !          6786:             tcg_temp_free_i32(fp32);
        !          6787:         }
1.1.1.6   root     6788:         opn = "cvt.s.l";
                   6789:         break;
                   6790:     case FOP(33, 21):
                   6791:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6792:         {
        !          6793:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6794: 
        !          6795:             gen_load_fpr64(ctx, fp0, fs);
        !          6796:             gen_helper_float_cvtd_l(fp0, fp0);
        !          6797:             gen_store_fpr64(ctx, fp0, fd);
        !          6798:             tcg_temp_free_i64(fp0);
        !          6799:         }
1.1.1.6   root     6800:         opn = "cvt.d.l";
                   6801:         break;
                   6802:     case FOP(38, 20):
                   6803:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6804:         {
        !          6805:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6806: 
        !          6807:             gen_load_fpr64(ctx, fp0, fs);
        !          6808:             gen_helper_float_cvtps_pw(fp0, fp0);
        !          6809:             gen_store_fpr64(ctx, fp0, fd);
        !          6810:             tcg_temp_free_i64(fp0);
        !          6811:         }
1.1.1.6   root     6812:         opn = "cvt.ps.pw";
                   6813:         break;
                   6814:     case FOP(0, 22):
                   6815:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6816:         {
        !          6817:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6818:             TCGv_i64 fp1 = tcg_temp_new_i64();
        !          6819: 
        !          6820:             gen_load_fpr64(ctx, fp0, fs);
        !          6821:             gen_load_fpr64(ctx, fp1, ft);
        !          6822:             gen_helper_float_add_ps(fp0, fp0, fp1);
        !          6823:             tcg_temp_free_i64(fp1);
        !          6824:             gen_store_fpr64(ctx, fp0, fd);
        !          6825:             tcg_temp_free_i64(fp0);
        !          6826:         }
1.1.1.6   root     6827:         opn = "add.ps";
                   6828:         break;
                   6829:     case FOP(1, 22):
                   6830:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6831:         {
        !          6832:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6833:             TCGv_i64 fp1 = tcg_temp_new_i64();
        !          6834: 
        !          6835:             gen_load_fpr64(ctx, fp0, fs);
        !          6836:             gen_load_fpr64(ctx, fp1, ft);
        !          6837:             gen_helper_float_sub_ps(fp0, fp0, fp1);
        !          6838:             tcg_temp_free_i64(fp1);
        !          6839:             gen_store_fpr64(ctx, fp0, fd);
        !          6840:             tcg_temp_free_i64(fp0);
        !          6841:         }
1.1.1.6   root     6842:         opn = "sub.ps";
                   6843:         break;
                   6844:     case FOP(2, 22):
                   6845:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6846:         {
        !          6847:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6848:             TCGv_i64 fp1 = tcg_temp_new_i64();
        !          6849: 
        !          6850:             gen_load_fpr64(ctx, fp0, fs);
        !          6851:             gen_load_fpr64(ctx, fp1, ft);
        !          6852:             gen_helper_float_mul_ps(fp0, fp0, fp1);
        !          6853:             tcg_temp_free_i64(fp1);
        !          6854:             gen_store_fpr64(ctx, fp0, fd);
        !          6855:             tcg_temp_free_i64(fp0);
        !          6856:         }
1.1.1.6   root     6857:         opn = "mul.ps";
                   6858:         break;
                   6859:     case FOP(5, 22):
                   6860:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6861:         {
        !          6862:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6863: 
        !          6864:             gen_load_fpr64(ctx, fp0, fs);
        !          6865:             gen_helper_float_abs_ps(fp0, fp0);
        !          6866:             gen_store_fpr64(ctx, fp0, fd);
        !          6867:             tcg_temp_free_i64(fp0);
        !          6868:         }
1.1.1.6   root     6869:         opn = "abs.ps";
                   6870:         break;
                   6871:     case FOP(6, 22):
                   6872:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6873:         {
        !          6874:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6875: 
        !          6876:             gen_load_fpr64(ctx, fp0, fs);
        !          6877:             gen_store_fpr64(ctx, fp0, fd);
        !          6878:             tcg_temp_free_i64(fp0);
        !          6879:         }
1.1.1.6   root     6880:         opn = "mov.ps";
                   6881:         break;
                   6882:     case FOP(7, 22):
                   6883:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6884:         {
        !          6885:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6886: 
        !          6887:             gen_load_fpr64(ctx, fp0, fs);
        !          6888:             gen_helper_float_chs_ps(fp0, fp0);
        !          6889:             gen_store_fpr64(ctx, fp0, fd);
        !          6890:             tcg_temp_free_i64(fp0);
        !          6891:         }
1.1.1.6   root     6892:         opn = "neg.ps";
                   6893:         break;
                   6894:     case FOP(17, 22):
                   6895:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6896:         gen_movcf_ps(fs, fd, (ft >> 2) & 0x7, ft & 0x1);
1.1.1.6   root     6897:         opn = "movcf.ps";
                   6898:         break;
                   6899:     case FOP(18, 22):
                   6900:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6901:         {
        !          6902:             int l1 = gen_new_label();
        !          6903:             TCGv t0 = tcg_temp_new();
        !          6904:             TCGv_i32 fp0 = tcg_temp_local_new_i32();
        !          6905:             TCGv_i32 fph0 = tcg_temp_local_new_i32();
        !          6906: 
        !          6907:             gen_load_gpr(t0, ft);
        !          6908:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
        !          6909:             gen_load_fpr32(fp0, fs);
        !          6910:             gen_load_fpr32h(fph0, fs);
        !          6911:             gen_store_fpr32(fp0, fd);
        !          6912:             gen_store_fpr32h(fph0, fd);
        !          6913:             tcg_temp_free_i32(fp0);
        !          6914:             tcg_temp_free_i32(fph0);
        !          6915:             gen_set_label(l1);
        !          6916:             tcg_temp_free(t0);
        !          6917:         }
1.1.1.6   root     6918:         opn = "movz.ps";
                   6919:         break;
                   6920:     case FOP(19, 22):
                   6921:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6922:         {
        !          6923:             int l1 = gen_new_label();
        !          6924:             TCGv t0 = tcg_temp_new();
        !          6925:             TCGv_i32 fp0 = tcg_temp_local_new_i32();
        !          6926:             TCGv_i32 fph0 = tcg_temp_local_new_i32();
        !          6927: 
        !          6928:             gen_load_gpr(t0, ft);
        !          6929:             tcg_gen_brcondi_tl(TCG_COND_EQ, t0, 0, l1);
        !          6930:             gen_load_fpr32(fp0, fs);
        !          6931:             gen_load_fpr32h(fph0, fs);
        !          6932:             gen_store_fpr32(fp0, fd);
        !          6933:             gen_store_fpr32h(fph0, fd);
        !          6934:             tcg_temp_free_i32(fp0);
        !          6935:             tcg_temp_free_i32(fph0);
        !          6936:             gen_set_label(l1);
        !          6937:             tcg_temp_free(t0);
        !          6938:         }
1.1.1.6   root     6939:         opn = "movn.ps";
                   6940:         break;
                   6941:     case FOP(24, 22):
                   6942:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6943:         {
        !          6944:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6945:             TCGv_i64 fp1 = tcg_temp_new_i64();
        !          6946: 
        !          6947:             gen_load_fpr64(ctx, fp0, ft);
        !          6948:             gen_load_fpr64(ctx, fp1, fs);
        !          6949:             gen_helper_float_addr_ps(fp0, fp0, fp1);
        !          6950:             tcg_temp_free_i64(fp1);
        !          6951:             gen_store_fpr64(ctx, fp0, fd);
        !          6952:             tcg_temp_free_i64(fp0);
        !          6953:         }
1.1.1.6   root     6954:         opn = "addr.ps";
                   6955:         break;
                   6956:     case FOP(26, 22):
                   6957:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6958:         {
        !          6959:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6960:             TCGv_i64 fp1 = tcg_temp_new_i64();
        !          6961: 
        !          6962:             gen_load_fpr64(ctx, fp0, ft);
        !          6963:             gen_load_fpr64(ctx, fp1, fs);
        !          6964:             gen_helper_float_mulr_ps(fp0, fp0, fp1);
        !          6965:             tcg_temp_free_i64(fp1);
        !          6966:             gen_store_fpr64(ctx, fp0, fd);
        !          6967:             tcg_temp_free_i64(fp0);
        !          6968:         }
1.1.1.6   root     6969:         opn = "mulr.ps";
                   6970:         break;
                   6971:     case FOP(28, 22):
                   6972:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6973:         {
        !          6974:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6975:             TCGv_i64 fp1 = tcg_temp_new_i64();
        !          6976: 
        !          6977:             gen_load_fpr64(ctx, fp0, fs);
        !          6978:             gen_load_fpr64(ctx, fp1, fd);
        !          6979:             gen_helper_float_recip2_ps(fp0, fp0, fp1);
        !          6980:             tcg_temp_free_i64(fp1);
        !          6981:             gen_store_fpr64(ctx, fp0, fd);
        !          6982:             tcg_temp_free_i64(fp0);
        !          6983:         }
1.1.1.6   root     6984:         opn = "recip2.ps";
                   6985:         break;
                   6986:     case FOP(29, 22):
                   6987:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     6988:         {
        !          6989:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          6990: 
        !          6991:             gen_load_fpr64(ctx, fp0, fs);
        !          6992:             gen_helper_float_recip1_ps(fp0, fp0);
        !          6993:             gen_store_fpr64(ctx, fp0, fd);
        !          6994:             tcg_temp_free_i64(fp0);
        !          6995:         }
1.1.1.6   root     6996:         opn = "recip1.ps";
                   6997:         break;
                   6998:     case FOP(30, 22):
                   6999:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     7000:         {
        !          7001:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          7002: 
        !          7003:             gen_load_fpr64(ctx, fp0, fs);
        !          7004:             gen_helper_float_rsqrt1_ps(fp0, fp0);
        !          7005:             gen_store_fpr64(ctx, fp0, fd);
        !          7006:             tcg_temp_free_i64(fp0);
        !          7007:         }
1.1.1.6   root     7008:         opn = "rsqrt1.ps";
                   7009:         break;
                   7010:     case FOP(31, 22):
                   7011:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     7012:         {
        !          7013:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          7014:             TCGv_i64 fp1 = tcg_temp_new_i64();
        !          7015: 
        !          7016:             gen_load_fpr64(ctx, fp0, fs);
        !          7017:             gen_load_fpr64(ctx, fp1, ft);
        !          7018:             gen_helper_float_rsqrt2_ps(fp0, fp0, fp1);
        !          7019:             tcg_temp_free_i64(fp1);
        !          7020:             gen_store_fpr64(ctx, fp0, fd);
        !          7021:             tcg_temp_free_i64(fp0);
        !          7022:         }
1.1.1.6   root     7023:         opn = "rsqrt2.ps";
                   7024:         break;
                   7025:     case FOP(32, 22):
                   7026:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     7027:         {
        !          7028:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          7029: 
        !          7030:             gen_load_fpr32h(fp0, fs);
        !          7031:             gen_helper_float_cvts_pu(fp0, fp0);
        !          7032:             gen_store_fpr32(fp0, fd);
        !          7033:             tcg_temp_free_i32(fp0);
        !          7034:         }
1.1.1.6   root     7035:         opn = "cvt.s.pu";
                   7036:         break;
                   7037:     case FOP(36, 22):
                   7038:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     7039:         {
        !          7040:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          7041: 
        !          7042:             gen_load_fpr64(ctx, fp0, fs);
        !          7043:             gen_helper_float_cvtpw_ps(fp0, fp0);
        !          7044:             gen_store_fpr64(ctx, fp0, fd);
        !          7045:             tcg_temp_free_i64(fp0);
        !          7046:         }
1.1.1.6   root     7047:         opn = "cvt.pw.ps";
1.1.1.4   root     7048:         break;
1.1.1.6   root     7049:     case FOP(40, 22):
                   7050:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     7051:         {
        !          7052:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          7053: 
        !          7054:             gen_load_fpr32(fp0, fs);
        !          7055:             gen_helper_float_cvts_pl(fp0, fp0);
        !          7056:             gen_store_fpr32(fp0, fd);
        !          7057:             tcg_temp_free_i32(fp0);
        !          7058:         }
1.1.1.6   root     7059:         opn = "cvt.s.pl";
1.1.1.4   root     7060:         break;
1.1.1.6   root     7061:     case FOP(44, 22):
                   7062:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     7063:         {
        !          7064:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          7065:             TCGv_i32 fp1 = tcg_temp_new_i32();
        !          7066: 
        !          7067:             gen_load_fpr32(fp0, fs);
        !          7068:             gen_load_fpr32(fp1, ft);
        !          7069:             gen_store_fpr32h(fp0, fd);
        !          7070:             gen_store_fpr32(fp1, fd);
        !          7071:             tcg_temp_free_i32(fp0);
        !          7072:             tcg_temp_free_i32(fp1);
        !          7073:         }
1.1.1.6   root     7074:         opn = "pll.ps";
1.1.1.4   root     7075:         break;
1.1.1.6   root     7076:     case FOP(45, 22):
                   7077:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     7078:         {
        !          7079:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          7080:             TCGv_i32 fp1 = tcg_temp_new_i32();
        !          7081: 
        !          7082:             gen_load_fpr32(fp0, fs);
        !          7083:             gen_load_fpr32h(fp1, ft);
        !          7084:             gen_store_fpr32(fp1, fd);
        !          7085:             gen_store_fpr32h(fp0, fd);
        !          7086:             tcg_temp_free_i32(fp0);
        !          7087:             tcg_temp_free_i32(fp1);
        !          7088:         }
1.1.1.6   root     7089:         opn = "plu.ps";
                   7090:         break;
                   7091:     case FOP(46, 22):
                   7092:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     7093:         {
        !          7094:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          7095:             TCGv_i32 fp1 = tcg_temp_new_i32();
        !          7096: 
        !          7097:             gen_load_fpr32h(fp0, fs);
        !          7098:             gen_load_fpr32(fp1, ft);
        !          7099:             gen_store_fpr32(fp1, fd);
        !          7100:             gen_store_fpr32h(fp0, fd);
        !          7101:             tcg_temp_free_i32(fp0);
        !          7102:             tcg_temp_free_i32(fp1);
        !          7103:         }
1.1.1.6   root     7104:         opn = "pul.ps";
1.1.1.4   root     7105:         break;
1.1.1.6   root     7106:     case FOP(47, 22):
                   7107:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     7108:         {
        !          7109:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          7110:             TCGv_i32 fp1 = tcg_temp_new_i32();
        !          7111: 
        !          7112:             gen_load_fpr32h(fp0, fs);
        !          7113:             gen_load_fpr32h(fp1, ft);
        !          7114:             gen_store_fpr32(fp1, fd);
        !          7115:             gen_store_fpr32h(fp0, fd);
        !          7116:             tcg_temp_free_i32(fp0);
        !          7117:             tcg_temp_free_i32(fp1);
        !          7118:         }
1.1.1.6   root     7119:         opn = "puu.ps";
                   7120:         break;
                   7121:     case FOP(48, 22):
                   7122:     case FOP(49, 22):
                   7123:     case FOP(50, 22):
                   7124:     case FOP(51, 22):
                   7125:     case FOP(52, 22):
                   7126:     case FOP(53, 22):
                   7127:     case FOP(54, 22):
                   7128:     case FOP(55, 22):
                   7129:     case FOP(56, 22):
                   7130:     case FOP(57, 22):
                   7131:     case FOP(58, 22):
                   7132:     case FOP(59, 22):
                   7133:     case FOP(60, 22):
                   7134:     case FOP(61, 22):
                   7135:     case FOP(62, 22):
                   7136:     case FOP(63, 22):
                   7137:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     7138:         {
        !          7139:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          7140:             TCGv_i64 fp1 = tcg_temp_new_i64();
        !          7141: 
        !          7142:             gen_load_fpr64(ctx, fp0, fs);
        !          7143:             gen_load_fpr64(ctx, fp1, ft);
        !          7144:             if (ctx->opcode & (1 << 6)) {
        !          7145:                 gen_cmpabs_ps(func-48, fp0, fp1, cc);
        !          7146:                 opn = condnames_abs[func-48];
        !          7147:             } else {
        !          7148:                 gen_cmp_ps(func-48, fp0, fp1, cc);
        !          7149:                 opn = condnames[func-48];
        !          7150:             }
        !          7151:             tcg_temp_free_i64(fp0);
        !          7152:             tcg_temp_free_i64(fp1);
1.1.1.6   root     7153:         }
1.1.1.4   root     7154:         break;
1.1.1.6   root     7155:     default:
                   7156:         MIPS_INVAL(opn);
                   7157:         generate_exception (ctx, EXCP_RI);
                   7158:         return;
                   7159:     }
                   7160:     switch (optype) {
                   7161:     case BINOP:
                   7162:         MIPS_DEBUG("%s %s, %s, %s", opn, fregnames[fd], fregnames[fs], fregnames[ft]);
                   7163:         break;
                   7164:     case CMPOP:
                   7165:         MIPS_DEBUG("%s %s,%s", opn, fregnames[fs], fregnames[ft]);
                   7166:         break;
                   7167:     default:
                   7168:         MIPS_DEBUG("%s %s,%s", opn, fregnames[fd], fregnames[fs]);
                   7169:         break;
                   7170:     }
                   7171: }
                   7172: 
                   7173: /* Coprocessor 3 (FPU) */
                   7174: static void gen_flt3_ldst (DisasContext *ctx, uint32_t opc,
                   7175:                            int fd, int fs, int base, int index)
                   7176: {
                   7177:     const char *opn = "extended float load/store";
                   7178:     int store = 0;
1.1.1.7 ! root     7179:     TCGv t0 = tcg_temp_local_new();
        !          7180:     TCGv t1 = tcg_temp_local_new();
1.1.1.6   root     7181: 
                   7182:     if (base == 0) {
1.1.1.7 ! root     7183:         gen_load_gpr(t0, index);
1.1.1.6   root     7184:     } else if (index == 0) {
1.1.1.7 ! root     7185:         gen_load_gpr(t0, base);
1.1.1.6   root     7186:     } else {
1.1.1.7 ! root     7187:         gen_load_gpr(t0, index);
        !          7188:         gen_op_addr_add(ctx, t0, cpu_gpr[base]);
1.1.1.6   root     7189:     }
                   7190:     /* Don't do NOP if destination is zero: we must perform the actual
                   7191:        memory access. */
                   7192:     switch (opc) {
                   7193:     case OPC_LWXC1:
                   7194:         check_cop1x(ctx);
1.1.1.7 ! root     7195:         {
        !          7196:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          7197: 
        !          7198:             tcg_gen_qemu_ld32s(t1, t0, ctx->mem_idx);
        !          7199:             tcg_gen_trunc_tl_i32(fp0, t1);
        !          7200:             gen_store_fpr32(fp0, fd);
        !          7201:             tcg_temp_free_i32(fp0);
        !          7202:         }
1.1.1.6   root     7203:         opn = "lwxc1";
                   7204:         break;
                   7205:     case OPC_LDXC1:
                   7206:         check_cop1x(ctx);
                   7207:         check_cp1_registers(ctx, fd);
1.1.1.7 ! root     7208:         {
        !          7209:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          7210: 
        !          7211:             tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
        !          7212:             gen_store_fpr64(ctx, fp0, fd);
        !          7213:             tcg_temp_free_i64(fp0);
        !          7214:         }
1.1.1.6   root     7215:         opn = "ldxc1";
                   7216:         break;
                   7217:     case OPC_LUXC1:
                   7218:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     7219:         tcg_gen_andi_tl(t0, t0, ~0x7);
        !          7220:         {
        !          7221:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          7222: 
        !          7223:             tcg_gen_qemu_ld64(fp0, t0, ctx->mem_idx);
        !          7224:             gen_store_fpr64(ctx, fp0, fd);
        !          7225:             tcg_temp_free_i64(fp0);
        !          7226:         }
1.1.1.6   root     7227:         opn = "luxc1";
                   7228:         break;
                   7229:     case OPC_SWXC1:
                   7230:         check_cop1x(ctx);
1.1.1.7 ! root     7231:         {
        !          7232:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          7233: 
        !          7234:             gen_load_fpr32(fp0, fs);
        !          7235:             tcg_gen_extu_i32_tl(t1, fp0);
        !          7236:             tcg_gen_qemu_st32(t1, t0, ctx->mem_idx);
        !          7237:             tcg_temp_free_i32(fp0);
        !          7238:         }
1.1.1.6   root     7239:         opn = "swxc1";
                   7240:         store = 1;
1.1.1.4   root     7241:         break;
1.1.1.6   root     7242:     case OPC_SDXC1:
                   7243:         check_cop1x(ctx);
                   7244:         check_cp1_registers(ctx, fs);
1.1.1.7 ! root     7245:         {
        !          7246:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          7247: 
        !          7248:             gen_load_fpr64(ctx, fp0, fs);
        !          7249:             tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
        !          7250:             tcg_temp_free_i64(fp0);
        !          7251:         }
1.1.1.6   root     7252:         opn = "sdxc1";
                   7253:         store = 1;
                   7254:         break;
                   7255:     case OPC_SUXC1:
                   7256:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     7257:         tcg_gen_andi_tl(t0, t0, ~0x7);
        !          7258:         {
        !          7259:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          7260: 
        !          7261:             gen_load_fpr64(ctx, fp0, fs);
        !          7262:             tcg_gen_qemu_st64(fp0, t0, ctx->mem_idx);
        !          7263:             tcg_temp_free_i64(fp0);
        !          7264:         }
1.1.1.6   root     7265:         opn = "suxc1";
                   7266:         store = 1;
                   7267:         break;
                   7268:     default:
                   7269:         MIPS_INVAL(opn);
                   7270:         generate_exception(ctx, EXCP_RI);
1.1.1.7 ! root     7271:         tcg_temp_free(t0);
        !          7272:         tcg_temp_free(t1);
1.1.1.6   root     7273:         return;
                   7274:     }
1.1.1.7 ! root     7275:     tcg_temp_free(t0);
        !          7276:     tcg_temp_free(t1);
1.1.1.6   root     7277:     MIPS_DEBUG("%s %s, %s(%s)", opn, fregnames[store ? fs : fd],
                   7278:                regnames[index], regnames[base]);
                   7279: }
                   7280: 
                   7281: static void gen_flt3_arith (DisasContext *ctx, uint32_t opc,
                   7282:                             int fd, int fr, int fs, int ft)
                   7283: {
                   7284:     const char *opn = "flt3_arith";
                   7285: 
                   7286:     switch (opc) {
                   7287:     case OPC_ALNV_PS:
                   7288:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     7289:         {
        !          7290:             TCGv t0 = tcg_temp_local_new();
        !          7291:             TCGv_i32 fp0 = tcg_temp_local_new_i32();
        !          7292:             TCGv_i32 fph0 = tcg_temp_local_new_i32();
        !          7293:             TCGv_i32 fp1 = tcg_temp_local_new_i32();
        !          7294:             TCGv_i32 fph1 = tcg_temp_local_new_i32();
        !          7295:             int l1 = gen_new_label();
        !          7296:             int l2 = gen_new_label();
        !          7297: 
        !          7298:             gen_load_gpr(t0, fr);
        !          7299:             tcg_gen_andi_tl(t0, t0, 0x7);
        !          7300:             gen_load_fpr32(fp0, fs);
        !          7301:             gen_load_fpr32h(fph0, fs);
        !          7302:             gen_load_fpr32(fp1, ft);
        !          7303:             gen_load_fpr32h(fph1, ft);
        !          7304: 
        !          7305:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 0, l1);
        !          7306:             gen_store_fpr32(fp0, fd);
        !          7307:             gen_store_fpr32h(fph0, fd);
        !          7308:             tcg_gen_br(l2);
        !          7309:             gen_set_label(l1);
        !          7310:             tcg_gen_brcondi_tl(TCG_COND_NE, t0, 4, l2);
        !          7311:             tcg_temp_free(t0);
        !          7312: #ifdef TARGET_WORDS_BIGENDIAN
        !          7313:             gen_store_fpr32(fph1, fd);
        !          7314:             gen_store_fpr32h(fp0, fd);
        !          7315: #else
        !          7316:             gen_store_fpr32(fph0, fd);
        !          7317:             gen_store_fpr32h(fp1, fd);
        !          7318: #endif
        !          7319:             gen_set_label(l2);
        !          7320:             tcg_temp_free_i32(fp0);
        !          7321:             tcg_temp_free_i32(fph0);
        !          7322:             tcg_temp_free_i32(fp1);
        !          7323:             tcg_temp_free_i32(fph1);
        !          7324:         }
1.1.1.6   root     7325:         opn = "alnv.ps";
                   7326:         break;
                   7327:     case OPC_MADD_S:
                   7328:         check_cop1x(ctx);
1.1.1.7 ! root     7329:         {
        !          7330:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          7331:             TCGv_i32 fp1 = tcg_temp_new_i32();
        !          7332:             TCGv_i32 fp2 = tcg_temp_new_i32();
        !          7333: 
        !          7334:             gen_load_fpr32(fp0, fs);
        !          7335:             gen_load_fpr32(fp1, ft);
        !          7336:             gen_load_fpr32(fp2, fr);
        !          7337:             gen_helper_float_muladd_s(fp2, fp0, fp1, fp2);
        !          7338:             tcg_temp_free_i32(fp0);
        !          7339:             tcg_temp_free_i32(fp1);
        !          7340:             gen_store_fpr32(fp2, fd);
        !          7341:             tcg_temp_free_i32(fp2);
        !          7342:         }
1.1.1.6   root     7343:         opn = "madd.s";
1.1.1.4   root     7344:         break;
1.1.1.6   root     7345:     case OPC_MADD_D:
                   7346:         check_cop1x(ctx);
                   7347:         check_cp1_registers(ctx, fd | fs | ft | fr);
1.1.1.7 ! root     7348:         {
        !          7349:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          7350:             TCGv_i64 fp1 = tcg_temp_new_i64();
        !          7351:             TCGv_i64 fp2 = tcg_temp_new_i64();
        !          7352: 
        !          7353:             gen_load_fpr64(ctx, fp0, fs);
        !          7354:             gen_load_fpr64(ctx, fp1, ft);
        !          7355:             gen_load_fpr64(ctx, fp2, fr);
        !          7356:             gen_helper_float_muladd_d(fp2, fp0, fp1, fp2);
        !          7357:             tcg_temp_free_i64(fp0);
        !          7358:             tcg_temp_free_i64(fp1);
        !          7359:             gen_store_fpr64(ctx, fp2, fd);
        !          7360:             tcg_temp_free_i64(fp2);
        !          7361:         }
1.1.1.6   root     7362:         opn = "madd.d";
                   7363:         break;
                   7364:     case OPC_MADD_PS:
                   7365:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     7366:         {
        !          7367:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          7368:             TCGv_i64 fp1 = tcg_temp_new_i64();
        !          7369:             TCGv_i64 fp2 = tcg_temp_new_i64();
        !          7370: 
        !          7371:             gen_load_fpr64(ctx, fp0, fs);
        !          7372:             gen_load_fpr64(ctx, fp1, ft);
        !          7373:             gen_load_fpr64(ctx, fp2, fr);
        !          7374:             gen_helper_float_muladd_ps(fp2, fp0, fp1, fp2);
        !          7375:             tcg_temp_free_i64(fp0);
        !          7376:             tcg_temp_free_i64(fp1);
        !          7377:             gen_store_fpr64(ctx, fp2, fd);
        !          7378:             tcg_temp_free_i64(fp2);
        !          7379:         }
1.1.1.6   root     7380:         opn = "madd.ps";
1.1.1.4   root     7381:         break;
1.1.1.6   root     7382:     case OPC_MSUB_S:
                   7383:         check_cop1x(ctx);
1.1.1.7 ! root     7384:         {
        !          7385:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          7386:             TCGv_i32 fp1 = tcg_temp_new_i32();
        !          7387:             TCGv_i32 fp2 = tcg_temp_new_i32();
        !          7388: 
        !          7389:             gen_load_fpr32(fp0, fs);
        !          7390:             gen_load_fpr32(fp1, ft);
        !          7391:             gen_load_fpr32(fp2, fr);
        !          7392:             gen_helper_float_mulsub_s(fp2, fp0, fp1, fp2);
        !          7393:             tcg_temp_free_i32(fp0);
        !          7394:             tcg_temp_free_i32(fp1);
        !          7395:             gen_store_fpr32(fp2, fd);
        !          7396:             tcg_temp_free_i32(fp2);
        !          7397:         }
1.1.1.6   root     7398:         opn = "msub.s";
1.1.1.4   root     7399:         break;
1.1.1.6   root     7400:     case OPC_MSUB_D:
                   7401:         check_cop1x(ctx);
                   7402:         check_cp1_registers(ctx, fd | fs | ft | fr);
1.1.1.7 ! root     7403:         {
        !          7404:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          7405:             TCGv_i64 fp1 = tcg_temp_new_i64();
        !          7406:             TCGv_i64 fp2 = tcg_temp_new_i64();
        !          7407: 
        !          7408:             gen_load_fpr64(ctx, fp0, fs);
        !          7409:             gen_load_fpr64(ctx, fp1, ft);
        !          7410:             gen_load_fpr64(ctx, fp2, fr);
        !          7411:             gen_helper_float_mulsub_d(fp2, fp0, fp1, fp2);
        !          7412:             tcg_temp_free_i64(fp0);
        !          7413:             tcg_temp_free_i64(fp1);
        !          7414:             gen_store_fpr64(ctx, fp2, fd);
        !          7415:             tcg_temp_free_i64(fp2);
        !          7416:         }
1.1.1.6   root     7417:         opn = "msub.d";
                   7418:         break;
                   7419:     case OPC_MSUB_PS:
                   7420:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     7421:         {
        !          7422:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          7423:             TCGv_i64 fp1 = tcg_temp_new_i64();
        !          7424:             TCGv_i64 fp2 = tcg_temp_new_i64();
        !          7425: 
        !          7426:             gen_load_fpr64(ctx, fp0, fs);
        !          7427:             gen_load_fpr64(ctx, fp1, ft);
        !          7428:             gen_load_fpr64(ctx, fp2, fr);
        !          7429:             gen_helper_float_mulsub_ps(fp2, fp0, fp1, fp2);
        !          7430:             tcg_temp_free_i64(fp0);
        !          7431:             tcg_temp_free_i64(fp1);
        !          7432:             gen_store_fpr64(ctx, fp2, fd);
        !          7433:             tcg_temp_free_i64(fp2);
        !          7434:         }
1.1.1.6   root     7435:         opn = "msub.ps";
1.1.1.4   root     7436:         break;
1.1.1.6   root     7437:     case OPC_NMADD_S:
                   7438:         check_cop1x(ctx);
1.1.1.7 ! root     7439:         {
        !          7440:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          7441:             TCGv_i32 fp1 = tcg_temp_new_i32();
        !          7442:             TCGv_i32 fp2 = tcg_temp_new_i32();
        !          7443: 
        !          7444:             gen_load_fpr32(fp0, fs);
        !          7445:             gen_load_fpr32(fp1, ft);
        !          7446:             gen_load_fpr32(fp2, fr);
        !          7447:             gen_helper_float_nmuladd_s(fp2, fp0, fp1, fp2);
        !          7448:             tcg_temp_free_i32(fp0);
        !          7449:             tcg_temp_free_i32(fp1);
        !          7450:             gen_store_fpr32(fp2, fd);
        !          7451:             tcg_temp_free_i32(fp2);
        !          7452:         }
1.1.1.6   root     7453:         opn = "nmadd.s";
1.1.1.4   root     7454:         break;
1.1.1.6   root     7455:     case OPC_NMADD_D:
                   7456:         check_cop1x(ctx);
                   7457:         check_cp1_registers(ctx, fd | fs | ft | fr);
1.1.1.7 ! root     7458:         {
        !          7459:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          7460:             TCGv_i64 fp1 = tcg_temp_new_i64();
        !          7461:             TCGv_i64 fp2 = tcg_temp_new_i64();
        !          7462: 
        !          7463:             gen_load_fpr64(ctx, fp0, fs);
        !          7464:             gen_load_fpr64(ctx, fp1, ft);
        !          7465:             gen_load_fpr64(ctx, fp2, fr);
        !          7466:             gen_helper_float_nmuladd_d(fp2, fp0, fp1, fp2);
        !          7467:             tcg_temp_free_i64(fp0);
        !          7468:             tcg_temp_free_i64(fp1);
        !          7469:             gen_store_fpr64(ctx, fp2, fd);
        !          7470:             tcg_temp_free_i64(fp2);
        !          7471:         }
1.1.1.6   root     7472:         opn = "nmadd.d";
1.1.1.5   root     7473:         break;
1.1.1.6   root     7474:     case OPC_NMADD_PS:
                   7475:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     7476:         {
        !          7477:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          7478:             TCGv_i64 fp1 = tcg_temp_new_i64();
        !          7479:             TCGv_i64 fp2 = tcg_temp_new_i64();
        !          7480: 
        !          7481:             gen_load_fpr64(ctx, fp0, fs);
        !          7482:             gen_load_fpr64(ctx, fp1, ft);
        !          7483:             gen_load_fpr64(ctx, fp2, fr);
        !          7484:             gen_helper_float_nmuladd_ps(fp2, fp0, fp1, fp2);
        !          7485:             tcg_temp_free_i64(fp0);
        !          7486:             tcg_temp_free_i64(fp1);
        !          7487:             gen_store_fpr64(ctx, fp2, fd);
        !          7488:             tcg_temp_free_i64(fp2);
        !          7489:         }
1.1.1.6   root     7490:         opn = "nmadd.ps";
1.1.1.4   root     7491:         break;
1.1.1.6   root     7492:     case OPC_NMSUB_S:
                   7493:         check_cop1x(ctx);
1.1.1.7 ! root     7494:         {
        !          7495:             TCGv_i32 fp0 = tcg_temp_new_i32();
        !          7496:             TCGv_i32 fp1 = tcg_temp_new_i32();
        !          7497:             TCGv_i32 fp2 = tcg_temp_new_i32();
        !          7498: 
        !          7499:             gen_load_fpr32(fp0, fs);
        !          7500:             gen_load_fpr32(fp1, ft);
        !          7501:             gen_load_fpr32(fp2, fr);
        !          7502:             gen_helper_float_nmulsub_s(fp2, fp0, fp1, fp2);
        !          7503:             tcg_temp_free_i32(fp0);
        !          7504:             tcg_temp_free_i32(fp1);
        !          7505:             gen_store_fpr32(fp2, fd);
        !          7506:             tcg_temp_free_i32(fp2);
        !          7507:         }
1.1.1.6   root     7508:         opn = "nmsub.s";
1.1.1.4   root     7509:         break;
1.1.1.6   root     7510:     case OPC_NMSUB_D:
                   7511:         check_cop1x(ctx);
                   7512:         check_cp1_registers(ctx, fd | fs | ft | fr);
1.1.1.7 ! root     7513:         {
        !          7514:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          7515:             TCGv_i64 fp1 = tcg_temp_new_i64();
        !          7516:             TCGv_i64 fp2 = tcg_temp_new_i64();
        !          7517: 
        !          7518:             gen_load_fpr64(ctx, fp0, fs);
        !          7519:             gen_load_fpr64(ctx, fp1, ft);
        !          7520:             gen_load_fpr64(ctx, fp2, fr);
        !          7521:             gen_helper_float_nmulsub_d(fp2, fp0, fp1, fp2);
        !          7522:             tcg_temp_free_i64(fp0);
        !          7523:             tcg_temp_free_i64(fp1);
        !          7524:             gen_store_fpr64(ctx, fp2, fd);
        !          7525:             tcg_temp_free_i64(fp2);
        !          7526:         }
1.1.1.6   root     7527:         opn = "nmsub.d";
1.1.1.4   root     7528:         break;
1.1.1.6   root     7529:     case OPC_NMSUB_PS:
                   7530:         check_cp1_64bitmode(ctx);
1.1.1.7 ! root     7531:         {
        !          7532:             TCGv_i64 fp0 = tcg_temp_new_i64();
        !          7533:             TCGv_i64 fp1 = tcg_temp_new_i64();
        !          7534:             TCGv_i64 fp2 = tcg_temp_new_i64();
        !          7535: 
        !          7536:             gen_load_fpr64(ctx, fp0, fs);
        !          7537:             gen_load_fpr64(ctx, fp1, ft);
        !          7538:             gen_load_fpr64(ctx, fp2, fr);
        !          7539:             gen_helper_float_nmulsub_ps(fp2, fp0, fp1, fp2);
        !          7540:             tcg_temp_free_i64(fp0);
        !          7541:             tcg_temp_free_i64(fp1);
        !          7542:             gen_store_fpr64(ctx, fp2, fd);
        !          7543:             tcg_temp_free_i64(fp2);
        !          7544:         }
1.1.1.6   root     7545:         opn = "nmsub.ps";
1.1.1.4   root     7546:         break;
1.1.1.6   root     7547:     default:
                   7548:         MIPS_INVAL(opn);
                   7549:         generate_exception (ctx, EXCP_RI);
1.1.1.4   root     7550:         return;
                   7551:     }
1.1.1.6   root     7552:     MIPS_DEBUG("%s %s, %s, %s, %s", opn, fregnames[fd], fregnames[fr],
                   7553:                fregnames[fs], fregnames[ft]);
1.1       root     7554: }
                   7555: 
1.1.1.5   root     7556: /* ISA extensions (ASEs) */
                   7557: /* MIPS16 extension to MIPS32 */
                   7558: /* SmartMIPS extension to MIPS32 */
                   7559: 
1.1.1.6   root     7560: #if defined(TARGET_MIPS64)
1.1       root     7561: 
                   7562: /* MDMX extension to MIPS64 */
                   7563: 
                   7564: #endif
                   7565: 
1.1.1.6   root     7566: static void decode_opc (CPUState *env, DisasContext *ctx)
1.1       root     7567: {
                   7568:     int32_t offset;
                   7569:     int rs, rt, rd, sa;
1.1.1.5   root     7570:     uint32_t op, op1, op2;
1.1       root     7571:     int16_t imm;
                   7572: 
1.1.1.4   root     7573:     /* make sure instructions are on a word boundary */
                   7574:     if (ctx->pc & 0x3) {
1.1.1.6   root     7575:         env->CP0_BadVAddr = ctx->pc;
1.1.1.4   root     7576:         generate_exception(ctx, EXCP_AdEL);
                   7577:         return;
                   7578:     }
                   7579: 
1.1.1.7 ! root     7580:     /* Handle blikely not taken case */
1.1.1.2   root     7581:     if ((ctx->hflags & MIPS_HFLAG_BMASK) == MIPS_HFLAG_BL) {
1.1.1.7 ! root     7582:         int l1 = gen_new_label();
        !          7583: 
1.1.1.6   root     7584:         MIPS_DEBUG("blikely condition (" TARGET_FMT_lx ")", ctx->pc + 4);
1.1.1.7 ! root     7585:         tcg_gen_brcondi_i32(TCG_COND_NE, bcond, 0, l1);
        !          7586:         {
        !          7587:             TCGv_i32 r_tmp = tcg_temp_new_i32();
        !          7588: 
        !          7589:             tcg_gen_movi_i32(r_tmp, ctx->hflags & ~MIPS_HFLAG_BMASK);
        !          7590:             tcg_gen_st_i32(r_tmp, cpu_env, offsetof(CPUState, hflags));
        !          7591:             tcg_temp_free_i32(r_tmp);
        !          7592:         }
1.1.1.6   root     7593:         gen_goto_tb(ctx, 1, ctx->pc + 4);
                   7594:         gen_set_label(l1);
1.1       root     7595:     }
1.1.1.5   root     7596:     op = MASK_OP_MAJOR(ctx->opcode);
                   7597:     rs = (ctx->opcode >> 21) & 0x1f;
                   7598:     rt = (ctx->opcode >> 16) & 0x1f;
                   7599:     rd = (ctx->opcode >> 11) & 0x1f;
                   7600:     sa = (ctx->opcode >> 6) & 0x1f;
1.1       root     7601:     imm = (int16_t)ctx->opcode;
                   7602:     switch (op) {
1.1.1.5   root     7603:     case OPC_SPECIAL:
                   7604:         op1 = MASK_SPECIAL(ctx->opcode);
1.1       root     7605:         switch (op1) {
1.1.1.5   root     7606:         case OPC_SLL:          /* Arithmetic with immediate */
                   7607:         case OPC_SRL ... OPC_SRA:
1.1.1.6   root     7608:             gen_arith_imm(env, ctx, op1, rd, rt, sa);
1.1.1.5   root     7609:             break;
1.1.1.6   root     7610:         case OPC_MOVZ ... OPC_MOVN:
                   7611:             check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
1.1.1.5   root     7612:         case OPC_SLLV:         /* Arithmetic */
                   7613:         case OPC_SRLV ... OPC_SRAV:
                   7614:         case OPC_ADD ... OPC_NOR:
                   7615:         case OPC_SLT ... OPC_SLTU:
1.1.1.6   root     7616:             gen_arith(env, ctx, op1, rd, rs, rt);
1.1       root     7617:             break;
1.1.1.5   root     7618:         case OPC_MULT ... OPC_DIVU:
1.1.1.6   root     7619:             if (sa) {
                   7620:                 check_insn(env, ctx, INSN_VR54XX);
                   7621:                 op1 = MASK_MUL_VR54XX(ctx->opcode);
                   7622:                 gen_mul_vr54xx(ctx, op1, rd, rs, rt);
                   7623:             } else
                   7624:                 gen_muldiv(ctx, op1, rs, rt);
1.1       root     7625:             break;
1.1.1.5   root     7626:         case OPC_JR ... OPC_JALR:
                   7627:             gen_compute_branch(ctx, op1, rs, rd, sa);
1.1       root     7628:             return;
1.1.1.5   root     7629:         case OPC_TGE ... OPC_TEQ: /* Traps */
                   7630:         case OPC_TNE:
                   7631:             gen_trap(ctx, op1, rs, rt, -1);
                   7632:             break;
                   7633:         case OPC_MFHI:          /* Move from HI/LO */
                   7634:         case OPC_MFLO:
                   7635:             gen_HILO(ctx, op1, rd);
1.1       root     7636:             break;
1.1.1.5   root     7637:         case OPC_MTHI:
                   7638:         case OPC_MTLO:          /* Move to HI/LO */
                   7639:             gen_HILO(ctx, op1, rs);
                   7640:             break;
1.1.1.6   root     7641:         case OPC_PMON:          /* Pmon entry point, also R4010 selsl */
                   7642: #ifdef MIPS_STRICT_STANDARD
                   7643:             MIPS_INVAL("PMON / selsl");
                   7644:             generate_exception(ctx, EXCP_RI);
                   7645: #else
1.1.1.7 ! root     7646:             gen_helper_0i(pmon, sa);
1.1.1.6   root     7647: #endif
1.1.1.5   root     7648:             break;
                   7649:         case OPC_SYSCALL:
1.1       root     7650:             generate_exception(ctx, EXCP_SYSCALL);
                   7651:             break;
1.1.1.5   root     7652:         case OPC_BREAK:
1.1       root     7653:             generate_exception(ctx, EXCP_BREAK);
                   7654:             break;
1.1.1.6   root     7655:         case OPC_SPIM:
                   7656: #ifdef MIPS_STRICT_STANDARD
                   7657:             MIPS_INVAL("SPIM");
                   7658:             generate_exception(ctx, EXCP_RI);
                   7659: #else
1.1.1.5   root     7660:            /* Implemented as RI exception for now. */
                   7661:             MIPS_INVAL("spim (unofficial)");
                   7662:             generate_exception(ctx, EXCP_RI);
1.1.1.6   root     7663: #endif
1.1       root     7664:             break;
1.1.1.5   root     7665:         case OPC_SYNC:
1.1.1.6   root     7666:             /* Treat as NOP. */
1.1       root     7667:             break;
1.1.1.2   root     7668: 
1.1.1.5   root     7669:         case OPC_MOVCI:
1.1.1.6   root     7670:             check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
                   7671:             if (env->CP0_Config1 & (1 << CP0C1_FP)) {
                   7672:                 save_cpu_state(ctx, 1);
                   7673:                 check_cp1_enabled(ctx);
                   7674:                 gen_movci(ctx, rd, rs, (ctx->opcode >> 18) & 0x7,
                   7675:                           (ctx->opcode >> 16) & 1);
                   7676:             } else {
                   7677:                 generate_exception_err(ctx, EXCP_CpU, 1);
                   7678:             }
1.1.1.2   root     7679:             break;
                   7680: 
1.1.1.6   root     7681: #if defined(TARGET_MIPS64)
1.1.1.5   root     7682:        /* MIPS64 specific opcodes */
                   7683:         case OPC_DSLL:
                   7684:         case OPC_DSRL ... OPC_DSRA:
                   7685:         case OPC_DSLL32:
                   7686:         case OPC_DSRL32 ... OPC_DSRA32:
1.1.1.6   root     7687:             check_insn(env, ctx, ISA_MIPS3);
                   7688:             check_mips_64(ctx);
                   7689:             gen_arith_imm(env, ctx, op1, rd, rt, sa);
1.1.1.5   root     7690:             break;
                   7691:         case OPC_DSLLV:
                   7692:         case OPC_DSRLV ... OPC_DSRAV:
                   7693:         case OPC_DADD ... OPC_DSUBU:
1.1.1.6   root     7694:             check_insn(env, ctx, ISA_MIPS3);
                   7695:             check_mips_64(ctx);
                   7696:             gen_arith(env, ctx, op1, rd, rs, rt);
1.1.1.5   root     7697:             break;
                   7698:         case OPC_DMULT ... OPC_DDIVU:
1.1.1.6   root     7699:             check_insn(env, ctx, ISA_MIPS3);
                   7700:             check_mips_64(ctx);
1.1.1.5   root     7701:             gen_muldiv(ctx, op1, rs, rt);
                   7702:             break;
1.1       root     7703: #endif
                   7704:         default:            /* Invalid */
                   7705:             MIPS_INVAL("special");
                   7706:             generate_exception(ctx, EXCP_RI);
                   7707:             break;
                   7708:         }
                   7709:         break;
1.1.1.5   root     7710:     case OPC_SPECIAL2:
                   7711:         op1 = MASK_SPECIAL2(ctx->opcode);
1.1       root     7712:         switch (op1) {
1.1.1.5   root     7713:         case OPC_MADD ... OPC_MADDU: /* Multiply and add/sub */
                   7714:         case OPC_MSUB ... OPC_MSUBU:
1.1.1.6   root     7715:             check_insn(env, ctx, ISA_MIPS32);
1.1.1.5   root     7716:             gen_muldiv(ctx, op1, rs, rt);
1.1       root     7717:             break;
1.1.1.5   root     7718:         case OPC_MUL:
1.1.1.6   root     7719:             gen_arith(env, ctx, op1, rd, rs, rt);
1.1       root     7720:             break;
1.1.1.5   root     7721:         case OPC_CLZ ... OPC_CLO:
1.1.1.6   root     7722:             check_insn(env, ctx, ISA_MIPS32);
1.1.1.5   root     7723:             gen_cl(ctx, op1, rd, rs);
1.1       root     7724:             break;
1.1.1.5   root     7725:         case OPC_SDBBP:
1.1       root     7726:             /* XXX: not clear which exception should be raised
                   7727:              *      when in debug mode...
                   7728:              */
1.1.1.6   root     7729:             check_insn(env, ctx, ISA_MIPS32);
1.1       root     7730:             if (!(ctx->hflags & MIPS_HFLAG_DM)) {
                   7731:                 generate_exception(ctx, EXCP_DBp);
                   7732:             } else {
                   7733:                 generate_exception(ctx, EXCP_DBp);
                   7734:             }
1.1.1.6   root     7735:             /* Treat as NOP. */
1.1       root     7736:             break;
1.1.1.6   root     7737: #if defined(TARGET_MIPS64)
1.1.1.5   root     7738:         case OPC_DCLZ ... OPC_DCLO:
1.1.1.6   root     7739:             check_insn(env, ctx, ISA_MIPS64);
                   7740:             check_mips_64(ctx);
1.1.1.5   root     7741:             gen_cl(ctx, op1, rd, rs);
                   7742:             break;
                   7743: #endif
1.1       root     7744:         default:            /* Invalid */
                   7745:             MIPS_INVAL("special2");
                   7746:             generate_exception(ctx, EXCP_RI);
                   7747:             break;
                   7748:         }
                   7749:         break;
1.1.1.5   root     7750:     case OPC_SPECIAL3:
1.1.1.7 ! root     7751:         op1 = MASK_SPECIAL3(ctx->opcode);
        !          7752:         switch (op1) {
        !          7753:         case OPC_EXT:
        !          7754:         case OPC_INS:
        !          7755:             check_insn(env, ctx, ISA_MIPS32R2);
        !          7756:             gen_bitops(ctx, op1, rt, rs, sa, rd);
        !          7757:             break;
        !          7758:         case OPC_BSHFL:
        !          7759:             check_insn(env, ctx, ISA_MIPS32R2);
        !          7760:             op2 = MASK_BSHFL(ctx->opcode);
        !          7761:             gen_bshfl(ctx, op2, rt, rd);
1.1.1.6   root     7762:             break;
                   7763:         case OPC_RDHWR:
                   7764:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     7765:             {
        !          7766:                 TCGv t0 = tcg_temp_local_new();
        !          7767: 
        !          7768:                 switch (rd) {
        !          7769:                 case 0:
        !          7770:                     save_cpu_state(ctx, 1);
        !          7771:                     gen_helper_rdhwr_cpunum(t0);
        !          7772:                     break;
        !          7773:                 case 1:
        !          7774:                     save_cpu_state(ctx, 1);
        !          7775:                     gen_helper_rdhwr_synci_step(t0);
        !          7776:                     break;
        !          7777:                 case 2:
        !          7778:                     save_cpu_state(ctx, 1);
        !          7779:                     gen_helper_rdhwr_cc(t0);
        !          7780:                     break;
        !          7781:                 case 3:
        !          7782:                     save_cpu_state(ctx, 1);
        !          7783:                     gen_helper_rdhwr_ccres(t0);
        !          7784:                     break;
        !          7785:                 case 29:
        !          7786: #if defined(CONFIG_USER_ONLY)
        !          7787:                     tcg_gen_ld_tl(t0, cpu_env, offsetof(CPUState, tls_value));
        !          7788:                     break;
        !          7789: #else
        !          7790:                     /* XXX: Some CPUs implement this in hardware.
        !          7791:                        Not supported yet. */
1.1.1.6   root     7792: #endif
1.1.1.7 ! root     7793:                 default:            /* Invalid */
        !          7794:                     MIPS_INVAL("rdhwr");
        !          7795:                     generate_exception(ctx, EXCP_RI);
        !          7796:                     break;
        !          7797:                 }
        !          7798:                 gen_store_gpr(t0, rt);
        !          7799:                 tcg_temp_free(t0);
1.1.1.6   root     7800:             }
                   7801:             break;
                   7802:         case OPC_FORK:
                   7803:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     7804:             {
        !          7805:                 TCGv t0 = tcg_temp_local_new();
        !          7806:                 TCGv t1 = tcg_temp_local_new();
        !          7807: 
        !          7808:                 gen_load_gpr(t0, rt);
        !          7809:                 gen_load_gpr(t1, rs);
        !          7810:                 gen_helper_fork(t0, t1);
        !          7811:                 tcg_temp_free(t0);
        !          7812:                 tcg_temp_free(t1);
        !          7813:             }
1.1.1.6   root     7814:             break;
                   7815:         case OPC_YIELD:
                   7816:             check_insn(env, ctx, ASE_MT);
1.1.1.7 ! root     7817:             {
        !          7818:                 TCGv t0 = tcg_temp_local_new();
        !          7819: 
        !          7820:                 gen_load_gpr(t0, rs);
        !          7821:                 gen_helper_yield(t0, t0);
        !          7822:                 gen_store_gpr(t0, rd);
        !          7823:                 tcg_temp_free(t0);
        !          7824:             }
1.1.1.6   root     7825:             break;
                   7826: #if defined(TARGET_MIPS64)
                   7827:         case OPC_DEXTM ... OPC_DEXT:
                   7828:         case OPC_DINSM ... OPC_DINS:
                   7829:             check_insn(env, ctx, ISA_MIPS64R2);
                   7830:             check_mips_64(ctx);
1.1.1.5   root     7831:             gen_bitops(ctx, op1, rt, rs, sa, rd);
                   7832:             break;
1.1.1.6   root     7833:         case OPC_DBSHFL:
                   7834:             check_insn(env, ctx, ISA_MIPS64R2);
                   7835:             check_mips_64(ctx);
                   7836:             op2 = MASK_DBSHFL(ctx->opcode);
1.1.1.7 ! root     7837:             gen_bshfl(ctx, op2, rt, rd);
1.1.1.6   root     7838:             break;
1.1.1.5   root     7839: #endif
                   7840:         default:            /* Invalid */
                   7841:             MIPS_INVAL("special3");
                   7842:             generate_exception(ctx, EXCP_RI);
                   7843:             break;
                   7844:         }
                   7845:         break;
                   7846:     case OPC_REGIMM:
                   7847:         op1 = MASK_REGIMM(ctx->opcode);
1.1       root     7848:         switch (op1) {
1.1.1.5   root     7849:         case OPC_BLTZ ... OPC_BGEZL: /* REGIMM branches */
                   7850:         case OPC_BLTZAL ... OPC_BGEZALL:
                   7851:             gen_compute_branch(ctx, op1, rs, -1, imm << 2);
1.1       root     7852:             return;
1.1.1.5   root     7853:         case OPC_TGEI ... OPC_TEQI: /* REGIMM traps */
                   7854:         case OPC_TNEI:
                   7855:             gen_trap(ctx, op1, rs, -1, imm);
                   7856:             break;
                   7857:         case OPC_SYNCI:
1.1.1.6   root     7858:             check_insn(env, ctx, ISA_MIPS32R2);
                   7859:             /* Treat as NOP. */
1.1       root     7860:             break;
                   7861:         default:            /* Invalid */
1.1.1.6   root     7862:             MIPS_INVAL("regimm");
1.1       root     7863:             generate_exception(ctx, EXCP_RI);
                   7864:             break;
                   7865:         }
                   7866:         break;
1.1.1.5   root     7867:     case OPC_CP0:
1.1.1.6   root     7868:         check_cp0_enabled(ctx);
1.1.1.5   root     7869:         op1 = MASK_CP0(ctx->opcode);
1.1       root     7870:         switch (op1) {
1.1.1.5   root     7871:         case OPC_MFC0:
                   7872:         case OPC_MTC0:
1.1.1.6   root     7873:         case OPC_MFTR:
                   7874:         case OPC_MTTR:
                   7875: #if defined(TARGET_MIPS64)
1.1.1.5   root     7876:         case OPC_DMFC0:
                   7877:         case OPC_DMTC0:
                   7878: #endif
1.1.1.7 ! root     7879: #ifndef CONFIG_USER_ONLY
1.1.1.6   root     7880:             gen_cp0(env, ctx, op1, rt, rd);
1.1.1.7 ! root     7881: #endif /* !CONFIG_USER_ONLY */
1.1.1.5   root     7882:             break;
                   7883:         case OPC_C0_FIRST ... OPC_C0_LAST:
1.1.1.7 ! root     7884: #ifndef CONFIG_USER_ONLY
1.1.1.6   root     7885:             gen_cp0(env, ctx, MASK_C0(ctx->opcode), rt, rd);
1.1.1.7 ! root     7886: #endif /* !CONFIG_USER_ONLY */
1.1.1.5   root     7887:             break;
                   7888:         case OPC_MFMC0:
1.1.1.7 ! root     7889: #ifndef CONFIG_USER_ONLY
        !          7890:             {
        !          7891:                 TCGv t0 = tcg_temp_local_new();
        !          7892: 
        !          7893:                 op2 = MASK_MFMC0(ctx->opcode);
        !          7894:                 switch (op2) {
        !          7895:                 case OPC_DMT:
        !          7896:                     check_insn(env, ctx, ASE_MT);
        !          7897:                     gen_helper_dmt(t0, t0);
        !          7898:                     break;
        !          7899:                 case OPC_EMT:
        !          7900:                     check_insn(env, ctx, ASE_MT);
        !          7901:                     gen_helper_emt(t0, t0);
        !          7902:                     break;
        !          7903:                 case OPC_DVPE:
        !          7904:                     check_insn(env, ctx, ASE_MT);
        !          7905:                     gen_helper_dvpe(t0, t0);
        !          7906:                     break;
        !          7907:                 case OPC_EVPE:
        !          7908:                     check_insn(env, ctx, ASE_MT);
        !          7909:                     gen_helper_evpe(t0, t0);
        !          7910:                     break;
        !          7911:                 case OPC_DI:
        !          7912:                     check_insn(env, ctx, ISA_MIPS32R2);
        !          7913:                     save_cpu_state(ctx, 1);
        !          7914:                     gen_helper_di(t0);
        !          7915:                     /* Stop translation as we may have switched the execution mode */
        !          7916:                     ctx->bstate = BS_STOP;
        !          7917:                     break;
        !          7918:                 case OPC_EI:
        !          7919:                     check_insn(env, ctx, ISA_MIPS32R2);
        !          7920:                     save_cpu_state(ctx, 1);
        !          7921:                     gen_helper_ei(t0);
        !          7922:                     /* Stop translation as we may have switched the execution mode */
        !          7923:                     ctx->bstate = BS_STOP;
        !          7924:                     break;
        !          7925:                 default:            /* Invalid */
        !          7926:                     MIPS_INVAL("mfmc0");
        !          7927:                     generate_exception(ctx, EXCP_RI);
        !          7928:                     break;
        !          7929:                 }
        !          7930:                 gen_store_gpr(t0, rt);
        !          7931:                 tcg_temp_free(t0);
1.1.1.5   root     7932:             }
1.1.1.7 ! root     7933: #endif /* !CONFIG_USER_ONLY */
1.1       root     7934:             break;
1.1.1.5   root     7935:         case OPC_RDPGPR:
1.1.1.6   root     7936:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     7937:             gen_load_srsgpr(rt, rd);
1.1.1.6   root     7938:             break;
1.1.1.5   root     7939:         case OPC_WRPGPR:
1.1.1.6   root     7940:             check_insn(env, ctx, ISA_MIPS32R2);
1.1.1.7 ! root     7941:             gen_store_srsgpr(rt, rd);
1.1.1.6   root     7942:             break;
1.1       root     7943:         default:
1.1.1.6   root     7944:             MIPS_INVAL("cp0");
1.1.1.5   root     7945:             generate_exception(ctx, EXCP_RI);
1.1       root     7946:             break;
                   7947:         }
                   7948:         break;
1.1.1.5   root     7949:     case OPC_ADDI ... OPC_LUI: /* Arithmetic with immediate opcode */
1.1.1.6   root     7950:          gen_arith_imm(env, ctx, op, rt, rs, imm);
1.1.1.5   root     7951:          break;
                   7952:     case OPC_J ... OPC_JAL: /* Jump */
                   7953:          offset = (int32_t)(ctx->opcode & 0x3FFFFFF) << 2;
                   7954:          gen_compute_branch(ctx, op, rs, rt, offset);
                   7955:          return;
                   7956:     case OPC_BEQ ... OPC_BGTZ: /* Branch */
                   7957:     case OPC_BEQL ... OPC_BGTZL:
                   7958:          gen_compute_branch(ctx, op, rs, rt, imm << 2);
                   7959:          return;
                   7960:     case OPC_LB ... OPC_LWR: /* Load and stores */
                   7961:     case OPC_SB ... OPC_SW:
                   7962:     case OPC_SWR:
                   7963:     case OPC_LL:
                   7964:     case OPC_SC:
                   7965:          gen_ldst(ctx, op, rt, rs, imm);
                   7966:          break;
                   7967:     case OPC_CACHE:
1.1.1.6   root     7968:         check_insn(env, ctx, ISA_MIPS3 | ISA_MIPS32);
                   7969:         /* Treat as NOP. */
                   7970:         break;
1.1.1.5   root     7971:     case OPC_PREF:
1.1.1.6   root     7972:         check_insn(env, ctx, ISA_MIPS4 | ISA_MIPS32);
                   7973:         /* Treat as NOP. */
1.1       root     7974:         break;
1.1.1.2   root     7975: 
1.1.1.6   root     7976:     /* Floating point (COP1). */
1.1.1.5   root     7977:     case OPC_LWC1:
                   7978:     case OPC_LDC1:
                   7979:     case OPC_SWC1:
                   7980:     case OPC_SDC1:
1.1.1.6   root     7981:         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
                   7982:             save_cpu_state(ctx, 1);
                   7983:             check_cp1_enabled(ctx);
                   7984:             gen_flt_ldst(ctx, op, rt, rs, imm);
                   7985:         } else {
                   7986:             generate_exception_err(ctx, EXCP_CpU, 1);
                   7987:         }
1.1.1.4   root     7988:         break;
                   7989: 
1.1.1.5   root     7990:     case OPC_CP1:
1.1.1.6   root     7991:         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
                   7992:             save_cpu_state(ctx, 1);
                   7993:             check_cp1_enabled(ctx);
                   7994:             op1 = MASK_CP1(ctx->opcode);
                   7995:             switch (op1) {
                   7996:             case OPC_MFHC1:
                   7997:             case OPC_MTHC1:
                   7998:                 check_insn(env, ctx, ISA_MIPS32R2);
                   7999:             case OPC_MFC1:
                   8000:             case OPC_CFC1:
                   8001:             case OPC_MTC1:
                   8002:             case OPC_CTC1:
                   8003:                 gen_cp1(ctx, op1, rt, rd);
                   8004:                 break;
                   8005: #if defined(TARGET_MIPS64)
                   8006:             case OPC_DMFC1:
                   8007:             case OPC_DMTC1:
                   8008:                 check_insn(env, ctx, ISA_MIPS3);
                   8009:                 gen_cp1(ctx, op1, rt, rd);
                   8010:                 break;
1.1.1.5   root     8011: #endif
1.1.1.6   root     8012:             case OPC_BC1ANY2:
                   8013:             case OPC_BC1ANY4:
                   8014:                 check_cop1x(ctx);
                   8015:                 check_insn(env, ctx, ASE_MIPS3D);
                   8016:                 /* fall through */
                   8017:             case OPC_BC1:
                   8018:                 gen_compute_branch1(env, ctx, MASK_BC1(ctx->opcode),
                   8019:                                     (rt >> 2) & 0x7, imm << 2);
                   8020:                 return;
                   8021:             case OPC_S_FMT:
                   8022:             case OPC_D_FMT:
                   8023:             case OPC_W_FMT:
                   8024:             case OPC_L_FMT:
                   8025:             case OPC_PS_FMT:
                   8026:                 gen_farith(ctx, MASK_CP1_FUNC(ctx->opcode), rt, rd, sa,
                   8027:                            (imm >> 8) & 0x7);
                   8028:                 break;
                   8029:             default:
                   8030:                 MIPS_INVAL("cp1");
                   8031:                 generate_exception (ctx, EXCP_RI);
                   8032:                 break;
                   8033:             }
                   8034:         } else {
                   8035:             generate_exception_err(ctx, EXCP_CpU, 1);
1.1.1.4   root     8036:         }
1.1.1.2   root     8037:         break;
                   8038: 
                   8039:     /* COP2.  */
1.1.1.5   root     8040:     case OPC_LWC2:
                   8041:     case OPC_LDC2:
                   8042:     case OPC_SWC2:
                   8043:     case OPC_SDC2:
                   8044:     case OPC_CP2:
                   8045:         /* COP2: Not implemented. */
1.1.1.2   root     8046:         generate_exception_err(ctx, EXCP_CpU, 2);
                   8047:         break;
                   8048: 
1.1.1.5   root     8049:     case OPC_CP3:
1.1.1.6   root     8050:         if (env->CP0_Config1 & (1 << CP0C1_FP)) {
                   8051:             save_cpu_state(ctx, 1);
                   8052:             check_cp1_enabled(ctx);
                   8053:             op1 = MASK_CP3(ctx->opcode);
                   8054:             switch (op1) {
                   8055:             case OPC_LWXC1:
                   8056:             case OPC_LDXC1:
                   8057:             case OPC_LUXC1:
                   8058:             case OPC_SWXC1:
                   8059:             case OPC_SDXC1:
                   8060:             case OPC_SUXC1:
                   8061:                 gen_flt3_ldst(ctx, op1, sa, rd, rs, rt);
                   8062:                 break;
                   8063:             case OPC_PREFX:
                   8064:                 /* Treat as NOP. */
                   8065:                 break;
                   8066:             case OPC_ALNV_PS:
                   8067:             case OPC_MADD_S:
                   8068:             case OPC_MADD_D:
                   8069:             case OPC_MADD_PS:
                   8070:             case OPC_MSUB_S:
                   8071:             case OPC_MSUB_D:
                   8072:             case OPC_MSUB_PS:
                   8073:             case OPC_NMADD_S:
                   8074:             case OPC_NMADD_D:
                   8075:             case OPC_NMADD_PS:
                   8076:             case OPC_NMSUB_S:
                   8077:             case OPC_NMSUB_D:
                   8078:             case OPC_NMSUB_PS:
                   8079:                 gen_flt3_arith(ctx, op1, sa, rs, rd, rt);
                   8080:                 break;
                   8081:             default:
                   8082:                 MIPS_INVAL("cp3");
                   8083:                 generate_exception (ctx, EXCP_RI);
                   8084:                 break;
                   8085:             }
                   8086:         } else {
                   8087:             generate_exception_err(ctx, EXCP_CpU, 1);
1.1.1.5   root     8088:         }
1.1.1.2   root     8089:         break;
                   8090: 
1.1.1.6   root     8091: #if defined(TARGET_MIPS64)
1.1.1.5   root     8092:     /* MIPS64 opcodes */
                   8093:     case OPC_LWU:
                   8094:     case OPC_LDL ... OPC_LDR:
                   8095:     case OPC_SDL ... OPC_SDR:
                   8096:     case OPC_LLD:
                   8097:     case OPC_LD:
                   8098:     case OPC_SCD:
                   8099:     case OPC_SD:
1.1.1.6   root     8100:         check_insn(env, ctx, ISA_MIPS3);
                   8101:         check_mips_64(ctx);
1.1.1.5   root     8102:         gen_ldst(ctx, op, rt, rs, imm);
                   8103:         break;
                   8104:     case OPC_DADDI ... OPC_DADDIU:
1.1.1.6   root     8105:         check_insn(env, ctx, ISA_MIPS3);
                   8106:         check_mips_64(ctx);
                   8107:         gen_arith_imm(env, ctx, op, rt, rs, imm);
1.1.1.5   root     8108:         break;
                   8109: #endif
                   8110:     case OPC_JALX:
1.1.1.6   root     8111:         check_insn(env, ctx, ASE_MIPS16);
1.1.1.5   root     8112:         /* MIPS16: Not implemented. */
                   8113:     case OPC_MDMX:
1.1.1.6   root     8114:         check_insn(env, ctx, ASE_MDMX);
1.1.1.5   root     8115:         /* MDMX: Not implemented. */
1.1       root     8116:     default:            /* Invalid */
1.1.1.6   root     8117:         MIPS_INVAL("major opcode");
1.1       root     8118:         generate_exception(ctx, EXCP_RI);
                   8119:         break;
                   8120:     }
1.1.1.2   root     8121:     if (ctx->hflags & MIPS_HFLAG_BMASK) {
1.1.1.6   root     8122:         int hflags = ctx->hflags & MIPS_HFLAG_BMASK;
1.1       root     8123:         /* Branches completion */
1.1.1.2   root     8124:         ctx->hflags &= ~MIPS_HFLAG_BMASK;
1.1       root     8125:         ctx->bstate = BS_BRANCH;
                   8126:         save_cpu_state(ctx, 0);
1.1.1.7 ! root     8127:         /* FIXME: Need to clear can_do_io.  */
1.1.1.6   root     8128:         switch (hflags) {
1.1       root     8129:         case MIPS_HFLAG_B:
                   8130:             /* unconditional branch */
                   8131:             MIPS_DEBUG("unconditional branch");
1.1.1.2   root     8132:             gen_goto_tb(ctx, 0, ctx->btarget);
1.1       root     8133:             break;
                   8134:         case MIPS_HFLAG_BL:
                   8135:             /* blikely taken case */
                   8136:             MIPS_DEBUG("blikely branch taken");
1.1.1.2   root     8137:             gen_goto_tb(ctx, 0, ctx->btarget);
1.1       root     8138:             break;
                   8139:         case MIPS_HFLAG_BC:
                   8140:             /* Conditional branch */
                   8141:             MIPS_DEBUG("conditional branch");
1.1.1.2   root     8142:             {
1.1.1.7 ! root     8143:                 int l1 = gen_new_label();
        !          8144: 
        !          8145:                 tcg_gen_brcondi_i32(TCG_COND_NE, bcond, 0, l1);
        !          8146:                 gen_goto_tb(ctx, 1, ctx->pc + 4);
        !          8147:                 gen_set_label(l1);
        !          8148:                 gen_goto_tb(ctx, 0, ctx->btarget);
1.1.1.2   root     8149:             }
1.1       root     8150:             break;
                   8151:         case MIPS_HFLAG_BR:
                   8152:             /* unconditional branch to register */
                   8153:             MIPS_DEBUG("branch to register");
1.1.1.7 ! root     8154:             tcg_gen_mov_tl(cpu_PC, btarget);
        !          8155:             tcg_gen_exit_tb(0);
1.1       root     8156:             break;
                   8157:         default:
                   8158:             MIPS_DEBUG("unknown branch");
                   8159:             break;
                   8160:         }
                   8161:     }
                   8162: }
                   8163: 
1.1.1.7 ! root     8164: static inline void
1.1.1.6   root     8165: gen_intermediate_code_internal (CPUState *env, TranslationBlock *tb,
                   8166:                                 int search_pc)
1.1       root     8167: {
1.1.1.6   root     8168:     DisasContext ctx;
1.1       root     8169:     target_ulong pc_start;
                   8170:     uint16_t *gen_opc_end;
1.1.1.7 ! root     8171:     CPUBreakpoint *bp;
1.1       root     8172:     int j, lj = -1;
1.1.1.7 ! root     8173:     int num_insns;
        !          8174:     int max_insns;
1.1       root     8175: 
1.1.1.7 ! root     8176:     if (search_pc)
        !          8177:         qemu_log("search pc %d\n", search_pc);
1.1.1.2   root     8178: 
1.1       root     8179:     pc_start = tb->pc;
1.1.1.7 ! root     8180:     /* Leave some spare opc slots for branch handling. */
        !          8181:     gen_opc_end = gen_opc_buf + OPC_MAX_SIZE - 16;
1.1       root     8182:     ctx.pc = pc_start;
1.1.1.2   root     8183:     ctx.saved_pc = -1;
1.1       root     8184:     ctx.tb = tb;
                   8185:     ctx.bstate = BS_NONE;
1.1.1.2   root     8186:     /* Restore delay slot state from the tb context.  */
1.1.1.6   root     8187:     ctx.hflags = (uint32_t)tb->flags; /* FIXME: maybe use 64 bits here? */
                   8188:     restore_cpu_state(env, &ctx);
1.1.1.7 ! root     8189: #ifdef CONFIG_USER_ONLY
        !          8190:         ctx.mem_idx = MIPS_HFLAG_UM;
1.1       root     8191: #else
1.1.1.7 ! root     8192:         ctx.mem_idx = ctx.hflags & MIPS_HFLAG_KSU;
1.1       root     8193: #endif
1.1.1.7 ! root     8194:     num_insns = 0;
        !          8195:     max_insns = tb->cflags & CF_COUNT_MASK;
        !          8196:     if (max_insns == 0)
        !          8197:         max_insns = CF_COUNT_MASK;
1.1       root     8198: #ifdef DEBUG_DISAS
1.1.1.7 ! root     8199:     qemu_log_mask(CPU_LOG_TB_CPU, "------------------------------------------------\n");
        !          8200:     /* FIXME: This may print out stale hflags from env... */
        !          8201:     log_cpu_state_mask(CPU_LOG_TB_CPU, env, 0);
        !          8202: #endif
        !          8203:     LOG_DISAS("\ntb %p idx %d hflags %04x\n", tb, ctx.mem_idx, ctx.hflags);
        !          8204:     gen_icount_start();
        !          8205:     while (ctx.bstate == BS_NONE) {
        !          8206:         if (unlikely(!TAILQ_EMPTY(&env->breakpoints))) {
        !          8207:             TAILQ_FOREACH(bp, &env->breakpoints, entry) {
        !          8208:                 if (bp->pc == ctx.pc) {
1.1.1.6   root     8209:                     save_cpu_state(&ctx, 1);
1.1.1.2   root     8210:                     ctx.bstate = BS_BRANCH;
1.1.1.7 ! root     8211:                     gen_helper_0i(raise_exception, EXCP_DEBUG);
1.1.1.6   root     8212:                     /* Include the breakpoint location or the tb won't
                   8213:                      * be flushed when it must be.  */
                   8214:                     ctx.pc += 4;
1.1.1.2   root     8215:                     goto done_generating;
                   8216:                 }
                   8217:             }
                   8218:         }
                   8219: 
1.1       root     8220:         if (search_pc) {
                   8221:             j = gen_opc_ptr - gen_opc_buf;
                   8222:             if (lj < j) {
                   8223:                 lj++;
                   8224:                 while (lj < j)
                   8225:                     gen_opc_instr_start[lj++] = 0;
                   8226:             }
1.1.1.2   root     8227:             gen_opc_pc[lj] = ctx.pc;
                   8228:             gen_opc_hflags[lj] = ctx.hflags & MIPS_HFLAG_BMASK;
                   8229:             gen_opc_instr_start[lj] = 1;
1.1.1.7 ! root     8230:             gen_opc_icount[lj] = num_insns;
1.1       root     8231:         }
1.1.1.7 ! root     8232:         if (num_insns + 1 == max_insns && (tb->cflags & CF_LAST_IO))
        !          8233:             gen_io_start();
1.1       root     8234:         ctx.opcode = ldl_code(ctx.pc);
1.1.1.6   root     8235:         decode_opc(env, &ctx);
1.1       root     8236:         ctx.pc += 4;
1.1.1.7 ! root     8237:         num_insns++;
1.1.1.2   root     8238: 
                   8239:         if (env->singlestep_enabled)
                   8240:             break;
                   8241: 
1.1       root     8242:         if ((ctx.pc & (TARGET_PAGE_SIZE - 1)) == 0)
                   8243:             break;
1.1.1.2   root     8244: 
1.1.1.7 ! root     8245:         if (gen_opc_ptr >= gen_opc_end)
        !          8246:             break;
        !          8247: 
        !          8248:         if (num_insns >= max_insns)
        !          8249:             break;
1.1       root     8250: #if defined (MIPS_SINGLE_STEP)
                   8251:         break;
                   8252: #endif
                   8253:     }
1.1.1.7 ! root     8254:     if (tb->cflags & CF_LAST_IO)
        !          8255:         gen_io_end();
1.1.1.2   root     8256:     if (env->singlestep_enabled) {
1.1.1.6   root     8257:         save_cpu_state(&ctx, ctx.bstate == BS_NONE);
1.1.1.7 ! root     8258:         gen_helper_0i(raise_exception, EXCP_DEBUG);
1.1.1.6   root     8259:     } else {
1.1.1.7 ! root     8260:         switch (ctx.bstate) {
1.1.1.6   root     8261:         case BS_STOP:
1.1.1.7 ! root     8262:             gen_helper_interrupt_restart();
1.1.1.6   root     8263:             gen_goto_tb(&ctx, 0, ctx.pc);
                   8264:             break;
                   8265:         case BS_NONE:
                   8266:             save_cpu_state(&ctx, 0);
                   8267:             gen_goto_tb(&ctx, 0, ctx.pc);
                   8268:             break;
                   8269:         case BS_EXCP:
1.1.1.7 ! root     8270:             gen_helper_interrupt_restart();
        !          8271:             tcg_gen_exit_tb(0);
1.1.1.6   root     8272:             break;
                   8273:         case BS_BRANCH:
                   8274:         default:
                   8275:             break;
1.1.1.7 ! root     8276:         }
1.1       root     8277:     }
1.1.1.2   root     8278: done_generating:
1.1.1.7 ! root     8279:     gen_icount_end(tb, num_insns);
1.1       root     8280:     *gen_opc_ptr = INDEX_op_end;
                   8281:     if (search_pc) {
                   8282:         j = gen_opc_ptr - gen_opc_buf;
                   8283:         lj++;
                   8284:         while (lj <= j)
                   8285:             gen_opc_instr_start[lj++] = 0;
                   8286:     } else {
                   8287:         tb->size = ctx.pc - pc_start;
1.1.1.7 ! root     8288:         tb->icount = num_insns;
1.1       root     8289:     }
                   8290: #ifdef DEBUG_DISAS
1.1.1.7 ! root     8291:     LOG_DISAS("\n");
        !          8292:     if (qemu_loglevel_mask(CPU_LOG_TB_IN_ASM)) {
        !          8293:         qemu_log("IN: %s\n", lookup_symbol(pc_start));
        !          8294:         log_target_disas(pc_start, ctx.pc - pc_start, 0);
        !          8295:         qemu_log("\n");
1.1       root     8296:     }
1.1.1.7 ! root     8297:     qemu_log_mask(CPU_LOG_TB_CPU, "---------------- %d %08x\n", ctx.bstate, ctx.hflags);
1.1       root     8298: #endif
                   8299: }
                   8300: 
1.1.1.7 ! root     8301: void gen_intermediate_code (CPUState *env, struct TranslationBlock *tb)
1.1       root     8302: {
1.1.1.7 ! root     8303:     gen_intermediate_code_internal(env, tb, 0);
1.1       root     8304: }
                   8305: 
1.1.1.7 ! root     8306: void gen_intermediate_code_pc (CPUState *env, struct TranslationBlock *tb)
1.1       root     8307: {
1.1.1.7 ! root     8308:     gen_intermediate_code_internal(env, tb, 1);
1.1       root     8309: }
                   8310: 
1.1.1.7 ! root     8311: static void fpu_dump_state(CPUState *env, FILE *f,
        !          8312:                            int (*fpu_fprintf)(FILE *f, const char *fmt, ...),
        !          8313:                            int flags)
1.1.1.4   root     8314: {
                   8315:     int i;
1.1.1.6   root     8316:     int is_fpu64 = !!(env->hflags & MIPS_HFLAG_F64);
1.1.1.4   root     8317: 
1.1.1.6   root     8318: #define printfpr(fp)                                                        \
                   8319:     do {                                                                    \
                   8320:         if (is_fpu64)                                                       \
                   8321:             fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu: %13g\n",   \
                   8322:                         (fp)->w[FP_ENDIAN_IDX], (fp)->d, (fp)->fd,          \
                   8323:                         (fp)->fs[FP_ENDIAN_IDX], (fp)->fs[!FP_ENDIAN_IDX]); \
                   8324:         else {                                                              \
                   8325:             fpr_t tmp;                                                      \
                   8326:             tmp.w[FP_ENDIAN_IDX] = (fp)->w[FP_ENDIAN_IDX];                  \
                   8327:             tmp.w[!FP_ENDIAN_IDX] = ((fp) + 1)->w[FP_ENDIAN_IDX];           \
                   8328:             fpu_fprintf(f, "w:%08x d:%016lx fd:%13g fs:%13g psu:%13g\n",    \
                   8329:                         tmp.w[FP_ENDIAN_IDX], tmp.d, tmp.fd,                \
                   8330:                         tmp.fs[FP_ENDIAN_IDX], tmp.fs[!FP_ENDIAN_IDX]);     \
                   8331:         }                                                                   \
1.1.1.4   root     8332:     } while(0)
                   8333: 
1.1.1.6   root     8334: 
                   8335:     fpu_fprintf(f, "CP1 FCR0 0x%08x  FCR31 0x%08x  SR.FR %d  fp_status 0x%08x(0x%02x)\n",
1.1.1.7 ! root     8336:                 env->active_fpu.fcr0, env->active_fpu.fcr31, is_fpu64, env->active_fpu.fp_status,
        !          8337:                 get_float_exception_flags(&env->active_fpu.fp_status));
1.1.1.6   root     8338:     for (i = 0; i < 32; (is_fpu64) ? i++ : (i += 2)) {
                   8339:         fpu_fprintf(f, "%3s: ", fregnames[i]);
1.1.1.7 ! root     8340:         printfpr(&env->active_fpu.fpr[i]);
1.1.1.4   root     8341:     }
                   8342: 
                   8343: #undef printfpr
                   8344: }
                   8345: 
1.1.1.6   root     8346: #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
1.1.1.5   root     8347: /* Debug help: The architecture requires 32bit code to maintain proper
1.1.1.7 ! root     8348:    sign-extended values on 64bit machines.  */
1.1.1.5   root     8349: 
                   8350: #define SIGN_EXT_P(val) ((((val) & ~0x7fffffff) == 0) || (((val) & ~0x7fffffff) == ~0x7fffffff))
                   8351: 
1.1.1.7 ! root     8352: static void
        !          8353: cpu_mips_check_sign_extensions (CPUState *env, FILE *f,
        !          8354:                                 int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
        !          8355:                                 int flags)
1.1.1.5   root     8356: {
                   8357:     int i;
                   8358: 
1.1.1.7 ! root     8359:     if (!SIGN_EXT_P(env->active_tc.PC))
        !          8360:         cpu_fprintf(f, "BROKEN: pc=0x" TARGET_FMT_lx "\n", env->active_tc.PC);
        !          8361:     if (!SIGN_EXT_P(env->active_tc.HI[0]))
        !          8362:         cpu_fprintf(f, "BROKEN: HI=0x" TARGET_FMT_lx "\n", env->active_tc.HI[0]);
        !          8363:     if (!SIGN_EXT_P(env->active_tc.LO[0]))
        !          8364:         cpu_fprintf(f, "BROKEN: LO=0x" TARGET_FMT_lx "\n", env->active_tc.LO[0]);
1.1.1.5   root     8365:     if (!SIGN_EXT_P(env->btarget))
1.1.1.6   root     8366:         cpu_fprintf(f, "BROKEN: btarget=0x" TARGET_FMT_lx "\n", env->btarget);
1.1.1.5   root     8367: 
                   8368:     for (i = 0; i < 32; i++) {
1.1.1.7 ! root     8369:         if (!SIGN_EXT_P(env->active_tc.gpr[i]))
        !          8370:             cpu_fprintf(f, "BROKEN: %s=0x" TARGET_FMT_lx "\n", regnames[i], env->active_tc.gpr[i]);
1.1.1.5   root     8371:     }
                   8372: 
                   8373:     if (!SIGN_EXT_P(env->CP0_EPC))
1.1.1.6   root     8374:         cpu_fprintf(f, "BROKEN: EPC=0x" TARGET_FMT_lx "\n", env->CP0_EPC);
1.1.1.5   root     8375:     if (!SIGN_EXT_P(env->CP0_LLAddr))
1.1.1.6   root     8376:         cpu_fprintf(f, "BROKEN: LLAddr=0x" TARGET_FMT_lx "\n", env->CP0_LLAddr);
1.1.1.5   root     8377: }
                   8378: #endif
                   8379: 
1.1.1.6   root     8380: void cpu_dump_state (CPUState *env, FILE *f,
1.1       root     8381:                      int (*cpu_fprintf)(FILE *f, const char *fmt, ...),
                   8382:                      int flags)
                   8383: {
                   8384:     int i;
1.1.1.6   root     8385: 
                   8386:     cpu_fprintf(f, "pc=0x" TARGET_FMT_lx " HI=0x" TARGET_FMT_lx " LO=0x" TARGET_FMT_lx " ds %04x " TARGET_FMT_lx " %d\n",
1.1.1.7 ! root     8387:                 env->active_tc.PC, env->active_tc.HI[0], env->active_tc.LO[0],
        !          8388:                 env->hflags, env->btarget, env->bcond);
1.1       root     8389:     for (i = 0; i < 32; i++) {
                   8390:         if ((i & 3) == 0)
                   8391:             cpu_fprintf(f, "GPR%02d:", i);
1.1.1.7 ! root     8392:         cpu_fprintf(f, " %s " TARGET_FMT_lx, regnames[i], env->active_tc.gpr[i]);
1.1       root     8393:         if ((i & 3) == 3)
                   8394:             cpu_fprintf(f, "\n");
                   8395:     }
                   8396: 
1.1.1.6   root     8397:     cpu_fprintf(f, "CP0 Status  0x%08x Cause   0x%08x EPC    0x" TARGET_FMT_lx "\n",
                   8398:                 env->CP0_Status, env->CP0_Cause, env->CP0_EPC);
                   8399:     cpu_fprintf(f, "    Config0 0x%08x Config1 0x%08x LLAddr 0x" TARGET_FMT_lx "\n",
1.1       root     8400:                 env->CP0_Config0, env->CP0_Config1, env->CP0_LLAddr);
1.1.1.6   root     8401:     if (env->hflags & MIPS_HFLAG_FPU)
1.1.1.5   root     8402:         fpu_dump_state(env, f, cpu_fprintf, flags);
1.1.1.6   root     8403: #if defined(TARGET_MIPS64) && defined(MIPS_DEBUG_SIGN_EXTENSIONS)
1.1.1.5   root     8404:     cpu_mips_check_sign_extensions(env, f, cpu_fprintf, flags);
1.1.1.4   root     8405: #endif
1.1       root     8406: }
                   8407: 
1.1.1.7 ! root     8408: static void mips_tcg_init(void)
        !          8409: {
        !          8410:     int i;
        !          8411:     static int inited;
        !          8412: 
        !          8413:     /* Initialize various static tables. */
        !          8414:     if (inited)
        !          8415:         return;
        !          8416: 
        !          8417:     cpu_env = tcg_global_reg_new_ptr(TCG_AREG0, "env");
        !          8418:     for (i = 0; i < 32; i++)
        !          8419:         cpu_gpr[i] = tcg_global_mem_new(TCG_AREG0,
        !          8420:                                         offsetof(CPUState, active_tc.gpr[i]),
        !          8421:                                         regnames[i]);
        !          8422:     cpu_PC = tcg_global_mem_new(TCG_AREG0,
        !          8423:                                 offsetof(CPUState, active_tc.PC), "PC");
        !          8424:     for (i = 0; i < MIPS_DSP_ACC; i++) {
        !          8425:         cpu_HI[i] = tcg_global_mem_new(TCG_AREG0,
        !          8426:                                        offsetof(CPUState, active_tc.HI[i]),
        !          8427:                                        regnames_HI[i]);
        !          8428:         cpu_LO[i] = tcg_global_mem_new(TCG_AREG0,
        !          8429: