aboutsummaryrefslogtreecommitdiffstats
path: root/gen
diff options
context:
space:
mode:
authorMattias Andrée <maandree@operamail.com>2015-10-16 20:43:50 +0200
committerMattias Andrée <maandree@operamail.com>2015-10-16 20:43:50 +0200
commitad143de39cb8b76404ddd307b5d93328dbb06c5e (patch)
tree57ca6f6f2a3941493b4338aad50f69a748a79f36 /gen
parentinfo: fnindex (diff)
downloadslibc-ad143de39cb8b76404ddd307b5d93328dbb06c5e.tar.gz
slibc-ad143de39cb8b76404ddd307b5d93328dbb06c5e.tar.bz2
slibc-ad143de39cb8b76404ddd307b5d93328dbb06c5e.tar.xz
heuristically determine int_fastN_t
Signed-off-by: Mattias Andrée <maandree@operamail.com>
Diffstat (limited to 'gen')
-rw-r--r--gen/bits/intconf.c120
-rw-r--r--gen/bits/intconf.h7
2 files changed, 112 insertions, 15 deletions
diff --git a/gen/bits/intconf.c b/gen/bits/intconf.c
index 5955d38..2ba2754 100644
--- a/gen/bits/intconf.c
+++ b/gen/bits/intconf.c
@@ -16,24 +16,118 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <stdio.h>
+#include <string.h>
+#include <time.h>
-int main(void)
+/**
+ * On my amd64 machine, the usual result is:
+ * int_fast8_t = int32_t
+ * int_fast16_t = int32_t
+ * int_fast32_t = int32_t
+ * int_fast64_t = int64_t
+ */
+
+
+#define FAST_TEST(VAR) \
+ n = 0, *VAR##p = 0; \
+ if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &start)) \
+ return perror(NULL), -1; \
+ for (;;) \
+ { \
+ for (m = 1000; m--;) \
+ VAR = 50, VAR += 50, VAR -= 50, VAR *= 50, VAR /= 50, VAR <<= 1, VAR >>= 1, *VAR##p |= 1; \
+ n++; \
+ if (clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end)) \
+ return perror(NULL), -1; \
+ if (end.tv_sec > start.tv_sec + 2) \
+ break; \
+ if (end.tv_sec > start.tv_sec + 1) \
+ if (end.tv_nsec >= start.tv_nsec) \
+ break; \
+ } \
+ time_elapsed = (long long int)(end.tv_sec) * 1000000000LL; \
+ time_elapsed += (long long int)(end.tv_nsec); \
+ time_elapsed -= (long long int)(start.tv_sec) * 1000000000LL; \
+ time_elapsed -= (long long int)(start.tv_nsec); \
+ adjn = (double)n, adjn /= (double)time_elapsed / 1000000000.; \
+ fprintf(stderr, "int%zu_t:%s %i000 op:s in %lli.%09lli s = %lf op:s/s\n", \
+ 8 * sizeof(VAR), 8 * sizeof(VAR) < 10 ? " " : "", 8 * n, \
+ time_elapsed / 1000000000LL, time_elapsed % 1000000000LL, adjn * 8000.); \
+ if (adjn > bestn) \
+ bestn = adjn, best = 8 * sizeof(VAR); \
+ last = this
+
+
+#define TEST(VAR) (this = 8 * (int)sizeof(VAR), ((this >= bits) && (this > last)))
+#ifdef __GNUC__
+__attribute__((optimize("-O0")))
+#endif
+static int fast(int bits)
{
- printf("CHAR_BIT %zu\n", 8 * sizeof(char));
- printf("SHORT_BIT %zu\n", 8 * sizeof(short int));
- printf("INT_BIT %zu\n", 8 * sizeof(int));
- printf("LONG_BIT %zu\n", 8 * sizeof(long int));
- printf("LONG_LONG_BIT %zu\n", 8 * sizeof(long long int));
- printf("PTR_BIT %zu\n", 8 * sizeof(void*));
+ int last = 0, this = 0, best = 0, n, m;
+ float bestn;
+ float adjn;
+ struct timespec start, end;
+ long long int time_elapsed;
- printf("INT%zu %s\n", 8 * sizeof(char), "char");
- printf("INT%zu %s\n", 8 * sizeof(short int), "short int");
- printf("INT%zu %s\n", 8 * sizeof(int), "int");
- printf("INT%zu %s\n", 8 * sizeof(long int), "long int");
- printf("INT%zu %s\n", 8 * sizeof(long long int), "long long int");
+ register volatile char hhi;
+ register volatile short int hi;
+ register volatile int i;
+ register volatile long int li;
+ register volatile long long int lli;
+ volatile char hhip[1];
+ volatile short int hip[1];
+ volatile int ip[1];
+ volatile long int lip[1];
+ volatile long long int llip[1];
+
+ if (TEST(hhi)) { FAST_TEST(hhi); }
+ if (TEST(hi)) { FAST_TEST(hi); }
+ if (TEST(i)) { FAST_TEST(i); }
+ if (TEST(li)) { FAST_TEST(li); }
+ if (best) {
+ if (TEST(lli)) { FAST_TEST(lli); }
+ } else
+ best = 64;
+ fprintf(stderr, "int_fast%i_t = int%i_t\n\n", bits, best);
+
+ return best;
+}
+#undef TEST
+
+
+int main(int argc, char* argv[])
+{
+ int r = 0;
+ if (argc < 2)
+ {
+ 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));
+ r |= printf("LONG_BIT %zu\n", 8 * sizeof(long int));
+ r |= printf("LONG_LONG_BIT %zu\n", 8 * sizeof(long long int));
+ r |= printf("PTR_BIT %zu\n", 8 * sizeof(void*));
+
+ 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");
+ r |= printf("INT%zu %s\n", 8 * sizeof(long int), "long int");
+ r |= printf("INT%zu %s\n", 8 * sizeof(long long int), "long long int");
+ return r < 0 ? 1 : 0;
+ }
+ else if (argc == 2)
+ {
+ if (!strcmp(argv[1], "fast8")) r = fast(8);
+ else if (!strcmp(argv[1], "fast16")) r = fast(16);
+ else if (!strcmp(argv[1], "fast32")) r = fast(32);
+ else if (!strcmp(argv[1], "fast64")) r = fast(64);
+ if (r <= 0)
+ return 1;
+ return printf("%i\n", r) < 0 ? 1 : 0;
+ }
- return 0;
+ return 1;
}
diff --git a/gen/bits/intconf.h b/gen/bits/intconf.h
index 2dca3b5..eb7b5b5 100644
--- a/gen/bits/intconf.h
+++ b/gen/bits/intconf.h
@@ -18,7 +18,11 @@
#ifndef _BITS_INTCONF_H
#define _BITS_INTCONF_H
//>set -e
-//>FAST8=8; FAST16=64; FAST32=64; FAST64=64
+
+//>FAST8=$(bin/gen/bits/intconf fast8)
+//>FAST16=$(bin/gen/bits/intconf fast16)
+//>FAST32=$(bin/gen/bits/intconf fast32)
+//>FAST64=$(bin/gen/bits/intconf fast64)
#define __MAX_TO_MIN(max) (-(max) - 1)
#define __CHAR_BIT //(bin/gen/bits/intconf | grep ^CHAR_BIT | sed "s/^[^ ]* //")
@@ -45,6 +49,5 @@
#define __UINT_FAST64_MAX UINT//{FAST64}_MAX
-
#endif