Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:48:05

0001 /*
0002 Copyright Charly Chevalier 2015
0003 Copyright Joel Falcou 2015
0004 Distributed under the Boost Software License, Version 1.0.
0005 (See accompanying file LICENSE_1_0.txt or copy at
0006 http://www.boost.org/LICENSE_1_0.txt)
0007 */
0008 
0009 #include <boost/predef/hardware/simd/x86.h>
0010 #include <boost/predef/hardware/simd/x86_amd.h>
0011 #include <boost/predef/hardware/simd/arm.h>
0012 #include <boost/predef/hardware/simd/ppc.h>
0013 
0014 #ifndef BOOST_PREDEF_HARDWARE_SIMD_H
0015 #define BOOST_PREDEF_HARDWARE_SIMD_H
0016 
0017 #include <boost/predef/version_number.h>
0018 
0019 /* tag::reference[]
0020 = Using the `BOOST_HW_SIMD_*` predefs
0021 
0022 SIMD predefs depend on compiler options. For example, you will have to add the
0023 option `-msse3` to clang or gcc to enable SSE3. SIMD predefs are also inclusive.
0024 This means that if SSE3 is enabled, then every other extensions with a lower
0025 version number will implicitly be enabled and detected. However, some extensions
0026 are CPU specific, they may not be detected nor enabled when an upper version is
0027 enabled.
0028 
0029 NOTE: SSE(1) and SSE2 are automatically enabled by default when using x86-64
0030 architecture.
0031 
0032 To check if any SIMD extension has been enabled, you can use:
0033 
0034 [source]
0035 ----
0036 #include <boost/predef/hardware/simd.h>
0037 #include <iostream>
0038 
0039 int main()
0040 {
0041 #if defined(BOOST_HW_SIMD_AVAILABLE)
0042     std::cout << "SIMD detected!" << std::endl;
0043 #endif
0044     return 0;
0045 }
0046 ----
0047 
0048 When writing SIMD specific code, you may want to check if a particular extension
0049 has been detected. To do so you have to use the right architecture predef and
0050 compare it. Those predef are of the form `BOOST_HW_SIMD_"ARCH"` (where `"ARCH"`
0051 is either `ARM`, `PPC`, or `X86`). For example, if you compile code for x86
0052 architecture, you will have to use `BOOST_HW_SIMD_X86`. Its value will be the
0053 version number of the most recent SIMD extension detected for the architecture.
0054 
0055 To check if an extension has been enabled:
0056 
0057 [source]
0058 ----
0059 #include <boost/predef/hardware/simd.h>
0060 #include <iostream>
0061 
0062 int main()
0063 {
0064 #if BOOST_HW_SIMD_X86 >= BOOST_HW_SIMD_X86_SSE3_VERSION
0065     std::cout << "This is SSE3!" << std::endl;
0066 #endif
0067     return 0;
0068 }
0069 ----
0070 
0071 NOTE: The *_VERSION* defines that map version number to actual real
0072 identifiers. This way it is easier to write comparisons without messing up with
0073 version numbers.
0074 
0075 To *"strictly"* check the most recent detected extension:
0076 
0077 [source]
0078 ----
0079 #include <boost/predef/hardware/simd.h>
0080 #include <iostream>
0081 
0082 int main()
0083 {
0084 #if BOOST_HW_SIMD_X86 == BOOST_HW_SIMD_X86_SSE3_VERSION
0085     std::cout << "This is SSE3 and this is the most recent enabled extension!"
0086         << std::endl;
0087 #endif
0088     return 0;
0089 }
0090 ----
0091 
0092 Because of the version systems of predefs and of the inclusive property of SIMD
0093 extensions macros, you can easily check for ranges of supported extensions:
0094 
0095 [source]
0096 ----
0097 #include <boost/predef/hardware/simd.h>
0098 #include <iostream>
0099 
0100 int main()
0101 {
0102 #if BOOST_HW_SIMD_X86 >= BOOST_HW_SIMD_X86_SSE2_VERSION &&\
0103     BOOST_HW_SIMD_X86 <= BOOST_HW_SIMD_X86_SSSE3_VERSION
0104     std::cout << "This is SSE2, SSE3 and SSSE3!" << std::endl;
0105 #endif
0106     return 0;
0107 }
0108 ----
0109 
0110 NOTE: Unlike gcc and clang, Visual Studio does not allow you to specify precisely
0111 the SSE variants you want to use, the only detections that will take place are
0112 SSE, SSE2, AVX and AVX2. For more informations,
0113     see [@https://msdn.microsoft.com/en-us/library/b0084kay.aspx here].
0114 
0115 
0116 */ // end::reference[]
0117 
0118 // We check if SIMD extension of multiples architectures have been detected,
0119 // if yes, then this is an error!
0120 //
0121 // NOTE: _X86_AMD implies _X86, so there is no need to check for it here!
0122 //
0123 #if defined(BOOST_HW_SIMD_ARM_AVAILABLE) && defined(BOOST_HW_SIMD_PPC_AVAILABLE) ||\
0124     defined(BOOST_HW_SIMD_ARM_AVAILABLE) && defined(BOOST_HW_SIMD_X86_AVAILABLE) ||\
0125     defined(BOOST_HW_SIMD_PPC_AVAILABLE) && defined(BOOST_HW_SIMD_X86_AVAILABLE)
0126 #   error "Multiple SIMD architectures detected, this cannot happen!"
0127 #endif
0128 
0129 #if defined(BOOST_HW_SIMD_X86_AVAILABLE) && defined(BOOST_HW_SIMD_X86_AMD_AVAILABLE)
0130     // If both standard _X86 and _X86_AMD are available,
0131     // then take the biggest version of the two!
0132 #   if BOOST_HW_SIMD_X86 >= BOOST_HW_SIMD_X86_AMD
0133 #      define BOOST_HW_SIMD BOOST_HW_SIMD_X86
0134 #   else
0135 #      define BOOST_HW_SIMD BOOST_HW_SIMD_X86_AMD
0136 #   endif
0137 #endif
0138 
0139 #if !defined(BOOST_HW_SIMD)
0140     // At this point, only one of these two is defined
0141 #   if defined(BOOST_HW_SIMD_X86_AVAILABLE)
0142 #      define BOOST_HW_SIMD BOOST_HW_SIMD_X86
0143 #   endif
0144 #   if defined(BOOST_HW_SIMD_X86_AMD_AVAILABLE)
0145 #      define BOOST_HW_SIMD BOOST_HW_SIMD_X86_AMD
0146 #   endif
0147 #endif
0148 
0149 #if defined(BOOST_HW_SIMD_ARM_AVAILABLE)
0150 #   define BOOST_HW_SIMD BOOST_HW_SIMD_ARM
0151 #endif
0152 
0153 #if defined(BOOST_HW_SIMD_PPC_AVAILABLE)
0154 #   define BOOST_HW_SIMD BOOST_HW_SIMD_PPC
0155 #endif
0156 
0157 #if defined(BOOST_HW_SIMD)
0158 #   define BOOST_HW_SIMD_AVAILABLE
0159 #else
0160 #   define BOOST_HW_SIMD BOOST_VERSION_NUMBER_NOT_AVAILABLE
0161 #endif
0162 
0163 #define BOOST_HW_SIMD_NAME "Hardware SIMD"
0164 
0165 #endif
0166 
0167 #include <boost/predef/detail/test.h>
0168 BOOST_PREDEF_DECLARE_TEST(BOOST_HW_SIMD, BOOST_HW_SIMD_NAME)