xref: /netbsd/external/gpl3/gcc/dist/gcc/genmodes.cc (revision f0fbc68b)
1*f0fbc68bSmrg /* Generate the machine mode enumeration and associated tables.
2*f0fbc68bSmrg    Copyright (C) 2003-2022 Free Software Foundation, Inc.
3*f0fbc68bSmrg 
4*f0fbc68bSmrg This file is part of GCC.
5*f0fbc68bSmrg 
6*f0fbc68bSmrg GCC is free software; you can redistribute it and/or modify it under
7*f0fbc68bSmrg the terms of the GNU General Public License as published by the Free
8*f0fbc68bSmrg Software Foundation; either version 3, or (at your option) any later
9*f0fbc68bSmrg version.
10*f0fbc68bSmrg 
11*f0fbc68bSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12*f0fbc68bSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
13*f0fbc68bSmrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14*f0fbc68bSmrg for more details.
15*f0fbc68bSmrg 
16*f0fbc68bSmrg You should have received a copy of the GNU General Public License
17*f0fbc68bSmrg along with GCC; see the file COPYING3.  If not see
18*f0fbc68bSmrg <http://www.gnu.org/licenses/>.  */
19*f0fbc68bSmrg 
20*f0fbc68bSmrg #include "bconfig.h"
21*f0fbc68bSmrg #include "system.h"
22*f0fbc68bSmrg #include "errors.h"
23*f0fbc68bSmrg 
24*f0fbc68bSmrg /* enum mode_class is normally defined by machmode.h but we can't
25*f0fbc68bSmrg    include that header here.  */
26*f0fbc68bSmrg #include "mode-classes.def"
27*f0fbc68bSmrg 
28*f0fbc68bSmrg #define DEF_MODE_CLASS(M) M
29*f0fbc68bSmrg enum mode_class { MODE_CLASSES, MAX_MODE_CLASS };
30*f0fbc68bSmrg #undef DEF_MODE_CLASS
31*f0fbc68bSmrg 
32*f0fbc68bSmrg /* Text names of mode classes, for output.  */
33*f0fbc68bSmrg #define DEF_MODE_CLASS(M) #M
34*f0fbc68bSmrg static const char *const mode_class_names[MAX_MODE_CLASS] =
35*f0fbc68bSmrg {
36*f0fbc68bSmrg   MODE_CLASSES
37*f0fbc68bSmrg };
38*f0fbc68bSmrg #undef DEF_MODE_CLASS
39*f0fbc68bSmrg #undef MODE_CLASSES
40*f0fbc68bSmrg 
41*f0fbc68bSmrg #ifdef EXTRA_MODES_FILE
42*f0fbc68bSmrg # define HAVE_EXTRA_MODES 1
43*f0fbc68bSmrg #else
44*f0fbc68bSmrg # define HAVE_EXTRA_MODES 0
45*f0fbc68bSmrg # define EXTRA_MODES_FILE ""
46*f0fbc68bSmrg #endif
47*f0fbc68bSmrg 
48*f0fbc68bSmrg /* Data structure for building up what we know about a mode.
49*f0fbc68bSmrg    They're clustered by mode class.  */
50*f0fbc68bSmrg struct mode_data
51*f0fbc68bSmrg {
52*f0fbc68bSmrg   struct mode_data *next;	/* next this class - arbitrary order */
53*f0fbc68bSmrg 
54*f0fbc68bSmrg   const char *name;		/* printable mode name -- SI, not SImode */
55*f0fbc68bSmrg   enum mode_class cl;		/* this mode class */
56*f0fbc68bSmrg   unsigned int order;		/* top-level sorting order */
57*f0fbc68bSmrg   unsigned int precision;	/* size in bits, equiv to TYPE_PRECISION */
58*f0fbc68bSmrg   unsigned int bytesize;	/* storage size in addressable units */
59*f0fbc68bSmrg   unsigned int ncomponents;	/* number of subunits */
60*f0fbc68bSmrg   unsigned int alignment;	/* mode alignment */
61*f0fbc68bSmrg   const char *format;		/* floating point format - float modes only */
62*f0fbc68bSmrg 
63*f0fbc68bSmrg   struct mode_data *component;	/* mode of components */
64*f0fbc68bSmrg   struct mode_data *wider;	/* next wider mode */
65*f0fbc68bSmrg 
66*f0fbc68bSmrg   struct mode_data *contained;  /* Pointer to list of modes that have
67*f0fbc68bSmrg 				   this mode as a component.  */
68*f0fbc68bSmrg   struct mode_data *next_cont;  /* Next mode in that list.  */
69*f0fbc68bSmrg 
70*f0fbc68bSmrg   struct mode_data *complex;	/* complex type with mode as component.  */
71*f0fbc68bSmrg   const char *file;		/* file and line of definition, */
72*f0fbc68bSmrg   unsigned int line;		/* for error reporting */
73*f0fbc68bSmrg   unsigned int counter;		/* Rank ordering of modes */
74*f0fbc68bSmrg   unsigned int ibit;		/* the number of integral bits */
75*f0fbc68bSmrg   unsigned int fbit;		/* the number of fractional bits */
76*f0fbc68bSmrg   bool need_nunits_adj;		/* true if this mode needs dynamic nunits
77*f0fbc68bSmrg 				   adjustment */
78*f0fbc68bSmrg   bool need_bytesize_adj;	/* true if this mode needs dynamic size
79*f0fbc68bSmrg 				   adjustment */
80*f0fbc68bSmrg   unsigned int int_n;		/* If nonzero, then __int<INT_N> will be defined */
81*f0fbc68bSmrg   bool boolean;
82*f0fbc68bSmrg };
83*f0fbc68bSmrg 
84*f0fbc68bSmrg static struct mode_data *modes[MAX_MODE_CLASS];
85*f0fbc68bSmrg static unsigned int n_modes[MAX_MODE_CLASS];
86*f0fbc68bSmrg static struct mode_data *void_mode;
87*f0fbc68bSmrg 
88*f0fbc68bSmrg static const struct mode_data blank_mode = {
89*f0fbc68bSmrg   0, "<unknown>", MAX_MODE_CLASS,
90*f0fbc68bSmrg   0, -1U, -1U, -1U, -1U,
91*f0fbc68bSmrg   0, 0, 0, 0, 0, 0,
92*f0fbc68bSmrg   "<unknown>", 0, 0, 0, 0, false, false, 0,
93*f0fbc68bSmrg   false
94*f0fbc68bSmrg };
95*f0fbc68bSmrg 
96*f0fbc68bSmrg static htab_t modes_by_name;
97*f0fbc68bSmrg 
98*f0fbc68bSmrg /* Data structure for recording target-specified runtime adjustments
99*f0fbc68bSmrg    to a particular mode.  We support varying the byte size, the
100*f0fbc68bSmrg    alignment, and the floating point format.  */
101*f0fbc68bSmrg struct mode_adjust
102*f0fbc68bSmrg {
103*f0fbc68bSmrg   struct mode_adjust *next;
104*f0fbc68bSmrg   struct mode_data *mode;
105*f0fbc68bSmrg   const char *adjustment;
106*f0fbc68bSmrg 
107*f0fbc68bSmrg   const char *file;
108*f0fbc68bSmrg   unsigned int line;
109*f0fbc68bSmrg };
110*f0fbc68bSmrg 
111*f0fbc68bSmrg static struct mode_adjust *adj_nunits;
112*f0fbc68bSmrg static struct mode_adjust *adj_bytesize;
113*f0fbc68bSmrg static struct mode_adjust *adj_alignment;
114*f0fbc68bSmrg static struct mode_adjust *adj_format;
115*f0fbc68bSmrg static struct mode_adjust *adj_ibit;
116*f0fbc68bSmrg static struct mode_adjust *adj_fbit;
117*f0fbc68bSmrg 
118*f0fbc68bSmrg /* Mode class operations.  */
119*f0fbc68bSmrg static enum mode_class
complex_class(enum mode_class c)120*f0fbc68bSmrg complex_class (enum mode_class c)
121*f0fbc68bSmrg {
122*f0fbc68bSmrg   switch (c)
123*f0fbc68bSmrg     {
124*f0fbc68bSmrg     case MODE_INT: return MODE_COMPLEX_INT;
125*f0fbc68bSmrg     case MODE_PARTIAL_INT: return MODE_COMPLEX_INT;
126*f0fbc68bSmrg     case MODE_FLOAT: return MODE_COMPLEX_FLOAT;
127*f0fbc68bSmrg     default:
128*f0fbc68bSmrg       error ("no complex class for class %s", mode_class_names[c]);
129*f0fbc68bSmrg       return MODE_RANDOM;
130*f0fbc68bSmrg     }
131*f0fbc68bSmrg }
132*f0fbc68bSmrg 
133*f0fbc68bSmrg static enum mode_class
vector_class(enum mode_class cl)134*f0fbc68bSmrg vector_class (enum mode_class cl)
135*f0fbc68bSmrg {
136*f0fbc68bSmrg   switch (cl)
137*f0fbc68bSmrg     {
138*f0fbc68bSmrg     case MODE_INT: return MODE_VECTOR_INT;
139*f0fbc68bSmrg     case MODE_FLOAT: return MODE_VECTOR_FLOAT;
140*f0fbc68bSmrg     case MODE_FRACT: return MODE_VECTOR_FRACT;
141*f0fbc68bSmrg     case MODE_UFRACT: return MODE_VECTOR_UFRACT;
142*f0fbc68bSmrg     case MODE_ACCUM: return MODE_VECTOR_ACCUM;
143*f0fbc68bSmrg     case MODE_UACCUM: return MODE_VECTOR_UACCUM;
144*f0fbc68bSmrg     default:
145*f0fbc68bSmrg       error ("no vector class for class %s", mode_class_names[cl]);
146*f0fbc68bSmrg       return MODE_RANDOM;
147*f0fbc68bSmrg     }
148*f0fbc68bSmrg }
149*f0fbc68bSmrg 
150*f0fbc68bSmrg /* Utility routines.  */
151*f0fbc68bSmrg static inline struct mode_data *
find_mode(const char * name)152*f0fbc68bSmrg find_mode (const char *name)
153*f0fbc68bSmrg {
154*f0fbc68bSmrg   struct mode_data key;
155*f0fbc68bSmrg 
156*f0fbc68bSmrg   key.name = name;
157*f0fbc68bSmrg   return (struct mode_data *) htab_find (modes_by_name, &key);
158*f0fbc68bSmrg }
159*f0fbc68bSmrg 
160*f0fbc68bSmrg static struct mode_data *
new_mode(enum mode_class cl,const char * name,const char * file,unsigned int line)161*f0fbc68bSmrg new_mode (enum mode_class cl, const char *name,
162*f0fbc68bSmrg 	  const char *file, unsigned int line)
163*f0fbc68bSmrg {
164*f0fbc68bSmrg   struct mode_data *m;
165*f0fbc68bSmrg   static unsigned int count = 0;
166*f0fbc68bSmrg 
167*f0fbc68bSmrg   m = find_mode (name);
168*f0fbc68bSmrg   if (m)
169*f0fbc68bSmrg     {
170*f0fbc68bSmrg       error ("%s:%d: duplicate definition of mode \"%s\"",
171*f0fbc68bSmrg 	     trim_filename (file), line, name);
172*f0fbc68bSmrg       error ("%s:%d: previous definition here", m->file, m->line);
173*f0fbc68bSmrg       return m;
174*f0fbc68bSmrg     }
175*f0fbc68bSmrg 
176*f0fbc68bSmrg   m = XNEW (struct mode_data);
177*f0fbc68bSmrg   memcpy (m, &blank_mode, sizeof (struct mode_data));
178*f0fbc68bSmrg   m->cl = cl;
179*f0fbc68bSmrg   m->name = name;
180*f0fbc68bSmrg   if (file)
181*f0fbc68bSmrg     m->file = trim_filename (file);
182*f0fbc68bSmrg   m->line = line;
183*f0fbc68bSmrg   m->counter = count++;
184*f0fbc68bSmrg 
185*f0fbc68bSmrg   m->next = modes[cl];
186*f0fbc68bSmrg   modes[cl] = m;
187*f0fbc68bSmrg   n_modes[cl]++;
188*f0fbc68bSmrg 
189*f0fbc68bSmrg   *htab_find_slot (modes_by_name, m, INSERT) = m;
190*f0fbc68bSmrg 
191*f0fbc68bSmrg   return m;
192*f0fbc68bSmrg }
193*f0fbc68bSmrg 
194*f0fbc68bSmrg static hashval_t
hash_mode(const void * p)195*f0fbc68bSmrg hash_mode (const void *p)
196*f0fbc68bSmrg {
197*f0fbc68bSmrg   const struct mode_data *m = (const struct mode_data *)p;
198*f0fbc68bSmrg   return htab_hash_string (m->name);
199*f0fbc68bSmrg }
200*f0fbc68bSmrg 
201*f0fbc68bSmrg static int
eq_mode(const void * p,const void * q)202*f0fbc68bSmrg eq_mode (const void *p, const void *q)
203*f0fbc68bSmrg {
204*f0fbc68bSmrg   const struct mode_data *a = (const struct mode_data *)p;
205*f0fbc68bSmrg   const struct mode_data *b = (const struct mode_data *)q;
206*f0fbc68bSmrg 
207*f0fbc68bSmrg   return !strcmp (a->name, b->name);
208*f0fbc68bSmrg }
209*f0fbc68bSmrg 
210*f0fbc68bSmrg #define for_all_modes(C, M)			\
211*f0fbc68bSmrg   for (C = 0; C < MAX_MODE_CLASS; C++)		\
212*f0fbc68bSmrg     for (M = modes[C]; M; M = M->next)
213*f0fbc68bSmrg 
214*f0fbc68bSmrg static void ATTRIBUTE_UNUSED
new_adjust(const char * name,struct mode_adjust ** category,const char * catname,const char * adjustment,enum mode_class required_class_from,enum mode_class required_class_to,const char * file,unsigned int line)215*f0fbc68bSmrg new_adjust (const char *name,
216*f0fbc68bSmrg 	    struct mode_adjust **category, const char *catname,
217*f0fbc68bSmrg 	    const char *adjustment,
218*f0fbc68bSmrg 	    enum mode_class required_class_from,
219*f0fbc68bSmrg 	    enum mode_class required_class_to,
220*f0fbc68bSmrg 	    const char *file, unsigned int line)
221*f0fbc68bSmrg {
222*f0fbc68bSmrg   struct mode_data *mode = find_mode (name);
223*f0fbc68bSmrg   struct mode_adjust *a;
224*f0fbc68bSmrg 
225*f0fbc68bSmrg   file = trim_filename (file);
226*f0fbc68bSmrg 
227*f0fbc68bSmrg   if (!mode)
228*f0fbc68bSmrg     {
229*f0fbc68bSmrg       error ("%s:%d: no mode \"%s\"", file, line, name);
230*f0fbc68bSmrg       return;
231*f0fbc68bSmrg     }
232*f0fbc68bSmrg 
233*f0fbc68bSmrg   if (required_class_from != MODE_RANDOM
234*f0fbc68bSmrg       && (mode->cl < required_class_from || mode->cl > required_class_to))
235*f0fbc68bSmrg     {
236*f0fbc68bSmrg       error ("%s:%d: mode \"%s\" is not among class {%s, %s}",
237*f0fbc68bSmrg 	     file, line, name, mode_class_names[required_class_from] + 5,
238*f0fbc68bSmrg 	     mode_class_names[required_class_to] + 5);
239*f0fbc68bSmrg       return;
240*f0fbc68bSmrg     }
241*f0fbc68bSmrg 
242*f0fbc68bSmrg   for (a = *category; a; a = a->next)
243*f0fbc68bSmrg     if (a->mode == mode)
244*f0fbc68bSmrg       {
245*f0fbc68bSmrg 	error ("%s:%d: mode \"%s\" already has a %s adjustment",
246*f0fbc68bSmrg 	       file, line, name, catname);
247*f0fbc68bSmrg 	error ("%s:%d: previous adjustment here", a->file, a->line);
248*f0fbc68bSmrg 	return;
249*f0fbc68bSmrg       }
250*f0fbc68bSmrg 
251*f0fbc68bSmrg   a = XNEW (struct mode_adjust);
252*f0fbc68bSmrg   a->mode = mode;
253*f0fbc68bSmrg   a->adjustment = adjustment;
254*f0fbc68bSmrg   a->file = file;
255*f0fbc68bSmrg   a->line = line;
256*f0fbc68bSmrg 
257*f0fbc68bSmrg   a->next = *category;
258*f0fbc68bSmrg   *category = a;
259*f0fbc68bSmrg }
260*f0fbc68bSmrg 
261*f0fbc68bSmrg /* Diagnose failure to meet expectations in a partially filled out
262*f0fbc68bSmrg    mode structure.  */
263*f0fbc68bSmrg enum requirement { SET, UNSET, OPTIONAL };
264*f0fbc68bSmrg 
265*f0fbc68bSmrg #define validate_field_(mname, fname, req, val, unset, file, line) do {	\
266*f0fbc68bSmrg   switch (req)								\
267*f0fbc68bSmrg     {									\
268*f0fbc68bSmrg     case SET:								\
269*f0fbc68bSmrg       if (val == unset)							\
270*f0fbc68bSmrg 	error ("%s:%d: (%s) field %s must be set",			\
271*f0fbc68bSmrg 	       file, line, mname, fname);				\
272*f0fbc68bSmrg       break;								\
273*f0fbc68bSmrg     case UNSET:								\
274*f0fbc68bSmrg       if (val != unset)							\
275*f0fbc68bSmrg 	error ("%s:%d: (%s) field %s must not be set",			\
276*f0fbc68bSmrg 	       file, line, mname, fname);				\
277*f0fbc68bSmrg     case OPTIONAL:							\
278*f0fbc68bSmrg       break;								\
279*f0fbc68bSmrg     }									\
280*f0fbc68bSmrg } while (0)
281*f0fbc68bSmrg 
282*f0fbc68bSmrg #define validate_field(M, F) \
283*f0fbc68bSmrg   validate_field_(M->name, #F, r_##F, M->F, blank_mode.F, M->file, M->line)
284*f0fbc68bSmrg 
285*f0fbc68bSmrg 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)286*f0fbc68bSmrg validate_mode (struct mode_data *m,
287*f0fbc68bSmrg 	       enum requirement r_precision,
288*f0fbc68bSmrg 	       enum requirement r_bytesize,
289*f0fbc68bSmrg 	       enum requirement r_component,
290*f0fbc68bSmrg 	       enum requirement r_ncomponents,
291*f0fbc68bSmrg 	       enum requirement r_format)
292*f0fbc68bSmrg {
293*f0fbc68bSmrg   validate_field (m, precision);
294*f0fbc68bSmrg   validate_field (m, bytesize);
295*f0fbc68bSmrg   validate_field (m, component);
296*f0fbc68bSmrg   validate_field (m, ncomponents);
297*f0fbc68bSmrg   validate_field (m, format);
298*f0fbc68bSmrg }
299*f0fbc68bSmrg #undef validate_field
300*f0fbc68bSmrg #undef validate_field_
301*f0fbc68bSmrg 
302*f0fbc68bSmrg /* Given a partially-filled-out mode structure, figure out what we can
303*f0fbc68bSmrg    and fill the rest of it in; die if it isn't enough.  */
304*f0fbc68bSmrg static void
complete_mode(struct mode_data * m)305*f0fbc68bSmrg complete_mode (struct mode_data *m)
306*f0fbc68bSmrg {
307*f0fbc68bSmrg   unsigned int alignment;
308*f0fbc68bSmrg 
309*f0fbc68bSmrg   if (!m->name)
310*f0fbc68bSmrg     {
311*f0fbc68bSmrg       error ("%s:%d: mode with no name", m->file, m->line);
312*f0fbc68bSmrg       return;
313*f0fbc68bSmrg     }
314*f0fbc68bSmrg   if (m->cl == MAX_MODE_CLASS)
315*f0fbc68bSmrg     {
316*f0fbc68bSmrg       error ("%s:%d: %smode has no mode class", m->file, m->line, m->name);
317*f0fbc68bSmrg       return;
318*f0fbc68bSmrg     }
319*f0fbc68bSmrg 
320*f0fbc68bSmrg   switch (m->cl)
321*f0fbc68bSmrg     {
322*f0fbc68bSmrg     case MODE_RANDOM:
323*f0fbc68bSmrg       /* Nothing more need be said.  */
324*f0fbc68bSmrg       if (!strcmp (m->name, "VOID"))
325*f0fbc68bSmrg 	void_mode = m;
326*f0fbc68bSmrg 
327*f0fbc68bSmrg       validate_mode (m, UNSET, UNSET, UNSET, UNSET, UNSET);
328*f0fbc68bSmrg 
329*f0fbc68bSmrg       m->precision = 0;
330*f0fbc68bSmrg       m->bytesize = 0;
331*f0fbc68bSmrg       m->ncomponents = 0;
332*f0fbc68bSmrg       m->component = 0;
333*f0fbc68bSmrg       break;
334*f0fbc68bSmrg 
335*f0fbc68bSmrg     case MODE_CC:
336*f0fbc68bSmrg       /* Again, nothing more need be said.  For historical reasons,
337*f0fbc68bSmrg 	 the size of a CC mode is four units.  */
338*f0fbc68bSmrg       validate_mode (m, UNSET, UNSET, UNSET, UNSET, UNSET);
339*f0fbc68bSmrg 
340*f0fbc68bSmrg       m->bytesize = 4;
341*f0fbc68bSmrg       m->ncomponents = 1;
342*f0fbc68bSmrg       m->component = 0;
343*f0fbc68bSmrg       break;
344*f0fbc68bSmrg 
345*f0fbc68bSmrg     case MODE_INT:
346*f0fbc68bSmrg     case MODE_FLOAT:
347*f0fbc68bSmrg     case MODE_DECIMAL_FLOAT:
348*f0fbc68bSmrg     case MODE_FRACT:
349*f0fbc68bSmrg     case MODE_UFRACT:
350*f0fbc68bSmrg     case MODE_ACCUM:
351*f0fbc68bSmrg     case MODE_UACCUM:
352*f0fbc68bSmrg       /* A scalar mode must have a byte size, may have a bit size,
353*f0fbc68bSmrg 	 and must not have components.   A float mode must have a
354*f0fbc68bSmrg          format.  */
355*f0fbc68bSmrg       validate_mode (m, OPTIONAL, SET, UNSET, UNSET,
356*f0fbc68bSmrg 		     (m->cl == MODE_FLOAT || m->cl == MODE_DECIMAL_FLOAT)
357*f0fbc68bSmrg 		     ? SET : UNSET);
358*f0fbc68bSmrg 
359*f0fbc68bSmrg       m->ncomponents = 1;
360*f0fbc68bSmrg       m->component = 0;
361*f0fbc68bSmrg       break;
362*f0fbc68bSmrg 
363*f0fbc68bSmrg     case MODE_OPAQUE:
364*f0fbc68bSmrg       /* Opaque modes have size and precision.  */
365*f0fbc68bSmrg       validate_mode (m, OPTIONAL, SET, UNSET, UNSET, UNSET);
366*f0fbc68bSmrg 
367*f0fbc68bSmrg       m->ncomponents = 1;
368*f0fbc68bSmrg       m->component = 0;
369*f0fbc68bSmrg       break;
370*f0fbc68bSmrg 
371*f0fbc68bSmrg     case MODE_PARTIAL_INT:
372*f0fbc68bSmrg       /* A partial integer mode uses ->component to say what the
373*f0fbc68bSmrg 	 corresponding full-size integer mode is, and may also
374*f0fbc68bSmrg 	 specify a bit size.  */
375*f0fbc68bSmrg       validate_mode (m, OPTIONAL, UNSET, SET, UNSET, UNSET);
376*f0fbc68bSmrg 
377*f0fbc68bSmrg       m->bytesize = m->component->bytesize;
378*f0fbc68bSmrg 
379*f0fbc68bSmrg       m->ncomponents = 1;
380*f0fbc68bSmrg       break;
381*f0fbc68bSmrg 
382*f0fbc68bSmrg     case MODE_COMPLEX_INT:
383*f0fbc68bSmrg     case MODE_COMPLEX_FLOAT:
384*f0fbc68bSmrg       /* Complex modes should have a component indicated, but no more.  */
385*f0fbc68bSmrg       validate_mode (m, UNSET, UNSET, SET, UNSET, UNSET);
386*f0fbc68bSmrg       m->ncomponents = 2;
387*f0fbc68bSmrg       if (m->component->precision != (unsigned int)-1)
388*f0fbc68bSmrg 	m->precision = 2 * m->component->precision;
389*f0fbc68bSmrg       m->bytesize = 2 * m->component->bytesize;
390*f0fbc68bSmrg       break;
391*f0fbc68bSmrg 
392*f0fbc68bSmrg     case MODE_VECTOR_BOOL:
393*f0fbc68bSmrg       validate_mode (m, UNSET, SET, SET, SET, UNSET);
394*f0fbc68bSmrg       break;
395*f0fbc68bSmrg 
396*f0fbc68bSmrg     case MODE_VECTOR_INT:
397*f0fbc68bSmrg     case MODE_VECTOR_FLOAT:
398*f0fbc68bSmrg     case MODE_VECTOR_FRACT:
399*f0fbc68bSmrg     case MODE_VECTOR_UFRACT:
400*f0fbc68bSmrg     case MODE_VECTOR_ACCUM:
401*f0fbc68bSmrg     case MODE_VECTOR_UACCUM:
402*f0fbc68bSmrg       /* Vector modes should have a component and a number of components.  */
403*f0fbc68bSmrg       validate_mode (m, UNSET, UNSET, SET, SET, UNSET);
404*f0fbc68bSmrg       if (m->component->precision != (unsigned int)-1)
405*f0fbc68bSmrg 	m->precision = m->ncomponents * m->component->precision;
406*f0fbc68bSmrg       m->bytesize = m->ncomponents * m->component->bytesize;
407*f0fbc68bSmrg       break;
408*f0fbc68bSmrg 
409*f0fbc68bSmrg     default:
410*f0fbc68bSmrg       gcc_unreachable ();
411*f0fbc68bSmrg     }
412*f0fbc68bSmrg 
413*f0fbc68bSmrg   /* If not already specified, the mode alignment defaults to the largest
414*f0fbc68bSmrg      power of two that divides the size of the object.  Complex types are
415*f0fbc68bSmrg      not more aligned than their contents.  */
416*f0fbc68bSmrg   if (m->cl == MODE_COMPLEX_INT || m->cl == MODE_COMPLEX_FLOAT)
417*f0fbc68bSmrg     alignment = m->component->bytesize;
418*f0fbc68bSmrg   else
419*f0fbc68bSmrg     alignment = m->bytesize;
420*f0fbc68bSmrg 
421*f0fbc68bSmrg   m->alignment = alignment & (~alignment + 1);
422*f0fbc68bSmrg 
423*f0fbc68bSmrg   /* If this mode has components, make the component mode point back
424*f0fbc68bSmrg      to this mode, for the sake of adjustments.  */
425*f0fbc68bSmrg   if (m->component)
426*f0fbc68bSmrg     {
427*f0fbc68bSmrg       m->next_cont = m->component->contained;
428*f0fbc68bSmrg       m->component->contained = m;
429*f0fbc68bSmrg     }
430*f0fbc68bSmrg }
431*f0fbc68bSmrg 
432*f0fbc68bSmrg static void
complete_all_modes(void)433*f0fbc68bSmrg complete_all_modes (void)
434*f0fbc68bSmrg {
435*f0fbc68bSmrg   struct mode_data *m;
436*f0fbc68bSmrg   int cl;
437*f0fbc68bSmrg 
438*f0fbc68bSmrg   for_all_modes (cl, m)
439*f0fbc68bSmrg     complete_mode (m);
440*f0fbc68bSmrg }
441*f0fbc68bSmrg 
442*f0fbc68bSmrg /* For each mode in class CLASS, construct a corresponding complex mode.  */
443*f0fbc68bSmrg #define COMPLEX_MODES(C) make_complex_modes (MODE_##C, __FILE__, __LINE__)
444*f0fbc68bSmrg static void
make_complex_modes(enum mode_class cl,const char * file,unsigned int line)445*f0fbc68bSmrg make_complex_modes (enum mode_class cl,
446*f0fbc68bSmrg 		    const char *file, unsigned int line)
447*f0fbc68bSmrg {
448*f0fbc68bSmrg   struct mode_data *m;
449*f0fbc68bSmrg   struct mode_data *c;
450*f0fbc68bSmrg   enum mode_class cclass = complex_class (cl);
451*f0fbc68bSmrg 
452*f0fbc68bSmrg   if (cclass == MODE_RANDOM)
453*f0fbc68bSmrg     return;
454*f0fbc68bSmrg 
455*f0fbc68bSmrg   for (m = modes[cl]; m; m = m->next)
456*f0fbc68bSmrg     {
457*f0fbc68bSmrg       char *p, *buf;
458*f0fbc68bSmrg       size_t m_len;
459*f0fbc68bSmrg 
460*f0fbc68bSmrg       /* Skip BImode.  FIXME: BImode probably shouldn't be MODE_INT.  */
461*f0fbc68bSmrg       if (m->boolean)
462*f0fbc68bSmrg 	continue;
463*f0fbc68bSmrg 
464*f0fbc68bSmrg       m_len = strlen (m->name);
465*f0fbc68bSmrg       /* The leading "1 +" is in case we prepend a "C" below.  */
466*f0fbc68bSmrg       buf = (char *) xmalloc (1 + m_len + 1);
467*f0fbc68bSmrg 
468*f0fbc68bSmrg       /* Float complex modes are named SCmode, etc.
469*f0fbc68bSmrg 	 Int complex modes are named CSImode, etc.
470*f0fbc68bSmrg          This inconsistency should be eliminated.  */
471*f0fbc68bSmrg       p = 0;
472*f0fbc68bSmrg       if (cl == MODE_FLOAT)
473*f0fbc68bSmrg 	{
474*f0fbc68bSmrg 	  memcpy (buf, m->name, m_len + 1);
475*f0fbc68bSmrg 	  p = strchr (buf, 'F');
476*f0fbc68bSmrg 	  if (p == 0 && strchr (buf, 'D') == 0)
477*f0fbc68bSmrg 	    {
478*f0fbc68bSmrg 	      error ("%s:%d: float mode \"%s\" has no 'F' or 'D'",
479*f0fbc68bSmrg 		     m->file, m->line, m->name);
480*f0fbc68bSmrg 	      free (buf);
481*f0fbc68bSmrg 	      continue;
482*f0fbc68bSmrg 	    }
483*f0fbc68bSmrg 	}
484*f0fbc68bSmrg       if (p != 0)
485*f0fbc68bSmrg 	*p = 'C';
486*f0fbc68bSmrg       else
487*f0fbc68bSmrg 	{
488*f0fbc68bSmrg 	  buf[0] = 'C';
489*f0fbc68bSmrg 	  memcpy (buf + 1, m->name, m_len + 1);
490*f0fbc68bSmrg 	}
491*f0fbc68bSmrg 
492*f0fbc68bSmrg       c = new_mode (cclass, buf, file, line);
493*f0fbc68bSmrg       c->component = m;
494*f0fbc68bSmrg       m->complex = c;
495*f0fbc68bSmrg     }
496*f0fbc68bSmrg }
497*f0fbc68bSmrg 
498*f0fbc68bSmrg /* For all modes in class CL, construct vector modes of width WIDTH,
499*f0fbc68bSmrg    having as many components as necessary.  ORDER is the sorting order
500*f0fbc68bSmrg    of the mode, with smaller numbers indicating a higher priority.  */
501*f0fbc68bSmrg #define VECTOR_MODES_WITH_PREFIX(PREFIX, C, W, ORDER) \
502*f0fbc68bSmrg   make_vector_modes (MODE_##C, #PREFIX, W, ORDER, __FILE__, __LINE__)
503*f0fbc68bSmrg #define VECTOR_MODES(C, W) VECTOR_MODES_WITH_PREFIX (V, C, W, 0)
504*f0fbc68bSmrg static void ATTRIBUTE_UNUSED
make_vector_modes(enum mode_class cl,const char * prefix,unsigned int width,unsigned int order,const char * file,unsigned int line)505*f0fbc68bSmrg make_vector_modes (enum mode_class cl, const char *prefix, unsigned int width,
506*f0fbc68bSmrg 		   unsigned int order, const char *file, unsigned int line)
507*f0fbc68bSmrg {
508*f0fbc68bSmrg   struct mode_data *m;
509*f0fbc68bSmrg   struct mode_data *v;
510*f0fbc68bSmrg   /* Big enough for a 32-bit UINT_MAX plus the text.  */
511*f0fbc68bSmrg   char buf[12];
512*f0fbc68bSmrg   unsigned int ncomponents;
513*f0fbc68bSmrg   enum mode_class vclass = vector_class (cl);
514*f0fbc68bSmrg 
515*f0fbc68bSmrg   if (vclass == MODE_RANDOM)
516*f0fbc68bSmrg     return;
517*f0fbc68bSmrg 
518*f0fbc68bSmrg   for (m = modes[cl]; m; m = m->next)
519*f0fbc68bSmrg     {
520*f0fbc68bSmrg       /* Do not construct vector modes with only one element, or
521*f0fbc68bSmrg 	 vector modes where the element size doesn't divide the full
522*f0fbc68bSmrg 	 size evenly.  */
523*f0fbc68bSmrg       ncomponents = width / m->bytesize;
524*f0fbc68bSmrg       if (ncomponents < 2)
525*f0fbc68bSmrg 	continue;
526*f0fbc68bSmrg       if (width % m->bytesize)
527*f0fbc68bSmrg 	continue;
528*f0fbc68bSmrg 
529*f0fbc68bSmrg       /* Skip QFmode and BImode.  FIXME: this special case should
530*f0fbc68bSmrg 	 not be necessary.  */
531*f0fbc68bSmrg       if (cl == MODE_FLOAT && m->bytesize == 1)
532*f0fbc68bSmrg 	continue;
533*f0fbc68bSmrg       if (m->boolean)
534*f0fbc68bSmrg 	continue;
535*f0fbc68bSmrg 
536*f0fbc68bSmrg       if ((size_t) snprintf (buf, sizeof buf, "%s%u%s", prefix,
537*f0fbc68bSmrg 			     ncomponents, m->name) >= sizeof buf)
538*f0fbc68bSmrg 	{
539*f0fbc68bSmrg 	  error ("%s:%d: mode name \"%s\" is too long",
540*f0fbc68bSmrg 		 m->file, m->line, m->name);
541*f0fbc68bSmrg 	  continue;
542*f0fbc68bSmrg 	}
543*f0fbc68bSmrg 
544*f0fbc68bSmrg       v = new_mode (vclass, xstrdup (buf), file, line);
545*f0fbc68bSmrg       v->order = order;
546*f0fbc68bSmrg       v->component = m;
547*f0fbc68bSmrg       v->ncomponents = ncomponents;
548*f0fbc68bSmrg     }
549*f0fbc68bSmrg }
550*f0fbc68bSmrg 
551*f0fbc68bSmrg /* Create a vector of booleans called NAME with COUNT elements and
552*f0fbc68bSmrg    BYTESIZE bytes in total.  */
553*f0fbc68bSmrg #define VECTOR_BOOL_MODE(NAME, COUNT, COMPONENT, BYTESIZE)		\
554*f0fbc68bSmrg   make_vector_bool_mode (#NAME, COUNT, #COMPONENT, BYTESIZE,		\
555*f0fbc68bSmrg 			 __FILE__, __LINE__)
556*f0fbc68bSmrg static void ATTRIBUTE_UNUSED
make_vector_bool_mode(const char * name,unsigned int count,const char * component,unsigned int bytesize,const char * file,unsigned int line)557*f0fbc68bSmrg make_vector_bool_mode (const char *name, unsigned int count,
558*f0fbc68bSmrg 		       const char *component, unsigned int bytesize,
559*f0fbc68bSmrg 		       const char *file, unsigned int line)
560*f0fbc68bSmrg {
561*f0fbc68bSmrg   struct mode_data *m = find_mode (component);
562*f0fbc68bSmrg   if (!m)
563*f0fbc68bSmrg     {
564*f0fbc68bSmrg       error ("%s:%d: no mode \"%s\"", file, line, component);
565*f0fbc68bSmrg       return;
566*f0fbc68bSmrg     }
567*f0fbc68bSmrg 
568*f0fbc68bSmrg   struct mode_data *v = new_mode (MODE_VECTOR_BOOL, name, file, line);
569*f0fbc68bSmrg   v->component = m;
570*f0fbc68bSmrg   v->ncomponents = count;
571*f0fbc68bSmrg   v->bytesize = bytesize;
572*f0fbc68bSmrg }
573*f0fbc68bSmrg 
574*f0fbc68bSmrg /* Input.  */
575*f0fbc68bSmrg 
576*f0fbc68bSmrg #define _SPECIAL_MODE(C, N) \
577*f0fbc68bSmrg   make_special_mode (MODE_##C, #N, __FILE__, __LINE__)
578*f0fbc68bSmrg #define RANDOM_MODE(N) _SPECIAL_MODE (RANDOM, N)
579*f0fbc68bSmrg #define CC_MODE(N) _SPECIAL_MODE (CC, N)
580*f0fbc68bSmrg 
581*f0fbc68bSmrg static void
make_special_mode(enum mode_class cl,const char * name,const char * file,unsigned int line)582*f0fbc68bSmrg make_special_mode (enum mode_class cl, const char *name,
583*f0fbc68bSmrg 		   const char *file, unsigned int line)
584*f0fbc68bSmrg {
585*f0fbc68bSmrg   new_mode (cl, name, file, line);
586*f0fbc68bSmrg }
587*f0fbc68bSmrg 
588*f0fbc68bSmrg #define INT_MODE(N, Y) FRACTIONAL_INT_MODE (N, -1U, Y)
589*f0fbc68bSmrg #define FRACTIONAL_INT_MODE(N, B, Y) \
590*f0fbc68bSmrg   make_int_mode (#N, B, Y, __FILE__, __LINE__)
591*f0fbc68bSmrg 
592*f0fbc68bSmrg static void
make_int_mode(const char * name,unsigned int precision,unsigned int bytesize,const char * file,unsigned int line)593*f0fbc68bSmrg make_int_mode (const char *name,
594*f0fbc68bSmrg 	       unsigned int precision, unsigned int bytesize,
595*f0fbc68bSmrg 	       const char *file, unsigned int line)
596*f0fbc68bSmrg {
597*f0fbc68bSmrg   struct mode_data *m = new_mode (MODE_INT, name, file, line);
598*f0fbc68bSmrg   m->bytesize = bytesize;
599*f0fbc68bSmrg   m->precision = precision;
600*f0fbc68bSmrg }
601*f0fbc68bSmrg 
602*f0fbc68bSmrg #define BOOL_MODE(N, B, Y) \
603*f0fbc68bSmrg   make_bool_mode (#N, B, Y, __FILE__, __LINE__)
604*f0fbc68bSmrg 
605*f0fbc68bSmrg static void
make_bool_mode(const char * name,unsigned int precision,unsigned int bytesize,const char * file,unsigned int line)606*f0fbc68bSmrg make_bool_mode (const char *name,
607*f0fbc68bSmrg 		unsigned int precision, unsigned int bytesize,
608*f0fbc68bSmrg 		const char *file, unsigned int line)
609*f0fbc68bSmrg {
610*f0fbc68bSmrg   struct mode_data *m = new_mode (MODE_INT, name, file, line);
611*f0fbc68bSmrg   m->bytesize = bytesize;
612*f0fbc68bSmrg   m->precision = precision;
613*f0fbc68bSmrg   m->boolean = true;
614*f0fbc68bSmrg }
615*f0fbc68bSmrg 
616*f0fbc68bSmrg #define OPAQUE_MODE(N, B)			\
617*f0fbc68bSmrg   make_opaque_mode (#N, -1U, B, __FILE__, __LINE__)
618*f0fbc68bSmrg 
619*f0fbc68bSmrg static void ATTRIBUTE_UNUSED
make_opaque_mode(const char * name,unsigned int precision,unsigned int bytesize,const char * file,unsigned int line)620*f0fbc68bSmrg make_opaque_mode (const char *name,
621*f0fbc68bSmrg 		  unsigned int precision,
622*f0fbc68bSmrg 		  unsigned int bytesize,
623*f0fbc68bSmrg 		  const char *file, unsigned int line)
624*f0fbc68bSmrg {
625*f0fbc68bSmrg   struct mode_data *m = new_mode (MODE_OPAQUE, name, file, line);
626*f0fbc68bSmrg   m->bytesize = bytesize;
627*f0fbc68bSmrg   m->precision = precision;
628*f0fbc68bSmrg }
629*f0fbc68bSmrg 
630*f0fbc68bSmrg #define FRACT_MODE(N, Y, F) \
631*f0fbc68bSmrg 	make_fixed_point_mode (MODE_FRACT, #N, Y, 0, F, __FILE__, __LINE__)
632*f0fbc68bSmrg 
633*f0fbc68bSmrg #define UFRACT_MODE(N, Y, F) \
634*f0fbc68bSmrg 	make_fixed_point_mode (MODE_UFRACT, #N, Y, 0, F, __FILE__, __LINE__)
635*f0fbc68bSmrg 
636*f0fbc68bSmrg #define ACCUM_MODE(N, Y, I, F) \
637*f0fbc68bSmrg 	make_fixed_point_mode (MODE_ACCUM, #N, Y, I, F, __FILE__, __LINE__)
638*f0fbc68bSmrg 
639*f0fbc68bSmrg #define UACCUM_MODE(N, Y, I, F) \
640*f0fbc68bSmrg 	make_fixed_point_mode (MODE_UACCUM, #N, Y, I, F, __FILE__, __LINE__)
641*f0fbc68bSmrg 
642*f0fbc68bSmrg /* Create a fixed-point mode by setting CL, NAME, BYTESIZE, IBIT, FBIT,
643*f0fbc68bSmrg    FILE, and LINE.  */
644*f0fbc68bSmrg 
645*f0fbc68bSmrg static void
make_fixed_point_mode(enum mode_class cl,const char * name,unsigned int bytesize,unsigned int ibit,unsigned int fbit,const char * file,unsigned int line)646*f0fbc68bSmrg make_fixed_point_mode (enum mode_class cl,
647*f0fbc68bSmrg 		       const char *name,
648*f0fbc68bSmrg 		       unsigned int bytesize,
649*f0fbc68bSmrg 		       unsigned int ibit,
650*f0fbc68bSmrg 		       unsigned int fbit,
651*f0fbc68bSmrg 		       const char *file, unsigned int line)
652*f0fbc68bSmrg {
653*f0fbc68bSmrg   struct mode_data *m = new_mode (cl, name, file, line);
654*f0fbc68bSmrg   m->bytesize = bytesize;
655*f0fbc68bSmrg   m->ibit = ibit;
656*f0fbc68bSmrg   m->fbit = fbit;
657*f0fbc68bSmrg }
658*f0fbc68bSmrg 
659*f0fbc68bSmrg #define FLOAT_MODE(N, Y, F)             FRACTIONAL_FLOAT_MODE (N, -1U, Y, F)
660*f0fbc68bSmrg #define FRACTIONAL_FLOAT_MODE(N, B, Y, F) \
661*f0fbc68bSmrg   make_float_mode (#N, B, Y, #F, __FILE__, __LINE__)
662*f0fbc68bSmrg 
663*f0fbc68bSmrg static void
make_float_mode(const char * name,unsigned int precision,unsigned int bytesize,const char * format,const char * file,unsigned int line)664*f0fbc68bSmrg make_float_mode (const char *name,
665*f0fbc68bSmrg 		 unsigned int precision, unsigned int bytesize,
666*f0fbc68bSmrg 		 const char *format,
667*f0fbc68bSmrg 		 const char *file, unsigned int line)
668*f0fbc68bSmrg {
669*f0fbc68bSmrg   struct mode_data *m = new_mode (MODE_FLOAT, name, file, line);
670*f0fbc68bSmrg   m->bytesize = bytesize;
671*f0fbc68bSmrg   m->precision = precision;
672*f0fbc68bSmrg   m->format = format;
673*f0fbc68bSmrg }
674*f0fbc68bSmrg 
675*f0fbc68bSmrg #define DECIMAL_FLOAT_MODE(N, Y, F)	\
676*f0fbc68bSmrg 	FRACTIONAL_DECIMAL_FLOAT_MODE (N, -1U, Y, F)
677*f0fbc68bSmrg #define FRACTIONAL_DECIMAL_FLOAT_MODE(N, B, Y, F)	\
678*f0fbc68bSmrg   make_decimal_float_mode (#N, B, Y, #F, __FILE__, __LINE__)
679*f0fbc68bSmrg 
680*f0fbc68bSmrg static void
make_decimal_float_mode(const char * name,unsigned int precision,unsigned int bytesize,const char * format,const char * file,unsigned int line)681*f0fbc68bSmrg make_decimal_float_mode (const char *name,
682*f0fbc68bSmrg 			 unsigned int precision, unsigned int bytesize,
683*f0fbc68bSmrg 			 const char *format,
684*f0fbc68bSmrg 			 const char *file, unsigned int line)
685*f0fbc68bSmrg {
686*f0fbc68bSmrg   struct mode_data *m = new_mode (MODE_DECIMAL_FLOAT, name, file, line);
687*f0fbc68bSmrg   m->bytesize = bytesize;
688*f0fbc68bSmrg   m->precision = precision;
689*f0fbc68bSmrg   m->format = format;
690*f0fbc68bSmrg }
691*f0fbc68bSmrg 
692*f0fbc68bSmrg #define RESET_FLOAT_FORMAT(N, F) \
693*f0fbc68bSmrg   reset_float_format (#N, #F, __FILE__, __LINE__)
694*f0fbc68bSmrg static void ATTRIBUTE_UNUSED
reset_float_format(const char * name,const char * format,const char * file,unsigned int line)695*f0fbc68bSmrg reset_float_format (const char *name, const char *format,
696*f0fbc68bSmrg 		    const char *file, unsigned int line)
697*f0fbc68bSmrg {
698*f0fbc68bSmrg   struct mode_data *m = find_mode (name);
699*f0fbc68bSmrg   if (!m)
700*f0fbc68bSmrg     {
701*f0fbc68bSmrg       error ("%s:%d: no mode \"%s\"", file, line, name);
702*f0fbc68bSmrg       return;
703*f0fbc68bSmrg     }
704*f0fbc68bSmrg   if (m->cl != MODE_FLOAT && m->cl != MODE_DECIMAL_FLOAT)
705*f0fbc68bSmrg     {
706*f0fbc68bSmrg       error ("%s:%d: mode \"%s\" is not a FLOAT class", file, line, name);
707*f0fbc68bSmrg       return;
708*f0fbc68bSmrg     }
709*f0fbc68bSmrg   m->format = format;
710*f0fbc68bSmrg }
711*f0fbc68bSmrg 
712*f0fbc68bSmrg /* __intN support.  */
713*f0fbc68bSmrg #define INT_N(M,PREC)				\
714*f0fbc68bSmrg   make_int_n (#M, PREC, __FILE__, __LINE__)
715*f0fbc68bSmrg static void ATTRIBUTE_UNUSED
make_int_n(const char * m,int bitsize,const char * file,unsigned int line)716*f0fbc68bSmrg make_int_n (const char *m, int bitsize,
717*f0fbc68bSmrg             const char *file, unsigned int line)
718*f0fbc68bSmrg {
719*f0fbc68bSmrg   struct mode_data *component = find_mode (m);
720*f0fbc68bSmrg   if (!component)
721*f0fbc68bSmrg     {
722*f0fbc68bSmrg       error ("%s:%d: no mode \"%s\"", file, line, m);
723*f0fbc68bSmrg       return;
724*f0fbc68bSmrg     }
725*f0fbc68bSmrg   if (component->cl != MODE_INT
726*f0fbc68bSmrg       && component->cl != MODE_PARTIAL_INT)
727*f0fbc68bSmrg     {
728*f0fbc68bSmrg       error ("%s:%d: mode \"%s\" is not class INT or PARTIAL_INT", file, line, m);
729*f0fbc68bSmrg       return;
730*f0fbc68bSmrg     }
731*f0fbc68bSmrg   if (component->int_n != 0)
732*f0fbc68bSmrg     {
733*f0fbc68bSmrg       error ("%s:%d: mode \"%s\" already has an intN", file, line, m);
734*f0fbc68bSmrg       return;
735*f0fbc68bSmrg     }
736*f0fbc68bSmrg 
737*f0fbc68bSmrg   component->int_n = bitsize;
738*f0fbc68bSmrg }
739*f0fbc68bSmrg 
740*f0fbc68bSmrg /* Partial integer modes are specified by relation to a full integer
741*f0fbc68bSmrg    mode.  */
742*f0fbc68bSmrg #define PARTIAL_INT_MODE(M,PREC,NAME)				\
743*f0fbc68bSmrg   make_partial_integer_mode (#M, #NAME, PREC, __FILE__, __LINE__)
744*f0fbc68bSmrg static void ATTRIBUTE_UNUSED
make_partial_integer_mode(const char * base,const char * name,unsigned int precision,const char * file,unsigned int line)745*f0fbc68bSmrg make_partial_integer_mode (const char *base, const char *name,
746*f0fbc68bSmrg 			   unsigned int precision,
747*f0fbc68bSmrg 			   const char *file, unsigned int line)
748*f0fbc68bSmrg {
749*f0fbc68bSmrg   struct mode_data *m;
750*f0fbc68bSmrg   struct mode_data *component = find_mode (base);
751*f0fbc68bSmrg   if (!component)
752*f0fbc68bSmrg     {
753*f0fbc68bSmrg       error ("%s:%d: no mode \"%s\"", file, line, name);
754*f0fbc68bSmrg       return;
755*f0fbc68bSmrg     }
756*f0fbc68bSmrg   if (component->cl != MODE_INT)
757*f0fbc68bSmrg     {
758*f0fbc68bSmrg       error ("%s:%d: mode \"%s\" is not class INT", file, line, name);
759*f0fbc68bSmrg       return;
760*f0fbc68bSmrg     }
761*f0fbc68bSmrg 
762*f0fbc68bSmrg   m = new_mode (MODE_PARTIAL_INT, name, file, line);
763*f0fbc68bSmrg   m->precision = precision;
764*f0fbc68bSmrg   m->component = component;
765*f0fbc68bSmrg }
766*f0fbc68bSmrg 
767*f0fbc68bSmrg /* A single vector mode can be specified by naming its component
768*f0fbc68bSmrg    mode and the number of components.  */
769*f0fbc68bSmrg #define VECTOR_MODE_WITH_PREFIX(PREFIX, C, M, N, ORDER) \
770*f0fbc68bSmrg   make_vector_mode (MODE_##C, #PREFIX, #M, N, ORDER, __FILE__, __LINE__);
771*f0fbc68bSmrg #define VECTOR_MODE(C, M, N) VECTOR_MODE_WITH_PREFIX(V, C, M, N, 0);
772*f0fbc68bSmrg static void ATTRIBUTE_UNUSED
make_vector_mode(enum mode_class bclass,const char * prefix,const char * base,unsigned int ncomponents,unsigned int order,const char * file,unsigned int line)773*f0fbc68bSmrg make_vector_mode (enum mode_class bclass,
774*f0fbc68bSmrg 		  const char *prefix,
775*f0fbc68bSmrg 		  const char *base,
776*f0fbc68bSmrg 		  unsigned int ncomponents,
777*f0fbc68bSmrg 		  unsigned int order,
778*f0fbc68bSmrg 		  const char *file, unsigned int line)
779*f0fbc68bSmrg {
780*f0fbc68bSmrg   struct mode_data *v;
781*f0fbc68bSmrg   enum mode_class vclass = vector_class (bclass);
782*f0fbc68bSmrg   struct mode_data *component = find_mode (base);
783*f0fbc68bSmrg   char namebuf[16];
784*f0fbc68bSmrg 
785*f0fbc68bSmrg   if (vclass == MODE_RANDOM)
786*f0fbc68bSmrg     return;
787*f0fbc68bSmrg   if (component == 0)
788*f0fbc68bSmrg     {
789*f0fbc68bSmrg       error ("%s:%d: no mode \"%s\"", file, line, base);
790*f0fbc68bSmrg       return;
791*f0fbc68bSmrg     }
792*f0fbc68bSmrg   if (component->cl != bclass
793*f0fbc68bSmrg       && (component->cl != MODE_PARTIAL_INT
794*f0fbc68bSmrg 	  || bclass != MODE_INT))
795*f0fbc68bSmrg     {
796*f0fbc68bSmrg       error ("%s:%d: mode \"%s\" is not class %s",
797*f0fbc68bSmrg 	     file, line, base, mode_class_names[bclass] + 5);
798*f0fbc68bSmrg       return;
799*f0fbc68bSmrg     }
800*f0fbc68bSmrg 
801*f0fbc68bSmrg   if ((size_t)snprintf (namebuf, sizeof namebuf, "%s%u%s", prefix,
802*f0fbc68bSmrg 			ncomponents, base) >= sizeof namebuf)
803*f0fbc68bSmrg     {
804*f0fbc68bSmrg       error ("%s:%d: mode name \"%s\" is too long",
805*f0fbc68bSmrg 	     file, line, base);
806*f0fbc68bSmrg       return;
807*f0fbc68bSmrg     }
808*f0fbc68bSmrg 
809*f0fbc68bSmrg   v = new_mode (vclass, xstrdup (namebuf), file, line);
810*f0fbc68bSmrg   v->order = order;
811*f0fbc68bSmrg   v->ncomponents = ncomponents;
812*f0fbc68bSmrg   v->component = component;
813*f0fbc68bSmrg }
814*f0fbc68bSmrg 
815*f0fbc68bSmrg /* Adjustability.  */
816*f0fbc68bSmrg #define _ADD_ADJUST(A, M, X, C1, C2) \
817*f0fbc68bSmrg   new_adjust (#M, &adj_##A, #A, #X, MODE_##C1, MODE_##C2, __FILE__, __LINE__)
818*f0fbc68bSmrg 
819*f0fbc68bSmrg #define ADJUST_NUNITS(M, X)    _ADD_ADJUST (nunits, M, X, RANDOM, RANDOM)
820*f0fbc68bSmrg #define ADJUST_BYTESIZE(M, X)  _ADD_ADJUST (bytesize, M, X, RANDOM, RANDOM)
821*f0fbc68bSmrg #define ADJUST_ALIGNMENT(M, X) _ADD_ADJUST (alignment, M, X, RANDOM, RANDOM)
822*f0fbc68bSmrg #define ADJUST_FLOAT_FORMAT(M, X)    _ADD_ADJUST (format, M, X, FLOAT, FLOAT)
823*f0fbc68bSmrg #define ADJUST_IBIT(M, X)  _ADD_ADJUST (ibit, M, X, ACCUM, UACCUM)
824*f0fbc68bSmrg #define ADJUST_FBIT(M, X)  _ADD_ADJUST (fbit, M, X, FRACT, UACCUM)
825*f0fbc68bSmrg 
826*f0fbc68bSmrg static int bits_per_unit;
827*f0fbc68bSmrg static int max_bitsize_mode_any_int;
828*f0fbc68bSmrg static int max_bitsize_mode_any_mode;
829*f0fbc68bSmrg 
830*f0fbc68bSmrg static void
create_modes(void)831*f0fbc68bSmrg create_modes (void)
832*f0fbc68bSmrg {
833*f0fbc68bSmrg #include "machmode.def"
834*f0fbc68bSmrg 
835*f0fbc68bSmrg   /* So put the default value unless the target needs a non standard
836*f0fbc68bSmrg      value. */
837*f0fbc68bSmrg #ifdef BITS_PER_UNIT
838*f0fbc68bSmrg   bits_per_unit = BITS_PER_UNIT;
839*f0fbc68bSmrg #else
840*f0fbc68bSmrg   bits_per_unit = 8;
841*f0fbc68bSmrg #endif
842*f0fbc68bSmrg 
843*f0fbc68bSmrg #ifdef MAX_BITSIZE_MODE_ANY_INT
844*f0fbc68bSmrg   max_bitsize_mode_any_int = MAX_BITSIZE_MODE_ANY_INT;
845*f0fbc68bSmrg #else
846*f0fbc68bSmrg   max_bitsize_mode_any_int = 0;
847*f0fbc68bSmrg #endif
848*f0fbc68bSmrg 
849*f0fbc68bSmrg #ifdef MAX_BITSIZE_MODE_ANY_MODE
850*f0fbc68bSmrg   max_bitsize_mode_any_mode = MAX_BITSIZE_MODE_ANY_MODE;
851*f0fbc68bSmrg #else
852*f0fbc68bSmrg   max_bitsize_mode_any_mode = 0;
853*f0fbc68bSmrg #endif
854*f0fbc68bSmrg }
855*f0fbc68bSmrg 
856*f0fbc68bSmrg #ifndef NUM_POLY_INT_COEFFS
857*f0fbc68bSmrg #define NUM_POLY_INT_COEFFS 1
858*f0fbc68bSmrg #endif
859*f0fbc68bSmrg 
860*f0fbc68bSmrg /* Processing.  */
861*f0fbc68bSmrg 
862*f0fbc68bSmrg /* Sort a list of modes into the order needed for the WIDER field:
863*f0fbc68bSmrg    major sort by precision, minor sort by component precision.
864*f0fbc68bSmrg 
865*f0fbc68bSmrg    For instance:
866*f0fbc68bSmrg      QI < HI < SI < DI < TI
867*f0fbc68bSmrg      V4QI < V2HI < V8QI < V4HI < V2SI.
868*f0fbc68bSmrg 
869*f0fbc68bSmrg    If the precision is not set, sort by the bytesize.  A mode with
870*f0fbc68bSmrg    precision set gets sorted before a mode without precision set, if
871*f0fbc68bSmrg    they have the same bytesize; this is the right thing because
872*f0fbc68bSmrg    the precision must always be smaller than the bytesize * BITS_PER_UNIT.
873*f0fbc68bSmrg    We don't have to do anything special to get this done -- an unset
874*f0fbc68bSmrg    precision shows up as (unsigned int)-1, i.e. UINT_MAX.  */
875*f0fbc68bSmrg static int
cmp_modes(const void * a,const void * b)876*f0fbc68bSmrg cmp_modes (const void *a, const void *b)
877*f0fbc68bSmrg {
878*f0fbc68bSmrg   const struct mode_data *const m = *(const struct mode_data *const*)a;
879*f0fbc68bSmrg   const struct mode_data *const n = *(const struct mode_data *const*)b;
880*f0fbc68bSmrg 
881*f0fbc68bSmrg   if (m->order > n->order)
882*f0fbc68bSmrg     return 1;
883*f0fbc68bSmrg   else if (m->order < n->order)
884*f0fbc68bSmrg     return -1;
885*f0fbc68bSmrg 
886*f0fbc68bSmrg   if (m->bytesize > n->bytesize)
887*f0fbc68bSmrg     return 1;
888*f0fbc68bSmrg   else if (m->bytesize < n->bytesize)
889*f0fbc68bSmrg     return -1;
890*f0fbc68bSmrg 
891*f0fbc68bSmrg   if (m->precision > n->precision)
892*f0fbc68bSmrg     return 1;
893*f0fbc68bSmrg   else if (m->precision < n->precision)
894*f0fbc68bSmrg     return -1;
895*f0fbc68bSmrg 
896*f0fbc68bSmrg   if (!m->component && !n->component)
897*f0fbc68bSmrg     {
898*f0fbc68bSmrg       if (m->counter < n->counter)
899*f0fbc68bSmrg 	return -1;
900*f0fbc68bSmrg       else
901*f0fbc68bSmrg 	return 1;
902*f0fbc68bSmrg     }
903*f0fbc68bSmrg 
904*f0fbc68bSmrg   if (m->component->bytesize > n->component->bytesize)
905*f0fbc68bSmrg     return 1;
906*f0fbc68bSmrg   else if (m->component->bytesize < n->component->bytesize)
907*f0fbc68bSmrg     return -1;
908*f0fbc68bSmrg 
909*f0fbc68bSmrg   if (m->component->precision > n->component->precision)
910*f0fbc68bSmrg     return 1;
911*f0fbc68bSmrg   else if (m->component->precision < n->component->precision)
912*f0fbc68bSmrg     return -1;
913*f0fbc68bSmrg 
914*f0fbc68bSmrg   if (m->counter < n->counter)
915*f0fbc68bSmrg     return -1;
916*f0fbc68bSmrg   else
917*f0fbc68bSmrg     return 1;
918*f0fbc68bSmrg }
919*f0fbc68bSmrg 
920*f0fbc68bSmrg static void
calc_wider_mode(void)921*f0fbc68bSmrg calc_wider_mode (void)
922*f0fbc68bSmrg {
923*f0fbc68bSmrg   int c;
924*f0fbc68bSmrg   struct mode_data *m;
925*f0fbc68bSmrg   struct mode_data **sortbuf;
926*f0fbc68bSmrg   unsigned int max_n_modes = 0;
927*f0fbc68bSmrg   unsigned int i, j;
928*f0fbc68bSmrg 
929*f0fbc68bSmrg   for (c = 0; c < MAX_MODE_CLASS; c++)
930*f0fbc68bSmrg     max_n_modes = MAX (max_n_modes, n_modes[c]);
931*f0fbc68bSmrg 
932*f0fbc68bSmrg   /* Allocate max_n_modes + 1 entries to leave room for the extra null
933*f0fbc68bSmrg      pointer assigned after the qsort call below.  */
934*f0fbc68bSmrg   sortbuf = XALLOCAVEC (struct mode_data *, max_n_modes + 1);
935*f0fbc68bSmrg 
936*f0fbc68bSmrg   for (c = 0; c < MAX_MODE_CLASS; c++)
937*f0fbc68bSmrg     {
938*f0fbc68bSmrg       /* "wider" is not meaningful for MODE_RANDOM and MODE_CC.
939*f0fbc68bSmrg 	 However, we want these in textual order, and we have
940*f0fbc68bSmrg 	 precisely the reverse.  */
941*f0fbc68bSmrg       if (c == MODE_RANDOM || c == MODE_CC)
942*f0fbc68bSmrg 	{
943*f0fbc68bSmrg 	  struct mode_data *prev, *next;
944*f0fbc68bSmrg 
945*f0fbc68bSmrg 	  for (prev = 0, m = modes[c]; m; m = next)
946*f0fbc68bSmrg 	    {
947*f0fbc68bSmrg 	      m->wider = void_mode;
948*f0fbc68bSmrg 
949*f0fbc68bSmrg 	      /* this is nreverse */
950*f0fbc68bSmrg 	      next = m->next;
951*f0fbc68bSmrg 	      m->next = prev;
952*f0fbc68bSmrg 	      prev = m;
953*f0fbc68bSmrg 	    }
954*f0fbc68bSmrg 	  modes[c] = prev;
955*f0fbc68bSmrg 	}
956*f0fbc68bSmrg       else
957*f0fbc68bSmrg 	{
958*f0fbc68bSmrg 	  if (!modes[c])
959*f0fbc68bSmrg 	    continue;
960*f0fbc68bSmrg 
961*f0fbc68bSmrg 	  for (i = 0, m = modes[c]; m; i++, m = m->next)
962*f0fbc68bSmrg 	    sortbuf[i] = m;
963*f0fbc68bSmrg 
964*f0fbc68bSmrg 	  (qsort) (sortbuf, i, sizeof (struct mode_data *), cmp_modes);
965*f0fbc68bSmrg 
966*f0fbc68bSmrg 	  sortbuf[i] = 0;
967*f0fbc68bSmrg 	  for (j = 0; j < i; j++)
968*f0fbc68bSmrg 	    {
969*f0fbc68bSmrg 	      sortbuf[j]->next = sortbuf[j + 1];
970*f0fbc68bSmrg 	      if (c == MODE_PARTIAL_INT)
971*f0fbc68bSmrg 		sortbuf[j]->wider = sortbuf[j]->component;
972*f0fbc68bSmrg 	      else
973*f0fbc68bSmrg 		sortbuf[j]->wider = sortbuf[j]->next;
974*f0fbc68bSmrg 	    }
975*f0fbc68bSmrg 
976*f0fbc68bSmrg 	  modes[c] = sortbuf[0];
977*f0fbc68bSmrg 	}
978*f0fbc68bSmrg     }
979*f0fbc68bSmrg }
980*f0fbc68bSmrg 
981*f0fbc68bSmrg /* Text to add to the constant part of a poly_int_pod initializer in
982*f0fbc68bSmrg    order to fill out te whole structure.  */
983*f0fbc68bSmrg #if NUM_POLY_INT_COEFFS == 1
984*f0fbc68bSmrg #define ZERO_COEFFS ""
985*f0fbc68bSmrg #elif NUM_POLY_INT_COEFFS == 2
986*f0fbc68bSmrg #define ZERO_COEFFS ", 0"
987*f0fbc68bSmrg #else
988*f0fbc68bSmrg #error "Unknown value of NUM_POLY_INT_COEFFS"
989*f0fbc68bSmrg #endif
990*f0fbc68bSmrg 
991*f0fbc68bSmrg /* Output routines.  */
992*f0fbc68bSmrg 
993*f0fbc68bSmrg #define tagged_printf(FMT, ARG, TAG) do {		\
994*f0fbc68bSmrg   int count_ = printf ("  " FMT ",", ARG);		\
995*f0fbc68bSmrg   printf ("%*s/* %s */\n", 27 - count_, "", TAG);	\
996*f0fbc68bSmrg } while (0)
997*f0fbc68bSmrg 
998*f0fbc68bSmrg #define print_decl(TYPE, NAME, ASIZE) \
999*f0fbc68bSmrg   puts ("\nconst " TYPE " " NAME "[" ASIZE "] =\n{");
1000*f0fbc68bSmrg 
1001*f0fbc68bSmrg #define print_maybe_const_decl(TYPE, NAME, ASIZE, NEEDS_ADJ)	\
1002*f0fbc68bSmrg   printf ("\n" TYPE " " NAME "[" ASIZE "] = \n{\n",		\
1003*f0fbc68bSmrg 	  NEEDS_ADJ ? "" : "const ")
1004*f0fbc68bSmrg 
1005*f0fbc68bSmrg #define print_closer() puts ("};")
1006*f0fbc68bSmrg 
1007*f0fbc68bSmrg /* Compute the max bitsize of some of the classes of integers.  It may
1008*f0fbc68bSmrg    be that there are needs for the other integer classes, and this
1009*f0fbc68bSmrg    code is easy to extend.  */
1010*f0fbc68bSmrg static void
emit_max_int(void)1011*f0fbc68bSmrg emit_max_int (void)
1012*f0fbc68bSmrg {
1013*f0fbc68bSmrg   unsigned int max, mmax;
1014*f0fbc68bSmrg   struct mode_data *i;
1015*f0fbc68bSmrg   int j;
1016*f0fbc68bSmrg 
1017*f0fbc68bSmrg   puts ("");
1018*f0fbc68bSmrg 
1019*f0fbc68bSmrg   printf ("#define BITS_PER_UNIT (%d)\n", bits_per_unit);
1020*f0fbc68bSmrg 
1021*f0fbc68bSmrg   if (max_bitsize_mode_any_int == 0)
1022*f0fbc68bSmrg     {
1023*f0fbc68bSmrg       for (max = 1, i = modes[MODE_INT]; i; i = i->next)
1024*f0fbc68bSmrg 	if (max < i->bytesize)
1025*f0fbc68bSmrg 	  max = i->bytesize;
1026*f0fbc68bSmrg       mmax = max;
1027*f0fbc68bSmrg       for (max = 1, i = modes[MODE_PARTIAL_INT]; i; i = i->next)
1028*f0fbc68bSmrg 	if (max < i->bytesize)
1029*f0fbc68bSmrg 	  max = i->bytesize;
1030*f0fbc68bSmrg       if (max > mmax)
1031*f0fbc68bSmrg 	mmax = max;
1032*f0fbc68bSmrg       printf ("#define MAX_BITSIZE_MODE_ANY_INT (%d*BITS_PER_UNIT)\n", mmax);
1033*f0fbc68bSmrg     }
1034*f0fbc68bSmrg   else
1035*f0fbc68bSmrg     printf ("#define MAX_BITSIZE_MODE_ANY_INT %d\n", max_bitsize_mode_any_int);
1036*f0fbc68bSmrg 
1037*f0fbc68bSmrg   if (max_bitsize_mode_any_mode == 0)
1038*f0fbc68bSmrg     {
1039*f0fbc68bSmrg       mmax = 0;
1040*f0fbc68bSmrg       for (j = 0; j < MAX_MODE_CLASS; j++)
1041*f0fbc68bSmrg 	for (i = modes[j]; i; i = i->next)
1042*f0fbc68bSmrg 	  if (mmax < i->bytesize)
1043*f0fbc68bSmrg 	    mmax = i->bytesize;
1044*f0fbc68bSmrg       printf ("#define MAX_BITSIZE_MODE_ANY_MODE (%d*BITS_PER_UNIT)\n", mmax);
1045*f0fbc68bSmrg     }
1046*f0fbc68bSmrg   else
1047*f0fbc68bSmrg     printf ("#define MAX_BITSIZE_MODE_ANY_MODE %d\n",
1048*f0fbc68bSmrg 	    max_bitsize_mode_any_mode);
1049*f0fbc68bSmrg }
1050*f0fbc68bSmrg 
1051*f0fbc68bSmrg /* Emit mode_size_inline routine into insn-modes.h header.  */
1052*f0fbc68bSmrg static void
emit_mode_size_inline(void)1053*f0fbc68bSmrg emit_mode_size_inline (void)
1054*f0fbc68bSmrg {
1055*f0fbc68bSmrg   int c;
1056*f0fbc68bSmrg   struct mode_adjust *a;
1057*f0fbc68bSmrg   struct mode_data *m;
1058*f0fbc68bSmrg 
1059*f0fbc68bSmrg   /* Size adjustments must be propagated to all containing modes.  */
1060*f0fbc68bSmrg   for (a = adj_bytesize; a; a = a->next)
1061*f0fbc68bSmrg     {
1062*f0fbc68bSmrg       a->mode->need_bytesize_adj = true;
1063*f0fbc68bSmrg       for (m = a->mode->contained; m; m = m->next_cont)
1064*f0fbc68bSmrg 	m->need_bytesize_adj = true;
1065*f0fbc68bSmrg     }
1066*f0fbc68bSmrg 
1067*f0fbc68bSmrg   /* Changing the number of units by a factor of X also changes the size
1068*f0fbc68bSmrg      by a factor of X.  */
1069*f0fbc68bSmrg   for (mode_adjust *a = adj_nunits; a; a = a->next)
1070*f0fbc68bSmrg     a->mode->need_bytesize_adj = true;
1071*f0fbc68bSmrg 
1072*f0fbc68bSmrg   printf ("\
1073*f0fbc68bSmrg #ifdef __cplusplus\n\
1074*f0fbc68bSmrg inline __attribute__((__always_inline__))\n\
1075*f0fbc68bSmrg #else\n\
1076*f0fbc68bSmrg extern __inline__ __attribute__((__always_inline__, __gnu_inline__))\n\
1077*f0fbc68bSmrg #endif\n\
1078*f0fbc68bSmrg poly_uint16\n\
1079*f0fbc68bSmrg mode_size_inline (machine_mode mode)\n\
1080*f0fbc68bSmrg {\n\
1081*f0fbc68bSmrg   extern %spoly_uint16_pod mode_size[NUM_MACHINE_MODES];\n\
1082*f0fbc68bSmrg   gcc_assert (mode >= 0 && mode < NUM_MACHINE_MODES);\n\
1083*f0fbc68bSmrg   switch (mode)\n\
1084*f0fbc68bSmrg     {\n", adj_nunits || adj_bytesize ? "" : "const ");
1085*f0fbc68bSmrg 
1086*f0fbc68bSmrg   for_all_modes (c, m)
1087*f0fbc68bSmrg     if (!m->need_bytesize_adj)
1088*f0fbc68bSmrg       printf ("    case E_%smode: return %u;\n", m->name, m->bytesize);
1089*f0fbc68bSmrg 
1090*f0fbc68bSmrg   puts ("\
1091*f0fbc68bSmrg     default: return mode_size[mode];\n\
1092*f0fbc68bSmrg     }\n\
1093*f0fbc68bSmrg }\n");
1094*f0fbc68bSmrg }
1095*f0fbc68bSmrg 
1096*f0fbc68bSmrg /* Emit mode_nunits_inline routine into insn-modes.h header.  */
1097*f0fbc68bSmrg static void
emit_mode_nunits_inline(void)1098*f0fbc68bSmrg emit_mode_nunits_inline (void)
1099*f0fbc68bSmrg {
1100*f0fbc68bSmrg   int c;
1101*f0fbc68bSmrg   struct mode_data *m;
1102*f0fbc68bSmrg 
1103*f0fbc68bSmrg   for (mode_adjust *a = adj_nunits; a; a = a->next)
1104*f0fbc68bSmrg     a->mode->need_nunits_adj = true;
1105*f0fbc68bSmrg 
1106*f0fbc68bSmrg   printf ("\
1107*f0fbc68bSmrg #ifdef __cplusplus\n\
1108*f0fbc68bSmrg inline __attribute__((__always_inline__))\n\
1109*f0fbc68bSmrg #else\n\
1110*f0fbc68bSmrg extern __inline__ __attribute__((__always_inline__, __gnu_inline__))\n\
1111*f0fbc68bSmrg #endif\n\
1112*f0fbc68bSmrg poly_uint16\n\
1113*f0fbc68bSmrg mode_nunits_inline (machine_mode mode)\n\
1114*f0fbc68bSmrg {\n\
1115*f0fbc68bSmrg   extern %spoly_uint16_pod mode_nunits[NUM_MACHINE_MODES];\n\
1116*f0fbc68bSmrg   switch (mode)\n\
1117*f0fbc68bSmrg     {\n", adj_nunits ? "" : "const ");
1118*f0fbc68bSmrg 
1119*f0fbc68bSmrg   for_all_modes (c, m)
1120*f0fbc68bSmrg     if (!m->need_nunits_adj)
1121*f0fbc68bSmrg       printf ("    case E_%smode: return %u;\n", m->name, m->ncomponents);
1122*f0fbc68bSmrg 
1123*f0fbc68bSmrg   puts ("\
1124*f0fbc68bSmrg     default: return mode_nunits[mode];\n\
1125*f0fbc68bSmrg     }\n\
1126*f0fbc68bSmrg }\n");
1127*f0fbc68bSmrg }
1128*f0fbc68bSmrg 
1129*f0fbc68bSmrg /* Emit mode_inner_inline routine into insn-modes.h header.  */
1130*f0fbc68bSmrg static void
emit_mode_inner_inline(void)1131*f0fbc68bSmrg emit_mode_inner_inline (void)
1132*f0fbc68bSmrg {
1133*f0fbc68bSmrg   int c;
1134*f0fbc68bSmrg   struct mode_data *m;
1135*f0fbc68bSmrg 
1136*f0fbc68bSmrg   puts ("\
1137*f0fbc68bSmrg #ifdef __cplusplus\n\
1138*f0fbc68bSmrg inline __attribute__((__always_inline__))\n\
1139*f0fbc68bSmrg #else\n\
1140*f0fbc68bSmrg extern __inline__ __attribute__((__always_inline__, __gnu_inline__))\n\
1141*f0fbc68bSmrg #endif\n\
1142*f0fbc68bSmrg unsigned char\n\
1143*f0fbc68bSmrg mode_inner_inline (machine_mode mode)\n\
1144*f0fbc68bSmrg {\n\
1145*f0fbc68bSmrg   extern const unsigned char mode_inner[NUM_MACHINE_MODES];\n\
1146*f0fbc68bSmrg   gcc_assert (mode >= 0 && mode < NUM_MACHINE_MODES);\n\
1147*f0fbc68bSmrg   switch (mode)\n\
1148*f0fbc68bSmrg     {");
1149*f0fbc68bSmrg 
1150*f0fbc68bSmrg   for_all_modes (c, m)
1151*f0fbc68bSmrg     printf ("    case E_%smode: return E_%smode;\n", m->name,
1152*f0fbc68bSmrg 	    c != MODE_PARTIAL_INT && m->component
1153*f0fbc68bSmrg 	    ? m->component->name : m->name);
1154*f0fbc68bSmrg 
1155*f0fbc68bSmrg   puts ("\
1156*f0fbc68bSmrg     default: return mode_inner[mode];\n\
1157*f0fbc68bSmrg     }\n\
1158*f0fbc68bSmrg }\n");
1159*f0fbc68bSmrg }
1160*f0fbc68bSmrg 
1161*f0fbc68bSmrg /* Emit mode_unit_size_inline routine into insn-modes.h header.  */
1162*f0fbc68bSmrg static void
emit_mode_unit_size_inline(void)1163*f0fbc68bSmrg emit_mode_unit_size_inline (void)
1164*f0fbc68bSmrg {
1165*f0fbc68bSmrg   int c;
1166*f0fbc68bSmrg   struct mode_data *m;
1167*f0fbc68bSmrg 
1168*f0fbc68bSmrg   puts ("\
1169*f0fbc68bSmrg #ifdef __cplusplus\n\
1170*f0fbc68bSmrg inline __attribute__((__always_inline__))\n\
1171*f0fbc68bSmrg #else\n\
1172*f0fbc68bSmrg extern __inline__ __attribute__((__always_inline__, __gnu_inline__))\n\
1173*f0fbc68bSmrg #endif\n\
1174*f0fbc68bSmrg unsigned char\n\
1175*f0fbc68bSmrg mode_unit_size_inline (machine_mode mode)\n\
1176*f0fbc68bSmrg {\n\
1177*f0fbc68bSmrg   extern CONST_MODE_UNIT_SIZE unsigned char mode_unit_size[NUM_MACHINE_MODES];\
1178*f0fbc68bSmrg \n\
1179*f0fbc68bSmrg   gcc_assert (mode >= 0 && mode < NUM_MACHINE_MODES);\n\
1180*f0fbc68bSmrg   switch (mode)\n\
1181*f0fbc68bSmrg     {");
1182*f0fbc68bSmrg 
1183*f0fbc68bSmrg   for_all_modes (c, m)
1184*f0fbc68bSmrg     {
1185*f0fbc68bSmrg       const char *name = m->name;
1186*f0fbc68bSmrg       struct mode_data *m2 = m;
1187*f0fbc68bSmrg       if (c != MODE_PARTIAL_INT && m2->component)
1188*f0fbc68bSmrg 	m2 = m2->component;
1189*f0fbc68bSmrg       if (!m2->need_bytesize_adj)
1190*f0fbc68bSmrg 	printf ("    case E_%smode: return %u;\n", name, m2->bytesize);
1191*f0fbc68bSmrg     }
1192*f0fbc68bSmrg 
1193*f0fbc68bSmrg   puts ("\
1194*f0fbc68bSmrg     default: return mode_unit_size[mode];\n\
1195*f0fbc68bSmrg     }\n\
1196*f0fbc68bSmrg }\n");
1197*f0fbc68bSmrg }
1198*f0fbc68bSmrg 
1199*f0fbc68bSmrg /* Emit mode_unit_precision_inline routine into insn-modes.h header.  */
1200*f0fbc68bSmrg static void
emit_mode_unit_precision_inline(void)1201*f0fbc68bSmrg emit_mode_unit_precision_inline (void)
1202*f0fbc68bSmrg {
1203*f0fbc68bSmrg   int c;
1204*f0fbc68bSmrg   struct mode_data *m;
1205*f0fbc68bSmrg 
1206*f0fbc68bSmrg   puts ("\
1207*f0fbc68bSmrg #ifdef __cplusplus\n\
1208*f0fbc68bSmrg inline __attribute__((__always_inline__))\n\
1209*f0fbc68bSmrg #else\n\
1210*f0fbc68bSmrg extern __inline__ __attribute__((__always_inline__, __gnu_inline__))\n\
1211*f0fbc68bSmrg #endif\n\
1212*f0fbc68bSmrg unsigned short\n\
1213*f0fbc68bSmrg mode_unit_precision_inline (machine_mode mode)\n\
1214*f0fbc68bSmrg {\n\
1215*f0fbc68bSmrg   extern const unsigned short mode_unit_precision[NUM_MACHINE_MODES];\n\
1216*f0fbc68bSmrg   gcc_assert (mode >= 0 && mode < NUM_MACHINE_MODES);\n\
1217*f0fbc68bSmrg   switch (mode)\n\
1218*f0fbc68bSmrg     {");
1219*f0fbc68bSmrg 
1220*f0fbc68bSmrg   for_all_modes (c, m)
1221*f0fbc68bSmrg     {
1222*f0fbc68bSmrg       struct mode_data *m2
1223*f0fbc68bSmrg 	= (c != MODE_PARTIAL_INT && m->component) ? m->component : m;
1224*f0fbc68bSmrg       if (m2->precision != (unsigned int)-1)
1225*f0fbc68bSmrg 	printf ("    case E_%smode: return %u;\n", m->name, m2->precision);
1226*f0fbc68bSmrg       else
1227*f0fbc68bSmrg 	printf ("    case E_%smode: return %u*BITS_PER_UNIT;\n",
1228*f0fbc68bSmrg 		m->name, m2->bytesize);
1229*f0fbc68bSmrg     }
1230*f0fbc68bSmrg 
1231*f0fbc68bSmrg   puts ("\
1232*f0fbc68bSmrg     default: return mode_unit_precision[mode];\n\
1233*f0fbc68bSmrg     }\n\
1234*f0fbc68bSmrg }\n");
1235*f0fbc68bSmrg }
1236*f0fbc68bSmrg 
1237*f0fbc68bSmrg /* Return the best machine mode class for MODE, or null if machine_mode
1238*f0fbc68bSmrg    should be used.  */
1239*f0fbc68bSmrg 
1240*f0fbc68bSmrg static const char *
get_mode_class(struct mode_data * mode)1241*f0fbc68bSmrg get_mode_class (struct mode_data *mode)
1242*f0fbc68bSmrg {
1243*f0fbc68bSmrg   switch (mode->cl)
1244*f0fbc68bSmrg     {
1245*f0fbc68bSmrg     case MODE_INT:
1246*f0fbc68bSmrg     case MODE_PARTIAL_INT:
1247*f0fbc68bSmrg       return "scalar_int_mode";
1248*f0fbc68bSmrg 
1249*f0fbc68bSmrg     case MODE_FRACT:
1250*f0fbc68bSmrg     case MODE_UFRACT:
1251*f0fbc68bSmrg     case MODE_ACCUM:
1252*f0fbc68bSmrg     case MODE_UACCUM:
1253*f0fbc68bSmrg       return "scalar_mode";
1254*f0fbc68bSmrg 
1255*f0fbc68bSmrg     case MODE_FLOAT:
1256*f0fbc68bSmrg     case MODE_DECIMAL_FLOAT:
1257*f0fbc68bSmrg       return "scalar_float_mode";
1258*f0fbc68bSmrg 
1259*f0fbc68bSmrg     case MODE_COMPLEX_INT:
1260*f0fbc68bSmrg     case MODE_COMPLEX_FLOAT:
1261*f0fbc68bSmrg       return "complex_mode";
1262*f0fbc68bSmrg 
1263*f0fbc68bSmrg     default:
1264*f0fbc68bSmrg       return NULL;
1265*f0fbc68bSmrg     }
1266*f0fbc68bSmrg }
1267*f0fbc68bSmrg 
1268*f0fbc68bSmrg static void
emit_insn_modes_h(void)1269*f0fbc68bSmrg emit_insn_modes_h (void)
1270*f0fbc68bSmrg {
1271*f0fbc68bSmrg   int c;
1272*f0fbc68bSmrg   struct mode_data *m, *first, *last;
1273*f0fbc68bSmrg   int n_int_n_ents = 0;
1274*f0fbc68bSmrg 
1275*f0fbc68bSmrg   printf ("/* Generated automatically from machmode.def%s%s\n",
1276*f0fbc68bSmrg 	   HAVE_EXTRA_MODES ? " and " : "",
1277*f0fbc68bSmrg 	   EXTRA_MODES_FILE);
1278*f0fbc68bSmrg 
1279*f0fbc68bSmrg   puts ("\
1280*f0fbc68bSmrg    by genmodes.  */\n\
1281*f0fbc68bSmrg \n\
1282*f0fbc68bSmrg #ifndef GCC_INSN_MODES_H\n\
1283*f0fbc68bSmrg #define GCC_INSN_MODES_H\n\
1284*f0fbc68bSmrg \n\
1285*f0fbc68bSmrg enum machine_mode\n{");
1286*f0fbc68bSmrg 
1287*f0fbc68bSmrg   for (c = 0; c < MAX_MODE_CLASS; c++)
1288*f0fbc68bSmrg     for (m = modes[c]; m; m = m->next)
1289*f0fbc68bSmrg       {
1290*f0fbc68bSmrg 	int count_ = printf ("  E_%smode,", m->name);
1291*f0fbc68bSmrg 	printf ("%*s/* %s:%d */\n", 27 - count_, "",
1292*f0fbc68bSmrg 		 trim_filename (m->file), m->line);
1293*f0fbc68bSmrg 	printf ("#define HAVE_%smode\n", m->name);
1294*f0fbc68bSmrg 	printf ("#ifdef USE_ENUM_MODES\n");
1295*f0fbc68bSmrg 	printf ("#define %smode E_%smode\n", m->name, m->name);
1296*f0fbc68bSmrg 	printf ("#else\n");
1297*f0fbc68bSmrg 	if (const char *mode_class = get_mode_class (m))
1298*f0fbc68bSmrg 	  printf ("#define %smode (%s ((%s::from_int) E_%smode))\n",
1299*f0fbc68bSmrg 		  m->name, mode_class, mode_class, m->name);
1300*f0fbc68bSmrg 	else
1301*f0fbc68bSmrg 	  printf ("#define %smode ((void) 0, E_%smode)\n",
1302*f0fbc68bSmrg 		  m->name, m->name);
1303*f0fbc68bSmrg 	printf ("#endif\n");
1304*f0fbc68bSmrg       }
1305*f0fbc68bSmrg 
1306*f0fbc68bSmrg   puts ("  MAX_MACHINE_MODE,\n");
1307*f0fbc68bSmrg 
1308*f0fbc68bSmrg   for (c = 0; c < MAX_MODE_CLASS; c++)
1309*f0fbc68bSmrg     {
1310*f0fbc68bSmrg       first = modes[c];
1311*f0fbc68bSmrg       last = 0;
1312*f0fbc68bSmrg       for (m = first; m; last = m, m = m->next)
1313*f0fbc68bSmrg 	;
1314*f0fbc68bSmrg 
1315*f0fbc68bSmrg       /* Don't use BImode for MIN_MODE_INT, since otherwise the middle
1316*f0fbc68bSmrg 	 end will try to use it for bitfields in structures and the
1317*f0fbc68bSmrg 	 like, which we do not want.  Only the target md file should
1318*f0fbc68bSmrg 	 generate BImode widgets.  Since some targets such as ARM/MVE
1319*f0fbc68bSmrg 	 define boolean modes with multiple bits, handle those too.  */
1320*f0fbc68bSmrg       if (first && first->boolean)
1321*f0fbc68bSmrg 	{
1322*f0fbc68bSmrg 	  struct mode_data *last_bool = first;
1323*f0fbc68bSmrg 	  printf ("  MIN_MODE_BOOL = E_%smode,\n", first->name);
1324*f0fbc68bSmrg 
1325*f0fbc68bSmrg 	  while (first && first->boolean)
1326*f0fbc68bSmrg 	    {
1327*f0fbc68bSmrg 	      last_bool = first;
1328*f0fbc68bSmrg 	      first = first->next;
1329*f0fbc68bSmrg 	    }
1330*f0fbc68bSmrg 
1331*f0fbc68bSmrg 	  printf ("  MAX_MODE_BOOL = E_%smode,\n\n", last_bool->name);
1332*f0fbc68bSmrg 	}
1333*f0fbc68bSmrg 
1334*f0fbc68bSmrg       if (first && last)
1335*f0fbc68bSmrg 	printf ("  MIN_%s = E_%smode,\n  MAX_%s = E_%smode,\n\n",
1336*f0fbc68bSmrg 		 mode_class_names[c], first->name,
1337*f0fbc68bSmrg 		 mode_class_names[c], last->name);
1338*f0fbc68bSmrg       else
1339*f0fbc68bSmrg 	printf ("  MIN_%s = E_%smode,\n  MAX_%s = E_%smode,\n\n",
1340*f0fbc68bSmrg 		 mode_class_names[c], void_mode->name,
1341*f0fbc68bSmrg 		 mode_class_names[c], void_mode->name);
1342*f0fbc68bSmrg     }
1343*f0fbc68bSmrg 
1344*f0fbc68bSmrg   puts ("\
1345*f0fbc68bSmrg   NUM_MACHINE_MODES = MAX_MACHINE_MODE\n\
1346*f0fbc68bSmrg };\n");
1347*f0fbc68bSmrg 
1348*f0fbc68bSmrg   /* Define a NUM_* macro for each mode class, giving the number of modes
1349*f0fbc68bSmrg      in the class.  */
1350*f0fbc68bSmrg   for (c = 0; c < MAX_MODE_CLASS; c++)
1351*f0fbc68bSmrg     {
1352*f0fbc68bSmrg       printf ("#define NUM_%s ", mode_class_names[c]);
1353*f0fbc68bSmrg       if (modes[c])
1354*f0fbc68bSmrg 	printf ("(MAX_%s - MIN_%s + 1)\n", mode_class_names[c],
1355*f0fbc68bSmrg 		mode_class_names[c]);
1356*f0fbc68bSmrg       else
1357*f0fbc68bSmrg 	printf ("0\n");
1358*f0fbc68bSmrg     }
1359*f0fbc68bSmrg   printf ("\n");
1360*f0fbc68bSmrg 
1361*f0fbc68bSmrg   /* I can't think of a better idea, can you?  */
1362*f0fbc68bSmrg   printf ("#define CONST_MODE_NUNITS%s\n", adj_nunits ? "" : " const");
1363*f0fbc68bSmrg   printf ("#define CONST_MODE_PRECISION%s\n", adj_nunits ? "" : " const");
1364*f0fbc68bSmrg   printf ("#define CONST_MODE_SIZE%s\n",
1365*f0fbc68bSmrg 	  adj_bytesize || adj_nunits ? "" : " const");
1366*f0fbc68bSmrg   printf ("#define CONST_MODE_UNIT_SIZE%s\n", adj_bytesize ? "" : " const");
1367*f0fbc68bSmrg   printf ("#define CONST_MODE_BASE_ALIGN%s\n", adj_alignment ? "" : " const");
1368*f0fbc68bSmrg #if 0 /* disabled for backward compatibility, temporary */
1369*f0fbc68bSmrg   printf ("#define CONST_REAL_FORMAT_FOR_MODE%s\n", adj_format ? "" :" const");
1370*f0fbc68bSmrg #endif
1371*f0fbc68bSmrg   printf ("#define CONST_MODE_IBIT%s\n", adj_ibit ? "" : " const");
1372*f0fbc68bSmrg   printf ("#define CONST_MODE_FBIT%s\n", adj_fbit ? "" : " const");
1373*f0fbc68bSmrg   printf ("#define CONST_MODE_MASK%s\n", adj_nunits ? "" : " const");
1374*f0fbc68bSmrg   emit_max_int ();
1375*f0fbc68bSmrg 
1376*f0fbc68bSmrg   for_all_modes (c, m)
1377*f0fbc68bSmrg     if (m->int_n)
1378*f0fbc68bSmrg       n_int_n_ents ++;
1379*f0fbc68bSmrg 
1380*f0fbc68bSmrg   printf ("#define NUM_INT_N_ENTS %d\n", n_int_n_ents);
1381*f0fbc68bSmrg 
1382*f0fbc68bSmrg   printf ("#define NUM_POLY_INT_COEFFS %d\n", NUM_POLY_INT_COEFFS);
1383*f0fbc68bSmrg 
1384*f0fbc68bSmrg   puts ("\
1385*f0fbc68bSmrg \n\
1386*f0fbc68bSmrg #endif /* insn-modes.h */");
1387*f0fbc68bSmrg }
1388*f0fbc68bSmrg 
1389*f0fbc68bSmrg static void
emit_insn_modes_inline_h(void)1390*f0fbc68bSmrg emit_insn_modes_inline_h (void)
1391*f0fbc68bSmrg {
1392*f0fbc68bSmrg   printf ("/* Generated automatically from machmode.def%s%s\n",
1393*f0fbc68bSmrg 	   HAVE_EXTRA_MODES ? " and " : "",
1394*f0fbc68bSmrg 	   EXTRA_MODES_FILE);
1395*f0fbc68bSmrg 
1396*f0fbc68bSmrg   puts ("\
1397*f0fbc68bSmrg    by genmodes.  */\n\
1398*f0fbc68bSmrg \n\
1399*f0fbc68bSmrg #ifndef GCC_INSN_MODES_INLINE_H\n\
1400*f0fbc68bSmrg #define GCC_INSN_MODES_INLINE_H");
1401*f0fbc68bSmrg 
1402*f0fbc68bSmrg   puts ("\n#if !defined (USED_FOR_TARGET) && GCC_VERSION >= 4001\n");
1403*f0fbc68bSmrg   emit_mode_size_inline ();
1404*f0fbc68bSmrg   emit_mode_nunits_inline ();
1405*f0fbc68bSmrg   emit_mode_inner_inline ();
1406*f0fbc68bSmrg   emit_mode_unit_size_inline ();
1407*f0fbc68bSmrg   emit_mode_unit_precision_inline ();
1408*f0fbc68bSmrg   puts ("#endif /* GCC_VERSION >= 4001 */");
1409*f0fbc68bSmrg 
1410*f0fbc68bSmrg   puts ("\
1411*f0fbc68bSmrg \n\
1412*f0fbc68bSmrg #endif /* insn-modes-inline.h */");
1413*f0fbc68bSmrg }
1414*f0fbc68bSmrg 
1415*f0fbc68bSmrg static void
emit_insn_modes_c_header(void)1416*f0fbc68bSmrg emit_insn_modes_c_header (void)
1417*f0fbc68bSmrg {
1418*f0fbc68bSmrg   printf ("/* Generated automatically from machmode.def%s%s\n",
1419*f0fbc68bSmrg 	   HAVE_EXTRA_MODES ? " and " : "",
1420*f0fbc68bSmrg 	   EXTRA_MODES_FILE);
1421*f0fbc68bSmrg 
1422*f0fbc68bSmrg   puts ("\
1423*f0fbc68bSmrg    by genmodes.  */\n\
1424*f0fbc68bSmrg \n\
1425*f0fbc68bSmrg #include \"config.h\"\n\
1426*f0fbc68bSmrg #include \"system.h\"\n\
1427*f0fbc68bSmrg #include \"coretypes.h\"\n\
1428*f0fbc68bSmrg #include \"tm.h\"\n\
1429*f0fbc68bSmrg #include \"real.h\"");
1430*f0fbc68bSmrg }
1431*f0fbc68bSmrg 
1432*f0fbc68bSmrg static void
emit_min_insn_modes_c_header(void)1433*f0fbc68bSmrg emit_min_insn_modes_c_header (void)
1434*f0fbc68bSmrg {
1435*f0fbc68bSmrg   printf ("/* Generated automatically from machmode.def%s%s\n",
1436*f0fbc68bSmrg 	   HAVE_EXTRA_MODES ? " and " : "",
1437*f0fbc68bSmrg 	   EXTRA_MODES_FILE);
1438*f0fbc68bSmrg 
1439*f0fbc68bSmrg   puts ("\
1440*f0fbc68bSmrg    by genmodes.  */\n\
1441*f0fbc68bSmrg \n\
1442*f0fbc68bSmrg #include \"bconfig.h\"\n\
1443*f0fbc68bSmrg #include \"system.h\"\n\
1444*f0fbc68bSmrg #include \"coretypes.h\"");
1445*f0fbc68bSmrg }
1446*f0fbc68bSmrg 
1447*f0fbc68bSmrg static void
emit_mode_name(void)1448*f0fbc68bSmrg emit_mode_name (void)
1449*f0fbc68bSmrg {
1450*f0fbc68bSmrg   int c;
1451*f0fbc68bSmrg   struct mode_data *m;
1452*f0fbc68bSmrg 
1453*f0fbc68bSmrg   print_decl ("char *const", "mode_name", "NUM_MACHINE_MODES");
1454*f0fbc68bSmrg 
1455*f0fbc68bSmrg   for_all_modes (c, m)
1456*f0fbc68bSmrg     printf ("  \"%s\",\n", m->name);
1457*f0fbc68bSmrg 
1458*f0fbc68bSmrg   print_closer ();
1459*f0fbc68bSmrg }
1460*f0fbc68bSmrg 
1461*f0fbc68bSmrg static void
emit_mode_class(void)1462*f0fbc68bSmrg emit_mode_class (void)
1463*f0fbc68bSmrg {
1464*f0fbc68bSmrg   int c;
1465*f0fbc68bSmrg   struct mode_data *m;
1466*f0fbc68bSmrg 
1467*f0fbc68bSmrg   print_decl ("unsigned char", "mode_class", "NUM_MACHINE_MODES");
1468*f0fbc68bSmrg 
1469*f0fbc68bSmrg   for_all_modes (c, m)
1470*f0fbc68bSmrg     tagged_printf ("%s", mode_class_names[m->cl], m->name);
1471*f0fbc68bSmrg 
1472*f0fbc68bSmrg   print_closer ();
1473*f0fbc68bSmrg }
1474*f0fbc68bSmrg 
1475*f0fbc68bSmrg static void
emit_mode_precision(void)1476*f0fbc68bSmrg emit_mode_precision (void)
1477*f0fbc68bSmrg {
1478*f0fbc68bSmrg   int c;
1479*f0fbc68bSmrg   struct mode_data *m;
1480*f0fbc68bSmrg 
1481*f0fbc68bSmrg   print_maybe_const_decl ("%spoly_uint16_pod", "mode_precision",
1482*f0fbc68bSmrg 			  "NUM_MACHINE_MODES", adj_nunits);
1483*f0fbc68bSmrg 
1484*f0fbc68bSmrg   for_all_modes (c, m)
1485*f0fbc68bSmrg     if (m->precision != (unsigned int)-1)
1486*f0fbc68bSmrg       tagged_printf ("{ %u" ZERO_COEFFS " }", m->precision, m->name);
1487*f0fbc68bSmrg     else
1488*f0fbc68bSmrg       tagged_printf ("{ %u * BITS_PER_UNIT" ZERO_COEFFS " }",
1489*f0fbc68bSmrg 		     m->bytesize, m->name);
1490*f0fbc68bSmrg 
1491*f0fbc68bSmrg   print_closer ();
1492*f0fbc68bSmrg }
1493*f0fbc68bSmrg 
1494*f0fbc68bSmrg static void
emit_mode_size(void)1495*f0fbc68bSmrg emit_mode_size (void)
1496*f0fbc68bSmrg {
1497*f0fbc68bSmrg   int c;
1498*f0fbc68bSmrg   struct mode_data *m;
1499*f0fbc68bSmrg 
1500*f0fbc68bSmrg   print_maybe_const_decl ("%spoly_uint16_pod", "mode_size",
1501*f0fbc68bSmrg 			  "NUM_MACHINE_MODES", adj_nunits || adj_bytesize);
1502*f0fbc68bSmrg 
1503*f0fbc68bSmrg   for_all_modes (c, m)
1504*f0fbc68bSmrg     tagged_printf ("{ %u" ZERO_COEFFS " }", m->bytesize, m->name);
1505*f0fbc68bSmrg 
1506*f0fbc68bSmrg   print_closer ();
1507*f0fbc68bSmrg }
1508*f0fbc68bSmrg 
1509*f0fbc68bSmrg static void
emit_mode_nunits(void)1510*f0fbc68bSmrg emit_mode_nunits (void)
1511*f0fbc68bSmrg {
1512*f0fbc68bSmrg   int c;
1513*f0fbc68bSmrg   struct mode_data *m;
1514*f0fbc68bSmrg 
1515*f0fbc68bSmrg   print_maybe_const_decl ("%spoly_uint16_pod", "mode_nunits",
1516*f0fbc68bSmrg 			  "NUM_MACHINE_MODES", adj_nunits);
1517*f0fbc68bSmrg 
1518*f0fbc68bSmrg   for_all_modes (c, m)
1519*f0fbc68bSmrg     tagged_printf ("{ %u" ZERO_COEFFS " }", m->ncomponents, m->name);
1520*f0fbc68bSmrg 
1521*f0fbc68bSmrg   print_closer ();
1522*f0fbc68bSmrg }
1523*f0fbc68bSmrg 
1524*f0fbc68bSmrg static void
emit_mode_wider(void)1525*f0fbc68bSmrg emit_mode_wider (void)
1526*f0fbc68bSmrg {
1527*f0fbc68bSmrg   int c;
1528*f0fbc68bSmrg   struct mode_data *m;
1529*f0fbc68bSmrg 
1530*f0fbc68bSmrg   print_decl ("unsigned char", "mode_wider", "NUM_MACHINE_MODES");
1531*f0fbc68bSmrg 
1532*f0fbc68bSmrg   for_all_modes (c, m)
1533*f0fbc68bSmrg     tagged_printf ("E_%smode",
1534*f0fbc68bSmrg 		   m->wider ? m->wider->name : void_mode->name,
1535*f0fbc68bSmrg 		   m->name);
1536*f0fbc68bSmrg 
1537*f0fbc68bSmrg   print_closer ();
1538*f0fbc68bSmrg   print_decl ("unsigned char", "mode_2xwider", "NUM_MACHINE_MODES");
1539*f0fbc68bSmrg 
1540*f0fbc68bSmrg   for_all_modes (c, m)
1541*f0fbc68bSmrg     {
1542*f0fbc68bSmrg       struct mode_data * m2;
1543*f0fbc68bSmrg 
1544*f0fbc68bSmrg       for (m2 = m;
1545*f0fbc68bSmrg 	   m2 && m2 != void_mode;
1546*f0fbc68bSmrg 	   m2 = m2->wider)
1547*f0fbc68bSmrg 	{
1548*f0fbc68bSmrg 	  if (m2->bytesize < 2 * m->bytesize)
1549*f0fbc68bSmrg 	    continue;
1550*f0fbc68bSmrg 	  if (m->precision != (unsigned int) -1)
1551*f0fbc68bSmrg 	    {
1552*f0fbc68bSmrg 	      if (m2->precision != 2 * m->precision)
1553*f0fbc68bSmrg 		continue;
1554*f0fbc68bSmrg 	    }
1555*f0fbc68bSmrg 	  else
1556*f0fbc68bSmrg 	    {
1557*f0fbc68bSmrg 	      if (m2->precision != (unsigned int) -1)
1558*f0fbc68bSmrg 		continue;
1559*f0fbc68bSmrg 	    }
1560*f0fbc68bSmrg 
1561*f0fbc68bSmrg 	  /* For vectors we want twice the number of components,
1562*f0fbc68bSmrg 	     with the same element type.  */
1563*f0fbc68bSmrg 	  if (m->cl == MODE_VECTOR_BOOL
1564*f0fbc68bSmrg 	      || m->cl == MODE_VECTOR_INT
1565*f0fbc68bSmrg 	      || m->cl == MODE_VECTOR_FLOAT
1566*f0fbc68bSmrg 	      || m->cl == MODE_VECTOR_FRACT
1567*f0fbc68bSmrg 	      || m->cl == MODE_VECTOR_UFRACT
1568*f0fbc68bSmrg 	      || m->cl == MODE_VECTOR_ACCUM
1569*f0fbc68bSmrg 	      || m->cl == MODE_VECTOR_UACCUM)
1570*f0fbc68bSmrg 	    {
1571*f0fbc68bSmrg 	      if (m2->ncomponents != 2 * m->ncomponents)
1572*f0fbc68bSmrg 		continue;
1573*f0fbc68bSmrg 	      if (m->component != m2->component)
1574*f0fbc68bSmrg 		continue;
1575*f0fbc68bSmrg 	    }
1576*f0fbc68bSmrg 
1577*f0fbc68bSmrg 	  break;
1578*f0fbc68bSmrg 	}
1579*f0fbc68bSmrg       if (m2 == void_mode)
1580*f0fbc68bSmrg 	m2 = 0;
1581*f0fbc68bSmrg       tagged_printf ("E_%smode",
1582*f0fbc68bSmrg 		     m2 ? m2->name : void_mode->name,
1583*f0fbc68bSmrg 		     m->name);
1584*f0fbc68bSmrg     }
1585*f0fbc68bSmrg 
1586*f0fbc68bSmrg   print_closer ();
1587*f0fbc68bSmrg }
1588*f0fbc68bSmrg 
1589*f0fbc68bSmrg static void
emit_mode_complex(void)1590*f0fbc68bSmrg emit_mode_complex (void)
1591*f0fbc68bSmrg {
1592*f0fbc68bSmrg   int c;
1593*f0fbc68bSmrg   struct mode_data *m;
1594*f0fbc68bSmrg 
1595*f0fbc68bSmrg   print_decl ("unsigned char", "mode_complex", "NUM_MACHINE_MODES");
1596*f0fbc68bSmrg 
1597*f0fbc68bSmrg   for_all_modes (c, m)
1598*f0fbc68bSmrg     tagged_printf ("E_%smode",
1599*f0fbc68bSmrg 		   m->complex ? m->complex->name : void_mode->name,
1600*f0fbc68bSmrg 		   m->name);
1601*f0fbc68bSmrg 
1602*f0fbc68bSmrg   print_closer ();
1603*f0fbc68bSmrg }
1604*f0fbc68bSmrg 
1605*f0fbc68bSmrg static void
emit_mode_mask(void)1606*f0fbc68bSmrg emit_mode_mask (void)
1607*f0fbc68bSmrg {
1608*f0fbc68bSmrg   int c;
1609*f0fbc68bSmrg   struct mode_data *m;
1610*f0fbc68bSmrg 
1611*f0fbc68bSmrg   print_maybe_const_decl ("%sunsigned HOST_WIDE_INT", "mode_mask_array",
1612*f0fbc68bSmrg 			  "NUM_MACHINE_MODES", adj_nunits);
1613*f0fbc68bSmrg   puts ("\
1614*f0fbc68bSmrg #define MODE_MASK(m)                          \\\n\
1615*f0fbc68bSmrg   ((m) >= HOST_BITS_PER_WIDE_INT)             \\\n\
1616*f0fbc68bSmrg    ? HOST_WIDE_INT_M1U                        \\\n\
1617*f0fbc68bSmrg    : (HOST_WIDE_INT_1U << (m)) - 1\n");
1618*f0fbc68bSmrg 
1619*f0fbc68bSmrg   for_all_modes (c, m)
1620*f0fbc68bSmrg     if (m->precision != (unsigned int)-1)
1621*f0fbc68bSmrg       tagged_printf ("MODE_MASK (%u)", m->precision, m->name);
1622*f0fbc68bSmrg     else
1623*f0fbc68bSmrg       tagged_printf ("MODE_MASK (%u*BITS_PER_UNIT)", m->bytesize, m->name);
1624*f0fbc68bSmrg 
1625*f0fbc68bSmrg   puts ("#undef MODE_MASK");
1626*f0fbc68bSmrg   print_closer ();
1627*f0fbc68bSmrg }
1628*f0fbc68bSmrg 
1629*f0fbc68bSmrg static void
emit_mode_inner(void)1630*f0fbc68bSmrg emit_mode_inner (void)
1631*f0fbc68bSmrg {
1632*f0fbc68bSmrg   int c;
1633*f0fbc68bSmrg   struct mode_data *m;
1634*f0fbc68bSmrg 
1635*f0fbc68bSmrg   print_decl ("unsigned char", "mode_inner", "NUM_MACHINE_MODES");
1636*f0fbc68bSmrg 
1637*f0fbc68bSmrg   for_all_modes (c, m)
1638*f0fbc68bSmrg     tagged_printf ("E_%smode",
1639*f0fbc68bSmrg 		   c != MODE_PARTIAL_INT && m->component
1640*f0fbc68bSmrg 		   ? m->component->name : m->name,
1641*f0fbc68bSmrg 		   m->name);
1642*f0fbc68bSmrg 
1643*f0fbc68bSmrg   print_closer ();
1644*f0fbc68bSmrg }
1645*f0fbc68bSmrg 
1646*f0fbc68bSmrg /* Emit mode_unit_size array into insn-modes.cc file.  */
1647*f0fbc68bSmrg static void
emit_mode_unit_size(void)1648*f0fbc68bSmrg emit_mode_unit_size (void)
1649*f0fbc68bSmrg {
1650*f0fbc68bSmrg   int c;
1651*f0fbc68bSmrg   struct mode_data *m;
1652*f0fbc68bSmrg 
1653*f0fbc68bSmrg   print_maybe_const_decl ("%sunsigned char", "mode_unit_size",
1654*f0fbc68bSmrg 			  "NUM_MACHINE_MODES", adj_bytesize);
1655*f0fbc68bSmrg 
1656*f0fbc68bSmrg   for_all_modes (c, m)
1657*f0fbc68bSmrg     tagged_printf ("%u",
1658*f0fbc68bSmrg 		   c != MODE_PARTIAL_INT && m->component
1659*f0fbc68bSmrg 		   ? m->component->bytesize : m->bytesize, m->name);
1660*f0fbc68bSmrg 
1661*f0fbc68bSmrg   print_closer ();
1662*f0fbc68bSmrg }
1663*f0fbc68bSmrg 
1664*f0fbc68bSmrg /* Emit mode_unit_precision array into insn-modes.cc file.  */
1665*f0fbc68bSmrg static void
emit_mode_unit_precision(void)1666*f0fbc68bSmrg emit_mode_unit_precision (void)
1667*f0fbc68bSmrg {
1668*f0fbc68bSmrg   int c;
1669*f0fbc68bSmrg   struct mode_data *m;
1670*f0fbc68bSmrg 
1671*f0fbc68bSmrg   print_decl ("unsigned short", "mode_unit_precision", "NUM_MACHINE_MODES");
1672*f0fbc68bSmrg 
1673*f0fbc68bSmrg   for_all_modes (c, m)
1674*f0fbc68bSmrg     {
1675*f0fbc68bSmrg       struct mode_data *m2 = (c != MODE_PARTIAL_INT && m->component) ?
1676*f0fbc68bSmrg 			     m->component : m;
1677*f0fbc68bSmrg       if (m2->precision != (unsigned int)-1)
1678*f0fbc68bSmrg 	tagged_printf ("%u", m2->precision, m->name);
1679*f0fbc68bSmrg       else
1680*f0fbc68bSmrg 	tagged_printf ("%u*BITS_PER_UNIT", m2->bytesize, m->name);
1681*f0fbc68bSmrg     }
1682*f0fbc68bSmrg 
1683*f0fbc68bSmrg   print_closer ();
1684*f0fbc68bSmrg }
1685*f0fbc68bSmrg 
1686*f0fbc68bSmrg 
1687*f0fbc68bSmrg static void
emit_mode_base_align(void)1688*f0fbc68bSmrg emit_mode_base_align (void)
1689*f0fbc68bSmrg {
1690*f0fbc68bSmrg   int c;
1691*f0fbc68bSmrg   struct mode_data *m;
1692*f0fbc68bSmrg 
1693*f0fbc68bSmrg   print_maybe_const_decl ("%sunsigned short",
1694*f0fbc68bSmrg 			  "mode_base_align", "NUM_MACHINE_MODES",
1695*f0fbc68bSmrg 			  adj_alignment);
1696*f0fbc68bSmrg 
1697*f0fbc68bSmrg   for_all_modes (c, m)
1698*f0fbc68bSmrg     tagged_printf ("%u", m->alignment, m->name);
1699*f0fbc68bSmrg 
1700*f0fbc68bSmrg   print_closer ();
1701*f0fbc68bSmrg }
1702*f0fbc68bSmrg 
1703*f0fbc68bSmrg static void
emit_class_narrowest_mode(void)1704*f0fbc68bSmrg emit_class_narrowest_mode (void)
1705*f0fbc68bSmrg {
1706*f0fbc68bSmrg   int c;
1707*f0fbc68bSmrg 
1708*f0fbc68bSmrg   print_decl ("unsigned char", "class_narrowest_mode", "MAX_MODE_CLASS");
1709*f0fbc68bSmrg 
1710*f0fbc68bSmrg   for (c = 0; c < MAX_MODE_CLASS; c++)
1711*f0fbc68bSmrg     {
1712*f0fbc68bSmrg       /* Bleah, all this to get the comment right for MIN_MODE_INT.  */
1713*f0fbc68bSmrg       struct mode_data *m = modes[c];
1714*f0fbc68bSmrg       while (m && m->boolean)
1715*f0fbc68bSmrg 	m = m->next;
1716*f0fbc68bSmrg       const char *comment_name = (m ? m : void_mode)->name;
1717*f0fbc68bSmrg 
1718*f0fbc68bSmrg       tagged_printf ("MIN_%s", mode_class_names[c], comment_name);
1719*f0fbc68bSmrg     }
1720*f0fbc68bSmrg 
1721*f0fbc68bSmrg   print_closer ();
1722*f0fbc68bSmrg }
1723*f0fbc68bSmrg 
1724*f0fbc68bSmrg static void
emit_real_format_for_mode(void)1725*f0fbc68bSmrg emit_real_format_for_mode (void)
1726*f0fbc68bSmrg {
1727*f0fbc68bSmrg   struct mode_data *m;
1728*f0fbc68bSmrg 
1729*f0fbc68bSmrg   /* The entities pointed to by this table are constant, whether
1730*f0fbc68bSmrg      or not the table itself is constant.
1731*f0fbc68bSmrg 
1732*f0fbc68bSmrg      For backward compatibility this table is always writable
1733*f0fbc68bSmrg      (several targets modify it in TARGET_OPTION_OVERRIDE).   FIXME:
1734*f0fbc68bSmrg      convert all said targets to use ADJUST_FORMAT instead.  */
1735*f0fbc68bSmrg #if 0
1736*f0fbc68bSmrg   print_maybe_const_decl ("const struct real_format *%s",
1737*f0fbc68bSmrg 			  "real_format_for_mode",
1738*f0fbc68bSmrg 			  "MAX_MODE_FLOAT - MIN_MODE_FLOAT + 1",
1739*f0fbc68bSmrg 			  format);
1740*f0fbc68bSmrg #else
1741*f0fbc68bSmrg   print_decl ("struct real_format *\n", "real_format_for_mode",
1742*f0fbc68bSmrg 	      "MAX_MODE_FLOAT - MIN_MODE_FLOAT + 1 "
1743*f0fbc68bSmrg 	      "+ MAX_MODE_DECIMAL_FLOAT - MIN_MODE_DECIMAL_FLOAT + 1");
1744*f0fbc68bSmrg #endif
1745*f0fbc68bSmrg 
1746*f0fbc68bSmrg   /* The beginning of the table is entries for float modes.  */
1747*f0fbc68bSmrg   for (m = modes[MODE_FLOAT]; m; m = m->next)
1748*f0fbc68bSmrg     if (!strcmp (m->format, "0"))
1749*f0fbc68bSmrg       tagged_printf ("%s", m->format, m->name);
1750*f0fbc68bSmrg     else
1751*f0fbc68bSmrg       tagged_printf ("&%s", m->format, m->name);
1752*f0fbc68bSmrg 
1753*f0fbc68bSmrg   /* The end of the table is entries for decimal float modes.  */
1754*f0fbc68bSmrg   for (m = modes[MODE_DECIMAL_FLOAT]; m; m = m->next)
1755*f0fbc68bSmrg     if (!strcmp (m->format, "0"))
1756*f0fbc68bSmrg       tagged_printf ("%s", m->format, m->name);
1757*f0fbc68bSmrg     else
1758*f0fbc68bSmrg       tagged_printf ("&%s", m->format, m->name);
1759*f0fbc68bSmrg 
1760*f0fbc68bSmrg   print_closer ();
1761*f0fbc68bSmrg }
1762*f0fbc68bSmrg 
1763*f0fbc68bSmrg static void
emit_mode_adjustments(void)1764*f0fbc68bSmrg emit_mode_adjustments (void)
1765*f0fbc68bSmrg {
1766*f0fbc68bSmrg   struct mode_adjust *a;
1767*f0fbc68bSmrg   struct mode_data *m;
1768*f0fbc68bSmrg 
1769*f0fbc68bSmrg   if (adj_nunits)
1770*f0fbc68bSmrg     printf ("\n"
1771*f0fbc68bSmrg 	    "void\n"
1772*f0fbc68bSmrg 	    "adjust_mode_mask (machine_mode mode)\n"
1773*f0fbc68bSmrg 	    "{\n"
1774*f0fbc68bSmrg 	    "  unsigned int precision;\n"
1775*f0fbc68bSmrg 	    "  if (GET_MODE_PRECISION (mode).is_constant (&precision)\n"
1776*f0fbc68bSmrg 	    "      && precision < HOST_BITS_PER_WIDE_INT)\n"
1777*f0fbc68bSmrg 	    "    mode_mask_array[mode] = (HOST_WIDE_INT_1U << precision) - 1;"
1778*f0fbc68bSmrg 	    "\n"
1779*f0fbc68bSmrg 	    "  else\n"
1780*f0fbc68bSmrg 	    "    mode_mask_array[mode] = HOST_WIDE_INT_M1U;\n"
1781*f0fbc68bSmrg 	    "}\n");
1782*f0fbc68bSmrg 
1783*f0fbc68bSmrg   puts ("\
1784*f0fbc68bSmrg \nvoid\
1785*f0fbc68bSmrg \ninit_adjust_machine_modes (void)\
1786*f0fbc68bSmrg \n{\
1787*f0fbc68bSmrg \n  poly_uint16 ps ATTRIBUTE_UNUSED;\n\
1788*f0fbc68bSmrg   size_t s ATTRIBUTE_UNUSED;");
1789*f0fbc68bSmrg 
1790*f0fbc68bSmrg   for (a = adj_nunits; a; a = a->next)
1791*f0fbc68bSmrg     {
1792*f0fbc68bSmrg       m = a->mode;
1793*f0fbc68bSmrg       printf ("\n"
1794*f0fbc68bSmrg 	      "  {\n"
1795*f0fbc68bSmrg 	      "    /* %s:%d */\n  ps = %s;\n",
1796*f0fbc68bSmrg 	      a->file, a->line, a->adjustment);
1797*f0fbc68bSmrg       printf ("    int old_factor = vector_element_size"
1798*f0fbc68bSmrg 	      " (mode_precision[E_%smode], mode_nunits[E_%smode]);\n",
1799*f0fbc68bSmrg 	      m->name, m->name);
1800*f0fbc68bSmrg       printf ("    mode_precision[E_%smode] = ps * old_factor;\n", m->name);
1801*f0fbc68bSmrg       printf ("    mode_size[E_%smode] = exact_div (mode_precision[E_%smode],"
1802*f0fbc68bSmrg 	      " BITS_PER_UNIT);\n", m->name, m->name);
1803*f0fbc68bSmrg       printf ("    mode_nunits[E_%smode] = ps;\n", m->name);
1804*f0fbc68bSmrg       printf ("    adjust_mode_mask (E_%smode);\n", m->name);
1805*f0fbc68bSmrg       printf ("  }\n");
1806*f0fbc68bSmrg     }
1807*f0fbc68bSmrg 
1808*f0fbc68bSmrg   /* Size adjustments must be propagated to all containing modes.
1809*f0fbc68bSmrg      A size adjustment forces us to recalculate the alignment too.  */
1810*f0fbc68bSmrg   for (a = adj_bytesize; a; a = a->next)
1811*f0fbc68bSmrg     {
1812*f0fbc68bSmrg       printf ("\n  /* %s:%d */\n", a->file, a->line);
1813*f0fbc68bSmrg       switch (a->mode->cl)
1814*f0fbc68bSmrg 	{
1815*f0fbc68bSmrg 	case MODE_VECTOR_BOOL:
1816*f0fbc68bSmrg 	case MODE_VECTOR_INT:
1817*f0fbc68bSmrg 	case MODE_VECTOR_FLOAT:
1818*f0fbc68bSmrg 	case MODE_VECTOR_FRACT:
1819*f0fbc68bSmrg 	case MODE_VECTOR_UFRACT:
1820*f0fbc68bSmrg 	case MODE_VECTOR_ACCUM:
1821*f0fbc68bSmrg 	case MODE_VECTOR_UACCUM:
1822*f0fbc68bSmrg 	  printf ("  ps = %s;\n", a->adjustment);
1823*f0fbc68bSmrg 	  printf ("  s = mode_unit_size[E_%smode];\n", a->mode->name);
1824*f0fbc68bSmrg 	  break;
1825*f0fbc68bSmrg 
1826*f0fbc68bSmrg 	default:
1827*f0fbc68bSmrg 	  printf ("  ps = s = %s;\n", a->adjustment);
1828*f0fbc68bSmrg 	  printf ("  mode_unit_size[E_%smode] = s;\n", a->mode->name);
1829*f0fbc68bSmrg 	  break;
1830*f0fbc68bSmrg 	}
1831*f0fbc68bSmrg       printf ("  mode_size[E_%smode] = ps;\n", a->mode->name);
1832*f0fbc68bSmrg       printf ("  mode_base_align[E_%smode] = known_alignment (ps);\n",
1833*f0fbc68bSmrg 	      a->mode->name);
1834*f0fbc68bSmrg 
1835*f0fbc68bSmrg       for (m = a->mode->contained; m; m = m->next_cont)
1836*f0fbc68bSmrg 	{
1837*f0fbc68bSmrg 	  switch (m->cl)
1838*f0fbc68bSmrg 	    {
1839*f0fbc68bSmrg 	    case MODE_COMPLEX_INT:
1840*f0fbc68bSmrg 	    case MODE_COMPLEX_FLOAT:
1841*f0fbc68bSmrg 	      printf ("  mode_size[E_%smode] = 2*s;\n", m->name);
1842*f0fbc68bSmrg 	      printf ("  mode_unit_size[E_%smode] = s;\n", m->name);
1843*f0fbc68bSmrg 	      printf ("  mode_base_align[E_%smode] = s & (~s + 1);\n",
1844*f0fbc68bSmrg 		      m->name);
1845*f0fbc68bSmrg 	      break;
1846*f0fbc68bSmrg 
1847*f0fbc68bSmrg 	    case MODE_VECTOR_BOOL:
1848*f0fbc68bSmrg 	      /* Changes to BImode should not affect vector booleans.  */
1849*f0fbc68bSmrg 	      break;
1850*f0fbc68bSmrg 
1851*f0fbc68bSmrg 	    case MODE_VECTOR_INT:
1852*f0fbc68bSmrg 	    case MODE_VECTOR_FLOAT:
1853*f0fbc68bSmrg 	    case MODE_VECTOR_FRACT:
1854*f0fbc68bSmrg 	    case MODE_VECTOR_UFRACT:
1855*f0fbc68bSmrg 	    case MODE_VECTOR_ACCUM:
1856*f0fbc68bSmrg 	    case MODE_VECTOR_UACCUM:
1857*f0fbc68bSmrg 	      printf ("  mode_size[E_%smode] = %d * ps;\n",
1858*f0fbc68bSmrg 		      m->name, m->ncomponents);
1859*f0fbc68bSmrg 	      printf ("  mode_unit_size[E_%smode] = s;\n", m->name);
1860*f0fbc68bSmrg 	      printf ("  mode_base_align[E_%smode]"
1861*f0fbc68bSmrg 		      " = known_alignment (%d * ps);\n",
1862*f0fbc68bSmrg 		      m->name, m->ncomponents);
1863*f0fbc68bSmrg 	      break;
1864*f0fbc68bSmrg 
1865*f0fbc68bSmrg 	    default:
1866*f0fbc68bSmrg 	      internal_error (
1867*f0fbc68bSmrg 	      "mode %s is neither vector nor complex but contains %s",
1868*f0fbc68bSmrg 	      m->name, a->mode->name);
1869*f0fbc68bSmrg 	      /* NOTREACHED */
1870*f0fbc68bSmrg 	    }
1871*f0fbc68bSmrg 	}
1872*f0fbc68bSmrg     }
1873*f0fbc68bSmrg 
1874*f0fbc68bSmrg   /* Alignment adjustments propagate too.
1875*f0fbc68bSmrg      ??? This may not be the right thing for vector modes.  */
1876*f0fbc68bSmrg   for (a = adj_alignment; a; a = a->next)
1877*f0fbc68bSmrg     {
1878*f0fbc68bSmrg       printf ("\n  /* %s:%d */\n  s = %s;\n",
1879*f0fbc68bSmrg 	      a->file, a->line, a->adjustment);
1880*f0fbc68bSmrg       printf ("  mode_base_align[E_%smode] = s;\n", a->mode->name);
1881*f0fbc68bSmrg 
1882*f0fbc68bSmrg       for (m = a->mode->contained; m; m = m->next_cont)
1883*f0fbc68bSmrg 	{
1884*f0fbc68bSmrg 	  switch (m->cl)
1885*f0fbc68bSmrg 	    {
1886*f0fbc68bSmrg 	    case MODE_COMPLEX_INT:
1887*f0fbc68bSmrg 	    case MODE_COMPLEX_FLOAT:
1888*f0fbc68bSmrg 	      printf ("  mode_base_align[E_%smode] = s;\n", m->name);
1889*f0fbc68bSmrg 	      break;
1890*f0fbc68bSmrg 
1891*f0fbc68bSmrg 	    case MODE_VECTOR_BOOL:
1892*f0fbc68bSmrg 	      /* Changes to BImode should not affect vector booleans.  */
1893*f0fbc68bSmrg 	      break;
1894*f0fbc68bSmrg 
1895*f0fbc68bSmrg 	    case MODE_VECTOR_INT:
1896*f0fbc68bSmrg 	    case MODE_VECTOR_FLOAT:
1897*f0fbc68bSmrg 	    case MODE_VECTOR_FRACT:
1898*f0fbc68bSmrg 	    case MODE_VECTOR_UFRACT:
1899*f0fbc68bSmrg 	    case MODE_VECTOR_ACCUM:
1900*f0fbc68bSmrg 	    case MODE_VECTOR_UACCUM:
1901*f0fbc68bSmrg 	      printf ("  mode_base_align[E_%smode] = %d*s;\n",
1902*f0fbc68bSmrg 		      m->name, m->ncomponents);
1903*f0fbc68bSmrg 	      break;
1904*f0fbc68bSmrg 
1905*f0fbc68bSmrg 	    default:
1906*f0fbc68bSmrg 	      internal_error (
1907*f0fbc68bSmrg 	      "mode %s is neither vector nor complex but contains %s",
1908*f0fbc68bSmrg 	      m->name, a->mode->name);
1909*f0fbc68bSmrg 	      /* NOTREACHED */
1910*f0fbc68bSmrg 	    }
1911*f0fbc68bSmrg 	}
1912*f0fbc68bSmrg     }
1913*f0fbc68bSmrg 
1914*f0fbc68bSmrg   /* Ibit adjustments don't have to propagate.  */
1915*f0fbc68bSmrg   for (a = adj_ibit; a; a = a->next)
1916*f0fbc68bSmrg     {
1917*f0fbc68bSmrg       printf ("\n  /* %s:%d */\n  s = %s;\n",
1918*f0fbc68bSmrg 	      a->file, a->line, a->adjustment);
1919*f0fbc68bSmrg       printf ("  mode_ibit[E_%smode] = s;\n", a->mode->name);
1920*f0fbc68bSmrg     }
1921*f0fbc68bSmrg 
1922*f0fbc68bSmrg   /* Fbit adjustments don't have to propagate.  */
1923*f0fbc68bSmrg   for (a = adj_fbit; a; a = a->next)
1924*f0fbc68bSmrg     {
1925*f0fbc68bSmrg       printf ("\n  /* %s:%d */\n  s = %s;\n",
1926*f0fbc68bSmrg 	      a->file, a->line, a->adjustment);
1927*f0fbc68bSmrg       printf ("  mode_fbit[E_%smode] = s;\n", a->mode->name);
1928*f0fbc68bSmrg     }
1929*f0fbc68bSmrg 
1930*f0fbc68bSmrg   /* Real mode formats don't have to propagate anywhere.  */
1931*f0fbc68bSmrg   for (a = adj_format; a; a = a->next)
1932*f0fbc68bSmrg     printf ("\n  /* %s:%d */\n  REAL_MODE_FORMAT (E_%smode) = %s;\n",
1933*f0fbc68bSmrg 	    a->file, a->line, a->mode->name, a->adjustment);
1934*f0fbc68bSmrg 
1935*f0fbc68bSmrg   puts ("}");
1936*f0fbc68bSmrg }
1937*f0fbc68bSmrg 
1938*f0fbc68bSmrg /* Emit ibit for all modes.  */
1939*f0fbc68bSmrg 
1940*f0fbc68bSmrg static void
emit_mode_ibit(void)1941*f0fbc68bSmrg emit_mode_ibit (void)
1942*f0fbc68bSmrg {
1943*f0fbc68bSmrg   int c;
1944*f0fbc68bSmrg   struct mode_data *m;
1945*f0fbc68bSmrg 
1946*f0fbc68bSmrg   print_maybe_const_decl ("%sunsigned char",
1947*f0fbc68bSmrg 			  "mode_ibit", "NUM_MACHINE_MODES",
1948*f0fbc68bSmrg 			  adj_ibit);
1949*f0fbc68bSmrg 
1950*f0fbc68bSmrg   for_all_modes (c, m)
1951*f0fbc68bSmrg     tagged_printf ("%u", m->ibit, m->name);
1952*f0fbc68bSmrg 
1953*f0fbc68bSmrg   print_closer ();
1954*f0fbc68bSmrg }
1955*f0fbc68bSmrg 
1956*f0fbc68bSmrg /* Emit fbit for all modes.  */
1957*f0fbc68bSmrg 
1958*f0fbc68bSmrg static void
emit_mode_fbit(void)1959*f0fbc68bSmrg emit_mode_fbit (void)
1960*f0fbc68bSmrg {
1961*f0fbc68bSmrg   int c;
1962*f0fbc68bSmrg   struct mode_data *m;
1963*f0fbc68bSmrg 
1964*f0fbc68bSmrg   print_maybe_const_decl ("%sunsigned char",
1965*f0fbc68bSmrg 			  "mode_fbit", "NUM_MACHINE_MODES",
1966*f0fbc68bSmrg 			  adj_fbit);
1967*f0fbc68bSmrg 
1968*f0fbc68bSmrg   for_all_modes (c, m)
1969*f0fbc68bSmrg     tagged_printf ("%u", m->fbit, m->name);
1970*f0fbc68bSmrg 
1971*f0fbc68bSmrg   print_closer ();
1972*f0fbc68bSmrg }
1973*f0fbc68bSmrg 
1974*f0fbc68bSmrg /* Emit __intN for all modes.  */
1975*f0fbc68bSmrg 
1976*f0fbc68bSmrg static void
emit_mode_int_n(void)1977*f0fbc68bSmrg emit_mode_int_n (void)
1978*f0fbc68bSmrg {
1979*f0fbc68bSmrg   int c;
1980*f0fbc68bSmrg   struct mode_data *m;
1981*f0fbc68bSmrg   struct mode_data **mode_sort;
1982*f0fbc68bSmrg   int n_modes = 0;
1983*f0fbc68bSmrg   int i, j;
1984*f0fbc68bSmrg 
1985*f0fbc68bSmrg   print_decl ("int_n_data_t", "int_n_data", "");
1986*f0fbc68bSmrg 
1987*f0fbc68bSmrg   n_modes = 0;
1988*f0fbc68bSmrg   for_all_modes (c, m)
1989*f0fbc68bSmrg     if (m->int_n)
1990*f0fbc68bSmrg       n_modes ++;
1991*f0fbc68bSmrg   mode_sort = XALLOCAVEC (struct mode_data *, n_modes);
1992*f0fbc68bSmrg 
1993*f0fbc68bSmrg   n_modes = 0;
1994*f0fbc68bSmrg   for_all_modes (c, m)
1995*f0fbc68bSmrg     if (m->int_n)
1996*f0fbc68bSmrg       mode_sort[n_modes++] = m;
1997*f0fbc68bSmrg 
1998*f0fbc68bSmrg   /* Yes, this is a bubblesort, but there are at most four (and
1999*f0fbc68bSmrg      usually only 1-2) entries to sort.  */
2000*f0fbc68bSmrg   for (i = 0; i<n_modes - 1; i++)
2001*f0fbc68bSmrg     for (j = i + 1; j < n_modes; j++)
2002*f0fbc68bSmrg       if (mode_sort[i]->int_n > mode_sort[j]->int_n)
2003*f0fbc68bSmrg 	std::swap (mode_sort[i], mode_sort[j]);
2004*f0fbc68bSmrg 
2005*f0fbc68bSmrg   for (i = 0; i < n_modes; i ++)
2006*f0fbc68bSmrg     {
2007*f0fbc68bSmrg       m = mode_sort[i];
2008*f0fbc68bSmrg       printf(" {\n");
2009*f0fbc68bSmrg       tagged_printf ("%u", m->int_n, m->name);
2010*f0fbc68bSmrg       printf ("{ E_%smode },", m->name);
2011*f0fbc68bSmrg       printf(" },\n");
2012*f0fbc68bSmrg     }
2013*f0fbc68bSmrg 
2014*f0fbc68bSmrg   print_closer ();
2015*f0fbc68bSmrg }
2016*f0fbc68bSmrg 
2017*f0fbc68bSmrg 
2018*f0fbc68bSmrg static void
emit_insn_modes_c(void)2019*f0fbc68bSmrg emit_insn_modes_c (void)
2020*f0fbc68bSmrg {
2021*f0fbc68bSmrg   emit_insn_modes_c_header ();
2022*f0fbc68bSmrg   emit_mode_name ();
2023*f0fbc68bSmrg   emit_mode_class ();
2024*f0fbc68bSmrg   emit_mode_precision ();
2025*f0fbc68bSmrg   emit_mode_size ();
2026*f0fbc68bSmrg   emit_mode_nunits ();
2027*f0fbc68bSmrg   emit_mode_wider ();
2028*f0fbc68bSmrg   emit_mode_complex ();
2029*f0fbc68bSmrg   emit_mode_mask ();
2030*f0fbc68bSmrg   emit_mode_inner ();
2031*f0fbc68bSmrg   emit_mode_unit_size ();
2032*f0fbc68bSmrg   emit_mode_unit_precision ();
2033*f0fbc68bSmrg   emit_mode_base_align ();
2034*f0fbc68bSmrg   emit_class_narrowest_mode ();
2035*f0fbc68bSmrg   emit_real_format_for_mode ();
2036*f0fbc68bSmrg   emit_mode_adjustments ();
2037*f0fbc68bSmrg   emit_mode_ibit ();
2038*f0fbc68bSmrg   emit_mode_fbit ();
2039*f0fbc68bSmrg   emit_mode_int_n ();
2040*f0fbc68bSmrg }
2041*f0fbc68bSmrg 
2042*f0fbc68bSmrg static void
emit_min_insn_modes_c(void)2043*f0fbc68bSmrg emit_min_insn_modes_c (void)
2044*f0fbc68bSmrg {
2045*f0fbc68bSmrg   emit_min_insn_modes_c_header ();
2046*f0fbc68bSmrg   emit_mode_name ();
2047*f0fbc68bSmrg   emit_mode_class ();
2048*f0fbc68bSmrg   emit_mode_nunits ();
2049*f0fbc68bSmrg   emit_mode_wider ();
2050*f0fbc68bSmrg   emit_mode_inner ();
2051*f0fbc68bSmrg   emit_class_narrowest_mode ();
2052*f0fbc68bSmrg }
2053*f0fbc68bSmrg 
2054*f0fbc68bSmrg /* Master control.  */
2055*f0fbc68bSmrg int
main(int argc,char ** argv)2056*f0fbc68bSmrg main (int argc, char **argv)
2057*f0fbc68bSmrg {
2058*f0fbc68bSmrg   bool gen_header = false, gen_inlines = false, gen_min = false;
2059*f0fbc68bSmrg   progname = argv[0];
2060*f0fbc68bSmrg 
2061*f0fbc68bSmrg   if (argc == 1)
2062*f0fbc68bSmrg     ;
2063*f0fbc68bSmrg   else if (argc == 2 && !strcmp (argv[1], "-h"))
2064*f0fbc68bSmrg     gen_header = true;
2065*f0fbc68bSmrg   else if (argc == 2 && !strcmp (argv[1], "-i"))
2066*f0fbc68bSmrg     gen_inlines = true;
2067*f0fbc68bSmrg   else if (argc == 2 && !strcmp (argv[1], "-m"))
2068*f0fbc68bSmrg     gen_min = true;
2069*f0fbc68bSmrg   else
2070*f0fbc68bSmrg     {
2071*f0fbc68bSmrg       error ("usage: %s [-h|-i|-m] > file", progname);
2072*f0fbc68bSmrg       return FATAL_EXIT_CODE;
2073*f0fbc68bSmrg     }
2074*f0fbc68bSmrg 
2075*f0fbc68bSmrg   modes_by_name = htab_create_alloc (64, hash_mode, eq_mode, 0, xcalloc, free);
2076*f0fbc68bSmrg 
2077*f0fbc68bSmrg   create_modes ();
2078*f0fbc68bSmrg   complete_all_modes ();
2079*f0fbc68bSmrg 
2080*f0fbc68bSmrg   if (have_error)
2081*f0fbc68bSmrg     return FATAL_EXIT_CODE;
2082*f0fbc68bSmrg 
2083*f0fbc68bSmrg   calc_wider_mode ();
2084*f0fbc68bSmrg 
2085*f0fbc68bSmrg   if (gen_header)
2086*f0fbc68bSmrg     emit_insn_modes_h ();
2087*f0fbc68bSmrg   else if (gen_inlines)
2088*f0fbc68bSmrg     emit_insn_modes_inline_h ();
2089*f0fbc68bSmrg   else if (gen_min)
2090*f0fbc68bSmrg     emit_min_insn_modes_c ();
2091*f0fbc68bSmrg   else
2092*f0fbc68bSmrg     emit_insn_modes_c ();
2093*f0fbc68bSmrg 
2094*f0fbc68bSmrg   if (fflush (stdout) || fclose (stdout))
2095*f0fbc68bSmrg     return FATAL_EXIT_CODE;
2096*f0fbc68bSmrg   return SUCCESS_EXIT_CODE;
2097*f0fbc68bSmrg }
2098