From 045cb7189be9717b2d7802989d97c99a28e51c54 Mon Sep 17 00:00:00 2001 From: Avril Date: Mon, 8 Nov 2021 09:17:59 +0000 Subject: [PATCH] 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. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 − 末小吉 --- src/rng/crand.c | 24 ++++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/src/rng/crand.c b/src/rng/crand.c index 198d6e4..7574a5b 100644 --- a/src/rng/crand.c +++ b/src/rng/crand.c @@ -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)"); 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) { @@ -43,6 +43,17 @@ inline static unsigned short* IFUNC_IMPL(_jr_st_resolv, high) (jr_xsub_t* restri { 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)) 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, 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) {