// Aqsis
// Copyright (c) 1997 - 2001, Paul C. Gregory
//
// Contact: pgregory@aqsis.com
//
// This library is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation; either
// version 2 of the License, or (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA

/**
 * Copyright (C) 2006-2007  NTT DATA CORPORATION
 * 
 * Version: 1.0.0 2007/04/01
 *  
 */
package net.cellcomputing.himawari.shadervm;

import static java.lang.Math.max;

import java.lang.reflect.Method;

import net.cellcomputing.himawari.accessory.STLArray;
import net.cellcomputing.himawari.accessory.STLVector;
import net.cellcomputing.himawari.accessory.primitive.p_String;
import net.cellcomputing.himawari.accessory.primitive.p_float;
import net.cellcomputing.himawari.accessory.primitive.p_int;
import net.cellcomputing.himawari.library.IqShaderData;
import net.cellcomputing.himawari.library.types.CqBitVector;
import net.cellcomputing.himawari.library.types.CqColor;
import net.cellcomputing.himawari.library.types.CqMatrix;
import net.cellcomputing.himawari.library.types.CqVector3D;
import net.cellcomputing.himawari.library.types.CqVector4D;
import net.cellcomputing.himawari.util.AccessSupplier;
import net.cellcomputing.himawari.util.HimawariLogger;

/**
 * 
 * shadervmパッケージのグローバル領域
 * 
 * @author NTT DATA Corporation
 */
