OSDN Git Service

* genmodes.c, mode-classes.def: New files.
[pf3gnuchains/gcc-fork.git] / gcc / genmodes.c
1 /* Generate the machine mode enumeration and associated tables.
2    Copyright (C) 2003
3    Free Software Foundation, Inc.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 2, or (at your option) any later
10 version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15 for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING.  If not, write to the Free
19 Software Foundation, 59 Temple Place - Suite 330, Boston, MA
20 02111-1307, USA.  */
21
22 #include "bconfig.h"
23 #include "system.h"
24 #include "errors.h"
25
26 /* enum mode_class is normally defined by machmode.h but we can't
27    include that header here.  */
28 #include "mode-classes.def"
29
30 #define DEF_MODE_CLASS(M) M
31 enum mode_class { MODE_CLASSES, MAX_MODE_CLASS };
32 #undef DEF_MODE_CLASS
33
34 /* Text names of mode classes, for output.  */
35 #define DEF_MODE_CLASS(M) #M
36 static const char *const mode_class_names[MAX_MODE_CLASS] =
37 {
38   MODE_CLASSES
39 };
40 #undef DEF_MODE_CLASS
41 #undef MODE_CLASSES
42
43 #ifdef EXTRA_MODES_FILE
44 # define HAVE_EXTRA_MODES 1
45 #else
46 # define HAVE_EXTRA_MODES 0
47 # define EXTRA_MODES_FILE ""
48 #endif
49
50 /* Data structure for building up what we know about a mode.
51    They're clustered by mode class.  */
52 struct mode_data
53 {
54   struct mode_data *next;       /* next this class - arbitrary order */
55
56   const char *name;             /* printable mode name -- SI, not SImode */
57   enum mode_class class;        /* this mode class */
58   unsigned int bitsize;         /* size in bits, equiv to TYPE_PRECISION */
59   unsigned int bytesize;        /* storage size in addressable units */
60   unsigned int ncomponents;     /* number of subunits */
61   unsigned int alignment;       /* mode alignment */
62
63   struct mode_data *component;  /* mode of components */
64   struct mode_data *wider;      /* next wider mode */
65
66   const char *file;             /* file and line of definition, */
67   unsigned int line;            /* for error reporting */
68 };
69
70 static struct mode_data *known_modes[MAX_MODE_CLASS];
71 static unsigned int n_modes[MAX_MODE_CLASS];
72 static struct mode_data *void_mode;
73
74 static const struct mode_data blank_mode = {
75   0, "<unknown>", MAX_MODE_CLASS,
76   -1, -1, -1, -1,
77   0, 0,
78   "<unknown>", 0
79 };
80
81 /* Mode class operations.  */
82 static enum mode_class
83 complex_class (enum mode_class class)
84 {
85   switch (class)
86     {
87     case MODE_INT: return MODE_COMPLEX_INT;
88     case MODE_FLOAT: return MODE_COMPLEX_FLOAT;
89     default:
90       error ("no complex class for class %s", mode_class_names[class]);
91       return MODE_RANDOM;
92     }
93 }
94
95 static enum mode_class
96 vector_class (enum mode_class class)
97 {
98   switch (class)
99     {
100     case MODE_INT: return MODE_VECTOR_INT;
101     case MODE_FLOAT: return MODE_VECTOR_FLOAT;
102     default:
103       error ("no vector class for class %s", mode_class_names[class]);
104       return MODE_RANDOM;
105     }
106 }
107
108 static struct mode_data *
109 find_mode (enum mode_class class, const char *name)
110 {
111   struct mode_data *m;
112
113   for (m = known_modes[class]; m; m = m->next)
114     if (!strcmp (name, m->name))
115       return m;
116
117   return 0;
118 }
119
120 static struct mode_data *
121 new_mode (enum mode_class class, const char *name,
122           const char *file, unsigned int line)
123 {
124   struct mode_data *m;
125
126   m = find_mode (class, name);
127   if (m)
128     {
129       error ("%s:%d: duplicate definition of mode \"%s\"",
130              trim_filename (file), line, name);
131       error ("%s:%d: previous definition here", m->file, m->line);
132       return m;
133     }
134
135   m = xmalloc (sizeof (struct mode_data));
136   memcpy (m, &blank_mode, sizeof (struct mode_data));
137   m->class = class;
138   m->name = name;
139   if (file)
140     m->file = trim_filename (file);
141   m->line = line;
142
143   m->next = known_modes[class];
144   known_modes[class] = m;
145   n_modes[class]++;
146   return m;
147 }
148
149 #define for_all_modes(C, M)                     \
150   for (C = 0; C < MAX_MODE_CLASS; C++)          \
151     for (M = known_modes[C]; M; M = M->next)
152
153
154 /* Diagnose failure to meet expectations in a partially filled out
155    mode structure.  */
156 enum requirement { SET, UNSET, OPTIONAL };
157
158 #define validate_field_(mname, fname, req, val, unset, file, line) do { \
159   switch (req)                                                          \
160     {                                                                   \
161     case SET:                                                           \
162       if (val == unset)                                                 \
163         error ("%s:%d: (%s) field %s must be set",                      \
164                file, line, mname, fname);                               \
165       break;                                                            \
166     case UNSET:                                                         \
167       if (val != unset)                                                 \
168         error ("%s:%d: (%s) field %s must not be set",                  \
169                file, line, mname, fname);                               \
170     case OPTIONAL:                                                      \
171       break;                                                            \
172     }                                                                   \
173 } while (0)
174
175 #define validate_field(M, F) \
176   validate_field_(M->name, #F, r_##F, M->F, blank_mode.F, M->file, M->line)
177
178 static void
179 validate_mode (struct mode_data *m,
180                enum requirement r_bitsize,
181                enum requirement r_bytesize,
182                enum requirement r_component,
183                enum requirement r_ncomponents)
184 {
185   validate_field (m, bitsize);
186   validate_field (m, bytesize);
187   validate_field (m, component);
188   validate_field (m, ncomponents);
189 }
190 #undef validate_field
191 #undef validate_field_
192
193 /* Given a partially-filled-out mode structure, figure out what we can
194    and fill the rest of it in; die if it isn't enough.  */
195 static void
196 complete_mode (struct mode_data *m)
197 {
198   unsigned int alignment;
199
200   if (!m->name)
201     {
202       error ("%s:%d: mode with no name", m->file, m->line);
203       return;
204     }
205   if (m->class == MAX_MODE_CLASS)
206     {
207       error ("%s:%d: %smode has no mode class", m->file, m->line, m->name);
208       return;
209     }
210
211   switch (m->class)
212     {
213     case MODE_RANDOM:
214       /* Nothing more need be said.  */
215       if (!strcmp (m->name, "VOID"))
216         void_mode = m;
217
218       validate_mode (m, UNSET, UNSET, UNSET, UNSET);
219
220       m->bitsize = 0;
221       m->bytesize = 0;
222       m->ncomponents = 0;
223       m->component = 0;
224       break;
225
226     case MODE_CC:
227       /* Again, nothing more need be said.  For historical reasons,
228          the size of a CC mode is four units.  */
229       validate_mode (m, UNSET, UNSET, UNSET, UNSET);
230
231       m->bytesize = 4;
232       m->ncomponents = 0;
233       m->component = 0;
234       break;
235
236     case MODE_INT:
237     case MODE_FLOAT:
238       /* A scalar mode must have a byte size, may have a bit size,
239          and must not have components.  */
240       validate_mode (m, OPTIONAL, SET, UNSET, UNSET);
241
242       m->ncomponents = 0;
243       m->component = 0;
244       break;
245
246     case MODE_PARTIAL_INT:
247       /* A partial integer mode uses ->component to say what the
248          corresponding full-size integer mode is, and may also
249          specify a bit size.  */
250       validate_mode (m, OPTIONAL, UNSET, SET, UNSET);
251
252       m->bytesize = m->component->bytesize;
253
254       m->ncomponents = 0;
255       m->component = 0;  /* ??? preserve this */
256       break;
257
258     case MODE_COMPLEX_INT:
259     case MODE_COMPLEX_FLOAT:
260       /* Complex modes should have a component indicated, but no more.  */
261       validate_mode (m, UNSET, UNSET, SET, UNSET);
262       m->ncomponents = 2;
263       if (m->component->bitsize != (unsigned int)-1)
264         m->bitsize = 2 * m->component->bitsize;
265       m->bytesize = 2 * m->component->bytesize;
266       break;
267
268     case MODE_VECTOR_INT:
269     case MODE_VECTOR_FLOAT:
270       /* Vector modes should have a component and a number of components.  */
271       validate_mode (m, UNSET, UNSET, SET, SET);
272       if (m->component->bitsize != (unsigned int)-1)
273         m->bitsize = m->ncomponents * m->component->bitsize;
274       m->bytesize = m->ncomponents * m->component->bytesize;
275       break;
276
277     default:
278       abort ();
279     }
280
281   /* If not already specified, the mode alignment defaults to the largest
282      power of two that divides the size of the object.  Complex types are
283      not more aligned than their contents.  */
284   if (m->class == MODE_COMPLEX_INT || m->class == MODE_COMPLEX_FLOAT)
285     alignment = m->component->bytesize;
286   else
287     alignment = m->bytesize;
288
289   m->alignment = alignment & (~alignment + 1);
290 }
291
292 static void
293 complete_all_modes (void)
294 {
295   struct mode_data *m;
296   enum mode_class c;
297   
298   for_all_modes (c, m)
299     complete_mode (m);
300 }
301
302 /* For each mode in class CLASS, construct a corresponding complex mode.  */
303 #define COMPLEX_MODES(C) make_complex_modes(MODE_##C, __FILE__, __LINE__)
304 static void
305 make_complex_modes (enum mode_class class,
306                     const char *file, unsigned int line)
307 {
308   struct mode_data *m;
309   struct mode_data *c;
310   char buf[8];
311   enum mode_class cclass = complex_class (class);
312
313   if (cclass == MODE_RANDOM)
314     return;
315     
316   for (m = known_modes[class]; m; m = m->next)
317     {
318       /* Skip BImode.  FIXME: BImode probably shouldn't be MODE_INT.  */
319       if (m->bitsize == 1)
320         continue;
321
322       if (strlen (m->name) >= sizeof buf)
323         {
324           error ("%s:%d:mode name \"%s\" is too long",
325                  m->file, m->line, m->name);
326           continue;
327         }
328
329       /* Float complex modes are named SCmode, etc.
330          Int complex modes are named CSImode, etc.
331          This inconsistency should be eliminated.  */
332       if (class == MODE_FLOAT)
333         {
334           char *p;
335           strncpy (buf, m->name, sizeof buf);
336           p = strchr (buf, 'F');
337           if (p == 0)
338             {
339               error ("%s:%d: float mode \"%s\" has no 'F'",
340                      m->file, m->line, m->name);
341               continue;
342             }
343
344           *p = 'C';
345         }
346       else
347         snprintf (buf, sizeof buf, "C%s", m->name);
348
349       c = new_mode (cclass, xstrdup (buf), file, line);
350       c->component = m;
351     }
352 }
353
354 /* For all modes in class CLASS, construct vector modes of width
355    WIDTH, having as many components as necessary.  */
356 #define VECTOR_MODES(C, W) make_vector_modes(MODE_##C, W, __FILE__, __LINE__)
357 static void
358 make_vector_modes (enum mode_class class, unsigned int width,
359                    const char *file, unsigned int line)
360 {
361   struct mode_data *m;
362   struct mode_data *v;
363   char buf[8];
364   unsigned int ncomponents;
365   enum mode_class vclass = vector_class (class);
366
367   if (vclass == MODE_RANDOM)
368     return;
369
370   for (m = known_modes[class]; m; m = m->next)
371     {
372       /* Do not construct vector modes with only one element, or
373          vector modes where the element size doesn't divide the full
374          size evenly.  */
375       ncomponents = width / m->bytesize;
376       if (ncomponents < 2)
377         continue;
378       if (width % m->bytesize)
379         continue;
380
381       /* Skip QFmode and BImode.  FIXME: this special case should
382          not be necessary.  */
383       if (class == MODE_FLOAT && m->bytesize == 1)
384         continue;
385       if (class == MODE_INT && m->bitsize == 1)
386         continue;
387
388       if ((size_t)snprintf (buf, sizeof buf, "V%u%s", ncomponents, m->name)
389           >= sizeof buf)
390         {
391           error ("%s:%d: mode name \"%s\" is too long",
392                  m->file, m->line, m->name);
393           continue;
394         }
395
396       v = new_mode (vclass, xstrdup (buf), file, line);
397       v->component = m;
398       v->ncomponents = ncomponents;
399     }
400 }
401
402 /* Input.  */
403
404 #define _SPECIAL_MODE(C, N) make_special_mode(MODE_##C, #N, __FILE__, __LINE__)
405 #define RANDOM_MODE(N) _SPECIAL_MODE (RANDOM, N)
406 #define CC_MODE(N) _SPECIAL_MODE (CC, N)
407
408 static void
409 make_special_mode (enum mode_class class, const char *name,
410                    const char *file, unsigned int line)
411 {
412   new_mode (class, name, file, line);
413 }
414
415 #define _SCALAR_MODE(C, N, B, Y) \
416   make_scalar_mode (MODE_##C, #N, B, Y, __FILE__, __LINE__)
417
418 #define INT_MODE(N, Y)                 _SCALAR_MODE (INT, N, -1, Y)
419 #define FRACTIONAL_INT_MODE(N, B, Y)   _SCALAR_MODE (INT, N, B, Y)
420 #define FLOAT_MODE(N, Y)               _SCALAR_MODE (FLOAT, N, -1, Y)
421 #define FRACTIONAL_FLOAT_MODE(N, B, Y) _SCALAR_MODE (FLOAT, N, B, Y)
422
423 static void
424 make_scalar_mode (enum mode_class class, const char *name,
425                   unsigned int bitsize, unsigned int bytesize,
426                   const char *file, unsigned int line)
427 {
428   struct mode_data *m = new_mode (class, name, file, line);
429   m->bytesize = bytesize;
430   m->bitsize = bitsize;
431 }
432
433 /* Partial integer modes are specified by relation to a full integer mode.
434    For now, we do not attempt to narrow down their bit sizes.  */
435 #define PARTIAL_INT_MODE(M) \
436   make_partial_integer_mode (#M, "P" #M, -1, __FILE__, __LINE__)
437 static void ATTRIBUTE_UNUSED
438 make_partial_integer_mode (const char *base, const char *name,
439                            unsigned int bitsize,
440                            const char *file, unsigned int line)
441 {
442   struct mode_data *m;
443   struct mode_data *component = find_mode (MODE_INT, base);
444   if (!component)
445     {
446       error ("%s:%d: no mode \"%s\" in class INT", file, line, name);
447       return;
448     }
449   
450   m = new_mode (MODE_PARTIAL_INT, name, file, line);
451   m->bitsize = bitsize;
452   m->component = component;
453 }
454
455 /* A single vector mode can be specified by naming its component
456    mode and the number of components.  */
457 #define VECTOR_MODE(C, M, N) \
458   make_vector_mode (MODE_##C, #M, N, __FILE__, __LINE__);
459 static void ATTRIBUTE_UNUSED
460 make_vector_mode (enum mode_class bclass,
461                   const char *base,
462                   unsigned int ncomponents,
463                   const char *file, unsigned int line)
464 {
465   struct mode_data *v;
466   enum mode_class vclass = vector_class (bclass);
467   struct mode_data *component = find_mode (bclass, base);
468   char namebuf[8];
469
470   if (vclass == MODE_RANDOM)
471     return;
472   if (component == 0)
473     {
474       error ("%s:%d: no mode \"%s\" in class %s",
475              file, line, base, mode_class_names[bclass] + 5);
476       return;
477     }
478
479   if ((size_t)snprintf (namebuf, sizeof namebuf, "V%u%s",
480                         ncomponents, base) >= sizeof namebuf)
481     {
482       error ("%s:%d: mode name \"%s\" is too long",
483              base, file, line);
484       return;
485     }
486
487   v = new_mode (vclass, xstrdup (namebuf), file, line);
488   v->ncomponents = ncomponents;
489   v->component = component;
490 }
491   
492
493 static void
494 create_modes (void)
495 {
496 #include "machmode.def"
497 }
498
499 /* Processing.  */
500
501 /* Sort a list of modes into the order needed for the WIDER field:
502    major sort by bitsize, minor sort by component bitsize.
503
504    For instance:
505      QI < HI < SI < DI < TI
506      V4QI < V2HI < V8QI < V4HI < V2SI.
507
508    If the bitsize is not set, sort by the bytesize.  A mode with
509    bitsize set gets sorted before a mode without bitsize set, if
510    they have the same bytesize; this is the right thing because
511    the bitsize must always be smaller than the bytesize * BITS_PER_UNIT.
512    We don't have to do anything special to get this done -- an unset
513    bitsize shows up as (unsigned int)-1, i.e. UINT_MAX.  */
514 static int
515 cmp_modes (const void *a, const void *b)
516 {
517   struct mode_data *m = *(struct mode_data **)a;
518   struct mode_data *n = *(struct mode_data **)b;
519
520   if (m->bytesize > n->bytesize)
521     return 1;
522   else if (m->bytesize < n->bytesize)
523     return -1;
524
525   if (m->bitsize > n->bitsize)
526     return 1;
527   else if (m->bitsize < n->bitsize)
528     return -1;
529
530   if (!m->component && !n->component)
531     return 0;
532
533   if (m->component->bytesize > n->component->bytesize)
534     return 1;
535   else if (m->component->bytesize < n->component->bytesize)
536     return -1;
537
538   if (m->component->bitsize > n->component->bitsize)
539     return 1;
540   else if (m->component->bitsize < n->component->bitsize)
541     return -1;
542
543   return 0;
544 }
545
546 static void
547 calc_wider_mode (void)
548 {
549   enum mode_class c;
550   struct mode_data *m;
551   struct mode_data **sortbuf;
552   unsigned int max_n_modes = 0;
553   unsigned int i, j;
554
555   for (c = 0; c < MAX_MODE_CLASS; c++)
556     max_n_modes = MAX (max_n_modes, n_modes[c]);
557
558   sortbuf = alloca (max_n_modes * sizeof (struct mode_data *));
559
560   for (c = 0; c < MAX_MODE_CLASS; c++)
561     {
562       /* "wider" is not meaningful for MODE_RANDOM and MODE_CC.
563          However, we want these in textual order, and we have
564          precisely the reverse.  */
565       if (c == MODE_RANDOM || c == MODE_CC)
566         {
567           struct mode_data *prev, *next;
568
569           for (prev = 0, m = known_modes[c]; m; m = next)
570             {
571               m->wider = void_mode;
572
573               /* this is nreverse */
574               next = m->next;
575               m->next = prev;
576               prev = m;
577             }
578           known_modes[c] = prev;
579         }
580       else
581         {
582           if (!known_modes[c])
583             continue;
584
585           for (i = 0, m = known_modes[c]; m; i++, m = m->next)
586             sortbuf[i] = m;
587
588           qsort (sortbuf, i, sizeof (struct mode_data *), cmp_modes);
589
590           sortbuf[i] = 0;
591           for (j = 0; j < i; j++)
592             sortbuf[j]->next = sortbuf[j]->wider = sortbuf[j + 1];
593
594
595           known_modes[c] = sortbuf[0];
596         }
597     }
598 }
599
600 /* Output routines.  */
601
602 #define tagged_printf(FMT, ARG, TAG) do {               \
603   int count_;                                           \
604   printf ("  " FMT ",%n", ARG, &count_);                \
605   printf ("%*s/* %s */\n", 27 - count_, "", TAG);       \
606 } while (0)
607
608 #define print_decl(TYPE, NAME, ASIZE) \
609   printf ("\nconst %s %s[%s] =\n{\n", TYPE, NAME, ASIZE);
610
611 #define print_closer() puts ("};")
612
613 static void
614 emit_insn_modes_h (void)
615 {
616   enum mode_class c;
617   struct mode_data *m, *first, *last;
618
619   printf ("/* Generated automatically from machmode.def%s%s\n",
620            HAVE_EXTRA_MODES ? " and " : "",
621            EXTRA_MODES_FILE);
622
623   puts ("\
624    by genmodes.  */\n\
625 \n\
626 #ifndef GCC_INSN_MODES_H\n\
627 #define GCC_INSN_MODES_H\n\
628 \n\
629 enum machine_mode\n{");
630
631   for (c = 0; c < MAX_MODE_CLASS; c++)
632     for (m = known_modes[c]; m; m = m->next)
633       {
634         int count_;
635         printf ("  %smode,%n", m->name, &count_);
636         printf ("%*s/* %s:%d */\n", 27 - count_, "",
637                  trim_filename (m->file), m->line);
638       }
639
640   puts ("  MAX_MACHINE_MODE,\n");
641
642   for (c = 0; c < MAX_MODE_CLASS; c++)
643     {
644       first = known_modes[c];
645       last = 0;
646       for (m = first; m; last = m, m = m->next)
647         ;
648
649       /* Don't use BImode for MIN_MODE_INT, since otherwise the middle
650          end will try to use it for bitfields in structures and the
651          like, which we do not want.  Only the target md file should
652          generate BImode widgets.  */
653       if (first && first->bitsize == 1)
654         first = first->next;
655
656       if (first && last)
657         printf ("  MIN_%s = %smode,\n  MAX_%s = %smode,\n\n",
658                  mode_class_names[c], first->name,
659                  mode_class_names[c], last->name);
660       else
661         printf ("  MIN_%s = %smode,\n  MAX_%s = %smode,\n\n",
662                  mode_class_names[c], void_mode->name,
663                  mode_class_names[c], void_mode->name);
664     }
665
666   puts ("\
667   NUM_MACHINE_MODES = MAX_MACHINE_MODE\n\
668 };\n\
669 \n\
670 #endif /* insn-modes.h */");
671 }
672
673 static void
674 emit_insn_modes_c_header (void)
675 {
676   printf ("/* Generated automatically from machmode.def%s%s\n",
677            HAVE_EXTRA_MODES ? " and " : "",
678            EXTRA_MODES_FILE);
679
680   puts ("\
681    by genmodes.  */\n\
682 \n\
683 #define GENERATOR_FILE /* This inhibits insn-flags.h and\n\
684                           insn-constants.h, which don't exist yet.  */\n\
685 #include \"config.h\"\n\
686 #include \"system.h\"\n\
687 #include \"coretypes.h\"\n\
688 #include \"tm.h\"\n\
689 #include \"machmode.h\"");
690 }
691
692 static void
693 emit_mode_name (void)
694 {
695   enum mode_class c;
696   struct mode_data *m;
697
698   print_decl ("char *const", "mode_name", "NUM_MACHINE_MODES");
699
700   for_all_modes (c, m)
701     printf ("  \"%s\",\n", m->name);
702
703   print_closer ();
704 }
705
706 static void
707 emit_mode_class (void)
708 {
709   enum mode_class c;
710   struct mode_data *m;
711
712   print_decl ("unsigned char", "mode_class", "NUM_MACHINE_MODES");
713
714   for_all_modes (c, m)
715     tagged_printf ("%s", mode_class_names[m->class], m->name);
716
717   print_closer ();
718 }
719
720 static void
721 emit_mode_bitsize (void)
722 {
723   enum mode_class c;
724   struct mode_data *m;
725
726   print_decl ("unsigned short", "mode_bitsize", "NUM_MACHINE_MODES");
727
728   for_all_modes (c, m)
729     if (m->bitsize != (unsigned int)-1)
730       tagged_printf ("%u", m->bitsize, m->name);
731     else
732       tagged_printf ("%u*BITS_PER_UNIT", m->bytesize, m->name);
733
734   print_closer ();
735 }
736
737 static void
738 emit_mode_size (void)
739 {
740   enum mode_class c;
741   struct mode_data *m;
742
743   print_decl ("unsigned char", "mode_size", "NUM_MACHINE_MODES");
744
745   for_all_modes (c, m)
746     tagged_printf ("%u", m->bytesize, m->name);
747
748   print_closer ();
749 }
750
751 static void
752 emit_mode_unit_size (void)
753 {
754   enum mode_class c;
755   struct mode_data *m;
756
757   print_decl ("unsigned char", "mode_unit_size", "NUM_MACHINE_MODES");
758
759   for_all_modes (c, m)
760     tagged_printf ("%u",
761                    m->component
762                    ? m->component->bytesize : m->bytesize,
763                    m->name);
764
765   print_closer ();
766 }
767
768 static void
769 emit_mode_wider (void)
770 {
771   enum mode_class c;
772   struct mode_data *m;
773
774   print_decl ("unsigned char", "mode_wider", "NUM_MACHINE_MODES");
775
776   for_all_modes (c, m)
777     tagged_printf ("%smode",
778                    m->wider ? m->wider->name : void_mode->name,
779                    m->name);
780
781   print_closer ();
782 }
783
784 static void
785 emit_mode_mask (void)
786 {
787   enum mode_class c;
788   struct mode_data *m;
789
790   print_decl ("unsigned HOST_WIDE_INT", "mode_mask_array",
791               "NUM_MACHINE_MODES");
792   puts ("\
793 #define MASK(m)                               \\\n\
794   ((m) >= HOST_BITS_PER_WIDE_INT)             \\\n\
795    ? ~(unsigned HOST_WIDE_INT) 0              \\\n\
796    : ((unsigned HOST_WIDE_INT) 1 << (m)) - 1\n");
797
798   for_all_modes (c, m)
799     if (m->bitsize != (unsigned int)-1)
800       tagged_printf ("MASK (%u)", m->bitsize, m->name);
801     else
802       tagged_printf ("MASK (%u*BITS_PER_UNIT)", m->bytesize, m->name);
803
804   puts ("#undef MASK");
805   print_closer ();
806 }
807
808 static void
809 emit_mode_inner (void)
810 {
811   enum mode_class c;
812   struct mode_data *m;
813
814   print_decl ("unsigned char", "mode_inner", "NUM_MACHINE_MODES");
815
816   for_all_modes (c, m)
817     tagged_printf ("%smode",
818                    m->component ? m->component->name : void_mode->name,
819                    m->name);
820
821   print_closer ();
822 }
823
824 static void
825 emit_mode_base_align (void)
826 {
827   enum mode_class c;
828   struct mode_data *m;
829
830   print_decl ("unsigned char", "mode_base_align", "NUM_MACHINE_MODES");
831
832   for_all_modes (c, m)
833     tagged_printf ("%u", m->alignment, m->name);
834
835   print_closer ();
836 }
837
838 static void
839 emit_class_narrowest_mode (void)
840 {
841   enum mode_class c;
842
843   print_decl ("unsigned char", "class_narrowest_mode", "MAX_MODE_CLASS");
844
845   for (c = 0; c < MAX_MODE_CLASS; c++)
846     /* Bleah, all this to get the comment right for MIN_MODE_INT.  */
847     tagged_printf ("MIN_%s", mode_class_names[c],
848                    known_modes[c]
849                    ? (known_modes[c]->bitsize != 1
850                       ? known_modes[c]->name
851                       : (known_modes[c]->next
852                          ? known_modes[c]->next->name
853                          : void_mode->name))
854                    : void_mode->name);
855   
856   print_closer ();
857 }
858
859 static void
860 emit_insn_modes_c (void)
861 {
862   emit_insn_modes_c_header ();
863   emit_mode_name ();
864   emit_mode_class ();
865   emit_mode_bitsize ();
866   emit_mode_size ();
867   emit_mode_unit_size ();
868   emit_mode_wider ();
869   emit_mode_mask ();
870   emit_mode_inner ();
871   emit_mode_base_align ();
872   emit_class_narrowest_mode ();
873 }
874
875 /* Master control.  */
876 int
877 main(int argc, char **argv)
878 {
879   bool gen_header;
880   progname = argv[0];
881
882   if (argc == 1)
883     gen_header = false;
884   else if (argc == 2 && !strcmp (argv[1], "-h"))
885     gen_header = true;
886   else
887     {
888       error ("usage: %s [-h] > file", progname);
889       return FATAL_EXIT_CODE;
890     }
891
892   create_modes ();
893   complete_all_modes ();
894
895   if (have_error)
896     return FATAL_EXIT_CODE;
897   
898   calc_wider_mode ();
899
900   if (gen_header)
901     emit_insn_modes_h ();
902   else
903     emit_insn_modes_c ();
904
905   if (fflush (stdout) || fclose (stdout))
906     return FATAL_EXIT_CODE;
907   return SUCCESS_EXIT_CODE;
908 }