]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/genopinit.c
Make argv const char ** in read_md_files etc
[thirdparty/gcc.git] / gcc / genopinit.c
CommitLineData
af9e4a0c 1/* Generate code to initialize optabs from machine description.
818ab71a 2 Copyright (C) 1993-2016 Free Software Foundation, Inc.
af9e4a0c 3
1322177d 4This file is part of GCC.
af9e4a0c 5
1322177d
LB
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
9dcd6f09 8Software Foundation; either version 3, or (at your option) any later
1322177d 9version.
af9e4a0c 10
1322177d
LB
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
af9e4a0c
RK
15
16You should have received a copy of the GNU General Public License
9dcd6f09
NC
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
af9e4a0c
RK
19
20
4977bab6 21#include "bconfig.h"
0b93b64e 22#include "system.h"
4977bab6
ZW
23#include "coretypes.h"
24#include "tm.h"
af9e4a0c 25#include "rtl.h"
f8b6598e 26#include "errors.h"
c88c0d42 27#include "gensupport.h"
ccd043a9 28
af9e4a0c 29
cd1440b1 30#define DEF_RTL_EXPR(V, N, X, C) #V,
af9e4a0c 31
cd1440b1
RH
32static const char * const rtx_upname[] = {
33#include "rtl.def"
34};
35
36#undef DEF_RTL_EXPR
37
cd1440b1 38/* Vector in which to collect insns that match. */
886456e2 39static vec<optab_pattern> patterns;
56c0e996 40
af9e4a0c 41static void
5d2d3e43 42gen_insn (md_rtx_info *info)
af9e4a0c 43{
886456e2
RS
44 optab_pattern p;
45 if (find_optab (&p, XSTR (info->def, 0)))
46 patterns.safe_push (p);
cd1440b1 47}
af9e4a0c 48
cd1440b1
RH
49static int
50pattern_cmp (const void *va, const void *vb)
51{
886456e2
RS
52 const optab_pattern *a = (const optab_pattern *)va;
53 const optab_pattern *b = (const optab_pattern *)vb;
cd1440b1
RH
54 return a->sort_num - b->sort_num;
55}
af9e4a0c 56
cd1440b1
RH
57static int
58optab_kind_cmp (const void *va, const void *vb)
59{
60 const optab_def *a = (const optab_def *)va;
61 const optab_def *b = (const optab_def *)vb;
62 int diff = a->kind - b->kind;
63 if (diff == 0)
64 diff = a->op - b->op;
65 return diff;
66}
af9e4a0c 67
cd1440b1
RH
68static int
69optab_rcode_cmp (const void *va, const void *vb)
70{
71 const optab_def *a = (const optab_def *)va;
72 const optab_def *b = (const optab_def *)vb;
73 return a->rcode - b->rcode;
74}
af9e4a0c 75
cd1440b1
RH
76static const char *header_file_name = "init-opinit.h";
77static const char *source_file_name = "init-opinit.c";
af9e4a0c 78
cd1440b1
RH
79static bool
80handle_arg (const char *arg)
81{
82 switch (arg[1])
af9e4a0c 83 {
cd1440b1
RH
84 case 'h':
85 header_file_name = &arg[2];
86 return true;
87 case 'c':
88 source_file_name = &arg[2];
89 return true;
90 default:
91 return false;
af9e4a0c 92 }
af9e4a0c 93}
af9e4a0c 94
cd1440b1
RH
95static FILE *
96open_outfile (const char *file_name)
97{
98 FILE *f = fopen (file_name, "w");
99 if (!f)
100 fatal ("cannot open file %s: %s", file_name, xstrerror (errno));
101 fprintf (f,
102 "/* Generated automatically by the program `genopinit'\n"
103 " from the machine description file `md'. */\n\n");
104 return f;
105}
c1b59dce 106
af9e4a0c 107int
66b0fe8f 108main (int argc, const char **argv)
af9e4a0c 109{
cd1440b1
RH
110 FILE *h_file, *s_file;
111 unsigned int i, j, n, last_kind[5];
886456e2 112 optab_pattern *p;
af9e4a0c 113
f8b6598e 114 progname = "genopinit";
af9e4a0c 115
cd1440b1
RH
116 if (NUM_OPTABS > 0xffff || MAX_MACHINE_MODE >= 0xff)
117 fatal ("genopinit range assumptions invalid");
118
119 if (!init_rtx_reader_args_cb (argc, argv, handle_arg))
c88c0d42 120 return (FATAL_EXIT_CODE);
af9e4a0c 121
cd1440b1
RH
122 h_file = open_outfile (header_file_name);
123 s_file = open_outfile (source_file_name);
dcc3fcf2 124
af9e4a0c 125 /* Read the machine description. */
5d2d3e43
RS
126 md_rtx_info info;
127 while (read_md_rtx (&info))
128 switch (GET_CODE (info.def))
129 {
130 case DEFINE_INSN:
131 case DEFINE_EXPAND:
132 gen_insn (&info);
af9e4a0c 133 break;
5d2d3e43
RS
134
135 default:
136 break;
137 }
af9e4a0c 138
cd1440b1 139 /* Sort the collected patterns. */
75509ba2 140 patterns.qsort (pattern_cmp);
cd1440b1
RH
141
142 /* Now that we've handled the "extra" patterns, eliminate them from
143 the optabs array. That way they don't get in the way below. */
886456e2 144 n = num_optabs;
cd1440b1
RH
145 for (i = 0; i < n; )
146 if (optabs[i].base == NULL)
147 optabs[i] = optabs[--n];
148 else
149 ++i;
150
151 /* Sort the (real) optabs. Better than forcing the optabs.def file to
152 remain sorted by kind. We also scrogged any real ordering with the
153 purging of the X patterns above. */
c3284718 154 qsort (optabs, n, sizeof (optab_def), optab_kind_cmp);
cd1440b1 155
385399a8
RS
156 fprintf (h_file, "#ifndef GCC_INSN_OPINIT_H\n");
157 fprintf (h_file, "#define GCC_INSN_OPINIT_H 1\n");
158
cd1440b1
RH
159 /* Emit the optab enumeration for the header file. */
160 fprintf (h_file, "enum optab_tag {\n");
161 for (i = j = 0; i < n; ++i)
162 {
163 optabs[i].op = i;
164 fprintf (h_file, " %s,\n", optabs[i].name);
165 if (optabs[i].kind != j)
166 last_kind[j++] = i - 1;
167 }
168 fprintf (h_file, " FIRST_CONV_OPTAB = %s,\n", optabs[last_kind[0]+1].name);
169 fprintf (h_file, " LAST_CONVLIB_OPTAB = %s,\n", optabs[last_kind[1]].name);
170 fprintf (h_file, " LAST_CONV_OPTAB = %s,\n", optabs[last_kind[2]].name);
171 fprintf (h_file, " FIRST_NORM_OPTAB = %s,\n", optabs[last_kind[2]+1].name);
172 fprintf (h_file, " LAST_NORMLIB_OPTAB = %s,\n", optabs[last_kind[3]].name);
173 fprintf (h_file, " LAST_NORM_OPTAB = %s\n", optabs[i-1].name);
174 fprintf (h_file, "};\n\n");
175
176 fprintf (h_file, "#define NUM_OPTABS %u\n", n);
177 fprintf (h_file, "#define NUM_CONVLIB_OPTABS %u\n",
178 last_kind[1] - last_kind[0]);
179 fprintf (h_file, "#define NUM_NORMLIB_OPTABS %u\n",
180 last_kind[3] - last_kind[2]);
181 fprintf (h_file, "#define NUM_OPTAB_PATTERNS %u\n",
9771b263 182 (unsigned) patterns.length ());
cd1440b1 183
b0710fe1
AM
184 fprintf (h_file,
185 "typedef enum optab_tag optab;\n"
186 "typedef enum optab_tag convert_optab;\n"
187 "typedef enum optab_tag direct_optab;\n"
188 "\n"
189 "struct optab_libcall_d\n"
190 "{\n"
191 " char libcall_suffix;\n"
192 " const char *libcall_basename;\n"
193 " void (*libcall_gen) (optab, const char *name,\n"
194 " char suffix, machine_mode);\n"
195 "};\n"
196 "\n"
197 "struct convert_optab_libcall_d\n"
198 "{\n"
199 " const char *libcall_basename;\n"
200 " void (*libcall_gen) (convert_optab, const char *name,\n"
201 " machine_mode, machine_mode);\n"
202 "};\n"
203 "\n"
204 "/* Given an enum insn_code, access the function to construct\n"
205 " the body of that kind of insn. */\n"
206 "#define GEN_FCN(CODE) (insn_data[CODE].genfun)\n"
207 "\n"
385399a8 208 "#ifdef NUM_RTX_CODE\n"
b0710fe1
AM
209 "/* Contains the optab used for each rtx code, and vice-versa. */\n"
210 "extern const optab code_to_optab_[NUM_RTX_CODE];\n"
211 "extern const enum rtx_code optab_to_code_[NUM_OPTABS];\n"
212 "\n"
213 "static inline optab\n"
214 "code_to_optab (enum rtx_code code)\n"
215 "{\n"
216 " return code_to_optab_[code];\n"
217 "}\n"
218 "\n"
219 "static inline enum rtx_code\n"
220 "optab_to_code (optab op)\n"
221 "{\n"
222 " return optab_to_code_[op];\n"
223 "}\n"
385399a8 224 "#endif\n"
b0710fe1
AM
225 "\n"
226 "extern const struct convert_optab_libcall_d convlib_def[NUM_CONVLIB_OPTABS];\n"
227 "extern const struct optab_libcall_d normlib_def[NUM_NORMLIB_OPTABS];\n"
228 "\n"
229 "/* Returns the active icode for the given (encoded) optab. */\n"
230 "extern enum insn_code raw_optab_handler (unsigned);\n"
231 "extern bool swap_optab_enable (optab, machine_mode, bool);\n"
232 "\n"
233 "/* Target-dependent globals. */\n"
234 "struct target_optabs {\n"
235 " /* Patterns that are used by optabs that are enabled for this target. */\n"
236 " bool pat_enable[NUM_OPTAB_PATTERNS];\n"
237 "};\n"
238 "extern void init_all_optabs (struct target_optabs *);\n"
239 "\n"
240 "extern struct target_optabs default_target_optabs;\n"
241 "extern struct target_optabs *this_fn_optabs;\n"
242 "#if SWITCHABLE_TARGET\n"
243 "extern struct target_optabs *this_target_optabs;\n"
244 "#else\n"
245 "#define this_target_optabs (&default_target_optabs)\n"
246 "#endif\n");
247
cd1440b1
RH
248 fprintf (s_file,
249 "#include \"config.h\"\n"
250 "#include \"system.h\"\n"
251 "#include \"coretypes.h\"\n"
c7131fb2 252 "#include \"backend.h\"\n"
9fdcd34e 253 "#include \"predict.h\"\n"
4d648807 254 "#include \"tree.h\"\n"
c7131fb2
AM
255 "#include \"rtl.h\"\n"
256 "#include \"alias.h\"\n"
d8a2d370
DN
257 "#include \"varasm.h\"\n"
258 "#include \"stor-layout.h\"\n"
259 "#include \"calls.h\"\n"
cd1440b1
RH
260 "#include \"tm_p.h\"\n"
261 "#include \"flags.h\"\n"
262 "#include \"insn-config.h\"\n"
36566b39
PK
263 "#include \"expmed.h\"\n"
264 "#include \"dojump.h\"\n"
265 "#include \"explow.h\"\n"
266 "#include \"emit-rtl.h\"\n"
267 "#include \"stmt.h\"\n"
cd1440b1 268 "#include \"expr.h\"\n"
b0710fe1 269 "#include \"insn-codes.h\"\n"
cd1440b1
RH
270 "#include \"optabs.h\"\n"
271 "\n"
272 "struct optab_pat {\n"
273 " unsigned scode;\n"
274 " enum insn_code icode;\n"
275 "};\n\n");
276
277 fprintf (s_file,
278 "static const struct optab_pat pats[NUM_OPTAB_PATTERNS] = {\n");
9771b263 279 for (i = 0; patterns.iterate (i, &p); ++i)
cd1440b1
RH
280 fprintf (s_file, " { %#08x, CODE_FOR_%s },\n", p->sort_num, p->name);
281 fprintf (s_file, "};\n\n");
282
135204dd
AH
283 fprintf (s_file, "void\ninit_all_optabs (struct target_optabs *optabs)\n{\n");
284 fprintf (s_file, " bool *ena = optabs->pat_enable;\n");
9771b263 285 for (i = 0; patterns.iterate (i, &p); ++i)
cd1440b1
RH
286 fprintf (s_file, " ena[%u] = HAVE_%s;\n", i, p->name);
287 fprintf (s_file, "}\n\n");
288
289 /* Perform a binary search on a pre-encoded optab+mode*2. */
290 /* ??? Perhaps even better to generate a minimal perfect hash.
291 Using gperf directly is awkward since it's so geared to working
292 with strings. Plus we have no visibility into the ordering of
293 the hash entries, which complicates the pat_enable array. */
294 fprintf (s_file,
295 "static int\n"
296 "lookup_handler (unsigned scode)\n"
297 "{\n"
298 " int l = 0, h = ARRAY_SIZE (pats), m;\n"
299 " while (h > l)\n"
300 " {\n"
301 " m = (h + l) / 2;\n"
302 " if (scode == pats[m].scode)\n"
303 " return m;\n"
304 " else if (scode < pats[m].scode)\n"
305 " h = m;\n"
306 " else\n"
307 " l = m + 1;\n"
308 " }\n"
309 " return -1;\n"
310 "}\n\n");
311
312 fprintf (s_file,
313 "enum insn_code\n"
314 "raw_optab_handler (unsigned scode)\n"
315 "{\n"
316 " int i = lookup_handler (scode);\n"
135204dd 317 " return (i >= 0 && this_fn_optabs->pat_enable[i]\n"
cd1440b1
RH
318 " ? pats[i].icode : CODE_FOR_nothing);\n"
319 "}\n\n");
320
321 fprintf (s_file,
322 "bool\n"
ef4bddc2 323 "swap_optab_enable (optab op, machine_mode m, bool set)\n"
cd1440b1
RH
324 "{\n"
325 " unsigned scode = (op << 16) | m;\n"
326 " int i = lookup_handler (scode);\n"
327 " if (i >= 0)\n"
328 " {\n"
135204dd
AH
329 " bool ret = this_fn_optabs->pat_enable[i];\n"
330 " this_fn_optabs->pat_enable[i] = set;\n"
cd1440b1
RH
331 " return ret;\n"
332 " }\n"
333 " else\n"
334 " {\n"
335 " gcc_assert (!set);\n"
336 " return false;\n"
337 " }\n"
338 "}\n\n");
339
340 /* C++ (even G++) does not support (non-trivial) designated initializers.
341 To work around that, generate these arrays programatically rather than
342 by our traditional multiple inclusion of def files. */
343
344 fprintf (s_file,
345 "const struct convert_optab_libcall_d "
346 "convlib_def[NUM_CONVLIB_OPTABS] = {\n");
347 for (i = last_kind[0] + 1; i <= last_kind[1]; ++i)
348 fprintf (s_file, " { %s, %s },\n", optabs[i].base, optabs[i].libcall);
349 fprintf (s_file, "};\n\n");
350
351 fprintf (s_file,
352 "const struct optab_libcall_d "
353 "normlib_def[NUM_NORMLIB_OPTABS] = {\n");
354 for (i = last_kind[2] + 1; i <= last_kind[3]; ++i)
355 fprintf (s_file, " { %s, %s, %s },\n",
356 optabs[i].suffix, optabs[i].base, optabs[i].libcall);
357 fprintf (s_file, "};\n\n");
358
359 fprintf (s_file, "enum rtx_code const optab_to_code_[NUM_OPTABS] = {\n");
360 for (i = 0; i < n; ++i)
361 fprintf (s_file, " %s,\n", rtx_upname[optabs[i].fcode]);
362 fprintf (s_file, "};\n\n");
363
364 qsort (optabs, n, sizeof (optab_def), optab_rcode_cmp);
365
366 fprintf (s_file, "const optab code_to_optab_[NUM_RTX_CODE] = {\n");
367 for (j = 0; optabs[j].rcode == UNKNOWN; ++j)
368 continue;
369 for (i = 0; i < NON_GENERATOR_NUM_RTX_CODE; ++i)
370 {
371 if (j < n && optabs[j].rcode == i)
372 fprintf (s_file, " %s,\n", optabs[j++].name);
373 else
374 fprintf (s_file, " unknown_optab,\n");
375 }
376 fprintf (s_file, "};\n\n");
377
385399a8 378 fprintf (h_file, "#endif\n");
cd1440b1
RH
379 return (fclose (h_file) == 0 && fclose (s_file) == 0
380 ? SUCCESS_EXIT_CODE : FATAL_EXIT_CODE);
af9e4a0c 381}