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

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [gnu-dev/] [or1k-gcc/] [gcc/] [read-rtl.c] - Blame information for rev 749

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

Line No. Rev Author Line
1 684 jeremybenn
/* RTL reader for GCC.
2
   Copyright (C) 1987, 1988, 1991, 1994, 1997, 1998, 1999, 2000, 2001, 2002,
3
   2003, 2004, 2005, 2007, 2008, 2010
4
   Free Software Foundation, Inc.
5
 
6
This file is part of GCC.
7
 
8
GCC is free software; you can redistribute it and/or modify it under
9
the terms of the GNU General Public License as published by the Free
10
Software Foundation; either version 3, or (at your option) any later
11
version.
12
 
13
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14
WARRANTY; without even the implied warranty of MERCHANTABILITY or
15
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
16
for more details.
17
 
18
You should have received a copy of the GNU General Public License
19
along with GCC; see the file COPYING3.  If not see
20
<http://www.gnu.org/licenses/>.  */
21
 
22
#include "bconfig.h"
23
 
24
/* Disable rtl checking; it conflicts with the iterator handling.  */
25
#undef ENABLE_RTL_CHECKING
26
 
27
#include "system.h"
28
#include "coretypes.h"
29
#include "tm.h"
30
#include "rtl.h"
31
#include "obstack.h"
32
#include "hashtab.h"
33
#include "read-md.h"
34
#include "gensupport.h"
35
 
36
/* One element in a singly-linked list of (integer, string) pairs.  */
37
struct map_value {
38
  struct map_value *next;
39
  int number;
40
  const char *string;
41
};
42
 
43
/* Maps an iterator or attribute name to a list of (integer, string) pairs.
44
   The integers are mode or code values; the strings are either C conditions
45
   or attribute values.  */
46
struct mapping {
47
  /* The name of the iterator or attribute.  */
48
  const char *name;
49
 
50
  /* The group (modes or codes) to which the iterator or attribute belongs.  */
51
  struct iterator_group *group;
52
 
53
  /* Gives a unique number to the attribute or iterator.  Numbers are
54
     allocated consecutively, starting at 0.  */
55
  int index;
56
 
57
  /* The list of (integer, string) pairs.  */
58
  struct map_value *values;
59
};
60
 
61
/* A structure for abstracting the common parts of code and mode iterators.  */
62
struct iterator_group {
63
  /* Tables of "mapping" structures, one for attributes and one for iterators.  */
64
  htab_t attrs, iterators;
65
 
66
  /* The number of "real" modes or codes (and by extension, the first
67
     number available for use as an iterator placeholder).  */
68
  int num_builtins;
69
 
70
  /* Treat the given string as the name of a standard mode or code and
71
     return its integer value.  */
72
  int (*find_builtin) (const char *);
73
 
74
  /* Return true if the given rtx uses the given mode or code.  */
75
  bool (*uses_iterator_p) (rtx, int);
76
 
77
  /* Make the given rtx use the given mode or code.  */
78
  void (*apply_iterator) (rtx, int);
79
};
80
 
81
/* A structure used to pass data from read_rtx to apply_iterator_traverse
82
   via htab_traverse.  */
83
struct iterator_traverse_data {
84
  /* Instruction queue.  */
85
  rtx queue;
86
  /* Attributes seen for modes.  */
87
  struct map_value *mode_maps;
88
  /* The last unknown attribute used as a mode.  */
89
  const char *unknown_mode_attr;
90
};
91
 
92
/* If CODE is the number of a code iterator, return a real rtx code that
93
   has the same format.  Return CODE otherwise.  */
94
#define BELLWETHER_CODE(CODE) \
95
  ((CODE) < NUM_RTX_CODE ? CODE : bellwether_codes[CODE - NUM_RTX_CODE])
96
 
97
static int find_mode (const char *);
98
static bool uses_mode_iterator_p (rtx, int);
99
static void apply_mode_iterator (rtx, int);
100
static int find_code (const char *);
101
static bool uses_code_iterator_p (rtx, int);
102
static void apply_code_iterator (rtx, int);
103
static const char *apply_iterator_to_string (const char *, struct mapping *, int);
104
static rtx apply_iterator_to_rtx (rtx, struct mapping *, int,
105
                                  struct map_value *, const char **);
106
static bool uses_iterator_p (rtx, struct mapping *);
107
static const char *add_condition_to_string (const char *, const char *);
108
static void add_condition_to_rtx (rtx, const char *);
109
static int apply_iterator_traverse (void **, void *);
110
static struct mapping *add_mapping (struct iterator_group *, htab_t t,
111
                                    const char *);
112
static struct map_value **add_map_value (struct map_value **,
113
                                         int, const char *);
114
static void initialize_iterators (void);
115
static void read_conditions (void);
116
static void validate_const_int (const char *);
117
static int find_iterator (struct iterator_group *, const char *);
118
static struct mapping *read_mapping (struct iterator_group *, htab_t);
119
static void check_code_iterator (struct mapping *);
120
static rtx read_rtx_code (const char *, struct map_value **);
121
static rtx read_nested_rtx (struct map_value **);
122
static rtx read_rtx_variadic (struct map_value **, rtx);
123
 
124
/* The mode and code iterator structures.  */
125
static struct iterator_group modes, codes;
126
 
