]>
Commit | Line | Data |
---|---|---|
f12b8918 | 1 | /* Generate attribute information (insn-attr.h) from machine description. |
9dcd6f09 | 2 | Copyright (C) 1991, 1994, 1996, 1998, 1999, 2000, 2003, 2004, 2007 |
3d7aafde | 3 | Free Software Foundation, Inc. |
c9309570 | 4 | Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) |
41299f41 | 5 | |
1322177d | 6 | This file is part of GCC. |
41299f41 | 7 | |
1322177d LB |
8 | GCC is free software; you can redistribute it and/or modify it under |
9 | the terms of the GNU General Public License as published by the Free | |
9dcd6f09 | 10 | Software Foundation; either version 3, or (at your option) any later |
1322177d | 11 | version. |
41299f41 | 12 | |
1322177d LB |
13 | GCC is distributed in the hope that it will be useful, but WITHOUT ANY |
14 | WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
15 | FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
16 | for more details. | |
41299f41 TW |
17 | |
18 | You should have received a copy of the GNU General Public License | |
9dcd6f09 NC |
19 | along with GCC; see the file COPYING3. If not see |
20 | <http://www.gnu.org/licenses/>. */ | |
41299f41 TW |
21 | |
22 | ||
4977bab6 | 23 | #include "bconfig.h" |
0b93b64e | 24 | #include "system.h" |
4977bab6 ZW |
25 | #include "coretypes.h" |
26 | #include "tm.h" | |
41299f41 | 27 | #include "rtl.h" |
f8b6598e | 28 | #include "errors.h" |
c88c0d42 | 29 | #include "gensupport.h" |
41299f41 | 30 | |
41299f41 | 31 | |
3d7aafde AJ |
32 | static void write_upcase (const char *); |
33 | static void gen_attr (rtx); | |
ef3fad04 | 34 | |
41299f41 | 35 | static void |
3d7aafde | 36 | write_upcase (const char *str) |
41299f41 | 37 | { |
f12b8918 | 38 | for (; *str; str++) |
92a438d1 | 39 | putchar (TOUPPER(*str)); |
4beba5da | 40 | } |
4beba5da TM |
41 | |
42 | static void | |
3d7aafde | 43 | gen_attr (rtx attr) |
4beba5da | 44 | { |
9a5834ae | 45 | const char *p, *tag; |
3d7aafde | 46 | int is_const = GET_CODE (XEXP (attr, 2)) == CONST; |
41299f41 | 47 | |
f12b8918 | 48 | printf ("#define HAVE_ATTR_%s\n", XSTR (attr, 0)); |
41299f41 | 49 | |
f12b8918 | 50 | /* If numeric attribute, don't need to write an enum. */ |
9a5834ae ZW |
51 | p = XSTR (attr, 1); |
52 | if (*p == '\0') | |
3d7aafde | 53 | printf ("extern int get_attr_%s (%s);\n", XSTR (attr, 0), |
ffee6d93 | 54 | (is_const ? "void" : "rtx")); |
41299f41 TW |
55 | else |
56 | { | |
f12b8918 | 57 | printf ("enum attr_%s {", XSTR (attr, 0)); |
4beba5da | 58 | |
9a5834ae | 59 | while ((tag = scan_comma_elt (&p)) != 0) |
41299f41 | 60 | { |
9a5834ae ZW |
61 | write_upcase (XSTR (attr, 0)); |
62 | putchar ('_'); | |
63 | while (tag != p) | |
64 | putchar (TOUPPER (*tag++)); | |
0b42c8f8 ZW |
65 | if (*p == ',') |
66 | fputs (", ", stdout); | |
41299f41 TW |
67 | } |
68 | ||
9a5834ae | 69 | fputs ("};\n", stdout); |
3d7aafde | 70 | printf ("extern enum attr_%s get_attr_%s (%s);\n\n", |
ffee6d93 | 71 | XSTR (attr, 0), XSTR (attr, 0), (is_const ? "void" : "rtx")); |
41299f41 TW |
72 | } |
73 | ||
f12b8918 TM |
74 | /* If `length' attribute, write additional function definitions and define |
75 | variables used by `insn_current_length'. */ | |
76 | if (! strcmp (XSTR (attr, 0), "length")) | |
41299f41 | 77 | { |
9a5834ae | 78 | puts ("\ |
3d7aafde AJ |
79 | extern void shorten_branches (rtx);\n\ |
80 | extern int insn_default_length (rtx);\n\ | |
070a7956 | 81 | extern int insn_min_length (rtx);\n\ |
3d7aafde AJ |
82 | extern int insn_variable_length_p (rtx);\n\ |
83 | extern int insn_current_length (rtx);\n\n\ | |
9a5834ae | 84 | #include \"insn-addr.h\"\n"); |
41299f41 TW |
85 | } |
86 | } | |
87 | ||
41299f41 | 88 | int |
3d7aafde | 89 | main (int argc, char **argv) |
41299f41 TW |
90 | { |
91 | rtx desc; | |
f12b8918 TM |
92 | int have_delay = 0; |
93 | int have_annul_true = 0; | |
94 | int have_annul_false = 0; | |
fae15c93 | 95 | int num_insn_reservations = 0; |
41299f41 TW |
96 | int i; |
97 | ||
f8b6598e | 98 | progname = "genattr"; |
41299f41 | 99 | |
04d8aa70 | 100 | if (init_md_reader_args (argc, argv) != SUCCESS_EXIT_CODE) |
c88c0d42 | 101 | return (FATAL_EXIT_CODE); |
41299f41 | 102 | |
0313e85b ZW |
103 | puts ("/* Generated automatically by the program `genattr'"); |
104 | puts (" from the machine description file `md'. */\n"); | |
105 | puts ("#ifndef GCC_INSN_ATTR_H"); | |
106 | puts ("#define GCC_INSN_ATTR_H\n"); | |
41299f41 | 107 | |
f12b8918 TM |
108 | /* For compatibility, define the attribute `alternative', which is just |
109 | a reference to the variable `which_alternative'. */ | |
110 | ||
0313e85b ZW |
111 | puts ("#define HAVE_ATTR_alternative"); |
112 | puts ("#define get_attr_alternative(insn) which_alternative"); | |
3d7aafde | 113 | |
41299f41 TW |
114 | /* Read the machine description. */ |
115 | ||
116 | while (1) | |
117 | { | |
c88c0d42 CP |
118 | int line_no, insn_code_number; |
119 | ||
120 | desc = read_md_rtx (&line_no, &insn_code_number); | |
121 | if (desc == NULL) | |
41299f41 | 122 | break; |
41299f41 | 123 | |
f12b8918 TM |
124 | if (GET_CODE (desc) == DEFINE_ATTR) |
125 | gen_attr (desc); | |
41299f41 | 126 | |
f12b8918 TM |
127 | else if (GET_CODE (desc) == DEFINE_DELAY) |
128 | { | |
129 | if (! have_delay) | |
130 | { | |
131 | printf ("#define DELAY_SLOTS\n"); | |
3d7aafde AJ |
132 | printf ("extern int num_delay_slots (rtx);\n"); |
133 | printf ("extern int eligible_for_delay (rtx, int, rtx, int);\n\n"); | |
134 | printf ("extern int const_num_delay_slots (rtx);\n\n"); | |
f12b8918 TM |
135 | have_delay = 1; |
136 | } | |
41299f41 | 137 | |
f12b8918 TM |
138 | for (i = 0; i < XVECLEN (desc, 1); i += 3) |
139 | { | |
140 | if (XVECEXP (desc, 1, i + 1) && ! have_annul_true) | |
141 | { | |
142 | printf ("#define ANNUL_IFTRUE_SLOTS\n"); | |
3d7aafde | 143 | printf ("extern int eligible_for_annul_true (rtx, int, rtx, int);\n"); |
f12b8918 TM |
144 | have_annul_true = 1; |
145 | } | |
ef3fad04 | 146 | |
f12b8918 TM |
147 | if (XVECEXP (desc, 1, i + 2) && ! have_annul_false) |
148 | { | |
149 | printf ("#define ANNUL_IFFALSE_SLOTS\n"); | |
3d7aafde | 150 | printf ("extern int eligible_for_annul_false (rtx, int, rtx, int);\n"); |
f12b8918 TM |
151 | have_annul_false = 1; |
152 | } | |
153 | } | |
154 | } | |
ef3fad04 | 155 | |
fae15c93 VM |
156 | else if (GET_CODE (desc) == DEFINE_INSN_RESERVATION) |
157 | num_insn_reservations++; | |
f12b8918 | 158 | } |
ef3fad04 | 159 | |
fa0aee89 | 160 | if (num_insn_reservations > 0) |
f12b8918 | 161 | { |
fae15c93 VM |
162 | /* Output interface for pipeline hazards recognition based on |
163 | DFA (deterministic finite state automata. */ | |
fa0aee89 | 164 | printf ("\n#define INSN_SCHEDULING\n"); |
fae15c93 | 165 | printf ("\n/* DFA based pipeline interface. */"); |
d530b07f VM |
166 | printf ("\n#ifndef AUTOMATON_ALTS\n"); |
167 | printf ("#define AUTOMATON_ALTS 0\n"); | |
168 | printf ("#endif\n\n"); | |
fae15c93 VM |
169 | printf ("\n#ifndef AUTOMATON_STATE_ALTS\n"); |
170 | printf ("#define AUTOMATON_STATE_ALTS 0\n"); | |
171 | printf ("#endif\n\n"); | |
172 | printf ("#ifndef CPU_UNITS_QUERY\n"); | |
173 | printf ("#define CPU_UNITS_QUERY 0\n"); | |
174 | printf ("#endif\n\n"); | |
175 | /* Interface itself: */ | |
8c94f366 ZW |
176 | printf ("/* Internal insn code number used by automata. */\n"); |
177 | printf ("extern int internal_dfa_insn_code (rtx);\n\n"); | |
fae15c93 | 178 | printf ("/* Insn latency time defined in define_insn_reservation. */\n"); |
3d7aafde | 179 | printf ("extern int insn_default_latency (rtx);\n\n"); |
fae15c93 VM |
180 | printf ("/* Return nonzero if there is a bypass for given insn\n"); |
181 | printf (" which is a data producer. */\n"); | |
3d7aafde | 182 | printf ("extern int bypass_p (rtx);\n\n"); |
fae15c93 VM |
183 | printf ("/* Insn latency time on data consumed by the 2nd insn.\n"); |
184 | printf (" Use the function if bypass_p returns nonzero for\n"); | |
185 | printf (" the 1st insn. */\n"); | |
3d7aafde | 186 | printf ("extern int insn_latency (rtx, rtx);\n\n"); |
d530b07f | 187 | printf ("\n#if AUTOMATON_ALTS\n"); |
fae15c93 VM |
188 | printf ("/* The following function returns number of alternative\n"); |
189 | printf (" reservations of given insn. It may be used for better\n"); | |
190 | printf (" insns scheduling heuristics. */\n"); | |
3d7aafde | 191 | printf ("extern int insn_alts (rtx);\n\n"); |
d530b07f | 192 | printf ("#endif\n\n"); |
fae15c93 VM |
193 | printf ("/* Maximal possible number of insns waiting results being\n"); |
194 | printf (" produced by insns whose execution is not finished. */\n"); | |
5f2f0edd | 195 | printf ("extern const int max_insn_queue_index;\n\n"); |
fae15c93 VM |
196 | printf ("/* Pointer to data describing current state of DFA. */\n"); |
197 | printf ("typedef void *state_t;\n\n"); | |
198 | printf ("/* Size of the data in bytes. */\n"); | |
3d7aafde | 199 | printf ("extern int state_size (void);\n\n"); |
fae15c93 VM |
200 | printf ("/* Initiate given DFA state, i.e. Set up the state\n"); |
201 | printf (" as all functional units were not reserved. */\n"); | |
3d7aafde | 202 | printf ("extern void state_reset (state_t);\n"); |
fae15c93 VM |
203 | printf ("/* The following function returns negative value if given\n"); |
204 | printf (" insn can be issued in processor state described by given\n"); | |
205 | printf (" DFA state. In this case, the DFA state is changed to\n"); | |
206 | printf (" reflect the current and future reservations by given\n"); | |
207 | printf (" insn. Otherwise the function returns minimal time\n"); | |
208 | printf (" delay to issue the insn. This delay may be zero\n"); | |
209 | printf (" for superscalar or VLIW processors. If the second\n"); | |
210 | printf (" parameter is NULL the function changes given DFA state\n"); | |
211 | printf (" as new processor cycle started. */\n"); | |
3d7aafde | 212 | printf ("extern int state_transition (state_t, rtx);\n"); |
fae15c93 VM |
213 | printf ("\n#if AUTOMATON_STATE_ALTS\n"); |
214 | printf ("/* The following function returns number of possible\n"); | |
215 | printf (" alternative reservations of given insn in given\n"); | |
216 | printf (" DFA state. It may be used for better insns scheduling\n"); | |
217 | printf (" heuristics. By default the function is defined if\n"); | |
218 | printf (" macro AUTOMATON_STATE_ALTS is defined because its\n"); | |
219 | printf (" implementation may require much memory. */\n"); | |
3d7aafde | 220 | printf ("extern int state_alts (state_t, rtx);\n"); |
fae15c93 | 221 | printf ("#endif\n\n"); |
3d7aafde | 222 | printf ("extern int min_issue_delay (state_t, rtx);\n"); |
fae15c93 VM |
223 | printf ("/* The following function returns nonzero if no one insn\n"); |
224 | printf (" can be issued in current DFA state. */\n"); | |
3d7aafde | 225 | printf ("extern int state_dead_lock_p (state_t);\n"); |
fae15c93 VM |
226 | printf ("/* The function returns minimal delay of issue of the 2nd\n"); |
227 | printf (" insn after issuing the 1st insn in given DFA state.\n"); | |
228 | printf (" The 1st insn should be issued in given state (i.e.\n"); | |
229 | printf (" state_transition should return negative value for\n"); | |
230 | printf (" the insn and the state). Data dependencies between\n"); | |
231 | printf (" the insns are ignored by the function. */\n"); | |
232 | printf | |
3d7aafde | 233 | ("extern int min_insn_conflict_delay (state_t, rtx, rtx);\n"); |
fae15c93 VM |
234 | printf ("/* The following function outputs reservations for given\n"); |
235 | printf (" insn as they are described in the corresponding\n"); | |
236 | printf (" define_insn_reservation. */\n"); | |
3d7aafde | 237 | printf ("extern void print_reservation (FILE *, rtx);\n"); |
fae15c93 VM |
238 | printf ("\n#if CPU_UNITS_QUERY\n"); |
239 | printf ("/* The following function returns code of functional unit\n"); | |
240 | printf (" with given name (see define_cpu_unit). */\n"); | |
3d7aafde | 241 | printf ("extern int get_cpu_unit_code (const char *);\n"); |
fae15c93 VM |
242 | printf ("/* The following function returns nonzero if functional\n"); |
243 | printf (" unit with given code is currently reserved in given\n"); | |
244 | printf (" DFA state. */\n"); | |
3d7aafde | 245 | printf ("extern int cpu_unit_reservation_p (state_t, int);\n"); |
dd1b7476 | 246 | printf ("#endif\n\n"); |
1c3d0d93 MK |
247 | printf ("/* The following function returns true if insn\n"); |
248 | printf (" has a dfa reservation. */\n"); | |
249 | printf ("extern bool insn_has_dfa_reservation_p (rtx);\n\n"); | |
30028c85 VM |
250 | printf ("/* Clean insn code cache. It should be called if there\n"); |
251 | printf (" is a chance that condition value in a\n"); | |
252 | printf (" define_insn_reservation will be changed after\n"); | |
253 | printf (" last call of dfa_start. */\n"); | |
3d7aafde | 254 | printf ("extern void dfa_clean_insn_cache (void);\n\n"); |
496d7bb0 | 255 | printf ("extern void dfa_clear_single_insn_cache (rtx);\n\n"); |
fae15c93 VM |
256 | printf ("/* Initiate and finish work with DFA. They should be\n"); |
257 | printf (" called as the first and the last interface\n"); | |
258 | printf (" functions. */\n"); | |
3d7aafde AJ |
259 | printf ("extern void dfa_start (void);\n"); |
260 | printf ("extern void dfa_finish (void);\n"); | |
fae15c93 VM |
261 | } |
262 | else | |
263 | { | |
264 | /* Otherwise we do no scheduling, but we need these typedefs | |
265 | in order to avoid uglifying other code with more ifdefs. */ | |
266 | printf ("typedef void *state_t;\n\n"); | |
a224278b | 267 | } |
b29d5f75 | 268 | |
3d7aafde | 269 | /* Output flag masks for use by reorg. |
eaa48dab JL |
270 | |
271 | Flags are used to hold branch direction and prediction information | |
272 | for use by eligible_for_... */ | |
273 | printf("\n#define ATTR_FLAG_forward\t0x1\n"); | |
274 | printf("#define ATTR_FLAG_backward\t0x2\n"); | |
275 | printf("#define ATTR_FLAG_likely\t0x4\n"); | |
276 | printf("#define ATTR_FLAG_very_likely\t0x8\n"); | |
277 | printf("#define ATTR_FLAG_unlikely\t0x10\n"); | |
278 | printf("#define ATTR_FLAG_very_unlikely\t0x20\n"); | |
279 | ||
0313e85b ZW |
280 | puts("\n#endif /* GCC_INSN_ATTR_H */"); |
281 | ||
282 | if (ferror (stdout) || fflush (stdout) || fclose (stdout)) | |
283 | return FATAL_EXIT_CODE; | |
284 | ||
285 | return SUCCESS_EXIT_CODE; | |
41299f41 | 286 | } |