1 /* Support routines for the various generation passes. 2 Copyright (C) 2000-2017 Free Software Foundation, Inc. 3 4 This file is part of GCC. 5 6 GCC is free software; you can redistribute it and/or modify it 7 under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3, or (at your option) 9 any later version. 10 11 GCC is distributed in the hope that it will be useful, but WITHOUT 12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with GCC; see the file COPYING3. If not see 18 <http://www.gnu.org/licenses/>. */ 19 20 #include "bconfig.h" 21 #include "system.h" 22 #include "coretypes.h" 23 #include "tm.h" 24 #include "rtl.h" 25 #include "obstack.h" 26 #include "errors.h" 27 #include "read-md.h" 28 #include "gensupport.h" 29 #include "vec.h" 30 31 #define MAX_OPERANDS 40 32 33 static rtx operand_data[MAX_OPERANDS]; 34 static rtx match_operand_entries_in_pattern[MAX_OPERANDS]; 35 static char used_operands_numbers[MAX_OPERANDS]; 36 37 38 /* In case some macros used by files we include need it, define this here. */ 39 int target_flags; 40 41 int insn_elision = 1; 42 43 static struct obstack obstack; 44 struct obstack *rtl_obstack = &obstack; 45 46 /* Counter for named patterns and INSN_CODEs. */ 47 static int insn_sequence_num; 48 49 /* Counter for define_splits. */ 50 static int split_sequence_num; 51 52 /* Counter for define_peephole2s. */ 53 static int peephole2_sequence_num; 54 55 static int predicable_default; 56 static const char *predicable_true; 57 static const char *predicable_false; 58 59 static const char *subst_true = "yes"; 60 static const char *subst_false = "no"; 61 62 static htab_t condition_table; 63 64 /* We initially queue all patterns, process the define_insn, 65 define_cond_exec and define_subst patterns, then return 66 them one at a time. */ 67 68 struct queue_elem 69 { 70 rtx data; 71 file_location loc; 72 struct queue_elem *next; 73 /* In a DEFINE_INSN that came from a DEFINE_INSN_AND_SPLIT, SPLIT 74 points to the generated DEFINE_SPLIT. */ 75 struct queue_elem *split; 76 }; 77 78 #define MNEMONIC_ATTR_NAME "mnemonic" 79 #define MNEMONIC_HTAB_SIZE 1024 80 81 static struct queue_elem *define_attr_queue; 82 static struct queue_elem **define_attr_tail = &define_attr_queue; 83 static struct queue_elem *define_pred_queue; 84 static struct queue_elem **define_pred_tail = &define_pred_queue; 85 static struct queue_elem *define_insn_queue; 86 static struct queue_elem **define_insn_tail = &define_insn_queue; 87 static struct queue_elem *define_cond_exec_queue; 88 static struct queue_elem **define_cond_exec_tail = &define_cond_exec_queue; 89 static struct queue_elem *define_subst_queue; 90 static struct queue_elem **define_subst_tail = &define_subst_queue; 91 static struct queue_elem *other_queue; 92 static struct queue_elem **other_tail = &other_queue; 93 static struct queue_elem *define_subst_attr_queue; 94 static struct queue_elem **define_subst_attr_tail = &define_subst_attr_queue; 95 96 /* Mapping from DEFINE_* rtxes to their location in the source file. */ 97 static hash_map <rtx, file_location> *rtx_locs; 98 99 static void remove_constraints (rtx); 100 101 static int is_predicable (struct queue_elem *); 102 static void identify_predicable_attribute (void); 103 static int n_alternatives (const char *); 104 static void collect_insn_data (rtx, int *, int *); 105 static const char *alter_test_for_insn (struct queue_elem *, 106 struct queue_elem *); 107 static char *shift_output_template (char *, const char *, int); 108 static const char *alter_output_for_insn (struct queue_elem *, 109 struct queue_elem *, 110 int, int); 111 static void process_one_cond_exec (struct queue_elem *); 112 static void process_define_cond_exec (void); 113 static void init_predicate_table (void); 114 static void record_insn_name (int, const char *); 115 116 static bool has_subst_attribute (struct queue_elem *, struct queue_elem *); 117 static const char * alter_output_for_subst_insn (rtx, int); 118 static void alter_attrs_for_subst_insn (struct queue_elem *, int); 119 static void process_substs_on_one_elem (struct queue_elem *, 120 struct queue_elem *); 121 static rtx subst_dup (rtx, int, int); 122 static void process_define_subst (void); 123 124 static const char * duplicate_alternatives (const char *, int); 125 static const char * duplicate_each_alternative (const char * str, int n_dup); 126 127 typedef const char * (*constraints_handler_t) (const char *, int); 128 static rtx alter_constraints (rtx, int, constraints_handler_t); 129 static rtx adjust_operands_numbers (rtx); 130 static rtx replace_duplicating_operands_in_pattern (rtx); 131 132 /* Make a version of gen_rtx_CONST_INT so that GEN_INT can be used in 133 the gensupport programs. */ 134 135 rtx 136 gen_rtx_CONST_INT (machine_mode ARG_UNUSED (mode), 137 HOST_WIDE_INT arg) 138 { 139 rtx rt = rtx_alloc (CONST_INT); 140 141 XWINT (rt, 0) = arg; 142 return rt; 143 } 144 145 /* Return the rtx pattern specified by the list of rtxes in a 146 define_insn or define_split. */ 147 148 rtx 149 add_implicit_parallel (rtvec vec) 150 { 151 if (GET_NUM_ELEM (vec) == 1) 152 return RTVEC_ELT (vec, 0); 153 else 154 { 155 rtx pattern = rtx_alloc (PARALLEL); 156 XVEC (pattern, 0) = vec; 157 return pattern; 158 } 159 } 160 161 /* Predicate handling. 162 163 We construct from the machine description a table mapping each 164 predicate to a list of the rtl codes it can possibly match. The 165 function 'maybe_both_true' uses it to deduce that there are no 166 expressions that can be matches by certain pairs of tree nodes. 167 Also, if a predicate can match only one code, we can hardwire that 168 code into the node testing the predicate. 169 170 Some predicates are flagged as special. validate_pattern will not 171 warn about modeless match_operand expressions if they have a 172 special predicate. Predicates that allow only constants are also 173 treated as special, for this purpose. 174 175 validate_pattern will warn about predicates that allow non-lvalues 176 when they appear in destination operands. 177 178 Calculating the set of rtx codes that can possibly be accepted by a 179 predicate expression EXP requires a three-state logic: any given 180 subexpression may definitively accept a code C (Y), definitively 181 reject a code C (N), or may have an indeterminate effect (I). N 182 and I is N; Y or I is Y; Y and I, N or I are both I. Here are full 183 truth tables. 184 185 a b a&b a|b 186 Y Y Y Y 187 N Y N Y 188 N N N N 189 I Y I Y 190 I N N I 191 I I I I 192 193 We represent Y with 1, N with 0, I with 2. If any code is left in 194 an I state by the complete expression, we must assume that that 195 code can be accepted. */ 196 197 #define N 0 198 #define Y 1 199 #define I 2 200 201 #define TRISTATE_AND(a,b) \ 202 ((a) == I ? ((b) == N ? N : I) : \ 203 (b) == I ? ((a) == N ? N : I) : \ 204 (a) && (b)) 205 206 #define TRISTATE_OR(a,b) \ 207 ((a) == I ? ((b) == Y ? Y : I) : \ 208 (b) == I ? ((a) == Y ? Y : I) : \ 209 (a) || (b)) 210 211 #define TRISTATE_NOT(a) \ 212 ((a) == I ? I : !(a)) 213 214 /* 0 means no warning about that code yet, 1 means warned. */ 215 static char did_you_mean_codes[NUM_RTX_CODE]; 216 217 /* Recursively calculate the set of rtx codes accepted by the 218 predicate expression EXP, writing the result to CODES. LOC is 219 the .md file location of the directive containing EXP. */ 220 221 void 222 compute_test_codes (rtx exp, file_location loc, char *codes) 223 { 224 char op0_codes[NUM_RTX_CODE]; 225 char op1_codes[NUM_RTX_CODE]; 226 char op2_codes[NUM_RTX_CODE]; 227 int i; 228 229 switch (GET_CODE (exp)) 230 { 231 case AND: 232 compute_test_codes (XEXP (exp, 0), loc, op0_codes); 233 compute_test_codes (XEXP (exp, 1), loc, op1_codes); 234 for (i = 0; i < NUM_RTX_CODE; i++) 235 codes[i] = TRISTATE_AND (op0_codes[i], op1_codes[i]); 236 break; 237 238 case IOR: 239 compute_test_codes (XEXP (exp, 0), loc, op0_codes); 240 compute_test_codes (XEXP (exp, 1), loc, op1_codes); 241 for (i = 0; i < NUM_RTX_CODE; i++) 242 codes[i] = TRISTATE_OR (op0_codes[i], op1_codes[i]); 243 break; 244 case NOT: 245 compute_test_codes (XEXP (exp, 0), loc, op0_codes); 246 for (i = 0; i < NUM_RTX_CODE; i++) 247 codes[i] = TRISTATE_NOT (op0_codes[i]); 248 break; 249 250 case IF_THEN_ELSE: 251 /* a ? b : c accepts the same codes as (a & b) | (!a & c). */ 252 compute_test_codes (XEXP (exp, 0), loc, op0_codes); 253 compute_test_codes (XEXP (exp, 1), loc, op1_codes); 254 compute_test_codes (XEXP (exp, 2), loc, op2_codes); 255 for (i = 0; i < NUM_RTX_CODE; i++) 256 codes[i] = TRISTATE_OR (TRISTATE_AND (op0_codes[i], op1_codes[i]), 257 TRISTATE_AND (TRISTATE_NOT (op0_codes[i]), 258 op2_codes[i])); 259 break; 260 261 case MATCH_CODE: 262 /* MATCH_CODE allows a specified list of codes. However, if it 263 does not apply to the top level of the expression, it does not 264 constrain the set of codes for the top level. */ 265 if (XSTR (exp, 1)[0] != '\0') 266 { 267 memset (codes, Y, NUM_RTX_CODE); 268 break; 269 } 270 271 memset (codes, N, NUM_RTX_CODE); 272 { 273 const char *next_code = XSTR (exp, 0); 274 const char *code; 275 276 if (*next_code == '\0') 277 { 278 error_at (loc, "empty match_code expression"); 279 break; 280 } 281 282 while ((code = scan_comma_elt (&next_code)) != 0) 283 { 284 size_t n = next_code - code; 285 int found_it = 0; 286 287 for (i = 0; i < NUM_RTX_CODE; i++) 288 if (!strncmp (code, GET_RTX_NAME (i), n) 289 && GET_RTX_NAME (i)[n] == '\0') 290 { 291 codes[i] = Y; 292 found_it = 1; 293 break; 294 } 295 if (!found_it) 296 { 297 error_at (loc, "match_code \"%.*s\" matches nothing", 298 (int) n, code); 299 for (i = 0; i < NUM_RTX_CODE; i++) 300 if (!strncasecmp (code, GET_RTX_NAME (i), n) 301 && GET_RTX_NAME (i)[n] == '\0' 302 && !did_you_mean_codes[i]) 303 { 304 did_you_mean_codes[i] = 1; 305 message_at (loc, "(did you mean \"%s\"?)", 306 GET_RTX_NAME (i)); 307 } 308 } 309 } 310 } 311 break; 312 313 case MATCH_OPERAND: 314 /* MATCH_OPERAND disallows the set of codes that the named predicate 315 disallows, and is indeterminate for the codes that it does allow. */ 316 { 317 struct pred_data *p = lookup_predicate (XSTR (exp, 1)); 318 if (!p) 319 { 320 error_at (loc, "reference to unknown predicate '%s'", 321 XSTR (exp, 1)); 322 break; 323 } 324 for (i = 0; i < NUM_RTX_CODE; i++) 325 codes[i] = p->codes[i] ? I : N; 326 } 327 break; 328 329 330 case MATCH_TEST: 331 /* (match_test WHATEVER) is completely indeterminate. */ 332 memset (codes, I, NUM_RTX_CODE); 333 break; 334 335 default: 336 error_at (loc, "'%s' cannot be used in predicates or constraints", 337 GET_RTX_NAME (GET_CODE (exp))); 338 memset (codes, I, NUM_RTX_CODE); 339 break; 340 } 341 } 342 343 #undef TRISTATE_OR 344 #undef TRISTATE_AND 345 #undef TRISTATE_NOT 346 347 /* Return true if NAME is a valid predicate name. */ 348 349 static bool 350 valid_predicate_name_p (const char *name) 351 { 352 const char *p; 353 354 if (!ISALPHA (name[0]) && name[0] != '_') 355 return false; 356 for (p = name + 1; *p; p++) 357 if (!ISALNUM (*p) && *p != '_') 358 return false; 359 return true; 360 } 361 362 /* Process define_predicate directive DESC, which appears at location LOC. 363 Compute the set of codes that can be matched, and record this as a known 364 predicate. */ 365 366 static void 367 process_define_predicate (rtx desc, file_location loc) 368 { 369 struct pred_data *pred; 370 char codes[NUM_RTX_CODE]; 371 int i; 372 373 if (!valid_predicate_name_p (XSTR (desc, 0))) 374 { 375 error_at (loc, "%s: predicate name must be a valid C function name", 376 XSTR (desc, 0)); 377 return; 378 } 379 380 pred = XCNEW (struct pred_data); 381 pred->name = XSTR (desc, 0); 382 pred->exp = XEXP (desc, 1); 383 pred->c_block = XSTR (desc, 2); 384 if (GET_CODE (desc) == DEFINE_SPECIAL_PREDICATE) 385 pred->special = true; 386 387 compute_test_codes (XEXP (desc, 1), loc, codes); 388 389 for (i = 0; i < NUM_RTX_CODE; i++) 390 if (codes[i] != N) 391 add_predicate_code (pred, (enum rtx_code) i); 392 393 add_predicate (pred); 394 } 395 #undef I 396 #undef N 397 #undef Y 398 399 /* Queue PATTERN on LIST_TAIL. Return the address of the new queue 400 element. */ 401 402 static struct queue_elem * 403 queue_pattern (rtx pattern, struct queue_elem ***list_tail, 404 file_location loc) 405 { 406 struct queue_elem *e = XNEW (struct queue_elem); 407 e->data = pattern; 408 e->loc = loc; 409 e->next = NULL; 410 e->split = NULL; 411 **list_tail = e; 412 *list_tail = &e->next; 413 return e; 414 } 415 416 /* Remove element ELEM from QUEUE. */ 417 static void 418 remove_from_queue (struct queue_elem *elem, struct queue_elem **queue) 419 { 420 struct queue_elem *prev, *e; 421 prev = NULL; 422 for (e = *queue; e ; e = e->next) 423 { 424 if (e == elem) 425 break; 426 prev = e; 427 } 428 if (e == NULL) 429 return; 430 431 if (prev) 432 prev->next = elem->next; 433 else 434 *queue = elem->next; 435 } 436 437 /* Build a define_attr for an binary attribute with name NAME and 438 possible values "yes" and "no", and queue it. */ 439 static void 440 add_define_attr (const char *name) 441 { 442 struct queue_elem *e = XNEW (struct queue_elem); 443 rtx t1 = rtx_alloc (DEFINE_ATTR); 444 XSTR (t1, 0) = name; 445 XSTR (t1, 1) = "no,yes"; 446 XEXP (t1, 2) = rtx_alloc (CONST_STRING); 447 XSTR (XEXP (t1, 2), 0) = "yes"; 448 e->data = t1; 449 e->loc = file_location ("built-in", -1, -1); 450 e->next = define_attr_queue; 451 define_attr_queue = e; 452 453 } 454 455 /* Recursively remove constraints from an rtx. */ 456 457 static void 458 remove_constraints (rtx part) 459 { 460 int i, j; 461 const char *format_ptr; 462 463 if (part == 0) 464 return; 465 466 if (GET_CODE (part) == MATCH_OPERAND) 467 XSTR (part, 2) = ""; 468 else if (GET_CODE (part) == MATCH_SCRATCH) 469 XSTR (part, 1) = ""; 470 471 format_ptr = GET_RTX_FORMAT (GET_CODE (part)); 472 473 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (part)); i++) 474 switch (*format_ptr++) 475 { 476 case 'e': 477 case 'u': 478 remove_constraints (XEXP (part, i)); 479 break; 480 case 'E': 481 if (XVEC (part, i) != NULL) 482 for (j = 0; j < XVECLEN (part, i); j++) 483 remove_constraints (XVECEXP (part, i, j)); 484 break; 485 } 486 } 487 488 /* Process a top level rtx in some way, queuing as appropriate. */ 489 490 static void 491 process_rtx (rtx desc, file_location loc) 492 { 493 switch (GET_CODE (desc)) 494 { 495 case DEFINE_INSN: 496 queue_pattern (desc, &define_insn_tail, loc); 497 break; 498 499 case DEFINE_COND_EXEC: 500 queue_pattern (desc, &define_cond_exec_tail, loc); 501 break; 502 503 case DEFINE_SUBST: 504 queue_pattern (desc, &define_subst_tail, loc); 505 break; 506 507 case DEFINE_SUBST_ATTR: 508 queue_pattern (desc, &define_subst_attr_tail, loc); 509 break; 510 511 case DEFINE_ATTR: 512 case DEFINE_ENUM_ATTR: 513 queue_pattern (desc, &define_attr_tail, loc); 514 break; 515 516 case DEFINE_PREDICATE: 517 case DEFINE_SPECIAL_PREDICATE: 518 process_define_predicate (desc, loc); 519 /* Fall through. */ 520 521 case DEFINE_CONSTRAINT: 522 case DEFINE_REGISTER_CONSTRAINT: 523 case DEFINE_MEMORY_CONSTRAINT: 524 case DEFINE_SPECIAL_MEMORY_CONSTRAINT: 525 case DEFINE_ADDRESS_CONSTRAINT: 526 queue_pattern (desc, &define_pred_tail, loc); 527 break; 528 529 case DEFINE_INSN_AND_SPLIT: 530 { 531 const char *split_cond; 532 rtx split; 533 rtvec attr; 534 int i; 535 struct queue_elem *insn_elem; 536 struct queue_elem *split_elem; 537 538 /* Create a split with values from the insn_and_split. */ 539 split = rtx_alloc (DEFINE_SPLIT); 540 541 i = XVECLEN (desc, 1); 542 XVEC (split, 0) = rtvec_alloc (i); 543 while (--i >= 0) 544 { 545 XVECEXP (split, 0, i) = copy_rtx (XVECEXP (desc, 1, i)); 546 remove_constraints (XVECEXP (split, 0, i)); 547 } 548 549 /* If the split condition starts with "&&", append it to the 550 insn condition to create the new split condition. */ 551 split_cond = XSTR (desc, 4); 552 if (split_cond[0] == '&' && split_cond[1] == '&') 553 { 554 rtx_reader_ptr->copy_md_ptr_loc (split_cond + 2, split_cond); 555 split_cond = rtx_reader_ptr->join_c_conditions (XSTR (desc, 2), 556 split_cond + 2); 557 } 558 XSTR (split, 1) = split_cond; 559 XVEC (split, 2) = XVEC (desc, 5); 560 XSTR (split, 3) = XSTR (desc, 6); 561 562 /* Fix up the DEFINE_INSN. */ 563 attr = XVEC (desc, 7); 564 PUT_CODE (desc, DEFINE_INSN); 565 XVEC (desc, 4) = attr; 566 567 /* Queue them. */ 568 insn_elem = queue_pattern (desc, &define_insn_tail, loc); 569 split_elem = queue_pattern (split, &other_tail, loc); 570 insn_elem->split = split_elem; 571 break; 572 } 573 574 default: 575 queue_pattern (desc, &other_tail, loc); 576 break; 577 } 578 } 579 580 /* Return true if attribute PREDICABLE is true for ELEM, which holds 581 a DEFINE_INSN. */ 582 583 static int 584 is_predicable (struct queue_elem *elem) 585 { 586 rtvec vec = XVEC (elem->data, 4); 587 const char *value; 588 int i; 589 590 if (! vec) 591 return predicable_default; 592 593 for (i = GET_NUM_ELEM (vec) - 1; i >= 0; --i) 594 { 595 rtx sub = RTVEC_ELT (vec, i); 596 switch (GET_CODE (sub)) 597 { 598 case SET_ATTR: 599 if (strcmp (XSTR (sub, 0), "predicable") == 0) 600 { 601 value = XSTR (sub, 1); 602 goto found; 603 } 604 break; 605 606 case SET_ATTR_ALTERNATIVE: 607 if (strcmp (XSTR (sub, 0), "predicable") == 0) 608 { 609 error_at (elem->loc, "multiple alternatives for `predicable'"); 610 return 0; 611 } 612 break; 613 614 case SET: 615 if (GET_CODE (SET_DEST (sub)) != ATTR 616 || strcmp (XSTR (SET_DEST (sub), 0), "predicable") != 0) 617 break; 618 sub = SET_SRC (sub); 619 if (GET_CODE (sub) == CONST_STRING) 620 { 621 value = XSTR (sub, 0); 622 goto found; 623 } 624 625 /* ??? It would be possible to handle this if we really tried. 626 It's not easy though, and I'm not going to bother until it 627 really proves necessary. */ 628 error_at (elem->loc, "non-constant value for `predicable'"); 629 return 0; 630 631 default: 632 gcc_unreachable (); 633 } 634 } 635 636 return predicable_default; 637 638 found: 639 /* Find out which value we're looking at. Multiple alternatives means at 640 least one is predicable. */ 641 if (strchr (value, ',') != NULL) 642 return 1; 643 if (strcmp (value, predicable_true) == 0) 644 return 1; 645 if (strcmp (value, predicable_false) == 0) 646 return 0; 647 648 error_at (elem->loc, "unknown value `%s' for `predicable' attribute", value); 649 return 0; 650 } 651 652 /* Find attribute SUBST in ELEM and assign NEW_VALUE to it. */ 653 static void 654 change_subst_attribute (struct queue_elem *elem, 655 struct queue_elem *subst_elem, 656 const char *new_value) 657 { 658 rtvec attrs_vec = XVEC (elem->data, 4); 659 const char *subst_name = XSTR (subst_elem->data, 0); 660 int i; 661 662 if (! attrs_vec) 663 return; 664 665 for (i = GET_NUM_ELEM (attrs_vec) - 1; i >= 0; --i) 666 { 667 rtx cur_attr = RTVEC_ELT (attrs_vec, i); 668 if (GET_CODE (cur_attr) != SET_ATTR) 669 continue; 670 if (strcmp (XSTR (cur_attr, 0), subst_name) == 0) 671 { 672 XSTR (cur_attr, 1) = new_value; 673 return; 674 } 675 } 676 } 677 678 /* Return true if ELEM has the attribute with the name of DEFINE_SUBST 679 represented by SUBST_ELEM and this attribute has value SUBST_TRUE. 680 DEFINE_SUBST isn't applied to patterns without such attribute. In other 681 words, we suppose the default value of the attribute to be 'no' since it is 682 always generated automatically in read-rtl.c. */ 683 static bool 684 has_subst_attribute (struct queue_elem *elem, struct queue_elem *subst_elem) 685 { 686 rtvec attrs_vec = XVEC (elem->data, 4); 687 const char *value, *subst_name = XSTR (subst_elem->data, 0); 688 int i; 689 690 if (! attrs_vec) 691 return false; 692 693 for (i = GET_NUM_ELEM (attrs_vec) - 1; i >= 0; --i) 694 { 695 rtx cur_attr = RTVEC_ELT (attrs_vec, i); 696 switch (GET_CODE (cur_attr)) 697 { 698 case SET_ATTR: 699 if (strcmp (XSTR (cur_attr, 0), subst_name) == 0) 700 { 701 value = XSTR (cur_attr, 1); 702 goto found; 703 } 704 break; 705 706 case SET: 707 if (GET_CODE (SET_DEST (cur_attr)) != ATTR 708 || strcmp (XSTR (SET_DEST (cur_attr), 0), subst_name) != 0) 709 break; 710 cur_attr = SET_SRC (cur_attr); 711 if (GET_CODE (cur_attr) == CONST_STRING) 712 { 713 value = XSTR (cur_attr, 0); 714 goto found; 715 } 716 717 /* Only (set_attr "subst" "yes/no") and 718 (set (attr "subst" (const_string "yes/no"))) 719 are currently allowed. */ 720 error_at (elem->loc, "unsupported value for `%s'", subst_name); 721 return false; 722 723 case SET_ATTR_ALTERNATIVE: 724 error_at (elem->loc, 725 "%s: `set_attr_alternative' is unsupported by " 726 "`define_subst'", XSTR (elem->data, 0)); 727 return false; 728 729 730 default: 731 gcc_unreachable (); 732 } 733 } 734 735 return false; 736 737 found: 738 if (strcmp (value, subst_true) == 0) 739 return true; 740 if (strcmp (value, subst_false) == 0) 741 return false; 742 743 error_at (elem->loc, "unknown value `%s' for `%s' attribute", 744 value, subst_name); 745 return false; 746 } 747 748 /* Compare RTL-template of original define_insn X to input RTL-template of 749 define_subst PT. Return 1 if the templates match, 0 otherwise. 750 During the comparison, the routine also fills global_array OPERAND_DATA. */ 751 static bool 752 subst_pattern_match (rtx x, rtx pt, file_location loc) 753 { 754 RTX_CODE code, code_pt; 755 int i, j, len; 756 const char *fmt, *pred_name; 757 758 code = GET_CODE (x); 759 code_pt = GET_CODE (pt); 760 761 if (code_pt == MATCH_OPERAND) 762 { 763 /* MATCH_DUP, and MATCH_OP_DUP don't have a specified mode, so we 764 always accept them. */ 765 if (GET_MODE (pt) != VOIDmode && GET_MODE (x) != GET_MODE (pt) 766 && (code != MATCH_DUP && code != MATCH_OP_DUP)) 767 return false; /* Modes don't match. */ 768 769 if (code == MATCH_OPERAND) 770 { 771 pred_name = XSTR (pt, 1); 772 if (pred_name[0] != 0) 773 { 774 const struct pred_data *pred_pt = lookup_predicate (pred_name); 775 if (!pred_pt || pred_pt != lookup_predicate (XSTR (x, 1))) 776 return false; /* Predicates don't match. */ 777 } 778 } 779 780 gcc_assert (XINT (pt, 0) >= 0 && XINT (pt, 0) < MAX_OPERANDS); 781 operand_data[XINT (pt, 0)] = x; 782 return true; 783 } 784 785 if (code_pt == MATCH_OPERATOR) 786 { 787 int x_vecexp_pos = -1; 788 789 /* Compare modes. */ 790 if (GET_MODE (pt) != VOIDmode && GET_MODE (x) != GET_MODE (pt)) 791 return false; 792 793 /* In case X is also match_operator, compare predicates. */ 794 if (code == MATCH_OPERATOR) 795 { 796 pred_name = XSTR (pt, 1); 797 if (pred_name[0] != 0) 798 { 799 const struct pred_data *pred_pt = lookup_predicate (pred_name); 800 if (!pred_pt || pred_pt != lookup_predicate (XSTR (x, 1))) 801 return false; 802 } 803 } 804 805 /* Compare operands. 806 MATCH_OPERATOR in input template could match in original template 807 either 1) MATCH_OPERAND, 2) UNSPEC, 3) ordinary operation (like PLUS). 808 In the first case operands are at (XVECEXP (x, 2, j)), in the second 809 - at (XVECEXP (x, 0, j)), in the last one - (XEXP (x, j)). 810 X_VECEXP_POS variable shows, where to look for these operands. */ 811 if (code == UNSPEC 812 || code == UNSPEC_VOLATILE) 813 x_vecexp_pos = 0; 814 else if (code == MATCH_OPERATOR) 815 x_vecexp_pos = 2; 816 else 817 x_vecexp_pos = -1; 818 819 /* MATCH_OPERATOR or UNSPEC case. */ 820 if (x_vecexp_pos >= 0) 821 { 822 /* Compare operands number in X and PT. */ 823 if (XVECLEN (x, x_vecexp_pos) != XVECLEN (pt, 2)) 824 return false; 825 for (j = 0; j < XVECLEN (pt, 2); j++) 826 if (!subst_pattern_match (XVECEXP (x, x_vecexp_pos, j), 827 XVECEXP (pt, 2, j), loc)) 828 return false; 829 } 830 831 /* Ordinary operator. */ 832 else 833 { 834 /* Compare operands number in X and PT. 835 We count operands differently for X and PT since we compare 836 an operator (with operands directly in RTX) and MATCH_OPERATOR 837 (that has a vector with operands). */ 838 if (GET_RTX_LENGTH (code) != XVECLEN (pt, 2)) 839 return false; 840 for (j = 0; j < XVECLEN (pt, 2); j++) 841 if (!subst_pattern_match (XEXP (x, j), XVECEXP (pt, 2, j), loc)) 842 return false; 843 } 844 845 /* Store the operand to OPERAND_DATA array. */ 846 gcc_assert (XINT (pt, 0) >= 0 && XINT (pt, 0) < MAX_OPERANDS); 847 operand_data[XINT (pt, 0)] = x; 848 return true; 849 } 850 851 if (code_pt == MATCH_PAR_DUP 852 || code_pt == MATCH_DUP 853 || code_pt == MATCH_OP_DUP 854 || code_pt == MATCH_SCRATCH 855 || code_pt == MATCH_PARALLEL) 856 { 857 /* Currently interface for these constructions isn't defined - 858 probably they aren't needed in input template of define_subst at all. 859 So, for now their usage in define_subst is forbidden. */ 860 error_at (loc, "%s cannot be used in define_subst", 861 GET_RTX_NAME (code_pt)); 862 } 863 864 gcc_assert (code != MATCH_PAR_DUP 865 && code_pt != MATCH_DUP 866 && code_pt != MATCH_OP_DUP 867 && code_pt != MATCH_SCRATCH 868 && code_pt != MATCH_PARALLEL 869 && code_pt != MATCH_OPERAND 870 && code_pt != MATCH_OPERATOR); 871 /* If PT is none of the handled above, then we match only expressions with 872 the same code in X. */ 873 if (code != code_pt) 874 return false; 875 876 fmt = GET_RTX_FORMAT (code_pt); 877 len = GET_RTX_LENGTH (code_pt); 878 879 for (i = 0; i < len; i++) 880 { 881 if (fmt[i] == '0') 882 break; 883 884 switch (fmt[i]) 885 { 886 case 'i': case 'r': case 'w': case 's': 887 continue; 888 889 case 'e': case 'u': 890 if (!subst_pattern_match (XEXP (x, i), XEXP (pt, i), loc)) 891 return false; 892 break; 893 case 'E': 894 { 895 if (XVECLEN (x, i) != XVECLEN (pt, i)) 896 return false; 897 for (j = 0; j < XVECLEN (pt, i); j++) 898 if (!subst_pattern_match (XVECEXP (x, i, j), 899 XVECEXP (pt, i, j), loc)) 900 return false; 901 break; 902 } 903 default: 904 gcc_unreachable (); 905 } 906 } 907 908 return true; 909 } 910 911 /* Examine the attribute "predicable"; discover its boolean values 912 and its default. */ 913 914 static void 915 identify_predicable_attribute (void) 916 { 917 struct queue_elem *elem; 918 char *p_true, *p_false; 919 const char *value; 920 921 /* Look for the DEFINE_ATTR for `predicable', which must exist. */ 922 for (elem = define_attr_queue; elem ; elem = elem->next) 923 if (strcmp (XSTR (elem->data, 0), "predicable") == 0) 924 goto found; 925 926 error_at (define_cond_exec_queue->loc, 927 "attribute `predicable' not defined"); 928 return; 929 930 found: 931 value = XSTR (elem->data, 1); 932 p_false = xstrdup (value); 933 p_true = strchr (p_false, ','); 934 if (p_true == NULL || strchr (++p_true, ',') != NULL) 935 { 936 error_at (elem->loc, "attribute `predicable' is not a boolean"); 937 free (p_false); 938 return; 939 } 940 p_true[-1] = '\0'; 941 942 predicable_true = p_true; 943 predicable_false = p_false; 944 945 switch (GET_CODE (XEXP (elem->data, 2))) 946 { 947 case CONST_STRING: 948 value = XSTR (XEXP (elem->data, 2), 0); 949 break; 950 951 case CONST: 952 error_at (elem->loc, "attribute `predicable' cannot be const"); 953 free (p_false); 954 return; 955 956 default: 957 error_at (elem->loc, 958 "attribute `predicable' must have a constant default"); 959 free (p_false); 960 return; 961 } 962 963 if (strcmp (value, p_true) == 0) 964 predicable_default = 1; 965 else if (strcmp (value, p_false) == 0) 966 predicable_default = 0; 967 else 968 { 969 error_at (elem->loc, "unknown value `%s' for `predicable' attribute", 970 value); 971 free (p_false); 972 } 973 } 974 975 /* Return the number of alternatives in constraint S. */ 976 977 static int 978 n_alternatives (const char *s) 979 { 980 int n = 1; 981 982 if (s) 983 while (*s) 984 n += (*s++ == ','); 985 986 return n; 987 } 988 989 /* The routine scans rtl PATTERN, find match_operand in it and counts 990 number of alternatives. If PATTERN contains several match_operands 991 with different number of alternatives, error is emitted, and the 992 routine returns 0. If all match_operands in PATTERN have the same 993 number of alternatives, it's stored in N_ALT, and the routine returns 1. 994 LOC is the location of PATTERN, for error reporting. */ 995 static int 996 get_alternatives_number (rtx pattern, int *n_alt, file_location loc) 997 { 998 const char *fmt; 999 enum rtx_code code; 1000 int i, j, len; 1001 1002 if (!n_alt) 1003 return 0; 1004 1005 code = GET_CODE (pattern); 1006 switch (code) 1007 { 1008 case MATCH_OPERAND: 1009 i = n_alternatives (XSTR (pattern, 2)); 1010 /* n_alternatives returns 1 if constraint string is empty - 1011 here we fix it up. */ 1012 if (!*(XSTR (pattern, 2))) 1013 i = 0; 1014 if (*n_alt <= 0) 1015 *n_alt = i; 1016 1017 else if (i && i != *n_alt) 1018 { 1019 error_at (loc, "wrong number of alternatives in operand %d", 1020 XINT (pattern, 0)); 1021 return 0; 1022 } 1023 1024 default: 1025 break; 1026 } 1027 1028 fmt = GET_RTX_FORMAT (code); 1029 len = GET_RTX_LENGTH (code); 1030 for (i = 0; i < len; i++) 1031 { 1032 switch (fmt[i]) 1033 { 1034 case 'e': case 'u': 1035 if (!get_alternatives_number (XEXP (pattern, i), n_alt, loc)) 1036 return 0; 1037 break; 1038 1039 case 'V': 1040 if (XVEC (pattern, i) == NULL) 1041 break; 1042 /* FALLTHRU */ 1043 1044 case 'E': 1045 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j) 1046 if (!get_alternatives_number (XVECEXP (pattern, i, j), n_alt, loc)) 1047 return 0; 1048 break; 1049 1050 case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T': 1051 break; 1052 1053 default: 1054 gcc_unreachable (); 1055 } 1056 } 1057 return 1; 1058 } 1059 1060 /* Determine how many alternatives there are in INSN, and how many 1061 operands. */ 1062 1063 static void 1064 collect_insn_data (rtx pattern, int *palt, int *pmax) 1065 { 1066 const char *fmt; 1067 enum rtx_code code; 1068 int i, j, len; 1069 1070 code = GET_CODE (pattern); 1071 switch (code) 1072 { 1073 case MATCH_OPERAND: 1074 case MATCH_SCRATCH: 1075 i = n_alternatives (XSTR (pattern, code == MATCH_SCRATCH ? 1 : 2)); 1076 *palt = (i > *palt ? i : *palt); 1077 /* Fall through. */ 1078 1079 case MATCH_OPERATOR: 1080 case MATCH_PARALLEL: 1081 i = XINT (pattern, 0); 1082 if (i > *pmax) 1083 *pmax = i; 1084 break; 1085 1086 default: 1087 break; 1088 } 1089 1090 fmt = GET_RTX_FORMAT (code); 1091 len = GET_RTX_LENGTH (code); 1092 for (i = 0; i < len; i++) 1093 { 1094 switch (fmt[i]) 1095 { 1096 case 'e': case 'u': 1097 collect_insn_data (XEXP (pattern, i), palt, pmax); 1098 break; 1099 1100 case 'V': 1101 if (XVEC (pattern, i) == NULL) 1102 break; 1103 /* Fall through. */ 1104 case 'E': 1105 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j) 1106 collect_insn_data (XVECEXP (pattern, i, j), palt, pmax); 1107 break; 1108 1109 case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T': 1110 break; 1111 1112 default: 1113 gcc_unreachable (); 1114 } 1115 } 1116 } 1117 1118 static rtx 1119 alter_predicate_for_insn (rtx pattern, int alt, int max_op, 1120 file_location loc) 1121 { 1122 const char *fmt; 1123 enum rtx_code code; 1124 int i, j, len; 1125 1126 code = GET_CODE (pattern); 1127 switch (code) 1128 { 1129 case MATCH_OPERAND: 1130 { 1131 const char *c = XSTR (pattern, 2); 1132 1133 if (n_alternatives (c) != 1) 1134 { 1135 error_at (loc, "too many alternatives for operand %d", 1136 XINT (pattern, 0)); 1137 return NULL; 1138 } 1139 1140 /* Replicate C as needed to fill out ALT alternatives. */ 1141 if (c && *c && alt > 1) 1142 { 1143 size_t c_len = strlen (c); 1144 size_t len = alt * (c_len + 1); 1145 char *new_c = XNEWVEC (char, len); 1146 1147 memcpy (new_c, c, c_len); 1148 for (i = 1; i < alt; ++i) 1149 { 1150 new_c[i * (c_len + 1) - 1] = ','; 1151 memcpy (&new_c[i * (c_len + 1)], c, c_len); 1152 } 1153 new_c[len - 1] = '\0'; 1154 XSTR (pattern, 2) = new_c; 1155 } 1156 } 1157 /* Fall through. */ 1158 1159 case MATCH_OPERATOR: 1160 case MATCH_SCRATCH: 1161 case MATCH_PARALLEL: 1162 XINT (pattern, 0) += max_op; 1163 break; 1164 1165 default: 1166 break; 1167 } 1168 1169 fmt = GET_RTX_FORMAT (code); 1170 len = GET_RTX_LENGTH (code); 1171 for (i = 0; i < len; i++) 1172 { 1173 rtx r; 1174 1175 switch (fmt[i]) 1176 { 1177 case 'e': case 'u': 1178 r = alter_predicate_for_insn (XEXP (pattern, i), alt, max_op, loc); 1179 if (r == NULL) 1180 return r; 1181 break; 1182 1183 case 'E': 1184 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j) 1185 { 1186 r = alter_predicate_for_insn (XVECEXP (pattern, i, j), 1187 alt, max_op, loc); 1188 if (r == NULL) 1189 return r; 1190 } 1191 break; 1192 1193 case 'i': case 'r': case 'w': case '0': case 's': 1194 break; 1195 1196 default: 1197 gcc_unreachable (); 1198 } 1199 } 1200 1201 return pattern; 1202 } 1203 1204 /* Duplicate constraints in PATTERN. If pattern is from original 1205 rtl-template, we need to duplicate each alternative - for that we 1206 need to use duplicate_each_alternative () as a functor ALTER. 1207 If pattern is from output-pattern of define_subst, we need to 1208 duplicate constraints in another way - with duplicate_alternatives (). 1209 N_DUP is multiplication factor. */ 1210 static rtx 1211 alter_constraints (rtx pattern, int n_dup, constraints_handler_t alter) 1212 { 1213 const char *fmt; 1214 enum rtx_code code; 1215 int i, j, len; 1216 1217 code = GET_CODE (pattern); 1218 switch (code) 1219 { 1220 case MATCH_OPERAND: 1221 XSTR (pattern, 2) = alter (XSTR (pattern, 2), n_dup); 1222 break; 1223 1224 default: 1225 break; 1226 } 1227 1228 fmt = GET_RTX_FORMAT (code); 1229 len = GET_RTX_LENGTH (code); 1230 for (i = 0; i < len; i++) 1231 { 1232 rtx r; 1233 1234 switch (fmt[i]) 1235 { 1236 case 'e': case 'u': 1237 r = alter_constraints (XEXP (pattern, i), n_dup, alter); 1238 if (r == NULL) 1239 return r; 1240 break; 1241 1242 case 'E': 1243 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j) 1244 { 1245 r = alter_constraints (XVECEXP (pattern, i, j), n_dup, alter); 1246 if (r == NULL) 1247 return r; 1248 } 1249 break; 1250 1251 case 'i': case 'r': case 'w': case '0': case 's': 1252 break; 1253 1254 default: 1255 break; 1256 } 1257 } 1258 1259 return pattern; 1260 } 1261 1262 static const char * 1263 alter_test_for_insn (struct queue_elem *ce_elem, 1264 struct queue_elem *insn_elem) 1265 { 1266 return rtx_reader_ptr->join_c_conditions (XSTR (ce_elem->data, 1), 1267 XSTR (insn_elem->data, 2)); 1268 } 1269 1270 /* Modify VAL, which is an attribute expression for the "enabled" attribute, 1271 to take "ce_enabled" into account. Return the new expression. */ 1272 static rtx 1273 modify_attr_enabled_ce (rtx val) 1274 { 1275 rtx eq_attr, str; 1276 rtx ite; 1277 eq_attr = rtx_alloc (EQ_ATTR); 1278 ite = rtx_alloc (IF_THEN_ELSE); 1279 str = rtx_alloc (CONST_STRING); 1280 1281 XSTR (eq_attr, 0) = "ce_enabled"; 1282 XSTR (eq_attr, 1) = "yes"; 1283 XSTR (str, 0) = "no"; 1284 XEXP (ite, 0) = eq_attr; 1285 XEXP (ite, 1) = val; 1286 XEXP (ite, 2) = str; 1287 1288 return ite; 1289 } 1290 1291 /* Alter the attribute vector of INSN, which is a COND_EXEC variant created 1292 from a define_insn pattern. We must modify the "predicable" attribute 1293 to be named "ce_enabled", and also change any "enabled" attribute that's 1294 present so that it takes ce_enabled into account. 1295 We rely on the fact that INSN was created with copy_rtx, and modify data 1296 in-place. */ 1297 1298 static void 1299 alter_attrs_for_insn (rtx insn) 1300 { 1301 static bool global_changes_made = false; 1302 rtvec vec = XVEC (insn, 4); 1303 rtvec new_vec; 1304 rtx val, set; 1305 int num_elem; 1306 int predicable_idx = -1; 1307 int enabled_idx = -1; 1308 int i; 1309 1310 if (! vec) 1311 return; 1312 1313 num_elem = GET_NUM_ELEM (vec); 1314 for (i = num_elem - 1; i >= 0; --i) 1315 { 1316 rtx sub = RTVEC_ELT (vec, i); 1317 switch (GET_CODE (sub)) 1318 { 1319 case SET_ATTR: 1320 if (strcmp (XSTR (sub, 0), "predicable") == 0) 1321 { 1322 predicable_idx = i; 1323 XSTR (sub, 0) = "ce_enabled"; 1324 } 1325 else if (strcmp (XSTR (sub, 0), "enabled") == 0) 1326 { 1327 enabled_idx = i; 1328 XSTR (sub, 0) = "nonce_enabled"; 1329 } 1330 break; 1331 1332 case SET_ATTR_ALTERNATIVE: 1333 if (strcmp (XSTR (sub, 0), "predicable") == 0) 1334 /* We already give an error elsewhere. */ 1335 return; 1336 else if (strcmp (XSTR (sub, 0), "enabled") == 0) 1337 { 1338 enabled_idx = i; 1339 XSTR (sub, 0) = "nonce_enabled"; 1340 } 1341 break; 1342 1343 case SET: 1344 if (GET_CODE (SET_DEST (sub)) != ATTR) 1345 break; 1346 if (strcmp (XSTR (SET_DEST (sub), 0), "predicable") == 0) 1347 { 1348 sub = SET_SRC (sub); 1349 if (GET_CODE (sub) == CONST_STRING) 1350 { 1351 predicable_idx = i; 1352 XSTR (sub, 0) = "ce_enabled"; 1353 } 1354 else 1355 /* We already give an error elsewhere. */ 1356 return; 1357 break; 1358 } 1359 if (strcmp (XSTR (SET_DEST (sub), 0), "enabled") == 0) 1360 { 1361 enabled_idx = i; 1362 XSTR (SET_DEST (sub), 0) = "nonce_enabled"; 1363 } 1364 break; 1365 1366 default: 1367 gcc_unreachable (); 1368 } 1369 } 1370 if (predicable_idx == -1) 1371 return; 1372 1373 if (!global_changes_made) 1374 { 1375 struct queue_elem *elem; 1376 1377 global_changes_made = true; 1378 add_define_attr ("ce_enabled"); 1379 add_define_attr ("nonce_enabled"); 1380 1381 for (elem = define_attr_queue; elem ; elem = elem->next) 1382 if (strcmp (XSTR (elem->data, 0), "enabled") == 0) 1383 { 1384 XEXP (elem->data, 2) 1385 = modify_attr_enabled_ce (XEXP (elem->data, 2)); 1386 } 1387 } 1388 if (enabled_idx == -1) 1389 return; 1390 1391 new_vec = rtvec_alloc (num_elem + 1); 1392 for (i = 0; i < num_elem; i++) 1393 RTVEC_ELT (new_vec, i) = RTVEC_ELT (vec, i); 1394 val = rtx_alloc (IF_THEN_ELSE); 1395 XEXP (val, 0) = rtx_alloc (EQ_ATTR); 1396 XEXP (val, 1) = rtx_alloc (CONST_STRING); 1397 XEXP (val, 2) = rtx_alloc (CONST_STRING); 1398 XSTR (XEXP (val, 0), 0) = "nonce_enabled"; 1399 XSTR (XEXP (val, 0), 1) = "yes"; 1400 XSTR (XEXP (val, 1), 0) = "yes"; 1401 XSTR (XEXP (val, 2), 0) = "no"; 1402 set = rtx_alloc (SET); 1403 SET_DEST (set) = rtx_alloc (ATTR); 1404 XSTR (SET_DEST (set), 0) = "enabled"; 1405 SET_SRC (set) = modify_attr_enabled_ce (val); 1406 RTVEC_ELT (new_vec, i) = set; 1407 XVEC (insn, 4) = new_vec; 1408 } 1409 1410 /* As number of constraints is changed after define_subst, we need to 1411 process attributes as well - we need to duplicate them the same way 1412 that we duplicated constraints in original pattern 1413 ELEM is a queue element, containing our rtl-template, 1414 N_DUP - multiplication factor. */ 1415 static void 1416 alter_attrs_for_subst_insn (struct queue_elem * elem, int n_dup) 1417 { 1418 rtvec vec = XVEC (elem->data, 4); 1419 int num_elem; 1420 int i; 1421 1422 if (n_dup < 2 || ! vec) 1423 return; 1424 1425 num_elem = GET_NUM_ELEM (vec); 1426 for (i = num_elem - 1; i >= 0; --i) 1427 { 1428 rtx sub = RTVEC_ELT (vec, i); 1429 switch (GET_CODE (sub)) 1430 { 1431 case SET_ATTR: 1432 if (strchr (XSTR (sub, 1), ',') != NULL) 1433 XSTR (sub, 1) = duplicate_alternatives (XSTR (sub, 1), n_dup); 1434 break; 1435 1436 case SET_ATTR_ALTERNATIVE: 1437 case SET: 1438 error_at (elem->loc, 1439 "%s: `define_subst' does not support attributes " 1440 "assigned by `set' and `set_attr_alternative'", 1441 XSTR (elem->data, 0)); 1442 return; 1443 1444 default: 1445 gcc_unreachable (); 1446 } 1447 } 1448 } 1449 1450 /* Adjust all of the operand numbers in SRC to match the shift they'll 1451 get from an operand displacement of DISP. Return a pointer after the 1452 adjusted string. */ 1453 1454 static char * 1455 shift_output_template (char *dest, const char *src, int disp) 1456 { 1457 while (*src) 1458 { 1459 char c = *src++; 1460 *dest++ = c; 1461 if (c == '%') 1462 { 1463 c = *src++; 1464 if (ISDIGIT ((unsigned char) c)) 1465 c += disp; 1466 else if (ISALPHA (c)) 1467 { 1468 *dest++ = c; 1469 c = *src++ + disp; 1470 } 1471 *dest++ = c; 1472 } 1473 } 1474 1475 return dest; 1476 } 1477 1478 static const char * 1479 alter_output_for_insn (struct queue_elem *ce_elem, 1480 struct queue_elem *insn_elem, 1481 int alt, int max_op) 1482 { 1483 const char *ce_out, *insn_out; 1484 char *result, *p; 1485 size_t len, ce_len, insn_len; 1486 1487 /* ??? Could coordinate with genoutput to not duplicate code here. */ 1488 1489 ce_out = XSTR (ce_elem->data, 2); 1490 insn_out = XTMPL (insn_elem->data, 3); 1491 if (!ce_out || *ce_out == '\0') 1492 return insn_out; 1493 1494 ce_len = strlen (ce_out); 1495 insn_len = strlen (insn_out); 1496 1497 if (*insn_out == '*') 1498 /* You must take care of the predicate yourself. */ 1499 return insn_out; 1500 1501 if (*insn_out == '@') 1502 { 1503 len = (ce_len + 1) * alt + insn_len + 1; 1504 p = result = XNEWVEC (char, len); 1505 1506 do 1507 { 1508 do 1509 *p++ = *insn_out++; 1510 while (ISSPACE ((unsigned char) *insn_out)); 1511 1512 if (*insn_out != '#') 1513 { 1514 p = shift_output_template (p, ce_out, max_op); 1515 *p++ = ' '; 1516 } 1517 1518 do 1519 *p++ = *insn_out++; 1520 while (*insn_out && *insn_out != '\n'); 1521 } 1522 while (*insn_out); 1523 *p = '\0'; 1524 } 1525 else 1526 { 1527 len = ce_len + 1 + insn_len + 1; 1528 result = XNEWVEC (char, len); 1529 1530 p = shift_output_template (result, ce_out, max_op); 1531 *p++ = ' '; 1532 memcpy (p, insn_out, insn_len + 1); 1533 } 1534 1535 return result; 1536 } 1537 1538 /* From string STR "a,b,c" produce "a,b,c,a,b,c,a,b,c", i.e. original 1539 string, duplicated N_DUP times. */ 1540 1541 static const char * 1542 duplicate_alternatives (const char * str, int n_dup) 1543 { 1544 int i, len, new_len; 1545 char *result, *sp; 1546 const char *cp; 1547 1548 if (n_dup < 2) 1549 return str; 1550 1551 while (ISSPACE (*str)) 1552 str++; 1553 1554 if (*str == '\0') 1555 return str; 1556 1557 cp = str; 1558 len = strlen (str); 1559 new_len = (len + 1) * n_dup; 1560 1561 sp = result = XNEWVEC (char, new_len); 1562 1563 /* Global modifier characters mustn't be duplicated: skip if found. */ 1564 if (*cp == '=' || *cp == '+' || *cp == '%') 1565 { 1566 *sp++ = *cp++; 1567 len--; 1568 } 1569 1570 /* Copy original constraints N_DUP times. */ 1571 for (i = 0; i < n_dup; i++, sp += len+1) 1572 { 1573 memcpy (sp, cp, len); 1574 *(sp+len) = (i == n_dup - 1) ? '\0' : ','; 1575 } 1576 1577 return result; 1578 } 1579 1580 /* From string STR "a,b,c" produce "a,a,a,b,b,b,c,c,c", i.e. string where 1581 each alternative from the original string is duplicated N_DUP times. */ 1582 static const char * 1583 duplicate_each_alternative (const char * str, int n_dup) 1584 { 1585 int i, len, new_len; 1586 char *result, *sp, *ep, *cp; 1587 1588 if (n_dup < 2) 1589 return str; 1590 1591 while (ISSPACE (*str)) 1592 str++; 1593 1594 if (*str == '\0') 1595 return str; 1596 1597 cp = xstrdup (str); 1598 1599 new_len = (strlen (cp) + 1) * n_dup; 1600 1601 sp = result = XNEWVEC (char, new_len); 1602 1603 /* Global modifier characters mustn't be duplicated: skip if found. */ 1604 if (*cp == '=' || *cp == '+' || *cp == '%') 1605 *sp++ = *cp++; 1606 1607 do 1608 { 1609 if ((ep = strchr (cp, ',')) != NULL) 1610 *ep++ = '\0'; 1611 len = strlen (cp); 1612 1613 /* Copy a constraint N_DUP times. */ 1614 for (i = 0; i < n_dup; i++, sp += len + 1) 1615 { 1616 memcpy (sp, cp, len); 1617 *(sp+len) = (ep == NULL && i == n_dup - 1) ? '\0' : ','; 1618 } 1619 1620 cp = ep; 1621 } 1622 while (cp != NULL); 1623 1624 return result; 1625 } 1626 1627 /* Alter the output of INSN whose pattern was modified by 1628 DEFINE_SUBST. We must replicate output strings according 1629 to the new number of alternatives ALT in substituted pattern. 1630 If ALT equals 1, output has one alternative or defined by C 1631 code, then output is returned without any changes. */ 1632 1633 static const char * 1634 alter_output_for_subst_insn (rtx insn, int alt) 1635 { 1636 const char *insn_out, *old_out; 1637 char *new_out, *cp; 1638 size_t old_len, new_len; 1639 int j; 1640 1641 insn_out = XTMPL (insn, 3); 1642 1643 if (alt < 2 || *insn_out != '@') 1644 return insn_out; 1645 1646 old_out = insn_out + 1; 1647 while (ISSPACE (*old_out)) 1648 old_out++; 1649 old_len = strlen (old_out); 1650 1651 new_len = alt * (old_len + 1) + 1; 1652 1653 new_out = XNEWVEC (char, new_len); 1654 new_out[0] = '@'; 1655 1656 for (j = 0, cp = new_out + 1; j < alt; j++, cp += old_len + 1) 1657 { 1658 memcpy (cp, old_out, old_len); 1659 cp[old_len] = (j == alt - 1) ? '\0' : '\n'; 1660 } 1661 1662 return new_out; 1663 } 1664 1665 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */ 1666 1667 static void 1668 process_one_cond_exec (struct queue_elem *ce_elem) 1669 { 1670 struct queue_elem *insn_elem; 1671 for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next) 1672 { 1673 int alternatives, max_operand; 1674 rtx pred, insn, pattern, split; 1675 char *new_name; 1676 int i; 1677 1678 if (! is_predicable (insn_elem)) 1679 continue; 1680 1681 alternatives = 1; 1682 max_operand = -1; 1683 collect_insn_data (insn_elem->data, &alternatives, &max_operand); 1684 max_operand += 1; 1685 1686 if (XVECLEN (ce_elem->data, 0) != 1) 1687 { 1688 error_at (ce_elem->loc, "too many patterns in predicate"); 1689 return; 1690 } 1691 1692 pred = copy_rtx (XVECEXP (ce_elem->data, 0, 0)); 1693 pred = alter_predicate_for_insn (pred, alternatives, max_operand, 1694 ce_elem->loc); 1695 if (pred == NULL) 1696 return; 1697 1698 /* Construct a new pattern for the new insn. */ 1699 insn = copy_rtx (insn_elem->data); 1700 new_name = XNEWVAR (char, strlen XSTR (insn_elem->data, 0) + 4); 1701 sprintf (new_name, "*p %s", XSTR (insn_elem->data, 0)); 1702 XSTR (insn, 0) = new_name; 1703 pattern = rtx_alloc (COND_EXEC); 1704 XEXP (pattern, 0) = pred; 1705 XEXP (pattern, 1) = add_implicit_parallel (XVEC (insn, 1)); 1706 XVEC (insn, 1) = rtvec_alloc (1); 1707 XVECEXP (insn, 1, 0) = pattern; 1708 1709 if (XVEC (ce_elem->data, 3) != NULL) 1710 { 1711 rtvec attributes = rtvec_alloc (XVECLEN (insn, 4) 1712 + XVECLEN (ce_elem->data, 3)); 1713 int i = 0; 1714 int j = 0; 1715 for (i = 0; i < XVECLEN (insn, 4); i++) 1716 RTVEC_ELT (attributes, i) = XVECEXP (insn, 4, i); 1717 1718 for (j = 0; j < XVECLEN (ce_elem->data, 3); j++, i++) 1719 RTVEC_ELT (attributes, i) = XVECEXP (ce_elem->data, 3, j); 1720 1721 XVEC (insn, 4) = attributes; 1722 } 1723 1724 XSTR (insn, 2) = alter_test_for_insn (ce_elem, insn_elem); 1725 XTMPL (insn, 3) = alter_output_for_insn (ce_elem, insn_elem, 1726 alternatives, max_operand); 1727 alter_attrs_for_insn (insn); 1728 1729 /* Put the new pattern on the `other' list so that it 1730 (a) is not reprocessed by other define_cond_exec patterns 1731 (b) appears after all normal define_insn patterns. 1732 1733 ??? B is debatable. If one has normal insns that match 1734 cond_exec patterns, they will be preferred over these 1735 generated patterns. Whether this matters in practice, or if 1736 it's a good thing, or whether we should thread these new 1737 patterns into the define_insn chain just after their generator 1738 is something we'll have to experiment with. */ 1739 1740 queue_pattern (insn, &other_tail, insn_elem->loc); 1741 1742 if (!insn_elem->split) 1743 continue; 1744 1745 /* If the original insn came from a define_insn_and_split, 1746 generate a new split to handle the predicated insn. */ 1747 split = copy_rtx (insn_elem->split->data); 1748 /* Predicate the pattern matched by the split. */ 1749 pattern = rtx_alloc (COND_EXEC); 1750 XEXP (pattern, 0) = pred; 1751 XEXP (pattern, 1) = add_implicit_parallel (XVEC (split, 0)); 1752 XVEC (split, 0) = rtvec_alloc (1); 1753 XVECEXP (split, 0, 0) = pattern; 1754 1755 /* Predicate all of the insns generated by the split. */ 1756 for (i = 0; i < XVECLEN (split, 2); i++) 1757 { 1758 pattern = rtx_alloc (COND_EXEC); 1759 XEXP (pattern, 0) = pred; 1760 XEXP (pattern, 1) = XVECEXP (split, 2, i); 1761 XVECEXP (split, 2, i) = pattern; 1762 } 1763 /* Add the new split to the queue. */ 1764 queue_pattern (split, &other_tail, insn_elem->split->loc); 1765 } 1766 } 1767 1768 /* Try to apply define_substs to the given ELEM. 1769 Only define_substs, specified via attributes would be applied. 1770 If attribute, requiring define_subst, is set, but no define_subst 1771 was applied, ELEM would be deleted. */ 1772 1773 static void 1774 process_substs_on_one_elem (struct queue_elem *elem, 1775 struct queue_elem *queue) 1776 { 1777 struct queue_elem *subst_elem; 1778 int i, j, patterns_match; 1779 1780 for (subst_elem = define_subst_queue; 1781 subst_elem; subst_elem = subst_elem->next) 1782 { 1783 int alternatives, alternatives_subst; 1784 rtx subst_pattern; 1785 rtvec subst_pattern_vec; 1786 1787 if (!has_subst_attribute (elem, subst_elem)) 1788 continue; 1789 1790 /* Compare original rtl-pattern from define_insn with input 1791 pattern from define_subst. 1792 Also, check if numbers of alternatives are the same in all 1793 match_operands. */ 1794 if (XVECLEN (elem->data, 1) != XVECLEN (subst_elem->data, 1)) 1795 continue; 1796 patterns_match = 1; 1797 alternatives = -1; 1798 alternatives_subst = -1; 1799 for (j = 0; j < XVECLEN (elem->data, 1); j++) 1800 { 1801 if (!subst_pattern_match (XVECEXP (elem->data, 1, j), 1802 XVECEXP (subst_elem->data, 1, j), 1803 subst_elem->loc)) 1804 { 1805 patterns_match = 0; 1806 break; 1807 } 1808 1809 if (!get_alternatives_number (XVECEXP (elem->data, 1, j), 1810 &alternatives, subst_elem->loc)) 1811 { 1812 patterns_match = 0; 1813 break; 1814 } 1815 } 1816 1817 /* Check if numbers of alternatives are the same in all 1818 match_operands in output template of define_subst. */ 1819 for (j = 0; j < XVECLEN (subst_elem->data, 3); j++) 1820 { 1821 if (!get_alternatives_number (XVECEXP (subst_elem->data, 3, j), 1822 &alternatives_subst, 1823 subst_elem->loc)) 1824 { 1825 patterns_match = 0; 1826 break; 1827 } 1828 } 1829 1830 if (!patterns_match) 1831 continue; 1832 1833 /* Clear array in which we save occupied indexes of operands. */ 1834 memset (used_operands_numbers, 0, sizeof (used_operands_numbers)); 1835 1836 /* Create a pattern, based on the output one from define_subst. */ 1837 subst_pattern_vec = rtvec_alloc (XVECLEN (subst_elem->data, 3)); 1838 for (j = 0; j < XVECLEN (subst_elem->data, 3); j++) 1839 { 1840 subst_pattern = copy_rtx (XVECEXP (subst_elem->data, 3, j)); 1841 1842 /* Duplicate constraints in substitute-pattern. */ 1843 subst_pattern = alter_constraints (subst_pattern, alternatives, 1844 duplicate_each_alternative); 1845 1846 subst_pattern = adjust_operands_numbers (subst_pattern); 1847 1848 /* Substitute match_dup and match_op_dup in the new pattern and 1849 duplicate constraints. */ 1850 subst_pattern = subst_dup (subst_pattern, alternatives, 1851 alternatives_subst); 1852 1853 replace_duplicating_operands_in_pattern (subst_pattern); 1854 1855 /* We don't need any constraints in DEFINE_EXPAND. */ 1856 if (GET_CODE (elem->data) == DEFINE_EXPAND) 1857 remove_constraints (subst_pattern); 1858 1859 RTVEC_ELT (subst_pattern_vec, j) = subst_pattern; 1860 } 1861 XVEC (elem->data, 1) = subst_pattern_vec; 1862 1863 for (i = 0; i < MAX_OPERANDS; i++) 1864 match_operand_entries_in_pattern[i] = NULL; 1865 1866 if (GET_CODE (elem->data) == DEFINE_INSN) 1867 { 1868 XTMPL (elem->data, 3) = 1869 alter_output_for_subst_insn (elem->data, alternatives_subst); 1870 alter_attrs_for_subst_insn (elem, alternatives_subst); 1871 } 1872 1873 /* Recalculate condition, joining conditions from original and 1874 DEFINE_SUBST input patterns. */ 1875 XSTR (elem->data, 2) 1876 = rtx_reader_ptr->join_c_conditions (XSTR (subst_elem->data, 2), 1877 XSTR (elem->data, 2)); 1878 /* Mark that subst was applied by changing attribute from "yes" 1879 to "no". */ 1880 change_subst_attribute (elem, subst_elem, subst_false); 1881 } 1882 1883 /* If ELEM contains a subst attribute with value "yes", then we 1884 expected that a subst would be applied, but it wasn't - so, 1885 we need to remove that elementto avoid duplicating. */ 1886 for (subst_elem = define_subst_queue; 1887 subst_elem; subst_elem = subst_elem->next) 1888 { 1889 if (has_subst_attribute (elem, subst_elem)) 1890 { 1891 remove_from_queue (elem, &queue); 1892 return; 1893 } 1894 } 1895 } 1896 1897 /* This is a subroutine of mark_operands_used_in_match_dup. 1898 This routine is marks all MATCH_OPERANDs inside PATTERN as occupied. */ 1899 static void 1900 mark_operands_from_match_dup (rtx pattern) 1901 { 1902 const char *fmt; 1903 int i, j, len, opno; 1904 1905 if (GET_CODE (pattern) == MATCH_OPERAND 1906 || GET_CODE (pattern) == MATCH_OPERATOR 1907 || GET_CODE (pattern) == MATCH_PARALLEL) 1908 { 1909 opno = XINT (pattern, 0); 1910 gcc_assert (opno >= 0 && opno < MAX_OPERANDS); 1911 used_operands_numbers [opno] = 1; 1912 } 1913 fmt = GET_RTX_FORMAT (GET_CODE (pattern)); 1914 len = GET_RTX_LENGTH (GET_CODE (pattern)); 1915 for (i = 0; i < len; i++) 1916 { 1917 switch (fmt[i]) 1918 { 1919 case 'e': case 'u': 1920 mark_operands_from_match_dup (XEXP (pattern, i)); 1921 break; 1922 case 'E': 1923 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j) 1924 mark_operands_from_match_dup (XVECEXP (pattern, i, j)); 1925 break; 1926 } 1927 } 1928 } 1929 1930 /* This is a subroutine of adjust_operands_numbers. 1931 It goes through all expressions in PATTERN and when MATCH_DUP is 1932 met, all MATCH_OPERANDs inside it is marked as occupied. The 1933 process of marking is done by routin mark_operands_from_match_dup. */ 1934 static void 1935 mark_operands_used_in_match_dup (rtx pattern) 1936 { 1937 const char *fmt; 1938 int i, j, len, opno; 1939 1940 if (GET_CODE (pattern) == MATCH_DUP) 1941 { 1942 opno = XINT (pattern, 0); 1943 gcc_assert (opno >= 0 && opno < MAX_OPERANDS); 1944 mark_operands_from_match_dup (operand_data[opno]); 1945 return; 1946 } 1947 fmt = GET_RTX_FORMAT (GET_CODE (pattern)); 1948 len = GET_RTX_LENGTH (GET_CODE (pattern)); 1949 for (i = 0; i < len; i++) 1950 { 1951 switch (fmt[i]) 1952 { 1953 case 'e': case 'u': 1954 mark_operands_used_in_match_dup (XEXP (pattern, i)); 1955 break; 1956 case 'E': 1957 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j) 1958 mark_operands_used_in_match_dup (XVECEXP (pattern, i, j)); 1959 break; 1960 } 1961 } 1962 } 1963 1964 /* This is subroutine of renumerate_operands_in_pattern. 1965 It finds first not-occupied operand-index. */ 1966 static int 1967 find_first_unused_number_of_operand () 1968 { 1969 int i; 1970 for (i = 0; i < MAX_OPERANDS; i++) 1971 if (!used_operands_numbers[i]) 1972 return i; 1973 return MAX_OPERANDS; 1974 } 1975 1976 /* This is subroutine of adjust_operands_numbers. 1977 It visits all expressions in PATTERN and assigns not-occupied 1978 operand indexes to MATCH_OPERANDs and MATCH_OPERATORs of this 1979 PATTERN. */ 1980 static void 1981 renumerate_operands_in_pattern (rtx pattern) 1982 { 1983 const char *fmt; 1984 enum rtx_code code; 1985 int i, j, len, new_opno; 1986 code = GET_CODE (pattern); 1987 1988 if (code == MATCH_OPERAND 1989 || code == MATCH_OPERATOR) 1990 { 1991 new_opno = find_first_unused_number_of_operand (); 1992 gcc_assert (new_opno >= 0 && new_opno < MAX_OPERANDS); 1993 XINT (pattern, 0) = new_opno; 1994 used_operands_numbers [new_opno] = 1; 1995 } 1996 1997 fmt = GET_RTX_FORMAT (GET_CODE (pattern)); 1998 len = GET_RTX_LENGTH (GET_CODE (pattern)); 1999 for (i = 0; i < len; i++) 2000 { 2001 switch (fmt[i]) 2002 { 2003 case 'e': case 'u': 2004 renumerate_operands_in_pattern (XEXP (pattern, i)); 2005 break; 2006 case 'E': 2007 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j) 2008 renumerate_operands_in_pattern (XVECEXP (pattern, i, j)); 2009 break; 2010 } 2011 } 2012 } 2013 2014 /* If output pattern of define_subst contains MATCH_DUP, then this 2015 expression would be replaced with the pattern, matched with 2016 MATCH_OPERAND from input pattern. This pattern could contain any 2017 number of MATCH_OPERANDs, MATCH_OPERATORs etc., so it's possible 2018 that a MATCH_OPERAND from output_pattern (if any) would have the 2019 same number, as MATCH_OPERAND from copied pattern. To avoid such 2020 indexes overlapping, we assign new indexes to MATCH_OPERANDs, 2021 laying in the output pattern outside of MATCH_DUPs. */ 2022 static rtx 2023 adjust_operands_numbers (rtx pattern) 2024 { 2025 mark_operands_used_in_match_dup (pattern); 2026 2027 renumerate_operands_in_pattern (pattern); 2028 2029 return pattern; 2030 } 2031 2032 /* Generate RTL expression 2033 (match_dup OPNO) 2034 */ 2035 static rtx 2036 generate_match_dup (int opno) 2037 { 2038 rtx return_rtx = rtx_alloc (MATCH_DUP); 2039 PUT_CODE (return_rtx, MATCH_DUP); 2040 XINT (return_rtx, 0) = opno; 2041 return return_rtx; 2042 } 2043 2044 /* This routine checks all match_operands in PATTERN and if some of 2045 have the same index, it replaces all of them except the first one to 2046 match_dup. 2047 Usually, match_operands with the same indexes are forbidden, but 2048 after define_subst copy an RTL-expression from original template, 2049 indexes of existed and just-copied match_operands could coincide. 2050 To fix it, we replace one of them with match_dup. */ 2051 static rtx 2052 replace_duplicating_operands_in_pattern (rtx pattern) 2053 { 2054 const char *fmt; 2055 int i, j, len, opno; 2056 rtx mdup; 2057 2058 if (GET_CODE (pattern) == MATCH_OPERAND) 2059 { 2060 opno = XINT (pattern, 0); 2061 gcc_assert (opno >= 0 && opno < MAX_OPERANDS); 2062 if (match_operand_entries_in_pattern[opno] == NULL) 2063 { 2064 match_operand_entries_in_pattern[opno] = pattern; 2065 return NULL; 2066 } 2067 else 2068 { 2069 /* Compare predicates before replacing with match_dup. */ 2070 if (strcmp (XSTR (pattern, 1), 2071 XSTR (match_operand_entries_in_pattern[opno], 1))) 2072 { 2073 error ("duplicated match_operands with different predicates were" 2074 " found."); 2075 return NULL; 2076 } 2077 return generate_match_dup (opno); 2078 } 2079 } 2080 fmt = GET_RTX_FORMAT (GET_CODE (pattern)); 2081 len = GET_RTX_LENGTH (GET_CODE (pattern)); 2082 for (i = 0; i < len; i++) 2083 { 2084 switch (fmt[i]) 2085 { 2086 case 'e': case 'u': 2087 mdup = replace_duplicating_operands_in_pattern (XEXP (pattern, i)); 2088 if (mdup) 2089 XEXP (pattern, i) = mdup; 2090 break; 2091 case 'E': 2092 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j) 2093 { 2094 mdup = 2095 replace_duplicating_operands_in_pattern (XVECEXP 2096 (pattern, i, j)); 2097 if (mdup) 2098 XVECEXP (pattern, i, j) = mdup; 2099 } 2100 break; 2101 } 2102 } 2103 return NULL; 2104 } 2105 2106 /* The routine modifies given input PATTERN of define_subst, replacing 2107 MATCH_DUP and MATCH_OP_DUP with operands from define_insn original 2108 pattern, whose operands are stored in OPERAND_DATA array. 2109 It also duplicates constraints in operands - constraints from 2110 define_insn operands are duplicated N_SUBST_ALT times, constraints 2111 from define_subst operands are duplicated N_ALT times. 2112 After the duplication, returned output rtl-pattern contains every 2113 combination of input constraints Vs constraints from define_subst 2114 output. */ 2115 static rtx 2116 subst_dup (rtx pattern, int n_alt, int n_subst_alt) 2117 { 2118 const char *fmt; 2119 enum rtx_code code; 2120 int i, j, len, opno; 2121 2122 code = GET_CODE (pattern); 2123 switch (code) 2124 { 2125 case MATCH_DUP: 2126 case MATCH_OP_DUP: 2127 opno = XINT (pattern, 0); 2128 2129 gcc_assert (opno >= 0 && opno < MAX_OPERANDS); 2130 2131 if (operand_data[opno]) 2132 { 2133 pattern = copy_rtx (operand_data[opno]); 2134 2135 /* Duplicate constraints. */ 2136 pattern = alter_constraints (pattern, n_subst_alt, 2137 duplicate_alternatives); 2138 } 2139 break; 2140 2141 default: 2142 break; 2143 } 2144 2145 fmt = GET_RTX_FORMAT (GET_CODE (pattern)); 2146 len = GET_RTX_LENGTH (GET_CODE (pattern)); 2147 for (i = 0; i < len; i++) 2148 { 2149 switch (fmt[i]) 2150 { 2151 case 'e': case 'u': 2152 if (code != MATCH_DUP && code != MATCH_OP_DUP) 2153 XEXP (pattern, i) = subst_dup (XEXP (pattern, i), 2154 n_alt, n_subst_alt); 2155 break; 2156 case 'V': 2157 if (XVEC (pattern, i) == NULL) 2158 break; 2159 /* FALLTHRU */ 2160 case 'E': 2161 if (code != MATCH_DUP && code != MATCH_OP_DUP) 2162 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j) 2163 XVECEXP (pattern, i, j) = subst_dup (XVECEXP (pattern, i, j), 2164 n_alt, n_subst_alt); 2165 break; 2166 2167 case 'i': case 'r': case 'w': case '0': case 's': case 'S': case 'T': 2168 break; 2169 2170 default: 2171 gcc_unreachable (); 2172 } 2173 } 2174 return pattern; 2175 } 2176 2177 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN 2178 patterns appropriately. */ 2179 2180 static void 2181 process_define_cond_exec (void) 2182 { 2183 struct queue_elem *elem; 2184 2185 identify_predicable_attribute (); 2186 if (have_error) 2187 return; 2188 2189 for (elem = define_cond_exec_queue; elem ; elem = elem->next) 2190 process_one_cond_exec (elem); 2191 } 2192 2193 /* If we have any DEFINE_SUBST patterns, expand DEFINE_INSN and 2194 DEFINE_EXPAND patterns appropriately. */ 2195 2196 static void 2197 process_define_subst (void) 2198 { 2199 struct queue_elem *elem, *elem_attr; 2200 2201 /* Check if each define_subst has corresponding define_subst_attr. */ 2202 for (elem = define_subst_queue; elem ; elem = elem->next) 2203 { 2204 for (elem_attr = define_subst_attr_queue; 2205 elem_attr; 2206 elem_attr = elem_attr->next) 2207 if (strcmp (XSTR (elem->data, 0), XSTR (elem_attr->data, 1)) == 0) 2208 goto found; 2209 2210 error_at (elem->loc, 2211 "%s: `define_subst' must have at least one " 2212 "corresponding `define_subst_attr'", 2213 XSTR (elem->data, 0)); 2214 return; 2215 2216 found: 2217 continue; 2218 } 2219 2220 for (elem = define_insn_queue; elem ; elem = elem->next) 2221 process_substs_on_one_elem (elem, define_insn_queue); 2222 for (elem = other_queue; elem ; elem = elem->next) 2223 { 2224 if (GET_CODE (elem->data) != DEFINE_EXPAND) 2225 continue; 2226 process_substs_on_one_elem (elem, other_queue); 2227 } 2228 } 2229 2230 /* A subclass of rtx_reader which reads .md files and calls process_rtx on 2231 the top-level elements. */ 2232 2233 class gen_reader : public rtx_reader 2234 { 2235 public: 2236 gen_reader () : rtx_reader (false) {} 2237 void handle_unknown_directive (file_location, const char *); 2238 }; 2239 2240 void 2241 gen_reader::handle_unknown_directive (file_location loc, const char *rtx_name) 2242 { 2243 auto_vec<rtx, 32> subrtxs; 2244 if (!read_rtx (rtx_name, &subrtxs)) 2245 return; 2246 2247 rtx x; 2248 unsigned int i; 2249 FOR_EACH_VEC_ELT (subrtxs, i, x) 2250 process_rtx (x, loc); 2251 } 2252 2253 /* Comparison function for the mnemonic hash table. */ 2254 2255 static int 2256 htab_eq_string (const void *s1, const void *s2) 2257 { 2258 return strcmp ((const char*)s1, (const char*)s2) == 0; 2259 } 2260 2261 /* Add mnemonic STR with length LEN to the mnemonic hash table 2262 MNEMONIC_HTAB. A trailing zero end character is appended to STR 2263 and a permanent heap copy of STR is created. */ 2264 2265 static void 2266 add_mnemonic_string (htab_t mnemonic_htab, const char *str, size_t len) 2267 { 2268 char *new_str; 2269 void **slot; 2270 char *str_zero = (char*)alloca (len + 1); 2271 2272 memcpy (str_zero, str, len); 2273 str_zero[len] = '\0'; 2274 2275 slot = htab_find_slot (mnemonic_htab, str_zero, INSERT); 2276 2277 if (*slot) 2278 return; 2279 2280 /* Not found; create a permanent copy and add it to the hash table. */ 2281 new_str = XNEWVAR (char, len + 1); 2282 memcpy (new_str, str_zero, len + 1); 2283 *slot = new_str; 2284 } 2285 2286 /* Scan INSN for mnemonic strings and add them to the mnemonic hash 2287 table in MNEMONIC_HTAB. 2288 2289 The mnemonics cannot be found if they are emitted using C code. 2290 2291 If a mnemonic string contains ';' or a newline the string assumed 2292 to consist of more than a single instruction. The attribute value 2293 will then be set to the user defined default value. */ 2294 2295 static void 2296 gen_mnemonic_setattr (htab_t mnemonic_htab, rtx insn) 2297 { 2298 const char *template_code, *cp; 2299 int i; 2300 int vec_len; 2301 rtx set_attr; 2302 char *attr_name; 2303 rtvec new_vec; 2304 struct obstack *string_obstack = rtx_reader_ptr->get_string_obstack (); 2305 2306 template_code = XTMPL (insn, 3); 2307 2308 /* Skip patterns which use C code to emit the template. */ 2309 if (template_code[0] == '*') 2310 return; 2311 2312 if (template_code[0] == '@') 2313 cp = &template_code[1]; 2314 else 2315 cp = &template_code[0]; 2316 2317 for (i = 0; *cp; ) 2318 { 2319 const char *ep, *sp; 2320 size_t size = 0; 2321 2322 while (ISSPACE (*cp)) 2323 cp++; 2324 2325 for (ep = sp = cp; !IS_VSPACE (*ep) && *ep != '\0'; ++ep) 2326 if (!ISSPACE (*ep)) 2327 sp = ep + 1; 2328 2329 if (i > 0) 2330 obstack_1grow (string_obstack, ','); 2331 2332 while (cp < sp && ((*cp >= '0' && *cp <= '9') 2333 || (*cp >= 'a' && *cp <= 'z'))) 2334 2335 { 2336 obstack_1grow (string_obstack, *cp); 2337 cp++; 2338 size++; 2339 } 2340 2341 while (cp < sp) 2342 { 2343 if (*cp == ';' || (*cp == '\\' && cp[1] == 'n')) 2344 { 2345 /* Don't set a value if there are more than one 2346 instruction in the string. */ 2347 obstack_blank_fast (string_obstack, -size); 2348 size = 0; 2349 2350 cp = sp; 2351 break; 2352 } 2353 cp++; 2354 } 2355 if (size == 0) 2356 obstack_1grow (string_obstack, '*'); 2357 else 2358 add_mnemonic_string (mnemonic_htab, 2359 (char *) obstack_next_free (string_obstack) - size, 2360 size); 2361 i++; 2362 } 2363 2364 /* An insn definition might emit an empty string. */ 2365 if (obstack_object_size (string_obstack) == 0) 2366 return; 2367 2368 obstack_1grow (string_obstack, '\0'); 2369 2370 set_attr = rtx_alloc (SET_ATTR); 2371 XSTR (set_attr, 1) = XOBFINISH (string_obstack, char *); 2372 attr_name = XNEWVAR (char, strlen (MNEMONIC_ATTR_NAME) + 1); 2373 strcpy (attr_name, MNEMONIC_ATTR_NAME); 2374 XSTR (set_attr, 0) = attr_name; 2375 2376 if (!XVEC (insn, 4)) 2377 vec_len = 0; 2378 else 2379 vec_len = XVECLEN (insn, 4); 2380 2381 new_vec = rtvec_alloc (vec_len + 1); 2382 for (i = 0; i < vec_len; i++) 2383 RTVEC_ELT (new_vec, i) = XVECEXP (insn, 4, i); 2384 RTVEC_ELT (new_vec, vec_len) = set_attr; 2385 XVEC (insn, 4) = new_vec; 2386 } 2387 2388 /* This function is called for the elements in the mnemonic hashtable 2389 and generates a comma separated list of the mnemonics. */ 2390 2391 static int 2392 mnemonic_htab_callback (void **slot, void *info ATTRIBUTE_UNUSED) 2393 { 2394 struct obstack *string_obstack = rtx_reader_ptr->get_string_obstack (); 2395 2396 obstack_grow (string_obstack, (char*) *slot, strlen ((char*) *slot)); 2397 obstack_1grow (string_obstack, ','); 2398 return 1; 2399 } 2400 2401 /* Generate (set_attr "mnemonic" "..") RTXs and append them to every 2402 insn definition in case the back end requests it by defining the 2403 mnemonic attribute. The values for the attribute will be extracted 2404 from the output patterns of the insn definitions as far as 2405 possible. */ 2406 2407 static void 2408 gen_mnemonic_attr (void) 2409 { 2410 struct queue_elem *elem; 2411 rtx mnemonic_attr = NULL; 2412 htab_t mnemonic_htab; 2413 const char *str, *p; 2414 int i; 2415 struct obstack *string_obstack = rtx_reader_ptr->get_string_obstack (); 2416 2417 if (have_error) 2418 return; 2419 2420 /* Look for the DEFINE_ATTR for `mnemonic'. */ 2421 for (elem = define_attr_queue; elem != *define_attr_tail; elem = elem->next) 2422 if (GET_CODE (elem->data) == DEFINE_ATTR 2423 && strcmp (XSTR (elem->data, 0), MNEMONIC_ATTR_NAME) == 0) 2424 { 2425 mnemonic_attr = elem->data; 2426 break; 2427 } 2428 2429 /* A (define_attr "mnemonic" "...") indicates that the back-end 2430 wants a mnemonic attribute to be generated. */ 2431 if (!mnemonic_attr) 2432 return; 2433 2434 mnemonic_htab = htab_create_alloc (MNEMONIC_HTAB_SIZE, htab_hash_string, 2435 htab_eq_string, 0, xcalloc, free); 2436 2437 for (elem = define_insn_queue; elem; elem = elem->next) 2438 { 2439 rtx insn = elem->data; 2440 bool found = false; 2441 2442 /* Check if the insn definition already has 2443 (set_attr "mnemonic" ...) or (set (attr "mnemonic") ...). */ 2444 if (XVEC (insn, 4)) 2445 for (i = 0; i < XVECLEN (insn, 4); i++) 2446 { 2447 rtx set_attr = XVECEXP (insn, 4, i); 2448 2449 switch (GET_CODE (set_attr)) 2450 { 2451 case SET_ATTR: 2452 case SET_ATTR_ALTERNATIVE: 2453 if (strcmp (XSTR (set_attr, 0), MNEMONIC_ATTR_NAME) == 0) 2454 found = true; 2455 break; 2456 case SET: 2457 if (GET_CODE (SET_DEST (set_attr)) == ATTR 2458 && strcmp (XSTR (SET_DEST (set_attr), 0), 2459 MNEMONIC_ATTR_NAME) == 0) 2460 found = true; 2461 break; 2462 default: 2463 break; 2464 } 2465 } 2466 2467 if (!found) 2468 gen_mnemonic_setattr (mnemonic_htab, insn); 2469 } 2470 2471 /* Add the user defined values to the hash table. */ 2472 str = XSTR (mnemonic_attr, 1); 2473 while ((p = scan_comma_elt (&str)) != NULL) 2474 add_mnemonic_string (mnemonic_htab, p, str - p); 2475 2476 htab_traverse (mnemonic_htab, mnemonic_htab_callback, NULL); 2477 2478 /* Replace the last ',' with the zero end character. */ 2479 *((char *) obstack_next_free (string_obstack) - 1) = '\0'; 2480 XSTR (mnemonic_attr, 1) = XOBFINISH (string_obstack, char *); 2481 } 2482 2483 /* Check if there are DEFINE_ATTRs with the same name. */ 2484 static void 2485 check_define_attr_duplicates () 2486 { 2487 struct queue_elem *elem; 2488 htab_t attr_htab; 2489 char * attr_name; 2490 void **slot; 2491 2492 attr_htab = htab_create (500, htab_hash_string, htab_eq_string, NULL); 2493 2494 for (elem = define_attr_queue; elem; elem = elem->next) 2495 { 2496 attr_name = xstrdup (XSTR (elem->data, 0)); 2497 2498 slot = htab_find_slot (attr_htab, attr_name, INSERT); 2499 2500 /* Duplicate. */ 2501 if (*slot) 2502 { 2503 error_at (elem->loc, "redefinition of attribute '%s'", attr_name); 2504 htab_delete (attr_htab); 2505 return; 2506 } 2507 2508 *slot = attr_name; 2509 } 2510 2511 htab_delete (attr_htab); 2512 } 2513 2514 /* The entry point for initializing the reader. */ 2515 2516 rtx_reader * 2517 init_rtx_reader_args_cb (int argc, const char **argv, 2518 bool (*parse_opt) (const char *)) 2519 { 2520 /* Prepare to read input. */ 2521 condition_table = htab_create (500, hash_c_test, cmp_c_test, NULL); 2522 init_predicate_table (); 2523 obstack_init (rtl_obstack); 2524 2525 /* Start at 1, to make 0 available for CODE_FOR_nothing. */ 2526 insn_sequence_num = 1; 2527 2528 /* These sequences are not used as indices, so can start at 1 also. */ 2529 split_sequence_num = 1; 2530 peephole2_sequence_num = 1; 2531 2532 gen_reader *reader = new gen_reader (); 2533 reader->read_md_files (argc, argv, parse_opt); 2534 2535 if (define_attr_queue != NULL) 2536 check_define_attr_duplicates (); 2537 2538 /* Process define_cond_exec patterns. */ 2539 if (define_cond_exec_queue != NULL) 2540 process_define_cond_exec (); 2541 2542 /* Process define_subst patterns. */ 2543 if (define_subst_queue != NULL) 2544 process_define_subst (); 2545 2546 if (define_attr_queue != NULL) 2547 gen_mnemonic_attr (); 2548 2549 if (have_error) 2550 { 2551 delete reader; 2552 return NULL; 2553 } 2554 2555 return reader; 2556 } 2557 2558 /* Programs that don't have their own options can use this entry point 2559 instead. */ 2560 rtx_reader * 2561 init_rtx_reader_args (int argc, const char **argv) 2562 { 2563 return init_rtx_reader_args_cb (argc, argv, 0); 2564 } 2565 2566 /* Try to read a single rtx from the file. Return true on success, 2567 describing it in *INFO. */ 2568 2569 bool 2570 read_md_rtx (md_rtx_info *info) 2571 { 2572 int truth, *counter; 2573 rtx def; 2574 2575 /* Discard insn patterns which we know can never match (because 2576 their C test is provably always false). If insn_elision is 2577 false, our caller needs to see all the patterns. Note that the 2578 elided patterns are never counted by the sequence numbering; it 2579 is the caller's responsibility, when insn_elision is false, not 2580 to use elided pattern numbers for anything. */ 2581 do 2582 { 2583 struct queue_elem **queue, *elem; 2584 2585 /* Read all patterns from a given queue before moving on to the next. */ 2586 if (define_attr_queue != NULL) 2587 queue = &define_attr_queue; 2588 else if (define_pred_queue != NULL) 2589 queue = &define_pred_queue; 2590 else if (define_insn_queue != NULL) 2591 queue = &define_insn_queue; 2592 else if (other_queue != NULL) 2593 queue = &other_queue; 2594 else 2595 return false; 2596 2597 elem = *queue; 2598 *queue = elem->next; 2599 def = elem->data; 2600 info->def = def; 2601 info->loc = elem->loc; 2602 free (elem); 2603 2604 truth = maybe_eval_c_test (get_c_test (def)); 2605 } 2606 while (truth == 0 && insn_elision); 2607 2608 /* Perform code-specific processing and pick the appropriate sequence 2609 number counter. */ 2610 switch (GET_CODE (def)) 2611 { 2612 case DEFINE_INSN: 2613 case DEFINE_EXPAND: 2614 /* insn_sequence_num is used here so the name table will match caller's 2615 idea of insn numbering, whether or not elision is active. */ 2616 record_insn_name (insn_sequence_num, XSTR (def, 0)); 2617 2618 /* Fall through. */ 2619 case DEFINE_PEEPHOLE: 2620 counter = &insn_sequence_num; 2621 break; 2622 2623 case DEFINE_SPLIT: 2624 counter = &split_sequence_num; 2625 break; 2626 2627 case DEFINE_PEEPHOLE2: 2628 counter = &peephole2_sequence_num; 2629 break; 2630 2631 default: 2632 counter = NULL; 2633 break; 2634 } 2635 2636 if (counter) 2637 { 2638 info->index = *counter; 2639 if (truth != 0) 2640 *counter += 1; 2641 } 2642 else 2643 info->index = -1; 2644 2645 if (!rtx_locs) 2646 rtx_locs = new hash_map <rtx, file_location>; 2647 rtx_locs->put (info->def, info->loc); 2648 2649 return true; 2650 } 2651 2652 /* Return the file location of DEFINE_* rtx X, which was previously 2653 returned by read_md_rtx. */ 2654 file_location 2655 get_file_location (rtx x) 2656 { 2657 gcc_assert (rtx_locs); 2658 file_location *entry = rtx_locs->get (x); 2659 gcc_assert (entry); 2660 return *entry; 2661 } 2662 2663 /* Return the number of possible INSN_CODEs. Only meaningful once the 2664 whole file has been processed. */ 2665 unsigned int 2666 get_num_insn_codes () 2667 { 2668 return insn_sequence_num; 2669 } 2670 2671 /* Return the C test that says whether definition rtx DEF can be used, 2672 or "" if it can be used unconditionally. */ 2673 2674 const char * 2675 get_c_test (rtx x) 2676 { 2677 switch (GET_CODE (x)) 2678 { 2679 case DEFINE_INSN: 2680 case DEFINE_EXPAND: 2681 case DEFINE_SUBST: 2682 return XSTR (x, 2); 2683 2684 case DEFINE_SPLIT: 2685 case DEFINE_PEEPHOLE: 2686 case DEFINE_PEEPHOLE2: 2687 return XSTR (x, 1); 2688 2689 default: 2690 return ""; 2691 } 2692 } 2693 2694 /* Helper functions for insn elision. */ 2695 2696 /* Compute a hash function of a c_test structure, which is keyed 2697 by its ->expr field. */ 2698 hashval_t 2699 hash_c_test (const void *x) 2700 { 2701 const struct c_test *a = (const struct c_test *) x; 2702 const unsigned char *base, *s = (const unsigned char *) a->expr; 2703 hashval_t hash; 2704 unsigned char c; 2705 unsigned int len; 2706 2707 base = s; 2708 hash = 0; 2709 2710 while ((c = *s++) != '\0') 2711 { 2712 hash += c + (c << 17); 2713 hash ^= hash >> 2; 2714 } 2715 2716 len = s - base; 2717 hash += len + (len << 17); 2718 hash ^= hash >> 2; 2719 2720 return hash; 2721 } 2722 2723 /* Compare two c_test expression structures. */ 2724 int 2725 cmp_c_test (const void *x, const void *y) 2726 { 2727 const struct c_test *a = (const struct c_test *) x; 2728 const struct c_test *b = (const struct c_test *) y; 2729 2730 return !strcmp (a->expr, b->expr); 2731 } 2732 2733 /* Given a string representing a C test expression, look it up in the 2734 condition_table and report whether or not its value is known 2735 at compile time. Returns a tristate: 1 for known true, 0 for 2736 known false, -1 for unknown. */ 2737 int 2738 maybe_eval_c_test (const char *expr) 2739 { 2740 const struct c_test *test; 2741 struct c_test dummy; 2742 2743 if (expr[0] == 0) 2744 return 1; 2745 2746 dummy.expr = expr; 2747 test = (const struct c_test *)htab_find (condition_table, &dummy); 2748 if (!test) 2749 return -1; 2750 return test->value; 2751 } 2752 2753 /* Record the C test expression EXPR in the condition_table, with 2754 value VAL. Duplicates clobber previous entries. */ 2755 2756 void 2757 add_c_test (const char *expr, int value) 2758 { 2759 struct c_test *test; 2760 2761 if (expr[0] == 0) 2762 return; 2763 2764 test = XNEW (struct c_test); 2765 test->expr = expr; 2766 test->value = value; 2767 2768 *(htab_find_slot (condition_table, test, INSERT)) = test; 2769 } 2770 2771 /* For every C test, call CALLBACK with two arguments: a pointer to 2772 the condition structure and INFO. Stops when CALLBACK returns zero. */ 2773 void 2774 traverse_c_tests (htab_trav callback, void *info) 2775 { 2776 if (condition_table) 2777 htab_traverse (condition_table, callback, info); 2778 } 2779 2780 /* Helper functions for define_predicate and define_special_predicate 2781 processing. Shared between genrecog.c and genpreds.c. */ 2782 2783 static htab_t predicate_table; 2784 struct pred_data *first_predicate; 2785 static struct pred_data **last_predicate = &first_predicate; 2786 2787 static hashval_t 2788 hash_struct_pred_data (const void *ptr) 2789 { 2790 return htab_hash_string (((const struct pred_data *)ptr)->name); 2791 } 2792 2793 static int 2794 eq_struct_pred_data (const void *a, const void *b) 2795 { 2796 return !strcmp (((const struct pred_data *)a)->name, 2797 ((const struct pred_data *)b)->name); 2798 } 2799 2800 struct pred_data * 2801 lookup_predicate (const char *name) 2802 { 2803 struct pred_data key; 2804 key.name = name; 2805 return (struct pred_data *) htab_find (predicate_table, &key); 2806 } 2807 2808 /* Record that predicate PRED can accept CODE. */ 2809 2810 void 2811 add_predicate_code (struct pred_data *pred, enum rtx_code code) 2812 { 2813 if (!pred->codes[code]) 2814 { 2815 pred->num_codes++; 2816 pred->codes[code] = true; 2817 2818 if (GET_RTX_CLASS (code) != RTX_CONST_OBJ) 2819 pred->allows_non_const = true; 2820 2821 if (code != REG 2822 && code != SUBREG 2823 && code != MEM 2824 && code != CONCAT 2825 && code != PARALLEL 2826 && code != STRICT_LOW_PART 2827 && code != SCRATCH) 2828 pred->allows_non_lvalue = true; 2829 2830 if (pred->num_codes == 1) 2831 pred->singleton = code; 2832 else if (pred->num_codes == 2) 2833 pred->singleton = UNKNOWN; 2834 } 2835 } 2836 2837 void 2838 add_predicate (struct pred_data *pred) 2839 { 2840 void **slot = htab_find_slot (predicate_table, pred, INSERT); 2841 if (*slot) 2842 { 2843 error ("duplicate predicate definition for '%s'", pred->name); 2844 return; 2845 } 2846 *slot = pred; 2847 *last_predicate = pred; 2848 last_predicate = &pred->next; 2849 } 2850 2851 /* This array gives the initial content of the predicate table. It 2852 has entries for all predicates defined in recog.c. */ 2853 2854 struct std_pred_table 2855 { 2856 const char *name; 2857 bool special; 2858 bool allows_const_p; 2859 RTX_CODE codes[NUM_RTX_CODE]; 2860 }; 2861 2862 static const struct std_pred_table std_preds[] = { 2863 {"general_operand", false, true, {SUBREG, REG, MEM}}, 2864 {"address_operand", true, true, {SUBREG, REG, MEM, PLUS, MINUS, MULT, 2865 ZERO_EXTEND, SIGN_EXTEND, AND}}, 2866 {"register_operand", false, false, {SUBREG, REG}}, 2867 {"pmode_register_operand", true, false, {SUBREG, REG}}, 2868 {"scratch_operand", false, false, {SCRATCH, REG}}, 2869 {"immediate_operand", false, true, {UNKNOWN}}, 2870 {"const_int_operand", false, false, {CONST_INT}}, 2871 #if TARGET_SUPPORTS_WIDE_INT 2872 {"const_scalar_int_operand", false, false, {CONST_INT, CONST_WIDE_INT}}, 2873 {"const_double_operand", false, false, {CONST_DOUBLE}}, 2874 #else 2875 {"const_double_operand", false, false, {CONST_INT, CONST_DOUBLE}}, 2876 #endif 2877 {"nonimmediate_operand", false, false, {SUBREG, REG, MEM}}, 2878 {"nonmemory_operand", false, true, {SUBREG, REG}}, 2879 {"push_operand", false, false, {MEM}}, 2880 {"pop_operand", false, false, {MEM}}, 2881 {"memory_operand", false, false, {SUBREG, MEM}}, 2882 {"indirect_operand", false, false, {SUBREG, MEM}}, 2883 {"ordered_comparison_operator", false, false, {EQ, NE, 2884 LE, LT, GE, GT, 2885 LEU, LTU, GEU, GTU}}, 2886 {"comparison_operator", false, false, {EQ, NE, 2887 LE, LT, GE, GT, 2888 LEU, LTU, GEU, GTU, 2889 UNORDERED, ORDERED, 2890 UNEQ, UNGE, UNGT, 2891 UNLE, UNLT, LTGT}} 2892 }; 2893 #define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds) 2894 2895 /* Initialize the table of predicate definitions, starting with 2896 the information we have on generic predicates. */ 2897 2898 static void 2899 init_predicate_table (void) 2900 { 2901 size_t i, j; 2902 struct pred_data *pred; 2903 2904 predicate_table = htab_create_alloc (37, hash_struct_pred_data, 2905 eq_struct_pred_data, 0, 2906 xcalloc, free); 2907 2908 for (i = 0; i < NUM_KNOWN_STD_PREDS; i++) 2909 { 2910 pred = XCNEW (struct pred_data); 2911 pred->name = std_preds[i].name; 2912 pred->special = std_preds[i].special; 2913 2914 for (j = 0; std_preds[i].codes[j] != 0; j++) 2915 add_predicate_code (pred, std_preds[i].codes[j]); 2916 2917 if (std_preds[i].allows_const_p) 2918 for (j = 0; j < NUM_RTX_CODE; j++) 2919 if (GET_RTX_CLASS (j) == RTX_CONST_OBJ) 2920 add_predicate_code (pred, (enum rtx_code) j); 2921 2922 add_predicate (pred); 2923 } 2924 } 2925 2926 /* These functions allow linkage with print-rtl.c. Also, some generators 2927 like to annotate their output with insn names. */ 2928 2929 /* Holds an array of names indexed by insn_code_number. */ 2930 static char **insn_name_ptr = 0; 2931 static int insn_name_ptr_size = 0; 2932 2933 const char * 2934 get_insn_name (int code) 2935 { 2936 if (code < insn_name_ptr_size) 2937 return insn_name_ptr[code]; 2938 else 2939 return NULL; 2940 } 2941 2942 static void 2943 record_insn_name (int code, const char *name) 2944 { 2945 static const char *last_real_name = "insn"; 2946 static int last_real_code = 0; 2947 char *new_name; 2948 2949 if (insn_name_ptr_size <= code) 2950 { 2951 int new_size; 2952 new_size = (insn_name_ptr_size ? insn_name_ptr_size * 2 : 512); 2953 insn_name_ptr = XRESIZEVEC (char *, insn_name_ptr, new_size); 2954 memset (insn_name_ptr + insn_name_ptr_size, 0, 2955 sizeof (char *) * (new_size - insn_name_ptr_size)); 2956 insn_name_ptr_size = new_size; 2957 } 2958 2959 if (!name || name[0] == '\0') 2960 { 2961 new_name = XNEWVAR (char, strlen (last_real_name) + 10); 2962 sprintf (new_name, "%s+%d", last_real_name, code - last_real_code); 2963 } 2964 else 2965 { 2966 last_real_name = new_name = xstrdup (name); 2967 last_real_code = code; 2968 } 2969 2970 insn_name_ptr[code] = new_name; 2971 } 2972 2973 /* Make STATS describe the operands that appear in rtx X. */ 2974 2975 static void 2976 get_pattern_stats_1 (struct pattern_stats *stats, rtx x) 2977 { 2978 RTX_CODE code; 2979 int i; 2980 int len; 2981 const char *fmt; 2982 2983 if (x == NULL_RTX) 2984 return; 2985 2986 code = GET_CODE (x); 2987 switch (code) 2988 { 2989 case MATCH_OPERAND: 2990 case MATCH_OPERATOR: 2991 case MATCH_PARALLEL: 2992 stats->max_opno = MAX (stats->max_opno, XINT (x, 0)); 2993 break; 2994 2995 case MATCH_DUP: 2996 case MATCH_OP_DUP: 2997 case MATCH_PAR_DUP: 2998 stats->num_dups++; 2999 stats->max_dup_opno = MAX (stats->max_dup_opno, XINT (x, 0)); 3000 break; 3001 3002 case MATCH_SCRATCH: 3003 if (stats->min_scratch_opno == -1) 3004 stats->min_scratch_opno = XINT (x, 0); 3005 else 3006 stats->min_scratch_opno = MIN (stats->min_scratch_opno, XINT (x, 0)); 3007 stats->max_scratch_opno = MAX (stats->max_scratch_opno, XINT (x, 0)); 3008 break; 3009 3010 default: 3011 break; 3012 } 3013 3014 fmt = GET_RTX_FORMAT (code); 3015 len = GET_RTX_LENGTH (code); 3016 for (i = 0; i < len; i++) 3017 { 3018 if (fmt[i] == 'e' || fmt[i] == 'u') 3019 get_pattern_stats_1 (stats, XEXP (x, i)); 3020 else if (fmt[i] == 'E') 3021 { 3022 int j; 3023 for (j = 0; j < XVECLEN (x, i); j++) 3024 get_pattern_stats_1 (stats, XVECEXP (x, i, j)); 3025 } 3026 } 3027 } 3028 3029 /* Make STATS describe the operands that appear in instruction pattern 3030 PATTERN. */ 3031 3032 void 3033 get_pattern_stats (struct pattern_stats *stats, rtvec pattern) 3034 { 3035 int i, len; 3036 3037 stats->max_opno = -1; 3038 stats->max_dup_opno = -1; 3039 stats->min_scratch_opno = -1; 3040 stats->max_scratch_opno = -1; 3041 stats->num_dups = 0; 3042 3043 len = GET_NUM_ELEM (pattern); 3044 for (i = 0; i < len; i++) 3045 get_pattern_stats_1 (stats, RTVEC_ELT (pattern, i)); 3046 3047 stats->num_generator_args = stats->max_opno + 1; 3048 stats->num_insn_operands = MAX (stats->max_opno, 3049 stats->max_scratch_opno) + 1; 3050 stats->num_operand_vars = MAX (stats->max_opno, 3051 MAX (stats->max_dup_opno, 3052 stats->max_scratch_opno)) + 1; 3053 } 3054 3055 /* Return the emit_* function that should be used for pattern X, or NULL 3056 if we can't pick a particular type at compile time and should instead 3057 fall back to "emit". */ 3058 3059 const char * 3060 get_emit_function (rtx x) 3061 { 3062 switch (classify_insn (x)) 3063 { 3064 case INSN: 3065 return "emit_insn"; 3066 3067 case CALL_INSN: 3068 return "emit_call_insn"; 3069 3070 case JUMP_INSN: 3071 return "emit_jump_insn"; 3072 3073 case UNKNOWN: 3074 return NULL; 3075 3076 default: 3077 gcc_unreachable (); 3078 } 3079 } 3080 3081 /* Return true if we must emit a barrier after pattern X. */ 3082 3083 bool 3084 needs_barrier_p (rtx x) 3085 { 3086 return (GET_CODE (x) == SET 3087 && GET_CODE (SET_DEST (x)) == PC 3088 && GET_CODE (SET_SRC (x)) == LABEL_REF); 3089 } 3090 3091 #define NS "NULL" 3092 #define ZS "'\\0'" 3093 #define OPTAB_CL(o, p, c, b, l) { #o, p, #b, ZS, #l, o, c, UNKNOWN, 1 }, 3094 #define OPTAB_CX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 1 }, 3095 #define OPTAB_CD(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 2 }, 3096 #define OPTAB_NL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, c, 3 }, 3097 #define OPTAB_NC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 3 }, 3098 #define OPTAB_NX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 }, 3099 #define OPTAB_VL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, UNKNOWN, 3 }, 3100 #define OPTAB_VC(o, p, c) { #o, p, NS, ZS, NS, o, c, UNKNOWN, 3 }, 3101 #define OPTAB_VX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 }, 3102 #define OPTAB_DC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 4 }, 3103 #define OPTAB_D(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 4 }, 3104 3105 /* An array of all optabs. Note that the same optab can appear more 3106 than once, with a different pattern. */ 3107 optab_def optabs[] = { 3108 { "unknown_optab", NULL, NS, ZS, NS, unknown_optab, UNKNOWN, UNKNOWN, 0 }, 3109 #include "optabs.def" 3110 }; 3111 3112 /* The number of entries in optabs[]. */ 3113 unsigned int num_optabs = ARRAY_SIZE (optabs); 3114 3115 #undef OPTAB_CL 3116 #undef OPTAB_CX 3117 #undef OPTAB_CD 3118 #undef OPTAB_NL 3119 #undef OPTAB_NC 3120 #undef OPTAB_NX 3121 #undef OPTAB_VL 3122 #undef OPTAB_VC 3123 #undef OPTAB_VX 3124 #undef OPTAB_DC 3125 #undef OPTAB_D 3126 3127 /* Return true if instruction NAME matches pattern PAT, storing information 3128 about the match in P if so. */ 3129 3130 static bool 3131 match_pattern (optab_pattern *p, const char *name, const char *pat) 3132 { 3133 bool force_float = false; 3134 bool force_int = false; 3135 bool force_partial_int = false; 3136 bool force_fixed = false; 3137 3138 if (pat == NULL) 3139 return false; 3140 for (; ; ++pat) 3141 { 3142 if (*pat != '$') 3143 { 3144 if (*pat != *name++) 3145 return false; 3146 if (*pat == '\0') 3147 return true; 3148 continue; 3149 } 3150 switch (*++pat) 3151 { 3152 case 'I': 3153 force_int = 1; 3154 break; 3155 case 'P': 3156 force_partial_int = 1; 3157 break; 3158 case 'F': 3159 force_float = 1; 3160 break; 3161 case 'Q': 3162 force_fixed = 1; 3163 break; 3164 3165 case 'a': 3166 case 'b': 3167 { 3168 int i; 3169 3170 /* This loop will stop at the first prefix match, so 3171 look through the modes in reverse order, in case 3172 there are extra CC modes and CC is a prefix of the 3173 CC modes (as it should be). */ 3174 for (i = (MAX_MACHINE_MODE) - 1; i >= 0; i--) 3175 { 3176 const char *p, *q; 3177 for (p = GET_MODE_NAME (i), q = name; *p; p++, q++) 3178 if (TOLOWER (*p) != *q) 3179 break; 3180 if (*p == 0 3181 && (! force_int || mode_class[i] == MODE_INT 3182 || mode_class[i] == MODE_VECTOR_INT) 3183 && (! force_partial_int 3184 || mode_class[i] == MODE_INT 3185 || mode_class[i] == MODE_PARTIAL_INT 3186 || mode_class[i] == MODE_VECTOR_INT) 3187 && (! force_float 3188 || mode_class[i] == MODE_FLOAT 3189 || mode_class[i] == MODE_DECIMAL_FLOAT 3190 || mode_class[i] == MODE_COMPLEX_FLOAT 3191 || mode_class[i] == MODE_VECTOR_FLOAT) 3192 && (! force_fixed 3193 || mode_class[i] == MODE_FRACT 3194 || mode_class[i] == MODE_UFRACT 3195 || mode_class[i] == MODE_ACCUM 3196 || mode_class[i] == MODE_UACCUM 3197 || mode_class[i] == MODE_VECTOR_FRACT 3198 || mode_class[i] == MODE_VECTOR_UFRACT 3199 || mode_class[i] == MODE_VECTOR_ACCUM 3200 || mode_class[i] == MODE_VECTOR_UACCUM)) 3201 break; 3202 } 3203 3204 if (i < 0) 3205 return false; 3206 name += strlen (GET_MODE_NAME (i)); 3207 if (*pat == 'a') 3208 p->m1 = i; 3209 else 3210 p->m2 = i; 3211 3212 force_int = false; 3213 force_partial_int = false; 3214 force_float = false; 3215 force_fixed = false; 3216 } 3217 break; 3218 3219 default: 3220 gcc_unreachable (); 3221 } 3222 } 3223 } 3224 3225 /* Return true if NAME is the name of an optab, describing it in P if so. */ 3226 3227 bool 3228 find_optab (optab_pattern *p, const char *name) 3229 { 3230 if (*name == 0 || *name == '*') 3231 return false; 3232 3233 /* See if NAME matches one of the patterns we have for the optabs 3234 we know about. */ 3235 for (unsigned int pindex = 0; pindex < ARRAY_SIZE (optabs); pindex++) 3236 { 3237 p->m1 = p->m2 = 0; 3238 if (match_pattern (p, name, optabs[pindex].pattern)) 3239 { 3240 p->name = name; 3241 p->op = optabs[pindex].op; 3242 p->sort_num = (p->op << 16) | (p->m2 << 8) | p->m1; 3243 return true; 3244 } 3245 } 3246 return false; 3247 } 3248