libfreerdp-codec: cleanup and fix __lzcnt on Windows

This commit is contained in:
Marc-André Moreau 2014-08-11 18:48:42 -04:00
parent dc7f89dbd5
commit 87fd839a35
9 changed files with 111 additions and 109 deletions

View File

@ -91,7 +91,7 @@ int encomsp_read_unicode_string(wStream* s, ENCOMSP_UNICODE_STRING* str)
if (str->cchString > 1024) if (str->cchString > 1024)
return -1; return -1;
if (Stream_GetRemainingLength(s) < (str->cchString * 2)) if (Stream_GetRemainingLength(s) < (size_t) (str->cchString * 2))
return -1; return -1;
Stream_Read(s, &(str->wString), (str->cchString * 2)); /* String (variable) */ Stream_Read(s, &(str->wString), (str->cchString * 2)); /* String (variable) */
@ -126,7 +126,7 @@ int encomsp_recv_filter_updated_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_
if ((beg + header->Length) > end) if ((beg + header->Length) > end)
{ {
if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end)) if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
return -1; return -1;
Stream_SetPosition(s, (beg + header->Length)); Stream_SetPosition(s, (beg + header->Length));
@ -171,7 +171,7 @@ int encomsp_recv_application_created_pdu(encomspPlugin* encomsp, wStream* s, ENC
if ((beg + header->Length) > end) if ((beg + header->Length) > end)
{ {
if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end)) if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
return -1; return -1;
Stream_SetPosition(s, (beg + header->Length)); Stream_SetPosition(s, (beg + header->Length));
@ -212,7 +212,7 @@ int encomsp_recv_application_removed_pdu(encomspPlugin* encomsp, wStream* s, ENC
if ((beg + header->Length) > end) if ((beg + header->Length) > end)
{ {
if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end)) if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
return -1; return -1;
Stream_SetPosition(s, (beg + header->Length)); Stream_SetPosition(s, (beg + header->Length));
@ -258,7 +258,7 @@ int encomsp_recv_window_created_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_
if ((beg + header->Length) > end) if ((beg + header->Length) > end)
{ {
if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end)) if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
return -1; return -1;
Stream_SetPosition(s, (beg + header->Length)); Stream_SetPosition(s, (beg + header->Length));
@ -299,7 +299,7 @@ int encomsp_recv_window_removed_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_
if ((beg + header->Length) > end) if ((beg + header->Length) > end)
{ {
if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end)) if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
return -1; return -1;
Stream_SetPosition(s, (beg + header->Length)); Stream_SetPosition(s, (beg + header->Length));
@ -340,7 +340,7 @@ int encomsp_recv_show_window_pdu(encomspPlugin* encomsp, wStream* s, ENCOMSP_ORD
if ((beg + header->Length) > end) if ((beg + header->Length) > end)
{ {
if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end)) if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
return -1; return -1;
Stream_SetPosition(s, (beg + header->Length)); Stream_SetPosition(s, (beg + header->Length));
@ -386,7 +386,7 @@ int encomsp_recv_participant_created_pdu(encomspPlugin* encomsp, wStream* s, ENC
if ((beg + header->Length) > end) if ((beg + header->Length) > end)
{ {
if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end)) if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
return -1; return -1;
Stream_SetPosition(s, (beg + header->Length)); Stream_SetPosition(s, (beg + header->Length));
@ -429,7 +429,7 @@ int encomsp_recv_participant_removed_pdu(encomspPlugin* encomsp, wStream* s, ENC
if ((beg + header->Length) > end) if ((beg + header->Length) > end)
{ {
if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end)) if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
return -1; return -1;
Stream_SetPosition(s, (beg + header->Length)); Stream_SetPosition(s, (beg + header->Length));
@ -471,7 +471,7 @@ int encomsp_recv_change_participant_control_level_pdu(encomspPlugin* encomsp, wS
if ((beg + header->Length) > end) if ((beg + header->Length) > end)
{ {
if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end)) if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
return -1; return -1;
Stream_SetPosition(s, (beg + header->Length)); Stream_SetPosition(s, (beg + header->Length));
@ -531,7 +531,7 @@ int encomsp_recv_graphics_stream_paused_pdu(encomspPlugin* encomsp, wStream* s,
if ((beg + header->Length) > end) if ((beg + header->Length) > end)
{ {
if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end)) if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
return -1; return -1;
Stream_SetPosition(s, (beg + header->Length)); Stream_SetPosition(s, (beg + header->Length));
@ -567,7 +567,7 @@ int encomsp_recv_graphics_stream_resumed_pdu(encomspPlugin* encomsp, wStream* s,
if ((beg + header->Length) > end) if ((beg + header->Length) > end)
{ {
if (Stream_GetRemainingLength(s) < ((beg + header->Length) - end)) if (Stream_GetRemainingLength(s) < (size_t) ((beg + header->Length) - end))
return -1; return -1;
Stream_SetPosition(s, (beg + header->Length)); Stream_SetPosition(s, (beg + header->Length));

View File

@ -203,7 +203,7 @@ int rdpgfx_recv_reset_graphics_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s
pad = 340 - (RDPGFX_HEADER_SIZE + 12 + (pdu.monitorCount * 20)); pad = 340 - (RDPGFX_HEADER_SIZE + 12 + (pdu.monitorCount * 20));
if (Stream_GetRemainingLength(s) < pad) if (Stream_GetRemainingLength(s) < (size_t) pad)
return -1; return -1;
Stream_Seek(s, pad); /* pad (total size is 340 bytes) */ Stream_Seek(s, pad); /* pad (total size is 340 bytes) */
@ -254,7 +254,7 @@ int rdpgfx_recv_cache_import_reply_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStrea
Stream_Read_UINT16(s, pdu.importedEntriesCount); /* cacheSlot (2 bytes) */ Stream_Read_UINT16(s, pdu.importedEntriesCount); /* cacheSlot (2 bytes) */
if (Stream_GetRemainingLength(s) < (pdu.importedEntriesCount * 2)) if (Stream_GetRemainingLength(s) < (size_t) (pdu.importedEntriesCount * 2))
return -1; return -1;
pdu.cacheSlots = (UINT16*) calloc(pdu.importedEntriesCount, sizeof(UINT16)); pdu.cacheSlots = (UINT16*) calloc(pdu.importedEntriesCount, sizeof(UINT16));
@ -525,7 +525,7 @@ int rdpgfx_recv_solid_fill_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream* s)
rdpgfx_read_color32(s, &(pdu.fillPixel)); /* fillPixel (4 bytes) */ rdpgfx_read_color32(s, &(pdu.fillPixel)); /* fillPixel (4 bytes) */
Stream_Read_UINT16(s, pdu.fillRectCount); /* fillRectCount (2 bytes) */ Stream_Read_UINT16(s, pdu.fillRectCount); /* fillRectCount (2 bytes) */
if (Stream_GetRemainingLength(s) < (pdu.fillRectCount * 8)) if (Stream_GetRemainingLength(s) < (size_t) (pdu.fillRectCount * 8))
return -1; return -1;
pdu.fillRects = (RDPGFX_RECT16*) calloc(pdu.fillRectCount, sizeof(RDPGFX_RECT16)); pdu.fillRects = (RDPGFX_RECT16*) calloc(pdu.fillRectCount, sizeof(RDPGFX_RECT16));
@ -566,7 +566,7 @@ int rdpgfx_recv_surface_to_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStrea
rdpgfx_read_rect16(s, &(pdu.rectSrc)); /* rectSrc (8 bytes ) */ rdpgfx_read_rect16(s, &(pdu.rectSrc)); /* rectSrc (8 bytes ) */
Stream_Read_UINT16(s, pdu.destPtsCount); /* destPtsCount (2 bytes) */ Stream_Read_UINT16(s, pdu.destPtsCount); /* destPtsCount (2 bytes) */
if (Stream_GetRemainingLength(s) < (pdu.destPtsCount * 4)) if (Stream_GetRemainingLength(s) < (size_t) (pdu.destPtsCount * 4))
return -1; return -1;
pdu.destPts = (RDPGFX_POINT16*) calloc(pdu.destPtsCount, sizeof(RDPGFX_POINT16)); pdu.destPts = (RDPGFX_POINT16*) calloc(pdu.destPtsCount, sizeof(RDPGFX_POINT16));
@ -637,7 +637,7 @@ int rdpgfx_recv_cache_to_surface_pdu(RDPGFX_CHANNEL_CALLBACK* callback, wStream*
Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */ Stream_Read_UINT16(s, pdu.surfaceId); /* surfaceId (2 bytes) */
Stream_Read_UINT16(s, pdu.destPtsCount); /* destPtsCount (2 bytes) */ Stream_Read_UINT16(s, pdu.destPtsCount); /* destPtsCount (2 bytes) */
if (Stream_GetRemainingLength(s) < (pdu.destPtsCount * 4)) if (Stream_GetRemainingLength(s) < (size_t) (pdu.destPtsCount * 4))
return -1; return -1;
pdu.destPts = (RDPGFX_POINT16*) calloc(pdu.destPtsCount, sizeof(RDPGFX_POINT16)); pdu.destPts = (RDPGFX_POINT16*) calloc(pdu.destPtsCount, sizeof(RDPGFX_POINT16));
@ -847,7 +847,7 @@ static int rdpgfx_on_data_received(IWTSVirtualChannelCallback* pChannelCallback,
s = Stream_New(pDstData, DstSize); s = Stream_New(pDstData, DstSize);
while (Stream_GetPosition(s) < Stream_Length(s)) while (((size_t) Stream_GetPosition(s)) < Stream_Length(s))
{ {
status = rdpgfx_recv_pdu(callback, s); status = rdpgfx_recv_pdu(callback, s);

View File

@ -135,14 +135,14 @@ int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize,
if (!glyphData) if (!glyphData)
return -1010; return -1010;
if ((nWidth * nHeight) > glyphEntry->count) if ((nWidth * nHeight) > (int) glyphEntry->count)
return -1011; return -1011;
nSrcStep = nWidth * 4; nSrcStep = nWidth * 4;
pSrcPixel8 = glyphData; pSrcPixel8 = glyphData;
pDstPixel8 = &pDstData[(nYDst * nDstStep) + (nXDst * 4)]; pDstPixel8 = &pDstData[(nYDst * nDstStep) + (nXDst * 4)];
for (y = 0; y < nHeight; y++) for (y = 0; y < (UINT32) nHeight; y++)
{ {
CopyMemory(pDstPixel8, pSrcPixel8, nSrcStep); CopyMemory(pDstPixel8, pSrcPixel8, nSrcStep);
pSrcPixel8 += nSrcStep; pSrcPixel8 += nSrcStep;
@ -177,7 +177,7 @@ int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize,
suboffset = 0; suboffset = 0;
residualData = &pSrcData[offset]; residualData = &pSrcData[offset];
if ((nWidth * nHeight * 4) > clear->TempSize) if ((nWidth * nHeight * 4) > (int) clear->TempSize)
{ {
clear->TempSize = (nWidth * nHeight * 4); clear->TempSize = (nWidth * nHeight * 4);
clear->TempBuffer = (BYTE*) realloc(clear->TempBuffer, clear->TempSize); clear->TempBuffer = (BYTE*) realloc(clear->TempBuffer, clear->TempSize);
@ -238,7 +238,7 @@ int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize,
if (pixelIndex != pixelCount) if (pixelIndex != pixelCount)
return -1019; return -1019;
for (y = 0; y < nHeight; y++) for (y = 0; y < (UINT32) nHeight; y++)
{ {
CopyMemory(pDstPixel8, pSrcPixel8, nSrcStep); CopyMemory(pDstPixel8, pSrcPixel8, nSrcStep);
pSrcPixel8 += nSrcStep; pSrcPixel8 += nSrcStep;
@ -543,7 +543,7 @@ int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize,
if (height > nHeight) if (height > nHeight)
return -1043; return -1043;
if ((width * height * 4) > clear->TempSize) if (((UINT32) (width * height * 4)) > clear->TempSize)
{ {
clear->TempSize = (width * height * 4); clear->TempSize = (width * height * 4);
clear->TempBuffer = (BYTE*) realloc(clear->TempBuffer, clear->TempSize); clear->TempBuffer = (BYTE*) realloc(clear->TempBuffer, clear->TempSize);
@ -732,7 +732,7 @@ int clear_decompress(CLEAR_CONTEXT* clear, BYTE* pSrcData, UINT32 SrcSize,
pDstPixel8 = glyphData; pDstPixel8 = glyphData;
pSrcPixel8 = &pDstData[(nYDst * nDstStep) + (nXDst * 4)]; pSrcPixel8 = &pDstData[(nYDst * nDstStep) + (nXDst * 4)];
for (y = 0; y < nHeight; y++) for (y = 0; y < (UINT32) nHeight; y++)
{ {
CopyMemory(pDstPixel8, pSrcPixel8, nSrcStep); CopyMemory(pDstPixel8, pSrcPixel8, nSrcStep);
pDstPixel8 += nSrcStep; pDstPixel8 += nSrcStep;

View File

@ -32,6 +32,7 @@
#include <winpr/crt.h> #include <winpr/crt.h>
#include <winpr/print.h> #include <winpr/print.h>
#include <winpr/sysinfo.h>
#include <winpr/bitstream.h> #include <winpr/bitstream.h>
#include "rfx_bitstream.h" #include "rfx_bitstream.h"
@ -72,6 +73,28 @@
_k = (_param >> LSGR); \ _k = (_param >> LSGR); \
} }
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 rfx_rlgr_decode(const BYTE* pSrcData, UINT32 SrcSize, INT16* pDstData, UINT32 DstSize, int mode) int rfx_rlgr_decode(const BYTE* pSrcData, UINT32 SrcSize, INT16* pDstData, UINT32 DstSize, int mode)
{ {
int vk; int vk;
@ -92,6 +115,8 @@ int rfx_rlgr_decode(const BYTE* pSrcData, UINT32 SrcSize, INT16* pDstData, UINT3
wBitStream* bs; wBitStream* bs;
wBitStream s_bs; wBitStream s_bs;
g_LZCNT = IsProcessorFeaturePresentEx(PF_EX_LZCNT);
k = 1; k = 1;
kp = k << LSGR; kp = k << LSGR;
@ -124,7 +149,7 @@ int rfx_rlgr_decode(const BYTE* pSrcData, UINT32 SrcSize, INT16* pDstData, UINT3
/* count number of leading 0s */ /* count number of leading 0s */
cnt = __lzcnt(bs->accumulator); cnt = lzcnt_s(bs->accumulator);
nbits = BitStream_GetRemainingLength(bs); nbits = BitStream_GetRemainingLength(bs);
@ -137,7 +162,7 @@ int rfx_rlgr_decode(const BYTE* pSrcData, UINT32 SrcSize, INT16* pDstData, UINT3
{ {
BitStream_Shift32(bs); BitStream_Shift32(bs);
cnt = __lzcnt(bs->accumulator); cnt = lzcnt_s(bs->accumulator);
nbits = BitStream_GetRemainingLength(bs); nbits = BitStream_GetRemainingLength(bs);
@ -187,7 +212,7 @@ int rfx_rlgr_decode(const BYTE* pSrcData, UINT32 SrcSize, INT16* pDstData, UINT3
/* count number of leading 1s */ /* count number of leading 1s */
cnt = __lzcnt(~(bs->accumulator)); cnt = lzcnt_s(~(bs->accumulator));
nbits = BitStream_GetRemainingLength(bs); nbits = BitStream_GetRemainingLength(bs);
@ -200,7 +225,7 @@ int rfx_rlgr_decode(const BYTE* pSrcData, UINT32 SrcSize, INT16* pDstData, UINT3
{ {
BitStream_Shift32(bs); BitStream_Shift32(bs);
cnt = __lzcnt(~(bs->accumulator)); cnt = lzcnt_s(~(bs->accumulator));
nbits = BitStream_GetRemainingLength(bs); nbits = BitStream_GetRemainingLength(bs);
@ -295,7 +320,7 @@ int rfx_rlgr_decode(const BYTE* pSrcData, UINT32 SrcSize, INT16* pDstData, UINT3
/* count number of leading 1s */ /* count number of leading 1s */
cnt = __lzcnt(~(bs->accumulator)); cnt = lzcnt_s(~(bs->accumulator));
nbits = BitStream_GetRemainingLength(bs); nbits = BitStream_GetRemainingLength(bs);
@ -308,7 +333,7 @@ int rfx_rlgr_decode(const BYTE* pSrcData, UINT32 SrcSize, INT16* pDstData, UINT3
{ {
BitStream_Shift32(bs); BitStream_Shift32(bs);
cnt = __lzcnt(~(bs->accumulator)); cnt = lzcnt_s(~(bs->accumulator));
nbits = BitStream_GetRemainingLength(bs); nbits = BitStream_GetRemainingLength(bs);
@ -411,7 +436,7 @@ int rfx_rlgr_decode(const BYTE* pSrcData, UINT32 SrcSize, INT16* pDstData, UINT3
if (code) if (code)
{ {
mag = (UINT32) code; mag = (UINT32) code;
nIdx = 32 - __lzcnt(mag); nIdx = 32 - lzcnt_s(mag);
} }
if (BitStream_GetRemainingLength(bs) < nIdx) if (BitStream_GetRemainingLength(bs) < nIdx)

View File

@ -182,7 +182,7 @@ BOOL tpdu_read_connection_confirm(wStream* s, BYTE* li)
*/ */
bytes_read = (Stream_GetPosition(s) - position) - 1; bytes_read = (Stream_GetPosition(s) - position) - 1;
return (Stream_GetRemainingLength(s) >= (*li - bytes_read)); return (Stream_GetRemainingLength(s) >= (size_t) (*li - bytes_read));
} }
/** /**

View File

@ -104,10 +104,6 @@ static INLINE UINT16 __lzcnt16(UINT16 _val16) {
return _val16 ? ((UINT16) (__builtin_clz((UINT32) _val16) - 16)) : 16; return _val16 ? ((UINT16) (__builtin_clz((UINT32) _val16) - 16)) : 16;
} }
static INLINE UINT64 __lzcnt64(UINT64 _val64) {
return _val64 ? ((UINT64) __builtin_clzll(_val64)) : 64;
}
#else #else
static INLINE UINT32 __lzcnt(UINT32 x) { static INLINE UINT32 __lzcnt(UINT32 x) {
@ -125,10 +121,6 @@ static INLINE UINT16 __lzcnt16(UINT16 x) {
return ((UINT16) __lzcnt((UINT32) x)); return ((UINT16) __lzcnt((UINT32) x));
} }
static INLINE UINT64 __lzcnt64(UINT64 x) {
return 0; /* TODO */
}
#endif #endif
#endif #endif

View File

@ -298,20 +298,21 @@ WINPR_API ULONGLONG GetTickCount64(void);
WINPR_API BOOL IsProcessorFeaturePresentEx(DWORD ProcessorFeature); WINPR_API BOOL IsProcessorFeaturePresentEx(DWORD ProcessorFeature);
/* extended flags */ /* extended flags */
#define PF_EX_3DNOW_PREFETCH 1 #define PF_EX_LZCNT 1
#define PF_EX_SSSE3 2 #define PF_EX_3DNOW_PREFETCH 2
#define PF_EX_SSE41 3 #define PF_EX_SSSE3 3
#define PF_EX_SSE42 4 #define PF_EX_SSE41 4
#define PF_EX_AVX 5 #define PF_EX_SSE42 5
#define PF_EX_FMA 6 #define PF_EX_AVX 6
#define PF_EX_AVX_AES 7 #define PF_EX_FMA 7
#define PF_EX_AVX2 8 #define PF_EX_AVX_AES 8
#define PF_EX_ARM_VFP1 9 #define PF_EX_AVX2 9
#define PF_EX_ARM_VFP3D16 10 #define PF_EX_ARM_VFP1 10
#define PF_EX_ARM_VFP4 11 #define PF_EX_ARM_VFP3D16 11
#define PF_EX_ARM_IDIVA 12 #define PF_EX_ARM_VFP4 12
#define PF_EX_ARM_IDIVT 13 #define PF_EX_ARM_IDIVA 13
#define PF_EX_AVX_PCLMULQDQ 14 #define PF_EX_ARM_IDIVT 14
#define PF_EX_AVX_PCLMULQDQ 15
/* /*
* some "aliases" for the standard defines * some "aliases" for the standard defines

View File

@ -1,36 +1,53 @@
#include <stdio.h>
#include <winpr/crt.h> #include <winpr/crt.h>
#include <winpr/sysinfo.h>
#include <winpr/windows.h> #include <winpr/windows.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() int test_lzcnt()
{ {
if (__lzcnt(0x0) != 32) { if (lzcnt_s(0x1) != 31) {
fprintf(stderr, "__lzcnt(0x0) != 32\n"); fprintf(stderr, "__lzcnt(0x1) != 31: %d\n", __lzcnt(0x1));
return -1; return -1;
} }
if (__lzcnt(0x1) != 31) { if (lzcnt_s(0xFF) != 24) {
fprintf(stderr, "__lzcnt(0x1) != 31\n");
return -1;
}
if (__lzcnt(0xFF) != 24) {
fprintf(stderr, "__lzcnt(0xFF) != 24\n"); fprintf(stderr, "__lzcnt(0xFF) != 24\n");
return -1; return -1;
} }
if (__lzcnt(0xFFFF) != 16) { if (lzcnt_s(0xFFFF) != 16) {
fprintf(stderr, "__lzcnt(0xFFFF) != 16\n"); fprintf(stderr, "__lzcnt(0xFFFF) != 16\n");
return -1; return -1;
} }
if (__lzcnt(0xFFFFFF) != 8) { if (lzcnt_s(0xFFFFFF) != 8) {
fprintf(stderr, "__lzcnt(0xFFFFFF) != 8\n"); fprintf(stderr, "__lzcnt(0xFFFFFF) != 8\n");
return -1; return -1;
} }
if (__lzcnt(0xFFFFFFFF) != 0) { if (lzcnt_s(0xFFFFFFFF) != 0) {
fprintf(stderr, "__lzcnt(0xFFFFFFFF) != 0\n"); fprintf(stderr, "__lzcnt(0xFFFFFFFF) != 0\n");
return -1; return -1;
} }
@ -40,11 +57,6 @@ int test_lzcnt()
int test_lzcnt16() int test_lzcnt16()
{ {
if (__lzcnt16(0x0) != 16) {
fprintf(stderr, "__lzcnt16(0x0) != 16\n");
return -1;
}
if (__lzcnt16(0x1) != 15) { if (__lzcnt16(0x1) != 15) {
fprintf(stderr, "__lzcnt16(0x1) != 15\n"); fprintf(stderr, "__lzcnt16(0x1) != 15\n");
return -1; return -1;
@ -63,47 +75,14 @@ int test_lzcnt16()
return 1; return 1;
} }
int test_lzcnt64()
{
if (__lzcnt64(0x0) != 64) {
fprintf(stderr, "__lzcnt64(0x0) != 64\n");
return -1;
}
if (__lzcnt64(0x1) != 63) {
fprintf(stderr, "__lzcnt64(0x1) != 63\n");
return -1;
}
if (__lzcnt64(0xFF) != 56) {
fprintf(stderr, "__lzcnt64(0xFF) != 56\n");
return -1;
}
if (__lzcnt64(0xFFFF) != 48) {
fprintf(stderr, "__lzcnt64(0xFFFF) != 48\n");
return -1;
}
if (__lzcnt64(0xFFFFFF) != 40) {
fprintf(stderr, "__lzcnt64(0xFFFFFF) != 40\n");
return -1;
}
if (__lzcnt64(0xFFFFFFFF) != 32) {
fprintf(stderr, "__lzcnt64(0xFFFFFFFF) != 32\n");
return -1;
}
return 1;
}
int TestIntrinsics(int argc, char* argv[]) int TestIntrinsics(int argc, char* argv[])
{ {
g_LZCNT = IsProcessorFeaturePresentEx(PF_EX_LZCNT);
printf("LZCNT available: %d\n", g_LZCNT);
test_lzcnt(); test_lzcnt();
test_lzcnt16(); //test_lzcnt16();
test_lzcnt64();
return 0; return 0;
} }

View File

@ -438,6 +438,7 @@ ULONGLONG GetTickCount64(void)
#define D_BIT_3DN (1<<30) #define D_BIT_3DN (1<<30)
#define C_BIT_SSE3 (1<<0) #define C_BIT_SSE3 (1<<0)
#define C_BIT_PCLMULQDQ (1<<1) #define C_BIT_PCLMULQDQ (1<<1)
#define C_BIT_LZCNT (1<<5)
#define C_BIT_3DNP (1<<8) #define C_BIT_3DNP (1<<8)
#define C_BIT_3DNP (1<<8) #define C_BIT_3DNP (1<<8)
#define C_BIT_SSSE3 (1<<9) #define C_BIT_SSSE3 (1<<9)
@ -691,6 +692,10 @@ BOOL IsProcessorFeaturePresentEx(DWORD ProcessorFeature)
switch (ProcessorFeature) switch (ProcessorFeature)
{ {
case PF_EX_LZCNT:
if (c & C_BIT_LZCNT)
ret = TRUE;
break;
case PF_EX_3DNOW_PREFETCH: case PF_EX_3DNOW_PREFETCH:
if (c & C_BIT_3DNP) if (c & C_BIT_3DNP)
ret = TRUE; ret = TRUE;