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