@ -32,20 +32,25 @@ typedef __typeof(((struct jr_state*)NULL)->st) jr_xsub_t;
_Static_assert ( sizeof ( uint48_t ) = = ( sizeof ( uint16_t ) * 3 ) , " bad uint48 (ushort[3]) " ) ;
_Static_assert ( sizeof ( uint48_t ) = = ( sizeof ( uint16_t ) * 3 ) , " bad uint48 (ushort[3]) " ) ;
_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) " ) ;
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 ) ) ) ;
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 )
{
{
return state - > xsubi ;
return state - > xsubi ;
}
}
static unsigned short * IFUNC_IMPL ( _jr_st_resolv , high ) ( jr_xsub_t * restrict state )
inline static unsigned short * IFUNC_IMPL ( _jr_st_resolv , high ) ( jr_xsub_t * restrict state )
{
{
return state - > xsubi + 1 ;
return state - > xsubi + 1 ;
}
}
__attribute__ ( ( const ) )
__attribute__ ( ( const ) )
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 )
{
{
// This ifunc is free.
// The optimiser recognises the return value of this function at compile time, and discards the unused function, removing the need for any runtime ifunc resolution.
// The ifunc `_jr_st_resolv()` is essentially (almost) the same as a symbol-aliased constexpr function.
// Ain't that neat?
struct jr_state chk = { 0 } ;
struct jr_state chk = { 0 } ;
chk . st . xsubh = JR_MAX ;
chk . st . xsubh = JR_MAX ;
return chk . st . _xsub
return chk . st . _xsub
@ -75,6 +80,8 @@ __attribute__((malloc(_jr_free)))
internal struct jr_state * _jr_alloc ( )
internal struct jr_state * _jr_alloc ( )
{
{
struct jr_state * bx = aligned_alloc ( _Alignof ( struct jr_state ) , sizeof ( struct jr_state ) ) ;
struct jr_state * bx = aligned_alloc ( _Alignof ( struct jr_state ) , sizeof ( struct jr_state ) ) ;
if ( UNLIKELY ( ! bx ) ) return NULL ;
memset ( bx , 0 , sizeof ( struct jr_state ) ) ;
memset ( bx , 0 , sizeof ( struct jr_state ) ) ;
return bx ;
return bx ;
@ -83,12 +90,15 @@ __attribute__((malloc(_jr_free)))
internal struct jr_state * _jr_new ( unsigned long with )
internal struct jr_state * _jr_new ( unsigned long with )
{
{
struct jr_state * state = _jr_alloc ( ) ;
struct jr_state * state = _jr_alloc ( ) ;
if ( UNLIKELY ( ! state ) ) return NULL ;
_jr_seed ( state , with ) ;
_jr_seed ( state , with ) ;
return state ;
return state ;
}
}
internal void _jr_free ( struct jr_state * restrict state )
internal void _jr_free ( struct jr_state * restrict state )
{
{
if ( LIKELY ( state ) )
free ( state ) ;
free ( state ) ;
}
}