xref: /netbsd-src/external/gpl3/gcc.old/dist/gcc/genconfig.c (revision 8feb0f0b7eaff0608f8350bbfa3098827b4bb91b)
11debfc3dSmrg /* Generate from machine description:
21debfc3dSmrg    - some #define configuration flags.
3*8feb0f0bSmrg    Copyright (C) 1987-2020 Free Software Foundation, Inc.
41debfc3dSmrg 
51debfc3dSmrg This file is part of GCC.
61debfc3dSmrg 
71debfc3dSmrg GCC is free software; you can redistribute it and/or modify it under
81debfc3dSmrg the terms of the GNU General Public License as published by the Free
91debfc3dSmrg Software Foundation; either version 3, or (at your option) any later
101debfc3dSmrg version.
111debfc3dSmrg 
121debfc3dSmrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY
131debfc3dSmrg WARRANTY; without even the implied warranty of MERCHANTABILITY or
141debfc3dSmrg FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
151debfc3dSmrg for more details.
161debfc3dSmrg 
171debfc3dSmrg You should have received a copy of the GNU General Public License
181debfc3dSmrg along with GCC; see the file COPYING3.  If not see
191debfc3dSmrg <http://www.gnu.org/licenses/>.  */
201debfc3dSmrg 
211debfc3dSmrg 
221debfc3dSmrg #include "bconfig.h"
231debfc3dSmrg #include "system.h"
241debfc3dSmrg #include "coretypes.h"
251debfc3dSmrg #include "tm.h"
261debfc3dSmrg #include "rtl.h"
271debfc3dSmrg #include "errors.h"
281debfc3dSmrg #include "gensupport.h"
291debfc3dSmrg 
301debfc3dSmrg 
311debfc3dSmrg /* flags to determine output of machine description dependent #define's.  */
321debfc3dSmrg static int max_recog_operands;  /* Largest operand number seen.  */
331debfc3dSmrg static int max_dup_operands;    /* Largest number of match_dup in any insn.  */
341debfc3dSmrg static int max_clobbers_per_insn;
351debfc3dSmrg static int have_cc0_flag;
361debfc3dSmrg static int have_cmove_flag;
371debfc3dSmrg static int have_cond_exec_flag;
381debfc3dSmrg static int have_lo_sum_flag;
391debfc3dSmrg static int have_rotate_flag;
401debfc3dSmrg static int have_rotatert_flag;
411debfc3dSmrg static int have_peephole_flag;
421debfc3dSmrg static int have_peephole2_flag;
431debfc3dSmrg 
441debfc3dSmrg /* Maximum number of insns seen in a split.  */
451debfc3dSmrg static int max_insns_per_split = 1;
461debfc3dSmrg 
471debfc3dSmrg /* Maximum number of input insns for peephole2.  */
481debfc3dSmrg static int max_insns_per_peep2;
491debfc3dSmrg 
501debfc3dSmrg static int clobbers_seen_this_insn;
511debfc3dSmrg static int dup_operands_seen_this_insn;
521debfc3dSmrg 
531debfc3dSmrg static void walk_insn_part (rtx, int, int);
541debfc3dSmrg 
551debfc3dSmrg /* RECOG_P will be nonzero if this pattern was seen in a context where it will
561debfc3dSmrg    be used to recognize, rather than just generate an insn.
571debfc3dSmrg 
581debfc3dSmrg    NON_PC_SET_SRC will be nonzero if this pattern was seen in a SET_SRC
591debfc3dSmrg    of a SET whose destination is not (pc).  */
601debfc3dSmrg 
611debfc3dSmrg static void
walk_insn_part(rtx part,int recog_p,int non_pc_set_src)621debfc3dSmrg walk_insn_part (rtx part, int recog_p, int non_pc_set_src)
631debfc3dSmrg {
641debfc3dSmrg   int i, j;
651debfc3dSmrg   RTX_CODE code;
661debfc3dSmrg   const char *format_ptr;
671debfc3dSmrg 
681debfc3dSmrg   if (part == 0)
691debfc3dSmrg     return;
701debfc3dSmrg 
711debfc3dSmrg   code = GET_CODE (part);
721debfc3dSmrg   switch (code)
731debfc3dSmrg     {
741debfc3dSmrg     case CLOBBER:
751debfc3dSmrg       clobbers_seen_this_insn++;
761debfc3dSmrg       break;
771debfc3dSmrg 
781debfc3dSmrg     case MATCH_OPERAND:
791debfc3dSmrg       if (XINT (part, 0) > max_recog_operands)
801debfc3dSmrg 	max_recog_operands = XINT (part, 0);
811debfc3dSmrg       return;
821debfc3dSmrg 
831debfc3dSmrg     case MATCH_OP_DUP:
841debfc3dSmrg     case MATCH_PAR_DUP:
851debfc3dSmrg       ++dup_operands_seen_this_insn;
861debfc3dSmrg       /* FALLTHRU */
871debfc3dSmrg     case MATCH_SCRATCH:
881debfc3dSmrg     case MATCH_PARALLEL:
891debfc3dSmrg     case MATCH_OPERATOR:
901debfc3dSmrg       if (XINT (part, 0) > max_recog_operands)
911debfc3dSmrg 	max_recog_operands = XINT (part, 0);
921debfc3dSmrg       /* Now scan the rtl's in the vector inside the MATCH_OPERATOR or
931debfc3dSmrg 	 MATCH_PARALLEL.  */
941debfc3dSmrg       break;
951debfc3dSmrg 
961debfc3dSmrg     case LABEL_REF:
971debfc3dSmrg       if (GET_CODE (XEXP (part, 0)) == MATCH_OPERAND
981debfc3dSmrg 	  || GET_CODE (XEXP (part, 0)) == MATCH_DUP)
991debfc3dSmrg 	break;
1001debfc3dSmrg       return;
1011debfc3dSmrg 
1021debfc3dSmrg     case MATCH_DUP:
1031debfc3dSmrg       ++dup_operands_seen_this_insn;
1041debfc3dSmrg       if (XINT (part, 0) > max_recog_operands)
1051debfc3dSmrg 	max_recog_operands = XINT (part, 0);
1061debfc3dSmrg       return;
1071debfc3dSmrg 
1081debfc3dSmrg     case CC0:
1091debfc3dSmrg       if (recog_p)
1101debfc3dSmrg 	have_cc0_flag = 1;
1111debfc3dSmrg       return;
1121debfc3dSmrg 
1131debfc3dSmrg     case LO_SUM:
1141debfc3dSmrg       if (recog_p)
1151debfc3dSmrg 	have_lo_sum_flag = 1;
1161debfc3dSmrg       return;
1171debfc3dSmrg 
1181debfc3dSmrg     case ROTATE:
1191debfc3dSmrg       if (recog_p)
1201debfc3dSmrg 	have_rotate_flag = 1;
1211debfc3dSmrg       return;
1221debfc3dSmrg 
1231debfc3dSmrg     case ROTATERT:
1241debfc3dSmrg       if (recog_p)
1251debfc3dSmrg 	have_rotatert_flag = 1;
1261debfc3dSmrg       return;
1271debfc3dSmrg 
1281debfc3dSmrg     case SET:
1291debfc3dSmrg       walk_insn_part (SET_DEST (part), 0, recog_p);
1301debfc3dSmrg       walk_insn_part (SET_SRC (part), recog_p,
1311debfc3dSmrg 		      GET_CODE (SET_DEST (part)) != PC);
1321debfc3dSmrg       return;
1331debfc3dSmrg 
1341debfc3dSmrg     case IF_THEN_ELSE:
1351debfc3dSmrg       /* Only consider this machine as having a conditional move if the
1361debfc3dSmrg 	 two arms of the IF_THEN_ELSE are both MATCH_OPERAND.  Otherwise,
1371debfc3dSmrg 	 we have some specific IF_THEN_ELSE construct (like the doz
1381debfc3dSmrg 	 instruction on the RS/6000) that can't be used in the general
1391debfc3dSmrg 	 context we want it for.  */
1401debfc3dSmrg 
1411debfc3dSmrg       if (recog_p && non_pc_set_src
1421debfc3dSmrg 	  && GET_CODE (XEXP (part, 1)) == MATCH_OPERAND
1431debfc3dSmrg 	  && GET_CODE (XEXP (part, 2)) == MATCH_OPERAND)
1441debfc3dSmrg 	have_cmove_flag = 1;
1451debfc3dSmrg       break;
1461debfc3dSmrg 
1471debfc3dSmrg     case COND_EXEC:
1481debfc3dSmrg       if (recog_p)
1491debfc3dSmrg 	have_cond_exec_flag = 1;
1501debfc3dSmrg       break;
1511debfc3dSmrg 
1521debfc3dSmrg     case REG: case CONST_INT: case SYMBOL_REF:
1531debfc3dSmrg     case PC:
1541debfc3dSmrg       return;
1551debfc3dSmrg 
1561debfc3dSmrg     default:
1571debfc3dSmrg       break;
1581debfc3dSmrg     }
1591debfc3dSmrg 
1601debfc3dSmrg   format_ptr = GET_RTX_FORMAT (GET_CODE (part));
1611debfc3dSmrg 
1621debfc3dSmrg   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
1631debfc3dSmrg     switch (*format_ptr++)
1641debfc3dSmrg       {
1651debfc3dSmrg       case 'e':
1661debfc3dSmrg       case 'u':
1671debfc3dSmrg 	walk_insn_part (XEXP (part, i), recog_p, non_pc_set_src);
1681debfc3dSmrg 	break;
1691debfc3dSmrg       case 'E':
1701debfc3dSmrg 	if (XVEC (part, i) != NULL)
1711debfc3dSmrg 	  for (j = 0; j < XVECLEN (part, i); j++)
1721debfc3dSmrg 	    walk_insn_part (XVECEXP (part, i, j), recog_p, non_pc_set_src);
1731debfc3dSmrg 	break;
1741debfc3dSmrg       }
1751debfc3dSmrg }
1761debfc3dSmrg 
1771debfc3dSmrg static void
gen_insn(md_rtx_info * info)1781debfc3dSmrg gen_insn (md_rtx_info *info)
1791debfc3dSmrg {
1801debfc3dSmrg   int i;
1811debfc3dSmrg 
1821debfc3dSmrg   /* Walk the insn pattern to gather the #define's status.  */
1831debfc3dSmrg   rtx insn = info->def;
1841debfc3dSmrg   clobbers_seen_this_insn = 0;
1851debfc3dSmrg   dup_operands_seen_this_insn = 0;
1861debfc3dSmrg   if (XVEC (insn, 1) != 0)
1871debfc3dSmrg     for (i = 0; i < XVECLEN (insn, 1); i++)
1881debfc3dSmrg       walk_insn_part (XVECEXP (insn, 1, i), 1, 0);
1891debfc3dSmrg 
1901debfc3dSmrg   if (clobbers_seen_this_insn > max_clobbers_per_insn)
1911debfc3dSmrg     max_clobbers_per_insn = clobbers_seen_this_insn;
1921debfc3dSmrg   if (dup_operands_seen_this_insn > max_dup_operands)
1931debfc3dSmrg     max_dup_operands = dup_operands_seen_this_insn;
1941debfc3dSmrg }
1951debfc3dSmrg 
1961debfc3dSmrg /* Similar but scan a define_expand.  */
1971debfc3dSmrg 
1981debfc3dSmrg static void
gen_expand(md_rtx_info * info)1991debfc3dSmrg gen_expand (md_rtx_info *info)
2001debfc3dSmrg {
2011debfc3dSmrg   int i;
2021debfc3dSmrg 
2031debfc3dSmrg   /* Walk the insn pattern to gather the #define's status.  */
2041debfc3dSmrg 
2051debfc3dSmrg   /* Note that we don't bother recording the number of MATCH_DUPs
2061debfc3dSmrg      that occur in a gen_expand, because only reload cares about that.  */
2071debfc3dSmrg   rtx insn = info->def;
2081debfc3dSmrg   if (XVEC (insn, 1) != 0)
2091debfc3dSmrg     for (i = 0; i < XVECLEN (insn, 1); i++)
2101debfc3dSmrg       {
2111debfc3dSmrg 	/* Compute the maximum SETs and CLOBBERS
2121debfc3dSmrg 	   in any one of the sub-insns;
2131debfc3dSmrg 	   don't sum across all of them.  */
2141debfc3dSmrg 	clobbers_seen_this_insn = 0;
2151debfc3dSmrg 
2161debfc3dSmrg 	walk_insn_part (XVECEXP (insn, 1, i), 0, 0);
2171debfc3dSmrg 
2181debfc3dSmrg 	if (clobbers_seen_this_insn > max_clobbers_per_insn)
2191debfc3dSmrg 	  max_clobbers_per_insn = clobbers_seen_this_insn;
2201debfc3dSmrg       }
2211debfc3dSmrg }
2221debfc3dSmrg 
2231debfc3dSmrg /* Similar but scan a define_split.  */
2241debfc3dSmrg 
2251debfc3dSmrg static void
gen_split(md_rtx_info * info)2261debfc3dSmrg gen_split (md_rtx_info *info)
2271debfc3dSmrg {
2281debfc3dSmrg   int i;
2291debfc3dSmrg 
2301debfc3dSmrg   /* Look through the patterns that are matched
2311debfc3dSmrg      to compute the maximum operand number.  */
2321debfc3dSmrg   rtx split = info->def;
2331debfc3dSmrg   for (i = 0; i < XVECLEN (split, 0); i++)
2341debfc3dSmrg     walk_insn_part (XVECEXP (split, 0, i), 1, 0);
2351debfc3dSmrg   /* Look at the number of insns this insn could split into.  */
2361debfc3dSmrg   if (XVECLEN (split, 2) > max_insns_per_split)
2371debfc3dSmrg     max_insns_per_split = XVECLEN (split, 2);
2381debfc3dSmrg }
2391debfc3dSmrg 
2401debfc3dSmrg static void
gen_peephole(md_rtx_info * info)2411debfc3dSmrg gen_peephole (md_rtx_info *info)
2421debfc3dSmrg {
2431debfc3dSmrg   int i;
2441debfc3dSmrg 
2451debfc3dSmrg   /* Look through the patterns that are matched
2461debfc3dSmrg      to compute the maximum operand number.  */
2471debfc3dSmrg   rtx peep = info->def;
2481debfc3dSmrg   for (i = 0; i < XVECLEN (peep, 0); i++)
2491debfc3dSmrg     walk_insn_part (XVECEXP (peep, 0, i), 1, 0);
2501debfc3dSmrg }
2511debfc3dSmrg 
2521debfc3dSmrg static void
gen_peephole2(md_rtx_info * info)2531debfc3dSmrg gen_peephole2 (md_rtx_info *info)
2541debfc3dSmrg {
2551debfc3dSmrg   int i, n;
2561debfc3dSmrg 
2571debfc3dSmrg   /* Look through the patterns that are matched
2581debfc3dSmrg      to compute the maximum operand number.  */
2591debfc3dSmrg   rtx peep = info->def;
2601debfc3dSmrg   for (i = XVECLEN (peep, 0) - 1; i >= 0; --i)
2611debfc3dSmrg     walk_insn_part (XVECEXP (peep, 0, i), 1, 0);
2621debfc3dSmrg 
2631debfc3dSmrg   /* Look at the number of insns this insn can be matched from.  */
2641debfc3dSmrg   for (i = XVECLEN (peep, 0) - 1, n = 0; i >= 0; --i)
2651debfc3dSmrg     if (GET_CODE (XVECEXP (peep, 0, i)) != MATCH_DUP
2661debfc3dSmrg 	&& GET_CODE (XVECEXP (peep, 0, i)) != MATCH_SCRATCH)
2671debfc3dSmrg       n++;
2681debfc3dSmrg   if (n > max_insns_per_peep2)
2691debfc3dSmrg     max_insns_per_peep2 = n;
2701debfc3dSmrg }
2711debfc3dSmrg 
2721debfc3dSmrg int
main(int argc,const char ** argv)2731debfc3dSmrg main (int argc, const char **argv)
2741debfc3dSmrg {
2751debfc3dSmrg   progname = "genconfig";
2761debfc3dSmrg 
2771debfc3dSmrg   if (!init_rtx_reader_args (argc, argv))
2781debfc3dSmrg     return (FATAL_EXIT_CODE);
2791debfc3dSmrg 
2801debfc3dSmrg   puts ("/* Generated automatically by the program `genconfig'");
2811debfc3dSmrg   puts ("   from the machine description file `md'.  */\n");
2821debfc3dSmrg   puts ("#ifndef GCC_INSN_CONFIG_H");
2831debfc3dSmrg   puts ("#define GCC_INSN_CONFIG_H\n");
2841debfc3dSmrg 
2851debfc3dSmrg   /* Allow at least 30 operands for the sake of asm constructs.  */
2861debfc3dSmrg   /* ??? We *really* ought to reorganize things such that there
2871debfc3dSmrg      is no fixed upper bound.  */
2881debfc3dSmrg   max_recog_operands = 29;  /* We will add 1 later.  */
2891debfc3dSmrg   max_dup_operands = 1;
2901debfc3dSmrg 
2911debfc3dSmrg   /* Read the machine description.  */
2921debfc3dSmrg 
2931debfc3dSmrg   md_rtx_info info;
2941debfc3dSmrg   while (read_md_rtx (&info))
2951debfc3dSmrg     switch (GET_CODE (info.def))
2961debfc3dSmrg       {
2971debfc3dSmrg       case DEFINE_INSN:
2981debfc3dSmrg 	gen_insn (&info);
2991debfc3dSmrg 	break;
3001debfc3dSmrg 
3011debfc3dSmrg       case DEFINE_EXPAND:
3021debfc3dSmrg 	gen_expand (&info);
3031debfc3dSmrg 	break;
3041debfc3dSmrg 
3051debfc3dSmrg       case DEFINE_SPLIT:
3061debfc3dSmrg 	gen_split (&info);
3071debfc3dSmrg 	break;
3081debfc3dSmrg 
3091debfc3dSmrg       case DEFINE_PEEPHOLE2:
3101debfc3dSmrg 	have_peephole2_flag = 1;
3111debfc3dSmrg 	gen_peephole2 (&info);
3121debfc3dSmrg 	break;
3131debfc3dSmrg 
3141debfc3dSmrg       case DEFINE_PEEPHOLE:
3151debfc3dSmrg 	have_peephole_flag = 1;
3161debfc3dSmrg 	gen_peephole (&info);
3171debfc3dSmrg 	break;
3181debfc3dSmrg 
3191debfc3dSmrg       default:
3201debfc3dSmrg 	break;
3211debfc3dSmrg       }
3221debfc3dSmrg 
3231debfc3dSmrg   printf ("#define MAX_RECOG_OPERANDS %d\n", max_recog_operands + 1);
3241debfc3dSmrg   printf ("#define MAX_DUP_OPERANDS %d\n", max_dup_operands);
3251debfc3dSmrg 
3261debfc3dSmrg   /* This is conditionally defined, in case the user writes code which emits
3271debfc3dSmrg      more splits than we can readily see (and knows s/he does it).  */
3281debfc3dSmrg   printf ("#ifndef MAX_INSNS_PER_SPLIT\n");
3291debfc3dSmrg   printf ("#define MAX_INSNS_PER_SPLIT %d\n", max_insns_per_split);
3301debfc3dSmrg   printf ("#endif\n");
3311debfc3dSmrg 
3321debfc3dSmrg   if (have_cc0_flag)
3331debfc3dSmrg     {
3341debfc3dSmrg       printf ("#define HAVE_cc0 1\n");
3351debfc3dSmrg       printf ("#define CC0_P(X) ((X) == cc0_rtx)\n");
3361debfc3dSmrg     }
3371debfc3dSmrg   else
3381debfc3dSmrg     {
3391debfc3dSmrg       /* We output CC0_P this way to make sure that X is declared
3401debfc3dSmrg 	 somewhere.  */
3411debfc3dSmrg       printf ("#define HAVE_cc0 0\n");
3421debfc3dSmrg       printf ("#define CC0_P(X) ((X) ? 0 : 0)\n");
3431debfc3dSmrg     }
3441debfc3dSmrg 
3451debfc3dSmrg   if (have_cmove_flag)
3461debfc3dSmrg     printf ("#define HAVE_conditional_move 1\n");
3471debfc3dSmrg   else
3481debfc3dSmrg     printf ("#define HAVE_conditional_move 0\n");
3491debfc3dSmrg 
3501debfc3dSmrg   if (have_cond_exec_flag)
3511debfc3dSmrg     printf ("#define HAVE_conditional_execution 1\n");
3521debfc3dSmrg   else
3531debfc3dSmrg     printf ("#define HAVE_conditional_execution 0\n");
3541debfc3dSmrg 
3551debfc3dSmrg   if (have_lo_sum_flag)
3561debfc3dSmrg     printf ("#define HAVE_lo_sum 1\n");
3571debfc3dSmrg   else
3581debfc3dSmrg     printf ("#define HAVE_lo_sum 0\n");
3591debfc3dSmrg 
3601debfc3dSmrg   if (have_rotate_flag)
3611debfc3dSmrg     printf ("#define HAVE_rotate 1\n");
3621debfc3dSmrg 
3631debfc3dSmrg   if (have_rotatert_flag)
3641debfc3dSmrg     printf ("#define HAVE_rotatert 1\n");
3651debfc3dSmrg 
3661debfc3dSmrg   if (have_peephole_flag)
3671debfc3dSmrg     printf ("#define HAVE_peephole 1\n");
3681debfc3dSmrg   else
3691debfc3dSmrg     printf ("#define HAVE_peephole 0\n");
3701debfc3dSmrg 
3711debfc3dSmrg   if (have_peephole2_flag)
3721debfc3dSmrg     {
3731debfc3dSmrg       printf ("#define HAVE_peephole2 1\n");
3741debfc3dSmrg       printf ("#define MAX_INSNS_PER_PEEP2 %d\n", max_insns_per_peep2);
3751debfc3dSmrg     }
3761debfc3dSmrg   else
3771debfc3dSmrg     {
3781debfc3dSmrg       printf ("#define HAVE_peephole2 0\n");
3791debfc3dSmrg       printf ("#define MAX_INSNS_PER_PEEP2 0\n");
3801debfc3dSmrg     }
3811debfc3dSmrg 
3821debfc3dSmrg   puts ("\n#endif /* GCC_INSN_CONFIG_H */");
3831debfc3dSmrg 
3841debfc3dSmrg   if (ferror (stdout) || fflush (stdout) || fclose (stdout))
3851debfc3dSmrg     return FATAL_EXIT_CODE;
3861debfc3dSmrg 
3871debfc3dSmrg   return SUCCESS_EXIT_CODE;
3881debfc3dSmrg }
389