Fixed BMI behavior on x86 and x32 targets, reported by @tycho (#178)

This commit is contained in:
Yann Collet
2016-05-01 10:26:30 +02:00
parent cf8584c90a
commit 6f9c056662
7 changed files with 193 additions and 175 deletions
+12 -2
View File
@@ -301,7 +301,12 @@ MEM_STATIC size_t BIT_getUpperBits(size_t bitD, U32 const start)
MEM_STATIC size_t BIT_getMiddleBits(size_t bitD, U32 const nbBits, U32 const start)
{
#if defined(__BMI__) && defined(__GNUC__) /* experimental */
return __builtin_ia32_bextr_u64(bitD, (nbBits<<8) | start );
# if defined(__x86_64__)
if (sizeof(bitD)==8)
return _bextr_u64(bitD, start, nbBits);
else
# endif
return _bextr_u32(bitD, start, nbBits);
#else
return (bitD >> start) & BIT_mask[nbBits];
#endif
@@ -322,7 +327,12 @@ MEM_STATIC size_t BIT_getLowerBits(size_t bitD, U32 const nbBits)
MEM_STATIC size_t BIT_lookBits(const BIT_DStream_t* bitD, U32 nbBits)
{
#if defined(__BMI__) && defined(__GNUC__) /* experimental */
return __builtin_ia32_bextr_u64(bitD->bitContainer, (nbBits<<8) | (64 - bitD->bitsConsumed - nbBits) );
# if defined(__x86_64__)
if (sizeof(bitD->bitContainer)==8)
return _bextr_u64(bitD->bitContainer, 64 - bitD->bitsConsumed - nbBits, nbBits);
else
# endif
return _bextr_u32(bitD->bitContainer, 32 - bitD->bitsConsumed - nbBits, nbBits);
#else
U32 const bitMask = sizeof(bitD->bitContainer)*8 - 1;
return ((bitD->bitContainer << (bitD->bitsConsumed & bitMask)) >> 1) >> ((bitMask-nbBits) & bitMask);