Vc: update to 0.7.4 release
authormkretz <kretz@compeng.uni-frankfurt.de>
Thu, 15 May 2014 12:17:19 +0000 (14:17 +0200)
committerMatthias Kretz <kretz@compeng.uni-frankfurt.de>
Fri, 16 May 2014 12:36:05 +0000 (14:36 +0200)
Summary of the changes in Vc 0.7.4:
* fixed several compile errors / warnings with newer or old C++
  compilers
* support clean compilation with more -W flags
* fixed compilation when compiling without optimization
* added operator-- to Vector<T>
* Copying Memory now uses SIMD move instructions
* Vc::Allocator<T> now uses a minimum alignment of the SIMD types of
  the chosen Vc implementation. Thus making it useable for containers of
  builtin types.

Signed-off-by: Matthias Kretz <kretz@compeng.uni-frankfurt.de>

27 files changed:
Vc/cmake/AddCompilerFlag.cmake
Vc/cmake/CheckCCompilerFlag.cmake
Vc/cmake/CheckCXXCompilerFlag.cmake
Vc/cmake/OptimizeForArchitecture.cmake
Vc/cmake/VcMacros.cmake
Vc/include/Vc/Allocator
Vc/include/Vc/avx/intrinsics.h
Vc/include/Vc/avx/vector.tcc
Vc/include/Vc/common/interleavedmemory.h
Vc/include/Vc/common/logarithm.h
Vc/include/Vc/common/macros.h
Vc/include/Vc/common/memory.h
Vc/include/Vc/common/memorybase.h
Vc/include/Vc/common/undomacros.h
Vc/include/Vc/global.h
Vc/include/Vc/internal/namespace.h
Vc/include/Vc/sse/casts.h
Vc/include/Vc/sse/intrinsics.h
Vc/include/Vc/sse/prefetches.tcc
Vc/include/Vc/sse/shuffle.h
Vc/include/Vc/sse/vector.h
Vc/include/Vc/sse/vector.tcc
Vc/include/Vc/sse/vectorhelper.h
Vc/include/Vc/sse/vectorhelper.tcc
Vc/include/Vc/version.h
Vc/src/avx_sorthelper.cpp
Vc/src/trigonometric.cpp

index 4acb35c..f3e5fd0 100644 (file)
@@ -42,39 +42,31 @@ include("${_currentDir}/CheckCXXCompilerFlag.cmake")
 macro(AddCompilerFlag _flag)
    string(REGEX REPLACE "[-.+/:= ]" "_" _flag_esc "${_flag}")
 
