1/* Generate built-in function initialization and recognition for Power.
2   Copyright (C) 2020-2022 Free Software Foundation, Inc.
3   Contributed by Bill Schmidt, IBM <wschmidt@linux.ibm.com>
4
5This file is part of GCC.
6
7GCC is free software; you can redistribute it and/or modify it under
8the terms of the GNU General Public License as published by the Free
9Software Foundation; either version 3, or (at your option) any later
10version.
11
12GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13WARRANTY; without even the implied warranty of MERCHANTABILITY or
14FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15for more details.
16
17You should have received a copy of the GNU General Public License
18along with GCC; see the file COPYING3.  If not see
19<http://www.gnu.org/licenses/>.  */
20
21/* This program generates built-in function initialization and
22   recognition code for Power targets, based on text files that
23   describe the built-in functions and vector overloads:
24
25     rs6000-builtins.def        Table of built-in functions
26     rs6000-overload.def        Table of overload functions
27
28   Both files group similar functions together in "stanzas," as
29   described below.
30
31   Each stanza in the built-in function file starts with a line
32   identifying the circumstances in which the group of functions is
33   permitted, with the gating predicate in square brackets.  For
34   example, this could be
35
36     [altivec]
37
38   or it could be
39
40     [power9]
41
42   The bracketed gating predicate is the only information allowed on
43   the stanza header line, other than whitespace.
44
45   Following the stanza header are two lines for each function: the
46   prototype line and the attributes line.  The prototype line has
47   this format, where the square brackets indicate optional
48   information and angle brackets indicate required information:
49
50     [kind] <return-type> <bif-name> (<argument-list>);
51
52   Here [kind] can be one of "const", "pure", or "fpmath";
53   <return-type> is a legal type for a built-in function result;
54   <bif-name> is the name by which the function can be called;
55   and <argument-list> is a comma-separated list of legal types
56   for built-in function arguments.  The argument list may be
57   empty, but the parentheses and semicolon are required.
58
59   The attributes line looks like this:
60
61     <bif-id> <bif-pattern> {<attribute-list>}
62
63   Here <bif-id> is a unique internal identifier for the built-in
64   function that will be used as part of an enumeration of all
65   built-in functions; <bif-pattern> is the define_expand or
66   define_insn that will be invoked when the call is expanded;
67   and <attribute-list> is a comma-separated list of special
68   conditions that apply to the built-in function.  The attribute
69   list may be empty, but the braces are required.
70
71   Attributes are strings, such as these:
72
73     init     Process as a vec_init function
74     set      Process as a vec_set function
75     extract  Process as a vec_extract function
76     nosoft   Not valid with -msoft-float
77     ldvec    Needs special handling for vec_ld semantics
78     stvec    Needs special handling for vec_st semantics
79     reve     Needs special handling for element reversal
80     pred     Needs special handling for comparison predicates
81     htm      Needs special handling for transactional memory
82     htmspr   HTM function using an SPR
83     htmcr    HTM function using a CR
84     mma      Needs special handling for MMA instructions
85     quad     MMA instruction using a register quad as an input operand
86     pair     MMA instruction using a register pair as an input operand
87     mmaint   MMA instruction expanding to internal call at GIMPLE time
88     no32bit  Not valid for TARGET_32BIT
89     32bit    Requires different handling for TARGET_32BIT
90     cpu      This is a "cpu_is" or "cpu_supports" builtin
91     ldstmask Altivec mask for load or store
92     lxvrse   Needs special handling for load-rightmost, sign-extended
93     lxvrze   Needs special handling for load-rightmost, zero-extended
94     endian   Needs special handling for endianness
95     ibmld    Restrict usage to the case when TFmode is IBM-128
96     ibm128   Restrict usage to the case where __ibm128 is supported or
97              if ibmld
98
99   An example stanza might look like this:
100
101[altivec]
102  const vsc __builtin_altivec_abs_v16qi (vsc);
103    ABS_V16QI absv16qi2 {}
104  const vss __builtin_altivec_abs_v8hi (vss);
105    ABS_V8HI absv8hi2 {}
106
107   Here "vsc" and "vss" are shorthand for "vector signed char" and
108   "vector signed short" to shorten line lengths and improve readability.
109   Note the use of indentation, which is recommended but not required.
110
111   The overload file has more complex stanza headers.  Here the stanza
112   represents all functions with the same overloaded function name:
113
114     [<overload-id>, <abi-name>, <builtin-name>[[, <ifdef>]] ]
115
116   Here the single square brackets are part of the syntax, <overload-id>
117   is a unique internal identifier for the overload that will be used as
118   part of an enumeration of all overloaded functions; <abi-name> is the
119   name that will appear as a #define in rs6000-vecdefines.h;
120   <builtin-name> is the name that is overloaded in the back end; and
121   <ifdef> is an optional token used to guard the #define with an #ifdef
122   in rs6000-vecdefines.h.
123
124   Each function entry again has two lines.  The first line is again a
125   prototype line (this time without [kind]):
126
127     <return-type> <internal-name> (<argument-list>);
128
129   The second line contains the <bif-id> that this particular instance of
130   the overloaded function maps to.  It must match a token that appears in
131   rs6000-builtins.def.  Optionally, a second token may appear.  If only
132   one token is on the line, it is also used to build the unique identifier
133   for the overloaded function.  If a second token is present, the second
134   token is used instead for this purpose.  This is necessary in cases
135   where a built-in function accepts more than one type signature.  It is
136   common to have a built-in function that, for example, specifies a
137   "vector signed char" argument, but accepts "vector unsigned char" and
138   "vector bool char" as well because only the mode matters.  Note that
139   the overload resolution mechanism has always handled these cases by
140   performing fold_convert on vector arguments to hide type mismatches,
141   and it will continue to do so.
142
143   As a concrete example, __builtin_altivec_mtvscr uses an opaque argument
144   type for the source operand.  Its built-in function id is MTVSCR.  The
145   overloaded function __builtin_vec_mtvscr takes a variety of specific
146   types, but not all vector types.  Each of these maps to the same
147   __builtin_altivec_mtvscr built-in function, but the overload ID must
148   be unique, so we must specify the second token as shown here.
149
150    [VEC_MTVSCR, vec_mtvscr, __builtin_vec_mtvscr]
151      void __builtin_vec_mtvscr (vbc);
152	MTVSCR  MTVSCR_VBC
153      void __builtin_vec_mtvscr (vsc);
154	MTVSCR  MTVSCR_VSC
155      ...
156
157  Blank lines may be used as desired in these files between the lines as
158  defined above; that is, you can introduce as many extra newlines as you
159  like after a required newline, but nowhere else.  Lines beginning with
160  a semicolon are also treated as blank lines.  */
161
162#include <stdio.h>
163#include <stdlib.h>
164#include <stdarg.h>
165#include <stdint.h>
166#include <ctype.h>
167#include <string.h>
168#include <assert.h>
169#include <unistd.h>
170#include "rbtree.h"
171
172/* Input and output file descriptors and pathnames.  */
173static FILE *bif_file;
174static FILE *ovld_file;
175static FILE *header_file;
176static FILE *init_file;
177static FILE *defines_file;
178
179static const char *pgm_path;
180static const char *bif_path;
181static const char *ovld_path;
182static const char *header_path;
183static const char *init_path;
184static const char *defines_path;
185
186/* Position information.  Note that "pos" is zero-indexed, but users
187   expect one-indexed column information, so representations of "pos"
188   as columns in diagnostic messages must be adjusted.  */
189#define MAXLINES 4
190#define LINELEN 1024
191static char linebuf[LINELEN * MAXLINES];
192static int line;
193static int pos;
194
195/* Escape-newline support.  For readability, we prefer to allow developers
196   to use escape-newline to continue long lines to the next one.  We
197   maintain a buffer of "original" lines here, which are concatenated into
198   linebuf, above, and which can be used to convert the virtual line
199   position "line / pos" into actual line and position information.  */
200static char *lines[MAXLINES];
201static int lastline;
202
203/* Used to determine whether a type can be void (only return types).  */
204enum void_status
205{
206 VOID_NOTOK,
207 VOID_OK
208};
209
210/* Stanzas are groupings of built-in functions and overloads by some
211   common feature/attribute.  These definitions are for built-in function
212   stanzas.  */
213enum bif_stanza
214{
215 BSTZ_ALWAYS,
216 BSTZ_P5,
217 BSTZ_P6,
218 BSTZ_P6_64,
219 BSTZ_ALTIVEC,
220 BSTZ_CELL,
221 BSTZ_VSX,
222 BSTZ_P7,
223 BSTZ_P7_64,
224 BSTZ_P8,
225 BSTZ_P8V,
226 BSTZ_P9,
227 BSTZ_P9_64,
228 BSTZ_P9V,
229 BSTZ_IEEE128_HW,
230 BSTZ_DFP,
231 BSTZ_CRYPTO,
232 BSTZ_HTM,
233 BSTZ_P10,
234 BSTZ_P10_64,
235 BSTZ_MMA,
236 NUMBIFSTANZAS
237};
238
239static bif_stanza curr_bif_stanza;
240
241struct stanza_entry
242{
243  const char *stanza_name;
244  bif_stanza stanza;
245};
246
247static stanza_entry stanza_map[NUMBIFSTANZAS] =
248  {
249    { "always",		BSTZ_ALWAYS	},
250    { "power5",		BSTZ_P5		},
251    { "power6",		BSTZ_P6		},
252    { "power6-64",	BSTZ_P6_64	},
253    { "altivec",	BSTZ_ALTIVEC	},
254    { "cell",		BSTZ_CELL	},
255    { "vsx",		BSTZ_VSX	},
256    { "power7",		BSTZ_P7		},
257    { "power7-64",	BSTZ_P7_64	},
258    { "power8",		BSTZ_P8		},
259    { "power8-vector",	BSTZ_P8V	},
260    { "power9",		BSTZ_P9		},
261    { "power9-64",	BSTZ_P9_64	},
262    { "power9-vector",	BSTZ_P9V	},
263    { "ieee128-hw",	BSTZ_IEEE128_HW	},
264    { "dfp",		BSTZ_DFP	},
265    { "crypto",		BSTZ_CRYPTO	},
266    { "htm",		BSTZ_HTM	},
267    { "power10",	BSTZ_P10	},
268    { "power10-64",	BSTZ_P10_64	},
269    { "mma",		BSTZ_MMA	}
270  };
271
272static const char *enable_string[NUMBIFSTANZAS] =
273  {
274    "ENB_ALWAYS",
275    "ENB_P5",
276    "ENB_P6",
277    "ENB_P6_64",
278    "ENB_ALTIVEC",
279    "ENB_CELL",
280    "ENB_VSX",
281    "ENB_P7",
282    "ENB_P7_64",
283    "ENB_P8",
284    "ENB_P8V",
285    "ENB_P9",
286    "ENB_P9_64",
287    "ENB_P9V",
288    "ENB_IEEE128_HW",
289    "ENB_DFP",
290    "ENB_CRYPTO",
291    "ENB_HTM",
292    "ENB_P10",
293    "ENB_P10_64",
294    "ENB_MMA"
295  };
296
297/* Function modifiers provide special handling for const, pure, and fpmath
298   functions.  These are mutually exclusive, and therefore kept separate
299   from other bif attributes.  */
300enum fnkinds
301{
302  FNK_NONE,
303  FNK_CONST,
304  FNK_PURE,
305  FNK_FPMATH
306};
307
308/* Legal base types for an argument or return type.  */
309enum basetype
310{
311  BT_CHAR,
312  BT_SHORT,
313  BT_INT,
314  BT_LONG,
315  BT_LONGLONG,
316  BT_FLOAT,
317  BT_DOUBLE,
318  BT_LONGDOUBLE,
319  BT_INT128,
320  BT_FLOAT128,
321  BT_BOOL,
322  BT_STRING,
323  BT_DECIMAL32,
324  BT_DECIMAL64,
325  BT_DECIMAL128,
326  BT_IBM128,
327  BT_VPAIR,
328  BT_VQUAD
329};
330
331/* Ways in which a const int value can be restricted.  RES_BITS indicates
332   that the integer is restricted to val1 bits, interpreted as an unsigned
333   number.  RES_RANGE indicates that the integer is restricted to values
334   between val1 and val2, inclusive.  RES_VAR_RANGE is like RES_RANGE, but
335   the argument may be variable, so it can only be checked if it is constant.
336   RES_VALUES indicates that the integer must have one of the values val1
337   or val2.  */
338enum restriction
339{
340  RES_NONE,
341  RES_BITS,
342  RES_RANGE,
343  RES_VAR_RANGE,
344  RES_VALUES
345};
346
347/* Type modifiers for an argument or return type.  */
348struct typeinfo
349{
350  char isvoid;
351  char isconst;
352  char isvector;
353  char issigned;
354  char isunsigned;
355  char isbool;
356  char ispixel;
357  char ispointer;
358  basetype base;
359  restriction restr;
360  char *val1;
361  char *val2;
362};
363
364/* A list of argument types.  */
365struct typelist
366{
367  typeinfo info;
368  typelist *next;
369};
370
371/* Attributes of a builtin function.  */
372struct attrinfo
373{
374  bool isinit;
375  bool isset;
376  bool isextract;
377  bool isnosoft;
378  bool isldvec;
379  bool isstvec;
380  bool isreve;
381  bool ispred;
382  bool ishtm;
383  bool ishtmspr;
384  bool ishtmcr;
385  bool ismma;
386  bool isquad;
387  bool ispair;
388  bool ismmaint;
389  bool isno32bit;
390  bool is32bit;
391  bool iscpu;
392  bool isldstmask;
393  bool islxvrse;
394  bool islxvrze;
395  bool isendian;
396  bool isibmld;
397  bool isibm128;
398};
399
400/* Fields associated with a function prototype (bif or overload).  */
401#define MAXRESTROPNDS 3
402struct prototype
403{
404  typeinfo rettype;
405  char *bifname;
406  int nargs;
407  typelist *args;
408  int restr_opnd[MAXRESTROPNDS];
409  restriction restr[MAXRESTROPNDS];
410  char *restr_val1[MAXRESTROPNDS];
411  char *restr_val2[MAXRESTROPNDS];
412};
413
414/* Data associated with a builtin function, and a table of such data.  */
415#define MAXBIFS 16384
416struct bifdata
417{
418  int stanza;
419  fnkinds kind;
420  prototype proto;
421  char *idname;
422  char *patname;
423  attrinfo attrs;
424  char *fndecl;
425};
426
427static bifdata bifs[MAXBIFS];
428static int num_bifs;
429static int curr_bif;
430
431/* Array used to track the order in which built-ins appeared in the
432   built-in file.  We reorder them alphabetically but sometimes need
433   this information.  */
434static int *bif_order;
435static int bif_index = 0;
436
437/* Stanzas are groupings of built-in functions and overloads by some
438   common feature/attribute.  These definitions are for overload stanzas.  */
439struct ovld_stanza
440{
441  char *stanza_id;
442  char *extern_name;
443  char *intern_name;
444  char *ifdef;
445};
446
447#define MAXOVLDSTANZAS 512
448static ovld_stanza ovld_stanzas[MAXOVLDSTANZAS];
449static int num_ovld_stanzas;
450static int curr_ovld_stanza;
451
452#define MAXOVLDS 16384
453struct ovlddata
454{
455  int stanza;
456  prototype proto;
457  char *bif_id_name;
458  char *ovld_id_name;
459  char *fndecl;
460};
461
462static ovlddata ovlds[MAXOVLDS];
463static int num_ovlds;
464static int curr_ovld;
465static int max_ovld_args = 0;
466
467/* Return codes for parsing routines.  */
468enum parse_codes
469{
470  PC_OK,
471  PC_EOFILE,
472  PC_EOSTANZA,
473  PC_PARSEFAIL
474};
475
476/* The red-black trees for built-in function identifiers, built-in
477   overload identifiers, and function type descriptors.  */
478static rbt_strings bif_rbt;
479static rbt_strings ovld_rbt;
480static rbt_strings fntype_rbt;
481
482/* Another red-black tree containing a mapping from built-in function
483   identifiers to the order in which they were encountered.  */
484static rbt_strings bifo_rbt;
485
486/* Mapping from type tokens to type node names.  */
487struct typemap
488{
489  const char *key;
490  const char *value;
491};
492
493/* This table must be kept in alphabetical order, as we use binary
494   search for table lookups in map_token_to_type_node.  The table
495   maps tokens from a fntype string to a tree type.  For example,
496   in "si_ftype_hi" we would map "si" to "intSI_type_node" and
497   map "hi" to "intHI_type_node".  */
498static typemap type_map[] =
499  {
500    { "bi",		"bool_int" },
501    { "bv16qi",		"bool_V16QI" },
502    { "bv1ti",		"bool_V1TI" },
503    { "bv2di",		"bool_V2DI" },
504    { "bv4si",		"bool_V4SI" },
505    { "bv8hi",		"bool_V8HI" },
506    { "ci",		"integer" },
507    { "dd",		"dfloat64" },
508    { "df",		"double" },
509    { "di",		"long_long_integer" },
510    { "hi",		"intHI" },
511    { "if",		"ibm128_float_type_node "
512			"? ibm128_float_type_node "
513			": long_double" },
514    { "ld",		"long_double" },
515    { "lg",		"long_integer" },
516    { "pbv16qi",	"ptr_bool_V16QI" },
517    { "pbv1ti",		"ptr_bool_V1TI" },
518    { "pbv2di",		"ptr_bool_V2DI" },
519    { "pbv4si",		"ptr_bool_V4SI" },
520    { "pbv8hi",		"ptr_bool_V8HI" },
521    { "pcvoid",		"pcvoid" },
522    { "pdd",		"ptr_dfloat64" },
523    { "pdf",		"ptr_double" },
524    { "pdi",		"ptr_long_long_integer" },
525    { "phi",		"ptr_intHI" },
526    { "pld",		"ptr_long_double" },
527    { "plg",		"ptr_long_integer" },
528    { "pqi",		"ptr_intQI" },
529    { "psf",		"ptr_float" },
530    { "psi",		"ptr_intSI" },
531    { "ptd",		"ptr_dfloat128" },
532    { "ptf",		"ptr_float128" },
533    { "pti",		"ptr_intTI" },
534    { "pudi",		"ptr_long_long_unsigned" },
535    { "puhi",		"ptr_uintHI" },
536    { "pulg",		"ptr_long_unsigned" },
537    { "puqi",		"ptr_uintQI" },
538    { "pusi",		"ptr_uintSI" },
539    { "puti",		"ptr_uintTI" },
540    { "puv16qi",	"ptr_unsigned_V16QI" },
541    { "puv1ti",		"ptr_unsigned_V1TI" },
542    { "puv2di",		"ptr_unsigned_V2DI" },
543    { "puv4si",		"ptr_unsigned_V4SI" },
544    { "puv8hi",		"ptr_unsigned_V8HI" },
545    { "pv",		"ptr" },
546    { "pv16qi",		"ptr_V16QI" },
547    { "pv1poi",		"ptr_vector_pair" },
548    { "pv1pxi",		"ptr_vector_quad" },
549    { "pv1ti",		"ptr_V1TI" },
550    { "pv2df",		"ptr_V2DF" },
551    { "pv2di",		"ptr_V2DI" },
552    { "pv4sf",		"ptr_V4SF" },
553    { "pv4si",		"ptr_V4SI" },
554    { "pv8hi",		"ptr_V8HI" },
555    { "pvp8hi",		"ptr_pixel_V8HI" },
556    { "qi",		"intQI" },
557    { "sd",		"dfloat32" },
558    { "sf",		"float" },
559    { "si",		"intSI" },
560    { "st",		"const_str" },
561    { "td",		"dfloat128" },
562    { "tf",		"float128" },
563    { "ti",		"intTI" },
564    { "udi",		"long_long_unsigned" },
565    { "uhi",		"unsigned_intHI" },
566    { "ulg",		"long_unsigned" },
567    { "uqi",		"unsigned_intQI" },
568    { "usi",		"unsigned_intSI" },
569    { "uti",		"unsigned_intTI" },
570    { "uv16qi",		"unsigned_V16QI" },
571    { "uv1ti",		"unsigned_V1TI" },
572    { "uv2di",		"unsigned_V2DI" },
573    { "uv4si",		"unsigned_V4SI" },
574    { "uv8hi",		"unsigned_V8HI" },
575    { "v",		"void" },
576    { "v16qi",		"V16QI" },
577    { "v1poi",		"vector_pair" },
578    { "v1pxi",		"vector_quad" },
579    { "v1ti",		"V1TI" },
580    { "v2df",		"V2DF" },
581    { "v2di",		"V2DI" },
582    { "v4sf",		"V4SF" },
583    { "v4si",		"V4SI" },
584    { "v8hi",		"V8HI" },
585    { "vp8hi",		"pixel_V8HI" },
586  };
587
588/* From a possibly extended line with a virtual position, calculate
589   the current line and character position.  */
590static void
591real_line_pos (int diagpos, int *real_line, int *real_pos)
592{
593  *real_line = line - lastline;
594  *real_pos = diagpos;
595
596  for (int i = 0; i < MAXLINES; i++)
597    {
598      int len = strlen(lines[i]);
599      if (*real_pos <= len)
600	break;
601
602      (*real_line)++;
603      *real_pos -= len - 2;
604    }
605
606  /* Convert from zero-base to one-base for printing.  */
607  (*real_pos)++;
608}
609
610/* Pointer to a diagnostic function.  */
611static void (*diag) (int, const char *, ...)
612  __attribute__ ((format (printf, 2, 3)));
613
614/* Custom diagnostics.  */
615static void __attribute__ ((format (printf, 2, 3)))
616bif_diag (int diagpos, const char * fmt, ...)
617{
618  va_list args;
619  int real_line, real_pos;
620  real_line_pos (diagpos, &real_line, &real_pos);
621  fprintf (stderr, "%s:%d:%d: ", bif_path, real_line, real_pos);
622  va_start (args, fmt);
623  vfprintf (stderr, fmt, args);
624  va_end (args);
625}
626
627static void __attribute__ ((format (printf, 2, 3)))
628ovld_diag (int diagpos, const char * fmt, ...)
629{
630  va_list args;
631  int real_line, real_pos;
632  real_line_pos (diagpos, &real_line, &real_pos);
633  fprintf (stderr, "%s:%d:%d: ", ovld_path, real_line, real_pos);
634  va_start (args, fmt);
635  vfprintf (stderr, fmt, args);
636  va_end (args);
637}
638
639/* Produce a fatal error message.  */
640static void
641fatal (const char *msg)
642{
643  fprintf (stderr, "FATAL: %s\n", msg);
644  abort ();
645}
646
647/* Pass over whitespace (other than a newline, which terminates the scan).  */
648static void
649consume_whitespace (void)
650{
651  while (pos < LINELEN && isspace(linebuf[pos]) && linebuf[pos] != '\n')
652    pos++;
653
654  if (pos >= LINELEN)
655    {
656      diag (pos, "line length overrun.\n");
657      exit (1);
658    }
659
660  return;
661}
662
663/* Get the next nonblank, noncomment line, returning 0 on EOF, 1 otherwise.  */
664static int
665advance_line (FILE *file)
666{
667  while (1)
668    {
669      /* Read ahead one line and check for EOF.  */
670      if (!fgets (linebuf, sizeof linebuf, file))
671	return 0;
672      line++;
673      size_t len = strlen (linebuf);
674
675      /* Escape-newline processing.  */
676      lastline = 0;
677      if (len > 1)
678	{
679	  strcpy (lines[0], linebuf);
680	  while (linebuf[len - 2] == '\\'
681		 && linebuf[len - 1] == '\n')
682	    {
683	      lastline++;
684	      if (lastline == MAXLINES)
685		fatal ("number of supported overflow lines exceeded");
686	      line++;
687	      if (!fgets (lines[lastline], LINELEN, file))
688		fatal ("unexpected end of file");
689	      strcpy (&linebuf[len - 2], lines[lastline]);
690	      len += strlen (lines[lastline]) - 2;
691	    }
692	}
693
694      if (linebuf[len - 1] != '\n')
695	fatal ("line doesn't terminate with newline");
696      pos = 0;
697      consume_whitespace ();
698      if (linebuf[pos] != '\n' && linebuf[pos] != ';')
699	return 1;
700    }
701}
702
703static inline void
704safe_inc_pos (void)
705{
706  if (++pos >= LINELEN)
707    {
708      diag (pos, "line length overrun.\n");
709      exit (1);
710    }
711}
712
713/* Match an identifier, returning NULL on failure, else a pointer to a
714   buffer containing the identifier.  */
715static char *
716match_identifier (void)
717{
718  int lastpos = pos - 1;
719  while (lastpos < LINELEN - 1
720	 && (isalnum (linebuf[lastpos + 1]) || linebuf[lastpos + 1] == '_'))
721    ++lastpos;
722
723  if (lastpos >= LINELEN - 1)
724    {
725      diag (lastpos, "line length overrun.\n");
726      exit (1);
727    }
728
729  if (lastpos < pos)
730    return 0;
731
732  char *buf = (char *) malloc (lastpos - pos + 2);
733  memcpy (buf, &linebuf[pos], lastpos - pos + 1);
734  buf[lastpos - pos + 1] = '\0';
735
736  pos = lastpos + 1;
737  return buf;
738}
739
740/* Match an integer and return the string representing its value,
741   or a null string on failure.  */
742static char *
743match_integer (void)
744{
745  int startpos = pos;
746  if (linebuf[pos] == '-')
747    safe_inc_pos ();
748
749  int lastpos = pos - 1;
750  while (lastpos < LINELEN - 1 && isdigit (linebuf[lastpos + 1]))
751    ++lastpos;
752
753  if (lastpos >= LINELEN - 1)
754    {
755      diag (lastpos, "line length overrun.\n");
756      exit (1);
757    }
758
759  if (lastpos < pos)
760    return NULL;
761
762  pos = lastpos + 1;
763  char *buf = (char *) malloc (lastpos - startpos + 2);
764  memcpy (buf, &linebuf[startpos], lastpos - startpos + 1);
765  buf[lastpos - startpos + 1] = '\0';
766  return buf;
767}
768
769/* Match a string up to but not including a ']', and return its value,
770   or zero if there is nothing before the ']'.  Error if we don't find
771   such a character.  */
772static const char *
773match_to_right_bracket (void)
774{
775  int lastpos = pos - 1;
776  while (lastpos < LINELEN - 1 && linebuf[lastpos + 1] != ']')
777    {
778      if (linebuf[lastpos + 1] == '\n')
779	fatal ("no ']' found before end of line.\n");
780      ++lastpos;
781    }
782
783  if (lastpos >= LINELEN - 1)
784    {
785      diag (lastpos, "line length overrun.\n");
786      exit (1);
787    }
788
789  if (lastpos < pos)
790    return 0;
791
792  char *buf = (char *) malloc (lastpos - pos + 2);
793  memcpy (buf, &linebuf[pos], lastpos - pos + 1);
794  buf[lastpos - pos + 1] = '\0';
795
796  pos = lastpos + 1;
797  return buf;
798}
799
800static inline void
801handle_pointer (typeinfo *typedata)
802{
803  consume_whitespace ();
804  if (linebuf[pos] == '*')
805    {
806      typedata->ispointer = 1;
807      safe_inc_pos ();
808    }
809}
810
811static bif_stanza
812stanza_name_to_stanza (const char *stanza_name)
813{
814  for (int i = 0; i < NUMBIFSTANZAS; i++)
815    if (!strcmp (stanza_name, stanza_map[i].stanza_name))
816      return stanza_map[i].stanza;
817  fatal ("Stanza mapping is inconsistent.");
818  /* Unreachable.  */
819  return BSTZ_ALWAYS;
820}
821
822/* Match one of the allowable base types.  Consumes one token unless the
823   token is "long", which must be paired with a second "long".  Optionally
824   consumes a following '*' token for pointers.  Return 1 for success,
825   0 for failure.  */
826static int
827match_basetype (typeinfo *typedata)
828{
829  consume_whitespace ();
830  int oldpos = pos;
831  char *token = match_identifier ();
832  if (!token)
833    {
834      diag (pos, "missing base type in return type\n");
835      return 0;
836    }
837
838  if (!strcmp (token, "char"))
839    typedata->base = BT_CHAR;
840  else if (!strcmp (token, "short"))
841    typedata->base = BT_SHORT;
842  else if (!strcmp (token, "int"))
843    typedata->base = BT_INT;
844  else if (!strcmp (token, "long"))
845    {
846      consume_whitespace ();
847      oldpos = pos;
848      char *mustbelongordbl = match_identifier ();
849      if (!mustbelongordbl)
850	typedata->base = BT_LONG;
851      else if (!strcmp (mustbelongordbl, "long"))
852	typedata->base = BT_LONGLONG;
853      else if (!strcmp (mustbelongordbl, "double"))
854	typedata->base = BT_LONGDOUBLE;
855      else
856	/* Speculatively accept "long" here and push back the token.
857	   This occurs when "long" is a return type and the next token
858	   is the function name.  */
859	{
860	  typedata->base = BT_LONG;
861	  pos = oldpos;
862	}
863    }
864  else if (!strcmp (token, "float"))
865    typedata->base = BT_FLOAT;
866  else if (!strcmp (token, "double"))
867    typedata->base = BT_DOUBLE;
868  else if (!strcmp (token, "__int128"))
869    typedata->base = BT_INT128;
870  else if (!strcmp (token, "_Float128"))
871    typedata->base = BT_FLOAT128;
872  else if (!strcmp (token, "bool"))
873    typedata->base = BT_BOOL;
874  /* A "string" is a special "const char *" -- we need it because it
875     cannot match either signed or unsigned char *.  */
876  else if (!strcmp (token, "string"))
877    typedata->base = BT_STRING;
878  else if (!strcmp (token, "_Decimal32"))
879    typedata->base = BT_DECIMAL32;
880  else if (!strcmp (token, "_Decimal64"))
881    typedata->base = BT_DECIMAL64;
882  else if (!strcmp (token, "_Decimal128"))
883    typedata->base = BT_DECIMAL128;
884  else if (!strcmp (token, "__ibm128"))
885    typedata->base = BT_IBM128;
886  else
887    {
888      diag (oldpos, "unrecognized base type\n");
889      return 0;
890    }
891
892  handle_pointer (typedata);
893  return 1;
894}
895
896/* Helper routine for match_const_restriction.  */
897static int
898match_bracketed_pair (typeinfo *typedata, char open, char close,
899		      restriction restr)
900{
901  if (linebuf[pos] == open)
902    {
903      safe_inc_pos ();
904      int oldpos = pos;
905      char *x = match_integer ();
906      if (x == NULL)
907	{
908	  diag (oldpos, "malformed integer.\n");
909	  return 0;
910	}
911      consume_whitespace ();
912      if (linebuf[pos] != ',')
913	{
914	  diag (pos, "missing comma.\n");
915	  return 0;
916	}
917      safe_inc_pos ();
918      consume_whitespace ();
919      oldpos = pos;
920      char *y = match_integer ();
921      if (y == NULL)
922	{
923	  diag (oldpos, "malformed integer.\n");
924	  return 0;
925	}
926      typedata->restr = restr;
927      typedata->val1 = x;
928      typedata->val2 = y;
929
930      consume_whitespace ();
931      if (linebuf[pos] != close)
932	{
933	  diag (pos, "malformed restriction.\n");
934	  return 0;
935	}
936      safe_inc_pos ();
937      return 1;
938    }
939
940  return 0;
941}
942
943/* A const int argument may be restricted to certain values.  This is
944   indicated by one of the following occurring after the "int' token:
945
946     <x>   restricts the constant to x bits, interpreted as unsigned
947     <x,y> restricts the constant to the inclusive range [x,y]
948     [x,y] restricts the constant to the inclusive range [x,y],
949	   but only applies if the argument is constant.
950     {x,y} restricts the constant to one of two values, x or y.
951
952   Here x and y are integer tokens.  Note that the "const" token is a
953   lie when the restriction is [x,y], but this simplifies the parsing
954   significantly and is hopefully forgivable.
955
956   Return 1 for success, else 0.  */
957static int
958match_const_restriction (typeinfo *typedata)
959{
960  int oldpos = pos;
961  if (linebuf[pos] == '<')
962    {
963      safe_inc_pos ();
964      oldpos = pos;
965      char *x = match_integer ();
966      if (x == NULL)
967	{
968	  diag (oldpos, "malformed integer.\n");
969	  return 0;
970	}
971      consume_whitespace ();
972      if (linebuf[pos] == '>')
973	{
974	  typedata->restr = RES_BITS;
975	  typedata->val1 = x;
976	  safe_inc_pos ();
977	  return 1;
978	}
979      else if (linebuf[pos] != ',')
980	{
981	  diag (pos, "malformed restriction.\n");
982	  return 0;
983	}
984      safe_inc_pos ();
985      oldpos = pos;
986      char *y = match_integer ();
987      if (y == NULL)
988	{
989	  diag (oldpos, "malformed integer.\n");
990	  return 0;
991	}
992      typedata->restr = RES_RANGE;
993      typedata->val1 = x;
994      typedata->val2 = y;
995
996      consume_whitespace ();
997      if (linebuf[pos] != '>')
998	{
999	  diag (pos, "malformed restriction.\n");
1000	  return 0;
1001	}
1002      safe_inc_pos ();
1003      return 1;
1004    }
1005  else if (match_bracketed_pair (typedata, '{', '}', RES_VALUES)
1006	   || match_bracketed_pair (typedata, '[', ']', RES_VAR_RANGE))
1007    return 1;
1008
1009  return 0;
1010}
1011
1012/* Look for a type, which can be terminated by a token that is not part of
1013   a type, a comma, or a closing parenthesis.  Place information about the
1014   type in TYPEDATA.  Return 1 for success, 0 for failure.  */
1015static int
1016match_type (typeinfo *typedata, int voidok)
1017{
1018  /* A legal type is of the form:
1019
1020       [const] [[signed|unsigned] <basetype> | <vectype>] [*]
1021
1022     Legal values of <basetype> are (for now):
1023
1024       char
1025       short
1026       int
1027       long
1028       long double
1029       long long
1030       float
1031       double
1032       __int128
1033       _Float128
1034       bool
1035       string
1036       _Decimal32
1037       _Decimal64
1038       _Decimal128
1039       __ibm128
1040
1041     Legal values of <vectype> are as follows, and are shorthand for
1042     the associated meaning:
1043
1044       vsc	vector signed char
1045       vuc	vector unsigned char
1046       vbc	vector bool char
1047       vss	vector signed short
1048       vus	vector unsigned short
1049       vbs	vector bool short
1050       vsi	vector signed int
1051       vui	vector unsigned int
1052       vbi	vector bool int
1053       vsll	vector signed long long
1054       vull	vector unsigned long long
1055       vbll	vector bool long long
1056       vsq	vector signed __int128
1057       vuq	vector unsigned __int128
1058       vbq	vector bool __int128
1059       vp	vector pixel
1060       vf	vector float
1061       vd	vector double
1062       v256	__vector_pair
1063       v512	__vector_quad
1064
1065     For simplicity, We don't support "short int" and "long long int".
1066     We don't currently support a <basetype> of "_Float16".  "signed"
1067     and "unsigned" only apply to integral base types.  The optional *
1068     indicates a pointer type.  */
1069
1070  consume_whitespace ();
1071  memset (typedata, 0, sizeof *typedata);
1072  int oldpos = pos;
1073
1074  char *token = match_identifier ();
1075  if (!token)
1076    return 0;
1077
1078  if (!strcmp (token, "const"))
1079    {
1080      typedata->isconst = 1;
1081      consume_whitespace ();
1082      oldpos = pos;
1083      token = match_identifier ();
1084    }
1085
1086  if (!strcmp (token, "void"))
1087    typedata->isvoid = 1;
1088
1089  if (!strcmp (token, "vsc"))
1090    {
1091      typedata->isvector = 1;
1092      typedata->issigned = 1;
1093      typedata->base = BT_CHAR;
1094      handle_pointer (typedata);
1095      return 1;
1096    }
1097  else if (!strcmp (token, "vuc"))
1098    {
1099      typedata->isvector = 1;
1100      typedata->isunsigned = 1;
1101      typedata->base = BT_CHAR;
1102      handle_pointer (typedata);
1103      return 1;
1104    }
1105  else if (!strcmp (token, "vbc"))
1106    {
1107      typedata->isvector = 1;
1108      typedata->isbool = 1;
1109      typedata->base = BT_CHAR;
1110      handle_pointer (typedata);
1111      return 1;
1112    }
1113  else if (!strcmp (token, "vss"))
1114    {
1115      typedata->isvector = 1;
1116      typedata->issigned = 1;
1117      typedata->base = BT_SHORT;
1118      handle_pointer (typedata);
1119      return 1;
1120    }
1121  else if (!strcmp (token, "vus"))
1122    {
1123      typedata->isvector = 1;
1124      typedata->isunsigned = 1;
1125      typedata->base = BT_SHORT;
1126      handle_pointer (typedata);
1127      return 1;
1128    }
1129  else if (!strcmp (token, "vbs"))
1130    {
1131      typedata->isvector = 1;
1132      typedata->isbool = 1;
1133      typedata->base = BT_SHORT;
1134      handle_pointer (typedata);
1135      return 1;
1136    }
1137  else if (!strcmp (token, "vsi"))
1138    {
1139      typedata->isvector = 1;
1140      typedata->issigned = 1;
1141      typedata->base = BT_INT;
1142      handle_pointer (typedata);
1143      return 1;
1144    }
1145  else if (!strcmp (token, "vui"))
1146    {
1147      typedata->isvector = 1;
1148      typedata->isunsigned = 1;
1149      typedata->base = BT_INT;
1150      handle_pointer (typedata);
1151      return 1;
1152    }
1153  else if (!strcmp (token, "vbi"))
1154    {
1155      typedata->isvector = 1;
1156      typedata->isbool = 1;
1157      typedata->base = BT_INT;
1158      handle_pointer (typedata);
1159      return 1;
1160    }
1161  else if (!strcmp (token, "vsll"))
1162    {
1163      typedata->isvector = 1;
1164      typedata->issigned = 1;
1165      typedata->base = BT_LONGLONG;
1166      handle_pointer (typedata);
1167      return 1;
1168    }
1169  else if (!strcmp (token, "vull"))
1170    {
1171      typedata->isvector = 1;
1172      typedata->isunsigned = 1;
1173      typedata->base = BT_LONGLONG;
1174      handle_pointer (typedata);
1175      return 1;
1176    }
1177  else if (!strcmp (token, "vbll"))
1178    {
1179      typedata->isvector = 1;
1180      typedata->isbool = 1;
1181      typedata->base = BT_LONGLONG;
1182      handle_pointer (typedata);
1183      return 1;
1184    }
1185  else if (!strcmp (token, "vsq"))
1186    {
1187      typedata->isvector = 1;
1188      typedata->issigned = 1;
1189      typedata->base = BT_INT128;
1190      handle_pointer (typedata);
1191      return 1;
1192    }
1193  else if (!strcmp (token, "vuq"))
1194    {
1195      typedata->isvector = 1;
1196      typedata->isunsigned = 1;
1197      typedata->base = BT_INT128;
1198      handle_pointer (typedata);
1199      return 1;
1200    }
1201  else if (!strcmp (token, "vbq"))
1202    {
1203      typedata->isvector = 1;
1204      typedata->isbool = 1;
1205      typedata->base = BT_INT128;
1206      handle_pointer (typedata);
1207      return 1;
1208    }
1209  else if (!strcmp (token, "vp"))
1210    {
1211      typedata->isvector = 1;
1212      typedata->ispixel = 1;
1213      typedata->base = BT_SHORT;
1214      handle_pointer (typedata);
1215      return 1;
1216    }
1217  else if (!strcmp (token, "vf"))
1218    {
1219      typedata->isvector = 1;
1220      typedata->base = BT_FLOAT;
1221      handle_pointer (typedata);
1222      return 1;
1223    }
1224  else if (!strcmp (token, "vd"))
1225    {
1226      typedata->isvector = 1;
1227      typedata->base = BT_DOUBLE;
1228      handle_pointer (typedata);
1229      return 1;
1230    }
1231  else if (!strcmp (token, "v256"))
1232    {
1233      typedata->isvector = 1;
1234      typedata->base = BT_VPAIR;
1235      handle_pointer (typedata);
1236      return 1;
1237    }
1238  else if (!strcmp (token, "v512"))
1239    {
1240      typedata->isvector = 1;
1241      typedata->base = BT_VQUAD;
1242      handle_pointer (typedata);
1243      return 1;
1244    }
1245  else if (!strcmp (token, "signed"))
1246    typedata->issigned = 1;
1247  else if (!strcmp (token, "unsigned"))
1248    typedata->isunsigned = 1;
1249  else if (!typedata->isvoid && !typedata->isconst)
1250    {
1251      /* Push back token.  */
1252      pos = oldpos;
1253      return match_basetype (typedata);
1254    }
1255
1256  if (typedata->isvoid)
1257    {
1258      consume_whitespace ();
1259      if (linebuf[pos] == '*')
1260	{
1261	  typedata->ispointer = 1;
1262	  safe_inc_pos ();
1263	}
1264      else if (!voidok)
1265	return 0;
1266      return 1;
1267    }
1268
1269  if (!typedata->issigned && !typedata->isunsigned)
1270    pos = oldpos;
1271  if (!match_basetype (typedata))
1272    return 0;
1273
1274  if (typedata->isconst)
1275    {
1276      if (typedata->ispointer)
1277	return 1;
1278      if (typedata->base != BT_INT)
1279	{
1280	  diag (oldpos, "'const' requires pointer or integer type\n");
1281	  return 0;
1282	}
1283      consume_whitespace ();
1284      if (linebuf[pos] == '<' || linebuf[pos] == '{' || linebuf[pos] == '[')
1285	return match_const_restriction (typedata);
1286    }
1287
1288  return 1;
1289}
1290
1291/* Parse the argument list.  */
1292static parse_codes
1293parse_args (prototype *protoptr)
1294{
1295  typelist **argptr = &protoptr->args;
1296  int *nargs = &protoptr->nargs;
1297  int *restr_opnd = protoptr->restr_opnd;
1298  restriction *restr = protoptr->restr;
1299  char **val1 = protoptr->restr_val1;
1300  char **val2 = protoptr->restr_val2;
1301  int restr_cnt = 0;
1302
1303  int success;
1304  *nargs = 0;
1305
1306  /* Start the argument list.  */
1307  consume_whitespace ();
1308  if (linebuf[pos] != '(')
1309    {
1310      diag (pos, "missing '('.\n");
1311      return PC_PARSEFAIL;
1312    }
1313  safe_inc_pos ();
1314
1315  do {
1316    consume_whitespace ();
1317    int oldpos = pos;
1318    typelist *argentry = (typelist *) malloc (sizeof (typelist));
1319    memset (argentry, 0, sizeof *argentry);
1320    typeinfo *argtype = &argentry->info;
1321    success = match_type (argtype, VOID_NOTOK);
1322    if (success)
1323      {
1324	if (argtype->restr)
1325	  {
1326	    if (restr_cnt >= MAXRESTROPNDS)
1327	      {
1328		diag (pos, "More than two %d operands\n", MAXRESTROPNDS);
1329		return PC_PARSEFAIL;
1330	      }
1331	    restr_opnd[restr_cnt] = *nargs + 1;
1332	    restr[restr_cnt] = argtype->restr;
1333	    val1[restr_cnt] = argtype->val1;
1334	    val2[restr_cnt] = argtype->val2;
1335	    restr_cnt++;
1336	  }
1337	(*nargs)++;
1338	*argptr = argentry;
1339	argptr = &argentry->next;
1340	consume_whitespace ();
1341	if (linebuf[pos] == ',')
1342	  safe_inc_pos ();
1343	else if (linebuf[pos] != ')')
1344	  {
1345	    diag (pos, "arg not followed by ',' or ')'.\n");
1346	    return PC_PARSEFAIL;
1347	  }
1348
1349#ifdef DEBUG
1350	diag (0,
1351	      "argument type: isvoid = %d, isconst = %d, isvector = %d, "
1352	      "issigned = %d, isunsigned = %d, isbool = %d, ispixel = %d, "
1353	      "ispointer = %d, base = %d, restr = %d, val1 = \"%s\", "
1354	      "val2 = \"%s\", pos = %d.\n",
1355	      argtype->isvoid, argtype->isconst, argtype->isvector,
1356	      argtype->issigned, argtype->isunsigned, argtype->isbool,
1357	      argtype->ispixel, argtype->ispointer, argtype->base,
1358	      argtype->restr, argtype->val1, argtype->val2, pos + 1);
1359#endif
1360      }
1361    else
1362      {
1363	free (argentry);
1364	*argptr = NULL;
1365	pos = oldpos;
1366	if (linebuf[pos] != ')')
1367	  {
1368	    diag (pos, "badly terminated arg list.\n");
1369	    return PC_PARSEFAIL;
1370	  }
1371	safe_inc_pos ();
1372      }
1373  } while (success);
1374
1375  return PC_OK;
1376}
1377
1378/* Parse the attribute list.  */
1379static parse_codes
1380parse_bif_attrs (attrinfo *attrptr)
1381{
1382  consume_whitespace ();
1383  if (linebuf[pos] != '{')
1384    {
1385      diag (pos, "missing attribute set.\n");
1386      return PC_PARSEFAIL;
1387    }
1388  safe_inc_pos ();
1389
1390  memset (attrptr, 0, sizeof *attrptr);
1391  char *attrname = NULL;
1392
1393  do {
1394    consume_whitespace ();
1395    int oldpos = pos;
1396    attrname = match_identifier ();
1397    if (attrname)
1398      {
1399	if (!strcmp (attrname, "init"))
1400	  attrptr->isinit = 1;
1401	else if (!strcmp (attrname, "set"))
1402	  attrptr->isset = 1;
1403	else if (!strcmp (attrname, "extract"))
1404	  attrptr->isextract = 1;
1405	else if (!strcmp (attrname, "nosoft"))
1406	  attrptr->isnosoft = 1;
1407	else if (!strcmp (attrname, "ldvec"))
1408	  attrptr->isldvec = 1;
1409	else if (!strcmp (attrname, "stvec"))
1410	  attrptr->isstvec = 1;
1411	else if (!strcmp (attrname, "reve"))
1412	  attrptr->isreve = 1;
1413	else if (!strcmp (attrname, "pred"))
1414	  attrptr->ispred = 1;
1415	else if (!strcmp (attrname, "htm"))
1416	  attrptr->ishtm = 1;
1417	else if (!strcmp (attrname, "htmspr"))
1418	  attrptr->ishtmspr = 1;
1419	else if (!strcmp (attrname, "htmcr"))
1420	  attrptr->ishtmcr = 1;
1421	else if (!strcmp (attrname, "mma"))
1422	  attrptr->ismma = 1;
1423	else if (!strcmp (attrname, "quad"))
1424	  attrptr->isquad = 1;
1425	else if (!strcmp (attrname, "pair"))
1426	  attrptr->ispair = 1;
1427	else if (!strcmp (attrname, "mmaint"))
1428	  attrptr->ismmaint = 1;
1429	else if (!strcmp (attrname, "no32bit"))
1430	  attrptr->isno32bit = 1;
1431	else if (!strcmp (attrname, "32bit"))
1432	  attrptr->is32bit = 1;
1433	else if (!strcmp (attrname, "cpu"))
1434	  attrptr->iscpu = 1;
1435	else if (!strcmp (attrname, "ldstmask"))
1436	  attrptr->isldstmask = 1;
1437	else if (!strcmp (attrname, "lxvrse"))
1438	  attrptr->islxvrse = 1;
1439	else if (!strcmp (attrname, "lxvrze"))
1440	  attrptr->islxvrze = 1;
1441	else if (!strcmp (attrname, "endian"))
1442	  attrptr->isendian = 1;
1443	else if (!strcmp (attrname, "ibmld"))
1444	  attrptr->isibmld = 1;
1445	else if (!strcmp (attrname, "ibm128"))
1446	  attrptr->isibm128 = 1;
1447	else
1448	  {
1449	    diag (oldpos, "unknown attribute.\n");
1450	    return PC_PARSEFAIL;
1451	  }
1452
1453	consume_whitespace ();
1454	if (linebuf[pos] == ',')
1455	  safe_inc_pos ();
1456	else if (linebuf[pos] != '}')
1457	  {
1458	    diag (pos, "arg not followed by ',' or '}'.\n");
1459	    return PC_PARSEFAIL;
1460	  }
1461      }
1462    else
1463      {
1464	pos = oldpos;
1465	if (linebuf[pos] != '}')
1466	  {
1467	    diag (pos, "badly terminated attr set.\n");
1468	    return PC_PARSEFAIL;
1469	  }
1470	safe_inc_pos ();
1471      }
1472  } while (attrname);
1473
1474#ifdef DEBUG
1475  diag (0,
1476	"attribute set: init = %d, set = %d, extract = %d, nosoft = %d, "
1477	"ldvec = %d, stvec = %d, reve = %d, pred = %d, htm = %d, "
1478	"htmspr = %d, htmcr = %d, mma = %d, quad = %d, pair = %d, "
1479	"mmaint = %d, no32bit = %d, 32bit = %d, cpu = %d, ldstmask = %d, "
1480	"lxvrse = %d, lxvrze = %d, endian = %d, ibmdld = %d, ibm128 = %d.\n",
1481	attrptr->isinit, attrptr->isset, attrptr->isextract,
1482	attrptr->isnosoft, attrptr->isldvec, attrptr->isstvec,
1483	attrptr->isreve, attrptr->ispred, attrptr->ishtm, attrptr->ishtmspr,
1484	attrptr->ishtmcr, attrptr->ismma, attrptr->isquad, attrptr->ispair,
1485	attrptr->ismmaint, attrptr->isno32bit, attrptr->is32bit,
1486	attrptr->iscpu, attrptr->isldstmask, attrptr->islxvrse,
1487	attrptr->islxvrze, attrptr->isendian, attrptr->isibmld,
1488	attrptr->isibm128);
1489#endif
1490
1491  return PC_OK;
1492}
1493
1494/* Convert a vector type into a mode string.  */
1495static void
1496complete_vector_type (typeinfo *typeptr, char *buf, int *bufi)
1497{
1498  if (typeptr->isbool)
1499    buf[(*bufi)++] = 'b';
1500  buf[(*bufi)++] = 'v';
1501  if (typeptr->ispixel)
1502    {
1503      memcpy (&buf[*bufi], "p8hi", 4);
1504      *bufi += 4;
1505      return;
1506    }
1507  switch (typeptr->base)
1508    {
1509    case BT_CHAR:
1510      memcpy (&buf[*bufi], "16qi", 4);
1511      *bufi += 4;
1512      break;
1513    case BT_SHORT:
1514      memcpy (&buf[*bufi], "8hi", 3);
1515      *bufi += 3;
1516      break;
1517    case BT_INT:
1518      memcpy (&buf[*bufi], "4si", 3);
1519      *bufi += 3;
1520      break;
1521    case BT_LONGLONG:
1522      memcpy (&buf[*bufi], "2di", 3);
1523      *bufi += 3;
1524      break;
1525    case BT_FLOAT:
1526      memcpy (&buf[*bufi], "4sf", 3);
1527      *bufi += 3;
1528      break;
1529    case BT_DOUBLE:
1530      memcpy (&buf[*bufi], "2df", 3);
1531      *bufi += 3;
1532      break;
1533    case BT_INT128:
1534      memcpy (&buf[*bufi], "1ti", 3);
1535      *bufi += 3;
1536      break;
1537    case BT_FLOAT128:
1538      memcpy (&buf[*bufi], "1tf", 3);
1539      *bufi += 3;
1540      break;
1541    case BT_VPAIR:
1542      memcpy (&buf[*bufi], "1poi", 4);
1543      *bufi += 4;
1544      break;
1545    case BT_VQUAD:
1546      memcpy (&buf[*bufi], "1pxi", 4);
1547      *bufi += 4;
1548      break;
1549    default:
1550      diag (pos, "unhandled basetype %d.\n", typeptr->base);
1551      exit (1);
1552    }
1553}
1554
1555/* Convert a base type into a mode string.  */
1556static void
1557complete_base_type (typeinfo *typeptr, char *buf, int *bufi)
1558{
1559  switch (typeptr->base)
1560    {
1561    case BT_CHAR:
1562      memcpy (&buf[*bufi], "qi", 2);
1563      break;
1564    case BT_SHORT:
1565      memcpy (&buf[*bufi], "hi", 2);
1566      break;
1567    case BT_INT:
1568      memcpy (&buf[*bufi], "si", 2);
1569      break;
1570    case BT_LONG:
1571      memcpy (&buf[*bufi], "lg", 2);
1572      break;
1573    case BT_LONGLONG:
1574      memcpy (&buf[*bufi], "di", 2);
1575      break;
1576    case BT_FLOAT:
1577      memcpy (&buf[*bufi], "sf", 2);
1578      break;
1579    case BT_DOUBLE:
1580      memcpy (&buf[*bufi], "df", 2);
1581      break;
1582    case BT_LONGDOUBLE:
1583      memcpy (&buf[*bufi], "ld", 2);
1584      break;
1585    case BT_INT128:
1586      memcpy (&buf[*bufi], "ti", 2);
1587      break;
1588    case BT_FLOAT128:
1589      memcpy (&buf[*bufi], "tf", 2);
1590      break;
1591    case BT_BOOL:
1592      memcpy (&buf[*bufi], "bi", 2);
1593      break;
1594    case BT_STRING:
1595      memcpy (&buf[*bufi], "st", 2);
1596      break;
1597    case BT_DECIMAL32:
1598      memcpy (&buf[*bufi], "sd", 2);
1599      break;
1600    case BT_DECIMAL64:
1601      memcpy (&buf[*bufi], "dd", 2);
1602      break;
1603    case BT_DECIMAL128:
1604      memcpy (&buf[*bufi], "td", 2);
1605      break;
1606    case BT_IBM128:
1607      memcpy (&buf[*bufi], "if", 2);
1608      break;
1609    default:
1610      diag (pos, "unhandled basetype %d.\n", typeptr->base);
1611      exit (1);
1612    }
1613
1614  *bufi += 2;
1615}
1616
1617/* Build a function type descriptor identifier from the return type
1618   and argument types described by PROTOPTR, and store it if it does
1619   not already exist.  Return the identifier.  */
1620static char *
1621construct_fntype_id (prototype *protoptr)
1622{
1623  /* Determine the maximum space for a function type descriptor id.
1624     Each type requires at most 9 characters (6 for the mode*, 1 for
1625     the optional 'u' preceding the mode, 1 for the optional 'p'
1626     preceding the mode, and 1 for an underscore following the mode).
1627     We also need 5 characters for the string "ftype" that separates
1628     the return mode from the argument modes.  The last argument doesn't
1629     need a trailing underscore, but we count that as the one trailing
1630     "ftype" instead.  For the special case of zero arguments, we need 9
1631     for the return type and 7 for "ftype_v".  Finally, we need one
1632     character for the terminating null.  Thus for a function with N
1633     arguments, we need at most 9N+15 characters for N>0, otherwise 17.
1634     ----
1635       *Worst case is bv16qi for "vector bool char".  */
1636  int len = protoptr->nargs ? (protoptr->nargs + 1) * 9 + 6 : 17;
1637  char *buf = (char *) malloc (len);
1638  int bufi = 0;
1639
1640  if (protoptr->rettype.ispointer)
1641    buf[bufi++] = 'p';
1642
1643  if (protoptr->rettype.isvoid)
1644    buf[bufi++] = 'v';
1645  else
1646    {
1647      if (protoptr->rettype.isunsigned)
1648	buf[bufi++] = 'u';
1649      if (protoptr->rettype.isvector)
1650	complete_vector_type (&protoptr->rettype, buf, &bufi);
1651      else
1652	complete_base_type (&protoptr->rettype, buf, &bufi);
1653    }
1654
1655  memcpy (&buf[bufi], "_ftype", 6);
1656  bufi += 6;
1657
1658  if (!protoptr->nargs)
1659    {
1660      memcpy (&buf[bufi], "_v", 2);
1661      bufi += 2;
1662    }
1663  else
1664    {
1665      typelist *argptr = protoptr->args;
1666      for (int i = 0; i < protoptr->nargs; i++, argptr = argptr->next)
1667	{
1668	  assert (argptr);
1669	  buf[bufi++] = '_';
1670	  if (argptr->info.isconst
1671	      && argptr->info.base == BT_INT
1672	      && !argptr->info.ispointer)
1673	    {
1674	      buf[bufi++] = 'c';
1675	      buf[bufi++] = 'i';
1676	      continue;
1677	    }
1678	  if (argptr->info.ispointer)
1679	    {
1680	      if (argptr->info.isvoid)
1681		{
1682		  if (argptr->info.isconst)
1683		    {
1684		      memcpy (&buf[bufi], "pcvoid", 6);
1685		      bufi += 6;
1686		      continue;
1687		    }
1688		  else
1689		    {
1690		      buf[bufi++] = 'p';
1691		      buf[bufi++] = 'v';
1692		      continue;
1693		    }
1694		}
1695	      else
1696		buf[bufi++] = 'p';
1697	    }
1698
1699	  if (argptr->info.isunsigned)
1700	    buf[bufi++] = 'u';
1701	  if (argptr->info.isvector)
1702	    complete_vector_type (&argptr->info, buf, &bufi);
1703	  else
1704	    complete_base_type (&argptr->info, buf, &bufi);
1705	}
1706      assert (!argptr);
1707    }
1708
1709  buf[bufi] = '\0';
1710
1711  /* Ignore return value, as duplicates are fine and expected here.  */
1712  rbt_insert (&fntype_rbt, buf);
1713
1714  return buf;
1715}
1716
1717/* Parse a function prototype.  This code is shared by the bif and overload
1718   file processing.  */
1719static parse_codes
1720parse_prototype (prototype *protoptr)
1721{
1722  typeinfo *ret_type = &protoptr->rettype;
1723  char **bifname = &protoptr->bifname;
1724
1725  /* Get the return type.  */
1726  consume_whitespace ();
1727  int oldpos = pos;
1728  int success = match_type (ret_type, VOID_OK);
1729  if (!success)
1730    {
1731      diag (oldpos, "missing or badly formed return type.\n");
1732      return PC_PARSEFAIL;
1733    }
1734
1735#ifdef DEBUG
1736  diag (0,
1737	"return type: isvoid = %d, isconst = %d, isvector = %d, "
1738	"issigned = %d, isunsigned = %d, isbool = %d, ispixel = %d, "
1739	"ispointer = %d, base = %d, restr = %d, val1 = \"%s\", "
1740	"val2 = \"%s\", pos = %d.\n",
1741	ret_type->isvoid, ret_type->isconst, ret_type->isvector,
1742	ret_type->issigned, ret_type->isunsigned, ret_type->isbool,
1743	ret_type->ispixel, ret_type->ispointer, ret_type->base,
1744	ret_type->restr, ret_type->val1, ret_type->val2, pos + 1);
1745#endif
1746
1747  /* Get the bif name.  */
1748  consume_whitespace ();
1749  oldpos = pos;
1750  *bifname = match_identifier ();
1751  if (!*bifname)
1752    {
1753      diag (oldpos, "missing function name.\n");
1754      return PC_PARSEFAIL;
1755    }
1756
1757#ifdef DEBUG
1758  diag (0, "function name is '%s'.\n", *bifname);
1759#endif
1760
1761  /* Process arguments.  */
1762  if (parse_args (protoptr) == PC_PARSEFAIL)
1763    return PC_PARSEFAIL;
1764
1765  /* Process terminating semicolon.  */
1766  consume_whitespace ();
1767  if (linebuf[pos] != ';')
1768    {
1769      diag (pos, "missing semicolon.\n");
1770      return PC_PARSEFAIL;
1771    }
1772  safe_inc_pos ();
1773  consume_whitespace ();
1774  if (linebuf[pos] != '\n')
1775    {
1776      diag (pos, "garbage at end of line.\n");
1777      return PC_PARSEFAIL;
1778    }
1779
1780  return PC_OK;
1781}
1782
1783/* Parse a two-line entry for a built-in function.  */
1784static parse_codes
1785parse_bif_entry (void)
1786{
1787  /* Check for end of stanza.  */
1788  pos = 0;
1789  consume_whitespace ();
1790  if (linebuf[pos] == '[')
1791    return PC_EOSTANZA;
1792
1793  /* Allocate an entry in the bif table.  */
1794  if (num_bifs >= MAXBIFS - 1)
1795    {
1796      diag (pos, "too many built-in functions.\n");
1797      return PC_PARSEFAIL;
1798    }
1799
1800  curr_bif = num_bifs++;
1801  bifs[curr_bif].stanza = curr_bif_stanza;
1802
1803  /* Read the first token and see if it is a function modifier.  */
1804  consume_whitespace ();
1805  int oldpos = pos;
1806  char *token = match_identifier ();
1807  if (!token)
1808    {
1809      diag (oldpos, "malformed entry.\n");
1810      return PC_PARSEFAIL;
1811    }
1812
1813  if (!strcmp (token, "const"))
1814    bifs[curr_bif].kind = FNK_CONST;
1815  else if (!strcmp (token, "pure"))
1816    bifs[curr_bif].kind = FNK_PURE;
1817  else if (!strcmp (token, "fpmath"))
1818    bifs[curr_bif].kind = FNK_FPMATH;
1819  else
1820    {
1821      /* No function modifier, so push the token back.  */
1822      pos = oldpos;
1823      bifs[curr_bif].kind = FNK_NONE;
1824    }
1825
1826  if (parse_prototype (&bifs[curr_bif].proto) == PC_PARSEFAIL)
1827    return PC_PARSEFAIL;
1828
1829  /* Build a function type descriptor identifier from the return type
1830     and argument types, and store it if it does not already exist.  */
1831  bifs[curr_bif].fndecl = construct_fntype_id (&bifs[curr_bif].proto);
1832
1833  /* Now process line 2.  First up is the builtin id.  */
1834  if (!advance_line (bif_file))
1835    {
1836      diag (pos, "unexpected EOF.\n");
1837      return PC_PARSEFAIL;
1838    }
1839
1840  pos = 0;
1841  consume_whitespace ();
1842  oldpos = pos;
1843  bifs[curr_bif].idname = match_identifier ();
1844  if (!bifs[curr_bif].idname)
1845    {
1846      diag (pos, "missing builtin id.\n");
1847      return PC_PARSEFAIL;
1848    }
1849
1850#ifdef DEBUG
1851  diag (0, "ID name is '%s'.\n", bifs[curr_bif].idname);
1852#endif
1853
1854  /* Save the ID in a lookup structure.  */
1855  if (!rbt_insert (&bif_rbt, bifs[curr_bif].idname))
1856    {
1857      diag (oldpos, "duplicate function ID '%s'.\n", bifs[curr_bif].idname);
1858      return PC_PARSEFAIL;
1859    }
1860
1861  /* Append a number representing the order in which this function
1862     was encountered to its name, and save in another lookup
1863     structure.  */
1864  int orig_len = strlen (bifs[curr_bif].idname);
1865  char *buf = (char *) malloc (orig_len + 7);
1866  sprintf (buf, "%s:%05d", bifs[curr_bif].idname, curr_bif);
1867
1868  if (!rbt_insert (&bifo_rbt, buf))
1869    {
1870      diag (pos, "internal error inserting '%s' in bifo_rbt\n", buf);
1871      return PC_PARSEFAIL;
1872    }
1873
1874  /* Now the pattern name.  */
1875  consume_whitespace ();
1876  bifs[curr_bif].patname = match_identifier ();
1877  if (!bifs[curr_bif].patname)
1878    {
1879      diag (pos, "missing pattern name.\n");
1880      return PC_PARSEFAIL;
1881    }
1882
1883#ifdef DEBUG
1884  diag (0, "pattern name is '%s'.\n", bifs[curr_bif].patname);
1885#endif
1886
1887  /* Process attributes.  */
1888  return parse_bif_attrs (&bifs[curr_bif].attrs);
1889}
1890
1891/* Parse one stanza of the input BIF file.  linebuf already contains the
1892   first line to parse.  */
1893static parse_codes
1894parse_bif_stanza (void)
1895{
1896  /* Parse the stanza header.  */
1897  pos = 0;
1898  consume_whitespace ();
1899
1900  if (linebuf[pos] != '[')
1901    {
1902      diag (pos, "ill-formed stanza header.\n");
1903      return PC_PARSEFAIL;
1904    }
1905  safe_inc_pos ();
1906
1907  const char *stanza_name = match_to_right_bracket ();
1908  if (!stanza_name)
1909    {
1910      diag (pos, "no expression found in stanza header.\n");
1911      return PC_PARSEFAIL;
1912    }
1913
1914  curr_bif_stanza = stanza_name_to_stanza (stanza_name);
1915
1916  if (linebuf[pos] != ']')
1917    {
1918      diag (pos, "ill-formed stanza header.\n");
1919      return PC_PARSEFAIL;
1920    }
1921  safe_inc_pos ();
1922
1923  consume_whitespace ();
1924  if (linebuf[pos] != '\n' && pos != LINELEN - 1)
1925    {
1926      diag (pos, "garbage after stanza header.\n");
1927      return PC_PARSEFAIL;
1928    }
1929
1930  parse_codes result = PC_OK;
1931
1932  while (result != PC_EOSTANZA)
1933    {
1934      if (!advance_line (bif_file))
1935	return PC_EOFILE;
1936      result = parse_bif_entry ();
1937      if (result == PC_PARSEFAIL)
1938	return PC_PARSEFAIL;
1939    }
1940
1941  return PC_OK;
1942}
1943
1944/* Parse the built-in file.  */
1945static parse_codes
1946parse_bif (void)
1947{
1948  parse_codes result;
1949  diag = &bif_diag;
1950  if (!advance_line (bif_file))
1951    return PC_OK;
1952
1953  do
1954    result = parse_bif_stanza ();
1955  while (result == PC_OK);
1956
1957  if (result == PC_EOFILE)
1958    return PC_OK;
1959  return result;
1960}
1961
1962/* Callback function for create_bif_order.  */
1963void set_bif_order (char *str)
1964{
1965  int num = 0;
1966  char *colon = strchr (str, ':');
1967  sscanf (++colon, "%d", &num);
1968  bif_order[bif_index++] = num;
1969}
1970
1971/* Create a mapping from function IDs in their final order to the order
1972   they appear in the built-in function file.  */
1973static void
1974create_bif_order (void)
1975{
1976  bif_order = (int *) malloc ((curr_bif + 1)  * sizeof (int));
1977  rbt_inorder_callback (&bifo_rbt, bifo_rbt.rbt_root, set_bif_order);
1978}
1979
1980/* Parse one two-line entry in the overload file.  */
1981static parse_codes
1982parse_ovld_entry (void)
1983{
1984  /* Check for end of stanza.  */
1985  pos = 0;
1986  consume_whitespace ();
1987  if (linebuf[pos] == '[')
1988    return PC_EOSTANZA;
1989
1990  /* Allocate an entry in the overload table.  */
1991  if (num_ovlds >= MAXOVLDS - 1)
1992    {
1993      diag (pos, "too many overloads.\n");
1994      return PC_PARSEFAIL;
1995    }
1996
1997  curr_ovld = num_ovlds++;
1998  ovlds[curr_ovld].stanza = curr_ovld_stanza;
1999
2000  if (parse_prototype (&ovlds[curr_ovld].proto) == PC_PARSEFAIL)
2001    return PC_PARSEFAIL;
2002
2003  if (ovlds[curr_ovld].proto.nargs > max_ovld_args)
2004    max_ovld_args = ovlds[curr_ovld].proto.nargs;
2005
2006  /* Build a function type descriptor identifier from the return type
2007     and argument types, and store it if it does not already exist.  */
2008  ovlds[curr_ovld].fndecl = construct_fntype_id (&ovlds[curr_ovld].proto);
2009
2010  /* Now process line 2, which just contains the builtin id and an
2011     optional overload id.  */
2012  if (!advance_line (ovld_file))
2013    {
2014      diag (0, "unexpected EOF.\n");
2015      return PC_EOFILE;
2016    }
2017
2018  pos = 0;
2019  consume_whitespace ();
2020  int oldpos = pos;
2021  char *id = match_identifier ();
2022  ovlds[curr_ovld].bif_id_name = id;
2023  ovlds[curr_ovld].ovld_id_name = id;
2024  if (!id)
2025    {
2026      diag (pos, "missing overload id.\n");
2027      return PC_PARSEFAIL;
2028    }
2029
2030#ifdef DEBUG
2031  diag (pos, "ID name is '%s'.\n", id);
2032#endif
2033
2034  /* The builtin id has to match one from the bif file.  */
2035  if (!rbt_find (&bif_rbt, id))
2036    {
2037      diag (pos, "builtin ID '%s' not found in bif file.\n", id);
2038      return PC_PARSEFAIL;
2039    }
2040
2041  /* Check for an optional overload id.  Usually we use the builtin
2042     function id for that purpose, but sometimes we need multiple
2043     overload entries for the same builtin id, and it needs to be unique.  */
2044  consume_whitespace ();
2045  if (linebuf[pos] != '\n')
2046    {
2047      id = match_identifier ();
2048      ovlds[curr_ovld].ovld_id_name = id;
2049      consume_whitespace ();
2050    }
2051
2052 /* Save the overload ID in a lookup structure.  */
2053  if (!rbt_insert (&ovld_rbt, id))
2054    {
2055      diag (oldpos, "duplicate overload ID '%s'.\n", id);
2056      return PC_PARSEFAIL;
2057    }
2058
2059  if (linebuf[pos] != '\n')
2060    {
2061      diag (pos, "garbage at end of line.\n");
2062      return PC_PARSEFAIL;
2063    }
2064  return PC_OK;
2065}
2066
2067/* Parse one stanza of the input overload file.  linebuf already contains the
2068   first line to parse.  */
2069static parse_codes
2070parse_ovld_stanza (void)
2071{
2072  /* Parse the stanza header.  */
2073  pos = 0;
2074  consume_whitespace ();
2075
2076  if (linebuf[pos] != '[')
2077    {
2078      diag (pos, "ill-formed stanza header.\n");
2079      return PC_PARSEFAIL;
2080    }
2081  safe_inc_pos ();
2082
2083  char *stanza_name = match_identifier ();
2084  if (!stanza_name)
2085    {
2086      diag (pos, "no identifier found in stanza header.\n");
2087      return PC_PARSEFAIL;
2088    }
2089
2090  /* Add the identifier to a table and set the number to be recorded
2091     with subsequent overload entries.  */
2092  if (num_ovld_stanzas >= MAXOVLDSTANZAS)
2093    {
2094      diag (pos, "too many stanza headers.\n");
2095      return PC_PARSEFAIL;
2096    }
2097
2098  curr_ovld_stanza = num_ovld_stanzas++;
2099  ovld_stanza *stanza = &ovld_stanzas[curr_ovld_stanza];
2100  stanza->stanza_id = stanza_name;
2101
2102  consume_whitespace ();
2103  if (linebuf[pos] != ',')
2104    {
2105      diag (pos, "missing comma.\n");
2106      return PC_PARSEFAIL;
2107    }
2108  safe_inc_pos ();
2109
2110  consume_whitespace ();
2111  stanza->extern_name = match_identifier ();
2112  if (!stanza->extern_name)
2113    {
2114      diag (pos, "missing external name.\n");
2115      return PC_PARSEFAIL;
2116    }
2117
2118  consume_whitespace ();
2119  if (linebuf[pos] != ',')
2120    {
2121      diag (pos, "missing comma.\n");
2122      return PC_PARSEFAIL;
2123    }
2124  safe_inc_pos ();
2125
2126  consume_whitespace ();
2127  stanza->intern_name = match_identifier ();
2128  if (!stanza->intern_name)
2129    {
2130      diag (pos, "missing internal name.\n");
2131      return PC_PARSEFAIL;
2132    }
2133
2134  consume_whitespace ();
2135  if (linebuf[pos] == ',')
2136    {
2137      safe_inc_pos ();
2138      consume_whitespace ();
2139      stanza->ifdef = match_identifier ();
2140      if (!stanza->ifdef)
2141	{
2142	  diag (pos, "missing ifdef token.\n");
2143	  return PC_PARSEFAIL;
2144	}
2145      consume_whitespace ();
2146    }
2147  else
2148    stanza->ifdef = 0;
2149
2150  if (linebuf[pos] != ']')
2151    {
2152      diag (pos, "ill-formed stanza header.\n");
2153      return PC_PARSEFAIL;
2154    }
2155  safe_inc_pos ();
2156
2157  consume_whitespace ();
2158  if (linebuf[pos] != '\n' && pos != LINELEN - 1)
2159    {
2160      diag (pos, "garbage after stanza header.\n");
2161      return PC_PARSEFAIL;
2162    }
2163
2164  parse_codes result = PC_OK;
2165
2166  while (result != PC_EOSTANZA)
2167    {
2168      if (!advance_line (ovld_file))
2169	return PC_EOFILE;
2170
2171      result = parse_ovld_entry ();
2172      if (result == PC_EOFILE || result == PC_PARSEFAIL)
2173	return result;
2174    }
2175
2176  return PC_OK;
2177}
2178
2179/* Parse the overload file.  */
2180static parse_codes
2181parse_ovld (void)
2182{
2183  parse_codes result = PC_OK;
2184  diag = &ovld_diag;
2185
2186  if (!advance_line (ovld_file))
2187    return PC_OK;
2188
2189  while (result == PC_OK)
2190    result = parse_ovld_stanza ();
2191
2192  if (result == PC_EOFILE)
2193    return PC_OK;
2194  return result;
2195}
2196
2197/* Write a comment at the top of FILE about how the code was generated.  */
2198static void
2199write_autogenerated_header (FILE *file)
2200{
2201  fprintf (file, "/* Automatically generated by the program '%s'\n",
2202	   pgm_path);
2203  fprintf (file, "   from the files '%s' and '%s'.  */\n\n",
2204	   bif_path, ovld_path);
2205}
2206
2207/* Write declarations into the header file.  */
2208static void
2209write_decls (void)
2210{
2211  fprintf (header_file, "enum rs6000_gen_builtins\n{\n  RS6000_BIF_NONE,\n");
2212  for (int i = 0; i <= curr_bif; i++)
2213    fprintf (header_file, "  RS6000_BIF_%s,\n", bifs[bif_order[i]].idname);
2214  fprintf (header_file, "  RS6000_BIF_MAX,\n");
2215  fprintf (header_file, "  RS6000_OVLD_NONE,\n");
2216  for (int i = 0; i < num_ovld_stanzas; i++)
2217    fprintf (header_file, "  RS6000_OVLD_%s,\n", ovld_stanzas[i].stanza_id);
2218  fprintf (header_file, "  RS6000_OVLD_MAX\n};\n\n");
2219
2220  fprintf (header_file,
2221	   "extern GTY(()) tree rs6000_builtin_decls[RS6000_OVLD_MAX];\n\n");
2222
2223  fprintf (header_file,
2224	   "enum rs6000_ovld_instances\n{\n  RS6000_INST_NONE,\n");
2225  for (int i = 0; i <= curr_ovld; i++)
2226    fprintf (header_file, "  RS6000_INST_%s,\n", ovlds[i].ovld_id_name);
2227  fprintf (header_file, "  RS6000_INST_MAX\n};\n\n");
2228
2229  fprintf (header_file, "#define MAX_OVLD_ARGS %d\n", max_ovld_args);
2230
2231  fprintf (header_file, "enum restriction {\n");
2232  fprintf (header_file, "  RES_NONE,\n");
2233  fprintf (header_file, "  RES_BITS,\n");
2234  fprintf (header_file, "  RES_RANGE,\n");
2235  fprintf (header_file, "  RES_VAR_RANGE,\n");
2236  fprintf (header_file, "  RES_VALUES\n");
2237  fprintf (header_file, "};\n\n");
2238
2239  fprintf (header_file, "enum bif_enable {\n");
2240  fprintf (header_file, "  ENB_ALWAYS,\n");
2241  fprintf (header_file, "  ENB_P5,\n");
2242  fprintf (header_file, "  ENB_P6,\n");
2243  fprintf (header_file, "  ENB_P6_64,\n");
2244  fprintf (header_file, "  ENB_ALTIVEC,\n");
2245  fprintf (header_file, "  ENB_CELL,\n");
2246  fprintf (header_file, "  ENB_VSX,\n");
2247  fprintf (header_file, "  ENB_P7,\n");
2248  fprintf (header_file, "  ENB_P7_64,\n");
2249  fprintf (header_file, "  ENB_P8,\n");
2250  fprintf (header_file, "  ENB_P8V,\n");
2251  fprintf (header_file, "  ENB_P9,\n");
2252  fprintf (header_file, "  ENB_P9_64,\n");
2253  fprintf (header_file, "  ENB_P9V,\n");
2254  fprintf (header_file, "  ENB_IEEE128_HW,\n");
2255  fprintf (header_file, "  ENB_DFP,\n");
2256  fprintf (header_file, "  ENB_CRYPTO,\n");
2257  fprintf (header_file, "  ENB_HTM,\n");
2258  fprintf (header_file, "  ENB_P10,\n");
2259  fprintf (header_file, "  ENB_P10_64,\n");
2260  fprintf (header_file, "  ENB_MMA\n");
2261  fprintf (header_file, "};\n\n");
2262
2263  fprintf (header_file, "#define PPC_MAXRESTROPNDS 3\n");
2264  fprintf (header_file, "struct GTY(()) bifdata\n");
2265  fprintf (header_file, "{\n");
2266  fprintf (header_file, "  const char *GTY((skip(\"\"))) bifname;\n");
2267  fprintf (header_file, "  bif_enable GTY((skip(\"\"))) enable;\n");
2268  fprintf (header_file, "  tree fntype;\n");
2269  fprintf (header_file, "  insn_code GTY((skip(\"\"))) icode;\n");
2270  fprintf (header_file, "  int  nargs;\n");
2271  fprintf (header_file, "  int  bifattrs;\n");
2272  fprintf (header_file, "  int  restr_opnd[PPC_MAXRESTROPNDS];\n");
2273  fprintf (header_file, "  restriction GTY((skip(\"\"))) restr[PPC_MAXRESTROPNDS];\n");
2274  fprintf (header_file, "  int  restr_val1[PPC_MAXRESTROPNDS];\n");
2275  fprintf (header_file, "  int  restr_val2[PPC_MAXRESTROPNDS];\n");
2276  fprintf (header_file, "  const char *GTY((skip(\"\"))) attr_string;\n");
2277  fprintf (header_file, "  rs6000_gen_builtins GTY((skip(\"\"))) assoc_bif;\n");
2278  fprintf (header_file, "};\n\n");
2279
2280  fprintf (header_file, "#define bif_init_bit\t\t(0x00000001)\n");
2281  fprintf (header_file, "#define bif_set_bit\t\t(0x00000002)\n");
2282  fprintf (header_file, "#define bif_extract_bit\t\t(0x00000004)\n");
2283  fprintf (header_file, "#define bif_nosoft_bit\t\t(0x00000008)\n");
2284  fprintf (header_file, "#define bif_ldvec_bit\t\t(0x00000010)\n");
2285  fprintf (header_file, "#define bif_stvec_bit\t\t(0x00000020)\n");
2286  fprintf (header_file, "#define bif_reve_bit\t\t(0x00000040)\n");
2287  fprintf (header_file, "#define bif_pred_bit\t\t(0x00000080)\n");
2288  fprintf (header_file, "#define bif_htm_bit\t\t(0x00000100)\n");
2289  fprintf (header_file, "#define bif_htmspr_bit\t\t(0x00000200)\n");
2290  fprintf (header_file, "#define bif_htmcr_bit\t\t(0x00000400)\n");
2291  fprintf (header_file, "#define bif_mma_bit\t\t(0x00000800)\n");
2292  fprintf (header_file, "#define bif_quad_bit\t\t(0x00001000)\n");
2293  fprintf (header_file, "#define bif_pair_bit\t\t(0x00002000)\n");
2294  fprintf (header_file, "#define bif_mmaint_bit\t\t(0x00004000)\n");
2295  fprintf (header_file, "#define bif_no32bit_bit\t\t(0x00008000)\n");
2296  fprintf (header_file, "#define bif_32bit_bit\t\t(0x00010000)\n");
2297  fprintf (header_file, "#define bif_cpu_bit\t\t(0x00020000)\n");
2298  fprintf (header_file, "#define bif_ldstmask_bit\t(0x00040000)\n");
2299  fprintf (header_file, "#define bif_lxvrse_bit\t\t(0x00080000)\n");
2300  fprintf (header_file, "#define bif_lxvrze_bit\t\t(0x00100000)\n");
2301  fprintf (header_file, "#define bif_endian_bit\t\t(0x00200000)\n");
2302  fprintf (header_file, "#define bif_ibmld_bit\t\t(0x00400000)\n");
2303  fprintf (header_file, "#define bif_ibm128_bit\t\t(0x00800000)\n");
2304  fprintf (header_file, "\n");
2305  fprintf (header_file,
2306	   "#define bif_is_init(x)\t\t((x).bifattrs & bif_init_bit)\n");
2307  fprintf (header_file,
2308	   "#define bif_is_set(x)\t\t((x).bifattrs & bif_set_bit)\n");
2309  fprintf (header_file,
2310	   "#define bif_is_extract(x)\t((x).bifattrs & bif_extract_bit)\n");
2311  fprintf (header_file,
2312	   "#define bif_is_nosoft(x)\t((x).bifattrs & bif_nosoft_bit)\n");
2313  fprintf (header_file,
2314	   "#define bif_is_ldvec(x)\t\t((x).bifattrs & bif_ldvec_bit)\n");
2315  fprintf (header_file,
2316	   "#define bif_is_stvec(x)\t\t((x).bifattrs & bif_stvec_bit)\n");
2317  fprintf (header_file,
2318	   "#define bif_is_reve(x)\t\t((x).bifattrs & bif_reve_bit)\n");
2319  fprintf (header_file,
2320	   "#define bif_is_predicate(x)\t((x).bifattrs & bif_pred_bit)\n");
2321  fprintf (header_file,
2322	   "#define bif_is_htm(x)\t\t((x).bifattrs & bif_htm_bit)\n");
2323  fprintf (header_file,
2324	   "#define bif_is_htmspr(x)\t((x).bifattrs & bif_htmspr_bit)\n");
2325  fprintf (header_file,
2326	   "#define bif_is_htmcr(x)\t\t((x).bifattrs & bif_htmcr_bit)\n");
2327  fprintf (header_file,
2328	   "#define bif_is_mma(x)\t\t((x).bifattrs & bif_mma_bit)\n");
2329  fprintf (header_file,
2330	   "#define bif_is_quad(x)\t\t((x).bifattrs & bif_quad_bit)\n");
2331  fprintf (header_file,
2332	   "#define bif_is_pair(x)\t\t((x).bifattrs & bif_pair_bit)\n");
2333  fprintf (header_file,
2334	   "#define bif_is_mmaint(x)\t\t((x).bifattrs & bif_mmaint_bit)\n");
2335  fprintf (header_file,
2336	   "#define bif_is_no32bit(x)\t((x).bifattrs & bif_no32bit_bit)\n");
2337  fprintf (header_file,
2338	   "#define bif_is_32bit(x)\t((x).bifattrs & bif_32bit_bit)\n");
2339  fprintf (header_file,
2340	   "#define bif_is_cpu(x)\t\t((x).bifattrs & bif_cpu_bit)\n");
2341  fprintf (header_file,
2342	   "#define bif_is_ldstmask(x)\t((x).bifattrs & bif_ldstmask_bit)\n");
2343  fprintf (header_file,
2344	   "#define bif_is_lxvrse(x)\t((x).bifattrs & bif_lxvrse_bit)\n");
2345  fprintf (header_file,
2346	   "#define bif_is_lxvrze(x)\t((x).bifattrs & bif_lxvrze_bit)\n");
2347  fprintf (header_file,
2348	   "#define bif_is_endian(x)\t((x).bifattrs & bif_endian_bit)\n");
2349  fprintf (header_file,
2350	   "#define bif_is_ibmld(x)\t((x).bifattrs & bif_ibmld_bit)\n");
2351  fprintf (header_file,
2352	   "#define bif_is_ibm128(x)\t((x).bifattrs & bif_ibm128_bit)\n");
2353  fprintf (header_file, "\n");
2354
2355  fprintf (header_file,
2356	   "extern GTY(()) bifdata rs6000_builtin_info[RS6000_BIF_MAX];\n\n");
2357
2358  fprintf (header_file, "struct GTY(()) ovlddata\n");
2359  fprintf (header_file, "{\n");
2360  fprintf (header_file, "  const char *GTY((skip(\"\"))) bifname;\n");
2361  fprintf (header_file, "  rs6000_gen_builtins GTY((skip(\"\"))) bifid;\n");
2362  fprintf (header_file, "  tree fntype;\n");
2363  fprintf (header_file, "  ovlddata *GTY((skip(\"\"))) next;\n");
2364  fprintf (header_file, "};\n\n");
2365
2366  fprintf (header_file, "struct ovldrecord\n");
2367  fprintf (header_file, "{\n");
2368  fprintf (header_file, "  const char *ovld_name;\n");
2369  fprintf (header_file, "  ovlddata *first_instance;\n");
2370  fprintf (header_file, "};\n\n");
2371
2372  fprintf (header_file,
2373	   "extern GTY(()) ovlddata rs6000_instance_info[RS6000_INST_MAX];\n");
2374  fprintf (header_file, "extern ovldrecord rs6000_overload_info[];\n\n");
2375
2376  fprintf (header_file, "extern void rs6000_init_generated_builtins ();\n\n");
2377  fprintf (header_file,
2378	   "extern bool rs6000_builtin_is_supported (rs6000_gen_builtins);\n");
2379  fprintf (header_file,
2380	   "extern tree rs6000_builtin_decl (unsigned, "
2381	   "bool ATTRIBUTE_UNUSED);\n\n");
2382}
2383
2384/* Comparator for bsearch on the type map.  */
2385int
2386typemap_cmp (const void *key, const void *entry)
2387{
2388  return strcmp ((const char *)key, ((const typemap *)entry)->key);
2389}
2390
2391/* Write the type node corresponding to TOK.  */
2392static void
2393write_type_node (char *tok, bool indent)
2394{
2395  if (indent)
2396    fprintf (init_file, "  ");
2397  typemap *entry
2398    = (typemap *) bsearch (tok, type_map,
2399			   sizeof type_map / sizeof type_map[0],
2400			   sizeof (typemap), typemap_cmp);
2401  if (!entry)
2402    fatal ("Type map is inconsistent.");
2403  fprintf (init_file, "%s_type_node", entry->value);
2404}
2405
2406/* Write an initializer for a function type identified by STR.  */
2407void
2408write_fntype_init (char *str)
2409{
2410  char *tok;
2411
2412  /* Check whether we have a "tf" token in this string, representing
2413     a float128_type_node.  It's possible that float128_type_node is
2414     undefined (occurs for -maltivec -mno-vsx, for example), so we
2415     must guard against that.  */
2416  int tf_found = strstr (str, "tf") != NULL;
2417
2418  /* Similarly, look for decimal float tokens.  */
2419  int dfp_found = (strstr (str, "dd") != NULL
2420		   || strstr (str, "td") != NULL
2421		   || strstr (str, "sd") != NULL);
2422
2423  /* Avoid side effects of strtok on the original string by using a copy.  */
2424  char *buf = strdup (str);
2425
2426  if (tf_found || dfp_found)
2427    fprintf (init_file, "  tree %s = NULL_TREE;\n", buf);
2428  else
2429    fprintf (init_file, "  tree ");
2430
2431  if (tf_found)
2432    fprintf (init_file, "  if (float128_type_node)\n    ");
2433  else if (dfp_found)
2434    fprintf (init_file, "  if (dfloat64_type_node)\n    ");
2435
2436  fprintf (init_file, "%s\n    = build_function_type_list (", buf);
2437  tok = strtok (buf, "_");
2438  write_type_node (tok, tf_found || dfp_found);
2439  tok = strtok (0, "_");
2440  assert (tok);
2441  assert (!strcmp (tok, "ftype"));
2442
2443  tok = strtok (0, "_");
2444  if (tok)
2445    fprintf (init_file, ",\n\t\t\t\t");
2446
2447  /* Note:  A function with no arguments ends with '_ftype_v'.  */
2448  while (tok && strcmp (tok, "v"))
2449    {
2450      write_type_node (tok, tf_found || dfp_found);
2451      tok = strtok (0, "_");
2452      fprintf (init_file, ",\n\t\t\t\t");
2453    }
2454  fprintf (init_file, "NULL_TREE);\n");
2455  free (buf);
2456}
2457
2458/* Write everything to the header file (rs6000-builtins.h).  Return
2459   1 if successful, 0 otherwise.  */
2460static int
2461write_header_file (void)
2462{
2463  write_autogenerated_header (header_file);
2464
2465  fprintf (header_file, "#ifndef _RS6000_BUILTINS_H\n");
2466  fprintf (header_file, "#define _RS6000_BUILTINS_H 1\n\n");
2467
2468  write_decls ();
2469
2470  fprintf (header_file, "\n");
2471  fprintf (header_file, "\n#endif\n");
2472
2473  return 1;
2474}
2475
2476/* Write the decl and initializer for rs6000_builtin_info[].  */
2477static void
2478write_bif_static_init (void)
2479{
2480  const char *res[3];
2481  fprintf (init_file, "bifdata rs6000_builtin_info[RS6000_BIF_MAX] =\n");
2482  fprintf (init_file, "  {\n");
2483  fprintf (init_file, "    { /* RS6000_BIF_NONE: */\n");
2484  fprintf (init_file, "      \"\", ENB_ALWAYS, 0, CODE_FOR_nothing, 0,\n");
2485  fprintf (init_file, "      0, {0, 0, 0}, {RES_NONE, RES_NONE, RES_NONE},\n");
2486  fprintf (init_file, "      {0, 0, 0}, {0, 0, 0}, \"\", RS6000_BIF_NONE\n");
2487  fprintf (init_file, "    },\n");
2488  for (int i = 0; i <= curr_bif; i++)
2489    {
2490      bifdata *bifp = &bifs[bif_order[i]];
2491      fprintf (init_file, "    { /* RS6000_BIF_%s: */\n", bifp->idname);
2492      fprintf (init_file, "      /* bifname */\t\"%s\",\n",
2493	       bifp->proto.bifname);
2494      fprintf (init_file, "      /* enable*/\t%s,\n",
2495	       enable_string[bifp->stanza]);
2496      /* Type must be instantiated at run time.  */
2497      fprintf (init_file, "      /* fntype */\t0,\n");
2498      fprintf (init_file, "      /* icode */\tCODE_FOR_%s,\n",
2499	       bifp->patname);
2500      fprintf (init_file, "      /* nargs */\t%d,\n",
2501	       bifp->proto.nargs);
2502      fprintf (init_file, "      /* bifattrs */\t0");
2503      if (bifp->attrs.isinit)
2504	fprintf (init_file, " | bif_init_bit");
2505      if (bifp->attrs.isset)
2506	fprintf (init_file, " | bif_set_bit");
2507      if (bifp->attrs.isextract)
2508	fprintf (init_file, " | bif_extract_bit");
2509      if (bifp->attrs.isnosoft)
2510	fprintf (init_file, " | bif_nosoft_bit");
2511      if (bifp->attrs.isldvec)
2512	fprintf (init_file, " | bif_ldvec_bit");
2513      if (bifp->attrs.isstvec)
2514	fprintf (init_file, " | bif_stvec_bit");
2515      if (bifp->attrs.isreve)
2516	fprintf (init_file, " | bif_reve_bit");
2517      if (bifp->attrs.ispred)
2518	fprintf (init_file, " | bif_pred_bit");
2519      if (bifp->attrs.ishtm)
2520	fprintf (init_file, " | bif_htm_bit");
2521      if (bifp->attrs.ishtmspr)
2522	fprintf (init_file, " | bif_htmspr_bit");
2523      if (bifp->attrs.ishtmcr)
2524	fprintf (init_file, " | bif_htmcr_bit");
2525      if (bifp->attrs.ismma)
2526	fprintf (init_file, " | bif_mma_bit");
2527      if (bifp->attrs.isquad)
2528	fprintf (init_file, " | bif_quad_bit");
2529      if (bifp->attrs.ispair)
2530	fprintf (init_file, " | bif_pair_bit");
2531      if (bifp->attrs.ismmaint)
2532	fprintf (init_file, " | bif_mmaint_bit");
2533      if (bifp->attrs.isno32bit)
2534	fprintf (init_file, " | bif_no32bit_bit");
2535      if (bifp->attrs.is32bit)
2536	fprintf (init_file, " | bif_32bit_bit");
2537      if (bifp->attrs.iscpu)
2538	fprintf (init_file, " | bif_cpu_bit");
2539      if (bifp->attrs.isldstmask)
2540	fprintf (init_file, " | bif_ldstmask_bit");
2541      if (bifp->attrs.islxvrse)
2542	fprintf (init_file, " | bif_lxvrse_bit");
2543      if (bifp->attrs.islxvrze)
2544	fprintf (init_file, " | bif_lxvrze_bit");
2545      if (bifp->attrs.isendian)
2546	fprintf (init_file, " | bif_endian_bit");
2547      if (bifp->attrs.isibmld)
2548	fprintf (init_file, " | bif_ibmld_bit");
2549      if (bifp->attrs.isibm128)
2550	fprintf (init_file, " | bif_ibm128_bit");
2551      fprintf (init_file, ",\n");
2552      fprintf (init_file, "      /* restr_opnd */\t{%d, %d, %d},\n",
2553	       bifp->proto.restr_opnd[0], bifp->proto.restr_opnd[1],
2554	       bifp->proto.restr_opnd[2]);
2555      for (int j = 0; j < 3; j++)
2556	if (!bifp->proto.restr_opnd[j])
2557	  res[j] = "RES_NONE";
2558	else if (bifp->proto.restr[j] == RES_BITS)
2559	  res[j] = "RES_BITS";
2560	else if (bifp->proto.restr[j] == RES_RANGE)
2561	  res[j] = "RES_RANGE";
2562	else if (bifp->proto.restr[j] == RES_VALUES)
2563	  res[j] = "RES_VALUES";
2564	else if (bifp->proto.restr[j] == RES_VAR_RANGE)
2565	  res[j] = "RES_VAR_RANGE";
2566	else
2567	  res[j] = "ERROR";
2568      fprintf (init_file, "      /* restr */\t{%s, %s, %s},\n",
2569	       res[0], res[1], res[2]);
2570      fprintf (init_file, "      /* restr_val1 */\t{%s, %s, %s},\n",
2571	       bifp->proto.restr_val1[0] ? bifp->proto.restr_val1[0] : "0",
2572	       bifp->proto.restr_val1[1] ? bifp->proto.restr_val1[1] : "0",
2573	       bifp->proto.restr_val1[2] ? bifp->proto.restr_val1[2] : "0");
2574      fprintf (init_file, "      /* restr_val2 */\t{%s, %s, %s},\n",
2575	       bifp->proto.restr_val2[0] ? bifp->proto.restr_val2[0] : "0",
2576	       bifp->proto.restr_val2[1] ? bifp->proto.restr_val2[1] : "0",
2577	       bifp->proto.restr_val2[2] ? bifp->proto.restr_val2[2] : "0");
2578      fprintf (init_file, "      /* attr_string */\t\"%s\",\n",
2579	       (bifp->kind == FNK_CONST ? "= const"
2580		: (bifp->kind == FNK_PURE ? "= pure"
2581		   : (bifp->kind == FNK_FPMATH ? "= fp, const"
2582		      : ""))));
2583      fprintf (init_file, "      /* assoc_bif */\tRS6000_BIF_%s%s\n",
2584	       bifp->attrs.ismmaint ? bifp->idname : "NONE",
2585	       bifp->attrs.ismmaint ? "_INTERNAL" : "");
2586      fprintf (init_file, "    },\n");
2587    }
2588  fprintf (init_file, "  };\n\n");
2589}
2590
2591/* Write the decls and initializers for rs6000_overload_info[] and
2592   rs6000_instance_info[].  */
2593static void
2594write_ovld_static_init (void)
2595{
2596  fprintf (init_file,
2597	   "ovldrecord rs6000_overload_info[RS6000_OVLD_MAX "
2598	   "- RS6000_OVLD_NONE] =\n");
2599  fprintf (init_file, "  {\n");
2600  fprintf (init_file, "    { /* RS6000_OVLD_NONE: */\n");
2601  fprintf (init_file, "      \"\", NULL\n");
2602  fprintf (init_file, "    },\n");
2603  for (int i = 0; i <= curr_ovld_stanza; i++)
2604    {
2605      fprintf (init_file, "    { /* RS6000_OVLD_%s: */\n",
2606	       ovld_stanzas[i].stanza_id);
2607      fprintf (init_file, "      /* ovld_name */\t\"%s\",\n",
2608	       ovld_stanzas[i].intern_name);
2609      /* First-instance must currently be instantiated at run time.  */
2610      fprintf (init_file, "      /* first_instance */\tNULL\n");
2611      fprintf (init_file, "    },\n");
2612    }
2613  fprintf (init_file, "  };\n\n");
2614
2615  fprintf (init_file, "ovlddata rs6000_instance_info[RS6000_INST_MAX] =\n");
2616  fprintf (init_file, "  {\n");
2617  fprintf (init_file, "    { /* RS6000_INST_NONE: */\n");
2618  fprintf (init_file, "      \"\", RS6000_BIF_NONE, NULL_TREE, NULL\n");
2619  fprintf (init_file, "    },\n");
2620  for (int i = 0; i <= curr_ovld; i++)
2621    {
2622      fprintf (init_file, "    { /* RS6000_INST_%s: */\n",
2623	       ovlds[i].ovld_id_name);
2624      fprintf (init_file, "      /* bifname */\t\"%s\",\n",
2625	       ovlds[i].proto.bifname);
2626      fprintf (init_file, "      /* bifid */\tRS6000_BIF_%s,\n",
2627	       ovlds[i].bif_id_name);
2628      /* Type must be instantiated at run time.  */
2629      fprintf (init_file, "      /* fntype */\t0,\n");
2630      fprintf (init_file, "      /* next */\t");
2631      if (i < curr_ovld
2632	  && !strcmp (ovlds[i+1].proto.bifname, ovlds[i].proto.bifname))
2633	fprintf (init_file,
2634		 "&rs6000_instance_info[RS6000_INST_%s]\n",
2635		 ovlds[i+1].ovld_id_name);
2636      else
2637	fprintf (init_file, "NULL\n");
2638      fprintf (init_file, "    },\n");
2639    }
2640  fprintf (init_file, "  };\n\n");
2641}
2642
2643/* Write code to initialize the built-in function table.  */
2644static void
2645write_init_bif_table (void)
2646{
2647  for (int i = 0; i <= curr_bif; i++)
2648    {
2649      fprintf (init_file,
2650	       "  rs6000_builtin_info[RS6000_BIF_%s].fntype"
2651	       "\n    = %s;\n",
2652	       bifs[i].idname, bifs[i].fndecl);
2653
2654      /* Check whether we have a "tf" token in this string, representing
2655	 a float128_type_node.  It's possible that float128_type_node is
2656	 undefined (occurs for -maltivec -mno-vsx, for example), so we
2657	 must guard against that.  */
2658      int tf_found = strstr (bifs[i].fndecl, "tf") != NULL;
2659
2660      /* Similarly, look for decimal float tokens.  */
2661      int dfp_found = (strstr (bifs[i].fndecl, "sd") != NULL
2662		       || strstr (bifs[i].fndecl, "dd") != NULL
2663		       || strstr (bifs[i].fndecl, "td") != NULL);
2664
2665      if (tf_found)
2666	{
2667	  fprintf (init_file, "  if (float128_type_node)\n");
2668	  fprintf (init_file, "    {\n");
2669	}
2670      else if (dfp_found)
2671	{
2672	  fprintf (init_file, "  if (dfloat64_type_node)\n");
2673	  fprintf (init_file, "    {\n");
2674	}
2675
2676      fprintf (init_file,
2677	       "  rs6000_builtin_decls[(int)RS6000_BIF_%s] = t\n",
2678	       bifs[i].idname);
2679      fprintf (init_file,
2680	       "    = add_builtin_function (\"%s\",\n",
2681	       bifs[i].proto.bifname);
2682      fprintf (init_file,
2683	       "                            %s,\n",
2684	       bifs[i].fndecl);
2685      fprintf (init_file,
2686	       "                            (int)RS6000_BIF_%s,"
2687	       " BUILT_IN_MD,\n",
2688	       bifs[i].idname);
2689      fprintf (init_file,
2690	       "                            NULL, NULL_TREE);\n");
2691      if (bifs[i].kind == FNK_CONST)
2692	{
2693	  fprintf (init_file, "  TREE_READONLY (t) = 1;\n");
2694	  fprintf (init_file, "  TREE_NOTHROW (t) = 1;\n");
2695	}
2696      else if (bifs[i].kind == FNK_PURE)
2697	{
2698	  fprintf (init_file, "  DECL_PURE_P (t) = 1;\n");
2699	  fprintf (init_file, "  TREE_NOTHROW (t) = 1;\n");
2700	}
2701      else if (bifs[i].kind == FNK_FPMATH)
2702	{
2703	  fprintf (init_file, "  TREE_NOTHROW (t) = 1;\n");
2704	  fprintf (init_file, "  if (flag_rounding_math)\n");
2705	  fprintf (init_file, "    {\n");
2706	  fprintf (init_file, "      DECL_PURE_P (t) = 1;\n");
2707	  fprintf (init_file, "      DECL_IS_NOVOPS (t) = 1;\n");
2708	  fprintf (init_file, "    }\n");
2709	  fprintf (init_file, "  else\n");
2710	  fprintf (init_file, "    TREE_READONLY (t) = 1;\n");
2711	}
2712
2713      if (tf_found || dfp_found)
2714	{
2715	  fprintf (init_file, "    }\n");
2716	  fprintf (init_file, "  else\n");
2717	  fprintf (init_file, "    {\n");
2718	  fprintf (init_file, "      rs6000_builtin_decls"
2719		   "[(int)RS6000_BIF_%s] = NULL_TREE;\n", bifs[i].idname);
2720	  fprintf (init_file, "    }\n");
2721	}
2722      fprintf (init_file, "\n");
2723    }
2724}
2725
2726/* Write code to initialize the overload table.  */
2727static void
2728write_init_ovld_table (void)
2729{
2730  fprintf (init_file, "  int base = RS6000_OVLD_NONE;\n\n");
2731  fprintf (init_file,
2732	   "  /* The fndecl for an overload is arbitrarily the first one\n"
2733	   "     for the overload.  We sort out the real types when\n"
2734	   "     processing the overload in the gcc front end.  */\n");
2735
2736  for (int i = 0; i <= curr_ovld; i++)
2737    {
2738      fprintf (init_file,
2739	       "  rs6000_instance_info[RS6000_INST_%s].fntype"
2740	       "\n    = %s;\n",
2741	       ovlds[i].ovld_id_name, ovlds[i].fndecl);
2742
2743      if (i == 0 || ovlds[i].stanza != ovlds[i-1].stanza)
2744	{
2745	  ovld_stanza *stanza = &ovld_stanzas[ovlds[i].stanza];
2746	  fprintf (init_file, "\n");
2747
2748	  /* Check whether we have a "tf" token in this string, representing
2749	     a float128_type_node.  It's possible that float128_type_node is
2750	     undefined (occurs for -maltivec -mno-vsx, for example), so we
2751	     must guard against that.  */
2752	  int tf_found = strstr (ovlds[i].fndecl, "tf") != NULL;
2753
2754	  /* Similarly, look for decimal float tokens.  */
2755	  int dfp_found = (strstr (ovlds[i].fndecl, "sd") != NULL
2756			   || strstr (ovlds[i].fndecl, "dd") != NULL
2757			   || strstr (ovlds[i].fndecl, "td") != NULL);
2758
2759	  if (tf_found)
2760	    {
2761	      fprintf (init_file, "  if (float128_type_node)\n");
2762	      fprintf (init_file, "    {\n");
2763	    }
2764	  else if (dfp_found)
2765	    {
2766	      fprintf (init_file, "  if (dfloat64_type_node)\n");
2767	      fprintf (init_file, "    {\n");
2768	    }
2769
2770	  fprintf (init_file,
2771		   "  rs6000_builtin_decls[(int)RS6000_OVLD_%s] = t\n",
2772		   stanza->stanza_id);
2773	  fprintf (init_file,
2774		   "    = add_builtin_function (\"%s\",\n",
2775		   stanza->intern_name);
2776	  fprintf (init_file,
2777		   "                            %s,\n",
2778		   ovlds[i].fndecl);
2779	  fprintf (init_file,
2780		   "                            (int)RS6000_OVLD_%s,"
2781		   " BUILT_IN_MD,\n",
2782		   stanza->stanza_id);
2783	  fprintf (init_file,
2784		   "                            NULL, NULL_TREE);\n");
2785
2786	  if (tf_found || dfp_found)
2787	    fprintf (init_file, "    }\n");
2788
2789	  fprintf (init_file, "\n");
2790
2791	  fprintf (init_file,
2792		   "  rs6000_overload_info[RS6000_OVLD_%s - base]"
2793		   ".first_instance\n",
2794		   stanza->stanza_id);
2795	  fprintf (init_file,
2796		   "    = &rs6000_instance_info[RS6000_INST_%s];\n\n",
2797		   ovlds[i].ovld_id_name);
2798	}
2799    }
2800}
2801
2802/* Write everything to the initialization file (rs6000-builtins.cc).
2803   Return 1 if successful, 0 otherwise.  */
2804static int
2805write_init_file (void)
2806{
2807  write_autogenerated_header (init_file);
2808
2809  fprintf (init_file, "#include \"config.h\"\n");
2810  fprintf (init_file, "#include \"system.h\"\n");
2811  fprintf (init_file, "#include \"coretypes.h\"\n");
2812  fprintf (init_file, "#include \"backend.h\"\n");
2813  fprintf (init_file, "#include \"rtl.h\"\n");
2814  fprintf (init_file, "#include \"tree.h\"\n");
2815  fprintf (init_file, "#include \"langhooks.h\"\n");
2816  fprintf (init_file, "#include \"insn-codes.h\"\n");
2817  fprintf (init_file, "#include \"rs6000-builtins.h\"\n");
2818  fprintf (init_file, "\n");
2819
2820  fprintf (init_file, "tree rs6000_builtin_decls[RS6000_OVLD_MAX];\n\n");
2821
2822  write_bif_static_init ();
2823  write_ovld_static_init ();
2824
2825  fprintf (init_file, "void\n");
2826  fprintf (init_file, "rs6000_init_generated_builtins ()\n");
2827  fprintf (init_file, "{\n");
2828  fprintf (init_file, "  tree t;\n");
2829  rbt_inorder_callback (&fntype_rbt, fntype_rbt.rbt_root, write_fntype_init);
2830  fprintf (init_file, "\n");
2831
2832  fprintf (init_file,
2833	   "  rs6000_builtin_decls[RS6000_BIF_NONE] = NULL_TREE;\n");
2834  fprintf (init_file,
2835	   "  rs6000_builtin_decls[RS6000_BIF_MAX] = NULL_TREE;\n");
2836  fprintf (init_file,
2837	   "  rs6000_builtin_decls[RS6000_OVLD_NONE] = NULL_TREE;\n\n");
2838
2839  write_init_bif_table ();
2840  write_init_ovld_table ();
2841
2842  fprintf (init_file, "}\n\n");
2843
2844  return 1;
2845}
2846
2847/* Write everything to the include file (rs6000-vecdefines.h).
2848   Return 1 if successful, 0 otherwise.  */
2849static int
2850write_defines_file (void)
2851{
2852  fprintf (defines_file, "#ifndef _RS6000_VECDEFINES_H\n");
2853  fprintf (defines_file, "#define _RS6000_VECDEFINES_H 1\n\n");
2854  fprintf (defines_file, "#if defined(_ARCH_PPC64) && defined (_ARCH_PWR9)\n");
2855  fprintf (defines_file, "  #define _ARCH_PPC64_PWR9 1\n");
2856  fprintf (defines_file, "#endif\n\n");
2857  for (int i = 0; i < num_ovld_stanzas; i++)
2858    if (strcmp (ovld_stanzas[i].extern_name, "SKIP"))
2859      {
2860	if (ovld_stanzas[i].ifdef)
2861	  fprintf (defines_file, "#ifdef %s\n", ovld_stanzas[i].ifdef);
2862	fprintf (defines_file, "#define %s %s\n",
2863		 ovld_stanzas[i].extern_name,
2864		 ovld_stanzas[i].intern_name);
2865	if (ovld_stanzas[i].ifdef)
2866	  fprintf (defines_file, "#endif\n");
2867      }
2868  fprintf (defines_file, "\n#endif\n");
2869  return 1;
2870}
2871
2872/* Close and delete output files after any failure, so that subsequent
2873   build dependencies will fail.  */
2874static void
2875delete_output_files (void)
2876{
2877  /* Depending on whence we're called, some of these may already be
2878     closed.  Don't check for errors.  */
2879  fclose (header_file);
2880  fclose (init_file);
2881  fclose (defines_file);
2882
2883  remove (header_path);
2884  remove (init_path);
2885  remove (defines_path);
2886}
2887
2888/* Main program to convert flat files into built-in initialization code.  */
2889int
2890main (int argc, const char **argv)
2891{
2892  if (argc != 6)
2893    {
2894      fprintf (stderr,
2895	       "Five arguments required: two input files and three output "
2896	       "files.\n");
2897      exit (1);
2898    }
2899
2900  pgm_path = argv[0];
2901  bif_path = argv[1];
2902  ovld_path = argv[2];
2903  header_path = argv[3];
2904  init_path = argv[4];
2905  defines_path = argv[5];
2906
2907  bif_file = fopen (bif_path, "r");
2908  if (!bif_file)
2909    {
2910      fprintf (stderr, "Cannot open input built-in file '%s'.\n", bif_path);
2911      exit (1);
2912    }
2913  ovld_file = fopen (ovld_path, "r");
2914  if (!ovld_file)
2915    {
2916      fprintf (stderr, "Cannot open input overload file '%s'.\n", ovld_path);
2917      exit (1);
2918    }
2919  header_file = fopen (header_path, "w");
2920  if (!header_file)
2921    {
2922      fprintf (stderr, "Cannot open header file '%s' for output.\n",
2923	       header_path);
2924      exit (1);
2925    }
2926  init_file = fopen (init_path, "w");
2927  if (!init_file)
2928    {
2929      fprintf (stderr, "Cannot open init file '%s' for output.\n", init_path);
2930      exit (1);
2931    }
2932  defines_file = fopen (defines_path, "w");
2933  if (!defines_file)
2934    {
2935      fprintf (stderr, "Cannot open defines file '%s' for output.\n",
2936	       defines_path);
2937      exit (1);
2938    }
2939
2940  /* Allocate some buffers.  */
2941  for (int i = 0; i < MAXLINES; i++)
2942    lines[i] = (char *) malloc (LINELEN);
2943
2944  /* Initialize the balanced trees containing built-in function ids,
2945     overload function ids, and function type declaration ids.  */
2946  rbt_new (&bif_rbt);
2947  rbt_new (&ovld_rbt);
2948  rbt_new (&fntype_rbt);
2949
2950  /* Initialize another balanced tree that contains a map from built-in
2951     function ids to the order in which they were encountered.  */
2952  rbt_new (&bifo_rbt);
2953
2954  /* Parse the built-in function file.  */
2955  num_bifs = 0;
2956  line = 0;
2957  if (parse_bif () == PC_PARSEFAIL)
2958    {
2959      fprintf (stderr, "Parsing of '%s' failed, aborting.\n", bif_path);
2960      delete_output_files ();
2961      exit (1);
2962    }
2963  fclose (bif_file);
2964
2965  /* Create a mapping from function IDs in their final order to
2966     the order they appear in the built-in function file.  */
2967  create_bif_order ();
2968
2969#ifdef DEBUG
2970  fprintf (stderr, "\nFunction ID list:\n");
2971  rbt_dump (&bif_rbt, bif_rbt.rbt_root);
2972  fprintf (stderr, "\n");
2973#endif
2974
2975  /* Parse the overload file.  */
2976  num_ovld_stanzas = 0;
2977  num_ovlds = 0;
2978  line = 0;
2979  if (parse_ovld () == PC_PARSEFAIL)
2980    {
2981      fprintf (stderr, "Parsing of '%s' failed, aborting.\n", ovld_path);
2982      delete_output_files ();
2983      exit (1);
2984    }
2985  fclose (ovld_file);
2986
2987#ifdef DEBUG
2988  fprintf (stderr, "\nFunction type decl list:\n");
2989  rbt_dump (&fntype_rbt, fntype_rbt.rbt_root);
2990  fprintf (stderr, "\n");
2991#endif
2992
2993  /* Write the header file and the file containing initialization code.  */
2994  if (!write_header_file ())
2995    {
2996      fprintf (stderr, "Output to '%s' failed, aborting.\n", header_path);
2997      delete_output_files ();
2998      exit (1);
2999    }
3000  if (!write_init_file ())
3001    {
3002      fprintf (stderr, "Output to '%s' failed, aborting.\n", init_path);
3003      delete_output_files ();
3004      exit (1);
3005    }
3006
3007  /* Write the defines file to be included into altivec.h.  */
3008  if (!write_defines_file ())
3009    {
3010      fprintf (stderr, "Output to '%s' failed, aborting.\n", defines_path);
3011      delete_output_files ();
3012      exit (1);
3013    }
3014
3015  /* Always close init_file last.  This avoids race conditions in the
3016     build machinery.  See comments in t-rs6000.  */
3017  fclose (header_file);
3018  fclose (defines_file);
3019  fclose (init_file);
3020
3021  return 0;
3022}
3023