127
/* Index I is the value of BELLWETHER_CODE (I + NUM_RTX_CODE).  */
128
static enum rtx_code *bellwether_codes;
129
 
130
/* Implementations of the iterator_group callbacks for modes.  */
131
 
132
static int
133
find_mode (const char *name)
134
{
135
  int i;
136
 
137
  for (i = 0; i < NUM_MACHINE_MODES; i++)
138
    if (strcmp (GET_MODE_NAME (i), name) == 0)
139
      return i;
140
 
141
  fatal_with_file_and_line ("unknown mode `%s'", name);
142
}
143
 
144
static bool
145
uses_mode_iterator_p (rtx x, int mode)
146
{
147
  return (int) GET_MODE (x) == mode;
148
}
149
 
150
static void
151
apply_mode_iterator (rtx x, int mode)
152
{
153
  PUT_MODE (x, (enum machine_mode) mode);
154
}
155
 
156
/* Implementations of the iterator_group callbacks for codes.  */
157
 
158
static int
159
find_code (const char *name)
160
{
161
  int i;
162
 
163
  for (i = 0; i < NUM_RTX_CODE; i++)
164
    if (strcmp (GET_RTX_NAME (i), name) == 0)
165
      return i;
166
 
167
  fatal_with_file_and_line ("unknown rtx code `%s'", name);
168
}
169
 
170
static bool
171
uses_code_iterator_p (rtx x, int code)
172
{
173
  return (int) GET_CODE (x) == code;
174
}
175
 
176
static void
177
apply_code_iterator (rtx x, int code)
178
{
179
  PUT_CODE (x, (enum rtx_code) code);
180
}
181
 
182
/* Map a code or mode attribute string P to the underlying string for
183
   ITERATOR and VALUE.  */
184
 
185
static struct map_value *
186
map_attr_string (const char *p, struct mapping *iterator, int value)
187
{
188
  const char *attr;
189
  struct mapping *m;
190
  struct map_value *v;
191
 
192
  /* If there's a "iterator:" prefix, check whether the iterator name matches.
193
     Set ATTR to the start of the attribute name.  */
194
  attr = strchr (p, ':');
195
  if (attr == 0)
196
    attr = p;
197
  else
198
    {
199
      if (strncmp (p, iterator->name, attr - p) != 0
200
          || iterator->name[attr - p] != 0)
201
        return 0;
202
      attr++;
203
    }
204
 
205
  /* Find the attribute specification.  */
206
  m = (struct mapping *) htab_find (iterator->group->attrs, &attr);
207
  if (m == 0)
208
    return 0;
209
 
210
  /* Find the attribute value for VALUE.  */
211
  for (v = m->values; v != 0; v = v->next)
212
    if (v->number == value)
213
      break;
214
 
215
  return v;
216
}
217
 
218
/* Given an attribute string used as a machine mode, return an index
219
   to store in the machine mode to be translated by
220
   apply_iterator_to_rtx.  */
221
 
222
static unsigned int
223
mode_attr_index (struct map_value **mode_maps, const char *string)
224
{
225
  char *p;
226
  struct map_value *mv;
227
 
228
  /* Copy the attribute string into permanent storage, without the
229
     angle brackets around it.  */
230
  obstack_grow0 (&string_obstack, string + 1, strlen (string) - 2);
231
  p = XOBFINISH (&string_obstack, char *);
232
 
233
  mv = XNEW (struct map_value);
234
  mv->number = *mode_maps == 0 ? 0 : (*mode_maps)->number + 1;
235
  mv->string = p;
236
  mv->next = *mode_maps;
237
  *mode_maps = mv;
238
 
239
  /* We return a code which we can map back into this string: the
240
     number of machine modes + the number of mode iterators + the index
241
     we just used.  */
242
  return MAX_MACHINE_MODE + htab_elements (modes.iterators) + mv->number;
243
}
244
 
245
/* Apply MODE_MAPS to the top level of X, expanding cases where an
246
   attribute is used for a mode.  ITERATOR is the current iterator we are
247
   expanding, and VALUE is the value to which we are expanding it.
248
   This sets *UNKNOWN to true if we find a mode attribute which has not
249
   yet been defined, and does not change it otherwise.  */
250
 
251
static void
252
apply_mode_maps (rtx x, struct map_value *mode_maps, struct mapping *iterator,
253
                 int value, const char **unknown)
254
{
255
  unsigned int offset;
256
  int indx;
257
  struct map_value *pm;
258
 
259
  offset = MAX_MACHINE_MODE + htab_elements (modes.iterators);
260
  if (GET_MODE (x) < offset)
261
    return;
262
 
263
  indx = GET_MODE (x) - offset;
264
  for (pm = mode_maps; pm; pm = pm->next)
265
    {
266
      if (pm->number == indx)
267
        {
268
          struct map_value *v;
269
 
270
          v = map_attr_string (pm->string, iterator, value);
271
          if (v)
272
            PUT_MODE (x, (enum machine_mode) find_mode (v->string));
273
          else
274
            *unknown = pm->string;
275
          return;
276
        }
277
    }
278
}
279
 
280
/* Given that ITERATOR is being expanded as VALUE, apply the appropriate
281
   string substitutions to STRING.  Return the new string if any changes
282
   were needed, otherwise return STRING itself.  */