-   if("${_flag}" STREQUAL "-mfma")
-      # Compiling with FMA3 support may fail only at the assembler level.
-      # In that case we need to have such an instruction in the test code
-      set(_code "#include <immintrin.h>
-      __m128 foo(__m128 x) { return _mm_fmadd_ps(x, x, x); }
-      int main() { return 0; }")
-      check_c_compiler_flag("${_flag}" check_c_compiler_flag_${_flag_esc} "${_code}")
-      check_cxx_compiler_flag("${_flag}" check_cxx_compiler_flag_${_flag_esc} "${_code}")
-   elseif("${_flag}" STREQUAL "-stdlib=libc++")
-      # Compiling with libc++ not only requires a compiler that understands it, but also
-      # the libc++ headers itself
-      set(_code "#include <iostream>
-      int main() { return 0; }")
-      check_c_compiler_flag("${_flag}" check_c_compiler_flag_${_flag_esc} "${_code}")
-      check_cxx_compiler_flag("${_flag}" check_cxx_compiler_flag_${_flag_esc} "${_code}")
-   else()
-      check_c_compiler_flag("${_flag}" check_c_compiler_flag_${_flag_esc})
-      check_cxx_compiler_flag("${_flag}" check_cxx_compiler_flag_${_flag_esc})
-   endif()
-
    set(_c_flags "CMAKE_C_FLAGS")
    set(_cxx_flags "CMAKE_CXX_FLAGS")
+   set(_c_result tmp)
+   set(_cxx_result tmp)
    if(${ARGC} EQUAL 2)
-      set(${ARGV1} "${check_cxx_compiler_flag_${_flag_esc}}")
+      message(WARNING "Deprecated use of the AddCompilerFlag macro.")
+      unset(_c_result)
+      set(_cxx_result ${ARGV1})
    elseif(${ARGC} GREATER 2)
       set(state 0)
       unset(_c_flags)
       unset(_cxx_flags)
+      unset(_c_result)
+      unset(_cxx_result)
       foreach(_arg ${ARGN})
          if(_arg STREQUAL "C_FLAGS")
             set(state 1)
+            if(NOT DEFINED _c_result)
+               set(_c_result tmp)
+            endif()
          elseif(_arg STREQUAL "CXX_FLAGS")
             set(state 2)
+            if(NOT DEFINED _cxx_result)
+               set(_cxx_result tmp)
+            endif()
          elseif(_arg STREQUAL "C_RESULT")
             set(state 3)
          elseif(_arg STREQUAL "CXX_RESULT")
@@ -84,15 +76,39 @@ macro(AddCompilerFlag _flag)
          elseif(state EQUAL 2)
             set(_cxx_flags "${_arg}")
          elseif(state EQUAL 3)
-            set(${_arg} ${check_c_compiler_flag_${_flag_esc}})
+            set(_c_result "${_arg}")
          elseif(state EQUAL 4)
-            set(${_arg} ${check_cxx_compiler_flag_${_flag_esc}})
+            set(_cxx_result "${_arg}")
          else()
             message(FATAL_ERROR "Syntax error for AddCompilerFlag")
          endif()
       endforeach()
    endif()
 
+   if("${_flag}" STREQUAL "-mfma")
+      # Compiling with FMA3 support may fail only at the assembler level.
+      # In that case we need to have such an instruction in the test code
+      set(_code "#include <immintrin.h>
+      __m128 foo(__m128 x) { return _mm_fmadd_ps(x, x, x); }
+      int main() { return 0; }")
+   elseif("${_flag}" STREQUAL "-stdlib=libc++")
+      # Compiling with libc++ not only requires a compiler that understands it, but also
+      # the libc++ headers itself
+      set(_code "#include <iostream>
+      int main() { return 0; }")
+   else()
+      set(_code "int main() { return 0; }")
+   endif()
+
+   if(DEFINED _c_result)
+      check_c_compiler_flag("${_flag}" check_c_compiler_flag_${_flag_esc} "${_code}")
+      set(${_c_result} ${check_c_compiler_flag_${_flag_esc}})
+   endif()
+   if(DEFINED _cxx_result)
+      check_cxx_compiler_flag("${_flag}" check_cxx_compiler_flag_${_flag_esc} "${_code}")
+      set(${_cxx_result} ${check_cxx_compiler_flag_${_flag_esc}})
+   endif()
+
    if(check_c_compiler_flag_${_flag_esc} AND DEFINED _c_flags)
       set(${_c_flags} "${${_c_flags}} ${_flag}")
    endif()
index 0cc5f52..a4c7b55 100644 (file)
@@ -62,6 +62,7 @@ MACRO (CHECK_C_COMPILER_FLAG _FLAG _RESULT)
      FAIL_REGEX "command option .* is not recognized"       # XL
      FAIL_REGEX "WARNING: unknown flag:"                    # Open64
      FAIL_REGEX " #10159: "                                 # ICC
+     FAIL_REGEX " #10353: "                                 # ICC: option '-mfma' ignored, suggest using '-march=core-avx2'
      )
    SET (CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
 ENDMACRO (CHECK_C_COMPILER_FLAG)
index 9f47454..c753a3a 100644 (file)
@@ -62,6 +62,7 @@ MACRO (CHECK_CXX_COMPILER_FLAG _FLAG _RESULT)
      FAIL_REGEX "command option .* is not recognized"       # XL
      FAIL_REGEX "WARNING: unknown flag:"                    # Open64
      FAIL_REGEX " #10159: "                                 # ICC
+     FAIL_REGEX " #10353: "                                 # ICC: option '-mfma' ignored, suggest using '-march=core-avx2'
      )
    SET (CMAKE_REQUIRED_DEFINITIONS "${SAFE_CMAKE_REQUIRED_DEFINITIONS}")
 ENDMACRO (CHECK_CXX_COMPILER_FLAG)
index 246889c..e7e6d3a 100644 (file)
@@ -71,7 +71,9 @@ macro(AutodetectHostArchitecture)
    if(_vendor_id STREQUAL "GenuineIntel")
       if(_cpu_family EQUAL 6)
          # Any recent Intel CPU except NetBurst
-         if(_cpu_model EQUAL 58)
+         if(_cpu_model EQUAL 62)
+            set(TARGET_ARCHITECTURE "ivy-bridge")
+         elseif(_cpu_model EQUAL 58)
             set(TARGET_ARCHITECTURE "ivy-bridge")
          elseif(_cpu_model EQUAL 47) # Xeon E7 4860
             set(TARGET_ARCHITECTURE "westmere")
@@ -117,13 +119,16 @@ macro(AutodetectHostArchitecture)
          endif(_cpu_model GREATER 2)
       endif(_cpu_family EQUAL 6)
    elseif(_vendor_id STREQUAL "AuthenticAMD")
-      if(_cpu_family EQUAL 21) # 15h
+      if(_cpu_family EQUAL 22) # 16h
+         set(TARGET_ARCHITECTURE "AMD 16h")
+      elseif(_cpu_family EQUAL 21) # 15h
          if(_cpu_model LESS 2)
             set(TARGET_ARCHITECTURE "bulldozer")
          else()
             set(TARGET_ARCHITECTURE "piledriver")
          endif()
       elseif(_cpu_family EQUAL 20) # 14h
+         set(TARGET_ARCHITECTURE "AMD 14h")
       elseif(_cpu_family EQUAL 18) # 12h
       elseif(_cpu_family EQUAL 16) # 10h
          set(TARGET_ARCHITECTURE "barcelona")
@@ -137,7 +142,7 @@ macro(AutodetectHostArchitecture)
 endmacro()
 
 macro(OptimizeForArchitecture)
-   set(TARGET_ARCHITECTURE "none" CACHE STRING "CPU architecture to optimize for. Using an incorrect setting here can result in crashes of the resulting binary because of invalid instructions used.\nSetting the value to \"auto\" will try to optimize for the architecture where cmake is called.\nOther supported values are: \"none\", \"generic\", \"core\", \"merom\" (65nm Core2), \"penryn\" (45nm Core2), \"nehalem\", \"westmere\", \"sandy-bridge\", \"ivy-bridge\", \"atom\", \"k8\", \"k8-sse3\", \"barcelona\", \"istanbul\", \"magny-cours\", \"bulldozer\", \"interlagos\", \"piledriver\".")
+   set(TARGET_ARCHITECTURE "none" CACHE STRING "CPU architecture to optimize for. Using an incorrect setting here can result in crashes of the resulting binary because of invalid instructions used.\nSetting the value to \"auto\" will try to optimize for the architecture where cmake is called.\nOther supported values are: \"none\", \"generic\", \"core\", \"merom\" (65nm Core2), \"penryn\" (45nm Core2), \"nehalem\", \"westmere\", \"sandy-bridge\", \"ivy-bridge\", \"atom\", \"k8\", \"k8-sse3\", \"barcelona\", \"istanbul\", \"magny-cours\", \"bulldozer\", \"interlagos\", \"piledriver\", \"AMD 14h\", \"AMD 16h\".")
    set(_force)
    if(NOT _last_target_arch STREQUAL "${TARGET_ARCHITECTURE}")
       message(STATUS "target changed from \"${_last_target_arch}\" to \"${TARGET_ARCHITECTURE}\"")
@@ -191,6 +196,7 @@ macro(OptimizeForArchitecture)
    elseif(TARGET_ARCHITECTURE STREQUAL "sandy-bridge")
       list(APPEND _march_flag_list "sandybridge")
       list(APPEND _march_flag_list "corei7-avx")
+      list(APPEND _march_flag_list "corei7")
       list(APPEND _march_flag_list "core2")
       list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "ssse3" "sse4.1" "sse4.2" "avx")
    elseif(TARGET_ARCHITECTURE STREQUAL "atom")
@@ -204,6 +210,13 @@ macro(OptimizeForArchitecture)
       list(APPEND _march_flag_list "k8-sse3")
       list(APPEND _march_flag_list "k8")
       list(APPEND _available_vector_units_list "sse" "sse2" "sse3")
+   elseif(TARGET_ARCHITECTURE STREQUAL "AMD 16h")
+      list(APPEND _march_flag_list "btver2")
+      list(APPEND _march_flag_list "btver1")
+      list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "ssse3" "sse4a" "sse4.1" "sse4.2" "avx" "f16c")
+   elseif(TARGET_ARCHITECTURE STREQUAL "AMD 14h")
+      list(APPEND _march_flag_list "btver1")
+      list(APPEND _available_vector_units_list "sse" "sse2" "sse3" "ssse3" "sse4a")
    elseif(TARGET_ARCHITECTURE STREQUAL "piledriver")
       list(APPEND _march_flag_list "bdver2")
       list(APPEND _march_flag_list "bdver1")
index 1ae761e..16000db 100644 (file)
@@ -50,7 +50,7 @@ macro(vc_determine_compiler)
       set(Vc_COMPILER_IS_CLANG false)
       set(Vc_COMPILER_IS_MSVC false)
       set(Vc_COMPILER_IS_GCC false)
-      if(CMAKE_CXX_COMPILER MATCHES "(icpc|icc)$")
+      if(CMAKE_CXX_COMPILER MATCHES "/(icpc|icc)$")
          set(Vc_COMPILER_IS_INTEL true)
          exec_program(${CMAKE_C_COMPILER} ARGS -dumpversion OUTPUT_VARIABLE Vc_ICC_VERSION)
          message(STATUS "Detected Compiler: Intel ${Vc_ICC_VERSION}")
@@ -208,7 +208,6 @@ macro(vc_set_preferred_compiler_flags)
          AddCompilerFlag("-Wpointer-arith")
          AddCompilerFlag("-Wcast-align")
          AddCompilerFlag("-Wreturn-type")
-         AddCompilerFlag("-Wno-unused-function")
          AddCompilerFlag("-ansi")
          AddCompilerFlag("-pedantic")
          AddCompilerFlag("-Wno-long-long")
@@ -229,8 +228,8 @@ macro(vc_set_preferred_compiler_flags)
       #                                              GCC                                               #
       ##################################################################################################
       if(_add_warning_flags)
-         set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -W -Wall -Wswitch -Wformat -Wchar-subscripts -Wparentheses -Wmultichar -Wtrigraphs -Wpointer-arith -Wcast-align -Wreturn-type -Wno-unused-function -pedantic -Wno-long-long -Wshadow")
-         set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -W -Wall -Wswitch -Wformat -Wchar-subscripts -Wparentheses -Wmultichar -Wtrigraphs -Wpointer-arith -Wcast-align -Wreturn-type -Wno-unused-function -pedantic -Wno-long-long -Wshadow")
+         set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -W -Wall -Wswitch -Wformat -Wchar-subscripts -Wparentheses -Wmultichar -Wtrigraphs -Wpointer-arith -Wcast-align -Wreturn-type -pedantic -Wno-long-long -Wshadow")
+         set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -W -Wall -Wswitch -Wformat -Wchar-subscripts -Wparentheses -Wmultichar -Wtrigraphs -Wpointer-arith -Wcast-align -Wreturn-type -pedantic -Wno-long-long -Wshadow")
          if(NOT WIN32)
             # the -ansi flag makes MinGW unusable, so maybe it's better to omit it
             set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -ansi")
@@ -243,11 +242,6 @@ macro(vc_set_preferred_compiler_flags)
             # GCC gives bogus "array subscript is above array bounds" warnings in math.cpp
             AddCompilerFlag("-Wno-array-bounds")
          endif()
-         if(Vc_GCC_VERSION VERSION_GREATER "4.7.99")
-            # GCC 4.8 warns about stuff we don't care about
-            # Some older GCC versions have problems to note that they don't support the flag
-            AddCompilerFlag("-Wno-unused-local-typedefs")
-         endif()
       endif()
       vc_add_compiler_flag(Vc_DEFINITIONS "-Wabi")
       vc_add_compiler_flag(Vc_DEFINITIONS "-fabi-version=0") # ABI version 4 is required to make __m128 and __m256 appear as different types. 0 should give us the latest version.
@@ -367,7 +361,7 @@ macro(vc_set_preferred_compiler_flags)
       # for now I don't know of any arguments I want to pass. -march and stuff is tried by OptimizeForArchitecture...
       if(Vc_CLANG_VERSION VERSION_EQUAL "3.0")
          UserWarning("Clang 3.0 has serious issues to compile Vc code and will most likely crash when trying to do so.\nPlease update to a recent clang version.")
-      elseif(Vc_CLANG_VERSION VERSION_LESS "3.3")
+      elseif(Vc_CLANG_VERSION VERSION_EQUAL "3.2" AND NOT APPLE)
          # the LLVM assembler gets FMAs wrong (bug 15040)
          vc_add_compiler_flag(Vc_DEFINITIONS "-no-integrated-as")
       endif()
@@ -376,13 +370,13 @@ macro(vc_set_preferred_compiler_flags)
       vc_add_compiler_flag(Vc_DEFINITIONS "-Wno-local-type-template-args")
       vc_add_compiler_flag(Vc_DEFINITIONS "-Wno-unnamed-type-template-args")
 
-      AddCompilerFlag(-stdlib=libc++)
+      if(NOT DEFINED Vc_INSIDE_ROOT)  # ROOT has to set this up
+         AddCompilerFlag(-stdlib=libc++)
+      endif()
    endif()
 
    if(NOT Vc_COMPILER_IS_MSVC)
-     if(NOT Vc_COMPILER_IS_INTEL)
-       vc_add_compiler_flag(Vc_DEFINITIONS "-ffp-contract=fast")
-     endif()
+      vc_add_compiler_flag(Vc_DEFINITIONS "-ffp-contract=fast")
    endif()
 
    OptimizeForArchitecture()
@@ -538,10 +532,8 @@ macro(vc_compile_for_all_implementations _objs _src)
       _vc_compile_one_implementation(${_objs} AVX      "-mavx"    "-xAVX"    "/arch:AVX")
       if(NOT Vc_XOP_INTRINSICS_BROKEN)
          if(NOT Vc_FMA4_INTRINSICS_BROKEN)
-          if (NOT Vc_COMPILER_IS_INTEL)
-             _vc_compile_one_implementation(${_objs} SSE+XOP+FMA4 "-mxop -mfma4"        ""    "")
-             _vc_compile_one_implementation(${_objs} AVX+XOP+FMA4 "-mavx -mxop -mfma4"  ""    "")
-         endif()
+            _vc_compile_one_implementation(${_objs} SSE+XOP+FMA4 "-mxop -mfma4"        ""    "")
+            _vc_compile_one_implementation(${_objs} AVX+XOP+FMA4 "-mavx -mxop -mfma4"  ""    "")
          endif()
          _vc_compile_one_implementation(${_objs} SSE+XOP+FMA "-mxop -mfma"        ""    "")
          _vc_compile_one_implementation(${_objs} AVX+XOP+FMA "-mavx -mxop -mfma"  ""    "")
index fdc134f..79961f8 100644 (file)
 #include <new>
 #include <cstddef>
 #include <cstdlib>
-#include "common/macros.h"
+#include "global.h"
 #ifdef VC_CXX11
 #include <utility>
 #endif
+#include "common/macros.h"
 
 namespace AliRoot {
 namespace Vc
@@ -125,7 +126,14 @@ namespace std \
             NaturalAlignment = sizeof(void *) > Vc_ALIGNOF(long double) ? sizeof(void *) :
                 (Vc_ALIGNOF(long double) > Vc_ALIGNOF(long long) ? Vc_ALIGNOF(long double) : Vc_ALIGNOF(long long)),
 #endif
-            Alignment = Vc_ALIGNOF(T),
+#ifdef VC_IMPL_AVX
+            SimdAlignment = 32,
+#elif defined VC_IMPL_SSE
+            SimdAlignment = 16,
+#else
+            SimdAlignment = 1,
+#endif
+            Alignment = Vc_ALIGNOF(T) > SimdAlignment ? Vc_ALIGNOF(T) : SimdAlignment,
             /* The number of extra bytes allocated must be large enough to put a pointer right
              * before the adjusted address. This pointer stores the original address, which is
              * required to call ::operator delete in deallocate.
index 709cbc9..0aabadc 100644 (file)
@@ -210,9 +210,9 @@ namespace AVX
     static Vc_INTRINSIC m256i Vc_CONST _mm256_setmin_epi32() { return _mm256_castps_si256(_mm256_broadcast_ss(reinterpret_cast<const float *>(&c_general::signMaskFloat[1]))); }
 
 #ifdef VC_REQUIRES_MACRO_FOR_IMMEDIATE_ARGUMENT
-#define _mm_extract_epu8 _mm_extract_epi8
-#define _mm_extract_epu16 _mm_extract_epi16
-#define _mm_extract_epu32 _mm_extract_epi32
+#define _mm_extract_epu8 (x, i) (static_cast<unsigned char> (_mm_extract_epi8 ((x), (i))))
+#define _mm_extract_epu16(x, i) (static_cast<unsigned short>(_mm_extract_epi16((x), (i))))
+#define _mm_extract_epu32(x, i) (static_cast<unsigned int>  (_mm_extract_epi32((x), (i))))
 #else
     static Vc_INTRINSIC unsigned char Vc_CONST _mm_extract_epu8(param128i x, const int i) { return _mm_extract_epi8(x, i); }
     static Vc_INTRINSIC unsigned short Vc_CONST _mm_extract_epu16(param128i x, const int i) { return _mm_extract_epi16(x, i); }
@@ -289,6 +289,16 @@ namespace AVX
     AVX_TO_SSE_2(cmpgt_epi16)
     AVX_TO_SSE_2(cmpgt_epi32)
 
+    // This code is AVX only (without AVX2). We never asked for AVX2 intrinsics. So go away... :)
+#if defined _mm256_srli_si256
+#undef _mm256_srli_si256
+#endif
+#if defined _mm256_slli_si256
+#undef _mm256_slli_si256
+#endif
+#if defined _mm256_blend_epi16
+#undef _mm256_blend_epi16
+#endif
     static Vc_INTRINSIC m256i Vc_CONST _mm256_srli_si256(param256i a0, const int i) {
         const m128i vLo = _mm256_castsi256_si128(a0);
         const m128i vHi = _mm256_extractf128_si256(a0, 1);
index a58e748..626eecb 100644 (file)
@@ -1286,24 +1286,27 @@ template<typename VectorType, typename EntryType> struct VectorShift<32, 8, Vect
 };
 template<typename VectorType, typename EntryType> struct VectorShift<16, 8, VectorType, EntryType>
 {
+    enum {
+        EntryTypeSizeof = sizeof(EntryType)
+    };
     static Vc_INTRINSIC VectorType shifted(VC_ALIGNED_PARAMETER(VectorType) v, int amount)
     {
         switch (amount) {
         case  0: return v;
-        case  1: return avx_cast<VectorType>(_mm_srli_si128(avx_cast<m128i>(v), 1 * sizeof(EntryType)));
-        case  2: return avx_cast<VectorType>(_mm_srli_si128(avx_cast<m128i>(v), 2 * sizeof(EntryType)));
-        case  3: return avx_cast<VectorType>(_mm_srli_si128(avx_cast<m128i>(v), 3 * sizeof(EntryType)));
-        case  4: return avx_cast<VectorType>(_mm_srli_si128(avx_cast<m128i>(v), 4 * sizeof(EntryType)));
-        case  5: return avx_cast<VectorType>(_mm_srli_si128(avx_cast<m128i>(v), 5 * sizeof(EntryType)));
-        case  6: return avx_cast<VectorType>(_mm_srli_si128(avx_cast<m128i>(v), 6 * sizeof(EntryType)));
-        case  7: return avx_cast<VectorType>(_mm_srli_si128(avx_cast<m128i>(v), 7 * sizeof(EntryType)));
-        case -1: return avx_cast<VectorType>(_mm_slli_si128(avx_cast<m128i>(v), 1 * sizeof(EntryType)));
-        case -2: return avx_cast<VectorType>(_mm_slli_si128(avx_cast<m128i>(v), 2 * sizeof(EntryType)));
-        case -3: return avx_cast<VectorType>(_mm_slli_si128(avx_cast<m128i>(v), 3 * sizeof(EntryType)));
-        case -4: return avx_cast<VectorType>(_mm_slli_si128(avx_cast<m128i>(v), 4 * sizeof(EntryType)));
-        case -5: return avx_cast<VectorType>(_mm_slli_si128(avx_cast<m128i>(v), 5 * sizeof(EntryType)));
-        case -6: return avx_cast<VectorType>(_mm_slli_si128(avx_cast<m128i>(v), 6 * sizeof(EntryType)));
-        case -7: return avx_cast<VectorType>(_mm_slli_si128(avx_cast<m128i>(v), 7 * sizeof(EntryType)));
+        case  1: return avx_cast<VectorType>(_mm_srli_si128(avx_cast<m128i>(v), 1 * EntryTypeSizeof));
+        case  2: return avx_cast<VectorType>(_mm_srli_si128(avx_cast<m128i>(v), 2 * EntryTypeSizeof));
+        case  3: return avx_cast<VectorType>(_mm_srli_si128(avx_cast<m128i>(v), 3 * EntryTypeSizeof));
+        case  4: return avx_cast<VectorType>(_mm_srli_si128(avx_cast<m128i>(v), 4 * EntryTypeSizeof));
+        case  5: return avx_cast<VectorType>(_mm_srli_si128(avx_cast<m128i>(v), 5 * EntryTypeSizeof));
+        case  6: return avx_cast<VectorType>(_mm_srli_si128(avx_cast<m128i>(v), 6 * EntryTypeSizeof));
+        case  7: return avx_cast<VectorType>(_mm_srli_si128(avx_cast<m128i>(v), 7 * EntryTypeSizeof));
+        case -1: return avx_cast<VectorType>(_mm_slli_si128(avx_cast<m128i>(v), 1 * EntryTypeSizeof));
+        case -2: return avx_cast<VectorType>(_mm_slli_si128(avx_cast<m128i>(v), 2 * EntryTypeSizeof));
+        case -3: return avx_cast<VectorType>(_mm_slli_si128(avx_cast<m128i>(v), 3 * EntryTypeSizeof));
+        case -4: return avx_cast<VectorType>(_mm_slli_si128(avx_cast<m128i>(v), 4 * EntryTypeSizeof));
+        case -5: return avx_cast<VectorType>(_mm_slli_si128(avx_cast<m128i>(v), 5 * EntryTypeSizeof));
+        case -6: return avx_cast<VectorType>(_mm_slli_si128(avx_cast<m128i>(v), 6 * EntryTypeSizeof));
+        case -7: return avx_cast<VectorType>(_mm_slli_si128(avx_cast<m128i>(v), 7 * EntryTypeSizeof));
         }
         return _mm_setzero_si128();
     }
@@ -1316,15 +1319,18 @@ template<size_t SIMDWidth, size_t Size, typename VectorType, typename EntryType>
 template<typename VectorType, typename EntryType> struct VectorRotate<32, 4, VectorType, EntryType>
 {
     typedef typename SseVectorType<VectorType>::Type SmallV;
+    enum {
+        EntryTypeSizeof = sizeof(EntryType)
+    };
     static Vc_INTRINSIC VectorType rotated(VC_ALIGNED_PARAMETER(VectorType) v, int amount)
     {
         const m128i vLo = avx_cast<m128i>(lo128(v));
         const m128i vHi = avx_cast<m128i>(hi128(v));
         switch (static_cast<unsigned int>(amount) % 4) {
         case  0: return v;
-        case  1: return concat(avx_cast<SmallV>(_mm_alignr_epi8(vHi, vLo, 1 * sizeof(EntryType))), avx_cast<SmallV>(_mm_alignr_epi8(vLo, vHi, 1 * sizeof(EntryType))));
+        case  1: return concat(avx_cast<SmallV>(_mm_alignr_epi8(vHi, vLo, 1 * EntryTypeSizeof)), avx_cast<SmallV>(_mm_alignr_epi8(vLo, vHi, 1 * EntryTypeSizeof)));
         case  2: return Mem::permute128<X1, X0>(v);
-        case  3: return concat(avx_cast<SmallV>(_mm_alignr_epi8(vLo, vHi, 1 * sizeof(EntryType))), avx_cast<SmallV>(_mm_alignr_epi8(vHi, vLo, 1 * sizeof(EntryType))));
+        case  3: return concat(avx_cast<SmallV>(_mm_alignr_epi8(vLo, vHi, 1 * EntryTypeSizeof)), avx_cast<SmallV>(_mm_alignr_epi8(vHi, vLo, 1 * EntryTypeSizeof)));
         }
         return _mm256_setzero_pd();
     }
@@ -1332,36 +1338,42 @@ template<typename VectorType, typename EntryType> struct VectorRotate<32, 4, Vec
 template<typename VectorType, typename EntryType> struct VectorRotate<32, 8, VectorType, EntryType>
 {
     typedef typename SseVectorType<VectorType>::Type SmallV;
+    enum {
+        EntryTypeSizeof = sizeof(EntryType)
+    };
     static Vc_INTRINSIC VectorType rotated(VC_ALIGNED_PARAMETER(VectorType) v, int amount)
     {
         const m128i vLo = avx_cast<m128i>(lo128(v));
         const m128i vHi = avx_cast<m128i>(hi128(v));
         switch (static_cast<unsigned int>(amount) % 8) {
         case  0: return v;
-        case  1: return concat(avx_cast<SmallV>(_mm_alignr_epi8(vHi, vLo, 1 * sizeof(EntryType))), avx_cast<SmallV>(_mm_alignr_epi8(vLo, vHi, 1 * sizeof(EntryType))));
-        case  2: return concat(avx_cast<SmallV>(_mm_alignr_epi8(vHi, vLo, 2 * sizeof(EntryType))), avx_cast<SmallV>(_mm_alignr_epi8(vLo, vHi, 2 * sizeof(EntryType))));
-        case  3: return concat(avx_cast<SmallV>(_mm_alignr_epi8(vHi, vLo, 3 * sizeof(EntryType))), avx_cast<SmallV>(_mm_alignr_epi8(vLo, vHi, 3 * sizeof(EntryType))));
+        case  1: return concat(avx_cast<SmallV>(_mm_alignr_epi8(vHi, vLo, 1 * EntryTypeSizeof)), avx_cast<SmallV>(_mm_alignr_epi8(vLo, vHi, 1 * EntryTypeSizeof)));
+        case  2: return concat(avx_cast<SmallV>(_mm_alignr_epi8(vHi, vLo, 2 * EntryTypeSizeof)), avx_cast<SmallV>(_mm_alignr_epi8(vLo, vHi, 2 * EntryTypeSizeof)));
+        case  3: return concat(avx_cast<SmallV>(_mm_alignr_epi8(vHi, vLo, 3 * EntryTypeSizeof)), avx_cast<SmallV>(_mm_alignr_epi8(vLo, vHi, 3 * EntryTypeSizeof)));
         case  4: return Mem::permute128<X1, X0>(v);
-        case  5: return concat(avx_cast<SmallV>(_mm_alignr_epi8(vLo, vHi, 1 * sizeof(EntryType))), avx_cast<SmallV>(_mm_alignr_epi8(vHi, vLo, 1 * sizeof(EntryType))));
-        case  6: return concat(avx_cast<SmallV>(_mm_alignr_epi8(vLo, vHi, 2 * sizeof(EntryType))), avx_cast<SmallV>(_mm_alignr_epi8(vHi, vLo, 2 * sizeof(EntryType))));
-        case  7: return concat(avx_cast<SmallV>(_mm_alignr_epi8(vLo, vHi, 3 * sizeof(EntryType))), avx_cast<SmallV>(_mm_alignr_epi8(vHi, vLo, 3 * sizeof(EntryType))));
+        case  5: return concat(avx_cast<SmallV>(_mm_alignr_epi8(vLo, vHi, 1 * EntryTypeSizeof)), avx_cast<SmallV>(_mm_alignr_epi8(vHi, vLo, 1 * EntryTypeSizeof)));
+        case  6: return concat(avx_cast<SmallV>(_mm_alignr_epi8(vLo, vHi, 2 * EntryTypeSizeof)), avx_cast<SmallV>(_mm_alignr_epi8(vHi, vLo, 2 * EntryTypeSizeof)));
+        case  7: return concat(avx_cast<SmallV>(_mm_alignr_epi8(vLo, vHi, 3 * EntryTypeSizeof)), avx_cast<SmallV>(_mm_alignr_epi8(vHi, vLo, 3 * EntryTypeSizeof)));
         }
         return avx_cast<VectorType>(_mm256_setzero_ps());
     }
 };
 template<typename VectorType, typename EntryType> struct VectorRotate<16, 8, VectorType, EntryType>
 {
+    enum {
+        EntryTypeSizeof = sizeof(EntryType)
+    };
     static Vc_INTRINSIC VectorType rotated(VC_ALIGNED_PARAMETER(VectorType) v, int amount)
     {
         switch (static_cast<unsigned int>(amount) % 8) {
         case  0: return v;
-        case  1: return avx_cast<VectorType>(_mm_alignr_epi8(v, v, 1 * sizeof(EntryType)));
-        case  2: return avx_cast<VectorType>(_mm_alignr_epi8(v, v, 2 * sizeof(EntryType)));
-        case  3: return avx_cast<VectorType>(_mm_alignr_epi8(v, v, 3 * sizeof(EntryType)));
-        case  4: return avx_cast<VectorType>(_mm_alignr_epi8(v, v, 4 * sizeof(EntryType)));
-        case  5: return avx_cast<VectorType>(_mm_alignr_epi8(v, v, 5 * sizeof(EntryType)));
-        case  6: return avx_cast<VectorType>(_mm_alignr_epi8(v, v, 6 * sizeof(EntryType)));
-        case  7: return avx_cast<VectorType>(_mm_alignr_epi8(v, v, 7 * sizeof(EntryType)));
+        case  1: return avx_cast<VectorType>(_mm_alignr_epi8(v, v, 1 * EntryTypeSizeof));
+        case  2: return avx_cast<VectorType>(_mm_alignr_epi8(v, v, 2 * EntryTypeSizeof));
+        case  3: return avx_cast<VectorType>(_mm_alignr_epi8(v, v, 3 * EntryTypeSizeof));
+        case  4: return avx_cast<VectorType>(_mm_alignr_epi8(v, v, 4 * EntryTypeSizeof));
+        case  5: return avx_cast<VectorType>(_mm_alignr_epi8(v, v, 5 * EntryTypeSizeof));
+        case  6: return avx_cast<VectorType>(_mm_alignr_epi8(v, v, 6 * EntryTypeSizeof));
+        case  7: return avx_cast<VectorType>(_mm_alignr_epi8(v, v, 7 * EntryTypeSizeof));
         }
         return _mm_setzero_si128();
     }
index 2403bec..9529807 100644 (file)
@@ -28,6 +28,15 @@ namespace Vc
 namespace Common
 {
 
+namespace Internal
+{
+template<typename A, typename B> struct CopyConst { typedef B Type; };
+template<typename A, typename B> struct CopyConst<const A, B> { typedef const B Type; };
+
+template<typename S, typename X, typename R> struct EnableInterleaves { typedef R Type; };
+template<typename S, typename X, typename R> struct EnableInterleaves<const S, X, R>;
+}  // namespace Internal
+
 /**
  * \internal
  */
@@ -73,8 +82,8 @@ template<size_t StructSize, typename V> struct InterleavedMemoryReadAccess : pub
     typedef typename Base::Ta Ta;
     typedef typename Base::I I;
 
-    Vc_ALWAYS_INLINE InterleavedMemoryReadAccess(Ta *data, typename I::AsArg indexes)
-        : Base(indexes * I(StructSize), data)
+    Vc_ALWAYS_INLINE InterleavedMemoryReadAccess(const Ta *data, typename I::AsArg indexes)
+        : Base(indexes * I(StructSize), const_cast<Ta *>(data)) // this needs to be refactored to properly keep the constness
     {
     }
 };
@@ -151,7 +160,7 @@ template<typename S, typename V> class InterleavedMemoryWrapper
     typedef typename I::AsArg IndexType;
     typedef InterleavedMemoryAccess<sizeof(S) / sizeof(T), V> Access;
     typedef InterleavedMemoryReadAccess<sizeof(S) / sizeof(T), V> ReadAccess;
-    typedef T Ta Vc_MAY_ALIAS;
+    typedef typename Internal::CopyConst<S, T>::Type Ta Vc_MAY_ALIAS;
     Ta *const m_data;
 
     VC_STATIC_ASSERT((sizeof(S) / sizeof(T)) * sizeof(T) == sizeof(S), InterleavedMemoryAccess_does_not_support_packed_structs);
@@ -219,19 +228,29 @@ Result in (x, y, z): ({x5 x0 x1 x7}, {y5 y0 y1 y7}, {z5 z0 z1 z7})
      * \warning If \p indexes contains non-unique entries on scatter, the result is undefined. If
      * \c NDEBUG is not defined the implementation will assert that the \p indexes entries are unique.
      */
+#ifdef DOXYGEN
     Vc_ALWAYS_INLINE Access operator[](IndexType indexes)
+#else
+    // need to SFINAE disable this for objects that wrap constant data
+    template <typename U>
+    Vc_ALWAYS_INLINE typename Internal::EnableInterleaves<S, U, Access>::Type operator[](
+        VC_ALIGNED_PARAMETER(U) indexes)
+#endif
     {
         return Access(m_data, indexes);
     }
 
     /// const overload (gathers only) of the above function
-    Vc_ALWAYS_INLINE ReadAccess operator[](IndexType indexes) const
+    Vc_ALWAYS_INLINE ReadAccess operator[](VC_ALIGNED_PARAMETER(IndexType) indexes) const
     {
         return ReadAccess(m_data, indexes);
     }
 
     /// alias of the above function
-    Vc_ALWAYS_INLINE ReadAccess gather(IndexType indexes) const { return operator[](indexes); }
+    Vc_ALWAYS_INLINE ReadAccess gather(VC_ALIGNED_PARAMETER(IndexType) indexes) const
+    {
+        return operator[](indexes);
+    }
 
     //Vc_ALWAYS_INLINE Access scatter(I indexes, VArg v0, VArg v1);
 };
