Merge pull request #2653 from bmiklautz/lzcnt

winpr: add intrin.h
This commit is contained in:
Marc-André Moreau 2015-05-27 09:00:22 -04:00
commit a2e0746f15
8 changed files with 101 additions and 50 deletions

View File

@ -34,6 +34,7 @@
#include <winpr/print.h>
#include <winpr/sysinfo.h>
#include <winpr/bitstream.h>
#include <winpr/intrin.h>
#include "rfx_bitstream.h"

View File

@ -75,6 +75,10 @@ if(NOT ANDROID AND NOT IOS)
add_subdirectory(tools)
endif()
if(BUILD_TESTING)
add_subdirectory(test)
endif()
# Exporting
if(${CMAKE_VERSION} VERSION_GREATER "2.8.10")

View File

@ -95,50 +95,7 @@ static INLINE UINT16 _byteswap_ushort(UINT16 _val) {
#endif
/**
* __lzcnt16, __lzcnt, __lzcnt64:
* http://msdn.microsoft.com/en-us/library/bb384809/
*/
#if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2))
/**
* __lzcnt16, __lzcnt, __lzcnt64:
* http://msdn.microsoft.com/en-us/library/bb384809/
*
* Beware: the result of __builtin_clz(0) is undefined
*/
static INLINE UINT32 __lzcnt(UINT32 _val32) {
return _val32 ? ((UINT32) __builtin_clz(_val32)) : 32;
}
static INLINE UINT16 __lzcnt16(UINT16 _val16) {
return _val16 ? ((UINT16) (__builtin_clz((UINT32) _val16) - 16)) : 16;
}
#else
static INLINE UINT32 __lzcnt(UINT32 x) {
unsigned 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;
}
static INLINE UINT16 __lzcnt16(UINT16 x) {
return ((UINT16) __lzcnt((UINT32) x));
}
#endif
#endif
#ifndef _WIN32
#define CopyMemory(Destination, Source, Length) memcpy((Destination), (Source), (Length))
#define MoveMemory(Destination, Source, Length) memmove((Destination), (Source), (Length))

View File

@ -0,0 +1,66 @@
/**
* WinPR: Windows Portable Runtime
* C Run-Time Library Routines
*
* Copyright 2015 Thincast Technologies GmbH
* Copyright 2015 Bernhard Miklautz <bernhard.miklautz@thincast.com>
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef WINPR_INTRIN_H
#define WINPR_INTRIN_H
#ifndef _WIN32
/**
* __lzcnt16, __lzcnt, __lzcnt64:
* http://msdn.microsoft.com/en-us/library/bb384809/
*
* Beware: the result of __builtin_clz(0) is undefined
*/
#if (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2))
static INLINE UINT32 __lzcnt(UINT32 _val32) {
return ((UINT32) __builtin_clz(_val32));
}
static INLINE UINT16 __lzcnt16(UINT16 _val16) {
return ((UINT16) (__builtin_clz((UINT32) _val16) - 16));
}
#else /* (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2) */
static INLINE UINT32 __lzcnt(UINT32 x)
{
unsigned 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;
}
static INLINE UINT16 __lzcnt16(UINT16 x)
{
return ((UINT16) __lzcnt((UINT32) x));
}
#endif /* (__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ >= 2) */
#endif /* _WIN32 */
#endif /* WINPR_INTRIN_H */

View File

@ -8,7 +8,6 @@ set(${MODULE_PREFIX}_TESTS
TestTypes.c
TestAlignment.c
TestString.c
TestIntrinsics.c
TestUnicodeConversion.c)
create_test_sourcelist(${MODULE_PREFIX}_SRCS

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

@ -1,8 +1,9 @@
#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)
@ -52,7 +53,7 @@ int test_lzcnt()
return -1;
}
return 1;
return 0;
}
int test_lzcnt16()
@ -72,7 +73,7 @@ int test_lzcnt16()
return -1;
}
return 1;
return 0;
}
int TestIntrinsics(int argc, char* argv[])
@ -81,8 +82,6 @@ int TestIntrinsics(int argc, char* argv[])
printf("LZCNT available: %d\n", g_LZCNT);
test_lzcnt();
//test_lzcnt16();
return 0;
return test_lzcnt();
}