283
 
284
static const char *
285
apply_iterator_to_string (const char *string, struct mapping *iterator, int value)
286
{
287
  char *base, *copy, *p, *start, *end;
288
  struct map_value *v;
289
 
290
  if (string == 0)
291
    return string;
292
 
293
  base = p = copy = ASTRDUP (string);
294
  while ((start = strchr (p, '<')) && (end = strchr (start, '>')))
295
    {
296
      p = start + 1;
297
 
298
      *end = 0;
299
      v = map_attr_string (p, iterator, value);
300
      *end = '>';
301
      if (v == 0)
302
        continue;
303
 
304
      /* Add everything between the last copied byte and the '<',
305
         then add in the attribute value.  */
306
      obstack_grow (&string_obstack, base, start - base);
307
      obstack_grow (&string_obstack, v->string, strlen (v->string));
308
      base = end + 1;
309
    }
310
  if (base != copy)
311
    {
312
      obstack_grow (&string_obstack, base, strlen (base) + 1);
313
      copy = XOBFINISH (&string_obstack, char *);
314
      copy_md_ptr_loc (copy, string);
315
      return copy;
316
    }
317
  return string;
318
}
319
 
320
/* Return a copy of ORIGINAL in which all uses of ITERATOR have been
321
   replaced by VALUE.  MODE_MAPS holds information about attribute
322
   strings used for modes.  This sets *UNKNOWN_MODE_ATTR to the value of
323
   an unknown mode attribute, and does not change it otherwise.  */
324
 
325
static rtx
326
apply_iterator_to_rtx (rtx original, struct mapping *iterator, int value,
327
                       struct map_value *mode_maps,
328
                       const char **unknown_mode_attr)
329
{
330
  struct iterator_group *group;
331
  const char *format_ptr;
332
  int i, j;
333
  rtx x;
334
  enum rtx_code bellwether_code;
335
 
336
  if (original == 0)
337
    return original;
338
 
339
  /* Create a shallow copy of ORIGINAL.  */
340
  bellwether_code = BELLWETHER_CODE (GET_CODE (original));
341
  x = rtx_alloc (bellwether_code);
342
  memcpy (x, original, RTX_CODE_SIZE (bellwether_code));
343
 
344
  /* Change the mode or code itself.  */
345
  group = iterator->group;
346
  if (group->uses_iterator_p (x, iterator->index + group->num_builtins))
347
    group->apply_iterator (x, value);
348
 
349
  if (mode_maps)
350
    apply_mode_maps (x, mode_maps, iterator, value, unknown_mode_attr);
351
 
352
  /* Change each string and recursively change each rtx.  */
353
  format_ptr = GET_RTX_FORMAT (bellwether_code);
354
  for (i = 0; format_ptr[i] != 0; i++)
355
    switch (format_ptr[i])
356
      {
357
      case 'T':
358
        XTMPL (x, i) = apply_iterator_to_string (XTMPL (x, i), iterator, value);
359
        break;
360
 
361
      case 'S':
362
      case 's':
363
        XSTR (x, i) = apply_iterator_to_string (XSTR (x, i), iterator, value);
364
        break;
365
 
366
      case 'e':
367
        XEXP (x, i) = apply_iterator_to_rtx (XEXP (x, i), iterator, value,
368
                                             mode_maps, unknown_mode_attr);
369
        break;
370
 
371
      case 'V':
372
      case 'E':
373
        if (XVEC (original, i))
374
          {
375
            XVEC (x, i) = rtvec_alloc (XVECLEN (original, i));
376
            for (j = 0; j < XVECLEN (x, i); j++)
377
              XVECEXP (x, i, j) = apply_iterator_to_rtx (XVECEXP (original, i, j),
378
                                                         iterator, value, mode_maps,
379
                                                         unknown_mode_attr);
380
          }
381
        break;
382
 
383
      default:
384
        break;
385
      }
386
  return x;
387
}
388
 
389
/* Return true if X (or some subexpression of X) uses iterator ITERATOR.  */
390
 
391
static bool
392
uses_iterator_p (rtx x, struct mapping *iterator)
393
{
394
  struct iterator_group *group;
395
  const char *format_ptr;
396
  int i, j;
397
 
398
  if (x == 0)
399
    return false;
400
 
401
  group = iterator->group;
402
  if (group->uses_iterator_p (x, iterator->index + group->num_builtins))
403
    return true;
404
 
405
  format_ptr = GET_RTX_FORMAT (BELLWETHER_CODE (GET_CODE (x)));
406
  for (i = 0; format_ptr[i] != 0; i++)
407
    switch (format_ptr[i])
408
      {
409
      case 'e':
410
        if (uses_iterator_p (XEXP (x, i), iterator))
411
          return true;
412
        break;
413
 
414
      case 'V':
415
      case 'E':
416
        if (XVEC (x, i))
417
          for (j = 0; j < XVECLEN (x, i); j++)
418
            if (uses_iterator_p (XVECEXP (x, i, j), iterator))
419
              return true;
420
        break;
421
 
422
      default:
423
        break;
424
      }
425
  return false;
426
}
427
 
