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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-old/] [gcc-4.2.2/] [gcc/] [genmodes.c] - Blame information for rev 816

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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