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:
Bernhard Miklautz
2015-05-26 16:41:29 +02:00
parent 83d5b26a46
commit f9c7e03044
8 changed files with 98 additions and 45 deletions

1
winpr/test/.gitignore vendored Normal file
View File

@@ -0,0 +1 @@
TestWinpr.c

24
winpr/test/CMakeLists.txt Normal file
View 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")

View 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;
}