chiark / gitweb /
math/mp-fibonacci.c: Fix spacing in comment.
[catacomb] / math / mptypes.c
1 /* -*-c-*-
2  *
3  * Generate `mptypes.h' header file for current architecture
4  *
5  * (c) 1999 Straylight/Edgeware
6  */
7
8 /*----- Licensing notice --------------------------------------------------*
9  *
10  * This file is part of Catacomb.
11  *
12  * Catacomb is free software; you can redistribute it and/or modify
13  * it under the terms of the GNU Library General Public License as
14  * published by the Free Software Foundation; either version 2 of the
15  * License, or (at your option) any later version.
16  *
17  * Catacomb is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
20  * GNU Library General Public License for more details.
21  *
22  * You should have received a copy of the GNU Library General Public
23  * License along with Catacomb; if not, write to the Free
24  * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
25  * MA 02111-1307, USA.
26  */
27
28 /*----- Header files ------------------------------------------------------*/
29
30 #define _GNU_SOURCE
31 #include "config.h"
32
33 #include <stdio.h>
34 #include <limits.h>
35 #if __STDC_VERSION__ >= 199900l
36 #  include <stdint.h>
37 #  include <inttypes.h>
38 #endif
39
40 /*----- Data types --------------------------------------------------------*/
41
42 /* --- Hack for GCC --- *
43  *
44  * WG14 in their infinite wisdom decided not to use the GCC constant name.
45  */
46
47 #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 91)
48 #  define EXT __extension__
49 #else
50 #  define EXT
51 #endif
52
53 #if defined(ULONG_LONG_MAX) && !defined(ULLONG_MAX)
54 #  define ULLONG_MAX ULONG_LONG_MAX
55 #endif
56
57 /* --- Choose the largest integer type --- */
58
59 #if defined(UINTMAX_MAX) && defined(PRIuMAX)
60   typedef uintmax_t umax;
61 # define P_UMAX PRIuMAX
62 #elif defined(ULLONG_MAX)
63   EXT typedef unsigned long long umax;
64 # define P_UMAX "llu"
65 #else
66   typedef unsigned long umax;
67 # define P_UMAX "lu"
68 #endif
69
70 /* --- Table of interesting types --- *
71  *
72  * These are in preference order.
73  */
74
75 enum {
76   f_stdint = 1u,
77   f_ext = 2u
78 };
79
80 struct itype {
81   const char *name;
82   const char *suff;
83   umax max;
84   unsigned flags;
85   unsigned bits;
86 } tytab[] = {
87   { "unsigned int",             "u",    UINT_MAX,               0 },
88   { "unsigned short",           "u",    USHRT_MAX,              0 },
89   { "unsigned long",            "ul",   ULONG_MAX,              0 },
90 #ifdef ULLONG_MAX
91   { "unsigned long long",       "ull",  EXT ULLONG_MAX,         f_ext },
92 #endif
93 #ifdef UINTMAX_MAX
94   { "uintmax_t",                "u",    UINTMAX_MAX,            f_stdint },
95 #endif
96   { 0,                          0 },
97 };
98
99 typedef struct itype itype;
100
101 /*----- Main code ---------------------------------------------------------*/
102
103 int main(int argc, char *argv[])
104 {
105   itype *i;
106   itype *largest, *mpw, *mpd;
107   const static char *extstr = "CATACOMB_MPTYPES_EXTENSION ";
108   unsigned p2;
109
110   /* --- Find the bitcounts --- */
111
112   for (i = tytab; i->name; i++) {
113     unsigned bits;
114     umax u = i->max;
115     for (bits = 0; u; bits++)
116       u >>= 1;
117     i->bits = bits;
118   }
119
120   /* --- Now try to find the interesting types --- *
121    *
122    * The first thing to do is to find the largest type.  Then I find the
123    * `best' type which is less than half that size, and then the `best' type
124    * which is twice as big as that one.
125    */
126
127 #if defined(FORCE_MPW_CUSSID)
128   largest = mpd = &tytab[3];
129   mpw = &tytab[2];
130   mpw->bits = 19; mpw->max = 0x7ffff;
131   mpd->bits = 38; mpd->max = 0x3fffffffffll;
132 #elif defined(FORCE_MPW_SHORT)
133   largest = mpd = &tytab[2];
134   mpw = &tytab[1];
135   mpw->bits = 16; mpw->max = 0xffff;
136   mpd->bits = 32; mpd->max = 0xffffffff;
137 #else
138   largest = tytab;
139   for (i = tytab; i->name; i++) {
140     if (i->bits > largest->bits)
141       largest = i;
142   }
143   for (mpw = 0, i = tytab; i->name; i++) {
144     if (i->bits * 2 <= largest->bits && (!mpw || i->bits > mpw->bits))
145       mpw = i;
146   }
147   if (!mpw)
148     mpw = tytab;
149   for (mpd = 0, i = tytab; i->name; i++) {
150     if (i->bits >= mpw->bits * 2 && (!mpd || i->bits < mpd->bits))
151       mpd = i;
152   }
153   if (!mpd) {
154     static itype w, d;
155     d = w = *mpw;
156     w.bits /= 2; w.max = ~(~((umax)0) << w.bits);
157     d.bits = w.bits * 2; d.max = ~(~((umax)0) << d.bits);
158     mpw = &w; mpd = &d;
159   }
160 #endif
161   for (p2 = 1; (p2 << 1) < mpw->bits; p2 <<= 1);
162
163   /* --- Output time --- */
164
165   puts("\
166 /* -*-c-*-\n\
167  *\n\
168  * mptypes.h [generated]\n\
169  */\n\
170 \n\
171 #ifndef CATACOMB_MPTYPES_H\n\
172 #define CATACOMB_MPTYPES_H\n\
173 ");
174   if ((mpd->flags | mpw->flags) & f_stdint) {
175     puts("\
176 #if __STDC_VERSION__ >= 199900l\n\
177 #  include <stdint.h>\n\
178 #endif\n\
179 ");
180   }
181   if ((mpd->flags | mpw->flags) & f_ext) {
182     printf("\
183 #if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 91)\n\
184 #  define %s __extension__\n\
185 #else\n\
186 #  define %s\n\
187 #endif\n\
188 ", extstr, extstr);
189   }
190   printf("\
191 %stypedef %s mpw;\n\
192 #define MPW_BITS %u\n\
193 #define MPW_P2 %u\n\
194 #define MPW_MAX %s%" P_UMAX "%s\n\
195 \n\
196 %stypedef %s mpd;\n\
197 #define MPD_BITS %u\n\
198 #define MPD_MAX %s%" P_UMAX "%s\n\
199 \n\
200 #endif\n\
201 ",
202   mpw->flags & f_ext ? extstr : "", mpw->name,
203   mpw->bits, p2,
204   mpw->flags & f_ext ? extstr : "", mpw->max, mpw->suff,
205   mpd->flags & f_ext ? extstr : "", mpd->name,
206   mpd->bits,
207   mpd->flags & f_ext ? extstr : "", mpd->max, mpd->suff);
208
209   return (0);
210 }
211
212 /*----- That's all, folks -------------------------------------------------*/