home *** CD-ROM | disk | FTP | other *** search
/ Education Sampler 1992 [NeXTSTEP] / Education_1992_Sampler.iso / NeXT / GnuSource / cc-61.0.1 / cc / genconfig.c < prev    next >
C/C++ Source or Header  |  1991-06-03  |  8KB  |  322 lines

  1. /* Generate from machine description:
  2.  
  3.    - some #define configuration flags.
  4.    Copyright (C) 1987 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
  20. the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
  21.  
  22.  
  23. #include <stdio.h>
  24. #include "config.h"
  25. #include "rtl.h"
  26. #include "obstack.h"
  27.  
  28. struct obstack obstack;
  29. struct obstack *rtl_obstack = &obstack;
  30.  
  31. #define obstack_chunk_alloc xmalloc
  32. #define obstack_chunk_free free
  33. extern int xmalloc ();
  34. extern void free ();
  35.  
  36. /* flags to determine output of machine description dependent #define's.  */
  37. int max_recog_operands_flag;
  38. int max_dup_operands_flag;
  39. int max_clobbers_per_insn_flag;
  40. int register_constraint_flag;
  41. int have_cc0_flag;
  42. int have_lo_sum_flag;
  43.  
  44. /* Maximum number of insns seen in a split.  */
  45. int max_insns_per_split = 1;
  46.  
  47. int clobbers_seen_this_insn;
  48. int dup_operands_seen_this_insn;
  49.  
  50. void fatal ();
  51. void fancy_abort ();
  52.  
  53. /* RECOG_P will be non-zero if this pattern was seen in a context where it will
  54.    be used to recognize, rather than just generate an insn.  */
  55.  
  56. void
  57. walk_insn_part (part, recog_p)
  58.      rtx part;
  59. {
  60.   register int i, j;
  61.   register RTX_CODE code;
  62.   register char *format_ptr;
  63.  
  64.   if (part == 0)
  65.     return;
  66.  
  67.   code = GET_CODE (part);
  68.   switch (code)
  69.     {
  70.     case CLOBBER:
  71.       clobbers_seen_this_insn++;
  72.       break;
  73.  
  74.     case MATCH_OPERAND:
  75.       if (XINT (part, 0) > max_recog_operands_flag)
  76.     max_recog_operands_flag = XINT (part, 0);
  77.       if (XSTR (part, 2) && *XSTR (part, 2))
  78.     register_constraint_flag = 1;
  79.       return;
  80.  
  81.     case MATCH_OP_DUP:
  82.       ++dup_operands_seen_this_insn;
  83.     case MATCH_SCRATCH:
  84.     case MATCH_PARALLEL:
  85.     case MATCH_OPERATOR:
  86.       if (XINT (part, 0) > max_recog_operands_flag)
  87.     max_recog_operands_flag = XINT (part, 0);
  88.       /* Now scan the rtl's in the vector inside the MATCH_OPERATOR or
  89.      MATCH_PARALLEL.  */
  90.       break;
  91.  
  92.     case LABEL_REF:
  93.       if (GET_CODE (XEXP (part, 0)) == MATCH_OPERAND)
  94.     break;
  95.       return;
  96.  
  97.     case MATCH_DUP:
  98.       ++dup_operands_seen_this_insn;
  99.       if (XINT (part, 0) > max_recog_operands_flag)
  100.     max_recog_operands_flag = XINT (part, 0);
  101.       return;
  102.  
  103.     case CC0:
  104.       if (recog_p)
  105.     have_cc0_flag = 1;
  106.       return;
  107.  
  108.     case LO_SUM:
  109.       if (recog_p)
  110.     have_lo_sum_flag = 1;
  111.       return;
  112.  
  113.     case REG: case CONST_INT: case SYMBOL_REF:
  114.     case PC:
  115.       return;
  116.     }
  117.  
  118.   format_ptr = GET_RTX_FORMAT (GET_CODE (part));
  119.  
  120.   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++)
  121.     switch (*format_ptr++)
  122.       {
  123.       case 'e':
  124.       case 'u':
  125.     walk_insn_part (XEXP (part, i), recog_p);
  126.     break;
  127.       case 'E':
  128.     if (XVEC (part, i) != NULL)
  129.       for (j = 0; j < XVECLEN (part, i); j++)
  130.         walk_insn_part (XVECEXP (part, i, j), recog_p);
  131.     break;
  132.       }
  133. }
  134.  
  135. void
  136. gen_insn (insn)
  137.      rtx insn;
  138. {
  139.   int i;
  140.  
  141.   /* Walk the insn pattern to gather the #define's status.  */
  142.   clobbers_seen_this_insn = 0;
  143.   dup_operands_seen_this_insn = 0;
  144.   if (XVEC (insn, 1) != 0)
  145.     for (i = 0; i < XVECLEN (insn, 1); i++)
  146.       walk_insn_part (XVECEXP (insn, 1, i), 1);
  147.  
  148.   if (clobbers_seen_this_insn > max_clobbers_per_insn_flag)
  149.     max_clobbers_per_insn_flag = clobbers_seen_this_insn;
  150.   if (dup_operands_seen_this_insn > max_dup_operands_flag)
  151.     max_dup_operands_flag = dup_operands_seen_this_insn;
  152. }
  153.  
  154. /* Similar but scan a define_expand.  */
  155.  
  156. void
  157. gen_expand (insn)
  158.      rtx insn;
  159. {
  160.   int i;
  161.  
  162.   /* Walk the insn pattern to gather the #define's status.  */
  163.  
  164.   /* Note that we don't bother recording the number of MATCH_DUPs
  165.      that occur in a gen_expand, because only reload cares about that.  */
  166.   if (XVEC (insn, 1) != 0)
  167.     for (i = 0; i < XVECLEN (insn, 1); i++)
  168.       {
  169.     /* Compute the maximum SETs and CLOBBERS
  170.        in any one of the sub-insns;
  171.        don't sum across all of them.  */
  172.     clobbers_seen_this_insn = 0;
  173.  
  174.     walk_insn_part (XVECEXP (insn, 1, i), 0);
  175.  
  176.     if (clobbers_seen_this_insn > max_clobbers_per_insn_flag)
  177.       max_clobbers_per_insn_flag = clobbers_seen_this_insn;
  178.       }
  179. }
  180.  
  181. /* Similar but scan a define_split.  */
  182.  
  183. void
  184. gen_split (split)
  185.      rtx split;
  186. {
  187.   int i;
  188.  
  189.   /* Look through the patterns that are matched
  190.      to compute the maximum operand number.  */
  191.   for (i = 0; i < XVECLEN (split, 0); i++)
  192.     walk_insn_part (XVECEXP (split, 0, i), 1);
  193.   /* Look at the number of insns this insn could split into.  */
  194.   if (XVECLEN (split, 2) > max_insns_per_split)
  195.     max_insns_per_split = XVECLEN (split, 2);
  196. }
  197.  
  198. void
  199. gen_peephole (peep)
  200.      rtx peep;
  201. {
  202.   int i;
  203.  
  204.   /* Look through the patterns that are matched
  205.      to compute the maximum operand number.  */
  206.   for (i = 0; i < XVECLEN (peep, 0); i++)
  207.     walk_insn_part (XVECEXP (peep, 0, i), 1);
  208. }
  209.  
  210. int
  211. xmalloc (size)
  212. {
  213.   register int val = malloc (size);
  214.  
  215.   if (val == 0)
  216.     fatal ("virtual memory exhausted");
  217.  
  218.   return val;
  219. }
  220.  
  221. int
  222. xrealloc (ptr, size)
  223.      char *ptr;
  224.      int size;
  225. {
  226.   int result = realloc (ptr, size);
  227.   if (!result)
  228.     fatal ("virtual memory exhausted");
  229.   return result;
  230. }
  231.  
  232. void
  233. fatal (s, a1, a2)
  234.      char *s;
  235. {
  236.   fprintf (stderr, "genconfig: ");
  237.   fprintf (stderr, s, a1, a2);
  238.   fprintf (stderr, "\n");
  239.   exit (FATAL_EXIT_CODE);
  240. }
  241.  
  242. /* More 'friendly' abort that prints the line and file.
  243.    config.h can #define abort fancy_abort if you like that sort of thing.  */
  244.  
  245. void
  246. fancy_abort ()
  247. {
  248.   fatal ("Internal gcc abort.");
  249. }
  250.  
  251. int
  252. main (argc, argv)
  253.      int argc;
  254.      char **argv;
  255. {
  256.   rtx desc;
  257.   FILE *infile;
  258.   extern rtx read_rtx ();
  259.   register int c;
  260.  
  261.   obstack_init (rtl_obstack);
  262.  
  263.   if (argc <= 1)
  264.     fatal ("No input file name.");
  265.  
  266.   infile = fopen (argv[1], "r");
  267.   if (infile == 0)
  268.     {
  269.       perror (argv[1]);
  270.       exit (FATAL_EXIT_CODE);
  271.     }
  272.  
  273.   init_rtl ();
  274.  
  275.   printf ("/* Generated automatically by the program `genconfig'\n\
  276. from the machine description file `md'.  */\n\n");
  277.  
  278.   /* Read the machine description.  */
  279.  
  280.   while (1)
  281.     {
  282.       c = read_skip_spaces (infile);
  283.       if (c == EOF)
  284.     break;
  285.       ungetc (c, infile);
  286.  
  287.       desc = read_rtx (infile);
  288.       if (GET_CODE (desc) == DEFINE_INSN)
  289.     gen_insn (desc);
  290.       if (GET_CODE (desc) == DEFINE_EXPAND)
  291.     gen_expand (desc);
  292.       if (GET_CODE (desc) == DEFINE_SPLIT)
  293.     gen_split (desc);
  294.       if (GET_CODE (desc) == DEFINE_PEEPHOLE)
  295.     gen_peephole (desc);
  296.     }
  297.  
  298.   /* 3 more than needed for this md file, for the sake of asm constructs.  */
  299.   printf ("\n#define MAX_RECOG_OPERANDS %d\n", max_recog_operands_flag + 4);
  300.  
  301.   if (max_dup_operands_flag == 0)
  302.     max_dup_operands_flag = 1;
  303.   printf ("\n#define MAX_DUP_OPERANDS %d\n", max_dup_operands_flag);
  304.  
  305.   /* This is conditionally defined, in case the user writes code which emits
  306.      more splits than we can readily see (and knows s/he does it).  */
  307.   printf ("#ifndef MAX_INSNS_PER_SPLIT\n#define MAX_INSNS_PER_SPLIT %d\n#endif\n",
  308.       max_insns_per_split);
  309.  
  310.   if (register_constraint_flag)
  311.     printf ("#define REGISTER_CONSTRAINTS\n");
  312.  
  313.   if (have_cc0_flag)
  314.     printf ("#define HAVE_cc0\n");
  315.  
  316.   if (have_lo_sum_flag)
  317.     printf ("#define HAVE_lo_sum\n");
  318.  
  319.   fflush (stdout);
  320.   exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
  321. }
  322.