|
|
1.1 root 1: /* Generate from machine description:
2:
3: - some #define configuration flags.
4: Copyright (C) 1987, 1991 Free Software Foundation, Inc.
5:
6: This file is part of GNU CC.
7:
8: GNU CC is free software; you can redistribute it and/or modify
9: it under the terms of the GNU General Public License as published by
10: the Free Software Foundation; either version 2, or (at your option)
11: any later version.
12:
13: GNU CC is distributed in the hope that it will be useful,
14: but WITHOUT ANY WARRANTY; without even the implied warranty of
15: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16: GNU General Public License for more details.
17:
18: You should have received a copy of the GNU General Public License
19: along with GNU CC; see the file COPYING. If not, write to
1.1.1.5 ! root 20: the Free Software Foundation, 59 Temple Place - Suite 330,
! 21: Boston, MA 02111-1307, USA. */
1.1 root 22:
23:
24: #include <stdio.h>
1.1.1.3 root 25: #include "hconfig.h"
1.1 root 26: #include "rtl.h"
27: #include "obstack.h"
28:
29: static struct obstack obstack;
30: struct obstack *rtl_obstack = &obstack;
31:
32: #define obstack_chunk_alloc xmalloc
33: #define obstack_chunk_free free
34:
35: extern void free ();
1.1.1.2 root 36: extern rtx read_rtx ();
1.1 root 37:
38: /* flags to determine output of machine description dependent #define's. */
1.1.1.2 root 39: static int max_recog_operands; /* Largest operand number seen. */
40: static int max_dup_operands; /* Largest number of match_dup in any insn. */
1.1 root 41: static int max_clobbers_per_insn;
42: static int register_constraint_flag;
43: static int have_cc0_flag;
1.1.1.3 root 44: static int have_cmove_flag;
1.1 root 45: static int have_lo_sum_flag;
46:
47: /* Maximum number of insns seen in a split. */
48: static int max_insns_per_split = 1;
49:
50: static int clobbers_seen_this_insn;
51: static int dup_operands_seen_this_insn;
52:
53: char *xmalloc ();
54: static void fatal ();
55: void fancy_abort ();
56:
57: /* RECOG_P will be non-zero if this pattern was seen in a context where it will
1.1.1.3 root 58: be used to recognize, rather than just generate an insn.
59:
60: NON_PC_SET_SRC will be non-zero if this pattern was seen in a SET_SRC
61: of a SET whose destination is not (pc). */
1.1 root 62:
63: static void
1.1.1.3 root 64: walk_insn_part (part, recog_p, non_pc_set_src)
1.1 root 65: rtx part;
1.1.1.3 root 66: int recog_p;
67: int non_pc_set_src;
1.1 root 68: {
69: register int i, j;
70: register RTX_CODE code;
71: register char *format_ptr;
72:
73: if (part == 0)
74: return;
75:
76: code = GET_CODE (part);
77: switch (code)
78: {
79: case CLOBBER:
80: clobbers_seen_this_insn++;
81: break;
82:
83: case MATCH_OPERAND:
84: if (XINT (part, 0) > max_recog_operands)
85: max_recog_operands = XINT (part, 0);
86: if (XSTR (part, 2) && *XSTR (part, 2))
87: register_constraint_flag = 1;
88: return;
89:
90: case MATCH_OP_DUP:
1.1.1.3 root 91: case MATCH_PAR_DUP:
1.1 root 92: ++dup_operands_seen_this_insn;
93: case MATCH_SCRATCH:
94: case MATCH_PARALLEL:
95: case MATCH_OPERATOR:
96: if (XINT (part, 0) > max_recog_operands)
97: max_recog_operands = XINT (part, 0);
98: /* Now scan the rtl's in the vector inside the MATCH_OPERATOR or
99: MATCH_PARALLEL. */
100: break;
101:
102: case LABEL_REF:
103: if (GET_CODE (XEXP (part, 0)) == MATCH_OPERAND)
104: break;
105: return;
106:
107: case MATCH_DUP:
108: ++dup_operands_seen_this_insn;
109: if (XINT (part, 0) > max_recog_operands)
110: max_recog_operands = XINT (part, 0);
111: return;
112:
113: case CC0:
114: if (recog_p)
115: have_cc0_flag = 1;
116: return;
117:
118: case LO_SUM:
119: if (recog_p)
120: have_lo_sum_flag = 1;
121: return;
122:
1.1.1.3 root 123: case SET:
124: walk_insn_part (SET_DEST (part), 0, recog_p);
125: walk_insn_part (SET_SRC (part), recog_p,
126: GET_CODE (SET_DEST (part)) != PC);
127: return;
128:
129: case IF_THEN_ELSE:
130: /* Only consider this machine as having a conditional move if the
131: two arms of the IF_THEN_ELSE are both MATCH_OPERAND. Otherwise,
132: we have some specific IF_THEN_ELSE construct (like the doz
133: instruction on the RS/6000) that can't be used in the general
134: context we want it for. */
135:
136: if (recog_p && non_pc_set_src
137: && GET_CODE (XEXP (part, 1)) == MATCH_OPERAND
138: && GET_CODE (XEXP (part, 2)) == MATCH_OPERAND)
139: have_cmove_flag = 1;
140: break;
141:
1.1 root 142: case REG: case CONST_INT: case SYMBOL_REF:
143: case PC:
144: return;
145: }
146:
147: format_ptr = GET_RTX_FORMAT (GET_CODE (part));
148:
149: for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
150: switch (*format_ptr++)
151: {
152: case 'e':
153: case 'u':
1.1.1.3 root 154: walk_insn_part (XEXP (part, i), recog_p, non_pc_set_src);
1.1 root 155: break;
156: case 'E':
157: if (XVEC (part, i) != NULL)
158: for (j = 0; j < XVECLEN (part, i); j++)
1.1.1.3 root 159: walk_insn_part (XVECEXP (part, i, j), recog_p, non_pc_set_src);
1.1 root 160: break;
161: }
162: }
163:
164: static void
165: gen_insn (insn)
166: rtx insn;
167: {
168: int i;
169:
170: /* Walk the insn pattern to gather the #define's status. */
171: clobbers_seen_this_insn = 0;
172: dup_operands_seen_this_insn = 0;
173: if (XVEC (insn, 1) != 0)
174: for (i = 0; i < XVECLEN (insn, 1); i++)
1.1.1.3 root 175: walk_insn_part (XVECEXP (insn, 1, i), 1, 0);
1.1 root 176:
177: if (clobbers_seen_this_insn > max_clobbers_per_insn)
178: max_clobbers_per_insn = clobbers_seen_this_insn;
179: if (dup_operands_seen_this_insn > max_dup_operands)
180: max_dup_operands = dup_operands_seen_this_insn;
181: }
182:
183: /* Similar but scan a define_expand. */
184:
185: static void
186: gen_expand (insn)
187: rtx insn;
188: {
189: int i;
190:
191: /* Walk the insn pattern to gather the #define's status. */
192:
193: /* Note that we don't bother recording the number of MATCH_DUPs
194: that occur in a gen_expand, because only reload cares about that. */
195: if (XVEC (insn, 1) != 0)
196: for (i = 0; i < XVECLEN (insn, 1); i++)
197: {
198: /* Compute the maximum SETs and CLOBBERS
199: in any one of the sub-insns;
200: don't sum across all of them. */
201: clobbers_seen_this_insn = 0;
202:
1.1.1.3 root 203: walk_insn_part (XVECEXP (insn, 1, i), 0, 0);
1.1 root 204:
205: if (clobbers_seen_this_insn > max_clobbers_per_insn)
206: max_clobbers_per_insn = clobbers_seen_this_insn;
207: }
208: }
209:
210: /* Similar but scan a define_split. */
211:
212: static void
213: gen_split (split)
214: rtx split;
215: {
216: int i;
217:
218: /* Look through the patterns that are matched
219: to compute the maximum operand number. */
220: for (i = 0; i < XVECLEN (split, 0); i++)
1.1.1.3 root 221: walk_insn_part (XVECEXP (split, 0, i), 1, 0);
1.1 root 222: /* Look at the number of insns this insn could split into. */
223: if (XVECLEN (split, 2) > max_insns_per_split)
224: max_insns_per_split = XVECLEN (split, 2);
225: }
226:
227: static void
228: gen_peephole (peep)
229: rtx peep;
230: {
231: int i;
232:
233: /* Look through the patterns that are matched
234: to compute the maximum operand number. */
235: for (i = 0; i < XVECLEN (peep, 0); i++)
1.1.1.3 root 236: walk_insn_part (XVECEXP (peep, 0, i), 1, 0);
1.1 root 237: }
238:
239: char *
240: xmalloc (size)
241: unsigned size;
242: {
243: register char *val = (char *) malloc (size);
244:
245: if (val == 0)
246: fatal ("virtual memory exhausted");
247:
248: return val;
249: }
250:
251: char *
252: xrealloc (ptr, size)
253: char *ptr;
254: unsigned size;
255: {
256: char *result = (char *) realloc (ptr, size);
257: if (!result)
258: fatal ("virtual memory exhausted");
259: return result;
260: }
261:
262: static void
263: fatal (s, a1, a2)
264: char *s;
265: {
266: fprintf (stderr, "genconfig: ");
267: fprintf (stderr, s, a1, a2);
268: fprintf (stderr, "\n");
269: exit (FATAL_EXIT_CODE);
270: }
271:
272: /* More 'friendly' abort that prints the line and file.
273: config.h can #define abort fancy_abort if you like that sort of thing. */
274:
275: void
276: fancy_abort ()
277: {
278: fatal ("Internal gcc abort.");
279: }
280:
281: int
282: main (argc, argv)
283: int argc;
284: char **argv;
285: {
286: rtx desc;
287: FILE *infile;
288: register int c;
289:
290: obstack_init (rtl_obstack);
291:
292: if (argc <= 1)
293: fatal ("No input file name.");
294:
295: infile = fopen (argv[1], "r");
296: if (infile == 0)
297: {
298: perror (argv[1]);
299: exit (FATAL_EXIT_CODE);
300: }
301:
302: init_rtl ();
303:
304: printf ("/* Generated automatically by the program `genconfig'\n\
305: from the machine description file `md'. */\n\n");
306:
307: /* Allow at least 10 operands for the sake of asm constructs. */
1.1.1.2 root 308: max_recog_operands = 9; /* We will add 1 later. */
1.1 root 309: max_dup_operands = 1;
310:
311: /* Read the machine description. */
312:
313: while (1)
314: {
315: c = read_skip_spaces (infile);
316: if (c == EOF)
317: break;
318: ungetc (c, infile);
319:
320: desc = read_rtx (infile);
321: if (GET_CODE (desc) == DEFINE_INSN)
322: gen_insn (desc);
323: if (GET_CODE (desc) == DEFINE_EXPAND)
324: gen_expand (desc);
325: if (GET_CODE (desc) == DEFINE_SPLIT)
326: gen_split (desc);
327: if (GET_CODE (desc) == DEFINE_PEEPHOLE)
328: gen_peephole (desc);
329: }
330:
1.1.1.2 root 331: printf ("\n#define MAX_RECOG_OPERANDS %d\n", max_recog_operands + 1);
1.1 root 332:
333: printf ("\n#define MAX_DUP_OPERANDS %d\n", max_dup_operands);
334:
335: /* This is conditionally defined, in case the user writes code which emits
336: more splits than we can readily see (and knows s/he does it). */
337: printf ("#ifndef MAX_INSNS_PER_SPLIT\n#define MAX_INSNS_PER_SPLIT %d\n#endif\n",
338: max_insns_per_split);
339:
340: if (register_constraint_flag)
341: printf ("#define REGISTER_CONSTRAINTS\n");
342:
343: if (have_cc0_flag)
344: printf ("#define HAVE_cc0\n");
345:
1.1.1.3 root 346: if (have_cmove_flag)
1.1.1.5 ! root 347: printf ("#define HAVE_conditional_move\n");
1.1.1.3 root 348:
1.1 root 349: if (have_lo_sum_flag)
350: printf ("#define HAVE_lo_sum\n");
351:
352: fflush (stdout);
353: exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
354: /* NOTREACHED */
355: return 0;
356: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.