//	Roast+ License

//	SIMD

#ifndef __SFJP_OPENMGL_roast_simd_core_HPP__
#define __SFJP_OPENMGL_roast_simd_core_HPP__

#include <stdio.h>
#include <memory.h>
#include "roast_pp.h"

#include <nmmintrin.h>   // MMX-SSE4.2命令セットを使用する場合インクルード //
#include <smmintrin.h>   // MMX-SSE4.1命令セットを使用する場合インクルード //
#include <intrin.h>      // MMX-SSE3命令セットを使用する場合インクルード   //
#include <emmintrin.h>   // MMX-SSE2命令セットを使用する場合インクルード   //
#include <xmmintrin.h>   // MMX-SSE命令セットを使用する場合インクルード    //
#include <mmintrin.h>    // MMX命令セットを使用する場合インクルード        //


//#define _ROAST_SIMD__ENABLE_FAST_INLINE

#define _ROAST_SIMD_XMM_MAX		(15)
#define _ROAST_SIMD_XMM_MAX_	(15)


#define _ROAST_SIMD__ALIGN_16				__declspec(align(16))
#define _ROAST_ALIGN_16						__declspec(align(16))
#define _ROAST_SIMD__ALIGN_16_FLOAT			_ROAST_SIMD__ALIGN_16 float
#define _ROAST_SIMD__ALIGN_16_CFLOAT		_ROAST_SIMD__ALIGN_16 const float
#define _ROAST_SIMD__ALIGN_16_CONST_FLOAT	_ROAST_SIMD__ALIGN_16_CFLOAT
#define _ROAST_SIMD__ALIGN_16_PVOID			void*
#define _ROAST_SIMD__NOAL_PDOUBLE			double*



/*	Roast SSE Memory Type (128bit)	*/
typedef union
	__declspec(intrin_type)	//	__declspec(intrin_type)って何だろ？（調べてみたが”謎”らしい
	tag_NO_ALIGNED__ROAST_SIMD_M128
{
	float               float_x4[4];

	__int8              char_x16[16];
	__int16             short_x8[8];
	__int32             int_x4[4];
	__int64             int64_x2[2];
	__int64             longlong_x2[2];
	unsigned __int8     byte_x16[16];
	unsigned __int16    ushort_x8[8];
	unsigned __int32    uint_x4[4];
	unsigned __int64    uint64_x2[2];
	unsigned __int64    ulonglong_x2[2];

	////////////////////////////////////////////

	float               f_x4[4];

	__int8              c_x16[16];
	__int16             s_x8[8];
	__int32             i_x4[4];
	__int64             i64_x2[2];
	__int64             ll_x2[2];
	unsigned __int8     b_x16[16];
	unsigned __int16    us_x8[8];
	unsigned __int32    ui_x4[4];
	unsigned __int64    ui64_x2[2];
	unsigned __int64    ull_x2[2];

	////////////////////////////////////////////

	float               f32[4];
	unsigned __int64    u64[2];
	__int8              i8[16];
	__int16             i16[8];
	__int32             i32[4];
	__int64             i64[2];
	unsigned __int8     u8[16];
	unsigned __int16    u16[8];
	unsigned __int32    u32[4];
/*
	float               m128_f32[4];
	unsigned __int64    m128_u64[2];
	__int8              m128_i8[16];
	__int16             m128_i16[8];
	__int32             m128_i32[4];
	__int64             m128_i64[2];
	unsigned __int8     m128_u8[16];
	unsigned __int16    m128_u16[8];
	unsigned __int32    m128_u32[4];
*/
} _NO_ALIGNED__ROAST_SIMD_M128;

/*	No Aligned	*/
typedef _NO_ALIGNED__ROAST_SIMD_M128 _FUNC_PARAM_ROAST_SIMD_M128;
typedef _FUNC_PARAM_ROAST_SIMD_M128 _ROAST_SIMD_M128;

/*	Aligned     */
typedef _ROAST_ALIGN_16 _NO_ALIGNED__ROAST_SIMD_M128 ROAST_SIMD_M128;




/* ######### Internal ########## */

//#	define ROAST_SIMD_CLASS_OR_NS				class
#	define ROAST_SIMD_CLASS_OR_NS				namespace
#	define ROAST_SIMD_STATIC					static
//#	define ROAST_SIMD_STATIC
#	define ROAST_SIMD_2ND_NAMESPACE_START(X)	ROAST_SIMD_CLASS_OR_NS X {
#	define ROAST_SIMD_2ND_NAMESPACE_END			}
//#	define ROAST_SIMD_2ND_NAMESPACE_START(X)
//#	define ROAST_SIMD_2ND_NAMESPACE_END

/* Internal End. */



//////////////////////////////////////////////////////////////////////////////////////////////////////

/*	namespace roast	*/
namespace roast{



	//	########  Definitations  ####################

	//typedef ROAST_SIMD_M128 m128;	/*	SSE Memory Type (128bit)	*/
	typedef ROAST_SIMD_M128 m128;	/*	SSE Memory Type (128bit)	*/
	typedef _NO_ALIGNED__ROAST_SIMD_M128 _na_m128;	/*	SSE Memory Type (128bit)	*/

	typedef _ROAST_SIMD__ALIGN_16_FLOAT aligned_float, al_float;

	//typedef __m128 _ROAST_SIMD_USE_M128;



	/*	namespace simd	*/
	ROAST_SIMD_CLASS_OR_NS simd
	{
		//	########  Definitations  ####################

		//typedef ROAST_SIMD_M128 m128;	/*	SSE Memory Type (128bit)	*/
		typedef ROAST_SIMD_M128 m128;	/*	SSE Memory Type (128bit)	*/
		typedef _NO_ALIGNED__ROAST_SIMD_M128 _na_m128;	/*	SSE Memory Type (128bit)	*/

		typedef _ROAST_SIMD__ALIGN_16_FLOAT aligned_float, al_float;

		//typedef __m128 _ROAST_SIMD_USE_M128;



		//////////////////////////////////////////////////////////////////


		//	########  MMX  ####################

		/*	あまりまともに実装する気はないです・・・	*/




		//	########  SSE  ####################
		//ROAST_SIMD_2ND_NAMESPACE_START(sse)
		class sse1 {
		public:

#include "simd_core_sse"


		//	########  SSE2  ####################
		//ROAST_SIMD_2ND_NAMESPACE_END
		//ROAST_SIMD_2ND_NAMESPACE_START(sse2)
		}; class sse2 : public sse1 {
		public:

#include "simd_core_sse2"


		//	########  SSE3  ####################
		//ROAST_SIMD_2ND_NAMESPACE_END
		//ROAST_SIMD_2ND_NAMESPACE_START(sse3)
		}; class sse3 : public sse2 {
		public:


		//	########  SSE4  ####################
		//ROAST_SIMD_2ND_NAMESPACE_END
		//ROAST_SIMD_2ND_NAMESPACE_START(sse4)
		}; class sse4 : public sse3 {
		public:



		/*
		//	########  SSE4.1  ####################
		ROAST_SIMD_2ND_NAMESPACE_END
		ROAST_SIMD_2ND_NAMESPACE_START(sse41)

		ROAST_SIMD_2ND_NAMESPACE_END
		*/


		//	########  SSE4.2  ####################
		//ROAST_SIMD_2ND_NAMESPACE_END
		//ROAST_SIMD_2ND_NAMESPACE_START(sse42)



		//ROAST_SIMD_2ND_NAMESPACE_END

		};
		typedef sse2 sse;
	};
}

#endif//__SFJP_OPENMGL_roast_simd_core_HPP__
