Changeset 76bf23c


Ignore:
Timestamp:
Apr 7, 2020, 1:34:59 PM (5 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
dccd1b0
Parents:
9d5d01f
Message:

second attempt at bit manipulation operations

Files:
4 added
3 deleted
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/bitmanip.hfa

    r9d5d01f r76bf23c  
    1111// Created On       : Sat Mar 14 18:12:27 2020
    1212// Last Modified By : Peter A. Buhr
    13 // Last Modified On : Mon Mar 16 14:28:46 2020
    14 // Update Count     : 49
     13// Last Modified On : Mon Apr  6 22:17:19 2020
     14// Update Count     : 78
    1515//
    1616
     
    2323#include <assert.h>
    2424
     25#define __bitsizeof( n ) (sizeof(n) * __CHAR_BIT__)
     26
    2527static inline {
    2628    // Count leading 0 bits.
    27     unsigned int cl0( unsigned char n ) { return n != 0 ? __builtin_clz( n ) - (sizeof(unsigned int) * __CHAR_BIT__ - sizeof(n) * __CHAR_BIT__) : sizeof(n) * __CHAR_BIT__; }
    28     unsigned int cl0( unsigned short int n ) { return n != 0 ? __builtin_clz( n ) - (sizeof(unsigned int) * __CHAR_BIT__ - sizeof(n) * __CHAR_BIT__) : sizeof(n) * __CHAR_BIT__; }
    29     unsigned int cl0( unsigned int n ) { return n != 0 ? __builtin_clz( n ) : sizeof(n) * __CHAR_BIT__; }
    30     unsigned int cl0( unsigned long int n ) { return n != 0 ? __builtin_clzl( n ) : sizeof(n) * __CHAR_BIT__; }
    31     unsigned int cl0( unsigned long long int n ) { return n != 0 ? __builtin_clzll( n ) : sizeof(n) * __CHAR_BIT__; }
     29    unsigned int leading0s( unsigned char n ) { return n != 0 ? __builtin_clz( n ) - (__bitsizeof(unsigned int) - __bitsizeof(n)) : __bitsizeof(n); }
     30    unsigned int leading0s( unsigned short int n ) { return n != 0 ? __builtin_clz( n ) - (__bitsizeof(unsigned int) - __bitsizeof(n)) : __bitsizeof(n); }
     31    unsigned int leading0s( unsigned int n ) { return n != 0 ? __builtin_clz( n ) : __bitsizeof(n); }
     32    unsigned int leading0s( unsigned long int n ) { return n != 0 ? __builtin_clzl( n ) : __bitsizeof(n); }
     33    unsigned int leading0s( unsigned long long int n ) { return n != 0 ? __builtin_clzll( n ) : __bitsizeof(n); }
    3234
    3335    // Count trailing 0 bits.
    34     unsigned int ct0( unsigned char n ) { return n != 0 ? __builtin_ctz( n ) : sizeof(n) * __CHAR_BIT__; }
    35     unsigned int ct0( unsigned short int n ) { return n != 0 ? __builtin_ctz( n ) : sizeof(n) * __CHAR_BIT__; }
    36     unsigned int ct0( unsigned int n ) { return n != 0 ? __builtin_ctz( n ) : sizeof(n) * __CHAR_BIT__; }
    37     unsigned int ct0( unsigned long int n ) { return n != 0 ? __builtin_ctzl( n ) : sizeof(n) * __CHAR_BIT__; }
    38     unsigned int ct0( unsigned long long int n ) { return n != 0 ? __builtin_ctzll( n ) : sizeof(n) * __CHAR_BIT__; }
     36    unsigned int trailing0s( unsigned char n ) { return n != 0 ? __builtin_ctz( n ) : __bitsizeof(n); }
     37    unsigned int trailing0s( unsigned short int n ) { return n != 0 ? __builtin_ctz( n ) : __bitsizeof(n); }
     38    unsigned int trailing0s( unsigned int n ) { return n != 0 ? __builtin_ctz( n ) : __bitsizeof(n); }
     39    unsigned int trailing0s( unsigned long int n ) { return n != 0 ? __builtin_ctzl( n ) : __bitsizeof(n); }
     40    unsigned int trailing0s( unsigned long long int n ) { return n != 0 ? __builtin_ctzll( n ) : __bitsizeof(n); }
    3941
    4042    // Count all 1 bits.
    41     unsigned int ca1( unsigned char n ) { return __builtin_popcount( n ); }
    42     unsigned int ca1( unsigned short int n ) { return __builtin_popcount( n ); }
    43     unsigned int ca1( unsigned int n ) { return __builtin_popcount( n ); }
    44     unsigned int ca1( unsigned long int n ) { return __builtin_popcountl( n ); }
    45     unsigned int ca1( unsigned long long int n ) { return __builtin_popcountll( n ); }
     43    unsigned int all1s( unsigned char n ) { return __builtin_popcount( n ); }
     44    unsigned int all1s( unsigned short int n ) { return __builtin_popcount( n ); }
     45    unsigned int all1s( unsigned int n ) { return __builtin_popcount( n ); }
     46    unsigned int all1s( unsigned long int n ) { return __builtin_popcountl( n ); }
     47    unsigned int all1s( unsigned long long int n ) { return __builtin_popcountll( n ); }
    4648
    4749    // Count all 0 bits.
    48     unsigned int ca0( unsigned char n ) { return sizeof(n) * __CHAR_BIT__ - __builtin_popcount( n ); }
    49     unsigned int ca0( unsigned short int n ) { return sizeof(n) * __CHAR_BIT__ - __builtin_popcount( n ); }
    50     unsigned int ca0( unsigned int n ) { return sizeof(n) * __CHAR_BIT__ - __builtin_popcount( n ); }
    51     unsigned int ca0( unsigned long int n ) { return sizeof(n) * __CHAR_BIT__ - __builtin_popcountl( n ); }
    52     unsigned int ca0( unsigned long long int n ) { return sizeof(n) * __CHAR_BIT__ - __builtin_popcountll( n ); }
     50    unsigned int all0s( unsigned char n ) { return __bitsizeof(n) - __builtin_popcount( n ); }
     51    unsigned int all0s( unsigned short int n ) { return __bitsizeof(n) - __builtin_popcount( n ); }
     52    unsigned int all0s( unsigned int n ) { return __bitsizeof(n) - __builtin_popcount( n ); }
     53    unsigned int all0s( unsigned long int n ) { return __bitsizeof(n) - __builtin_popcountl( n ); }
     54    unsigned int all0s( unsigned long long int n ) { return __bitsizeof(n) - __builtin_popcountll( n ); }
    5355
    54     // Find least significiant set bit. (ffs)
    55     unsigned int fls( unsigned int n ) { return __builtin_ffs( n ); }
    56     unsigned int fls( unsigned long int n ) { return __builtin_ffsl( n ); }
    57     unsigned int fls( unsigned long long int n ) { return __builtin_ffsll( n ); }
     56    // Find least significiant zero bit. (ffs)
     57    unsigned int low0( unsigned char n ) { return __builtin_ffs( (typeof(n))~n ); }
     58    unsigned int low0( unsigned short int n ) { return __builtin_ffs( (typeof(n))~n ); }
     59    unsigned int low0( unsigned int n ) { return __builtin_ffs( ~n ); }
     60    unsigned int low0( unsigned long int n ) { return __builtin_ffsl( ~n ); }
     61    unsigned int low0( unsigned long long int n ) { return __builtin_ffsll( ~n ); }
    5862
    59     // Find most significiant set bit.
    60     unsigned int fms( unsigned char n ) { return n != 0 ? sizeof(unsigned int) * __CHAR_BIT__ - __builtin_clz( n ) : 0; }
    61     unsigned int fms( unsigned short int n ) { return n != 0 ? sizeof(unsigned int) * __CHAR_BIT__ - __builtin_clz( n ) : 0; }
    62     unsigned int fms( unsigned int n ) { return n != 0 ? sizeof(n) * __CHAR_BIT__ - __builtin_clz( n ) : 0; }
    63     unsigned int fms( unsigned long int n ) { return n != 0 ? sizeof(n) * __CHAR_BIT__ - __builtin_clzl( n ) : 0; }
    64     unsigned int fms( unsigned long long int n ) { return n != 0 ? sizeof(n) * __CHAR_BIT__ - __builtin_clzll( n ) : 0; }
     63    // Find least significiant one bit.
     64    unsigned int low1( unsigned int n ) { return __builtin_ffs( n ); }
     65    unsigned int low1( unsigned long int n ) { return __builtin_ffsl( n ); }
     66    unsigned int low1( unsigned long long int n ) { return __builtin_ffsll( n ); }
    6567
    66     // Check for power of 2
    67     bool pow2( unsigned long int value ) {
    68                 return (value & (value - 1)) == 0;                              // clears bits below value, rounding down to the next lower multiple of value
    69     } // pow2
     68    // Find most significiant zero bit.
     69    unsigned int high0( unsigned char n ) { return n != (typeof(n))-1 ? __bitsizeof(unsigned int) - __builtin_clz( (typeof(n))~n ) : 0; }
     70    unsigned int high0( unsigned short int n ) { return n != (typeof(n))-1 ? __bitsizeof(unsigned int) - __builtin_clz( (typeof(n))~n ) : 0; }
     71    unsigned int high0( unsigned int n ) { return n != -1 ? __bitsizeof(n) - __builtin_clz( ~n ) : 0; }
     72    unsigned int high0( unsigned long int n ) { return n != -1 ? __bitsizeof(n) - __builtin_clzl( ~n ) : 0; }
     73    unsigned int high0( unsigned long long int n ) { return n != -1 ? __bitsizeof(n) - __builtin_clzll( ~n ) : 0; }
    7074
    71     // Returns value aligned at the floor of align.
    72     unsigned long int floor( unsigned long int value, unsigned long int align ) {
    73                 assert( pow2( align ) );
    74                 return value & -align;                                                  // clear bits above or equal to align, giving value % align
    75     } // floor
     75    // Find most significiant one bit.
     76    unsigned int high1( unsigned char n ) { return n != 0 ? __bitsizeof(unsigned int) - __builtin_clz( n ) : 0; }
     77    unsigned int high1( unsigned short int n ) { return n != 0 ? __bitsizeof(unsigned int) - __builtin_clz( n ) : 0; }
     78    unsigned int high1( unsigned int n ) { return n != 0 ? __bitsizeof(n) - __builtin_clz( n ) : 0; }
     79    unsigned int high1( unsigned long int n ) { return n != 0 ? __bitsizeof(n) - __builtin_clzl( n ) : 0; }
     80    unsigned int high1( unsigned long long int n ) { return n != 0 ? __bitsizeof(n) - __builtin_clzll( n ) : 0; }
    7681
    77     // Returns value aligned at the ceiling of align.
    78     unsigned long int ceiling( unsigned long int value, unsigned long int align ) {
    79                 assert( pow2( align ) );
    80                 return -floor( -value, align );                                 // negate, round down, negate is the same as round up
    81     } // ceiling
    82 }
     82    // Check for power of 2, clears bits below value, rounding down to the next lower multiple of value.
     83    bool is_pow2( int value ) { return (value & (value - 1)) == 0; }
     84    bool is_pow2( unsigned long long int value ) { return (value & (value - 1)) == 0; }
     85
     86    // Returns value aligned at the floor of align, clear bits above or equal to align, giving value % align.
     87    unsigned int floor2( unsigned int value, unsigned int align ) { assert( is_pow2( align ) ); return value & -align; }
     88    unsigned long long int floor2( unsigned long long int value, unsigned long long int align ) { assert( is_pow2( align ) ); return value & -align; }
     89
     90    unsigned int floor( unsigned int value, unsigned int align ) { return value / align * align; }
     91    unsigned long long int floor( unsigned long long int value, unsigned long long int align ) { return value / align * align; }
     92
     93    // Returns value aligned at the ceiling of align, negate, round down, negate is the same as round up.
     94    unsigned int ceiling2( unsigned int value, unsigned int align ) { assert( is_pow2( align ) ); return -floor2( -value, align ); }
     95    unsigned long long int ceiling2( unsigned long long int value, unsigned long long int align ) { assert( is_pow2( align ) ); return -floor2( -value, align ); }
     96
     97    unsigned int ceiling( unsigned int value, unsigned int align ) { return (value + (align - 1)) / align; }
     98    unsigned long long int ceiling( unsigned long long int value, unsigned long long int align ) { return (value + (align - 1)) / align; }
     99} // distribution
    83100
    84101// Local Variables: //
Note: See TracChangeset for help on using the changeset viewer.