xref: /openbsd-src/gnu/gcc/gcc/genmodes.c (revision 28fe39c8b64e2a28225dd596f0fbf5248ae68fca)
1 /* Generate the machine mode enumeration and associated tables.
2    Copyright (C) 2003, 2004
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, 51 Franklin Street, Fifth Floor, Boston, MA
20 02110-1301, USA.  */
21 
22 #include "bconfig.h"
23 #include "system.h"
24 #include "errors.h"
25 #include "hashtab.h"
26 
27 /* enum mode_class is normally defined by machmode.h but we can't
28    include that header here.  */
29 #include "mode-classes.def"
30 
31 #define DEF_MODE_CLASS(M) M
32 enum mode_class { MODE_CLASSES, MAX_MODE_CLASS };
33 #undef DEF_MODE_CLASS
34 
35 /* Text names of mode classes, for output.  */
36 #define DEF_MODE_CLASS(M) #M
37 static const char *const mode_class_names[MAX_MODE_CLASS] =
38 {
39   MODE_CLASSES
40 };
41 #undef DEF_MODE_CLASS
42 #undef MODE_CLASSES
43 
44 #ifdef EXTRA_MODES_FILE
45 # define HAVE_EXTRA_MODES 1
46 #else
47 # define HAVE_EXTRA_MODES 0
48 # define EXTRA_MODES_FILE ""
49 #endif
50 
51 /* Data structure for building up what we know about a mode.
52    They're clustered by mode class.  */
53 struct mode_data
54 {
55   struct mode_data *next;	/* next this class - arbitrary order */
56 
57   const char *name;		/* printable mode name -- SI, not SImode */
58   enum mode_class cl;		/* this mode class */
59   unsigned int precision;	/* size in bits, equiv to TYPE_PRECISION */
60   unsigned int bytesize;	/* storage size in addressable units */
61   unsigned int ncomponents;	/* number of subunits */
62   unsigned int alignment;	/* mode alignment */
63   const char *format;		/* floating point format - float modes only */
64 
65   struct mode_data *component;	/* mode of components */
66   struct mode_data *wider;	/* next wider mode */
67   struct mode_data *wider_2x;	/* 2x wider mode */
68 
69   struct mode_data *contained;  /* Pointer to list of modes that have
70 				   this mode as a component.  */
71   struct mode_data *next_cont;  /* Next mode in that list.  */
72 
73   const char *file;		/* file and line of definition, */
74   unsigned int line;		/* for error reporting */
75   unsigned int counter;		/* Rank ordering of modes */
76 };
77 
78 static struct mode_data *modes[MAX_MODE_CLASS];
79 static unsigned int n_modes[MAX_MODE_CLASS];
80 static struct mode_data *void_mode;
81 
82 static const struct mode_data blank_mode = {
83   0, "<unknown>", MAX_MODE_CLASS,
84   -1U, -1U, -1U, -1U,
85   0, 0, 0, 0, 0, 0,
86   "<unknown>", 0, 0
87 };
88 
89 static htab_t modes_by_name;
90 
91 /* Data structure for recording target-specified runtime adjustments
92    to a particular mode.  We support varying the byte size, the
93    alignment, and the floating point format.  */
94 struct mode_adjust
95 {
96   struct mode_adjust *next;
97   struct mode_data *mode;
98   const char *adjustment;
99 
100   const char *file;
101   unsigned int line;
102 };
103 
104 static struct mode_adjust *adj_bytesize;
105 static struct mode_adjust *adj_alignment;
106 static struct mode_adjust *adj_format;
107 
108 /* Mode class operations.  */
109 static enum mode_class
complex_class(enum mode_class c)110 complex_class (enum mode_class c)
111 {
112   switch (c)
113     {
114     case MODE_INT: return MODE_COMPLEX_INT;
115     case MODE_FLOAT: return MODE_COMPLEX_FLOAT;
116     default:
117       error ("no complex class for class %s", mode_class_names[c]);
118       return MODE_RANDOM;
119     }
120 }
121 
122 static enum mode_class
vector_class(enum mode_class cl)123 vector_class (enum mode_class cl)
124 {
125   switch (cl)
126     {
127     case MODE_INT: return MODE_VECTOR_INT;
128     case MODE_FLOAT: return MODE_VECTOR_FLOAT;
129     default:
130       error ("no vector class for class %s", mode_class_names[cl]);
131       return MODE_RANDOM;
132     }
133 }
134 
135 /* Utility routines.  */
136 static inline struct mode_data *
find_mode(const char * name)137 find_mode (const char *name)
138 {
139   struct mode_data key;
140 
141   key.name = name;
142   return (struct mode_data *) htab_find (modes_by_name, &key);
143 }
144 
145 static struct mode_data *
new_mode(enum mode_class cl,const char * name,const char * file,unsigned int line)146 new_mode (enum mode_class cl, const char *name,
147 	  const char *file, unsigned int line)
148 {
149   struct mode_data *m;
150   static unsigned int count = 0;
151 
152   m = find_mode (name);
153   if (m)
154     {
155       error ("%s:%d: duplicate definition of mode \"%s\"",
156 	     trim_filename (file), line, name);
157       error ("%s:%d: previous definition here", m->file, m->line);
158       return m;
159     }
160 
161   m = XNEW (struct mode_data);
162   memcpy (m, &blank_mode, sizeof (struct mode_data));
163   m->cl = cl;
164   m->name = name;
165   if (file)
166     m->file = trim_filename (file);
167   m->line = line;
168   m->counter = count++;
169 
170   m->next = modes[cl];
171   modes[cl] = m;
172   n_modes[cl]++;
173 
174   *htab_find_slot (modes_by_name, m, INSERT) = m;
175 
176   return m;
177 }
178 
179 static hashval_t
hash_mode(const void * p)180 hash_mode (const void *p)
181 {
182   const struct mode_data *m = (const struct mode_data *)p;
183   return htab_hash_string (m->name);
184 }
185 
186 static int
eq_mode(const void * p,const void * q)187 eq_mode (const void *p, const void *q)
188 {
189   const struct mode_data *a = (const struct mode_data *)p;
190   const struct mode_data *b = (const struct mode_data *)q;
191 
192   return !strcmp (a->name, b->name);
193 }
194 
195 #define for_all_modes(C, M)			\
196   for (C = 0; C < MAX_MODE_CLASS; C++)		\
197     for (M = modes[C]; M; M = M->next)
198 
199 static void ATTRIBUTE_UNUSED
new_adjust(const char * name,struct mode_adjust ** category,const char * catname,const char * adjustment,enum mode_class required_class,const char * file,unsigned int line)200 new_adjust (const char *name,
201 	    struct mode_adjust **category, const char *catname,
202 	    const char *adjustment,
203 	    enum mode_class required_class,
204 	    const char *file, unsigned int line)
205 {
206   struct mode_data *mode = find_mode (name);
207   struct mode_adjust *a;
208 
209   file = trim_filename (file);
210 
211   if (!mode)
212     {
213       error ("%s:%d: no mode \"%s\"", file, line, name);
214       return;
215     }
216 
217   if (required_class != MODE_RANDOM && mode->cl != required_class)
218     {
219       error ("%s:%d: mode \"%s\" is not class %s",
220 	     file, line, name, mode_class_names[required_class] + 5);
221       return;
222     }
223 
224   for (a = *category; a; a = a->next)
225     if (a->mode == mode)
226       {
227 	error ("%s:%d: mode \"%s\" already has a %s adjustment",
228 	       file, line, name, catname);
229 	error ("%s:%d: previous adjustment here", a->file, a->line);
230 	return;
231       }
232 
233   a = XNEW (struct mode_adjust);
234   a->mode = mode;
235   a->adjustment = adjustment;
236   a->file = file;
237   a->line = line;
238 
239   a->next = *category;
240   *category = a;
241 }
242 
243 /* Diagnose failure to meet expectations in a partially filled out
244    mode structure.  */
245 enum requirement { SET, UNSET, OPTIONAL };
246 
247 #define validate_field_(mname, fname, req, val, unset, file, line) do {	\
248   switch (req)								\
249     {									\
250     case SET:								\
251       if (val == unset)							\
252 	error ("%s:%d: (%s) field %s must be set",			\
253 	       file, line, mname, fname);				\
254       break;								\
255     case UNSET:								\
256       if (val != unset)							\
257 	error ("%s:%d: (%s) field %s must not be set",			\
258 	       file, line, mname, fname);				\
259     case OPTIONAL:							\
260       break;								\
261     }									\
262 } while (0)
263 
264 #define validate_field(M, F) \
265   validate_field_(M->name, #F, r_##F, M->F, blank_mode.F, M->file, M->line)
266 
267 static void
validate_mode(struct mode_data * m,enum requirement r_precision,enum requirement r_bytesize,enum requirement r_component,enum requirement r_ncomponents,enum requirement r_format)268 validate_mode (struct mode_data *m,
269 	       enum requirement r_precision,
270 	       enum requirement r_bytesize,
271 	       enum requirement r_component,
272 	       enum requirement r_ncomponents,
273 	       enum requirement r_format)
274 {
275   validate_field (m, precision);
276   validate_field (m, bytesize);
277   validate_field (m, component);
278   validate_field (m, ncomponents);
279   validate_field (m, format);
280 }
281 #undef validate_field
282 #undef validate_field_
283 
284 /* Given a partially-filled-out mode structure, figure out what we can
285    and fill the rest of it in; die if it isn't enough.  */
286 static void
complete_mode(struct mode_data * m)287 complete_mode (struct mode_data *m)
288 {
289   unsigned int alignment;
290 
291   if (!m->name)
292     {
293       error ("%s:%d: mode with no name", m->file, m->line);
294       return;
295     }
296   if (m->cl == MAX_MODE_CLASS)
297     {
298       error ("%s:%d: %smode has no mode class", m->file, m->line, m->name);
299       return;
300     }
301 
302   switch (m->cl)
303     {
304     case MODE_RANDOM:
305       /* Nothing more need be said.  */
306       if (!strcmp (m->name, "VOID"))
307 	void_mode = m;
308 
309       validate_mode (m, UNSET, UNSET, UNSET, UNSET, UNSET);
310 
311       m->precision = 0;
312       m->bytesize = 0;
313       m->ncomponents = 0;
314       m->component = 0;
315       break;
316 
317     case MODE_CC:
318       /* Again, nothing more need be said.  For historical reasons,
319 	 the size of a CC mode is four units.  */
320       validate_mode (m, UNSET, UNSET, UNSET, UNSET, UNSET);
321 
322       m->bytesize = 4;
323       m->ncomponents = 1;
324       m->component = 0;
325       break;
326 
327     case MODE_INT:
328     case MODE_FLOAT:
329     case MODE_DECIMAL_FLOAT:
330       /* A scalar mode must have a byte size, may have a bit size,
331 	 and must not have components.   A float mode must have a
332          format.  */
333       validate_mode (m, OPTIONAL, SET, UNSET, UNSET,
334 		     m->cl != MODE_INT ? SET : UNSET);
335 
336       m->ncomponents = 1;
337       m->component = 0;
338       break;
339 
340     case MODE_PARTIAL_INT:
341       /* A partial integer mode uses ->component to say what the
342 	 corresponding full-size integer mode is, and may also
343 	 specify a bit size.  */
344       validate_mode (m, OPTIONAL, UNSET, SET, UNSET, UNSET);
345 
346       m->bytesize = m->component->bytesize;
347 
348       m->ncomponents = 1;
349       m->component = 0;  /* ??? preserve this */
350       break;
351 
352     case MODE_COMPLEX_INT:
353     case MODE_COMPLEX_FLOAT:
354       /* Complex modes should have a component indicated, but no more.  */
355       validate_mode (m, UNSET, UNSET, SET, UNSET, UNSET);
356       m->ncomponents = 2;
357       if (m->component->precision != (unsigned int)-1)
358 	m->precision = 2 * m->component->precision;
359       m->bytesize = 2 * m->component->bytesize;
360       break;
361 
362     case MODE_VECTOR_INT:
363     case MODE_VECTOR_FLOAT:
364       /* Vector modes should have a component and a number of components.  */
365       validate_mode (m, UNSET, UNSET, SET, SET, UNSET);
366       if (m->component->precision != (unsigned int)-1)
367 	m->precision = m->ncomponents * m->component->precision;
368       m->bytesize = m->ncomponents * m->component->bytesize;
369       break;
370 
371     default:
372       gcc_unreachable ();
373     }
374 
375   /* If not already specified, the mode alignment defaults to the largest
376      power of two that divides the size of the object.  Complex types are
377      not more aligned than their contents.  */
378   if (m->cl == MODE_COMPLEX_INT || m->cl == MODE_COMPLEX_FLOAT)
379     alignment = m->component->bytesize;
380   else
381     alignment = m->bytesize;
382 
383   m->alignment = alignment & (~alignment + 1);
384 
385   /* If this mode has components, make the component mode point back
386      to this mode, for the sake of adjustments.  */
387   if (m->component)
388     {
389       m->next_cont = m->component->contained;
390       m->component->contained = m;
391     }
392 }
393 
394 static void
complete_all_modes(void)395 complete_all_modes (void)
396 {
397   struct mode_data *m;
398   int cl;
399 
400   for_all_modes (cl, m)
401     complete_mode (m);
402 }
403 
404 /* For each mode in class CLASS, construct a corresponding complex mode.  */
405 #define COMPLEX_MODES(C) make_complex_modes(MODE_##C, __FILE__, __LINE__)
406 static void
make_complex_modes(enum mode_class cl,const char * file,unsigned int line)407 make_complex_modes (enum mode_class cl,
408 		    const char *file, unsigned int line)
409 {
410   struct mode_data *m;
411   struct mode_data *c;
412   char buf[8];
413   enum mode_class cclass = complex_class (cl);
414 
415   if (cclass == MODE_RANDOM)
416     return;
417 
418   for (m = modes[cl]; m; m = m->next)
419     {
420       /* Skip BImode.  FIXME: BImode probably shouldn't be MODE_INT.  */
421       if (m->precision == 1)
422 	continue;
423 
424       if (strlen (m->name) >= sizeof buf)
425 	{
426 	  error ("%s:%d:mode name \"%s\" is too long",
427 		 m->file, m->line, m->name);
428 	  continue;
429 	}
430 
431       /* Float complex modes are named SCmode, etc.
432 	 Int complex modes are named CSImode, etc.
433          This inconsistency should be eliminated.  */
434       if (cl == MODE_FLOAT)
435 	{
436 	  char *p, *q = 0;
437 	  strncpy (buf, m->name, sizeof buf);
438 	  p = strchr (buf, 'F');
439 	  if (p == 0)
440 	    q = strchr (buf, 'D');
441 	  if (p == 0 && q == 0)
442 	    {
443 	      error ("%s:%d: float mode \"%s\" has no 'F' or 'D'",
444 		     m->file, m->line, m->name);
445 	      continue;
446 	    }
447 
448 	  if (p != 0)
449 	    *p = 'C';
450 	  else
451 	    snprintf (buf, sizeof buf, "C%s", m->name);
452 	}
453       else
454 	snprintf (buf, sizeof buf, "C%s", m->name);
455 
456       c = new_mode (cclass, xstrdup (buf), file, line);
457       c->component = m;
458     }
459 }
460 
461 /* For all modes in class CL, construct vector modes of width
462    WIDTH, having as many components as necessary.  */
463 #define VECTOR_MODES(C, W) make_vector_modes(MODE_##C, W, __FILE__, __LINE__)
464 static void ATTRIBUTE_UNUSED
make_vector_modes(enum mode_class cl,unsigned int width,const char * file,unsigned int line)465 make_vector_modes (enum mode_class cl, unsigned int width,
466 		   const char *file, unsigned int line)
467 {
468   struct mode_data *m;
469   struct mode_data *v;
470   char buf[8];
471   unsigned int ncomponents;
472   enum mode_class vclass = vector_class (cl);
473 
474   if (vclass == MODE_RANDOM)
475     return;
476 
477   for (m = modes[cl]; m; m = m->next)
478     {
479       /* Do not construct vector modes with only one element, or
480 	 vector modes where the element size doesn't divide the full
481 	 size evenly.  */
482       ncomponents = width / m->bytesize;
483       if (ncomponents < 2)
484 	continue;
485       if (width % m->bytesize)
486 	continue;
487 
488       /* Skip QFmode and BImode.  FIXME: this special case should
489 	 not be necessary.  */
490       if (cl == MODE_FLOAT && m->bytesize == 1)
491 	continue;
492       if (cl == MODE_INT && m->precision == 1)
493 	continue;
494 
495       if ((size_t)snprintf (buf, sizeof buf, "V%u%s", ncomponents, m->name)
496 	  >= sizeof buf)
497 	{
498 	  error ("%s:%d: mode name \"%s\" is too long",
499 		 m->file, m->line, m->name);
500 	  continue;
501 	}
502 
503       v = new_mode (vclass, xstrdup (buf), file, line);
504       v->component = m;
505       v->ncomponents = ncomponents;
506     }
507 }
508 
509 /* Input.  */
510 
511 #define _SPECIAL_MODE(C, N) make_special_mode(MODE_##C, #N, __FILE__, __LINE__)
512 #define RANDOM_MODE(N) _SPECIAL_MODE (RANDOM, N)
513 #define CC_MODE(N) _SPECIAL_MODE (CC, N)
514 
515 static void
make_special_mode(enum mode_class cl,const char * name,const char * file,unsigned int line)516 make_special_mode (enum mode_class cl, const char *name,
517 		   const char *file, unsigned int line)
518 {
519   new_mode (cl, name, file, line);
520 }
521 
522 #define INT_MODE(N, Y) FRACTIONAL_INT_MODE (N, -1U, Y)
523 #define FRACTIONAL_INT_MODE(N, B, Y) \
524   make_int_mode (#N, B, Y, __FILE__, __LINE__)
525 
526 static void
make_int_mode(const char * name,unsigned int precision,unsigned int bytesize,const char * file,unsigned int line)527 make_int_mode (const char *name,
528 	       unsigned int precision, unsigned int bytesize,
529 	       const char *file, unsigned int line)
530 {
531   struct mode_data *m = new_mode (MODE_INT, name, file, line);
532   m->bytesize = bytesize;
533   m->precision = precision;
534 }
535 
536 #define FLOAT_MODE(N, Y, F)             FRACTIONAL_FLOAT_MODE (N, -1U, Y, F)
537 #define FRACTIONAL_FLOAT_MODE(N, B, Y, F) \
538   make_float_mode (#N, B, Y, #F, __FILE__, __LINE__)
539 
540 static void
make_float_mode(const char * name,unsigned int precision,unsigned int bytesize,const char * format,const char * file,unsigned int line)541 make_float_mode (const char *name,
542 		 unsigned int precision, unsigned int bytesize,
543 		 const char *format,
544 		 const char *file, unsigned int line)
545 {
546   struct mode_data *m = new_mode (MODE_FLOAT, name, file, line);
547   m->bytesize = bytesize;
548   m->precision = precision;
549   m->format = format;
550 }
551 
552 #define DECIMAL_FLOAT_MODE(N, Y, F)	\
553 	FRACTIONAL_DECIMAL_FLOAT_MODE (N, -1U, Y, F)
554 #define FRACTIONAL_DECIMAL_FLOAT_MODE(N, B, Y, F)	\
555   make_decimal_float_mode (#N, B, Y, #F, __FILE__, __LINE__)
556 
557 static void
make_decimal_float_mode(const char * name,unsigned int precision,unsigned int bytesize,const char * format,const char * file,unsigned int line)558 make_decimal_float_mode (const char *name,
559 			 unsigned int precision, unsigned int bytesize,
560 			 const char *format,
561 			 const char *file, unsigned int line)
562 {
563   struct mode_data *m = new_mode (MODE_DECIMAL_FLOAT, name, file, line);
564   m->bytesize = bytesize;
565   m->precision = precision;
566   m->format = format;
567 }
568 
569 #define RESET_FLOAT_FORMAT(N, F) \
570   reset_float_format (#N, #F, __FILE__, __LINE__)
571 static void ATTRIBUTE_UNUSED
reset_float_format(const char * name,const char * format,const char * file,unsigned int line)572 reset_float_format (const char *name, const char *format,
573 		    const char *file, unsigned int line)
574 {
575   struct mode_data *m = find_mode (name);
576   if (!m)
577     {
578       error ("%s:%d: no mode \"%s\"", file, line, name);
579       return;
580     }
581   if (m->cl != MODE_FLOAT && m->cl != MODE_DECIMAL_FLOAT)
582     {
583       error ("%s:%d: mode \"%s\" is not a FLOAT class", file, line, name);
584       return;
585     }
586   m->format = format;
587 }
588 
589 /* Partial integer modes are specified by relation to a full integer mode.
590    For now, we do not attempt to narrow down their bit sizes.  */
591 #define PARTIAL_INT_MODE(M) \
592   make_partial_integer_mode (#M, "P" #M, -1U, __FILE__, __LINE__)
593 static void ATTRIBUTE_UNUSED
make_partial_integer_mode(const char * base,const char * name,unsigned int precision,const char * file,unsigned int line)594 make_partial_integer_mode (const char *base, const char *name,
595 			   unsigned int precision,
596 			   const char *file, unsigned int line)
597 {
598   struct mode_data *m;
599   struct mode_data *component = find_mode (base);
600   if (!component)
601     {
602       error ("%s:%d: no mode \"%s\"", file, line, name);
603       return;
604     }
605   if (component->cl != MODE_INT)
606     {
607       error ("%s:%d: mode \"%s\" is not class INT", file, line, name);
608       return;
609     }
610 
611   m = new_mode (MODE_PARTIAL_INT, name, file, line);
612   m->precision = precision;
613   m->component = component;
614 }
615 
616 /* A single vector mode can be specified by naming its component
617    mode and the number of components.  */
618 #define VECTOR_MODE(C, M, N) \
619   make_vector_mode (MODE_##C, #M, N, __FILE__, __LINE__);
620 static void ATTRIBUTE_UNUSED
make_vector_mode(enum mode_class bclass,const char * base,unsigned int ncomponents,const char * file,unsigned int line)621 make_vector_mode (enum mode_class bclass,
622 		  const char *base,
623 		  unsigned int ncomponents,
624 		  const char *file, unsigned int line)
625 {
626   struct mode_data *v;
627   enum mode_class vclass = vector_class (bclass);
628   struct mode_data *component = find_mode (base);
629   char namebuf[8];
630 
631   if (vclass == MODE_RANDOM)
632     return;
633   if (component == 0)
634     {
635       error ("%s:%d: no mode \"%s\"", file, line, base);
636       return;
637     }
638   if (component->cl != bclass
639       && (component->cl != MODE_PARTIAL_INT
640 	  || bclass != MODE_INT))
641     {
642       error ("%s:%d: mode \"%s\" is not class %s",
643 	     file, line, base, mode_class_names[bclass] + 5);
644       return;
645     }
646 
647   if ((size_t)snprintf (namebuf, sizeof namebuf, "V%u%s",
648 			ncomponents, base) >= sizeof namebuf)
649     {
650       error ("%s:%d: mode name \"%s\" is too long",
651 	     file, line, base);
652       return;
653     }
654 
655   v = new_mode (vclass, xstrdup (namebuf), file, line);
656   v->ncomponents = ncomponents;
657   v->component = component;
658 }
659 
660 /* Adjustability.  */
661 #define _ADD_ADJUST(A, M, X, C) \
662   new_adjust (#M, &adj_##A, #A, #X, MODE_##C, __FILE__, __LINE__)
663 
664 #define ADJUST_BYTESIZE(M, X)  _ADD_ADJUST(bytesize, M, X, RANDOM)
665 #define ADJUST_ALIGNMENT(M, X) _ADD_ADJUST(alignment, M, X, RANDOM)
666 #define ADJUST_FLOAT_FORMAT(M, X)    _ADD_ADJUST(format, M, X, FLOAT)
667 
668 static void
create_modes(void)669 create_modes (void)
670 {
671 #include "machmode.def"
672 }
673 
674 /* Processing.  */
675 
676 /* Sort a list of modes into the order needed for the WIDER field:
677    major sort by precision, minor sort by component precision.
678 
679    For instance:
680      QI < HI < SI < DI < TI
681      V4QI < V2HI < V8QI < V4HI < V2SI.
682 
683    If the precision is not set, sort by the bytesize.  A mode with
684    precision set gets sorted before a mode without precision set, if
685    they have the same bytesize; this is the right thing because
686    the precision must always be smaller than the bytesize * BITS_PER_UNIT.
687    We don't have to do anything special to get this done -- an unset
688    precision shows up as (unsigned int)-1, i.e. UINT_MAX.  */
689 static int
cmp_modes(const void * a,const void * b)690 cmp_modes (const void *a, const void *b)
691 {
692   struct mode_data *m = *(struct mode_data **)a;
693   struct mode_data *n = *(struct mode_data **)b;
694 
695   if (m->bytesize > n->bytesize)
696     return 1;
697   else if (m->bytesize < n->bytesize)
698     return -1;
699 
700   if (m->precision > n->precision)
701     return 1;
702   else if (m->precision < n->precision)
703     return -1;
704 
705   if (!m->component && !n->component)
706     {
707       if (m->counter < n->counter)
708 	return -1;
709       else
710 	return 1;
711     }
712 
713   if (m->component->bytesize > n->component->bytesize)
714     return 1;
715   else if (m->component->bytesize < n->component->bytesize)
716     return -1;
717 
718   if (m->component->precision > n->component->precision)
719     return 1;
720   else if (m->component->precision < n->component->precision)
721     return -1;
722 
723   if (m->counter < n->counter)
724     return -1;
725   else
726     return 1;
727 }
728 
729 static void
calc_wider_mode(void)730 calc_wider_mode (void)
731 {
732   int c;
733   struct mode_data *m;
734   struct mode_data **sortbuf;
735   unsigned int max_n_modes = 0;
736   unsigned int i, j;
737 
738   for (c = 0; c < MAX_MODE_CLASS; c++)
739     max_n_modes = MAX (max_n_modes, n_modes[c]);
740 
741   /* Allocate max_n_modes + 1 entries to leave room for the extra null
742      pointer assigned after the qsort call below.  */
743   sortbuf = (struct mode_data **) alloca ((max_n_modes + 1) * sizeof (struct mode_data *));
744 
745   for (c = 0; c < MAX_MODE_CLASS; c++)
746     {
747       /* "wider" is not meaningful for MODE_RANDOM and MODE_CC.
748 	 However, we want these in textual order, and we have
749 	 precisely the reverse.  */
750       if (c == MODE_RANDOM || c == MODE_CC)
751 	{
752 	  struct mode_data *prev, *next;
753 
754 	  for (prev = 0, m = modes[c]; m; m = next)
755 	    {
756 	      m->wider = void_mode;
757 	      m->wider_2x = void_mode;
758 
759 	      /* this is nreverse */
760 	      next = m->next;
761 	      m->next = prev;
762 	      prev = m;
763 	    }
764 	  modes[c] = prev;
765 	}
766       else
767 	{
768 	  if (!modes[c])
769 	    continue;
770 
771 	  for (i = 0, m = modes[c]; m; i++, m = m->next)
772 	    sortbuf[i] = m;
773 
774 	  qsort (sortbuf, i, sizeof (struct mode_data *), cmp_modes);
775 
776 	  sortbuf[i] = 0;
777 	  for (j = 0; j < i; j++)
778 	    sortbuf[j]->next = sortbuf[j]->wider = sortbuf[j + 1];
779 
780 
781 	  modes[c] = sortbuf[0];
782 	}
783     }
784 }
785 
786 /* Output routines.  */
787 
788 #define tagged_printf(FMT, ARG, TAG) do {		\
789   int count_;						\
790   count_ = printf ("  " FMT ",", ARG);			\
791   printf ("%*s/* %s */\n", 27 - count_, "", TAG);	\
792 } while (0)
793 
794 #define print_decl(TYPE, NAME, ASIZE) \
795   puts ("\nconst " TYPE " " NAME "[" ASIZE "] =\n{");
796 
797 #define print_maybe_const_decl(TYPE, NAME, ASIZE, CATEGORY)	\
798   printf ("\n" TYPE " " NAME "[" ASIZE "] = \n{\n",		\
799 	  adj_##CATEGORY ? "" : "const ")
800 
801 #define print_closer() puts ("};")
802 
803 static void
emit_insn_modes_h(void)804 emit_insn_modes_h (void)
805 {
806   int c;
807   struct mode_data *m, *first, *last;
808 
809   printf ("/* Generated automatically from machmode.def%s%s\n",
810 	   HAVE_EXTRA_MODES ? " and " : "",
811 	   EXTRA_MODES_FILE);
812 
813   puts ("\
814    by genmodes.  */\n\
815 \n\
816 #ifndef GCC_INSN_MODES_H\n\
817 #define GCC_INSN_MODES_H\n\
818 \n\
819 enum machine_mode\n{");
820 
821   for (c = 0; c < MAX_MODE_CLASS; c++)
822     for (m = modes[c]; m; m = m->next)
823       {
824 	int count_;
825 	count_ = printf ("  %smode,", m->name);
826 	printf ("%*s/* %s:%d */\n", 27 - count_, "",
827 		 trim_filename (m->file), m->line);
828       }
829 
830   puts ("  MAX_MACHINE_MODE,\n");
831 
832   for (c = 0; c < MAX_MODE_CLASS; c++)
833     {
834       first = modes[c];
835       last = 0;
836       for (m = first; m; last = m, m = m->next)
837 	;
838 
839       /* Don't use BImode for MIN_MODE_INT, since otherwise the middle
840 	 end will try to use it for bitfields in structures and the
841 	 like, which we do not want.  Only the target md file should
842 	 generate BImode widgets.  */
843       if (first && first->precision == 1)
844 	first = first->next;
845 
846       if (first && last)
847 	printf ("  MIN_%s = %smode,\n  MAX_%s = %smode,\n\n",
848 		 mode_class_names[c], first->name,
849 		 mode_class_names[c], last->name);
850       else
851 	printf ("  MIN_%s = %smode,\n  MAX_%s = %smode,\n\n",
852 		 mode_class_names[c], void_mode->name,
853 		 mode_class_names[c], void_mode->name);
854     }
855 
856   puts ("\
857   NUM_MACHINE_MODES = MAX_MACHINE_MODE\n\
858 };\n");
859 
860   /* I can't think of a better idea, can you?  */
861   printf ("#define CONST_MODE_SIZE%s\n", adj_bytesize ? "" : " const");
862   printf ("#define CONST_MODE_BASE_ALIGN%s\n", adj_alignment ? "" : " const");
863 #if 0 /* disabled for backward compatibility, temporary */
864   printf ("#define CONST_REAL_FORMAT_FOR_MODE%s\n", adj_format ? "" :" const");
865 #endif
866   puts ("\
867 \n\
868 #endif /* insn-modes.h */");
869 }
870 
871 static void
emit_insn_modes_c_header(void)872 emit_insn_modes_c_header (void)
873 {
874   printf ("/* Generated automatically from machmode.def%s%s\n",
875 	   HAVE_EXTRA_MODES ? " and " : "",
876 	   EXTRA_MODES_FILE);
877 
878   puts ("\
879    by genmodes.  */\n\
880 \n\
881 #include \"config.h\"\n\
882 #include \"system.h\"\n\
883 #include \"coretypes.h\"\n\
884 #include \"tm.h\"\n\
885 #include \"machmode.h\"\n\
886 #include \"real.h\"");
887 }
888 
889 static void
emit_min_insn_modes_c_header(void)890 emit_min_insn_modes_c_header (void)
891 {
892   printf ("/* Generated automatically from machmode.def%s%s\n",
893 	   HAVE_EXTRA_MODES ? " and " : "",
894 	   EXTRA_MODES_FILE);
895 
896   puts ("\
897    by genmodes.  */\n\
898 \n\
899 #include \"bconfig.h\"\n\
900 #include \"system.h\"\n\
901 #include \"machmode.h\"");
902 }
903 
904 static void
emit_mode_name(void)905 emit_mode_name (void)
906 {
907   int c;
908   struct mode_data *m;
909 
910   print_decl ("char *const", "mode_name", "NUM_MACHINE_MODES");
911 
912   for_all_modes (c, m)
913     printf ("  \"%s\",\n", m->name);
914 
915   print_closer ();
916 }
917 
918 static void
emit_mode_class(void)919 emit_mode_class (void)
920 {
921   int c;
922   struct mode_data *m;
923 
924   print_decl ("unsigned char", "mode_class", "NUM_MACHINE_MODES");
925 
926   for_all_modes (c, m)
927     tagged_printf ("%s", mode_class_names[m->cl], m->name);
928 
929   print_closer ();
930 }
931 
932 static void
emit_mode_precision(void)933 emit_mode_precision (void)
934 {
935   int c;
936   struct mode_data *m;
937 
938   print_decl ("unsigned short", "mode_precision", "NUM_MACHINE_MODES");
939 
940   for_all_modes (c, m)
941     if (m->precision != (unsigned int)-1)
942       tagged_printf ("%u", m->precision, m->name);
943     else
944       tagged_printf ("%u*BITS_PER_UNIT", m->bytesize, m->name);
945 
946   print_closer ();
947 }
948 
949 static void
emit_mode_size(void)950 emit_mode_size (void)
951 {
952   int c;
953   struct mode_data *m;
954 
955   print_maybe_const_decl ("%sunsigned char", "mode_size",
956 			  "NUM_MACHINE_MODES", bytesize);
957 
958   for_all_modes (c, m)
959     tagged_printf ("%u", m->bytesize, m->name);
960 
961   print_closer ();
962 }
963 
964 static void
emit_mode_nunits(void)965 emit_mode_nunits (void)
966 {
967   int c;
968   struct mode_data *m;
969 
970   print_decl ("unsigned char", "mode_nunits", "NUM_MACHINE_MODES");
971 
972   for_all_modes (c, m)
973     tagged_printf ("%u", m->ncomponents, m->name);
974 
975   print_closer ();
976 }
977 
978 static void
emit_mode_wider(void)979 emit_mode_wider (void)
980 {
981   int c;
982   struct mode_data *m;
983 
984   print_decl ("unsigned char", "mode_wider", "NUM_MACHINE_MODES");
985 
986   for_all_modes (c, m)
987     tagged_printf ("%smode",
988 		   m->wider ? m->wider->name : void_mode->name,
989 		   m->name);
990 
991   print_closer ();
992   print_decl ("unsigned char", "mode_2xwider", "NUM_MACHINE_MODES");
993 
994   for_all_modes (c, m)
995     {
996       struct mode_data * m2;
997 
998       for (m2 = m;
999 	   m2 && m2 != void_mode;
1000 	   m2 = m2->wider)
1001 	{
1002 	  if (m2->bytesize < 2 * m->bytesize)
1003 	    continue;
1004 	  if (m->precision != (unsigned int) -1)
1005 	    {
1006 	      if (m2->precision != 2 * m->precision)
1007 		continue;
1008 	    }
1009 	  else
1010 	    {
1011 	      if (m2->precision != (unsigned int) -1)
1012 		continue;
1013 	    }
1014 
1015 	  break;
1016 	}
1017       if (m2 == void_mode)
1018 	m2 = 0;
1019       tagged_printf ("%smode",
1020 		     m2 ? m2->name : void_mode->name,
1021 		     m->name);
1022     }
1023 
1024   print_closer ();
1025 }
1026 
1027 static void
emit_mode_mask(void)1028 emit_mode_mask (void)
1029 {
1030   int c;
1031   struct mode_data *m;
1032 
1033   print_decl ("unsigned HOST_WIDE_INT", "mode_mask_array",
1034 	      "NUM_MACHINE_MODES");
1035   puts ("\
1036 #define MODE_MASK(m)                          \\\n\
1037   ((m) >= HOST_BITS_PER_WIDE_INT)             \\\n\
1038    ? ~(unsigned HOST_WIDE_INT) 0              \\\n\
1039    : ((unsigned HOST_WIDE_INT) 1 << (m)) - 1\n");
1040 
1041   for_all_modes (c, m)
1042     if (m->precision != (unsigned int)-1)
1043       tagged_printf ("MODE_MASK (%u)", m->precision, m->name);
1044     else
1045       tagged_printf ("MODE_MASK (%u*BITS_PER_UNIT)", m->bytesize, m->name);
1046 
1047   puts ("#undef MODE_MASK");
1048   print_closer ();
1049 }
1050 
1051 static void
emit_mode_inner(void)1052 emit_mode_inner (void)
1053 {
1054   int c;
1055   struct mode_data *m;
1056 
1057   print_decl ("unsigned char", "mode_inner", "NUM_MACHINE_MODES");
1058 
1059   for_all_modes (c, m)
1060     tagged_printf ("%smode",
1061 		   m->component ? m->component->name : void_mode->name,
1062 		   m->name);
1063 
1064   print_closer ();
1065 }
1066 
1067 static void
emit_mode_base_align(void)1068 emit_mode_base_align (void)
1069 {
1070   int c;
1071   struct mode_data *m;
1072 
1073   print_maybe_const_decl ("%sunsigned char",
1074 			  "mode_base_align", "NUM_MACHINE_MODES",
1075 			  alignment);
1076 
1077   for_all_modes (c, m)
1078     tagged_printf ("%u", m->alignment, m->name);
1079 
1080   print_closer ();
1081 }
1082 
1083 static void
emit_class_narrowest_mode(void)1084 emit_class_narrowest_mode (void)
1085 {
1086   int c;
1087 
1088   print_decl ("unsigned char", "class_narrowest_mode", "MAX_MODE_CLASS");
1089 
1090   for (c = 0; c < MAX_MODE_CLASS; c++)
1091     /* Bleah, all this to get the comment right for MIN_MODE_INT.  */
1092     tagged_printf ("MIN_%s", mode_class_names[c],
1093 		   modes[c]
1094 		   ? (modes[c]->precision != 1
1095 		      ? modes[c]->name
1096 		      : (modes[c]->next
1097 			 ? modes[c]->next->name
1098 			 : void_mode->name))
1099 		   : void_mode->name);
1100 
1101   print_closer ();
1102 }
1103 
1104 static void
emit_real_format_for_mode(void)1105 emit_real_format_for_mode (void)
1106 {
1107   struct mode_data *m;
1108 
1109   /* The entities pointed to by this table are constant, whether
1110      or not the table itself is constant.
1111 
1112      For backward compatibility this table is always writable
1113      (several targets modify it in OVERRIDE_OPTIONS).   FIXME:
1114      convert all said targets to use ADJUST_FORMAT instead.  */
1115 #if 0
1116   print_maybe_const_decl ("const struct real_format *%s",
1117 			  "real_format_for_mode",
1118 			  "MAX_MODE_FLOAT - MIN_MODE_FLOAT + 1",
1119 			  format);
1120 #else
1121   print_decl ("struct real_format *\n", "real_format_for_mode",
1122 	      "MAX_MODE_FLOAT - MIN_MODE_FLOAT + 1 "
1123 	      "+ MAX_MODE_DECIMAL_FLOAT - MIN_MODE_DECIMAL_FLOAT + 1");
1124 #endif
1125 
1126   /* The beginning of the table is entries for float modes.  */
1127   for (m = modes[MODE_FLOAT]; m; m = m->next)
1128     if (!strcmp (m->format, "0"))
1129       tagged_printf ("%s", m->format, m->name);
1130     else
1131       tagged_printf ("&%s", m->format, m->name);
1132 
1133   /* The end of the table is entries for decimal float modes.  */
1134   for (m = modes[MODE_DECIMAL_FLOAT]; m; m = m->next)
1135     if (!strcmp (m->format, "0"))
1136       tagged_printf ("%s", m->format, m->name);
1137     else
1138       tagged_printf ("&%s", m->format, m->name);
1139 
1140   print_closer ();
1141 }
1142 
1143 static void
emit_mode_adjustments(void)1144 emit_mode_adjustments (void)
1145 {
1146   struct mode_adjust *a;
1147   struct mode_data *m;
1148 
1149   puts ("\
1150 \nvoid\
1151 \ninit_adjust_machine_modes (void)\
1152 \n{\
1153 \n  size_t s ATTRIBUTE_UNUSED;");
1154 
1155   /* Size adjustments must be propagated to all containing modes.
1156      A size adjustment forces us to recalculate the alignment too.  */
1157   for (a = adj_bytesize; a; a = a->next)
1158     {
1159       printf ("\n  /* %s:%d */\n  s = %s;\n",
1160 	      a->file, a->line, a->adjustment);
1161       printf ("  mode_size[%smode] = s;\n", a->mode->name);
1162       printf ("  mode_base_align[%smode] = s & (~s + 1);\n",
1163 	      a->mode->name);
1164 
1165       for (m = a->mode->contained; m; m = m->next_cont)
1166 	{
1167 	  switch (m->cl)
1168 	    {
1169 	    case MODE_COMPLEX_INT:
1170 	    case MODE_COMPLEX_FLOAT:
1171 	      printf ("  mode_size[%smode] = 2*s;\n", m->name);
1172 	      printf ("  mode_base_align[%smode] = s & (~s + 1);\n",
1173 		      m->name);
1174 	      break;
1175 
1176 	    case MODE_VECTOR_INT:
1177 	    case MODE_VECTOR_FLOAT:
1178 	      printf ("  mode_size[%smode] = %d*s;\n",
1179 		      m->name, m->ncomponents);
1180 	      printf ("  mode_base_align[%smode] = (%d*s) & (~(%d*s)+1);\n",
1181 		      m->name, m->ncomponents, m->ncomponents);
1182 	      break;
1183 
1184 	    default:
1185 	      internal_error (
1186 	      "mode %s is neither vector nor complex but contains %s",
1187 	      m->name, a->mode->name);
1188 	      /* NOTREACHED */
1189 	    }
1190 	}
1191     }
1192 
1193   /* Alignment adjustments propagate too.
1194      ??? This may not be the right thing for vector modes.  */
1195   for (a = adj_alignment; a; a = a->next)
1196     {
1197       printf ("\n  /* %s:%d */\n  s = %s;\n",
1198 	      a->file, a->line, a->adjustment);
1199       printf ("  mode_base_align[%smode] = s;\n", a->mode->name);
1200 
1201       for (m = a->mode->contained; m; m = m->next_cont)
1202 	{
1203 	  switch (m->cl)
1204 	    {
1205 	    case MODE_COMPLEX_INT:
1206 	    case MODE_COMPLEX_FLOAT:
1207 	      printf ("  mode_base_align[%smode] = s;\n", m->name);
1208 	      break;
1209 
1210 	    case MODE_VECTOR_INT:
1211 	    case MODE_VECTOR_FLOAT:
1212 	      printf ("  mode_base_align[%smode] = %d*s;\n",
1213 		      m->name, m->ncomponents);
1214 	      break;
1215 
1216 	    default:
1217 	      internal_error (
1218 	      "mode %s is neither vector nor complex but contains %s",
1219 	      m->name, a->mode->name);
1220 	      /* NOTREACHED */
1221 	    }
1222 	}
1223     }
1224 
1225   /* Real mode formats don't have to propagate anywhere.  */
1226   for (a = adj_format; a; a = a->next)
1227     printf ("\n  /* %s:%d */\n  REAL_MODE_FORMAT (%smode) = %s;\n",
1228 	    a->file, a->line, a->mode->name, a->adjustment);
1229 
1230   puts ("}");
1231 }
1232 
1233 static void
emit_insn_modes_c(void)1234 emit_insn_modes_c (void)
1235 {
1236   emit_insn_modes_c_header ();
1237   emit_mode_name ();
1238   emit_mode_class ();
1239   emit_mode_precision ();
1240   emit_mode_size ();
1241   emit_mode_nunits ();
1242   emit_mode_wider ();
1243   emit_mode_mask ();
1244   emit_mode_inner ();
1245   emit_mode_base_align ();
1246   emit_class_narrowest_mode ();
1247   emit_real_format_for_mode ();
1248   emit_mode_adjustments ();
1249 }
1250 
1251 static void
emit_min_insn_modes_c(void)1252 emit_min_insn_modes_c (void)
1253 {
1254   emit_min_insn_modes_c_header ();
1255   emit_mode_name ();
1256   emit_mode_class ();
1257   emit_mode_wider ();
1258   emit_class_narrowest_mode ();
1259 }
1260 
1261 /* Master control.  */
1262 int
main(int argc,char ** argv)1263 main(int argc, char **argv)
1264 {
1265   bool gen_header = false, gen_min = false;
1266   progname = argv[0];
1267 
1268   if (argc == 1)
1269     ;
1270   else if (argc == 2 && !strcmp (argv[1], "-h"))
1271     gen_header = true;
1272   else if (argc == 2 && !strcmp (argv[1], "-m"))
1273     gen_min = true;
1274   else
1275     {
1276       error ("usage: %s [-h|-m] > file", progname);
1277       return FATAL_EXIT_CODE;
1278     }
1279 
1280   modes_by_name = htab_create_alloc (64, hash_mode, eq_mode, 0, xcalloc, free);
1281 
1282   create_modes ();
1283   complete_all_modes ();
1284 
1285   if (have_error)
1286     return FATAL_EXIT_CODE;
1287 
1288   calc_wider_mode ();
1289 
1290   if (gen_header)
1291     emit_insn_modes_h ();
1292   else if (gen_min)
1293     emit_min_insn_modes_c ();
1294   else
1295     emit_insn_modes_c ();
1296 
1297   if (fflush (stdout) || fclose (stdout))
1298     return FATAL_EXIT_CODE;
1299   return SUCCESS_EXIT_CODE;
1300 }
1301