@SuppressWarnings("unchecked")
public strictfp class GlobalShaderVM {
	
	public static p_float		temp_float	= new p_float();
	public static CqVector3D	temp_point	= new CqVector3D();
	public static CqColor		temp_color	= new CqColor();
	public static p_String		temp_string	= new p_String();
	public static CqMatrix		temp_matrix	= new CqMatrix();
	
	
	
	
	public static void OpLSS_FF( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpLSS(temp_float,temp_float,temp_float,a,b,Res,State,p_float.class,p_float.class,p_float.class);
	}
	public static void OpLSS_PP( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpLSS(temp_point,temp_point,temp_float,a,b,Res,State,CqVector3D.class,CqVector3D.class,p_float.class);
	}
	public static void OpLSS_CC( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpLSS(temp_color,temp_color,temp_float,a,b,Res,State,CqColor.class,CqColor.class,p_float.class);
	}
	
	public static void OpGRT_FF( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpGRT(temp_float,temp_float,temp_float,a,b,Res,State,p_float.class,p_float.class,p_float.class);
	}
	public static void OpGRT_PP( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpGRT(temp_point,temp_point,temp_float,a,b,Res,State,CqVector3D.class,CqVector3D.class,p_float.class);
	}
	public static void OpGRT_CC( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpGRT(temp_color,temp_color,temp_float,a,b,Res,State,CqColor.class,CqColor.class,p_float.class);
	}
	
	public static void OpLE_FF( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpLE(temp_float,temp_float,temp_float,a,b,Res,State,p_float.class,p_float.class,p_float.class);
	}
	public static void OpLE_PP( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpLE(temp_point,temp_point,temp_float,a,b,Res,State,CqVector3D.class,CqVector3D.class,p_float.class);
	}
	public static void OpLE_CC( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpLE(temp_color,temp_color,temp_float,a,b,Res,State,CqColor.class,CqColor.class,p_float.class);
	}
	
	public static void OpGE_FF( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpGE(temp_float,temp_float,temp_float,a,b,Res,State,p_float.class,p_float.class,p_float.class);
	}
	public static void OpGE_PP( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpGE(temp_point,temp_point,temp_float,a,b,Res,State,CqVector3D.class,CqVector3D.class,p_float.class);
	}
	public static void OpGE_CC( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpGE(temp_color,temp_color,temp_float,a,b,Res,State,CqColor.class,CqColor.class,p_float.class);
	}
	
	public static void OpEQ_FF( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpEQ(temp_float,temp_float,temp_float,a,b,Res,State,p_float.class,p_float.class,p_float.class);
	}
	public static void OpEQ_PP( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpEQ(temp_point,temp_point,temp_float,a,b,Res,State,CqVector3D.class,CqVector3D.class,p_float.class);
	}
	public static void OpEQ_CC( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpEQ(temp_color,temp_color,temp_float,a,b,Res,State,CqColor.class,CqColor.class,p_float.class);
	}
	public static void OpEQ_SS( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpEQ(temp_string,temp_string,temp_float,a,b,Res,State,p_String.class,p_String.class,p_float.class);
	}
	
	public static void OpNE_FF( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpNE(temp_float,temp_float,temp_float,a,b,Res,State,p_float.class,p_float.class,p_float.class);
	}
	public static void OpNE_PP( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpNE(temp_point,temp_point,temp_float,a,b,Res,State,CqVector3D.class,CqVector3D.class,p_float.class);
	}
	public static void OpNE_CC( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpNE(temp_color,temp_color,temp_float,a,b,Res,State,CqColor.class,CqColor.class,p_float.class);
	}
	public static void OpNE_SS( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpNE(temp_string,temp_string,temp_float,a,b,Res,State,p_String.class,p_String.class,p_float.class);
	}
	
	public static void OpMUL_FF( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpMUL(temp_float,temp_float,temp_float,a,b,Res,State,p_float.class,p_float.class,p_float.class);
	}
	public static void OpDIV_FF( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpDIV(temp_float,temp_float,temp_float,a,b,Res,State,p_float.class,p_float.class,p_float.class);
	}
	public static void OpADD_FF( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpADD(temp_float,temp_float,temp_float,a,b,Res,State,p_float.class,p_float.class,p_float.class);
	}
	public static void OpSUB_FF( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpSUB(temp_float,temp_float,temp_float,a,b,Res,State,p_float.class,p_float.class,p_float.class);
	}
	public static void OpNEG_F( IqShaderData a, IqShaderData Res, CqBitVector State ){
		OpNEG(temp_float,a,Res,State,p_float.class);
	}
	
	public static void OpMUL_PP( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpMUL(temp_point,temp_point,temp_point,a,b,Res,State,CqVector3D.class,CqVector3D.class,CqVector3D.class);
	}
	public static void OpDIV_PP( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpDIV(temp_point,temp_point,temp_point,a,b,Res,State,CqVector3D.class,CqVector3D.class,CqVector3D.class);
	}
	public static void OpADD_PP( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpADD(temp_point,temp_point,temp_point,a,b,Res,State,CqVector3D.class,CqVector3D.class,CqVector3D.class);
	}
	public static void OpSUB_PP( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpSUB(temp_point,temp_point,temp_point,a,b,Res,State,CqVector3D.class,CqVector3D.class,CqVector3D.class);
	}
	public static void OpCRS_PP( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpCRS(temp_point,temp_point,temp_point,a,b,Res,State,CqVector3D.class,CqVector3D.class,CqVector3D.class);
	}
	public static void OpDOT_PP( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpDOT(temp_point,temp_point,temp_float,a,b,Res,State,CqVector3D.class,CqVector3D.class,p_float.class);
	}
	public static void OpNEG_P( IqShaderData a, IqShaderData Res, CqBitVector State ){
		OpNEG(temp_point,a,Res,State,CqVector3D.class);
	}
	
	public static void OpMUL_CC( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpMUL(temp_color,temp_color,temp_color,a,b,Res,State,CqColor.class,CqColor.class,CqColor.class);
	}
	public static void OpDIV_CC( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpDIV(temp_color,temp_color,temp_color,a,b,Res,State,CqColor.class,CqColor.class,CqColor.class);
	}
	public static void OpADD_CC( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpADD(temp_color,temp_color,temp_color,a,b,Res,State,CqColor.class,CqColor.class,CqColor.class);
	}
	public static void OpSUB_CC( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpSUB(temp_color,temp_color,temp_color,a,b,Res,State,CqColor.class,CqColor.class,CqColor.class);
	}
	public static void OpCRS_CC( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpCRS(temp_color,temp_color,temp_color,a,b,Res,State,CqColor.class,CqColor.class,CqColor.class);
	}
	public static void OpDOT_CC( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpDOT(temp_color,temp_color,temp_color,a,b,Res,State,CqColor.class,CqColor.class,CqColor.class);
	}
	public static void OpNEG_C( IqShaderData a, IqShaderData Res, CqBitVector State ){
		OpNEG(temp_color,a,Res,State,CqColor.class);
	}
	
	public static void OpMUL_FP( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpMUL(temp_float,temp_point,temp_point,a,b,Res,State,p_float.class,CqVector3D.class,CqVector3D.class);
	}
	public static void OpDIV_FP( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpDIV(temp_float,temp_point,temp_point,a,b,Res,State,p_float.class,CqVector3D.class,CqVector3D.class);
	}
	public static void OpADD_FP( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpADD(temp_float,temp_point,temp_point,a,b,Res,State,p_float.class,CqVector3D.class,CqVector3D.class);
	}
	public static void OpSUB_FP( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpSUB(temp_float,temp_point,temp_point,a,b,Res,State,p_float.class,CqVector3D.class,CqVector3D.class);
	}
	
	public static void OpMUL_FC( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpMUL(temp_float,temp_color,temp_color,a,b,Res,State,p_float.class,CqColor.class,CqColor.class);
	}
	public static void OpDIV_FC( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpDIV(temp_float,temp_color,temp_color,a,b,Res,State,p_float.class,CqColor.class,CqColor.class);
	}
	public static void OpADD_FC( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpADD(temp_float,temp_color,temp_color,a,b,Res,State,p_float.class,CqColor.class,CqColor.class);
	}
	public static void OpSUB_FC( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpSUB(temp_float,temp_color,temp_color,a,b,Res,State,p_float.class,CqColor.class,CqColor.class);
	}
	
	public static void OpLAND_B( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpLAND(temp_float,temp_float,temp_float,a,b,Res,State,p_float.class,p_float.class,p_float.class);
	}
	public static void OpLOR_B( IqShaderData a, IqShaderData b, IqShaderData Res, CqBitVector State ){
		OpLOR(temp_float,temp_float,temp_float,a,b,Res,State,p_float.class,p_float.class,p_float.class);
	}
	
	public static void OpCAST_FC( IqShaderData a, IqShaderData Res, CqBitVector State ){
		OpCAST(temp_float,temp_color, a,Res,State,p_float.class,CqColor.class);
	}
	public static void OpCAST_FP( IqShaderData a, IqShaderData Res, CqBitVector State ){
		OpCAST(temp_float,temp_point, a,Res,State,p_float.class,CqVector3D.class);
	}
	public static void OpCAST_PC( IqShaderData a, IqShaderData Res, CqBitVector State ){
		OpCAST(temp_point,temp_color, a,Res,State,CqVector3D.class,CqColor.class);
	}
	public static void OpCAST_CP( IqShaderData a, IqShaderData Res, CqBitVector State ){
		OpCAST(temp_color,temp_point, a,Res,State,CqColor.class,CqVector3D.class);
	}
	public static void OpCAST_FM( IqShaderData a, IqShaderData Res, CqBitVector State ){
		OpCAST(temp_float,temp_matrix, a,Res,State,p_float.class,CqMatrix.class);
	}
	
	public static void OpTRIPLE_C( IqShaderData r, IqShaderData a, IqShaderData b, IqShaderData c, CqBitVector State ){
		OpTRIPLE(temp_color,r,a,b,c,State,CqColor.class);
	}
	public static void OpTRIPLE_P( IqShaderData r, IqShaderData a, IqShaderData b, IqShaderData c, CqBitVector State ){
		OpTRIPLE(temp_point,r,a,b,c,State,CqVector3D.class);
	}
	
	public static void OpHEXTUPLE_M( IqShaderData r, IqShaderData a, IqShaderData b, IqShaderData c, IqShaderData d, IqShaderData e, IqShaderData f, IqShaderData g, IqShaderData h, IqShaderData i, IqShaderData j, IqShaderData k, IqShaderData l, IqShaderData m, IqShaderData n, IqShaderData o, IqShaderData p, CqBitVector State){
		OpHEXTUPLE(temp_matrix,r,a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,State,CqMatrix.class);
	}
	
	public static void OpCOMP_C( IqShaderData a, IqShaderData index, IqShaderData Res, CqBitVector State){
		OpCOMP(temp_color,a,index,Res,State,CqColor.class);
	}
	public static void OpCOMP_P( IqShaderData a, IqShaderData index, IqShaderData Res, CqBitVector State){
		OpCOMP(temp_point,a,index,Res,State,CqVector3D.class);
	}
	public static void OpCOMP_C( IqShaderData a, int index, IqShaderData Res, CqBitVector State){
		OpCOMP(temp_color,a,index,Res,State,CqColor.class);
	}
	public static void OpCOMP_P( IqShaderData a, int index, IqShaderData Res, CqBitVector State){
		OpCOMP(temp_point,a,index,Res,State,CqVector3D.class);
	}
	
	
	
	//
	//	 Define macros for defining Opcodes efficiently
	//	 a The type of the first operand, used to determine templateisation, needed by VC++..
	//	 b The type of the second operand, used to determine templateisation, needed by VC++..
	//	 Comp The stack entry to use as the second operand.
	//	 Res The stack entry to store the result in.
	//	 RunningState The current SIMD state.
	//nttdata 高速化
//	private static <A, B, R> void  OpABRS( String OP, A a, B b, R r, IqShaderData pA, IqShaderData pB, IqShaderData pRes, CqBitVector RunningState, Class<A> clsA, Class<B> clsB, Class<R> clsR )
//	{
//		A vA	= AccessSupplier.getNewInstance(clsA);
//		B vB	= AccessSupplier.getNewInstance(clsB);
//		STLVector<A> pdA = new STLVector<A>(clsA);
//		STLVector<B> pdB = new STLVector<B>(clsB);
//		STLVector<R> pdR = new STLVector<R>(clsR);
//		int idxA, idxB, idxR;
//		idxA = idxB = idxR = 0;
//		
//		int i, ii;
//		boolean fAVar = pA.Size() > 1;
//		boolean fBVar = pB.Size() > 1;
//		if( fAVar && fBVar )
//		{
//			/* Both are varying, must go accross all processing each element. */
//			pA.GetValuePtr( pdA );
//			pB.GetValuePtr( pdB );
//			pRes.GetValuePtr( pdR );
//			ii = (int)pA.Size();
//			for ( i = 0; i < ii; i++ )
//			{
//				if ( RunningState.Value( i ) )
//					pRes.SetValue( (R)oparator( OP, pdA.get(idxA), pdB.get(idxB), clsA, clsB ), idxR, clsR );
//				idxA++;
//				idxB++;
//				idxR++;
//			}
//		}
//		else if( !fBVar && fAVar)
//		{
//			/* A is varying, can just get B's value once. */
//			ii = (int)pA.Size();
//			pA.GetValuePtr( pdA );
//			pB.GetValue( vB, clsB );
//			pRes.GetValuePtr( pdR );
//			for ( i = 0; i < ii; i++ )
//			{
//				if ( RunningState.Value( i ) )
//					pRes.SetValue( (R)oparator( OP, pdA.get(idxA), vB, clsA, clsB ), idxR, clsR );
//				idxA++;
//				idxR++;
//			}
//		}
//		else if( !fAVar && fBVar)
//		{
//			/* B is varying, can just get A's value once. */
//			ii = (int)pB.Size();
//			pB.GetValuePtr( pdB );
//			pA.GetValue( vA, clsA );
//			pRes.GetValuePtr( pdR );
//			for ( i = 0; i < ii; i++ )
//			{
//				if ( RunningState.Value( i ) )
//					pRes.SetValue( (R)oparator( OP, vA, pdB.get(idxB), clsA, clsB ), idxR, clsR );
//				idxB++;
//				idxR++;
//			}
//		}
//		else
//		{
//			/* Both are uniform, simple one shot case. */
//			pA.GetValue( vA, clsA );
//			pB.GetValue( vB, clsB );
//			pRes.SetValue( (R)oparator( OP, vA, vB, clsA, clsB ), clsR );
//		}
//	}
	private static <A, B, R> void  OpABRS( String OP, A a, B b, R r, IqShaderData pA, IqShaderData pB, IqShaderData pRes, CqBitVector RunningState, Class<A> clsA, Class<B> clsB, Class<R> clsR )
	{
//		A vA	= AccessSupplier.getNewInstance(clsA);
//		B vB	= AccessSupplier.getNewInstance(clsB);
		A vA = null;
		B vB = null;
		try {
			vA = clsA.newInstance();
			vB = clsB.newInstance();
		} catch (InstantiationException e) {
			e.printStackTrace();
		} catch (IllegalAccessException e) {
			e.printStackTrace();
		}	
		
//		STLVector<A> pdA ;
//		STLVector<B> pdB ;
//		STLVector<R> pdR ;
		STLArray<A> pdA ;
		STLArray<B> pdB ;
		STLArray<R> pdR ;
		int idxA, idxB, idxR;
		idxA = idxB = idxR = 0;
		
		int i, ii;
		boolean fAVar = pA.Size() > 1;
		boolean fBVar = pB.Size() > 1;
		if( fAVar && fBVar )
		{
			/* Both are varying, must go accross all processing each element. */
			pdA = pA.GetValuePtr_2( a );
			pdB = pB.GetValuePtr_2( b );
			pdR = pRes.GetValuePtr_2( r );
			ii = (int)pA.Size();
			for ( i = 0; i < ii; i++ )
			{
				if ( RunningState.Value( i ) )
					pRes.SetValue( (R)oparator( OP, pdA.get(idxA), pdB.get(idxB), clsA, clsB ), idxR, clsR );
				idxA++;
				idxB++;
				idxR++;
			}
		}
		else if( !fBVar && fAVar)
		{
			/* A is varying, can just get B's value once. */
			ii = (int)pA.Size();
			pdA = pA.GetValuePtr_2( a );
			pB.GetValue( vB, clsB );
			pdR = pRes.GetValuePtr_2( r );
			
			for ( i = 0; i < ii; i++ )
			{
				if ( RunningState.Value( i ) )
					pRes.SetValue( (R)oparator( OP, pdA.get(idxA), vB, clsA, clsB ), idxR, clsR );
				idxA++;
				idxR++;
			}
		}
		else if( !fAVar && fBVar)
		{
			/* B is varying, can just get A's value once. */
			ii = (int)pB.Size();
			pdB = pB.GetValuePtr_2( b );
			pA.GetValue( vA, clsA );
			pdR = pRes.GetValuePtr_2( r );
			for ( i = 0; i < ii; i++ )
			{
				if ( RunningState.Value( i ) )
					pRes.SetValue( (R)oparator( OP, vA, pdB.get(idxB), clsA, clsB ), idxR, clsR );
				idxB++;
				idxR++;
			}
		}
		else
		{
			/* Both are uniform, simple one shot case. */
			pA.GetValue( vA, clsA );
			pB.GetValue( vB, clsB );
			pRes.SetValue( (R)oparator( OP, vA, vB, clsA, clsB ), clsR );
		}
	}
	/**
	 * Templatised less than operator.
	 * The template classes decide the cast used, there must be an appropriate operator between the two types.
	 */
	private static <A, B, R> void OpLSS( A a, B b, R r, IqShaderData pA, IqShaderData pB, IqShaderData pRes, CqBitVector RunningState, Class<A> clsA, Class<B> clsB, Class<R> clsR ) {
		OpABRS( "<", a, b, r, pA, pB, pRes, RunningState, clsA, clsB, clsR );
	}
	
	/**
	 * Templatised greater than operator.
	 * The template classes decide the cast used, there must be an appropriate operator between the two types.
	 */
	private static <A, B, R> void OpGRT( A a, B b, R r, IqShaderData pA, IqShaderData pB, IqShaderData pRes, CqBitVector RunningState, Class<A> clsA, Class<B> clsB, Class<R> clsR ) {
		OpABRS( ">", a, b, r, pA, pB, pRes, RunningState, clsA, clsB, clsR );
	}
	
	/**
	 * Templatised less than or equal to operator.
	 * The template classes decide the cast used, there must be an appropriate operator between the two types.
	 */
	private static <A, B, R> void OpLE( A a, B b, R r, IqShaderData pA, IqShaderData pB, IqShaderData pRes, CqBitVector RunningState, Class<A> clsA, Class<B> clsB, Class<R> clsR ) {
		OpABRS( "<=", a, b, r, pA, pB, pRes, RunningState, clsA, clsB, clsR );
	}
	
	/**
	 * Templatised greater than or equal to operator.
	 * The template classes decide the cast used, there must be an appropriate operator between the two types.
	 */
	private static <A, B, R> void OpGE( A a, B b, R r, IqShaderData pA, IqShaderData pB, IqShaderData pRes, CqBitVector RunningState, Class<A> clsA, Class<B> clsB, Class<R> clsR ) {
		OpABRS( ">=", a, b, r, pA, pB, pRes, RunningState, clsA, clsB, clsR );
	}
	
	/**
	 * Templatised equality operator.
	 * The template classes decide the cast used, there must be an appropriate operator between the two types.
	 */
	private static <A, B, R> void OpEQ( A a, B b, R r, IqShaderData pA, IqShaderData pB, IqShaderData pRes, CqBitVector RunningState, Class<A> clsA, Class<B> clsB, Class<R> clsR ) {
		OpABRS( "==", a, b, r, pA, pB, pRes, RunningState, clsA, clsB, clsR );
	}
	
	/**
	 * Templatised inequality operator.
	 * The template classes decide the cast used, there must be an appropriate operator between the two types.
	 */
	private static <A, B, R> void OpNE( A a, B b, R r, IqShaderData pA, IqShaderData pB, IqShaderData pRes, CqBitVector RunningState, Class<A> clsA, Class<B> clsB, Class<R> clsR ) {
		OpABRS( "!=", a, b, r, pA, pB, pRes, RunningState, clsA, clsB, clsR );
	}
	
	/**
	 * Templatised multiplication operator.
	 * The template classes decide the cast used, there must be an appropriate operator between the two types.
	 */
	private static <A, B, R> void OpMUL( A a, B b, R r, IqShaderData pA, IqShaderData pB, IqShaderData pRes, CqBitVector RunningState, Class<A> clsA, Class<B> clsB, Class<R> clsR ) {
		OpABRS( "*", a, b, r, pA, pB, pRes, RunningState, clsA, clsB, clsR );
	}
	
	/** 
	 * Special case vector multiplication operator.
	 * The template classes decide the cast used, there must be an appropriate operator between the two types.
	 */
//	public static void OpMULV( IqShaderData pA, IqShaderData pB, IqShaderData pRes, CqBitVector RunningState )
//	{
//	    CqVector3D vA = new CqVector3D(), vB = new CqVector3D();
//	    
//	    STLVector<CqVector3D> pdA = new STLVector<CqVector3D>(CqVector3D.class);
//	    STLVector<CqVector3D> pdB = new STLVector<CqVector3D>(CqVector3D.class);;
//	    int idxA,idxB;
//	    idxA = idxB = 0;
//	    
//	    int i, ii;
//
//	    boolean fAVar = pA.Size() > 1;
//	    boolean fBVar = pB.Size() > 1;
//
//	    if ( fAVar && fBVar )
//	    {
//	        /* Both are varying, must go accross all processing each element. */
//	        pA.GetValuePtr( pdA );
//	        pB.GetValuePtr( pdB );
//	        ii = (int)pA.Size();
//	        for ( i = 0; i < ii; i++ )
//	        {
//	            if ( RunningState.Value( i ) )
//	            	pRes.SetValue( new CqVector3D( pdA.get(idxA).x * pdB.get(idxB).x,
//							            			pdA.get(idxA).y * pdB.get(idxB).y,
//							            			pdA.get(idxA).z * pdB.get(idxB).z ), i );
//	            idxA++;
//	            idxB++;
//	        }
//	    }
//	    else if ( !fBVar && fAVar )
//	    {
//	        /* A is varying, can just get B's value once. */
//	        ii = (int)pA.Size();
//	        pA.GetValuePtr( pdA );
//	        pB.GetValue( vB );
//	        for ( i = 0; i < ii; i++ )
//	        {
//	            if ( RunningState.Value( i ) )
//	                pRes.SetValue( new CqVector3D( pdA.get(idxA).x * vB.x,
//							                		pdA.get(idxA).y * vB.y,
//							                		pdA.get(idxA).z * vB.z ), i );
//	            idxA++;
//	        }
//	    }
//	    else if ( !fAVar && fBVar )
//	    {
//	        /* B is varying, can just get A's value once. */
//	        ii = (int)pB.Size();
//	        pB.GetValuePtr( pdB );
//	        pA.GetValue( vA );
//	        for ( i = 0; i < ii; i++ )
//	        {
//	            if ( RunningState.Value( i ) )
//	                pRes.SetValue( new CqVector3D( vA.x * pdB.get(idxB).x,
//		                                            vA.y * pdB.get(idxB).y,
//		                                            vA.z * pdB.get(idxB).z ), i );
//	            idxB++;
//	        }
//	    }
//	    else
//	    {
//	        /* Both are uniform, simple one shot case. */
//	        pA.GetValue( vA );
//	        pB.GetValue( vB );
//	        pRes.SetValue( new CqVector3D( vA.x * vB.x,
//		                                    vA.y * vB.y,
//		                                    vA.z * vB.z ) );
//	    }
//	}
	public static void OpMULV( IqShaderData pA, IqShaderData pB, IqShaderData pRes, CqBitVector RunningState )
	{
	    CqVector3D vA = new CqVector3D(), vB = new CqVector3D();
	    
//	    STLVector<CqVector3D> pdA ;
//	    STLVector<CqVector3D> pdB ;
	    
	    STLArray<CqVector3D> pdA ;
	    STLArray<CqVector3D> pdB ;
	    int idxA,idxB;
	    idxA = idxB = 0;
	    
	    int i, ii;

	    boolean fAVar = pA.Size() > 1;
	    boolean fBVar = pB.Size() > 1;

	    if ( fAVar && fBVar )
	    {
	        /* Both are varying, must go accross all processing each element. */
	    	pdA = pA.GetValuePtr_2( vA );
	    	pdB = pB.GetValuePtr_2( vB );
	        ii = (int)pA.Size();
	        for ( i = 0; i < ii; i++ )
	        {
	            if ( RunningState.Value( i ) )
	            	pRes.SetValue( new CqVector3D( pdA.get(idxA).x * pdB.get(idxB).x,
							            			pdA.get(idxA).y * pdB.get(idxB).y,
							            			pdA.get(idxA).z * pdB.get(idxB).z ), i );
	            idxA++;
	            idxB++;
	        }
	    }
	    else if ( !fBVar && fAVar )
	    {
	        /* A is varying, can just get B's value once. */
	        ii = (int)pA.Size();
	        pdA = pA.GetValuePtr_2( vA );
	        pB.GetValue( vB );
	        for ( i = 0; i < ii; i++ )
	        {
	            if ( RunningState.Value( i ) )
	                pRes.SetValue( new CqVector3D( pdA.get(idxA).x * vB.x,
							                		pdA.get(idxA).y * vB.y,
							                		pdA.get(idxA).z * vB.z ), i );
	            idxA++;
	        }
	    }
	    else if ( !fAVar && fBVar )
	    {
	        /* B is varying, can just get A's value once. */
	        ii = (int)pB.Size();
	        pdB = pB.GetValuePtr_2( vB );
	        pA.GetValue( vA );
	        for ( i = 0; i < ii; i++ )
	        {
	            if ( RunningState.Value( i ) )
	                pRes.SetValue( new CqVector3D( vA.x * pdB.get(idxB).x,
		                                            vA.y * pdB.get(idxB).y,
		                                            vA.z * pdB.get(idxB).z ), i );
	            idxB++;
	        }
	    }
	    else
	    {
	        /* Both are uniform, simple one shot case. */
	        pA.GetValue( vA );
	        pB.GetValue( vB );
	        pRes.SetValue( new CqVector3D( vA.x * vB.x,
		                                    vA.y * vB.y,
		                                    vA.z * vB.z ) );
	    }
	}
	/**
	 * Templatised division operator.
	 * The template classes decide the cast used, there must be an appropriate operator between the two types.
	 */
	private static <A, B, R> void OpDIV( A a, B b, R r, IqShaderData pA, IqShaderData pB, IqShaderData pRes, CqBitVector RunningState, Class<A> clsA, Class<B> clsB, Class<R> clsR ) {
		OpABRS( "/", a, b, r, pA, pB, pRes, RunningState, clsA, clsB, clsR );
	}
	
	/**
	 * Templatised addition operator.
	 * The template classes decide the cast used, there must be an appropriate operator between the two types.
	 */
	private static <A, B, R> void OpADD( A a, B b, R r, IqShaderData pA, IqShaderData pB, IqShaderData pRes, CqBitVector RunningState, Class<A> clsA, Class<B> clsB, Class<R> clsR ) {
		OpABRS( "+", a, b, r, pA, pB, pRes, RunningState, clsA, clsB, clsR );
	}
	
	/**
	 * Templatised subtraction operator.
	 * The template classes decide the cast used, there must be an appropriate operator between the two types.
	 */
	private static <A, B, R> void OpSUB( A a, B b, R r, IqShaderData pA, IqShaderData pB, IqShaderData pRes, CqBitVector RunningState, Class<A> clsA, Class<B> clsB, Class<R> clsR ) {
		OpABRS( "-", a, b, r, pA, pB, pRes, RunningState, clsA, clsB, clsR );
	}
	
	/**
	 * Templatised dot operator.
	 * The template classes decide the cast used, there must be an appropriate operator between the two types.
	 */
	private static <A, B, R> void OpDOT( A a, B b, R r, IqShaderData pA, IqShaderData pB, IqShaderData pRes, CqBitVector RunningState, Class<A> clsA, Class<B> clsB, Class<R> clsR ) {
		OpABRS( "*", a, b, r, pA, pB, pRes, RunningState, clsA, clsB, clsR );
	}
	
	/**
	 * Templatised cross product operator.
	 * The template classes decide the cast used, there must be an appropriate operator between the two types.
	 */
	private static <A, B, R> void OpCRS( A a, B b, R r, IqShaderData pA, IqShaderData pB, IqShaderData pRes, CqBitVector RunningState, Class<A> clsA, Class<B> clsB, Class<R> clsR ) {
		OpABRS( "%", a, b, r, pA, pB, pRes, RunningState, clsA, clsB, clsR );
	}
	
	/**
	 * Templatised logical AND operator.
	 * The template classes decide the cast used, there must be an appropriate operator between the two types.
	 */
	private static <A, B, R> void OpLAND( A a, B b, R r, IqShaderData pA, IqShaderData pB, IqShaderData pRes, CqBitVector RunningState, Class<A> clsA, Class<B> clsB, Class<R> clsR ) {
		OpABRS( "&&", a, b, r, pA, pB, pRes, RunningState, clsA, clsB, clsR );
	}
	
	/**
	 * Templatised logical OR operator.
	 * The template classes decide the cast used, there must be an appropriate operator between the two types.
	 */
	private static <A, B, R> void OpLOR( A a, B b, R r, IqShaderData pA, IqShaderData pB, IqShaderData pRes, CqBitVector RunningState, Class<A> clsA, Class<B> clsB, Class<R> clsR ) {
		OpABRS( "||", a, b, r, pA, pB, pRes, RunningState, clsA, clsB, clsR );
	}
	
	/**
	 * Templatised negation operator. The template classes decide the cast used, there must be an appropriate operator between the two types.
	 * @param a The type of the first operand, used to determine templateisation, needed by VC++..
	 * @param pA The shader data to use as the second operand.
	 * @param pRes The shader data to store the result in.
	 * @param RunningState The current SIMD state.
	 */
	private static <A> void OpNEG( A a, IqShaderData pA, IqShaderData pRes, CqBitVector RunningState, Class<A> clsA )
	{
	    A vA = AccessSupplier.getNewInstance(clsA);
	    //STLVector<A> pdA = new STLVector<A>(clsA);
	    STLArray<A> pdA ;//= new STLVector<A>(clsA);
	    int idxA = 0;
	    
	    int i, ii;

	    boolean fAVar = pA.Size() > 1;

	    if ( fAVar )
	    {
	        /* Varying, must go accross all processing each element. */
	    	//nttdata 高速化
	        //pA.GetValuePtr( pdA );
	    	pdA = pA.GetValuePtr_2( vA );
	        ii = (int)pA.Size();
	        for ( i = 0; i < ii; i++ )
	        {
	        	if ( RunningState.Value( i ) ){
	        		
	        		if ( clsA == p_float.class ) {
						p_float fltA = (p_float) pdA.get(idxA);
						pRes.SetValue( -fltA.value, i );
					}
	        		else if( clsA == CqVector3D.class ){
	        			try{
	        				Method negate = AccessSupplier.getMethod( pdA.get(idxA), "negative" );
	        				pRes.SetValue( negate.invoke(pdA.get(idxA)), i, clsA );
	        			}catch( Exception e ) {
	        				HimawariLogger.outputException( e );
						}
	        		}
	        		else if( clsA == CqColor.class ){
	        			try{
	        				Method negate = AccessSupplier.getMethod( pdA.get(idxA), "negate" );
	        				pRes.SetValue( negate.invoke(pdA.get(idxA)), i, clsA );
	        			}catch( Exception e ) {
	        				HimawariLogger.outputException( e );
						}
	        		}
	        		
	        	}//end of if( RunnningState )
	        	
	        	idxA++;
	        	
	        }
	    }
	    else
	    {
	        /* Uniform, simple one shot case. */
	        pA.GetValue( vA, clsA );
	        
	        if ( clsA == p_float.class ) {
				p_float fltA = (p_float) vA;
				pRes.SetValue( -fltA.value );
			}
	        else if( clsA == CqVector3D.class ){
    			try{
    				Method negate = AccessSupplier.getMethod( vA, "negative" );
    				pRes.SetValue( negate.invoke(vA), clsA );
    			}catch( Exception e ) {
    				HimawariLogger.outputException( e );
    			}
    		}
	        else if( clsA == CqColor.class ){
	        	try{
    				Method negate = AccessSupplier.getMethod( vA, "negate" );
    				pRes.SetValue( negate.invoke(vA), clsA );
    			}catch( Exception e ) {
    				HimawariLogger.outputException( e );
    			}
	        }
	    }
	}
	
	/**
	 * Templatised cast operator, cast the current stack entry to the spcified type.
	 * The template classes decide the cast used, there must be an appropriate operator between the two types.
	 * @param a The type of the first operand, used to determine templateisation, needed by VC++..
	 * @param b The type of the second operand, used to determine templateisation, needed by VC++..
	 * @param pA The shader data to use as the second operand.
	 * @param pRes The shader data to store the result in.
	 * @param RunningState The current SIMD state.
	 */
//nttdata 高速化
//	private static <A,B> void OpCAST( A a, B b, IqShaderData pA, IqShaderData pRes, CqBitVector RunningState, Class<A> clsA, Class<B> clsB )
//	{
//	    A vA	= AccessSupplier.getNewInstance(clsA);
//	    STLVector<A> pdA = new STLVector<A>(clsA);
//	    int idxA = 0;
//	    
//	    int i, ii;
//
//	    boolean fAVar = pA.Size() > 1;
//
//	    if ( fAVar )
//	    {
//	        /* Varying, must go accross all processing each element. */
//	        pA.GetValuePtr( pdA );
//	        ii = (int)pA.Size();
//	        for ( i = 0; i < ii; i++ )
//	        {
//	            if ( RunningState.Value( i ) ){
//	            	if( clsA == p_float.class ){
//	            		//static_castの実装
//	            		B ret = AccessSupplier.getNewInstance( clsB, ((p_float)pdA.get(idxA)).value );
//	            		pRes.SetValue( ret, i, clsB );
//	            	}
//	            	else{
//	            		//static_castの実装
//	            		B ret = AccessSupplier.getNewInstance( clsB, pdA.get(idxA) );
//	            		pRes.SetValue( ret, i, clsB );
//	            	}
//	            }
//	            idxA++;
//	        }
//	    }
//	    else
//	    {
//	        /* Uniform, simple one shot case. */
//	        pA.GetValue( vA, clsA );
//
//	        if( clsA == p_float.class ){
//	        	//static_castの実装
//	        	B ret = AccessSupplier.getNewInstance( clsB, ((p_float)vA).value );
//	        	pRes.SetValue( ret, clsB );
//	        }
//	        else{
//	        	//static_castの実装
//	        	B ret = AccessSupplier.getNewInstance( clsB, vA );
//	        	pRes.SetValue( ret, clsB );
//	        }
//	    }
//	}
	private static <A,B> void OpCAST( A a, B b, IqShaderData pA, IqShaderData pRes, CqBitVector RunningState, Class<A> clsA, Class<B> clsB )
	{
	    A vA	= AccessSupplier.getNewInstance(clsA);
	    //STLVector<A> pdA = new STLVector<A>(clsA);
	    STLArray<A> pdA = new STLArray<A>(clsA);
	    int idxA = 0;
	    
	    int i, ii;

	    boolean fAVar = pA.Size() > 1;

	    if ( fAVar )
	    {
	        /* Varying, must go accross all processing each element. */
	    	pdA = pA.GetValuePtr_2( vA );
	        ii = (int)pA.Size();
	        for ( i = 0; i < ii; i++ )
	        {
	            if ( RunningState.Value( i ) ){
	            	if( clsA == p_float.class ){
	            		//static_castの実装
	            		B ret = AccessSupplier.getNewInstance( clsB, ((p_float)pdA.get(idxA)).value );
	            		pRes.SetValue( ret, i, clsB );
	            	}
	            	else{
	            		//static_castの実装
	            		B ret = AccessSupplier.getNewInstance( clsB, pdA.get(idxA) );
	            		pRes.SetValue( ret, i, clsB );
	            	}
	            }
	            idxA++;
	        }
	    }
	    else
	    {
	        /* Uniform, simple one shot case. */
	        pA.GetValue( vA, clsA );

	        if( clsA == p_float.class ){
	        	//static_castの実装
	        	B ret = AccessSupplier.getNewInstance( clsB, ((p_float)vA).value );
	        	pRes.SetValue( ret, clsB );
	        }
	        else{
	        	//static_castの実装
	        	B ret = AccessSupplier.getNewInstance( clsB, vA );
	        	pRes.SetValue( ret, clsB );
	        }
	    }
	}
	
	/**
	 * Templatised cast three operands to a single triple type (vector/normal/color etc.) and store the result in this stack entry
	 * @param a The type of the first operand, used to determine templateisation, needed by VC++..
	 * @param pA The shader data to use as the first triple element.
	 * @param pB The shader data to use as the second triple element.
	 * @param pC The shader data to use as the third triple element.
	 * @param pRes The shader data to store the result in.
	 * @param RunningState The current SIMD state.
	 */
	private static <A> void OpTRIPLE( A a, IqShaderData pRes, IqShaderData pA, IqShaderData pB, IqShaderData pC, CqBitVector RunningState, Class<A> clsA )
	{
	    p_float x, y, z;
	    x = new p_float();
	    y = new p_float();
	    z = new p_float();

	    int i = (int)max( max( pA.Size(), pB.Size() ), pC.Size() ) - 1;
	    boolean __fVarying = i > 0;
	    for ( ; i >= 0; i-- )
	        if ( !__fVarying || RunningState.Value( i ) )
	        {
	            pA.GetValue( x, i );
	            pB.GetValue( y, i );
	            pC.GetValue( z, i );
	            pRes.SetValue( AccessSupplier.getNewInstance( clsA, x.value, y.value, z.value ), i, clsA );
	        }
	}
	
	/**
	 * Templatised cast sixteen operands to a single matrix type and store the result in this stack entry
	 * @param z The type of the operand, used to determine templateisation, needed by VC++..
	 * @param pRes The shader data to store the result in.
	 * @param pA The shader data to use as the 0,0 element.
	 * @param pB The shader data to use as the 1,0 element.
	 * @param pC The shader data to use as the 2,0 element.
	 * @param pD The shader data to use as the 3,0 element.
	 * @param pE The shader data to use as the 0,1 element.
	 * @param pF The shader data to use as the 1,1 element.
	 * @param pG The shader data to use as the 2,1 element.
	 * @param pH The shader data to use as the 3,1 element.
	 * @param pI The shader data to use as the 0,2 element.
	 * @param pJ The shader data to use as the 1,2 element.
	 * @param pK The shader data to use as the 2,2 element.
	 * @param pL The shader data to use as the 3,2 element.
	 * @param pM The shader data to use as the 0,3 element.
	 * @param pN The shader data to use as the 1,3 element.
	 * @param pO The shader data to use as the 2,3 element.
	 * @param pP The shader data to use as the 3,3 element.
	 * @param RunningState The current SIMD state.
	 */
	private static <A> void OpHEXTUPLE( A z, IqShaderData pRes,
	                        IqShaderData pA, IqShaderData pB, IqShaderData pC, IqShaderData pD,
	                        IqShaderData pE, IqShaderData pF, IqShaderData pG, IqShaderData pH,
	                        IqShaderData pI, IqShaderData pJ, IqShaderData pK, IqShaderData pL,
	                        IqShaderData pM, IqShaderData pN, IqShaderData pO, IqShaderData pP, CqBitVector RunningState, Class<A> clsA )
	{
	    p_float a1, a2, a3, a4;
	    p_float b1, b2, b3, b4;
	    p_float c1, c2, c3, c4;
	    p_float d1, d2, d3, d4;
	    
	    a1 = new p_float(); a2 = new p_float(); a3 = new p_float(); a4 = new p_float();
	    b1 = new p_float(); b2 = new p_float(); b3 = new p_float(); b4 = new p_float();
	    c1 = new p_float(); c2 = new p_float(); c3 = new p_float(); c4 = new p_float();
	    d1 = new p_float(); d2 = new p_float(); d3 = new p_float(); d4 = new p_float();
	    

	    int ii1 = (int)max( max( max( pA.Size(), pB.Size() ), pC.Size() ), pD.Size() );
	    int ii2 = (int)max( max( max( pE.Size(), pF.Size() ), pG.Size() ), pH.Size() );
	    int ii3 = (int)max( max( max( pI.Size(), pJ.Size() ), pK.Size() ), pL.Size() );
	    int ii4 = (int)max( max( max( pM.Size(), pN.Size() ), pO.Size() ), pP.Size() );
	    int ii  = (int)max( max( max( ii1, ii2 ), ii3 ), ii4 );
	    boolean __fVarying = ii > 0;	//XXX: 保留。これでも動くけど、１と比較するのが正しいと思います。 nttdata
	    for ( ; ii >= 0; ii-- )
	    {
	        if ( !__fVarying || RunningState.Value( ii ) )
	        {
	            pA.GetValue( a1, ii );	pB.GetValue( a2, ii );	pC.GetValue( a3, ii );	pD.GetValue( a4, ii );
	            pE.GetValue( b1, ii );	pF.GetValue( b2, ii );	pG.GetValue( b3, ii );	pH.GetValue( b4, ii );
	            pI.GetValue( c1, ii );	pJ.GetValue( c2, ii );	pK.GetValue( c3, ii );	pL.GetValue( c4, ii );
	            pM.GetValue( d1, ii );	pN.GetValue( d2, ii );	pO.GetValue( d3, ii );	pP.GetValue( d4, ii );
	            
	            A tt = AccessSupplier.getNewInstance( clsA, a1.value, a2.value, a3.value, a4.value, 
	            						  b1.value, b2.value, b3.value, b4.value,
	            						  c1.value, c2.value, c3.value, c4.value,
	            						  d1.value, d2.value, d3.value, d4.value );
	            AccessSupplier.invokeMethod( tt, "SetfIdentity", false );
	            pRes.SetValue( tt, ii, clsA );
//	            A tt( a1, a2, a3, a4,
//	                  b1, b2, b3, b4,
//	                  c1, c2, c3, c4,
//	                  d1, d2, d3, d4 );
//	            tt.SetfIdentity( false );
//	            pRes.SetValue( tt, ii );
	        }
	    }
	}
	
	/**
	 *  Templatised component access operator.
	 * @param z The type of the operand, used to determine templatisation, needed by VC++..
	 * @param pA The shader data to extract the component from.
	 * @param index The index of the component to extract.
	 * @param pRes The shader data to store the result in.
	 * @param RunningState The current SIMD state.
	 */
	public static <A> void OpCOMP( A z, IqShaderData pA, int index, IqShaderData pRes, CqBitVector RunningState, Class<A> clsA )
	{
	    A vA	= AccessSupplier.getNewInstance(clsA);
	    //STLVector<A> pdA = new STLVector<A>(clsA);
	    STLArray<A> pdA = new STLArray<A>(clsA);
	    int idxA = 0;
	    
	    int i, ii;

	    boolean fAVar = pA.Size() > 1;

	    if ( fAVar )
	    {
	        /* Varying, must go accross all processing each element. */
	        //nttdata 高速化
	    	//pA.GetValuePtr( pdA );
	    	pdA = pA.GetValuePtr_2( vA );
	        ii = (int)pA.Size();
	        for ( i = 0; i < ii; i++ )
	        {
	            if ( RunningState.Value( i ) ){
	            	float res = (Float)AccessSupplier.invokeMethod( pdA.get(idxA), "valueAt", index );
	            	pRes.SetValue( new p_float(res), i, p_float.class ); 
//	                pRes.SetValue( ( *pdA ) [ index ], i );
	            }
	            idxA++;
	        }
	    }
	    else
	    {
	        /* Uniform, simple one shot case. */
	        pA.GetValue( vA, clsA );
	        float res = (Float)AccessSupplier.invokeMethod(  vA, "valueAt", index );
	        pRes.SetValue( new p_float(res), p_float.class );
	    }
	}
	
	/**
	 * Templatised component access operator.
	 * @param z The type of the operand, used to determine templatisation, needed by VC++..
	 * @param pA The shader data to extract the component from.
	 * @param pB The shader data to use to get the index to extract.
	 * @param pRes The shader data to store the result in.
	 * @param RunningState The current SIMD state.
	 */
	public static <A> void OpCOMP( A z, IqShaderData pA, IqShaderData pB, IqShaderData pRes, CqBitVector RunningState, Class<A> clsA )
	{
	    A vA		= AccessSupplier.getNewInstance(clsA);
	    p_float vB	= new p_float();
//	    STLVector<A> pdA		= new STLVector<A>(clsA);
//	    STLVector<p_float> pdB	= new STLVector<p_float>(p_float.class);
	    STLArray<A> pdA		= new STLArray<A>(clsA);
	    STLArray<p_float> pdB	= new STLArray<p_float>(p_float.class);
	    
	    int idxA, idxB;
	    idxA = idxB = 0;
	    
	    int i, ii;

	    boolean fAVar = pA.Size() > 1;
	    boolean fBVar = pB.Size() > 1;

	    if ( fAVar && fBVar )
	    {
	        /* Both are varying, must go accross all processing each element. */
//			nttdata 高速化
//	        pA.GetValuePtr( pdA );
//	        pB.GetValuePtr( pdB );
	    	pdA = pA.GetValuePtr_2( vA );
	    	pdB = pB.GetValuePtr_2( vB );
	        ii = (int)pA.Size();
	        for ( i = 0; i < ii; i++ )
	        {
	            if ( RunningState.Value( i ) ){
	            	float res = (Float)AccessSupplier.invokeMethod( pdA.get(idxA), "valueAt", (int)pdB.get(idxB).value );
	                pRes.SetValue( new p_float(res), i, p_float.class );
	            }
	            idxA++;
	            idxB++;
	        }
	    }
	    else if ( !fBVar && fAVar )
	    {
	        /* A is varying, can just get B's value once. */
	        ii = (int)pA.Size();
	        //nttdata 高速化
	        //pA.GetValuePtr( pdA );
	        pdA = pA.GetValuePtr_2( vA );
	        pB.GetValue( vB );
	        int index = (int)( vB.value );
	        for ( i = 0; i < ii; i++ )
	        {
	            if ( RunningState.Value( i ) ){
	            	float res = (Float)AccessSupplier.invokeMethod( pdA.get(idxA), "valueAt", index );
	                pRes.SetValue( new p_float(res), i, p_float.class );
	            }
	            idxA++;
	        }
	    }
	    else if ( !fAVar && fBVar )
	    {
	        /* B is varying, can just get A's value once. */
	        ii = (int)pB.Size();
	        //nttdata 高速化
	        //pB.GetValuePtr( pdB );
	        pdB = pB.GetValuePtr_2( vB );
	        pA.GetValue( vA, clsA );
	        for ( i = 0; i < ii; i++ )
	        {
	            if ( RunningState.Value( i ) ){
	            	float res = (Float)AccessSupplier.invokeMethod( vA, "valueAt", (int)pdB.get(idxB).value );
	                pRes.SetValue( new p_float(res), i, p_float.class );
	            }
	            idxB++;
	        }
	    }
	    else
	    {
	        /* Both are uniform, simple one shot case. */
	        pA.GetValue( vA, clsA );
	        pB.GetValue( vB );
	        int index = (int)( vB.value );
	        float res = (Float)AccessSupplier.invokeMethod( vA, "valueAt", index );
	        pRes.SetValue(  new p_float(res), p_float.class );
	    }
	}
	
	//使っていないのでコメントアウト。2005.11.01 nttdata
//	/* Templatised component set operator.
//	 * @param z The type of the operand, used to determine templatisation, needed by VC++..
//	 * @param pRes The shader data to store the result in.
//	 * @param index The index of the component to set.
//	 * @param pA The shader data to set the component within.
//	 * @param RunningState The current SIMD state.
//	 */
//	template <class A>
//	inline void	OpSETCOMP( A& z, IqShaderData* pRes, int index, IqShaderData* pA, CqBitVector& RunningState )
//	{
//	    A vA;
//	    TqFloat val;
//
//	    TqInt i = MAX( pRes->Size(), pA->Size() ) - 1;
//	    TqBool __fVarying = i > 0;
//	    for ( ; i >= 0; i-- )
//	    {
//	        if ( !__fVarying || RunningState.Value( i ) )
//	        {
//	            GetValue( vA, i );
//	            pA->GetValue( val, i );
//	            vA [ index ] = val;
//	            pRes->SetValue( vA, i );
//	        }
//	    }
//	}
//	/* Templatised component set operator.
//	 * @param z The type of the operand, used to determine templatisation, needed by VC++..
//	 * @param pRes The shader data to store the result in.
//	 * @param index The shader data to get the index of the component to set from.
//	 * @param pA The shader data to set the component within.
//	 * @param RunningState The current SIMD state.
//	 */
//	template <class A>
//	inline void	OpSETCOMP( A& z, IqShaderData* pRes, IqShaderData* index, IqShaderData* pA, CqBitVector& RunningState )
//	{
//	    A vA;
//	    TqFloat val, fi;
//
//	    TqInt i = MAX( MAX( pRes->Size(), pA->Size() ), index->Size() ) - 1;
//	    TqBool __fVarying = i > 0;
//	    for ( ; i >= 0; i-- )
//	    {
//	        if ( !__fVarying || RunningState.Value( i ) )
//	        {
//	            pRes->GetValue( vA, i );
//	            pA->GetValue( val, i );
//	            index->GetValue( fi, i );
//	            vA [ static_cast<TqInt>( fi ) ] = val;
//	            pRes->SetValue( vA, i );
//	        }
//	    }
//	}
	
	/** 
	 * Special case matrix component access.
	 * @param pA The shader data that stores the matrix.
	 * @param pR The shader data to get the index into the rows from.
	 * @param pC The shader data to get the index into the columns from.
	 * @param pRes The shader data to store the result in.
	 * @param RunningState The current SIMD state.
	 */
	public static void OpCOMPM( IqShaderData pA, IqShaderData pR, IqShaderData pC, IqShaderData pRes, CqBitVector RunningState )
	{
	    CqMatrix m = new CqMatrix();
	    p_float fr = new p_float(), fc = new p_float();

	    int i = (int)max( pA.Size(), pRes.Size() ) - 1;
	    boolean __fVarying = i > 0;
	    for ( ; i >= 0; i-- )
	        if ( !__fVarying || RunningState.Value( i ) )
	        {
	            pA.GetValue( m, i );
	            pR.GetValue( fr, i );
	            pC.GetValue( fc, i );
	            pRes.SetValue( m.m_aaElement[ (int)( fr.value ) ][ (int)( fc.value ) ], i );
	        }
	}

	//使っていないのでコメントアウト。2005.11.01 nttdata
//	/**
//	 * Special case matrix component access.
//	 * @param pA The shader data that stores the matrix.
//	 * @param pR The shader data to get the index into the rows from.
//	 * @param pC The shader data to get the index into the columns from.
//	 * @param pV The shader data which holds the value to place in the appropriate row/column.
//	 * @param RunningState The current SIMD state.
//	 */
//	private static void OpSETCOMPM( IqShaderData pA, IqShaderData pR, IqShaderData pC, IqShaderData pV, CqBitVector RunningState )
//	{
//	    CqMatrix m = new CqMatrix();
//	    p_float fr = new p_float(), fc = new p_float(), val = new p_float();
//
//	    int i = (int)max( pA.Size(), pV.Size() ) - 1;
//	    boolean __fVarying = i > 0;
//	    for ( ; i >= 0; i-- )
//	    {
//	        if ( !__fVarying || RunningState.Value( i ) )
//	        {
//	            pA.GetValue( m, i );
//	            pR.GetValue( fr, i );
//	            pC.GetValue( fc, i );
//	            pV.GetValue( val, i );
//	            m.setElement( (int)( fr.value ), (int)( fc.value ), val.value );
//	            pA.SetValue( m, i );
//	        }
//	    }
//	}
	
	
		
	private static final int	_OP_LSS_	= "<".hashCode();
	private static final int	_OP_GRT_	= ">".hashCode();
	private static final int	_OP_LE_		= "<=".hashCode();
	private static final int	_OP_GE_		= ">=".hashCode();
	private static final int	_OP_EQ_		= "==".hashCode();
	private static final int	_OP_NE_		= "!=".hashCode();
	private static final int	_OP_MUL_	= "*".hashCode();
	private static final int	_OP_DIV_	= "/".hashCode();
	private static final int	_OP_ADD_	= "+".hashCode();
	private static final int	_OP_SUB_	= "-".hashCode();
	private static final int	_OP_DOT_	= "*".hashCode();
	private static final int	_OP_CRS_	= "%".hashCode();
	private static final int	_OP_LAND_	= "&&".hashCode();
	private static final int	_OP_LOR_	= "||".hashCode();
	
//	private static <A,B> Object oparator( String op, A vA, B vB, Class<A> clsA, Class<B> clsB ){
//		
//		try{
//			
//			Method oprator;					//演算子が定義されたメソッド（ltとかgeとか）
//			
//			boolean isPfloat  = false;		//vAがp_floatか
//			boolean isPstring = false;		//vAがp_Stringか
//			boolean isNotSame = false;		//vAとvBは異なるクラス
//			
//			//インスタンスはなんですか？
//			if ( clsA == p_float.class && clsB == p_float.class ) {
//				isPfloat = true;
//			}
//			else if( clsA == p_String.class && clsB == p_String.class ){
//				isPstring = true;
//			}
//			else if( clsA != clsB ){
//				isNotSame = true;
//			}
//			
//			//演算子のハッシュコード
//			int opHash = op.hashCode();
//			
//			//演算子による分岐
//			if( opHash == _OP_LSS_ ){
//				
//				if( isPfloat ){
//					p_float fltA = (p_float)vA;		// <- cast
//					p_float fltB = (p_float)vB;
//					return new p_float( ( fltA.value < fltB.value )?1:0 );
//				}
//				else if( isPstring ){
//					p_String strA = (p_String)vA;	// <- cast
//					p_String strB = (p_String)vB;
//					return new p_float( ( strA.value.compareTo(strB.value) < 0 )?1:0 );
//				}
//				else{
//					oprator = AccessSupplier.getMethod( vA, "lt", clsB );
//					return new p_float( (Boolean)oprator.invoke( vA, vB )?1:0 );
//				}
//				
//			}
//			else if( opHash == _OP_GRT_ ){
//				
//				if( isPfloat ){
//					p_float fltA = (p_float)vA;		// <- cast
//					p_float fltB = (p_float)vB;
//					return new p_float( ( fltA.value > fltB.value )?1:0 );
//				}
//				else if( isPstring ){
//					p_String strA = (p_String)vA;	// <- cast
//					p_String strB = (p_String)vB;
//					return new p_float( ( strA.value.compareTo(strB.value) > 0 )?1:0 );
//				}
//				else{
//					oprator = AccessSupplier.getMethod( vA, "gt", clsB );
//					return new p_float( (Boolean)oprator.invoke( vA, vB )?1:0 );
//				}
//				
//			}
//			else if( opHash == _OP_LE_ ){
//				
//				if( isPfloat ){
//					p_float fltA = (p_float)vA;		// <- cast
//					p_float fltB = (p_float)vB;
//					return new p_float( ( fltA.value <= fltB.value )?1:0 );
//				}
//				else if( isPstring ){
//					p_String strA = (p_String)vA;	// <- cast
//					p_String strB = (p_String)vB;
//					return new p_float( ( strA.value.compareTo(strB.value) <= 0 )?1:0 );
//				}
//				else{
//					oprator = AccessSupplier.getMethod( vA, "le", clsB );
//					return new p_float( (Boolean)oprator.invoke( vA, vB )?1:0 );
//				}
//				
//			}
//			else if( opHash == _OP_GE_ ){
//				
//				if( isPfloat ){
//					p_float fltA = (p_float)vA;		// <- cast
//					p_float fltB = (p_float)vB;
//					return new p_float( ( fltA.value >= fltB.value )?1:0 );
//				}
//				else if( isPstring ){
//					p_String strA = (p_String)vA;	// <- cast
//					p_String strB = (p_String)vB;
//					return new p_float( ( strA.value.compareTo(strB.value) >= 0 )?1:0 );
//				}
//				else{
//					oprator = AccessSupplier.getMethod( vA, "ge", clsB );
//					return new p_float( (Boolean)oprator.invoke( vA, vB )?1:0 );
//				}
//				
//			}
//			else if( opHash == _OP_EQ_ ){
//				
//				if( isPfloat ){
//					p_float fltA = (p_float)vA;		// <- cast
//					p_float fltB = (p_float)vB;
//					return new p_float( ( fltA.value == fltB.value )?1:0 );
//				}
//				else if( isPstring ){
//					p_String strA = (p_String)vA;	// <- cast
//					p_String strB = (p_String)vB;
//					return new p_float( ( strA.value.compareTo(strB.value) == 0 )?1:0 );
//				}
//				else{
//					oprator = AccessSupplier.getMethod( vA, "equals", clsB );
//					return new p_float( (Boolean)oprator.invoke( vA, vB )?1:0 );
//				}
//				
//			}
//			else if( opHash == _OP_NE_ ){
//				
//				if( isPfloat ){
//					p_float fltA = (p_float)vA;		// <- cast
//					p_float fltB = (p_float)vB;
//					return new p_float( ( fltA.value != fltB.value )?1:0 );
//				}
//				else if( isPstring ){
//					p_String strA = (p_String)vA;	// <- cast
//					p_String strB = (p_String)vB;
//					return new p_float( ( strA.value.compareTo(strB.value) != 0 )?1:0 );
//				}
//				else{
//					oprator = AccessSupplier.getMethod( vA, "equals", clsB );
//					Boolean ret = (Boolean)oprator.invoke( vA, vB );
//					return new p_float( ( !ret )?1:0 );
//				}
//				
//			}
//			else if( opHash == _OP_MUL_ ){
//				
//				if( isPfloat ){
//					p_float fltA = (p_float)vA;		// <- cast
//					p_float fltB = (p_float)vB;
//					return new p_float( fltA.value * fltB.value );
//				}
//				else if( isPstring ){
//					p_String strA = (p_String)vA;	// <- cast
////					p_String strB = (p_String)vB;
//					return strA;
//				}
//				else{
//					if( !isNotSame ){
//						oprator = AccessSupplier.getMethod( vA, "mul", clsB );
//						Object ret = oprator.invoke( vA, vB );
//						
//						if( ret instanceof Float )	return new p_float((Float)ret);
//						return ret;
//					}
//					else if( clsA == p_float.class ){
//						oprator = AccessSupplier.getMethod( vB, "mul", float.class );
//						return oprator.invoke( vB, ((p_float)vA).value );
//					}
//					else if( clsB == p_float.class ){
//						oprator = AccessSupplier.getMethod( vA, "mul", float.class );
//						return oprator.invoke( vA, ((p_float)vB).value );
//					}
//				}
//				
//			}
//			else if( opHash == _OP_DIV_ ){
//				
//				if( isPfloat ){
//					p_float fltA = (p_float)vA;		// <- cast
//					p_float fltB = (p_float)vB;
//					return new p_float( fltA.value / fltB.value );
//				}
//				else if( isPstring ){
//					p_String strA = (p_String)vA;	// <- cast
////					p_String strB = (p_String)vB;
//					return strA;
//				}
//				else{
//					if( !isNotSame ){
//						oprator = AccessSupplier.getMethod( vA, "div", clsB );
//						Object ret = oprator.invoke( vA, vB );
//						
//						if( ret instanceof Float )	return new p_float((Float)ret);
//						return ret;
//					}
//					else if( clsA == p_float.class ){
//						oprator = AccessSupplier.getMethod( vB, "divInv", float.class );
//						return oprator.invoke( vB, ((p_float)vA).value );
//					}
//					else if( clsB == p_float.class ){
//						oprator = AccessSupplier.getMethod( vA, "div", float.class );
//						return oprator.invoke( vA, ((p_float)vB).value );
//					}
//				}
//				
//			}
//			else if( opHash == _OP_ADD_ ){
//				
//				if( isPfloat ){
//					p_float fltA = (p_float)vA;		// <- cast
//					p_float fltB = (p_float)vB;
//					return new p_float( fltA.value + fltB.value );
//				}
//				else if( isPstring ){
//					p_String strA = (p_String)vA;	// <- cast
//					p_String strB = (p_String)vB;
//					return new p_String( strA.value + strB.value );
//				}
//				else{
//					if( !isNotSame ){
//						oprator = AccessSupplier.getMethod( vA, "add", clsB );
//						Object ret = oprator.invoke( vA, vB );
//						
//						if( ret instanceof Float )	return new p_float((Float)ret);
//						return ret;
//					}
//					else if( clsA == p_float.class ){
//						oprator = AccessSupplier.getMethod( vB, "add", float.class );
//						return oprator.invoke( vB, ((p_float)vA).value );
//					}
//					else if( clsB == p_float.class ){
//						oprator = AccessSupplier.getMethod( vA, "add", float.class );
//						return oprator.invoke( vA, ((p_float)vB).value );
//					}
//				}
//				
//			}
//			else if( opHash == _OP_SUB_ ){
//				
//				if( isPfloat ){
//					p_float fltA = (p_float)vA;		// <- cast
//					p_float fltB = (p_float)vB;
//					return new p_float( fltA.value - fltB.value );
//				}
//				else if( isPstring ){
//					p_String strA = (p_String)vA;	// <- cast
////					p_String strB = (p_String)vB;
//					return strA;
//				}
//				else{
//					if( !isNotSame ){
//						oprator = AccessSupplier.getMethod( vA, "sub", clsB );
//						Object ret = oprator.invoke( vA, vB );
//						
//						if( ret instanceof Float )	return new p_float((Float)ret);
//						return ret;
//					}
//					else if( clsA == p_float.class ){
//						oprator = AccessSupplier.getMethod( vB, "subInv", float.class );
//						return oprator.invoke( vB, ((p_float)vA).value );
//					}
//					else if( clsB == p_float.class ){
//						oprator = AccessSupplier.getMethod( vA, "sub", float.class );
//						return oprator.invoke( vA, ((p_float)vB).value );
//					}
//				}
//				
//			}
//			else if( opHash == _OP_DOT_ ){
//				
//				if( isPfloat ){
//					p_float fltA = (p_float)vA;		// <- cast
//					p_float fltB = (p_float)vB;
//					return new p_float( fltA.value * fltB.value );
//				}
//				else if( isPstring ){
//					p_String strA = (p_String)vA;	// <- cast
////					p_String strB = (p_String)vB;
//					return strA;
//				}
//				else{
//					oprator = AccessSupplier.getMethod( vA, "mul", clsB );
//					Object ret = oprator.invoke( vA, vB );
//					
//					if( ret instanceof Float )	return new p_float((Float)ret);
//					return ret;
//				}
//				
//			}
//			else if( opHash == _OP_CRS_ ){
//				
//				if( isPfloat ){
//					p_float fltA = (p_float)vA;		// <- cast
//					p_float fltB = (p_float)vB;
//					return new p_float( fltA.value % fltB.value );
//				}
//				else if( isPstring ){
//					p_String strA = (p_String)vA;	// <- cast
////					p_String strB = (p_String)vB;
//					return strA;
//				}
//				else if( !isNotSame && clsA==CqColor.class ){
//					CqVector3D vecA = new CqVector3D( (CqColor)vA );
//					CqVector3D vecB = new CqVector3D( (CqColor)vB );
//					
//					oprator = AccessSupplier.getMethod( vecA, "mod", CqVector3D.class );
//					CqVector3D ret = (CqVector3D)oprator.invoke( vecA, vecB );
//					
//					return new CqColor( ret );
//					
//				}
//				else{
//					oprator = AccessSupplier.getMethod( vA, "mod", clsB );
//					Object ret = oprator.invoke( vA, vB );
//					
//					if( ret instanceof Float )	return new p_float((Float)ret);
//					return ret;
//				}
//				
//			}
//			else if( opHash == _OP_LAND_ ){
//				
//				if( isPfloat ){
//					p_float fltA = (p_float)vA;		// <- cast
//					p_float fltB = (p_float)vB;
//					return new p_float( ( fltA.value!=0 && fltB.value!=0 )?1:0 );
//				}
//				else if( isPstring ){
//					p_String strA = (p_String)vA;	// <- cast
//					p_String strB = (p_String)vB;
//					return new p_float( ( strA.value!=null && strB.value!=null )?1:0 );
//				}
//				else{
//					return new p_float( ( vA!=null && vB!=null )?1:0 );
//				}
//				
//			}
//			else if( opHash == _OP_LOR_ ){
//				
//				if( isPfloat ){
//					p_float fltA = (p_float)vA;		// <- cast
//					p_float fltB = (p_float)vB;
//					return new p_float( ( fltA.value!=0 || fltB.value!=0 )?1:0 );
//				}
//				else if( isPstring ){
//					p_String strA = (p_String)vA;	// <- cast
//					p_String strB = (p_String)vB;
//					return new p_float( ( strA.value!=null || strB.value!=null )?1:0 );
//				}
//				else{
//					return new p_float( ( vA!=null || vB!=null )?1:0 );
//				}
//				
//			}
//			//end of if-else( op )
//			
//			
//		} catch( Exception e ) {
//			HimawariLogger.outputException( e );
//		}
//		
//		//以上の演算子でない場合や、エラーがあった場合はnullを返す
//		return null;
//	}

	private static <A,B> Object oparator( String op, A vA, B vB, Class<A> clsA, Class<B> clsB ){
	
	try{
		
		Method oprator;					//演算子が定義されたメソッド（ltとかgeとか）
		
		boolean isNotSame = false;		//vAとvBは異なるクラス
		boolean existPfloat  = false;

		if ( clsA == p_float.class || clsB == p_float.class ) {
			existPfloat = true;
		}
		if( clsA != clsB ){
			isNotSame = true;
		}
		
		//演算子のハッシュコード
		int opHash = op.hashCode();
		
		//演算子による分岐
		if( opHash == _OP_LSS_ ){
			
			if(clsA == p_float.class){
				p_float fltA = (p_float)vA;		// <- cast
				p_float fltB = (p_float)vB;
				return new p_float( ( fltA.value < fltB.value )?1:0 );
			}
			else if(clsA == p_String.class){
				p_String strA = (p_String)vA;	// <- cast
				p_String strB = (p_String)vB;
				return new p_float( ( strA.value.compareTo(strB.value) < 0 )?1:0 );
			}
			else if(clsA == CqVector3D.class){
				return new p_float( (Boolean)( (CqVector3D)vA).lt( (CqVector3D)vB ) ?1:0 );
			}
			else if(clsA == CqVector4D.class){
				return new p_float( (Boolean)( (CqVector4D)vA).lt( (CqVector4D)vB ) ?1:0 );
			}
			else if(clsA == CqColor.class){
				return new p_float( (Boolean)( (CqColor)vA).lt( (CqColor)vB ) ?1:0 );
			}
//			if( isPfloat ){
//				p_float fltA = (p_float)vA;		// <- cast
//				p_float fltB = (p_float)vB;
//				return new p_float( ( fltA.value < fltB.value )?1:0 );
//			}
//			else if( isPstring ){
//				p_String strA = (p_String)vA;	// <- cast
//				p_String strB = (p_String)vB;
//				return new p_float( ( strA.value.compareTo(strB.value) < 0 )?1:0 );
//			}
//			else{
//				oprator = AccessSupplier.getMethod( vA, "lt", clsB );
//				return new p_float( (Boolean)oprator.invoke( vA, vB )?1:0 );
//			}
			
		}
		else if( opHash == _OP_GRT_ ){
			
			if(clsA == p_float.class){
				p_float fltA = (p_float)vA;		// <- cast
				p_float fltB = (p_float)vB;
				return new p_float( ( fltA.value > fltB.value )?1:0 );
			}
			else if(clsA == p_String.class){
				p_String strA = (p_String)vA;	// <- cast
				p_String strB = (p_String)vB;
				return new p_float( ( strA.value.compareTo(strB.value) > 0 )?1:0 );
			}
			else if(clsA == CqVector3D.class){
				return new p_float( (Boolean)( (CqVector3D)vA).gt( (CqVector3D)vB ) ?1:0 );
			}
			else if(clsA == CqVector4D.class){
				return new p_float( (Boolean)( (CqVector4D)vA).gt( (CqVector4D)vB ) ?1:0 );
			}
			else if(clsA == CqColor.class){
				return new p_float( (Boolean)( (CqColor)vA).gt( (CqColor)vB ) ?1:0 );
			}
//			if( isPfloat ){
//				p_float fltA = (p_float)vA;		// <- cast
//				p_float fltB = (p_float)vB;
//				return new p_float( ( fltA.value > fltB.value )?1:0 );
//			}
//			else if( isPstring ){
//				p_String strA = (p_String)vA;	// <- cast
//				p_String strB = (p_String)vB;
//				return new p_float( ( strA.value.compareTo(strB.value) > 0 )?1:0 );
//			}
//			else{
//				oprator = AccessSupplier.getMethod( vA, "gt", clsB );
//				return new p_float( (Boolean)oprator.invoke( vA, vB )?1:0 );
//			}
			
		}
		else if( opHash == _OP_LE_ ){
			
			if(clsA == p_float.class){
				p_float fltA = (p_float)vA;		// <- cast
				p_float fltB = (p_float)vB;
				return new p_float( ( fltA.value <= fltB.value )?1:0 );
			}
			else if(clsA == p_String.class){
				p_String strA = (p_String)vA;	// <- cast
				p_String strB = (p_String)vB;
				return new p_float( ( strA.value.compareTo(strB.value) <= 0 )?1:0 );
			}
			else if(clsA == CqVector3D.class){
				return new p_float( (Boolean)( (CqVector3D)vA).le( (CqVector3D)vB ) ?1:0 );
			}
			else if(clsA == CqVector4D.class){
				return new p_float( (Boolean)( (CqVector4D)vA).le( (CqVector4D)vB ) ?1:0 );
			}
			else if(clsA == CqColor.class){
				return new p_float( (Boolean)( (CqColor)vA).le( (CqColor)vB ) ?1:0 );
			}
//			if( isPfloat ){
//				p_float fltA = (p_float)vA;		// <- cast
//				p_float fltB = (p_float)vB;
//				return new p_float( ( fltA.value <= fltB.value )?1:0 );
//			}
//			else if( isPstring ){
//				p_String strA = (p_String)vA;	// <- cast
//				p_String strB = (p_String)vB;
//				return new p_float( ( strA.value.compareTo(strB.value) <= 0 )?1:0 );
//			}
//			else{
//				oprator = AccessSupplier.getMethod( vA, "le", clsB );
//				return new p_float( (Boolean)oprator.invoke( vA, vB )?1:0 );
//			}
			
		}
		else if( opHash == _OP_GE_ ){
			
			if(clsA == p_float.class){
				p_float fltA = (p_float)vA;		// <- cast
				p_float fltB = (p_float)vB;
				return new p_float( ( fltA.value >= fltB.value )?1:0 );
			}
			else if(clsA == p_String.class){
				p_String strA = (p_String)vA;	// <- cast
				p_String strB = (p_String)vB;
				return new p_float( ( strA.value.compareTo(strB.value) >= 0 )?1:0 );
			}
			else if(clsA == CqVector3D.class){
				return new p_float( (Boolean)( (CqVector3D)vA).ge( (CqVector3D)vB ) ?1:0 );
			}
			else if(clsA == CqVector4D.class){
				return new p_float( (Boolean)( (CqVector4D)vA).ge( (CqVector4D)vB ) ?1:0 );
			}
			else if(clsA == CqColor.class){
				return new p_float( (Boolean)( (CqColor)vA).ge( (CqColor)vB ) ?1:0 );
			}
//			if( isPfloat ){
//				p_float fltA = (p_float)vA;		// <- cast
//				p_float fltB = (p_float)vB;
//				return new p_float( ( fltA.value >= fltB.value )?1:0 );
//			}
//			else if( isPstring ){
//				p_String strA = (p_String)vA;	// <- cast
//				p_String strB = (p_String)vB;
//				return new p_float( ( strA.value.compareTo(strB.value) >= 0 )?1:0 );
//			}
//			else{
//				oprator = AccessSupplier.getMethod( vA, "ge", clsB );
//				return new p_float( (Boolean)oprator.invoke( vA, vB )?1:0 );
//			}
			
		}
		else if( opHash == _OP_EQ_ ){
			
			if(clsA == p_float.class){
				p_float fltA = (p_float)vA;		// <- cast
				p_float fltB = (p_float)vB;
				return new p_float( ( fltA.value == fltB.value )?1:0 );
			}
			else if(clsA == p_String.class){
				p_String strA = (p_String)vA;	// <- cast
				p_String strB = (p_String)vB;
				return new p_float( ( strA.value.compareTo(strB.value) == 0 )?1:0 );
			}
			else if(clsA == CqVector3D.class){
				return new p_float( (Boolean)( (CqVector3D)vA).equals( (CqVector3D)vB ) ?1:0 );
			}
			else if(clsA == CqVector4D.class){
				return new p_float( (Boolean)( (CqVector4D)vA).equals( (CqVector4D)vB ) ?1:0 );
			}
			else if(clsA == CqColor.class){
				return new p_float( (Boolean)( (CqColor)vA).equals( (CqColor)vB ) ?1:0 );
			}
			
		}
		else if( opHash == _OP_NE_ ){
			
			if(clsA == p_float.class){
				p_float fltA = (p_float)vA;		// <- cast
				p_float fltB = (p_float)vB;
				return new p_float( ( fltA.value != fltB.value )?1:0 );
			}
			else if(clsA == p_String.class){
				p_String strA = (p_String)vA;	// <- cast
				p_String strB = (p_String)vB;
				return new p_float( ( strA.value.compareTo(strB.value) != 0 )?1:0 );
			}
			else if(clsA == CqVector3D.class){
				return new p_float( !(Boolean)( (CqVector3D)vA).equals( (CqVector3D)vB ) ?1:0 );
			}
			else if(clsA == CqVector4D.class){
				return new p_float( !(Boolean)( (CqVector4D)vA).equals( (CqVector4D)vB ) ?1:0 );
			}
			else if(clsA == CqColor.class){
				return new p_float( !(Boolean)( (CqColor)vA).equals( (CqColor)vB ) ?1:0 );
			}
//			if( isPfloat ){
//				p_float fltA = (p_float)vA;		// <- cast
//				p_float fltB = (p_float)vB;
//				return new p_float( ( fltA.value != fltB.value )?1:0 );
//			}
//			else if( isPstring ){
//				p_String strA = (p_String)vA;	// <- cast
//				p_String strB = (p_String)vB;
//				return new p_float( ( strA.value.compareTo(strB.value) != 0 )?1:0 );
//			}
//			else{
//				oprator = AccessSupplier.getMethod( vA, "equals", clsB );
//				Boolean ret = (Boolean)oprator.invoke( vA, vB );
//				return new p_float( ( !ret )?1:0 );
//			}
			
		}
		else if( opHash == _OP_MUL_ ){
			if( !isNotSame || !existPfloat)
			{
						
						if(clsA == CqVector3D.class){
							return new p_float(((CqVector3D)vA).mul((CqVector3D)vB));
						}
						else if(clsA == p_float.class){
							p_float fltA = (p_float)vA;		// <- cast
							p_float fltB = (p_float)vB;
							return new p_float( fltA.value * fltB.value );
						}
						else if(clsA == CqVector4D.class){
							return new p_float(((CqVector4D)vA).mul((CqVector4D)vB));
						}
						else if(clsA == CqColor.class){
							return ((CqColor)vA).mul((CqColor)vB);
						}
						else if(clsA == p_String.class){
							p_String strA = (p_String)vA;	// <- cast
//							p_String strB = (p_String)vB;
							return strA;
						}
				
				
			}
			else if( clsA == p_float.class ){
				if(clsB == CqVector3D.class){
					return ((CqVector3D)vB).mul(((p_float)vA).value);
				}
				else if(clsB == CqVector4D.class){
					return ((CqVector4D)vB).mul(((p_float)vA).value);
				}
				else if(clsB == CqColor.class){
					return ((CqColor)vB).mul(((p_float)vA).value);
				}
			}
			else if( clsB == p_float.class ){
				if(clsA == CqVector3D.class){
					return ((CqVector3D)vA).mul(((p_float)vB).value);
				}
				else if(clsA == CqVector4D.class){
					return ((CqVector4D)vA).mul(((p_float)vB).value);
				}
				else if(clsA == CqColor.class){
					return ((CqColor)vA).mul(((p_float)vB).value);
				}
			}
//			if( isPfloat ){
//				p_float fltA = (p_float)vA;		// <- cast
//				p_float fltB = (p_float)vB;
//				return new p_float( fltA.value * fltB.value );
//			}
//			else if( isPstring ){
//				p_String strA = (p_String)vA;	// <- cast
////				p_String strB = (p_String)vB;
//				return strA;
//			}
//			else{
//				if( !isNotSame ){
//					oprator = AccessSupplier.getMethod( vA, "mul", clsB );
//					Object ret = oprator.invoke( vA, vB );
//					
//					if( ret instanceof Float )	return new p_float((Float)ret);
//					return ret;
//				}
//				else if( clsA == p_float.class ){
//					oprator = AccessSupplier.getMethod( vB, "mul", float.class );
//					return oprator.invoke( vB, ((p_float)vA).value );
//				}
//				else if( clsB == p_float.class ){
//					oprator = AccessSupplier.getMethod( vA, "mul", float.class );
//					return oprator.invoke( vA, ((p_float)vB).value );
//				}
//			}
			
		}
		else if( opHash == _OP_DIV_ ){

			if( !isNotSame || !existPfloat)
			{
				if(clsA == CqVector3D.class){
					return ((CqVector3D)vA).div((CqVector3D)vB);
				}
				else if(clsA == p_float.class){
					p_float fltA = (p_float)vA;		// <- cast
					p_float fltB = (p_float)vB;
					return new p_float( fltA.value / fltB.value );
				}
//				else if(clsA == CqVector4D.class){
//					return ((CqVector4D)vA).div((CqVector4D)vB);
//				}
				else if(clsA == CqColor.class){
					return ((CqColor)vA).div((CqColor)vB);
				}
				else if(clsA == p_String.class){
					p_String strA = (p_String)vA;	// <- cast
//					p_String strB = (p_String)vB;
					return strA;
				}
			}
			else if( clsA == p_float.class ){
				if(clsB == CqVector3D.class){
					return ((CqVector3D)vB).divInv(((p_float)vA).value);
				}
				else if(clsB == CqVector4D.class){
					return ((CqVector4D)vB).divInv(((p_float)vA).value);
				}
				else if(clsB == CqColor.class){
					return ((CqColor)vB).divInv(((p_float)vA).value);
				}
			}
			else if( clsB == p_float.class ){
				if(clsA == CqVector3D.class){
					return ((CqVector3D)vA).div(((p_float)vB).value);
				}
				else if(clsA == CqVector4D.class){
					return ((CqVector4D)vA).div(((p_float)vB).value);
				}
				else if(clsA == CqColor.class){
					return ((CqColor)vA).div(((p_float)vB).value);
				}
			}
//			if( isPfloat ){
//				p_float fltA = (p_float)vA;		// <- cast
//				p_float fltB = (p_float)vB;
//				return new p_float( fltA.value / fltB.value );
//			}
//			else if( isPstring ){
//				p_String strA = (p_String)vA;	// <- cast
////				p_String strB = (p_String)vB;
//				return strA;
//			}
//			else{
//				if( !isNotSame ){
//					oprator = AccessSupplier.getMethod( vA, "div", clsB );
//					Object ret = oprator.invoke( vA, vB );
//					
//					if( ret instanceof Float )	return new p_float((Float)ret);
//					return ret;
//				}
//				else if( clsA == p_float.class ){
//					oprator = AccessSupplier.getMethod( vB, "divInv", float.class );
//					return oprator.invoke( vB, ((p_float)vA).value );
//				}
//				else if( clsB == p_float.class ){
//					oprator = AccessSupplier.getMethod( vA, "div", float.class );
//					return oprator.invoke( vA, ((p_float)vB).value );
//				}
//			}
			
		}
		else if( opHash == _OP_ADD_ ){
			if( !isNotSame || !existPfloat)
			{
						if(clsA == CqVector3D.class){
							return ((CqVector3D)vA).add((CqVector3D)vB);
						}
						else if(clsA == p_float.class){
							p_float fltA = (p_float)vA;		// <- cast
							p_float fltB = (p_float)vB;
							return new p_float( fltA.value + fltB.value );
						}
						else if(clsA == CqVector4D.class){
							return ((CqVector4D)vA).add((CqVector4D)vB);
						}
						else if(clsA == CqColor.class){
							return ((CqColor)vA).add((CqColor)vB);
						}
						else if(clsA == p_String.class){
							p_String strA = (p_String)vA;	// <- cast
							p_String strB = (p_String)vB;
							return new p_String( strA.value + strB.value );
						}
			}
			else if( clsA == p_float.class ){
				if(clsB == CqVector3D.class){
					return ((CqVector3D)vB).add(((p_float)vA).value);
				}
//				else if(clsB == CqVector4D.class){
//					return ((CqVector4D)vB).add(((p_float)vA).value);
//				}
				else if(clsB == CqColor.class){
					return ((CqColor)vB).add(((p_float)vA).value);
				}
			}
			else if( clsB == p_float.class ){
				if(clsA == CqVector3D.class){
					return ((CqVector3D)vA).add(((p_float)vB).value);
				}
//				else if(clsA == CqVector4D.class){
//					return ((CqVector4D)vA).add(((p_float)vB).value);
//				}
				else if(clsA == CqColor.class){
					return ((CqColor)vA).add(((p_float)vB).value);
				}
			}
			
//			if( isPfloat ){
//				p_float fltA = (p_float)vA;		// <- cast
//				p_float fltB = (p_float)vB;
//				return new p_float( fltA.value + fltB.value );
//			}
//			else if( isPstring ){
//				p_String strA = (p_String)vA;	// <- cast
//				p_String strB = (p_String)vB;
//				return new p_String( strA.value + strB.value );
//			}
//			else{
//				if( !isNotSame ){
//					oprator = AccessSupplier.getMethod( vA, "add", clsB );
//					Object ret = oprator.invoke( vA, vB );
//					
//					if( ret instanceof Float )	return new p_float((Float)ret);
//					return ret;
//				}
//				else if( clsA == p_float.class ){
//					oprator = AccessSupplier.getMethod( vB, "add", float.class );
//					return oprator.invoke( vB, ((p_float)vA).value );
//				}
//				else if( clsB == p_float.class ){
//					oprator = AccessSupplier.getMethod( vA, "add", float.class );
//					return oprator.invoke( vA, ((p_float)vB).value );
//				}
//			}
			
		}
		else if( opHash == _OP_SUB_ ){
			if( !isNotSame || !existPfloat)
			{
						if(clsA == CqVector3D.class){
							return ((CqVector3D)vA).sub((CqVector3D)vB);
						}
						else if(clsA == p_float.class){
							p_float fltA = (p_float)vA;		// <- cast
							p_float fltB = (p_float)vB;
							return new p_float( fltA.value - fltB.value );
						}
						else if(clsA == CqVector4D.class){
							return ((CqVector4D)vA).sub((CqVector4D)vB);
						}
						else if(clsA == CqColor.class){
							return ((CqColor)vA).sub((CqColor)vB);
						}
						else if(clsA == p_String.class){
							p_String strA = (p_String)vA;	// <- cast
							p_String strB = (p_String)vB;
						return strA;
						}
				
			}
			else if( clsA == p_float.class ){
				if(clsB == CqVector3D.class){
					return ((CqVector3D)vB).subInv(((p_float)vA).value);
				}
//				else if(clsB == CqVector4D.class){
//					return ((CqVector4D)vB).subInv(((p_float)vA).value);
//				}
				else if(clsB == CqColor.class){
					return ((CqColor)vB).subInv(((p_float)vA).value);
				}
			}
			else if( clsB == p_float.class ){
				if(clsA == CqVector3D.class){
					return ((CqVector3D)vA).sub(((p_float)vB).value);
				}
//				else if(clsA == CqVector4D.class){
//					return ((CqVector4D)vA).sub(((p_float)vB).value);
//				}
				else if(clsA == CqColor.class){
					return ((CqColor)vA).sub(((p_float)vB).value);
				}
			}
//			if( isPfloat ){
//				p_float fltA = (p_float)vA;		// <- cast
//				p_float fltB = (p_float)vB;
//				return new p_float( fltA.value - fltB.value );
//			}
//			else if( isPstring ){
//				p_String strA = (p_String)vA;	// <- cast
////				p_String strB = (p_String)vB;
//				return strA;
//			}
//			else{
//				if( !isNotSame ){
//					oprator = AccessSupplier.getMethod( vA, "sub", clsB );
//					Object ret = oprator.invoke( vA, vB );
//					
//					if( ret instanceof Float )	return new p_float((Float)ret);
//					return ret;
//				}
//				else if( clsA == p_float.class ){
//					oprator = AccessSupplier.getMethod( vB, "subInv", float.class );
//					return oprator.invoke( vB, ((p_float)vA).value );
//				}
//				else if( clsB == p_float.class ){
//					oprator = AccessSupplier.getMethod( vA, "sub", float.class );
//					return oprator.invoke( vA, ((p_float)vB).value );
//				}
//			}
			
		}
		else if( opHash == _OP_DOT_ ){
			
			if(clsA == p_float.class){
				p_float fltA = (p_float)vA;		// <- cast
				p_float fltB = (p_float)vB;
				return new p_float( fltA.value * fltB.value );
			}
			else if(clsA == p_String.class){
				p_String strA = (p_String)vA;	// <- cast
//				p_String strB = (p_String)vB;
				return strA;
			}
			else if(clsA == CqVector3D.class){
				return new p_float(((CqVector3D)vA).mul((CqVector3D)vB));
			}
			else if(clsA == CqVector4D.class){
				return new p_float(((CqVector4D)vA).mul((CqVector4D)vB));
			}
			else if(clsA == CqColor.class){
				return ((CqColor)vA).mul((CqColor)vB);
			}
		}
		else if( opHash == _OP_CRS_ ){
			
			if(clsA == p_float.class){
				p_float fltA = (p_float)vA;		// <- cast
				p_float fltB = (p_float)vB;
				return new p_float( fltA.value % fltB.value );
			}
			else if(clsA == p_String.class){
				p_String strA = (p_String)vA;	// <- cast
//				p_String strB = (p_String)vB;
				return strA;
			}
			else if( !isNotSame && clsA==CqColor.class ){
				CqVector3D vecA = new CqVector3D( (CqColor)vA );
				CqVector3D vecB = new CqVector3D( (CqColor)vB );
				CqVector3D ret = vecA.mod( vecB );
				
				return new CqColor( ret );
				
			}
			else if(clsA == CqVector3D.class){
				return ((CqVector3D)vA).mod((CqVector3D)vB);
			}
			else if(clsA == CqVector4D.class){
				return ((CqVector4D)vA).mod((CqVector4D)vB);
			}
			
		}
		else if( opHash == _OP_LAND_ ){
			
			if(clsA == p_float.class){
				p_float fltA = (p_float)vA;		// <- cast
				p_float fltB = (p_float)vB;
				return new p_float( ( fltA.value!=0 && fltB.value!=0 )?1:0 );
			}
			else if(clsA == p_String.class){
				p_String strA = (p_String)vA;	// <- cast
				p_String strB = (p_String)vB;
				return new p_float( ( strA.value!=null && strB.value!=null )?1:0 );
			}
			else{
				return new p_float( ( vA!=null && vB!=null )?1:0 );
			}
			
		}
		else if( opHash == _OP_LOR_ ){
			
			if(clsA == p_float.class){
				p_float fltA = (p_float)vA;		// <- cast
				p_float fltB = (p_float)vB;
				return new p_float( ( fltA.value!=0 || fltB.value!=0 )?1:0 );
			}
			else if(clsA == p_String.class){
				p_String strA = (p_String)vA;	// <- cast
				p_String strB = (p_String)vB;
				return new p_float( ( strA.value!=null || strB.value!=null )?1:0 );
			}
			else{
				return new p_float( ( vA!=null || vB!=null )?1:0 );
			}
			
		}
		//end of if-else( op )
		
		
	} catch( Exception e ) {
		HimawariLogger.outputException( e );
	}
	
	//以上の演算子でない場合や、エラーがあった場合はnullを返す
	return null;
}	
}
