1 /* Support routines for the various generation passes. 2 Copyright (C) 2000-2018 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 'r': case 'p': case 'i': 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 'r': case 'p': case 'i': case 'w': 1051 case '0': case 's': case 'S': case 'T': 1052 break; 1053 1054 default: 1055 gcc_unreachable (); 1056 } 1057 } 1058 return 1; 1059 } 1060 1061 /* Determine how many alternatives there are in INSN, and how many 1062 operands. */ 1063 1064 static void 1065 collect_insn_data (rtx pattern, int *palt, int *pmax) 1066 { 1067 const char *fmt; 1068 enum rtx_code code; 1069 int i, j, len; 1070 1071 code = GET_CODE (pattern); 1072 switch (code) 1073 { 1074 case MATCH_OPERAND: 1075 case MATCH_SCRATCH: 1076 i = n_alternatives (XSTR (pattern, code == MATCH_SCRATCH ? 1 : 2)); 1077 *palt = (i > *palt ? i : *palt); 1078 /* Fall through. */ 1079 1080 case MATCH_OPERATOR: 1081 case MATCH_PARALLEL: 1082 i = XINT (pattern, 0); 1083 if (i > *pmax) 1084 *pmax = i; 1085 break; 1086 1087 default: 1088 break; 1089 } 1090 1091 fmt = GET_RTX_FORMAT (code); 1092 len = GET_RTX_LENGTH (code); 1093 for (i = 0; i < len; i++) 1094 { 1095 switch (fmt[i]) 1096 { 1097 case 'e': case 'u': 1098 collect_insn_data (XEXP (pattern, i), palt, pmax); 1099 break; 1100 1101 case 'V': 1102 if (XVEC (pattern, i) == NULL) 1103 break; 1104 /* Fall through. */ 1105 case 'E': 1106 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j) 1107 collect_insn_data (XVECEXP (pattern, i, j), palt, pmax); 1108 break; 1109 1110 case 'r': case 'p': case 'i': case 'w': 1111 case '0': case 's': case 'S': case 'T': 1112 break; 1113 1114 default: 1115 gcc_unreachable (); 1116 } 1117 } 1118 } 1119 1120 static rtx 1121 alter_predicate_for_insn (rtx pattern, int alt, int max_op, 1122 file_location loc) 1123 { 1124 const char *fmt; 1125 enum rtx_code code; 1126 int i, j, len; 1127 1128 code = GET_CODE (pattern); 1129 switch (code) 1130 { 1131 case MATCH_OPERAND: 1132 { 1133 const char *c = XSTR (pattern, 2); 1134 1135 if (n_alternatives (c) != 1) 1136 { 1137 error_at (loc, "too many alternatives for operand %d", 1138 XINT (pattern, 0)); 1139 return NULL; 1140 } 1141 1142 /* Replicate C as needed to fill out ALT alternatives. */ 1143 if (c && *c && alt > 1) 1144 { 1145 size_t c_len = strlen (c); 1146 size_t len = alt * (c_len + 1); 1147 char *new_c = XNEWVEC (char, len); 1148 1149 memcpy (new_c, c, c_len); 1150 for (i = 1; i < alt; ++i) 1151 { 1152 new_c[i * (c_len + 1) - 1] = ','; 1153 memcpy (&new_c[i * (c_len + 1)], c, c_len); 1154 } 1155 new_c[len - 1] = '\0'; 1156 XSTR (pattern, 2) = new_c; 1157 } 1158 } 1159 /* Fall through. */ 1160 1161 case MATCH_OPERATOR: 1162 case MATCH_SCRATCH: 1163 case MATCH_PARALLEL: 1164 XINT (pattern, 0) += max_op; 1165 break; 1166 1167 default: 1168 break; 1169 } 1170 1171 fmt = GET_RTX_FORMAT (code); 1172 len = GET_RTX_LENGTH (code); 1173 for (i = 0; i < len; i++) 1174 { 1175 rtx r; 1176 1177 switch (fmt[i]) 1178 { 1179 case 'e': case 'u': 1180 r = alter_predicate_for_insn (XEXP (pattern, i), alt, max_op, loc); 1181 if (r == NULL) 1182 return r; 1183 break; 1184 1185 case 'E': 1186 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j) 1187 { 1188 r = alter_predicate_for_insn (XVECEXP (pattern, i, j), 1189 alt, max_op, loc); 1190 if (r == NULL) 1191 return r; 1192 } 1193 break; 1194 1195 case 'r': case 'p': case 'i': case 'w': case '0': case 's': 1196 break; 1197 1198 default: 1199 gcc_unreachable (); 1200 } 1201 } 1202 1203 return pattern; 1204 } 1205 1206 /* Duplicate constraints in PATTERN. If pattern is from original 1207 rtl-template, we need to duplicate each alternative - for that we 1208 need to use duplicate_each_alternative () as a functor ALTER. 1209 If pattern is from output-pattern of define_subst, we need to 1210 duplicate constraints in another way - with duplicate_alternatives (). 1211 N_DUP is multiplication factor. */ 1212 static rtx 1213 alter_constraints (rtx pattern, int n_dup, constraints_handler_t alter) 1214 { 1215 const char *fmt; 1216 enum rtx_code code; 1217 int i, j, len; 1218 1219 code = GET_CODE (pattern); 1220 switch (code) 1221 { 1222 case MATCH_OPERAND: 1223 XSTR (pattern, 2) = alter (XSTR (pattern, 2), n_dup); 1224 break; 1225 1226 default: 1227 break; 1228 } 1229 1230 fmt = GET_RTX_FORMAT (code); 1231 len = GET_RTX_LENGTH (code); 1232 for (i = 0; i < len; i++) 1233 { 1234 rtx r; 1235 1236 switch (fmt[i]) 1237 { 1238 case 'e': case 'u': 1239 r = alter_constraints (XEXP (pattern, i), n_dup, alter); 1240 if (r == NULL) 1241 return r; 1242 break; 1243 1244 case 'E': 1245 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j) 1246 { 1247 r = alter_constraints (XVECEXP (pattern, i, j), n_dup, alter); 1248 if (r == NULL) 1249 return r; 1250 } 1251 break; 1252 1253 case 'r': case 'p': case 'i': case 'w': case '0': case 's': 1254 break; 1255 1256 default: 1257 break; 1258 } 1259 } 1260 1261 return pattern; 1262 } 1263 1264 static const char * 1265 alter_test_for_insn (struct queue_elem *ce_elem, 1266 struct queue_elem *insn_elem) 1267 { 1268 return rtx_reader_ptr->join_c_conditions (XSTR (ce_elem->data, 1), 1269 XSTR (insn_elem->data, 2)); 1270 } 1271 1272 /* Modify VAL, which is an attribute expression for the "enabled" attribute, 1273 to take "ce_enabled" into account. Return the new expression. */ 1274 static rtx 1275 modify_attr_enabled_ce (rtx val) 1276 { 1277 rtx eq_attr, str; 1278 rtx ite; 1279 eq_attr = rtx_alloc (EQ_ATTR); 1280 ite = rtx_alloc (IF_THEN_ELSE); 1281 str = rtx_alloc (CONST_STRING); 1282 1283 XSTR (eq_attr, 0) = "ce_enabled"; 1284 XSTR (eq_attr, 1) = "yes"; 1285 XSTR (str, 0) = "no"; 1286 XEXP (ite, 0) = eq_attr; 1287 XEXP (ite, 1) = val; 1288 XEXP (ite, 2) = str; 1289 1290 return ite; 1291 } 1292 1293 /* Alter the attribute vector of INSN, which is a COND_EXEC variant created 1294 from a define_insn pattern. We must modify the "predicable" attribute 1295 to be named "ce_enabled", and also change any "enabled" attribute that's 1296 present so that it takes ce_enabled into account. 1297 We rely on the fact that INSN was created with copy_rtx, and modify data 1298 in-place. */ 1299 1300 static void 1301 alter_attrs_for_insn (rtx insn) 1302 { 1303 static bool global_changes_made = false; 1304 rtvec vec = XVEC (insn, 4); 1305 rtvec new_vec; 1306 rtx val, set; 1307 int num_elem; 1308 int predicable_idx = -1; 1309 int enabled_idx = -1; 1310 int i; 1311 1312 if (! vec) 1313 return; 1314 1315 num_elem = GET_NUM_ELEM (vec); 1316 for (i = num_elem - 1; i >= 0; --i) 1317 { 1318 rtx sub = RTVEC_ELT (vec, i); 1319 switch (GET_CODE (sub)) 1320 { 1321 case SET_ATTR: 1322 if (strcmp (XSTR (sub, 0), "predicable") == 0) 1323 { 1324 predicable_idx = i; 1325 XSTR (sub, 0) = "ce_enabled"; 1326 } 1327 else if (strcmp (XSTR (sub, 0), "enabled") == 0) 1328 { 1329 enabled_idx = i; 1330 XSTR (sub, 0) = "nonce_enabled"; 1331 } 1332 break; 1333 1334 case SET_ATTR_ALTERNATIVE: 1335 if (strcmp (XSTR (sub, 0), "predicable") == 0) 1336 /* We already give an error elsewhere. */ 1337 return; 1338 else if (strcmp (XSTR (sub, 0), "enabled") == 0) 1339 { 1340 enabled_idx = i; 1341 XSTR (sub, 0) = "nonce_enabled"; 1342 } 1343 break; 1344 1345 case SET: 1346 if (GET_CODE (SET_DEST (sub)) != ATTR) 1347 break; 1348 if (strcmp (XSTR (SET_DEST (sub), 0), "predicable") == 0) 1349 { 1350 sub = SET_SRC (sub); 1351 if (GET_CODE (sub) == CONST_STRING) 1352 { 1353 predicable_idx = i; 1354 XSTR (sub, 0) = "ce_enabled"; 1355 } 1356 else 1357 /* We already give an error elsewhere. */ 1358 return; 1359 break; 1360 } 1361 if (strcmp (XSTR (SET_DEST (sub), 0), "enabled") == 0) 1362 { 1363 enabled_idx = i; 1364 XSTR (SET_DEST (sub), 0) = "nonce_enabled"; 1365 } 1366 break; 1367 1368 default: 1369 gcc_unreachable (); 1370 } 1371 } 1372 if (predicable_idx == -1) 1373 return; 1374 1375 if (!global_changes_made) 1376 { 1377 struct queue_elem *elem; 1378 1379 global_changes_made = true; 1380 add_define_attr ("ce_enabled"); 1381 add_define_attr ("nonce_enabled"); 1382 1383 for (elem = define_attr_queue; elem ; elem = elem->next) 1384 if (strcmp (XSTR (elem->data, 0), "enabled") == 0) 1385 { 1386 XEXP (elem->data, 2) 1387 = modify_attr_enabled_ce (XEXP (elem->data, 2)); 1388 } 1389 } 1390 if (enabled_idx == -1) 1391 return; 1392 1393 new_vec = rtvec_alloc (num_elem + 1); 1394 for (i = 0; i < num_elem; i++) 1395 RTVEC_ELT (new_vec, i) = RTVEC_ELT (vec, i); 1396 val = rtx_alloc (IF_THEN_ELSE); 1397 XEXP (val, 0) = rtx_alloc (EQ_ATTR); 1398 XEXP (val, 1) = rtx_alloc (CONST_STRING); 1399 XEXP (val, 2) = rtx_alloc (CONST_STRING); 1400 XSTR (XEXP (val, 0), 0) = "nonce_enabled"; 1401 XSTR (XEXP (val, 0), 1) = "yes"; 1402 XSTR (XEXP (val, 1), 0) = "yes"; 1403 XSTR (XEXP (val, 2), 0) = "no"; 1404 set = rtx_alloc (SET); 1405 SET_DEST (set) = rtx_alloc (ATTR); 1406 XSTR (SET_DEST (set), 0) = "enabled"; 1407 SET_SRC (set) = modify_attr_enabled_ce (val); 1408 RTVEC_ELT (new_vec, i) = set; 1409 XVEC (insn, 4) = new_vec; 1410 } 1411 1412 /* As number of constraints is changed after define_subst, we need to 1413 process attributes as well - we need to duplicate them the same way 1414 that we duplicated constraints in original pattern 1415 ELEM is a queue element, containing our rtl-template, 1416 N_DUP - multiplication factor. */ 1417 static void 1418 alter_attrs_for_subst_insn (struct queue_elem * elem, int n_dup) 1419 { 1420 rtvec vec = XVEC (elem->data, 4); 1421 int num_elem; 1422 int i; 1423 1424 if (n_dup < 2 || ! vec) 1425 return; 1426 1427 num_elem = GET_NUM_ELEM (vec); 1428 for (i = num_elem - 1; i >= 0; --i) 1429 { 1430 rtx sub = RTVEC_ELT (vec, i); 1431 switch (GET_CODE (sub)) 1432 { 1433 case SET_ATTR: 1434 if (strchr (XSTR (sub, 1), ',') != NULL) 1435 XSTR (sub, 1) = duplicate_alternatives (XSTR (sub, 1), n_dup); 1436 break; 1437 1438 case SET_ATTR_ALTERNATIVE: 1439 case SET: 1440 error_at (elem->loc, 1441 "%s: `define_subst' does not support attributes " 1442 "assigned by `set' and `set_attr_alternative'", 1443 XSTR (elem->data, 0)); 1444 return; 1445 1446 default: 1447 gcc_unreachable (); 1448 } 1449 } 1450 } 1451 1452 /* Adjust all of the operand numbers in SRC to match the shift they'll 1453 get from an operand displacement of DISP. Return a pointer after the 1454 adjusted string. */ 1455 1456 static char * 1457 shift_output_template (char *dest, const char *src, int disp) 1458 { 1459 while (*src) 1460 { 1461 char c = *src++; 1462 *dest++ = c; 1463 if (c == '%') 1464 { 1465 c = *src++; 1466 if (ISDIGIT ((unsigned char) c)) 1467 c += disp; 1468 else if (ISALPHA (c)) 1469 { 1470 *dest++ = c; 1471 c = *src++ + disp; 1472 } 1473 *dest++ = c; 1474 } 1475 } 1476 1477 return dest; 1478 } 1479 1480 static const char * 1481 alter_output_for_insn (struct queue_elem *ce_elem, 1482 struct queue_elem *insn_elem, 1483 int alt, int max_op) 1484 { 1485 const char *ce_out, *insn_out; 1486 char *result, *p; 1487 size_t len, ce_len, insn_len; 1488 1489 /* ??? Could coordinate with genoutput to not duplicate code here. */ 1490 1491 ce_out = XSTR (ce_elem->data, 2); 1492 insn_out = XTMPL (insn_elem->data, 3); 1493 if (!ce_out || *ce_out == '\0') 1494 return insn_out; 1495 1496 ce_len = strlen (ce_out); 1497 insn_len = strlen (insn_out); 1498 1499 if (*insn_out == '*') 1500 /* You must take care of the predicate yourself. */ 1501 return insn_out; 1502 1503 if (*insn_out == '@') 1504 { 1505 len = (ce_len + 1) * alt + insn_len + 1; 1506 p = result = XNEWVEC (char, len); 1507 1508 do 1509 { 1510 do 1511 *p++ = *insn_out++; 1512 while (ISSPACE ((unsigned char) *insn_out)); 1513 1514 if (*insn_out != '#') 1515 { 1516 p = shift_output_template (p, ce_out, max_op); 1517 *p++ = ' '; 1518 } 1519 1520 do 1521 *p++ = *insn_out++; 1522 while (*insn_out && *insn_out != '\n'); 1523 } 1524 while (*insn_out); 1525 *p = '\0'; 1526 } 1527 else 1528 { 1529 len = ce_len + 1 + insn_len + 1; 1530 result = XNEWVEC (char, len); 1531 1532 p = shift_output_template (result, ce_out, max_op); 1533 *p++ = ' '; 1534 memcpy (p, insn_out, insn_len + 1); 1535 } 1536 1537 return result; 1538 } 1539 1540 /* From string STR "a,b,c" produce "a,b,c,a,b,c,a,b,c", i.e. original 1541 string, duplicated N_DUP times. */ 1542 1543 static const char * 1544 duplicate_alternatives (const char * str, int n_dup) 1545 { 1546 int i, len, new_len; 1547 char *result, *sp; 1548 const char *cp; 1549 1550 if (n_dup < 2) 1551 return str; 1552 1553 while (ISSPACE (*str)) 1554 str++; 1555 1556 if (*str == '\0') 1557 return str; 1558 1559 cp = str; 1560 len = strlen (str); 1561 new_len = (len + 1) * n_dup; 1562 1563 sp = result = XNEWVEC (char, new_len); 1564 1565 /* Global modifier characters mustn't be duplicated: skip if found. */ 1566 if (*cp == '=' || *cp == '+' || *cp == '%') 1567 { 1568 *sp++ = *cp++; 1569 len--; 1570 } 1571 1572 /* Copy original constraints N_DUP times. */ 1573 for (i = 0; i < n_dup; i++, sp += len+1) 1574 { 1575 memcpy (sp, cp, len); 1576 *(sp+len) = (i == n_dup - 1) ? '\0' : ','; 1577 } 1578 1579 return result; 1580 } 1581 1582 /* From string STR "a,b,c" produce "a,a,a,b,b,b,c,c,c", i.e. string where 1583 each alternative from the original string is duplicated N_DUP times. */ 1584 static const char * 1585 duplicate_each_alternative (const char * str, int n_dup) 1586 { 1587 int i, len, new_len; 1588 char *result, *sp, *ep, *cp; 1589 1590 if (n_dup < 2) 1591 return str; 1592 1593 while (ISSPACE (*str)) 1594 str++; 1595 1596 if (*str == '\0') 1597 return str; 1598 1599 cp = xstrdup (str); 1600 1601 new_len = (strlen (cp) + 1) * n_dup; 1602 1603 sp = result = XNEWVEC (char, new_len); 1604 1605 /* Global modifier characters mustn't be duplicated: skip if found. */ 1606 if (*cp == '=' || *cp == '+' || *cp == '%') 1607 *sp++ = *cp++; 1608 1609 do 1610 { 1611 if ((ep = strchr (cp, ',')) != NULL) 1612 *ep++ = '\0'; 1613 len = strlen (cp); 1614 1615 /* Copy a constraint N_DUP times. */ 1616 for (i = 0; i < n_dup; i++, sp += len + 1) 1617 { 1618 memcpy (sp, cp, len); 1619 *(sp+len) = (ep == NULL && i == n_dup - 1) ? '\0' : ','; 1620 } 1621 1622 cp = ep; 1623 } 1624 while (cp != NULL); 1625 1626 return result; 1627 } 1628 1629 /* Alter the output of INSN whose pattern was modified by 1630 DEFINE_SUBST. We must replicate output strings according 1631 to the new number of alternatives ALT in substituted pattern. 1632 If ALT equals 1, output has one alternative or defined by C 1633 code, then output is returned without any changes. */ 1634 1635 static const char * 1636 alter_output_for_subst_insn (rtx insn, int alt) 1637 { 1638 const char *insn_out, *old_out; 1639 char *new_out, *cp; 1640 size_t old_len, new_len; 1641 int j; 1642 1643 insn_out = XTMPL (insn, 3); 1644 1645 if (alt < 2 || *insn_out != '@') 1646 return insn_out; 1647 1648 old_out = insn_out + 1; 1649 while (ISSPACE (*old_out)) 1650 old_out++; 1651 old_len = strlen (old_out); 1652 1653 new_len = alt * (old_len + 1) + 1; 1654 1655 new_out = XNEWVEC (char, new_len); 1656 new_out[0] = '@'; 1657 1658 for (j = 0, cp = new_out + 1; j < alt; j++, cp += old_len + 1) 1659 { 1660 memcpy (cp, old_out, old_len); 1661 cp[old_len] = (j == alt - 1) ? '\0' : '\n'; 1662 } 1663 1664 return new_out; 1665 } 1666 1667 /* Replicate insns as appropriate for the given DEFINE_COND_EXEC. */ 1668 1669 static void 1670 process_one_cond_exec (struct queue_elem *ce_elem) 1671 { 1672 struct queue_elem *insn_elem; 1673 for (insn_elem = define_insn_queue; insn_elem ; insn_elem = insn_elem->next) 1674 { 1675 int alternatives, max_operand; 1676 rtx pred, insn, pattern, split; 1677 char *new_name; 1678 int i; 1679 1680 if (! is_predicable (insn_elem)) 1681 continue; 1682 1683 alternatives = 1; 1684 max_operand = -1; 1685 collect_insn_data (insn_elem->data, &alternatives, &max_operand); 1686 max_operand += 1; 1687 1688 if (XVECLEN (ce_elem->data, 0) != 1) 1689 { 1690 error_at (ce_elem->loc, "too many patterns in predicate"); 1691 return; 1692 } 1693 1694 pred = copy_rtx (XVECEXP (ce_elem->data, 0, 0)); 1695 pred = alter_predicate_for_insn (pred, alternatives, max_operand, 1696 ce_elem->loc); 1697 if (pred == NULL) 1698 return; 1699 1700 /* Construct a new pattern for the new insn. */ 1701 insn = copy_rtx (insn_elem->data); 1702 new_name = XNEWVAR (char, strlen XSTR (insn_elem->data, 0) + 4); 1703 sprintf (new_name, "*p %s", XSTR (insn_elem->data, 0)); 1704 XSTR (insn, 0) = new_name; 1705 pattern = rtx_alloc (COND_EXEC); 1706 XEXP (pattern, 0) = pred; 1707 XEXP (pattern, 1) = add_implicit_parallel (XVEC (insn, 1)); 1708 XVEC (insn, 1) = rtvec_alloc (1); 1709 XVECEXP (insn, 1, 0) = pattern; 1710 1711 if (XVEC (ce_elem->data, 3) != NULL) 1712 { 1713 rtvec attributes = rtvec_alloc (XVECLEN (insn, 4) 1714 + XVECLEN (ce_elem->data, 3)); 1715 int i = 0; 1716 int j = 0; 1717 for (i = 0; i < XVECLEN (insn, 4); i++) 1718 RTVEC_ELT (attributes, i) = XVECEXP (insn, 4, i); 1719 1720 for (j = 0; j < XVECLEN (ce_elem->data, 3); j++, i++) 1721 RTVEC_ELT (attributes, i) = XVECEXP (ce_elem->data, 3, j); 1722 1723 XVEC (insn, 4) = attributes; 1724 } 1725 1726 XSTR (insn, 2) = alter_test_for_insn (ce_elem, insn_elem); 1727 XTMPL (insn, 3) = alter_output_for_insn (ce_elem, insn_elem, 1728 alternatives, max_operand); 1729 alter_attrs_for_insn (insn); 1730 1731 /* Put the new pattern on the `other' list so that it 1732 (a) is not reprocessed by other define_cond_exec patterns 1733 (b) appears after all normal define_insn patterns. 1734 1735 ??? B is debatable. If one has normal insns that match 1736 cond_exec patterns, they will be preferred over these 1737 generated patterns. Whether this matters in practice, or if 1738 it's a good thing, or whether we should thread these new 1739 patterns into the define_insn chain just after their generator 1740 is something we'll have to experiment with. */ 1741 1742 queue_pattern (insn, &other_tail, insn_elem->loc); 1743 1744 if (!insn_elem->split) 1745 continue; 1746 1747 /* If the original insn came from a define_insn_and_split, 1748 generate a new split to handle the predicated insn. */ 1749 split = copy_rtx (insn_elem->split->data); 1750 /* Predicate the pattern matched by the split. */ 1751 pattern = rtx_alloc (COND_EXEC); 1752 XEXP (pattern, 0) = pred; 1753 XEXP (pattern, 1) = add_implicit_parallel (XVEC (split, 0)); 1754 XVEC (split, 0) = rtvec_alloc (1); 1755 XVECEXP (split, 0, 0) = pattern; 1756 1757 /* Predicate all of the insns generated by the split. */ 1758 for (i = 0; i < XVECLEN (split, 2); i++) 1759 { 1760 pattern = rtx_alloc (COND_EXEC); 1761 XEXP (pattern, 0) = pred; 1762 XEXP (pattern, 1) = XVECEXP (split, 2, i); 1763 XVECEXP (split, 2, i) = pattern; 1764 } 1765 /* Add the new split to the queue. */ 1766 queue_pattern (split, &other_tail, insn_elem->split->loc); 1767 } 1768 } 1769 1770 /* Try to apply define_substs to the given ELEM. 1771 Only define_substs, specified via attributes would be applied. 1772 If attribute, requiring define_subst, is set, but no define_subst 1773 was applied, ELEM would be deleted. */ 1774 1775 static void 1776 process_substs_on_one_elem (struct queue_elem *elem, 1777 struct queue_elem *queue) 1778 { 1779 struct queue_elem *subst_elem; 1780 int i, j, patterns_match; 1781 1782 for (subst_elem = define_subst_queue; 1783 subst_elem; subst_elem = subst_elem->next) 1784 { 1785 int alternatives, alternatives_subst; 1786 rtx subst_pattern; 1787 rtvec subst_pattern_vec; 1788 1789 if (!has_subst_attribute (elem, subst_elem)) 1790 continue; 1791 1792 /* Compare original rtl-pattern from define_insn with input 1793 pattern from define_subst. 1794 Also, check if numbers of alternatives are the same in all 1795 match_operands. */ 1796 if (XVECLEN (elem->data, 1) != XVECLEN (subst_elem->data, 1)) 1797 continue; 1798 patterns_match = 1; 1799 alternatives = -1; 1800 alternatives_subst = -1; 1801 for (j = 0; j < XVECLEN (elem->data, 1); j++) 1802 { 1803 if (!subst_pattern_match (XVECEXP (elem->data, 1, j), 1804 XVECEXP (subst_elem->data, 1, j), 1805 subst_elem->loc)) 1806 { 1807 patterns_match = 0; 1808 break; 1809 } 1810 1811 if (!get_alternatives_number (XVECEXP (elem->data, 1, j), 1812 &alternatives, subst_elem->loc)) 1813 { 1814 patterns_match = 0; 1815 break; 1816 } 1817 } 1818 1819 /* Check if numbers of alternatives are the same in all 1820 match_operands in output template of define_subst. */ 1821 for (j = 0; j < XVECLEN (subst_elem->data, 3); j++) 1822 { 1823 if (!get_alternatives_number (XVECEXP (subst_elem->data, 3, j), 1824 &alternatives_subst, 1825 subst_elem->loc)) 1826 { 1827 patterns_match = 0; 1828 break; 1829 } 1830 } 1831 1832 if (!patterns_match) 1833 continue; 1834 1835 /* Clear array in which we save occupied indexes of operands. */ 1836 memset (used_operands_numbers, 0, sizeof (used_operands_numbers)); 1837 1838 /* Create a pattern, based on the output one from define_subst. */ 1839 subst_pattern_vec = rtvec_alloc (XVECLEN (subst_elem->data, 3)); 1840 for (j = 0; j < XVECLEN (subst_elem->data, 3); j++) 1841 { 1842 subst_pattern = copy_rtx (XVECEXP (subst_elem->data, 3, j)); 1843 1844 /* Duplicate constraints in substitute-pattern. */ 1845 subst_pattern = alter_constraints (subst_pattern, alternatives, 1846 duplicate_each_alternative); 1847 1848 subst_pattern = adjust_operands_numbers (subst_pattern); 1849 1850 /* Substitute match_dup and match_op_dup in the new pattern and 1851 duplicate constraints. */ 1852 subst_pattern = subst_dup (subst_pattern, alternatives, 1853 alternatives_subst); 1854 1855 replace_duplicating_operands_in_pattern (subst_pattern); 1856 1857 /* We don't need any constraints in DEFINE_EXPAND. */ 1858 if (GET_CODE (elem->data) == DEFINE_EXPAND) 1859 remove_constraints (subst_pattern); 1860 1861 RTVEC_ELT (subst_pattern_vec, j) = subst_pattern; 1862 } 1863 XVEC (elem->data, 1) = subst_pattern_vec; 1864 1865 for (i = 0; i < MAX_OPERANDS; i++) 1866 match_operand_entries_in_pattern[i] = NULL; 1867 1868 if (GET_CODE (elem->data) == DEFINE_INSN) 1869 { 1870 XTMPL (elem->data, 3) = 1871 alter_output_for_subst_insn (elem->data, alternatives_subst); 1872 alter_attrs_for_subst_insn (elem, alternatives_subst); 1873 } 1874 1875 /* Recalculate condition, joining conditions from original and 1876 DEFINE_SUBST input patterns. */ 1877 XSTR (elem->data, 2) 1878 = rtx_reader_ptr->join_c_conditions (XSTR (subst_elem->data, 2), 1879 XSTR (elem->data, 2)); 1880 /* Mark that subst was applied by changing attribute from "yes" 1881 to "no". */ 1882 change_subst_attribute (elem, subst_elem, subst_false); 1883 } 1884 1885 /* If ELEM contains a subst attribute with value "yes", then we 1886 expected that a subst would be applied, but it wasn't - so, 1887 we need to remove that elementto avoid duplicating. */ 1888 for (subst_elem = define_subst_queue; 1889 subst_elem; subst_elem = subst_elem->next) 1890 { 1891 if (has_subst_attribute (elem, subst_elem)) 1892 { 1893 remove_from_queue (elem, &queue); 1894 return; 1895 } 1896 } 1897 } 1898 1899 /* This is a subroutine of mark_operands_used_in_match_dup. 1900 This routine is marks all MATCH_OPERANDs inside PATTERN as occupied. */ 1901 static void 1902 mark_operands_from_match_dup (rtx pattern) 1903 { 1904 const char *fmt; 1905 int i, j, len, opno; 1906 1907 if (GET_CODE (pattern) == MATCH_OPERAND 1908 || GET_CODE (pattern) == MATCH_OPERATOR 1909 || GET_CODE (pattern) == MATCH_PARALLEL) 1910 { 1911 opno = XINT (pattern, 0); 1912 gcc_assert (opno >= 0 && opno < MAX_OPERANDS); 1913 used_operands_numbers [opno] = 1; 1914 } 1915 fmt = GET_RTX_FORMAT (GET_CODE (pattern)); 1916 len = GET_RTX_LENGTH (GET_CODE (pattern)); 1917 for (i = 0; i < len; i++) 1918 { 1919 switch (fmt[i]) 1920 { 1921 case 'e': case 'u': 1922 mark_operands_from_match_dup (XEXP (pattern, i)); 1923 break; 1924 case 'E': 1925 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j) 1926 mark_operands_from_match_dup (XVECEXP (pattern, i, j)); 1927 break; 1928 } 1929 } 1930 } 1931 1932 /* This is a subroutine of adjust_operands_numbers. 1933 It goes through all expressions in PATTERN and when MATCH_DUP is 1934 met, all MATCH_OPERANDs inside it is marked as occupied. The 1935 process of marking is done by routin mark_operands_from_match_dup. */ 1936 static void 1937 mark_operands_used_in_match_dup (rtx pattern) 1938 { 1939 const char *fmt; 1940 int i, j, len, opno; 1941 1942 if (GET_CODE (pattern) == MATCH_DUP) 1943 { 1944 opno = XINT (pattern, 0); 1945 gcc_assert (opno >= 0 && opno < MAX_OPERANDS); 1946 mark_operands_from_match_dup (operand_data[opno]); 1947 return; 1948 } 1949 fmt = GET_RTX_FORMAT (GET_CODE (pattern)); 1950 len = GET_RTX_LENGTH (GET_CODE (pattern)); 1951 for (i = 0; i < len; i++) 1952 { 1953 switch (fmt[i]) 1954 { 1955 case 'e': case 'u': 1956 mark_operands_used_in_match_dup (XEXP (pattern, i)); 1957 break; 1958 case 'E': 1959 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j) 1960 mark_operands_used_in_match_dup (XVECEXP (pattern, i, j)); 1961 break; 1962 } 1963 } 1964 } 1965 1966 /* This is subroutine of renumerate_operands_in_pattern. 1967 It finds first not-occupied operand-index. */ 1968 static int 1969 find_first_unused_number_of_operand () 1970 { 1971 int i; 1972 for (i = 0; i < MAX_OPERANDS; i++) 1973 if (!used_operands_numbers[i]) 1974 return i; 1975 return MAX_OPERANDS; 1976 } 1977 1978 /* This is subroutine of adjust_operands_numbers. 1979 It visits all expressions in PATTERN and assigns not-occupied 1980 operand indexes to MATCH_OPERANDs and MATCH_OPERATORs of this 1981 PATTERN. */ 1982 static void 1983 renumerate_operands_in_pattern (rtx pattern) 1984 { 1985 const char *fmt; 1986 enum rtx_code code; 1987 int i, j, len, new_opno; 1988 code = GET_CODE (pattern); 1989 1990 if (code == MATCH_OPERAND 1991 || code == MATCH_OPERATOR) 1992 { 1993 new_opno = find_first_unused_number_of_operand (); 1994 gcc_assert (new_opno >= 0 && new_opno < MAX_OPERANDS); 1995 XINT (pattern, 0) = new_opno; 1996 used_operands_numbers [new_opno] = 1; 1997 } 1998 1999 fmt = GET_RTX_FORMAT (GET_CODE (pattern)); 2000 len = GET_RTX_LENGTH (GET_CODE (pattern)); 2001 for (i = 0; i < len; i++) 2002 { 2003 switch (fmt[i]) 2004 { 2005 case 'e': case 'u': 2006 renumerate_operands_in_pattern (XEXP (pattern, i)); 2007 break; 2008 case 'E': 2009 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j) 2010 renumerate_operands_in_pattern (XVECEXP (pattern, i, j)); 2011 break; 2012 } 2013 } 2014 } 2015 2016 /* If output pattern of define_subst contains MATCH_DUP, then this 2017 expression would be replaced with the pattern, matched with 2018 MATCH_OPERAND from input pattern. This pattern could contain any 2019 number of MATCH_OPERANDs, MATCH_OPERATORs etc., so it's possible 2020 that a MATCH_OPERAND from output_pattern (if any) would have the 2021 same number, as MATCH_OPERAND from copied pattern. To avoid such 2022 indexes overlapping, we assign new indexes to MATCH_OPERANDs, 2023 laying in the output pattern outside of MATCH_DUPs. */ 2024 static rtx 2025 adjust_operands_numbers (rtx pattern) 2026 { 2027 mark_operands_used_in_match_dup (pattern); 2028 2029 renumerate_operands_in_pattern (pattern); 2030 2031 return pattern; 2032 } 2033 2034 /* Generate RTL expression 2035 (match_dup OPNO) 2036 */ 2037 static rtx 2038 generate_match_dup (int opno) 2039 { 2040 rtx return_rtx = rtx_alloc (MATCH_DUP); 2041 PUT_CODE (return_rtx, MATCH_DUP); 2042 XINT (return_rtx, 0) = opno; 2043 return return_rtx; 2044 } 2045 2046 /* This routine checks all match_operands in PATTERN and if some of 2047 have the same index, it replaces all of them except the first one to 2048 match_dup. 2049 Usually, match_operands with the same indexes are forbidden, but 2050 after define_subst copy an RTL-expression from original template, 2051 indexes of existed and just-copied match_operands could coincide. 2052 To fix it, we replace one of them with match_dup. */ 2053 static rtx 2054 replace_duplicating_operands_in_pattern (rtx pattern) 2055 { 2056 const char *fmt; 2057 int i, j, len, opno; 2058 rtx mdup; 2059 2060 if (GET_CODE (pattern) == MATCH_OPERAND) 2061 { 2062 opno = XINT (pattern, 0); 2063 gcc_assert (opno >= 0 && opno < MAX_OPERANDS); 2064 if (match_operand_entries_in_pattern[opno] == NULL) 2065 { 2066 match_operand_entries_in_pattern[opno] = pattern; 2067 return NULL; 2068 } 2069 else 2070 { 2071 /* Compare predicates before replacing with match_dup. */ 2072 if (strcmp (XSTR (pattern, 1), 2073 XSTR (match_operand_entries_in_pattern[opno], 1))) 2074 { 2075 error ("duplicated match_operands with different predicates were" 2076 " found."); 2077 return NULL; 2078 } 2079 return generate_match_dup (opno); 2080 } 2081 } 2082 fmt = GET_RTX_FORMAT (GET_CODE (pattern)); 2083 len = GET_RTX_LENGTH (GET_CODE (pattern)); 2084 for (i = 0; i < len; i++) 2085 { 2086 switch (fmt[i]) 2087 { 2088 case 'e': case 'u': 2089 mdup = replace_duplicating_operands_in_pattern (XEXP (pattern, i)); 2090 if (mdup) 2091 XEXP (pattern, i) = mdup; 2092 break; 2093 case 'E': 2094 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j) 2095 { 2096 mdup = 2097 replace_duplicating_operands_in_pattern (XVECEXP 2098 (pattern, i, j)); 2099 if (mdup) 2100 XVECEXP (pattern, i, j) = mdup; 2101 } 2102 break; 2103 } 2104 } 2105 return NULL; 2106 } 2107 2108 /* The routine modifies given input PATTERN of define_subst, replacing 2109 MATCH_DUP and MATCH_OP_DUP with operands from define_insn original 2110 pattern, whose operands are stored in OPERAND_DATA array. 2111 It also duplicates constraints in operands - constraints from 2112 define_insn operands are duplicated N_SUBST_ALT times, constraints 2113 from define_subst operands are duplicated N_ALT times. 2114 After the duplication, returned output rtl-pattern contains every 2115 combination of input constraints Vs constraints from define_subst 2116 output. */ 2117 static rtx 2118 subst_dup (rtx pattern, int n_alt, int n_subst_alt) 2119 { 2120 const char *fmt; 2121 enum rtx_code code; 2122 int i, j, len, opno; 2123 2124 code = GET_CODE (pattern); 2125 switch (code) 2126 { 2127 case MATCH_DUP: 2128 case MATCH_OP_DUP: 2129 opno = XINT (pattern, 0); 2130 2131 gcc_assert (opno >= 0 && opno < MAX_OPERANDS); 2132 2133 if (operand_data[opno]) 2134 { 2135 pattern = copy_rtx (operand_data[opno]); 2136 2137 /* Duplicate constraints. */ 2138 pattern = alter_constraints (pattern, n_subst_alt, 2139 duplicate_alternatives); 2140 } 2141 break; 2142 2143 default: 2144 break; 2145 } 2146 2147 fmt = GET_RTX_FORMAT (GET_CODE (pattern)); 2148 len = GET_RTX_LENGTH (GET_CODE (pattern)); 2149 for (i = 0; i < len; i++) 2150 { 2151 switch (fmt[i]) 2152 { 2153 case 'e': case 'u': 2154 if (code != MATCH_DUP && code != MATCH_OP_DUP) 2155 XEXP (pattern, i) = subst_dup (XEXP (pattern, i), 2156 n_alt, n_subst_alt); 2157 break; 2158 case 'V': 2159 if (XVEC (pattern, i) == NULL) 2160 break; 2161 /* FALLTHRU */ 2162 case 'E': 2163 if (code != MATCH_DUP && code != MATCH_OP_DUP) 2164 for (j = XVECLEN (pattern, i) - 1; j >= 0; --j) 2165 XVECEXP (pattern, i, j) = subst_dup (XVECEXP (pattern, i, j), 2166 n_alt, n_subst_alt); 2167 break; 2168 2169 case 'r': case 'p': case 'i': case 'w': 2170 case '0': case 's': case 'S': case 'T': 2171 break; 2172 2173 default: 2174 gcc_unreachable (); 2175 } 2176 } 2177 return pattern; 2178 } 2179 2180 /* If we have any DEFINE_COND_EXEC patterns, expand the DEFINE_INSN 2181 patterns appropriately. */ 2182 2183 static void 2184 process_define_cond_exec (void) 2185 { 2186 struct queue_elem *elem; 2187 2188 identify_predicable_attribute (); 2189 if (have_error) 2190 return; 2191 2192 for (elem = define_cond_exec_queue; elem ; elem = elem->next) 2193 process_one_cond_exec (elem); 2194 } 2195 2196 /* If we have any DEFINE_SUBST patterns, expand DEFINE_INSN and 2197 DEFINE_EXPAND patterns appropriately. */ 2198 2199 static void 2200 process_define_subst (void) 2201 { 2202 struct queue_elem *elem, *elem_attr; 2203 2204 /* Check if each define_subst has corresponding define_subst_attr. */ 2205 for (elem = define_subst_queue; elem ; elem = elem->next) 2206 { 2207 for (elem_attr = define_subst_attr_queue; 2208 elem_attr; 2209 elem_attr = elem_attr->next) 2210 if (strcmp (XSTR (elem->data, 0), XSTR (elem_attr->data, 1)) == 0) 2211 goto found; 2212 2213 error_at (elem->loc, 2214 "%s: `define_subst' must have at least one " 2215 "corresponding `define_subst_attr'", 2216 XSTR (elem->data, 0)); 2217 return; 2218 2219 found: 2220 continue; 2221 } 2222 2223 for (elem = define_insn_queue; elem ; elem = elem->next) 2224 process_substs_on_one_elem (elem, define_insn_queue); 2225 for (elem = other_queue; elem ; elem = elem->next) 2226 { 2227 if (GET_CODE (elem->data) != DEFINE_EXPAND) 2228 continue; 2229 process_substs_on_one_elem (elem, other_queue); 2230 } 2231 } 2232 2233 /* A subclass of rtx_reader which reads .md files and calls process_rtx on 2234 the top-level elements. */ 2235 2236 class gen_reader : public rtx_reader 2237 { 2238 public: 2239 gen_reader () : rtx_reader (false) {} 2240 void handle_unknown_directive (file_location, const char *); 2241 }; 2242 2243 void 2244 gen_reader::handle_unknown_directive (file_location loc, const char *rtx_name) 2245 { 2246 auto_vec<rtx, 32> subrtxs; 2247 if (!read_rtx (rtx_name, &subrtxs)) 2248 return; 2249 2250 rtx x; 2251 unsigned int i; 2252 FOR_EACH_VEC_ELT (subrtxs, i, x) 2253 process_rtx (x, loc); 2254 } 2255 2256 /* Comparison function for the mnemonic hash table. */ 2257 2258 static int 2259 htab_eq_string (const void *s1, const void *s2) 2260 { 2261 return strcmp ((const char*)s1, (const char*)s2) == 0; 2262 } 2263 2264 /* Add mnemonic STR with length LEN to the mnemonic hash table 2265 MNEMONIC_HTAB. A trailing zero end character is appended to STR 2266 and a permanent heap copy of STR is created. */ 2267 2268 static void 2269 add_mnemonic_string (htab_t mnemonic_htab, const char *str, size_t len) 2270 { 2271 char *new_str; 2272 void **slot; 2273 char *str_zero = (char*)alloca (len + 1); 2274 2275 memcpy (str_zero, str, len); 2276 str_zero[len] = '\0'; 2277 2278 slot = htab_find_slot (mnemonic_htab, str_zero, INSERT); 2279 2280 if (*slot) 2281 return; 2282 2283 /* Not found; create a permanent copy and add it to the hash table. */ 2284 new_str = XNEWVAR (char, len + 1); 2285 memcpy (new_str, str_zero, len + 1); 2286 *slot = new_str; 2287 } 2288 2289 /* Scan INSN for mnemonic strings and add them to the mnemonic hash 2290 table in MNEMONIC_HTAB. 2291 2292 The mnemonics cannot be found if they are emitted using C code. 2293 2294 If a mnemonic string contains ';' or a newline the string assumed 2295 to consist of more than a single instruction. The attribute value 2296 will then be set to the user defined default value. */ 2297 2298 static void 2299 gen_mnemonic_setattr (htab_t mnemonic_htab, rtx insn) 2300 { 2301 const char *template_code, *cp; 2302 int i; 2303 int vec_len; 2304 rtx set_attr; 2305 char *attr_name; 2306 rtvec new_vec; 2307 struct obstack *string_obstack = rtx_reader_ptr->get_string_obstack (); 2308 2309 template_code = XTMPL (insn, 3); 2310 2311 /* Skip patterns which use C code to emit the template. */ 2312 if (template_code[0] == '*') 2313 return; 2314 2315 if (template_code[0] == '@') 2316 cp = &template_code[1]; 2317 else 2318 cp = &template_code[0]; 2319 2320 for (i = 0; *cp; ) 2321 { 2322 const char *ep, *sp; 2323 size_t size = 0; 2324 2325 while (ISSPACE (*cp)) 2326 cp++; 2327 2328 for (ep = sp = cp; !IS_VSPACE (*ep) && *ep != '\0'; ++ep) 2329 if (!ISSPACE (*ep)) 2330 sp = ep + 1; 2331 2332 if (i > 0) 2333 obstack_1grow (string_obstack, ','); 2334 2335 while (cp < sp && ((*cp >= '0' && *cp <= '9') 2336 || (*cp >= 'a' && *cp <= 'z'))) 2337 2338 { 2339 obstack_1grow (string_obstack, *cp); 2340 cp++; 2341 size++; 2342 } 2343 2344 while (cp < sp) 2345 { 2346 if (*cp == ';' || (*cp == '\\' && cp[1] == 'n')) 2347 { 2348 /* Don't set a value if there are more than one 2349 instruction in the string. */ 2350 obstack_blank_fast (string_obstack, -size); 2351 size = 0; 2352 2353 cp = sp; 2354 break; 2355 } 2356 cp++; 2357 } 2358 if (size == 0) 2359 obstack_1grow (string_obstack, '*'); 2360 else 2361 add_mnemonic_string (mnemonic_htab, 2362 (char *) obstack_next_free (string_obstack) - size, 2363 size); 2364 i++; 2365 } 2366 2367 /* An insn definition might emit an empty string. */ 2368 if (obstack_object_size (string_obstack) == 0) 2369 return; 2370 2371 obstack_1grow (string_obstack, '\0'); 2372 2373 set_attr = rtx_alloc (SET_ATTR); 2374 XSTR (set_attr, 1) = XOBFINISH (string_obstack, char *); 2375 attr_name = XNEWVAR (char, strlen (MNEMONIC_ATTR_NAME) + 1); 2376 strcpy (attr_name, MNEMONIC_ATTR_NAME); 2377 XSTR (set_attr, 0) = attr_name; 2378 2379 if (!XVEC (insn, 4)) 2380 vec_len = 0; 2381 else 2382 vec_len = XVECLEN (insn, 4); 2383 2384 new_vec = rtvec_alloc (vec_len + 1); 2385 for (i = 0; i < vec_len; i++) 2386 RTVEC_ELT (new_vec, i) = XVECEXP (insn, 4, i); 2387 RTVEC_ELT (new_vec, vec_len) = set_attr; 2388 XVEC (insn, 4) = new_vec; 2389 } 2390 2391 /* This function is called for the elements in the mnemonic hashtable 2392 and generates a comma separated list of the mnemonics. */ 2393 2394 static int 2395 mnemonic_htab_callback (void **slot, void *info ATTRIBUTE_UNUSED) 2396 { 2397 struct obstack *string_obstack = rtx_reader_ptr->get_string_obstack (); 2398 2399 obstack_grow (string_obstack, (char*) *slot, strlen ((char*) *slot)); 2400 obstack_1grow (string_obstack, ','); 2401 return 1; 2402 } 2403 2404 /* Generate (set_attr "mnemonic" "..") RTXs and append them to every 2405 insn definition in case the back end requests it by defining the 2406 mnemonic attribute. The values for the attribute will be extracted 2407 from the output patterns of the insn definitions as far as 2408 possible. */ 2409 2410 static void 2411 gen_mnemonic_attr (void) 2412 { 2413 struct queue_elem *elem; 2414 rtx mnemonic_attr = NULL; 2415 htab_t mnemonic_htab; 2416 const char *str, *p; 2417 int i; 2418 struct obstack *string_obstack = rtx_reader_ptr->get_string_obstack (); 2419 2420 if (have_error) 2421 return; 2422 2423 /* Look for the DEFINE_ATTR for `mnemonic'. */ 2424 for (elem = define_attr_queue; elem != *define_attr_tail; elem = elem->next) 2425 if (GET_CODE (elem->data) == DEFINE_ATTR 2426 && strcmp (XSTR (elem->data, 0), MNEMONIC_ATTR_NAME) == 0) 2427 { 2428 mnemonic_attr = elem->data; 2429 break; 2430 } 2431 2432 /* A (define_attr "mnemonic" "...") indicates that the back-end 2433 wants a mnemonic attribute to be generated. */ 2434 if (!mnemonic_attr) 2435 return; 2436 2437 mnemonic_htab = htab_create_alloc (MNEMONIC_HTAB_SIZE, htab_hash_string, 2438 htab_eq_string, 0, xcalloc, free); 2439 2440 for (elem = define_insn_queue; elem; elem = elem->next) 2441 { 2442 rtx insn = elem->data; 2443 bool found = false; 2444 2445 /* Check if the insn definition already has 2446 (set_attr "mnemonic" ...) or (set (attr "mnemonic") ...). */ 2447 if (XVEC (insn, 4)) 2448 for (i = 0; i < XVECLEN (insn, 4); i++) 2449 { 2450 rtx set_attr = XVECEXP (insn, 4, i); 2451 2452 switch (GET_CODE (set_attr)) 2453 { 2454 case SET_ATTR: 2455 case SET_ATTR_ALTERNATIVE: 2456 if (strcmp (XSTR (set_attr, 0), MNEMONIC_ATTR_NAME) == 0) 2457 found = true; 2458 break; 2459 case SET: 2460 if (GET_CODE (SET_DEST (set_attr)) == ATTR 2461 && strcmp (XSTR (SET_DEST (set_attr), 0), 2462 MNEMONIC_ATTR_NAME) == 0) 2463 found = true; 2464 break; 2465 default: 2466 break; 2467 } 2468 } 2469 2470 if (!found) 2471 gen_mnemonic_setattr (mnemonic_htab, insn); 2472 } 2473 2474 /* Add the user defined values to the hash table. */ 2475 str = XSTR (mnemonic_attr, 1); 2476 while ((p = scan_comma_elt (&str)) != NULL) 2477 add_mnemonic_string (mnemonic_htab, p, str - p); 2478 2479 htab_traverse (mnemonic_htab, mnemonic_htab_callback, NULL); 2480 2481 /* Replace the last ',' with the zero end character. */ 2482 *((char *) obstack_next_free (string_obstack) - 1) = '\0'; 2483 XSTR (mnemonic_attr, 1) = XOBFINISH (string_obstack, char *); 2484 } 2485 2486 /* Check if there are DEFINE_ATTRs with the same name. */ 2487 static void 2488 check_define_attr_duplicates () 2489 { 2490 struct queue_elem *elem; 2491 htab_t attr_htab; 2492 char * attr_name; 2493 void **slot; 2494 2495 attr_htab = htab_create (500, htab_hash_string, htab_eq_string, NULL); 2496 2497 for (elem = define_attr_queue; elem; elem = elem->next) 2498 { 2499 attr_name = xstrdup (XSTR (elem->data, 0)); 2500 2501 slot = htab_find_slot (attr_htab, attr_name, INSERT); 2502 2503 /* Duplicate. */ 2504 if (*slot) 2505 { 2506 error_at (elem->loc, "redefinition of attribute '%s'", attr_name); 2507 htab_delete (attr_htab); 2508 return; 2509 } 2510 2511 *slot = attr_name; 2512 } 2513 2514 htab_delete (attr_htab); 2515 } 2516 2517 /* The entry point for initializing the reader. */ 2518 2519 rtx_reader * 2520 init_rtx_reader_args_cb (int argc, const char **argv, 2521 bool (*parse_opt) (const char *)) 2522 { 2523 /* Prepare to read input. */ 2524 condition_table = htab_create (500, hash_c_test, cmp_c_test, NULL); 2525 init_predicate_table (); 2526 obstack_init (rtl_obstack); 2527 2528 /* Start at 1, to make 0 available for CODE_FOR_nothing. */ 2529 insn_sequence_num = 1; 2530 2531 /* These sequences are not used as indices, so can start at 1 also. */ 2532 split_sequence_num = 1; 2533 peephole2_sequence_num = 1; 2534 2535 gen_reader *reader = new gen_reader (); 2536 reader->read_md_files (argc, argv, parse_opt); 2537 2538 if (define_attr_queue != NULL) 2539 check_define_attr_duplicates (); 2540 2541 /* Process define_cond_exec patterns. */ 2542 if (define_cond_exec_queue != NULL) 2543 process_define_cond_exec (); 2544 2545 /* Process define_subst patterns. */ 2546 if (define_subst_queue != NULL) 2547 process_define_subst (); 2548 2549 if (define_attr_queue != NULL) 2550 gen_mnemonic_attr (); 2551 2552 if (have_error) 2553 { 2554 delete reader; 2555 return NULL; 2556 } 2557 2558 return reader; 2559 } 2560 2561 /* Programs that don't have their own options can use this entry point 2562 instead. */ 2563 rtx_reader * 2564 init_rtx_reader_args (int argc, const char **argv) 2565 { 2566 return init_rtx_reader_args_cb (argc, argv, 0); 2567 } 2568 2569 /* Try to read a single rtx from the file. Return true on success, 2570 describing it in *INFO. */ 2571 2572 bool 2573 read_md_rtx (md_rtx_info *info) 2574 { 2575 int truth, *counter; 2576 rtx def; 2577 2578 /* Discard insn patterns which we know can never match (because 2579 their C test is provably always false). If insn_elision is 2580 false, our caller needs to see all the patterns. Note that the 2581 elided patterns are never counted by the sequence numbering; it 2582 is the caller's responsibility, when insn_elision is false, not 2583 to use elided pattern numbers for anything. */ 2584 do 2585 { 2586 struct queue_elem **queue, *elem; 2587 2588 /* Read all patterns from a given queue before moving on to the next. */ 2589 if (define_attr_queue != NULL) 2590 queue = &define_attr_queue; 2591 else if (define_pred_queue != NULL) 2592 queue = &define_pred_queue; 2593 else if (define_insn_queue != NULL) 2594 queue = &define_insn_queue; 2595 else if (other_queue != NULL) 2596 queue = &other_queue; 2597 else 2598 return false; 2599 2600 elem = *queue; 2601 *queue = elem->next; 2602 def = elem->data; 2603 info->def = def; 2604 info->loc = elem->loc; 2605 free (elem); 2606 2607 truth = maybe_eval_c_test (get_c_test (def)); 2608 } 2609 while (truth == 0 && insn_elision); 2610 2611 /* Perform code-specific processing and pick the appropriate sequence 2612 number counter. */ 2613 switch (GET_CODE (def)) 2614 { 2615 case DEFINE_INSN: 2616 case DEFINE_EXPAND: 2617 /* insn_sequence_num is used here so the name table will match caller's 2618 idea of insn numbering, whether or not elision is active. */ 2619 record_insn_name (insn_sequence_num, XSTR (def, 0)); 2620 2621 /* Fall through. */ 2622 case DEFINE_PEEPHOLE: 2623 counter = &insn_sequence_num; 2624 break; 2625 2626 case DEFINE_SPLIT: 2627 counter = &split_sequence_num; 2628 break; 2629 2630 case DEFINE_PEEPHOLE2: 2631 counter = &peephole2_sequence_num; 2632 break; 2633 2634 default: 2635 counter = NULL; 2636 break; 2637 } 2638 2639 if (counter) 2640 { 2641 info->index = *counter; 2642 if (truth != 0) 2643 *counter += 1; 2644 } 2645 else 2646 info->index = -1; 2647 2648 if (!rtx_locs) 2649 rtx_locs = new hash_map <rtx, file_location>; 2650 rtx_locs->put (info->def, info->loc); 2651 2652 return true; 2653 } 2654 2655 /* Return the file location of DEFINE_* rtx X, which was previously 2656 returned by read_md_rtx. */ 2657 file_location 2658 get_file_location (rtx x) 2659 { 2660 gcc_assert (rtx_locs); 2661 file_location *entry = rtx_locs->get (x); 2662 gcc_assert (entry); 2663 return *entry; 2664 } 2665 2666 /* Return the number of possible INSN_CODEs. Only meaningful once the 2667 whole file has been processed. */ 2668 unsigned int 2669 get_num_insn_codes () 2670 { 2671 return insn_sequence_num; 2672 } 2673 2674 /* Return the C test that says whether definition rtx DEF can be used, 2675 or "" if it can be used unconditionally. */ 2676 2677 const char * 2678 get_c_test (rtx x) 2679 { 2680 switch (GET_CODE (x)) 2681 { 2682 case DEFINE_INSN: 2683 case DEFINE_EXPAND: 2684 case DEFINE_SUBST: 2685 return XSTR (x, 2); 2686 2687 case DEFINE_SPLIT: 2688 case DEFINE_PEEPHOLE: 2689 case DEFINE_PEEPHOLE2: 2690 return XSTR (x, 1); 2691 2692 default: 2693 return ""; 2694 } 2695 } 2696 2697 /* Helper functions for insn elision. */ 2698 2699 /* Compute a hash function of a c_test structure, which is keyed 2700 by its ->expr field. */ 2701 hashval_t 2702 hash_c_test (const void *x) 2703 { 2704 const struct c_test *a = (const struct c_test *) x; 2705 const unsigned char *base, *s = (const unsigned char *) a->expr; 2706 hashval_t hash; 2707 unsigned char c; 2708 unsigned int len; 2709 2710 base = s; 2711 hash = 0; 2712 2713 while ((c = *s++) != '\0') 2714 { 2715 hash += c + (c << 17); 2716 hash ^= hash >> 2; 2717 } 2718 2719 len = s - base; 2720 hash += len + (len << 17); 2721 hash ^= hash >> 2; 2722 2723 return hash; 2724 } 2725 2726 /* Compare two c_test expression structures. */ 2727 int 2728 cmp_c_test (const void *x, const void *y) 2729 { 2730 const struct c_test *a = (const struct c_test *) x; 2731 const struct c_test *b = (const struct c_test *) y; 2732 2733 return !strcmp (a->expr, b->expr); 2734 } 2735 2736 /* Given a string representing a C test expression, look it up in the 2737 condition_table and report whether or not its value is known 2738 at compile time. Returns a tristate: 1 for known true, 0 for 2739 known false, -1 for unknown. */ 2740 int 2741 maybe_eval_c_test (const char *expr) 2742 { 2743 const struct c_test *test; 2744 struct c_test dummy; 2745 2746 if (expr[0] == 0) 2747 return 1; 2748 2749 dummy.expr = expr; 2750 test = (const struct c_test *)htab_find (condition_table, &dummy); 2751 if (!test) 2752 return -1; 2753 return test->value; 2754 } 2755 2756 /* Record the C test expression EXPR in the condition_table, with 2757 value VAL. Duplicates clobber previous entries. */ 2758 2759 void 2760 add_c_test (const char *expr, int value) 2761 { 2762 struct c_test *test; 2763 2764 if (expr[0] == 0) 2765 return; 2766 2767 test = XNEW (struct c_test); 2768 test->expr = expr; 2769 test->value = value; 2770 2771 *(htab_find_slot (condition_table, test, INSERT)) = test; 2772 } 2773 2774 /* For every C test, call CALLBACK with two arguments: a pointer to 2775 the condition structure and INFO. Stops when CALLBACK returns zero. */ 2776 void 2777 traverse_c_tests (htab_trav callback, void *info) 2778 { 2779 if (condition_table) 2780 htab_traverse (condition_table, callback, info); 2781 } 2782 2783 /* Helper functions for define_predicate and define_special_predicate 2784 processing. Shared between genrecog.c and genpreds.c. */ 2785 2786 static htab_t predicate_table; 2787 struct pred_data *first_predicate; 2788 static struct pred_data **last_predicate = &first_predicate; 2789 2790 static hashval_t 2791 hash_struct_pred_data (const void *ptr) 2792 { 2793 return htab_hash_string (((const struct pred_data *)ptr)->name); 2794 } 2795 2796 static int 2797 eq_struct_pred_data (const void *a, const void *b) 2798 { 2799 return !strcmp (((const struct pred_data *)a)->name, 2800 ((const struct pred_data *)b)->name); 2801 } 2802 2803 struct pred_data * 2804 lookup_predicate (const char *name) 2805 { 2806 struct pred_data key; 2807 key.name = name; 2808 return (struct pred_data *) htab_find (predicate_table, &key); 2809 } 2810 2811 /* Record that predicate PRED can accept CODE. */ 2812 2813 void 2814 add_predicate_code (struct pred_data *pred, enum rtx_code code) 2815 { 2816 if (!pred->codes[code]) 2817 { 2818 pred->num_codes++; 2819 pred->codes[code] = true; 2820 2821 if (GET_RTX_CLASS (code) != RTX_CONST_OBJ) 2822 pred->allows_non_const = true; 2823 2824 if (code != REG 2825 && code != SUBREG 2826 && code != MEM 2827 && code != CONCAT 2828 && code != PARALLEL 2829 && code != STRICT_LOW_PART 2830 && code != SCRATCH) 2831 pred->allows_non_lvalue = true; 2832 2833 if (pred->num_codes == 1) 2834 pred->singleton = code; 2835 else if (pred->num_codes == 2) 2836 pred->singleton = UNKNOWN; 2837 } 2838 } 2839 2840 void 2841 add_predicate (struct pred_data *pred) 2842 { 2843 void **slot = htab_find_slot (predicate_table, pred, INSERT); 2844 if (*slot) 2845 { 2846 error ("duplicate predicate definition for '%s'", pred->name); 2847 return; 2848 } 2849 *slot = pred; 2850 *last_predicate = pred; 2851 last_predicate = &pred->next; 2852 } 2853 2854 /* This array gives the initial content of the predicate table. It 2855 has entries for all predicates defined in recog.c. */ 2856 2857 struct std_pred_table 2858 { 2859 const char *name; 2860 bool special; 2861 bool allows_const_p; 2862 RTX_CODE codes[NUM_RTX_CODE]; 2863 }; 2864 2865 static const struct std_pred_table std_preds[] = { 2866 {"general_operand", false, true, {SUBREG, REG, MEM}}, 2867 {"address_operand", true, true, {SUBREG, REG, MEM, PLUS, MINUS, MULT, 2868 ZERO_EXTEND, SIGN_EXTEND, AND}}, 2869 {"register_operand", false, false, {SUBREG, REG}}, 2870 {"pmode_register_operand", true, false, {SUBREG, REG}}, 2871 {"scratch_operand", false, false, {SCRATCH, REG}}, 2872 {"immediate_operand", false, true, {UNKNOWN}}, 2873 {"const_int_operand", false, false, {CONST_INT}}, 2874 #if TARGET_SUPPORTS_WIDE_INT 2875 {"const_scalar_int_operand", false, false, {CONST_INT, CONST_WIDE_INT}}, 2876 {"const_double_operand", false, false, {CONST_DOUBLE}}, 2877 #else 2878 {"const_double_operand", false, false, {CONST_INT, CONST_DOUBLE}}, 2879 #endif 2880 {"nonimmediate_operand", false, false, {SUBREG, REG, MEM}}, 2881 {"nonmemory_operand", false, true, {SUBREG, REG}}, 2882 {"push_operand", false, false, {MEM}}, 2883 {"pop_operand", false, false, {MEM}}, 2884 {"memory_operand", false, false, {SUBREG, MEM}}, 2885 {"indirect_operand", false, false, {SUBREG, MEM}}, 2886 {"ordered_comparison_operator", false, false, {EQ, NE, 2887 LE, LT, GE, GT, 2888 LEU, LTU, GEU, GTU}}, 2889 {"comparison_operator", false, false, {EQ, NE, 2890 LE, LT, GE, GT, 2891 LEU, LTU, GEU, GTU, 2892 UNORDERED, ORDERED, 2893 UNEQ, UNGE, UNGT, 2894 UNLE, UNLT, LTGT}} 2895 }; 2896 #define NUM_KNOWN_STD_PREDS ARRAY_SIZE (std_preds) 2897 2898 /* Initialize the table of predicate definitions, starting with 2899 the information we have on generic predicates. */ 2900 2901 static void 2902 init_predicate_table (void) 2903 { 2904 size_t i, j; 2905 struct pred_data *pred; 2906 2907 predicate_table = htab_create_alloc (37, hash_struct_pred_data, 2908 eq_struct_pred_data, 0, 2909 xcalloc, free); 2910 2911 for (i = 0; i < NUM_KNOWN_STD_PREDS; i++) 2912 { 2913 pred = XCNEW (struct pred_data); 2914 pred->name = std_preds[i].name; 2915 pred->special = std_preds[i].special; 2916 2917 for (j = 0; std_preds[i].codes[j] != 0; j++) 2918 add_predicate_code (pred, std_preds[i].codes[j]); 2919 2920 if (std_preds[i].allows_const_p) 2921 for (j = 0; j < NUM_RTX_CODE; j++) 2922 if (GET_RTX_CLASS (j) == RTX_CONST_OBJ) 2923 add_predicate_code (pred, (enum rtx_code) j); 2924 2925 add_predicate (pred); 2926 } 2927 } 2928 2929 /* These functions allow linkage with print-rtl.c. Also, some generators 2930 like to annotate their output with insn names. */ 2931 2932 /* Holds an array of names indexed by insn_code_number. */ 2933 static char **insn_name_ptr = 0; 2934 static int insn_name_ptr_size = 0; 2935 2936 const char * 2937 get_insn_name (int code) 2938 { 2939 if (code < insn_name_ptr_size) 2940 return insn_name_ptr[code]; 2941 else 2942 return NULL; 2943 } 2944 2945 static void 2946 record_insn_name (int code, const char *name) 2947 { 2948 static const char *last_real_name = "insn"; 2949 static int last_real_code = 0; 2950 char *new_name; 2951 2952 if (insn_name_ptr_size <= code) 2953 { 2954 int new_size; 2955 new_size = (insn_name_ptr_size ? insn_name_ptr_size * 2 : 512); 2956 insn_name_ptr = XRESIZEVEC (char *, insn_name_ptr, new_size); 2957 memset (insn_name_ptr + insn_name_ptr_size, 0, 2958 sizeof (char *) * (new_size - insn_name_ptr_size)); 2959 insn_name_ptr_size = new_size; 2960 } 2961 2962 if (!name || name[0] == '\0') 2963 { 2964 new_name = XNEWVAR (char, strlen (last_real_name) + 10); 2965 sprintf (new_name, "%s+%d", last_real_name, code - last_real_code); 2966 } 2967 else 2968 { 2969 last_real_name = new_name = xstrdup (name); 2970 last_real_code = code; 2971 } 2972 2973 insn_name_ptr[code] = new_name; 2974 } 2975 2976 /* Make STATS describe the operands that appear in rtx X. */ 2977 2978 static void 2979 get_pattern_stats_1 (struct pattern_stats *stats, rtx x) 2980 { 2981 RTX_CODE code; 2982 int i; 2983 int len; 2984 const char *fmt; 2985 2986 if (x == NULL_RTX) 2987 return; 2988 2989 code = GET_CODE (x); 2990 switch (code) 2991 { 2992 case MATCH_OPERAND: 2993 case MATCH_OPERATOR: 2994 case MATCH_PARALLEL: 2995 stats->max_opno = MAX (stats->max_opno, XINT (x, 0)); 2996 break; 2997 2998 case MATCH_DUP: 2999 case MATCH_OP_DUP: 3000 case MATCH_PAR_DUP: 3001 stats->num_dups++; 3002 stats->max_dup_opno = MAX (stats->max_dup_opno, XINT (x, 0)); 3003 break; 3004 3005 case MATCH_SCRATCH: 3006 if (stats->min_scratch_opno == -1) 3007 stats->min_scratch_opno = XINT (x, 0); 3008 else 3009 stats->min_scratch_opno = MIN (stats->min_scratch_opno, XINT (x, 0)); 3010 stats->max_scratch_opno = MAX (stats->max_scratch_opno, XINT (x, 0)); 3011 break; 3012 3013 default: 3014 break; 3015 } 3016 3017 fmt = GET_RTX_FORMAT (code); 3018 len = GET_RTX_LENGTH (code); 3019 for (i = 0; i < len; i++) 3020 { 3021 if (fmt[i] == 'e' || fmt[i] == 'u') 3022 get_pattern_stats_1 (stats, XEXP (x, i)); 3023 else if (fmt[i] == 'E') 3024 { 3025 int j; 3026 for (j = 0; j < XVECLEN (x, i); j++) 3027 get_pattern_stats_1 (stats, XVECEXP (x, i, j)); 3028 } 3029 } 3030 } 3031 3032 /* Make STATS describe the operands that appear in instruction pattern 3033 PATTERN. */ 3034 3035 void 3036 get_pattern_stats (struct pattern_stats *stats, rtvec pattern) 3037 { 3038 int i, len; 3039 3040 stats->max_opno = -1; 3041 stats->max_dup_opno = -1; 3042 stats->min_scratch_opno = -1; 3043 stats->max_scratch_opno = -1; 3044 stats->num_dups = 0; 3045 3046 len = GET_NUM_ELEM (pattern); 3047 for (i = 0; i < len; i++) 3048 get_pattern_stats_1 (stats, RTVEC_ELT (pattern, i)); 3049 3050 stats->num_generator_args = stats->max_opno + 1; 3051 stats->num_insn_operands = MAX (stats->max_opno, 3052 stats->max_scratch_opno) + 1; 3053 stats->num_operand_vars = MAX (stats->max_opno, 3054 MAX (stats->max_dup_opno, 3055 stats->max_scratch_opno)) + 1; 3056 } 3057 3058 /* Return the emit_* function that should be used for pattern X, or NULL 3059 if we can't pick a particular type at compile time and should instead 3060 fall back to "emit". */ 3061 3062 const char * 3063 get_emit_function (rtx x) 3064 { 3065 switch (classify_insn (x)) 3066 { 3067 case INSN: 3068 return "emit_insn"; 3069 3070 case CALL_INSN: 3071 return "emit_call_insn"; 3072 3073 case JUMP_INSN: 3074 return "emit_jump_insn"; 3075 3076 case UNKNOWN: 3077 return NULL; 3078 3079 default: 3080 gcc_unreachable (); 3081 } 3082 } 3083 3084 /* Return true if we must emit a barrier after pattern X. */ 3085 3086 bool 3087 needs_barrier_p (rtx x) 3088 { 3089 return (GET_CODE (x) == SET 3090 && GET_CODE (SET_DEST (x)) == PC 3091 && GET_CODE (SET_SRC (x)) == LABEL_REF); 3092 } 3093 3094 #define NS "NULL" 3095 #define ZS "'\\0'" 3096 #define OPTAB_CL(o, p, c, b, l) { #o, p, #b, ZS, #l, o, c, UNKNOWN, 1 }, 3097 #define OPTAB_CX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 1 }, 3098 #define OPTAB_CD(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 2 }, 3099 #define OPTAB_NL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, c, 3 }, 3100 #define OPTAB_NC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 3 }, 3101 #define OPTAB_NX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 }, 3102 #define OPTAB_VL(o, p, c, b, s, l) { #o, p, #b, #s, #l, o, c, UNKNOWN, 3 }, 3103 #define OPTAB_VC(o, p, c) { #o, p, NS, ZS, NS, o, c, UNKNOWN, 3 }, 3104 #define OPTAB_VX(o, p) { #o, p, NULL, NULL, NULL, o, UNKNOWN, UNKNOWN, 3 }, 3105 #define OPTAB_DC(o, p, c) { #o, p, NS, ZS, NS, o, c, c, 4 }, 3106 #define OPTAB_D(o, p) { #o, p, NS, ZS, NS, o, UNKNOWN, UNKNOWN, 4 }, 3107 3108 /* An array of all optabs. Note that the same optab can appear more 3109 than once, with a different pattern. */ 3110 optab_def optabs[] = { 3111 { "unknown_optab", NULL, NS, ZS, NS, unknown_optab, UNKNOWN, UNKNOWN, 0 }, 3112 #include "optabs.def" 3113 }; 3114 3115 /* The number of entries in optabs[]. */ 3116 unsigned int num_optabs = ARRAY_SIZE (optabs); 3117 3118 #undef OPTAB_CL 3119 #undef OPTAB_CX 3120 #undef OPTAB_CD 3121 #undef OPTAB_NL 3122 #undef OPTAB_NC 3123 #undef OPTAB_NX 3124 #undef OPTAB_VL 3125 #undef OPTAB_VC 3126 #undef OPTAB_VX 3127 #undef OPTAB_DC 3128 #undef OPTAB_D 3129 3130 /* Return true if instruction NAME matches pattern PAT, storing information 3131 about the match in P if so. */ 3132 3133 static bool 3134 match_pattern (optab_pattern *p, const char *name, const char *pat) 3135 { 3136 bool force_float = false; 3137 bool force_int = false; 3138 bool force_partial_int = false; 3139 bool force_fixed = false; 3140 3141 if (pat == NULL) 3142 return false; 3143 for (; ; ++pat) 3144 { 3145 if (*pat != '$') 3146 { 3147 if (*pat != *name++) 3148 return false; 3149 if (*pat == '\0') 3150 return true; 3151 continue; 3152 } 3153 switch (*++pat) 3154 { 3155 case 'I': 3156 force_int = 1; 3157 break; 3158 case 'P': 3159 force_partial_int = 1; 3160 break; 3161 case 'F': 3162 force_float = 1; 3163 break; 3164 case 'Q': 3165 force_fixed = 1; 3166 break; 3167 3168 case 'a': 3169 case 'b': 3170 { 3171 int i; 3172 3173 /* This loop will stop at the first prefix match, so 3174 look through the modes in reverse order, in case 3175 there are extra CC modes and CC is a prefix of the 3176 CC modes (as it should be). */ 3177 for (i = (MAX_MACHINE_MODE) - 1; i >= 0; i--) 3178 { 3179 const char *p, *q; 3180 for (p = GET_MODE_NAME (i), q = name; *p; p++, q++) 3181 if (TOLOWER (*p) != *q) 3182 break; 3183 if (*p == 0 3184 && (! force_int || mode_class[i] == MODE_INT 3185 || mode_class[i] == MODE_VECTOR_INT) 3186 && (! force_partial_int 3187 || mode_class[i] == MODE_INT 3188 || mode_class[i] == MODE_PARTIAL_INT 3189 || mode_class[i] == MODE_VECTOR_INT) 3190 && (! force_float 3191 || mode_class[i] == MODE_FLOAT 3192 || mode_class[i] == MODE_DECIMAL_FLOAT 3193 || mode_class[i] == MODE_COMPLEX_FLOAT 3194 || mode_class[i] == MODE_VECTOR_FLOAT) 3195 && (! force_fixed 3196 || mode_class[i] == MODE_FRACT 3197 || mode_class[i] == MODE_UFRACT 3198 || mode_class[i] == MODE_ACCUM 3199 || mode_class[i] == MODE_UACCUM 3200 || mode_class[i] == MODE_VECTOR_FRACT 3201 || mode_class[i] == MODE_VECTOR_UFRACT 3202 || mode_class[i] == MODE_VECTOR_ACCUM 3203 || mode_class[i] == MODE_VECTOR_UACCUM)) 3204 break; 3205 } 3206 3207 if (i < 0) 3208 return false; 3209 name += strlen (GET_MODE_NAME (i)); 3210 if (*pat == 'a') 3211 p->m1 = i; 3212 else 3213 p->m2 = i; 3214 3215 force_int = false; 3216 force_partial_int = false; 3217 force_float = false; 3218 force_fixed = false; 3219 } 3220 break; 3221 3222 default: 3223 gcc_unreachable (); 3224 } 3225 } 3226 } 3227 3228 /* Return true if NAME is the name of an optab, describing it in P if so. */ 3229 3230 bool 3231 find_optab (optab_pattern *p, const char *name) 3232 { 3233 if (*name == 0 || *name == '*') 3234 return false; 3235 3236 /* See if NAME matches one of the patterns we have for the optabs 3237 we know about. */ 3238 for (unsigned int pindex = 0; pindex < ARRAY_SIZE (optabs); pindex++) 3239 { 3240 p->m1 = p->m2 = 0; 3241 if (match_pattern (p, name, optabs[pindex].pattern)) 3242 { 3243 p->name = name; 3244 p->op = optabs[pindex].op; 3245 p->sort_num = (p->op << 16) | (p->m2 << 8) | p->m1; 3246 return true; 3247 } 3248 } 3249 return false; 3250 } 3251