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

Subversion Repositories openrisc_me

[/] [openrisc/] [trunk/] [gnu-src/] [gcc-4.5.1/] [gcc/] [read-rtl.c] - Blame information for rev 280

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 280 jeremybenn
/* RTL reader for GCC.
2
   Copyright (C) 1987, 1988, 1991, 1994, 1997, 1998, 1999, 2000, 2001, 2002,
3
   2003, 2004, 2005, 2007, 2008
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 "gensupport.h"
34
 
35
static htab_t md_constants;
36
 
37
/* One element in a singly-linked list of (integer, string) pairs.  */
38
struct map_value {
39
  struct map_value *next;
40
  int number;
41
  const char *string;
42
};
43
 
44
/* Maps an iterator or attribute name to a list of (integer, string) pairs.
45
   The integers are mode or code values; the strings are either C conditions
46
   or attribute values.  */
47
struct mapping {
48
  /* The name of the iterator or attribute.  */
49
  const char *name;
50
 
51
  /* The group (modes or codes) to which the iterator or attribute belongs.  */
52
  struct iterator_group *group;
53
 
54
  /* Gives a unique number to the attribute or iterator.  Numbers are
55
     allocated consecutively, starting at 0.  */
56
  int index;
57
 
58
  /* The list of (integer, string) pairs.  */
59
  struct map_value *values;
60
};
61
 
62
/* A structure for abstracting the common parts of code and mode iterators.  */
63
struct iterator_group {
64
  /* Tables of "mapping" structures, one for attributes and one for iterators.  */
65
  htab_t attrs, iterators;
66
 
67
  /* The number of "real" modes or codes (and by extension, the first
68
     number available for use as an iterator placeholder).  */
69
  int num_builtins;
70
 
71
  /* Treat the given string as the name of a standard mode or code and
72
     return its integer value.  Use the given file for error reporting.  */
73
  int (*find_builtin) (const char *, FILE *);
74
 
75
  /* Return true if the given rtx uses the given mode or code.  */
76
  bool (*uses_iterator_p) (rtx, int);
77
 
78
  /* Make the given rtx use the given mode or code.  */
79
  void (*apply_iterator) (rtx, int);
80
};
81
 
82
/* Associates PTR (which can be a string, etc.) with the file location
83
   specified by FILENAME and LINENO.  */
84
struct ptr_loc {
85
  const void *ptr;
86
  const char *filename;
87
  int lineno;
88
};
89
 
90
/* A structure used to pass data from read_rtx to apply_iterator_traverse
91
   via htab_traverse.  */
92
struct iterator_traverse_data {
93
  /* Instruction queue.  */
94
  rtx queue;
95
  /* Attributes seen for modes.  */
96
  struct map_value *mode_maps;
97
  /* Input file.  */
98
  FILE *infile;
99
  /* The last unknown attribute used as a mode.  */
100
  const char *unknown_mode_attr;
101
};
102
 
103
/* If CODE is the number of a code iterator, return a real rtx code that
104
   has the same format.  Return CODE otherwise.  */
105
#define BELLWETHER_CODE(CODE) \
106
  ((CODE) < NUM_RTX_CODE ? CODE : bellwether_codes[CODE - NUM_RTX_CODE])
107
 
108
static void fatal_with_file_and_line (FILE *, const char *, ...)
109
  ATTRIBUTE_PRINTF_2 ATTRIBUTE_NORETURN;
110
static void fatal_expected_char (FILE *, int, int) ATTRIBUTE_NORETURN;
111
static int find_mode (const char *, FILE *);
112
static bool uses_mode_iterator_p (rtx, int);
113
static void apply_mode_iterator (rtx, int);
114
static int find_code (const char *, FILE *);
115
static bool uses_code_iterator_p (rtx, int);
116
static void apply_code_iterator (rtx, int);
117
static const char *apply_iterator_to_string (const char *, struct mapping *, int);
118
static rtx apply_iterator_to_rtx (rtx, struct mapping *, int,
119
                                  struct map_value *, FILE *, const char **);
120
static bool uses_iterator_p (rtx, struct mapping *);
121
static const char *add_condition_to_string (const char *, const char *);
122
static void add_condition_to_rtx (rtx, const char *);
123
static int apply_iterator_traverse (void **, void *);
124
static struct mapping *add_mapping (struct iterator_group *, htab_t t,
125
                                    const char *, FILE *);
126
static struct map_value **add_map_value (struct map_value **,
127
                                         int, const char *);
128
static void initialize_iterators (void);
129
static void read_name (char *, FILE *);
130
static hashval_t leading_ptr_hash (const void *);
131
static int leading_ptr_eq_p (const void *, const void *);
132
static void set_rtx_ptr_loc (const void *, const char *, int);
133
static const struct ptr_loc *get_rtx_ptr_loc (const void *);
134
static char *read_string (FILE *, int);
135
static char *read_quoted_string (FILE *);
136
static char *read_braced_string (FILE *);
137
static void read_escape (FILE *);
138
static hashval_t def_hash (const void *);
139
static int def_name_eq_p (const void *, const void *);
140
static void read_constants (FILE *infile, char *tmp_char);
141
static void read_conditions (FILE *infile, char *tmp_char);
142
static void validate_const_int (FILE *, const char *);
143
static int find_iterator (struct iterator_group *, const char *, FILE *);
144
static struct mapping *read_mapping (struct iterator_group *, htab_t, FILE *);
145
static void check_code_iterator (struct mapping *, FILE *);
146
static rtx read_rtx_1 (FILE *, struct map_value **);
147
static rtx read_rtx_variadic (FILE *, struct map_value **, rtx);
148
 
149
/* The mode and code iterator structures.  */
150
static struct iterator_group modes, codes;
151
 
152
/* Index I is the value of BELLWETHER_CODE (I + NUM_RTX_CODE).  */
153
static enum rtx_code *bellwether_codes;
154
 
155
/* Obstack used for allocating RTL strings.  */
156
static struct obstack string_obstack;
157
 
158
/* A table of ptr_locs, hashed on the PTR field.  */
159
static htab_t ptr_locs;
160
 
161
/* An obstack for the above.  Plain xmalloc is a bit heavyweight for a
162
   small structure like ptr_loc.  */
163
static struct obstack ptr_loc_obstack;
164
 
165
/* A hash table of triples (A, B, C), where each of A, B and C is a condition
166
   and A is equivalent to "B && C".  This is used to keep track of the source
167
   of conditions that are made up of separate rtx strings (such as the split
168
   condition of a define_insn_and_split).  */
169
static htab_t joined_conditions;
170
 
171
/* An obstack for allocating joined_conditions entries.  */
172
static struct obstack joined_conditions_obstack;
173
 
174
/* Subroutines of read_rtx.  */
175
 
176
/* The current line number for the file.  */
177
int read_rtx_lineno = 1;
178
 
179
/* The filename for error reporting.  */
180
const char *read_rtx_filename = "<unknown>";
181
 
182
static void
183
fatal_with_file_and_line (FILE *infile, const char *msg, ...)
184
{
185
  char context[64];
186
  size_t i;
187
  int c;
188
  va_list ap;
189
 
190
  va_start (ap, msg);
191
 
192
  fprintf (stderr, "%s:%d: ", read_rtx_filename, read_rtx_lineno);
193
  vfprintf (stderr, msg, ap);
194
  putc ('\n', stderr);
195
 
196
  /* Gather some following context.  */
197
  for (i = 0; i < sizeof (context)-1; ++i)
198
    {
199
      c = getc (infile);
200
      if (c == EOF)
201
        break;
202
      if (c == '\r' || c == '\n')
203
        break;
204
      context[i] = c;
205
    }
206
  context[i] = '\0';
207
 
208
  fprintf (stderr, "%s:%d: following context is `%s'\n",
209
           read_rtx_filename, read_rtx_lineno, context);
210
 
211
  va_end (ap);
212
  exit (1);
213
}
214
 
215
/* Dump code after printing a message.  Used when read_rtx finds
216
   invalid data.  */