428
/* Return a condition that must satisfy both ORIGINAL and EXTRA.  If ORIGINAL
429
   has the form "&& ..." (as used in define_insn_and_splits), assume that
430
   EXTRA is already satisfied.  Empty strings are treated like "true".  */
431
 
432
static const char *
433
add_condition_to_string (const char *original, const char *extra)
434
{
435
  if (original != 0 && original[0] == '&' && original[1] == '&')
436
    return original;
437
  return join_c_conditions (original, extra);
438
}
439
 
440
/* Like add_condition, but applied to all conditions in rtx X.  */
441
 
442
static void
443
add_condition_to_rtx (rtx x, const char *extra)
444
{
445
  switch (GET_CODE (x))
446
    {
447
    case DEFINE_INSN:
448
    case DEFINE_EXPAND:
449
      XSTR (x, 2) = add_condition_to_string (XSTR (x, 2), extra);
450
      break;
451
 
452
    case DEFINE_SPLIT:
453
    case DEFINE_PEEPHOLE:
454
    case DEFINE_PEEPHOLE2:
455
    case DEFINE_COND_EXEC:
456
      XSTR (x, 1) = add_condition_to_string (XSTR (x, 1), extra);
457
      break;
458
 
459
    case DEFINE_INSN_AND_SPLIT:
460
      XSTR (x, 2) = add_condition_to_string (XSTR (x, 2), extra);
461
      XSTR (x, 4) = add_condition_to_string (XSTR (x, 4), extra);
462
      break;
463
 
464
    default:
465
      break;
466
    }
467
}
468
 
469
/* A htab_traverse callback.  Search the EXPR_LIST given by DATA
470
   for rtxes that use the iterator in *SLOT.  Replace each such rtx
471
   with a list of expansions.  */
472
 
473
static int
474
apply_iterator_traverse (void **slot, void *data)
475
{
476
  struct iterator_traverse_data *mtd = (struct iterator_traverse_data *) data;
477
  struct mapping *iterator;
478
  struct map_value *v;
479
  rtx elem, new_elem, original, x;
480
 
481
  iterator = (struct mapping *) *slot;
482
  for (elem = mtd->queue; elem != 0; elem = XEXP (elem, 1))
483
    if (uses_iterator_p (XEXP (elem, 0), iterator))
484
      {
485
        /* For each iterator we expand, we set UNKNOWN_MODE_ATTR to NULL.
486
           If apply_iterator_rtx finds an unknown attribute for a mode,
487
           it will set it to the attribute.  We want to know whether
488
           the attribute is unknown after we have expanded all
489
           possible iterators, so setting it to NULL here gives us the
490
           right result when the hash table traversal is complete.  */
491
        mtd->unknown_mode_attr = NULL;
492
 
493
        original = XEXP (elem, 0);
494
        for (v = iterator->values; v != 0; v = v->next)
495
          {
496
            x = apply_iterator_to_rtx (original, iterator, v->number,
497
                                       mtd->mode_maps,
498
                                       &mtd->unknown_mode_attr);
499
            add_condition_to_rtx (x, v->string);
500
            if (v != iterator->values)
501
              {
502
                /* Insert a new EXPR_LIST node after ELEM and put the
503
                   new expansion there.  */
504
                new_elem = rtx_alloc (EXPR_LIST);
505
                XEXP (new_elem, 1) = XEXP (elem, 1);
506
                XEXP (elem, 1) = new_elem;
507
                elem = new_elem;
508
              }
509
            XEXP (elem, 0) = x;
510
          }
511
    }
512
  return 1;
513
}
514
 
515
/* Add a new "mapping" structure to hashtable TABLE.  NAME is the name
516
   of the mapping and GROUP is the group to which it belongs.  */
517
 
518
static struct mapping *
519
add_mapping (struct iterator_group *group, htab_t table, const char *name)
520
{
521
  struct mapping *m;
522
  void **slot;
523
 
524
  m = XNEW (struct mapping);
525
  m->name = xstrdup (name);
526
  m->group = group;
527
  m->index = htab_elements (table);
528
  m->values = 0;
529
 
530
  slot = htab_find_slot (table, m, INSERT);
531
  if (*slot != 0)
532
    fatal_with_file_and_line ("`%s' already defined", name);
533
 
534
  *slot = m;
535
  return m;
536
}
537
 
538
/* Add the pair (NUMBER, STRING) to a list of map_value structures.
539
   END_PTR points to the current null terminator for the list; return
540
   a pointer the new null terminator.  */
541
 
542
static struct map_value **
543
add_map_value (struct map_value **end_ptr, int number, const char *string)
544
{
545
  struct map_value *value;
546
 
547
  value = XNEW (struct map_value);
548
  value->next = 0;
549
  value->number = number;
550
  value->string = string;
551
 
552
  *end_ptr = value;
553
  return &value->next;
554
}
555
 
556
/* Do one-time initialization of the mode and code attributes.  */
557
 
