diff options
Diffstat (limited to 'gen/bits')
-rw-r--r-- | gen/bits/intconf.c | 52 | ||||
-rw-r--r-- | gen/bits/intconf.h | 117 |
2 files changed, 168 insertions, 1 deletions
diff --git a/gen/bits/intconf.c b/gen/bits/intconf.c index 7e48fce..5a52d12 100644 --- a/gen/bits/intconf.c +++ b/gen/bits/intconf.c @@ -21,7 +21,18 @@ +/** + * Used to determine the signness of `char`. + */ volatile char nul = 0; + +/** + * Used to determine the signness of `wchar_t`. + * + * Note that `wchar_t` is set implicitly by the + * help of the compiler so that our libc does + * not taint the result. + */ volatile typeof(L'\0') wnul = 0; @@ -35,6 +46,15 @@ volatile typeof(L'\0') wnul = 0; */ +/** + * Measure the performance of a intrinsic integer type, + * and if it is faster than the previous candidate (or + * is the first candidate,) store it as the, yet, most + * performant candidate. + * + * @param VAR A volatile register variable of the + * type that shall be tested. + */ #define FAST_TEST(VAR) \ n = 0, *VAR##p = 0; \ if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start)) \ @@ -65,10 +85,26 @@ volatile typeof(L'\0') wnul = 0; last = this +/** + * Determine whether the performance of `typeof(VAR)` should be determined, + * when finding the most performant, compatiable intrinsic type of a `int_fastN_t`. + * + * @param VAR An variable of the type (or the type itself) that is a candidate. + * @return Determine whether the type shall be tested. + */ #define TEST(VAR) (this = 8 * (int)sizeof(VAR), ((this >= bits) && (this > last))) + #if defined(__GNUC__) __attribute__((optimize("-O0"))) #endif +/** + * Find the (in general) fastest intrinsic integer type, + * that has at least a specified number of bits. + * + * @param bits The minimum number of bits the type may have. + * @return The number of bits the most performance + * compatible integer type has. + */ static int fast(int bits) { int last = 0, this = 0, best = 0, n, m; @@ -103,11 +139,26 @@ static int fast(int bits) #undef TEST +/** + * @param argc The number of command line arguments, should + * be either 1 (print integer width information) + * or 2 (otherwise). + * @param argv Command line arguments, if `argc == 2`, `argv[2]` + * is interpreted as follows: + * - "fast8" Print the number of bits in `int_fast8_t` and `uint_fast8_t`. + * - "fast16" Print the number of bits in `int_fast16_t` and `uint_fast16_t`. + * - "fast32" Print the number of bits in `int_fast32_t` and `uint_fast32_t`. + * - "fast64" Print the number of bits in `int_fast64_t` and `uint_fast64_t`. + * - "char-signed" Print 1 if `char` is signed, and `0` if it is unsigned. + * - "wchar-signed" Print 1 if `wchar_t` is signed, and `0` if it is unsigned. + * @return 0 on success, 1 on error (including printing error.) + */ int main(int argc, char* argv[]) { int r = 0; if (argc < 2) { + /* Print the number of bits in the intrinsic integers types. */ r |= printf("CHAR_BIT %zu\n", 8 * sizeof(char)); r |= printf("SHORT_BIT %zu\n", 8 * sizeof(short int)); r |= printf("INT_BIT %zu\n", 8 * sizeof(int)); @@ -116,6 +167,7 @@ int main(int argc, char* argv[]) r |= printf("PTR_BIT %zu\n", 8 * sizeof(void*)); r |= printf("WCHAR_BIT %zu\n", 8 * sizeof(L'\0')); + /* Print the intrinsic type for specific numbers of bits. */ r |= printf("INT%zu %s\n", 8 * sizeof(char), "char"); r |= printf("INT%zu %s\n", 8 * sizeof(short int), "short int"); r |= printf("INT%zu %s\n", 8 * sizeof(int), "int"); diff --git a/gen/bits/intconf.h b/gen/bits/intconf.h index 128b0ba..69ea473 100644 --- a/gen/bits/intconf.h +++ b/gen/bits/intconf.h @@ -24,41 +24,156 @@ //>FAST32=$(bin/gen/bits/intconf fast32) //>FAST64=$(bin/gen/bits/intconf fast64) -#define __MAX_TO_MIN(max) (-(max) - 1) + +/** + * Converts an integer's maximum value to + * its [the integer's] minimum value. + */ +#define __MAX_TO_MIN(max) (-(max) - 1) /* TODO compiler-flag-dependent */ + +/* TODO compiler-flag-dependent */ #if //(bin/gen/bits/intconf char-signed) +/** + * Set if and only if `char` is signed by default. + */ # define __CHAR_SIGNED + +/** + * The default signness-modifiers for `char`. + */ # define __CHAR_SIGNNESS signed #else # define __CHAR_SIGNNESS unsigned #endif + #if //(bin/gen/bits/intconf wchar-signed) +/** + * Set if and only if `wchar_t` is signed by default. + */ # define __WCHAR_SIGNED + +/** + * The default signness-modifiers for `wchar_t`. + */ # define __WCHAR_SIGNNESS signed #else # define __WCHAR_SIGNNESS unsigned #endif + +/** + * The number of bits in `char`. + * (8 is mandatates, but I did it thus way for uniformity.) + */ #define __CHAR_BIT //(bin/gen/bits/intconf | grep ^CHAR_BIT | sed "s/^[^ ]* //") + +/** + * The number of bits in `short int`. + */ #define __SHORT_BIT //(bin/gen/bits/intconf | grep ^SHORT_BIT | sed "s/^[^ ]* //") + +/** + * The number of bits in `int`. + */ #define __INT_BIT //(bin/gen/bits/intconf | grep ^INT_BIT | sed "s/^[^ ]* //") + +/** + * The number of bits in `long int`. + */ #define __LONG_BIT //(bin/gen/bits/intconf | grep ^LONG_BIT | sed "s/^[^ ]* //") + +/** + * The number of bits in `long long int`. + */ #define __LONG_LONG_BIT //(bin/gen/bits/intconf | grep ^LONG_LONG_BIT | sed "s/^[^ ]* //") + +/** + * The number of bits in `void*`. + */ #define __PTR_BIT //(bin/gen/bits/intconf | grep ^PTR_BIT | sed "s/^[^ ]* //") + +/** + * The number of bits in `wchar`. + */ #define __WCHAR_BIT //(bin/gen/bits/intconf | grep ^WCHAR_BIT | sed "s/^[^ ]* //") + +/** + * The underlaying intrinsic type for `int8_t` or `uint8_t`. + */ #define __INT8 //(bin/gen/bits/intconf | grep ^INT8 | sed "s/^[^ ]* //" | sed 1q) + +/** + * The underlaying intrinsic type for `int16_t` or `uint16_t`. + */ #define __INT16 //(bin/gen/bits/intconf | grep ^INT16 | sed "s/^[^ ]* //" | sed 1q) + +/** + * The underlaying intrinsic type for `int32_t` or `uint32_t`. + */ #define __INT32 //(bin/gen/bits/intconf | grep ^INT32 | sed "s/^[^ ]* //" | sed 1q) + +/** + * The underlaying intrinsic type for `int64_t` or `uint64_t`. + */ #define __INT64 //(bin/gen/bits/intconf | grep ^INT64 | sed "s/^[^ ]* //" | sed 1q) + +/** + * The underlaying intrinsic type for `int8_t` or `uint8_t`. + */ #define __INT_FAST8 __INT//{FAST8} + +/** + * The underlaying intrinsic type for `int16_t` or `uint16_t`. + */ #define __INT_FAST16 __INT//{FAST16} + +/** + * The underlaying intrinsic type for `int32_t` or `uint32_t`. + */ #define __INT_FAST32 __INT//{FAST32} + +/** + * The underlaying intrinsic type for `int64_t` or `uint64_t`. + */ #define __INT_FAST64 __INT//{FAST64} + +/** + * The maximum value of `int_fast8_t`. + */ #define __INT_FAST8_MAX INT//{FAST8}_MAX + +/** + * The maximum value of `int_fast16_t`. + */ #define __INT_FAST16_MAX INT//{FAST16}_MAX + +/** + * The maximum value of `int_fast32_t`. + */ #define __INT_FAST32_MAX INT//{FAST32}_MAX + +/** + * The maximum value of `int_fast64_t`. + */ #define __INT_FAST64_MAX INT//{FAST64}_MAX + +/** + * The maximum value of `uint_fast8_t`. + */ #define __UINT_FAST8_MAX UINT//{FAST8}_MAX + +/** + * The maximum value of `uint_fast16_t`. + */ #define __UINT_FAST16_MAX UINT//{FAST16}_MAX + +/** + * The maximum value of `uint_fast32_t`. + */ #define __UINT_FAST32_MAX UINT//{FAST32}_MAX + +/** + * The maximum value of `uint_fast64_t`. + */ #define __UINT_FAST64_MAX UINT//{FAST64}_MAX |