217
 
218
static void
219
fatal_expected_char (FILE *infile, int expected_c, int actual_c)
220
{
221
  if (actual_c == EOF)
222
    fatal_with_file_and_line (infile, "expected character `%c', found EOF",
223
                              expected_c);
224
  else
225
    fatal_with_file_and_line (infile, "expected character `%c', found `%c'",
226
                              expected_c, actual_c);
227
}
228
 
229
/* Implementations of the iterator_group callbacks for modes.  */
230
 
231
static int
232
find_mode (const char *name, FILE *infile)
233
{
234
  int i;
235
 
236
  for (i = 0; i < NUM_MACHINE_MODES; i++)
237
    if (strcmp (GET_MODE_NAME (i), name) == 0)
238
      return i;
239
 
240
  fatal_with_file_and_line (infile, "unknown mode `%s'", name);
241
}
242
 
243
static bool
244
uses_mode_iterator_p (rtx x, int mode)
245
{
246
  return (int) GET_MODE (x) == mode;
247
}
248
 
249
static void
250
apply_mode_iterator (rtx x, int mode)
251
{
252
  PUT_MODE (x, (enum machine_mode) mode);
253
}
254
 
255
/* Implementations of the iterator_group callbacks for codes.  */
256
 
257
static int
258
find_code (const char *name, FILE *infile)
259
{
260
  int i;
261
 
262
  for (i = 0; i < NUM_RTX_CODE; i++)
263
    if (strcmp (GET_RTX_NAME (i), name) == 0)
264
      return i;
265
 
266
  fatal_with_file_and_line (infile, "unknown rtx code `%s'", name);
267
}
268
 
269
static bool
270
uses_code_iterator_p (rtx x, int code)
271
{
272
  return (int) GET_CODE (x) == code;
273
}
274
 
275
static void
276
apply_code_iterator (rtx x, int code)
277
{
278
  PUT_CODE (x, (enum rtx_code) code);
279
}
280
 
281
/* Map a code or mode attribute string P to the underlying string for
282
   ITERATOR and VALUE.  */
283
 
284
static struct map_value *
285
map_attr_string (const char *p, struct mapping *iterator, int value)
286
{
287
  const char *attr;
288
  struct mapping *m;
289
  struct map_value *v;
290
 
291
  /* If there's a "iterator:" prefix, check whether the iterator name matches.
292
     Set ATTR to the start of the attribute name.  */
293
  attr = strchr (p, ':');
294
  if (attr == 0)
295
    attr = p;
296
  else
297
    {
298
      if (strncmp (p, iterator->name, attr - p) != 0
299
          || iterator->name[attr - p] != 0)
300
        return 0;
301
      attr++;
302
    }
303
 
304
  /* Find the attribute specification.  */
305
  m = (struct mapping *) htab_find (iterator->group->attrs, &attr);
306
  if (m == 0)
307
    return 0;
308
 
309
  /* Find the attribute value for VALUE.  */
310
  for (v = m->values; v != 0; v = v->next)
311
    if (v->number == value)
312
      break;
313
 
314
  return v;
315
}
316
 
317
/* Given an attribute string used as a machine mode, return an index
318
   to store in the machine mode to be translated by
319
   apply_iterator_to_rtx.  */
320
 
321
static unsigned int
322
mode_attr_index (struct map_value **mode_maps, const char *string)
323
{
324
  char *p;
325
  struct map_value *mv;
326
 
327
  /* Copy the attribute string into permanent storage, without the
328
     angle brackets around it.  */
329
  obstack_grow0 (&string_obstack, string + 1, strlen (string) - 2);
330
  p = XOBFINISH (&string_obstack, char *);
331
 
332
  mv = XNEW (struct map_value);
333
  mv->number = *mode_maps == 0 ? 0 : (*mode_maps)->number + 1;
334
  mv->string = p;
335
  mv->next = *mode_maps;
336
  *mode_maps = mv;
337
 
338
  /* We return a code which we can map back into this string: the
339
     number of machine modes + the number of mode iterators + the index
340
     we just used.  */
341
  return MAX_MACHINE_MODE + htab_elements (modes.iterators) + mv->number;
342
}
343
 
344
/* Apply MODE_MAPS to the top level of X, expanding cases where an
345
   attribute is used for a mode.  ITERATOR is the current iterator we are
346
   expanding, and VALUE is the value to which we are expanding it.
347
   INFILE is used for error messages.  This sets *UNKNOWN to true if
348
   we find a mode attribute which has not yet been defined, and does
349
   not change it otherwise.  */
350
 
351
static void
352
apply_mode_maps (rtx x, struct map_value *mode_maps, struct mapping *iterator,
353
                 int value, FILE *infile, const char **unknown)
354
{
355
  unsigned int offset;
356
  int indx;
357
  struct map_value *pm;
358
 
359
  offset = MAX_MACHINE_MODE + htab_elements (modes.iterators);
360
  if (GET_MODE (x) < offset)
361
    return;
362
 
363
  indx = GET_MODE (x) - offset;
364
  for (pm = mode_maps; pm; pm = pm->next)
365
    {
366
      if (pm->number == indx)
367
        {
368
          struct map_value *v;
369
 
370
          v = map_attr_string (pm->string, iterator, value);
371
          if (v)
372
            PUT_MODE (x, (enum machine_mode) find_mode (v->string, infile));
373
          else
374
            *unknown = pm->string;
375
          return;
376
        }
377
    }
378
}
379
 
380
/* Given that ITERATOR is being expanded as VALUE, apply the appropriate
381
   string substitutions to STRING.  Return the new string if any changes
382
   were needed, otherwise return STRING itself.  */
383
 
384
static const char *
385
apply_iterator_to_string (const char *string, struct mapping *iterator, int value)
386
{
387
  char *base, *copy, *p, *start, *end;
388
  struct map_value *v;
389
 
390
  if (string == 0)
391
    return string;
392
 
393
  base = p = copy = ASTRDUP (string);
394
  while ((start = strchr (p, '<')) && (end = strchr (start, '>')))
395
    {
396
      p = start + 1;
397
 
398
      *end = 0;
399
      v = map_attr_string (p, iterator, value);
400
      *end = '>';
401
      if (v == 0)
402
        continue;
403
 
404
      /* Add everything between the last copied byte and the '<',
405
         then add in the attribute value.  */
406
      obstack_grow (&string_obstack, base, start - base);
407
      obstack_grow (&string_obstack, v->string, strlen (v->string));
408
      base = end + 1;
409
    }
410
  if (base != copy)
411
    {
412
      obstack_grow (&string_obstack, base, strlen (base) + 1);
413
      copy = XOBFINISH (&string_obstack, char *);
414
      copy_rtx_ptr_loc (copy, string);
415
      return copy;
416
    }
417
  return string;
418
}
419
 
420
/* Return a copy of ORIGINAL in which all uses of ITERATOR have been
421
   replaced by VALUE.  MODE_MAPS holds information about attribute
422
   strings used for modes.  INFILE is used for error messages.  This
423
   sets *UNKNOWN_MODE_ATTR to the value of an unknown mode attribute,
424
   and does not change it otherwise.  */
425
 
426
static rtx
427
apply_iterator_to_rtx (rtx original, struct mapping *iterator, int value,
428
                       struct map_value *mode_maps, FILE *infile,
429
                       const char **unknown_mode_attr)
