OpenSDE Packages Database (without history before r20070)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

193 lines
5.8 KiB

  1. /*
  2. * --- SDE-COPYRIGHT-NOTE-BEGIN ---
  3. * This copyright note is auto-generated by ./scripts/Create-CopyPatch.
  4. *
  5. * Filename: package/.../glibc/include-old-gcc/cpuid.h
  6. * Copyright (C) 2010 The OpenSDE Project
  7. *
  8. * More information can be found in the files COPYING and README.
  9. *
  10. * This program is free software; you can redistribute it and/or modify
  11. * it under the terms of the GNU General Public License as published by
  12. * the Free Software Foundation; version 2 of the License. A copy of the
  13. * GNU General Public License can be found in the file COPYING.
  14. * --- SDE-COPYRIGHT-NOTE-END ---
  15. */
  16. /*
  17. * Copyright (C) 2007, 2008, 2009 Free Software Foundation, Inc.
  18. *
  19. * This file is free software; you can redistribute it and/or modify it
  20. * under the terms of the GNU General Public License as published by the
  21. * Free Software Foundation; either version 3, or (at your option) any
  22. * later version.
  23. *
  24. * This file is distributed in the hope that it will be useful, but
  25. * WITHOUT ANY WARRANTY; without even the implied warranty of
  26. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  27. * General Public License for more details.
  28. *
  29. * Under Section 7 of GPL version 3, you are granted additional
  30. * permissions described in the GCC Runtime Library Exception, version
  31. * 3.1, as published by the Free Software Foundation.
  32. *
  33. * You should have received a copy of the GNU General Public License and
  34. * a copy of the GCC Runtime Library Exception along with this program;
  35. * see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
  36. * <http://www.gnu.org/licenses/>.
  37. */
  38. /* %ecx */
  39. #define bit_SSE3 (1 << 0)
  40. #define bit_PCLMUL (1 << 1)
  41. #define bit_SSSE3 (1 << 9)
  42. #define bit_FMA (1 << 12)
  43. #define bit_CMPXCHG16B (1 << 13)
  44. #define bit_SSE4_1 (1 << 19)
  45. #define bit_SSE4_2 (1 << 20)
  46. #define bit_POPCNT (1 << 23)
  47. #define bit_AES (1 << 25)
  48. #define bit_XSAVE (1 << 26)
  49. #define bit_OSXSAVE (1 << 27)
  50. #define bit_AVX (1 << 28)
  51. /* %edx */
  52. #define bit_CMPXCHG8B (1 << 8)
  53. #define bit_CMOV (1 << 15)
  54. #define bit_MMX (1 << 23)
  55. #define bit_FXSAVE (1 << 24)
  56. #define bit_SSE (1 << 25)
  57. #define bit_SSE2 (1 << 26)
  58. /* Extended Features */
  59. /* %ecx */
  60. #define bit_LAHF_LM (1 << 0)
  61. #define bit_SSE4a (1 << 6)
  62. #define bit_SSE5 (1 << 11)
  63. /* %edx */
  64. #define bit_LM (1 << 29)
  65. #define bit_3DNOWP (1 << 30)
  66. #define bit_3DNOW (1 << 31)
  67. #if defined(__i386__) && defined(__PIC__)
  68. /* %ebx may be the PIC register. */
  69. #if __GNUC__ >= 3
  70. #define __cpuid(level, a, b, c, d) \
  71. __asm__ ("xchg{l}\t{%%}ebx, %1\n\t" \
  72. "cpuid\n\t" \
  73. "xchg{l}\t{%%}ebx, %1\n\t" \
  74. : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
  75. : "0" (level))
  76. #define __cpuid_count(level, count, a, b, c, d) \
  77. __asm__ ("xchg{l}\t{%%}ebx, %1\n\t" \
  78. "cpuid\n\t" \
  79. "xchg{l}\t{%%}ebx, %1\n\t" \
  80. : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
  81. : "0" (level), "2" (count))
  82. #else
  83. /* Host GCCs older than 3.0 weren't supporting Intel asm syntax
  84. nor alternatives in i386 code. */
  85. #define __cpuid(level, a, b, c, d) \
  86. __asm__ ("xchgl\t%%ebx, %1\n\t" \
  87. "cpuid\n\t" \
  88. "xchgl\t%%ebx, %1\n\t" \
  89. : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
  90. : "0" (level))
  91. #define __cpuid_count(level, count, a, b, c, d) \
  92. __asm__ ("xchgl\t%%ebx, %1\n\t" \
  93. "cpuid\n\t" \
  94. "xchgl\t%%ebx, %1\n\t" \
  95. : "=a" (a), "=r" (b), "=c" (c), "=d" (d) \
  96. : "0" (level), "2" (count))
  97. #endif
  98. #else
  99. #define __cpuid(level, a, b, c, d) \
  100. __asm__ ("cpuid\n\t" \
  101. : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \
  102. : "0" (level))
  103. #define __cpuid_count(level, count, a, b, c, d) \
  104. __asm__ ("cpuid\n\t" \
  105. : "=a" (a), "=b" (b), "=c" (c), "=d" (d) \
  106. : "0" (level), "2" (count))
  107. #endif
  108. /* Return highest supported input value for cpuid instruction. ext can
  109. be either 0x0 or 0x8000000 to return highest supported value for
  110. basic or extended cpuid information. Function returns 0 if cpuid
  111. is not supported or whatever cpuid returns in eax register. If sig
  112. pointer is non-null, then first four bytes of the signature
  113. (as found in ebx register) are returned in location pointed by sig. */
  114. static __inline unsigned int
  115. __get_cpuid_max (unsigned int __ext, unsigned int *__sig)
  116. {
  117. unsigned int __eax, __ebx, __ecx, __edx;
  118. #ifndef __x86_64__
  119. #if __GNUC__ >= 3
  120. /* See if we can use cpuid. On AMD64 we always can. */
  121. __asm__ ("pushf{l|d}\n\t"
  122. "pushf{l|d}\n\t"
  123. "pop{l}\t%0\n\t"
  124. "mov{l}\t{%0, %1|%1, %0}\n\t"
  125. "xor{l}\t{%2, %0|%0, %2}\n\t"
  126. "push{l}\t%0\n\t"
  127. "popf{l|d}\n\t"
  128. "pushf{l|d}\n\t"
  129. "pop{l}\t%0\n\t"
  130. "popf{l|d}\n\t"
  131. : "=&r" (__eax), "=&r" (__ebx)
  132. : "i" (0x00200000));
  133. #else
  134. /* Host GCCs older than 3.0 weren't supporting Intel asm syntax
  135. nor alternatives in i386 code. */
  136. __asm__ ("pushfl\n\t"
  137. "pushfl\n\t"
  138. "popl\t%0\n\t"
  139. "movl\t%0, %1\n\t"
  140. "xorl\t%2, %0\n\t"
  141. "pushl\t%0\n\t"
  142. "popfl\n\t"
  143. "pushfl\n\t"
  144. "popl\t%0\n\t"
  145. "popfl\n\t"
  146. : "=&r" (__eax), "=&r" (__ebx)
  147. : "i" (0x00200000));
  148. #endif
  149. if (!((__eax ^ __ebx) & 0x00200000))
  150. return 0;
  151. #endif
  152. /* Host supports cpuid. Return highest supported cpuid input value. */
  153. __cpuid (__ext, __eax, __ebx, __ecx, __edx);
  154. if (__sig)
  155. *__sig = __ebx;
  156. return __eax;
  157. }
  158. /* Return cpuid data for requested cpuid level, as found in returned
  159. eax, ebx, ecx and edx registers. The function checks if cpuid is
  160. supported and returns 1 for valid cpuid information or 0 for
  161. unsupported cpuid level. All pointers are required to be non-null. */
  162. static __inline int
  163. __get_cpuid (unsigned int __level,
  164. unsigned int *__eax, unsigned int *__ebx,
  165. unsigned int *__ecx, unsigned int *__edx)
  166. {
  167. unsigned int __ext = __level & 0x80000000;
  168. if (__get_cpuid_max (__ext, 0) < __level)
  169. return 0;
  170. __cpuid (__level, *__eax, *__ebx, *__ecx, *__edx);
  171. return 1;
  172. }