zend_cpuinfo.h 7.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. /*
  2. +----------------------------------------------------------------------+
  3. | Zend Engine |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 2018-2018 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 <xinchen.h@zend.com> |
  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 (1<<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();
  94. ZEND_API int zend_cpu_supports(zend_cpu_feature feature);
  95. /* Address sanitizer is incompatible with ifunc resolvers, so exclude the
  96. * CPU support helpers from asan.
  97. * See also https://github.com/google/sanitizers/issues/342. */
  98. #if __has_attribute(no_sanitize_address)
  99. # define ZEND_NO_SANITIZE_ADDRESS __attribute__((no_sanitize_address))
  100. #else
  101. # define ZEND_NO_SANITIZE_ADDRESS
  102. #endif
  103. #if PHP_HAVE_BUILTIN_CPU_SUPPORTS
  104. /* NOTE: you should use following inline function in
  105. * resolver functions (ifunc), as it could be called
  106. * before all PLT symbols are resloved. in other words,
  107. * resolver functions should not depends any external
  108. * functions */
  109. ZEND_NO_SANITIZE_ADDRESS
  110. static zend_always_inline int zend_cpu_supports_sse2() {
  111. #if PHP_HAVE_BUILTIN_CPU_INIT
  112. __builtin_cpu_init();
  113. #endif
  114. return __builtin_cpu_supports("sse2");
  115. }
  116. ZEND_NO_SANITIZE_ADDRESS
  117. static zend_always_inline int zend_cpu_supports_sse3() {
  118. #if PHP_HAVE_BUILTIN_CPU_INIT
  119. __builtin_cpu_init();
  120. #endif
  121. return __builtin_cpu_supports("sse3");
  122. }
  123. ZEND_NO_SANITIZE_ADDRESS
  124. static zend_always_inline int zend_cpu_supports_ssse3() {
  125. #if PHP_HAVE_BUILTIN_CPU_INIT
  126. __builtin_cpu_init();
  127. #endif
  128. return __builtin_cpu_supports("ssse3");
  129. }
  130. ZEND_NO_SANITIZE_ADDRESS
  131. static zend_always_inline int zend_cpu_supports_sse41() {
  132. #if PHP_HAVE_BUILTIN_CPU_INIT
  133. __builtin_cpu_init();
  134. #endif
  135. return __builtin_cpu_supports("sse4.1");
  136. }
  137. ZEND_NO_SANITIZE_ADDRESS
  138. static zend_always_inline int zend_cpu_supports_sse42() {
  139. #if PHP_HAVE_BUILTIN_CPU_INIT
  140. __builtin_cpu_init();
  141. #endif
  142. return __builtin_cpu_supports("sse4.2");
  143. }
  144. ZEND_NO_SANITIZE_ADDRESS
  145. static zend_always_inline int zend_cpu_supports_avx() {
  146. #if PHP_HAVE_BUILTIN_CPU_INIT
  147. __builtin_cpu_init();
  148. #endif
  149. return __builtin_cpu_supports("avx");
  150. }
  151. ZEND_NO_SANITIZE_ADDRESS
  152. static zend_always_inline int zend_cpu_supports_avx2() {
  153. #if PHP_HAVE_BUILTIN_CPU_INIT
  154. __builtin_cpu_init();
  155. #endif
  156. return __builtin_cpu_supports("avx2");
  157. }
  158. #else
  159. static zend_always_inline int zend_cpu_supports_sse2() {
  160. return zend_cpu_supports(ZEND_CPU_FEATURE_SSE2);
  161. }
  162. static zend_always_inline int zend_cpu_supports_sse3() {
  163. return zend_cpu_supports(ZEND_CPU_FEATURE_SSE3);
  164. }
  165. static zend_always_inline int zend_cpu_supports_ssse3() {
  166. return zend_cpu_supports(ZEND_CPU_FEATURE_SSSE3);
  167. }
  168. static zend_always_inline int zend_cpu_supports_sse41() {
  169. return zend_cpu_supports(ZEND_CPU_FEATURE_SSE41);
  170. }
  171. static zend_always_inline int zend_cpu_supports_sse42() {
  172. return zend_cpu_supports(ZEND_CPU_FEATURE_SSE42);
  173. }
  174. static zend_always_inline int zend_cpu_supports_avx() {
  175. return zend_cpu_supports(ZEND_CPU_FEATURE_AVX);
  176. }
  177. static zend_always_inline int zend_cpu_supports_avx2() {
  178. return zend_cpu_supports(ZEND_CPU_FEATURE_AVX2);
  179. }
  180. #endif
  181. #endif
  182. /*
  183. * Local variables:
  184. * tab-width: 4
  185. * c-basic-offset: 4
  186. * indent-tabs-mode: t
  187. * End:
  188. */