430
{
431
  struct iterator_group *group;
432
  const char *format_ptr;
433
  int i, j;
434
  rtx x;
435
  enum rtx_code bellwether_code;
436
 
437
  if (original == 0)
438
    return original;
439
 
440
  /* Create a shallow copy of ORIGINAL.  */
441
  bellwether_code = BELLWETHER_CODE (GET_CODE (original));
442
  x = rtx_alloc (bellwether_code);
443
  memcpy (x, original, RTX_CODE_SIZE (bellwether_code));
444
 
445
  /* Change the mode or code itself.  */
446
  group = iterator->group;
447
  if (group->uses_iterator_p (x, iterator->index + group->num_builtins))
448
    group->apply_iterator (x, value);
449
 
450
  if (mode_maps)
451
    apply_mode_maps (x, mode_maps, iterator, value, infile, unknown_mode_attr);
452
 
453
  /* Change each string and recursively change each rtx.  */
454
  format_ptr = GET_RTX_FORMAT (bellwether_code);
455
  for (i = 0; format_ptr[i] != 0; i++)
456
    switch (format_ptr[i])
457
      {
458
      case 'T':
459
        XTMPL (x, i) = apply_iterator_to_string (XTMPL (x, i), iterator, value);
460
        break;
461
 
462
      case 'S':
463
      case 's':
464
        XSTR (x, i) = apply_iterator_to_string (XSTR (x, i), iterator, value);
465
        break;
466
 
467
      case 'e':
468
        XEXP (x, i) = apply_iterator_to_rtx (XEXP (x, i), iterator, value,
469
                                             mode_maps, infile,
470
                                             unknown_mode_attr);
471
        break;
472
 
473
      case 'V':
474
      case 'E':
475
        if (XVEC (original, i))
476
          {
477
            XVEC (x, i) = rtvec_alloc (XVECLEN (original, i));
478
            for (j = 0; j < XVECLEN (x, i); j++)
479
              XVECEXP (x, i, j) = apply_iterator_to_rtx (XVECEXP (original, i, j),
480
                                                         iterator, value, mode_maps,
481
                                                         infile,
482
                                                         unknown_mode_attr);
483
          }
484
        break;
485
 
486
      default:
487
        break;
488
      }
489
  return x;
490
}
491
 
492
/* Return true if X (or some subexpression of X) uses iterator ITERATOR.  */
493
 
494
static bool
495
uses_iterator_p (rtx x, struct mapping *iterator)
496
{
497
  struct iterator_group *group;
498
  const char *format_ptr;
499
  int i, j;
500
 
501
  if (x == 0)
502
    return false;
503
 
504
  group = iterator->group;
505
  if (group->uses_iterator_p (x, iterator->index + group->num_builtins))
506
    return true;
507
 
508
  format_ptr = GET_RTX_FORMAT (BELLWETHER_CODE (GET_CODE (x)));
509
  for (i = 0; format_ptr[i] != 0; i++)
510
    switch (format_ptr[i])
511
      {
512
      case 'e':
513
        if (uses_iterator_p (XEXP (x, i), iterator))
514
          return true;
515
        break;
516
 
517
      case 'V':
518
      case 'E':
519
        if (XVEC (x, i))
520
          for (j = 0; j < XVECLEN (x, i); j++)
521
            if (uses_iterator_p (XVECEXP (x, i, j), iterator))
522
              return true;
523
        break;
524
 
525
      default:
526
        break;
527
      }
528
  return false;
529
}
530
 
531
/* Return a condition that must satisfy both ORIGINAL and EXTRA.  If ORIGINAL
532
   has the form "&& ..." (as used in define_insn_and_splits), assume that
533
   EXTRA is already satisfied.  Empty strings are treated like "true".  */
534
 
535
static const char *
536
add_condition_to_string (const char *original, const char *extra)
537
{
538
  if (original != 0 && original[0] == '&' && original[1] == '&')
539
    return original;
540
  return join_c_conditions (original, extra);
541
}
542
 
543
/* Like add_condition, but applied to all conditions in rtx X.  */
544
 
545
static void
546
add_condition_to_rtx (rtx x, const char *extra)
547
{
548
  switch (GET_CODE (x))
549
    {
550
    case DEFINE_INSN:
551
    case DEFINE_EXPAND:
552
      XSTR (x, 2) = add_condition_to_string (XSTR (x, 2), extra);
553
      break;
554
 
555
    case DEFINE_SPLIT:
556
    case DEFINE_PEEPHOLE:
557
    case DEFINE_PEEPHOLE2:
558
    case DEFINE_COND_EXEC:
559
      XSTR (x, 1) = add_condition_to_string (XSTR (x, 1), extra);
560
      break;
561
 
562
    case DEFINE_INSN_AND_SPLIT:
563
      XSTR (x, 2) = add_condition_to_string (XSTR (x, 2), extra);
564
      XSTR (x, 4) = add_condition_to_string (XSTR (x, 4), extra);
565
      break;
566
 
567
    default:
568
      break;
569
    }
570
}
571
 
572
/* A htab_traverse callback.  Search the EXPR_LIST given by DATA
573
   for rtxes that use the iterator in *SLOT.  Replace each such rtx
574
   with a list of expansions.  */
575
 
576
static int
577
apply_iterator_traverse (void **slot, void *data)
578
{
579
  struct iterator_traverse_data *mtd = (struct iterator_traverse_data *) data;
580
  struct mapping *iterator;
581
  struct map_value *v;
582
  rtx elem, new_elem, original, x;
583
 
584
  iterator = (struct mapping *) *slot;
585
  for (elem = mtd->queue; elem != 0; elem = XEXP (elem, 1))
586
    if (uses_iterator_p (XEXP (elem, 0), iterator))
587
      {
588
        /* For each iterator we expand, we set UNKNOWN_MODE_ATTR to NULL.
589
           If apply_iterator_rtx finds an unknown attribute for a mode,
590
           it will set it to the attribute.  We want to know whether
591
           the attribute is unknown after we have expanded all
592
           possible iterators, so setting it to NULL here gives us the
593
           right result when the hash table traversal is complete.  */
594
        mtd->unknown_mode_attr = NULL;
595
 
596
        original = XEXP (elem, 0);
597
        for (v = iterator->values; v != 0; v = v->next)
598
          {
599
            x = apply_iterator_to_rtx (original, iterator, v->number,
600
                                       mtd->mode_maps, mtd->infile,
601
                                       &mtd->unknown_mode_attr);
602
            add_condition_to_rtx (x, v->string);
603
            if (v != iterator->values)
604
              {
605
                /* Insert a new EXPR_LIST node after ELEM and put the
606
                   new expansion there.  */
607
                new_elem = rtx_alloc (EXPR_LIST);
608
                XEXP (new_elem, 1) = XEXP (elem, 1);
609
                XEXP (elem, 1) = new_elem;
610
                elem = new_elem;
611
              }
612
            XEXP (elem, 0) = x;
613
          }
614
    }
615
  return 1;
616
}
617
 
618
/* Add a new "mapping" structure to hashtable TABLE.  NAME is the name
619
   of the mapping, GROUP is the group to which it belongs, and INFILE
620
   is the file that defined the mapping.  */
621
 
622
static struct mapping *
623
add_mapping (struct iterator_group *group, htab_t table,
624
             const char *name, FILE *infile)
625
{
626
  struct mapping *m;
627
  void **slot;
628
 
629
  m = XNEW (struct mapping);
630
  m->name = xstrdup (name);
631
  m->group = group;
632
  m->index = htab_elements (table);
633
  m->values = 0;
634
 
635
  slot = htab_find_slot (table, m, INSERT);
636
  if (*slot != 0)
637
    fatal_with_file_and_line (infile, "`%s' already defined", name);
638
 
639
  *slot = m;
640
  return m;
641
}
642
 
643
/* Add the pair (NUMBER, STRING) to a list of map_value structures.
644
   END_PTR points to the current null terminator for the list; return
645
   a pointer the new null terminator.  */
646
 
647
static struct map_value **
648
add_map_value (struct map_value **end_ptr, int number, const char *string)
649
{
650
  struct map_value *value;
651
 
652
  value = XNEW (struct map_value);
653
  value->next = 0;
654
  value->number = number;
655
  value->string = string;
656
 
657
  *end_ptr = value;
658
  return &value->next;
659
}
660
 
661
/* Do one-time initialization of the mode and code attributes.  */
662
 
