HardwareCapabilities.cs 3.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. using System;
  2. using System.Runtime.Intrinsics.X86;
  3. namespace ARMeilleure.CodeGen.X86
  4. {
  5. static class HardwareCapabilities
  6. {
  7. static HardwareCapabilities()
  8. {
  9. if (!X86Base.IsSupported)
  10. {
  11. return;
  12. }
  13. (int maxNum, _, _, _) = X86Base.CpuId(0x00000000, 0x00000000);
  14. (_, _, int ecx1, int edx1) = X86Base.CpuId(0x00000001, 0x00000000);
  15. FeatureInfo1Edx = (FeatureFlags1Edx)edx1;
  16. FeatureInfo1Ecx = (FeatureFlags1Ecx)ecx1;
  17. if (maxNum >= 7)
  18. {
  19. (_, int ebx7, int ecx7, _) = X86Base.CpuId(0x00000007, 0x00000000);
  20. FeatureInfo7Ebx = (FeatureFlags7Ebx)ebx7;
  21. FeatureInfo7Ecx = (FeatureFlags7Ecx)ecx7;
  22. }
  23. }
  24. [Flags]
  25. public enum FeatureFlags1Edx
  26. {
  27. Sse = 1 << 25,
  28. Sse2 = 1 << 26
  29. }
  30. [Flags]
  31. public enum FeatureFlags1Ecx
  32. {
  33. Sse3 = 1 << 0,
  34. Pclmulqdq = 1 << 1,
  35. Ssse3 = 1 << 9,
  36. Fma = 1 << 12,
  37. Sse41 = 1 << 19,
  38. Sse42 = 1 << 20,
  39. Popcnt = 1 << 23,
  40. Aes = 1 << 25,
  41. Avx = 1 << 28,
  42. F16c = 1 << 29
  43. }
  44. [Flags]
  45. public enum FeatureFlags7Ebx
  46. {
  47. Avx2 = 1 << 5,
  48. Sha = 1 << 29
  49. }
  50. [Flags]
  51. public enum FeatureFlags7Ecx
  52. {
  53. Gfni = 1 << 8,
  54. }
  55. public static FeatureFlags1Edx FeatureInfo1Edx { get; }
  56. public static FeatureFlags1Ecx FeatureInfo1Ecx { get; }
  57. public static FeatureFlags7Ebx FeatureInfo7Ebx { get; } = 0;
  58. public static FeatureFlags7Ecx FeatureInfo7Ecx { get; } = 0;
  59. public static bool SupportsSse => FeatureInfo1Edx.HasFlag(FeatureFlags1Edx.Sse);
  60. public static bool SupportsSse2 => FeatureInfo1Edx.HasFlag(FeatureFlags1Edx.Sse2);
  61. public static bool SupportsSse3 => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Sse3);
  62. public static bool SupportsPclmulqdq => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Pclmulqdq);
  63. public static bool SupportsSsse3 => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Ssse3);
  64. public static bool SupportsFma => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Fma);
  65. public static bool SupportsSse41 => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Sse41);
  66. public static bool SupportsSse42 => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Sse42);
  67. public static bool SupportsPopcnt => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Popcnt);
  68. public static bool SupportsAesni => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Aes);
  69. public static bool SupportsAvx => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.Avx);
  70. public static bool SupportsAvx2 => FeatureInfo7Ebx.HasFlag(FeatureFlags7Ebx.Avx2) && SupportsAvx;
  71. public static bool SupportsF16c => FeatureInfo1Ecx.HasFlag(FeatureFlags1Ecx.F16c);
  72. public static bool SupportsSha => FeatureInfo7Ebx.HasFlag(FeatureFlags7Ebx.Sha);
  73. public static bool SupportsGfni => FeatureInfo7Ecx.HasFlag(FeatureFlags7Ecx.Gfni);
  74. public static bool ForceLegacySse { get; set; }
  75. public static bool SupportsVexEncoding => SupportsAvx && !ForceLegacySse;
  76. }
  77. }