mirror of
https://github.com/morgan9e/FreeRDP
synced 2026-04-15 00:44:19 +09:00
winpr: add intrin.h
Exposing lzcnt in crt.h might causes compiler errors (redefinition) with recent versions of gcc (>=4.9) when winpr is included in other projects. As lzcnt isn't part of crt according to MSDN and also shouldn't be exported by default it was moved to intrin.h. The related test was also moved to the top level directory of winpr.
This commit is contained in:
1
winpr/test/.gitignore
vendored
Normal file
1
winpr/test/.gitignore
vendored
Normal file
@@ -0,0 +1 @@
|
||||
TestWinpr.c
|
||||
24
winpr/test/CMakeLists.txt
Normal file
24
winpr/test/CMakeLists.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
|
||||
set(MODULE_NAME "TestWinpr")
|
||||
set(MODULE_PREFIX "TEST_WINPR")
|
||||
|
||||
set(${MODULE_PREFIX}_DRIVER ${MODULE_NAME}.c)
|
||||
|
||||
set(${MODULE_PREFIX}_TESTS TestIntrinsics.c)
|
||||
|
||||
create_test_sourcelist(${MODULE_PREFIX}_SRCS
|
||||
${${MODULE_PREFIX}_DRIVER}
|
||||
${${MODULE_PREFIX}_TESTS})
|
||||
|
||||
add_executable(${MODULE_NAME} ${${MODULE_PREFIX}_SRCS})
|
||||
|
||||
target_link_libraries(${MODULE_NAME} winpr)
|
||||
|
||||
set_target_properties(${MODULE_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${TESTING_OUTPUT_DIRECTORY}")
|
||||
|
||||
foreach(test ${${MODULE_PREFIX}_TESTS})
|
||||
get_filename_component(TestName ${test} NAME_WE)
|
||||
add_test(${TestName} ${TESTING_OUTPUT_DIRECTORY}/${MODULE_NAME} ${TestName})
|
||||
endforeach()
|
||||
|
||||
set_property(TARGET ${MODULE_NAME} PROPERTY FOLDER "WinPR/Test")
|
||||
89
winpr/test/TestIntrinsics.c
Normal file
89
winpr/test/TestIntrinsics.c
Normal file
@@ -0,0 +1,89 @@
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/sysinfo.h>
|
||||
#include <winpr/windows.h>
|
||||
|
||||
#include <winpr/intrin.h>
|
||||
|
||||
static BOOL g_LZCNT = FALSE;
|
||||
|
||||
static INLINE UINT32 lzcnt_s(UINT32 x)
|
||||
{
|
||||
if (!x)
|
||||
return 32;
|
||||
|
||||
if (!g_LZCNT)
|
||||
{
|
||||
UINT32 y;
|
||||
int n = 32;
|
||||
y = x >> 16; if (y != 0) { n = n - 16; x = y; }
|
||||
y = x >> 8; if (y != 0) { n = n - 8; x = y; }
|
||||
y = x >> 4; if (y != 0) { n = n - 4; x = y; }
|
||||
y = x >> 2; if (y != 0) { n = n - 2; x = y; }
|
||||
y = x >> 1; if (y != 0) return n - 2;
|
||||
return n - x;
|
||||
}
|
||||
|
||||
return __lzcnt(x);
|
||||
}
|
||||
|
||||
int test_lzcnt()
|
||||
{
|
||||
if (lzcnt_s(0x1) != 31) {
|
||||
fprintf(stderr, "__lzcnt(0x1) != 31: %d\n", __lzcnt(0x1));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lzcnt_s(0xFF) != 24) {
|
||||
fprintf(stderr, "__lzcnt(0xFF) != 24\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lzcnt_s(0xFFFF) != 16) {
|
||||
fprintf(stderr, "__lzcnt(0xFFFF) != 16\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lzcnt_s(0xFFFFFF) != 8) {
|
||||
fprintf(stderr, "__lzcnt(0xFFFFFF) != 8\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (lzcnt_s(0xFFFFFFFF) != 0) {
|
||||
fprintf(stderr, "__lzcnt(0xFFFFFFFF) != 0\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int test_lzcnt16()
|
||||
{
|
||||
if (__lzcnt16(0x1) != 15) {
|
||||
fprintf(stderr, "__lzcnt16(0x1) != 15\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (__lzcnt16(0xFF) != 8) {
|
||||
fprintf(stderr, "__lzcnt16(0xFF) != 8\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (__lzcnt16(0xFFFF) != 0) {
|
||||
fprintf(stderr, "__lzcnt16(0xFFFF) != 0\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int TestIntrinsics(int argc, char* argv[])
|
||||
{
|
||||
g_LZCNT = IsProcessorFeaturePresentEx(PF_EX_LZCNT);
|
||||
|
||||
printf("LZCNT available: %d\n", g_LZCNT);
|
||||
|
||||
test_lzcnt();
|
||||
//test_lzcnt16();
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user