comparison gcc/genattr.c @ 111:04ced10e8804

gcc 7
author kono
date Fri, 27 Oct 2017 22:46:09 +0900
parents f6334be47118
children 84e7813d76e9
comparison
equal deleted inserted replaced
68:561a7518be6b 111:04ced10e8804
1 /* Generate attribute information (insn-attr.h) from machine description. 1 /* Generate attribute information (insn-attr.h) from machine description.
2 Copyright (C) 1991, 1994, 1996, 1998, 1999, 2000, 2003, 2004, 2007, 2008, 2 Copyright (C) 1991-2017 Free Software Foundation, Inc.
3 2010 Free Software Foundation, Inc.
4 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) 3 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu)
5 4
6 This file is part of GCC. 5 This file is part of GCC.
7 6
8 GCC is free software; you can redistribute it and/or modify it under 7 GCC is free software; you can redistribute it and/or modify it under
28 #include "errors.h" 27 #include "errors.h"
29 #include "read-md.h" 28 #include "read-md.h"
30 #include "gensupport.h" 29 #include "gensupport.h"
31 30
32 31
33 static void write_upcase (const char *); 32 static vec<rtx> const_attrs, reservations;
34 static void gen_attr (rtx); 33
35 34
36 static void 35 static void
37 write_upcase (const char *str) 36 gen_attr (md_rtx_info *info)
38 { 37 {
39 for (; *str; str++) 38 const char *p;
40 putchar (TOUPPER(*str)); 39 rtx attr = info->def;
41 }
42
43 static VEC (rtx, heap) *const_attrs, *reservations;
44
45
46 static void
47 gen_attr (rtx attr)
48 {
49 const char *p, *tag;
50 int is_const = GET_CODE (XEXP (attr, 2)) == CONST; 40 int is_const = GET_CODE (XEXP (attr, 2)) == CONST;
51 41
52 if (is_const) 42 if (is_const)
53 VEC_safe_push (rtx, heap, const_attrs, attr); 43 const_attrs.safe_push (attr);
54 44
55 printf ("#define HAVE_ATTR_%s\n", XSTR (attr, 0)); 45 printf ("#define HAVE_ATTR_%s 1\n", XSTR (attr, 0));
56 46
57 /* If numeric attribute, don't need to write an enum. */ 47 /* If numeric attribute, don't need to write an enum. */
58 if (GET_CODE (attr) == DEFINE_ENUM_ATTR) 48 if (GET_CODE (attr) == DEFINE_ENUM_ATTR)
59 printf ("extern enum %s get_attr_%s (%s);\n\n", 49 printf ("extern enum %s get_attr_%s (%s);\n\n",
60 XSTR (attr, 1), XSTR (attr, 0), (is_const ? "void" : "rtx")); 50 XSTR (attr, 1), XSTR (attr, 0),
51 (is_const ? "void" : "rtx_insn *"));
61 else 52 else
62 { 53 {
63 p = XSTR (attr, 1); 54 p = XSTR (attr, 1);
64 if (*p == '\0') 55 if (*p == '\0')
65 printf ("extern int get_attr_%s (%s);\n", XSTR (attr, 0), 56 printf ("extern int get_attr_%s (%s);\n", XSTR (attr, 0),
66 (is_const ? "void" : "rtx")); 57 (is_const ? "void" : "rtx_insn *"));
67 else 58 else
68 { 59 printf ("extern enum attr_%s get_attr_%s (%s);\n\n",
69 printf ("enum attr_%s {", XSTR (attr, 0)); 60 XSTR (attr, 0), XSTR (attr, 0),
70 61 (is_const ? "void" : "rtx_insn *"));
71 while ((tag = scan_comma_elt (&p)) != 0)
72 {
73 write_upcase (XSTR (attr, 0));
74 putchar ('_');
75 while (tag != p)
76 putchar (TOUPPER (*tag++));
77 if (*p == ',')
78 fputs (", ", stdout);
79 }
80 fputs ("};\n", stdout);
81
82 printf ("extern enum attr_%s get_attr_%s (%s);\n\n",
83 XSTR (attr, 0), XSTR (attr, 0), (is_const ? "void" : "rtx"));
84 }
85 } 62 }
86 63
87 /* If `length' attribute, write additional function definitions and define 64 /* If `length' attribute, write additional function definitions and define
88 variables used by `insn_current_length'. */ 65 variables used by `insn_current_length'. */
89 if (! strcmp (XSTR (attr, 0), "length")) 66 if (! strcmp (XSTR (attr, 0), "length"))
90 { 67 {
91 puts ("\ 68 puts ("\
92 extern void shorten_branches (rtx);\n\ 69 extern void shorten_branches (rtx_insn *);\n\
93 extern int insn_default_length (rtx);\n\ 70 extern int insn_default_length (rtx_insn *);\n\
94 extern int insn_min_length (rtx);\n\ 71 extern int insn_min_length (rtx_insn *);\n\
95 extern int insn_variable_length_p (rtx);\n\ 72 extern int insn_variable_length_p (rtx_insn *);\n\
96 extern int insn_current_length (rtx);\n\n\ 73 extern int insn_current_length (rtx_insn *);\n\n\
97 #include \"insn-addr.h\"\n"); 74 #include \"insn-addr.h\"\n");
98 } 75 }
99 } 76 }
100 77
101 /* Check that attribute NAME is used in define_insn_reservation condition 78 /* Check that attribute NAME is used in define_insn_reservation condition
140 117
141 case EQ_ATTR: 118 case EQ_ATTR:
142 if (strcmp (XSTR (exp, 0), "alternative") == 0) 119 if (strcmp (XSTR (exp, 0), "alternative") == 0)
143 return false; 120 return false;
144 121
145 FOR_EACH_VEC_ELT (rtx, const_attrs, i, attr) 122 FOR_EACH_VEC_ELT (const_attrs, i, attr)
146 if (strcmp (XSTR (attr, 0), XSTR (exp, 0)) == 0) 123 if (strcmp (XSTR (attr, 0), XSTR (exp, 0)) == 0)
147 { 124 {
148 unsigned int j; 125 unsigned int j;
149 rtx resv; 126 rtx resv;
150 127
151 FOR_EACH_VEC_ELT (rtx, reservations, j, resv) 128 FOR_EACH_VEC_ELT (reservations, j, resv)
152 if (! check_tune_attr (XSTR (attr, 0), XEXP (resv, 2))) 129 if (! check_tune_attr (XSTR (attr, 0), XEXP (resv, 2)))
153 return false; 130 return false;
154 return true; 131 return true;
155 } 132 }
156 return false; 133 return false;
159 return false; 136 return false;
160 } 137 }
161 } 138 }
162 139
163 int 140 int
164 main (int argc, char **argv) 141 main (int argc, const char **argv)
165 { 142 {
166 rtx desc; 143 bool have_annul_true = false;
167 int have_delay = 0; 144 bool have_annul_false = false;
168 int have_annul_true = 0;
169 int have_annul_false = 0;
170 int num_insn_reservations = 0; 145 int num_insn_reservations = 0;
171 int i; 146 int i;
172 147
173 progname = "genattr"; 148 progname = "genattr";
174 149
178 puts ("/* Generated automatically by the program `genattr'"); 153 puts ("/* Generated automatically by the program `genattr'");
179 puts (" from the machine description file `md'. */\n"); 154 puts (" from the machine description file `md'. */\n");
180 puts ("#ifndef GCC_INSN_ATTR_H"); 155 puts ("#ifndef GCC_INSN_ATTR_H");
181 puts ("#define GCC_INSN_ATTR_H\n"); 156 puts ("#define GCC_INSN_ATTR_H\n");
182 157
183 /* For compatibility, define the attribute `alternative', which is just 158 puts ("#include \"insn-attr-common.h\"\n");
184 a reference to the variable `which_alternative'. */
185
186 puts ("#define HAVE_ATTR_alternative");
187 puts ("#define get_attr_alternative(insn) which_alternative");
188 159
189 /* Read the machine description. */ 160 /* Read the machine description. */
190 161
191 while (1) 162 md_rtx_info info;
192 { 163 while (read_md_rtx (&info))
193 int line_no, insn_code_number; 164 {
194 165 rtx def = info.def;
195 desc = read_md_rtx (&line_no, &insn_code_number); 166 switch (GET_CODE (def))
196 if (desc == NULL) 167 {
197 break; 168 case DEFINE_ATTR:
198 169 case DEFINE_ENUM_ATTR:
199 if (GET_CODE (desc) == DEFINE_ATTR 170 gen_attr (&info);
200 || GET_CODE (desc) == DEFINE_ENUM_ATTR) 171 break;
201 gen_attr (desc); 172
202 173 case DEFINE_DELAY:
203 else if (GET_CODE (desc) == DEFINE_DELAY) 174 for (i = 0; i < XVECLEN (def, 1); i += 3)
204 {
205 if (! have_delay)
206 { 175 {
207 printf ("#define DELAY_SLOTS\n"); 176 if (XVECEXP (def, 1, i + 1))
208 printf ("extern int num_delay_slots (rtx);\n"); 177 have_annul_true = true;
209 printf ("extern int eligible_for_delay (rtx, int, rtx, int);\n\n"); 178
210 printf ("extern int const_num_delay_slots (rtx);\n\n"); 179 if (XVECEXP (def, 1, i + 2))
211 have_delay = 1; 180 have_annul_false = true;
212 } 181 }
213 182 break;
214 for (i = 0; i < XVECLEN (desc, 1); i += 3) 183
215 { 184 case DEFINE_INSN_RESERVATION:
216 if (XVECEXP (desc, 1, i + 1) && ! have_annul_true)
217 {
218 printf ("#define ANNUL_IFTRUE_SLOTS\n");
219 printf ("extern int eligible_for_annul_true (rtx, int, rtx, int);\n");
220 have_annul_true = 1;
221 }
222
223 if (XVECEXP (desc, 1, i + 2) && ! have_annul_false)
224 {
225 printf ("#define ANNUL_IFFALSE_SLOTS\n");
226 printf ("extern int eligible_for_annul_false (rtx, int, rtx, int);\n");
227 have_annul_false = 1;
228 }
229 }
230 }
231
232 else if (GET_CODE (desc) == DEFINE_INSN_RESERVATION)
233 {
234 num_insn_reservations++; 185 num_insn_reservations++;
235 VEC_safe_push (rtx, heap, reservations, desc); 186 reservations.safe_push (def);
187 break;
188
189 default:
190 break;
236 } 191 }
237 } 192 }
238 193
194 printf ("extern int num_delay_slots (rtx_insn *);\n");
195 printf ("extern int eligible_for_delay (rtx_insn *, int, rtx_insn *, int);\n\n");
196 printf ("extern int const_num_delay_slots (rtx_insn *);\n\n");
197 printf ("#define ANNUL_IFTRUE_SLOTS %d\n", have_annul_true);
198 printf ("extern int eligible_for_annul_true (rtx_insn *, int, rtx_insn *, int);\n");
199 printf ("#define ANNUL_IFFALSE_SLOTS %d\n", have_annul_false);
200 printf ("extern int eligible_for_annul_false (rtx_insn *, int, rtx_insn *, int);\n");
201
239 if (num_insn_reservations > 0) 202 if (num_insn_reservations > 0)
240 { 203 {
241 bool has_tune_attr 204 bool has_tune_attr
242 = find_tune_attr (XEXP (VEC_index (rtx, reservations, 0), 2)); 205 = find_tune_attr (XEXP (reservations[0], 2));
243 /* Output interface for pipeline hazards recognition based on 206 /* Output interface for pipeline hazards recognition based on
244 DFA (deterministic finite state automata. */ 207 DFA (deterministic finite state automata. */
245 printf ("\n#define INSN_SCHEDULING\n");
246 printf ("\n/* DFA based pipeline interface. */"); 208 printf ("\n/* DFA based pipeline interface. */");
247 printf ("\n#ifndef AUTOMATON_ALTS\n"); 209 printf ("\n#ifndef AUTOMATON_ALTS\n");
248 printf ("#define AUTOMATON_ALTS 0\n"); 210 printf ("#define AUTOMATON_ALTS 0\n");
249 printf ("#endif\n\n"); 211 printf ("#endif\n\n");
250 printf ("\n#ifndef AUTOMATON_STATE_ALTS\n"); 212 printf ("\n#ifndef AUTOMATON_STATE_ALTS\n");
258 { 220 {
259 printf ("/* Initialize fn pointers for internal_dfa_insn_code\n"); 221 printf ("/* Initialize fn pointers for internal_dfa_insn_code\n");
260 printf (" and insn_default_latency. */\n"); 222 printf (" and insn_default_latency. */\n");
261 printf ("extern void init_sched_attrs (void);\n\n"); 223 printf ("extern void init_sched_attrs (void);\n\n");
262 printf ("/* Internal insn code number used by automata. */\n"); 224 printf ("/* Internal insn code number used by automata. */\n");
263 printf ("extern int (*internal_dfa_insn_code) (rtx);\n\n"); 225 printf ("extern int (*internal_dfa_insn_code) (rtx_insn *);\n\n");
264 printf ("/* Insn latency time defined in define_insn_reservation. */\n"); 226 printf ("/* Insn latency time defined in define_insn_reservation. */\n");
265 printf ("extern int (*insn_default_latency) (rtx);\n\n"); 227 printf ("extern int (*insn_default_latency) (rtx_insn *);\n\n");
266 } 228 }
267 else 229 else
268 { 230 {
269 printf ("#define init_sched_attrs() do { } while (0)\n\n"); 231 printf ("#define init_sched_attrs() do { } while (0)\n\n");
270 printf ("/* Internal insn code number used by automata. */\n"); 232 printf ("/* Internal insn code number used by automata. */\n");
271 printf ("extern int internal_dfa_insn_code (rtx);\n\n"); 233 printf ("extern int internal_dfa_insn_code (rtx_insn *);\n\n");
272 printf ("/* Insn latency time defined in define_insn_reservation. */\n"); 234 printf ("/* Insn latency time defined in define_insn_reservation. */\n");
273 printf ("extern int insn_default_latency (rtx);\n\n"); 235 printf ("extern int insn_default_latency (rtx_insn *);\n\n");
274 } 236 }
275 printf ("/* Return nonzero if there is a bypass for given insn\n"); 237 printf ("/* Return nonzero if there is a bypass for given insn\n");
276 printf (" which is a data producer. */\n"); 238 printf (" which is a data producer. */\n");
277 printf ("extern int bypass_p (rtx);\n\n"); 239 printf ("extern int bypass_p (rtx_insn *);\n\n");
278 printf ("/* Insn latency time on data consumed by the 2nd insn.\n"); 240 printf ("/* Insn latency time on data consumed by the 2nd insn.\n");
279 printf (" Use the function if bypass_p returns nonzero for\n"); 241 printf (" Use the function if bypass_p returns nonzero for\n");
280 printf (" the 1st insn. */\n"); 242 printf (" the 1st insn. */\n");
281 printf ("extern int insn_latency (rtx, rtx);\n\n"); 243 printf ("extern int insn_latency (rtx_insn *, rtx_insn *);\n\n");
282 printf ("/* Maximal insn latency time possible of all bypasses for this insn.\n"); 244 printf ("/* Maximal insn latency time possible of all bypasses for this insn.\n");
283 printf (" Use the function if bypass_p returns nonzero for\n"); 245 printf (" Use the function if bypass_p returns nonzero for\n");
284 printf (" the 1st insn. */\n"); 246 printf (" the 1st insn. */\n");
285 printf ("extern int maximal_insn_latency (rtx);\n\n"); 247 printf ("extern int maximal_insn_latency (rtx_insn *);\n\n");
286 printf ("\n#if AUTOMATON_ALTS\n"); 248 printf ("\n#if AUTOMATON_ALTS\n");
287 printf ("/* The following function returns number of alternative\n"); 249 printf ("/* The following function returns number of alternative\n");
288 printf (" reservations of given insn. It may be used for better\n"); 250 printf (" reservations of given insn. It may be used for better\n");
289 printf (" insns scheduling heuristics. */\n"); 251 printf (" insns scheduling heuristics. */\n");
290 printf ("extern int insn_alts (rtx);\n\n"); 252 printf ("extern int insn_alts (rtx);\n\n");
316 printf (" heuristics. By default the function is defined if\n"); 278 printf (" heuristics. By default the function is defined if\n");
317 printf (" macro AUTOMATON_STATE_ALTS is defined because its\n"); 279 printf (" macro AUTOMATON_STATE_ALTS is defined because its\n");
318 printf (" implementation may require much memory. */\n"); 280 printf (" implementation may require much memory. */\n");
319 printf ("extern int state_alts (state_t, rtx);\n"); 281 printf ("extern int state_alts (state_t, rtx);\n");
320 printf ("#endif\n\n"); 282 printf ("#endif\n\n");
321 printf ("extern int min_issue_delay (state_t, rtx);\n"); 283 printf ("extern int min_issue_delay (state_t, rtx_insn *);\n");
322 printf ("/* The following function returns nonzero if no one insn\n"); 284 printf ("/* The following function returns nonzero if no one insn\n");
323 printf (" can be issued in current DFA state. */\n"); 285 printf (" can be issued in current DFA state. */\n");
324 printf ("extern int state_dead_lock_p (state_t);\n"); 286 printf ("extern int state_dead_lock_p (state_t);\n");
325 printf ("/* The function returns minimal delay of issue of the 2nd\n"); 287 printf ("/* The function returns minimal delay of issue of the 2nd\n");
326 printf (" insn after issuing the 1st insn in given DFA state.\n"); 288 printf (" insn after issuing the 1st insn in given DFA state.\n");
327 printf (" The 1st insn should be issued in given state (i.e.\n"); 289 printf (" The 1st insn should be issued in given state (i.e.\n");
328 printf (" state_transition should return negative value for\n"); 290 printf (" state_transition should return negative value for\n");
329 printf (" the insn and the state). Data dependencies between\n"); 291 printf (" the insn and the state). Data dependencies between\n");
330 printf (" the insns are ignored by the function. */\n"); 292 printf (" the insns are ignored by the function. */\n");
331 printf 293 printf ("extern int "
332 ("extern int min_insn_conflict_delay (state_t, rtx, rtx);\n"); 294 "min_insn_conflict_delay (state_t, rtx_insn *, rtx_insn *);\n");
333 printf ("/* The following function outputs reservations for given\n"); 295 printf ("/* The following function outputs reservations for given\n");
334 printf (" insn as they are described in the corresponding\n"); 296 printf (" insn as they are described in the corresponding\n");
335 printf (" define_insn_reservation. */\n"); 297 printf (" define_insn_reservation. */\n");
336 printf ("extern void print_reservation (FILE *, rtx);\n"); 298 printf ("extern void print_reservation (FILE *, rtx_insn *);\n");
337 printf ("\n#if CPU_UNITS_QUERY\n"); 299 printf ("\n#if CPU_UNITS_QUERY\n");
338 printf ("/* The following function returns code of functional unit\n"); 300 printf ("/* The following function returns code of functional unit\n");
339 printf (" with given name (see define_cpu_unit). */\n"); 301 printf (" with given name (see define_cpu_unit). */\n");
340 printf ("extern int get_cpu_unit_code (const char *);\n"); 302 printf ("extern int get_cpu_unit_code (const char *);\n");
341 printf ("/* The following function returns nonzero if functional\n"); 303 printf ("/* The following function returns nonzero if functional\n");
343 printf (" DFA state. */\n"); 305 printf (" DFA state. */\n");
344 printf ("extern int cpu_unit_reservation_p (state_t, int);\n"); 306 printf ("extern int cpu_unit_reservation_p (state_t, int);\n");
345 printf ("#endif\n\n"); 307 printf ("#endif\n\n");
346 printf ("/* The following function returns true if insn\n"); 308 printf ("/* The following function returns true if insn\n");
347 printf (" has a dfa reservation. */\n"); 309 printf (" has a dfa reservation. */\n");
348 printf ("extern bool insn_has_dfa_reservation_p (rtx);\n\n"); 310 printf ("extern bool insn_has_dfa_reservation_p (rtx_insn *);\n\n");
349 printf ("/* Clean insn code cache. It should be called if there\n"); 311 printf ("/* Clean insn code cache. It should be called if there\n");
350 printf (" is a chance that condition value in a\n"); 312 printf (" is a chance that condition value in a\n");
351 printf (" define_insn_reservation will be changed after\n"); 313 printf (" define_insn_reservation will be changed after\n");
352 printf (" last call of dfa_start. */\n"); 314 printf (" last call of dfa_start. */\n");
353 printf ("extern void dfa_clean_insn_cache (void);\n\n"); 315 printf ("extern void dfa_clean_insn_cache (void);\n\n");
354 printf ("extern void dfa_clear_single_insn_cache (rtx);\n\n"); 316 printf ("extern void dfa_clear_single_insn_cache (rtx_insn *);\n\n");
355 printf ("/* Initiate and finish work with DFA. They should be\n"); 317 printf ("/* Initiate and finish work with DFA. They should be\n");
356 printf (" called as the first and the last interface\n"); 318 printf (" called as the first and the last interface\n");
357 printf (" functions. */\n"); 319 printf (" functions. */\n");
358 printf ("extern void dfa_start (void);\n"); 320 printf ("extern void dfa_start (void);\n");
359 printf ("extern void dfa_finish (void);\n"); 321 printf ("extern void dfa_finish (void);\n");
363 /* Otherwise we do no scheduling, but we need these typedefs 325 /* Otherwise we do no scheduling, but we need these typedefs
364 in order to avoid uglifying other code with more ifdefs. */ 326 in order to avoid uglifying other code with more ifdefs. */
365 printf ("typedef void *state_t;\n\n"); 327 printf ("typedef void *state_t;\n\n");
366 } 328 }
367 329
330 /* Special-purpose attributes should be tested with if, not #ifdef. */
331 const char * const special_attrs[] = { "length", "enabled",
332 "preferred_for_size",
333 "preferred_for_speed", 0 };
334 for (const char * const *p = special_attrs; *p; p++)
335 {
336 printf ("#ifndef HAVE_ATTR_%s\n"
337 "#define HAVE_ATTR_%s 0\n"
338 "#endif\n", *p, *p);
339 }
340 /* We make an exception here to provide stub definitions for
341 insn_*_length* / get_attr_enabled functions. */
342 puts ("#if !HAVE_ATTR_length\n"
343 "extern int hook_int_rtx_insn_unreachable (rtx_insn *);\n"
344 "#define insn_default_length hook_int_rtx_insn_unreachable\n"
345 "#define insn_min_length hook_int_rtx_insn_unreachable\n"
346 "#define insn_variable_length_p hook_int_rtx_insn_unreachable\n"
347 "#define insn_current_length hook_int_rtx_insn_unreachable\n"
348 "#include \"insn-addr.h\"\n"
349 "#endif\n"
350 "extern int hook_int_rtx_1 (rtx);\n"
351 "#if !HAVE_ATTR_enabled\n"
352 "#define get_attr_enabled hook_int_rtx_1\n"
353 "#endif\n"
354 "#if !HAVE_ATTR_preferred_for_size\n"
355 "#define get_attr_preferred_for_size hook_int_rtx_1\n"
356 "#endif\n"
357 "#if !HAVE_ATTR_preferred_for_speed\n"
358 "#define get_attr_preferred_for_speed hook_int_rtx_1\n"
359 "#endif\n");
360
368 /* Output flag masks for use by reorg. 361 /* Output flag masks for use by reorg.
369 362
370 Flags are used to hold branch direction and prediction information 363 Flags are used to hold branch direction for use by eligible_for_... */
371 for use by eligible_for_... */ 364 printf ("\n#define ATTR_FLAG_forward\t0x1\n");
372 printf("\n#define ATTR_FLAG_forward\t0x1\n"); 365 printf ("#define ATTR_FLAG_backward\t0x2\n");
373 printf("#define ATTR_FLAG_backward\t0x2\n"); 366
374 printf("#define ATTR_FLAG_likely\t0x4\n"); 367 puts ("\n#endif /* GCC_INSN_ATTR_H */");
375 printf("#define ATTR_FLAG_very_likely\t0x8\n");
376 printf("#define ATTR_FLAG_unlikely\t0x10\n");
377 printf("#define ATTR_FLAG_very_unlikely\t0x20\n");
378
379 puts("\n#endif /* GCC_INSN_ATTR_H */");
380 368
381 if (ferror (stdout) || fflush (stdout) || fclose (stdout)) 369 if (ferror (stdout) || fflush (stdout) || fclose (stdout))
382 return FATAL_EXIT_CODE; 370 return FATAL_EXIT_CODE;
383 371
384 return SUCCESS_EXIT_CODE; 372 return SUCCESS_EXIT_CODE;