558
static void
559
initialize_iterators (void)
560
{
561
  struct mapping *lower, *upper;
562
  struct map_value **lower_ptr, **upper_ptr;
563
  char *copy, *p;
564
  int i;
565
 
566
  modes.attrs = htab_create (13, leading_string_hash, leading_string_eq_p, 0);
567
  modes.iterators = htab_create (13, leading_string_hash,
568
                                 leading_string_eq_p, 0);
569
  modes.num_builtins = MAX_MACHINE_MODE;
570
  modes.find_builtin = find_mode;
571
  modes.uses_iterator_p = uses_mode_iterator_p;
572
  modes.apply_iterator = apply_mode_iterator;
573
 
574
  codes.attrs = htab_create (13, leading_string_hash, leading_string_eq_p, 0);
575
  codes.iterators = htab_create (13, leading_string_hash,
576
                                 leading_string_eq_p, 0);
577
  codes.num_builtins = NUM_RTX_CODE;
578
  codes.find_builtin = find_code;
579
  codes.uses_iterator_p = uses_code_iterator_p;
580
  codes.apply_iterator = apply_code_iterator;
581
 
582
  lower = add_mapping (&modes, modes.attrs, "mode");
583
  upper = add_mapping (&modes, modes.attrs, "MODE");
584
  lower_ptr = &lower->values;
585
  upper_ptr = &upper->values;
586
  for (i = 0; i < MAX_MACHINE_MODE; i++)
587
    {
588
      copy = xstrdup (GET_MODE_NAME (i));
589
      for (p = copy; *p != 0; p++)
590
        *p = TOLOWER (*p);
591
 
592
      upper_ptr = add_map_value (upper_ptr, i, GET_MODE_NAME (i));
593
      lower_ptr = add_map_value (lower_ptr, i, copy);
594
    }
595
 
596
  lower = add_mapping (&codes, codes.attrs, "code");
597
  upper = add_mapping (&codes, codes.attrs, "CODE");
598
  lower_ptr = &lower->values;
599
  upper_ptr = &upper->values;
600
  for (i = 0; i < NUM_RTX_CODE; i++)
601
    {
602
      copy = xstrdup (GET_RTX_NAME (i));
603
      for (p = copy; *p != 0; p++)
604
        *p = TOUPPER (*p);
605
 
606
      lower_ptr = add_map_value (lower_ptr, i, GET_RTX_NAME (i));
607
      upper_ptr = add_map_value (upper_ptr, i, copy);
608
    }
609
}
610
 
611
/* Provide a version of a function to read a long long if the system does
612
   not provide one.  */
613
#if HOST_BITS_PER_WIDE_INT > HOST_BITS_PER_LONG && !defined(HAVE_ATOLL) && !defined(HAVE_ATOQ)
614
HOST_WIDE_INT atoll (const char *);
615
 
616
HOST_WIDE_INT
617
atoll (const char *p)
618
{
619
  int neg = 0;
620
  HOST_WIDE_INT tmp_wide;
621
 
622
  while (ISSPACE (*p))
623
    p++;
624
  if (*p == '-')
625
    neg = 1, p++;
626
  else if (*p == '+')
627
    p++;
628
 
629
  tmp_wide = 0;
630
  while (ISDIGIT (*p))
631
    {
632
      HOST_WIDE_INT new_wide = tmp_wide*10 + (*p - '0');
633
      if (new_wide < tmp_wide)
634
        {
635
          /* Return INT_MAX equiv on overflow.  */
636
          tmp_wide = (~(unsigned HOST_WIDE_INT) 0) >> 1;
637
          break;
638
        }
639
      tmp_wide = new_wide;
640
      p++;
641
    }
642
 
643
  if (neg)
644
    tmp_wide = -tmp_wide;
645
  return tmp_wide;
646
}
647
#endif
648
 
649
/* Process a define_conditions directive, starting with the optional
650
   space after the "define_conditions".  The directive looks like this:
651
 
652
     (define_conditions [
653
        (number "string")
654
        (number "string")
655
        ...
656
     ])
657
 
658
   It's not intended to appear in machine descriptions.  It is
659
   generated by (the program generated by) genconditions.c, and
660
   slipped in at the beginning of the sequence of MD files read by
661
   most of the other generators.  */
662
static void
663
read_conditions (void)
664
{
665
  int c;
666
 
667
  c = read_skip_spaces ();
668
  if (c != '[')
669
    fatal_expected_char ('[', c);
670
 
671
  while ( (c = read_skip_spaces ()) != ']')
672
    {
673
      struct md_name name;
674
      char *expr;
675
      int value;
676
 
677
      if (c != '(')
678
        fatal_expected_char ('(', c);
679
 
680
      read_name (&name);
681
      validate_const_int (name.string);
682
      value = atoi (name.string);
683
 
684
      c = read_skip_spaces ();
685
      if (c != '"')
686
        fatal_expected_char ('"', c);
687
      expr = read_quoted_string ();
688
 
689
      c = read_skip_spaces ();
690
      if (c != ')')
691
        fatal_expected_char (')', c);
692
 
693
      add_c_test (expr, value);
694
    }
695
}
696
 
697
static void
698
validate_const_int (const char *string)
699
{
700
  const char *cp;
701
  int valid = 1;
702
 
703
  cp = string;
704
  while (*cp && ISSPACE (*cp))
705
    cp++;
706
  if (*cp == '-' || *cp == '+')
707
    cp++;
708
  if (*cp == 0)
709
    valid = 0;
710
  for (; *cp; cp++)
711
    if (! ISDIGIT (*cp))
712
      valid = 0;
713
  if (!valid)
714
    fatal_with_file_and_line ("invalid decimal constant \"%s\"\n", string);
715
}
716
 