index 642081d..4f9caf3 100644 (file)
@@ -252,18 +252,12 @@ struct LogImpl
 };
 
 template<typename T> static Vc_ALWAYS_INLINE Vc_CONST Vector<T> log(VC_ALIGNED_PARAMETER(Vector<T>) x) {
-    typedef typename Vector<T>::Mask M;
-    typedef Const<T> C;
     return LogImpl<BaseE>::calc(x);
 }
 template<typename T> static Vc_ALWAYS_INLINE Vc_CONST Vector<T> log10(VC_ALIGNED_PARAMETER(Vector<T>) x) {
-    typedef typename Vector<T>::Mask M;
-    typedef Const<T> C;
     return LogImpl<Base10>::calc(x);
 }
 template<typename T> static Vc_ALWAYS_INLINE Vc_CONST Vector<T> log2(VC_ALIGNED_PARAMETER(Vector<T>) x) {
-    typedef typename Vector<T>::Mask M;
-    typedef Const<T> C;
     return LogImpl<Base2>::calc(x);
 }
 } // namespace Common
index e2bd339..fbdbdb8 100644 (file)
 
 #include <Vc/global.h>
 
-#if VC_GCC && !__OPTIMIZE__
+#if defined(VC_GCC) && !defined(__OPTIMIZE__)
+#  if VC_GCC >= 0x40500
+#    pragma GCC diagnostic push
+#    define Vc_POP_GCC_DIAGNOSTIC__ 1
+#  endif
 // GCC uses lots of old-style-casts in macros that disguise as intrinsics
-#pragma GCC diagnostic push
-#pragma GCC diagnostic ignored "-Wold-style-cast"
+#  pragma GCC diagnostic ignored "-Wold-style-cast"
 #endif
 
 #ifdef VC_MSVC
 # define ALIGNED_TYPEDEF(n, _type_, _newType_) typedef _type_ _newType_ ALIGN(n)
 #endif
 
-#define FREE_STORE_OPERATORS_ALIGNED(alignment) \
-        inline void *operator new(size_t size) { return _mm_malloc(size, alignment); } \
-        inline void *operator new(size_t, void *p) { return p; } \
-        inline void *operator new[](size_t size) { return _mm_malloc(size, alignment); } \
-        inline void operator delete(void *ptr, size_t) { _mm_free(ptr); } \
-        inline void operator delete[](void *ptr, size_t) { _mm_free(ptr); }
-
 #ifdef VC_CXX11
 #define Vc_ALIGNOF(_TYPE_) alignof(_TYPE_)
 #else
 # define _VC_NOEXCEPT throw()
 #endif
 
+#define FREE_STORE_OPERATORS_ALIGNED(alignment) \
+        Vc_ALWAYS_INLINE void *operator new(size_t size) { return _mm_malloc(size, alignment); } \
+        Vc_ALWAYS_INLINE void *operator new(size_t, void *p) { return p; } \
+        Vc_ALWAYS_INLINE void *operator new[](size_t size) { return _mm_malloc(size, alignment); } \
+        Vc_ALWAYS_INLINE void *operator new[](size_t , void *p) { return p; } \
+        Vc_ALWAYS_INLINE void operator delete(void *ptr, size_t) { _mm_free(ptr); } \
+        Vc_ALWAYS_INLINE void operator delete(void *, void *) {} \
+        Vc_ALWAYS_INLINE void operator delete[](void *ptr, size_t) { _mm_free(ptr); } \
+        Vc_ALWAYS_INLINE void operator delete[](void *, void *) {}
 
 #ifdef VC_GCC
 # define VC_WARN_INLINE
