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

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

unix.superglobalmegacorp.com

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