summaryrefslogtreecommitdiffhomepage
path: root/stc
diff options
context:
space:
mode:
authorTyge Løvset <[email protected]>2020-07-30 12:50:56 +0200
committerTyge Løvset <[email protected]>2020-07-30 12:50:56 +0200
commit39d6f5ccd16360cd38d5d43752b4325aa6575bac (patch)
treed3d785be4621e45b837d84e208ac7360f25ce814 /stc
parent3bf571bd7f0c8eface28bb5d2b7607d934865e00 (diff)
downloadSTC-modified-39d6f5ccd16360cd38d5d43752b4325aa6575bac.tar.gz
STC-modified-39d6f5ccd16360cd38d5d43752b4325aa6575bac.zip
Various cleanup of examples and READM.md. Added support for popcount on compilers without intrinsics.
Diffstat (limited to 'stc')
-rw-r--r--stc/cbitset.h30
-rw-r--r--stc/cdefs.h2
-rw-r--r--stc/crand.h7
3 files changed, 26 insertions, 13 deletions
diff --git a/stc/cbitset.h b/stc/cbitset.h
index aed8b6a7..cb8040ce 100644
--- a/stc/cbitset.h
+++ b/stc/cbitset.h
@@ -48,13 +48,6 @@ int main() {
#include <assert.h>
#include "cdefs.h"
-#if defined(__GNUC__)
-#define cbitset_popcnt64(i) __builtin_popcountll(i)
-#else
-#include <nmmintrin.h>
-#define cbitset_popcnt64(i) _mm_popcnt_u64(i)
-#endif
-
typedef struct { uint64_t* _arr; size_t size; } cbitset_t;
#define cbitset_init {NULL, 0}
@@ -158,11 +151,30 @@ STC_API void cbitset_resize(cbitset_t* self, size_t size, bool value) {
}
}
+#if defined(__GNUC__)
+ #define c_popcount64(x) __builtin_popcountll(x)
+#elif defined(_MSC_VER)
+ #include <nmmintrin.h>
+ #define c_popcount64(x) _mm_popcnt_u64(x)
+#else
+/* http://en.wikipedia.org/wiki/Hamming_weight#Efficient_implementation */
+static inline uint64_t c_popcount64(uint64_t x) {
+ uint64_t m1 = 0x5555555555555555ll;
+ uint64_t m2 = 0x3333333333333333ll;
+ uint64_t m4 = 0x0F0F0F0F0F0F0F0Fll;
+ uint64_t h01 = 0x0101010101010101ll;
+ x -= (x >> 1) & m1;
+ x = (x & m2) + ((x >> 2) & m2);
+ x = (x + (x >> 4)) & m4;
+ return (x * h01) >> 56;
+}
+#endif
+
STC_API size_t cbitset_count(cbitset_t set) {
size_t count = 0, n = (set.size + 63) >> 6;
if (set.size > 0) {
- --n; for (size_t i=0; i<n; ++i) count += cbitset_popcnt64(set._arr[i]);
- count += cbitset_popcnt64(set._arr[n] & ((1ull << (set.size & 63)) - 1));
+ --n; for (size_t i=0; i<n; ++i) count += c_popcount64(set._arr[i]);
+ count += c_popcount64(set._arr[n] & ((1ull << (set.size & 63)) - 1));
}
return count;
}
diff --git a/stc/cdefs.h b/stc/cdefs.h
index 8f5b896f..18cc9f51 100644
--- a/stc/cdefs.h
+++ b/stc/cdefs.h
@@ -105,7 +105,7 @@ static inline uint32_t c_fibonacci_hash64(const void* data, size_t len) {
const volatile uint64_t *key = (const uint64_t *) data;
uint64_t x = *key++ * 11400714819323198485ull;
while (len -= 8) x ^= *key++ * 11400714819323198485ull;
- return (uint32_t) (x >> 13);
+ return (uint32_t) x; // (x >> 13);
}
#endif
diff --git a/stc/crand.h b/stc/crand.h
index 63a10156..b6595bcd 100644
--- a/stc/crand.h
+++ b/stc/crand.h
@@ -43,7 +43,7 @@ typedef struct {float min, range;} crand_uniform_f32_t;
/* 32 bit random number generator engine */
STC_API crand_eng32_t crand_eng32_with_seq(uint64_t seed, uint64_t seq);
STC_INLINE crand_eng32_t crand_eng32_init(uint64_t seed) {
- return crand_eng32_with_seq(seed, 1);
+ return crand_eng32_with_seq(seed, seed);
}
/* int random number generator, range [0, 2^32) */
@@ -98,7 +98,7 @@ STC_INLINE double crand_uniform_f64(crand_eng64_t* rng, crand_uniform_f64_t dist
#if !defined(STC_HEADER) || defined(STC_IMPLEMENTATION)
-/* PCG32 random number generator: https://www.pcg-random.org/index.html */
+/* PCG32 random number generator: https://www.pcg-random.org/download.html */
STC_API crand_eng32_t crand_eng32_with_seq(uint64_t seed, uint64_t seq) {
crand_eng32_t rng = {0u, (seq << 1u) | 1u}; /* inc must be odd */
@@ -107,6 +107,7 @@ STC_API crand_eng32_t crand_eng32_with_seq(uint64_t seed, uint64_t seq) {
crand_gen_i32(&rng);
return rng;
}
+
STC_API uint32_t crand_gen_i32(crand_eng32_t* rng) {
uint64_t old = rng->state[0];
rng->state[0] = old * 6364136223846793005ull + rng->state[1];
@@ -133,7 +134,7 @@ STC_API uint64_t crand_gen_i64(crand_eng64_t* rng) {
return result;
}
-/* // Original SFC64 random number generator: http://pracrand.sourceforge.net
+/* // SFC64 random number generator: http://pracrand.sourceforge.net
STC_API uint64_t crand_gen_i64(crand_eng64_t* rng) {
enum {LROT = 24, RSHIFT = 11, LSHIFT = 3};
uint64_t *s = rng->state;