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