663
static void
664
initialize_iterators (void)
665
{
666
  struct mapping *lower, *upper;
667
  struct map_value **lower_ptr, **upper_ptr;
668
  char *copy, *p;
669
  int i;
670
 
671
  modes.attrs = htab_create (13, def_hash, def_name_eq_p, 0);
672
  modes.iterators = htab_create (13, def_hash, def_name_eq_p, 0);
673
  modes.num_builtins = MAX_MACHINE_MODE;
674
  modes.find_builtin = find_mode;
675
  modes.uses_iterator_p = uses_mode_iterator_p;
676
  modes.apply_iterator = apply_mode_iterator;
677
 
678
  codes.attrs = htab_create (13, def_hash, def_name_eq_p, 0);
679
  codes.iterators = htab_create (13, def_hash, def_name_eq_p, 0);
680
  codes.num_builtins = NUM_RTX_CODE;
681
  codes.find_builtin = find_code;
682
  codes.uses_iterator_p = uses_code_iterator_p;
683
  codes.apply_iterator = apply_code_iterator;
684
 
685
  lower = add_mapping (&modes, modes.attrs, "mode", 0);
686
  upper = add_mapping (&modes, modes.attrs, "MODE", 0);
687
  lower_ptr = &lower->values;
688
  upper_ptr = &upper->values;
689
  for (i = 0; i < MAX_MACHINE_MODE; i++)
690
    {
691
      copy = xstrdup (GET_MODE_NAME (i));
692
      for (p = copy; *p != 0; p++)
693
        *p = TOLOWER (*p);
694
 
695
      upper_ptr = add_map_value (upper_ptr, i, GET_MODE_NAME (i));
696
      lower_ptr = add_map_value (lower_ptr, i, copy);
697
    }
698
 
699
  lower = add_mapping (&codes, codes.attrs, "code", 0);
700
  upper = add_mapping (&codes, codes.attrs, "CODE", 0);
701
  lower_ptr = &lower->values;
702
  upper_ptr = &upper->values;
703
  for (i = 0; i < NUM_RTX_CODE; i++)
704
    {
705
      copy = xstrdup (GET_RTX_NAME (i));
706
      for (p = copy; *p != 0; p++)
707
        *p = TOUPPER (*p);
708
 
709
      lower_ptr = add_map_value (lower_ptr, i, GET_RTX_NAME (i));
710
      upper_ptr = add_map_value (upper_ptr, i, copy);
711
    }
712
}
713
 
714
/* Return a hash value for the pointer pointed to by DEF.  */
715
 
716
static hashval_t
717
leading_ptr_hash (const void *def)
718
{
719
  return htab_hash_pointer (*(const void *const *) def);
720
}
721
 
722
/* Return true if DEF1 and DEF2 are pointers to the same pointer.  */
723
 
724
static int
725
leading_ptr_eq_p (const void *def1, const void *def2)
726
{
727
  return *(const void *const *) def1 == *(const void *const *) def2;
728
}
729
 
730
/* Associate PTR with the file position given by FILENAME and LINENO.  */
731
 
732
static void
733
set_rtx_ptr_loc (const void *ptr, const char *filename, int lineno)
734
{
735
  struct ptr_loc *loc;
736
 
737
  loc = (struct ptr_loc *) obstack_alloc (&ptr_loc_obstack,
738
                                          sizeof (struct ptr_loc));
739
  loc->ptr = ptr;
740
  loc->filename = filename;
741
  loc->lineno = lineno;
742
  *htab_find_slot (ptr_locs, loc, INSERT) = loc;
743
}
744
 
745
/* Return the position associated with pointer PTR.  Return null if no
746
   position was set.  */
747
 
748
static const struct ptr_loc *
749
get_rtx_ptr_loc (const void *ptr)
750
{
751
  return (const struct ptr_loc *) htab_find (ptr_locs, &ptr);
752
}
753
 
754
/* Associate NEW_PTR with the same file position as OLD_PTR.  */
755
 
756
void
757
copy_rtx_ptr_loc (const void *new_ptr, const void *old_ptr)
758
{
759
  const struct ptr_loc *loc = get_rtx_ptr_loc (old_ptr);
760
  if (loc != 0)
761
    set_rtx_ptr_loc (new_ptr, loc->filename, loc->lineno);
762
}
763
 
764
/* If PTR is associated with a known file position, print a #line
765
   directive for it.  */
766
 
767
void
768
print_rtx_ptr_loc (const void *ptr)
769
{
770
  const struct ptr_loc *loc = get_rtx_ptr_loc (ptr);
771
  if (loc != 0)
772
    printf ("#line %d \"%s\"\n", loc->lineno, loc->filename);
773
}
774
 
775
/* Return a condition that satisfies both COND1 and COND2.  Either string
776
   may be null or empty.  */
777
 
778
const char *
779
join_c_conditions (const char *cond1, const char *cond2)
780
{
781
  char *result;
782
  const void **entry;
783
 
784
  if (cond1 == 0 || cond1[0] == 0)
785
    return cond2;
786
 
787
  if (cond2 == 0 || cond2[0] == 0)
788
    return cond1;
789
 
790
  if (strcmp (cond1, cond2) == 0)
791
    return cond1;
792
 
793
  result = concat ("(", cond1, ") && (", cond2, ")", NULL);
794
  obstack_ptr_grow (&joined_conditions_obstack, result);
795
  obstack_ptr_grow (&joined_conditions_obstack, cond1);
796
  obstack_ptr_grow (&joined_conditions_obstack, cond2);
797
  entry = XOBFINISH (&joined_conditions_obstack, const void **);
798
  *htab_find_slot (joined_conditions, entry, INSERT) = entry;
799
  return result;
800
}
801
 
802
/* Print condition COND, wrapped in brackets.  If COND was created by
803
   join_c_conditions, recursively invoke this function for the original
804
   conditions and join the result with "&&".  Otherwise print a #line
805
   directive for COND if its original file position is known.  */
806
 
807
void
808
print_c_condition (const char *cond)
809
{
810
  const char **halves = (const char **) htab_find (joined_conditions, &cond);
811
  if (halves != 0)
812
    {
813
      printf ("(");
814
      print_c_condition (halves[1]);
815
      printf (" && ");
816
      print_c_condition (halves[2]);
817
      printf (")");
818
    }
819
  else
820
    {
821
      putc ('\n', stdout);
822
      print_rtx_ptr_loc (cond);
823
      printf ("(%s)", cond);
824
    }
825
}
826
 
827
/* Read chars from INFILE until a non-whitespace char
828
   and return that.  Comments, both Lisp style and C style,
829
   are treated as whitespace.
830
   Tools such as genflags use this function.  */
831
 
832
int
833
read_skip_spaces (FILE *infile)
834
{
835
  int c;
836
 
837
  while (1)
838
    {
839
      c = getc (infile);
840
      switch (c)
841
        {
842
        case '\n':
843
          read_rtx_lineno++;
844
          break;
845
 
846
        case ' ': case '\t': case '\f': case '\r':
847
          break;
848
 
849
        case ';':
850
          do
851
            c = getc (infile);
852
          while (c != '\n' && c != EOF);
853
          read_rtx_lineno++;
854
          break;
855
 
856
        case '/':
857
          {
858
            int prevc;
859
            c = getc (infile);
860
            if (c != '*')
861
              fatal_expected_char (infile, '*', c);
862
 
863
            prevc = 0;
864
            while ((c = getc (infile)) && c != EOF)
865
              {
866
                if (c == '\n')
867
                   read_rtx_lineno++;
868
                else if (prevc == '*' && c == '/')
869
                  break;
870
                prevc = c;
871
              }
872
          }
873
          break;
874
 
875
        default:
876
          return c;
877
        }
878
    }
879
}
880
 
881
/* Read an rtx code name into the buffer STR[].
882
   It is terminated by any of the punctuation chars of rtx printed syntax.  */
883
 
