/* This file is part of the Vc library. Copyright (C) 2009-2011 Matthias Kretz Vc is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. Vc 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with Vc. If not, see . */ #ifndef SSE_TYPES_H #define SSE_TYPES_H #include "intrinsics.h" #include "../common/storage.h" #define VC_DOUBLE_V_SIZE 2 #define VC_FLOAT_V_SIZE 4 #define VC_SFLOAT_V_SIZE 8 #define VC_INT_V_SIZE 4 #define VC_UINT_V_SIZE 4 #define VC_SHORT_V_SIZE 8 #define VC_USHORT_V_SIZE 8 #include "../common/types.h" #include "macros.h" /*OUTER_NAMESPACE_BEGIN*/ namespace Vc { namespace SSE { template class Vector; template class WriteMaskedVector; // define our own long because on Windows64 long == int while on Linux long == max. register width // since we want to have a type that depends on 32 vs. 64 bit we need to do some special casing on Windows #ifdef _WIN64 typedef __int64 _long; typedef unsigned __int64 _ulong; #else typedef long _long; typedef unsigned long _ulong; #endif class Float8Mask; class Float8GatherMask; template class Mask; /* * Hack to create a vector object with 8 floats */ typedef Vc::sfloat float8; class M256 { public: //Vc_INTRINSIC M256() {} //Vc_INTRINSIC M256(_M128 a, _M128 b) { d[0] = a; d[1] = b; } static Vc_INTRINSIC Vc_CONST M256 dup(_M128 a) { M256 r; r.d[0] = a; r.d[1] = a; return r; } static Vc_INTRINSIC Vc_CONST M256 create(_M128 a, _M128 b) { M256 r; r.d[0] = a; r.d[1] = b; return r; } Vc_INTRINSIC _M128 &operator[](int i) { return d[i]; } Vc_INTRINSIC const _M128 &operator[](int i) const { return d[i]; } private: #ifdef VC_COMPILE_BENCHMARKS public: #endif _M128 d[2]; }; #ifdef VC_CHECK_ALIGNMENT static Vc_ALWAYS_INLINE void assertCorrectAlignment(const M256 *ptr) { const size_t s = sizeof(__m128); if((reinterpret_cast(ptr) & ((s ^ (s & (s - 1))) - 1)) != 0) { fprintf(stderr, "A vector with incorrect alignment has just been created. Look at the stacktrace to find the guilty object.\n"); abort(); } } #endif template struct ParameterHelper { typedef T ByValue; typedef T & Reference; typedef const T & ConstRef; }; #if defined VC_MSVC && !defined _WIN64 // The calling convention on WIN32 can't guarantee alignment. // An exception are the first three arguments, which may be passed in a register. template<> struct ParameterHelper { typedef const M256 & ByValue; typedef M256 & Reference; typedef const M256 & ConstRef; }; #endif template struct VectorHelper {}; template struct IndexTypeHelper; template<> struct IndexTypeHelper<2u> { typedef unsigned int Type; }; template<> struct IndexTypeHelper<4u> { typedef unsigned int Type; }; template<> struct IndexTypeHelper<8u> { typedef unsigned short Type; }; template<> struct IndexTypeHelper<16u>{ typedef unsigned char Type; }; template struct CtorTypeHelper { typedef T Type; }; template<> struct CtorTypeHelper { typedef int Type; }; template<> struct CtorTypeHelper { typedef unsigned int Type; }; template<> struct CtorTypeHelper { typedef double Type; }; template struct ExpandTypeHelper { typedef T Type; }; template<> struct ExpandTypeHelper { typedef int Type; }; template<> struct ExpandTypeHelper { typedef unsigned int Type; }; template<> struct ExpandTypeHelper { typedef double Type; }; template struct VectorTypeHelper { typedef __m128i Type; }; template<> struct VectorTypeHelper { typedef __m128d Type; }; template<> struct VectorTypeHelper< float> { typedef __m128 Type; }; template<> struct VectorTypeHelper { typedef M256 Type; }; template struct DetermineMask { typedef Mask Type; }; template<> struct DetermineMask { typedef Float8Mask Type; }; template struct DetermineGatherMask { typedef T Type; }; template<> struct DetermineGatherMask { typedef Float8GatherMask Type; }; template struct VectorTraits { typedef typename VectorTypeHelper::Type VectorType; typedef typename DetermineEntryType::Type EntryType; enum Constants { Size = sizeof(VectorType) / sizeof(EntryType), HasVectorDivision = !IsInteger::Value }; typedef typename DetermineMask::Type MaskType; typedef typename DetermineGatherMask::Type GatherMaskType; typedef Vector::Type> IndexType; typedef Common::VectorMemoryUnion StorageType; }; template struct VectorHelperSize; template > class STRUCT_ALIGN1(16) VectorAlignedBaseT { public: FREE_STORE_OPERATORS_ALIGNED(16) } STRUCT_ALIGN2(16); } // namespace SSE } // namespace Vc /*OUTER_NAMESPACE_END*/ #include "undomacros.h" #endif // SSE_TYPES_H