public static bool addi( uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands )
        {
            // TODO: instrinsic
            // if rs == 0, li rt, imm

            return IType( address, code, entry, out opcode, out operands );
        }
 public static bool FromHiloTransfer(uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands)
 {
     opcode   = new Opcode(entry);
     operands = new Operand[] {
         new Operand(RD(code)),
     };
     return(true);
 }
 public static bool JumpRegType(uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands)
 {
     opcode   = new Opcode(entry);
     operands = new Operand[] {
         new Operand(OperandType.JumpTarget, RS(code)),
     };
     return(true);
 }
 public static bool Allegrex2(uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands)
 {
     opcode   = new Opcode(entry);
     operands = new Operand[] {
         new Operand(RD(code)),
         new Operand(RT(code)),
     };
     return(true);
 }
 public static bool FPUComp(uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands)
 {
     opcode   = new Opcode(entry);
     operands = new Operand[] {
         new Operand(FS(code)),
         new Operand(FT(code)),
     };
     return(true);
 }
 public static bool FPULS(uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands)
 {
     opcode   = new Opcode(entry);
     operands = new Operand[] {
         new Operand(FT(code)),
         new Operand(OperandType.MemoryAccess, RS(code), IMM16(code)),
     };
     return(true);
 }
 public static bool IType1(uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands)
 {
     opcode   = new Opcode(entry);
     operands = new Operand[] {
         new Operand(RT(code)),
         new Operand(IMM16(code), 2),
     };
     return(true);
 }
        public static bool VectorSet1(uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands)
        {
            DataSize sz = GetVecSize(code);

            opcode   = new Opcode(entry, VSuff(code));
            operands = new Operand[] {
                new Operand(VD(code), sz),
            };
            return(true);
        }
        public static bool FPUBranch(uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands)
        {
            int imm = IMM16(code) << 2;

            opcode   = new Opcode(entry);
            operands = new Operand[] {
                new Operand(OperandType.BranchTarget, imm),
            };
            return(true);
        }
        public static bool JumpType(uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands)
        {
            uint offset = ((code & 0x03FFFFFF) << 2);
            uint addr   = (address & 0xF0000000) | offset;

            opcode   = new Opcode(entry);
            operands = new Operand[] {
                new Operand(OperandType.JumpTarget, ( int )addr),
            };
            return(true);
        }
        public static bool VBranch(uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands)
        {
            uint imm3 = (code >> 18) & 7;

            opcode   = new Opcode(entry);
            operands = new Operand[] {
                new Operand(( int )imm3, 4, "CC"),
                new Operand(OperandType.BranchTarget, IMM16(code)),
            };
            return(true);
        }
        public static bool MatrixSet2(uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands)
        {
            DataSize sz = GetMtxSize(code);

            opcode   = new Opcode(entry, VSuff(code));
            operands = new Operand[] {
                new Operand(VD(code), sz),                     // Matrix
                new Operand(VS(code), sz),                     // Matrix
            };
            return(true);
        }
        public static bool Vfad(uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands)
        {
            DataSize sz = GetVecSize(code);

            opcode   = new Opcode(entry);
            operands = new Operand[] {
                new Operand(VD(code), DataSize.V_Single),
                new Operand(VS(code), sz),
            };
            return(true);
        }
        public static bool Vcmp(uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands)
        {
            uint     cond = code & 15;
            DataSize sz   = GetVecSize(code);

            opcode   = new Opcode(entry, VSuff(code));
            operands = new Operand[] {
                new Operand(condNames[cond]),
                new Operand(VS(code), sz),
                new Operand(VT(code), sz),
            };
            return(true);
        }
        public static bool ori(uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands)
        {
            // TODO: instrinsic
            // if rs == 0, li rt, imm

            opcode   = new Opcode(entry);
            operands = new Operand[] {
                new Operand(RT(code)),
                new Operand(RS(code)),
                new Operand(IMM16(code), 2),
            };
            return(true);
        }
        public static bool SV(uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands)
        {
            int offset = ( short )(code & 0xFFFC);
            int vt     = ( int )((code >> 16) & 0x1F) | ( int )((code & 3) << 5);

            // if vt & 0x80, transposed
            opcode   = new Opcode(entry);
            operands = new Operand[] {
                new Operand(RegisterBanks.Vfpu.Registers[vt], DataSize.V_Single),
                new Operand(OperandType.MemoryAccess, RS(code), offset),
            };
            return(true);
        }
        public static bool Mftv(uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands)
        {
            // This may be broken!
            int  vr         = ( int )(code & 0xFF);
            bool transposed = (vr & 0x80) != 0;

            opcode   = new Opcode(entry, transposed ? "c" : "");
            operands = new Operand[] {
                new Operand(RT(code)),
                new Operand(RegisterBanks.Vfpu.Registers[(vr & 0x80)], DataSize.V_Single, transposed),
            };
            return(true);
        }
        public static bool Vf2i(uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands)
        {
            DataSize sz  = GetVecSize(code);
            uint     imm = (code >> 16) & 0x1F;

            opcode   = new Opcode(entry, VSuff(code));
            operands = new Operand[] {
                new Operand(VD(code), sz),
                new Operand(VS(code), sz),
                new Operand(( int )imm, 1),
            };
            return(true);
        }
        public static bool Syscall(uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands)
        {
            uint callno    = (code >> 6) & 0xFFFFF;            //20 bits
            uint funcnum   = callno & 0xFFF;
            uint modulenum = (callno & 0xFF000) >> 12;

            //sprintf(out, "syscall\t  %s",/*PSPHLE::GetModuleName(modulenum),*/PSPHLE::GetFuncName(modulenum, funcnum));
            opcode   = new Opcode(entry);
            operands = new Operand[] {
                new Operand(( int )callno, 4),
            };
            return(true);
        }
        public static bool SVLRQ(uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands)
        {
            int    offset = ( short )(code & 0xFFFC);
            int    vt     = ( int )(((code >> 16) & 0x1f)) | ( int )((code & 1) << 5);
            int    lr     = ( int )(code >> 1) & 1;
            string suffix = string.Format("{0}.q", (lr != 0) ? "r" : "l");

            opcode   = new Opcode(entry, suffix);
            operands = new Operand[] {
                new Operand(RegisterBanks.Vfpu.Registers[vt], DataSize.V_Quad),
                new Operand(OperandType.MemoryAccess, RS(code), offset),
            };
            return(true);
        }