884
static void
885
read_name (char *str, FILE *infile)
886
{
887
  char *p;
888
  int c;
889
 
890
  c = read_skip_spaces (infile);
891
 
892
  p = str;
893
  while (1)
894
    {
895
      if (c == ' ' || c == '\n' || c == '\t' || c == '\f' || c == '\r' || c == EOF)
896
        break;
897
      if (c == ':' || c == ')' || c == ']' || c == '"' || c == '/'
898
          || c == '(' || c == '[')
899
        {
900
          ungetc (c, infile);
901
          break;
902
        }
903
      *p++ = c;
904
      c = getc (infile);
905
    }
906
  if (p == str)
907
    fatal_with_file_and_line (infile, "missing name or number");
908
  if (c == '\n')
909
    read_rtx_lineno++;
910
 
911
  *p = 0;
912
 
913
  if (md_constants)
914
    {
915
      /* Do constant expansion.  */
916
      struct md_constant *def;
917
 
918
      p = str;
919
      do
920
        {
921
          struct md_constant tmp_def;
922
 
923
          tmp_def.name = p;
924
          def = (struct md_constant *) htab_find (md_constants, &tmp_def);
925
          if (def)
926
            p = def->value;
927
        } while (def);
928
      if (p != str)
929
        strcpy (str, p);
930
    }
931
}
932
 
933
/* Subroutine of the string readers.  Handles backslash escapes.
934
   Caller has read the backslash, but not placed it into the obstack.  */
935
static void
936
read_escape (FILE *infile)
937
{
938
  int c = getc (infile);
939
 
940
  switch (c)
941
    {
942
      /* Backslash-newline is replaced by nothing, as in C.  */
943
    case '\n':
944
      read_rtx_lineno++;
945
      return;
946
 
947
      /* \" \' \\ are replaced by the second character.  */
948
    case '\\':
949
    case '"':
950
    case '\'':
951
      break;
952
 
953
      /* Standard C string escapes:
954
         \a \b \f \n \r \t \v
955
         \[0-7] \x
956
         all are passed through to the output string unmolested.
957
         In normal use these wind up in a string constant processed
958
         by the C compiler, which will translate them appropriately.
959
         We do not bother checking that \[0-7] are followed by up to
960
         two octal digits, or that \x is followed by N hex digits.
961
         \? \u \U are left out because they are not in traditional C.  */
962
    case 'a': case 'b': case 'f': case 'n': case 'r': case 't': case 'v':
963
    case '0': case '1': case '2': case '3': case '4': case '5': case '6':
964
    case '7': case 'x':
965
      obstack_1grow (&string_obstack, '\\');
966
      break;
967
 
968
      /* \; makes stuff for a C string constant containing
969
         newline and tab.  */
970
    case ';':
971
      obstack_grow (&string_obstack, "\\n\\t", 4);
972
      return;
973
 
974
      /* pass anything else through, but issue a warning.  */
975
    default:
976
      fprintf (stderr, "%s:%d: warning: unrecognized escape \\%c\n",
977
               read_rtx_filename, read_rtx_lineno, c);
978
      obstack_1grow (&string_obstack, '\\');
979
      break;
980
    }
981
 
982
  obstack_1grow (&string_obstack, c);
983
}
984
 
985
 
986
/* Read a double-quoted string onto the obstack.  Caller has scanned
987
   the leading quote.  */
988
static char *
989
read_quoted_string (FILE *infile)
990
{
991
  int c;
992
 
993
  while (1)
994
    {
995
      c = getc (infile); /* Read the string  */
996
      if (c == '\n')
997
        read_rtx_lineno++;
998
      else if (c == '\\')
999
        {
1000
          read_escape (infile);
1001
          continue;
1002
        }
1003
      else if (c == '"' || c == EOF)
1004
        break;
1005
 
1006
      obstack_1grow (&string_obstack, c);
1007
    }
1008
 
1009
  obstack_1grow (&string_obstack, 0);
1010
  return XOBFINISH (&string_obstack, char *);
1011
}
1012
 
1013
/* Read a braced string (a la Tcl) onto the string obstack.  Caller
1014
   has scanned the leading brace.  Note that unlike quoted strings,
1015
   the outermost braces _are_ included in the string constant.  */
1016
static char *
1017
read_braced_string (FILE *infile)
1018
{
1019
  int c;
1020
  int brace_depth = 1;  /* caller-processed */
1021
  unsigned long starting_read_rtx_lineno = read_rtx_lineno;
1022
 
1023
  obstack_1grow (&string_obstack, '{');
1024
  while (brace_depth)
1025
    {
1026
      c = getc (infile); /* Read the string  */
1027
 
1028
      if (c == '\n')
1029
        read_rtx_lineno++;
1030
      else if (c == '{')
1031
        brace_depth++;
1032
      else if (c == '}')
1033
        brace_depth--;
1034
      else if (c == '\\')
1035
        {
1036
          read_escape (infile);
1037
          continue;
1038
        }
1039
      else if (c == EOF)
1040
        fatal_with_file_and_line
1041
          (infile, "missing closing } for opening brace on line %lu",
1042
           starting_read_rtx_lineno);
1043
 
1044
      obstack_1grow (&string_obstack, c);
1045
    }
1046
 
1047
  obstack_1grow (&string_obstack, 0);
1048
  return XOBFINISH (&string_obstack, char *);
1049
}
1050
 
1051
/* Read some kind of string constant.  This is the high-level routine
1052
   used by read_rtx.  It handles surrounding parentheses, leading star,
1053
   and dispatch to the appropriate string constant reader.  */
1054
 
1055
static char *
1056
read_string (FILE *infile, int star_if_braced)
1057
{
1058
  char *stringbuf;
1059
  int saw_paren = 0;
1060
  int c, old_lineno;
1061
 
1062
  c = read_skip_spaces (infile);
1063
  if (c == '(')
1064
    {
1065
      saw_paren = 1;
1066
      c = read_skip_spaces (infile);
1067
    }
1068
 
1069
  old_lineno = read_rtx_lineno;
1070
  if (c == '"')
1071
    stringbuf = read_quoted_string (infile);
1072
  else if (c == '{')
1073
    {
1074
      if (star_if_braced)
1075
        obstack_1grow (&string_obstack, '*');
1076
      stringbuf = read_braced_string (infile);
1077
    }
1078
  else
1079
    fatal_with_file_and_line (infile, "expected `\"' or `{', found `%c'", c);
1080
 
1081
  if (saw_paren)
1082
    {
1083
      c = read_skip_spaces (infile);
1084
      if (c != ')')
1085
        fatal_expected_char (infile, ')', c);
1086
    }
1087
 
1088
  set_rtx_ptr_loc (stringbuf, read_rtx_filename, old_lineno);
1089
  return stringbuf;
1090
}
1091
 
1092
/* Provide a version of a function to read a long long if the system does
1093
   not provide one.  */
1094
#if HOST_BITS_PER_WIDE_INT > HOST_BITS_PER_LONG && !defined(HAVE_ATOLL) && !defined(HAVE_ATOQ)
1095
HOST_WIDE_INT atoll (const char *);
1096
 
1097
HOST_WIDE_INT
1098
atoll (const char *p)
1099
{
1100
  int neg = 0;
1101
  HOST_WIDE_INT tmp_wide;
1102
 
1103
  while (ISSPACE (*p))
1104
    p++;
1105
  if (*p == '-')
1106
    neg = 1, p++;
1107
  else if (*p == '+')
1108
    p++;
1109
 
1110
  tmp_wide = 0;
1111
  while (ISDIGIT (*p))
1112
    {
1113
      HOST_WIDE_INT new_wide = tmp_wide*10 + (*p - '0');
1114
      if (new_wide < tmp_wide)
1115
        {
1116
          /* Return INT_MAX equiv on overflow.  */
1117
          tmp_wide = (~(unsigned HOST_WIDE_INT) 0) >> 1;
1118
          break;
1119
        }
1120
      tmp_wide = new_wide;
1121
      p++;
1122
    }
1123
 
1124
  if (neg)
1125
    tmp_wide = -tmp_wide;
1126
  return tmp_wide;
1127
}
1128
#endif
1129
 
1130
/* Given an object that starts with a char * name field, return a hash
1131
   code for its name.  */
