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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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; }