0dac2f5f0a0f25d8f6b789ba089f1a2d01c529a6Josef 'Jeff' Sipek/* Returns x, such that x is the smallest power of 2 >= num. */
d6e496a8bdb887a49112250e781f219d91fee117Timo Sirainen/* Returns TRUE if 2^x=num, i.e. if num has only a single bit set to 1. */
d6e496a8bdb887a49112250e781f219d91fee117Timo Sirainenstatic inline bool ATTR_CONST
33c05298ab11c13b409da265a6bf2f745196156fTimo Sirainen#if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
84f697c5e30565823619abaaeb57164c789d4b66Phil Carmodystatic inline unsigned int ATTR_CONST
84f697c5e30565823619abaaeb57164c789d4b66Phil Carmodystatic inline unsigned int ATTR_CONST
84f697c5e30565823619abaaeb57164c789d4b66Phil Carmodybits_required8(uint8_t num) { return bits_required32(num); }
84f697c5e30565823619abaaeb57164c789d4b66Phil Carmodystatic inline unsigned int ATTR_CONST
84f697c5e30565823619abaaeb57164c789d4b66Phil Carmodybits_required16(uint16_t num) { return bits_required32(num); }
84f697c5e30565823619abaaeb57164c789d4b66Phil Carmodystatic inline unsigned int ATTR_CONST
9e9711ebed27c8efeece02d57cf91bb00f10015cTimo Sirainen return num == 0 ? 0 : 64 - __builtin_clzll(num);
3637a2ad3b2ead17efd5591f73effd3b140d8d2dPhil Carmodyunsigned int bits_required8(uint8_t num) ATTR_CONST;
3637a2ad3b2ead17efd5591f73effd3b140d8d2dPhil Carmodystatic inline
3637a2ad3b2ead17efd5591f73effd3b140d8d2dPhil Carmodystatic inline
3637a2ad3b2ead17efd5591f73effd3b140d8d2dPhil Carmodystatic inline
3637a2ad3b2ead17efd5591f73effd3b140d8d2dPhil Carmody return (num <= 0xffffffff) ? bits_required32(num)
f1577719e3bed5fd814788642f165f1d3d699636Aki Tuomi const unsigned int mask = CHAR_BIT*sizeof(num) - 1;
f1577719e3bed5fd814788642f165f1d3d699636Aki Tuomi const unsigned int mask = CHAR_BIT*sizeof(num) - 1;
f1577719e3bed5fd814788642f165f1d3d699636Aki Tuomi const unsigned int mask = CHAR_BIT*sizeof(num) - 1;
f1577719e3bed5fd814788642f165f1d3d699636Aki Tuomi const unsigned int mask = CHAR_BIT*sizeof(num) - 1;
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmody/* These functions look too big to be inline, but in almost all expected
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmody uses, 'fracbits' will be a compile-time constant, and most of the
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmody expressions will simplify greatly.
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmody/* Perform a piecewise-linear approximation to a log2, with fracbits "fractional" bits.
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmody Best explained with examples:
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmody With 2 fractional bits splitting each power of 2 into 4 bands:
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmody 00, 01, 10, 11 -> 00, 01, 10, 11 (small corner cases)
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmody 100, 101, 110, 111 -> 100, 101, 110, 111 ([4-8) split into 4 bands)
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmody 1000, 1001, 1010, 1011 -> 1000, 1000, 1001, 1001 ([8-15) split ...
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmody 1100, 1101, 1110, 1111 -> 1010, 1010, 1011, 1011 ... into 4 bands)
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmody [16..31) -> 11bb
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmody [32..63) -> 100bb
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmody [64..127) -> 101bb
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmody [128..255) -> 110bb
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmody e.g. 236 = 11101100 -> ((8-2)<<2 == 11000) + (111.....>> 5 == 111) - 100 == 11011
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmodystatic inline unsigned int ATTR_CONST
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmodybits_fraclog(unsigned int val, unsigned int fracbits)
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmody unsigned int fracoffsbad = val >> (bandnum - 1); /* has leading 1 still */
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmody unsigned int bucket = bandstart + fracoffsbad - BIT(fracbits);
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmodystatic inline unsigned int ATTR_CONST
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmodybits_fraclog_bucket_start(unsigned int bucket, unsigned int fracbits)
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmody unsigned int fracoffs = bucket & (BIT(fracbits)-1);
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmody unsigned int fracoffs1 = BIT(fracbits) + fracoffs;
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmody unsigned int bandstart = fracoffs1 << (bandnum - 1);
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmodystatic inline unsigned int ATTR_CONST
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmodybits_fraclog_bucket_end(unsigned int bucket, unsigned int fracbits)
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmody unsigned int fracoffs = bucket & (BIT(fracbits)-1);
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmody unsigned int nextfracoffs1 = 1 + BIT(fracbits) + fracoffs;
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmody unsigned int nextbandstart = nextfracoffs1 << (bandnum - 1);
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmody/* UNSAFE: multiple use of parameter (but expecting a constant in reality).
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmody But a macro as it's most likely to be used to declare an array size.
bb0eabc25c8ec2ee98e31fb81274481cc8ed245ePhil Carmody#define BITS_FRACLOG_BUCKETS(bits) ((33u - (bits)) << (bits))