1132
static hashval_t
1133
def_hash (const void *def)
1134
{
1135
  unsigned result, i;
1136
  const char *string = *(const char *const *) def;
1137
 
1138
  for (result = i = 0; *string++ != '\0'; i++)
1139
    result += ((unsigned char) *string << (i % CHAR_BIT));
1140
  return result;
1141
}
1142
 
1143
/* Given two objects that start with char * name fields, return true if
1144
   they have the same name.  */
1145
static int
1146
def_name_eq_p (const void *def1, const void *def2)
1147
{
1148
  return ! strcmp (*(const char *const *) def1,
1149
                   *(const char *const *) def2);
1150
}
1151
 
1152
/* INFILE is a FILE pointer to read text from.  TMP_CHAR is a buffer suitable
1153
   to read a name or number into.  Process a define_constants directive,
1154
   starting with the optional space after the "define_constants".  */
1155
static void
1156
read_constants (FILE *infile, char *tmp_char)
1157
{
1158
  int c;
1159
  htab_t defs;
1160
 
1161
  c = read_skip_spaces (infile);
1162
  if (c != '[')
1163
    fatal_expected_char (infile, '[', c);
1164
  defs = md_constants;
1165
  if (! defs)
1166
    defs = htab_create (32, def_hash, def_name_eq_p, (htab_del) 0);
1167
  /* Disable constant expansion during definition processing.  */
1168
  md_constants = 0;
1169
  while ( (c = read_skip_spaces (infile)) != ']')
1170
    {
1171
      struct md_constant *def;
1172
      void **entry_ptr;
1173
 
1174
      if (c != '(')
1175
        fatal_expected_char (infile, '(', c);
1176
      def = XNEW (struct md_constant);
1177
      def->name = tmp_char;
1178
      read_name (tmp_char, infile);
1179
      entry_ptr = htab_find_slot (defs, def, INSERT);
1180
      if (! *entry_ptr)
1181
        def->name = xstrdup (tmp_char);
1182
      c = read_skip_spaces (infile);
1183
      ungetc (c, infile);
1184
      read_name (tmp_char, infile);
1185
      if (! *entry_ptr)
1186
        {
1187
          def->value = xstrdup (tmp_char);
1188
          *entry_ptr = def;
1189
        }
1190
      else
1191
        {
1192
          def = (struct md_constant *) *entry_ptr;
1193
          if (strcmp (def->value, tmp_char))
1194
            fatal_with_file_and_line (infile,
1195
                                      "redefinition of %s, was %s, now %s",
1196
                                      def->name, def->value, tmp_char);
1197
        }
1198
      c = read_skip_spaces (infile);
1199
      if (c != ')')
1200
        fatal_expected_char (infile, ')', c);
1201
    }
1202
  md_constants = defs;
1203
  c = read_skip_spaces (infile);
1204
  if (c != ')')
1205
    fatal_expected_char (infile, ')', c);
1206
}
1207
 
1208
/* For every constant definition, call CALLBACK with two arguments:
1209
   a pointer a pointer to the constant definition and INFO.
1210
   Stops when CALLBACK returns zero.  */
1211
void
1212
traverse_md_constants (htab_trav callback, void *info)
1213
{
1214
  if (md_constants)
1215
    htab_traverse (md_constants, callback, info);
1216
}
1217
 
1218
/* INFILE is a FILE pointer to read text from.  TMP_CHAR is a buffer
1219
   suitable to read a name or number into.  Process a
1220
   define_conditions directive, starting with the optional space after
1221
   the "define_conditions".  The directive looks like this:
1222
 
1223
     (define_conditions [
1224
        (number "string")
1225
        (number "string")
1226
        ...
1227
     ])
1228
 
1229
   It's not intended to appear in machine descriptions.  It is
1230
   generated by (the program generated by) genconditions.c, and
1231
   slipped in at the beginning of the sequence of MD files read by
1232
   most of the other generators.  */
1233
static void
1234
read_conditions (FILE *infile, char *tmp_char)
1235
{
1236
  int c;
1237
 
1238
  c = read_skip_spaces (infile);
1239
  if (c != '[')
1240
    fatal_expected_char (infile, '[', c);
1241
 
1242
  while ( (c = read_skip_spaces (infile)) != ']')
1243
    {
1244
      char *expr;
1245
      int value;
1246
 
1247
      if (c != '(')
1248
        fatal_expected_char (infile, '(', c);
1249
 
1250
      read_name (tmp_char, infile);
1251
      validate_const_int (infile, tmp_char);
1252
      value = atoi (tmp_char);
1253
 
1254
      c = read_skip_spaces (infile);
1255
      if (c != '"')
1256
        fatal_expected_char (infile, '"', c);
1257
      expr = read_quoted_string (infile);
1258
 
1259
      c = read_skip_spaces (infile);
1260
      if (c != ')')
1261
        fatal_expected_char (infile, ')', c);
1262
 
1263
      add_c_test (expr, value);
1264
    }
1265
  c = read_skip_spaces (infile);
1266
  if (c != ')')
1267
    fatal_expected_char (infile, ')', c);
1268
}
1269
 
1270
static void
1271
validate_const_int (FILE *infile, const char *string)
1272
{
1273
  const char *cp;
1274
  int valid = 1;
1275
 
1276
  cp = string;
1277
  while (*cp && ISSPACE (*cp))
1278
    cp++;
1279
  if (*cp == '-' || *cp == '+')
1280
    cp++;
1281
  if (*cp == 0)
1282
    valid = 0;
1283
  for (; *cp; cp++)
1284
    if (! ISDIGIT (*cp))
1285
      valid = 0;
1286
  if (!valid)
1287
    fatal_with_file_and_line (infile, "invalid decimal constant \"%s\"\n", string);
1288
}
1289
 
1290
/* Search GROUP for a mode or code called NAME and return its numerical
1291
   identifier.  INFILE is the file that contained NAME.  */
1292
 
1293
static int
1294
find_iterator (struct iterator_group *group, const char *name, FILE *infile)
1295
{
1296
  struct mapping *m;
1297
 
1298
  m = (struct mapping *) htab_find (group->iterators, &name);
1299
  if (m != 0)
1300
    return m->index + group->num_builtins;
1301
  return group->find_builtin (name, infile);
1302
}
1303
 
1304
/* Finish reading a declaration of the form:
1305
 
1306
       (define... <name> [<value1> ... <valuen>])
1307
 
1308
   from INFILE, where each <valuei> is either a bare symbol name or a
1309
   "(<name> <string>)" pair.  The "(define..." part has already been read.
1310
 
1311
   Represent the declaration as a "mapping" structure; add it to TABLE
1312
   (which belongs to GROUP) and return it.  */
1313
 
1314
static struct mapping *
1315
read_mapping (struct iterator_group *group, htab_t table, FILE *infile)
1316
{
1317
  char tmp_char[256];
1318
  struct mapping *m;
1319
  struct map_value **end_ptr;
1320
  const char *string;
1321
  int number, c;
1322
 
1323
  /* Read the mapping name and create a structure for it.  */
1324
  read_name (tmp_char, infile);
1325
  m = add_mapping (group, table, tmp_char, infile);
1326
 
1327
  c = read_skip_spaces (infile);
1328
  if (c != '[')
1329
    fatal_expected_char (infile, '[', c);
1330
 
1331
  /* Read each value.  */
1332
  end_ptr = &m->values;
1333
  c = read_skip_spaces (infile);
1334
  do
1335
    {
1336
      if (c != '(')
1337
        {
1338
          /* A bare symbol name that is implicitly paired to an
1339
             empty string.  */
1340
          ungetc (c, infile);
1341
          read_name (tmp_char, infile);
1342
          string = "";
1343
        }
1344
      else
1345
        {
1346
          /* A "(name string)" pair.  */
1347
          read_name (tmp_char, infile);
1348
          string = read_string (infile, false);
1349
          c = read_skip_spaces (infile);
1350
          if (c != ')')
1351
            fatal_expected_char (infile, ')', c);
1352
        }
1353
      number = group->find_builtin (tmp_char, infile);
1354
      end_ptr = add_map_value (end_ptr, number, string);
1355
      c = read_skip_spaces (infile);
1356
    }
1357
  while (c != ']');
1358
 
1359
  c = read_skip_spaces (infile);
1360
  if (c != ')')
1361
    fatal_expected_char (infile, ')', c);
1362
 
1363
  return m;
1364
}
1365
 
