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