comparison gcc/gensupport.c @ 67:f6334be47118

update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
author nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
date Tue, 22 Mar 2011 17:18:12 +0900
parents b7f97abdc517
children 04ced10e8804
comparison
equal deleted inserted replaced
65:65488c3d617d 67:f6334be47118
24 #include "tm.h" 24 #include "tm.h"
25 #include "rtl.h" 25 #include "rtl.h"
26 #include "obstack.h" 26 #include "obstack.h"
27 #include "errors.h" 27 #include "errors.h"
28 #include "hashtab.h" 28 #include "hashtab.h"
29 #include "read-md.h"
29 #include "gensupport.h" 30 #include "gensupport.h"
30 31
31 32
32 /* In case some macros used by files we include need it, define this here. */ 33 /* In case some macros used by files we include need it, define this here. */
33 int target_flags; 34 int target_flags;
34 35
35 int insn_elision = 1; 36 int insn_elision = 1;
36 37
37 const char *in_fname;
38
39 /* This callback will be invoked whenever an rtl include directive is
40 processed. To be used for creation of the dependency file. */
41 void (*include_callback) (const char *);
42
43 static struct obstack obstack; 38 static struct obstack obstack;
44 struct obstack *rtl_obstack = &obstack; 39 struct obstack *rtl_obstack = &obstack;
45 40
46 static int sequence_num; 41 static int sequence_num;
47 static int errors;
48 42
49 static int predicable_default; 43 static int predicable_default;
50 static const char *predicable_true; 44 static const char *predicable_true;
51 static const char *predicable_false; 45 static const char *predicable_false;
52 46
53 static htab_t condition_table; 47 static htab_t condition_table;
54
55 static char *base_dir = NULL;
56 48
57 /* We initially queue all patterns, process the define_insn and 49 /* We initially queue all patterns, process the define_insn and
58 define_cond_exec patterns, then return them one at a time. */ 50 define_cond_exec patterns, then return them one at a time. */
59 51
60 struct queue_elem 52 struct queue_elem
65 struct queue_elem *next; 57 struct queue_elem *next;
66 /* In a DEFINE_INSN that came from a DEFINE_INSN_AND_SPLIT, SPLIT 58 /* In a DEFINE_INSN that came from a DEFINE_INSN_AND_SPLIT, SPLIT
67 points to the generated DEFINE_SPLIT. */ 59 points to the generated DEFINE_SPLIT. */
68 struct queue_elem *split; 60 struct queue_elem *split;
69 }; 61 };
62
63 #define MNEMONIC_ATTR_NAME "mnemonic"
64 #define MNEMONIC_HTAB_SIZE 1024
70 65
71 static struct queue_elem *define_attr_queue; 66 static struct queue_elem *define_attr_queue;
72 static struct queue_elem **define_attr_tail = &define_attr_queue; 67 static struct queue_elem **define_attr_tail = &define_attr_queue;
73 static struct queue_elem *define_pred_queue; 68 static struct queue_elem *define_pred_queue;
74 static struct queue_elem **define_pred_tail = &define_pred_queue; 69 static struct queue_elem **define_pred_tail = &define_pred_queue;
79 static struct queue_elem *other_queue; 74 static struct queue_elem *other_queue;
80 static struct queue_elem **other_tail = &other_queue; 75 static struct queue_elem **other_tail = &other_queue;
81 76
82 static struct queue_elem *queue_pattern (rtx, struct queue_elem ***, 77 static struct queue_elem *queue_pattern (rtx, struct queue_elem ***,
83 const char *, int); 78 const char *, int);
84
85 /* Current maximum length of directory names in the search path
86 for include files. (Altered as we get more of them.) */
87
88 size_t max_include_len;
89
90 struct file_name_list
91 {
92 struct file_name_list *next;
93 const char *fname;
94 };
95
96 struct file_name_list *first_dir_md_include = 0; /* First dir to search */
97 /* First dir to search for <file> */
98 struct file_name_list *first_bracket_include = 0;
99 struct file_name_list *last_dir_md_include = 0; /* Last in chain */
100 79
101 static void remove_constraints (rtx); 80 static void remove_constraints (rtx);
102 static void process_rtx (rtx, int); 81 static void process_rtx (rtx, int);
103 82
104 static int is_predicable (struct queue_elem *); 83 static int is_predicable (struct queue_elem *);
112 static const char *alter_output_for_insn (struct queue_elem *, 91 static const char *alter_output_for_insn (struct queue_elem *,
113 struct queue_elem *, 92 struct queue_elem *,
114 int, int); 93 int, int);
115 static void process_one_cond_exec (struct queue_elem *); 94 static void process_one_cond_exec (struct queue_elem *);
116 static void process_define_cond_exec (void); 95 static void process_define_cond_exec (void);
117 static void process_include (rtx, int);
118 static char *save_string (const char *, int);
119 static void init_predicate_table (void); 96 static void init_predicate_table (void);
120 static void record_insn_name (int, const char *); 97 static void record_insn_name (int, const char *);
121 98
122 void
123 message_with_line (int lineno, const char *msg, ...)
124 {
125 va_list ap;
126
127 va_start (ap, msg);
128
129 fprintf (stderr, "%s:%d: ", read_rtx_filename, lineno);
130 vfprintf (stderr, msg, ap);
131 fputc ('\n', stderr);
132
133 va_end (ap);
134 }
135
136 /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in 99 /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in
137 the gensupport programs. */ 100 the gensupport programs. */
138 101
139 rtx 102 rtx
140 gen_rtx_CONST_INT (enum machine_mode ARG_UNUSED (mode), 103 gen_rtx_CONST_INT (enum machine_mode ARG_UNUSED (mode),
195 remove_constraints (XVECEXP (part, i, j)); 158 remove_constraints (XVECEXP (part, i, j));
196 break; 159 break;
197 } 160 }
198 } 161 }
199 162
200 /* Process an include file assuming that it lives in gcc/config/{target}/
201 if the include looks like (include "file"). */
202
203 static void
204 process_include (rtx desc, int lineno)
205 {
206 const char *filename = XSTR (desc, 0);
207 const char *old_filename;
208 int old_lineno;
209 char *pathname;
210 FILE *input_file;
211
212 /* If specified file name is absolute, skip the include stack. */
213 if (! IS_ABSOLUTE_PATH (filename))
214 {
215 struct file_name_list *stackp;
216
217 /* Search directory path, trying to open the file. */
218 for (stackp = first_dir_md_include; stackp; stackp = stackp->next)
219 {
220 static const char sep[2] = { DIR_SEPARATOR, '\0' };
221
222 pathname = concat (stackp->fname, sep, filename, NULL);
223 input_file = fopen (pathname, "r");
224 if (input_file != NULL)
225 goto success;
226 free (pathname);
227 }
228 }
229
230 if (base_dir)
231 pathname = concat (base_dir, filename, NULL);
232 else
233 pathname = xstrdup (filename);
234 input_file = fopen (pathname, "r");
235 if (input_file == NULL)
236 {
237 free (pathname);
238 message_with_line (lineno, "include file `%s' not found", filename);
239 errors = 1;
240 return;
241 }
242 success:
243
244 /* Save old cursor; setup new for the new file. Note that "lineno" the
245 argument to this function is the beginning of the include statement,
246 while read_rtx_lineno has already been advanced. */
247 old_filename = read_rtx_filename;
248 old_lineno = read_rtx_lineno;
249 read_rtx_filename = pathname;
250 read_rtx_lineno = 1;
251
252 if (include_callback)
253 include_callback (pathname);
254
255 /* Read the entire file. */
256 while (read_rtx (input_file, &desc, &lineno))
257 process_rtx (desc, lineno);
258
259 /* Do not free pathname. It is attached to the various rtx queue
260 elements. */
261
262 read_rtx_filename = old_filename;
263 read_rtx_lineno = old_lineno;
264
265 fclose (input_file);
266 }
267
268 /* Process a top level rtx in some way, queuing as appropriate. */ 163 /* Process a top level rtx in some way, queuing as appropriate. */
269 164
270 static void 165 static void
271 process_rtx (rtx desc, int lineno) 166 process_rtx (rtx desc, int lineno)
272 { 167 {
273 switch (GET_CODE (desc)) 168 switch (GET_CODE (desc))
274 { 169 {
275 case DEFINE_INSN: 170 case DEFINE_INSN:
276 queue_pattern (desc, &define_insn_tail, read_rtx_filename, lineno); 171 queue_pattern (desc, &define_insn_tail, read_md_filename, lineno);
277 break; 172 break;
278 173
279 case DEFINE_COND_EXEC: 174 case DEFINE_COND_EXEC:
280 queue_pattern (desc, &define_cond_exec_tail, read_rtx_filename, lineno); 175 queue_pattern (desc, &define_cond_exec_tail, read_md_filename, lineno);
281 break; 176 break;
282 177
283 case DEFINE_ATTR: 178 case DEFINE_ATTR:
284 queue_pattern (desc, &define_attr_tail, read_rtx_filename, lineno); 179 case DEFINE_ENUM_ATTR:
180 queue_pattern (desc, &define_attr_tail, read_md_filename, lineno);
285 break; 181 break;
286 182
287 case DEFINE_PREDICATE: 183 case DEFINE_PREDICATE:
288 case DEFINE_SPECIAL_PREDICATE: 184 case DEFINE_SPECIAL_PREDICATE:
289 case DEFINE_CONSTRAINT: 185 case DEFINE_CONSTRAINT:
290 case DEFINE_REGISTER_CONSTRAINT: 186 case DEFINE_REGISTER_CONSTRAINT:
291 case DEFINE_MEMORY_CONSTRAINT: 187 case DEFINE_MEMORY_CONSTRAINT:
292 case DEFINE_ADDRESS_CONSTRAINT: 188 case DEFINE_ADDRESS_CONSTRAINT:
293 queue_pattern (desc, &define_pred_tail, read_rtx_filename, lineno); 189 queue_pattern (desc, &define_pred_tail, read_md_filename, lineno);
294 break;
295
296 case INCLUDE:
297 process_include (desc, lineno);
298 break; 190 break;
299 191
300 case DEFINE_INSN_AND_SPLIT: 192 case DEFINE_INSN_AND_SPLIT:
301 { 193 {
302 const char *split_cond; 194 const char *split_cond;
320 /* If the split condition starts with "&&", append it to the 212 /* If the split condition starts with "&&", append it to the
321 insn condition to create the new split condition. */ 213 insn condition to create the new split condition. */
322 split_cond = XSTR (desc, 4); 214 split_cond = XSTR (desc, 4);
323 if (split_cond[0] == '&' && split_cond[1] == '&') 215 if (split_cond[0] == '&' && split_cond[1] == '&')
324 { 216 {
325 copy_rtx_ptr_loc (split_cond + 2, split_cond); 217 copy_md_ptr_loc (split_cond + 2, split_cond);
326 split_cond = join_c_conditions (XSTR (desc, 2), split_cond + 2); 218 split_cond = join_c_conditions (XSTR (desc, 2), split_cond + 2);
327 } 219 }
328 XSTR (split, 1) = split_cond; 220 XSTR (split, 1) = split_cond;
329 XVEC (split, 2) = XVEC (desc, 5); 221 XVEC (split, 2) = XVEC (desc, 5);
330 XSTR (split, 3) = XSTR (desc, 6); 222 XSTR (split, 3) = XSTR (desc, 6);
334 PUT_CODE (desc, DEFINE_INSN); 226 PUT_CODE (desc, DEFINE_INSN);
335 XVEC (desc, 4) = attr; 227 XVEC (desc, 4) = attr;
336 228
337 /* Queue them. */ 229 /* Queue them. */
338 insn_elem 230 insn_elem
339 = queue_pattern (desc, &define_insn_tail, read_rtx_filename, 231 = queue_pattern (desc, &define_insn_tail, read_md_filename,
340 lineno); 232 lineno);
341 split_elem 233 split_elem
342 = queue_pattern (split, &other_tail, read_rtx_filename, lineno); 234 = queue_pattern (split, &other_tail, read_md_filename, lineno);
343 insn_elem->split = split_elem; 235 insn_elem->split = split_elem;
344 break; 236 break;
345 } 237 }
346 238
347 default: 239 default:
348 queue_pattern (desc, &other_tail, read_rtx_filename, lineno); 240 queue_pattern (desc, &other_tail, read_md_filename, lineno);
349 break; 241 break;
350 } 242 }
351 } 243 }
352 244
353 /* Return true if attribute PREDICABLE is true for ELEM, which holds 245 /* Return true if attribute PREDICABLE is true for ELEM, which holds
377 break; 269 break;
378 270
379 case SET_ATTR_ALTERNATIVE: 271 case SET_ATTR_ALTERNATIVE:
380 if (strcmp (XSTR (sub, 0), "predicable") == 0) 272 if (strcmp (XSTR (sub, 0), "predicable") == 0)
381 { 273 {
382 message_with_line (elem->lineno, 274 error_with_line (elem->lineno,
383 "multiple alternatives for `predicable'"); 275 "multiple alternatives for `predicable'");
384 errors = 1;
385 return 0; 276 return 0;
386 } 277 }
387 break; 278 break;
388 279
389 case SET: 280 case SET:
398 } 289 }
399 290
400 /* ??? It would be possible to handle this if we really tried. 291 /* ??? It would be possible to handle this if we really tried.
401 It's not easy though, and I'm not going to bother until it 292 It's not easy though, and I'm not going to bother until it
402 really proves necessary. */ 293 really proves necessary. */
403 message_with_line (elem->lineno, 294 error_with_line (elem->lineno,
404 "non-constant value for `predicable'"); 295 "non-constant value for `predicable'");
405 errors = 1;
406 return 0; 296 return 0;
407 297
408 default: 298 default:
409 gcc_unreachable (); 299 gcc_unreachable ();
410 } 300 }
417 /* ??? It should be possible to handle this by simply eliminating 307 /* ??? It should be possible to handle this by simply eliminating
418 the non-predicable alternatives from the insn. FRV would like 308 the non-predicable alternatives from the insn. FRV would like
419 to do this. Delay this until we've got the basics solid. */ 309 to do this. Delay this until we've got the basics solid. */
420 if (strchr (value, ',') != NULL) 310 if (strchr (value, ',') != NULL)
421 { 311 {
422 message_with_line (elem->lineno, 312 error_with_line (elem->lineno, "multiple alternatives for `predicable'");
423 "multiple alternatives for `predicable'");
424 errors = 1;
425 return 0; 313 return 0;
426 } 314 }
427 315
428 /* Find out which value we're looking at. */ 316 /* Find out which value we're looking at. */
429 if (strcmp (value, predicable_true) == 0) 317 if (strcmp (value, predicable_true) == 0)
430 return 1; 318 return 1;
431 if (strcmp (value, predicable_false) == 0) 319 if (strcmp (value, predicable_false) == 0)
432 return 0; 320 return 0;
433 321
434 message_with_line (elem->lineno, 322 error_with_line (elem->lineno,
435 "unknown value `%s' for `predicable' attribute", 323 "unknown value `%s' for `predicable' attribute", value);
436 value);
437 errors = 1;
438 return 0; 324 return 0;
439 } 325 }
440 326
441 /* Examine the attribute "predicable"; discover its boolean values 327 /* Examine the attribute "predicable"; discover its boolean values
442 and its default. */ 328 and its default. */
451 /* Look for the DEFINE_ATTR for `predicable', which must exist. */ 337 /* Look for the DEFINE_ATTR for `predicable', which must exist. */
452 for (elem = define_attr_queue; elem ; elem = elem->next) 338 for (elem = define_attr_queue; elem ; elem = elem->next)
453 if (strcmp (XSTR (elem->data, 0), "predicable") == 0) 339 if (strcmp (XSTR (elem->data, 0), "predicable") == 0)
454 goto found; 340 goto found;
455 341
456 message_with_line (define_cond_exec_queue->lineno, 342 error_with_line (define_cond_exec_queue->lineno,
457 "attribute `predicable' not defined"); 343 "attribute `predicable' not defined");
458 errors = 1;
459 return; 344 return;
460 345
461 found: 346 found:
462 value = XSTR (elem->data, 1); 347 value = XSTR (elem->data, 1);
463 p_false = xstrdup (value); 348 p_false = xstrdup (value);
464 p_true = strchr (p_false, ','); 349 p_true = strchr (p_false, ',');
465 if (p_true == NULL || strchr (++p_true, ',') != NULL) 350 if (p_true == NULL || strchr (++p_true, ',') != NULL)
466 { 351 {
467 message_with_line (elem->lineno, 352 error_with_line (elem->lineno, "attribute `predicable' is not a boolean");
468 "attribute `predicable' is not a boolean");
469 errors = 1;
470 if (p_false) 353 if (p_false)
471 free (p_false); 354 free (p_false);
472 return; 355 return;
473 } 356 }
474 p_true[-1] = '\0'; 357 p_true[-1] = '\0';
481 case CONST_STRING: 364 case CONST_STRING:
482 value = XSTR (XEXP (elem->data, 2), 0); 365 value = XSTR (XEXP (elem->data, 2), 0);
483 break; 366 break;
484 367
485 case CONST: 368 case CONST:
486 message_with_line (elem->lineno, 369 error_with_line (elem->lineno, "attribute `predicable' cannot be const");
487 "attribute `predicable' cannot be const");
488 errors = 1;
489 if (p_false) 370 if (p_false)
490 free (p_false); 371 free (p_false);
491 return; 372 return;
492 373
493 default: 374 default:
494 message_with_line (elem->lineno, 375 error_with_line (elem->lineno,
495 "attribute `predicable' must have a constant default"); 376 "attribute `predicable' must have a constant default");
496 errors = 1;
497 if (p_false) 377 if (p_false)
498 free (p_false); 378 free (p_false);
499 return; 379 return;
500 } 380 }
501 381
503 predicable_default = 1; 383 predicable_default = 1;
504 else if (strcmp (value, p_false) == 0) 384 else if (strcmp (value, p_false) == 0)
505 predicable_default = 0; 385 predicable_default = 0;
506 else 386 else
507 { 387 {
508 message_with_line (elem->lineno, 388 error_with_line (elem->lineno,
509 "unknown value `%s' for `predicable' attribute", 389 "unknown value `%s' for `predicable' attribute", value);
510 value);
511 errors = 1;
512 if (p_false) 390 if (p_false)
513 free (p_false); 391 free (p_false);
514 } 392 }
515 } 393 }
516 394
600 { 478 {
601 const char *c = XSTR (pattern, 2); 479 const char *c = XSTR (pattern, 2);
602 480
603 if (n_alternatives (c) != 1) 481 if (n_alternatives (c) != 1)
604 { 482 {
605 message_with_line (lineno, 483 error_with_line (lineno, "too many alternatives for operand %d",
606 "too many alternatives for operand %d", 484 XINT (pattern, 0));
607 XINT (pattern, 0));
608 errors = 1;
609 return NULL; 485 return NULL;
610 } 486 }
611 487
612 /* Replicate C as needed to fill out ALT alternatives. */ 488 /* Replicate C as needed to fill out ALT alternatives. */
613 if (c && *c && alt > 1) 489 if (c && *c && alt > 1)
791 collect_insn_data (insn_elem->data, &alternatives, &max_operand); 667 collect_insn_data (insn_elem->data, &alternatives, &max_operand);
792 max_operand += 1; 668 max_operand += 1;
793 669
794 if (XVECLEN (ce_elem->data, 0) != 1) 670 if (XVECLEN (ce_elem->data, 0) != 1)
795 { 671 {
796 message_with_line (ce_elem->lineno, 672 error_with_line (ce_elem->lineno, "too many patterns in predicate");
797 "too many patterns in predicate");
798 errors = 1;
799 return; 673 return;
800 } 674 }
801 675
802 pred = copy_rtx (XVECEXP (ce_elem->data, 0, 0)); 676 pred = copy_rtx (XVECEXP (ce_elem->data, 0, 0));
803 pred = alter_predicate_for_insn (pred, alternatives, max_operand, 677 pred = alter_predicate_for_insn (pred, alternatives, max_operand,
876 XEXP (pattern, 0) = pred; 750 XEXP (pattern, 0) = pred;
877 XEXP (pattern, 1) = XVECEXP (split, 2, i); 751 XEXP (pattern, 1) = XVECEXP (split, 2, i);
878 XVECEXP (split, 2, i) = pattern; 752 XVECEXP (split, 2, i) = pattern;
879 } 753 }
880 /* Add the new split to the queue. */ 754 /* Add the new split to the queue. */
881 queue_pattern (split, &other_tail, read_rtx_filename, 755 queue_pattern (split, &other_tail, read_md_filename,
882 insn_elem->split->lineno); 756 insn_elem->split->lineno);
883 } 757 }
884 } 758 }
885 759
886 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN 760 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN
890 process_define_cond_exec (void) 764 process_define_cond_exec (void)
891 { 765 {
892 struct queue_elem *elem; 766 struct queue_elem *elem;
893 767
894 identify_predicable_attribute (); 768 identify_predicable_attribute ();
895 if (errors) 769 if (have_error)
896 return; 770 return;
897 771
898 for (elem = define_cond_exec_queue; elem ; elem = elem->next) 772 for (elem = define_cond_exec_queue; elem ; elem = elem->next)
899 process_one_cond_exec (elem); 773 process_one_cond_exec (elem);
900 } 774 }
901
902 static char *
903 save_string (const char *s, int len)
904 {
905 char *result = XNEWVEC (char, len + 1);
906
907 memcpy (result, s, len);
908 result[len] = 0;
909 return result;
910 }
911
912 775
776 /* A read_md_files callback for reading an rtx. */
777
778 static void
779 rtx_handle_directive (int lineno, const char *rtx_name)
780 {
781 rtx queue, x;
782
783 if (read_rtx (rtx_name, &queue))
784 for (x = queue; x; x = XEXP (x, 1))
785 process_rtx (XEXP (x, 0), lineno);
786 }
787
788 /* Comparison function for the mnemonic hash table. */
789
790 static int
791 htab_eq_string (const void *s1, const void *s2)
792 {
793 return strcmp ((const char*)s1, (const char*)s2) == 0;
794 }
795
796 /* Add mnemonic STR with length LEN to the mnemonic hash table
797 MNEMONIC_HTAB. A trailing zero end character is appendend to STR
798 and a permanent heap copy of STR is created. */
799
800 static void
801 add_mnemonic_string (htab_t mnemonic_htab, const char *str, int len)
802 {
803 char *new_str;
804 void **slot;
805 char *str_zero = (char*)alloca (len + 1);
806
807 memcpy (str_zero, str, len);
808 str_zero[len] = '\0';
809
810 slot = htab_find_slot (mnemonic_htab, str_zero, INSERT);
811
812 if (*slot)
813 return;
814
815 /* Not found; create a permanent copy and add it to the hash table. */
816 new_str = XNEWVAR (char, len + 1);
817 memcpy (new_str, str_zero, len + 1);
818 *slot = new_str;
819 }
820
821 /* Scan INSN for mnemonic strings and add them to the mnemonic hash
822 table in MNEMONIC_HTAB.
823
824 The mnemonics cannot be found if they are emitted using C code.
825
826 If a mnemonic string contains ';' or a newline the string assumed
827 to consist of more than a single instruction. The attribute value
828 will then be set to the user defined default value. */
829
830 static void
831 gen_mnemonic_setattr (htab_t mnemonic_htab, rtx insn)
832 {
833 const char *template_code, *cp;
834 int i;
835 int vec_len;
836 rtx set_attr;
837 char *attr_name;
838 rtvec new_vec;
839
840 template_code = XTMPL (insn, 3);
841
842 /* Skip patterns which use C code to emit the template. */
843 if (template_code[0] == '*')
844 return;
845
846 if (template_code[0] == '@')
847 cp = &template_code[1];
848 else
849 cp = &template_code[0];
850
851 for (i = 0; *cp; )
852 {
853 const char *ep, *sp;
854 int size = 0;
855
856 while (ISSPACE (*cp))
857 cp++;
858
859 for (ep = sp = cp; !IS_VSPACE (*ep) && *ep != '\0'; ++ep)
860 if (!ISSPACE (*ep))
861 sp = ep + 1;
862
863 if (i > 0)
864 obstack_1grow (&string_obstack, ',');
865
866 while (cp < sp && ((*cp >= '0' && *cp <= '9')
867 || (*cp >= 'a' && *cp <= 'z')))
868
869 {
870 obstack_1grow (&string_obstack, *cp);
871 cp++;
872 size++;
873 }
874
875 while (cp < sp)
876 {
877 if (*cp == ';' || (*cp == '\\' && cp[1] == 'n'))
878 {
879 /* Don't set a value if there are more than one
880 instruction in the string. */
881 obstack_next_free (&string_obstack) =
882 obstack_next_free (&string_obstack) - size;
883 size = 0;
884
885 cp = sp;
886 break;
887 }
888 cp++;
889 }
890 if (size == 0)
891 obstack_1grow (&string_obstack, '*');
892 else
893 add_mnemonic_string (mnemonic_htab,
894 obstack_next_free (&string_obstack) - size,
895 size);
896 i++;
897 }
898
899 /* An insn definition might emit an empty string. */
900 if (obstack_object_size (&string_obstack) == 0)
901 return;
902
903 obstack_1grow (&string_obstack, '\0');
904
905 set_attr = rtx_alloc (SET_ATTR);
906 XSTR (set_attr, 1) = XOBFINISH (&string_obstack, char *);
907 attr_name = XNEWVAR (char, strlen (MNEMONIC_ATTR_NAME) + 1);
908 strcpy (attr_name, MNEMONIC_ATTR_NAME);
909 XSTR (set_attr, 0) = attr_name;
910
911 if (!XVEC (insn, 4))
912 vec_len = 0;
913 else
914 vec_len = XVECLEN (insn, 4);
915
916 new_vec = rtvec_alloc (vec_len + 1);
917 for (i = 0; i < vec_len; i++)
918 RTVEC_ELT (new_vec, i) = XVECEXP (insn, 4, i);
919 RTVEC_ELT (new_vec, vec_len) = set_attr;
920 XVEC (insn, 4) = new_vec;
921 }
922
923 /* This function is called for the elements in the mnemonic hashtable
924 and generates a comma separated list of the mnemonics. */
925
926 static int
927 mnemonic_htab_callback (void **slot, void *info ATTRIBUTE_UNUSED)
928 {
929 obstack_grow (&string_obstack, (char*)*slot, strlen ((char*)*slot));
930 obstack_1grow (&string_obstack, ',');
931 return 1;
932 }
933
934 /* Generate (set_attr "mnemonic" "..") RTXs and append them to every
935 insn definition in case the back end requests it by defining the
936 mnemonic attribute. The values for the attribute will be extracted
937 from the output patterns of the insn definitions as far as
938 possible. */
939
940 static void
941 gen_mnemonic_attr (void)
942 {
943 struct queue_elem *elem;
944 rtx mnemonic_attr = NULL;
945 htab_t mnemonic_htab;
946 const char *str, *p;
947 int i;
948
949 if (have_error)
950 return;
951
952 /* Look for the DEFINE_ATTR for `mnemonic'. */
953 for (elem = define_attr_queue; elem != *define_attr_tail; elem = elem->next)
954 if (GET_CODE (elem->data) == DEFINE_ATTR
955 && strcmp (XSTR (elem->data, 0), MNEMONIC_ATTR_NAME) == 0)
956 {
957 mnemonic_attr = elem->data;
958 break;
959 }
960
961 /* A (define_attr "mnemonic" "...") indicates that the back-end
962 wants a mnemonic attribute to be generated. */
963 if (!mnemonic_attr)
964 return;
965
966 mnemonic_htab = htab_create_alloc (MNEMONIC_HTAB_SIZE, htab_hash_string,
967 htab_eq_string, 0, xcalloc, free);
968
969 for (elem = define_insn_queue; elem; elem = elem->next)
970 {
971 rtx insn = elem->data;
972 bool found = false;
973
974 /* Check if the insn definition already has
975 (set_attr "mnemonic" ...). */
976 if (XVEC (insn, 4))
977 for (i = 0; i < XVECLEN (insn, 4); i++)
978 if (strcmp (XSTR (XVECEXP (insn, 4, i), 0), MNEMONIC_ATTR_NAME) == 0)
979 {
980 found = true;
981 break;
982 }
983
984 if (!found)
985 gen_mnemonic_setattr (mnemonic_htab, insn);
986 }
987
988 /* Add the user defined values to the hash table. */
989 str = XSTR (mnemonic_attr, 1);
990 while ((p = scan_comma_elt (&str)) != NULL)
991 add_mnemonic_string (mnemonic_htab, p, str - p);
992
993 htab_traverse (mnemonic_htab, mnemonic_htab_callback, NULL);
994
995 /* Replace the last ',' with the zero end character. */
996 *((char *)obstack_next_free (&string_obstack) - 1) = '\0';
997 XSTR (mnemonic_attr, 1) = XOBFINISH (&string_obstack, char *);
998 }
999
913 /* The entry point for initializing the reader. */ 1000 /* The entry point for initializing the reader. */
914 1001
915 int 1002 bool
916 init_md_reader_args_cb (int argc, char **argv, bool (*parse_opt)(const char *)) 1003 init_rtx_reader_args_cb (int argc, char **argv,
917 { 1004 bool (*parse_opt) (const char *))
918 FILE *input_file; 1005 {
919 int c, i, lineno;
920 char *lastsl;
921 rtx desc;
922 bool no_more_options;
923 bool already_read_stdin;
924
925 /* Unlock the stdio streams. */
926 unlock_std_streams ();
927
928 /* First we loop over all the options. */
929 for (i = 1; i < argc; i++)
930 {
931 if (argv[i][0] != '-')
932 continue;
933
934 c = argv[i][1];
935 switch (c)
936 {
937 case 'I': /* Add directory to path for includes. */
938 {
939 struct file_name_list *dirtmp;
940
941 dirtmp = XNEW (struct file_name_list);
942 dirtmp->next = 0; /* New one goes on the end */
943 if (first_dir_md_include == 0)
944 first_dir_md_include = dirtmp;
945 else
946 last_dir_md_include->next = dirtmp;
947 last_dir_md_include = dirtmp; /* Tail follows the last one */
948 if (argv[i][1] == 'I' && argv[i][2] != 0)
949 dirtmp->fname = argv[i] + 2;
950 else if (i + 1 == argc)
951 fatal ("directory name missing after -I option");
952 else
953 dirtmp->fname = argv[++i];
954 if (strlen (dirtmp->fname) > max_include_len)
955 max_include_len = strlen (dirtmp->fname);
956 }
957 break;
958
959 case '\0':
960 /* An argument consisting of exactly one dash is a request to
961 read stdin. This will be handled in the second loop. */
962 continue;
963
964 case '-':
965 /* An argument consisting of just two dashes causes option
966 parsing to cease. */
967 if (argv[i][2] == '\0')
968 goto stop_parsing_options;
969
970 default:
971 /* The program may have provided a callback so it can
972 accept its own options. */
973 if (parse_opt && parse_opt (argv[i]))
974 break;
975
976 fatal ("invalid option `%s'", argv[i]);
977 }
978 }
979
980 stop_parsing_options:
981
982 /* Prepare to read input. */ 1006 /* Prepare to read input. */
983 condition_table = htab_create (500, hash_c_test, cmp_c_test, NULL); 1007 condition_table = htab_create (500, hash_c_test, cmp_c_test, NULL);
984 init_predicate_table (); 1008 init_predicate_table ();
985 obstack_init (rtl_obstack); 1009 obstack_init (rtl_obstack);
986 errors = 0;
987 sequence_num = 0; 1010 sequence_num = 0;
988 no_more_options = false; 1011
989 already_read_stdin = false; 1012 read_md_files (argc, argv, parse_opt, rtx_handle_directive);
990
991
992 /* Now loop over all input files. */
993 for (i = 1; i < argc; i++)
994 {
995 if (argv[i][0] == '-')
996 {
997 if (argv[i][1] == '\0')
998 {
999 /* Read stdin. */
1000 if (already_read_stdin)
1001 fatal ("cannot read standard input twice");
1002
1003 base_dir = NULL;
1004 read_rtx_filename = in_fname = "<stdin>";
1005 read_rtx_lineno = 1;
1006 input_file = stdin;
1007 already_read_stdin = true;
1008
1009 while (read_rtx (input_file, &desc, &lineno))
1010 process_rtx (desc, lineno);
1011 fclose (input_file);
1012 continue;
1013 }
1014 else if (argv[i][1] == '-' && argv[i][2] == '\0')
1015 {
1016 /* No further arguments are to be treated as options. */
1017 no_more_options = true;
1018 continue;
1019 }
1020 else if (!no_more_options)
1021 continue;
1022 }
1023
1024 /* If we get here we are looking at a non-option argument, i.e.
1025 a file to be processed. */
1026
1027 in_fname = argv[i];
1028 lastsl = strrchr (in_fname, '/');
1029 if (lastsl != NULL)
1030 base_dir = save_string (in_fname, lastsl - in_fname + 1 );
1031 else
1032 base_dir = NULL;
1033
1034 read_rtx_filename = in_fname;
1035 read_rtx_lineno = 1;
1036 input_file = fopen (in_fname, "r");
1037 if (input_file == 0)
1038 {
1039 perror (in_fname);
1040 return FATAL_EXIT_CODE;
1041 }
1042
1043 while (read_rtx (input_file, &desc, &lineno))
1044 process_rtx (desc, lineno);
1045 fclose (input_file);
1046 }
1047
1048 /* If we get to this point without having seen any files to process,
1049 read standard input now. */
1050 if (!in_fname)
1051 {
1052 base_dir = NULL;
1053 read_rtx_filename = in_fname = "<stdin>";
1054 read_rtx_lineno = 1;
1055 input_file = stdin;
1056
1057 while (read_rtx (input_file, &desc, &lineno))
1058 process_rtx (desc, lineno);
1059 fclose (input_file);
1060 }
1061 1013
1062 /* Process define_cond_exec patterns. */ 1014 /* Process define_cond_exec patterns. */
1063 if (define_cond_exec_queue != NULL) 1015 if (define_cond_exec_queue != NULL)
1064 process_define_cond_exec (); 1016 process_define_cond_exec ();
1065 1017
1066 return errors ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE; 1018 if (define_attr_queue != NULL)
1019 gen_mnemonic_attr ();
1020
1021 return !have_error;
1067 } 1022 }
1068 1023
1069 /* Programs that don't have their own options can use this entry point 1024 /* Programs that don't have their own options can use this entry point
1070 instead. */ 1025 instead. */
1071 int 1026 bool
1072 init_md_reader_args (int argc, char **argv) 1027 init_rtx_reader_args (int argc, char **argv)
1073 { 1028 {
1074 return init_md_reader_args_cb (argc, argv, 0); 1029 return init_rtx_reader_args_cb (argc, argv, 0);
1075 } 1030 }
1076 1031
1077 /* The entry point for reading a single rtx from an md file. */ 1032 /* The entry point for reading a single rtx from an md file. */
1078 1033
1079 rtx 1034 rtx
1097 return NULL_RTX; 1052 return NULL_RTX;
1098 1053
1099 elem = *queue; 1054 elem = *queue;
1100 *queue = elem->next; 1055 *queue = elem->next;
1101 desc = elem->data; 1056 desc = elem->data;
1102 read_rtx_filename = elem->filename; 1057 read_md_filename = elem->filename;
1103 *lineno = elem->lineno; 1058 *lineno = elem->lineno;
1104 *seqnr = sequence_num; 1059 *seqnr = sequence_num;
1105 1060
1106 free (elem); 1061 free (elem);
1107 1062
1223 void 1178 void
1224 traverse_c_tests (htab_trav callback, void *info) 1179 traverse_c_tests (htab_trav callback, void *info)
1225 { 1180 {
1226 if (condition_table) 1181 if (condition_table)
1227 htab_traverse (condition_table, callback, info); 1182 htab_traverse (condition_table, callback, info);
1228 }
1229
1230
1231 /* Given a string, return the number of comma-separated elements in it.
1232 Return 0 for the null string. */
1233 int
1234 n_comma_elts (const char *s)
1235 {
1236 int n;
1237
1238 if (*s == '\0')
1239 return 0;
1240
1241 for (n = 1; *s; s++)
1242 if (*s == ',')
1243 n++;
1244
1245 return n;
1246 }
1247
1248 /* Given a pointer to a (char *), return a pointer to the beginning of the
1249 next comma-separated element in the string. Advance the pointer given
1250 to the end of that element. Return NULL if at end of string. Caller
1251 is responsible for copying the string if necessary. White space between
1252 a comma and an element is ignored. */
1253
1254 const char *
1255 scan_comma_elt (const char **pstr)
1256 {
1257 const char *start;
1258 const char *p = *pstr;
1259
1260 if (*p == ',')
1261 p++;
1262 while (ISSPACE(*p))
1263 p++;
1264
1265 if (*p == '\0')
1266 return NULL;
1267
1268 start = p;
1269
1270 while (*p != ',' && *p != '\0')
1271 p++;
1272
1273 *pstr = p;
1274 return start;
1275 } 1183 }
1276 1184
1277 /* Helper functions for define_predicate and define_special_predicate 1185 /* Helper functions for define_predicate and define_special_predicate
1278 processing. Shared between genrecog.c and genpreds.c. */ 1186 processing. Shared between genrecog.c and genpreds.c. */
1279 1187