717
/* Search GROUP for a mode or code called NAME and return its numerical
718
   identifier.  */
719
 
720
static int
721
find_iterator (struct iterator_group *group, const char *name)
722
{
723
  struct mapping *m;
724
 
725
  m = (struct mapping *) htab_find (group->iterators, &name);
726
  if (m != 0)
727
    return m->index + group->num_builtins;
728
  return group->find_builtin (name);
729
}
730
 
731
/* Finish reading a declaration of the form:
732
 
733
       (define... <name> [<value1> ... <valuen>])
734
 
735
   from the MD file, where each <valuei> is either a bare symbol name or a
736
   "(<name> <string>)" pair.  The "(define..." part has already been read.
737
 
738
   Represent the declaration as a "mapping" structure; add it to TABLE
739
   (which belongs to GROUP) and return it.  */
740
 
741
static struct mapping *
742
read_mapping (struct iterator_group *group, htab_t table)
743
{
744
  struct md_name name;
745
  struct mapping *m;
746
  struct map_value **end_ptr;
747
  const char *string;
748
  int number, c;
749
 
750
  /* Read the mapping name and create a structure for it.  */
751
  read_name (&name);
752
  m = add_mapping (group, table, name.string);
753
 
754
  c = read_skip_spaces ();
755
  if (c != '[')
756
    fatal_expected_char ('[', c);
757
 
758
  /* Read each value.  */
759
  end_ptr = &m->values;
760
  c = read_skip_spaces ();
761
  do
762
    {
763
      if (c != '(')
764
        {
765
          /* A bare symbol name that is implicitly paired to an
766
             empty string.  */
767
          unread_char (c);
768
          read_name (&name);
769
          string = "";
770
        }
771
      else
772
        {
773
          /* A "(name string)" pair.  */
774
          read_name (&name);
775
          string = read_string (false);
776
          c = read_skip_spaces ();
777
          if (c != ')')
778
            fatal_expected_char (')', c);
779
        }
780
      number = group->find_builtin (name.string);
781
      end_ptr = add_map_value (end_ptr, number, string);
782
      c = read_skip_spaces ();
783
    }
784
  while (c != ']');
785
 
786
  return m;
787
}
788
 
789
/* Check newly-created code iterator ITERATOR to see whether every code has the
790
   same format.  Initialize the iterator's entry in bellwether_codes.  */
791
 
792
static void
793
check_code_iterator (struct mapping *iterator)
794
{
795
  struct map_value *v;
796
  enum rtx_code bellwether;
797
 
798
  bellwether = (enum rtx_code) iterator->values->number;
799
  for (v = iterator->values->next; v != 0; v = v->next)
800
    if (strcmp (GET_RTX_FORMAT (bellwether), GET_RTX_FORMAT (v->number)) != 0)
801
      fatal_with_file_and_line ("code iterator `%s' combines "
802
                                "different rtx formats", iterator->name);
803
 
804
  bellwether_codes = XRESIZEVEC (enum rtx_code, bellwether_codes,
805
                                 iterator->index + 1);
806
  bellwether_codes[iterator->index] = bellwether;
807
}
808
 
809
/* Read an rtx-related declaration from the MD file, given that it
810
   starts with directive name RTX_NAME.  Return true if it expands to
811
   one or more rtxes (as defined by rtx.def).  When returning true,
812
   store the list of rtxes as an EXPR_LIST in *X.  */
813
 
814
bool
815
read_rtx (const char *rtx_name, rtx *x)
816
{
817
  static rtx queue_head;
818
  struct map_value *mode_maps;
819
  struct iterator_traverse_data mtd;
820
 
821
  /* Do one-time initialization.  */
822
  if (queue_head == 0)
823
    {
824
      initialize_iterators ();
825
      queue_head = rtx_alloc (EXPR_LIST);
826
    }
827
 
828
  /* Handle various rtx-related declarations that aren't themselves
829
     encoded as rtxes.  */
830
  if (strcmp (rtx_name, "define_conditions") == 0)
831
    {
832
      read_conditions ();
833
      return false;
834
    }
835
  if (strcmp (rtx_name, "define_mode_attr") == 0)
836
    {
837
      read_mapping (&modes, modes.attrs);
838
      return false;
839
    }
840
  if (strcmp (rtx_name, "define_mode_iterator") == 0)
841
    {
842
      read_mapping (&modes, modes.iterators);
843
      return false;
844
    }
845
  if (strcmp (rtx_name, "define_code_attr") == 0)
846
    {
847
      read_mapping (&codes, codes.attrs);
848
      return false;
849
    }
850
  if (strcmp (rtx_name, "define_code_iterator") == 0)
851
    {
852
      check_code_iterator (read_mapping (&codes, codes.iterators));
853
      return false;
854
    }
855
 
856
  mode_maps = 0;
857
  XEXP (queue_head, 0) = read_rtx_code (rtx_name, &mode_maps);
858
  XEXP (queue_head, 1) = 0;
859
 
860
  mtd.queue = queue_head;
861
  mtd.mode_maps = mode_maps;
862
  mtd.unknown_mode_attr = mode_maps ? mode_maps->string : NULL;
863
  htab_traverse (modes.iterators, apply_iterator_traverse, &mtd);
864
  htab_traverse (codes.iterators, apply_iterator_traverse, &mtd);
865
  if (mtd.unknown_mode_attr)
866
    fatal_with_file_and_line ("undefined attribute '%s' used for mode",
867
                              mtd.unknown_mode_attr);
868
 
869
  *x = queue_head;
870
  return true;
871
}
872
 
