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