@@ -241,35 +246,35 @@ namespace Vc {
 #define VC_STATIC_ASSERT(cond, msg) VC_STATIC_ASSERT_NC(cond, msg)
 #endif // C++11/98
 
-    template<int e, int center> struct exponentToMultiplier { enum {
+    template<int e, int center> struct exponentToMultiplier { enum Values__ {
         X = exponentToMultiplier<e - 1, center>::X * ((e - center < 31) ? 2 : 1),
         Value = (X == 0 ? 1 : X)
     }; };
-    template<int center> struct exponentToMultiplier<center,center> { enum { X = 1, Value = X }; };
-    template<int center> struct exponentToMultiplier<   -1, center> { enum { X = 0, Value = 1 }; };
-    template<int center> struct exponentToMultiplier< -128, center> { enum { X = 0, Value = 1 }; };
-    template<int center> struct exponentToMultiplier< -256, center> { enum { X = 0, Value = 1 }; };
-    template<int center> struct exponentToMultiplier< -384, center> { enum { X = 0, Value = 1 }; };
-    template<int center> struct exponentToMultiplier< -512, center> { enum { X = 0, Value = 1 }; };
-    template<int center> struct exponentToMultiplier< -640, center> { enum { X = 0, Value = 1 }; };
-    template<int center> struct exponentToMultiplier< -768, center> { enum { X = 0, Value = 1 }; };
-    template<int center> struct exponentToMultiplier< -896, center> { enum { X = 0, Value = 1 }; };
-    template<int center> struct exponentToMultiplier<-1024, center> { enum { X = 0, Value = 1 }; };
-
-    template<int e, int center> struct exponentToDivisor { enum {
+    template<int center> struct exponentToMultiplier<center,center> { enum Values__ { X = 1, Value = X }; };
+    template<int center> struct exponentToMultiplier<   -1, center> { enum Values__ { X = 0, Value = 1 }; };
+    template<int center> struct exponentToMultiplier< -128, center> { enum Values__ { X = 0, Value = 1 }; };
+    template<int center> struct exponentToMultiplier< -256, center> { enum Values__ { X = 0, Value = 1 }; };
+    template<int center> struct exponentToMultiplier< -384, center> { enum Values__ { X = 0, Value = 1 }; };
+    template<int center> struct exponentToMultiplier< -512, center> { enum Values__ { X = 0, Value = 1 }; };
+    template<int center> struct exponentToMultiplier< -640, center> { enum Values__ { X = 0, Value = 1 }; };
+    template<int center> struct exponentToMultiplier< -768, center> { enum Values__ { X = 0, Value = 1 }; };
+    template<int center> struct exponentToMultiplier< -896, center> { enum Values__ { X = 0, Value = 1 }; };
+    template<int center> struct exponentToMultiplier<-1024, center> { enum Values__ { X = 0, Value = 1 }; };
+
+    template<int e, int center> struct exponentToDivisor { enum Values__ {
         X = exponentToDivisor<e + 1, center>::X * ((center - e < 31) ? 2 : 1),
         Value = (X == 0 ? 1 : X)
     }; };
-    template<int center> struct exponentToDivisor<center, center> { enum { X = 1, Value = X }; };
-    template<int center> struct exponentToDivisor<     1, center> { enum { X = 0, Value = 1 }; };
-    template<int center> struct exponentToDivisor<   128, center> { enum { X = 0, Value = 1 }; };
-    template<int center> struct exponentToDivisor<   256, center> { enum { X = 0, Value = 1 }; };
-    template<int center> struct exponentToDivisor<   384, center> { enum { X = 0, Value = 1 }; };
-    template<int center> struct exponentToDivisor<   512, center> { enum { X = 0, Value = 1 }; };
-    template<int center> struct exponentToDivisor<   640, center> { enum { X = 0, Value = 1 }; };
-    template<int center> struct exponentToDivisor<   768, center> { enum { X = 0, Value = 1 }; };
-    template<int center> struct exponentToDivisor<   896, center> { enum { X = 0, Value = 1 }; };
-    template<int center> struct exponentToDivisor<  1024, center> { enum { X = 0, Value = 1 }; };
+    template<int center> struct exponentToDivisor<center, center> { enum Values__ { X = 1, Value = X }; };
+    template<int center> struct exponentToDivisor<     1, center> { enum Values__ { X = 0, Value = 1 }; };
+    template<int center> struct exponentToDivisor<   128, center> { enum Values__ { X = 0, Value = 1 }; };
+    template<int center> struct exponentToDivisor<   256, center> { enum Values__ { X = 0, Value = 1 }; };
+    template<int center> struct exponentToDivisor<   384, center> { enum Values__ { X = 0, Value = 1 }; };
+    template<int center> struct exponentToDivisor<   512, center> { enum Values__ { X = 0, Value = 1 }; };
+    template<int center> struct exponentToDivisor<   640, center> { enum Values__ { X = 0, Value = 1 }; };
+    template<int center> struct exponentToDivisor<   768, center> { enum Values__ { X = 0, Value = 1 }; };
+    template<int center> struct exponentToDivisor<   896, center> { enum Values__ { X = 0, Value = 1 }; };
+    template<int center> struct exponentToDivisor<  1024, center> { enum Values__ { X = 0, Value = 1 }; };
 #endif // VC_COMMON_MACROS_H_ONCE
 
 #define _CAT_IMPL(a, b) a##b
index 9f61796..0d04a10 100644 (file)
@@ -180,9 +180,15 @@ template<typename V, size_t Size1, size_t Size2> class Memory : public VectorAli
             template<typename Parent, typename RM>
             Vc_ALWAYS_INLINE Memory &operator=(const MemoryBase<V, Parent, 2, RM> &rhs) {
                 assert(vectorsCount() == rhs.vectorsCount());
-                std::memcpy(m_mem, rhs.m_mem, vectorsCount() * sizeof(V));
+                Internal::copyVectors(*this, rhs);
                 return *this;
             }
+
+            Vc_ALWAYS_INLINE Memory &operator=(const Memory &rhs) {
+                Internal::copyVectors(*this, rhs);
+                return *this;
+            }
+
             /**
              * Initialize all data with the given vector.
              *
@@ -325,13 +331,37 @@ template<typename V, size_t Size1, size_t Size2> class Memory : public VectorAli
              */
             _VC_CONSTEXPR size_t vectorsCount() const { return VectorsCount; }
 
-            template<typename Parent, typename RM>
-            Vc_ALWAYS_INLINE Memory<V> &operator=(const MemoryBase<V, Parent, 1, RM> &rhs) {
+#ifdef VC_CXX11
+            Vc_ALWAYS_INLINE Memory() = default;
+#else
+            Vc_ALWAYS_INLINE Memory() {}
+#endif
+
+            inline Memory(const Memory &rhs)
+            {
+                Internal::copyVectors(*this, rhs);
+            }
+
+            template <size_t S> inline Memory(const Memory<V, S> &rhs)
+            {
+                assert(vectorsCount() == rhs.vectorsCount());
+                Internal::copyVectors(*this, rhs);
+            }
+
+            inline Memory &operator=(const Memory &rhs)
+            {
+                Internal::copyVectors(*this, rhs);
+                return *this;
+            }
+
+            template <size_t S> inline Memory &operator=(const Memory<V, S> &rhs)
+            {
                 assert(vectorsCount() == rhs.vectorsCount());
-                std::memcpy(m_mem, rhs.m_mem, entriesCount() * sizeof(EntryType));
+                Internal::copyVectors(*this, rhs);
                 return *this;
             }
-            Vc_ALWAYS_INLINE Memory<V> &operator=(const EntryType *rhs) {
+
+            Vc_ALWAYS_INLINE Memory &operator=(const EntryType *rhs) {
                 std::memcpy(m_mem, rhs, entriesCount() * sizeof(EntryType));
                 return *this;
             }
@@ -438,7 +468,7 @@ template<typename V, size_t Size1, size_t Size2> class Memory : public VectorAli
             m_vectorsCount(rhs.vectorsCount()),
             m_mem(Vc::malloc<EntryType, Vc::AlignOnVector>(m_vectorsCount * V::Size))
         {
-            std::memcpy(m_mem, rhs.m_mem, entriesCount() * sizeof(EntryType));
+            Internal::copyVectors(*this, rhs);
         }
 
         /**
@@ -448,12 +478,12 @@ template<typename V, size_t Size1, size_t Size2> class Memory : public VectorAli
          *
          * \param rhs The Memory object to copy from.
          */
-        Vc_ALWAYS_INLINE Memory(const Memory<V, 0u> &rhs)
+        Vc_ALWAYS_INLINE Memory(const Memory &rhs)
             : m_entriesCount(rhs.entriesCount()),
             m_vectorsCount(rhs.vectorsCount()),
             m_mem(Vc::malloc<EntryType, Vc::AlignOnVector>(m_vectorsCount * V::Size))
         {
-            std::memcpy(m_mem, rhs.m_mem, entriesCount() * sizeof(EntryType));
+            Internal::copyVectors(*this, rhs);
         }
 
         /**
@@ -495,9 +525,15 @@ template<typename V, size_t Size1, size_t Size2> class Memory : public VectorAli
          * \note this function requires the vectorsCount() of both Memory objects to be equal.
          */
         template<typename Parent, typename RM>
-        Vc_ALWAYS_INLINE Memory<V> &operator=(const MemoryBase<V, Parent, 1, RM> &rhs) {
+        Vc_ALWAYS_INLINE Memory &operator=(const MemoryBase<V, Parent, 1, RM> &rhs) {
+            assert(vectorsCount() == rhs.vectorsCount());
+            Internal::copyVectors(*this, rhs);
+            return *this;
+        }
+
+        Vc_ALWAYS_INLINE Memory &operator=(const Memory &rhs) {
             assert(vectorsCount() == rhs.vectorsCount());
-            std::memcpy(m_mem, rhs.m_mem, entriesCount() * sizeof(EntryType));
+            Internal::copyVectors(*this, rhs);
             return *this;
         }
 
@@ -510,7 +546,7 @@ template<typename V, size_t Size1, size_t Size2> class Memory : public VectorAli
          *
          * \note this function requires that there are entriesCount() many values accessible from \p rhs.
          */
-        Vc_ALWAYS_INLINE Memory<V> &operator=(const EntryType *rhs) {
+        Vc_ALWAYS_INLINE Memory &operator=(const EntryType *rhs) {
             std::memcpy(m_mem, rhs, entriesCount() * sizeof(EntryType));
             return *this;
         }
index 5205067..0929d81 100644 (file)
@@ -566,6 +566,35 @@ template<typename V, typename Parent, int Dimension, typename RowMemory> class M
         }
 };
 
+namespace Internal
+{
+template <typename V,
+          typename ParentL,
+          typename ParentR,
+          int Dimension,
+          typename RowMemoryL,
+          typename RowMemoryR>
+inline void copyVectors(MemoryBase<V, ParentL, Dimension, RowMemoryL> &dst,
+                        const MemoryBase<V, ParentR, Dimension, RowMemoryR> &src)
+{
+    const size_t vectorsCount = dst.vectorsCount();
+    size_t i = 3;
+    for (; i < vectorsCount; i += 4) {
+        const V tmp3 = src.vector(i - 3);
+        const V tmp2 = src.vector(i - 2);
+        const V tmp1 = src.vector(i - 1);
+        const V tmp0 = src.vector(i - 0);
+        dst.vector(i - 3) = tmp3;
+        dst.vector(i - 2) = tmp2;
+        dst.vector(i - 1) = tmp1;
+        dst.vector(i - 0) = tmp0;
+    }
+    for (i -= 3; i < vectorsCount; ++i) {
+        dst.vector(i) = src.vector(i);
+    }
+}
+} // namespace Internal
+
 } // namespace Vc
 } // namespace AliRoot
 
index e7c279c..4f62379 100644 (file)
 #undef VC_ALIGNED_PARAMETER
 #undef VC_OFFSETOF
 
-#if VC_GCC && !__OPTIMIZE__
+#ifdef Vc_POP_GCC_DIAGNOSTIC__
 #pragma GCC diagnostic pop
+#undef Vc_POP_GCC_DIAGNOSTIC__
 #endif
 
 #endif // VC_COMMON_UNDOMACROS_H
index 87eec9e..5636b8b 100644 (file)
@@ -62,6 +62,8 @@
 //     ::max_align_t was introduced with GCC 4.7. std::max_align_t took a bit longer.
 #      define VC_HAVE_MAX_ALIGN_T 1
 #    endif
+#  elif defined(VC_ICC)
+#      define VC_HAVE_MAX_ALIGN_T 1
 #  elif !defined(VC_CLANG)
 //   Clang doesn't provide max_align_t at all
 #    define VC_HAVE_STD_MAX_ALIGN_T 1
@@ -345,13 +347,13 @@ enum MallocAlignment {
 };
 
 #if __cplusplus >= 201103 /*C++11*/
-#define Vc_CONSTEXPR static constexpr
+#define Vc_CONSTEXPR constexpr
 #elif defined(__GNUC__)
-#define Vc_CONSTEXPR static inline __attribute__((__always_inline__, __const__))
+#define Vc_CONSTEXPR inline __attribute__((__always_inline__, __const__))
 #elif defined(VC_MSVC)
-#define Vc_CONSTEXPR static inline __forceinline
+#define Vc_CONSTEXPR inline __forceinline
 #else
-#define Vc_CONSTEXPR static inline
+#define Vc_CONSTEXPR inline
 #endif
 Vc_CONSTEXPR StreamingAndUnalignedFlag operator|(UnalignedFlag, StreamingAndAlignedFlag) { return StreamingAndUnaligned; }
 Vc_CONSTEXPR StreamingAndUnalignedFlag operator|(StreamingAndAlignedFlag, UnalignedFlag) { return StreamingAndUnaligned; }
@@ -477,10 +479,10 @@ namespace Internal {
     typedef HelperImpl<VC_IMPL> Helper;
 
     template<typename A> struct FlagObject;
-    template<> struct FlagObject<AlignedFlag> { Vc_CONSTEXPR AlignedFlag the() { return Aligned; } };
-    template<> struct FlagObject<UnalignedFlag> { Vc_CONSTEXPR UnalignedFlag the() { return Unaligned; } };
-    template<> struct FlagObject<StreamingAndAlignedFlag> { Vc_CONSTEXPR StreamingAndAlignedFlag the() { return Streaming; } };
-    template<> struct FlagObject<StreamingAndUnalignedFlag> { Vc_CONSTEXPR StreamingAndUnalignedFlag the() { return StreamingAndUnaligned; } };
+    template<> struct FlagObject<AlignedFlag> { static Vc_CONSTEXPR AlignedFlag the() { return Aligned; } };
+    template<> struct FlagObject<UnalignedFlag> { static Vc_CONSTEXPR UnalignedFlag the() { return Unaligned; } };
+    template<> struct FlagObject<StreamingAndAlignedFlag> { static Vc_CONSTEXPR StreamingAndAlignedFlag the() { return Streaming; } };
+    template<> struct FlagObject<StreamingAndUnalignedFlag> { static Vc_CONSTEXPR StreamingAndUnalignedFlag the() { return StreamingAndUnaligned; } };
 } // namespace Internal
 
 namespace Warnings
index 9e99cd1..7b305d6 100644 (file)
@@ -23,4 +23,6 @@
 # define VECTOR_NAMESPACE Vc::AVX
 #elif defined(VC_IMPL_SSE)
 # define VECTOR_NAMESPACE Vc::SSE
+#else
+# error "No known Vc implementation was selected. This should not happen. The logic in Vc/global.h failed."
 #endif
index 570aca6..afe9774 100644 (file)
@@ -43,7 +43,7 @@ namespace SSE
     template<> struct StaticCastHelper<int         , int         > { static Vc_ALWAYS_INLINE _M128I cast(const _M128I &v) { return v; } };
     template<> struct StaticCastHelper<unsigned int, int         > { static Vc_ALWAYS_INLINE _M128I cast(const _M128I &v) { return v; } };
     template<> struct StaticCastHelper<float       , unsigned int> { static Vc_ALWAYS_INLINE _M128I cast(const _M128  &v) {
-        return _mm_castps_si128(_mm_blendv_ps(
+        return _mm_castps_si128(mm_blendv_ps(
                 _mm_castsi128_ps(_mm_cvttps_epi32(v)),
                 _mm_castsi128_ps(_mm_add_epi32(_mm_cvttps_epi32(_mm_sub_ps(v, _mm_set1_ps(1u << 31))), _mm_set1_epi32(1 << 31))),
                 _mm_cmpge_ps(v, _mm_set1_ps(1u << 31))
@@ -57,7 +57,7 @@ namespace SSE
     template<> struct StaticCastHelper<double      , float       > { static Vc_ALWAYS_INLINE _M128  cast(const _M128D &v) { return _mm_cvtpd_ps(v); } };
     template<> struct StaticCastHelper<int         , float       > { static Vc_ALWAYS_INLINE _M128  cast(const _M128I &v) { return _mm_cvtepi32_ps(v); } };
     template<> struct StaticCastHelper<unsigned int, float       > { static Vc_ALWAYS_INLINE _M128  cast(const _M128I &v) {
-        return _mm_blendv_ps(
+        return mm_blendv_ps(
                 _mm_cvtepi32_ps(v),
                 _mm_add_ps(_mm_cvtepi32_ps(_mm_sub_epi32(v, _mm_set1_epi32(1 << 31))), _mm_set1_ps(1u << 31)),
                 _mm_castsi128_ps(_mm_cmplt_epi32(v, _mm_setzero_si128()))
index 3fb6402..cd9b841 100644 (file)
@@ -37,10 +37,6 @@ extern "C" {
 
 #include "../common/fix_clang_emmintrin.h"
 
-#if defined(__GNUC__) && !defined(VC_IMPL_SSE2)
-#error "SSE Vector class needs at least SSE2"
-#endif
-
 #include "const_data.h"
 #include <cstdlib>
 #include "macros.h"
@@ -127,14 +123,16 @@ namespace SSE
 extern "C" {
 #include <pmmintrin.h>
 }
-#elif defined _PMMINTRIN_H_INCLUDED
-#error "SSE3 was disabled but something includes <pmmintrin.h>. Please fix your code."
 #endif
 // SSSE3
 #ifdef VC_IMPL_SSSE3
 extern "C" {
 #include <tmmintrin.h>
 }
+#define mm_abs_epi8  _mm_abs_epi8
+#define mm_abs_epi16 _mm_abs_epi16
+#define mm_abs_epi32 _mm_abs_epi32
+#define mm_alignr_epi8 _mm_alignr_epi8
 namespace AliRoot {
 namespace Vc
 {
@@ -154,15 +152,13 @@ namespace SSE
 } // namespace SSE
 } // namespace Vc
 } // namespace AliRoot
-#elif defined _TMMINTRIN_H_INCLUDED
-#error "SSSE3 was disabled but something includes <tmmintrin.h>. Please fix your code."
 #else
 namespace AliRoot {
 namespace Vc
 {
 namespace SSE
 {
-    static Vc_INTRINSIC __m128i Vc_CONST _mm_abs_epi8 (__m128i a) {
+    static Vc_INTRINSIC __m128i Vc_CONST mm_abs_epi8 (__m128i a) {
         __m128i negative = _mm_cmplt_epi8 (a, _mm_setzero_si128());
         return _mm_add_epi8 (_mm_xor_si128(a, negative), _mm_and_si128(negative,  _mm_setone_epi8()));
     }
@@ -176,18 +172,18 @@ namespace SSE
     //   a xor -1 -> -a - 1
     //   -1 >> 31 -> 1
     //   -a - 1 + 1 -> -a
-    static Vc_INTRINSIC __m128i Vc_CONST _mm_abs_epi16(__m128i a) {
+    static Vc_INTRINSIC __m128i Vc_CONST mm_abs_epi16(__m128i a) {
         __m128i negative = _mm_cmplt_epi16(a, _mm_setzero_si128());
         return _mm_add_epi16(_mm_xor_si128(a, negative), _mm_srli_epi16(negative, 15));
     }
-    static Vc_INTRINSIC __m128i Vc_CONST _mm_abs_epi32(__m128i a) {
+    static Vc_INTRINSIC __m128i Vc_CONST mm_abs_epi32(__m128i a) {
         __m128i negative = _mm_cmplt_epi32(a, _mm_setzero_si128());
         return _mm_add_epi32(_mm_xor_si128(a, negative), _mm_srli_epi32(negative, 31));
     }
     static Vc_INTRINSIC __m128i Vc_CONST set1_epi8(int a) {
         return _mm_set1_epi8(a);
     }
-    static Vc_INTRINSIC __m128i Vc_CONST _mm_alignr_epi8(__m128i a, __m128i b, const int s) {
+    static Vc_INTRINSIC __m128i Vc_CONST mm_alignr_epi8(__m128i a, __m128i b, const int s) {
         switch (s) {
             case  0: return b;
             case  1: return _mm_or_si128(_mm_slli_si128(a, 15), _mm_srli_si128(b,  1));
@@ -236,28 +232,60 @@ namespace SSE
 extern "C" {
 #include <smmintrin.h>
 }
+namespace AliRoot {
+namespace Vc
+{
+namespace SSE
+{
+#define mm_blendv_pd _mm_blendv_pd
+#define mm_blendv_ps _mm_blendv_ps
+#define mm_blendv_epi8 _mm_blendv_epi8
+#define mm_blend_epi16 _mm_blend_epi16
+#define mm_blend_ps _mm_blend_ps
+#define mm_blend_pd _mm_blend_pd
+
+#define mm_min_epi32 _mm_min_epi32
+#define mm_max_epi32 _mm_max_epi32
+#define mm_min_epu32 _mm_min_epu32
+#define mm_max_epu32 _mm_max_epu32
+//#define mm_min_epi16 _mm_min_epi16
+//#define mm_max_epi16 _mm_max_epi16
+#define mm_min_epu16 _mm_min_epu16
+#define mm_max_epu16 _mm_max_epu16
+#define mm_min_epi8  _mm_min_epi8
+#define mm_max_epi8  _mm_max_epi8
+
+#define mm_cvtepu16_epi32 _mm_cvtepu16_epi32
+#define mm_cvtepu8_epi16 _mm_cvtepu8_epi16
+#define mm_cvtepi8_epi16 _mm_cvtepi8_epi16
+#define mm_cvtepu16_epi32 _mm_cvtepu16_epi32
+#define mm_cvtepi16_epi32 _mm_cvtepi16_epi32
+#define mm_cvtepu8_epi32 _mm_cvtepu8_epi32
+#define mm_cvtepi8_epi32 _mm_cvtepi8_epi32
+#define mm_stream_load_si128 _mm_stream_load_si128
+// TODO
+} // namespace SSE
+} // namespace Vc
+} // namespace AliRoot
 #else
-#ifdef _SMMINTRIN_H_INCLUDED
-#error "SSE4.1 was disabled but something includes <smmintrin.h>. Please fix your code."
-#endif
 namespace AliRoot {
 namespace Vc
 {
 namespace SSE
 {
-    static Vc_INTRINSIC __m128d _mm_blendv_pd(__m128d a, __m128d b, __m128d c) {
+    static Vc_INTRINSIC __m128d mm_blendv_pd(__m128d a, __m128d b, __m128d c) {
         return _mm_or_pd(_mm_andnot_pd(c, a), _mm_and_pd(c, b));
     }
-    static Vc_INTRINSIC __m128  _mm_blendv_ps(__m128  a, __m128  b, __m128  c) {
+    static Vc_INTRINSIC __m128  mm_blendv_ps(__m128  a, __m128  b, __m128  c) {
         return _mm_or_ps(_mm_andnot_ps(c, a), _mm_and_ps(c, b));
     }
-    static Vc_INTRINSIC __m128i _mm_blendv_epi8(__m128i a, __m128i b, __m128i c) {
+    static Vc_INTRINSIC __m128i mm_blendv_epi8(__m128i a, __m128i b, __m128i c) {
         return _mm_or_si128(_mm_andnot_si128(c, a), _mm_and_si128(c, b));
     }
 
     // only use the following blend functions with immediates as mask and, of course, compiling
     // with optimization
-    static Vc_INTRINSIC __m128d _mm_blend_pd(__m128d a, __m128d b, const int mask) {
+    static Vc_INTRINSIC __m128d mm_blend_pd(__m128d a, __m128d b, const int mask) {
         switch (mask) {
         case 0x0:
             return a;
@@ -272,7 +300,7 @@ namespace SSE
             return a; // should never be reached, but MSVC needs it else it warns about 'not all control paths return a value'
         }
     }
-    static Vc_INTRINSIC __m128  _mm_blend_ps(__m128  a, __m128  b, const int mask) {
+    static Vc_INTRINSIC __m128  mm_blend_ps(__m128  a, __m128  b, const int mask) {
         __m128i c;
         switch (mask) {
         case 0x0:
@@ -329,7 +357,7 @@ namespace SSE
         __m128 _c = _mm_castsi128_ps(c);
         return _mm_or_ps(_mm_andnot_ps(_c, a), _mm_and_ps(_c, b));
     }
-    static Vc_INTRINSIC __m128i _mm_blend_epi16(__m128i a, __m128i b, const int mask) {
+    static Vc_INTRINSIC __m128i mm_blend_epi16(__m128i a, __m128i b, const int mask) {
         __m128i c;
         switch (mask) {
         case 0x00:
@@ -389,57 +417,57 @@ namespace SSE
         return _mm_or_si128(_mm_andnot_si128(c, a), _mm_and_si128(c, b));
     }
 
-    static Vc_INTRINSIC __m128i Vc_CONST _mm_max_epi8 (__m128i a, __m128i b) {
-        return _mm_blendv_epi8(b, a, _mm_cmpgt_epi8 (a, b));
+    static Vc_INTRINSIC __m128i Vc_CONST mm_max_epi8 (__m128i a, __m128i b) {
+        return mm_blendv_epi8(b, a, _mm_cmpgt_epi8 (a, b));
     }
-    static Vc_INTRINSIC __m128i Vc_CONST _mm_max_epi32(__m128i a, __m128i b) {
-        return _mm_blendv_epi8(b, a, _mm_cmpgt_epi32(a, b));
+    static Vc_INTRINSIC __m128i Vc_CONST mm_max_epi32(__m128i a, __m128i b) {
+        return mm_blendv_epi8(b, a, _mm_cmpgt_epi32(a, b));
     }
-//X         static Vc_INTRINSIC __m128i Vc_CONST _mm_max_epu8 (__m128i a, __m128i b) {
-//X             return _mm_blendv_epi8(b, a, _mm_cmpgt_epu8 (a, b));
+//X         static Vc_INTRINSIC __m128i Vc_CONST mm_max_epu8 (__m128i a, __m128i b) {
+//X             return mm_blendv_epi8(b, a, _mm_cmpgt_epu8 (a, b));
 //X         }
-    static Vc_INTRINSIC __m128i Vc_CONST _mm_max_epu16(__m128i a, __m128i b) {
-        return _mm_blendv_epi8(b, a, _mm_cmpgt_epu16(a, b));
+    static Vc_INTRINSIC __m128i Vc_CONST mm_max_epu16(__m128i a, __m128i b) {
+        return mm_blendv_epi8(b, a, _mm_cmpgt_epu16(a, b));
     }
-    static Vc_INTRINSIC __m128i Vc_CONST _mm_max_epu32(__m128i a, __m128i b) {
-        return _mm_blendv_epi8(b, a, _mm_cmpgt_epu32(a, b));
+    static Vc_INTRINSIC __m128i Vc_CONST mm_max_epu32(__m128i a, __m128i b) {
+        return mm_blendv_epi8(b, a, _mm_cmpgt_epu32(a, b));
     }
-//X         static Vc_INTRINSIC __m128i Vc_CONST _mm_min_epu8 (__m128i a, __m128i b) {
-//X             return _mm_blendv_epi8(a, b, _mm_cmpgt_epu8 (a, b));
+//X         static Vc_INTRINSIC __m128i Vc_CONST mm_min_epu8 (__m128i a, __m128i b) {
+//X             return mm_blendv_epi8(a, b, _mm_cmpgt_epu8 (a, b));
 //X         }
-    static Vc_INTRINSIC __m128i Vc_CONST _mm_min_epu16(__m128i a, __m128i b) {
-        return _mm_blendv_epi8(a, b, _mm_cmpgt_epu16(a, b));
+    static Vc_INTRINSIC __m128i Vc_CONST mm_min_epu16(__m128i a, __m128i b) {
+        return mm_blendv_epi8(a, b, _mm_cmpgt_epu16(a, b));
     }
-    static Vc_INTRINSIC __m128i Vc_CONST _mm_min_epu32(__m128i a, __m128i b) {
-        return _mm_blendv_epi8(a, b, _mm_cmpgt_epu32(a, b));
+    static Vc_INTRINSIC __m128i Vc_CONST mm_min_epu32(__m128i a, __m128i b) {
+        return mm_blendv_epi8(a, b, _mm_cmpgt_epu32(a, b));
     }
-    static Vc_INTRINSIC __m128i Vc_CONST _mm_min_epi8 (__m128i a, __m128i b) {
-        return _mm_blendv_epi8(a, b, _mm_cmpgt_epi8 (a, b));
+    static Vc_INTRINSIC __m128i Vc_CONST mm_min_epi8 (__m128i a, __m128i b) {
+        return mm_blendv_epi8(a, b, _mm_cmpgt_epi8 (a, b));
     }
-    static Vc_INTRINSIC __m128i Vc_CONST _mm_min_epi32(__m128i a, __m128i b) {
-        return _mm_blendv_epi8(a, b, _mm_cmpgt_epi32(a, b));
+    static Vc_INTRINSIC __m128i Vc_CONST mm_min_epi32(__m128i a, __m128i b) {
+        return mm_blendv_epi8(a, b, _mm_cmpgt_epi32(a, b));
     }
-    static Vc_INTRINSIC Vc_CONST __m128i _mm_cvtepu8_epi16(__m128i epu8) {
+    static Vc_INTRINSIC Vc_CONST __m128i mm_cvtepu8_epi16(__m128i epu8) {
         return _mm_unpacklo_epi8(epu8, _mm_setzero_si128());
     }
-    static Vc_INTRINSIC Vc_CONST __m128i _mm_cvtepi8_epi16(__m128i epi8) {
+    static Vc_INTRINSIC Vc_CONST __m128i mm_cvtepi8_epi16(__m128i epi8) {
         return _mm_unpacklo_epi8(epi8, _mm_cmplt_epi8(epi8, _mm_setzero_si128()));
     }
-    static Vc_INTRINSIC Vc_CONST __m128i _mm_cvtepu16_epi32(__m128i epu16) {
+    static Vc_INTRINSIC Vc_CONST __m128i mm_cvtepu16_epi32(__m128i epu16) {
         return _mm_unpacklo_epi16(epu16, _mm_setzero_si128());
     }
-    static Vc_INTRINSIC Vc_CONST __m128i _mm_cvtepi16_epi32(__m128i epu16) {
+    static Vc_INTRINSIC Vc_CONST __m128i mm_cvtepi16_epi32(__m128i epu16) {
         return _mm_unpacklo_epi16(epu16, _mm_cmplt_epi16(epu16, _mm_setzero_si128()));
     }
-    static Vc_INTRINSIC Vc_CONST __m128i _mm_cvtepu8_epi32(__m128i epu8) {
-        return _mm_cvtepu16_epi32(_mm_cvtepu8_epi16(epu8));
+    static Vc_INTRINSIC Vc_CONST __m128i mm_cvtepu8_epi32(__m128i epu8) {
+        return mm_cvtepu16_epi32(mm_cvtepu8_epi16(epu8));
     }
-    static Vc_INTRINSIC Vc_CONST __m128i _mm_cvtepi8_epi32(__m128i epi8) {
+    static Vc_INTRINSIC Vc_CONST __m128i mm_cvtepi8_epi32(__m128i epi8) {
         const __m128i neg = _mm_cmplt_epi8(epi8, _mm_setzero_si128());
         const __m128i epi16 = _mm_unpacklo_epi8(epi8, neg);
         return _mm_unpacklo_epi16(epi16, _mm_unpacklo_epi8(neg, neg));
     }
-    static Vc_INTRINSIC Vc_PURE __m128i _mm_stream_load_si128(__m128i *mem) {
+    static Vc_INTRINSIC Vc_PURE __m128i mm_stream_load_si128(__m128i *mem) {
         return _mm_load_si128(mem);
     }
 
@@ -457,8 +485,6 @@ namespace SSE
 extern "C" {
 #include <nmmintrin.h>
 }
-#elif defined _NMMINTRIN_H_INCLUDED
-#error "SSE4.2 was disabled but something includes <nmmintrin.h>. Please fix your code."
 #endif
 
 namespace AliRoot {
index f16c94c..41000f0 100644 (file)
@@ -44,7 +44,7 @@ Vc_ALWAYS_INLINE void HelperImpl<Vc::SSE2Impl>::prefetchFar(const void *addr)
 }
 Vc_ALWAYS_INLINE void HelperImpl<Vc::SSE2Impl>::prefetchForModify(const void *addr)
 {
-#ifdef __3dNOW__
+#if defined(__3dNOW__) && (!defined(VC_CLANG) || VC_CLANG >= 0x30200)
     _m_prefetchw(const_cast<void *>(addr));
 #else
     _mm_prefetch(static_cast<char *>(const_cast<void *>(addr)), _MM_HINT_T0);
index 37e74be..b0cdb0a 100644 (file)
@@ -46,14 +46,17 @@ namespace Vc
             return _mm_shuffle_pd(x, y, Dst0 + (Dst1 - Y0) * 2);
         }
 
+#if !defined(VC_IMPL_SSE4_1) && !defined(VC_IMPL_AVX)
+#define Vc_MAKE_INTRINSIC__(name__) Vc::SSE::_VC_CAT(m,m,_,name__)
+#else
+#define Vc_MAKE_INTRINSIC__(name__) _VC_CAT(_,mm,_,name__)
+#endif
+
         // blend<X0, Y1>([x0 x1], [y0, y1]) = [x0 y1]
         template<VecPos Dst0, VecPos Dst1> static Vc_ALWAYS_INLINE __m128d Vc_CONST blend(__m128d x, __m128d y) {
             VC_STATIC_ASSERT(Dst0 == X0 || Dst0 == Y0, Incorrect_Range);
             VC_STATIC_ASSERT(Dst1 == X1 || Dst1 == Y1, Incorrect_Range);
-#if !defined(VC_IMPL_SSE4_1) && !defined(VC_IMPL_AVX)
-            using Vc::SSE::_mm_blend_pd;
-#endif
-            return _mm_blend_pd(x, y, (Dst0 / Y0) + (Dst1 / Y0) * 2);
+            return Vc_MAKE_INTRINSIC__(blend_pd)(x, y, (Dst0 / Y0) + (Dst1 / Y0) * 2);
         }
 
         // blend<X0, Y1>([x0 x1], [y0, y1]) = [x0 y1]
@@ -62,10 +65,7 @@ namespace Vc
             VC_STATIC_ASSERT(Dst1 == X1 || Dst1 == Y1, Incorrect_Range);
             VC_STATIC_ASSERT(Dst2 == X2 || Dst2 == Y2, Incorrect_Range);
             VC_STATIC_ASSERT(Dst3 == X3 || Dst3 == Y3, Incorrect_Range);
-#if !defined(VC_IMPL_SSE4_1) && !defined(VC_IMPL_AVX)
-            using Vc::SSE::_mm_blend_ps;
-#endif
-            return _mm_blend_ps(x, y,
+            return Vc_MAKE_INTRINSIC__(blend_ps)(x, y,
                     (Dst0 / Y0) *  1 + (Dst1 / Y1) *  2 +
                     (Dst2 / Y2) *  4 + (Dst3 / Y3) *  8);
         }
@@ -80,10 +80,7 @@ namespace Vc
             VC_STATIC_ASSERT(Dst5 == X5 || Dst5 == Y5, Incorrect_Range);
             VC_STATIC_ASSERT(Dst6 == X6 || Dst6 == Y6, Incorrect_Range);
             VC_STATIC_ASSERT(Dst7 == X7 || Dst7 == Y7, Incorrect_Range);
-#if !defined(VC_IMPL_SSE4_1) && !defined(VC_IMPL_AVX)
-            using Vc::SSE::_mm_blend_epi16;
-#endif
-            return _mm_blend_epi16(x, y,
+            return Vc_MAKE_INTRINSIC__(blend_epi16)(x, y,
                     (Dst0 / Y0) *  1 + (Dst1 / Y1) *  2 +
                     (Dst2 / Y2) *  4 + (Dst3 / Y3) *  8 +
                     (Dst4 / Y4) * 16 + (Dst5 / Y5) * 32 +
index ba5415b..cd1d21f 100644 (file)
@@ -499,16 +499,16 @@ template<> Vc_ALWAYS_INLINE Vc_PURE Vector<float8> Vector<float8>::broadcast4(co
 
 template<typename T> class SwizzledVector : public Vector<T> {};
 
-static Vc_ALWAYS_INLINE Vc_PURE int_v    min(const int_v    &x, const int_v    &y) { return _mm_min_epi32(x.data(), y.data()); }
-static Vc_ALWAYS_INLINE Vc_PURE uint_v   min(const uint_v   &x, const uint_v   &y) { return _mm_min_epu32(x.data(), y.data()); }
+static Vc_ALWAYS_INLINE Vc_PURE int_v    min(const int_v    &x, const int_v    &y) { return mm_min_epi32(x.data(), y.data()); }
+static Vc_ALWAYS_INLINE Vc_PURE uint_v   min(const uint_v   &x, const uint_v   &y) { return mm_min_epu32(x.data(), y.data()); }
 static Vc_ALWAYS_INLINE Vc_PURE short_v  min(const short_v  &x, const short_v  &y) { return _mm_min_epi16(x.data(), y.data()); }
-static Vc_ALWAYS_INLINE Vc_PURE ushort_v min(const ushort_v &x, const ushort_v &y) { return _mm_min_epu16(x.data(), y.data()); }
+static Vc_ALWAYS_INLINE Vc_PURE ushort_v min(const ushort_v &x, const ushort_v &y) { return mm_min_epu16(x.data(), y.data()); }
 static Vc_ALWAYS_INLINE Vc_PURE float_v  min(const float_v  &x, const float_v  &y) { return _mm_min_ps(x.data(), y.data()); }
 static Vc_ALWAYS_INLINE Vc_PURE double_v min(const double_v &x, const double_v &y) { return _mm_min_pd(x.data(), y.data()); }
-static Vc_ALWAYS_INLINE Vc_PURE int_v    max(const int_v    &x, const int_v    &y) { return _mm_max_epi32(x.data(), y.data()); }
-static Vc_ALWAYS_INLINE Vc_PURE uint_v   max(const uint_v   &x, const uint_v   &y) { return _mm_max_epu32(x.data(), y.data()); }
+static Vc_ALWAYS_INLINE Vc_PURE int_v    max(const int_v    &x, const int_v    &y) { return mm_max_epi32(x.data(), y.data()); }
+static Vc_ALWAYS_INLINE Vc_PURE uint_v   max(const uint_v   &x, const uint_v   &y) { return mm_max_epu32(x.data(), y.data()); }
 static Vc_ALWAYS_INLINE Vc_PURE short_v  max(const short_v  &x, const short_v  &y) { return _mm_max_epi16(x.data(), y.data()); }
-static Vc_ALWAYS_INLINE Vc_PURE ushort_v max(const ushort_v &x, const ushort_v &y) { return _mm_max_epu16(x.data(), y.data()); }
+static Vc_ALWAYS_INLINE Vc_PURE ushort_v max(const ushort_v &x, const ushort_v &y) { return mm_max_epu16(x.data(), y.data()); }
 static Vc_ALWAYS_INLINE Vc_PURE float_v  max(const float_v  &x, const float_v  &y) { return _mm_max_ps(x.data(), y.data()); }
 static Vc_ALWAYS_INLINE Vc_PURE double_v max(const double_v &x, const double_v &y) { return _mm_max_pd(x.data(), y.data()); }
 
index e66f3bf..e18b3b0 100644 (file)
@@ -190,25 +190,25 @@ template<typename Flags> struct LoadHelper<int, unsigned int, Flags> {
 template<typename Flags> struct LoadHelper<int, unsigned short, Flags> {
     static Vc_ALWAYS_INLINE Vc_PURE __m128i load(const unsigned short *mem, Flags)
     {
-        return _mm_cvtepu16_epi32( _mm_loadl_epi64(reinterpret_cast<const __m128i *>(mem)));
+        return mm_cvtepu16_epi32( _mm_loadl_epi64(reinterpret_cast<const __m128i *>(mem)));
     }
 };
 template<typename Flags> struct LoadHelper<int, short, Flags> {
     static Vc_ALWAYS_INLINE Vc_PURE __m128i load(const short *mem, Flags)
     {
-        return _mm_cvtepi16_epi32(_mm_loadl_epi64(reinterpret_cast<const __m128i *>(mem)));
+        return mm_cvtepi16_epi32(_mm_loadl_epi64(reinterpret_cast<const __m128i *>(mem)));
     }
 };
 template<typename Flags> struct LoadHelper<int, unsigned char, Flags> {
     static Vc_ALWAYS_INLINE Vc_PURE __m128i load(const unsigned char *mem, Flags)
     {
-        return _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*reinterpret_cast<const int *>(mem)));
+        return mm_cvtepu8_epi32(_mm_cvtsi32_si128(*reinterpret_cast<const int *>(mem)));
     }
 };
 template<typename Flags> struct LoadHelper<int, signed char, Flags> {
     static Vc_ALWAYS_INLINE Vc_PURE __m128i load(const signed char *mem, Flags)
     {
-        return _mm_cvtepi8_epi32(_mm_cvtsi32_si128(*reinterpret_cast<const int *>(mem)));
+        return mm_cvtepi8_epi32(_mm_cvtsi32_si128(*reinterpret_cast<const int *>(mem)));
     }
 };
 
@@ -216,13 +216,13 @@ template<typename Flags> struct LoadHelper<int, signed char, Flags> {
 template<typename Flags> struct LoadHelper<unsigned int, unsigned short, Flags> {
     static Vc_ALWAYS_INLINE Vc_PURE __m128i load(const unsigned short *mem, Flags)
     {
-        return _mm_cvtepu16_epi32(_mm_loadl_epi64(reinterpret_cast<const __m128i *>(mem)));
+        return mm_cvtepu16_epi32(_mm_loadl_epi64(reinterpret_cast<const __m128i *>(mem)));
     }
 };
 template<typename Flags> struct LoadHelper<unsigned int, unsigned char, Flags> {
     static Vc_ALWAYS_INLINE Vc_PURE __m128i load(const unsigned char *mem, Flags)
     {
-        return _mm_cvtepu8_epi32(_mm_cvtsi32_si128(*reinterpret_cast<const int *>(mem)));
+        return mm_cvtepu8_epi32(_mm_cvtsi32_si128(*reinterpret_cast<const int *>(mem)));
     }
 };
 
@@ -236,13 +236,13 @@ template<typename Flags> struct LoadHelper<short, unsigned short, Flags> {
 template<typename Flags> struct LoadHelper<short, unsigned char, Flags> {
     static Vc_ALWAYS_INLINE Vc_PURE __m128i load(const unsigned char *mem, Flags)
     {
-        return _mm_cvtepu8_epi16(_mm_loadl_epi64(reinterpret_cast<const __m128i *>(mem)));
+        return mm_cvtepu8_epi16(_mm_loadl_epi64(reinterpret_cast<const __m128i *>(mem)));
     }
 };
 template<typename Flags> struct LoadHelper<short, signed char, Flags> {
     static Vc_ALWAYS_INLINE Vc_PURE __m128i load(const signed char *mem, Flags)
     {
-        return _mm_cvtepi8_epi16(_mm_loadl_epi64(reinterpret_cast<const __m128i *>(mem)));
+        return mm_cvtepi8_epi16(_mm_loadl_epi64(reinterpret_cast<const __m128i *>(mem)));
     }
 };
 
@@ -250,7 +250,7 @@ template<typename Flags> struct LoadHelper<short, signed char, Flags> {
 template<typename Flags> struct LoadHelper<unsigned short, unsigned char, Flags> {
     static Vc_ALWAYS_INLINE Vc_PURE __m128i load(const unsigned char *mem, Flags)
     {
-        return _mm_cvtepu8_epi16(_mm_loadl_epi64(reinterpret_cast<const __m128i *>(mem)));
+        return mm_cvtepu8_epi16(_mm_loadl_epi64(reinterpret_cast<const __m128i *>(mem)));
     }
 };
 
@@ -1389,79 +1389,91 @@ template<> Vc_ALWAYS_INLINE Vector<double> Vector<double>::Random()
 // shifted / rotated {{{1
 template<typename T> Vc_INTRINSIC Vc_PURE Vector<T> Vector<T>::shifted(int amount) const
 {
+    enum {
+        EntryTypeSizeof = sizeof(EntryType)
+    };
     switch (amount) {
     case  0: return *this;
-    case  1: return mm128_reinterpret_cast<VectorType>(_mm_srli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 1 * sizeof(EntryType)));
-    case  2: return mm128_reinterpret_cast<VectorType>(_mm_srli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 2 * sizeof(EntryType)));
-    case  3: return mm128_reinterpret_cast<VectorType>(_mm_srli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 3 * sizeof(EntryType)));
-    case  4: return mm128_reinterpret_cast<VectorType>(_mm_srli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 4 * sizeof(EntryType)));
-    case  5: return mm128_reinterpret_cast<VectorType>(_mm_srli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 5 * sizeof(EntryType)));
-    case  6: return mm128_reinterpret_cast<VectorType>(_mm_srli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 6 * sizeof(EntryType)));
-    case  7: return mm128_reinterpret_cast<VectorType>(_mm_srli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 7 * sizeof(EntryType)));
-    case  8: return mm128_reinterpret_cast<VectorType>(_mm_srli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 8 * sizeof(EntryType)));
-    case -1: return mm128_reinterpret_cast<VectorType>(_mm_slli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 1 * sizeof(EntryType)));
-    case -2: return mm128_reinterpret_cast<VectorType>(_mm_slli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 2 * sizeof(EntryType)));
-    case -3: return mm128_reinterpret_cast<VectorType>(_mm_slli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 3 * sizeof(EntryType)));
-    case -4: return mm128_reinterpret_cast<VectorType>(_mm_slli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 4 * sizeof(EntryType)));
-    case -5: return mm128_reinterpret_cast<VectorType>(_mm_slli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 5 * sizeof(EntryType)));
-    case -6: return mm128_reinterpret_cast<VectorType>(_mm_slli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 6 * sizeof(EntryType)));
-    case -7: return mm128_reinterpret_cast<VectorType>(_mm_slli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 7 * sizeof(EntryType)));
-    case -8: return mm128_reinterpret_cast<VectorType>(_mm_slli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 8 * sizeof(EntryType)));
+    case  1: return mm128_reinterpret_cast<VectorType>(_mm_srli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 1 * EntryTypeSizeof));
+    case  2: return mm128_reinterpret_cast<VectorType>(_mm_srli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 2 * EntryTypeSizeof));
+    case  3: return mm128_reinterpret_cast<VectorType>(_mm_srli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 3 * EntryTypeSizeof));
+    case  4: return mm128_reinterpret_cast<VectorType>(_mm_srli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 4 * EntryTypeSizeof));
+    case  5: return mm128_reinterpret_cast<VectorType>(_mm_srli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 5 * EntryTypeSizeof));
+    case  6: return mm128_reinterpret_cast<VectorType>(_mm_srli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 6 * EntryTypeSizeof));
+    case  7: return mm128_reinterpret_cast<VectorType>(_mm_srli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 7 * EntryTypeSizeof));
+    case  8: return mm128_reinterpret_cast<VectorType>(_mm_srli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 8 * EntryTypeSizeof));
+    case -1: return mm128_reinterpret_cast<VectorType>(_mm_slli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 1 * EntryTypeSizeof));
+    case -2: return mm128_reinterpret_cast<VectorType>(_mm_slli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 2 * EntryTypeSizeof));
+    case -3: return mm128_reinterpret_cast<VectorType>(_mm_slli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 3 * EntryTypeSizeof));
+    case -4: return mm128_reinterpret_cast<VectorType>(_mm_slli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 4 * EntryTypeSizeof));
+    case -5: return mm128_reinterpret_cast<VectorType>(_mm_slli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 5 * EntryTypeSizeof));
+    case -6: return mm128_reinterpret_cast<VectorType>(_mm_slli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 6 * EntryTypeSizeof));
+    case -7: return mm128_reinterpret_cast<VectorType>(_mm_slli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 7 * EntryTypeSizeof));
+    case -8: return mm128_reinterpret_cast<VectorType>(_mm_slli_si128(mm128_reinterpret_cast<__m128i>(d.v()), 8 * EntryTypeSizeof));
     }
     return Zero();
 }
 template<> Vc_INTRINSIC Vc_PURE sfloat_v sfloat_v::shifted(int amount) const
 {
+    enum {
+        EntryTypeSizeof = sizeof(EntryType)
+    };
     switch (amount) {
-    case -7: return M256::create(_mm_setzero_ps(), _mm_castsi128_ps(_mm_slli_si128(_mm_castps_si128(d.v()[0]), 3 * sizeof(EntryType))));
-    case -6: return M256::create(_mm_setzero_ps(), _mm_castsi128_ps(_mm_slli_si128(_mm_castps_si128(d.v()[0]), 2 * sizeof(EntryType))));
-    case -5: return M256::create(_mm_setzero_ps(), _mm_castsi128_ps(_mm_slli_si128(_mm_castps_si128(d.v()[0]), 1 * sizeof(EntryType))));
+    case -7: return M256::create(_mm_setzero_ps(), _mm_castsi128_ps(_mm_slli_si128(_mm_castps_si128(d.v()[0]), 3 * EntryTypeSizeof)));
+    case -6: return M256::create(_mm_setzero_ps(), _mm_castsi128_ps(_mm_slli_si128(_mm_castps_si128(d.v()[0]), 2 * EntryTypeSizeof)));
+    case -5: return M256::create(_mm_setzero_ps(), _mm_castsi128_ps(_mm_slli_si128(_mm_castps_si128(d.v()[0]), 1 * EntryTypeSizeof)));
     case -4: return M256::create(_mm_setzero_ps(), d.v()[0]);
-    case -3: return M256::create(_mm_castsi128_ps(_mm_slli_si128(_mm_castps_si128(d.v()[0]), 3 * sizeof(EntryType))), _mm_castsi128_ps(_mm_alignr_epi8(_mm_castps_si128(d.v()[1]), _mm_castps_si128(d.v()[0]), 1 * sizeof(EntryType))));
-    case -2: return M256::create(_mm_castsi128_ps(_mm_slli_si128(_mm_castps_si128(d.v()[0]), 2 * sizeof(EntryType))), _mm_castsi128_ps(_mm_alignr_epi8(_mm_castps_si128(d.v()[1]), _mm_castps_si128(d.v()[0]), 2 * sizeof(EntryType))));
-    case -1: return M256::create(_mm_castsi128_ps(_mm_slli_si128(_mm_castps_si128(d.v()[0]), 1 * sizeof(EntryType))), _mm_castsi128_ps(_mm_alignr_epi8(_mm_castps_si128(d.v()[1]), _mm_castps_si128(d.v()[0]), 3 * sizeof(EntryType))));
+    case -3: return M256::create(_mm_castsi128_ps(_mm_slli_si128(_mm_castps_si128(d.v()[0]), 3 * EntryTypeSizeof)), _mm_castsi128_ps(mm_alignr_epi8(_mm_castps_si128(d.v()[1]), _mm_castps_si128(d.v()[0]), 1 * EntryTypeSizeof)));
+    case -2: return M256::create(_mm_castsi128_ps(_mm_slli_si128(_mm_castps_si128(d.v()[0]), 2 * EntryTypeSizeof)), _mm_castsi128_ps(mm_alignr_epi8(_mm_castps_si128(d.v()[1]), _mm_castps_si128(d.v()[0]), 2 * EntryTypeSizeof)));
+    case -1: return M256::create(_mm_castsi128_ps(_mm_slli_si128(_mm_castps_si128(d.v()[0]), 1 * EntryTypeSizeof)), _mm_castsi128_ps(mm_alignr_epi8(_mm_castps_si128(d.v()[1]), _mm_castps_si128(d.v()[0]), 3 * EntryTypeSizeof)));
     case  0: return *this;
-    case  1: return M256::create(_mm_castsi128_ps(_mm_alignr_epi8(_mm_castps_si128(d.v()[1]), _mm_castps_si128(d.v()[0]), 1 * sizeof(EntryType))), _mm_castsi128_ps(_mm_srli_si128(_mm_castps_si128(d.v()[1]), 1 * sizeof(EntryType))));
-    case  2: return M256::create(_mm_castsi128_ps(_mm_alignr_epi8(_mm_castps_si128(d.v()[1]), _mm_castps_si128(d.v()[0]), 2 * sizeof(EntryType))), _mm_castsi128_ps(_mm_srli_si128(_mm_castps_si128(d.v()[1]), 2 * sizeof(EntryType))));
-    case  3: return M256::create(_mm_castsi128_ps(_mm_alignr_epi8(_mm_castps_si128(d.v()[1]), _mm_castps_si128(d.v()[0]), 3 * sizeof(EntryType))), _mm_castsi128_ps(_mm_srli_si128(_mm_castps_si128(d.v()[1]), 3 * sizeof(EntryType))));
+    case  1: return M256::create(_mm_castsi128_ps(mm_alignr_epi8(_mm_castps_si128(d.v()[1]), _mm_castps_si128(d.v()[0]), 1 * EntryTypeSizeof)), _mm_castsi128_ps(_mm_srli_si128(_mm_castps_si128(d.v()[1]), 1 * EntryTypeSizeof)));
+    case  2: return M256::create(_mm_castsi128_ps(mm_alignr_epi8(_mm_castps_si128(d.v()[1]), _mm_castps_si128(d.v()[0]), 2 * EntryTypeSizeof)), _mm_castsi128_ps(_mm_srli_si128(_mm_castps_si128(d.v()[1]), 2 * EntryTypeSizeof)));
+    case  3: return M256::create(_mm_castsi128_ps(mm_alignr_epi8(_mm_castps_si128(d.v()[1]), _mm_castps_si128(d.v()[0]), 3 * EntryTypeSizeof)), _mm_castsi128_ps(_mm_srli_si128(_mm_castps_si128(d.v()[1]), 3 * EntryTypeSizeof)));
     case  4: return M256::create(d.v()[1], _mm_setzero_ps());
-    case  5: return M256::create(_mm_castsi128_ps(_mm_srli_si128(_mm_castps_si128(d.v()[1]), 1 * sizeof(EntryType))), _mm_setzero_ps());
-    case  6: return M256::create(_mm_castsi128_ps(_mm_srli_si128(_mm_castps_si128(d.v()[1]), 2 * sizeof(EntryType))), _mm_setzero_ps());
-    case  7: return M256::create(_mm_castsi128_ps(_mm_srli_si128(_mm_castps_si128(d.v()[1]), 3 * sizeof(EntryType))), _mm_setzero_ps());
+    case  5: return M256::create(_mm_castsi128_ps(_mm_srli_si128(_mm_castps_si128(d.v()[1]), 1 * EntryTypeSizeof)), _mm_setzero_ps());
+    case  6: return M256::create(_mm_castsi128_ps(_mm_srli_si128(_mm_castps_si128(d.v()[1]), 2 * EntryTypeSizeof)), _mm_setzero_ps());
+    case  7: return M256::create(_mm_castsi128_ps(_mm_srli_si128(_mm_castps_si128(d.v()[1]), 3 * EntryTypeSizeof)), _mm_setzero_ps());
     }
     return Zero();
 }
 template<typename T> Vc_INTRINSIC Vc_PURE Vector<T> Vector<T>::rotated(int amount) const
 {
+    enum {
+        EntryTypeSizeof = sizeof(EntryType)
+    };
     const __m128i v = mm128_reinterpret_cast<__m128i>(d.v());
     switch (static_cast<unsigned int>(amount) % Size) {
     case  0: return *this;
-    case  1: return mm128_reinterpret_cast<VectorType>(_mm_alignr_epi8(v, v, 1 * sizeof(EntryType)));
-    case  2: return mm128_reinterpret_cast<VectorType>(_mm_alignr_epi8(v, v, 2 * sizeof(EntryType)));
-    case  3: return mm128_reinterpret_cast<VectorType>(_mm_alignr_epi8(v, v, 3 * sizeof(EntryType)));
+    case  1: return mm128_reinterpret_cast<VectorType>(mm_alignr_epi8(v, v, 1 * EntryTypeSizeof));
+    case  2: return mm128_reinterpret_cast<VectorType>(mm_alignr_epi8(v, v, 2 * EntryTypeSizeof));
+    case  3: return mm128_reinterpret_cast<VectorType>(mm_alignr_epi8(v, v, 3 * EntryTypeSizeof));
              // warning "Immediate parameter to intrinsic call too large" disabled in VcMacros.cmake.
              // ICC fails to see that the modulo operation (Size == sizeof(VectorType) / sizeof(EntryType))
              // disables the following four calls unless sizeof(EntryType) == 2.
-    case  4: return mm128_reinterpret_cast<VectorType>(_mm_alignr_epi8(v, v, 4 * sizeof(EntryType)));
-    case  5: return mm128_reinterpret_cast<VectorType>(_mm_alignr_epi8(v, v, 5 * sizeof(EntryType)));
-    case  6: return mm128_reinterpret_cast<VectorType>(_mm_alignr_epi8(v, v, 6 * sizeof(EntryType)));
-    case  7: return mm128_reinterpret_cast<VectorType>(_mm_alignr_epi8(v, v, 7 * sizeof(EntryType)));
+    case  4: return mm128_reinterpret_cast<VectorType>(mm_alignr_epi8(v, v, 4 * EntryTypeSizeof));
+    case  5: return mm128_reinterpret_cast<VectorType>(mm_alignr_epi8(v, v, 5 * EntryTypeSizeof));
+    case  6: return mm128_reinterpret_cast<VectorType>(mm_alignr_epi8(v, v, 6 * EntryTypeSizeof));
+    case  7: return mm128_reinterpret_cast<VectorType>(mm_alignr_epi8(v, v, 7 * EntryTypeSizeof));
     }
     return Zero();
 }
 template<> Vc_INTRINSIC Vc_PURE sfloat_v sfloat_v::rotated(int amount) const
 {
+    enum {
+        EntryTypeSizeof = sizeof(EntryType)
+    };
     const __m128i v0 = sse_cast<__m128i>(d.v()[0]);
     const __m128i v1 = sse_cast<__m128i>(d.v()[1]);
     switch (static_cast<unsigned int>(amount) % Size) {
     case  0: return *this;
-    case  1: return M256::create(sse_cast<__m128>(_mm_alignr_epi8(v1, v0, 1 * sizeof(EntryType))), sse_cast<__m128>(_mm_alignr_epi8(v0, v1, 1 * sizeof(EntryType))));
-    case  2: return M256::create(sse_cast<__m128>(_mm_alignr_epi8(v1, v0, 2 * sizeof(EntryType))), sse_cast<__m128>(_mm_alignr_epi8(v0, v1, 2 * sizeof(EntryType))));
-    case  3: return M256::create(sse_cast<__m128>(_mm_alignr_epi8(v1, v0, 3 * sizeof(EntryType))), sse_cast<__m128>(_mm_alignr_epi8(v0, v1, 3 * sizeof(EntryType))));
+    case  1: return M256::create(sse_cast<__m128>(mm_alignr_epi8(v1, v0, 1 * EntryTypeSizeof)), sse_cast<__m128>(mm_alignr_epi8(v0, v1, 1 * EntryTypeSizeof)));
+    case  2: return M256::create(sse_cast<__m128>(mm_alignr_epi8(v1, v0, 2 * EntryTypeSizeof)), sse_cast<__m128>(mm_alignr_epi8(v0, v1, 2 * EntryTypeSizeof)));
+    case  3: return M256::create(sse_cast<__m128>(mm_alignr_epi8(v1, v0, 3 * EntryTypeSizeof)), sse_cast<__m128>(mm_alignr_epi8(v0, v1, 3 * EntryTypeSizeof)));
     case  4: return M256::create(d.v()[1], d.v()[0]);
-    case  5: return M256::create(sse_cast<__m128>(_mm_alignr_epi8(v0, v1, 1 * sizeof(EntryType))), sse_cast<__m128>(_mm_alignr_epi8(v1, v0, 1 * sizeof(EntryType))));
-    case  6: return M256::create(sse_cast<__m128>(_mm_alignr_epi8(v0, v1, 2 * sizeof(EntryType))), sse_cast<__m128>(_mm_alignr_epi8(v1, v0, 2 * sizeof(EntryType))));
-    case  7: return M256::create(sse_cast<__m128>(_mm_alignr_epi8(v0, v1, 3 * sizeof(EntryType))), sse_cast<__m128>(_mm_alignr_epi8(v1, v0, 3 * sizeof(EntryType))));
+    case  5: return M256::create(sse_cast<__m128>(mm_alignr_epi8(v0, v1, 1 * EntryTypeSizeof)), sse_cast<__m128>(mm_alignr_epi8(v1, v0, 1 * EntryTypeSizeof)));
+    case  6: return M256::create(sse_cast<__m128>(mm_alignr_epi8(v0, v1, 2 * EntryTypeSizeof)), sse_cast<__m128>(mm_alignr_epi8(v1, v0, 2 * EntryTypeSizeof)));
+    case  7: return M256::create(sse_cast<__m128>(mm_alignr_epi8(v0, v1, 3 * EntryTypeSizeof)), sse_cast<__m128>(mm_alignr_epi8(v1, v0, 3 * EntryTypeSizeof)));
     }
     return Zero();
 }
@@ -1471,19 +1483,19 @@ template<> inline Vc_PURE uint_v uint_v::sorted() const
 {
     __m128i x = data();
     __m128i y = _mm_shuffle_epi32(x, _MM_SHUFFLE(2, 3, 0, 1));
-    __m128i l = _mm_min_epu32(x, y);
-    __m128i h = _mm_max_epu32(x, y);
+    __m128i l = mm_min_epu32(x, y);
+    __m128i h = mm_max_epu32(x, y);
     x = _mm_unpacklo_epi32(l, h);
     y = _mm_unpackhi_epi32(h, l);
 
     // sort quads
-    l = _mm_min_epu32(x, y);
-    h = _mm_max_epu32(x, y);
+    l = mm_min_epu32(x, y);
+    h = mm_max_epu32(x, y);
     x = _mm_unpacklo_epi32(l, h);
     y = _mm_unpackhi_epi64(x, x);
 
-    l = _mm_min_epu32(x, y);
-    h = _mm_max_epu32(x, y);
+    l = mm_min_epu32(x, y);
+    h = mm_max_epu32(x, y);
     return _mm_unpacklo_epi32(l, h);
 }
 template<> inline Vc_PURE ushort_v ushort_v::sorted() const
@@ -1491,35 +1503,35 @@ template<> inline Vc_PURE ushort_v ushort_v::sorted() const
     __m128i lo, hi, y, x = data();
     // sort pairs
     y = Mem::permute<X1, X0, X3, X2, X5, X4, X7, X6>(x);
-    lo = _mm_min_epu16(x, y);
-    hi = _mm_max_epu16(x, y);
-    x = _mm_blend_epi16(lo, hi, 0xaa);
+    lo = mm_min_epu16(x, y);
+    hi = mm_max_epu16(x, y);
+    x = mm_blend_epi16(lo, hi, 0xaa);
 
     // merge left and right quads
     y = Mem::permute<X3, X2, X1, X0, X7, X6, X5, X4>(x);
-    lo = _mm_min_epu16(x, y);
-    hi = _mm_max_epu16(x, y);
-    x = _mm_blend_epi16(lo, hi, 0xcc);
+    lo = mm_min_epu16(x, y);
+    hi = mm_max_epu16(x, y);
+    x = mm_blend_epi16(lo, hi, 0xcc);
     y = _mm_srli_si128(x, 2);
-    lo = _mm_min_epu16(x, y);
-    hi = _mm_max_epu16(x, y);
-    x = _mm_blend_epi16(lo, _mm_slli_si128(hi, 2), 0xaa);
+    lo = mm_min_epu16(x, y);
+    hi = mm_max_epu16(x, y);
+    x = mm_blend_epi16(lo, _mm_slli_si128(hi, 2), 0xaa);
 
     // merge quads into octs
     y = _mm_shuffle_epi32(x, _MM_SHUFFLE(1, 0, 3, 2));
     y = _mm_shufflelo_epi16(y, _MM_SHUFFLE(0, 1, 2, 3));
-    lo = _mm_min_epu16(x, y);
-    hi = _mm_max_epu16(x, y);
+    lo = mm_min_epu16(x, y);
+    hi = mm_max_epu16(x, y);
 
     x = _mm_unpacklo_epi16(lo, hi);
     y = _mm_srli_si128(x, 8);
-    lo = _mm_min_epu16(x, y);
-    hi = _mm_max_epu16(x, y);
+    lo = mm_min_epu16(x, y);
+    hi = mm_max_epu16(x, y);
 
     x = _mm_unpacklo_epi16(lo, hi);
     y = _mm_srli_si128(x, 8);
-    lo = _mm_min_epu16(x, y);
-    hi = _mm_max_epu16(x, y);
+    lo = mm_min_epu16(x, y);
+    hi = mm_max_epu16(x, y);
 
     return _mm_unpacklo_epi16(lo, hi);
 }
index 077edf4..ff47322 100644 (file)
@@ -90,7 +90,7 @@ Vc_INTRINSIC Vc_CONST __m128d exponent(__m128d v)
         OP2(xor_, VectorType::create(_mm_xor_ps(a[0], b[0]), _mm_xor_ps(a[1], b[1])))
         OP2(and_, VectorType::create(_mm_and_ps(a[0], b[0]), _mm_and_ps(a[1], b[1])))
         OP2(andnot_, VectorType::create(_mm_andnot_ps(a[0], b[0]), _mm_andnot_ps(a[1], b[1])))
-        OP3(blend, VectorType::create(_mm_blendv_ps(a[0], b[0], c[0]), _mm_blendv_ps(a[1], b[1], c[1])))
+        OP3(blend, VectorType::create(mm_blendv_ps(a[0], b[0], c[0]), mm_blendv_ps(a[1], b[1], c[1])))
     };
 #undef OP0
 #undef OP2
@@ -120,7 +120,7 @@ Vc_INTRINSIC Vc_CONST __m128d exponent(__m128d v)
             OP2(xor_, _mm_xor_ps(a, b))
             OP2(and_, _mm_and_ps(a, b))
             OP2(andnot_, _mm_andnot_ps(a, b))
-            OP3(blend, _mm_blendv_ps(a, b, c))
+            OP3(blend, mm_blendv_ps(a, b, c))
         };
 
 
@@ -143,7 +143,7 @@ Vc_INTRINSIC Vc_CONST __m128d exponent(__m128d v)
             OP2(xor_, _mm_xor_pd(a, b))
             OP2(and_, _mm_and_pd(a, b))
             OP2(andnot_, _mm_andnot_pd(a, b))
-            OP3(blend, _mm_blendv_pd(a, b, c))
+            OP3(blend, mm_blendv_pd(a, b, c))
         };
 
         template<> struct VectorHelper<_M128I>
@@ -168,7 +168,7 @@ Vc_INTRINSIC Vc_CONST __m128d exponent(__m128d v)
             OP2(xor_, _mm_xor_si128(a, b))
             OP2(and_, _mm_and_si128(a, b))
             OP2(andnot_, _mm_andnot_si128(a, b))
-            OP3(blend, _mm_blendv_epi8(a, b, c))
+            OP3(blend, mm_blendv_epi8(a, b, c))
         };
 
 #undef OP1
@@ -226,8 +226,8 @@ Vc_INTRINSIC Vc_CONST __m128d exponent(__m128d v)
                 const VectorType hh = mul(h1, h2);
                 // ll < lh < hh for all entries is certain
                 const VectorType lh_lt_v3 = cmplt(abs(lh), abs(v3)); // |lh| < |v3|
-                const VectorType b = _mm_blendv_pd(v3, lh, lh_lt_v3);
-                const VectorType c = _mm_blendv_pd(lh, v3, lh_lt_v3);
+                const VectorType b = mm_blendv_pd(v3, lh, lh_lt_v3);
+                const VectorType c = mm_blendv_pd(lh, v3, lh_lt_v3);
                 v1 = add(add(ll, b), add(c, hh));
             }
 #endif
@@ -464,9 +464,10 @@ Vc_INTRINSIC Vc_CONST __m128d exponent(__m128d v)
             static Vc_ALWAYS_INLINE Vc_CONST VectorType shiftRight(VectorType a, int shift) {
                 return CAT(_mm_srai_, SUFFIX)(a, shift);
             }
-            OP1(abs)
+            static Vc_INTRINSIC Vc_CONST VectorType abs(const VectorType a) { return mm_abs_epi32(a); }
 
-            MINMAX
+            static Vc_INTRINSIC Vc_CONST VectorType min(const VectorType a, const VectorType b) { return mm_min_epi32(a, b); }
+            static Vc_INTRINSIC Vc_CONST VectorType max(const VectorType a, const VectorType b) { return mm_max_epi32(a, b); }
             static Vc_ALWAYS_INLINE Vc_CONST EntryType min(VectorType a) {
                 a = min(a, _mm_shuffle_epi32(a, _MM_SHUFFLE(1, 0, 3, 2)));
                 // using lo_epi16 for speed here
@@ -525,7 +526,8 @@ Vc_INTRINSIC Vc_CONST __m128d exponent(__m128d v)
 #define SUFFIX epu32
             static Vc_ALWAYS_INLINE Vc_CONST VectorType one() { return CAT(_mm_setone_, SUFFIX)(); }
 
-            MINMAX
+            static Vc_INTRINSIC Vc_CONST VectorType min(const VectorType a, const VectorType b) { return mm_min_epu32(a, b); }
+            static Vc_INTRINSIC Vc_CONST VectorType max(const VectorType a, const VectorType b) { return mm_max_epu32(a, b); }
             static Vc_ALWAYS_INLINE Vc_CONST EntryType min(VectorType a) {
                 a = min(a, _mm_shuffle_epi32(a, _MM_SHUFFLE(1, 0, 3, 2)));
                 // using lo_epi16 for speed here
@@ -640,7 +642,7 @@ Vc_INTRINSIC Vc_CONST __m128d exponent(__m128d v)
             static Vc_ALWAYS_INLINE void fma(VectorType &v1, VectorType v2, VectorType v3) {
                 v1 = add(mul(v1, v2), v3); }
 
-            OP1(abs)
+            static Vc_INTRINSIC Vc_CONST VectorType abs(const VectorType a) { return mm_abs_epi16(a); }
 
             OPx(mul, mullo)
             OP(min) OP(max)
@@ -722,7 +724,8 @@ Vc_INTRINSIC Vc_CONST __m128d exponent(__m128d v)
 //X                 return mul(a, set(b));
 //X             }
 #if !defined(USE_INCORRECT_UNSIGNED_COMPARE) || VC_IMPL_SSE4_1
-            OP(min) OP(max)
+            static Vc_INTRINSIC Vc_CONST VectorType min(const VectorType a, const VectorType b) { return CAT(mm_min_, SUFFIX)(a, b); }
+            static Vc_INTRINSIC Vc_CONST VectorType max(const VectorType a, const VectorType b) { return CAT(mm_max_, SUFFIX)(a, b); }
 #endif
 #undef SUFFIX
 #define SUFFIX epi16
index 6022521..10ac48d 100644 (file)
@@ -68,11 +68,11 @@ Vc_ALWAYS_INLINE void VectorHelper<_M128>::store(float *mem, const VectorType x,
 }
 Vc_ALWAYS_INLINE void VectorHelper<_M128>::store(float *mem, const VectorType x, const VectorType m, AlignedFlag)
 {
-    _mm_store_ps(mem, _mm_blendv_ps(_mm_load_ps(mem), x, m));
+    _mm_store_ps(mem, mm_blendv_ps(_mm_load_ps(mem), x, m));
 }
 Vc_ALWAYS_INLINE void VectorHelper<_M128>::store(float *mem, const VectorType x, const VectorType m, UnalignedFlag)
 {
-    _mm_storeu_ps(mem, _mm_blendv_ps(_mm_loadu_ps(mem), x, m));
+    _mm_storeu_ps(mem, mm_blendv_ps(_mm_loadu_ps(mem), x, m));
 }
 Vc_ALWAYS_INLINE void VectorHelper<_M128>::store(float *mem, const VectorType x, const VectorType m, StreamingAndAlignedFlag)
 {
@@ -129,13 +129,13 @@ Vc_ALWAYS_INLINE void VectorHelper<M256>::store(float *mem, VectorTypeArg x, Str
 }
 Vc_ALWAYS_INLINE void VectorHelper<M256>::store(float *mem, VectorTypeArg x, VectorTypeArg m, AlignedFlag)
 {
-    _mm_store_ps(mem, _mm_blendv_ps(_mm_load_ps(mem), x[0], m[0]));
-    _mm_store_ps(mem + 4, _mm_blendv_ps(_mm_load_ps(mem + 4), x[1], m[1]));
+    _mm_store_ps(mem, mm_blendv_ps(_mm_load_ps(mem), x[0], m[0]));
+    _mm_store_ps(mem + 4, mm_blendv_ps(_mm_load_ps(mem + 4), x[1], m[1]));
 }
 Vc_ALWAYS_INLINE void VectorHelper<M256>::store(float *mem, VectorTypeArg x, VectorTypeArg m, UnalignedFlag)
 {
-    _mm_storeu_ps(mem, _mm_blendv_ps(_mm_loadu_ps(mem), x[0], m[0]));
-    _mm_storeu_ps(mem + 4, _mm_blendv_ps(_mm_loadu_ps(mem + 4), x[1], m[1]));
+    _mm_storeu_ps(mem, mm_blendv_ps(_mm_loadu_ps(mem), x[0], m[0]));
+    _mm_storeu_ps(mem + 4, mm_blendv_ps(_mm_loadu_ps(mem + 4), x[1], m[1]));
 }
 Vc_ALWAYS_INLINE void VectorHelper<M256>::store(float *mem, VectorTypeArg x, VectorTypeArg m, StreamingAndAlignedFlag)
 {
@@ -190,11 +190,11 @@ Vc_ALWAYS_INLINE void VectorHelper<_M128D>::store(double *mem, const VectorType
 }
 Vc_ALWAYS_INLINE void VectorHelper<_M128D>::store(double *mem, const VectorType x, const VectorType m, AlignedFlag)
 {
-    _mm_store_pd(mem, _mm_blendv_pd(_mm_load_pd(mem), x, m));
+    _mm_store_pd(mem, mm_blendv_pd(_mm_load_pd(mem), x, m));
 }
 Vc_ALWAYS_INLINE void VectorHelper<_M128D>::store(double *mem, const VectorType x, const VectorType m, UnalignedFlag)
 {
-    _mm_storeu_pd(mem, _mm_blendv_pd(_mm_loadu_pd(mem), x, m));
+    _mm_storeu_pd(mem, mm_blendv_pd(_mm_loadu_pd(mem), x, m));
 }
 Vc_ALWAYS_INLINE void VectorHelper<_M128D>::store(double *mem, const VectorType x, const VectorType m, StreamingAndAlignedFlag)
 {
@@ -247,11 +247,11 @@ template<typename T> Vc_ALWAYS_INLINE void VectorHelper<_M128I>::store(T *mem, c
 }
 template<typename T> Vc_ALWAYS_INLINE void VectorHelper<_M128I>::store(T *mem, const VectorType x, const VectorType m, AlignedFlag align)
 {
-    store(mem, _mm_blendv_epi8(load(mem, align), x, m), align);
+    store(mem, mm_blendv_epi8(load(mem, align), x, m), align);
 }
 template<typename T> Vc_ALWAYS_INLINE void VectorHelper<_M128I>::store(T *mem, const VectorType x, const VectorType m, UnalignedFlag align)
 {
-    store(mem, _mm_blendv_epi8(load(mem, align), x, m), align);
+    store(mem, mm_blendv_epi8(load(mem, align), x, m), align);
 }
 template<typename T> Vc_ALWAYS_INLINE void VectorHelper<_M128I>::store(T *mem, const VectorType x, const VectorType m, StreamingAndAlignedFlag)
 {
@@ -269,17 +269,17 @@ template<typename T> Vc_ALWAYS_INLINE void VectorHelper<_M128I>::store(T *mem, c
         y = Mem::permute<X1, X0, X3, X2, X5, X4, X7, X6>(x);
         lo = _mm_min_epi16(x, y);
         hi = _mm_max_epi16(x, y);
-        x = _mm_blend_epi16(lo, hi, 0xaa);
+        x = mm_blend_epi16(lo, hi, 0xaa);
 
         // merge left and right quads
         y = Mem::permute<X3, X2, X1, X0, X7, X6, X5, X4>(x);
         lo = _mm_min_epi16(x, y);
         hi = _mm_max_epi16(x, y);
-        x = _mm_blend_epi16(lo, hi, 0xcc);
+        x = mm_blend_epi16(lo, hi, 0xcc);
         y = _mm_srli_si128(x, 2);
         lo = _mm_min_epi16(x, y);
         hi = _mm_max_epi16(x, y);
-        x = _mm_blend_epi16(lo, _mm_slli_si128(hi, 2), 0xaa);
+        x = mm_blend_epi16(lo, _mm_slli_si128(hi, 2), 0xaa);
 
         // merge quads into octs
         y = _mm_shuffle_epi32(x, _MM_SHUFFLE(1, 0, 3, 2));
@@ -307,8 +307,8 @@ template<typename T> Vc_ALWAYS_INLINE void VectorHelper<_M128I>::store(T *mem, c
         // x = [a b c d]
         // y = [c d a b]
         _M128I y = _mm_shuffle_epi32(x, _MM_SHUFFLE(1, 0, 3, 2));
-        _M128I l = _mm_min_epi32(x, y); // min[ac bd ac bd]
-        _M128I h = _mm_max_epi32(x, y); // max[ac bd ac bd]
+        _M128I l = mm_min_epi32(x, y); // min[ac bd ac bd]
+        _M128I h = mm_max_epi32(x, y); // max[ac bd ac bd]
         if (IS_UNLIKELY(_mm_cvtsi128_si32(h) <= l[1])) { // l[0] < h[0] < l[1] < h[1]
             return _mm_unpacklo_epi32(l, h);
         }
@@ -317,19 +317,19 @@ template<typename T> Vc_ALWAYS_INLINE void VectorHelper<_M128I>::store(T *mem, c
 
         // sort pairs
         _M128I y = _mm_shuffle_epi32(x, _MM_SHUFFLE(2, 3, 0, 1));
-        _M128I l = _mm_min_epi32(x, y);
-        _M128I h = _mm_max_epi32(x, y);
+        _M128I l = mm_min_epi32(x, y);
+        _M128I h = mm_max_epi32(x, y);
         x = _mm_unpacklo_epi32(l, h);
         y = _mm_unpackhi_epi32(h, l);
 
         // sort quads
-        l = _mm_min_epi32(x, y);
-        h = _mm_max_epi32(x, y);
+        l = mm_min_epi32(x, y);
+        h = mm_max_epi32(x, y);
         x = _mm_unpacklo_epi32(l, h);
         y = _mm_unpackhi_epi64(x, x);
 
-        l = _mm_min_epi32(x, y);
-        h = _mm_max_epi32(x, y);
+        l = mm_min_epi32(x, y);
+        h = mm_max_epi32(x, y);
         return _mm_unpacklo_epi32(l, h);
     }
     template<> inline Vc_CONST _M128 SortHelper<_M128, 4>::sort(_M128 x)
@@ -350,15 +350,15 @@ template<typename T> Vc_ALWAYS_INLINE void VectorHelper<_M128I>::store(T *mem, c
         return _mm_unpacklo_ps(l, h);
 //X         _M128 k = _mm_cmpgt_ps(x, y);
 //X         k = _mm_shuffle_ps(k, k, _MM_SHUFFLE(2, 2, 0, 0));
-//X         x = _mm_blendv_ps(x, y, k);
+//X         x = mm_blendv_ps(x, y, k);
 //X         y = _mm_shuffle_ps(x, x, _MM_SHUFFLE(1, 0, 3, 2));
 //X         k = _mm_cmpgt_ps(x, y);
 //X         k = _mm_shuffle_ps(k, k, _MM_SHUFFLE(1, 0, 1, 0));
-//X         x = _mm_blendv_ps(x, y, k);
+//X         x = mm_blendv_ps(x, y, k);
 //X         y = _mm_shuffle_ps(x, x, _MM_SHUFFLE(3, 1, 2, 0));
 //X         k = _mm_cmpgt_ps(x, y);
 //X         k = _mm_shuffle_ps(k, k, _MM_SHUFFLE(0, 1, 1, 0));
-//X         return _mm_blendv_ps(x, y, k);
+//X         return mm_blendv_ps(x, y, k);
     }
     template<> inline Vc_PURE M256 SortHelper<M256, 8>::sort(const M256 &_x)
     {
index c33a020..fdc39b7 100644 (file)
@@ -20,8 +20,8 @@
 #ifndef VC_VERSION_H
 #define VC_VERSION_H
 
-#define VC_VERSION_STRING "0.7.3-dev"
-#define VC_VERSION_NUMBER 0x000707
+#define VC_VERSION_STRING "0.7.4"
+#define VC_VERSION_NUMBER 0x000708
 #define VC_VERSION_CHECK(major, minor, patch) ((major << 16) | (minor << 8) | (patch << 1))
 #define VC_LIBRARY_ABI_VERSION 3
 
index 7b01a82..32e81dc 100644 (file)
@@ -123,9 +123,11 @@ template<> m256i SortHelper<int>::sort(VTArg _hgfedcba)
     m128i b = Reg::shuffle<Y0, Y1, X0, X1>(y, x); // b3 <= b2 <= b1 <= b0
     m128i a = _mm_unpackhi_epi64(x, y);           // a3 >= a2 >= a1 >= a0
 
-    if (VC_IS_UNLIKELY(_mm_extract_epi32(x, 2) >= _mm_extract_epi32(y, 1))) {
+    // _mm_extract_epi32 from clang < 3.4 returns an unsigned int - the static_cast is free for
+    // conforming compilers, but fixes broken ones
+    if (VC_IS_UNLIKELY(static_cast<int>(_mm_extract_epi32(x, 2)) >= static_cast<int>(_mm_extract_epi32(y, 1)))) {
         return concat(Reg::permute<X0, X1, X2, X3>(b), a);
-    } else if (VC_IS_UNLIKELY(_mm_extract_epi32(x, 0) >= _mm_extract_epi32(y, 3))) {
+    } else if (VC_IS_UNLIKELY(static_cast<int>(_mm_extract_epi32(x, 0)) >= static_cast<int>(_mm_extract_epi32(y, 3)))) {
         return concat(a, Reg::permute<X0, X1, X2, X3>(b));
     }
 
index dc4e7a3..5a2435c 100644 (file)
@@ -197,8 +197,6 @@ template<> template<> double_v Trigonometric<Vc::Internal::TrigonometricImplemen
 }
 template<> template<typename _T> void Trigonometric<Vc::Internal::TrigonometricImplementation>::sincos(const Vector<_T> &_x, Vector<_T> *_sin, Vector<_T> *_cos) {
     typedef Vector<_T> V;
-    typedef Const<_T> C;
-    typedef typename V::EntryType T;
     typedef typename V::Mask M;
     typedef typename signed_integer<V>::type IV;
 
@@ -245,7 +243,6 @@ template<> template<> void Trigonometric<Vc::Internal::TrigonometricImplementati
 template<> template<typename _T> Vector<_T> Trigonometric<Vc::Internal::TrigonometricImplementation>::asin (const Vector<_T> &_x) {
     typedef Const<_T> C;
     typedef Vector<_T> V;
-    typedef typename V::EntryType T;
     typedef typename V::Mask M;
 
     const M &negative = _x < V::Zero();
@@ -274,7 +271,6 @@ template<> template<typename _T> Vector<_T> Trigonometric<Vc::Internal::Trigonom
 template<> template<> double_v Trigonometric<Vc::Internal::TrigonometricImplementation>::asin (const double_v &_x) {
     typedef Const<double> C;
     typedef double_v V;
-    typedef V::EntryType T;
     typedef V::Mask M;
 
     const M negative = _x < V::Zero();
@@ -310,7 +306,6 @@ template<> template<> double_v Trigonometric<Vc::Internal::TrigonometricImplemen
 template<> template<typename _T> Vector<_T> Trigonometric<Vc::Internal::TrigonometricImplementation>::atan (const Vector<_T> &_x) {
     typedef Const<_T> C;
     typedef Vector<_T> V;
-    typedef typename V::EntryType T;
     typedef typename V::Mask M;
     V x = abs(_x);
     const M &gt_tan_3pi_8 = x > C::atanThrsHi();
@@ -333,7 +328,6 @@ template<> template<typename _T> Vector<_T> Trigonometric<Vc::Internal::Trigonom
 template<> template<> double_v Trigonometric<Vc::Internal::TrigonometricImplementation>::atan (const double_v &_x) {
     typedef Const<double> C;
     typedef double_v V;
-    typedef V::EntryType T;
     typedef V::Mask M;
 
     M sign = _x < V::Zero();
@@ -364,7 +358,6 @@ template<> template<> double_v Trigonometric<Vc::Internal::TrigonometricImplemen
 template<> template<typename _T> Vector<_T> Trigonometric<Vc::Internal::TrigonometricImplementation>::atan2(const Vector<_T> &y, const Vector<_T> &x) {
     typedef Const<_T> C;
     typedef Vector<_T> V;
-    typedef typename V::EntryType T;
     typedef typename V::Mask M;
 
     const M xZero = x == V::Zero();
@@ -406,7 +399,6 @@ template<> template<typename _T> Vector<_T> Trigonometric<Vc::Internal::Trigonom
 template<> template<> double_v Trigonometric<Vc::Internal::TrigonometricImplementation>::atan2 (const double_v &y, const double_v &x) {
     typedef Const<double> C;
     typedef double_v V;
-    typedef V::EntryType T;
     typedef V::Mask M;
 
     const M xZero = x == V::Zero();