Annotation of coherent/f/usr/include/common/_tricks.h, revision 1.1

1.1     ! root        1: #ifndef        __COMMON__TRICKS_H__
        !             2: #define        __COMMON__TRICKS_H__
        !             3: 
        !             4: /*
        !             5:  * This file contains macro-definitions for a number of frequently-
        !             6:  * rediscovered fundamental tricks from the field of radix-2 arithmetic
        !             7:  * and the properties of Standard C.
        !             8:  *
        !             9:  * These include: discovering whether a number is a power of two, finding
        !            10:  * the number of the least-significant set bit in an integer, finding the
        !            11:  * number of the most-significant set bit in an integer, positive-integer
        !            12:  * division that rounds upward, and so forth.
        !            13:  *
        !            14:  * The majority of the hacks given here are only defined on unsigned
        !            15:  * arguments. Wherever appropriate, factors such as 0U or 1U are used to
        !            16:  * encourage the system to coerce the result to an unsigned type. However,
        !            17:  * while using 0UL or 1UL would guarantee this, we use 0U and 1U to allow
        !            18:  * the operation to potentially be performed in as narrow an arithmetic
        !            19:  * mode as possible.
        !            20:  *
        !            21:  * We have some special motives for using integral operand conversions in
        !            22:  * this way rather than casts; not only can we be polymorphic, but we gain
        !            23:  * the even greater advantage of keeping the expansions as integral constant
        !            24:  * expressions suitable for evaluation in #if-expressions.
        !            25:  *
        !            26:  * In order to be flexible in the way we deal with the non-polymorphic
        !            27:  * macros, we need data like that in <limits.h>. We get this information
        !            28:  * from <common/_limits.h> so that we don't export stuff into the user
        !            29:  * namespace.
        !            30:  */ 
        !            31: 
        !            32: #include <common/feature.h>
        !            33: #include <common/_limits.h>
        !            34: 
        !            35: /*
        !            36:  * Since many of these hacks only work for special operand ranges, we allow
        !            37:  * users the ability to selectively enable paranoid debugging; if a macro with
        !            38:  * the name _TRICKS_ASSERT () is defined, we call it up with an argument that
        !            39:  * is a predicate we insist on being true; don't forget that like the real-
        !            40:  * life assert () in <assert.h>, this must evaluate to a void expression!
        !            41:  *
        !            42:  * Note that many compilers won't accept expressions with commas, casts, or
        !            43:  * function calls in the unevaluated arm of a ternary with constant condition
        !            44:  * in a place where an integral constant expression is valid. To satisfy them,
        !            45:  * you can skip the assertions in places where the constants are by using the
        !            46:  * ..._CONST () versions of the tricks. Not many compilers do that, but you
        !            47:  * can get unlucky.
        !            48:  *
        !            49:  * Making the distinction between true-constant and possibly non-constant
        !            50:  * versions of the tricks may permit some special hacks in some cases for the
        !            51:  * non-constant versions.
        !            52:  */
        !            53: 
        !            54: #ifndef        _TRICKS_ASSERT
        !            55: # define       _TRICKS_ASSERT(pred)    ((void) 0)
        !            56: #endif
        !            57: 
        !            58: 
        !            59: /*
        !            60:  * Is a number a power of two? This macro determines this, and should work
        !            61:  * for numbers of any unsigned type. Users are cautioned to avoid passing
        !            62:  * values of signed type to this macro, because then the result may depend
        !            63:  * on the underlying machine representation of negative numbers. While twos-
        !            64:  * complement machines are very common, they are not universal!
        !            65:  */
        !            66: 
        !            67: #define        __IS_POWER_OF_TWO(an_integer)   \
        !            68:                ((((an_integer) - 1U) & (an_integer)) == 0)
        !            69: 
        !            70: 
        !            71: /*
        !            72:  * Divide, with any non-zero remainder causing the result to be rounded to
        !            73:  * the next highest integer, as opposed to the default unsigned rounding
        !            74:  * mode of round-towards-zero. Users are cautioned that this technique does
        !            75:  * not apply to signed integers, because implementations have the freedom to
        !            76:  * use a rounding mode there that suits the properties of their signed-
        !            77:  * integer representation.
        !            78:  *
        !            79:  * Furthermore, users should be aware that this technique can fail in a most
        !            80:  * disastrous manner if (numerator - 1U + denominator) overflows the chosen
        !            81:  * representation. In this case, users should use div () or ldiv () and
        !            82:  * inspect the remainder to perform the rounding.
        !            83:  */
        !            84: 
        !            85: #define        __DIVIDE_ROUNDUP_CONST(numerator, denominator) \
        !            86:                (((numerator) - 1U + (denominator)) / (denominator))
        !            87: 
        !            88: #define        __DIVIDE_ROUNDUP(numerator, denominator) \
        !            89:        (_TRICKS_ASSERT ((numerator) - 1U + (denominator) >= (numerator)), \
        !            90:         __DIVIDE_ROUNDUP_CONST (numerator, denominator))
        !            91: 
        !            92: 
        !            93: /*
        !            94:  * Round a number up to being the nearest multiple of some other number. Here
        !            95:  * we are careful to avoid overflow wherever possible, but as above overflow
        !            96:  * can happen if (n - 1U + mult) overflows. The number we want to reach a
        !            97:  * multiple of is almost always an integral constant, so we could look for
        !            98:  * that special case to simplify the arithmetic performed in a machine-
        !            99:  * independent way... however, GCC is smart enough to do this by itself, so
        !           100:  * if you have a dumb compiler add in
        !           101:  *             __IS_POWER_OF_TWO (mult) ? ((n) - 1U + (mult) & ~ (mult)) :
        !           102:  * to the macros below.        
        !           103:  */
        !           104: 
        !           105: #define        __ROUND_UP_TO_MULTIPLE_CONST(n,mult) \
        !           106:                 (__DIVIDE_ROUNDUP_CONST (n, mult) * (mult))
        !           107: 
        !           108: #define        __ROUND_UP_TO_MULTIPLE(n,mult) \
        !           109:                (__DIVIDE_ROUNDUP (n, mult) * (mult))
        !           110: 
        !           111: 
        !           112: /*
        !           113:  * Locate the least-significant bit set within an integer, assuming that one
        !           114:  * exists. The existence test has been left out because it is trivial and it
        !           115:  * may be more efficently coded elsewhere... the other problem is the choice
        !           116:  * of what value to return in this case. Since these macros are aimed at
        !           117:  * speed, we punt this problem up to the caller.
        !           118:  *
        !           119:  * Since these macros involve lots of fixed constants, we provide a version
        !           120:  * parameterised for each unsigned type.
        !           121:  *
        !           122:  * Note that for the portable versions, extra bits outside the defined size
        !           123:  * are not considered; be warned that this is not part of the specification,
        !           124:  * so our paranoia checks look to see that the extra bits are all zero, so
        !           125:  * that maximum freedom is given to the assembly-language versions to be
        !           126:  * fast.
        !           127:  */
        !           128: 
        !           129: #define        __LEAST_BIT_8_CONST(bit_mask)   \
        !           130:        ((((bit_mask) & 0x0FU) == 0 ? 4 : 0) + \
        !           131:         (((bit_mask) & 0x33U) == 0 ? 2 : 0) + \
        !           132:         (((bit_mask) & 0x55U) == 0 ? 1 : 0))
        !           133: 
        !           134: #define        __LEAST_BIT_16_CONST(bit_mask)  \
        !           135:        ((((bit_mask) & 0x00FFU) == 0 ? 8 : 0) + \
        !           136:         (((bit_mask) & 0x0F0FU) == 0 ? 4 : 0) + \
        !           137:         (((bit_mask) & 0x3333U) == 0 ? 2 : 0) + \
        !           138:         (((bit_mask) & 0x5555U) == 0 ? 1 : 0))
        !           139: 
        !           140: #define        __LEAST_BIT_32_CONST(bit_mask)  \
        !           141:        ((((bit_mask) & 0x0000FFFFUL) == 0 ? 16 : 0) + \
        !           142:         (((bit_mask) & 0x00FF00FFUL) == 0 ? 8 : 0) + \
        !           143:         (((bit_mask) & 0x0F0F0F0FUL) == 0 ? 4 : 0) + \
        !           144:         (((bit_mask) & 0x33333333UL) == 0 ? 2 : 0) + \
        !           145:         (((bit_mask) & 0x55555555UL) == 0 ? 1 : 0))
        !           146:   
        !           147: #define        __MOST_BIT_8_CONST(bit_mask)    \
        !           148:        ((((bit_mask) & 0xF0U) != 0 ? 4 : 0) + \
        !           149:         (((bit_mask) & 0xCCU) != 0 ? 2 : 0) + \
        !           150:         (((bit_mask) & 0xAAU) != 0 ? 1 : 0))
        !           151: 
        !           152: #define        __MOST_BIT_16_CONST(bit_mask)   \
        !           153:        ((((bit_mask) & 0xFF00U) != 0 ? 8 : 0) + \
        !           154:         (((bit_mask) & 0xF0F0U) != 0 ? 4 : 0) + \
        !           155:         (((bit_mask) & 0xCCCCU) != 0 ? 2 : 0) + \
        !           156:         (((bit_mask) & 0xAAAAU) != 0 ? 1 : 0))
        !           157: 
        !           158: #define        __MOST_BIT_32_CONST(bit_mask)   \
        !           159:        ((((bit_mask) & 0xFFFF0000UL) != 0 ? 16 : 0) + \
        !           160:         (((bit_mask) & 0xFF00FF00UL) != 0 ? 8 : 0) + \
        !           161:         (((bit_mask) & 0xF0F0F0F0UL) != 0 ? 4 : 0) + \
        !           162:         (((bit_mask) & 0xCCCCCCCCUL) != 0 ? 2 : 0) + \
        !           163:         (((bit_mask) & 0xAAAAAAAAUL) != 0 ? 1 : 0))
        !           164: 
        !           165: #define        __LEAST_BIT_8(bit_mask) \
        !           166:        (_TRICKS_ASSERT (((bit_mask) & 0xFFU) != 0), \
        !           167:         _TRICKS_ASSERT (((bit_mask) & ~ 0xFFU) == 0), \
        !           168:         __LEAST_BIT_8_CONST (bit_mask))
        !           169: 
        !           170: #define        __LEAST_BIT_16(bit_mask)        \
        !           171:        (_TRICKS_ASSERT (((bit_mask) & 0xFFFFU) != 0), \
        !           172:         _TRICKS_ASSERT (((bit_mask) & ~ 0xFFFFU) == 0), \
        !           173:         __LEAST_BIT_16_CONST (bit_mask))
        !           174: 
        !           175: #define        __LEAST_BIT_32(bit_mask)        \
        !           176:        (_TRICKS_ASSERT ((bit_mask) != 0), \
        !           177:         __LEAST_BIT_32_CONST (bit_mask))
        !           178:   
        !           179: #define        __MOST_BIT_8(bit_mask)  \
        !           180:        (_TRICKS_ASSERT (((bit_mask) & 0xFFU) != 0), \
        !           181:         _TRICKS_ASSERT (((bit_mask) & ~ 0xFFU) == 0), \
        !           182:         __MOST_BIT_8_CONST (bit_mask))
        !           183: 
        !           184: #define        __MOST_BIT_16(bit_mask) \
        !           185:        (_TRICKS_ASSERT (((bit_mask) & 0xFFFFU) != 0), \
        !           186:         _TRICKS_ASSERT (((bit_mask) & ~ 0xFFFFU) == 0), \
        !           187:         __MOST_BIT_16_CONST (bit_mask))
        !           188: 
        !           189: #define        __MOST_BIT_32(bit_mask) \
        !           190:        (_TRICKS_ASSERT ((bit_mask) != 0), \
        !           191:         __MOST_BIT_32_CONST (bit_mask))
        !           192: 
        !           193: #if    __GNUC__ && _I386
        !           194: 
        !           195: /*
        !           196:  * For the speed-obsessed, here are in-line versions for GCC on Intel i386/
        !           197:  * i486 processors.
        !           198:  */
        !           199: 
        !           200: #if    __CHAR_BIT != 8 || __SHRT_BIT != 16 || __INT_BIT != 32 || \
        !           201:                __LONG_BIT != 32
        !           202: # error        Do you *really* have an i386/i486 system?
        !           203: #endif
        !           204: 
        !           205: #include <common/ccompat.h>
        !           206: #include <common/xdebug.h>
        !           207: #include <common/__types.h>
        !           208: 
        !           209: __LOCAL__ __INLINE__ __uint_t (__LEAST_BIT_8) (__ulong_t _bit_mask) {
        !           210:        int             _result;
        !           211:        _TRICKS_ASSERT ((_bit_mask & 0xFFU) != 0); 
        !           212:        _TRICKS_ASSERT ((_bit_mask & ~ 0xFFU) == 0); 
        !           213:        __NON_ISO (asm) ("bsf %1,%0" : "=r" (_result) :
        !           214:                         "g" (_bit_mask));
        !           215:        return _result;
        !           216: }
        !           217: 
        !           218: __LOCAL__ __INLINE__ __uint_t (__LEAST_BIT_16) (__ulong_t _bit_mask) {
        !           219:        int             _result;
        !           220:        _TRICKS_ASSERT ((_bit_mask & 0xFFFFU) != 0);
        !           221:        _TRICKS_ASSERT ((_bit_mask & ~ 0xFFFFU) == 0);
        !           222:        __NON_ISO (asm) ("bsf %1,%0" : "=r" (_result) :
        !           223:                         "g" (_bit_mask));
        !           224:        return _result;
        !           225: }
        !           226: 
        !           227: __LOCAL__ __INLINE__ __uint_t (__LEAST_BIT_32) (__ulong_t _bit_mask) {
        !           228:        int             _result;
        !           229:        _TRICKS_ASSERT (_bit_mask != 0);
        !           230:        __NON_ISO (asm) ("bsf %1,%0" : "=r" (_result) :
        !           231:                         "g" (_bit_mask));
        !           232:        return _result;
        !           233: }
        !           234: 
        !           235: __LOCAL__ __INLINE__ __uint_t (__MOST_BIT_8) (__ulong_t _bit_mask) {
        !           236:        int             _result;
        !           237:        _TRICKS_ASSERT ((_bit_mask & 0xFFU) != 0);
        !           238:        _TRICKS_ASSERT ((_bit_mask & ~ 0xFFU) == 0);
        !           239:        __NON_ISO (asm) ("bsr %1,%0" : "=r" (_result) :
        !           240:                         "g" (_bit_mask));
        !           241:        return _result;
        !           242: }
        !           243: 
        !           244: __LOCAL__ __INLINE__ __uint_t (__MOST_BIT_16) (__ulong_t _bit_mask) {
        !           245:        int             _result;
        !           246:        _TRICKS_ASSERT ((_bit_mask & 0xFFFFU) != 0);
        !           247:        _TRICKS_ASSERT ((_bit_mask & ~ 0xFFFFU) == 0);
        !           248:        __NON_ISO (asm) ("bsr %1,%0" : "=r" (_result) :
        !           249:                         "g" (_bit_mask));
        !           250:        return _result;
        !           251: }
        !           252: 
        !           253: __LOCAL__ __INLINE__ __uint_t (__MOST_BIT_32) (__ulong_t _bit_mask) {
        !           254:        int             _result;
        !           255:        _TRICKS_ASSERT (_bit_mask != 0);
        !           256:        __NON_ISO (asm) ("bsr %1,%0" : "=r" (_result) :
        !           257:                         "g" (_bit_mask));
        !           258:        return _result;
        !           259: }
        !           260: 
        !           261: /*
        !           262:  * Make the portable versions go away... we leave them around up to this point
        !           263:  * for those people that want to check that the fast versions really work :-)
        !           264:  */
        !           265: 
        !           266: #undef __LEAST_BIT_8
        !           267: #undef __LEAST_BIT_16
        !           268: #undef __LEAST_BIT_32
        !           269: #undef __MOST_BIT_8
        !           270: #undef __MOST_BIT_16
        !           271: #undef __MOST_BIT_32
        !           272: 
        !           273: #endif /* __GNUC__ && _I386 */
        !           274: 
        !           275: 
        !           276: /*
        !           277:  * Use the combined abilities of __CONCAT () and rescanning with the type ->
        !           278:  * size macros from <common/_limits.h> to simplify the creation of different
        !           279:  * versions of the scanning macros.
        !           280:  */
        !           281: 
        !           282: #define        __SCAN_BIT_CONST(bit_mask, direction, type) \
        !           283:                __CONCAT5 (__, direction,_BIT_, type, _CONST) (bit_mask)
        !           284: 
        !           285: #define        __SCAN_BIT(bit_mask, direction, type) \
        !           286:                __CONCAT4 (__, direction,_BIT_, type) (bit_mask)
        !           287: 
        !           288: #define        __LEAST_BIT_UCHAR_CONST(bit_mask) \
        !           289:                __SCAN_BIT_CONST (bit_mask, LEAST, __CHAR)
        !           290: #define        __LEAST_BIT_USHRT_CONST(bit_mask) \
        !           291:                __SCAN_BIT_CONST (bit_mask, LEAST, __SHORT)
        !           292: #define        __LEAST_BIT_UINT_CONST(bit_mask) \
        !           293:                __SCAN_BIT_CONST (bit_mask, LEAST, __INT)
        !           294: #define        __LEAST_BIT_ULONG_CONST(bit_mask) \
        !           295:                __SCAN_BIT_CONST (bit_mask, LEAST, __LONG)
        !           296: 
        !           297: #define        __MOST_BIT_UCHAR_CONST(bit_mask) \
        !           298:                __SCAN_BIT_CONST (bit_mask, MOST, __CHAR)
        !           299: #define        __MOST_BIT_USHRT_CONST(bit_mask) \
        !           300:                __SCAN_BIT_CONST (bit_mask, MOST, __SHORT)
        !           301: #define        __MOST_BIT_UINT_CONST(bit_mask) \
        !           302:                __SCAN_BIT_CONST (bit_mask, MOST, __INT)
        !           303: #define        __MOST_BIT_ULONG_CONST(bit_mask) \
        !           304:                __SCAN_BIT_CONST (bit_mask, MOST, __LONG)
        !           305: 
        !           306: #define        __LEAST_BIT_UCHAR(bit_mask)     __SCAN_BIT (bit_mask, LEAST, __CHAR)
        !           307: #define        __LEAST_BIT_USHRT(bit_mask)     __SCAN_BIT (bit_mask, LEAST, __SHORT)
        !           308: #define        __LEAST_BIT_UINT(bit_mask)      __SCAN_BIT (bit_mask, LEAST, __INT)
        !           309: #define        __LEAST_BIT_ULONG(bit_mask)     __SCAN_BIT (bit_mask, LEAST, __LONG)
        !           310: 
        !           311: #define        __MOST_BIT_UCHAR(bit_mask)      __SCAN_BIT (bit_mask, MOST, __CHAR)
        !           312: #define        __MOST_BIT_USHRT(bit_mask)      __SCAN_BIT (bit_mask, MOST, __SHORT)
        !           313: #define        __MOST_BIT_UINT(bit_mask)       __SCAN_BIT (bit_mask, MOST, __INT)
        !           314: #define        __MOST_BIT_ULONG(bit_mask)      __SCAN_BIT (bit_mask, MOST, __LONG)
        !           315: 
        !           316: 
        !           317: /*
        !           318:  * This is not really a trick, it's too obvious. However, it is so frequently
        !           319:  * used that we keep it around.
        !           320:  */
        !           321: 
        !           322: #define        __ARRAY_LENGTH(array_type_or_object) \
        !           323:                (sizeof (array_type_or_object) / \
        !           324:                         sizeof ((array_type_or_object) [0]))
        !           325: 
        !           326: 
        !           327: /*
        !           328:  * Add one unsigned integer to another, producing an unsigned result that does
        !           329:  * not overflow normally but which pegs itself at the value of UINT_MAX. Plus,
        !           330:  * we define subtraction of one unsigned integer from another with no
        !           331:  * underflow, the result sticking at 0.
        !           332:  */
        !           333: 
        !           334: #define        __ADD_UINT_WITH_MAX(addend,augend) \
        !           335:        ((addend) + 0U + (augend) < (addend) ? __UINT_MAX : \
        !           336:                (addend) + 0U + (augend))
        !           337: 
        !           338: #define        __SUB_UINT_WITH_MIN(minuend,subtrahend) \
        !           339:        ((minuend) + 0U - (subtrahend) > (minuend) ? 0U : \
        !           340:                (minuend) + 0U - (subtrahend))
        !           341: 
        !           342: #if    __GNUC__ && _I386
        !           343: 
        !           344: /*
        !           345:  * As above, but we cheat by using "subtract with borrow" when we know the
        !           346:  * carry flag is set as a very cheap way of getting a -1 into the result.
        !           347:  */
        !           348: 
        !           349: __LOCAL__ __INLINE__
        !           350: __uint_t (__ADD_UINT_WITH_MAX) (__uint_t _addend, __uint_t _augend) {
        !           351:        __uint_t        _result;
        !           352:        __NON_ISO (asm) ("addl %2, %0\n"
        !           353:                         "jnc  Ltricks_addu\n"
        !           354:                         "sbbl %0, %0\n"
        !           355:                         "Ltricks_addu:\n" :
        !           356:                         "=r" (_result) : "0" (_addend), "g" (_augend));
        !           357:        return _result;
        !           358: }
        !           359: 
        !           360: __LOCAL__ __INLINE__
        !           361: __uint_t (__SUB_UINT_WITH_MIN) (__uint_t _minuend, __uint_t _subtrahend) {
        !           362:        __uint_t        _result;
        !           363:        __NON_ISO (asm) ("subl %2, %0\n"
        !           364:                         "jnc  Ltricks_subu\n"
        !           365:                         "subl %0, %0\n"
        !           366:                         "Ltricks_subu:" :
        !           367:                         "=r" (_result) : "0" (_minuend), "g" (_subtrahend));
        !           368:        return _result;
        !           369: }
        !           370: 
        !           371: #undef __ADD_UINT_WITH_MAX
        !           372: #undef __SUB_UINT_WITH_MIN
        !           373: 
        !           374: #endif /* __GNUC__ && _I386 */
        !           375: 
        !           376: #endif /* ! defined (__COMMON__TRICKS_H__) */

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.