1/* Support routines for the various generation passes. 2 Copyright (C) 2000, 2001, 2002, 2003, 2004, 2005 3 Free Software Foundation, Inc. 4 5 This file is part of GCC. 6 7 GCC is free software; you can redistribute it and/or modify it 8 under the terms of the GNU General Public License as published by 9 the Free Software Foundation; either version 2, or (at your option) 10 any later version. 11 12 GCC is distributed in the hope that it will be useful, but WITHOUT 13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15 License for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with GCC; see the file COPYING. If not, write to the Free 19 Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 20 02110-1301, USA. */ 21 22#include "bconfig.h" 23#include "system.h" 24#include "coretypes.h" 25#include "tm.h" 26#include "rtl.h" 27#include "obstack.h" 28#include "errors.h" 29#include "hashtab.h" 30#include "gensupport.h" 31 32 33/* In case some macros used by files we include need it, define this here. */ 34int target_flags; 35 36int insn_elision = 1; 37 38const char *in_fname; 39 40/* This callback will be invoked whenever an rtl include directive is 41 processed. To be used for creation of the dependency file. */ 42void (*include_callback) (const char *); 43 44static struct obstack obstack; 45struct obstack *rtl_obstack = &obstack; 46 47static int sequence_num; 48static int errors; 49 50static int predicable_default; 51static const char *predicable_true; 52static const char *predicable_false; 53 54static htab_t condition_table; 55 56static char *base_dir = NULL; 57 58/* We initially queue all patterns, process the define_insn and 59 define_cond_exec patterns, then return them one at a time. */ 60 61struct queue_elem 62{ 63 rtx data; 64 const char *filename; 65 int lineno; 66 struct queue_elem *next; 67 /* In a DEFINE_INSN that came from a DEFINE_INSN_AND_SPLIT, SPLIT 68 points to the generated DEFINE_SPLIT. */ 69 struct queue_elem *split; 70}; 71 72static struct queue_elem *define_attr_queue; 73static struct queue_elem **define_attr_tail = &define_attr_queue; 74static struct queue_elem *define_pred_queue; 75static struct queue_elem **define_pred_tail = &define_pred_queue; 76static struct queue_elem *define_insn_queue; 77static struct queue_elem **define_insn_tail = &define_insn_queue; 78static struct queue_elem *define_cond_exec_queue; 79static struct queue_elem **define_cond_exec_tail = &define_cond_exec_queue; 80static struct queue_elem *other_queue; 81static struct queue_elem **other_tail = &other_queue; 82 83static struct queue_elem *queue_pattern (rtx, struct queue_elem ***, 84 const char *, int); 85 86/* Current maximum length of directory names in the search path 87 for include files. (Altered as we get more of them.) */ 88 89size_t max_include_len; 90 91struct file_name_list 92 { 93 struct file_name_list *next; 94 const char *fname; 95 }; 96 97struct file_name_list *first_dir_md_include = 0; /* First dir to search */ 98 /* First dir to search for <file> */ 99struct file_name_list *first_bracket_include = 0; 100struct file_name_list *last_dir_md_include = 0; /* Last in chain */ 101 102static void remove_constraints (rtx); 103static void process_rtx (rtx, int); 104 105static int is_predicable (struct queue_elem *); 106static void identify_predicable_attribute (void); 107static int n_alternatives (const char *); 108static void collect_insn_data (rtx, int *, int *); 109static rtx alter_predicate_for_insn (rtx, int, int, int); 110static const char *alter_test_for_insn (struct queue_elem *, 111 struct queue_elem *); 112static char *shift_output_template (char *, const char *, int); 113static const char *alter_output_for_insn (struct queue_elem *, 114 struct queue_elem *, 115 int, int); 116static void process_one_cond_exec (struct queue_elem *); 117static void process_define_cond_exec (void); 118static void process_include (rtx, int); 119static char *save_string (const char *, int); 120static void init_predicate_table (void); 121 122void 123message_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 137 the gensupport programs. */ 138 139rtx 140gen_rtx_CONST_INT (enum machine_mode ARG_UNUSED (mode), 141 HOST_WIDE_INT arg) 142{ 143 rtx rt = rtx_alloc (CONST_INT); 144 145 XWINT (rt, 0) = arg; 146 return rt; 147} 148 149/* Queue PATTERN on LIST_TAIL. Return the address of the new queue 150 element. */ 151 152static struct queue_elem * 153queue_pattern (rtx pattern, struct queue_elem ***list_tail, 154 const char *filename, int lineno) 155{ 156 struct queue_elem *e = XNEW(struct queue_elem); 157 e->data = pattern; 158 e->filename = filename; 159 e->lineno = lineno; 160 e->next = NULL; 161 e->split = NULL; 162 **list_tail = e; 163 *list_tail = &e->next; 164 return e; 165} 166 167/* Recursively remove constraints from an rtx. */ 168 169static void 170remove_constraints (rtx part) 171{ 172 int i, j; 173 const char *format_ptr; 174 175 if (part == 0) 176 return; 177 178 if (GET_CODE (part) == MATCH_OPERAND) 179 XSTR (part, 2) = ""; 180 else if (GET_CODE (part) == MATCH_SCRATCH) 181 XSTR (part, 1) = ""; 182 183 format_ptr = GET_RTX_FORMAT (GET_CODE (part)); 184 185 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++) 186 switch (*format_ptr++) 187 { 188 case 'e': 189 case 'u': 190 remove_constraints (XEXP (part, i)); 191 break; 192 case 'E': 193 if (XVEC (part, i) != NULL) 194 for (j = 0; j < XVECLEN (part, i); j++) 195 remove_constraints (XVECEXP (part, i, j)); 196 break; 197 } 198} 199 200/* Process an include file assuming that it lives in gcc/config/{target}/ 201 if the include looks like (include "file"). */ 202 203static void 204process_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. */ 269 270static void 271process_rtx (rtx desc, int lineno) 272{ 273 switch (GET_CODE (desc)) 274 { 275 case DEFINE_INSN: 276 queue_pattern (desc, &define_insn_tail, read_rtx_filename, lineno); 277 break; 278 279 case DEFINE_COND_EXEC: 280 queue_pattern (desc, &define_cond_exec_tail, read_rtx_filename, lineno); 281 break; 282 283 case DEFINE_ATTR: 284 queue_pattern (desc, &define_attr_tail, read_rtx_filename, lineno); 285 break; 286 287 case DEFINE_PREDICATE: 288 case DEFINE_SPECIAL_PREDICATE: 289 queue_pattern (desc, &define_pred_tail, read_rtx_filename, lineno); 290 break; 291 292 case INCLUDE: 293 process_include (desc, lineno); 294 break; 295 296 case DEFINE_INSN_AND_SPLIT: 297 { 298 const char *split_cond; 299 rtx split; 300 rtvec attr; 301 int i; 302 struct queue_elem *insn_elem; 303 struct queue_elem *split_elem; 304 305 /* Create a split with values from the insn_and_split. */ 306 split = rtx_alloc (DEFINE_SPLIT); 307 308 i = XVECLEN (desc, 1); 309 XVEC (split, 0) = rtvec_alloc (i); 310 while (--i >= 0) 311 { 312 XVECEXP (split, 0, i) = copy_rtx (XVECEXP (desc, 1, i)); 313 remove_constraints (XVECEXP (split, 0, i)); 314 } 315 316 /* If the split condition starts with "&&", append it to the 317 insn condition to create the new split condition. */ 318 split_cond = XSTR (desc, 4); 319 if (split_cond[0] == '&' && split_cond[1] == '&') 320 { 321 copy_rtx_ptr_loc (split_cond + 2, split_cond); 322 split_cond = join_c_conditions (XSTR (desc, 2), split_cond + 2); 323 } 324 XSTR (split, 1) = split_cond; 325 XVEC (split, 2) = XVEC (desc, 5); 326 XSTR (split, 3) = XSTR (desc, 6); 327 328 /* Fix up the DEFINE_INSN. */ 329 attr = XVEC (desc, 7); 330 PUT_CODE (desc, DEFINE_INSN); 331 XVEC (desc, 4) = attr; 332 333 /* Queue them. */ 334 insn_elem 335 = queue_pattern (desc, &define_insn_tail, read_rtx_filename, 336 lineno); 337 split_elem 338 = queue_pattern (split, &other_tail, read_rtx_filename, lineno); 339 insn_elem->split = split_elem; 340 break; 341 } 342 343 default: 344 queue_pattern (desc, &other_tail, read_rtx_filename, lineno); 345 break; 346 } 347} 348 349/* Return true if attribute PREDICABLE is true for ELEM, which holds 350 a DEFINE_INSN. */ 351 352static int 353is_predicable (struct queue_elem *elem) 354{ 355 rtvec vec = XVEC (elem->data, 4); 356 const char *value; 357 int i; 358 359 if (! vec) 360 return predicable_default; 361 362 for (i = GET_NUM_ELEM (vec) - 1; i >= 0; --i) 363 { 364 rtx sub = RTVEC_ELT (vec, i); 365 switch (GET_CODE (sub)) 366 { 367 case SET_ATTR: 368 if (strcmp (XSTR (sub, 0), "predicable") == 0) 369 { 370 value = XSTR (sub, 1); 371 goto found; 372 } 373 break; 374 375 case SET_ATTR_ALTERNATIVE: 376 if (strcmp (XSTR (sub, 0), "predicable") == 0) 377 { 378 message_with_line (elem->lineno, 379 "multiple alternatives for `predicable'"); 380 errors = 1; 381 return 0; 382 } 383 break; 384 385 case SET: 386 if (GET_CODE (SET_DEST (sub)) != ATTR 387 || strcmp (XSTR (SET_DEST (sub), 0), "predicable") != 0) 388 break; 389 sub = SET_SRC (sub); 390 if (GET_CODE (sub) == CONST_STRING) 391 { 392 value = XSTR (sub, 0); 393 goto found; 394 } 395 396 /* ??? It would be possible to handle this if we really tried. 397 It's not easy though, and I'm not going to bother until it 398 really proves necessary. */ 399 message_with_line (elem->lineno, 400 "non-constant value for `predicable'"); 401 errors = 1; 402 return 0; 403 404 default: 405 gcc_unreachable (); 406 } 407 } 408 409 return predicable_default; 410 411 found: 412 /* Verify that predicability does not vary on the alternative. */ 413 /* ??? It should be possible to handle this by simply eliminating 414 the non-predicable alternatives from the insn. FRV would like 415 to do this. Delay this until we've got the basics solid. */ 416 if (strchr (value, ',') != NULL) 417 { 418 message_with_line (elem->lineno, 419 "multiple alternatives for `predicable'"); 420 errors = 1; 421 return 0; 422 } 423 424 /* Find out which value we're looking at. */ 425 if (strcmp (value, predicable_true) == 0) 426 return 1; 427 if (strcmp (value, predicable_false) == 0) 428 return 0; 429 430 message_with_line (elem->lineno, 431 "unknown value `%s' for `predicable' attribute", 432 value); 433 errors = 1; 434 return 0; 435} 436 437/* Examine the attribute "predicable"; discover its boolean values 438 and its default. */ 439 440static void 441identify_predicable_attribute (void) 442{ 443 struct queue_elem *elem; 444 char *p_true, *p_false; 445 const char *value; 446 447 /* Look for the DEFINE_ATTR for `predicable', which must exist. */ 448 for (elem = define_attr_queue; elem ; elem = elem->next) 449 if (strcmp (XSTR (elem->data, 0), "predicable") == 0) 450 goto found; 451 452 message_with_line (define_cond_exec_queue->lineno, 453 "attribute `predicable' not defined"); 454 errors = 1; 455 return; 456 457 found: 458 value = XSTR (elem->data, 1); 459 p_false = xstrdup (value); 460 p_true = strchr (p_false, ','); 461 if (p_true == NULL || strchr (++p_true, ',') != NULL) 462 { 463 message_with_line (elem->lineno, 464 "attribute `predicable' is not a boolean"); 465 errors = 1; 466 return; 467 } 468 p_true[-1] = '\0'; 469 470 predicable_true = p_true; 471 predicable_false = p_false; 472 473 switch (GET_CODE (XEXP (elem->data, 2))) 474 { 475 case CONST_STRING: 476 value = XSTR (XEXP (elem->data, 2), 0); 477 break; 478 479 case CONST: 480 message_with_line (elem->lineno, 481 "attribute `predicable' cannot be const"); 482 errors = 1; 483 return; 484 485 default: 486 message_with_line (elem->lineno, 487 "attribute `predicable' must have a constant default"); 488 errors = 1; 489 return; 490 } 491 492 if (strcmp (value, p_true) == 0) 493 predicable_default = 1; 494 else if (strcmp (value, p_false) == 0) 495 predicable_default = 0; 496 else 497 { 498 message_with_line (elem->lineno, 499 "unknown value `%s' for `predicable' attribute", 500 value); 501 errors = 1; 502 } 503} 504 505/* Return the number of alternatives in constraint S. */ 506 507static int 508n_alternatives (const char *s) 509{ 510 int n = 1; 511 512 if (s) 513 while (*s) 514 n += (*s++ == ','); 515 516 return n; 517} 518 519/* Determine how many alternatives there are in INSN, and how many 520 operands. */ 521 522static void 523collect_insn_data (rtx pattern, int *palt, int *pmax) 524{ 525 const char *fmt; 526 enum rtx_code code; 527 int i, j, len; 528 529 code = GET_CODE (pattern); 530 switch (code) 531 { 532 case MATCH_OPERAND: 533 i = n_alternatives (XSTR (pattern, 2)); 534 *palt = (i > *palt ? i : *palt); 535 /* Fall through. */ 536 537 case MATCH_OPERATOR: 538 case MATCH_SCRATCH: 539 case MATCH_PARALLEL: 540 i = XINT (pattern, 0); 541 if (i > *pmax) 542 *pmax = i; 543 break; 544 545 default: 546 break; 547 } 548 549 fmt = GET_RTX_FORMAT (code); 550 len = GET_RTX_LENGTH (code); 551 for (i = 0; i < len; i++) 552 { 553 switch (fmt[i]) 554 { 555 case 'e': case 'u': 556 collect_insn_data (XEXP (pattern, i), palt, pmax); 557 break; 558 559 case 'V': 560 if (XVEC (pattern, i) == NULL) 561 break; 562 /* Fall through. */ 563 case 'E': 564 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j) 565 collect_insn_data (XVECEXP (pattern, i, j), palt, pmax); 566 break; 567 568 case 'i': case 'w': case '0': case 's': case 'S': case 'T': 569 break; 570 571 default: 572 gcc_unreachable (); 573 } 574 } 575} 576 577static rtx 578alter_predicate_for_insn (rtx pattern, int alt, int max_op, int lineno) 579{ 580 const char *fmt; 581 enum rtx_code code; 582 int i, j, len; 583 584 code = GET_CODE (pattern); 585 switch (code) 586 { 587 case MATCH_OPERAND: 588 { 589 const char *c = XSTR (pattern, 2); 590 591 if (n_alternatives (c) != 1) 592 { 593 message_with_line (lineno, 594 "too many alternatives for operand %d", 595 XINT (pattern, 0)); 596 errors = 1; 597 return NULL; 598 } 599 600 /* Replicate C as needed to fill out ALT alternatives. */ 601 if (c && *c && alt > 1) 602 { 603 size_t c_len = strlen (c); 604 size_t len = alt * (c_len + 1); 605 char *new_c = XNEWVEC(char, len); 606 607 memcpy (new_c, c, c_len); 608 for (i = 1; i < alt; ++i) 609 { 610 new_c[i * (c_len + 1) - 1] = ','; 611 memcpy (&new_c[i * (c_len + 1)], c, c_len); 612 } 613 new_c[len - 1] = '\0'; 614 XSTR (pattern, 2) = new_c; 615 } 616 } 617 /* Fall through. */ 618 619 case MATCH_OPERATOR: 620 case MATCH_SCRATCH: 621 case MATCH_PARALLEL: 622 XINT (pattern, 0) += max_op; 623 break; 624 625 default: 626 break; 627 } 628 629 fmt = GET_RTX_FORMAT (code); 630 len = GET_RTX_LENGTH (code); 631 for (i = 0; i < len; i++) 632 { 633 rtx r; 634 635 switch (fmt[i]) 636 { 637 case 'e': case 'u': 638 r = alter_predicate_for_insn (XEXP (pattern, i), alt, 639 max_op, lineno); 640 if (r == NULL) 641 return r; 642 break; 643 644 case 'E': 645 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j) 646 { 647 r = alter_predicate_for_insn (XVECEXP (pattern, i, j), 648 alt, max_op, lineno); 649 if (r == NULL) 650 return r; 651 } 652 break; 653 654 case 'i': case 'w': case '0': case 's': 655 break; 656 657 default: 658 gcc_unreachable (); 659 } 660 } 661 662 return pattern; 663} 664 665static const char * 666alter_test_for_insn (struct queue_elem *ce_elem, 667 struct queue_elem *insn_elem) 668{ 669 return join_c_conditions (XSTR (ce_elem->data, 1), 670 XSTR (insn_elem->data, 2)); 671} 672 673/* Adjust all of the operand numbers in SRC to match the shift they'll 674 get from an operand displacement of DISP. Return a pointer after the 675 adjusted string. */ 676 677static char * 678shift_output_template (char *dest, const char *src, int disp) 679{ 680 while (*src) 681 { 682 char c = *src++; 683 *dest++ = c; 684 if (c == '%') 685 { 686 c = *src++; 687 if (ISDIGIT ((unsigned char) c)) 688 c += disp; 689 else if (ISALPHA (c)) 690 { 691 *dest++ = c; 692 c = *src++ + disp; 693 } 694 *dest++ = c; 695 } 696 } 697 698 return dest; 699} 700 701static const char * 702alter_output_for_insn (struct queue_elem *ce_elem, 703 struct queue_elem *insn_elem, 704 int alt, int max_op) 705{ 706 const char *ce_out, *insn_out; 707 char *result, *p; 708 size_t len, ce_len, insn_len; 709 710 /* ??? Could coordinate with genoutput to not duplicate code here. */ 711 712 ce_out = XSTR (ce_elem->data, 2); 713 insn_out = XTMPL (insn_elem->data, 3); 714 if (!ce_out || *ce_out == '\0') 715 return insn_out; 716 717 ce_len = strlen (ce_out); 718 insn_len = strlen (insn_out); 719 720 if (*insn_out == '*') 721 /* You must take care of the predicate yourself. */ 722 return insn_out; 723 724 if (*insn_out == '@') 725 { 726 len = (ce_len + 1) * alt + insn_len + 1; 727 p = result = XNEWVEC(char, len); 728 729 do 730 { 731 do 732 *p++ = *insn_out++; 733 while (ISSPACE ((unsigned char) *insn_out)); 734 735 if (*insn_out != '#') 736 { 737 p = shift_output_template (p, ce_out, max_op); 738 *p++ = ' '; 739 } 740 741 do 742 *p++ = *insn_out++; 743 while (*insn_out && *insn_out != '\n'); 744 } 745 while (*insn_out); 746 *p = '\0'; 747 } 748 else 749 { 750 len = ce_len + 1 + insn_len + 1; 751 result = XNEWVEC (char, len); 752 753 p = shift_output_template (result, ce_out, max_op); 754 *p++ = ' '; 755 memcpy (p, insn_out, insn_len + 1); 756 } 757 758 return result; 759} 760 761/* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */ 762 763static void 764process_one_cond_exec (struct queue_elem *ce_elem) 765{ 766 struct queue_elem *insn_elem; 767 for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next) 768 { 769 int alternatives, max_operand; 770 rtx pred, insn, pattern, split; 771 int i; 772 773 if (! is_predicable (insn_elem)) 774 continue; 775 776 alternatives = 1; 777 max_operand = -1; 778 collect_insn_data (insn_elem->data, &alternatives, &max_operand); 779 max_operand += 1; 780 781 if (XVECLEN (ce_elem->data, 0) != 1) 782 { 783 message_with_line (ce_elem->lineno, 784 "too many patterns in predicate"); 785 errors = 1; 786 return; 787 } 788 789 pred = copy_rtx (XVECEXP (ce_elem->data, 0, 0)); 790 pred = alter_predicate_for_insn (pred, alternatives, max_operand, 791 ce_elem->lineno); 792 if (pred == NULL) 793 return; 794 795 /* Construct a new pattern for the new insn. */ 796 insn = copy_rtx (insn_elem->data); 797 XSTR (insn, 0) = ""; 798 pattern = rtx_alloc (COND_EXEC); 799 XEXP (pattern, 0) = pred; 800 if (XVECLEN (insn, 1) == 1) 801 { 802 XEXP (pattern, 1) = XVECEXP (insn, 1, 0); 803 XVECEXP (insn, 1, 0) = pattern; 804 PUT_NUM_ELEM (XVEC (insn, 1), 1); 805 } 806 else 807 { 808 XEXP (pattern, 1) = rtx_alloc (PARALLEL); 809 XVEC (XEXP (pattern, 1), 0) = XVEC (insn, 1); 810 XVEC (insn, 1) = rtvec_alloc (1); 811 XVECEXP (insn, 1, 0) = pattern; 812 } 813 814 XSTR (insn, 2) = alter_test_for_insn (ce_elem, insn_elem); 815 XTMPL (insn, 3) = alter_output_for_insn (ce_elem, insn_elem, 816 alternatives, max_operand); 817 818 /* ??? Set `predicable' to false. Not crucial since it's really 819 only used here, and we won't reprocess this new pattern. */ 820 821 /* Put the new pattern on the `other' list so that it 822 (a) is not reprocessed by other define_cond_exec patterns 823 (b) appears after all normal define_insn patterns. 824 825 ??? B is debatable. If one has normal insns that match 826 cond_exec patterns, they will be preferred over these 827 generated patterns. Whether this matters in practice, or if 828 it's a good thing, or whether we should thread these new 829 patterns into the define_insn chain just after their generator 830 is something we'll have to experiment with. */ 831 832 queue_pattern (insn, &other_tail, insn_elem->filename, 833 insn_elem->lineno); 834 835 if (!insn_elem->split) 836 continue; 837 838 /* If the original insn came from a define_insn_and_split, 839 generate a new split to handle the predicated insn. */ 840 split = copy_rtx (insn_elem->split->data); 841 /* Predicate the pattern matched by the split. */ 842 pattern = rtx_alloc (COND_EXEC); 843 XEXP (pattern, 0) = pred; 844 if (XVECLEN (split, 0) == 1) 845 { 846 XEXP (pattern, 1) = XVECEXP (split, 0, 0); 847 XVECEXP (split, 0, 0) = pattern; 848 PUT_NUM_ELEM (XVEC (split, 0), 1); 849 } 850 else 851 { 852 XEXP (pattern, 1) = rtx_alloc (PARALLEL); 853 XVEC (XEXP (pattern, 1), 0) = XVEC (split, 0); 854 XVEC (split, 0) = rtvec_alloc (1); 855 XVECEXP (split, 0, 0) = pattern; 856 } 857 /* Predicate all of the insns generated by the split. */ 858 for (i = 0; i < XVECLEN (split, 2); i++) 859 { 860 pattern = rtx_alloc (COND_EXEC); 861 XEXP (pattern, 0) = pred; 862 XEXP (pattern, 1) = XVECEXP (split, 2, i); 863 XVECEXP (split, 2, i) = pattern; 864 } 865 /* Add the new split to the queue. */ 866 queue_pattern (split, &other_tail, read_rtx_filename, 867 insn_elem->split->lineno); 868 } 869} 870 871/* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN 872 patterns appropriately. */ 873 874static void 875process_define_cond_exec (void) 876{ 877 struct queue_elem *elem; 878 879 identify_predicable_attribute (); 880 if (errors) 881 return; 882 883 for (elem = define_cond_exec_queue; elem ; elem = elem->next) 884 process_one_cond_exec (elem); 885} 886 887static char * 888save_string (const char *s, int len) 889{ 890 char *result = XNEWVEC (char, len + 1); 891 892 memcpy (result, s, len); 893 result[len] = 0; 894 return result; 895} 896 897 898/* The entry point for initializing the reader. */ 899 900int 901init_md_reader_args_cb (int argc, char **argv, bool (*parse_opt)(const char *)) 902{ 903 FILE *input_file; 904 int i, lineno; 905 size_t ix; 906 char *lastsl; 907 rtx desc; 908 909 /* Unlock the stdio streams. */ 910 unlock_std_streams (); 911 912 for (i = 1; i < argc; i++) 913 { 914 if (argv[i][0] != '-') 915 { 916 if (in_fname) 917 fatal ("too many input files"); 918 919 in_fname = argv[i]; 920 } 921 else 922 { 923 int c = argv[i][1]; 924 switch (c) 925 { 926 case 'I': /* Add directory to path for includes. */ 927 { 928 struct file_name_list *dirtmp; 929 930 dirtmp = XNEW (struct file_name_list); 931 dirtmp->next = 0; /* New one goes on the end */ 932 if (first_dir_md_include == 0) 933 first_dir_md_include = dirtmp; 934 else 935 last_dir_md_include->next = dirtmp; 936 last_dir_md_include = dirtmp; /* Tail follows the last one */ 937 if (argv[i][1] == 'I' && argv[i][2] != 0) 938 dirtmp->fname = argv[i] + 2; 939 else if (i + 1 == argc) 940 fatal ("directory name missing after -I option"); 941 else 942 dirtmp->fname = argv[++i]; 943 if (strlen (dirtmp->fname) > max_include_len) 944 max_include_len = strlen (dirtmp->fname); 945 } 946 break; 947 default: 948 /* The program may have provided a callback so it can 949 accept its own options. */ 950 if (parse_opt && parse_opt (argv[i])) 951 break; 952 953 fatal ("invalid option `%s'", argv[i]); 954 } 955 } 956 } 957 958 if (!in_fname) 959 fatal ("no input file name"); 960 961 lastsl = strrchr (in_fname, '/'); 962 if (lastsl != NULL) 963 base_dir = save_string (in_fname, lastsl - in_fname + 1 ); 964 965 read_rtx_filename = in_fname; 966 input_file = fopen (in_fname, "r"); 967 if (input_file == 0) 968 { 969 perror (in_fname); 970 return FATAL_EXIT_CODE; 971 } 972 973 /* Initialize the table of insn conditions. */ 974 condition_table = htab_create (n_insn_conditions, 975 hash_c_test, cmp_c_test, NULL); 976 977 for (ix = 0; ix < n_insn_conditions; ix++) 978 *(htab_find_slot (condition_table, &insn_conditions[ix], INSERT)) 979 = (void *) &insn_conditions[ix]; 980 981 init_predicate_table (); 982 983 obstack_init (rtl_obstack); 984 errors = 0; 985 sequence_num = 0; 986 987 /* Read the entire file. */ 988 while (read_rtx (input_file, &desc, &lineno)) 989 process_rtx (desc, lineno); 990 fclose (input_file); 991 992 /* Process define_cond_exec patterns. */ 993 if (define_cond_exec_queue != NULL) 994 process_define_cond_exec (); 995 996 return errors ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE; 997} 998 999/* Programs that don't have their own options can use this entry point 1000 instead. */ 1001int 1002init_md_reader_args (int argc, char **argv) 1003{ 1004 return init_md_reader_args_cb (argc, argv, 0); 1005} 1006 1007/* The entry point for reading a single rtx from an md file. */ 1008 1009rtx 1010read_md_rtx (int *lineno, int *seqnr) 1011{ 1012 struct queue_elem **queue, *elem; 1013 rtx desc; 1014 1015 discard: 1016 1017 /* Read all patterns from a given queue before moving on to the next. */ 1018 if (define_attr_queue != NULL) 1019 queue = &define_attr_queue; 1020 else if (define_pred_queue != NULL) 1021 queue = &define_pred_queue; 1022 else if (define_insn_queue != NULL) 1023 queue = &define_insn_queue; 1024 else if (other_queue != NULL) 1025 queue = &other_queue; 1026 else 1027 return NULL_RTX; 1028 1029 elem = *queue; 1030 *queue = elem->next; 1031 desc = elem->data; 1032 read_rtx_filename = elem->filename; 1033 *lineno = elem->lineno; 1034 *seqnr = sequence_num; 1035 1036 free (elem); 1037 1038 /* Discard insn patterns which we know can never match (because 1039 their C test is provably always false). If insn_elision is 1040 false, our caller needs to see all the patterns. Note that the 1041 elided patterns are never counted by the sequence numbering; it 1042 it is the caller's responsibility, when insn_elision is false, not 1043 to use elided pattern numbers for anything. */ 1044 switch (GET_CODE (desc)) 1045 { 1046 case DEFINE_INSN: 1047 case DEFINE_EXPAND: 1048 if (maybe_eval_c_test (XSTR (desc, 2)) != 0) 1049 sequence_num++; 1050 else if (insn_elision) 1051 goto discard; 1052 break; 1053 1054 case DEFINE_SPLIT: 1055 case DEFINE_PEEPHOLE: 1056 case DEFINE_PEEPHOLE2: 1057 if (maybe_eval_c_test (XSTR (desc, 1)) != 0) 1058 sequence_num++; 1059 else if (insn_elision) 1060 goto discard; 1061 break; 1062 1063 default: 1064 break; 1065 } 1066 1067 return desc; 1068} 1069 1070/* Helper functions for insn elision. */ 1071 1072/* Compute a hash function of a c_test structure, which is keyed 1073 by its ->expr field. */ 1074hashval_t 1075hash_c_test (const void *x) 1076{ 1077 const struct c_test *a = (const struct c_test *) x; 1078 const unsigned char *base, *s = (const unsigned char *) a->expr; 1079 hashval_t hash; 1080 unsigned char c; 1081 unsigned int len; 1082 1083 base = s; 1084 hash = 0; 1085 1086 while ((c = *s++) != '\0') 1087 { 1088 hash += c + (c << 17); 1089 hash ^= hash >> 2; 1090 } 1091 1092 len = s - base; 1093 hash += len + (len << 17); 1094 hash ^= hash >> 2; 1095 1096 return hash; 1097} 1098 1099/* Compare two c_test expression structures. */ 1100int 1101cmp_c_test (const void *x, const void *y) 1102{ 1103 const struct c_test *a = (const struct c_test *) x; 1104 const struct c_test *b = (const struct c_test *) y; 1105 1106 return !strcmp (a->expr, b->expr); 1107} 1108 1109/* Given a string representing a C test expression, look it up in the 1110 condition_table and report whether or not its value is known 1111 at compile time. Returns a tristate: 1 for known true, 0 for 1112 known false, -1 for unknown. */ 1113int 1114maybe_eval_c_test (const char *expr) 1115{ 1116 const struct c_test *test; 1117 struct c_test dummy; 1118 1119 if (expr[0] == 0) 1120 return 1; 1121 1122 if (insn_elision_unavailable) 1123 return -1; 1124 1125 dummy.expr = expr; 1126 test = (const struct c_test *)htab_find (condition_table, &dummy); 1127 gcc_assert (test); 1128 1129 return test->value; 1130} 1131 1132/* Given a string, return the number of comma-separated elements in it. 1133 Return 0 for the null string. */ 1134int 1135n_comma_elts (const char *s) 1136{ 1137 int n; 1138 1139 if (*s == '\0') 1140 return 0; 1141 1142 for (n = 1; *s; s++) 1143 if (*s == ',') 1144 n++; 1145 1146 return n; 1147} 1148 1149/* Given a pointer to a (char *), return a pointer to the beginning of the 1150 next comma-separated element in the string. Advance the pointer given 1151 to the end of that element. Return NULL if at end of string. Caller 1152 is responsible for copying the string if necessary. White space between 1153 a comma and an element is ignored. */ 1154 1155const char * 1156scan_comma_elt (const char **pstr) 1157{ 1158 const char *start; 1159 const char *p = *pstr; 1160 1161 if (*p == ',') 1162 p++; 1163 while (ISSPACE(*p)) 1164 p++; 1165 1166 if (*p == '\0') 1167 return NULL; 1168 1169 start = p; 1170 1171 while (*p != ',' && *p != '\0') 1172 p++; 1173 1174 *pstr = p; 1175 return start; 1176} 1177 1178/* Helper functions for define_predicate and define_special_predicate 1179 processing. Shared between genrecog.c and genpreds.c. */ 1180 1181static htab_t predicate_table; 1182struct pred_data *first_predicate; 1183static struct pred_data **last_predicate = &first_predicate; 1184 1185static hashval_t 1186hash_struct_pred_data (const void *ptr) 1187{ 1188 return htab_hash_string (((const struct pred_data *)ptr)->name); 1189} 1190 1191static int 1192eq_struct_pred_data (const void *a, const void *b) 1193{ 1194 return !strcmp (((const struct pred_data *)a)->name, 1195 ((const struct pred_data *)b)->name); 1196} 1197 1198struct pred_data * 1199lookup_predicate (const char *name) 1200{ 1201 struct pred_data key; 1202 key.name = name; 1203 return htab_find (predicate_table, &key); 1204} 1205 1206void 1207add_predicate (struct pred_data *pred) 1208{ 1209 void **slot = htab_find_slot (predicate_table, pred, INSERT); 1210 if (*slot) 1211 { 1212 error ("duplicate predicate definition for '%s'", pred->name); 1213 return; 1214 } 1215 *slot = pred; 1216 *last_predicate = pred; 1217 last_predicate = &pred->next; 1218} 1219 1220/* This array gives the initial content of the predicate table. It 1221 has entries for all predicates defined in recog.c. */ 1222 1223struct old_pred_table 1224{ 1225 const char *name; 1226 RTX_CODE codes[NUM_RTX_CODE]; 1227}; 1228 1229static const struct old_pred_table old_preds[] = { 1230 {"general_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, 1231 LABEL_REF, SUBREG, REG, MEM }}, 1232 {"address_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, 1233 LABEL_REF, SUBREG, REG, MEM, 1234 PLUS, MINUS, MULT}}, 1235 {"register_operand", {SUBREG, REG}}, 1236 {"pmode_register_operand", {SUBREG, REG}}, 1237 {"scratch_operand", {SCRATCH, REG}}, 1238 {"immediate_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, 1239 LABEL_REF}}, 1240 {"const_int_operand", {CONST_INT}}, 1241 {"const_double_operand", {CONST_INT, CONST_DOUBLE}}, 1242 {"nonimmediate_operand", {SUBREG, REG, MEM}}, 1243 {"nonmemory_operand", {CONST_INT, CONST_DOUBLE, CONST, SYMBOL_REF, 1244 LABEL_REF, SUBREG, REG}}, 1245 {"push_operand", {MEM}}, 1246 {"pop_operand", {MEM}}, 1247 {"memory_operand", {SUBREG, MEM}}, 1248 {"indirect_operand", {SUBREG, MEM}}, 1249 {"comparison_operator", {EQ, NE, LE, LT, GE, GT, LEU, LTU, GEU, GTU, 1250 UNORDERED, ORDERED, UNEQ, UNGE, UNGT, UNLE, 1251 UNLT, LTGT}} 1252}; 1253#define NUM_KNOWN_OLD_PREDS ARRAY_SIZE (old_preds) 1254 1255/* This table gives the set of special predicates. It has entries for 1256 all special predicates defined in recog.c. */ 1257static const char *const old_special_pred_table[] = { 1258 "address_operand", 1259 "pmode_register_operand", 1260}; 1261 1262#define NUM_OLD_SPECIAL_MODE_PREDS ARRAY_SIZE (old_special_pred_table) 1263 1264/* Initialize the table of predicate definitions, starting with 1265 the information we have on generic predicates. */ 1266 1267static void 1268init_predicate_table (void) 1269{ 1270 size_t i, j; 1271 struct pred_data *pred; 1272 1273 predicate_table = htab_create_alloc (37, hash_struct_pred_data, 1274 eq_struct_pred_data, 0, 1275 xcalloc, free); 1276 1277 for (i = 0; i < NUM_KNOWN_OLD_PREDS; i++) 1278 { 1279 pred = xcalloc (sizeof (struct pred_data), 1); 1280 pred->name = old_preds[i].name; 1281 1282 for (j = 0; old_preds[i].codes[j] != 0; j++) 1283 { 1284 enum rtx_code code = old_preds[i].codes[j]; 1285 1286 pred->codes[code] = true; 1287 if (GET_RTX_CLASS (code) != RTX_CONST_OBJ) 1288 pred->allows_non_const = true; 1289 if (code != REG 1290 && code != SUBREG 1291 && code != MEM 1292 && code != CONCAT 1293 && code != PARALLEL 1294 && code != STRICT_LOW_PART) 1295 pred->allows_non_lvalue = true; 1296 } 1297 if (j == 1) 1298 pred->singleton = old_preds[i].codes[0]; 1299 1300 add_predicate (pred); 1301 } 1302 1303 for (i = 0; i < NUM_OLD_SPECIAL_MODE_PREDS; i++) 1304 { 1305 pred = lookup_predicate (old_special_pred_table[i]); 1306 if (!pred) 1307 { 1308 error ("old-style special predicate list refers " 1309 "to unknown predicate '%s'", old_special_pred_table[i]); 1310 continue; 1311 } 1312 pred->special = true; 1313 } 1314} 1315