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