873
/* Subroutine of read_rtx and read_nested_rtx.  CODE_NAME is the name of
874
   either an rtx code or a code iterator.  Parse the rest of the rtx and
875
   return it.  MODE_MAPS is as for iterator_traverse_data.  */
876
 
877
static rtx
878
read_rtx_code (const char *code_name, struct map_value **mode_maps)
879
{
880
  int i;
881
  RTX_CODE real_code, bellwether_code;
882
  const char *format_ptr;
883
  struct md_name name;
884
  rtx return_rtx;
885
  int c;
886
  int tmp_int;
887
  HOST_WIDE_INT tmp_wide;
888
 
889
  /* Linked list structure for making RTXs: */
890
  struct rtx_list
891
    {
892
      struct rtx_list *next;
893
      rtx value;                /* Value of this node.  */
894
    };
895
 
896
  real_code = (enum rtx_code) find_iterator (&codes, code_name);
897
  bellwether_code = BELLWETHER_CODE (real_code);
898
 
899
  /* If we end up with an insn expression then we free this space below.  */
900
  return_rtx = rtx_alloc (bellwether_code);
901
  format_ptr = GET_RTX_FORMAT (bellwether_code);
902
  PUT_CODE (return_rtx, real_code);
903
 
904
  /* If what follows is `: mode ', read it and
905
     store the mode in the rtx.  */
906
 
907
  i = read_skip_spaces ();
908
  if (i == ':')
909
    {
910
      unsigned int mode;
911
 
912
      read_name (&name);
913
      if (name.string[0] != '<' || name.string[strlen (name.string) - 1] != '>')
914
        mode = find_iterator (&modes, name.string);
915
      else
916
        mode = mode_attr_index (mode_maps, name.string);
917
      PUT_MODE (return_rtx, (enum machine_mode) mode);
918
      if (GET_MODE (return_rtx) != mode)
919
        fatal_with_file_and_line ("mode too large");
920
    }
921
  else
922
    unread_char (i);
923
 
924
  for (i = 0; format_ptr[i] != 0; i++)
925
    switch (format_ptr[i])
926
      {
927
        /* 0 means a field for internal use only.
928
           Don't expect it to be present in the input.  */
929
      case '0':
930
        break;
931
 
932
      case 'e':
933
      case 'u':
934
        XEXP (return_rtx, i) = read_nested_rtx (mode_maps);
935
        break;
936
 
937
      case 'V':
938
        /* 'V' is an optional vector: if a closeparen follows,
939
           just store NULL for this element.  */
940
        c = read_skip_spaces ();
941
        unread_char (c);
942
        if (c == ')')
943
          {
944
            XVEC (return_rtx, i) = 0;
945
            break;
946
          }
947
        /* Now process the vector.  */
948
 
949
      case 'E':
950
        {
951
          /* Obstack to store scratch vector in.  */
952
          struct obstack vector_stack;
953
          int list_counter = 0;
954
          rtvec return_vec = NULL_RTVEC;
955
 
956
          c = read_skip_spaces ();
957
          if (c != '[')
958
            fatal_expected_char ('[', c);
959
 
960
          /* Add expressions to a list, while keeping a count.  */
961
          obstack_init (&vector_stack);
962
          while ((c = read_skip_spaces ()) && c != ']')
963
            {
964
              if (c == EOF)
965
                fatal_expected_char (']', c);
966
              unread_char (c);
967
              list_counter++;
968
              obstack_ptr_grow (&vector_stack, read_nested_rtx (mode_maps));
969
            }
970
          if (list_counter > 0)
971
            {
972
              return_vec = rtvec_alloc (list_counter);
973
              memcpy (&return_vec->elem[0], obstack_finish (&vector_stack),
974
                      list_counter * sizeof (rtx));
975
            }
976
          else if (format_ptr[i] == 'E')
977
            fatal_with_file_and_line ("vector must have at least one element");
978
          XVEC (return_rtx, i) = return_vec;
979
          obstack_free (&vector_stack, NULL);
980
          /* close bracket gotten */
981
        }
982
        break;
983
 
984
      case 'S':
985
      case 'T':
986
      case 's':
987
        {
988
          char *stringbuf;
989
          int star_if_braced;
990
 
991
          c = read_skip_spaces ();
992
          unread_char (c);
993
          if (c == ')')
994
            {
995
              /* 'S' fields are optional and should be NULL if no string
996
                 was given.  Also allow normal 's' and 'T' strings to be
997
                 omitted, treating them in the same way as empty strings.  */
998
              XSTR (return_rtx, i) = (format_ptr[i] == 'S' ? NULL : "");
999
              break;
1000
            }
1001
 
1002
          /* The output template slot of a DEFINE_INSN,
1003
             DEFINE_INSN_AND_SPLIT, or DEFINE_PEEPHOLE automatically
1004
             gets a star inserted as its first character, if it is
1005
             written with a brace block instead of a string constant.  */
1006
          star_if_braced = (format_ptr[i] == 'T');
1007
 
1008
          stringbuf = read_string (star_if_braced);
1009
 
1010
          /* For insn patterns, we want to provide a default name
1011
             based on the file and line, like "*foo.md:12", if the
1012
             given name is blank.  These are only for define_insn and
1013
             define_insn_and_split, to aid debugging.  */
1014
          if (*stringbuf == '\0'
1015
              && i == 0
1016
              && (GET_CODE (return_rtx) == DEFINE_INSN
1017
                  || GET_CODE (return_rtx) == DEFINE_INSN_AND_SPLIT))
1018
            {
1019
              char line_name[20];
1020
              const char *fn = (read_md_filename ? read_md_filename : "rtx");
1021
              const char *slash;
1022
              for (slash = fn; *slash; slash ++)
1023
                if (*slash == '/' || *slash == '\\' || *slash == ':')
1024
                  fn = slash + 1;
1025
              obstack_1grow (&string_obstack, '*');
1026
              obstack_grow (&string_obstack, fn, strlen (fn));
1027
              sprintf (line_name, ":%d", read_md_lineno);
1028
              obstack_grow (&string_obstack, line_name, strlen (line_name)+1);
1029
              stringbuf = XOBFINISH (&string_obstack, char *);
1030
            }
1031
 
1032
          if (star_if_braced)
1033
            XTMPL (return_rtx, i) = stringbuf;
1034
          else
1035
            XSTR (return_rtx, i) = stringbuf;
1036
        }
1037
        break;
1038
 
1039
      case 'w':
1040
        read_name (&name);
1041
        validate_const_int (name.string);
1042
#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
1043
        tmp_wide = atoi (name.string);
1044
#else
1045
#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
1046
        tmp_wide = atol (name.string);
1047
#else
1048
        /* Prefer atoll over atoq, since the former is in the ISO C99 standard.
1049
           But prefer not to use our hand-rolled function above either.  */
1050
#if defined(HAVE_ATOLL) || !defined(HAVE_ATOQ)
1051
        tmp_wide = atoll (name.string);
1052
#else
1053
        tmp_wide = atoq (name.string);
1054
#endif
1055
#endif
1056
#endif
1057
        XWINT (return_rtx, i) = tmp_wide;
1058
        break;
1059
 
1060
      case 'i':
1061
      case 'n':
1062
        read_name (&name);
1063
        validate_const_int (name.string);
1064
        tmp_int = atoi (name.string);
1065
        XINT (return_rtx, i) = tmp_int;
1066
        break;
1067
 
1068
      default:
1069
        gcc_unreachable ();
1070
      }
1071
 
1072
  c = read_skip_spaces ();
1073
  /* Syntactic sugar for AND and IOR, allowing Lisp-like
1074
     arbitrary number of arguments for them.  */
1075
  if (c == '('
1076
      && (GET_CODE (return_rtx) == AND
1077
          || GET_CODE (return_rtx) == IOR))
1078
    return read_rtx_variadic (mode_maps, return_rtx);
1079
 
1080
  unread_char (c);
1081
  return return_rtx;
1082
}
1083
 
