genattr.c revision 267654
116566Ssos/* Generate attribute information (insn-attr.h) from machine description.
216566Ssos   Copyright (C) 1991, 1994, 1996, 1998, 1999, 2000, 2003, 2004
316566Ssos   Free Software Foundation, Inc.
416566Ssos   Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
516566Ssos
616566SsosThis file is part of GCC.
716566Ssos
816566SsosGCC is free software; you can redistribute it and/or modify it under
916566Ssosthe terms of the GNU General Public License as published by the Free
1016566SsosSoftware Foundation; either version 2, or (at your option) any later
1116566Ssosversion.
1216566Ssos
1316566SsosGCC is distributed in the hope that it will be useful, but WITHOUT ANY
1416566SsosWARRANTY; without even the implied warranty of MERCHANTABILITY or
1516566SsosFITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
1616566Ssosfor more details.
1716566Ssos
1816566SsosYou should have received a copy of the GNU General Public License
1916566Ssosalong with GCC; see the file COPYING.  If not, write to the Free
2016566SsosSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
2116566Ssos02110-1301, USA.  */
2216566Ssos
2316566Ssos
2416566Ssos#include "bconfig.h"
2516566Ssos#include "system.h"
2616566Ssos#include "coretypes.h"
2716566Ssos#include "tm.h"
2816566Ssos#include "rtl.h"
2916566Ssos#include "errors.h"
3016566Ssos#include "gensupport.h"
3116566Ssos
3216566Ssos
3316566Ssosstatic void write_upcase (const char *);
3416566Ssosstatic void gen_attr (rtx);
3516566Ssos
3616566Ssosstatic void
3731604Syokotawrite_upcase (const char *str)
38122605Sdes{
3931604Syokota  for (; *str; str++)
4016566Ssos    putchar (TOUPPER(*str));
4116566Ssos}
4216566Ssos
4316566Ssosstatic void
44122605Sdesgen_attr (rtx attr)
4516566Ssos{
4616566Ssos  const char *p, *tag;
47122854Sdes  int is_const = GET_CODE (XEXP (attr, 2)) == CONST;
48122854Sdes
4929849Scharnier  printf ("#define HAVE_ATTR_%s\n", XSTR (attr, 0));
50122853Sdes
51122853Sdes  /* If numeric attribute, don't need to write an enum.  */
52122853Sdes  p = XSTR (attr, 1);
53122853Sdes  if (*p == '\0')
54122853Sdes    printf ("extern int get_attr_%s (%s);\n", XSTR (attr, 0),
55122853Sdes	    (is_const ? "void" : "rtx"));
56122853Sdes  else
57122853Sdes    {
5858231Syokota      printf ("enum attr_%s {", XSTR (attr, 0));
5929849Scharnier
6029849Scharnier      while ((tag = scan_comma_elt (&p)) != 0)
6129849Scharnier	{
62149426Spjd	  write_upcase (XSTR (attr, 0));
6329849Scharnier	  putchar ('_');
64122853Sdes	  while (tag != p)
65122853Sdes	    putchar (TOUPPER (*tag++));
66122853Sdes	  if (*p == ',')
67176889Sjkim	    fputs (", ", stdout);
6816566Ssos	}
6916566Ssos
7016566Ssos      fputs ("};\n", stdout);
71122853Sdes      printf ("extern enum attr_%s get_attr_%s (%s);\n\n",
7216566Ssos	      XSTR (attr, 0), XSTR (attr, 0), (is_const ? "void" : "rtx"));
7321885Ssos    }
74167461Sphilip
7516566Ssos  /* If `length' attribute, write additional function definitions and define
7631604Syokota     variables used by `insn_current_length'.  */
7758344Syokota  if (! strcmp (XSTR (attr, 0), "length"))
7858344Syokota    {
7959465Syokota      puts ("\
80136372Sphilipextern void shorten_branches (rtx);\n\
81179015Sphilipextern int insn_default_length (rtx);\n\
8231604Syokotaextern int insn_min_length (rtx);\n\
8379430Siedowseextern int insn_variable_length_p (rtx);\n\
8479430Siedowseextern int insn_current_length (rtx);\n\n\
8579430Siedowse#include \"insn-addr.h\"\n");
8631604Syokota    }
8731604Syokota}
8831604Syokota
8931604Syokotaint
9031604Syokotamain (int argc, char **argv)
9131604Syokota{
9248778Syokota  rtx desc;
9348778Syokota  int have_delay = 0;
9448778Syokota  int have_annul_true = 0;
9548778Syokota  int have_annul_false = 0;
9648778Syokota  int num_insn_reservations = 0;
9748778Syokota  int i;
9831604Syokota
9931604Syokota  progname = "genattr";
10031604Syokota
10131604Syokota  if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE)
10231604Syokota    return (FATAL_EXIT_CODE);
103136372Sphilip
104148161Sphilip  puts ("/* Generated automatically by the program `genattr'");
105167461Sphilip  puts ("   from the machine description file `md'.  */\n");
106122605Sdes  puts ("#ifndef GCC_INSN_ATTR_H");
10731604Syokota  puts ("#define GCC_INSN_ATTR_H\n");
10831604Syokota
10931604Syokota  /* For compatibility, define the attribute `alternative', which is just
110136372Sphilip     a reference to the variable `which_alternative'.  */
11131604Syokota
11231604Syokota  puts ("#define HAVE_ATTR_alternative");
11331604Syokota  puts ("#define get_attr_alternative(insn) which_alternative");
114176854Sjkim
115176854Sjkim  /* Read the machine description.  */
116176854Sjkim
117176854Sjkim  while (1)
118176854Sjkim    {
119176854Sjkim      int line_no, insn_code_number;
120176854Sjkim
121176854Sjkim      desc = read_md_rtx (&line_no, &insn_code_number);
122176854Sjkim      if (desc == NULL)
123176854Sjkim	break;
124176854Sjkim
125176854Sjkim      if (GET_CODE (desc) == DEFINE_ATTR)
126176854Sjkim	gen_attr (desc);
127176854Sjkim
128176854Sjkim      else if (GET_CODE (desc) == DEFINE_DELAY)
129176854Sjkim        {
130160523Sstefanf	  if (! have_delay)
13195629Siedowse	    {
132160523Sstefanf	      printf ("#define DELAY_SLOTS\n");
13395629Siedowse	      printf ("extern int num_delay_slots (rtx);\n");
13416566Ssos	      printf ("extern int eligible_for_delay (rtx, int, rtx, int);\n\n");
135160523Sstefanf	      printf ("extern int const_num_delay_slots (rtx);\n\n");
136160523Sstefanf	      have_delay = 1;
13795629Siedowse	    }
13895629Siedowse
13931604Syokota	  for (i = 0; i < XVECLEN (desc, 1); i += 3)
140160523Sstefanf	    {
141160523Sstefanf	      if (XVECEXP (desc, 1, i + 1) && ! have_annul_true)
14295629Siedowse		{
14395629Siedowse		  printf ("#define ANNUL_IFTRUE_SLOTS\n");
14431604Syokota		  printf ("extern int eligible_for_annul_true (rtx, int, rtx, int);\n");
145160523Sstefanf		  have_annul_true = 1;
146160523Sstefanf		}
14731604Syokota
148160523Sstefanf	      if (XVECEXP (desc, 1, i + 2) && ! have_annul_false)
149160523Sstefanf		{
15031604Syokota		  printf ("#define ANNUL_IFFALSE_SLOTS\n");
15131604Syokota		  printf ("extern int eligible_for_annul_false (rtx, int, rtx, int);\n");
15231604Syokota		  have_annul_false = 1;
15331604Syokota		}
15431604Syokota	    }
155176855Sjkim        }
15631604Syokota
15731604Syokota      else if (GET_CODE (desc) == DEFINE_INSN_RESERVATION)
15831604Syokota	num_insn_reservations++;
15931604Syokota    }
16031604Syokota
16131604Syokota  if (num_insn_reservations > 0)
16231604Syokota    {
163176855Sjkim      /* Output interface for pipeline hazards recognition based on
16431604Syokota	 DFA (deterministic finite state automata.  */
165176855Sjkim      printf ("\n#define INSN_SCHEDULING\n");
16631604Syokota      printf ("\n/* DFA based pipeline interface.  */");
16731604Syokota      printf ("\n#ifndef AUTOMATON_ALTS\n");
16831604Syokota      printf ("#define AUTOMATON_ALTS 0\n");
16931604Syokota      printf ("#endif\n\n");
17031604Syokota      printf ("\n#ifndef AUTOMATON_STATE_ALTS\n");
17131604Syokota      printf ("#define AUTOMATON_STATE_ALTS 0\n");
17231604Syokota      printf ("#endif\n\n");
17331604Syokota      printf ("#ifndef CPU_UNITS_QUERY\n");
17431604Syokota      printf ("#define CPU_UNITS_QUERY 0\n");
17531604Syokota      printf ("#endif\n\n");
17631604Syokota      /* Interface itself: */
177227256Sed      printf ("/* Internal insn code number used by automata.  */\n");
178227256Sed      printf ("extern int internal_dfa_insn_code (rtx);\n\n");
179227256Sed      printf ("/* Insn latency time defined in define_insn_reservation. */\n");
180227256Sed      printf ("extern int insn_default_latency (rtx);\n\n");
181227256Sed      printf ("/* Return nonzero if there is a bypass for given insn\n");
182227256Sed      printf ("   which is a data producer.  */\n");
183227256Sed      printf ("extern int bypass_p (rtx);\n\n");
184227256Sed      printf ("/* Insn latency time on data consumed by the 2nd insn.\n");
18516566Ssos      printf ("   Use the function if bypass_p returns nonzero for\n");
186136372Sphilip      printf ("   the 1st insn. */\n");
187136372Sphilip      printf ("extern int insn_latency (rtx, rtx);\n\n");
188136372Sphilip      printf ("\n#if AUTOMATON_ALTS\n");
189136372Sphilip      printf ("/* The following function returns number of alternative\n");
190136372Sphilip      printf ("   reservations of given insn.  It may be used for better\n");
191136372Sphilip      printf ("   insns scheduling heuristics. */\n");
192148161Sphilip      printf ("extern int insn_alts (rtx);\n\n");
193136372Sphilip      printf ("#endif\n\n");
19431604Syokota      printf ("/* Maximal possible number of insns waiting results being\n");
19516566Ssos      printf ("   produced by insns whose execution is not finished. */\n");
19631604Syokota      printf ("extern const int max_insn_queue_index;\n\n");
19731604Syokota      printf ("/* Pointer to data describing current state of DFA.  */\n");
198176855Sjkim      printf ("typedef void *state_t;\n\n");
199176855Sjkim      printf ("/* Size of the data in bytes.  */\n");
200176855Sjkim      printf ("extern int state_size (void);\n\n");
201176855Sjkim      printf ("/* Initiate given DFA state, i.e. Set up the state\n");
202176855Sjkim      printf ("   as all functional units were not reserved.  */\n");
203176855Sjkim      printf ("extern void state_reset (state_t);\n");
204176855Sjkim      printf ("/* The following function returns negative value if given\n");
20531604Syokota      printf ("   insn can be issued in processor state described by given\n");
20616566Ssos      printf ("   DFA state.  In this case, the DFA state is changed to\n");
20731604Syokota      printf ("   reflect the current and future reservations by given\n");
208176855Sjkim      printf ("   insn.  Otherwise the function returns minimal time\n");
20916566Ssos      printf ("   delay to issue the insn.  This delay may be zero\n");
21016566Ssos      printf ("   for superscalar or VLIW processors.  If the second\n");
21131604Syokota      printf ("   parameter is NULL the function changes given DFA state\n");
21216566Ssos      printf ("   as new processor cycle started.  */\n");
21331604Syokota      printf ("extern int state_transition (state_t, rtx);\n");
21416566Ssos      printf ("\n#if AUTOMATON_STATE_ALTS\n");
21531604Syokota      printf ("/* The following function returns number of possible\n");
21616566Ssos      printf ("   alternative reservations of given insn in given\n");
21718222Speter      printf ("   DFA state.  It may be used for better insns scheduling\n");
21831604Syokota      printf ("   heuristics.  By default the function is defined if\n");
21931604Syokota      printf ("   macro AUTOMATON_STATE_ALTS is defined because its\n");
22031604Syokota      printf ("   implementation may require much memory.  */\n");
22131604Syokota      printf ("extern int state_alts (state_t, rtx);\n");
22236991Sahasty      printf ("#endif\n\n");
22341271Syokota      printf ("extern int min_issue_delay (state_t, rtx);\n");
22493071Swill      printf ("/* The following function returns nonzero if no one insn\n");
22593071Swill      printf ("   can be issued in current DFA state. */\n");
22631604Syokota      printf ("extern int state_dead_lock_p (state_t);\n");
22731604Syokota      printf ("/* The function returns minimal delay of issue of the 2nd\n");
22831604Syokota      printf ("   insn after issuing the 1st insn in given DFA state.\n");
229145001Smdodd      printf ("   The 1st insn should be issued in given state (i.e.\n");
23016566Ssos      printf ("    state_transition should return negative value for\n");
23116566Ssos      printf ("    the insn and the state).  Data dependencies between\n");
23216566Ssos      printf ("    the insns are ignored by the function.  */\n");
23331604Syokota      printf
23431604Syokota	("extern int min_insn_conflict_delay (state_t, rtx, rtx);\n");
235176855Sjkim      printf ("/* The following function outputs reservations for given\n");
236176855Sjkim      printf ("   insn as they are described in the corresponding\n");
237176855Sjkim      printf ("   define_insn_reservation.  */\n");
238176855Sjkim      printf ("extern void print_reservation (FILE *, rtx);\n");
239176855Sjkim      printf ("\n#if CPU_UNITS_QUERY\n");
240176855Sjkim      printf ("/* The following function returns code of functional unit\n");
241176855Sjkim      printf ("   with given name (see define_cpu_unit). */\n");
242176855Sjkim      printf ("extern int get_cpu_unit_code (const char *);\n");
243176855Sjkim      printf ("/* The following function returns nonzero if functional\n");
244176855Sjkim      printf ("   unit with given code is currently reserved in given\n");
245176855Sjkim      printf ("   DFA state.  */\n");
246176855Sjkim      printf ("extern int cpu_unit_reservation_p (state_t, int);\n");
247176855Sjkim      printf ("#endif\n\n");
248248478Sjkim      printf ("/* Clean insn code cache.  It should be called if there\n");
249176855Sjkim      printf ("   is a chance that condition value in a\n");
250176855Sjkim      printf ("   define_insn_reservation will be changed after\n");
25131604Syokota      printf ("   last call of dfa_start.  */\n");
25231604Syokota      printf ("extern void dfa_clean_insn_cache (void);\n\n");
25331604Syokota      printf ("extern void dfa_clear_single_insn_cache (rtx);\n\n");
25431604Syokota      printf ("/* Initiate and finish work with DFA.  They should be\n");
25531604Syokota      printf ("   called as the first and the last interface\n");
25631604Syokota      printf ("   functions.  */\n");
25731604Syokota      printf ("extern void dfa_start (void);\n");
25831604Syokota      printf ("extern void dfa_finish (void);\n");
25931604Syokota    }
26031604Syokota  else
26158099Sache    {
26258099Sache      /* Otherwise we do no scheduling, but we need these typedefs
26333074Sache	 in order to avoid uglifying other code with more ifdefs.  */
26433074Sache      printf ("typedef void *state_t;\n\n");
26556524Syokota    }
26656524Syokota
26733074Sache  /* Output flag masks for use by reorg.
26833074Sache
26941271Syokota     Flags are used to hold branch direction and prediction information
27041271Syokota     for use by eligible_for_...  */
27131604Syokota  printf("\n#define ATTR_FLAG_forward\t0x1\n");
272122605Sdes  printf("#define ATTR_FLAG_backward\t0x2\n");
27356335Syokota  printf("#define ATTR_FLAG_likely\t0x4\n");
27456335Syokota  printf("#define ATTR_FLAG_very_likely\t0x8\n");
27531949Syokota  printf("#define ATTR_FLAG_unlikely\t0x10\n");
27631949Syokota  printf("#define ATTR_FLAG_very_unlikely\t0x20\n");
27731604Syokota
27831604Syokota  puts("\n#endif /* GCC_INSN_ATTR_H */");
27931604Syokota
28031604Syokota  if (ferror (stdout) || fflush (stdout) || fclose (stdout))
28132634Syokota    return FATAL_EXIT_CODE;
28232634Syokota
28358231Syokota  return SUCCESS_EXIT_CODE;
28458231Syokota}
28558231Syokota