Fix issue for 32 bits systems

mpz_core_clz wasn't reproductible for 32 bits system.
This commit is contained in:
Patrick Pélissier committed 2018-04-14 23:08:53 +02:00
1 parent a94a5feb84
commit d97f46133b
2 files changed
+26 -20

No files matched your search

+24 -18
View File
@@ -1277,18 +1277,38 @@ static inline uint64_t m_core_roundpow2(uint64_t v)
/* Return the count leading zero of the argument */
#if defined(__GNUC__) && (__GNUC__*100 + __GNUC_MINOR__) >= 304
static inline unsigned int m_core_clz(unsigned long limb)
static inline unsigned int m_core_clz(uint32_t limb)
{
return M_UNLIKELY (limb == 0) ? sizeof(unsigned long)*CHAR_BIT : __builtin_clzl(limb);
return M_UNLIKELY (limb == 0) ? sizeof(uint32_t)*CHAR_BIT : __builtin_clzl(limb) - (sizeof(unsigned long) - sizeof(uint32_t)) * CHAR_BIT;
}
static inline unsigned int m_core_clz64(uint64_t limb)
{
return M_UNLIKELY (limb == 0ULL) ? sizeof (uint64_t)*CHAR_BIT : __builtin_clzll(limb) - (sizeof (unsigned long long) - sizeof (uint64_t)) * CHAR_BIT;
}
#else
#define M_CORE_CLZ_TAB "\010\07\06\06\05\05\05\05\04\04\04\04\04\04\04\04\03\03\03\03\03\03\03\03\03\03\03\03\03\03\03\03\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\02\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\01\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00\00"
static inline unsigned int m_core_clz(unsigned long limb)
static inline unsigned int m_core_clz(uint32_t limb)
{
unsigned int shift = 0;
/* This code should be branchless on most targets */
/* Compute shift so that, it is
+ -3 if the highest 24 bits are clear,
+ -2 for the highest 16 bits,
+ -1 for the highest 8 bits,
+ 0 otherwise */
shift = -(limb < 0x1000000UL);
shift -= (limb < 0x10000UL);
shift -= (limb < 0x100UL);
shift = shift*8 + 24;
shift = 24 - shift + M_CORE_CLZ_TAB[limb >> shift ];
return shift;
}
static inline unsigned int m_core_clz64(uint64_t limb)
{
unsigned int shift = 0;
/* This code should be branchless on most targets */
#if ULONG_MAX == 18446744073709551615UL
/* Compute shift so that, it is
+ -7 if the highest 56 bits are clear,
+ -6 for the highest 48 bits,
@@ -1307,20 +1327,6 @@ static inline unsigned int m_core_clz(unsigned long limb)
shift -= (limb < 0x100UL);
shift = shift*8 + 56;
shift = 56 - shift + M_CORE_CLZ_TAB[limb >> shift ];
#elif ULONG_MAX == 4294967295UL
/* Compute shift so that, it is
+ -3 if the highest 24 bits are clear,
+ -2 for the highest 16 bits,
+ -1 for the highest 8 bits,
+ 0 otherwise */
shift = -(limb < 0x1000000UL);
shift -= (limb < 0x10000UL);
shift -= (limb < 0x100UL);
shift = shift*8 + 24;
shift = 24 - shift + M_CORE_CLZ_TAB[limb >> shift ];
#else
# error Unkown size for unsigned long. Please create a bug report and report the ULONG_MAX value.
#endif
return shift;
}
#endif
+2 -2
View File
@@ -122,7 +122,7 @@ static inline size_t genint_pop(genint_t s)
// While master is not full
while ((master >> GENINT_ABA_CPT) != s->mask_master) {
// Let's get the index i of the first not full limb according to master.
unsigned int i = m_core_clz(~master);
unsigned int i = m_core_clz64(~master);
// Let's compute the mask of this limb representing the limb as being full
genint_limb_t mask = s->mask0;
mask = (i == s->max) ? mask : -GENINT_ONE;
@@ -134,7 +134,7 @@ static inline size_t genint_pop(genint_t s)
if (M_UNLIKELY (org == mask))
goto next_element;
// At least one bit is free in the limb. Find one.
bit = GENINT_LIMBSIZE - 1 - m_core_clz(~org);
bit = GENINT_LIMBSIZE - 1 - m_core_clz64(~org);
assert ((org & (GENINT_ONE<<bit)) == 0);
assert (i * GENINT_LIMBSIZE + GENINT_LIMBSIZE - 1 - bit < s->n);
// Set the integer as being used.