Exemple #21
0
        public Instruction(uint address, uint code)
        {
            this.Address = address;
            this.Code    = code;

            InstructionEntry instructionEntry = InstructionTables.GetInstruction(code);

            Debug.Assert(instructionEntry != null);
            Debug.Assert(instructionEntry.Formatter != null);

            bool formatted = instructionEntry.Formatter(address, code, instructionEntry, out this.Opcode, out this.Operands);

            Debug.Assert(formatted == true);
        }
        public static bool Vi2x(uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands)
        {
            DataSize sz  = GetVecSize(code);
            DataSize dsz = GetHalfSize(sz);

            if (((code >> 16) & 3) == 0)
            {
                dsz = DataSize.V_Single;
            }
            opcode   = new Opcode(entry, VSuff(code));
            operands = new Operand[] {
                new Operand(VD(code), dsz),
                new Operand(VS(code), sz),
            };
            return(true);
        }
        public static bool VPFXST(uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands)
        {
            List <Operand> ops  = new List <Operand>();
            int            data = ( int )(code & 0xFFFFF);

            for (int n = 0; n < 4; n++)
            {
                int    regnum    = (data >> (n * 2)) & 3;
                int    abs       = (data >> (8 + n)) & 1;
                int    negate    = (data >> (16 + n)) & 1;
                int    constants = (data >> (12 + n)) & 1;
                string op        = "";
                if (negate != 0)
                {
                    op += "-";
                }
                if ((abs != 0) && (constants == 0))
                {
                    op += "|";
                }
                if (constants == 0)
                {
                    op += vregnames[regnum];
                }
                else
                {
                    if (abs != 0)
                    {
                        regnum += 4;
                    }
                    op += vconstants[regnum];
                }
                if ((abs != 0) && (constants == 0))
                {
                    op += "|";
                }
                if (op.Length > 0)
                {
                    ops.Add(new Operand(op));
                }
            }
            opcode   = new Opcode(entry);
            operands = ops.ToArray();
            return(true);
        }
        public static bool addu( uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands )
        {
            // TODO: instrinsic
            //if (rs==0 && rt==0)
            //    sprintf(out,"li\t%s, 0",RN(rd));
            //else if (rs == 0)
            //    sprintf(out,"mov\t%s, %s",RN(rd),RN(rt));
            //else if (rt == 0)
            //    sprintf(out,"mov\t%s, %s",RN(rd),RN(rs));

            opcode = new Opcode( entry );
            operands = new Operand[]{
                new Operand( RD( code ) ),
                new Operand( RS( code ) ),
                new Operand( RT( code ) ),
            };
            return true;
        }
        public static bool addu(uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands)
        {
            // TODO: instrinsic
            //if (rs==0 && rt==0)
            //    sprintf(out,"li\t%s, 0",RN(rd));
            //else if (rs == 0)
            //    sprintf(out,"mov\t%s, %s",RN(rd),RN(rt));
            //else if (rt == 0)
            //    sprintf(out,"mov\t%s, %s",RN(rd),RN(rs));

            opcode   = new Opcode(entry);
            operands = new Operand[] {
                new Operand(RD(code)),
                new Operand(RS(code)),
                new Operand(RT(code)),
            };
            return(true);
        }
        public static bool VRot(uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands)
        {
            int  imm    = ( int )(code >> 16) & 0x1F;
            bool negSin = ((imm & 0x10) == 0x10);

            char[] c    = new char[] { '.', '.', '.', '.' };
            char[] temp = new char[16];
            if (((imm >> 2) & 3) == (imm & 3))
            {
                for (int n = 0; n < 4; n++)
                {
                    c[n] = 'S';
                }
            }
            c[(imm >> 2) & 3] = 'S';
            c[imm & 3]        = 'C';
            DataSize sz       = GetVecSize(code);
            int      numElems = GetNumElements(sz);
            int      pos      = 0;

            temp[pos++] = '[';
            for (int n = 0; n < numElems; n++)
            {
                if (c[n] == 'S' && negSin)
                {
                    temp[pos++] = '-';
                }
                else
                {
                    temp[pos++] = ' ';
                }
                temp[pos++] = c[n];
                temp[pos++] = ' ';
            }
            temp[pos++] = ']';
            opcode      = new Opcode(entry, VSuff(code));
            operands    = new Operand[] {
                new Operand(VD(code), sz),
                new Operand(VS(code), DataSize.V_Single),
                new Operand(new string( temp, 0, pos )),
            };
            return(true);
        }
        public static bool Vcmov(uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands)
        {
            DataSize sz   = GetVecSize(code);
            Register vd   = VD(code);
            Register vs   = VS(code);
            uint     tf   = (code >> 19) & 3;
            uint     imm3 = (code >> 16) & 7;

            if (tf > 1)
            {
                // ?????
                opcode   = new Opcode(entry, ".??????");
                operands = new Operand[] {
                    new Operand(( int )tf, 1),
                };
            }
            else
            {
                string suffix = string.Format("{0}{1}",
                                              (tf == 0) ? "t" : "f",
                                              VSuff(code));
                opcode = new Opcode(entry, suffix);
                if (imm3 < 6)
                {
                    operands = new Operand[] {
                        new Operand(vd, sz),
                        new Operand(vs, sz),
                        new Operand(( int )imm3, 1, "CC"),
                    };
                }
                else
                {
                    Debug.Assert(imm3 == 6);
                    operands = new Operand[] {
                        new Operand(vd, sz),
                        new Operand(vs, sz),
                        new Operand("CC[...]"),
                    };
                }
            }
            return(true);
        }
        public static bool Vcst(uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands)
        {
            int    conNum = ( int )(code >> 16) & 0x1F;
            string con;

            if (conNum >= vfpuconstants.Length)
            {
                con = vfpuconstants[0];
            }
            else
            {
                con = vfpuconstants[conNum];
            }
            opcode   = new Opcode(entry, VSuff(code));
            operands = new Operand[] {
                new Operand(VD(code), DataSize.V_Single),
                new Operand(con),
            };
            return(true);
        }
        public static bool Vtfm(uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands)
        {
            Register vd  = VD(code);
            Register vs  = VS(code);
            Register vt  = VT(code);
            uint     ins = (code >> 23) & 7;
            DataSize sz  = GetVecSize(code);
            DataSize msz = GetMtxSize(code);
            int      n   = GetNumElements(sz);

            string suffix = string.Format("{0}{1}", n, VSuff(code));

            if (n == ins)
            {
                //homogenous
                opcode   = new Opcode(entry, suffix, "vhtfm");
                operands = new Operand[] {
                    new Operand(vd, sz),
                    new Operand(vs, msz),                       // Matrix
                    new Operand(vt, sz),
                };
            }
            else if (n == ins + 1)
            {
                opcode   = new Opcode(entry, suffix, "vtfm");
                operands = new Operand[] {
                    new Operand(vd, sz),
                    new Operand(vs, msz),                       // Matrix
                    new Operand(vt, sz),
                };
            }
            else
            {
                // ?
                opcode   = new Opcode(entry, suffix);
                operands = new Operand[] {
                    new Operand("badvtfm"),
                };
            }
            return(true);
        }
        public static bool RelBranch2(uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands)
        {
            // TODO: intrinsic
            //int o = op>>26;
            //if (o==4 && rs == rt)//beq
            //    sprintf(out,"b\t->$%08x",off);
            //else if (o==4 && rs == rt)//beq
            //    sprintf(out,"bl\t->$%08x",off);
            //else
            //    sprintf(out, "%s\t%s, %s, ->$%08x",name,RN(rt),RN(rs),off);

            int imm = IMM16(code) << 2;

            opcode   = new Opcode(entry);
            operands = new Operand[] {
                new Operand(RT(code)),
                new Operand(RS(code)),
                new Operand(OperandType.BranchTarget, imm),
            };
            return(true);
        }
        public static bool Vcrs(uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands)
        {
            DataSize sz = GetVecSize(code);

            if (sz != DataSize.V_Triple)
            {
                // ?
                opcode   = new Opcode(entry, ".??????");
                operands = new Operand[] {
                };
            }
            else
            {
                opcode   = new Opcode(entry, VSuff(code));
                operands = new Operand[] {
                    new Operand(VD(code), sz),
                    new Operand(VS(code), sz),
                    new Operand(VT(code), sz),
                };
            }
            return(true);
        }
        public static bool Special3(uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands)
        {
            int size = 0;

            switch (code & 0x3F)
            {
            case 0x0:                     // ext
                size = SIZE(code) + 1;
                break;

            case 0x4:                     // ins
                size = (SIZE(code) + 1) - POS(code);
                break;
            }
            opcode   = new Opcode(entry);
            operands = new Operand[] {
                new Operand(RT(code)),
                new Operand(RS(code)),
                new Operand(POS(code), 1),
                new Operand(size, 1),
            };
            return(true);
        }
 public static bool VRot( uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands )
 {
     int imm = ( int )( code >> 16 ) & 0x1F;
     bool negSin = ( ( imm & 0x10 ) == 0x10 );
     char[] c = new char[] { '.', '.', '.', '.' };
     char[] temp = new char[ 16 ];
     if( ( ( imm >> 2 ) & 3 ) == ( imm & 3 ) )
     {
         for( int n = 0; n < 4; n++ )
             c[ n ] = 'S';
     }
     c[ ( imm >> 2 ) & 3 ] = 'S';
     c[ imm & 3 ] = 'C';
     DataSize sz = GetVecSize( code );
     int numElems = GetNumElements( sz );
     int pos = 0;
     temp[ pos++ ] = '[';
     for( int n = 0; n < numElems; n++ )
     {
         if( c[ n ] == 'S' && negSin )
             temp[ pos++ ] = '-';
         else
             temp[ pos++ ] = ' ';
         temp[ pos++ ] = c[ n ];
         temp[ pos++ ] = ' ';
     }
     temp[ pos++ ] = ']';
     opcode = new Opcode( entry, VSuff( code ) );
     operands = new Operand[]{
         new Operand( VD( code ), sz ),
         new Operand( VS( code ), DataSize.V_Single ),
         new Operand( new string( temp, 0, pos ) ),
     };
     return true;
 }
 public static bool Viim( uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands )
 {
     int imm = ( int )( code & 0xFFFF );
     int type = ( int )( code >> 23 ) & 7;
     opcode = new Opcode( entry );
     if( type == 6 )
     {
         operands = new Operand[]{
             new Operand( VT( code ), DataSize.V_Single ),
             new Operand( imm, 2 ),
         };
     }
     else if( type == 7 )
     {
         operands = new Operand[]{
             new Operand( VT( code ), DataSize.V_Single ),
             new Operand( Float16ToFloat32( ( ushort )imm ) ),
         };
     }
     else
     {
         operands = new Operand[]{
             new Operand( "????" ),
         };
     }
     return true;
 }
 public static bool Vflush( uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands )
 {
     opcode = new Opcode( entry, ".??????" );
     operands = new Operand[]{
     };
     return true;
 }
 public static bool Vcst( uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands )
 {
     int conNum = ( int )( code >> 16 ) & 0x1F;
     string con;
     if( conNum >= vfpuconstants.Length )
         con = vfpuconstants[ 0 ];
     else
         con = vfpuconstants[ conNum ];
     opcode = new Opcode( entry, VSuff( code ) );
     operands = new Operand[]{
         new Operand( VD( code ), DataSize.V_Single ),
         new Operand( con ),
     };
     return true;
 }
 public static bool Vcmp( uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands )
 {
     uint cond = code & 15;
     DataSize sz = GetVecSize( code );
     opcode = new Opcode( entry, VSuff( code ) );
     operands = new Operand[]{
         new Operand( condNames[ cond ] ),
         new Operand( VS( code ), sz ),
         new Operand( VT( code ), sz ),
     };
     return true;
 }
 public static bool VBranch( uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands )
 {
     uint imm3 = ( code >> 18 ) & 7;
     opcode = new Opcode( entry );
     operands = new Operand[]{
         new Operand( ( int )imm3, 4, "CC" ),
         new Operand( OperandType.BranchTarget, IMM16( code ) ),
     };
     return true;
 }
 public static bool Syscall( uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands )
 {
     uint callno = ( code >> 6 ) & 0xFFFFF; //20 bits
     uint funcnum = callno & 0xFFF;
     uint modulenum = ( callno & 0xFF000 ) >> 12;
     //sprintf(out, "syscall\t  %s",/*PSPHLE::GetModuleName(modulenum),*/PSPHLE::GetFuncName(modulenum, funcnum));
     opcode = new Opcode( entry );
     operands = new Operand[]{
         new Operand( ( int )callno, 4 ),
     };
     return true;
 }
        public static bool Vtfm( uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands )
        {
            Register vd = VD( code );
            Register vs = VS( code );
            Register vt = VT( code );
            uint ins = ( code >> 23 ) & 7;
            DataSize sz = GetVecSize( code );
            DataSize msz = GetMtxSize( code );
            int n = GetNumElements( sz );

            string suffix = string.Format( "{0}{1}", n, VSuff( code ) );
            if( n == ins )
            {
                //homogenous
                opcode = new Opcode( entry, suffix, "vhtfm" );
                operands = new Operand[]{
                    new Operand( vd, sz ),
                    new Operand( vs, msz ), // Matrix
                    new Operand( vt, sz ),
                };
            }
            else if( n == ins + 1 )
            {
                opcode = new Opcode( entry, suffix, "vtfm" );
                operands = new Operand[]{
                    new Operand( vd, sz ),
                    new Operand( vs, msz ), // Matrix
                    new Operand( vt, sz ),
                };
            }
            else
            {
                // ?
                opcode = new Opcode( entry, suffix );
                operands = new Operand[]{
                    new Operand( "badvtfm" ),
                };
            }
            return true;
        }
 public static bool ToHiloTransfer( uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands )
 {
     opcode = new Opcode( entry );
     operands = new Operand[]{
         new Operand( RS( code ) ),
     };
     return true;
 }
 public static bool MatrixSet2( uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands )
 {
     DataSize sz = GetMtxSize( code );
     opcode = new Opcode( entry, VSuff( code ) );
     operands = new Operand[]{
         new Operand( VD( code ), sz ), // Matrix
         new Operand( VS( code ), sz ), // Matrix
     };
     return true;
 }
 public static bool Vcmov( uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands )
 {
     DataSize sz = GetVecSize( code );
     Register vd = VD( code );
     Register vs = VS( code );
     uint tf = ( code >> 19 ) & 3;
     uint imm3 = ( code >> 16 ) & 7;
     if( tf > 1 )
     {
         // ?????
         opcode = new Opcode( entry, ".??????" );
         operands = new Operand[]{
             new Operand( ( int )tf, 1 ),
         };
     }
     else
     {
         string suffix = string.Format( "{0}{1}",
             ( tf == 0 ) ? "t" : "f",
             VSuff( code ) );
         opcode = new Opcode( entry, suffix );
         if( imm3 < 6 )
         {
             operands = new Operand[]{
                 new Operand( vd, sz ),
                 new Operand( vs, sz ),
                 new Operand( ( int )imm3, 1, "CC" ),
             };
         }
         else
         {
             Debug.Assert( imm3 == 6 );
             operands = new Operand[]{
                 new Operand( vd, sz ),
                 new Operand( vs, sz ),
                 new Operand( "CC[...]" ),
             };
         }
     }
     return true;
 }
 public static bool Mftv( uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands )
 {
     // This may be broken!
     int vr = ( int )( code & 0xFF );
     bool transposed = ( vr & 0x80 ) != 0;
     opcode = new Opcode( entry, transposed ? "c" : "" );
     operands = new Operand[]{
         new Operand( RT( code ) ),
         new Operand( RegisterBanks.Vfpu.Registers[ ( vr & 0x80 ) ], DataSize.V_Single, transposed ),
     };
     return true;
 }
 public static bool Vcrs( uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands )
 {
     DataSize sz = GetVecSize( code );
     if( sz != DataSize.V_Triple )
     {
         // ?
         opcode = new Opcode( entry, ".??????" );
         operands = new Operand[]{
         };
     }
     else
     {
         opcode = new Opcode( entry, VSuff( code ) );
         operands = new Operand[]{
             new Operand( VD( code ), sz ),
             new Operand( VS( code ), sz ),
             new Operand( VT( code ), sz ),
         };
     }
     return true;
 }
        public static bool ori( uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands )
        {
            // TODO: instrinsic
            // if rs == 0, li rt, imm

            opcode = new Opcode( entry );
            operands = new Operand[]{
                new Operand( RT( code ) ),
                new Operand( RS( code ) ),
                new Operand( IMM16( code ), 2 ),
            };
            return true;
        }
 public static bool VectorSet3( uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands )
 {
     DataSize sz = GetVecSize( code );
     opcode = new Opcode( entry, VSuff( code ) );
     operands = new Operand[]{
         new Operand( VD( code ), sz ),
         new Operand( VS( code ), sz ),
         new Operand( VT( code ), sz ),
     };
     return true;
 }
 public static bool RelBranch( uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands )
 {
     int imm = IMM16( code ) << 2;
     opcode = new Opcode( entry );
     operands = new Operand[]{
         new Operand( RS( code ) ),
         new Operand( OperandType.BranchTarget, imm ),
     };
     return true;
 }
 public static bool Vf2i( uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands )
 {
     DataSize sz = GetVecSize( code );
     uint imm = ( code >> 16 ) & 0x1F;
     opcode = new Opcode( entry, VSuff( code ) );
     operands = new Operand[]{
         new Operand( VD( code ), sz ),
         new Operand( VS( code ), sz ),
         new Operand( ( int )imm, 1 ),
     };
     return true;
 }
        public static bool RelBranch2( uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands )
        {
            // TODO: intrinsic
            //int o = op>>26;
            //if (o==4 && rs == rt)//beq
            //    sprintf(out,"b\t->$%08x",off);
            //else if (o==4 && rs == rt)//beq
            //    sprintf(out,"bl\t->$%08x",off);
            //else
            //    sprintf(out, "%s\t%s, %s, ->$%08x",name,RN(rt),RN(rs),off);

            int imm = IMM16( code ) << 2;
            opcode = new Opcode( entry );
            operands = new Operand[]{
                new Operand( RT( code ) ),
                new Operand( RS( code ) ),
                new Operand( OperandType.BranchTarget, imm ),
            };
            return true;
        }
 public static bool Vi2x( uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands )
 {
     DataSize sz = GetVecSize( code );
     DataSize dsz = GetHalfSize( sz );
     if( ( ( code >> 16 ) & 3 ) == 0 )
         dsz = DataSize.V_Single;
     opcode = new Opcode( entry, VSuff( code ) );
     operands = new Operand[]{
         new Operand( VD( code ), dsz ),
         new Operand( VS( code ), sz ),
     };
     return true;
 }
 public static bool Special3( uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands )
 {
     int size = 0;
     switch( code & 0x3F )
     {
         case 0x0: // ext
             size = SIZE( code ) + 1;
             break;
         case 0x4: // ins
             size = ( SIZE( code ) + 1 ) - POS( code );
             break;
     }
     opcode = new Opcode( entry );
     operands = new Operand[]{
         new Operand( RT( code ) ),
         new Operand( RS( code ) ),
         new Operand( POS( code ), 1 ),
         new Operand( size, 1 ),
     };
     return true;
 }
 public static bool VPFXD( uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands )
 {
     List<Operand> ops = new List<Operand>();
     int data = ( int )( code & 0xFFFFF );
     for( int n = 0; n < 4; n++ )
     {
         int sat = ( data >> ( n * 2 ) ) & 0x3;
         int mask = ( data >> ( 8 + n ) ) & 0x1;
         string op = "";
         if( sat != 0 )
             op += satNames[ sat ];
         if( mask != 0 )
             op += "M";
         if( op.Length > 0 )
             ops.Add( new Operand( op ) );
     }
     opcode = new Opcode( entry );
     operands = ops.ToArray();
     return true;
 }
 public static bool SV( uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands )
 {
     int offset = ( short )( code & 0xFFFC );
     int vt = ( int )( ( code >> 16 ) & 0x1F ) | ( int )( ( code & 3 ) << 5 );
     // if vt & 0x80, transposed
     opcode = new Opcode( entry );
     operands = new Operand[]{
         new Operand( RegisterBanks.Vfpu.Registers[ vt ], DataSize.V_Single ),
         new Operand( OperandType.MemoryAccess, RS( code ), offset ),
     };
     return true;
 }
 public static bool VPFXST( uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands )
 {
     List<Operand> ops = new List<Operand>();
     int data = ( int )( code & 0xFFFFF );
     for( int n = 0; n < 4; n++ )
     {
         int regnum = ( data >> ( n * 2 ) ) & 3;
         int abs = ( data >> ( 8 + n ) ) & 1;
         int negate = ( data >> ( 16 + n ) ) & 1;
         int constants = ( data >> ( 12 + n ) ) & 1;
         string op = "";
         if( negate != 0 )
             op += "-";
         if( ( abs != 0 ) && ( constants == 0 ) )
             op += "|";
         if( constants == 0 )
             op += vregnames[ regnum ];
         else
         {
             if( abs != 0 )
                 regnum += 4;
             op += vconstants[ regnum ];
         }
         if( ( abs != 0 ) && ( constants == 0 ) )
             op += "|";
         if( op.Length > 0 )
             ops.Add( new Operand( op ) );
     }
     opcode = new Opcode( entry );
     operands = ops.ToArray();
     return true;
 }
 public static bool SVLRQ( uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands )
 {
     int offset = ( short )( code & 0xFFFC );
     int vt = ( int )( ( ( code >> 16 ) & 0x1f ) ) | ( int )( ( code & 1 ) << 5 );
     int lr = ( int )( code >> 1 ) & 1;
     string suffix = string.Format( "{0}.q", ( lr != 0 ) ? "r" : "l" );
     opcode = new Opcode( entry, suffix );
     operands = new Operand[]{
         new Operand( RegisterBanks.Vfpu.Registers[ vt ], DataSize.V_Quad ),
         new Operand( OperandType.MemoryAccess, RS( code ), offset ),
     };
     return true;
 }
 public static bool VScl( uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands )
 {
     DataSize sz = GetVecSize( code );
     opcode = new Opcode( entry );
     operands = new Operand[]{
         new Operand( VD( code ), sz ),
         new Operand( VS( code ), sz ),
         new Operand( VT( code ), DataSize.V_Single ),
     };
     return true;
 }
 public static bool SVQ( uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands )
 {
     int offset = ( short )( code & 0xFFFC );
     int vt = ( int )( ( ( code >> 16 ) & 0x1F ) ) | ( int )( ( code & 1 ) << 5 );
     opcode = new Opcode( entry );
     Operand op1 = new Operand( RegisterBanks.Vfpu.Registers[ vt ], DataSize.V_Quad );
     Operand op2 = new Operand( OperandType.MemoryAccess, RS( code ), offset );
     if( ( code & 0x2 ) != 0 )
     {
         operands = new Operand[]{
             op1, op2,
             new Operand( "wb" ),
         };
     }
     else
     {
         operands = new Operand[]{
             op1, op2,
         };
     }
     return true;
 }
 public static bool Allegrex( uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands )
 {
     opcode = new Opcode( entry );
     operands = new Operand[]{
         new Operand( RD( code ) ),
         new Operand( RT( code ) ),
     };
     return true;
 }
 public static bool JumpType( uint address, uint code, InstructionEntry entry, out Opcode opcode, out Operand[] operands )
 {
     uint offset = ( ( code & 0x03FFFFFF ) << 2 );
     uint addr = ( address & 0xF0000000 ) | offset;
     opcode = new Opcode( entry );
     operands = new Operand[]{
         new Operand( OperandType.JumpTarget, ( int )addr ),
     };
     return true;
 }