isa.h 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. // Copyright 2009-2021 Intel Corporation
  2. // SPDX-License-Identifier: Apache-2.0
  3. #pragma once
  4. #include "../../common/sys/platform.h"
  5. #include "../../common/sys/sysinfo.h"
  6. namespace embree
  7. {
  8. #define DEFINE_SYMBOL2(type,name) \
  9. typedef type (*name##Func)(); \
  10. name##Func name;
  11. #define DECLARE_SYMBOL2(type,name) \
  12. namespace sse2 { extern type name(); } \
  13. namespace sse42 { extern type name(); } \
  14. namespace avx { extern type name(); } \
  15. namespace avx2 { extern type name(); } \
  16. namespace avx512 { extern type name(); } \
  17. void name##_error2() { throw_RTCError(RTC_ERROR_UNKNOWN,"internal error in ISA selection for " TOSTRING(name)); } \
  18. type name##_error() { return type(name##_error2); } \
  19. type name##_zero() { return type(nullptr); }
  20. #define DECLARE_ISA_FUNCTION(type,symbol,args) \
  21. namespace sse2 { extern type symbol(args); } \
  22. namespace sse42 { extern type symbol(args); } \
  23. namespace avx { extern type symbol(args); } \
  24. namespace avx2 { extern type symbol(args); } \
  25. namespace avx512 { extern type symbol(args); } \
  26. inline type symbol##_error(args) { throw_RTCError(RTC_ERROR_UNSUPPORTED_CPU,"function " TOSTRING(symbol) " not supported by your CPU"); } \
  27. typedef type (*symbol##Ty)(args); \
  28. #define DEFINE_ISA_FUNCTION(type,symbol,args) \
  29. typedef type (*symbol##Func)(args); \
  30. symbol##Func symbol;
  31. #define ZERO_SYMBOL(features,intersector) \
  32. intersector = intersector##_zero;
  33. #define INIT_SYMBOL(features,intersector) \
  34. intersector = decltype(intersector)(intersector##_error);
  35. #define SELECT_SYMBOL_DEFAULT(features,intersector) \
  36. intersector = isa::intersector;
  37. #if defined(__SSE__) || defined(__ARM_NEON)
  38. #if !defined(EMBREE_TARGET_SIMD4)
  39. #define EMBREE_TARGET_SIMD4
  40. #endif
  41. #endif
  42. #if defined(EMBREE_TARGET_SSE42)
  43. #define SELECT_SYMBOL_SSE42(features,intersector) \
  44. if ((features & SSE42) == SSE42) intersector = sse42::intersector;
  45. #else
  46. #define SELECT_SYMBOL_SSE42(features,intersector)
  47. #endif
  48. #if defined(EMBREE_TARGET_AVX) || defined(__AVX__)
  49. #if !defined(EMBREE_TARGET_SIMD8)
  50. #define EMBREE_TARGET_SIMD8
  51. #endif
  52. #if defined(__AVX__) // if default ISA is >= AVX we treat AVX target as default target
  53. #define SELECT_SYMBOL_AVX(features,intersector) \
  54. if ((features & ISA) == ISA) intersector = isa::intersector;
  55. #else
  56. #define SELECT_SYMBOL_AVX(features,intersector) \
  57. if ((features & AVX) == AVX) intersector = avx::intersector;
  58. #endif
  59. #else
  60. #define SELECT_SYMBOL_AVX(features,intersector)
  61. #endif
  62. #if defined(EMBREE_TARGET_AVX2)
  63. #if !defined(EMBREE_TARGET_SIMD8)
  64. #define EMBREE_TARGET_SIMD8
  65. #endif
  66. #define SELECT_SYMBOL_AVX2(features,intersector) \
  67. if ((features & AVX2) == AVX2) intersector = avx2::intersector;
  68. #else
  69. #define SELECT_SYMBOL_AVX2(features,intersector)
  70. #endif
  71. #if defined(EMBREE_TARGET_AVX512)
  72. #if !defined(EMBREE_TARGET_SIMD16)
  73. #define EMBREE_TARGET_SIMD16
  74. #endif
  75. #define SELECT_SYMBOL_AVX512(features,intersector) \
  76. if ((features & AVX512) == AVX512) intersector = avx512::intersector;
  77. #else
  78. #define SELECT_SYMBOL_AVX512(features,intersector)
  79. #endif
  80. #define SELECT_SYMBOL_DEFAULT_SSE42(features,intersector) \
  81. SELECT_SYMBOL_DEFAULT(features,intersector); \
  82. SELECT_SYMBOL_SSE42(features,intersector);
  83. #define SELECT_SYMBOL_DEFAULT_SSE42_AVX(features,intersector) \
  84. SELECT_SYMBOL_DEFAULT(features,intersector); \
  85. SELECT_SYMBOL_SSE42(features,intersector); \
  86. SELECT_SYMBOL_AVX(features,intersector);
  87. #define SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2(features,intersector) \
  88. SELECT_SYMBOL_DEFAULT(features,intersector); \
  89. SELECT_SYMBOL_SSE42(features,intersector); \
  90. SELECT_SYMBOL_AVX(features,intersector); \
  91. SELECT_SYMBOL_AVX2(features,intersector);
  92. #define SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX512(features,intersector) \
  93. SELECT_SYMBOL_DEFAULT(features,intersector); \
  94. SELECT_SYMBOL_SSE42(features,intersector); \
  95. SELECT_SYMBOL_AVX(features,intersector); \
  96. SELECT_SYMBOL_AVX512(features,intersector);
  97. #define SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(features,intersector) \
  98. SELECT_SYMBOL_DEFAULT(features,intersector); \
  99. SELECT_SYMBOL_AVX(features,intersector); \
  100. SELECT_SYMBOL_AVX2(features,intersector); \
  101. SELECT_SYMBOL_AVX512(features,intersector);
  102. #define SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(features,intersector) \
  103. SELECT_SYMBOL_DEFAULT(features,intersector); \
  104. SELECT_SYMBOL_AVX(features,intersector); \
  105. SELECT_SYMBOL_AVX2(features,intersector); \
  106. SELECT_SYMBOL_AVX512(features,intersector);
  107. #define SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,intersector) \
  108. SELECT_SYMBOL_DEFAULT(features,intersector); \
  109. SELECT_SYMBOL_SSE42(features,intersector); \
  110. SELECT_SYMBOL_AVX(features,intersector); \
  111. SELECT_SYMBOL_AVX2(features,intersector); \
  112. SELECT_SYMBOL_AVX512(features,intersector);
  113. #define SELECT_SYMBOL_DEFAULT_SSE42_AVX_AVX2_AVX512(features,intersector) \
  114. SELECT_SYMBOL_DEFAULT(features,intersector); \
  115. SELECT_SYMBOL_SSE42(features,intersector); \
  116. SELECT_SYMBOL_AVX(features,intersector); \
  117. SELECT_SYMBOL_AVX2(features,intersector); \
  118. SELECT_SYMBOL_AVX512(features,intersector);
  119. #define SELECT_SYMBOL_DEFAULT_AVX(features,intersector) \
  120. SELECT_SYMBOL_DEFAULT(features,intersector); \
  121. SELECT_SYMBOL_AVX(features,intersector);
  122. #define SELECT_SYMBOL_DEFAULT_AVX_AVX2(features,intersector) \
  123. SELECT_SYMBOL_DEFAULT(features,intersector); \
  124. SELECT_SYMBOL_AVX(features,intersector); \
  125. SELECT_SYMBOL_AVX2(features,intersector);
  126. #define SELECT_SYMBOL_DEFAULT_AVX(features,intersector) \
  127. SELECT_SYMBOL_DEFAULT(features,intersector); \
  128. SELECT_SYMBOL_AVX(features,intersector);
  129. #define SELECT_SYMBOL_DEFAULT_AVX_AVX512(features,intersector) \
  130. SELECT_SYMBOL_DEFAULT(features,intersector); \
  131. SELECT_SYMBOL_AVX(features,intersector); \
  132. SELECT_SYMBOL_AVX512(features,intersector);
  133. #define SELECT_SYMBOL_DEFAULT_AVX_AVX512(features,intersector) \
  134. SELECT_SYMBOL_DEFAULT(features,intersector); \
  135. SELECT_SYMBOL_AVX(features,intersector); \
  136. SELECT_SYMBOL_AVX512(features,intersector);
  137. #define SELECT_SYMBOL_INIT_AVX(features,intersector) \
  138. INIT_SYMBOL(features,intersector); \
  139. SELECT_SYMBOL_AVX(features,intersector);
  140. #define SELECT_SYMBOL_INIT_AVX_AVX2(features,intersector) \
  141. INIT_SYMBOL(features,intersector); \
  142. SELECT_SYMBOL_AVX(features,intersector); \
  143. SELECT_SYMBOL_AVX2(features,intersector);
  144. #define SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,intersector) \
  145. INIT_SYMBOL(features,intersector); \
  146. SELECT_SYMBOL_AVX(features,intersector); \
  147. SELECT_SYMBOL_AVX2(features,intersector); \
  148. SELECT_SYMBOL_AVX512(features,intersector);
  149. #define SELECT_SYMBOL_INIT_SSE42_AVX_AVX2(features,intersector) \
  150. INIT_SYMBOL(features,intersector); \
  151. SELECT_SYMBOL_SSE42(features,intersector); \
  152. SELECT_SYMBOL_AVX(features,intersector); \
  153. SELECT_SYMBOL_AVX2(features,intersector);
  154. #define SELECT_SYMBOL_INIT_AVX(features,intersector) \
  155. INIT_SYMBOL(features,intersector); \
  156. SELECT_SYMBOL_AVX(features,intersector);
  157. #define SELECT_SYMBOL_INIT_AVX_AVX512(features,intersector) \
  158. INIT_SYMBOL(features,intersector); \
  159. SELECT_SYMBOL_AVX(features,intersector); \
  160. SELECT_SYMBOL_AVX512(features,intersector);
  161. #define SELECT_SYMBOL_INIT_AVX_AVX2(features,intersector) \
  162. INIT_SYMBOL(features,intersector); \
  163. SELECT_SYMBOL_AVX(features,intersector); \
  164. SELECT_SYMBOL_AVX2(features,intersector);
  165. #define SELECT_SYMBOL_INIT_AVX_AVX2_AVX512(features,intersector) \
  166. INIT_SYMBOL(features,intersector); \
  167. SELECT_SYMBOL_AVX(features,intersector); \
  168. SELECT_SYMBOL_AVX2(features,intersector); \
  169. SELECT_SYMBOL_AVX512(features,intersector);
  170. #define SELECT_SYMBOL_INIT_SSE42_AVX_AVX2_AVX512(features,intersector) \
  171. INIT_SYMBOL(features,intersector); \
  172. SELECT_SYMBOL_SSE42(features,intersector); \
  173. SELECT_SYMBOL_AVX(features,intersector); \
  174. SELECT_SYMBOL_AVX2(features,intersector); \
  175. SELECT_SYMBOL_AVX512(features,intersector);
  176. #define SELECT_SYMBOL_ZERO_SSE42_AVX_AVX2_AVX512(features,intersector) \
  177. ZERO_SYMBOL(features,intersector); \
  178. SELECT_SYMBOL_SSE42(features,intersector); \
  179. SELECT_SYMBOL_AVX(features,intersector); \
  180. SELECT_SYMBOL_AVX2(features,intersector); \
  181. SELECT_SYMBOL_AVX512(features,intersector);
  182. #define SELECT_SYMBOL_DEFAULT_AVX_AVX2_AVX512(features,intersector) \
  183. SELECT_SYMBOL_DEFAULT(features,intersector); \
  184. SELECT_SYMBOL_AVX(features,intersector); \
  185. SELECT_SYMBOL_AVX2(features,intersector); \
  186. SELECT_SYMBOL_AVX512(features,intersector);
  187. #define SELECT_SYMBOL_INIT_AVX512(features,intersector) \
  188. INIT_SYMBOL(features,intersector); \
  189. SELECT_SYMBOL_AVX512(features,intersector);
  190. #define SELECT_SYMBOL_SSE42_AVX_AVX2(features,intersector) \
  191. SELECT_SYMBOL_SSE42(features,intersector); \
  192. SELECT_SYMBOL_AVX(features,intersector); \
  193. SELECT_SYMBOL_AVX2(features,intersector);
  194. struct VerifyMultiTargetLinking {
  195. static __noinline int getISA(int depth = 5) {
  196. if (depth == 0) return ISA;
  197. else return getISA(depth-1);
  198. }
  199. };
  200. namespace sse2 { int getISA(); };
  201. namespace sse42 { int getISA(); };
  202. namespace avx { int getISA(); };
  203. namespace avx2 { int getISA(); };
  204. namespace avx512 { int getISA(); };
  205. }