TestIntrinsics.c 1.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #include <winpr/crt.h>
  2. #include <winpr/sysinfo.h>
  3. #include <winpr/windows.h>
  4. #include <winpr/intrin.h>
  5. static BOOL g_LZCNT = FALSE;
  6. static INLINE UINT32 lzcnt_s(UINT32 x)
  7. {
  8. if (!x)
  9. return 32;
  10. if (!g_LZCNT)
  11. {
  12. UINT32 y;
  13. int n = 32;
  14. y = x >> 16;
  15. if (y != 0)
  16. {
  17. n = n - 16;
  18. x = y;
  19. }
  20. y = x >> 8;
  21. if (y != 0)
  22. {
  23. n = n - 8;
  24. x = y;
  25. }
  26. y = x >> 4;
  27. if (y != 0)
  28. {
  29. n = n - 4;
  30. x = y;
  31. }
  32. y = x >> 2;
  33. if (y != 0)
  34. {
  35. n = n - 2;
  36. x = y;
  37. }
  38. y = x >> 1;
  39. if (y != 0)
  40. return n - 2;
  41. return n - x;
  42. }
  43. return __lzcnt(x);
  44. }
  45. int test_lzcnt()
  46. {
  47. if (lzcnt_s(0x1) != 31)
  48. {
  49. fprintf(stderr, "__lzcnt(0x1) != 31: %" PRIu32 "\n", __lzcnt(0x1));
  50. return -1;
  51. }
  52. if (lzcnt_s(0xFF) != 24)
  53. {
  54. fprintf(stderr, "__lzcnt(0xFF) != 24\n");
  55. return -1;
  56. }
  57. if (lzcnt_s(0xFFFF) != 16)
  58. {
  59. fprintf(stderr, "__lzcnt(0xFFFF) != 16\n");
  60. return -1;
  61. }
  62. if (lzcnt_s(0xFFFFFF) != 8)
  63. {
  64. fprintf(stderr, "__lzcnt(0xFFFFFF) != 8\n");
  65. return -1;
  66. }
  67. if (lzcnt_s(0xFFFFFFFF) != 0)
  68. {
  69. fprintf(stderr, "__lzcnt(0xFFFFFFFF) != 0\n");
  70. return -1;
  71. }
  72. return 0;
  73. }
  74. int test_lzcnt16()
  75. {
  76. if (__lzcnt16(0x1) != 15)
  77. {
  78. fprintf(stderr, "__lzcnt16(0x1) != 15\n");
  79. return -1;
  80. }
  81. if (__lzcnt16(0xFF) != 8)
  82. {
  83. fprintf(stderr, "__lzcnt16(0xFF) != 8\n");
  84. return -1;
  85. }
  86. if (__lzcnt16(0xFFFF) != 0)
  87. {
  88. fprintf(stderr, "__lzcnt16(0xFFFF) != 0\n");
  89. return -1;
  90. }
  91. return 0;
  92. }
  93. int TestIntrinsics(int argc, char* argv[])
  94. {
  95. g_LZCNT = IsProcessorFeaturePresentEx(PF_EX_LZCNT);
  96. printf("LZCNT available: %" PRId32 "\n", g_LZCNT);
  97. // test_lzcnt16();
  98. return test_lzcnt();
  99. }