1366
/* Check newly-created code iterator ITERATOR to see whether every code has the
1367
   same format.  Initialize the iterator's entry in bellwether_codes.  */
1368
 
1369
static void
1370
check_code_iterator (struct mapping *iterator, FILE *infile)
1371
{
1372
  struct map_value *v;
1373
  enum rtx_code bellwether;
1374
 
1375
  bellwether = (enum rtx_code) iterator->values->number;
1376
  for (v = iterator->values->next; v != 0; v = v->next)
1377
    if (strcmp (GET_RTX_FORMAT (bellwether), GET_RTX_FORMAT (v->number)) != 0)
1378
      fatal_with_file_and_line (infile, "code iterator `%s' combines "
1379
                                "different rtx formats", iterator->name);
1380
 
1381
  bellwether_codes = XRESIZEVEC (enum rtx_code, bellwether_codes,
1382
                                 iterator->index + 1);
1383
  bellwether_codes[iterator->index] = bellwether;
1384
}
1385
 
1386
/* Read an rtx in printed representation from INFILE and store its
1387
   core representation in *X.  Also store the line number of the
1388
   opening '(' in *LINENO.  Return true on success or false if the
1389
   end of file has been reached.
1390
 
1391
   read_rtx is not used in the compiler proper, but rather in
1392
   the utilities gen*.c that construct C code from machine descriptions.  */
1393
 
1394
bool
1395
read_rtx (FILE *infile, rtx *x, int *lineno)
1396
{
1397
  static rtx queue_head, queue_next;
1398
  static int queue_lineno;
1399
  int c;
1400
 
1401
  /* Do one-time initialization.  */
1402
  if (queue_head == 0)
1403
    {
1404
      initialize_iterators ();
1405
      obstack_init (&string_obstack);
1406
      queue_head = rtx_alloc (EXPR_LIST);
1407
      ptr_locs = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0);
1408
      obstack_init (&ptr_loc_obstack);
1409
      joined_conditions = htab_create (161, leading_ptr_hash,
1410
                                       leading_ptr_eq_p, 0);
1411
      obstack_init (&joined_conditions_obstack);
1412
    }
1413
 
1414
  if (queue_next == 0)
1415
    {
1416
      struct map_value *mode_maps;
1417
      struct iterator_traverse_data mtd;
1418
      rtx from_file;
1419
 
1420
      c = read_skip_spaces (infile);
1421
      if (c == EOF)
1422
        return false;
1423
      ungetc (c, infile);
1424
 
1425
      queue_lineno = read_rtx_lineno;
1426
      mode_maps = 0;
1427
      from_file = read_rtx_1 (infile, &mode_maps);
1428
      if (from_file == 0)
1429
        return false;  /* This confuses a top level (nil) with end of
1430
                          file, but a top level (nil) would have
1431
                          crashed our caller anyway.  */
1432
 
1433
      queue_next = queue_head;
1434
      XEXP (queue_next, 0) = from_file;
1435
      XEXP (queue_next, 1) = 0;
1436
 
1437
      mtd.queue = queue_next;
1438
      mtd.mode_maps = mode_maps;
1439
      mtd.infile = infile;
1440
      mtd.unknown_mode_attr = mode_maps ? mode_maps->string : NULL;
1441
      htab_traverse (modes.iterators, apply_iterator_traverse, &mtd);
1442
      htab_traverse (codes.iterators, apply_iterator_traverse, &mtd);
1443
      if (mtd.unknown_mode_attr)
1444
        fatal_with_file_and_line (infile,
1445
                                  "undefined attribute '%s' used for mode",
1446
                                  mtd.unknown_mode_attr);
1447
    }
1448
 
1449
  *x = XEXP (queue_next, 0);
1450
  *lineno = queue_lineno;
1451
  queue_next = XEXP (queue_next, 1);
1452
 
1453
  return true;
1454
}
1455
 
1456
/* Subroutine of read_rtx that reads one construct from INFILE but
1457
   doesn't apply any iterators.  */
1458
 
