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