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

Subversion Repositories scarts

[/] [scarts/] [trunk/] [toolchain/] [scarts-gcc/] [gcc-4.1.1/] [gcc/] [read-rtl.c] - Blame information for rev 20

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

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

powered by: WebSVN 2.1.0

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