]> gcc.gnu.org Git - gcc.git/blame - gcc/gengenrtl.c
reload.c: PROTO -> PARAMS.
[gcc.git] / gcc / gengenrtl.c
CommitLineData
3b80f6ca 1/* Generate code to allocate RTL structures.
0133b7d9 2 Copyright (C) 1997, 1998, 1999 Free Software Foundation, Inc.
3b80f6ca
RH
3
4This file is part of GNU CC.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING. If not, write to
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
20
21
22#include "hconfig.h"
b04cd507 23#include "system.h"
3b80f6ca 24
3b80f6ca
RH
25#define NO_GENRTL_H
26#include "rtl.h"
987009bf 27#undef abort
3b80f6ca 28
aa0b4465
ZW
29#include "real.h"
30
31/* Calculate the format for CONST_DOUBLE. This depends on the relative
32 widths of HOST_WIDE_INT and REAL_VALUE_TYPE.
b6b4c6c6
RH
33
34 We need to go out to e0wwwww, since REAL_ARITHMETIC assumes 16-bits
35 per element in REAL_VALUE_TYPE.
36
37 This is duplicated in rtl.c.
38
aa0b4465
ZW
39 A number of places assume that there are always at least two 'w'
40 slots in a CONST_DOUBLE, so we provide them even if one would suffice. */
b6b4c6c6
RH
41
42#ifdef REAL_ARITHMETIC
43#if LONG_DOUBLE_TYPE_SIZE == 96
44#define REAL_WIDTH (11*8 + HOST_BITS_PER_WIDE_INT)/HOST_BITS_PER_WIDE_INT
45#elif LONG_DOUBLE_TYPE_SIZE == 128
46#define REAL_WIDTH (19*8 + HOST_BITS_PER_WIDE_INT)/HOST_BITS_PER_WIDE_INT
47#elif HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
48#define REAL_WIDTH (7*8 + HOST_BITS_PER_WIDE_INT)/HOST_BITS_PER_WIDE_INT
49#endif
50#endif /* REAL_ARITHMETIC */
51
52#ifndef REAL_WIDTH
53#if HOST_BITS_PER_WIDE_INT*2 >= LONG_DOUBLE_TYPE_SIZE
54#define REAL_WIDTH 2
55#elif HOST_BITS_PER_WIDE_INT*3 >= LONG_DOUBLE_TYPE_SIZE
56#define REAL_WIDTH 3
57#elif HOST_BITS_PER_WIDE_INT*4 >= LONG_DOUBLE_TYPE_SIZE
58#define REAL_WIDTH 4
59#endif
60#endif /* REAL_WIDTH */
61
62#if REAL_WIDTH == 1
aa0b4465 63#define CONST_DOUBLE_FORMAT "e0ww"
b6b4c6c6 64#elif REAL_WIDTH == 2
aa0b4465 65#define CONST_DOUBLE_FORMAT "e0ww"
b6b4c6c6 66#elif REAL_WIDTH == 3
aa0b4465 67#define CONST_DOUBLE_FORMAT "e0www"
b6b4c6c6 68#elif REAL_WIDTH == 4
aa0b4465 69#define CONST_DOUBLE_FORMAT "e0wwww"
b6b4c6c6
RH
70#elif REAL_WIDTH == 5
71#define CONST_DOUBLE_FORMAT "e0wwwww"
aa0b4465
ZW
72#else
73#define CONST_DOUBLE_FORMAT /* nothing - will cause syntax error */
74#endif
75
3b80f6ca
RH
76
77struct rtx_definition
78{
79 const char *enumname, *name, *format;
80};
81
d4ba0ead 82#define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS) { STRINGIFY(ENUM), NAME, FORMAT },
3b80f6ca
RH
83
84struct rtx_definition defs[] =
85{
86#include "rtl.def" /* rtl expressions are documented here */
87};
88
89const char *formats[NUM_RTX_CODE];
90
a94ae8f5
KG
91static const char *type_from_format PARAMS ((int));
92static const char *accessor_from_format PARAMS ((int));
93static int special_format PARAMS ((const char *));
94static int special_rtx PARAMS ((int));
95static void find_formats PARAMS ((void));
96static void gendecl PARAMS ((const char *));
97static void genmacro PARAMS ((int));
98static void gendef PARAMS ((const char *));
99static void genlegend PARAMS ((void));
100static void genheader PARAMS ((void));
101static void gencode PARAMS ((void));
c5c76735 102\f
0133b7d9
RH
103/* Decode a format letter into a C type string. */
104
3b80f6ca 105static const char *
982255c8 106type_from_format (c)
fd97443c 107 int c;
3b80f6ca
RH
108{
109 switch (c)
110 {
111 case 'i':
c5c76735
JL
112 return "int ";
113
3b80f6ca 114 case 'w':
c5c76735
JL
115 return "HOST_WIDE_INT ";
116
3b80f6ca
RH
117 case 's':
118 return "char *";
c5c76735
JL
119
120 case 'e': case 'u':
121 return "rtx ";
122
3b80f6ca 123 case 'E':
c5c76735 124 return "rtvec ";
0dfa1860 125 case 'b':
8f985ec4 126 return "struct bitmap_head_def *"; /* bitmap - typedef not available */
0dfa1860 127 case 't':
8f985ec4 128 return "union tree_node *"; /* tree - typedef not available */
3b80f6ca
RH
129 default:
130 abort ();
131 }
132}
133
0133b7d9
RH
134/* Decode a format letter into the proper accessor function. */
135
3b80f6ca 136static const char *
982255c8 137accessor_from_format (c)
fd97443c 138 int c;
3b80f6ca
RH
139{
140 switch (c)
141 {
142 case 'i':
143 return "XINT";
c5c76735 144
3b80f6ca
RH
145 case 'w':
146 return "XWINT";
c5c76735 147
3b80f6ca
RH
148 case 's':
149 return "XSTR";
c5c76735
JL
150
151 case 'e': case 'u':
3b80f6ca 152 return "XEXP";
c5c76735 153
3b80f6ca
RH
154 case 'E':
155 return "XVEC";
c5c76735 156
0dfa1860
MM
157 case 'b':
158 return "XBITMAP";
c5c76735 159
0dfa1860
MM
160 case 't':
161 return "XTREE";
c5c76735 162
3b80f6ca
RH
163 default:
164 abort ();
165 }
166}
167
c5c76735
JL
168/* Return nonzero if we should ignore FMT, an RTL format, when making
169 the list of formats we write routines to create. */
0133b7d9 170
3b80f6ca
RH
171static int
172special_format (fmt)
173 const char *fmt;
174{
175 return (strchr (fmt, '*') != 0
176 || strchr (fmt, 'V') != 0
177 || strchr (fmt, 'S') != 0
178 || strchr (fmt, 'n') != 0);
179}
180
c5c76735
JL
181/* Return nonzero if the RTL code given by index IDX is one that we should not
182 generate a gen_RTX_FOO function foo (because that function is present
183 elsewhere in the compiler. */
0133b7d9 184
3b80f6ca
RH
185static int
186special_rtx (idx)
187 int idx;
188{
189 return (strcmp (defs[idx].enumname, "CONST_INT") == 0
0133b7d9 190 || strcmp (defs[idx].enumname, "CONST_DOUBLE") == 0
41472af8
MM
191 || strcmp (defs[idx].enumname, "REG") == 0
192 || strcmp (defs[idx].enumname, "MEM") == 0);
3b80f6ca
RH
193}
194
c5c76735 195/* Place a list of all format specifiers we use into the array FORMAT. */
0133b7d9 196
3b80f6ca
RH
197static void
198find_formats ()
199{
200 int i;
201
c5c76735 202 for (i = 0; i < NUM_RTX_CODE; i++)
3b80f6ca
RH
203 {
204 const char **f;
205
206 if (special_format (defs[i].format))
207 continue;
208
c5c76735 209 for (f = formats; *f; f++)
0133b7d9 210 if (! strcmp (*f, defs[i].format))
3b80f6ca
RH
211 break;
212
c5c76735 213 if (*f == 0)
3b80f6ca
RH
214 *f = defs[i].format;
215 }
216}
217
c5c76735 218/* Write the declarations for the routine to allocate RTL with FORMAT. */
0133b7d9 219
3b80f6ca 220static void
c5c76735 221gendecl (format)
3b80f6ca
RH
222 const char *format;
223{
224 const char *p;
c5c76735 225 int i, pos;
3b80f6ca 226
a94ae8f5 227 printf ("extern rtx gen_rtx_fmt_%s\tPARAMS ((RTX_CODE, ", format);
c5c76735
JL
228 printf ("enum machine_mode mode");
229
230 /* Write each parameter that is needed and start a new line when the line
231 would overflow. */
232 for (p = format, i = 0, pos = 75; *p != 0; p++)
3b80f6ca 233 if (*p != '0')
c5c76735
JL
234 {
235 int ourlen = strlen (type_from_format (*p)) + 6 + (i > 9);
236
237 printf (",");
238 if (pos + ourlen > 76)
239 printf ("\n\t\t\t\t "), pos = 39;
240
241 printf (" %sarg%d", type_from_format (*p), i++);
242 pos += ourlen;
243 }
244
245 printf ("));\n");
3b80f6ca
RH
246}
247
c5c76735
JL
248/* Generate macros to generate RTL of code IDX using the functions we
249 write. */
0133b7d9 250
3b80f6ca 251static void
c5c76735 252genmacro (idx)
3b80f6ca
RH
253 int idx;
254{
255 const char *p;
256 int i;
257
c5c76735
JL
258 /* We write a macro that defines gen_rtx_RTLCODE to be an equivalent to
259 gen_rtx_fmt_FORMAT where FORMAT is the RTX_FORMAT of RTLCODE. */
3b80f6ca 260
c5c76735
JL
261 printf ("#define gen_rtx_%s%s(MODE",
262 special_rtx (idx) ? "raw_" : "", defs[idx].enumname);
263
264 for (p = defs[idx].format, i = 0; *p != 0; p++)
3b80f6ca 265 if (*p != '0')
c5c76735
JL
266 printf (", ARG%d", i++);
267
268 printf (") \\\n gen_rtx_fmt_%s (%s, (MODE)",
269 defs[idx].format, defs[idx].enumname);
3b80f6ca 270
c5c76735 271 for (p = defs[idx].format, i = 0; *p != 0; p++)
3b80f6ca 272 if (*p != '0')
c5c76735
JL
273 printf (", (ARG%d)", i++);
274
275 printf (")\n");
3b80f6ca
RH
276}
277
c5c76735
JL
278/* Generate the code for the function to generate RTL whose
279 format is FORMAT. */
0133b7d9 280
3b80f6ca 281static void
c5c76735 282gendef (format)
3b80f6ca
RH
283 const char *format;
284{
285 const char *p;
286 int i, j;
287
c5c76735
JL
288 /* Start by writing the definition of the function name and the types
289 of the arguments. */
3b80f6ca 290
c5c76735
JL
291 printf ("rtx\ngen_rtx_fmt_%s (code, mode", format);
292 for (p = format, i = 0; *p != 0; p++)
3b80f6ca 293 if (*p != '0')
c5c76735 294 printf (", arg%d", i++);
3b80f6ca 295
c5c76735
JL
296 printf (")\n RTX_CODE code;\n enum machine_mode mode;\n");
297 for (p = format, i = 0; *p != 0; p++)
298 if (*p != '0')
299 printf (" %sarg%d;\n", type_from_format (*p), i++);
300
301 /* Now write out the body of the function itself, which allocates
302 the memory and initializes it. */
303 printf ("{\n");
304 printf (" rtx rt;\n");
305 printf (" if (ggc_p)\n");
306 printf (" rt = ggc_alloc_rtx (%d);\n",
2168d24a 307 (int) strlen (format));
c5c76735
JL
308 printf (" else\n");
309 printf (" rt = obstack_alloc_rtx (sizeof (struct rtx_def) + %d * sizeof (rtunion));\n",
4b8140a6 310 (int) strlen (format) - 1);
3b80f6ca 311
c5c76735
JL
312 printf (" PUT_CODE (rt, code);\n");
313 printf (" PUT_MODE (rt, mode);\n");
3b80f6ca
RH
314
315 for (p = format, i = j = 0; *p ; ++p, ++i)
316 if (*p != '0')
c5c76735 317 printf (" %s (rt, %d) = arg%d;\n", accessor_from_format (*p), i, j++);
3b80f6ca 318
c5c76735 319 printf ("\n return rt;\n}\n\n");
3b80f6ca
RH
320}
321
c5c76735 322/* Generate the documentation header for files we write. */
0133b7d9 323
3b80f6ca 324static void
c5c76735 325genlegend ()
3b80f6ca 326{
c5c76735
JL
327 printf ("/* Generated automaticaly by the program `gengenrtl'\n");
328 printf (" from the RTL description file `rtl.def' */\n\n");
3b80f6ca
RH
329}
330
c5c76735 331/* Generate the text of the header file we make, genrtl.h. */
0133b7d9 332
3b80f6ca 333static void
c5c76735 334genheader ()
3b80f6ca
RH
335{
336 int i;
337 const char **fmt;
c5c76735 338
3b80f6ca 339 for (fmt = formats; *fmt; ++fmt)
c5c76735 340 gendecl (*fmt);
3b80f6ca 341
c5c76735 342 printf ("\n");
3b80f6ca
RH
343
344 for (i = 0; i < NUM_RTX_CODE; i++)
c5c76735
JL
345 if (! special_format (defs[i].format))
346 genmacro (i);
3b80f6ca
RH
347}
348
c5c76735 349/* Generate the text of the code file we write, genrtl.c. */
0133b7d9 350
3b80f6ca 351static void
c5c76735 352gencode ()
3b80f6ca
RH
353{
354 const char **fmt;
355
c5c76735
JL
356 puts ("#include \"config.h\"\n");
357 puts ("#include \"system.h\"\n");
358 puts ("#include \"obstack.h\"\n");
359 puts ("#include \"rtl.h\"\n");
360 puts ("#include \"ggc.h\"\n\n");
361 puts ("extern struct obstack *rtl_obstack;\n\n");
a94ae8f5 362 puts ("static rtx obstack_alloc_rtx PARAMS ((int length));\n");
c5c76735
JL
363 puts ("static rtx obstack_alloc_rtx (length)\n");
364 puts (" register int length;\n{\n");
365 puts (" rtx rt = (rtx) obstack_alloc (rtl_obstack, length);\n\n");
366 puts (" memset(rt, 0, sizeof(struct rtx_def) - sizeof(rtunion));\n\n");
367 puts (" return rt;\n}\n\n");
368
369 for (fmt = formats; *fmt != 0; fmt++)
370 gendef (*fmt);
3b80f6ca
RH
371}
372
402cdad5 373#if defined(USE_C_ALLOCA)
2778b98d 374PTR
982255c8 375xmalloc (nbytes)
2778b98d 376 size_t nbytes;
982255c8 377{
2778b98d 378 register PTR tmp = (PTR) malloc (nbytes);
982255c8
KG
379
380 if (!tmp)
381 {
402cdad5
RH
382 fprintf (stderr, "can't allocate %d bytes (out of virtual memory)\n",
383 nbytes);
982255c8
KG
384 exit (FATAL_EXIT_CODE);
385 }
386
387 return tmp;
388}
402cdad5 389#endif /* USE_C_ALLOCA */
982255c8 390
c5c76735
JL
391/* This is the main program. We accept only one argument, "-h", which
392 says we are writing the genrtl.h file. Otherwise we are writing the
393 genrtl.c file. */
a94ae8f5 394extern int main PARAMS ((int, char **));
c5c76735 395
3b80f6ca 396int
c5c76735 397main (argc, argv)
3b80f6ca
RH
398 int argc;
399 char **argv;
400{
3b80f6ca 401 find_formats ();
c5c76735 402 genlegend ();
3b80f6ca 403
c5c76735
JL
404 if (argc == 2 && argv[1][0] == '-' && argv[1][1] == 'h')
405 genheader ();
406 else
407 gencode ();
3b80f6ca 408
c5c76735 409 fflush (stdout);
c1b59dce 410 return (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
3b80f6ca 411}
This page took 0.701932 seconds and 5 git commands to generate.