1132718Skan/* RTL reader for GCC.
2132718Skan   Copyright (C) 1987, 1988, 1991, 1994, 1997, 1998, 1999, 2000, 2001, 2002,
3169689Skan   2003, 2004, 2005
490075Sobrien   Free Software Foundation, Inc.
590075Sobrien
690075SobrienThis file is part of GCC.
790075Sobrien
890075SobrienGCC is free software; you can redistribute it and/or modify it under
990075Sobrienthe terms of the GNU General Public License as published by the Free
1090075SobrienSoftware Foundation; either version 2, or (at your option) any later
1190075Sobrienversion.
1290075Sobrien
1390075SobrienGCC is distributed in the hope that it will be useful, but WITHOUT ANY
1490075SobrienWARRANTY; without even the implied warranty of MERCHANTABILITY or
1590075SobrienFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1690075Sobrienfor more details.
1790075Sobrien
1890075SobrienYou should have received a copy of the GNU General Public License
1990075Sobrienalong with GCC; see the file COPYING.  If not, write to the Free
20169689SkanSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
21169689Skan02110-1301, USA.  */
2290075Sobrien
23132718Skan#include "bconfig.h"
24169689Skan
25169689Skan/* Disable rtl checking; it conflicts with the macro handling.  */
26169689Skan#undef ENABLE_RTL_CHECKING
27169689Skan
2890075Sobrien#include "system.h"
29132718Skan#include "coretypes.h"
30132718Skan#include "tm.h"
3190075Sobrien#include "rtl.h"
3290075Sobrien#include "obstack.h"
3390075Sobrien#include "hashtab.h"
34169689Skan#include "gensupport.h"
3590075Sobrien
3690075Sobrienstatic htab_t md_constants;
3790075Sobrien
38169689Skan/* One element in a singly-linked list of (integer, string) pairs.  */
39169689Skanstruct map_value {
40169689Skan  struct map_value *next;
41169689Skan  int number;
42169689Skan  const char *string;
43169689Skan};
44169689Skan
45169689Skan/* Maps a macro or attribute name to a list of (integer, string) pairs.
46169689Skan   The integers are mode or code values; the strings are either C conditions
47169689Skan   or attribute values.  */
48169689Skanstruct mapping {
49169689Skan  /* The name of the macro or attribute.  */
50169689Skan  const char *name;
51169689Skan
52169689Skan  /* The group (modes or codes) to which the macro or attribute belongs.  */
53169689Skan  struct macro_group *group;
54169689Skan
55169689Skan  /* Gives a unique number to the attribute or macro.  Numbers are
56169689Skan     allocated consecutively, starting at 0.  */
57169689Skan  int index;
58169689Skan
59169689Skan  /* The list of (integer, string) pairs.  */
60169689Skan  struct map_value *values;
61169689Skan};
62169689Skan
63169689Skan/* A structure for abstracting the common parts of code and mode macros.  */
64169689Skanstruct macro_group {
65169689Skan  /* Tables of "mapping" structures, one for attributes and one for macros.  */
66169689Skan  htab_t attrs, macros;
67169689Skan
68169689Skan  /* The number of "real" modes or codes (and by extension, the first
69169689Skan     number available for use as a macro placeholder).  */
70169689Skan  int num_builtins;
71169689Skan
72169689Skan  /* Treat the given string as the name of a standard mode or code and
73169689Skan     return its integer value.  Use the given file for error reporting.  */
74169689Skan  int (*find_builtin) (const char *, FILE *);
75169689Skan
76169689Skan  /* Return true if the given rtx uses the given mode or code.  */
77169689Skan  bool (*uses_macro_p) (rtx, int);
78169689Skan
79169689Skan  /* Make the given rtx use the given mode or code.  */
80169689Skan  void (*apply_macro) (rtx, int);
81169689Skan};
82169689Skan
83169689Skan/* Associates PTR (which can be a string, etc.) with the file location
84169689Skan   specified by FILENAME and LINENO.  */
85169689Skanstruct ptr_loc {
86169689Skan  const void *ptr;
87169689Skan  const char *filename;
88169689Skan  int lineno;
89169689Skan};
90169689Skan
91169689Skan/* A structure used to pass data from read_rtx to apply_macro_traverse
92169689Skan   via htab_traverse.  */
93169689Skanstruct macro_traverse_data {
94169689Skan  /* Instruction queue.  */
95169689Skan  rtx queue;
96169689Skan  /* Attributes seen for modes.  */
97169689Skan  struct map_value *mode_maps;
98169689Skan  /* Input file.  */
99169689Skan  FILE *infile;
100169689Skan  /* The last unknown attribute used as a mode.  */
101169689Skan  const char *unknown_mode_attr;
102169689Skan};
103169689Skan
104169689Skan/* If CODE is the number of a code macro, return a real rtx code that
105169689Skan   has the same format.  Return CODE otherwise.  */
106169689Skan#define BELLWETHER_CODE(CODE) \
107169689Skan  ((CODE) < NUM_RTX_CODE ? CODE : bellwether_codes[CODE - NUM_RTX_CODE])
108169689Skan
109132718Skanstatic void fatal_with_file_and_line (FILE *, const char *, ...)
11090075Sobrien  ATTRIBUTE_PRINTF_2 ATTRIBUTE_NORETURN;
111132718Skanstatic void fatal_expected_char (FILE *, int, int) ATTRIBUTE_NORETURN;
112169689Skanstatic int find_mode (const char *, FILE *);
113169689Skanstatic bool uses_mode_macro_p (rtx, int);
114169689Skanstatic void apply_mode_macro (rtx, int);
115169689Skanstatic int find_code (const char *, FILE *);
116169689Skanstatic bool uses_code_macro_p (rtx, int);
117169689Skanstatic void apply_code_macro (rtx, int);
118169689Skanstatic const char *apply_macro_to_string (const char *, struct mapping *, int);
119169689Skanstatic rtx apply_macro_to_rtx (rtx, struct mapping *, int,
120169689Skan			       struct map_value *, FILE *, const char **);
121169689Skanstatic bool uses_macro_p (rtx, struct mapping *);
122169689Skanstatic const char *add_condition_to_string (const char *, const char *);
123169689Skanstatic void add_condition_to_rtx (rtx, const char *);
124169689Skanstatic int apply_macro_traverse (void **, void *);
125169689Skanstatic struct mapping *add_mapping (struct macro_group *, htab_t t,
126169689Skan				    const char *, FILE *);
127169689Skanstatic struct map_value **add_map_value (struct map_value **,
128169689Skan					 int, const char *);
129169689Skanstatic void initialize_macros (void);
130132718Skanstatic void read_name (char *, FILE *);
131169689Skanstatic hashval_t leading_ptr_hash (const void *);
132169689Skanstatic int leading_ptr_eq_p (const void *, const void *);
133169689Skanstatic void set_rtx_ptr_loc (const void *, const char *, int);
134169689Skanstatic const struct ptr_loc *get_rtx_ptr_loc (const void *);
135169689Skanstatic char *read_string (FILE *, int);
136169689Skanstatic char *read_quoted_string (FILE *);
137169689Skanstatic char *read_braced_string (FILE *);
138169689Skanstatic void read_escape (FILE *);
139132718Skanstatic hashval_t def_hash (const void *);
140132718Skanstatic int def_name_eq_p (const void *, const void *);
141132718Skanstatic void read_constants (FILE *infile, char *tmp_char);
142169689Skanstatic void read_conditions (FILE *infile, char *tmp_char);
143132718Skanstatic void validate_const_int (FILE *, const char *);
144169689Skanstatic int find_macro (struct macro_group *, const char *, FILE *);
145169689Skanstatic struct mapping *read_mapping (struct macro_group *, htab_t, FILE *);
146169689Skanstatic void check_code_macro (struct mapping *, FILE *);
147169689Skanstatic rtx read_rtx_1 (FILE *, struct map_value **);
148169689Skanstatic rtx read_rtx_variadic (FILE *, struct map_value **, rtx);
14990075Sobrien
150169689Skan/* The mode and code macro structures.  */
151169689Skanstatic struct macro_group modes, codes;
152169689Skan
153169689Skan/* Index I is the value of BELLWETHER_CODE (I + NUM_RTX_CODE).  */
154169689Skanstatic enum rtx_code *bellwether_codes;
155169689Skan
156169689Skan/* Obstack used for allocating RTL strings.  */
157169689Skanstatic struct obstack string_obstack;
158169689Skan
159169689Skan/* A table of ptr_locs, hashed on the PTR field.  */
160169689Skanstatic htab_t ptr_locs;
161169689Skan
162169689Skan/* An obstack for the above.  Plain xmalloc is a bit heavyweight for a
163169689Skan   small structure like ptr_loc.  */
164169689Skanstatic struct obstack ptr_loc_obstack;
165169689Skan
166169689Skan/* A hash table of triples (A, B, C), where each of A, B and C is a condition
167169689Skan   and A is equivalent to "B && C".  This is used to keep track of the source
168169689Skan   of conditions that are made up of separate rtx strings (such as the split
169169689Skan   condition of a define_insn_and_split).  */
170169689Skanstatic htab_t joined_conditions;
171169689Skan
172169689Skan/* An obstack for allocating joined_conditions entries.  */
173169689Skanstatic struct obstack joined_conditions_obstack;
174169689Skan
17590075Sobrien/* Subroutines of read_rtx.  */
17690075Sobrien
17790075Sobrien/* The current line number for the file.  */
17890075Sobrienint read_rtx_lineno = 1;
17990075Sobrien
180169689Skan/* The filename for error reporting.  */
18190075Sobrienconst char *read_rtx_filename = "<unknown>";
18290075Sobrien
18390075Sobrienstatic void
184132718Skanfatal_with_file_and_line (FILE *infile, const char *msg, ...)
18590075Sobrien{
18690075Sobrien  char context[64];
18790075Sobrien  size_t i;
18890075Sobrien  int c;
189132718Skan  va_list ap;
19090075Sobrien
191132718Skan  va_start (ap, msg);
19290075Sobrien
19390075Sobrien  fprintf (stderr, "%s:%d: ", read_rtx_filename, read_rtx_lineno);
19490075Sobrien  vfprintf (stderr, msg, ap);
19590075Sobrien  putc ('\n', stderr);
19690075Sobrien
19790075Sobrien  /* Gather some following context.  */
19890075Sobrien  for (i = 0; i < sizeof (context)-1; ++i)
19990075Sobrien    {
20090075Sobrien      c = getc (infile);
20190075Sobrien      if (c == EOF)
20290075Sobrien	break;
20390075Sobrien      if (c == '\r' || c == '\n')
20490075Sobrien	break;
20590075Sobrien      context[i] = c;
20690075Sobrien    }
20790075Sobrien  context[i] = '\0';
20890075Sobrien
20990075Sobrien  fprintf (stderr, "%s:%d: following context is `%s'\n",
21090075Sobrien	   read_rtx_filename, read_rtx_lineno, context);
21190075Sobrien
212132718Skan  va_end (ap);
21390075Sobrien  exit (1);
21490075Sobrien}
21590075Sobrien
21690075Sobrien/* Dump code after printing a message.  Used when read_rtx finds
21790075Sobrien   invalid data.  */
21890075Sobrien
21990075Sobrienstatic void
220132718Skanfatal_expected_char (FILE *infile, int expected_c, int actual_c)
22190075Sobrien{
22290075Sobrien  fatal_with_file_and_line (infile, "expected character `%c', found `%c'",
22390075Sobrien			    expected_c, actual_c);
22490075Sobrien}
22590075Sobrien
226169689Skan/* Implementations of the macro_group callbacks for modes.  */
227169689Skan
228169689Skanstatic int
229169689Skanfind_mode (const char *name, FILE *infile)
230169689Skan{
231169689Skan  int i;
232169689Skan
233169689Skan  for (i = 0; i < NUM_MACHINE_MODES; i++)
234169689Skan    if (strcmp (GET_MODE_NAME (i), name) == 0)
235169689Skan      return i;
236169689Skan
237169689Skan  fatal_with_file_and_line (infile, "unknown mode `%s'", name);
238169689Skan}
239169689Skan
240169689Skanstatic bool
241169689Skanuses_mode_macro_p (rtx x, int mode)
242169689Skan{
243169689Skan  return (int) GET_MODE (x) == mode;
244169689Skan}
245169689Skan
246169689Skanstatic void
247169689Skanapply_mode_macro (rtx x, int mode)
248169689Skan{
249169689Skan  PUT_MODE (x, (enum machine_mode) mode);
250169689Skan}
251169689Skan
252169689Skan/* Implementations of the macro_group callbacks for codes.  */
253169689Skan
254169689Skanstatic int
255169689Skanfind_code (const char *name, FILE *infile)
256169689Skan{
257169689Skan  int i;
258169689Skan
259169689Skan  for (i = 0; i < NUM_RTX_CODE; i++)
260169689Skan    if (strcmp (GET_RTX_NAME (i), name) == 0)
261169689Skan      return i;
262169689Skan
263169689Skan  fatal_with_file_and_line (infile, "unknown rtx code `%s'", name);
264169689Skan}
265169689Skan
266169689Skanstatic bool
267169689Skanuses_code_macro_p (rtx x, int code)
268169689Skan{
269169689Skan  return (int) GET_CODE (x) == code;
270169689Skan}
271169689Skan
272169689Skanstatic void
273169689Skanapply_code_macro (rtx x, int code)
274169689Skan{
275169689Skan  PUT_CODE (x, (enum rtx_code) code);
276169689Skan}
277169689Skan
278169689Skan/* Map a code or mode attribute string P to the underlying string for
279169689Skan   MACRO and VALUE.  */
280169689Skan
281169689Skanstatic struct map_value *
282169689Skanmap_attr_string (const char *p, struct mapping *macro, int value)
283169689Skan{
284169689Skan  const char *attr;
285169689Skan  struct mapping *m;
286169689Skan  struct map_value *v;
287169689Skan
288169689Skan  /* If there's a "macro:" prefix, check whether the macro name matches.
289169689Skan     Set ATTR to the start of the attribute name.  */
290169689Skan  attr = strchr (p, ':');
291169689Skan  if (attr == 0)
292169689Skan    attr = p;
293169689Skan  else
294169689Skan    {
295169689Skan      if (strncmp (p, macro->name, attr - p) != 0
296169689Skan	  || macro->name[attr - p] != 0)
297169689Skan	return 0;
298169689Skan      attr++;
299169689Skan    }
300169689Skan
301169689Skan  /* Find the attribute specification.  */
302169689Skan  m = (struct mapping *) htab_find (macro->group->attrs, &attr);
303169689Skan  if (m == 0)
304169689Skan    return 0;
305169689Skan
306169689Skan  /* Find the attribute value for VALUE.  */
307169689Skan  for (v = m->values; v != 0; v = v->next)
308169689Skan    if (v->number == value)
309169689Skan      break;
310169689Skan
311169689Skan  return v;
312169689Skan}
313169689Skan
314169689Skan/* Given an attribute string used as a machine mode, return an index
315169689Skan   to store in the machine mode to be translated by
316169689Skan   apply_macro_to_rtx.  */
317169689Skan
318169689Skanstatic unsigned int
319169689Skanmode_attr_index (struct map_value **mode_maps, const char *string)
320169689Skan{
321169689Skan  char *p;
322169689Skan  struct map_value *mv;
323169689Skan
324169689Skan  /* Copy the attribute string into permanent storage, without the
325169689Skan     angle brackets around it.  */
326169689Skan  obstack_grow0 (&string_obstack, string + 1, strlen (string) - 2);
327169689Skan  p = XOBFINISH (&string_obstack, char *);
328169689Skan
329169689Skan  mv = XNEW (struct map_value);
330169689Skan  mv->number = *mode_maps == 0 ? 0 : (*mode_maps)->number + 1;
331169689Skan  mv->string = p;
332169689Skan  mv->next = *mode_maps;
333169689Skan  *mode_maps = mv;
334169689Skan
335169689Skan  /* We return a code which we can map back into this string: the
336169689Skan     number of machine modes + the number of mode macros + the index
337169689Skan     we just used.  */
338169689Skan  return MAX_MACHINE_MODE + htab_elements (modes.macros) + mv->number;
339169689Skan}
340169689Skan
341169689Skan/* Apply MODE_MAPS to the top level of X, expanding cases where an
342169689Skan   attribute is used for a mode.  MACRO is the current macro we are
343169689Skan   expanding, and VALUE is the value to which we are expanding it.
344169689Skan   INFILE is used for error messages.  This sets *UNKNOWN to true if
345169689Skan   we find a mode attribute which has not yet been defined, and does
346169689Skan   not change it otherwise.  */
347169689Skan
348169689Skanstatic void
349169689Skanapply_mode_maps (rtx x, struct map_value *mode_maps, struct mapping *macro,
350169689Skan		 int value, FILE *infile, const char **unknown)
351169689Skan{
352169689Skan  unsigned int offset;
353169689Skan  int indx;
354169689Skan  struct map_value *pm;
355169689Skan
356169689Skan  offset = MAX_MACHINE_MODE + htab_elements (modes.macros);
357169689Skan  if (GET_MODE (x) < offset)
358169689Skan    return;
359169689Skan
360169689Skan  indx = GET_MODE (x) - offset;
361169689Skan  for (pm = mode_maps; pm; pm = pm->next)
362169689Skan    {
363169689Skan      if (pm->number == indx)
364169689Skan	{
365169689Skan	  struct map_value *v;
366169689Skan
367169689Skan	  v = map_attr_string (pm->string, macro, value);
368169689Skan	  if (v)
369169689Skan	    PUT_MODE (x, (enum machine_mode) find_mode (v->string, infile));
370169689Skan	  else
371169689Skan	    *unknown = pm->string;
372169689Skan	  return;
373169689Skan	}
374169689Skan    }
375169689Skan}
376169689Skan
377169689Skan/* Given that MACRO is being expanded as VALUE, apply the appropriate
378169689Skan   string substitutions to STRING.  Return the new string if any changes
379169689Skan   were needed, otherwise return STRING itself.  */
380169689Skan
381169689Skanstatic const char *
382169689Skanapply_macro_to_string (const char *string, struct mapping *macro, int value)
383169689Skan{
384169689Skan  char *base, *copy, *p, *start, *end;
385169689Skan  struct map_value *v;
386169689Skan
387169689Skan  if (string == 0)
388169689Skan    return string;
389169689Skan
390169689Skan  base = p = copy = ASTRDUP (string);
391169689Skan  while ((start = strchr (p, '<')) && (end = strchr (start, '>')))
392169689Skan    {
393169689Skan      p = start + 1;
394169689Skan
395169689Skan      *end = 0;
396169689Skan      v = map_attr_string (p, macro, value);
397169689Skan      *end = '>';
398169689Skan      if (v == 0)
399169689Skan	continue;
400169689Skan
401169689Skan      /* Add everything between the last copied byte and the '<',
402169689Skan	 then add in the attribute value.  */
403169689Skan      obstack_grow (&string_obstack, base, start - base);
404169689Skan      obstack_grow (&string_obstack, v->string, strlen (v->string));
405169689Skan      base = end + 1;
406169689Skan    }
407169689Skan  if (base != copy)
408169689Skan    {
409169689Skan      obstack_grow (&string_obstack, base, strlen (base) + 1);
410169689Skan      copy = XOBFINISH (&string_obstack, char *);
411169689Skan      copy_rtx_ptr_loc (copy, string);
412169689Skan      return copy;
413169689Skan    }
414169689Skan  return string;
415169689Skan}
416169689Skan
417169689Skan/* Return a copy of ORIGINAL in which all uses of MACRO have been
418169689Skan   replaced by VALUE.  MODE_MAPS holds information about attribute
419169689Skan   strings used for modes.  INFILE is used for error messages.  This
420169689Skan   sets *UNKNOWN_MODE_ATTR to the value of an unknown mode attribute,
421169689Skan   and does not change it otherwise.  */
422169689Skan
423169689Skanstatic rtx
424169689Skanapply_macro_to_rtx (rtx original, struct mapping *macro, int value,
425169689Skan		    struct map_value *mode_maps, FILE *infile,
426169689Skan		    const char **unknown_mode_attr)
427169689Skan{
428169689Skan  struct macro_group *group;
429169689Skan  const char *format_ptr;
430169689Skan  int i, j;
431169689Skan  rtx x;
432169689Skan  enum rtx_code bellwether_code;
433169689Skan
434169689Skan  if (original == 0)
435169689Skan    return original;
436169689Skan
437169689Skan  /* Create a shallow copy of ORIGINAL.  */
438169689Skan  bellwether_code = BELLWETHER_CODE (GET_CODE (original));
439169689Skan  x = rtx_alloc (bellwether_code);
440169689Skan  memcpy (x, original, RTX_CODE_SIZE (bellwether_code));
441169689Skan
442169689Skan  /* Change the mode or code itself.  */
443169689Skan  group = macro->group;
444169689Skan  if (group->uses_macro_p (x, macro->index + group->num_builtins))
445169689Skan    group->apply_macro (x, value);
446169689Skan
447169689Skan  if (mode_maps)
448169689Skan    apply_mode_maps (x, mode_maps, macro, value, infile, unknown_mode_attr);
449169689Skan
450169689Skan  /* Change each string and recursively change each rtx.  */
451169689Skan  format_ptr = GET_RTX_FORMAT (bellwether_code);
452169689Skan  for (i = 0; format_ptr[i] != 0; i++)
453169689Skan    switch (format_ptr[i])
454169689Skan      {
455169689Skan      case 'T':
456169689Skan	XTMPL (x, i) = apply_macro_to_string (XTMPL (x, i), macro, value);
457169689Skan	break;
458169689Skan
459169689Skan      case 'S':
460169689Skan      case 's':
461169689Skan	XSTR (x, i) = apply_macro_to_string (XSTR (x, i), macro, value);
462169689Skan	break;
463169689Skan
464169689Skan      case 'e':
465169689Skan	XEXP (x, i) = apply_macro_to_rtx (XEXP (x, i), macro, value,
466169689Skan					  mode_maps, infile,
467169689Skan					  unknown_mode_attr);
468169689Skan	break;
469169689Skan
470169689Skan      case 'V':
471169689Skan      case 'E':
472169689Skan	if (XVEC (original, i))
473169689Skan	  {
474169689Skan	    XVEC (x, i) = rtvec_alloc (XVECLEN (original, i));
475169689Skan	    for (j = 0; j < XVECLEN (x, i); j++)
476169689Skan	      XVECEXP (x, i, j) = apply_macro_to_rtx (XVECEXP (original, i, j),
477169689Skan						      macro, value, mode_maps,
478169689Skan						      infile,
479169689Skan						      unknown_mode_attr);
480169689Skan	  }
481169689Skan	break;
482169689Skan
483169689Skan      default:
484169689Skan	break;
485169689Skan      }
486169689Skan  return x;
487169689Skan}
488169689Skan
489169689Skan/* Return true if X (or some subexpression of X) uses macro MACRO.  */
490169689Skan
491169689Skanstatic bool
492169689Skanuses_macro_p (rtx x, struct mapping *macro)
493169689Skan{
494169689Skan  struct macro_group *group;
495169689Skan  const char *format_ptr;
496169689Skan  int i, j;
497169689Skan
498169689Skan  if (x == 0)
499169689Skan    return false;
500169689Skan
501169689Skan  group = macro->group;
502169689Skan  if (group->uses_macro_p (x, macro->index + group->num_builtins))
503169689Skan    return true;
504169689Skan
505169689Skan  format_ptr = GET_RTX_FORMAT (BELLWETHER_CODE (GET_CODE (x)));
506169689Skan  for (i = 0; format_ptr[i] != 0; i++)
507169689Skan    switch (format_ptr[i])
508169689Skan      {
509169689Skan      case 'e':
510169689Skan	if (uses_macro_p (XEXP (x, i), macro))
511169689Skan	  return true;
512169689Skan	break;
513169689Skan
514169689Skan      case 'V':
515169689Skan      case 'E':
516169689Skan	if (XVEC (x, i))
517169689Skan	  for (j = 0; j < XVECLEN (x, i); j++)
518169689Skan	    if (uses_macro_p (XVECEXP (x, i, j), macro))
519169689Skan	      return true;
520169689Skan	break;
521169689Skan
522169689Skan      default:
523169689Skan	break;
524169689Skan      }
525169689Skan  return false;
526169689Skan}
527169689Skan
528169689Skan/* Return a condition that must satisfy both ORIGINAL and EXTRA.  If ORIGINAL
529169689Skan   has the form "&& ..." (as used in define_insn_and_splits), assume that
530169689Skan   EXTRA is already satisfied.  Empty strings are treated like "true".  */
531169689Skan
532169689Skanstatic const char *
533169689Skanadd_condition_to_string (const char *original, const char *extra)
534169689Skan{
535169689Skan  if (original != 0 && original[0] == '&' && original[1] == '&')
536169689Skan    return original;
537169689Skan  return join_c_conditions (original, extra);
538169689Skan}
539169689Skan
540169689Skan/* Like add_condition, but applied to all conditions in rtx X.  */
541169689Skan
542169689Skanstatic void
543169689Skanadd_condition_to_rtx (rtx x, const char *extra)
544169689Skan{
545169689Skan  switch (GET_CODE (x))
546169689Skan    {
547169689Skan    case DEFINE_INSN:
548169689Skan    case DEFINE_EXPAND:
549169689Skan      XSTR (x, 2) = add_condition_to_string (XSTR (x, 2), extra);
550169689Skan      break;
551169689Skan
552169689Skan    case DEFINE_SPLIT:
553169689Skan    case DEFINE_PEEPHOLE:
554169689Skan    case DEFINE_PEEPHOLE2:
555169689Skan    case DEFINE_COND_EXEC:
556169689Skan      XSTR (x, 1) = add_condition_to_string (XSTR (x, 1), extra);
557169689Skan      break;
558169689Skan
559169689Skan    case DEFINE_INSN_AND_SPLIT:
560169689Skan      XSTR (x, 2) = add_condition_to_string (XSTR (x, 2), extra);
561169689Skan      XSTR (x, 4) = add_condition_to_string (XSTR (x, 4), extra);
562169689Skan      break;
563169689Skan
564169689Skan    default:
565169689Skan      break;
566169689Skan    }
567169689Skan}
568169689Skan
569169689Skan/* A htab_traverse callback.  Search the EXPR_LIST given by DATA
570169689Skan   for rtxes that use the macro in *SLOT.  Replace each such rtx
571169689Skan   with a list of expansions.  */
572169689Skan
573169689Skanstatic int
574169689Skanapply_macro_traverse (void **slot, void *data)
575169689Skan{
576169689Skan  struct macro_traverse_data *mtd = (struct macro_traverse_data *) data;
577169689Skan  struct mapping *macro;
578169689Skan  struct map_value *v;
579169689Skan  rtx elem, new_elem, original, x;
580169689Skan
581169689Skan  macro = (struct mapping *) *slot;
582169689Skan  for (elem = mtd->queue; elem != 0; elem = XEXP (elem, 1))
583169689Skan    if (uses_macro_p (XEXP (elem, 0), macro))
584169689Skan      {
585169689Skan	/* For each macro we expand, we set UNKNOWN_MODE_ATTR to NULL.
586169689Skan	   If apply_macro_rtx finds an unknown attribute for a mode,
587169689Skan	   it will set it to the attribute.  We want to know whether
588169689Skan	   the attribute is unknown after we have expanded all
589169689Skan	   possible macros, so setting it to NULL here gives us the
590169689Skan	   right result when the hash table traversal is complete.  */
591169689Skan	mtd->unknown_mode_attr = NULL;
592169689Skan
593169689Skan	original = XEXP (elem, 0);
594169689Skan	for (v = macro->values; v != 0; v = v->next)
595169689Skan	  {
596169689Skan	    x = apply_macro_to_rtx (original, macro, v->number,
597169689Skan				    mtd->mode_maps, mtd->infile,
598169689Skan				    &mtd->unknown_mode_attr);
599169689Skan	    add_condition_to_rtx (x, v->string);
600169689Skan	    if (v != macro->values)
601169689Skan	      {
602169689Skan		/* Insert a new EXPR_LIST node after ELEM and put the
603169689Skan		   new expansion there.  */
604169689Skan		new_elem = rtx_alloc (EXPR_LIST);
605169689Skan		XEXP (new_elem, 1) = XEXP (elem, 1);
606169689Skan		XEXP (elem, 1) = new_elem;
607169689Skan		elem = new_elem;
608169689Skan	      }
609169689Skan	    XEXP (elem, 0) = x;
610169689Skan	  }
611169689Skan    }
612169689Skan  return 1;
613169689Skan}
614169689Skan
615169689Skan/* Add a new "mapping" structure to hashtable TABLE.  NAME is the name
616169689Skan   of the mapping, GROUP is the group to which it belongs, and INFILE
617169689Skan   is the file that defined the mapping.  */
618169689Skan
619169689Skanstatic struct mapping *
620169689Skanadd_mapping (struct macro_group *group, htab_t table,
621169689Skan	     const char *name, FILE *infile)
622169689Skan{
623169689Skan  struct mapping *m;
624169689Skan  void **slot;
625169689Skan
626169689Skan  m = XNEW (struct mapping);
627169689Skan  m->name = xstrdup (name);
628169689Skan  m->group = group;
629169689Skan  m->index = htab_elements (table);
630169689Skan  m->values = 0;
631169689Skan
632169689Skan  slot = htab_find_slot (table, m, INSERT);
633169689Skan  if (*slot != 0)
634169689Skan    fatal_with_file_and_line (infile, "`%s' already defined", name);
635169689Skan
636169689Skan  *slot = m;
637169689Skan  return m;
638169689Skan}
639169689Skan
640169689Skan/* Add the pair (NUMBER, STRING) to a list of map_value structures.
641169689Skan   END_PTR points to the current null terminator for the list; return
642169689Skan   a pointer the new null terminator.  */
643169689Skan
644169689Skanstatic struct map_value **
645169689Skanadd_map_value (struct map_value **end_ptr, int number, const char *string)
646169689Skan{
647169689Skan  struct map_value *value;
648169689Skan
649169689Skan  value = XNEW (struct map_value);
650169689Skan  value->next = 0;
651169689Skan  value->number = number;
652169689Skan  value->string = string;
653169689Skan
654169689Skan  *end_ptr = value;
655169689Skan  return &value->next;
656169689Skan}
657169689Skan
658169689Skan/* Do one-time initialization of the mode and code attributes.  */
659169689Skan
660169689Skanstatic void
661169689Skaninitialize_macros (void)
662169689Skan{
663169689Skan  struct mapping *lower, *upper;
664169689Skan  struct map_value **lower_ptr, **upper_ptr;
665169689Skan  char *copy, *p;
666169689Skan  int i;
667169689Skan
668169689Skan  modes.attrs = htab_create (13, def_hash, def_name_eq_p, 0);
669169689Skan  modes.macros = htab_create (13, def_hash, def_name_eq_p, 0);
670169689Skan  modes.num_builtins = MAX_MACHINE_MODE;
671169689Skan  modes.find_builtin = find_mode;
672169689Skan  modes.uses_macro_p = uses_mode_macro_p;
673169689Skan  modes.apply_macro = apply_mode_macro;
674169689Skan
675169689Skan  codes.attrs = htab_create (13, def_hash, def_name_eq_p, 0);
676169689Skan  codes.macros = htab_create (13, def_hash, def_name_eq_p, 0);
677169689Skan  codes.num_builtins = NUM_RTX_CODE;
678169689Skan  codes.find_builtin = find_code;
679169689Skan  codes.uses_macro_p = uses_code_macro_p;
680169689Skan  codes.apply_macro = apply_code_macro;
681169689Skan
682169689Skan  lower = add_mapping (&modes, modes.attrs, "mode", 0);
683169689Skan  upper = add_mapping (&modes, modes.attrs, "MODE", 0);
684169689Skan  lower_ptr = &lower->values;
685169689Skan  upper_ptr = &upper->values;
686169689Skan  for (i = 0; i < MAX_MACHINE_MODE; i++)
687169689Skan    {
688169689Skan      copy = xstrdup (GET_MODE_NAME (i));
689169689Skan      for (p = copy; *p != 0; p++)
690169689Skan	*p = TOLOWER (*p);
691169689Skan
692169689Skan      upper_ptr = add_map_value (upper_ptr, i, GET_MODE_NAME (i));
693169689Skan      lower_ptr = add_map_value (lower_ptr, i, copy);
694169689Skan    }
695169689Skan
696169689Skan  lower = add_mapping (&codes, codes.attrs, "code", 0);
697169689Skan  upper = add_mapping (&codes, codes.attrs, "CODE", 0);
698169689Skan  lower_ptr = &lower->values;
699169689Skan  upper_ptr = &upper->values;
700169689Skan  for (i = 0; i < NUM_RTX_CODE; i++)
701169689Skan    {
702169689Skan      copy = xstrdup (GET_RTX_NAME (i));
703169689Skan      for (p = copy; *p != 0; p++)
704169689Skan	*p = TOUPPER (*p);
705169689Skan
706169689Skan      lower_ptr = add_map_value (lower_ptr, i, GET_RTX_NAME (i));
707169689Skan      upper_ptr = add_map_value (upper_ptr, i, copy);
708169689Skan    }
709169689Skan}
710169689Skan
711169689Skan/* Return a hash value for the pointer pointed to by DEF.  */
712169689Skan
713169689Skanstatic hashval_t
714169689Skanleading_ptr_hash (const void *def)
715169689Skan{
716169689Skan  return htab_hash_pointer (*(const void *const *) def);
717169689Skan}
718169689Skan
719169689Skan/* Return true if DEF1 and DEF2 are pointers to the same pointer.  */
720169689Skan
721169689Skanstatic int
722169689Skanleading_ptr_eq_p (const void *def1, const void *def2)
723169689Skan{
724169689Skan  return *(const void *const *) def1 == *(const void *const *) def2;
725169689Skan}
726169689Skan
727169689Skan/* Associate PTR with the file position given by FILENAME and LINENO.  */
728169689Skan
729169689Skanstatic void
730169689Skanset_rtx_ptr_loc (const void *ptr, const char *filename, int lineno)
731169689Skan{
732169689Skan  struct ptr_loc *loc;
733169689Skan
734169689Skan  loc = (struct ptr_loc *) obstack_alloc (&ptr_loc_obstack,
735169689Skan					  sizeof (struct ptr_loc));
736169689Skan  loc->ptr = ptr;
737169689Skan  loc->filename = filename;
738169689Skan  loc->lineno = lineno;
739169689Skan  *htab_find_slot (ptr_locs, loc, INSERT) = loc;
740169689Skan}
741169689Skan
742169689Skan/* Return the position associated with pointer PTR.  Return null if no
743169689Skan   position was set.  */
744169689Skan
745169689Skanstatic const struct ptr_loc *
746169689Skanget_rtx_ptr_loc (const void *ptr)
747169689Skan{
748169689Skan  return (const struct ptr_loc *) htab_find (ptr_locs, &ptr);
749169689Skan}
750169689Skan
751169689Skan/* Associate NEW_PTR with the same file position as OLD_PTR.  */
752169689Skan
753169689Skanvoid
754169689Skancopy_rtx_ptr_loc (const void *new_ptr, const void *old_ptr)
755169689Skan{
756169689Skan  const struct ptr_loc *loc = get_rtx_ptr_loc (old_ptr);
757169689Skan  if (loc != 0)
758169689Skan    set_rtx_ptr_loc (new_ptr, loc->filename, loc->lineno);
759169689Skan}
760169689Skan
761169689Skan/* If PTR is associated with a known file position, print a #line
762169689Skan   directive for it.  */
763169689Skan
764169689Skanvoid
765169689Skanprint_rtx_ptr_loc (const void *ptr)
766169689Skan{
767169689Skan  const struct ptr_loc *loc = get_rtx_ptr_loc (ptr);
768169689Skan  if (loc != 0)
769169689Skan    printf ("#line %d \"%s\"\n", loc->lineno, loc->filename);
770169689Skan}
771169689Skan
772169689Skan/* Return a condition that satisfies both COND1 and COND2.  Either string
773169689Skan   may be null or empty.  */
774169689Skan
775169689Skanconst char *
776169689Skanjoin_c_conditions (const char *cond1, const char *cond2)
777169689Skan{
778169689Skan  char *result;
779169689Skan  const void **entry;
780169689Skan
781169689Skan  if (cond1 == 0 || cond1[0] == 0)
782169689Skan    return cond2;
783169689Skan
784169689Skan  if (cond2 == 0 || cond2[0] == 0)
785169689Skan    return cond1;
786169689Skan
787169689Skan  result = concat ("(", cond1, ") && (", cond2, ")", NULL);
788169689Skan  obstack_ptr_grow (&joined_conditions_obstack, result);
789169689Skan  obstack_ptr_grow (&joined_conditions_obstack, cond1);
790169689Skan  obstack_ptr_grow (&joined_conditions_obstack, cond2);
791169689Skan  entry = XOBFINISH (&joined_conditions_obstack, const void **);
792169689Skan  *htab_find_slot (joined_conditions, entry, INSERT) = entry;
793169689Skan  return result;
794169689Skan}
795169689Skan
796169689Skan/* Print condition COND, wrapped in brackets.  If COND was created by
797169689Skan   join_c_conditions, recursively invoke this function for the original
798169689Skan   conditions and join the result with "&&".  Otherwise print a #line
799169689Skan   directive for COND if its original file position is known.  */
800169689Skan
801169689Skanvoid
802169689Skanprint_c_condition (const char *cond)
803169689Skan{
804169689Skan  const char **halves = (const char **) htab_find (joined_conditions, &cond);
805169689Skan  if (halves != 0)
806169689Skan    {
807169689Skan      printf ("(");
808169689Skan      print_c_condition (halves[1]);
809169689Skan      printf (" && ");
810169689Skan      print_c_condition (halves[2]);
811169689Skan      printf (")");
812169689Skan    }
813169689Skan  else
814169689Skan    {
815169689Skan      putc ('\n', stdout);
816169689Skan      print_rtx_ptr_loc (cond);
817169689Skan      printf ("(%s)", cond);
818169689Skan    }
819169689Skan}
820169689Skan
82190075Sobrien/* Read chars from INFILE until a non-whitespace char
82290075Sobrien   and return that.  Comments, both Lisp style and C style,
82390075Sobrien   are treated as whitespace.
82490075Sobrien   Tools such as genflags use this function.  */
82590075Sobrien
82690075Sobrienint
827132718Skanread_skip_spaces (FILE *infile)
82890075Sobrien{
82990075Sobrien  int c;
83090075Sobrien
83190075Sobrien  while (1)
83290075Sobrien    {
83390075Sobrien      c = getc (infile);
83490075Sobrien      switch (c)
83590075Sobrien	{
83690075Sobrien	case '\n':
83790075Sobrien	  read_rtx_lineno++;
83890075Sobrien	  break;
83990075Sobrien
84090075Sobrien	case ' ': case '\t': case '\f': case '\r':
84190075Sobrien	  break;
84290075Sobrien
84390075Sobrien	case ';':
84490075Sobrien	  do
84590075Sobrien	    c = getc (infile);
84690075Sobrien	  while (c != '\n' && c != EOF);
84790075Sobrien	  read_rtx_lineno++;
84890075Sobrien	  break;
84990075Sobrien
85090075Sobrien	case '/':
85190075Sobrien	  {
85290075Sobrien	    int prevc;
85390075Sobrien	    c = getc (infile);
85490075Sobrien	    if (c != '*')
85590075Sobrien	      fatal_expected_char (infile, '*', c);
85690075Sobrien
85790075Sobrien	    prevc = 0;
85890075Sobrien	    while ((c = getc (infile)) && c != EOF)
85990075Sobrien	      {
86090075Sobrien		if (c == '\n')
86190075Sobrien		   read_rtx_lineno++;
86290075Sobrien	        else if (prevc == '*' && c == '/')
86390075Sobrien		  break;
86490075Sobrien	        prevc = c;
86590075Sobrien	      }
86690075Sobrien	  }
86790075Sobrien	  break;
86890075Sobrien
86990075Sobrien	default:
87090075Sobrien	  return c;
87190075Sobrien	}
87290075Sobrien    }
87390075Sobrien}
87490075Sobrien
87590075Sobrien/* Read an rtx code name into the buffer STR[].
87690075Sobrien   It is terminated by any of the punctuation chars of rtx printed syntax.  */
87790075Sobrien
87890075Sobrienstatic void
879132718Skanread_name (char *str, FILE *infile)
88090075Sobrien{
88190075Sobrien  char *p;
88290075Sobrien  int c;
88390075Sobrien
88490075Sobrien  c = read_skip_spaces (infile);
88590075Sobrien
88690075Sobrien  p = str;
88790075Sobrien  while (1)
88890075Sobrien    {
889169689Skan      if (c == ' ' || c == '\n' || c == '\t' || c == '\f' || c == '\r' || c == EOF)
89090075Sobrien	break;
89190075Sobrien      if (c == ':' || c == ')' || c == ']' || c == '"' || c == '/'
89290075Sobrien	  || c == '(' || c == '[')
89390075Sobrien	{
89490075Sobrien	  ungetc (c, infile);
89590075Sobrien	  break;
89690075Sobrien	}
89790075Sobrien      *p++ = c;
89890075Sobrien      c = getc (infile);
89990075Sobrien    }
90090075Sobrien  if (p == str)
90190075Sobrien    fatal_with_file_and_line (infile, "missing name or number");
90290075Sobrien  if (c == '\n')
90390075Sobrien    read_rtx_lineno++;
90490075Sobrien
90590075Sobrien  *p = 0;
90690075Sobrien
90790075Sobrien  if (md_constants)
90890075Sobrien    {
90990075Sobrien      /* Do constant expansion.  */
91090075Sobrien      struct md_constant *def;
91190075Sobrien
91290075Sobrien      p = str;
91390075Sobrien      do
91490075Sobrien	{
91590075Sobrien	  struct md_constant tmp_def;
91690075Sobrien
91790075Sobrien	  tmp_def.name = p;
918169689Skan	  def = (struct md_constant *) htab_find (md_constants, &tmp_def);
91990075Sobrien	  if (def)
92090075Sobrien	    p = def->value;
92190075Sobrien	} while (def);
92290075Sobrien      if (p != str)
92390075Sobrien	strcpy (str, p);
92490075Sobrien    }
92590075Sobrien}
92690075Sobrien
92790075Sobrien/* Subroutine of the string readers.  Handles backslash escapes.
92890075Sobrien   Caller has read the backslash, but not placed it into the obstack.  */
92990075Sobrienstatic void
930169689Skanread_escape (FILE *infile)
93190075Sobrien{
93290075Sobrien  int c = getc (infile);
93390075Sobrien
93490075Sobrien  switch (c)
93590075Sobrien    {
93690075Sobrien      /* Backslash-newline is replaced by nothing, as in C.  */
93790075Sobrien    case '\n':
93890075Sobrien      read_rtx_lineno++;
93990075Sobrien      return;
94090075Sobrien
94190075Sobrien      /* \" \' \\ are replaced by the second character.  */
94290075Sobrien    case '\\':
94390075Sobrien    case '"':
94490075Sobrien    case '\'':
94590075Sobrien      break;
94690075Sobrien
94790075Sobrien      /* Standard C string escapes:
94890075Sobrien	 \a \b \f \n \r \t \v
94990075Sobrien	 \[0-7] \x
95090075Sobrien	 all are passed through to the output string unmolested.
95190075Sobrien	 In normal use these wind up in a string constant processed
95290075Sobrien	 by the C compiler, which will translate them appropriately.
95390075Sobrien	 We do not bother checking that \[0-7] are followed by up to
95490075Sobrien	 two octal digits, or that \x is followed by N hex digits.
95590075Sobrien	 \? \u \U are left out because they are not in traditional C.  */
95690075Sobrien    case 'a': case 'b': case 'f': case 'n': case 'r': case 't': case 'v':
95790075Sobrien    case '0': case '1': case '2': case '3': case '4': case '5': case '6':
95890075Sobrien    case '7': case 'x':
959169689Skan      obstack_1grow (&string_obstack, '\\');
96090075Sobrien      break;
96190075Sobrien
96290075Sobrien      /* \; makes stuff for a C string constant containing
96390075Sobrien	 newline and tab.  */
96490075Sobrien    case ';':
965169689Skan      obstack_grow (&string_obstack, "\\n\\t", 4);
96690075Sobrien      return;
96790075Sobrien
96890075Sobrien      /* pass anything else through, but issue a warning.  */
96990075Sobrien    default:
97090075Sobrien      fprintf (stderr, "%s:%d: warning: unrecognized escape \\%c\n",
97190075Sobrien	       read_rtx_filename, read_rtx_lineno, c);
972169689Skan      obstack_1grow (&string_obstack, '\\');
97390075Sobrien      break;
97490075Sobrien    }
97590075Sobrien
976169689Skan  obstack_1grow (&string_obstack, c);
97790075Sobrien}
97890075Sobrien
979117395Skan
98090075Sobrien/* Read a double-quoted string onto the obstack.  Caller has scanned
98190075Sobrien   the leading quote.  */
98290075Sobrienstatic char *
983169689Skanread_quoted_string (FILE *infile)
98490075Sobrien{
98590075Sobrien  int c;
98690075Sobrien
98790075Sobrien  while (1)
98890075Sobrien    {
98990075Sobrien      c = getc (infile); /* Read the string  */
99090075Sobrien      if (c == '\n')
99190075Sobrien	read_rtx_lineno++;
99290075Sobrien      else if (c == '\\')
99390075Sobrien	{
994169689Skan	  read_escape (infile);
99590075Sobrien	  continue;
99690075Sobrien	}
997169689Skan      else if (c == '"' || c == EOF)
99890075Sobrien	break;
99990075Sobrien
1000169689Skan      obstack_1grow (&string_obstack, c);
100190075Sobrien    }
100290075Sobrien
1003169689Skan  obstack_1grow (&string_obstack, 0);
1004169689Skan  return XOBFINISH (&string_obstack, char *);
100590075Sobrien}
100690075Sobrien
1007169689Skan/* Read a braced string (a la Tcl) onto the string obstack.  Caller
1008169689Skan   has scanned the leading brace.  Note that unlike quoted strings,
100990075Sobrien   the outermost braces _are_ included in the string constant.  */
101090075Sobrienstatic char *
1011169689Skanread_braced_string (FILE *infile)
101290075Sobrien{
101390075Sobrien  int c;
101490075Sobrien  int brace_depth = 1;  /* caller-processed */
1015132718Skan  unsigned long starting_read_rtx_lineno = read_rtx_lineno;
101690075Sobrien
1017169689Skan  obstack_1grow (&string_obstack, '{');
101890075Sobrien  while (brace_depth)
101990075Sobrien    {
102090075Sobrien      c = getc (infile); /* Read the string  */
1021132718Skan
102290075Sobrien      if (c == '\n')
102390075Sobrien	read_rtx_lineno++;
102490075Sobrien      else if (c == '{')
102590075Sobrien	brace_depth++;
102690075Sobrien      else if (c == '}')
102790075Sobrien	brace_depth--;
102890075Sobrien      else if (c == '\\')
102990075Sobrien	{
1030169689Skan	  read_escape (infile);
103190075Sobrien	  continue;
103290075Sobrien	}
1033132718Skan      else if (c == EOF)
1034132718Skan	fatal_with_file_and_line
1035132718Skan	  (infile, "missing closing } for opening brace on line %lu",
1036132718Skan	   starting_read_rtx_lineno);
103790075Sobrien
1038169689Skan      obstack_1grow (&string_obstack, c);
103990075Sobrien    }
1040117395Skan
1041169689Skan  obstack_1grow (&string_obstack, 0);
1042169689Skan  return XOBFINISH (&string_obstack, char *);
104390075Sobrien}
104490075Sobrien
104590075Sobrien/* Read some kind of string constant.  This is the high-level routine
104690075Sobrien   used by read_rtx.  It handles surrounding parentheses, leading star,
104790075Sobrien   and dispatch to the appropriate string constant reader.  */
104890075Sobrien
104990075Sobrienstatic char *
1050169689Skanread_string (FILE *infile, int star_if_braced)
105190075Sobrien{
105290075Sobrien  char *stringbuf;
105390075Sobrien  int saw_paren = 0;
1054169689Skan  int c, old_lineno;
105590075Sobrien
105690075Sobrien  c = read_skip_spaces (infile);
105790075Sobrien  if (c == '(')
105890075Sobrien    {
105990075Sobrien      saw_paren = 1;
106090075Sobrien      c = read_skip_spaces (infile);
106190075Sobrien    }
106290075Sobrien
1063169689Skan  old_lineno = read_rtx_lineno;
106490075Sobrien  if (c == '"')
1065169689Skan    stringbuf = read_quoted_string (infile);
106690075Sobrien  else if (c == '{')
106790075Sobrien    {
106890075Sobrien      if (star_if_braced)
1069169689Skan	obstack_1grow (&string_obstack, '*');
1070169689Skan      stringbuf = read_braced_string (infile);
107190075Sobrien    }
107290075Sobrien  else
107390075Sobrien    fatal_with_file_and_line (infile, "expected `\"' or `{', found `%c'", c);
1074117395Skan
107590075Sobrien  if (saw_paren)
107690075Sobrien    {
107790075Sobrien      c = read_skip_spaces (infile);
107890075Sobrien      if (c != ')')
107990075Sobrien	fatal_expected_char (infile, ')', c);
108090075Sobrien    }
108190075Sobrien
1082169689Skan  set_rtx_ptr_loc (stringbuf, read_rtx_filename, old_lineno);
108390075Sobrien  return stringbuf;
108490075Sobrien}
108590075Sobrien
108690075Sobrien/* Provide a version of a function to read a long long if the system does
108790075Sobrien   not provide one.  */
108890075Sobrien#if HOST_BITS_PER_WIDE_INT > HOST_BITS_PER_LONG && !defined(HAVE_ATOLL) && !defined(HAVE_ATOQ)
1089132718SkanHOST_WIDE_INT atoll (const char *);
1090132718Skan
109190075SobrienHOST_WIDE_INT
1092132718Skanatoll (const char *p)
109390075Sobrien{
109490075Sobrien  int neg = 0;
109590075Sobrien  HOST_WIDE_INT tmp_wide;
109690075Sobrien
109790075Sobrien  while (ISSPACE (*p))
109890075Sobrien    p++;
109990075Sobrien  if (*p == '-')
110090075Sobrien    neg = 1, p++;
110190075Sobrien  else if (*p == '+')
110290075Sobrien    p++;
110390075Sobrien
110490075Sobrien  tmp_wide = 0;
110590075Sobrien  while (ISDIGIT (*p))
110690075Sobrien    {
110790075Sobrien      HOST_WIDE_INT new_wide = tmp_wide*10 + (*p - '0');
110890075Sobrien      if (new_wide < tmp_wide)
110990075Sobrien	{
111090075Sobrien	  /* Return INT_MAX equiv on overflow.  */
111190075Sobrien	  tmp_wide = (~(unsigned HOST_WIDE_INT) 0) >> 1;
111290075Sobrien	  break;
111390075Sobrien	}
111490075Sobrien      tmp_wide = new_wide;
111590075Sobrien      p++;
111690075Sobrien    }
111790075Sobrien
111890075Sobrien  if (neg)
111990075Sobrien    tmp_wide = -tmp_wide;
112090075Sobrien  return tmp_wide;
112190075Sobrien}
112290075Sobrien#endif
112390075Sobrien
1124169689Skan/* Given an object that starts with a char * name field, return a hash
1125169689Skan   code for its name.  */
1126117395Skanstatic hashval_t
1127132718Skandef_hash (const void *def)
112890075Sobrien{
112990075Sobrien  unsigned result, i;
1130169689Skan  const char *string = *(const char *const *) def;
113190075Sobrien
1132169689Skan  for (result = i = 0; *string++ != '\0'; i++)
113390075Sobrien    result += ((unsigned char) *string << (i % CHAR_BIT));
113490075Sobrien  return result;
113590075Sobrien}
113690075Sobrien
1137169689Skan/* Given two objects that start with char * name fields, return true if
1138169689Skan   they have the same name.  */
113990075Sobrienstatic int
1140132718Skandef_name_eq_p (const void *def1, const void *def2)
114190075Sobrien{
1142169689Skan  return ! strcmp (*(const char *const *) def1,
1143169689Skan		   *(const char *const *) def2);
114490075Sobrien}
114590075Sobrien
114690075Sobrien/* INFILE is a FILE pointer to read text from.  TMP_CHAR is a buffer suitable
114790075Sobrien   to read a name or number into.  Process a define_constants directive,
114890075Sobrien   starting with the optional space after the "define_constants".  */
114990075Sobrienstatic void
1150132718Skanread_constants (FILE *infile, char *tmp_char)
115190075Sobrien{
115290075Sobrien  int c;
115390075Sobrien  htab_t defs;
115490075Sobrien
115590075Sobrien  c = read_skip_spaces (infile);
115690075Sobrien  if (c != '[')
115790075Sobrien    fatal_expected_char (infile, '[', c);
115890075Sobrien  defs = md_constants;
115990075Sobrien  if (! defs)
116090075Sobrien    defs = htab_create (32, def_hash, def_name_eq_p, (htab_del) 0);
116190075Sobrien  /* Disable constant expansion during definition processing.  */
116290075Sobrien  md_constants = 0;
116390075Sobrien  while ( (c = read_skip_spaces (infile)) != ']')
116490075Sobrien    {
116590075Sobrien      struct md_constant *def;
116690075Sobrien      void **entry_ptr;
116790075Sobrien
116890075Sobrien      if (c != '(')
116990075Sobrien	fatal_expected_char (infile, '(', c);
1170169689Skan      def = XNEW (struct md_constant);
117190075Sobrien      def->name = tmp_char;
117290075Sobrien      read_name (tmp_char, infile);
1173169689Skan      entry_ptr = htab_find_slot (defs, def, INSERT);
117490075Sobrien      if (! *entry_ptr)
117590075Sobrien	def->name = xstrdup (tmp_char);
117690075Sobrien      c = read_skip_spaces (infile);
117790075Sobrien      ungetc (c, infile);
117890075Sobrien      read_name (tmp_char, infile);
117990075Sobrien      if (! *entry_ptr)
118090075Sobrien	{
118190075Sobrien	  def->value = xstrdup (tmp_char);
118290075Sobrien	  *entry_ptr = def;
118390075Sobrien	}
118490075Sobrien      else
118590075Sobrien	{
1186169689Skan	  def = (struct md_constant *) *entry_ptr;
118790075Sobrien	  if (strcmp (def->value, tmp_char))
118890075Sobrien	    fatal_with_file_and_line (infile,
118990075Sobrien				      "redefinition of %s, was %s, now %s",
119090075Sobrien				      def->name, def->value, tmp_char);
119190075Sobrien	}
119290075Sobrien      c = read_skip_spaces (infile);
119390075Sobrien      if (c != ')')
119490075Sobrien	fatal_expected_char (infile, ')', c);
119590075Sobrien    }
119690075Sobrien  md_constants = defs;
119790075Sobrien  c = read_skip_spaces (infile);
119890075Sobrien  if (c != ')')
119990075Sobrien    fatal_expected_char (infile, ')', c);
120090075Sobrien}
120190075Sobrien
120290075Sobrien/* For every constant definition, call CALLBACK with two arguments:
120390075Sobrien   a pointer a pointer to the constant definition and INFO.
120490075Sobrien   Stops when CALLBACK returns zero.  */
120590075Sobrienvoid
1206132718Skantraverse_md_constants (htab_trav callback, void *info)
120790075Sobrien{
120890075Sobrien  if (md_constants)
120990075Sobrien    htab_traverse (md_constants, callback, info);
121090075Sobrien}
1211169689Skan
1212169689Skan/* INFILE is a FILE pointer to read text from.  TMP_CHAR is a buffer
1213169689Skan   suitable to read a name or number into.  Process a
1214169689Skan   define_conditions directive, starting with the optional space after
1215169689Skan   the "define_conditions".  The directive looks like this:
121690075Sobrien
1217169689Skan     (define_conditions [
1218169689Skan        (number "string")
1219169689Skan        (number "string")
1220169689Skan        ...
1221169689Skan     ])
1222169689Skan
1223169689Skan   It's not intended to appear in machine descriptions.  It is
1224169689Skan   generated by (the program generated by) genconditions.c, and
1225169689Skan   slipped in at the beginning of the sequence of MD files read by
1226169689Skan   most of the other generators.  */
122790075Sobrienstatic void
1228169689Skanread_conditions (FILE *infile, char *tmp_char)
1229169689Skan{
1230169689Skan  int c;
1231169689Skan
1232169689Skan  c = read_skip_spaces (infile);
1233169689Skan  if (c != '[')
1234169689Skan    fatal_expected_char (infile, '[', c);
1235169689Skan
1236169689Skan  while ( (c = read_skip_spaces (infile)) != ']')
1237169689Skan    {
1238169689Skan      char *expr;
1239169689Skan      int value;
1240169689Skan
1241169689Skan      if (c != '(')
1242169689Skan	fatal_expected_char (infile, '(', c);
1243169689Skan
1244169689Skan      read_name (tmp_char, infile);
1245169689Skan      validate_const_int (infile, tmp_char);
1246169689Skan      value = atoi (tmp_char);
1247169689Skan
1248169689Skan      c = read_skip_spaces (infile);
1249169689Skan      if (c != '"')
1250169689Skan	fatal_expected_char (infile, '"', c);
1251169689Skan      expr = read_quoted_string (infile);
1252169689Skan
1253169689Skan      c = read_skip_spaces (infile);
1254169689Skan      if (c != ')')
1255169689Skan	fatal_expected_char (infile, ')', c);
1256169689Skan
1257169689Skan      add_c_test (expr, value);
1258169689Skan    }
1259169689Skan  c = read_skip_spaces (infile);
1260169689Skan  if (c != ')')
1261169689Skan    fatal_expected_char (infile, ')', c);
1262169689Skan}
1263169689Skan
1264169689Skanstatic void
1265132718Skanvalidate_const_int (FILE *infile, const char *string)
126690075Sobrien{
126790075Sobrien  const char *cp;
126890075Sobrien  int valid = 1;
126990075Sobrien
127090075Sobrien  cp = string;
127190075Sobrien  while (*cp && ISSPACE (*cp))
127290075Sobrien    cp++;
127390075Sobrien  if (*cp == '-' || *cp == '+')
127490075Sobrien    cp++;
127590075Sobrien  if (*cp == 0)
127690075Sobrien    valid = 0;
127790075Sobrien  for (; *cp; cp++)
127890075Sobrien    if (! ISDIGIT (*cp))
127990075Sobrien      valid = 0;
128090075Sobrien  if (!valid)
128190075Sobrien    fatal_with_file_and_line (infile, "invalid decimal constant \"%s\"\n", string);
128290075Sobrien}
128390075Sobrien
1284169689Skan/* Search GROUP for a mode or code called NAME and return its numerical
1285169689Skan   identifier.  INFILE is the file that contained NAME.  */
1286169689Skan
1287169689Skanstatic int
1288169689Skanfind_macro (struct macro_group *group, const char *name, FILE *infile)
1289169689Skan{
1290169689Skan  struct mapping *m;
1291169689Skan
1292169689Skan  m = (struct mapping *) htab_find (group->macros, &name);
1293169689Skan  if (m != 0)
1294169689Skan    return m->index + group->num_builtins;
1295169689Skan  return group->find_builtin (name, infile);
1296169689Skan}
1297169689Skan
1298169689Skan/* Finish reading a declaration of the form:
1299169689Skan
1300169689Skan       (define... <name> [<value1> ... <valuen>])
1301169689Skan
1302169689Skan   from INFILE, where each <valuei> is either a bare symbol name or a
1303169689Skan   "(<name> <string>)" pair.  The "(define..." part has already been read.
1304169689Skan
1305169689Skan   Represent the declaration as a "mapping" structure; add it to TABLE
1306169689Skan   (which belongs to GROUP) and return it.  */
1307169689Skan
1308169689Skanstatic struct mapping *
1309169689Skanread_mapping (struct macro_group *group, htab_t table, FILE *infile)
1310169689Skan{
1311169689Skan  char tmp_char[256];
1312169689Skan  struct mapping *m;
1313169689Skan  struct map_value **end_ptr;
1314169689Skan  const char *string;
1315169689Skan  int number, c;
1316169689Skan
1317169689Skan  /* Read the mapping name and create a structure for it.  */
1318169689Skan  read_name (tmp_char, infile);
1319169689Skan  m = add_mapping (group, table, tmp_char, infile);
1320169689Skan
1321169689Skan  c = read_skip_spaces (infile);
1322169689Skan  if (c != '[')
1323169689Skan    fatal_expected_char (infile, '[', c);
1324169689Skan
1325169689Skan  /* Read each value.  */
1326169689Skan  end_ptr = &m->values;
1327169689Skan  c = read_skip_spaces (infile);
1328169689Skan  do
1329169689Skan    {
1330169689Skan      if (c != '(')
1331169689Skan	{
1332169689Skan	  /* A bare symbol name that is implicitly paired to an
1333169689Skan	     empty string.  */
1334169689Skan	  ungetc (c, infile);
1335169689Skan	  read_name (tmp_char, infile);
1336169689Skan	  string = "";
1337169689Skan	}
1338169689Skan      else
1339169689Skan	{
1340169689Skan	  /* A "(name string)" pair.  */
1341169689Skan	  read_name (tmp_char, infile);
1342169689Skan	  string = read_string (infile, false);
1343169689Skan	  c = read_skip_spaces (infile);
1344169689Skan	  if (c != ')')
1345169689Skan	    fatal_expected_char (infile, ')', c);
1346169689Skan	}
1347169689Skan      number = group->find_builtin (tmp_char, infile);
1348169689Skan      end_ptr = add_map_value (end_ptr, number, string);
1349169689Skan      c = read_skip_spaces (infile);
1350169689Skan    }
1351169689Skan  while (c != ']');
1352169689Skan
1353169689Skan  c = read_skip_spaces (infile);
1354169689Skan  if (c != ')')
1355169689Skan    fatal_expected_char (infile, ')', c);
1356169689Skan
1357169689Skan  return m;
1358169689Skan}
1359169689Skan
1360169689Skan/* Check newly-created code macro MACRO to see whether every code has the
1361169689Skan   same format.  Initialize the macro's entry in bellwether_codes.  */
1362169689Skan
1363169689Skanstatic void
1364169689Skancheck_code_macro (struct mapping *macro, FILE *infile)
1365169689Skan{
1366169689Skan  struct map_value *v;
1367169689Skan  enum rtx_code bellwether;
1368169689Skan
1369169689Skan  bellwether = (enum rtx_code) macro->values->number;
1370169689Skan  for (v = macro->values->next; v != 0; v = v->next)
1371169689Skan    if (strcmp (GET_RTX_FORMAT (bellwether), GET_RTX_FORMAT (v->number)) != 0)
1372169689Skan      fatal_with_file_and_line (infile, "code macro `%s' combines "
1373169689Skan				"different rtx formats", macro->name);
1374169689Skan
1375169689Skan  bellwether_codes = XRESIZEVEC (enum rtx_code, bellwether_codes,
1376169689Skan				 macro->index + 1);
1377169689Skan  bellwether_codes[macro->index] = bellwether;
1378169689Skan}
1379169689Skan
1380169689Skan/* Read an rtx in printed representation from INFILE and store its
1381169689Skan   core representation in *X.  Also store the line number of the
1382169689Skan   opening '(' in *LINENO.  Return true on success or false if the
1383169689Skan   end of file has been reached.
1384169689Skan
138590075Sobrien   read_rtx is not used in the compiler proper, but rather in
138690075Sobrien   the utilities gen*.c that construct C code from machine descriptions.  */
138790075Sobrien
1388169689Skanbool
1389169689Skanread_rtx (FILE *infile, rtx *x, int *lineno)
139090075Sobrien{
1391169689Skan  static rtx queue_head, queue_next;
1392169689Skan  static int queue_lineno;
1393169689Skan  int c;
1394169689Skan
1395169689Skan  /* Do one-time initialization.  */
1396169689Skan  if (queue_head == 0)
1397169689Skan    {
1398169689Skan      initialize_macros ();
1399169689Skan      obstack_init (&string_obstack);
1400169689Skan      queue_head = rtx_alloc (EXPR_LIST);
1401169689Skan      ptr_locs = htab_create (161, leading_ptr_hash, leading_ptr_eq_p, 0);
1402169689Skan      obstack_init (&ptr_loc_obstack);
1403169689Skan      joined_conditions = htab_create (161, leading_ptr_hash,
1404169689Skan				       leading_ptr_eq_p, 0);
1405169689Skan      obstack_init (&joined_conditions_obstack);
1406169689Skan    }
1407169689Skan
1408169689Skan  if (queue_next == 0)
1409169689Skan    {
1410169689Skan      struct map_value *mode_maps;
1411169689Skan      struct macro_traverse_data mtd;
1412169689Skan      rtx from_file;
1413169689Skan
1414169689Skan      c = read_skip_spaces (infile);
1415169689Skan      if (c == EOF)
1416169689Skan	return false;
1417169689Skan      ungetc (c, infile);
1418169689Skan
1419169689Skan      queue_lineno = read_rtx_lineno;
1420169689Skan      mode_maps = 0;
1421169689Skan      from_file = read_rtx_1 (infile, &mode_maps);
1422169689Skan      if (from_file == 0)
1423169689Skan	return false;  /* This confuses a top level (nil) with end of
1424169689Skan			  file, but a top level (nil) would have
1425169689Skan			  crashed our caller anyway.  */
1426169689Skan
1427169689Skan      queue_next = queue_head;
1428169689Skan      XEXP (queue_next, 0) = from_file;
1429169689Skan      XEXP (queue_next, 1) = 0;
1430169689Skan
1431169689Skan      mtd.queue = queue_next;
1432169689Skan      mtd.mode_maps = mode_maps;
1433169689Skan      mtd.infile = infile;
1434169689Skan      mtd.unknown_mode_attr = mode_maps ? mode_maps->string : NULL;
1435169689Skan      htab_traverse (modes.macros, apply_macro_traverse, &mtd);
1436169689Skan      htab_traverse (codes.macros, apply_macro_traverse, &mtd);
1437169689Skan      if (mtd.unknown_mode_attr)
1438169689Skan	fatal_with_file_and_line (infile,
1439169689Skan				  "undefined attribute '%s' used for mode",
1440169689Skan				  mtd.unknown_mode_attr);
1441169689Skan    }
1442169689Skan
1443169689Skan  *x = XEXP (queue_next, 0);
1444169689Skan  *lineno = queue_lineno;
1445169689Skan  queue_next = XEXP (queue_next, 1);
1446169689Skan
1447169689Skan  return true;
1448169689Skan}
1449169689Skan
1450169689Skan/* Subroutine of read_rtx that reads one construct from INFILE but
1451169689Skan   doesn't apply any macros.  */
1452169689Skan
1453169689Skanstatic rtx
1454169689Skanread_rtx_1 (FILE *infile, struct map_value **mode_maps)
1455169689Skan{
1456169689Skan  int i;
1457169689Skan  RTX_CODE real_code, bellwether_code;
145890075Sobrien  const char *format_ptr;
145990075Sobrien  /* tmp_char is a buffer used for reading decimal integers
146090075Sobrien     and names of rtx types and machine modes.
146190075Sobrien     Therefore, 256 must be enough.  */
146290075Sobrien  char tmp_char[256];
146390075Sobrien  rtx return_rtx;
146490075Sobrien  int c;
146590075Sobrien  int tmp_int;
146690075Sobrien  HOST_WIDE_INT tmp_wide;
146790075Sobrien
146890075Sobrien  /* Linked list structure for making RTXs: */
146990075Sobrien  struct rtx_list
147090075Sobrien    {
147190075Sobrien      struct rtx_list *next;
147290075Sobrien      rtx value;		/* Value of this node.  */
147390075Sobrien    };
147490075Sobrien
1475169689Skan again:
1476169689Skan  c = read_skip_spaces (infile); /* Should be open paren.  */
147790075Sobrien
1478169689Skan  if (c == EOF)
1479169689Skan    return 0;
1480169689Skan
148190075Sobrien  if (c != '(')
148290075Sobrien    fatal_expected_char (infile, '(', c);
148390075Sobrien
148490075Sobrien  read_name (tmp_char, infile);
1485169689Skan  if (strcmp (tmp_char, "nil") == 0)
148690075Sobrien    {
1487169689Skan      /* (nil) stands for an expression that isn't there.  */
1488169689Skan      c = read_skip_spaces (infile);
1489169689Skan      if (c != ')')
1490169689Skan	fatal_expected_char (infile, ')', c);
1491169689Skan      return 0;
1492169689Skan    }
1493169689Skan  if (strcmp (tmp_char, "define_constants") == 0)
1494169689Skan    {
149590075Sobrien      read_constants (infile, tmp_char);
149690075Sobrien      goto again;
149790075Sobrien    }
1498169689Skan  if (strcmp (tmp_char, "define_conditions") == 0)
149990075Sobrien    {
1500169689Skan      read_conditions (infile, tmp_char);
1501169689Skan      goto again;
150290075Sobrien    }
1503169689Skan  if (strcmp (tmp_char, "define_mode_attr") == 0)
1504169689Skan    {
1505169689Skan      read_mapping (&modes, modes.attrs, infile);
1506169689Skan      goto again;
1507169689Skan    }
1508169689Skan  if (strcmp (tmp_char, "define_mode_macro") == 0)
1509169689Skan    {
1510169689Skan      read_mapping (&modes, modes.macros, infile);
1511169689Skan      goto again;
1512169689Skan    }
1513169689Skan  if (strcmp (tmp_char, "define_code_attr") == 0)
1514169689Skan    {
1515169689Skan      read_mapping (&codes, codes.attrs, infile);
1516169689Skan      goto again;
1517169689Skan    }
1518169689Skan  if (strcmp (tmp_char, "define_code_macro") == 0)
1519169689Skan    {
1520169689Skan      check_code_macro (read_mapping (&codes, codes.macros, infile), infile);
1521169689Skan      goto again;
1522169689Skan    }
1523169689Skan  real_code = (enum rtx_code) find_macro (&codes, tmp_char, infile);
1524169689Skan  bellwether_code = BELLWETHER_CODE (real_code);
152590075Sobrien
152690075Sobrien  /* If we end up with an insn expression then we free this space below.  */
1527169689Skan  return_rtx = rtx_alloc (bellwether_code);
1528169689Skan  format_ptr = GET_RTX_FORMAT (bellwether_code);
1529169689Skan  PUT_CODE (return_rtx, real_code);
153090075Sobrien
153190075Sobrien  /* If what follows is `: mode ', read it and
153290075Sobrien     store the mode in the rtx.  */
153390075Sobrien
153490075Sobrien  i = read_skip_spaces (infile);
153590075Sobrien  if (i == ':')
153690075Sobrien    {
1537169689Skan      unsigned int mode;
1538169689Skan
153990075Sobrien      read_name (tmp_char, infile);
1540169689Skan      if (tmp_char[0] != '<' || tmp_char[strlen (tmp_char) - 1] != '>')
1541169689Skan	mode = find_macro (&modes, tmp_char, infile);
1542169689Skan      else
1543169689Skan	mode = mode_attr_index (mode_maps, tmp_char);
1544169689Skan      PUT_MODE (return_rtx, (enum machine_mode) mode);
1545169689Skan      if (GET_MODE (return_rtx) != mode)
1546169689Skan	fatal_with_file_and_line (infile, "mode too large");
154790075Sobrien    }
154890075Sobrien  else
154990075Sobrien    ungetc (i, infile);
155090075Sobrien
1551169689Skan  for (i = 0; format_ptr[i] != 0; i++)
1552169689Skan    switch (format_ptr[i])
155390075Sobrien      {
155490075Sobrien	/* 0 means a field for internal use only.
155590075Sobrien	   Don't expect it to be present in the input.  */
155690075Sobrien      case '0':
155790075Sobrien	break;
155890075Sobrien
155990075Sobrien      case 'e':
156090075Sobrien      case 'u':
1561169689Skan	XEXP (return_rtx, i) = read_rtx_1 (infile, mode_maps);
156290075Sobrien	break;
156390075Sobrien
156490075Sobrien      case 'V':
156590075Sobrien	/* 'V' is an optional vector: if a closeparen follows,
156690075Sobrien	   just store NULL for this element.  */
156790075Sobrien	c = read_skip_spaces (infile);
156890075Sobrien	ungetc (c, infile);
156990075Sobrien	if (c == ')')
157090075Sobrien	  {
157190075Sobrien	    XVEC (return_rtx, i) = 0;
157290075Sobrien	    break;
1573117395Skan	  }
157490075Sobrien	/* Now process the vector.  */
157590075Sobrien
157690075Sobrien      case 'E':
157790075Sobrien	{
157890075Sobrien	  /* Obstack to store scratch vector in.  */
157990075Sobrien	  struct obstack vector_stack;
158090075Sobrien	  int list_counter = 0;
158190075Sobrien	  rtvec return_vec = NULL_RTVEC;
158290075Sobrien
158390075Sobrien	  c = read_skip_spaces (infile);
158490075Sobrien	  if (c != '[')
158590075Sobrien	    fatal_expected_char (infile, '[', c);
158690075Sobrien
1587169689Skan	  /* Add expressions to a list, while keeping a count.  */
158890075Sobrien	  obstack_init (&vector_stack);
158990075Sobrien	  while ((c = read_skip_spaces (infile)) && c != ']')
159090075Sobrien	    {
159190075Sobrien	      ungetc (c, infile);
159290075Sobrien	      list_counter++;
1593169689Skan	      obstack_ptr_grow (&vector_stack, read_rtx_1 (infile, mode_maps));
159490075Sobrien	    }
159590075Sobrien	  if (list_counter > 0)
159690075Sobrien	    {
159790075Sobrien	      return_vec = rtvec_alloc (list_counter);
159890075Sobrien	      memcpy (&return_vec->elem[0], obstack_finish (&vector_stack),
159990075Sobrien		      list_counter * sizeof (rtx));
160090075Sobrien	    }
1601169689Skan	  else if (format_ptr[i] == 'E')
1602169689Skan	    fatal_with_file_and_line (infile,
1603169689Skan				      "vector must have at least one element");
160490075Sobrien	  XVEC (return_rtx, i) = return_vec;
160590075Sobrien	  obstack_free (&vector_stack, NULL);
160690075Sobrien	  /* close bracket gotten */
160790075Sobrien	}
160890075Sobrien	break;
160990075Sobrien
161090075Sobrien      case 'S':
161190075Sobrien      case 'T':
161290075Sobrien      case 's':
161390075Sobrien	{
161490075Sobrien	  char *stringbuf;
1615169689Skan	  int star_if_braced;
161690075Sobrien
1617169689Skan	  c = read_skip_spaces (infile);
1618169689Skan	  ungetc (c, infile);
1619169689Skan	  if (c == ')')
1620169689Skan	    {
1621169689Skan	      /* 'S' fields are optional and should be NULL if no string
1622169689Skan		 was given.  Also allow normal 's' and 'T' strings to be
1623169689Skan		 omitted, treating them in the same way as empty strings.  */
1624169689Skan	      XSTR (return_rtx, i) = (format_ptr[i] == 'S' ? NULL : "");
1625169689Skan	      break;
1626169689Skan	    }
1627169689Skan
162890075Sobrien	  /* The output template slot of a DEFINE_INSN,
162990075Sobrien	     DEFINE_INSN_AND_SPLIT, or DEFINE_PEEPHOLE automatically
163090075Sobrien	     gets a star inserted as its first character, if it is
163190075Sobrien	     written with a brace block instead of a string constant.  */
1632169689Skan	  star_if_braced = (format_ptr[i] == 'T');
1633117395Skan
1634169689Skan	  stringbuf = read_string (infile, star_if_braced);
163590075Sobrien
163690075Sobrien	  /* For insn patterns, we want to provide a default name
163790075Sobrien	     based on the file and line, like "*foo.md:12", if the
163890075Sobrien	     given name is blank.  These are only for define_insn and
163990075Sobrien	     define_insn_and_split, to aid debugging.  */
164090075Sobrien	  if (*stringbuf == '\0'
164190075Sobrien	      && i == 0
164290075Sobrien	      && (GET_CODE (return_rtx) == DEFINE_INSN
164390075Sobrien		  || GET_CODE (return_rtx) == DEFINE_INSN_AND_SPLIT))
164490075Sobrien	    {
164590075Sobrien	      char line_name[20];
164690075Sobrien	      const char *fn = (read_rtx_filename ? read_rtx_filename : "rtx");
164790075Sobrien	      const char *slash;
164890075Sobrien	      for (slash = fn; *slash; slash ++)
164990075Sobrien		if (*slash == '/' || *slash == '\\' || *slash == ':')
165090075Sobrien		  fn = slash + 1;
1651169689Skan	      obstack_1grow (&string_obstack, '*');
1652169689Skan	      obstack_grow (&string_obstack, fn, strlen (fn));
165390075Sobrien	      sprintf (line_name, ":%d", read_rtx_lineno);
1654169689Skan	      obstack_grow (&string_obstack, line_name, strlen (line_name)+1);
1655169689Skan	      stringbuf = XOBFINISH (&string_obstack, char *);
165690075Sobrien	    }
165790075Sobrien
165890075Sobrien	  if (star_if_braced)
165990075Sobrien	    XTMPL (return_rtx, i) = stringbuf;
166090075Sobrien	  else
166190075Sobrien	    XSTR (return_rtx, i) = stringbuf;
166290075Sobrien	}
166390075Sobrien	break;
166490075Sobrien
166590075Sobrien      case 'w':
166690075Sobrien	read_name (tmp_char, infile);
166790075Sobrien	validate_const_int (infile, tmp_char);
166890075Sobrien#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
166990075Sobrien	tmp_wide = atoi (tmp_char);
167090075Sobrien#else
167190075Sobrien#if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_LONG
167290075Sobrien	tmp_wide = atol (tmp_char);
167390075Sobrien#else
167490075Sobrien	/* Prefer atoll over atoq, since the former is in the ISO C99 standard.
167590075Sobrien	   But prefer not to use our hand-rolled function above either.  */
167690075Sobrien#if defined(HAVE_ATOLL) || !defined(HAVE_ATOQ)
167790075Sobrien	tmp_wide = atoll (tmp_char);
167890075Sobrien#else
167990075Sobrien	tmp_wide = atoq (tmp_char);
168090075Sobrien#endif
168190075Sobrien#endif
168290075Sobrien#endif
168390075Sobrien	XWINT (return_rtx, i) = tmp_wide;
168490075Sobrien	break;
168590075Sobrien
168690075Sobrien      case 'i':
168790075Sobrien      case 'n':
168890075Sobrien	read_name (tmp_char, infile);
168990075Sobrien	validate_const_int (infile, tmp_char);
169090075Sobrien	tmp_int = atoi (tmp_char);
169190075Sobrien	XINT (return_rtx, i) = tmp_int;
169290075Sobrien	break;
169390075Sobrien
169490075Sobrien      default:
1695169689Skan	gcc_unreachable ();
169690075Sobrien      }
169790075Sobrien
169890075Sobrien  c = read_skip_spaces (infile);
169990075Sobrien  if (c != ')')
1700169689Skan    {
1701169689Skan      /* Syntactic sugar for AND and IOR, allowing Lisp-like
1702169689Skan	 arbitrary number of arguments for them.  */
1703169689Skan      if (c == '(' && (GET_CODE (return_rtx) == AND
1704169689Skan		       || GET_CODE (return_rtx) == IOR))
1705169689Skan	return read_rtx_variadic (infile, mode_maps, return_rtx);
1706169689Skan      else
1707169689Skan	fatal_expected_char (infile, ')', c);
1708169689Skan    }
170990075Sobrien
171090075Sobrien  return return_rtx;
171190075Sobrien}
1712169689Skan
1713169689Skan/* Mutually recursive subroutine of read_rtx which reads
1714169689Skan   (thing x1 x2 x3 ...) and produces RTL as if
1715169689Skan   (thing x1 (thing x2 (thing x3 ...)))  had been written.
1716169689Skan   When called, FORM is (thing x1 x2), and the file position
1717169689Skan   is just past the leading parenthesis of x3.  Only works
1718169689Skan   for THINGs which are dyadic expressions, e.g. AND, IOR.  */
1719169689Skanstatic rtx
1720169689Skanread_rtx_variadic (FILE *infile, struct map_value **mode_maps, rtx form)
1721169689Skan{
1722169689Skan  char c = '(';
1723169689Skan  rtx p = form, q;
1724169689Skan
1725169689Skan  do
1726169689Skan    {
1727169689Skan      ungetc (c, infile);
1728169689Skan
1729169689Skan      q = rtx_alloc (GET_CODE (p));
1730169689Skan      PUT_MODE (q, GET_MODE (p));
1731169689Skan
1732169689Skan      XEXP (q, 0) = XEXP (p, 1);
1733169689Skan      XEXP (q, 1) = read_rtx_1 (infile, mode_maps);
1734169689Skan
1735169689Skan      XEXP (p, 1) = q;
1736169689Skan      p = q;
1737169689Skan      c = read_skip_spaces (infile);
1738169689Skan    }
1739169689Skan  while (c == '(');
1740169689Skan
1741169689Skan  if (c != ')')
1742169689Skan    fatal_expected_char (infile, ')', c);
1743169689Skan
1744169689Skan  return form;
1745169689Skan}
1746