1 /* 2 Copyright 2010-2011, D. E. Shaw Research. 3 All rights reserved. 4 5 Redistribution and use in source and binary forms, with or without 6 modification, are permitted provided that the following conditions are 7 met: 8 9 * Redistributions of source code must retain the above copyright 10 notice, this list of conditions, and the following disclaimer. 11 12 * Redistributions in binary form must reproduce the above copyright 13 notice, this list of conditions, and the following disclaimer in the 14 documentation and/or other materials provided with the distribution. 15 16 * Neither the name of D. E. Shaw Research nor the names of its 17 contributors may be used to endorse or promote products derived from 18 this software without specific prior written permission. 19 20 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 21 "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 22 LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 23 A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 24 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 25 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 26 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 27 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 28 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 29 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 30 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 31 */ 32 #ifndef __gccfeatures_dot_hpp 33 #define __gccfeatures_dot_hpp 34 35 #define R123_GNUC_VERSION (__GNUC__*10000 + __GNUC_MINOR__*100 + __GNUC_PATCHLEVEL__) 36 37 #if !defined(__x86_64__) && !defined(__i386__) && !defined(__powerpc__) 38 # error "This code has only been tested on x86 and powerpc platforms." 39 #include <including_a_nonexistent_file_will_stop_some_compilers_from_continuing_with_a_hopeless_task> 40 { /* maybe an unbalanced brace will terminate the compilation */ 41 /* Feel free to try the Random123 library on other architectures by changing 42 the conditions that reach this error, but you should consider it a 43 porting exercise and expect to encounter bugs and deficiencies. 44 Please let the authors know of any successes (or failures). */ 45 #endif 46 47 #if defined(__powerpc__) && !defined(__clang__) 48 #include <ppu_intrinsics.h> 49 #endif 50 51 #ifndef R123_STATIC_INLINE 52 #define R123_STATIC_INLINE static __inline__ 53 #endif 54 55 #ifndef R123_FORCE_INLINE 56 #if R123_GNUC_VERSION >= 40000 57 #define R123_FORCE_INLINE(decl) decl __attribute__((always_inline)) 58 #else 59 #define R123_FORCE_INLINE(decl) decl 60 #endif 61 #endif 62 63 #ifndef R123_CUDA_DEVICE 64 #define R123_CUDA_DEVICE 65 #endif 66 67 #ifndef R123_ASSERT 68 #include <assert.h> 69 #define R123_ASSERT(x) assert(x) 70 #endif 71 72 #ifndef R123_BUILTIN_EXPECT 73 #define R123_BUILTIN_EXPECT(expr,likely) __builtin_expect(expr,likely) 74 #endif 75 76 /* According to the C++0x standard, we should be able to test the numeric 77 value of __cplusplus == 199701L for C++98, __cplusplus == 201103L for C++0x 78 But gcc has had an open bug http://gcc.gnu.org/bugzilla/show_bug.cgi?id=1773 79 since early 2001, which was finally fixed in 4.7 (early 2012). For 80 earlier versions, the only way to detect whether --std=c++0x was requested 81 on the command line is to look at the __GCC_EXPERIMENTAL_CXX0X__ pp-symbol. 82 */ 83 #define GNU_CXX11 (__cplusplus>=201103L || (R123_GNUC_VERSION<40700 && defined(__GCC_EXPERIMENTAL_CXX0X__) )) 84 85 #ifndef R123_USE_CXX11_UNRESTRICTED_UNIONS 86 #define R123_USE_CXX11_UNRESTRICTED_UNIONS ((R123_GNUC_VERSION >= 40600) && GNU_CXX11) 87 #endif 88 89 #ifndef R123_USE_CXX11_STATIC_ASSERT 90 #define R123_USE_CXX11_STATIC_ASSERT ((R123_GNUC_VERSION >= 40300) && GNU_CXX11) 91 #endif 92 93 #ifndef R123_USE_CXX11_CONSTEXPR 94 #define R123_USE_CXX11_CONSTEXPR ((R123_GNUC_VERSION >= 40600) && GNU_CXX11) 95 #endif 96 97 #ifndef R123_USE_CXX11_EXPLICIT_CONVERSIONS 98 #define R123_USE_CXX11_EXPLICIT_CONVERSIONS ((R123_GNUC_VERSION >= 40500) && GNU_CXX11) 99 #endif 100 101 #ifndef R123_USE_CXX11_RANDOM 102 #define R123_USE_CXX11_RANDOM ((R123_GNUC_VERSION>=40500) && GNU_CXX11) 103 #endif 104 105 #ifndef R123_USE_CXX11_TYPE_TRAITS 106 #define R123_USE_CXX11_TYPE_TRAITS ((R123_GNUC_VERSION>=40400) && GNU_CXX11) 107 #endif 108 109 #ifndef R123_USE_AES_NI 110 #ifdef __AES__ 111 #define R123_USE_AES_NI 1 112 #else 113 #define R123_USE_AES_NI 0 114 #endif 115 #endif 116 117 #ifndef R123_USE_SSE4_2 118 #ifdef __SSE4_2__ 119 #define R123_USE_SSE4_2 1 120 #else 121 #define R123_USE_SSE4_2 0 122 #endif 123 #endif 124 125 #ifndef R123_USE_SSE4_1 126 #ifdef __SSE4_1__ 127 #define R123_USE_SSE4_1 1 128 #else 129 #define R123_USE_SSE4_1 0 130 #endif 131 #endif 132 133 #ifndef R123_USE_SSE 134 /* There's no point in trying to compile SSE code in Random123 135 unless SSE2 is available. */ 136 #ifdef __SSE2__ 137 #define R123_USE_SSE 1 138 #else 139 #define R123_USE_SSE 0 140 #endif 141 #endif 142 143 #ifndef R123_USE_AES_OPENSSL 144 /* There isn't really a good way to tell at compile time whether 145 openssl is available. Without a pre-compilation configure-like 146 tool, it's less error-prone to guess that it isn't available. Add 147 -DR123_USE_AES_OPENSSL=1 and any necessary LDFLAGS or LDLIBS to 148 play with openssl */ 149 #define R123_USE_AES_OPENSSL 0 150 #endif 151 152 #ifndef R123_USE_GNU_UINT128 153 #ifdef __x86_64__ 154 #define R123_USE_GNU_UINT128 1 155 #else 156 #define R123_USE_GNU_UINT128 0 157 #endif 158 #endif 159 160 #ifndef R123_USE_ASM_GNU 161 #define R123_USE_ASM_GNU (defined(__x86_64__)||defined(__i386__)) 162 #endif 163 164 #ifndef R123_USE_CPUID_MSVC 165 #define R123_USE_CPUID_MSVC 0 166 #endif 167 168 #ifndef R123_USE_X86INTRIN_H 169 #define R123_USE_X86INTRIN_H ((defined(__x86_64__)||defined(__i386__)) && R123_GNUC_VERSION >= 40402) 170 #endif 171 172 #ifndef R123_USE_IA32INTRIN_H 173 #define R123_USE_IA32INTRIN_H 0 174 #endif 175 176 #ifndef R123_USE_XMMINTRIN_H 177 #define R123_USE_XMMINTRIN_H 0 178 #endif 179 180 #ifndef R123_USE_EMMINTRIN_H 181 /* gcc -m64 on Solaris 10 defines __SSE2__ but doesn't have 182 emmintrin.h in the include search path. This is 183 so broken that I refuse to try to work around it. If this 184 affects you, figure out where your emmintrin.h lives and 185 add an appropriate -I to your CPPFLAGS. Or add -DR123_USE_SSE=0. */ 186 #define R123_USE_EMMINTRIN_H (R123_USE_SSE && (R123_GNUC_VERSION < 40402)) 187 #endif 188 189 #ifndef R123_USE_SMMINTRIN_H 190 #define R123_USE_SMMINTRIN_H ((R123_USE_SSE4_1 || R123_USE_SSE4_2) && (R123_GNUC_VERSION < 40402)) 191 #endif 192 193 #ifndef R123_USE_WMMINTRIN_H 194 #define R123_USE_WMMINTRIN_H 0 195 #endif 196 197 #ifndef R123_USE_INTRIN_H 198 #define R123_USE_INTRIN_H 0 199 #endif 200 201 #ifndef R123_USE_MULHILO32_ASM 202 #define R123_USE_MULHILO32_ASM 0 203 #endif 204 205 #ifndef R123_USE_MULHILO64_ASM 206 #define R123_USE_MULHILO64_ASM 0 207 #endif 208 209 #ifndef R123_USE_MULHILO64_MSVC_INTRIN 210 #define R123_USE_MULHILO64_MSVC_INTRIN 0 211 #endif 212 213 #ifndef R123_USE_MULHILO64_CUDA_INTRIN 214 #define R123_USE_MULHILO64_CUDA_INTRIN 0 215 #endif 216 217 #ifndef R123_USE_MULHILO64_OPENCL_INTRIN 218 #define R123_USE_MULHILO64_OPENCL_INTRIN 0 219 #endif 220 221 #ifndef R123_USE_MULHILO64_MULHI_INTRIN 222 #define R123_USE_MULHILO64_MULHI_INTRIN (defined(__powerpc64__)) 223 #endif 224 225 #ifndef R123_MULHILO64_MULHI_INTRIN 226 #define R123_MULHILO64_MULHI_INTRIN __mulhdu 227 #endif 228 229 #ifndef R123_USE_MULHILO32_MULHI_INTRIN 230 #define R123_USE_MULHILO32_MULHI_INTRIN 0 231 #endif 232 233 #ifndef R123_MULHILO32_MULHI_INTRIN 234 #define R123_MULHILO32_MULHI_INTRIN __mulhwu 235 #endif 236 237 #ifndef __STDC_CONSTANT_MACROS 238 #define __STDC_CONSTANT_MACROS 239 #endif 240 #include <stdint.h> 241 #ifndef UINT64_C 242 #error UINT64_C not defined. You must define __STDC_CONSTANT_MACROS before you #include <stdint.h> 243 #endif 244 245 /* If you add something, it must go in all the other XXfeatures.hpp 246 and in ../ut_features.cpp */ 247 #endif 248