OpenCores
URL https://opencores.org/ocsvn/scarts/scarts/trunk

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [genmodes.c] - Blame information for rev 16

Go to most recent revision | Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.