1459
static rtx
1460
read_rtx_1 (FILE *infile, struct map_value **mode_maps)
1461
{
1462
  int i;
1463
  RTX_CODE real_code, bellwether_code;
1464
  const char *format_ptr;
1465
  /* tmp_char is a buffer used for reading decimal integers
1466
     and names of rtx types and machine modes.
1467
     Therefore, 256 must be enough.  */
1468
  char tmp_char[256];
1469
  rtx return_rtx;
1470
  int c;
1471
  int tmp_int;
1472
  HOST_WIDE_INT tmp_wide;
1473
 
1474
  /* Linked list structure for making RTXs: */
1475
  struct rtx_list
1476
    {
1477
      struct rtx_list *next;
1478
      rtx value;                /* Value of this node.  */
1479
    };
1480
 
1481
 again:
1482
  c = read_skip_spaces (infile); /* Should be open paren.  */
1483
 
1484
  if (c == EOF)
1485
    return 0;
1486
 
1487
  if (c != '(')
1488
    fatal_expected_char (infile, '(', c);
1489
 
1490
  read_name (tmp_char, infile);
1491
  if (strcmp (tmp_char, "nil") == 0)
1492
    {
1493
      /* (nil) stands for an expression that isn't there.  */
1494
      c = read_skip_spaces (infile);
1495
      if (c != ')')
1496
        fatal_expected_char (infile, ')', c);
1497
      return 0;
1498
    }
1499
  if (strcmp (tmp_char, "define_constants") == 0)
1500
    {
1501
      read_constants (infile, tmp_char);
1502
      goto again;
1503
    }
1504
  if (strcmp (tmp_char, "define_conditions") == 0)
1505
    {
1506
      read_conditions (infile, tmp_char);
1507
      goto again;
1508
    }
1509
  if (strcmp (tmp_char, "define_mode_attr") == 0)
1510
    {
1511
      read_mapping (&modes, modes.attrs, infile);
1512
      goto again;
1513
    }
1514
  if (strcmp (tmp_char, "define_mode_iterator") == 0)
1515
    {
1516
      read_mapping (&modes, modes.iterators, infile);
1517
      goto again;
1518
    }
1519
  if (strcmp (tmp_char, "define_code_attr") == 0)
1520
    {
1521
      read_mapping (&codes, codes.attrs, infile);
1522
      goto again;
1523
    }
1524
  if (strcmp (tmp_char, "define_code_iterator") == 0)
1525
    {
1526
      check_code_iterator (read_mapping (&codes, codes.iterators, infile),
1527
                           infile);
1528
      goto again;
1529
    }
1530
  real_code = (enum rtx_code) find_iterator (&codes, tmp_char, infile);
1531
  bellwether_code = BELLWETHER_CODE (real_code);
1532
 
1533
  /* If we end up with an insn expression then we free this space below.  */
1534
  return_rtx = rtx_alloc (bellwether_code);
1535
  format_ptr = GET_RTX_FORMAT (bellwether_code);
1536
  PUT_CODE (return_rtx, real_code);
1537
 
1538
  /* If what follows is `: mode ', read it and
1539
     store the mode in the rtx.  */
1540
 
1541
  i = read_skip_spaces (infile);
1542
  if (i == ':')
1543
    {
1544
      unsigned int mode;
1545
 
1546
      read_name (tmp_char, infile);
1547
      if (tmp_char[0] != '<' || tmp_char[strlen (tmp_char) - 1] != '>')
1548
        mode = find_iterator (&modes, tmp_char, infile);
1549
      else
1550
        mode = mode_attr_index (mode_maps, tmp_char);
1551
      PUT_MODE (return_rtx, (enum machine_mode) mode);
1552
      if (GET_MODE (return_rtx) != mode)
1553
        fatal_with_file_and_line (infile, "mode too large");
1554
    }
1555
  else
1556
    ungetc (i, infile);
1557
 
1558
  for (i = 0; format_ptr[i] != 0; i++)
1559
    switch (format_ptr[i])
1560
      {
1561
        /* 0 means a field for internal use only.
1562
           Don't expect it to be present in the input.  */
1563
      case '0':
1564
        break;
1565
 
1566
      case 'e':
1567
      case 'u':
1568
        XEXP (return_rtx, i) = read_rtx_1 (infile, mode_maps);
1569
        break;
1570
 
1571
      case 'V':
1572
        /* 'V' is an optional vector: if a closeparen follows,
1573
           just store NULL for this element.  */
1574
        c = read_skip_spaces (infile);
1575
        ungetc (c, infile);
1576
        if (c == ')')
1577
          {
1578
            XVEC (return_rtx, i) = 0;
1579
            break;
1580
          }
1581
        /* Now process the vector.  */
1582
 
1583
      case 'E':
1584
        {
1585
          /* Obstack to store scratch vector in.  */
1586
          struct obstack vector_stack;
1587
          int list_counter = 0;
1588
          rtvec return_vec = NULL_RTVEC;
1589
 
1590
          c = read_skip_spaces (infile);
1591
          if (c != '[')
1592
            fatal_expected_char (infile, '[', c);
1593
 
1594
          /* Add expressions to a list, while keeping a count.  */
1595
          obstack_init (&vector_stack);
1596
          while ((c = read_skip_spaces (infile)) && c != ']')
1597
            {
1598
              if (c == EOF)
1599
                fatal_expected_char (infile, ']', c);
1600
              ungetc (c, infile);
1601
              list_counter++;
1602
              obstack_ptr_grow (&vector_stack, read_rtx_1 (infile, mode_maps));
1603
            }
1604
          if (list_counter > 0)
1605
            {
1606
              return_vec = rtvec_alloc (list_counter);
1607
              memcpy (&return_vec->elem[0], obstack_finish (&vector_stack),
1608
                      list_counter * sizeof (rtx));
1609
            }
1610
          else if (format_ptr[i] == 'E')
1611
            fatal_with_file_and_line (infile,
1612
                                      "vector must have at least one element");
1613
          XVEC (return_rtx, i) = return_vec;
1614
          obstack_free (&vector_stack, NULL);
1615
          /* close bracket gotten */
1616
        }
1617
        break;
1618
 
1619
      case 'S':
1620
      case 'T':
1621
      case 's':
1622
        {
1623
          char *stringbuf;
1624
          int star_if_braced;
1625
 
1626
          c = read_skip_spaces (infile);
1627
          ungetc (c, infile);
1628
          if (c == ')')
1629
            {
1630
              /* 'S' fields are optional and should be NULL if no string
1631
                 was given.  Also allow normal 's' and 'T' strings to be
1632
                 omitted, treating them in the same way as empty strings.  */
1633
              XSTR (return_rtx, i) = (format_ptr[i] == 'S' ? NULL : "");
1634
              break;
1635
            }
1636
 
1637
          /* The output template slot of a DEFINE_INSN,
1638
             DEFINE_INSN_AND_SPLIT, or DEFINE_PEEPHOLE automatically
1639
             gets a star inserted as its first character, if it is
1640
             written with a brace block instead of a string constant.  */
1641
          star_if_braced = (format_ptr[i] == 'T');
1642
 
1643
          stringbuf = read_string (infile, star_if_braced);
1644
 
1645
          /* For insn patterns, we want to provide a default name
1646
             based on the file and line, like "*foo.md:12", if the
1647
             given name is blank.  These are only for define_insn and
1648
             define_insn_and_split, to aid debugging.  */
1649
          if (*stringbuf == '\0'
1650
              && i == 0
1651
              && (GET_CODE (return_rtx) == DEFINE_INSN
1652
                  || GET_CODE (return_rtx) == DEFINE_INSN_AND_SPLIT))
1653
            {
1654
              char line_name[20];
1655
              const char *fn = (read_rtx_filename ? read_rtx_filename : "rtx");
1656
              const char *slash;
1657
              for (slash = fn; *slash; slash ++)
1658
                if (*slash == '/' || *slash == '\\' || *slash == ':')
1659
                  fn = slash + 1;
1660
              obstack_1grow (&string_obstack, '*');
1661
              obstack_grow (&string_obstack, fn, strlen (fn));
1662
              sprintf (line_name, ":%d", read_rtx_lineno);
1663
              obstack_grow (&string_obstack, line_name, strlen (line_name)+1);
1664
              stringbuf = XOBFINISH (&string_obstack, char *);
1665
            }
1666
 
1667
          if (star_if_braced)
1668
            XTMPL (return_rtx, i) = stringbuf;
1669
          else
1670
            XSTR (return_rtx, i) = stringbuf;
1671
        }
1672
        break;
1673
 
1674
      case 'w':
1675
        read_name (tmp_char, infile);
1676
        validate_const_int (infile, tmp_char);
1677
#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
1678
        tmp_wide = atoi (tmp_char);
1679
#else
1680
#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
1681
        tmp_wide = atol (tmp_char);
1682
#else
1683
        /* Prefer atoll over atoq, since the former is in the ISO C99 standard.
1684
           But prefer not to use our hand-rolled function above either.  */
1685
#if defined(HAVE_ATOLL) || !defined(HAVE_ATOQ)
1686
        tmp_wide = atoll (tmp_char);
1687
#else
1688
        tmp_wide = atoq (tmp_char);
1689
#endif
1690
#endif
1691
#endif
1692
        XWINT (return_rtx, i) = tmp_wide;
1693
        break;
1694
 
1695
      case 'i':
1696
      case 'n':
1697
        read_name (tmp_char, infile);
1698
        validate_const_int (infile, tmp_char);
1699
        tmp_int = atoi (tmp_char);
1700
        XINT (return_rtx, i) = tmp_int;
1701
        break;
1702
 
1703
      default:
1704
        gcc_unreachable ();
1705
      }
1706
 
1707
  c = read_skip_spaces (infile);
1708
  if (c != ')')
1709
    {
1710
      /* Syntactic sugar for AND and IOR, allowing Lisp-like
1711
         arbitrary number of arguments for them.  */
1712
      if (c == '(' && (GET_CODE (return_rtx) == AND
1713
                       || GET_CODE (return_rtx) == IOR))
1714
        return read_rtx_variadic (infile, mode_maps, return_rtx);
1715
      else
1716
        fatal_expected_char (infile, ')', c);
1717
    }
1718
 
1719
  return return_rtx;
1720
}
1721
 
1722
/* Mutually recursive subroutine of read_rtx which reads
1723
   (thing x1 x2 x3 ...) and produces RTL as if
1724
   (thing x1 (thing x2 (thing x3 ...)))  had been written.
1725
   When called, FORM is (thing x1 x2), and the file position
1726
   is just past the leading parenthesis of x3.  Only works
1727
   for THINGs which are dyadic expressions, e.g. AND, IOR.  */
1728
static rtx
1729
read_rtx_variadic (FILE *infile, struct map_value **mode_maps, rtx form)
1730
{
1731
  char c = '(';
1732
  rtx p = form, q;
1733
 
1734
  do
1735
    {
1736
      ungetc (c, infile);
1737
 
1738
      q = rtx_alloc (GET_CODE (p));
1739
      PUT_MODE (q, GET_MODE (p));
1740
 
1741
      XEXP (q, 0) = XEXP (p, 1);
1742
      XEXP (q, 1) = read_rtx_1 (infile, mode_maps);
1743
 
1744
      XEXP (p, 1) = q;
1745
      p = q;
1746
      c = read_skip_spaces (infile);
1747
    }
1748
  while (c == '(');
1749
 
1750
  if (c != ')')
1751
    fatal_expected_char (infile, ')', c);
1752
 
1753
  return form;
1754
}

powered by: WebSVN 2.1.0

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