1084
/* Read a nested rtx construct from the MD file and return it.
1085
   MODE_MAPS is as for iterator_traverse_data.  */
1086
 
1087
static rtx
1088
read_nested_rtx (struct map_value **mode_maps)
1089
{
1090
  struct md_name name;
1091
  int c;
1092
  rtx return_rtx;
1093
 
1094
  c = read_skip_spaces ();
1095
  if (c != '(')
1096
    fatal_expected_char ('(', c);
1097
 
1098
  read_name (&name);
1099
  if (strcmp (name.string, "nil") == 0)
1100
    return_rtx = NULL;
1101
  else
1102
    return_rtx = read_rtx_code (name.string, mode_maps);
1103
 
1104
  c = read_skip_spaces ();
1105
  if (c != ')')
1106
    fatal_expected_char (')', c);
1107
 
1108
  return return_rtx;
1109
}
1110
 
1111
/* Mutually recursive subroutine of read_rtx which reads
1112
   (thing x1 x2 x3 ...) and produces RTL as if
1113
   (thing x1 (thing x2 (thing x3 ...)))  had been written.
1114
   When called, FORM is (thing x1 x2), and the file position
1115
   is just past the leading parenthesis of x3.  Only works
1116
   for THINGs which are dyadic expressions, e.g. AND, IOR.  */
1117
static rtx
1118
read_rtx_variadic (struct map_value **mode_maps, rtx form)
1119
{
1120
  char c = '(';
1121
  rtx p = form, q;
1122
 
1123
  do
1124
    {
1125
      unread_char (c);
1126
 
1127
      q = rtx_alloc (GET_CODE (p));
1128
      PUT_MODE (q, GET_MODE (p));
1129
 
1130
      XEXP (q, 0) = XEXP (p, 1);
1131
      XEXP (q, 1) = read_nested_rtx (mode_maps);
1132
 
1133
      XEXP (p, 1) = q;
1134
      p = q;
1135
      c = read_skip_spaces ();
1136
    }
1137
  while (c == '(');
1138
  unread_char (c);
1139
  return form;
1140
}

powered by: WebSVN 2.1.0

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