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