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