Changeset View
Changeset View
Standalone View
Standalone View
head/sys/contrib/pcg-c/include/pcg_variants.h
Show All 30 Lines | |||||
* postprocessing and hand editing the output. | * postprocessing and hand editing the output. | ||||
* | * | ||||
* Much of the remaining code was generated by C-preprocessor metaprogramming. | * Much of the remaining code was generated by C-preprocessor metaprogramming. | ||||
*/ | */ | ||||
#ifndef PCG_VARIANTS_H_INCLUDED | #ifndef PCG_VARIANTS_H_INCLUDED | ||||
#define PCG_VARIANTS_H_INCLUDED 1 | #define PCG_VARIANTS_H_INCLUDED 1 | ||||
#include <inttypes.h> | #if defined(__SIZEOF_INT128__) && __SIZEOF_INT128__ | ||||
#if __SIZEOF_INT128__ | |||||
typedef __uint128_t pcg128_t; | typedef __uint128_t pcg128_t; | ||||
#define PCG_128BIT_CONSTANT(high,low) \ | #define PCG_128BIT_CONSTANT(high,low) \ | ||||
((((pcg128_t)high) << 64) + low) | ((((pcg128_t)high) << 64) + low) | ||||
#define PCG_HAS_128BIT_OPS 1 | #define PCG_HAS_128BIT_OPS 1 | ||||
#else | |||||
#define PCG_HAS_128BIT_OPS 0 | |||||
#endif | #endif | ||||
#if __GNUC_GNU_INLINE__ && !defined(__cplusplus) | #ifdef __cplusplus | ||||
#error Nonstandard GNU inlining semantics. Compile with -std=c99 or better. | |||||
/* We could instead use macros PCG_INLINE and PCG_EXTERN_INLINE | |||||
but better to just reject ancient C code. */ | |||||
#endif | |||||
#if __cplusplus | |||||
extern "C" { | extern "C" { | ||||
#endif | #endif | ||||
/* | /* | ||||
* Rotate helper functions. | * Rotate helper functions. | ||||
*/ | */ | ||||
inline uint8_t pcg_rotr_8(uint8_t value, unsigned int rot) | inline uint8_t pcg_rotr_8(uint8_t value, unsigned int rot) | ||||
{ | { | ||||
/* Unfortunately, clang is kinda pathetic when it comes to properly | /* Unfortunately, clang is kinda pathetic when it comes to properly | ||||
* recognizing idiomatic rotate code, so for clang we actually provide | * recognizing idiomatic rotate code, so for clang we actually provide | ||||
* assembler directives (enabled with PCG_USE_INLINE_ASM). Boo, hiss. | * assembler directives (enabled with PCG_USE_INLINE_ASM). Boo, hiss. | ||||
*/ | */ | ||||
#if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__) | #if PCG_USE_INLINE_ASM && defined(__clang__) && (defined(__x86_64__) || defined(__i386__)) | ||||
asm ("rorb %%cl, %0" : "=r" (value) : "0" (value), "c" (rot)); | __asm__ ("rorb %%cl, %0" : "=r" (value) : "0" (value), "c" (rot)); | ||||
return value; | return value; | ||||
#else | #else | ||||
return (value >> rot) | (value << ((- rot) & 7)); | return (value >> rot) | (value << ((- rot) & 7)); | ||||
#endif | #endif | ||||
} | } | ||||
inline uint16_t pcg_rotr_16(uint16_t value, unsigned int rot) | inline uint16_t pcg_rotr_16(uint16_t value, unsigned int rot) | ||||
{ | { | ||||
#if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__) | #if PCG_USE_INLINE_ASM && defined(__clang__) && (defined(__x86_64__) || defined(__i386__)) | ||||
asm ("rorw %%cl, %0" : "=r" (value) : "0" (value), "c" (rot)); | __asm__ ("rorw %%cl, %0" : "=r" (value) : "0" (value), "c" (rot)); | ||||
return value; | return value; | ||||
#else | #else | ||||
return (value >> rot) | (value << ((- rot) & 15)); | return (value >> rot) | (value << ((- rot) & 15)); | ||||
#endif | #endif | ||||
} | } | ||||
inline uint32_t pcg_rotr_32(uint32_t value, unsigned int rot) | inline uint32_t pcg_rotr_32(uint32_t value, unsigned int rot) | ||||
{ | { | ||||
#if PCG_USE_INLINE_ASM && __clang__ && (__x86_64__ || __i386__) | #if PCG_USE_INLINE_ASM && defined(__clang__) && (defined(__x86_64__) || defined(__i386__)) | ||||
asm ("rorl %%cl, %0" : "=r" (value) : "0" (value), "c" (rot)); | __asm__ ("rorl %%cl, %0" : "=r" (value) : "0" (value), "c" (rot)); | ||||
return value; | return value; | ||||
#else | #else | ||||
return (value >> rot) | (value << ((- rot) & 31)); | return (value >> rot) | (value << ((- rot) & 31)); | ||||
#endif | #endif | ||||
} | } | ||||
inline uint64_t pcg_rotr_64(uint64_t value, unsigned int rot) | inline uint64_t pcg_rotr_64(uint64_t value, unsigned int rot) | ||||
{ | { | ||||
#if 0 && PCG_USE_INLINE_ASM && __clang__ && __x86_64__ | #if 0 && PCG_USE_INLINE_ASM && defined(__clang__) && (defined(__x86_64__) || defined(__i386__)) | ||||
/* For whatever reason, clang actually *does* generate rotq by | /* For whatever reason, clang actually *does* generate rotq by | ||||
itself, so we don't need this code. */ | itself, so we don't need this code. */ | ||||
asm ("rorq %%cl, %0" : "=r" (value) : "0" (value), "c" (rot)); | __asm__ ("rorq %%cl, %0" : "=r" (value) : "0" (value), "c" (rot)); | ||||
return value; | return value; | ||||
#else | #else | ||||
return (value >> rot) | (value << ((- rot) & 63)); | return (value >> rot) | (value << ((- rot) & 63)); | ||||
#endif | #endif | ||||
} | } | ||||
#if PCG_HAS_128BIT_OPS | #if PCG_HAS_128BIT_OPS | ||||
inline pcg128_t pcg_rotr_128(pcg128_t value, unsigned int rot) | inline pcg128_t pcg_rotr_128(pcg128_t value, unsigned int rot) | ||||
▲ Show 20 Lines • Show All 2,376 Lines • ▼ Show 20 Lines | |||||
#if PCG_HAS_128BIT_OPS | #if PCG_HAS_128BIT_OPS | ||||
typedef struct pcg_state_setseq_128 pcg128i_random_t; | typedef struct pcg_state_setseq_128 pcg128i_random_t; | ||||
#define pcg128i_random_r pcg_setseq_128_rxs_m_xs_128_random_r | #define pcg128i_random_r pcg_setseq_128_rxs_m_xs_128_random_r | ||||
#define pcg128i_boundedrand_r pcg_setseq_128_rxs_m_xs_128_boundedrand_r | #define pcg128i_boundedrand_r pcg_setseq_128_rxs_m_xs_128_boundedrand_r | ||||
#define pcg128i_srandom_r pcg_setseq_128_srandom_r | #define pcg128i_srandom_r pcg_setseq_128_srandom_r | ||||
#define pcg128i_advance_r pcg_setseq_128_advance_r | #define pcg128i_advance_r pcg_setseq_128_advance_r | ||||
#endif | #endif | ||||
extern uint32_t pcg32_random(void); | |||||
extern uint32_t pcg32_boundedrand(uint32_t bound); | |||||
extern void pcg32_srandom(uint64_t seed, uint64_t seq); | |||||
extern void pcg32_advance(uint64_t delta); | |||||
#if PCG_HAS_128BIT_OPS | |||||
extern uint64_t pcg64_random(void); | |||||
extern uint64_t pcg64_boundedrand(uint64_t bound); | |||||
extern void pcg64_srandom(pcg128_t seed, pcg128_t seq); | |||||
extern void pcg64_advance(pcg128_t delta); | |||||
#endif | |||||
/* | /* | ||||
* Static initialization constants (if you can't call srandom for some | * Static initialization constants (if you can't call srandom for some | ||||
* bizarre reason). | * bizarre reason). | ||||
*/ | */ | ||||
#define PCG32_INITIALIZER PCG_STATE_SETSEQ_64_INITIALIZER | #define PCG32_INITIALIZER PCG_STATE_SETSEQ_64_INITIALIZER | ||||
#define PCG32U_INITIALIZER PCG_STATE_UNIQUE_64_INITIALIZER | #define PCG32U_INITIALIZER PCG_STATE_UNIQUE_64_INITIALIZER | ||||
#define PCG32S_INITIALIZER PCG_STATE_ONESEQ_64_INITIALIZER | #define PCG32S_INITIALIZER PCG_STATE_ONESEQ_64_INITIALIZER | ||||
Show All 17 Lines | |||||
#define PCG8I_INITIALIZER PCG_STATE_SETSEQ_8_INITIALIZER | #define PCG8I_INITIALIZER PCG_STATE_SETSEQ_8_INITIALIZER | ||||
#define PCG16I_INITIALIZER PCG_STATE_SETSEQ_16_INITIALIZER | #define PCG16I_INITIALIZER PCG_STATE_SETSEQ_16_INITIALIZER | ||||
#define PCG32I_INITIALIZER PCG_STATE_SETSEQ_32_INITIALIZER | #define PCG32I_INITIALIZER PCG_STATE_SETSEQ_32_INITIALIZER | ||||
#define PCG64I_INITIALIZER PCG_STATE_SETSEQ_64_INITIALIZER | #define PCG64I_INITIALIZER PCG_STATE_SETSEQ_64_INITIALIZER | ||||
#if PCG_HAS_128BIT_OPS | #if PCG_HAS_128BIT_OPS | ||||
#define PCG128I_INITIALIZER PCG_STATE_SETSEQ_128_INITIALIZER | #define PCG128I_INITIALIZER PCG_STATE_SETSEQ_128_INITIALIZER | ||||
#endif | #endif | ||||
#if __cplusplus | #ifdef __cplusplus | ||||
} | } | ||||
#endif | #endif | ||||
#endif /* PCG_VARIANTS_H_INCLUDED */ | #endif /* PCG_VARIANTS_H_INCLUDED */ | ||||