zend_cpuinfo.h 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. /*
  2. +----------------------------------------------------------------------+
  3. | Zend Engine |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) Zend Technologies Ltd. (http://www.zend.com) |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 2.00 of the Zend license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | http://www.zend.com/license/2_00.txt. |
  11. | If you did not receive a copy of the Zend license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@zend.com so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Authors: Xinchen Hui <laruence@php.net> |
  16. +----------------------------------------------------------------------+
  17. */
  18. #ifndef ZEND_CPU_INFO_H
  19. #define ZEND_CPU_INFO_H
  20. #include "zend.h"
  21. #define ZEND_CPU_EBX_MASK (1<<30)
  22. #define ZEND_CPU_EDX_MASK (1U<<31)
  23. typedef enum _zend_cpu_feature {
  24. /* ECX */
  25. ZEND_CPU_FEATURE_SSE3 = (1<<0),
  26. ZEND_CPU_FEATURE_PCLMULQDQ = (1<<1),
  27. ZEND_CPU_FEATURE_DTES64 = (1<<2),
  28. ZEND_CPU_FEATURE_MONITOR = (1<<3),
  29. ZEND_CPU_FEATURE_DSCPL = (1<<4),
  30. ZEND_CPU_FEATURE_VMX = (1<<5),
  31. ZEND_CPU_FEATURE_SMX = (1<<6),
  32. ZEND_CPU_FEATURE_EST = (1<<7),
  33. ZEND_CPU_FEATURE_TM2 = (1<<8),
  34. ZEND_CPU_FEATURE_SSSE3 = (1<<9),
  35. ZEND_CPU_FEATURE_CID = (1<<10),
  36. ZEND_CPU_FEATURE_SDBG = (1<<11),
  37. ZEND_CPU_FEATURE_FMA = (1<<12),
  38. ZEND_CPU_FEATURE_CX16 = (1<<13),
  39. ZEND_CPU_FEATURE_XTPR = (1<<14),
  40. ZEND_CPU_FEATURE_PDCM = (1<<15),
  41. /* reserved = (1<<16),*/
  42. ZEND_CPU_FEATURE_PCID = (1<<17),
  43. ZEND_CPU_FEATURE_DCA = (1<<18),
  44. ZEND_CPU_FEATURE_SSE41 = (1<<19),
  45. ZEND_CPU_FEATURE_SSE42 = (1<<20),
  46. ZEND_CPU_FEATURE_X2APIC = (1<<21),
  47. ZEND_CPU_FEATURE_MOVBE = (1<<22),
  48. ZEND_CPU_FEATURE_POPCNT = (1<<23),
  49. ZEND_CPU_FEATURE_TSC_DEADLINE = (1<<24),
  50. ZEND_CPU_FEATURE_AES = (1<<25),
  51. ZEND_CPU_FEATURE_XSAVE = (1<<26),
  52. ZEND_CPU_FEATURE_OSXSAVE = (1<<27) ,
  53. ZEND_CPU_FEATURE_AVX = (1<<28),
  54. ZEND_CPU_FEATURE_F16C = (1<<29),
  55. /* intentionally don't support = (1<<30) */
  56. /* intentionally don't support = (1<<31) */
  57. /* EBX */
  58. ZEND_CPU_FEATURE_AVX2 = (1<<5 | ZEND_CPU_EBX_MASK),
  59. /* EDX */
  60. ZEND_CPU_FEATURE_FPU = (1<<0 | ZEND_CPU_EDX_MASK),
  61. ZEND_CPU_FEATURE_VME = (1<<1 | ZEND_CPU_EDX_MASK),
  62. ZEND_CPU_FEATURE_DE = (1<<2 | ZEND_CPU_EDX_MASK),
  63. ZEND_CPU_FEATURE_PSE = (1<<3 | ZEND_CPU_EDX_MASK),
  64. ZEND_CPU_FEATURE_TSC = (1<<4 | ZEND_CPU_EDX_MASK),
  65. ZEND_CPU_FEATURE_MSR = (1<<5 | ZEND_CPU_EDX_MASK),
  66. ZEND_CPU_FEATURE_PAE = (1<<6 | ZEND_CPU_EDX_MASK),
  67. ZEND_CPU_FEATURE_MCE = (1<<7 | ZEND_CPU_EDX_MASK),
  68. ZEND_CPU_FEATURE_CX8 = (1<<8 | ZEND_CPU_EDX_MASK),
  69. ZEND_CPU_FEATURE_APIC = (1<<9 | ZEND_CPU_EDX_MASK),
  70. /* reserved = (1<<10 | ZEND_CPU_EDX_MASK),*/
  71. ZEND_CPU_FEATURE_SEP = (1<<11 | ZEND_CPU_EDX_MASK),
  72. ZEND_CPU_FEATURE_MTRR = (1<<12 | ZEND_CPU_EDX_MASK),
  73. ZEND_CPU_FEATURE_PGE = (1<<13 | ZEND_CPU_EDX_MASK),
  74. ZEND_CPU_FEATURE_MCA = (1<<14 | ZEND_CPU_EDX_MASK),
  75. ZEND_CPU_FEATURE_CMOV = (1<<15 | ZEND_CPU_EDX_MASK),
  76. ZEND_CPU_FEATURE_PAT = (1<<16 | ZEND_CPU_EDX_MASK),
  77. ZEND_CPU_FEATURE_PSE36 = (1<<17 | ZEND_CPU_EDX_MASK),
  78. ZEND_CPU_FEATURE_PN = (1<<18 | ZEND_CPU_EDX_MASK),
  79. ZEND_CPU_FEATURE_CLFLUSH = (1<<19 | ZEND_CPU_EDX_MASK),
  80. /* reserved = (1<<20 | ZEND_CPU_EDX_MASK),*/
  81. ZEND_CPU_FEATURE_DS = (1<<21 | ZEND_CPU_EDX_MASK),
  82. ZEND_CPU_FEATURE_ACPI = (1<<22 | ZEND_CPU_EDX_MASK),
  83. ZEND_CPU_FEATURE_MMX = (1<<23 | ZEND_CPU_EDX_MASK),
  84. ZEND_CPU_FEATURE_FXSR = (1<<24 | ZEND_CPU_EDX_MASK),
  85. ZEND_CPU_FEATURE_SSE = (1<<25 | ZEND_CPU_EDX_MASK),
  86. ZEND_CPU_FEATURE_SSE2 = (1<<26 | ZEND_CPU_EDX_MASK),
  87. ZEND_CPU_FEATURE_SS = (1<<27 | ZEND_CPU_EDX_MASK),
  88. ZEND_CPU_FEATURE_HT = (1<<28 | ZEND_CPU_EDX_MASK),
  89. ZEND_CPU_FEATURE_TM = (1<<29 | ZEND_CPU_EDX_MASK)
  90. /*intentionally don't support = (1<<30 | ZEND_CPU_EDX_MASK)*/
  91. /*intentionally don't support = (1<<31 | ZEND_CPU_EDX_MASK)*/
  92. } zend_cpu_feature;
  93. void zend_cpu_startup(void);
  94. ZEND_API int zend_cpu_supports(zend_cpu_feature feature);
  95. #ifndef __has_attribute
  96. # define __has_attribute(x) 0
  97. #endif
  98. /* Address sanitizer is incompatible with ifunc resolvers, so exclude the
  99. * CPU support helpers from asan.
  100. * See also https://github.com/google/sanitizers/issues/342. */
  101. #if __has_attribute(no_sanitize_address)
  102. # define ZEND_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
  103. #else
  104. # define ZEND_NO_SANITIZE_ADDRESS
  105. #endif
  106. #if PHP_HAVE_BUILTIN_CPU_SUPPORTS
  107. /* NOTE: you should use following inline function in
  108. * resolver functions (ifunc), as it could be called
  109. * before all PLT symbols are resolved. in other words,
  110. * resolver functions should not depend on any external
  111. * functions */
  112. ZEND_NO_SANITIZE_ADDRESS
  113. static inline int zend_cpu_supports_sse2(void) {
  114. #if PHP_HAVE_BUILTIN_CPU_INIT
  115. __builtin_cpu_init();
  116. #endif
  117. return __builtin_cpu_supports("sse2");
  118. }
  119. ZEND_NO_SANITIZE_ADDRESS
  120. static inline int zend_cpu_supports_sse3(void) {
  121. #if PHP_HAVE_BUILTIN_CPU_INIT
  122. __builtin_cpu_init();
  123. #endif
  124. return __builtin_cpu_supports("sse3");
  125. }
  126. ZEND_NO_SANITIZE_ADDRESS
  127. static inline int zend_cpu_supports_ssse3(void) {
  128. #if PHP_HAVE_BUILTIN_CPU_INIT
  129. __builtin_cpu_init();
  130. #endif
  131. return __builtin_cpu_supports("ssse3");
  132. }
  133. ZEND_NO_SANITIZE_ADDRESS
  134. static inline int zend_cpu_supports_sse41(void) {
  135. #if PHP_HAVE_BUILTIN_CPU_INIT
  136. __builtin_cpu_init();
  137. #endif
  138. return __builtin_cpu_supports("sse4.1");
  139. }
  140. ZEND_NO_SANITIZE_ADDRESS
  141. static inline int zend_cpu_supports_sse42(void) {
  142. #if PHP_HAVE_BUILTIN_CPU_INIT
  143. __builtin_cpu_init();
  144. #endif
  145. return __builtin_cpu_supports("sse4.2");
  146. }
  147. ZEND_NO_SANITIZE_ADDRESS
  148. static inline int zend_cpu_supports_avx(void) {
  149. #if PHP_HAVE_BUILTIN_CPU_INIT
  150. __builtin_cpu_init();
  151. #endif
  152. return __builtin_cpu_supports("avx");
  153. }
  154. ZEND_NO_SANITIZE_ADDRESS
  155. static inline int zend_cpu_supports_avx2(void) {
  156. #if PHP_HAVE_BUILTIN_CPU_INIT
  157. __builtin_cpu_init();
  158. #endif
  159. return __builtin_cpu_supports("avx2");
  160. }
  161. #else
  162. static inline int zend_cpu_supports_sse2(void) {
  163. return zend_cpu_supports(ZEND_CPU_FEATURE_SSE2);
  164. }
  165. static inline int zend_cpu_supports_sse3(void) {
  166. return zend_cpu_supports(ZEND_CPU_FEATURE_SSE3);
  167. }
  168. static inline int zend_cpu_supports_ssse3(void) {
  169. return zend_cpu_supports(ZEND_CPU_FEATURE_SSSE3);
  170. }
  171. static inline int zend_cpu_supports_sse41(void) {
  172. return zend_cpu_supports(ZEND_CPU_FEATURE_SSE41);
  173. }
  174. static inline int zend_cpu_supports_sse42(void) {
  175. return zend_cpu_supports(ZEND_CPU_FEATURE_SSE42);
  176. }
  177. static inline int zend_cpu_supports_avx(void) {
  178. return zend_cpu_supports(ZEND_CPU_FEATURE_AVX);
  179. }
  180. static inline int zend_cpu_supports_avx2(void) {
  181. return zend_cpu_supports(ZEND_CPU_FEATURE_AVX2);
  182. }
  183. #endif
  184. /* __builtin_cpu_supports has pclmul from gcc9 */
  185. #if PHP_HAVE_BUILTIN_CPU_SUPPORTS && (!defined(__GNUC__) || (ZEND_GCC_VERSION >= 9000))
  186. ZEND_NO_SANITIZE_ADDRESS
  187. static inline int zend_cpu_supports_pclmul() {
  188. #if PHP_HAVE_BUILTIN_CPU_INIT
  189. __builtin_cpu_init();
  190. #endif
  191. return __builtin_cpu_supports("pclmul");
  192. }
  193. #else
  194. static inline int zend_cpu_supports_pclmul(void) {
  195. return zend_cpu_supports(ZEND_CPU_FEATURE_PCLMULQDQ);
  196. }
  197. #endif
  198. #endif