adding GNU dc ("desk calculator")
[unix-history] / gnu / usr.bin / gcc1 / cc1 / genconfig.c
CommitLineData
15637ed4
RG
1/* Generate from machine description:
2
3 - some #define configuration flags.
4 Copyright (C) 1987 Free Software Foundation, Inc.
5
6This file is part of GNU CC.
7
8GNU CC is free software; you can redistribute it and/or modify
9it under the terms of the GNU General Public License as published by
10the Free Software Foundation; either version 1, or (at your option)
11any later version.
12
13GNU CC is distributed in the hope that it will be useful,
14but WITHOUT ANY WARRANTY; without even the implied warranty of
15MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16GNU General Public License for more details.
17
18You should have received a copy of the GNU General Public License
19along with GNU CC; see the file COPYING. If not, write to
20the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
21
22
23#include <stdio.h>
24#include "config.h"
25#include "rtl.h"
26#include "obstack.h"
27
28struct obstack obstack;
29struct obstack *rtl_obstack = &obstack;
30
31#define obstack_chunk_alloc xmalloc
32#define obstack_chunk_free free
33extern int xmalloc ();
34extern void free ();
35
36/* flags to determine output of machine description dependent #define's. */
37int max_recog_operands_flag;
38int max_dup_operands_flag;
39int max_clobbers_per_insn_flag;
40int register_constraint_flag;
41
42int clobbers_seen_this_insn;
43int dup_operands_seen_this_insn;
44
45void fatal ();
46void fancy_abort ();
47
48void
49walk_insn_part (part)
50 rtx part;
51{
52 register int i, j;
53 register RTX_CODE code;
54 register char *format_ptr;
55
56 if (part == 0)
57 return;
58
59 code = GET_CODE (part);
60 switch (code)
61 {
62 case CLOBBER:
63 clobbers_seen_this_insn++;
64 break;
65
66 case MATCH_OPERAND:
67 if (XINT (part, 0) > max_recog_operands_flag)
68 max_recog_operands_flag = XINT (part, 0);
69 if (XSTR (part, 2) && *XSTR (part, 2))
70 register_constraint_flag = 1;
71 return;
72
73 case MATCH_OPERATOR:
74 if (XINT (part, 0) > max_recog_operands_flag)
75 max_recog_operands_flag = XINT (part, 0);
76 /* Now scan the rtl'x in the vector inside the match_operator. */
77 break;
78
79 case LABEL_REF:
80 if (GET_CODE (XEXP (part, 0)) == MATCH_OPERAND)
81 break;
82 return;
83
84 case MATCH_DUP:
85 ++dup_operands_seen_this_insn;
86 if (XINT (part, 0) > max_recog_operands_flag)
87 max_recog_operands_flag = XINT (part, 0);
88
89 case REG: case CONST_INT: case SYMBOL_REF:
90 case PC: case CC0:
91 return;
92 }
93
94 format_ptr = GET_RTX_FORMAT (GET_CODE (part));
95
96 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
97 switch (*format_ptr++)
98 {
99 case 'e':
100 case 'u':
101 walk_insn_part (XEXP (part, i));
102 break;
103 case 'E':
104 if (XVEC (part, i) != NULL)
105 for (j = 0; j < XVECLEN (part, i); j++)
106 walk_insn_part (XVECEXP (part, i, j));
107 break;
108 }
109}
110
111void
112gen_insn (insn)
113 rtx insn;
114{
115 int i;
116
117 /* Walk the insn pattern to gather the #define's status. */
118 clobbers_seen_this_insn = 0;
119 dup_operands_seen_this_insn = 0;
120 if (XVEC (insn, 1) != 0)
121 for (i = 0; i < XVECLEN (insn, 1); i++)
122 walk_insn_part (XVECEXP (insn, 1, i));
123
124 if (clobbers_seen_this_insn > max_clobbers_per_insn_flag)
125 max_clobbers_per_insn_flag = clobbers_seen_this_insn;
126 if (dup_operands_seen_this_insn > max_dup_operands_flag)
127 max_dup_operands_flag = dup_operands_seen_this_insn;
128}
129
130/* Similar but scan a define_expand. */
131
132void
133gen_expand (insn)
134 rtx insn;
135{
136 int i;
137
138 /* Walk the insn pattern to gather the #define's status. */
139
140 /* Note that we don't bother recording the number of MATCH_DUPs
141 that occur in a gen_expand, because only reload cares about that. */
142 if (XVEC (insn, 1) != 0)
143 for (i = 0; i < XVECLEN (insn, 1); i++)
144 {
145 /* Compute the maximum SETs and CLOBBERS
146 in any one of the sub-insns;
147 don't sum across all of them. */
148 clobbers_seen_this_insn = 0;
149
150 walk_insn_part (XVECEXP (insn, 1, i));
151
152 if (clobbers_seen_this_insn > max_clobbers_per_insn_flag)
153 max_clobbers_per_insn_flag = clobbers_seen_this_insn;
154 }
155}
156
157void
158gen_peephole (peep)
159 rtx peep;
160{
161 int i;
162
163 /* Look through the patterns that are matched
164 to compute the maximum operand number. */
165 for (i = 0; i < XVECLEN (peep, 0); i++)
166 walk_insn_part (XVECEXP (peep, 0, i));
167}
168\f
169int
170xmalloc (size)
171{
172 register int val = malloc (size);
173
174 if (val == 0)
175 fatal ("virtual memory exhausted");
176
177 return val;
178}
179
180int
181xrealloc (ptr, size)
182 char *ptr;
183 int size;
184{
185 int result = realloc (ptr, size);
186 if (!result)
187 fatal ("virtual memory exhausted");
188 return result;
189}
190
191void
192fatal (s, a1, a2)
193 char *s;
194{
195 fprintf (stderr, "genconfig: ");
196 fprintf (stderr, s, a1, a2);
197 fprintf (stderr, "\n");
198 exit (FATAL_EXIT_CODE);
199}
200
201/* More 'friendly' abort that prints the line and file.
202 config.h can #define abort fancy_abort if you like that sort of thing. */
203
204void
205fancy_abort ()
206{
207 fatal ("Internal gcc abort.");
208}
209\f
210int
211main (argc, argv)
212 int argc;
213 char **argv;
214{
215 rtx desc;
216 FILE *infile;
217 extern rtx read_rtx ();
218 register int c;
219
220 obstack_init (rtl_obstack);
221
222 if (argc <= 1)
223 fatal ("No input file name.");
224
225 infile = fopen (argv[1], "r");
226 if (infile == 0)
227 {
228 perror (argv[1]);
229 exit (FATAL_EXIT_CODE);
230 }
231
232 init_rtl ();
233
234 printf ("/* Generated automatically by the program `genconfig'\n\
235from the machine description file `md'. */\n\n");
236
237 /* Read the machine description. */
238
239 while (1)
240 {
241 c = read_skip_spaces (infile);
242 if (c == EOF)
243 break;
244 ungetc (c, infile);
245
246 desc = read_rtx (infile);
247 if (GET_CODE (desc) == DEFINE_INSN)
248 gen_insn (desc);
249 if (GET_CODE (desc) == DEFINE_EXPAND)
250 gen_expand (desc);
251 if (GET_CODE (desc) == DEFINE_PEEPHOLE)
252 gen_peephole (desc);
253 }
254
255 /* 3 more than needed for this md file, for the sake of asm constructs. */
256 printf ("\n#define MAX_RECOG_OPERANDS %d\n", max_recog_operands_flag + 4);
257
258 if (max_dup_operands_flag == 0)
259 max_dup_operands_flag = 1;
260 printf ("\n#define MAX_DUP_OPERANDS %d\n", max_dup_operands_flag);
261
262 if (register_constraint_flag)
263 printf ("#define REGISTER_CONSTRAINTS\n");
264
265 fflush (stdout);
266 exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
267}