1 /* Generate built-in function initialization and recognition for Power.
2 Copyright (C) 2020-2023 Free Software Foundation, Inc.
3 Contributed by Bill Schmidt, IBM <wschmidt@linux.ibm.com>
5 This file is part of GCC.
7 GCC is free software; you can redistribute it and/or modify it under
8 the terms of the GNU General Public License as published by the Free
9 Software Foundation; either version 3, or (at your option) any later
12 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13 WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3. If not see
19 <http://www.gnu.org/licenses/>. */
21 /* This program generates built-in function initialization and
22 recognition code for Power targets, based on text files that
23 describe the built-in functions and vector overloads:
25 rs6000-builtins.def Table of built-in functions
26 rs6000-overload.def Table of overload functions
28 Both files group similar functions together in "stanzas," as
31 Each stanza in the built-in function file starts with a line
32 identifying the circumstances in which the group of functions is
33 permitted, with the gating predicate in square brackets. For
34 example, this could be
42 The bracketed gating predicate is the only information allowed on
43 the stanza header line, other than whitespace.
45 Following the stanza header are two lines for each function: the
46 prototype line and the attributes line. The prototype line has
47 this format, where the square brackets indicate optional
48 information and angle brackets indicate required information:
50 [kind] <return-type> <bif-name> (<argument-list>);
52 Here [kind] can be one of "const", "pure", or "fpmath";
53 <return-type> is a legal type for a built-in function result;
54 <bif-name> is the name by which the function can be called;
55 and <argument-list> is a comma-separated list of legal types
56 for built-in function arguments. The argument list may be
57 empty, but the parentheses and semicolon are required.
59 The attributes line looks like this:
61 <bif-id> <bif-pattern> {<attribute-list>}
63 Here <bif-id> is a unique internal identifier for the built-in
64 function that will be used as part of an enumeration of all
65 built-in functions; <bif-pattern> is the define_expand or
66 define_insn that will be invoked when the call is expanded;
67 and <attribute-list> is a comma-separated list of special
68 conditions that apply to the built-in function. The attribute
69 list may be empty, but the braces are required.
71 Attributes are strings, such as these:
73 init Process as a vec_init function
74 set Process as a vec_set function
75 extract Process as a vec_extract function
76 nosoft Not valid with -msoft-float
77 ldvec Needs special handling for vec_ld semantics
78 stvec Needs special handling for vec_st semantics
79 reve Needs special handling for element reversal
80 pred Needs special handling for comparison predicates
81 htm Needs special handling for transactional memory
82 htmspr HTM function using an SPR
83 htmcr HTM function using a CR
84 mma Needs special handling for MMA instructions
85 quad MMA instruction using a register quad as an input operand
86 pair MMA instruction using a register pair as an input operand
87 mmaint MMA instruction expanding to internal call at GIMPLE time
88 no32bit Not valid for TARGET_32BIT
89 32bit Requires different handling for TARGET_32BIT
90 cpu This is a "cpu_is" or "cpu_supports" builtin
91 ldstmask Altivec mask for load or store
92 lxvrse Needs special handling for load-rightmost, sign-extended
93 lxvrze Needs special handling for load-rightmost, zero-extended
94 endian Needs special handling for endianness
95 ibmld Restrict usage to the case when TFmode is IBM-128
96 ibm128 Restrict usage to the case where __ibm128 is supported or
99 An example stanza might look like this:
102 const vsc __builtin_altivec_abs_v16qi (vsc);
103 ABS_V16QI absv16qi2 {}
104 const vss __builtin_altivec_abs_v8hi (vss);
107 Here "vsc" and "vss" are shorthand for "vector signed char" and
108 "vector signed short" to shorten line lengths and improve readability.
109 Note the use of indentation, which is recommended but not required.
111 The overload file has more complex stanza headers. Here the stanza
112 represents all functions with the same overloaded function name:
114 [<overload-id>, <abi-name>, <builtin-name>[[, <ifdef>]] ]
116 Here the single square brackets are part of the syntax, <overload-id>
117 is a unique internal identifier for the overload that will be used as
118 part of an enumeration of all overloaded functions; <abi-name> is the
119 name that will appear as a #define in rs6000-vecdefines.h;
120 <builtin-name> is the name that is overloaded in the back end; and
121 <ifdef> is an optional token used to guard the #define with an #ifdef
122 in rs6000-vecdefines.h.
124 Each function entry again has two lines. The first line is again a
125 prototype line (this time without [kind]):
127 <return-type> <internal-name> (<argument-list>);
129 The second line contains the <bif-id> that this particular instance of
130 the overloaded function maps to. It must match a token that appears in
131 rs6000-builtins.def. Optionally, a second token may appear. If only
132 one token is on the line, it is also used to build the unique identifier
133 for the overloaded function. If a second token is present, the second
134 token is used instead for this purpose. This is necessary in cases
135 where a built-in function accepts more than one type signature. It is
136 common to have a built-in function that, for example, specifies a
137 "vector signed char" argument, but accepts "vector unsigned char" and
138 "vector bool char" as well because only the mode matters. Note that
139 the overload resolution mechanism has always handled these cases by
140 performing fold_convert on vector arguments to hide type mismatches,
141 and it will continue to do so.
143 As a concrete example, __builtin_altivec_mtvscr uses an opaque argument
144 type for the source operand. Its built-in function id is MTVSCR. The
145 overloaded function __builtin_vec_mtvscr takes a variety of specific
146 types, but not all vector types. Each of these maps to the same
147 __builtin_altivec_mtvscr built-in function, but the overload ID must
148 be unique, so we must specify the second token as shown here.
150 [VEC_MTVSCR, vec_mtvscr, __builtin_vec_mtvscr]
151 void __builtin_vec_mtvscr (vbc);
153 void __builtin_vec_mtvscr (vsc);
157 Blank lines may be used as desired in these files between the lines as
158 defined above; that is, you can introduce as many extra newlines as you
159 like after a required newline, but nowhere else. Lines beginning with
160 a semicolon are also treated as blank lines. */
172 /* Input and output file descriptors and pathnames. */
173 static FILE *bif_file
;
174 static FILE *ovld_file
;
175 static FILE *header_file
;
176 static FILE *init_file
;
177 static FILE *defines_file
;
179 static const char *pgm_path
;
180 static const char *bif_path
;
181 static const char *ovld_path
;
182 static const char *header_path
;
183 static const char *init_path
;
184 static const char *defines_path
;
186 /* Position information. Note that "pos" is zero-indexed, but users
187 expect one-indexed column information, so representations of "pos"
188 as columns in diagnostic messages must be adjusted. */
191 static char linebuf
[LINELEN
* MAXLINES
];
195 /* Escape-newline support. For readability, we prefer to allow developers
196 to use escape-newline to continue long lines to the next one. We
197 maintain a buffer of "original" lines here, which are concatenated into
198 linebuf, above, and which can be used to convert the virtual line
199 position "line / pos" into actual line and position information. */
200 static char *lines
[MAXLINES
];
203 /* Used to determine whether a type can be void (only return types). */
210 /* Stanzas are groupings of built-in functions and overloads by some
211 common feature/attribute. These definitions are for built-in function
239 static bif_stanza curr_bif_stanza
;
243 const char *stanza_name
;
247 static stanza_entry stanza_map
[NUMBIFSTANZAS
] =
249 { "always", BSTZ_ALWAYS
},
250 { "power5", BSTZ_P5
},
251 { "power6", BSTZ_P6
},
252 { "power6-64", BSTZ_P6_64
},
253 { "altivec", BSTZ_ALTIVEC
},
254 { "cell", BSTZ_CELL
},
256 { "power7", BSTZ_P7
},
257 { "power7-64", BSTZ_P7_64
},
258 { "power8", BSTZ_P8
},
259 { "power8-vector", BSTZ_P8V
},
260 { "power9", BSTZ_P9
},
261 { "power9-64", BSTZ_P9_64
},
262 { "power9-vector", BSTZ_P9V
},
263 { "ieee128-hw", BSTZ_IEEE128_HW
},
265 { "crypto", BSTZ_CRYPTO
},
267 { "power10", BSTZ_P10
},
268 { "power10-64", BSTZ_P10_64
},
272 static const char *enable_string
[NUMBIFSTANZAS
] =
297 /* Function modifiers provide special handling for const, pure, and fpmath
298 functions. These are mutually exclusive, and therefore kept separate
299 from other bif attributes. */
308 /* Legal base types for an argument or return type. */
331 /* Ways in which a const int value can be restricted. RES_BITS indicates
332 that the integer is restricted to val1 bits, interpreted as an unsigned
333 number. RES_RANGE indicates that the integer is restricted to values
334 between val1 and val2, inclusive. RES_VAR_RANGE is like RES_RANGE, but
335 the argument may be variable, so it can only be checked if it is constant.
336 RES_VALUES indicates that the integer must have one of the values val1
347 /* Type modifiers for an argument or return type. */
364 /* A list of argument types. */
371 /* Attributes of a builtin function. */
400 /* Fields associated with a function prototype (bif or overload). */
401 #define MAXRESTROPNDS 3
408 int restr_opnd
[MAXRESTROPNDS
];
409 restriction restr
[MAXRESTROPNDS
];
410 char *restr_val1
[MAXRESTROPNDS
];
411 char *restr_val2
[MAXRESTROPNDS
];
414 /* Data associated with a builtin function, and a table of such data. */
415 #define MAXBIFS 16384
427 static bifdata bifs
[MAXBIFS
];
431 /* Array used to track the order in which built-ins appeared in the
432 built-in file. We reorder them alphabetically but sometimes need
434 static int *bif_order
;
435 static int bif_index
= 0;
437 /* Stanzas are groupings of built-in functions and overloads by some
438 common feature/attribute. These definitions are for overload stanzas. */
447 #define MAXOVLDSTANZAS 512
448 static ovld_stanza ovld_stanzas
[MAXOVLDSTANZAS
];
449 static int num_ovld_stanzas
;
450 static int curr_ovld_stanza
;
452 #define MAXOVLDS 16384
462 static ovlddata ovlds
[MAXOVLDS
];
463 static int num_ovlds
;
464 static int curr_ovld
;
465 static int max_ovld_args
= 0;
467 /* Return codes for parsing routines. */
476 /* The red-black trees for built-in function identifiers, built-in
477 overload identifiers, and function type descriptors. */
478 static rbt_strings bif_rbt
;
479 static rbt_strings ovld_rbt
;
480 static rbt_strings fntype_rbt
;
482 /* Another red-black tree containing a mapping from built-in function
483 identifiers to the order in which they were encountered. */
484 static rbt_strings bifo_rbt
;
486 /* Mapping from type tokens to type node names. */
493 /* This table must be kept in alphabetical order, as we use binary
494 search for table lookups in map_token_to_type_node. The table
495 maps tokens from a fntype string to a tree type. For example,
496 in "si_ftype_hi" we would map "si" to "intSI_type_node" and
497 map "hi" to "intHI_type_node". */
498 static typemap type_map
[] =
500 { "bi", "bool_int" },
501 { "bv16qi", "bool_V16QI" },
502 { "bv1ti", "bool_V1TI" },
503 { "bv2di", "bool_V2DI" },
504 { "bv4si", "bool_V4SI" },
505 { "bv8hi", "bool_V8HI" },
507 { "dd", "dfloat64" },
509 { "di", "long_long_integer" },
511 { "if", "ibm128_float_type_node "
512 "? ibm128_float_type_node "
514 { "ld", "long_double" },
515 { "lg", "long_integer" },
516 { "pbv16qi", "ptr_bool_V16QI" },
517 { "pbv1ti", "ptr_bool_V1TI" },
518 { "pbv2di", "ptr_bool_V2DI" },
519 { "pbv4si", "ptr_bool_V4SI" },
520 { "pbv8hi", "ptr_bool_V8HI" },
521 { "pcvoid", "pcvoid" },
522 { "pdd", "ptr_dfloat64" },
523 { "pdf", "ptr_double" },
524 { "pdi", "ptr_long_long_integer" },
525 { "phi", "ptr_intHI" },
526 { "pld", "ptr_long_double" },
527 { "plg", "ptr_long_integer" },
528 { "pqi", "ptr_intQI" },
529 { "psf", "ptr_float" },
530 { "psi", "ptr_intSI" },
531 { "ptd", "ptr_dfloat128" },
532 { "ptf", "ptr_float128" },
533 { "pti", "ptr_intTI" },
534 { "pudi", "ptr_long_long_unsigned" },
535 { "puhi", "ptr_uintHI" },
536 { "pulg", "ptr_long_unsigned" },
537 { "puqi", "ptr_uintQI" },
538 { "pusi", "ptr_uintSI" },
539 { "puti", "ptr_uintTI" },
540 { "puv16qi", "ptr_unsigned_V16QI" },
541 { "puv1ti", "ptr_unsigned_V1TI" },
542 { "puv2di", "ptr_unsigned_V2DI" },
543 { "puv4si", "ptr_unsigned_V4SI" },
544 { "puv8hi", "ptr_unsigned_V8HI" },
546 { "pv16qi", "ptr_V16QI" },
547 { "pv1poi", "ptr_vector_pair" },
548 { "pv1pxi", "ptr_vector_quad" },
549 { "pv1ti", "ptr_V1TI" },
550 { "pv2df", "ptr_V2DF" },
551 { "pv2di", "ptr_V2DI" },
552 { "pv4sf", "ptr_V4SF" },
553 { "pv4si", "ptr_V4SI" },
554 { "pv8hi", "ptr_V8HI" },
555 { "pvp8hi", "ptr_pixel_V8HI" },
557 { "sd", "dfloat32" },
560 { "st", "const_str" },
561 { "td", "dfloat128" },
562 { "tf", "float128" },
564 { "udi", "long_long_unsigned" },
565 { "uhi", "unsigned_intHI" },
566 { "ulg", "long_unsigned" },
567 { "uqi", "unsigned_intQI" },
568 { "usi", "unsigned_intSI" },
569 { "uti", "unsigned_intTI" },
570 { "uv16qi", "unsigned_V16QI" },
571 { "uv1ti", "unsigned_V1TI" },
572 { "uv2di", "unsigned_V2DI" },
573 { "uv4si", "unsigned_V4SI" },
574 { "uv8hi", "unsigned_V8HI" },
576 { "v16qi", "V16QI" },
577 { "v1poi", "vector_pair" },
578 { "v1pxi", "vector_quad" },
585 { "vp8hi", "pixel_V8HI" },
588 /* From a possibly extended line with a virtual position, calculate
589 the current line and character position. */
591 real_line_pos (int diagpos
, int *real_line
, int *real_pos
)
593 *real_line
= line
- lastline
;
596 for (int i
= 0; i
< MAXLINES
; i
++)
598 int len
= strlen(lines
[i
]);
599 if (*real_pos
<= len
)
603 *real_pos
-= len
- 2;
606 /* Convert from zero-base to one-base for printing. */
610 /* Pointer to a diagnostic function. */
611 static void (*diag
) (int, const char *, ...)
612 __attribute__ ((format (printf
, 2, 3)));
614 /* Custom diagnostics. */
615 static void __attribute__ ((format (printf
, 2, 3)))
616 bif_diag (int diagpos
, const char * fmt
, ...)
619 int real_line
, real_pos
;
620 real_line_pos (diagpos
, &real_line
, &real_pos
);
621 fprintf (stderr
, "%s:%d:%d: ", bif_path
, real_line
, real_pos
);
622 va_start (args
, fmt
);
623 vfprintf (stderr
, fmt
, args
);
627 static void __attribute__ ((format (printf
, 2, 3)))
628 ovld_diag (int diagpos
, const char * fmt
, ...)
631 int real_line
, real_pos
;
632 real_line_pos (diagpos
, &real_line
, &real_pos
);
633 fprintf (stderr
, "%s:%d:%d: ", ovld_path
, real_line
, real_pos
);
634 va_start (args
, fmt
);
635 vfprintf (stderr
, fmt
, args
);
639 /* Produce a fatal error message. */
641 fatal (const char *msg
)
643 fprintf (stderr
, "FATAL: %s\n", msg
);
647 /* Pass over whitespace (other than a newline, which terminates the scan). */
649 consume_whitespace (void)
651 while (pos
< LINELEN
&& isspace(linebuf
[pos
]) && linebuf
[pos
] != '\n')
656 diag (pos
, "line length overrun.\n");
663 /* Get the next nonblank, noncomment line, returning 0 on EOF, 1 otherwise. */
665 advance_line (FILE *file
)
669 /* Read ahead one line and check for EOF. */
670 if (!fgets (linebuf
, sizeof linebuf
, file
))
673 size_t len
= strlen (linebuf
);
675 /* Escape-newline processing. */
679 strcpy (lines
[0], linebuf
);
680 while (linebuf
[len
- 2] == '\\'
681 && linebuf
[len
- 1] == '\n')
684 if (lastline
== MAXLINES
)
685 fatal ("number of supported overflow lines exceeded");
687 if (!fgets (lines
[lastline
], LINELEN
, file
))
688 fatal ("unexpected end of file");
689 strcpy (&linebuf
[len
- 2], lines
[lastline
]);
690 len
+= strlen (lines
[lastline
]) - 2;
694 if (linebuf
[len
- 1] != '\n')
695 fatal ("line doesn't terminate with newline");
697 consume_whitespace ();
698 if (linebuf
[pos
] != '\n' && linebuf
[pos
] != ';')
706 if (++pos
>= LINELEN
)
708 diag (pos
, "line length overrun.\n");
713 /* Match an identifier, returning NULL on failure, else a pointer to a
714 buffer containing the identifier. */
716 match_identifier (void)
718 int lastpos
= pos
- 1;
719 while (lastpos
< LINELEN
- 1
720 && (isalnum (linebuf
[lastpos
+ 1]) || linebuf
[lastpos
+ 1] == '_'))
723 if (lastpos
>= LINELEN
- 1)
725 diag (lastpos
, "line length overrun.\n");
732 char *buf
= (char *) malloc (lastpos
- pos
+ 2);
733 memcpy (buf
, &linebuf
[pos
], lastpos
- pos
+ 1);
734 buf
[lastpos
- pos
+ 1] = '\0';
740 /* Match an integer and return the string representing its value,
741 or a null string on failure. */
746 if (linebuf
[pos
] == '-')
749 int lastpos
= pos
- 1;
750 while (lastpos
< LINELEN
- 1 && isdigit (linebuf
[lastpos
+ 1]))
753 if (lastpos
>= LINELEN
- 1)
755 diag (lastpos
, "line length overrun.\n");
763 char *buf
= (char *) malloc (lastpos
- startpos
+ 2);
764 memcpy (buf
, &linebuf
[startpos
], lastpos
- startpos
+ 1);
765 buf
[lastpos
- startpos
+ 1] = '\0';
769 /* Match a string up to but not including a ']', and return its value,
770 or zero if there is nothing before the ']'. Error if we don't find
773 match_to_right_bracket (void)
775 int lastpos
= pos
- 1;
776 while (lastpos
< LINELEN
- 1 && linebuf
[lastpos
+ 1] != ']')
778 if (linebuf
[lastpos
+ 1] == '\n')
779 fatal ("no ']' found before end of line.\n");
783 if (lastpos
>= LINELEN
- 1)
785 diag (lastpos
, "line length overrun.\n");
792 char *buf
= (char *) malloc (lastpos
- pos
+ 2);
793 memcpy (buf
, &linebuf
[pos
], lastpos
- pos
+ 1);
794 buf
[lastpos
- pos
+ 1] = '\0';
801 handle_pointer (typeinfo
*typedata
)
803 consume_whitespace ();
804 if (linebuf
[pos
] == '*')
806 typedata
->ispointer
= 1;
812 stanza_name_to_stanza (const char *stanza_name
)
814 for (int i
= 0; i
< NUMBIFSTANZAS
; i
++)
815 if (!strcmp (stanza_name
, stanza_map
[i
].stanza_name
))
816 return stanza_map
[i
].stanza
;
817 fatal ("Stanza mapping is inconsistent.");
822 /* Match one of the allowable base types. Consumes one token unless the
823 token is "long", which must be paired with a second "long". Optionally
824 consumes a following '*' token for pointers. Return 1 for success,
827 match_basetype (typeinfo
*typedata
)
829 consume_whitespace ();
831 char *token
= match_identifier ();
834 diag (pos
, "missing base type in return type\n");
838 if (!strcmp (token
, "char"))
839 typedata
->base
= BT_CHAR
;
840 else if (!strcmp (token
, "short"))
841 typedata
->base
= BT_SHORT
;
842 else if (!strcmp (token
, "int"))
843 typedata
->base
= BT_INT
;
844 else if (!strcmp (token
, "long"))
846 consume_whitespace ();
848 char *mustbelongordbl
= match_identifier ();
849 if (!mustbelongordbl
)
850 typedata
->base
= BT_LONG
;
851 else if (!strcmp (mustbelongordbl
, "long"))
852 typedata
->base
= BT_LONGLONG
;
853 else if (!strcmp (mustbelongordbl
, "double"))
854 typedata
->base
= BT_LONGDOUBLE
;
856 /* Speculatively accept "long" here and push back the token.
857 This occurs when "long" is a return type and the next token
858 is the function name. */
860 typedata
->base
= BT_LONG
;
864 else if (!strcmp (token
, "float"))
865 typedata
->base
= BT_FLOAT
;
866 else if (!strcmp (token
, "double"))
867 typedata
->base
= BT_DOUBLE
;
868 else if (!strcmp (token
, "__int128"))
869 typedata
->base
= BT_INT128
;
870 else if (!strcmp (token
, "_Float128"))
871 typedata
->base
= BT_FLOAT128
;
872 else if (!strcmp (token
, "bool"))
873 typedata
->base
= BT_BOOL
;
874 /* A "string" is a special "const char *" -- we need it because it
875 cannot match either signed or unsigned char *. */
876 else if (!strcmp (token
, "string"))
877 typedata
->base
= BT_STRING
;
878 else if (!strcmp (token
, "_Decimal32"))
879 typedata
->base
= BT_DECIMAL32
;
880 else if (!strcmp (token
, "_Decimal64"))
881 typedata
->base
= BT_DECIMAL64
;
882 else if (!strcmp (token
, "_Decimal128"))
883 typedata
->base
= BT_DECIMAL128
;
884 else if (!strcmp (token
, "__ibm128"))
885 typedata
->base
= BT_IBM128
;
888 diag (oldpos
, "unrecognized base type\n");
892 handle_pointer (typedata
);
896 /* Helper routine for match_const_restriction. */
898 match_bracketed_pair (typeinfo
*typedata
, char open
, char close
,
901 if (linebuf
[pos
] == open
)
905 char *x
= match_integer ();
908 diag (oldpos
, "malformed integer.\n");
911 consume_whitespace ();
912 if (linebuf
[pos
] != ',')
914 diag (pos
, "missing comma.\n");
918 consume_whitespace ();
920 char *y
= match_integer ();
923 diag (oldpos
, "malformed integer.\n");
926 typedata
->restr
= restr
;
930 consume_whitespace ();
931 if (linebuf
[pos
] != close
)
933 diag (pos
, "malformed restriction.\n");
943 /* A const int argument may be restricted to certain values. This is
944 indicated by one of the following occurring after the "int' token:
946 <x> restricts the constant to x bits, interpreted as unsigned
947 <x,y> restricts the constant to the inclusive range [x,y]
948 [x,y] restricts the constant to the inclusive range [x,y],
949 but only applies if the argument is constant.
950 {x,y} restricts the constant to one of two values, x or y.
952 Here x and y are integer tokens. Note that the "const" token is a
953 lie when the restriction is [x,y], but this simplifies the parsing
954 significantly and is hopefully forgivable.
956 Return 1 for success, else 0. */
958 match_const_restriction (typeinfo
*typedata
)
961 if (linebuf
[pos
] == '<')
965 char *x
= match_integer ();
968 diag (oldpos
, "malformed integer.\n");
971 consume_whitespace ();
972 if (linebuf
[pos
] == '>')
974 typedata
->restr
= RES_BITS
;
979 else if (linebuf
[pos
] != ',')
981 diag (pos
, "malformed restriction.\n");
986 char *y
= match_integer ();
989 diag (oldpos
, "malformed integer.\n");
992 typedata
->restr
= RES_RANGE
;
996 consume_whitespace ();
997 if (linebuf
[pos
] != '>')
999 diag (pos
, "malformed restriction.\n");
1005 else if (match_bracketed_pair (typedata
, '{', '}', RES_VALUES
)
1006 || match_bracketed_pair (typedata
, '[', ']', RES_VAR_RANGE
))
1012 /* Look for a type, which can be terminated by a token that is not part of
1013 a type, a comma, or a closing parenthesis. Place information about the
1014 type in TYPEDATA. Return 1 for success, 0 for failure. */
1016 match_type (typeinfo
*typedata
, int voidok
)
1018 /* A legal type is of the form:
1020 [const] [[signed|unsigned] <basetype> | <vectype>] [*]
1022 Legal values of <basetype> are (for now):
1041 Legal values of <vectype> are as follows, and are shorthand for
1042 the associated meaning:
1044 vsc vector signed char
1045 vuc vector unsigned char
1046 vbc vector bool char
1047 vss vector signed short
1048 vus vector unsigned short
1049 vbs vector bool short
1050 vsi vector signed int
1051 vui vector unsigned int
1053 vsll vector signed long long
1054 vull vector unsigned long long
1055 vbll vector bool long long
1056 vsq vector signed __int128
1057 vuq vector unsigned __int128
1058 vbq vector bool __int128
1065 For simplicity, We don't support "short int" and "long long int".
1066 We don't currently support a <basetype> of "_Float16". "signed"
1067 and "unsigned" only apply to integral base types. The optional *
1068 indicates a pointer type. */
1070 consume_whitespace ();
1071 memset (typedata
, 0, sizeof *typedata
);
1074 char *token
= match_identifier ();
1078 if (!strcmp (token
, "const"))
1080 typedata
->isconst
= 1;
1081 consume_whitespace ();
1083 token
= match_identifier ();
1086 if (!strcmp (token
, "void"))
1087 typedata
->isvoid
= 1;
1089 if (!strcmp (token
, "vsc"))
1091 typedata
->isvector
= 1;
1092 typedata
->issigned
= 1;
1093 typedata
->base
= BT_CHAR
;
1094 handle_pointer (typedata
);
1097 else if (!strcmp (token
, "vuc"))
1099 typedata
->isvector
= 1;
1100 typedata
->isunsigned
= 1;
1101 typedata
->base
= BT_CHAR
;
1102 handle_pointer (typedata
);
1105 else if (!strcmp (token
, "vbc"))
1107 typedata
->isvector
= 1;
1108 typedata
->isbool
= 1;
1109 typedata
->base
= BT_CHAR
;
1110 handle_pointer (typedata
);
1113 else if (!strcmp (token
, "vss"))
1115 typedata
->isvector
= 1;
1116 typedata
->issigned
= 1;
1117 typedata
->base
= BT_SHORT
;
1118 handle_pointer (typedata
);
1121 else if (!strcmp (token
, "vus"))
1123 typedata
->isvector
= 1;
1124 typedata
->isunsigned
= 1;
1125 typedata
->base
= BT_SHORT
;
1126 handle_pointer (typedata
);
1129 else if (!strcmp (token
, "vbs"))
1131 typedata
->isvector
= 1;
1132 typedata
->isbool
= 1;
1133 typedata
->base
= BT_SHORT
;
1134 handle_pointer (typedata
);
1137 else if (!strcmp (token
, "vsi"))
1139 typedata
->isvector
= 1;
1140 typedata
->issigned
= 1;
1141 typedata
->base
= BT_INT
;
1142 handle_pointer (typedata
);
1145 else if (!strcmp (token
, "vui"))
1147 typedata
->isvector
= 1;
1148 typedata
->isunsigned
= 1;
1149 typedata
->base
= BT_INT
;
1150 handle_pointer (typedata
);
1153 else if (!strcmp (token
, "vbi"))
1155 typedata
->isvector
= 1;
1156 typedata
->isbool
= 1;
1157 typedata
->base
= BT_INT
;
1158 handle_pointer (typedata
);
1161 else if (!strcmp (token
, "vsll"))
1163 typedata
->isvector
= 1;
1164 typedata
->issigned
= 1;
1165 typedata
->base
= BT_LONGLONG
;
1166 handle_pointer (typedata
);
1169 else if (!strcmp (token
, "vull"))
1171 typedata
->isvector
= 1;
1172 typedata
->isunsigned
= 1;
1173 typedata
->base
= BT_LONGLONG
;
1174 handle_pointer (typedata
);
1177 else if (!strcmp (token
, "vbll"))
1179 typedata
->isvector
= 1;
1180 typedata
->isbool
= 1;
1181 typedata
->base
= BT_LONGLONG
;
1182 handle_pointer (typedata
);
1185 else if (!strcmp (token
, "vsq"))
1187 typedata
->isvector
= 1;
1188 typedata
->issigned
= 1;
1189 typedata
->base
= BT_INT128
;
1190 handle_pointer (typedata
);
1193 else if (!strcmp (token
, "vuq"))
1195 typedata
->isvector
= 1;
1196 typedata
->isunsigned
= 1;
1197 typedata
->base
= BT_INT128
;
1198 handle_pointer (typedata
);
1201 else if (!strcmp (token
, "vbq"))
1203 typedata
->isvector
= 1;
1204 typedata
->isbool
= 1;
1205 typedata
->base
= BT_INT128
;
1206 handle_pointer (typedata
);
1209 else if (!strcmp (token
, "vp"))
1211 typedata
->isvector
= 1;
1212 typedata
->ispixel
= 1;
1213 typedata
->base
= BT_SHORT
;
1214 handle_pointer (typedata
);
1217 else if (!strcmp (token
, "vf"))
1219 typedata
->isvector
= 1;
1220 typedata
->base
= BT_FLOAT
;
1221 handle_pointer (typedata
);
1224 else if (!strcmp (token
, "vd"))
1226 typedata
->isvector
= 1;
1227 typedata
->base
= BT_DOUBLE
;
1228 handle_pointer (typedata
);
1231 else if (!strcmp (token
, "v256"))
1233 typedata
->isvector
= 1;
1234 typedata
->base
= BT_VPAIR
;
1235 handle_pointer (typedata
);
1238 else if (!strcmp (token
, "v512"))
1240 typedata
->isvector
= 1;
1241 typedata
->base
= BT_VQUAD
;
1242 handle_pointer (typedata
);
1245 else if (!strcmp (token
, "signed"))
1246 typedata
->issigned
= 1;
1247 else if (!strcmp (token
, "unsigned"))
1248 typedata
->isunsigned
= 1;
1249 else if (!typedata
->isvoid
&& !typedata
->isconst
)
1251 /* Push back token. */
1253 return match_basetype (typedata
);
1256 if (typedata
->isvoid
)
1258 consume_whitespace ();
1259 if (linebuf
[pos
] == '*')
1261 typedata
->ispointer
= 1;
1269 if (!typedata
->issigned
&& !typedata
->isunsigned
)
1271 if (!match_basetype (typedata
))
1274 if (typedata
->isconst
)
1276 if (typedata
->ispointer
)
1278 if (typedata
->base
!= BT_INT
)
1280 diag (oldpos
, "'const' requires pointer or integer type\n");
1283 consume_whitespace ();
1284 if (linebuf
[pos
] == '<' || linebuf
[pos
] == '{' || linebuf
[pos
] == '[')
1285 return match_const_restriction (typedata
);
1291 /* Parse the argument list. */
1293 parse_args (prototype
*protoptr
)
1295 typelist
**argptr
= &protoptr
->args
;
1296 int *nargs
= &protoptr
->nargs
;
1297 int *restr_opnd
= protoptr
->restr_opnd
;
1298 restriction
*restr
= protoptr
->restr
;
1299 char **val1
= protoptr
->restr_val1
;
1300 char **val2
= protoptr
->restr_val2
;
1306 /* Start the argument list. */
1307 consume_whitespace ();
1308 if (linebuf
[pos
] != '(')
1310 diag (pos
, "missing '('.\n");
1311 return PC_PARSEFAIL
;
1316 consume_whitespace ();
1318 typelist
*argentry
= (typelist
*) malloc (sizeof (typelist
));
1319 memset (argentry
, 0, sizeof *argentry
);
1320 typeinfo
*argtype
= &argentry
->info
;
1321 success
= match_type (argtype
, VOID_NOTOK
);
1326 if (restr_cnt
>= MAXRESTROPNDS
)
1328 diag (pos
, "More than two %d operands\n", MAXRESTROPNDS
);
1329 return PC_PARSEFAIL
;
1331 restr_opnd
[restr_cnt
] = *nargs
+ 1;
1332 restr
[restr_cnt
] = argtype
->restr
;
1333 val1
[restr_cnt
] = argtype
->val1
;
1334 val2
[restr_cnt
] = argtype
->val2
;
1339 argptr
= &argentry
->next
;
1340 consume_whitespace ();
1341 if (linebuf
[pos
] == ',')
1343 else if (linebuf
[pos
] != ')')
1345 diag (pos
, "arg not followed by ',' or ')'.\n");
1346 return PC_PARSEFAIL
;
1351 "argument type: isvoid = %d, isconst = %d, isvector = %d, "
1352 "issigned = %d, isunsigned = %d, isbool = %d, ispixel = %d, "
1353 "ispointer = %d, base = %d, restr = %d, val1 = \"%s\", "
1354 "val2 = \"%s\", pos = %d.\n",
1355 argtype
->isvoid
, argtype
->isconst
, argtype
->isvector
,
1356 argtype
->issigned
, argtype
->isunsigned
, argtype
->isbool
,
1357 argtype
->ispixel
, argtype
->ispointer
, argtype
->base
,
1358 argtype
->restr
, argtype
->val1
, argtype
->val2
, pos
+ 1);
1366 if (linebuf
[pos
] != ')')
1368 diag (pos
, "badly terminated arg list.\n");
1369 return PC_PARSEFAIL
;
1378 /* Parse the attribute list. */
1380 parse_bif_attrs (attrinfo
*attrptr
)
1382 consume_whitespace ();
1383 if (linebuf
[pos
] != '{')
1385 diag (pos
, "missing attribute set.\n");
1386 return PC_PARSEFAIL
;
1390 memset (attrptr
, 0, sizeof *attrptr
);
1391 char *attrname
= NULL
;
1394 consume_whitespace ();
1396 attrname
= match_identifier ();
1399 if (!strcmp (attrname
, "init"))
1400 attrptr
->isinit
= 1;
1401 else if (!strcmp (attrname
, "set"))
1403 else if (!strcmp (attrname
, "extract"))
1404 attrptr
->isextract
= 1;
1405 else if (!strcmp (attrname
, "nosoft"))
1406 attrptr
->isnosoft
= 1;
1407 else if (!strcmp (attrname
, "ldvec"))
1408 attrptr
->isldvec
= 1;
1409 else if (!strcmp (attrname
, "stvec"))
1410 attrptr
->isstvec
= 1;
1411 else if (!strcmp (attrname
, "reve"))
1412 attrptr
->isreve
= 1;
1413 else if (!strcmp (attrname
, "pred"))
1414 attrptr
->ispred
= 1;
1415 else if (!strcmp (attrname
, "htm"))
1417 else if (!strcmp (attrname
, "htmspr"))
1418 attrptr
->ishtmspr
= 1;
1419 else if (!strcmp (attrname
, "htmcr"))
1420 attrptr
->ishtmcr
= 1;
1421 else if (!strcmp (attrname
, "mma"))
1423 else if (!strcmp (attrname
, "quad"))
1424 attrptr
->isquad
= 1;
1425 else if (!strcmp (attrname
, "pair"))
1426 attrptr
->ispair
= 1;
1427 else if (!strcmp (attrname
, "mmaint"))
1428 attrptr
->ismmaint
= 1;
1429 else if (!strcmp (attrname
, "no32bit"))
1430 attrptr
->isno32bit
= 1;
1431 else if (!strcmp (attrname
, "32bit"))
1432 attrptr
->is32bit
= 1;
1433 else if (!strcmp (attrname
, "cpu"))
1435 else if (!strcmp (attrname
, "ldstmask"))
1436 attrptr
->isldstmask
= 1;
1437 else if (!strcmp (attrname
, "lxvrse"))
1438 attrptr
->islxvrse
= 1;
1439 else if (!strcmp (attrname
, "lxvrze"))
1440 attrptr
->islxvrze
= 1;
1441 else if (!strcmp (attrname
, "endian"))
1442 attrptr
->isendian
= 1;
1443 else if (!strcmp (attrname
, "ibmld"))
1444 attrptr
->isibmld
= 1;
1445 else if (!strcmp (attrname
, "ibm128"))
1446 attrptr
->isibm128
= 1;
1449 diag (oldpos
, "unknown attribute.\n");
1450 return PC_PARSEFAIL
;
1453 consume_whitespace ();
1454 if (linebuf
[pos
] == ',')
1456 else if (linebuf
[pos
] != '}')
1458 diag (pos
, "arg not followed by ',' or '}'.\n");
1459 return PC_PARSEFAIL
;
1465 if (linebuf
[pos
] != '}')
1467 diag (pos
, "badly terminated attr set.\n");
1468 return PC_PARSEFAIL
;
1476 "attribute set: init = %d, set = %d, extract = %d, nosoft = %d, "
1477 "ldvec = %d, stvec = %d, reve = %d, pred = %d, htm = %d, "
1478 "htmspr = %d, htmcr = %d, mma = %d, quad = %d, pair = %d, "
1479 "mmaint = %d, no32bit = %d, 32bit = %d, cpu = %d, ldstmask = %d, "
1480 "lxvrse = %d, lxvrze = %d, endian = %d, ibmdld = %d, ibm128 = %d.\n",
1481 attrptr
->isinit
, attrptr
->isset
, attrptr
->isextract
,
1482 attrptr
->isnosoft
, attrptr
->isldvec
, attrptr
->isstvec
,
1483 attrptr
->isreve
, attrptr
->ispred
, attrptr
->ishtm
, attrptr
->ishtmspr
,
1484 attrptr
->ishtmcr
, attrptr
->ismma
, attrptr
->isquad
, attrptr
->ispair
,
1485 attrptr
->ismmaint
, attrptr
->isno32bit
, attrptr
->is32bit
,
1486 attrptr
->iscpu
, attrptr
->isldstmask
, attrptr
->islxvrse
,
1487 attrptr
->islxvrze
, attrptr
->isendian
, attrptr
->isibmld
,
1494 /* Convert a vector type into a mode string. */
1496 complete_vector_type (typeinfo
*typeptr
, char *buf
, int *bufi
)
1498 if (typeptr
->isbool
)
1499 buf
[(*bufi
)++] = 'b';
1500 buf
[(*bufi
)++] = 'v';
1501 if (typeptr
->ispixel
)
1503 memcpy (&buf
[*bufi
], "p8hi", 4);
1507 switch (typeptr
->base
)
1510 memcpy (&buf
[*bufi
], "16qi", 4);
1514 memcpy (&buf
[*bufi
], "8hi", 3);
1518 memcpy (&buf
[*bufi
], "4si", 3);
1522 memcpy (&buf
[*bufi
], "2di", 3);
1526 memcpy (&buf
[*bufi
], "4sf", 3);
1530 memcpy (&buf
[*bufi
], "2df", 3);
1534 memcpy (&buf
[*bufi
], "1ti", 3);
1538 memcpy (&buf
[*bufi
], "1tf", 3);
1542 memcpy (&buf
[*bufi
], "1poi", 4);
1546 memcpy (&buf
[*bufi
], "1pxi", 4);
1550 diag (pos
, "unhandled basetype %d.\n", typeptr
->base
);
1555 /* Convert a base type into a mode string. */
1557 complete_base_type (typeinfo
*typeptr
, char *buf
, int *bufi
)
1559 switch (typeptr
->base
)
1562 memcpy (&buf
[*bufi
], "qi", 2);
1565 memcpy (&buf
[*bufi
], "hi", 2);
1568 memcpy (&buf
[*bufi
], "si", 2);
1571 memcpy (&buf
[*bufi
], "lg", 2);
1574 memcpy (&buf
[*bufi
], "di", 2);
1577 memcpy (&buf
[*bufi
], "sf", 2);
1580 memcpy (&buf
[*bufi
], "df", 2);
1583 memcpy (&buf
[*bufi
], "ld", 2);
1586 memcpy (&buf
[*bufi
], "ti", 2);
1589 memcpy (&buf
[*bufi
], "tf", 2);
1592 memcpy (&buf
[*bufi
], "bi", 2);
1595 memcpy (&buf
[*bufi
], "st", 2);
1598 memcpy (&buf
[*bufi
], "sd", 2);
1601 memcpy (&buf
[*bufi
], "dd", 2);
1604 memcpy (&buf
[*bufi
], "td", 2);
1607 memcpy (&buf
[*bufi
], "if", 2);
1610 diag (pos
, "unhandled basetype %d.\n", typeptr
->base
);
1617 /* Build a function type descriptor identifier from the return type
1618 and argument types described by PROTOPTR, and store it if it does
1619 not already exist. Return the identifier. */
1621 construct_fntype_id (prototype
*protoptr
)
1623 /* Determine the maximum space for a function type descriptor id.
1624 Each type requires at most 9 characters (6 for the mode*, 1 for
1625 the optional 'u' preceding the mode, 1 for the optional 'p'
1626 preceding the mode, and 1 for an underscore following the mode).
1627 We also need 5 characters for the string "ftype" that separates
1628 the return mode from the argument modes. The last argument doesn't
1629 need a trailing underscore, but we count that as the one trailing
1630 "ftype" instead. For the special case of zero arguments, we need 9
1631 for the return type and 7 for "ftype_v". Finally, we need one
1632 character for the terminating null. Thus for a function with N
1633 arguments, we need at most 9N+15 characters for N>0, otherwise 17.
1635 *Worst case is bv16qi for "vector bool char". */
1636 int len
= protoptr
->nargs
? (protoptr
->nargs
+ 1) * 9 + 6 : 17;
1637 char *buf
= (char *) malloc (len
);
1640 if (protoptr
->rettype
.ispointer
)
1643 if (protoptr
->rettype
.isvoid
)
1647 if (protoptr
->rettype
.isunsigned
)
1649 if (protoptr
->rettype
.isvector
)
1650 complete_vector_type (&protoptr
->rettype
, buf
, &bufi
);
1652 complete_base_type (&protoptr
->rettype
, buf
, &bufi
);
1655 memcpy (&buf
[bufi
], "_ftype", 6);
1658 if (!protoptr
->nargs
)
1660 memcpy (&buf
[bufi
], "_v", 2);
1665 typelist
*argptr
= protoptr
->args
;
1666 for (int i
= 0; i
< protoptr
->nargs
; i
++, argptr
= argptr
->next
)
1670 if (argptr
->info
.isconst
1671 && argptr
->info
.base
== BT_INT
1672 && !argptr
->info
.ispointer
)
1678 if (argptr
->info
.ispointer
)
1680 if (argptr
->info
.isvoid
)
1682 if (argptr
->info
.isconst
)
1684 memcpy (&buf
[bufi
], "pcvoid", 6);
1699 if (argptr
->info
.isunsigned
)
1701 if (argptr
->info
.isvector
)
1702 complete_vector_type (&argptr
->info
, buf
, &bufi
);
1704 complete_base_type (&argptr
->info
, buf
, &bufi
);
1711 /* Ignore return value, as duplicates are fine and expected here. */
1712 rbt_insert (&fntype_rbt
, buf
);
1717 /* Parse a function prototype. This code is shared by the bif and overload
1720 parse_prototype (prototype
*protoptr
)
1722 typeinfo
*ret_type
= &protoptr
->rettype
;
1723 char **bifname
= &protoptr
->bifname
;
1725 /* Get the return type. */
1726 consume_whitespace ();
1728 int success
= match_type (ret_type
, VOID_OK
);
1731 diag (oldpos
, "missing or badly formed return type.\n");
1732 return PC_PARSEFAIL
;
1737 "return type: isvoid = %d, isconst = %d, isvector = %d, "
1738 "issigned = %d, isunsigned = %d, isbool = %d, ispixel = %d, "
1739 "ispointer = %d, base = %d, restr = %d, val1 = \"%s\", "
1740 "val2 = \"%s\", pos = %d.\n",
1741 ret_type
->isvoid
, ret_type
->isconst
, ret_type
->isvector
,
1742 ret_type
->issigned
, ret_type
->isunsigned
, ret_type
->isbool
,
1743 ret_type
->ispixel
, ret_type
->ispointer
, ret_type
->base
,
1744 ret_type
->restr
, ret_type
->val1
, ret_type
->val2
, pos
+ 1);
1747 /* Get the bif name. */
1748 consume_whitespace ();
1750 *bifname
= match_identifier ();
1753 diag (oldpos
, "missing function name.\n");
1754 return PC_PARSEFAIL
;
1758 diag (0, "function name is '%s'.\n", *bifname
);
1761 /* Process arguments. */
1762 if (parse_args (protoptr
) == PC_PARSEFAIL
)
1763 return PC_PARSEFAIL
;
1765 /* Process terminating semicolon. */
1766 consume_whitespace ();
1767 if (linebuf
[pos
] != ';')
1769 diag (pos
, "missing semicolon.\n");
1770 return PC_PARSEFAIL
;
1773 consume_whitespace ();
1774 if (linebuf
[pos
] != '\n')
1776 diag (pos
, "garbage at end of line.\n");
1777 return PC_PARSEFAIL
;
1783 /* Parse a two-line entry for a built-in function. */
1785 parse_bif_entry (void)
1787 /* Check for end of stanza. */
1789 consume_whitespace ();
1790 if (linebuf
[pos
] == '[')
1793 /* Allocate an entry in the bif table. */
1794 if (num_bifs
>= MAXBIFS
- 1)
1796 diag (pos
, "too many built-in functions.\n");
1797 return PC_PARSEFAIL
;
1800 curr_bif
= num_bifs
++;
1801 bifs
[curr_bif
].stanza
= curr_bif_stanza
;
1803 /* Read the first token and see if it is a function modifier. */
1804 consume_whitespace ();
1806 char *token
= match_identifier ();
1809 diag (oldpos
, "malformed entry.\n");
1810 return PC_PARSEFAIL
;
1813 if (!strcmp (token
, "const"))
1814 bifs
[curr_bif
].kind
= FNK_CONST
;
1815 else if (!strcmp (token
, "pure"))
1816 bifs
[curr_bif
].kind
= FNK_PURE
;
1817 else if (!strcmp (token
, "fpmath"))
1818 bifs
[curr_bif
].kind
= FNK_FPMATH
;
1821 /* No function modifier, so push the token back. */
1823 bifs
[curr_bif
].kind
= FNK_NONE
;
1826 if (parse_prototype (&bifs
[curr_bif
].proto
) == PC_PARSEFAIL
)
1827 return PC_PARSEFAIL
;
1829 /* Build a function type descriptor identifier from the return type
1830 and argument types, and store it if it does not already exist. */
1831 bifs
[curr_bif
].fndecl
= construct_fntype_id (&bifs
[curr_bif
].proto
);
1833 /* Now process line 2. First up is the builtin id. */
1834 if (!advance_line (bif_file
))
1836 diag (pos
, "unexpected EOF.\n");
1837 return PC_PARSEFAIL
;
1841 consume_whitespace ();
1843 bifs
[curr_bif
].idname
= match_identifier ();
1844 if (!bifs
[curr_bif
].idname
)
1846 diag (pos
, "missing builtin id.\n");
1847 return PC_PARSEFAIL
;
1851 diag (0, "ID name is '%s'.\n", bifs
[curr_bif
].idname
);
1854 /* Save the ID in a lookup structure. */
1855 if (!rbt_insert (&bif_rbt
, bifs
[curr_bif
].idname
))
1857 diag (oldpos
, "duplicate function ID '%s'.\n", bifs
[curr_bif
].idname
);
1858 return PC_PARSEFAIL
;
1861 /* Append a number representing the order in which this function
1862 was encountered to its name, and save in another lookup
1864 int orig_len
= strlen (bifs
[curr_bif
].idname
);
1865 char *buf
= (char *) malloc (orig_len
+ 7);
1866 sprintf (buf
, "%s:%05d", bifs
[curr_bif
].idname
, curr_bif
);
1868 if (!rbt_insert (&bifo_rbt
, buf
))
1870 diag (pos
, "internal error inserting '%s' in bifo_rbt\n", buf
);
1871 return PC_PARSEFAIL
;
1874 /* Now the pattern name. */
1875 consume_whitespace ();
1876 bifs
[curr_bif
].patname
= match_identifier ();
1877 if (!bifs
[curr_bif
].patname
)
1879 diag (pos
, "missing pattern name.\n");
1880 return PC_PARSEFAIL
;
1884 diag (0, "pattern name is '%s'.\n", bifs
[curr_bif
].patname
);
1887 /* Process attributes. */
1888 return parse_bif_attrs (&bifs
[curr_bif
].attrs
);
1891 /* Parse one stanza of the input BIF file. linebuf already contains the
1892 first line to parse. */
1894 parse_bif_stanza (void)
1896 /* Parse the stanza header. */
1898 consume_whitespace ();
1900 if (linebuf
[pos
] != '[')
1902 diag (pos
, "ill-formed stanza header.\n");
1903 return PC_PARSEFAIL
;
1907 const char *stanza_name
= match_to_right_bracket ();
1910 diag (pos
, "no expression found in stanza header.\n");
1911 return PC_PARSEFAIL
;
1914 curr_bif_stanza
= stanza_name_to_stanza (stanza_name
);
1916 if (linebuf
[pos
] != ']')
1918 diag (pos
, "ill-formed stanza header.\n");
1919 return PC_PARSEFAIL
;
1923 consume_whitespace ();
1924 if (linebuf
[pos
] != '\n' && pos
!= LINELEN
- 1)
1926 diag (pos
, "garbage after stanza header.\n");
1927 return PC_PARSEFAIL
;
1930 parse_codes result
= PC_OK
;
1932 while (result
!= PC_EOSTANZA
)
1934 if (!advance_line (bif_file
))
1936 result
= parse_bif_entry ();
1937 if (result
== PC_PARSEFAIL
)
1938 return PC_PARSEFAIL
;
1944 /* Parse the built-in file. */
1950 if (!advance_line (bif_file
))
1954 result
= parse_bif_stanza ();
1955 while (result
== PC_OK
);
1957 if (result
== PC_EOFILE
)
1962 /* Callback function for create_bif_order. */
1963 void set_bif_order (char *str
)
1966 char *colon
= strchr (str
, ':');
1967 sscanf (++colon
, "%d", &num
);
1968 bif_order
[bif_index
++] = num
;
1971 /* Create a mapping from function IDs in their final order to the order
1972 they appear in the built-in function file. */
1974 create_bif_order (void)
1976 bif_order
= (int *) malloc ((curr_bif
+ 1) * sizeof (int));
1977 rbt_inorder_callback (&bifo_rbt
, bifo_rbt
.rbt_root
, set_bif_order
);
1980 /* Parse one two-line entry in the overload file. */
1982 parse_ovld_entry (void)
1984 /* Check for end of stanza. */
1986 consume_whitespace ();
1987 if (linebuf
[pos
] == '[')
1990 /* Allocate an entry in the overload table. */
1991 if (num_ovlds
>= MAXOVLDS
- 1)
1993 diag (pos
, "too many overloads.\n");
1994 return PC_PARSEFAIL
;
1997 curr_ovld
= num_ovlds
++;
1998 ovlds
[curr_ovld
].stanza
= curr_ovld_stanza
;
2000 if (parse_prototype (&ovlds
[curr_ovld
].proto
) == PC_PARSEFAIL
)
2001 return PC_PARSEFAIL
;
2003 if (ovlds
[curr_ovld
].proto
.nargs
> max_ovld_args
)
2004 max_ovld_args
= ovlds
[curr_ovld
].proto
.nargs
;
2006 /* Build a function type descriptor identifier from the return type
2007 and argument types, and store it if it does not already exist. */
2008 ovlds
[curr_ovld
].fndecl
= construct_fntype_id (&ovlds
[curr_ovld
].proto
);
2010 /* Now process line 2, which just contains the builtin id and an
2011 optional overload id. */
2012 if (!advance_line (ovld_file
))
2014 diag (0, "unexpected EOF.\n");
2019 consume_whitespace ();
2021 char *id
= match_identifier ();
2022 ovlds
[curr_ovld
].bif_id_name
= id
;
2023 ovlds
[curr_ovld
].ovld_id_name
= id
;
2026 diag (pos
, "missing overload id.\n");
2027 return PC_PARSEFAIL
;
2031 diag (pos
, "ID name is '%s'.\n", id
);
2034 /* The builtin id has to match one from the bif file. */
2035 if (!rbt_find (&bif_rbt
, id
))
2037 diag (pos
, "builtin ID '%s' not found in bif file.\n", id
);
2038 return PC_PARSEFAIL
;
2041 /* Check for an optional overload id. Usually we use the builtin
2042 function id for that purpose, but sometimes we need multiple
2043 overload entries for the same builtin id, and it needs to be unique. */
2044 consume_whitespace ();
2045 if (linebuf
[pos
] != '\n')
2047 id
= match_identifier ();
2048 ovlds
[curr_ovld
].ovld_id_name
= id
;
2049 consume_whitespace ();
2052 /* Save the overload ID in a lookup structure. */
2053 if (!rbt_insert (&ovld_rbt
, id
))
2055 diag (oldpos
, "duplicate overload ID '%s'.\n", id
);
2056 return PC_PARSEFAIL
;
2059 if (linebuf
[pos
] != '\n')
2061 diag (pos
, "garbage at end of line.\n");
2062 return PC_PARSEFAIL
;
2067 /* Parse one stanza of the input overload file. linebuf already contains the
2068 first line to parse. */
2070 parse_ovld_stanza (void)
2072 /* Parse the stanza header. */
2074 consume_whitespace ();
2076 if (linebuf
[pos
] != '[')
2078 diag (pos
, "ill-formed stanza header.\n");
2079 return PC_PARSEFAIL
;
2083 char *stanza_name
= match_identifier ();
2086 diag (pos
, "no identifier found in stanza header.\n");
2087 return PC_PARSEFAIL
;
2090 /* Add the identifier to a table and set the number to be recorded
2091 with subsequent overload entries. */
2092 if (num_ovld_stanzas
>= MAXOVLDSTANZAS
)
2094 diag (pos
, "too many stanza headers.\n");
2095 return PC_PARSEFAIL
;
2098 curr_ovld_stanza
= num_ovld_stanzas
++;
2099 ovld_stanza
*stanza
= &ovld_stanzas
[curr_ovld_stanza
];
2100 stanza
->stanza_id
= stanza_name
;
2102 consume_whitespace ();
2103 if (linebuf
[pos
] != ',')
2105 diag (pos
, "missing comma.\n");
2106 return PC_PARSEFAIL
;
2110 consume_whitespace ();
2111 stanza
->extern_name
= match_identifier ();
2112 if (!stanza
->extern_name
)
2114 diag (pos
, "missing external name.\n");
2115 return PC_PARSEFAIL
;
2118 consume_whitespace ();
2119 if (linebuf
[pos
] != ',')
2121 diag (pos
, "missing comma.\n");
2122 return PC_PARSEFAIL
;
2126 consume_whitespace ();
2127 stanza
->intern_name
= match_identifier ();
2128 if (!stanza
->intern_name
)
2130 diag (pos
, "missing internal name.\n");
2131 return PC_PARSEFAIL
;
2134 consume_whitespace ();
2135 if (linebuf
[pos
] == ',')
2138 consume_whitespace ();
2139 stanza
->ifdef
= match_identifier ();
2142 diag (pos
, "missing ifdef token.\n");
2143 return PC_PARSEFAIL
;
2145 consume_whitespace ();
2150 if (linebuf
[pos
] != ']')
2152 diag (pos
, "ill-formed stanza header.\n");
2153 return PC_PARSEFAIL
;
2157 consume_whitespace ();
2158 if (linebuf
[pos
] != '\n' && pos
!= LINELEN
- 1)
2160 diag (pos
, "garbage after stanza header.\n");
2161 return PC_PARSEFAIL
;
2164 parse_codes result
= PC_OK
;
2166 while (result
!= PC_EOSTANZA
)
2168 if (!advance_line (ovld_file
))
2171 result
= parse_ovld_entry ();
2172 if (result
== PC_EOFILE
|| result
== PC_PARSEFAIL
)
2179 /* Parse the overload file. */
2183 parse_codes result
= PC_OK
;
2186 if (!advance_line (ovld_file
))
2189 while (result
== PC_OK
)
2190 result
= parse_ovld_stanza ();
2192 if (result
== PC_EOFILE
)
2197 /* Write a comment at the top of FILE about how the code was generated. */
2199 write_autogenerated_header (FILE *file
)
2201 fprintf (file
, "/* Automatically generated by the program '%s'\n",
2203 fprintf (file
, " from the files '%s' and '%s'. */\n\n",
2204 bif_path
, ovld_path
);
2207 /* Write declarations into the header file. */
2211 fprintf (header_file
, "enum rs6000_gen_builtins\n{\n RS6000_BIF_NONE,\n");
2212 for (int i
= 0; i
<= curr_bif
; i
++)
2213 fprintf (header_file
, " RS6000_BIF_%s,\n", bifs
[bif_order
[i
]].idname
);
2214 fprintf (header_file
, " RS6000_BIF_MAX,\n");
2215 fprintf (header_file
, " RS6000_OVLD_NONE,\n");
2216 for (int i
= 0; i
< num_ovld_stanzas
; i
++)
2217 fprintf (header_file
, " RS6000_OVLD_%s,\n", ovld_stanzas
[i
].stanza_id
);
2218 fprintf (header_file
, " RS6000_OVLD_MAX\n};\n\n");
2220 fprintf (header_file
,
2221 "extern GTY(()) tree rs6000_builtin_decls[RS6000_OVLD_MAX];\n\n");
2223 fprintf (header_file
,
2224 "enum rs6000_ovld_instances\n{\n RS6000_INST_NONE,\n");
2225 for (int i
= 0; i
<= curr_ovld
; i
++)
2226 fprintf (header_file
, " RS6000_INST_%s,\n", ovlds
[i
].ovld_id_name
);
2227 fprintf (header_file
, " RS6000_INST_MAX\n};\n\n");
2229 fprintf (header_file
, "#define MAX_OVLD_ARGS %d\n", max_ovld_args
);
2231 fprintf (header_file
, "enum restriction {\n");
2232 fprintf (header_file
, " RES_NONE,\n");
2233 fprintf (header_file
, " RES_BITS,\n");
2234 fprintf (header_file
, " RES_RANGE,\n");
2235 fprintf (header_file
, " RES_VAR_RANGE,\n");
2236 fprintf (header_file
, " RES_VALUES\n");
2237 fprintf (header_file
, "};\n\n");
2239 fprintf (header_file
, "enum bif_enable {\n");
2240 fprintf (header_file
, " ENB_ALWAYS,\n");
2241 fprintf (header_file
, " ENB_P5,\n");
2242 fprintf (header_file
, " ENB_P6,\n");
2243 fprintf (header_file
, " ENB_P6_64,\n");
2244 fprintf (header_file
, " ENB_ALTIVEC,\n");
2245 fprintf (header_file
, " ENB_CELL,\n");
2246 fprintf (header_file
, " ENB_VSX,\n");
2247 fprintf (header_file
, " ENB_P7,\n");
2248 fprintf (header_file
, " ENB_P7_64,\n");
2249 fprintf (header_file
, " ENB_P8,\n");
2250 fprintf (header_file
, " ENB_P8V,\n");
2251 fprintf (header_file
, " ENB_P9,\n");
2252 fprintf (header_file
, " ENB_P9_64,\n");
2253 fprintf (header_file
, " ENB_P9V,\n");
2254 fprintf (header_file
, " ENB_IEEE128_HW,\n");
2255 fprintf (header_file
, " ENB_DFP,\n");
2256 fprintf (header_file
, " ENB_CRYPTO,\n");
2257 fprintf (header_file
, " ENB_HTM,\n");
2258 fprintf (header_file
, " ENB_P10,\n");
2259 fprintf (header_file
, " ENB_P10_64,\n");
2260 fprintf (header_file
, " ENB_MMA\n");
2261 fprintf (header_file
, "};\n\n");
2263 fprintf (header_file
, "#define PPC_MAXRESTROPNDS 3\n");
2264 fprintf (header_file
, "struct GTY(()) bifdata\n");
2265 fprintf (header_file
, "{\n");
2266 fprintf (header_file
, " const char *GTY((skip(\"\"))) bifname;\n");
2267 fprintf (header_file
, " bif_enable GTY((skip(\"\"))) enable;\n");
2268 fprintf (header_file
, " tree fntype;\n");
2269 fprintf (header_file
, " insn_code GTY((skip(\"\"))) icode;\n");
2270 fprintf (header_file
, " int nargs;\n");
2271 fprintf (header_file
, " int bifattrs;\n");
2272 fprintf (header_file
, " int restr_opnd[PPC_MAXRESTROPNDS];\n");
2273 fprintf (header_file
, " restriction GTY((skip(\"\"))) restr[PPC_MAXRESTROPNDS];\n");
2274 fprintf (header_file
, " int restr_val1[PPC_MAXRESTROPNDS];\n");
2275 fprintf (header_file
, " int restr_val2[PPC_MAXRESTROPNDS];\n");
2276 fprintf (header_file
, " const char *GTY((skip(\"\"))) attr_string;\n");
2277 fprintf (header_file
, " rs6000_gen_builtins GTY((skip(\"\"))) assoc_bif;\n");
2278 fprintf (header_file
, "};\n\n");
2280 fprintf (header_file
, "#define bif_init_bit\t\t(0x00000001)\n");
2281 fprintf (header_file
, "#define bif_set_bit\t\t(0x00000002)\n");
2282 fprintf (header_file
, "#define bif_extract_bit\t\t(0x00000004)\n");
2283 fprintf (header_file
, "#define bif_nosoft_bit\t\t(0x00000008)\n");
2284 fprintf (header_file
, "#define bif_ldvec_bit\t\t(0x00000010)\n");
2285 fprintf (header_file
, "#define bif_stvec_bit\t\t(0x00000020)\n");
2286 fprintf (header_file
, "#define bif_reve_bit\t\t(0x00000040)\n");
2287 fprintf (header_file
, "#define bif_pred_bit\t\t(0x00000080)\n");
2288 fprintf (header_file
, "#define bif_htm_bit\t\t(0x00000100)\n");
2289 fprintf (header_file
, "#define bif_htmspr_bit\t\t(0x00000200)\n");
2290 fprintf (header_file
, "#define bif_htmcr_bit\t\t(0x00000400)\n");
2291 fprintf (header_file
, "#define bif_mma_bit\t\t(0x00000800)\n");
2292 fprintf (header_file
, "#define bif_quad_bit\t\t(0x00001000)\n");
2293 fprintf (header_file
, "#define bif_pair_bit\t\t(0x00002000)\n");
2294 fprintf (header_file
, "#define bif_mmaint_bit\t\t(0x00004000)\n");
2295 fprintf (header_file
, "#define bif_no32bit_bit\t\t(0x00008000)\n");
2296 fprintf (header_file
, "#define bif_32bit_bit\t\t(0x00010000)\n");
2297 fprintf (header_file
, "#define bif_cpu_bit\t\t(0x00020000)\n");
2298 fprintf (header_file
, "#define bif_ldstmask_bit\t(0x00040000)\n");
2299 fprintf (header_file
, "#define bif_lxvrse_bit\t\t(0x00080000)\n");
2300 fprintf (header_file
, "#define bif_lxvrze_bit\t\t(0x00100000)\n");
2301 fprintf (header_file
, "#define bif_endian_bit\t\t(0x00200000)\n");
2302 fprintf (header_file
, "#define bif_ibmld_bit\t\t(0x00400000)\n");
2303 fprintf (header_file
, "#define bif_ibm128_bit\t\t(0x00800000)\n");
2304 fprintf (header_file
, "\n");
2305 fprintf (header_file
,
2306 "#define bif_is_init(x)\t\t((x).bifattrs & bif_init_bit)\n");
2307 fprintf (header_file
,
2308 "#define bif_is_set(x)\t\t((x).bifattrs & bif_set_bit)\n");
2309 fprintf (header_file
,
2310 "#define bif_is_extract(x)\t((x).bifattrs & bif_extract_bit)\n");
2311 fprintf (header_file
,
2312 "#define bif_is_nosoft(x)\t((x).bifattrs & bif_nosoft_bit)\n");
2313 fprintf (header_file
,
2314 "#define bif_is_ldvec(x)\t\t((x).bifattrs & bif_ldvec_bit)\n");
2315 fprintf (header_file
,
2316 "#define bif_is_stvec(x)\t\t((x).bifattrs & bif_stvec_bit)\n");
2317 fprintf (header_file
,
2318 "#define bif_is_reve(x)\t\t((x).bifattrs & bif_reve_bit)\n");
2319 fprintf (header_file
,
2320 "#define bif_is_predicate(x)\t((x).bifattrs & bif_pred_bit)\n");
2321 fprintf (header_file
,
2322 "#define bif_is_htm(x)\t\t((x).bifattrs & bif_htm_bit)\n");
2323 fprintf (header_file
,
2324 "#define bif_is_htmspr(x)\t((x).bifattrs & bif_htmspr_bit)\n");
2325 fprintf (header_file
,
2326 "#define bif_is_htmcr(x)\t\t((x).bifattrs & bif_htmcr_bit)\n");
2327 fprintf (header_file
,
2328 "#define bif_is_mma(x)\t\t((x).bifattrs & bif_mma_bit)\n");
2329 fprintf (header_file
,
2330 "#define bif_is_quad(x)\t\t((x).bifattrs & bif_quad_bit)\n");
2331 fprintf (header_file
,
2332 "#define bif_is_pair(x)\t\t((x).bifattrs & bif_pair_bit)\n");
2333 fprintf (header_file
,
2334 "#define bif_is_mmaint(x)\t\t((x).bifattrs & bif_mmaint_bit)\n");
2335 fprintf (header_file
,
2336 "#define bif_is_no32bit(x)\t((x).bifattrs & bif_no32bit_bit)\n");
2337 fprintf (header_file
,
2338 "#define bif_is_32bit(x)\t((x).bifattrs & bif_32bit_bit)\n");
2339 fprintf (header_file
,
2340 "#define bif_is_cpu(x)\t\t((x).bifattrs & bif_cpu_bit)\n");
2341 fprintf (header_file
,
2342 "#define bif_is_ldstmask(x)\t((x).bifattrs & bif_ldstmask_bit)\n");
2343 fprintf (header_file
,
2344 "#define bif_is_lxvrse(x)\t((x).bifattrs & bif_lxvrse_bit)\n");
2345 fprintf (header_file
,
2346 "#define bif_is_lxvrze(x)\t((x).bifattrs & bif_lxvrze_bit)\n");
2347 fprintf (header_file
,
2348 "#define bif_is_endian(x)\t((x).bifattrs & bif_endian_bit)\n");
2349 fprintf (header_file
,
2350 "#define bif_is_ibmld(x)\t((x).bifattrs & bif_ibmld_bit)\n");
2351 fprintf (header_file
,
2352 "#define bif_is_ibm128(x)\t((x).bifattrs & bif_ibm128_bit)\n");
2353 fprintf (header_file
, "\n");
2355 fprintf (header_file
,
2356 "extern GTY(()) bifdata rs6000_builtin_info[RS6000_BIF_MAX];\n\n");
2358 fprintf (header_file
, "struct GTY(()) ovlddata\n");
2359 fprintf (header_file
, "{\n");
2360 fprintf (header_file
, " const char *GTY((skip(\"\"))) bifname;\n");
2361 fprintf (header_file
, " rs6000_gen_builtins GTY((skip(\"\"))) bifid;\n");
2362 fprintf (header_file
, " tree fntype;\n");
2363 fprintf (header_file
, " ovlddata *GTY((skip(\"\"))) next;\n");
2364 fprintf (header_file
, "};\n\n");
2366 fprintf (header_file
, "struct ovldrecord\n");
2367 fprintf (header_file
, "{\n");
2368 fprintf (header_file
, " const char *ovld_name;\n");
2369 fprintf (header_file
, " ovlddata *first_instance;\n");
2370 fprintf (header_file
, "};\n\n");
2372 fprintf (header_file
,
2373 "extern GTY(()) ovlddata rs6000_instance_info[RS6000_INST_MAX];\n");
2374 fprintf (header_file
, "extern ovldrecord rs6000_overload_info[];\n\n");
2376 fprintf (header_file
, "extern void rs6000_init_generated_builtins ();\n\n");
2377 fprintf (header_file
,
2378 "extern bool rs6000_builtin_is_supported (rs6000_gen_builtins);\n");
2379 fprintf (header_file
,
2380 "extern tree rs6000_builtin_decl (unsigned, "
2381 "bool ATTRIBUTE_UNUSED);\n\n");
2384 /* Comparator for bsearch on the type map. */
2386 typemap_cmp (const void *key
, const void *entry
)
2388 return strcmp ((const char *)key
, ((const typemap
*)entry
)->key
);
2391 /* Write the type node corresponding to TOK. */
2393 write_type_node (char *tok
, bool indent
)
2396 fprintf (init_file
, " ");
2398 = (typemap
*) bsearch (tok
, type_map
,
2399 sizeof type_map
/ sizeof type_map
[0],
2400 sizeof (typemap
), typemap_cmp
);
2402 fatal ("Type map is inconsistent.");
2403 fprintf (init_file
, "%s_type_node", entry
->value
);
2406 /* Write an initializer for a function type identified by STR. */
2408 write_fntype_init (char *str
)
2412 /* Check whether we have a "tf" token in this string, representing
2413 a float128_type_node. It's possible that float128_type_node is
2414 undefined (occurs for -maltivec -mno-vsx, for example), so we
2415 must guard against that. */
2416 int tf_found
= strstr (str
, "tf") != NULL
;
2418 /* Similarly, look for decimal float tokens. */
2419 int dfp_found
= (strstr (str
, "dd") != NULL
2420 || strstr (str
, "td") != NULL
2421 || strstr (str
, "sd") != NULL
);
2423 /* Avoid side effects of strtok on the original string by using a copy. */
2424 char *buf
= strdup (str
);
2426 if (tf_found
|| dfp_found
)
2427 fprintf (init_file
, " tree %s = NULL_TREE;\n", buf
);
2429 fprintf (init_file
, " tree ");
2432 fprintf (init_file
, " if (float128_type_node)\n ");
2434 fprintf (init_file
, " if (dfloat64_type_node)\n ");
2436 fprintf (init_file
, "%s\n = build_function_type_list (", buf
);
2437 tok
= strtok (buf
, "_");
2438 write_type_node (tok
, tf_found
|| dfp_found
);
2439 tok
= strtok (0, "_");
2441 assert (!strcmp (tok
, "ftype"));
2443 tok
= strtok (0, "_");
2445 fprintf (init_file
, ",\n\t\t\t\t");
2447 /* Note: A function with no arguments ends with '_ftype_v'. */
2448 while (tok
&& strcmp (tok
, "v"))
2450 write_type_node (tok
, tf_found
|| dfp_found
);
2451 tok
= strtok (0, "_");
2452 fprintf (init_file
, ",\n\t\t\t\t");
2454 fprintf (init_file
, "NULL_TREE);\n");
2458 /* Write everything to the header file (rs6000-builtins.h). Return
2459 1 if successful, 0 otherwise. */
2461 write_header_file (void)
2463 write_autogenerated_header (header_file
);
2465 fprintf (header_file
, "#ifndef _RS6000_BUILTINS_H\n");
2466 fprintf (header_file
, "#define _RS6000_BUILTINS_H 1\n\n");
2470 fprintf (header_file
, "\n");
2471 fprintf (header_file
, "\n#endif\n");
2476 /* Write the decl and initializer for rs6000_builtin_info[]. */
2478 write_bif_static_init (void)
2481 fprintf (init_file
, "bifdata rs6000_builtin_info[RS6000_BIF_MAX] =\n");
2482 fprintf (init_file
, " {\n");
2483 fprintf (init_file
, " { /* RS6000_BIF_NONE: */\n");
2484 fprintf (init_file
, " \"\", ENB_ALWAYS, 0, CODE_FOR_nothing, 0,\n");
2485 fprintf (init_file
, " 0, {0, 0, 0}, {RES_NONE, RES_NONE, RES_NONE},\n");
2486 fprintf (init_file
, " {0, 0, 0}, {0, 0, 0}, \"\", RS6000_BIF_NONE\n");
2487 fprintf (init_file
, " },\n");
2488 for (int i
= 0; i
<= curr_bif
; i
++)
2490 bifdata
*bifp
= &bifs
[bif_order
[i
]];
2491 fprintf (init_file
, " { /* RS6000_BIF_%s: */\n", bifp
->idname
);
2492 fprintf (init_file
, " /* bifname */\t\"%s\",\n",
2493 bifp
->proto
.bifname
);
2494 fprintf (init_file
, " /* enable*/\t%s,\n",
2495 enable_string
[bifp
->stanza
]);
2496 /* Type must be instantiated at run time. */
2497 fprintf (init_file
, " /* fntype */\t0,\n");
2498 fprintf (init_file
, " /* icode */\tCODE_FOR_%s,\n",
2500 fprintf (init_file
, " /* nargs */\t%d,\n",
2502 fprintf (init_file
, " /* bifattrs */\t0");
2503 if (bifp
->attrs
.isinit
)
2504 fprintf (init_file
, " | bif_init_bit");
2505 if (bifp
->attrs
.isset
)
2506 fprintf (init_file
, " | bif_set_bit");
2507 if (bifp
->attrs
.isextract
)
2508 fprintf (init_file
, " | bif_extract_bit");
2509 if (bifp
->attrs
.isnosoft
)
2510 fprintf (init_file
, " | bif_nosoft_bit");
2511 if (bifp
->attrs
.isldvec
)
2512 fprintf (init_file
, " | bif_ldvec_bit");
2513 if (bifp
->attrs
.isstvec
)
2514 fprintf (init_file
, " | bif_stvec_bit");
2515 if (bifp
->attrs
.isreve
)
2516 fprintf (init_file
, " | bif_reve_bit");
2517 if (bifp
->attrs
.ispred
)
2518 fprintf (init_file
, " | bif_pred_bit");
2519 if (bifp
->attrs
.ishtm
)
2520 fprintf (init_file
, " | bif_htm_bit");
2521 if (bifp
->attrs
.ishtmspr
)
2522 fprintf (init_file
, " | bif_htmspr_bit");
2523 if (bifp
->attrs
.ishtmcr
)
2524 fprintf (init_file
, " | bif_htmcr_bit");
2525 if (bifp
->attrs
.ismma
)
2526 fprintf (init_file
, " | bif_mma_bit");
2527 if (bifp
->attrs
.isquad
)
2528 fprintf (init_file
, " | bif_quad_bit");
2529 if (bifp
->attrs
.ispair
)
2530 fprintf (init_file
, " | bif_pair_bit");
2531 if (bifp
->attrs
.ismmaint
)
2532 fprintf (init_file
, " | bif_mmaint_bit");
2533 if (bifp
->attrs
.isno32bit
)
2534 fprintf (init_file
, " | bif_no32bit_bit");
2535 if (bifp
->attrs
.is32bit
)
2536 fprintf (init_file
, " | bif_32bit_bit");
2537 if (bifp
->attrs
.iscpu
)
2538 fprintf (init_file
, " | bif_cpu_bit");
2539 if (bifp
->attrs
.isldstmask
)
2540 fprintf (init_file
, " | bif_ldstmask_bit");
2541 if (bifp
->attrs
.islxvrse
)
2542 fprintf (init_file
, " | bif_lxvrse_bit");
2543 if (bifp
->attrs
.islxvrze
)
2544 fprintf (init_file
, " | bif_lxvrze_bit");
2545 if (bifp
->attrs
.isendian
)
2546 fprintf (init_file
, " | bif_endian_bit");
2547 if (bifp
->attrs
.isibmld
)
2548 fprintf (init_file
, " | bif_ibmld_bit");
2549 if (bifp
->attrs
.isibm128
)
2550 fprintf (init_file
, " | bif_ibm128_bit");
2551 fprintf (init_file
, ",\n");
2552 fprintf (init_file
, " /* restr_opnd */\t{%d, %d, %d},\n",
2553 bifp
->proto
.restr_opnd
[0], bifp
->proto
.restr_opnd
[1],
2554 bifp
->proto
.restr_opnd
[2]);
2555 for (int j
= 0; j
< 3; j
++)
2556 if (!bifp
->proto
.restr_opnd
[j
])
2557 res
[j
] = "RES_NONE";
2558 else if (bifp
->proto
.restr
[j
] == RES_BITS
)
2559 res
[j
] = "RES_BITS";
2560 else if (bifp
->proto
.restr
[j
] == RES_RANGE
)
2561 res
[j
] = "RES_RANGE";
2562 else if (bifp
->proto
.restr
[j
] == RES_VALUES
)
2563 res
[j
] = "RES_VALUES";
2564 else if (bifp
->proto
.restr
[j
] == RES_VAR_RANGE
)
2565 res
[j
] = "RES_VAR_RANGE";
2568 fprintf (init_file
, " /* restr */\t{%s, %s, %s},\n",
2569 res
[0], res
[1], res
[2]);
2570 fprintf (init_file
, " /* restr_val1 */\t{%s, %s, %s},\n",
2571 bifp
->proto
.restr_val1
[0] ? bifp
->proto
.restr_val1
[0] : "0",
2572 bifp
->proto
.restr_val1
[1] ? bifp
->proto
.restr_val1
[1] : "0",
2573 bifp
->proto
.restr_val1
[2] ? bifp
->proto
.restr_val1
[2] : "0");
2574 fprintf (init_file
, " /* restr_val2 */\t{%s, %s, %s},\n",
2575 bifp
->proto
.restr_val2
[0] ? bifp
->proto
.restr_val2
[0] : "0",
2576 bifp
->proto
.restr_val2
[1] ? bifp
->proto
.restr_val2
[1] : "0",
2577 bifp
->proto
.restr_val2
[2] ? bifp
->proto
.restr_val2
[2] : "0");
2578 fprintf (init_file
, " /* attr_string */\t\"%s\",\n",
2579 (bifp
->kind
== FNK_CONST
? "= const"
2580 : (bifp
->kind
== FNK_PURE
? "= pure"
2581 : (bifp
->kind
== FNK_FPMATH
? "= fp, const"
2583 fprintf (init_file
, " /* assoc_bif */\tRS6000_BIF_%s%s\n",
2584 bifp
->attrs
.ismmaint
? bifp
->idname
: "NONE",
2585 bifp
->attrs
.ismmaint
? "_INTERNAL" : "");
2586 fprintf (init_file
, " },\n");
2588 fprintf (init_file
, " };\n\n");
2591 /* Write the decls and initializers for rs6000_overload_info[] and
2592 rs6000_instance_info[]. */
2594 write_ovld_static_init (void)
2597 "ovldrecord rs6000_overload_info[RS6000_OVLD_MAX "
2598 "- RS6000_OVLD_NONE] =\n");
2599 fprintf (init_file
, " {\n");
2600 fprintf (init_file
, " { /* RS6000_OVLD_NONE: */\n");
2601 fprintf (init_file
, " \"\", NULL\n");
2602 fprintf (init_file
, " },\n");
2603 for (int i
= 0; i
<= curr_ovld_stanza
; i
++)
2605 fprintf (init_file
, " { /* RS6000_OVLD_%s: */\n",
2606 ovld_stanzas
[i
].stanza_id
);
2607 fprintf (init_file
, " /* ovld_name */\t\"%s\",\n",
2608 ovld_stanzas
[i
].intern_name
);
2609 /* First-instance must currently be instantiated at run time. */
2610 fprintf (init_file
, " /* first_instance */\tNULL\n");
2611 fprintf (init_file
, " },\n");
2613 fprintf (init_file
, " };\n\n");
2615 fprintf (init_file
, "ovlddata rs6000_instance_info[RS6000_INST_MAX] =\n");
2616 fprintf (init_file
, " {\n");
2617 fprintf (init_file
, " { /* RS6000_INST_NONE: */\n");
2618 fprintf (init_file
, " \"\", RS6000_BIF_NONE, NULL_TREE, NULL\n");
2619 fprintf (init_file
, " },\n");
2620 for (int i
= 0; i
<= curr_ovld
; i
++)
2622 fprintf (init_file
, " { /* RS6000_INST_%s: */\n",
2623 ovlds
[i
].ovld_id_name
);
2624 fprintf (init_file
, " /* bifname */\t\"%s\",\n",
2625 ovlds
[i
].proto
.bifname
);
2626 fprintf (init_file
, " /* bifid */\tRS6000_BIF_%s,\n",
2627 ovlds
[i
].bif_id_name
);
2628 /* Type must be instantiated at run time. */
2629 fprintf (init_file
, " /* fntype */\t0,\n");
2630 fprintf (init_file
, " /* next */\t");
2632 && !strcmp (ovlds
[i
+1].proto
.bifname
, ovlds
[i
].proto
.bifname
))
2634 "&rs6000_instance_info[RS6000_INST_%s]\n",
2635 ovlds
[i
+1].ovld_id_name
);
2637 fprintf (init_file
, "NULL\n");
2638 fprintf (init_file
, " },\n");
2640 fprintf (init_file
, " };\n\n");
2643 /* Write code to initialize the built-in function table. */
2645 write_init_bif_table (void)
2647 for (int i
= 0; i
<= curr_bif
; i
++)
2650 " rs6000_builtin_info[RS6000_BIF_%s].fntype"
2652 bifs
[i
].idname
, bifs
[i
].fndecl
);
2654 /* Check whether we have a "tf" token in this string, representing
2655 a float128_type_node. It's possible that float128_type_node is
2656 undefined (occurs for -maltivec -mno-vsx, for example), so we
2657 must guard against that. */
2658 int tf_found
= strstr (bifs
[i
].fndecl
, "tf") != NULL
;
2660 /* Similarly, look for decimal float tokens. */
2661 int dfp_found
= (strstr (bifs
[i
].fndecl
, "sd") != NULL
2662 || strstr (bifs
[i
].fndecl
, "dd") != NULL
2663 || strstr (bifs
[i
].fndecl
, "td") != NULL
);
2667 fprintf (init_file
, " if (float128_type_node)\n");
2668 fprintf (init_file
, " {\n");
2672 fprintf (init_file
, " if (dfloat64_type_node)\n");
2673 fprintf (init_file
, " {\n");
2677 " rs6000_builtin_decls[(int)RS6000_BIF_%s] = t\n",
2680 " = add_builtin_function (\"%s\",\n",
2681 bifs
[i
].proto
.bifname
);
2686 " (int)RS6000_BIF_%s,"
2690 " NULL, NULL_TREE);\n");
2691 if (bifs
[i
].kind
== FNK_CONST
)
2693 fprintf (init_file
, " TREE_READONLY (t) = 1;\n");
2694 fprintf (init_file
, " TREE_NOTHROW (t) = 1;\n");
2696 else if (bifs
[i
].kind
== FNK_PURE
)
2698 fprintf (init_file
, " DECL_PURE_P (t) = 1;\n");
2699 fprintf (init_file
, " TREE_NOTHROW (t) = 1;\n");
2701 else if (bifs
[i
].kind
== FNK_FPMATH
)
2703 fprintf (init_file
, " TREE_NOTHROW (t) = 1;\n");
2704 fprintf (init_file
, " if (flag_rounding_math)\n");
2705 fprintf (init_file
, " {\n");
2706 fprintf (init_file
, " DECL_PURE_P (t) = 1;\n");
2707 fprintf (init_file
, " DECL_IS_NOVOPS (t) = 1;\n");
2708 fprintf (init_file
, " }\n");
2709 fprintf (init_file
, " else\n");
2710 fprintf (init_file
, " TREE_READONLY (t) = 1;\n");
2713 if (tf_found
|| dfp_found
)
2715 fprintf (init_file
, " }\n");
2716 fprintf (init_file
, " else\n");
2717 fprintf (init_file
, " {\n");
2718 fprintf (init_file
, " rs6000_builtin_decls"
2719 "[(int)RS6000_BIF_%s] = NULL_TREE;\n", bifs
[i
].idname
);
2720 fprintf (init_file
, " }\n");
2722 fprintf (init_file
, "\n");
2726 /* Write code to initialize the overload table. */
2728 write_init_ovld_table (void)
2730 fprintf (init_file
, " int base = RS6000_OVLD_NONE;\n\n");
2732 " /* The fndecl for an overload is arbitrarily the first one\n"
2733 " for the overload. We sort out the real types when\n"
2734 " processing the overload in the gcc front end. */\n");
2736 for (int i
= 0; i
<= curr_ovld
; i
++)
2739 " rs6000_instance_info[RS6000_INST_%s].fntype"
2741 ovlds
[i
].ovld_id_name
, ovlds
[i
].fndecl
);
2743 if (i
== 0 || ovlds
[i
].stanza
!= ovlds
[i
-1].stanza
)
2745 ovld_stanza
*stanza
= &ovld_stanzas
[ovlds
[i
].stanza
];
2746 fprintf (init_file
, "\n");
2748 /* Check whether we have a "tf" token in this string, representing
2749 a float128_type_node. It's possible that float128_type_node is
2750 undefined (occurs for -maltivec -mno-vsx, for example), so we
2751 must guard against that. */
2752 int tf_found
= strstr (ovlds
[i
].fndecl
, "tf") != NULL
;
2754 /* Similarly, look for decimal float tokens. */
2755 int dfp_found
= (strstr (ovlds
[i
].fndecl
, "sd") != NULL
2756 || strstr (ovlds
[i
].fndecl
, "dd") != NULL
2757 || strstr (ovlds
[i
].fndecl
, "td") != NULL
);
2761 fprintf (init_file
, " if (float128_type_node)\n");
2762 fprintf (init_file
, " {\n");
2766 fprintf (init_file
, " if (dfloat64_type_node)\n");
2767 fprintf (init_file
, " {\n");
2771 " rs6000_builtin_decls[(int)RS6000_OVLD_%s] = t\n",
2774 " = add_builtin_function (\"%s\",\n",
2775 stanza
->intern_name
);
2780 " (int)RS6000_OVLD_%s,"
2784 " NULL, NULL_TREE);\n");
2786 if (tf_found
|| dfp_found
)
2787 fprintf (init_file
, " }\n");
2789 fprintf (init_file
, "\n");
2792 " rs6000_overload_info[RS6000_OVLD_%s - base]"
2793 ".first_instance\n",
2796 " = &rs6000_instance_info[RS6000_INST_%s];\n\n",
2797 ovlds
[i
].ovld_id_name
);
2802 /* Write everything to the initialization file (rs6000-builtins.cc).
2803 Return 1 if successful, 0 otherwise. */
2805 write_init_file (void)
2807 write_autogenerated_header (init_file
);
2809 fprintf (init_file
, "#include \"config.h\"\n");
2810 fprintf (init_file
, "#include \"system.h\"\n");
2811 fprintf (init_file
, "#include \"coretypes.h\"\n");
2812 fprintf (init_file
, "#include \"backend.h\"\n");
2813 fprintf (init_file
, "#include \"rtl.h\"\n");
2814 fprintf (init_file
, "#include \"tree.h\"\n");
2815 fprintf (init_file
, "#include \"langhooks.h\"\n");
2816 fprintf (init_file
, "#include \"insn-codes.h\"\n");
2817 fprintf (init_file
, "#include \"rs6000-builtins.h\"\n");
2818 fprintf (init_file
, "\n");
2820 fprintf (init_file
, "tree rs6000_builtin_decls[RS6000_OVLD_MAX];\n\n");
2822 write_bif_static_init ();
2823 write_ovld_static_init ();
2825 fprintf (init_file
, "void\n");
2826 fprintf (init_file
, "rs6000_init_generated_builtins ()\n");
2827 fprintf (init_file
, "{\n");
2828 fprintf (init_file
, " tree t;\n");
2829 rbt_inorder_callback (&fntype_rbt
, fntype_rbt
.rbt_root
, write_fntype_init
);
2830 fprintf (init_file
, "\n");
2833 " rs6000_builtin_decls[RS6000_BIF_NONE] = NULL_TREE;\n");
2835 " rs6000_builtin_decls[RS6000_BIF_MAX] = NULL_TREE;\n");
2837 " rs6000_builtin_decls[RS6000_OVLD_NONE] = NULL_TREE;\n\n");
2839 write_init_bif_table ();
2840 write_init_ovld_table ();
2842 fprintf (init_file
, "}\n\n");
2847 /* Write everything to the include file (rs6000-vecdefines.h).
2848 Return 1 if successful, 0 otherwise. */
2850 write_defines_file (void)
2852 fprintf (defines_file
, "#ifndef _RS6000_VECDEFINES_H\n");
2853 fprintf (defines_file
, "#define _RS6000_VECDEFINES_H 1\n\n");
2854 fprintf (defines_file
, "#if defined(_ARCH_PPC64) && defined (_ARCH_PWR9)\n");
2855 fprintf (defines_file
, " #define _ARCH_PPC64_PWR9 1\n");
2856 fprintf (defines_file
, "#endif\n\n");
2857 for (int i
= 0; i
< num_ovld_stanzas
; i
++)
2858 if (strcmp (ovld_stanzas
[i
].extern_name
, "SKIP"))
2860 if (ovld_stanzas
[i
].ifdef
)
2861 fprintf (defines_file
, "#ifdef %s\n", ovld_stanzas
[i
].ifdef
);
2862 fprintf (defines_file
, "#define %s %s\n",
2863 ovld_stanzas
[i
].extern_name
,
2864 ovld_stanzas
[i
].intern_name
);
2865 if (ovld_stanzas
[i
].ifdef
)
2866 fprintf (defines_file
, "#endif\n");
2868 fprintf (defines_file
, "\n#endif\n");
2872 /* Close and delete output files after any failure, so that subsequent
2873 build dependencies will fail. */
2875 delete_output_files (void)
2877 /* Depending on whence we're called, some of these may already be
2878 closed. Don't check for errors. */
2879 fclose (header_file
);
2881 fclose (defines_file
);
2883 remove (header_path
);
2885 remove (defines_path
);
2888 /* Main program to convert flat files into built-in initialization code. */
2890 main (int argc
, const char **argv
)
2895 "Five arguments required: two input files and three output "
2902 ovld_path
= argv
[2];
2903 header_path
= argv
[3];
2904 init_path
= argv
[4];
2905 defines_path
= argv
[5];
2907 bif_file
= fopen (bif_path
, "r");
2910 fprintf (stderr
, "Cannot open input built-in file '%s'.\n", bif_path
);
2913 ovld_file
= fopen (ovld_path
, "r");
2916 fprintf (stderr
, "Cannot open input overload file '%s'.\n", ovld_path
);
2919 header_file
= fopen (header_path
, "w");
2922 fprintf (stderr
, "Cannot open header file '%s' for output.\n",
2926 init_file
= fopen (init_path
, "w");
2929 fprintf (stderr
, "Cannot open init file '%s' for output.\n", init_path
);
2932 defines_file
= fopen (defines_path
, "w");
2935 fprintf (stderr
, "Cannot open defines file '%s' for output.\n",
2940 /* Allocate some buffers. */
2941 for (int i
= 0; i
< MAXLINES
; i
++)
2942 lines
[i
] = (char *) malloc (LINELEN
);
2944 /* Initialize the balanced trees containing built-in function ids,
2945 overload function ids, and function type declaration ids. */
2947 rbt_new (&ovld_rbt
);
2948 rbt_new (&fntype_rbt
);
2950 /* Initialize another balanced tree that contains a map from built-in
2951 function ids to the order in which they were encountered. */
2952 rbt_new (&bifo_rbt
);
2954 /* Parse the built-in function file. */
2957 if (parse_bif () == PC_PARSEFAIL
)
2959 fprintf (stderr
, "Parsing of '%s' failed, aborting.\n", bif_path
);
2960 delete_output_files ();
2965 /* Create a mapping from function IDs in their final order to
2966 the order they appear in the built-in function file. */
2967 create_bif_order ();
2970 fprintf (stderr
, "\nFunction ID list:\n");
2971 rbt_dump (&bif_rbt
, bif_rbt
.rbt_root
);
2972 fprintf (stderr
, "\n");
2975 /* Parse the overload file. */
2976 num_ovld_stanzas
= 0;
2979 if (parse_ovld () == PC_PARSEFAIL
)
2981 fprintf (stderr
, "Parsing of '%s' failed, aborting.\n", ovld_path
);
2982 delete_output_files ();
2988 fprintf (stderr
, "\nFunction type decl list:\n");
2989 rbt_dump (&fntype_rbt
, fntype_rbt
.rbt_root
);
2990 fprintf (stderr
, "\n");
2993 /* Write the header file and the file containing initialization code. */
2994 if (!write_header_file ())
2996 fprintf (stderr
, "Output to '%s' failed, aborting.\n", header_path
);
2997 delete_output_files ();
3000 if (!write_init_file ())
3002 fprintf (stderr
, "Output to '%s' failed, aborting.\n", init_path
);
3003 delete_output_files ();
3007 /* Write the defines file to be included into altivec.h. */
3008 if (!write_defines_file ())
3010 fprintf (stderr
, "Output to '%s' failed, aborting.\n", defines_path
);
3011 delete_output_files ();
3015 /* Always close init_file last. This avoids race conditions in the
3016 build machinery. See comments in t-rs6000. */
3017 fclose (header_file
);
3018 fclose (defines_file
);