genconfig.c revision 169690
1139969Simp/* Generate from machine description:
21556Srgrimes   - some #define configuration flags.
31556Srgrimes   Copyright (C) 1987, 1991, 1997, 1998, 1999, 2000, 2003, 2004
41556Srgrimes   Free Software Foundation, Inc.
51556Srgrimes
61556SrgrimesThis file is part of GCC.
71556Srgrimes
81556SrgrimesGCC is free software; you can redistribute it and/or modify it under
91556Srgrimesthe terms of the GNU General Public License as published by the Free
101556SrgrimesSoftware Foundation; either version 2, or (at your option) any later
111556Srgrimesversion.
121556Srgrimes
131556SrgrimesGCC is distributed in the hope that it will be useful, but WITHOUT ANY
141556SrgrimesWARRANTY; without even the implied warranty of MERCHANTABILITY or
151556SrgrimesFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
161556Srgrimesfor more details.
171556Srgrimes
181556SrgrimesYou should have received a copy of the GNU General Public License
191556Srgrimesalong with GCC; see the file COPYING.  If not, write to the Free
201556SrgrimesSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
211556Srgrimes02110-1301, USA.  */
221556Srgrimes
231556Srgrimes
241556Srgrimes#include "bconfig.h"
251556Srgrimes#include "system.h"
261556Srgrimes#include "coretypes.h"
271556Srgrimes#include "tm.h"
281556Srgrimes#include "rtl.h"
291556Srgrimes#include "errors.h"
301556Srgrimes#include "gensupport.h"
311556Srgrimes
321556Srgrimes
33114433Sobrien/* flags to determine output of machine description dependent #define's.  */
341556Srgrimesstatic int max_recog_operands;  /* Largest operand number seen.  */
3520420Sstevestatic int max_dup_operands;    /* Largest number of match_dup in any insn.  */
361556Srgrimesstatic int max_clobbers_per_insn;
371556Srgrimesstatic int have_cc0_flag;
381556Srgrimesstatic int have_cmove_flag;
391556Srgrimesstatic int have_cond_exec_flag;
401556Srgrimesstatic int have_lo_sum_flag;
4136049Scharnierstatic int have_peephole_flag;
42114433Sobrienstatic int have_peephole2_flag;
4336049Scharnier
4492974Sobrien/* Maximum number of insns seen in a split.  */
4592974Sobrienstatic int max_insns_per_split = 1;
461556Srgrimes
47149790Scsjp/* Maximum number of input insns for peephole2.  */
48149790Scsjpstatic int max_insns_per_peep2;
491556Srgrimes
501556Srgrimesstatic int clobbers_seen_this_insn;
511556Srgrimesstatic int dup_operands_seen_this_insn;
521556Srgrimes
5331664Seivindstatic void walk_insn_part (rtx, int, int);
541556Srgrimesstatic void gen_insn (rtx);
551556Srgrimesstatic void gen_expand (rtx);
561556Srgrimesstatic void gen_split (rtx);
571556Srgrimesstatic void gen_peephole (rtx);
5890644Simpstatic void gen_peephole2 (rtx);
5977409Simp
6096806Sjmallett/* RECOG_P will be nonzero if this pattern was seen in a context where it will
6190644Simp   be used to recognize, rather than just generate an insn.
621556Srgrimes
631556Srgrimes   NON_PC_SET_SRC will be nonzero if this pattern was seen in a SET_SRC
641556Srgrimes   of a SET whose destination is not (pc).  */
6550544Smharo
661556Srgrimesstatic void
671556Srgrimeswalk_insn_part (rtx part, int recog_p, int non_pc_set_src)
68174935Sdds{
69174935Sdds  int i, j;
70174935Sdds  RTX_CODE code;
71239951Sjhb  const char *format_ptr;
721556Srgrimes
73180604Sdelphij  if (part == 0)
74180604Sdelphij    return;
75180604Sdelphij
76180604Sdelphij  code = GET_CODE (part);
77196841Strasz  switch (code)
78196841Strasz    {
791556Srgrimes    case CLOBBER:
801556Srgrimes      clobbers_seen_this_insn++;
8190110Simp      break;
821556Srgrimes
8391085Smarkm    case MATCH_OPERAND:
8491085Smarkm      if (XINT (part, 0) > max_recog_operands)
8590114Simp	max_recog_operands = XINT (part, 0);
861556Srgrimes      return;
871556Srgrimes
8877409Simp    case MATCH_OP_DUP:
891556Srgrimes    case MATCH_PAR_DUP:
90239951Sjhb      ++dup_operands_seen_this_insn;
911556Srgrimes    case MATCH_SCRATCH:
92239951Sjhb    case MATCH_PARALLEL:
93239951Sjhb    case MATCH_OPERATOR:
94239951Sjhb      if (XINT (part, 0) > max_recog_operands)
951556Srgrimes	max_recog_operands = XINT (part, 0);
9614154Swosch      /* Now scan the rtl's in the vector inside the MATCH_OPERATOR or
9792935Sobrien	 MATCH_PARALLEL.  */
981556Srgrimes      break;
991556Srgrimes
1001556Srgrimes    case LABEL_REF:
10192935Sobrien      if (GET_CODE (XEXP (part, 0)) == MATCH_OPERAND
1021556Srgrimes	  || GET_CODE (XEXP (part, 0)) == MATCH_DUP)
10392935Sobrien	break;
10492935Sobrien      return;
10592935Sobrien
10692935Sobrien    case MATCH_DUP:
10750544Smharo      ++dup_operands_seen_this_insn;
10850544Smharo      if (XINT (part, 0) > max_recog_operands)
10950544Smharo	max_recog_operands = XINT (part, 0);
1101556Srgrimes      return;
1111556Srgrimes
1121556Srgrimes    case CC0:
11314305Swosch      if (recog_p)
1141556Srgrimes	have_cc0_flag = 1;
1151556Srgrimes      return;
1161556Srgrimes
1171556Srgrimes    case LO_SUM:
1181556Srgrimes      if (recog_p)
1191556Srgrimes	have_lo_sum_flag = 1;
1201556Srgrimes      return;
1211556Srgrimes
1221556Srgrimes    case SET:
1231556Srgrimes      walk_insn_part (SET_DEST (part), 0, recog_p);
1241556Srgrimes      walk_insn_part (SET_SRC (part), recog_p,
125284916Sjilles		      GET_CODE (SET_DEST (part)) != PC);
1261556Srgrimes      return;
1271556Srgrimes
1281556Srgrimes    case IF_THEN_ELSE:
129239951Sjhb      /* Only consider this machine as having a conditional move if the
130239951Sjhb	 two arms of the IF_THEN_ELSE are both MATCH_OPERAND.  Otherwise,
131239951Sjhb	 we have some specific IF_THEN_ELSE construct (like the doz
132239951Sjhb	 instruction on the RS/6000) that can't be used in the general
133239951Sjhb	 context we want it for.  */
134239951Sjhb
135239951Sjhb      if (recog_p && non_pc_set_src
136239951Sjhb	  && GET_CODE (XEXP (part, 1)) == MATCH_OPERAND
137239951Sjhb	  && GET_CODE (XEXP (part, 2)) == MATCH_OPERAND)
138239951Sjhb	have_cmove_flag = 1;
139239951Sjhb      break;
1401556Srgrimes
14136785Simp    case COND_EXEC:
14236785Simp      if (recog_p)
1431556Srgrimes	have_cond_exec_flag = 1;
1441556Srgrimes      break;
1451556Srgrimes
14636383Ssteve    case REG: case CONST_INT: case SYMBOL_REF:
14736383Ssteve    case PC:
14836383Ssteve      return;
14936383Ssteve
1501556Srgrimes    default:
15111298Sbde      break;
15211298Sbde    }
15311298Sbde
15411298Sbde  format_ptr = GET_RTX_FORMAT (GET_CODE (part));
15511298Sbde
15611298Sbde  for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
15711298Sbde    switch (*format_ptr++)
15811298Sbde      {
15911298Sbde      case 'e':
16011298Sbde      case 'u':
16177409Simp	walk_insn_part (XEXP (part, i), recog_p, non_pc_set_src);
1621556Srgrimes	break;
1631556Srgrimes      case 'E':
1641556Srgrimes	if (XVEC (part, i) != NULL)
16576878Skris	  for (j = 0; j < XVECLEN (part, i); j++)
1661556Srgrimes	    walk_insn_part (XVECEXP (part, i, j), recog_p, non_pc_set_src);
1671556Srgrimes	break;
1681556Srgrimes      }
1691556Srgrimes}
1701556Srgrimes
1711556Srgrimesstatic void
1721556Srgrimesgen_insn (rtx insn)
173180604Sdelphij{
174180604Sdelphij  int i;
1751556Srgrimes
1761556Srgrimes  /* Walk the insn pattern to gather the #define's status.  */
17729933Swosch  clobbers_seen_this_insn = 0;
1781556Srgrimes  dup_operands_seen_this_insn = 0;
1791556Srgrimes  if (XVEC (insn, 1) != 0)
1801556Srgrimes    for (i = 0; i < XVECLEN (insn, 1); i++)
1811556Srgrimes      walk_insn_part (XVECEXP (insn, 1, i), 1, 0);
1821556Srgrimes
1831556Srgrimes  if (clobbers_seen_this_insn > max_clobbers_per_insn)
1841556Srgrimes    max_clobbers_per_insn = clobbers_seen_this_insn;
1851556Srgrimes  if (dup_operands_seen_this_insn > max_dup_operands)
18614166Swosch    max_dup_operands = dup_operands_seen_this_insn;
18714166Swosch}
18814166Swosch
18914305Swosch/* Similar but scan a define_expand.  */
19014305Swosch
19114166Swoschstatic void
19230106Swoschgen_expand (rtx insn)
19330106Swosch{
1941556Srgrimes  int i;
19592935Sobrien
19692935Sobrien  /* Walk the insn pattern to gather the #define's status.  */
19792935Sobrien
19892935Sobrien  /* Note that we don't bother recording the number of MATCH_DUPs
19992935Sobrien     that occur in a gen_expand, because only reload cares about that.  */
20030106Swosch  if (XVEC (insn, 1) != 0)
2011556Srgrimes    for (i = 0; i < XVECLEN (insn, 1); i++)
202243072Seadler      {
2031556Srgrimes	/* Compute the maximum SETs and CLOBBERS
20430106Swosch	   in any one of the sub-insns;
2051556Srgrimes	   don't sum across all of them.  */
20676878Skris	clobbers_seen_this_insn = 0;
20776878Skris
2081556Srgrimes	walk_insn_part (XVECEXP (insn, 1, i), 0, 0);
2091556Srgrimes
2101556Srgrimes	if (clobbers_seen_this_insn > max_clobbers_per_insn)
21129933Swosch	  max_clobbers_per_insn = clobbers_seen_this_insn;
21229933Swosch      }
21329933Swosch}
21430106Swosch
21530106Swosch/* Similar but scan a define_split.  */
2161556Srgrimes
21730106Swoschstatic void
2181556Srgrimesgen_split (rtx split)
2191556Srgrimes{
220174935Sdds  int i;
221174935Sdds
222174935Sdds  /* Look through the patterns that are matched
223174935Sdds     to compute the maximum operand number.  */
224174935Sdds  for (i = 0; i < XVECLEN (split, 0); i++)
22550544Smharo    walk_insn_part (XVECEXP (split, 0, i), 1, 0);
22650544Smharo  /* Look at the number of insns this insn could split into.  */
22750544Smharo  if (XVECLEN (split, 2) > max_insns_per_split)
2281556Srgrimes    max_insns_per_split = XVECLEN (split, 2);
22950544Smharo}
2301556Srgrimes
23131664Seivindstatic void
23231664Seivindgen_peephole (rtx peep)
23377409Simp{
23431664Seivind  int i;
235127272Spjd
236127272Spjd  /* Look through the patterns that are matched
237127272Spjd     to compute the maximum operand number.  */
238127272Spjd  for (i = 0; i < XVECLEN (peep, 0); i++)
239127272Spjd    walk_insn_part (XVECEXP (peep, 0, i), 1, 0);
240127272Spjd}
24131664Seivind
24231664Seivindstatic void
243127272Spjdgen_peephole2 (rtx peep)
244127272Spjd{
245127272Spjd  int i, n;
246174935Sdds
247127272Spjd  /* Look through the patterns that are matched
248127272Spjd     to compute the maximum operand number.  */
249127272Spjd  for (i = XVECLEN (peep, 0) - 1; i >= 0; --i)
250127272Spjd    walk_insn_part (XVECEXP (peep, 0, i), 1, 0);
251127272Spjd
252127272Spjd  /* Look at the number of insns this insn can be matched from.  */
253127272Spjd  for (i = XVECLEN (peep, 0) - 1, n = 0; i >= 0; --i)
25431664Seivind    if (GET_CODE (XVECEXP (peep, 0, i)) != MATCH_DUP
25531664Seivind	&& GET_CODE (XVECEXP (peep, 0, i)) != MATCH_SCRATCH)
2561556Srgrimes      n++;
2571556Srgrimes  if (n > max_insns_per_peep2)
2581556Srgrimes    max_insns_per_peep2 = n;
2591556Srgrimes}
2601556Srgrimes
2611556Srgrimesint
2621556Srgrimesmain (int argc, char **argv)
2631556Srgrimes{
2641556Srgrimes  rtx desc;
26562963Sdwmalone
2661556Srgrimes  progname = "genconfig";
2671556Srgrimes
2681556Srgrimes  if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
2691556Srgrimes    return (FATAL_EXIT_CODE);
2701556Srgrimes
2711556Srgrimes  puts ("/* Generated automatically by the program `genconfig'");
2721556Srgrimes  puts ("   from the machine description file `md'.  */\n");
273180604Sdelphij  puts ("#ifndef GCC_INSN_CONFIG_H");
274180604Sdelphij  puts ("#define GCC_INSN_CONFIG_H\n");
2751556Srgrimes
276277645Sjilles  /* Allow at least 30 operands for the sake of asm constructs.  */
277225954Sivoras  /* ??? We *really* ought to reorganize things such that there
278225954Sivoras     is no fixed upper bound.  */
27923525Sguido  max_recog_operands = 29;  /* We will add 1 later.  */
28090114Simp  max_dup_operands = 1;
281268129Sdelphij
2821556Srgrimes  /* Read the machine description.  */
2831556Srgrimes
284225954Sivoras  while (1)
2851556Srgrimes    {
2861556Srgrimes      int line_no, insn_code_number = 0;
287225954Sivoras
288225954Sivoras      desc = read_md_rtx (&line_no, &insn_code_number);
289225954Sivoras      if (desc == NULL)
29023525Sguido	break;
29123525Sguido
29223525Sguido      switch (GET_CODE (desc))
29323525Sguido	{
29423525Sguido  	  case DEFINE_INSN:
295225954Sivoras	    gen_insn (desc);
2961556Srgrimes	    break;
2971556Srgrimes
2981556Srgrimes	  case DEFINE_EXPAND:
29976878Skris	    gen_expand (desc);
30076878Skris	    break;
301225954Sivoras
3021556Srgrimes	  case DEFINE_SPLIT:
3031556Srgrimes	    gen_split (desc);
3041556Srgrimes	    break;
305225954Sivoras
3061556Srgrimes	  case DEFINE_PEEPHOLE2:
3071556Srgrimes	    have_peephole2_flag = 1;
3081556Srgrimes	    gen_peephole2 (desc);
3091556Srgrimes	    break;
3101556Srgrimes
3111556Srgrimes	  case DEFINE_PEEPHOLE:
3121556Srgrimes	    have_peephole_flag = 1;
31323525Sguido	    gen_peephole (desc);
31423525Sguido	    break;
31537245Sbde
31637245Sbde	  default:
31723525Sguido	    break;
31823525Sguido	}
31923525Sguido    }
32023525Sguido
32123525Sguido  printf ("#define MAX_RECOG_OPERANDS %d\n", max_recog_operands + 1);
32223525Sguido  printf ("#define MAX_DUP_OPERANDS %d\n", max_dup_operands);
32323525Sguido
324196841Strasz  /* This is conditionally defined, in case the user writes code which emits
325196841Strasz     more splits than we can readily see (and knows s/he does it).  */
326149790Scsjp  printf ("#ifndef MAX_INSNS_PER_SPLIT\n");
327149790Scsjp  printf ("#define MAX_INSNS_PER_SPLIT %d\n", max_insns_per_split);
328174935Sdds  printf ("#endif\n");
329149790Scsjp
330149790Scsjp  if (have_cc0_flag)
331196841Strasz    {
332149790Scsjp      printf ("#define HAVE_cc0 1\n");
33363680Ssada      printf ("#define CC0_P(X) ((X) == cc0_rtx)\n");
33463680Ssada    }
33563680Ssada  else
33663680Ssada    {
33763680Ssada      /* We output CC0_P this way to make sure that X is declared
33863680Ssada	 somewhere.  */
33963680Ssada      printf ("#define CC0_P(X) ((X) ? 0 : 0)\n");
340268129Sdelphij    }
341268129Sdelphij
342268129Sdelphij  if (have_cmove_flag)
343268129Sdelphij    printf ("#define HAVE_conditional_move 1\n");
344268129Sdelphij
345268129Sdelphij  if (have_cond_exec_flag)
346268129Sdelphij    printf ("#define HAVE_conditional_execution 1\n");
347268129Sdelphij
348268129Sdelphij  if (have_lo_sum_flag)
349268129Sdelphij    printf ("#define HAVE_lo_sum 1\n");
350268129Sdelphij
351268129Sdelphij  if (have_peephole_flag)
3521556Srgrimes    printf ("#define HAVE_peephole 1\n");
353277645Sjilles
354277645Sjilles  if (have_peephole2_flag)
355280386Sjilles    {
3561556Srgrimes      printf ("#define HAVE_peephole2 1\n");
3571556Srgrimes      printf ("#define MAX_INSNS_PER_PEEP2 %d\n", max_insns_per_peep2);
3581556Srgrimes    }
3591556Srgrimes
3601556Srgrimes  puts("\n#endif /* GCC_INSN_CONFIG_H */");
3611556Srgrimes
3621556Srgrimes  if (ferror (stdout) || fflush (stdout) || fclose (stdout))
3631556Srgrimes    return FATAL_EXIT_CODE;
3641556Srgrimes
3651556Srgrimes  return SUCCESS_EXIT_CODE;
3661556Srgrimes}
36750544Smharo