xref: /dflybsd-src/contrib/gcc-4.7/gcc/genconfig.c (revision 04febcfb30580676d3e95f58a16c5137ee478b32)
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