Added compile-time (macro) determiation of endianess shift needed for jr_state"s bitfield over xsubi. Reduces code size and removes 2 levels of indirection.

To switch to the old (still available, through the function"s symbol itself) ifunc implementation, build with `-D_RNGXX_JR_RESOLV_RUNTIME` (the resolution still happens at compile-time, but the ifunc impl demands indirection even if it does nothing.)

Fortune for rngxx's current commit: Future small blessing − 末小吉
master
Avril 3 years ago
parent bd22305f77
commit 045cb7189b
Signed by: flanchan
GPG Key ID: 284488987C31F630

@ -33,7 +33,7 @@ _Static_assert( sizeof(uint48_t) == (sizeof(uint16_t) * 3), "bad uint48 (ushort[
_Static_assert( sizeof(((struct jr_state*)NULL)->st) == sizeof(uint64_t), "bad uint64 (union st)"); _Static_assert( sizeof(((struct jr_state*)NULL)->st) == sizeof(uint64_t), "bad uint64 (union st)");
inline static unsigned short* IFUNC_DEF(_jr_st_resolv, (jr_xsub_t* restrict state) inline static unsigned short* IFUNC_DEF(_jr_st_resolv, (jr_xsub_t* restrict state)
__attribute__((const, nonnull, returns_nonnull))); __attribute__((const, nonnull, returns_nonnull, access(none, 1))));
inline static unsigned short* IFUNC_IMPL(_jr_st_resolv, low) (jr_xsub_t* restrict state) inline static unsigned short* IFUNC_IMPL(_jr_st_resolv, low) (jr_xsub_t* restrict state)
{ {
@ -43,6 +43,17 @@ inline static unsigned short* IFUNC_IMPL(_jr_st_resolv, high) (jr_xsub_t* restri
{ {
return state->xsubi+1; return state->xsubi+1;
} }
inline static __attribute__((gnu_inline, const)) int _resv_is_high()
{
static const struct jr_state chk = {
.st.xsubl = JR_MAX,
};
return chk.st._xsub
? 1
: 0;
}
__attribute__((const)) __attribute__((const))
inline static unsigned short* IFUNC_RESOLVER(_jr_st_resolv) (jr_xsub_t* restrict state) inline static unsigned short* IFUNC_RESOLVER(_jr_st_resolv) (jr_xsub_t* restrict state)
{ {
@ -57,7 +68,16 @@ inline static unsigned short* IFUNC_RESOLVER(_jr_st_resolv) (jr_xsub_t* restrict
? & IFUNC_NAME(_jr_st_resolv, high) ? & IFUNC_NAME(_jr_st_resolv, high)
: & IFUNC_NAME(_jr_st_resolv, low); : & IFUNC_NAME(_jr_st_resolv, low);
} }
#ifndef _RNGXX_JR_RESOLV_RUNTIME
#define _jr_st_resolv_f (_resv_is_high() \
? & IFUNC_NAME(_jr_st_resolv, high) \
: & IFUNC_NAME(_jr_st_resolv, low))
//unsigned short* (*const _jr_st_resolv_fp)(jr_xsub_t* restrict state) = _jr_st_resolv_f; // "not a constant expr ://
#define _jr_st_resolv(st) _jr_st_resolv_f (st)
#else
#define _jr_st_resolv_f _jr_st_resolv
#endif
_fspec(readonly) internal long _jr_lastl(const struct jr_state* restrict state) _fspec(readonly) internal long _jr_lastl(const struct jr_state* restrict state)
{ {

Loading…
Cancel
Save