1/* Generate code from machine description to compute values of attributes. 2 Copyright (C) 1991-2015 Free Software Foundation, Inc. 3 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) 4 5This file is part of GCC. 6 7GCC is free software; you can redistribute it and/or modify it under 8the terms of the GNU General Public License as published by the Free 9Software Foundation; either version 3, or (at your option) any later 10version. 11 12GCC is distributed in the hope that it will be useful, but WITHOUT ANY 13WARRANTY; without even the implied warranty of MERCHANTABILITY or 14FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15for more details. 16 17You should have received a copy of the GNU General Public License 18along with GCC; see the file COPYING3. If not see 19<http://www.gnu.org/licenses/>. */ 20 21/* This program handles insn attributes and the DEFINE_DELAY and 22 DEFINE_INSN_RESERVATION definitions. 23 24 It produces a series of functions named `get_attr_...', one for each insn 25 attribute. Each of these is given the rtx for an insn and returns a member 26 of the enum for the attribute. 27 28 These subroutines have the form of a `switch' on the INSN_CODE (via 29 `recog_memoized'). Each case either returns a constant attribute value 30 or a value that depends on tests on other attributes, the form of 31 operands, or some random C expression (encoded with a SYMBOL_REF 32 expression). 33 34 If the attribute `alternative', or a random C expression is present, 35 `constrain_operands' is called. If either of these cases of a reference to 36 an operand is found, `extract_insn' is called. 37 38 The special attribute `length' is also recognized. For this operand, 39 expressions involving the address of an operand or the current insn, 40 (address (pc)), are valid. In this case, an initial pass is made to 41 set all lengths that do not depend on address. Those that do are set to 42 the maximum length. Then each insn that depends on an address is checked 43 and possibly has its length changed. The process repeats until no further 44 changed are made. The resulting lengths are saved for use by 45 `get_attr_length'. 46 47 A special form of DEFINE_ATTR, where the expression for default value is a 48 CONST expression, indicates an attribute that is constant for a given run 49 of the compiler. The subroutine generated for these attributes has no 50 parameters as it does not depend on any particular insn. Constant 51 attributes are typically used to specify which variety of processor is 52 used. 53 54 Internal attributes are defined to handle DEFINE_DELAY and 55 DEFINE_INSN_RESERVATION. Special routines are output for these cases. 56 57 This program works by keeping a list of possible values for each attribute. 58 These include the basic attribute choices, default values for attribute, and 59 all derived quantities. 60 61 As the description file is read, the definition for each insn is saved in a 62 `struct insn_def'. When the file reading is complete, a `struct insn_ent' 63 is created for each insn and chained to the corresponding attribute value, 64 either that specified, or the default. 65 66 An optimization phase is then run. This simplifies expressions for each 67 insn. EQ_ATTR tests are resolved, whenever possible, to a test that 68 indicates when the attribute has the specified value for the insn. This 69 avoids recursive calls during compilation. 70 71 The strategy used when processing DEFINE_DELAY definitions is to create 72 arbitrarily complex expressions and have the optimization simplify them. 73 74 Once optimization is complete, any required routines and definitions 75 will be written. 76 77 An optimization that is not yet implemented is to hoist the constant 78 expressions entirely out of the routines and definitions that are written. 79 A way to do this is to iterate over all possible combinations of values 80 for constant attributes and generate a set of functions for that given 81 combination. An initialization function would be written that evaluates 82 the attributes and installs the corresponding set of routines and 83 definitions (each would be accessed through a pointer). 84 85 We use the flags in an RTX as follows: 86 `unchanging' (ATTR_IND_SIMPLIFIED_P): This rtx is fully simplified 87 independent of the insn code. 88 `in_struct' (ATTR_CURR_SIMPLIFIED_P): This rtx is fully simplified 89 for the insn code currently being processed (see optimize_attrs). 90 `return_val' (ATTR_PERMANENT_P): This rtx is permanent and unique 91 (see attr_rtx). */ 92 93#define ATTR_IND_SIMPLIFIED_P(RTX) (RTX_FLAG ((RTX), unchanging)) 94#define ATTR_CURR_SIMPLIFIED_P(RTX) (RTX_FLAG ((RTX), in_struct)) 95#define ATTR_PERMANENT_P(RTX) (RTX_FLAG ((RTX), return_val)) 96 97#if 0 98#define strcmp_check(S1, S2) ((S1) == (S2) \ 99 ? 0 \ 100 : (gcc_assert (strcmp ((S1), (S2))), 1)) 101#else 102#define strcmp_check(S1, S2) ((S1) != (S2)) 103#endif 104 105#include "bconfig.h" 106#include "system.h" 107#include "coretypes.h" 108#include "tm.h" 109#include "rtl.h" 110#include "obstack.h" 111#include "errors.h" 112#include "read-md.h" 113#include "gensupport.h" 114#include "fnmatch.h" 115 116#define DEBUG 0 117 118/* Flags for make_internal_attr's `special' parameter. */ 119#define ATTR_NONE 0 120#define ATTR_SPECIAL (1 << 0) 121 122static struct obstack obstack1, obstack2; 123static struct obstack *hash_obstack = &obstack1; 124static struct obstack *temp_obstack = &obstack2; 125 126/* enough space to reserve for printing out ints */ 127#define MAX_DIGITS (HOST_BITS_PER_INT * 3 / 10 + 3) 128 129/* Define structures used to record attributes and values. */ 130 131/* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is 132 encountered, we store all the relevant information into a 133 `struct insn_def'. This is done to allow attribute definitions to occur 134 anywhere in the file. */ 135 136struct insn_def 137{ 138 struct insn_def *next; /* Next insn in chain. */ 139 rtx def; /* The DEFINE_... */ 140 int insn_code; /* Instruction number. */ 141 int insn_index; /* Expression number in file, for errors. */ 142 const char *filename; /* Filename. */ 143 int lineno; /* Line number. */ 144 int num_alternatives; /* Number of alternatives. */ 145 int vec_idx; /* Index of attribute vector in `def'. */ 146}; 147 148/* Once everything has been read in, we store in each attribute value a list 149 of insn codes that have that value. Here is the structure used for the 150 list. */ 151 152struct insn_ent 153{ 154 struct insn_ent *next; /* Next in chain. */ 155 struct insn_def *def; /* Instruction definition. */ 156}; 157 158/* Each value of an attribute (either constant or computed) is assigned a 159 structure which is used as the listhead of the insns that have that 160 value. */ 161 162struct attr_value 163{ 164 rtx value; /* Value of attribute. */ 165 struct attr_value *next; /* Next attribute value in chain. */ 166 struct insn_ent *first_insn; /* First insn with this value. */ 167 int num_insns; /* Number of insns with this value. */ 168 int has_asm_insn; /* True if this value used for `asm' insns */ 169}; 170 171/* Structure for each attribute. */ 172 173struct attr_desc 174{ 175 char *name; /* Name of attribute. */ 176 const char *enum_name; /* Enum name for DEFINE_ENUM_NAME. */ 177 struct attr_desc *next; /* Next attribute. */ 178 struct attr_value *first_value; /* First value of this attribute. */ 179 struct attr_value *default_val; /* Default value for this attribute. */ 180 int lineno : 24; /* Line number. */ 181 unsigned is_numeric : 1; /* Values of this attribute are numeric. */ 182 unsigned is_const : 1; /* Attribute value constant for each run. */ 183 unsigned is_special : 1; /* Don't call `write_attr_set'. */ 184}; 185 186/* Structure for each DEFINE_DELAY. */ 187 188struct delay_desc 189{ 190 rtx def; /* DEFINE_DELAY expression. */ 191 struct delay_desc *next; /* Next DEFINE_DELAY. */ 192 int num; /* Number of DEFINE_DELAY, starting at 1. */ 193 int lineno; /* Line number. */ 194}; 195 196struct attr_value_list 197{ 198 struct attr_value *av; 199 struct insn_ent *ie; 200 struct attr_desc *attr; 201 struct attr_value_list *next; 202}; 203 204/* Listheads of above structures. */ 205 206/* This one is indexed by the first character of the attribute name. */ 207#define MAX_ATTRS_INDEX 256 208static struct attr_desc *attrs[MAX_ATTRS_INDEX]; 209static struct insn_def *defs; 210static struct delay_desc *delays; 211struct attr_value_list **insn_code_values; 212 213/* Other variables. */ 214 215static int insn_code_number; 216static int insn_index_number; 217static int got_define_asm_attributes; 218static int must_extract; 219static int must_constrain; 220static int address_used; 221static int length_used; 222static int num_delays; 223static int have_annul_true, have_annul_false; 224static int num_insn_ents; 225 226/* Stores, for each insn code, the number of constraint alternatives. */ 227 228static int *insn_n_alternatives; 229 230/* Stores, for each insn code, a bitmap that has bits on for each possible 231 alternative. */ 232 233static uint64_t *insn_alternatives; 234 235/* Used to simplify expressions. */ 236 237static rtx true_rtx, false_rtx; 238 239/* Used to reduce calls to `strcmp' */ 240 241static const char *alternative_name; 242static const char *length_str; 243static const char *delay_type_str; 244static const char *delay_1_0_str; 245static const char *num_delay_slots_str; 246 247/* Simplify an expression. Only call the routine if there is something to 248 simplify. */ 249#define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \ 250 (ATTR_IND_SIMPLIFIED_P (EXP) || ATTR_CURR_SIMPLIFIED_P (EXP) ? (EXP) \ 251 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX)) 252 253#define DEF_ATTR_STRING(S) (attr_string ((S), strlen (S))) 254 255/* Forward declarations of functions used before their definitions, only. */ 256static char *attr_string (const char *, int); 257static char *attr_printf (unsigned int, const char *, ...) 258 ATTRIBUTE_PRINTF_2; 259static rtx make_numeric_value (int); 260static struct attr_desc *find_attr (const char **, int); 261static rtx mk_attr_alt (uint64_t); 262static char *next_comma_elt (const char **); 263static rtx insert_right_side (enum rtx_code, rtx, rtx, int, int); 264static rtx copy_boolean (rtx); 265static int compares_alternatives_p (rtx); 266static void make_internal_attr (const char *, rtx, int); 267static void insert_insn_ent (struct attr_value *, struct insn_ent *); 268static void walk_attr_value (rtx); 269static int max_attr_value (rtx, int*); 270static int min_attr_value (rtx, int*); 271static int or_attr_value (rtx, int*); 272static rtx simplify_test_exp (rtx, int, int); 273static rtx simplify_test_exp_in_temp (rtx, int, int); 274static rtx copy_rtx_unchanging (rtx); 275static bool attr_alt_subset_p (rtx, rtx); 276static bool attr_alt_subset_of_compl_p (rtx, rtx); 277static void clear_struct_flag (rtx); 278static void write_attr_valueq (FILE *, struct attr_desc *, const char *); 279static struct attr_value *find_most_used (struct attr_desc *); 280static void write_attr_set (FILE *, struct attr_desc *, int, rtx, 281 const char *, const char *, rtx, 282 int, int, unsigned int); 283static void write_attr_case (FILE *, struct attr_desc *, 284 struct attr_value *, 285 int, const char *, const char *, int, rtx); 286static void write_attr_value (FILE *, struct attr_desc *, rtx); 287static void write_upcase (FILE *, const char *); 288static void write_indent (FILE *, int); 289static rtx identity_fn (rtx); 290static rtx zero_fn (rtx); 291static rtx one_fn (rtx); 292static rtx max_fn (rtx); 293static rtx min_fn (rtx); 294 295#define oballoc(T) XOBNEW (hash_obstack, T) 296#define oballocvec(T, N) XOBNEWVEC (hash_obstack, T, (N)) 297 298/* This gen* file is unique, in that it writes out multiple files. 299 300 Before GCC 4.8, insn-attrtab.c was written out containing many large 301 functions and tables. This made insn-attrtab.c _the_ bottle-neck in 302 a parallel build, and even made it impossible to build GCC on machines 303 with relatively small RAM space (PR other/29442). Therefore, the 304 atrribute functions/tables are now written out to three separate 305 files: all "*insn_default_latency" functions go to LATENCY_FILE_NAME, 306 all "*internal_dfa_insn_code" functions go to DFA_FILE_NAME, and the 307 rest goes to ATTR_FILE_NAME. */ 308 309static const char *attr_file_name = NULL; 310static const char *dfa_file_name = NULL; 311static const char *latency_file_name = NULL; 312 313static FILE *attr_file, *dfa_file, *latency_file; 314 315/* Hash table for sharing RTL and strings. */ 316 317/* Each hash table slot is a bucket containing a chain of these structures. 318 Strings are given negative hash codes; RTL expressions are given positive 319 hash codes. */ 320 321struct attr_hash 322{ 323 struct attr_hash *next; /* Next structure in the bucket. */ 324 unsigned int hashcode; /* Hash code of this rtx or string. */ 325 union 326 { 327 char *str; /* The string (negative hash codes) */ 328 rtx rtl; /* or the RTL recorded here. */ 329 } u; 330}; 331 332/* Now here is the hash table. When recording an RTL, it is added to 333 the slot whose index is the hash code mod the table size. Note 334 that the hash table is used for several kinds of RTL (see attr_rtx) 335 and for strings. While all these live in the same table, they are 336 completely independent, and the hash code is computed differently 337 for each. */ 338 339#define RTL_HASH_SIZE 4093 340static struct attr_hash *attr_hash_table[RTL_HASH_SIZE]; 341 342/* Here is how primitive or already-shared RTL's hash 343 codes are made. */ 344#define RTL_HASH(RTL) ((intptr_t) (RTL) & 0777777) 345 346/* Add an entry to the hash table for RTL with hash code HASHCODE. */ 347 348static void 349attr_hash_add_rtx (unsigned int hashcode, rtx rtl) 350{ 351 struct attr_hash *h; 352 353 h = XOBNEW (hash_obstack, struct attr_hash); 354 h->hashcode = hashcode; 355 h->u.rtl = rtl; 356 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE]; 357 attr_hash_table[hashcode % RTL_HASH_SIZE] = h; 358} 359 360/* Add an entry to the hash table for STRING with hash code HASHCODE. */ 361 362static void 363attr_hash_add_string (unsigned int hashcode, char *str) 364{ 365 struct attr_hash *h; 366 367 h = XOBNEW (hash_obstack, struct attr_hash); 368 h->hashcode = -hashcode; 369 h->u.str = str; 370 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE]; 371 attr_hash_table[hashcode % RTL_HASH_SIZE] = h; 372} 373 374/* Generate an RTL expression, but avoid duplicates. 375 Set the ATTR_PERMANENT_P flag for these permanent objects. 376 377 In some cases we cannot uniquify; then we return an ordinary 378 impermanent rtx with ATTR_PERMANENT_P clear. 379 380 Args are as follows: 381 382 rtx attr_rtx (code, [element1, ..., elementn]) */ 383 384static rtx 385attr_rtx_1 (enum rtx_code code, va_list p) 386{ 387 rtx rt_val = NULL_RTX;/* RTX to return to caller... */ 388 unsigned int hashcode; 389 struct attr_hash *h; 390 struct obstack *old_obstack = rtl_obstack; 391 392 /* For each of several cases, search the hash table for an existing entry. 393 Use that entry if one is found; otherwise create a new RTL and add it 394 to the table. */ 395 396 if (GET_RTX_CLASS (code) == RTX_UNARY) 397 { 398 rtx arg0 = va_arg (p, rtx); 399 400 /* A permanent object cannot point to impermanent ones. */ 401 if (! ATTR_PERMANENT_P (arg0)) 402 { 403 rt_val = rtx_alloc (code); 404 XEXP (rt_val, 0) = arg0; 405 return rt_val; 406 } 407 408 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0)); 409 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next) 410 if (h->hashcode == hashcode 411 && GET_CODE (h->u.rtl) == code 412 && XEXP (h->u.rtl, 0) == arg0) 413 return h->u.rtl; 414 415 if (h == 0) 416 { 417 rtl_obstack = hash_obstack; 418 rt_val = rtx_alloc (code); 419 XEXP (rt_val, 0) = arg0; 420 } 421 } 422 else if (GET_RTX_CLASS (code) == RTX_BIN_ARITH 423 || GET_RTX_CLASS (code) == RTX_COMM_ARITH 424 || GET_RTX_CLASS (code) == RTX_COMPARE 425 || GET_RTX_CLASS (code) == RTX_COMM_COMPARE) 426 { 427 rtx arg0 = va_arg (p, rtx); 428 rtx arg1 = va_arg (p, rtx); 429 430 /* A permanent object cannot point to impermanent ones. */ 431 if (! ATTR_PERMANENT_P (arg0) || ! ATTR_PERMANENT_P (arg1)) 432 { 433 rt_val = rtx_alloc (code); 434 XEXP (rt_val, 0) = arg0; 435 XEXP (rt_val, 1) = arg1; 436 return rt_val; 437 } 438 439 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1)); 440 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next) 441 if (h->hashcode == hashcode 442 && GET_CODE (h->u.rtl) == code 443 && XEXP (h->u.rtl, 0) == arg0 444 && XEXP (h->u.rtl, 1) == arg1) 445 return h->u.rtl; 446 447 if (h == 0) 448 { 449 rtl_obstack = hash_obstack; 450 rt_val = rtx_alloc (code); 451 XEXP (rt_val, 0) = arg0; 452 XEXP (rt_val, 1) = arg1; 453 } 454 } 455 else if (code == SYMBOL_REF 456 || (GET_RTX_LENGTH (code) == 1 457 && GET_RTX_FORMAT (code)[0] == 's')) 458 { 459 char *arg0 = va_arg (p, char *); 460 461 arg0 = DEF_ATTR_STRING (arg0); 462 463 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0)); 464 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next) 465 if (h->hashcode == hashcode 466 && GET_CODE (h->u.rtl) == code 467 && XSTR (h->u.rtl, 0) == arg0) 468 return h->u.rtl; 469 470 if (h == 0) 471 { 472 rtl_obstack = hash_obstack; 473 rt_val = rtx_alloc (code); 474 XSTR (rt_val, 0) = arg0; 475 if (code == SYMBOL_REF) 476 X0EXP (rt_val, 1) = NULL_RTX; 477 } 478 } 479 else if (GET_RTX_LENGTH (code) == 2 480 && GET_RTX_FORMAT (code)[0] == 's' 481 && GET_RTX_FORMAT (code)[1] == 's') 482 { 483 char *arg0 = va_arg (p, char *); 484 char *arg1 = va_arg (p, char *); 485 486 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1)); 487 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next) 488 if (h->hashcode == hashcode 489 && GET_CODE (h->u.rtl) == code 490 && XSTR (h->u.rtl, 0) == arg0 491 && XSTR (h->u.rtl, 1) == arg1) 492 return h->u.rtl; 493 494 if (h == 0) 495 { 496 rtl_obstack = hash_obstack; 497 rt_val = rtx_alloc (code); 498 XSTR (rt_val, 0) = arg0; 499 XSTR (rt_val, 1) = arg1; 500 } 501 } 502 else if (code == CONST_INT) 503 { 504 HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT); 505 if (arg0 == 0) 506 return false_rtx; 507 else if (arg0 == 1) 508 return true_rtx; 509 else 510 goto nohash; 511 } 512 else 513 { 514 int i; /* Array indices... */ 515 const char *fmt; /* Current rtx's format... */ 516 nohash: 517 rt_val = rtx_alloc (code); /* Allocate the storage space. */ 518 519 fmt = GET_RTX_FORMAT (code); /* Find the right format... */ 520 for (i = 0; i < GET_RTX_LENGTH (code); i++) 521 { 522 switch (*fmt++) 523 { 524 case '0': /* Unused field. */ 525 break; 526 527 case 'i': /* An integer? */ 528 XINT (rt_val, i) = va_arg (p, int); 529 break; 530 531 case 'w': /* A wide integer? */ 532 XWINT (rt_val, i) = va_arg (p, HOST_WIDE_INT); 533 break; 534 535 case 's': /* A string? */ 536 XSTR (rt_val, i) = va_arg (p, char *); 537 break; 538 539 case 'e': /* An expression? */ 540 case 'u': /* An insn? Same except when printing. */ 541 XEXP (rt_val, i) = va_arg (p, rtx); 542 break; 543 544 case 'E': /* An RTX vector? */ 545 XVEC (rt_val, i) = va_arg (p, rtvec); 546 break; 547 548 default: 549 gcc_unreachable (); 550 } 551 } 552 return rt_val; 553 } 554 555 rtl_obstack = old_obstack; 556 attr_hash_add_rtx (hashcode, rt_val); 557 ATTR_PERMANENT_P (rt_val) = 1; 558 return rt_val; 559} 560 561static rtx 562attr_rtx (enum rtx_code code, ...) 563{ 564 rtx result; 565 va_list p; 566 567 va_start (p, code); 568 result = attr_rtx_1 (code, p); 569 va_end (p); 570 return result; 571} 572 573/* Create a new string printed with the printf line arguments into a space 574 of at most LEN bytes: 575 576 rtx attr_printf (len, format, [arg1, ..., argn]) */ 577 578static char * 579attr_printf (unsigned int len, const char *fmt, ...) 580{ 581 char str[256]; 582 va_list p; 583 584 va_start (p, fmt); 585 586 gcc_assert (len < sizeof str); /* Leave room for \0. */ 587 588 vsprintf (str, fmt, p); 589 va_end (p); 590 591 return DEF_ATTR_STRING (str); 592} 593 594static rtx 595attr_eq (const char *name, const char *value) 596{ 597 return attr_rtx (EQ_ATTR, DEF_ATTR_STRING (name), DEF_ATTR_STRING (value)); 598} 599 600static const char * 601attr_numeral (int n) 602{ 603 return XSTR (make_numeric_value (n), 0); 604} 605 606/* Return a permanent (possibly shared) copy of a string STR (not assumed 607 to be null terminated) with LEN bytes. */ 608 609static char * 610attr_string (const char *str, int len) 611{ 612 struct attr_hash *h; 613 unsigned int hashcode; 614 int i; 615 char *new_str; 616 617 /* Compute the hash code. */ 618 hashcode = (len + 1) * 613U + (unsigned) str[0]; 619 for (i = 1; i < len; i += 2) 620 hashcode = ((hashcode * 613) + (unsigned) str[i]); 621 if ((int) hashcode < 0) 622 hashcode = -hashcode; 623 624 /* Search the table for the string. */ 625 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next) 626 if (h->hashcode == -hashcode && h->u.str[0] == str[0] 627 && !strncmp (h->u.str, str, len)) 628 return h->u.str; /* <-- return if found. */ 629 630 /* Not found; create a permanent copy and add it to the hash table. */ 631 new_str = XOBNEWVAR (hash_obstack, char, len + 1); 632 memcpy (new_str, str, len); 633 new_str[len] = '\0'; 634 attr_hash_add_string (hashcode, new_str); 635 copy_md_ptr_loc (new_str, str); 636 637 return new_str; /* Return the new string. */ 638} 639 640/* Check two rtx's for equality of contents, 641 taking advantage of the fact that if both are hashed 642 then they can't be equal unless they are the same object. */ 643 644static int 645attr_equal_p (rtx x, rtx y) 646{ 647 return (x == y || (! (ATTR_PERMANENT_P (x) && ATTR_PERMANENT_P (y)) 648 && rtx_equal_p (x, y))); 649} 650 651/* Copy an attribute value expression, 652 descending to all depths, but not copying any 653 permanent hashed subexpressions. */ 654 655static rtx 656attr_copy_rtx (rtx orig) 657{ 658 rtx copy; 659 int i, j; 660 RTX_CODE code; 661 const char *format_ptr; 662 663 /* No need to copy a permanent object. */ 664 if (ATTR_PERMANENT_P (orig)) 665 return orig; 666 667 code = GET_CODE (orig); 668 669 switch (code) 670 { 671 case REG: 672 CASE_CONST_ANY: 673 case SYMBOL_REF: 674 case MATCH_TEST: 675 case CODE_LABEL: 676 case PC: 677 case CC0: 678 return orig; 679 680 default: 681 break; 682 } 683 684 copy = rtx_alloc (code); 685 PUT_MODE (copy, GET_MODE (orig)); 686 ATTR_IND_SIMPLIFIED_P (copy) = ATTR_IND_SIMPLIFIED_P (orig); 687 ATTR_CURR_SIMPLIFIED_P (copy) = ATTR_CURR_SIMPLIFIED_P (orig); 688 ATTR_PERMANENT_P (copy) = ATTR_PERMANENT_P (orig); 689 690 format_ptr = GET_RTX_FORMAT (GET_CODE (copy)); 691 692 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++) 693 { 694 switch (*format_ptr++) 695 { 696 case 'e': 697 XEXP (copy, i) = XEXP (orig, i); 698 if (XEXP (orig, i) != NULL) 699 XEXP (copy, i) = attr_copy_rtx (XEXP (orig, i)); 700 break; 701 702 case 'E': 703 case 'V': 704 XVEC (copy, i) = XVEC (orig, i); 705 if (XVEC (orig, i) != NULL) 706 { 707 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i)); 708 for (j = 0; j < XVECLEN (copy, i); j++) 709 XVECEXP (copy, i, j) = attr_copy_rtx (XVECEXP (orig, i, j)); 710 } 711 break; 712 713 case 'n': 714 case 'i': 715 XINT (copy, i) = XINT (orig, i); 716 break; 717 718 case 'w': 719 XWINT (copy, i) = XWINT (orig, i); 720 break; 721 722 case 's': 723 case 'S': 724 XSTR (copy, i) = XSTR (orig, i); 725 break; 726 727 default: 728 gcc_unreachable (); 729 } 730 } 731 return copy; 732} 733 734/* Given a test expression for an attribute, ensure it is validly formed. 735 IS_CONST indicates whether the expression is constant for each compiler 736 run (a constant expression may not test any particular insn). 737 738 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..)) 739 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter 740 test first so that (eq_attr "att" "!a1,a2,a3") works as expected. 741 742 Update the string address in EQ_ATTR expression to be the same used 743 in the attribute (or `alternative_name') to speed up subsequent 744 `find_attr' calls and eliminate most `strcmp' calls. 745 746 Return the new expression, if any. */ 747 748static rtx 749check_attr_test (rtx exp, int is_const, int lineno) 750{ 751 struct attr_desc *attr; 752 struct attr_value *av; 753 const char *name_ptr, *p; 754 rtx orexp, newexp; 755 756 switch (GET_CODE (exp)) 757 { 758 case EQ_ATTR: 759 /* Handle negation test. */ 760 if (XSTR (exp, 1)[0] == '!') 761 return check_attr_test (attr_rtx (NOT, 762 attr_eq (XSTR (exp, 0), 763 &XSTR (exp, 1)[1])), 764 is_const, lineno); 765 766 else if (n_comma_elts (XSTR (exp, 1)) == 1) 767 { 768 attr = find_attr (&XSTR (exp, 0), 0); 769 if (attr == NULL) 770 { 771 if (! strcmp (XSTR (exp, 0), "alternative")) 772 return mk_attr_alt (((uint64_t) 1) << atoi (XSTR (exp, 1))); 773 else 774 fatal ("unknown attribute `%s' in EQ_ATTR", XSTR (exp, 0)); 775 } 776 777 if (is_const && ! attr->is_const) 778 fatal ("constant expression uses insn attribute `%s' in EQ_ATTR", 779 XSTR (exp, 0)); 780 781 /* Copy this just to make it permanent, 782 so expressions using it can be permanent too. */ 783 exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1)); 784 785 /* It shouldn't be possible to simplify the value given to a 786 constant attribute, so don't expand this until it's time to 787 write the test expression. */ 788 if (attr->is_const) 789 ATTR_IND_SIMPLIFIED_P (exp) = 1; 790 791 if (attr->is_numeric) 792 { 793 for (p = XSTR (exp, 1); *p; p++) 794 if (! ISDIGIT (*p)) 795 fatal ("attribute `%s' takes only numeric values", 796 XSTR (exp, 0)); 797 } 798 else 799 { 800 for (av = attr->first_value; av; av = av->next) 801 if (GET_CODE (av->value) == CONST_STRING 802 && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0))) 803 break; 804 805 if (av == NULL) 806 fatal ("unknown value `%s' for `%s' attribute", 807 XSTR (exp, 1), XSTR (exp, 0)); 808 } 809 } 810 else 811 { 812 if (! strcmp (XSTR (exp, 0), "alternative")) 813 { 814 int set = 0; 815 816 name_ptr = XSTR (exp, 1); 817 while ((p = next_comma_elt (&name_ptr)) != NULL) 818 set |= ((uint64_t) 1) << atoi (p); 819 820 return mk_attr_alt (set); 821 } 822 else 823 { 824 /* Make an IOR tree of the possible values. */ 825 orexp = false_rtx; 826 name_ptr = XSTR (exp, 1); 827 while ((p = next_comma_elt (&name_ptr)) != NULL) 828 { 829 newexp = attr_eq (XSTR (exp, 0), p); 830 orexp = insert_right_side (IOR, orexp, newexp, -2, -2); 831 } 832 833 return check_attr_test (orexp, is_const, lineno); 834 } 835 } 836 break; 837 838 case ATTR_FLAG: 839 break; 840 841 case CONST_INT: 842 /* Either TRUE or FALSE. */ 843 if (XWINT (exp, 0)) 844 return true_rtx; 845 else 846 return false_rtx; 847 848 case IOR: 849 case AND: 850 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno); 851 XEXP (exp, 1) = check_attr_test (XEXP (exp, 1), is_const, lineno); 852 break; 853 854 case NOT: 855 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const, lineno); 856 break; 857 858 case MATCH_TEST: 859 exp = attr_rtx (MATCH_TEST, XSTR (exp, 0)); 860 ATTR_IND_SIMPLIFIED_P (exp) = 1; 861 break; 862 863 case MATCH_OPERAND: 864 if (is_const) 865 fatal ("RTL operator \"%s\" not valid in constant attribute test", 866 GET_RTX_NAME (GET_CODE (exp))); 867 /* These cases can't be simplified. */ 868 ATTR_IND_SIMPLIFIED_P (exp) = 1; 869 break; 870 871 case LE: case LT: case GT: case GE: 872 case LEU: case LTU: case GTU: case GEU: 873 case NE: case EQ: 874 if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF 875 && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF) 876 exp = attr_rtx (GET_CODE (exp), 877 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)), 878 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0))); 879 /* These cases can't be simplified. */ 880 ATTR_IND_SIMPLIFIED_P (exp) = 1; 881 break; 882 883 case SYMBOL_REF: 884 if (is_const) 885 { 886 /* These cases are valid for constant attributes, but can't be 887 simplified. */ 888 exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0)); 889 ATTR_IND_SIMPLIFIED_P (exp) = 1; 890 break; 891 } 892 default: 893 fatal ("RTL operator \"%s\" not valid in attribute test", 894 GET_RTX_NAME (GET_CODE (exp))); 895 } 896 897 return exp; 898} 899 900/* Given an expression, ensure that it is validly formed and that all named 901 attribute values are valid for the given attribute. Issue a fatal error 902 if not. If no attribute is specified, assume a numeric attribute. 903 904 Return a perhaps modified replacement expression for the value. */ 905 906static rtx 907check_attr_value (rtx exp, struct attr_desc *attr) 908{ 909 struct attr_value *av; 910 const char *p; 911 int i; 912 913 switch (GET_CODE (exp)) 914 { 915 case CONST_INT: 916 if (attr && ! attr->is_numeric) 917 { 918 error_with_line (attr->lineno, 919 "CONST_INT not valid for non-numeric attribute %s", 920 attr->name); 921 break; 922 } 923 924 if (INTVAL (exp) < 0) 925 { 926 error_with_line (attr->lineno, 927 "negative numeric value specified for attribute %s", 928 attr->name); 929 break; 930 } 931 break; 932 933 case CONST_STRING: 934 if (! strcmp (XSTR (exp, 0), "*")) 935 break; 936 937 if (attr == 0 || attr->is_numeric) 938 { 939 p = XSTR (exp, 0); 940 for (; *p; p++) 941 if (! ISDIGIT (*p)) 942 { 943 error_with_line (attr ? attr->lineno : 0, 944 "non-numeric value for numeric attribute %s", 945 attr ? attr->name : "internal"); 946 break; 947 } 948 break; 949 } 950 951 for (av = attr->first_value; av; av = av->next) 952 if (GET_CODE (av->value) == CONST_STRING 953 && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0))) 954 break; 955 956 if (av == NULL) 957 error_with_line (attr->lineno, 958 "unknown value `%s' for `%s' attribute", 959 XSTR (exp, 0), attr ? attr->name : "internal"); 960 break; 961 962 case IF_THEN_ELSE: 963 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), 964 attr ? attr->is_const : 0, 965 attr ? attr->lineno : 0); 966 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr); 967 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr); 968 break; 969 970 case PLUS: 971 case MINUS: 972 case MULT: 973 case DIV: 974 case MOD: 975 if (attr && !attr->is_numeric) 976 { 977 error_with_line (attr->lineno, 978 "invalid operation `%s' for non-numeric" 979 " attribute value", GET_RTX_NAME (GET_CODE (exp))); 980 break; 981 } 982 /* Fall through. */ 983 984 case IOR: 985 case AND: 986 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr); 987 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr); 988 break; 989 990 case FFS: 991 case CLZ: 992 case CTZ: 993 case POPCOUNT: 994 case PARITY: 995 case BSWAP: 996 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr); 997 break; 998 999 case COND: 1000 if (XVECLEN (exp, 0) % 2 != 0) 1001 { 1002 error_with_line (attr->lineno, 1003 "first operand of COND must have even length"); 1004 break; 1005 } 1006 1007 for (i = 0; i < XVECLEN (exp, 0); i += 2) 1008 { 1009 XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i), 1010 attr ? attr->is_const : 0, 1011 attr ? attr->lineno : 0); 1012 XVECEXP (exp, 0, i + 1) 1013 = check_attr_value (XVECEXP (exp, 0, i + 1), attr); 1014 } 1015 1016 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr); 1017 break; 1018 1019 case ATTR: 1020 { 1021 struct attr_desc *attr2 = find_attr (&XSTR (exp, 0), 0); 1022 if (attr2 == NULL) 1023 error_with_line (attr ? attr->lineno : 0, 1024 "unknown attribute `%s' in ATTR", 1025 XSTR (exp, 0)); 1026 else if (attr && attr->is_const && ! attr2->is_const) 1027 error_with_line (attr->lineno, 1028 "non-constant attribute `%s' referenced from `%s'", 1029 XSTR (exp, 0), attr->name); 1030 else if (attr 1031 && attr->is_numeric != attr2->is_numeric) 1032 error_with_line (attr->lineno, 1033 "numeric attribute mismatch calling `%s' from `%s'", 1034 XSTR (exp, 0), attr->name); 1035 } 1036 break; 1037 1038 case SYMBOL_REF: 1039 /* A constant SYMBOL_REF is valid as a constant attribute test and 1040 is expanded later by make_canonical into a COND. In a non-constant 1041 attribute test, it is left be. */ 1042 return attr_rtx (SYMBOL_REF, XSTR (exp, 0)); 1043 1044 default: 1045 error_with_line (attr ? attr->lineno : 0, 1046 "invalid operation `%s' for attribute value", 1047 GET_RTX_NAME (GET_CODE (exp))); 1048 break; 1049 } 1050 1051 return exp; 1052} 1053 1054/* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET. 1055 It becomes a COND with each test being (eq_attr "alternative" "n") */ 1056 1057static rtx 1058convert_set_attr_alternative (rtx exp, struct insn_def *id) 1059{ 1060 int num_alt = id->num_alternatives; 1061 rtx condexp; 1062 int i; 1063 1064 if (XVECLEN (exp, 1) != num_alt) 1065 { 1066 error_with_line (id->lineno, 1067 "bad number of entries in SET_ATTR_ALTERNATIVE, was %d expected %d", 1068 XVECLEN (exp, 1), num_alt); 1069 return NULL_RTX; 1070 } 1071 1072 /* Make a COND with all tests but the last. Select the last value via the 1073 default. */ 1074 condexp = rtx_alloc (COND); 1075 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2); 1076 1077 for (i = 0; i < num_alt - 1; i++) 1078 { 1079 const char *p; 1080 p = attr_numeral (i); 1081 1082 XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p); 1083 XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i); 1084 } 1085 1086 XEXP (condexp, 1) = XVECEXP (exp, 1, i); 1087 1088 return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp); 1089} 1090 1091/* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated 1092 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */ 1093 1094static rtx 1095convert_set_attr (rtx exp, struct insn_def *id) 1096{ 1097 rtx newexp; 1098 const char *name_ptr; 1099 char *p; 1100 int n; 1101 1102 /* See how many alternative specified. */ 1103 n = n_comma_elts (XSTR (exp, 1)); 1104 if (n == 1) 1105 return attr_rtx (SET, 1106 attr_rtx (ATTR, XSTR (exp, 0)), 1107 attr_rtx (CONST_STRING, XSTR (exp, 1))); 1108 1109 newexp = rtx_alloc (SET_ATTR_ALTERNATIVE); 1110 XSTR (newexp, 0) = XSTR (exp, 0); 1111 XVEC (newexp, 1) = rtvec_alloc (n); 1112 1113 /* Process each comma-separated name. */ 1114 name_ptr = XSTR (exp, 1); 1115 n = 0; 1116 while ((p = next_comma_elt (&name_ptr)) != NULL) 1117 XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p); 1118 1119 return convert_set_attr_alternative (newexp, id); 1120} 1121 1122/* Scan all definitions, checking for validity. Also, convert any SET_ATTR 1123 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET 1124 expressions. */ 1125 1126static void 1127check_defs (void) 1128{ 1129 struct insn_def *id; 1130 struct attr_desc *attr; 1131 int i; 1132 rtx value; 1133 1134 for (id = defs; id; id = id->next) 1135 { 1136 if (XVEC (id->def, id->vec_idx) == NULL) 1137 continue; 1138 1139 read_md_filename = id->filename; 1140 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++) 1141 { 1142 value = XVECEXP (id->def, id->vec_idx, i); 1143 switch (GET_CODE (value)) 1144 { 1145 case SET: 1146 if (GET_CODE (XEXP (value, 0)) != ATTR) 1147 { 1148 error_with_line (id->lineno, "bad attribute set"); 1149 value = NULL_RTX; 1150 } 1151 break; 1152 1153 case SET_ATTR_ALTERNATIVE: 1154 value = convert_set_attr_alternative (value, id); 1155 break; 1156 1157 case SET_ATTR: 1158 value = convert_set_attr (value, id); 1159 break; 1160 1161 default: 1162 error_with_line (id->lineno, "invalid attribute code %s", 1163 GET_RTX_NAME (GET_CODE (value))); 1164 value = NULL_RTX; 1165 } 1166 if (value == NULL_RTX) 1167 continue; 1168 1169 if ((attr = find_attr (&XSTR (XEXP (value, 0), 0), 0)) == NULL) 1170 { 1171 error_with_line (id->lineno, "unknown attribute %s", 1172 XSTR (XEXP (value, 0), 0)); 1173 continue; 1174 } 1175 1176 XVECEXP (id->def, id->vec_idx, i) = value; 1177 XEXP (value, 1) = check_attr_value (XEXP (value, 1), attr); 1178 } 1179 } 1180} 1181 1182/* Given a valid expression for an attribute value, remove any IF_THEN_ELSE 1183 expressions by converting them into a COND. This removes cases from this 1184 program. Also, replace an attribute value of "*" with the default attribute 1185 value. */ 1186 1187static rtx 1188make_canonical (struct attr_desc *attr, rtx exp) 1189{ 1190 int i; 1191 rtx newexp; 1192 1193 switch (GET_CODE (exp)) 1194 { 1195 case CONST_INT: 1196 exp = make_numeric_value (INTVAL (exp)); 1197 break; 1198 1199 case CONST_STRING: 1200 if (! strcmp (XSTR (exp, 0), "*")) 1201 { 1202 if (attr == 0 || attr->default_val == 0) 1203 fatal ("(attr_value \"*\") used in invalid context"); 1204 exp = attr->default_val->value; 1205 } 1206 else 1207 XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0)); 1208 1209 break; 1210 1211 case SYMBOL_REF: 1212 if (!attr->is_const || ATTR_IND_SIMPLIFIED_P (exp)) 1213 break; 1214 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging. 1215 This makes the COND something that won't be considered an arbitrary 1216 expression by walk_attr_value. */ 1217 ATTR_IND_SIMPLIFIED_P (exp) = 1; 1218 exp = check_attr_value (exp, attr); 1219 break; 1220 1221 case IF_THEN_ELSE: 1222 newexp = rtx_alloc (COND); 1223 XVEC (newexp, 0) = rtvec_alloc (2); 1224 XVECEXP (newexp, 0, 0) = XEXP (exp, 0); 1225 XVECEXP (newexp, 0, 1) = XEXP (exp, 1); 1226 1227 XEXP (newexp, 1) = XEXP (exp, 2); 1228 1229 exp = newexp; 1230 /* Fall through to COND case since this is now a COND. */ 1231 1232 case COND: 1233 { 1234 int allsame = 1; 1235 rtx defval; 1236 1237 /* First, check for degenerate COND. */ 1238 if (XVECLEN (exp, 0) == 0) 1239 return make_canonical (attr, XEXP (exp, 1)); 1240 defval = XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1)); 1241 1242 for (i = 0; i < XVECLEN (exp, 0); i += 2) 1243 { 1244 XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i)); 1245 XVECEXP (exp, 0, i + 1) 1246 = make_canonical (attr, XVECEXP (exp, 0, i + 1)); 1247 if (! rtx_equal_p (XVECEXP (exp, 0, i + 1), defval)) 1248 allsame = 0; 1249 } 1250 if (allsame) 1251 return defval; 1252 } 1253 break; 1254 1255 default: 1256 break; 1257 } 1258 1259 return exp; 1260} 1261 1262static rtx 1263copy_boolean (rtx exp) 1264{ 1265 if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR) 1266 return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)), 1267 copy_boolean (XEXP (exp, 1))); 1268 if (GET_CODE (exp) == MATCH_OPERAND) 1269 { 1270 XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1)); 1271 XSTR (exp, 2) = DEF_ATTR_STRING (XSTR (exp, 2)); 1272 } 1273 else if (GET_CODE (exp) == EQ_ATTR) 1274 { 1275 XSTR (exp, 0) = DEF_ATTR_STRING (XSTR (exp, 0)); 1276 XSTR (exp, 1) = DEF_ATTR_STRING (XSTR (exp, 1)); 1277 } 1278 1279 return exp; 1280} 1281 1282/* Given a value and an attribute description, return a `struct attr_value *' 1283 that represents that value. This is either an existing structure, if the 1284 value has been previously encountered, or a newly-created structure. 1285 1286 `insn_code' is the code of an insn whose attribute has the specified 1287 value (-2 if not processing an insn). We ensure that all insns for 1288 a given value have the same number of alternatives if the value checks 1289 alternatives. */ 1290 1291static struct attr_value * 1292get_attr_value (rtx value, struct attr_desc *attr, int insn_code) 1293{ 1294 struct attr_value *av; 1295 uint64_t num_alt = 0; 1296 1297 value = make_canonical (attr, value); 1298 if (compares_alternatives_p (value)) 1299 { 1300 if (insn_code < 0 || insn_alternatives == NULL) 1301 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context"); 1302 else 1303 num_alt = insn_alternatives[insn_code]; 1304 } 1305 1306 for (av = attr->first_value; av; av = av->next) 1307 if (rtx_equal_p (value, av->value) 1308 && (num_alt == 0 || av->first_insn == NULL 1309 || insn_alternatives[av->first_insn->def->insn_code])) 1310 return av; 1311 1312 av = oballoc (struct attr_value); 1313 av->value = value; 1314 av->next = attr->first_value; 1315 attr->first_value = av; 1316 av->first_insn = NULL; 1317 av->num_insns = 0; 1318 av->has_asm_insn = 0; 1319 1320 return av; 1321} 1322 1323/* After all DEFINE_DELAYs have been read in, create internal attributes 1324 to generate the required routines. 1325 1326 First, we compute the number of delay slots for each insn (as a COND of 1327 each of the test expressions in DEFINE_DELAYs). Then, if more than one 1328 delay type is specified, we compute a similar function giving the 1329 DEFINE_DELAY ordinal for each insn. 1330 1331 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that 1332 tells whether a given insn can be in that delay slot. 1333 1334 Normal attribute filling and optimization expands these to contain the 1335 information needed to handle delay slots. */ 1336 1337static void 1338expand_delays (void) 1339{ 1340 struct delay_desc *delay; 1341 rtx condexp; 1342 rtx newexp; 1343 int i; 1344 char *p; 1345 1346 /* First, generate data for `num_delay_slots' function. */ 1347 1348 condexp = rtx_alloc (COND); 1349 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2); 1350 XEXP (condexp, 1) = make_numeric_value (0); 1351 1352 for (i = 0, delay = delays; delay; i += 2, delay = delay->next) 1353 { 1354 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0); 1355 XVECEXP (condexp, 0, i + 1) 1356 = make_numeric_value (XVECLEN (delay->def, 1) / 3); 1357 } 1358 1359 make_internal_attr (num_delay_slots_str, condexp, ATTR_NONE); 1360 1361 /* If more than one delay type, do the same for computing the delay type. */ 1362 if (num_delays > 1) 1363 { 1364 condexp = rtx_alloc (COND); 1365 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2); 1366 XEXP (condexp, 1) = make_numeric_value (0); 1367 1368 for (i = 0, delay = delays; delay; i += 2, delay = delay->next) 1369 { 1370 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0); 1371 XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num); 1372 } 1373 1374 make_internal_attr (delay_type_str, condexp, ATTR_SPECIAL); 1375 } 1376 1377 /* For each delay possibility and delay slot, compute an eligibility 1378 attribute for non-annulled insns and for each type of annulled (annul 1379 if true and annul if false). */ 1380 for (delay = delays; delay; delay = delay->next) 1381 { 1382 for (i = 0; i < XVECLEN (delay->def, 1); i += 3) 1383 { 1384 condexp = XVECEXP (delay->def, 1, i); 1385 if (condexp == 0) 1386 condexp = false_rtx; 1387 newexp = attr_rtx (IF_THEN_ELSE, condexp, 1388 make_numeric_value (1), make_numeric_value (0)); 1389 1390 p = attr_printf (sizeof "*delay__" + MAX_DIGITS * 2, 1391 "*delay_%d_%d", delay->num, i / 3); 1392 make_internal_attr (p, newexp, ATTR_SPECIAL); 1393 1394 if (have_annul_true) 1395 { 1396 condexp = XVECEXP (delay->def, 1, i + 1); 1397 if (condexp == 0) condexp = false_rtx; 1398 newexp = attr_rtx (IF_THEN_ELSE, condexp, 1399 make_numeric_value (1), 1400 make_numeric_value (0)); 1401 p = attr_printf (sizeof "*annul_true__" + MAX_DIGITS * 2, 1402 "*annul_true_%d_%d", delay->num, i / 3); 1403 make_internal_attr (p, newexp, ATTR_SPECIAL); 1404 } 1405 1406 if (have_annul_false) 1407 { 1408 condexp = XVECEXP (delay->def, 1, i + 2); 1409 if (condexp == 0) condexp = false_rtx; 1410 newexp = attr_rtx (IF_THEN_ELSE, condexp, 1411 make_numeric_value (1), 1412 make_numeric_value (0)); 1413 p = attr_printf (sizeof "*annul_false__" + MAX_DIGITS * 2, 1414 "*annul_false_%d_%d", delay->num, i / 3); 1415 make_internal_attr (p, newexp, ATTR_SPECIAL); 1416 } 1417 } 1418 } 1419} 1420 1421/* Once all attributes and insns have been read and checked, we construct for 1422 each attribute value a list of all the insns that have that value for 1423 the attribute. */ 1424 1425static void 1426fill_attr (struct attr_desc *attr) 1427{ 1428 struct attr_value *av; 1429 struct insn_ent *ie; 1430 struct insn_def *id; 1431 int i; 1432 rtx value; 1433 1434 /* Don't fill constant attributes. The value is independent of 1435 any particular insn. */ 1436 if (attr->is_const) 1437 return; 1438 1439 for (id = defs; id; id = id->next) 1440 { 1441 /* If no value is specified for this insn for this attribute, use the 1442 default. */ 1443 value = NULL; 1444 if (XVEC (id->def, id->vec_idx)) 1445 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++) 1446 if (! strcmp_check (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0), 1447 attr->name)) 1448 value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1); 1449 1450 if (value == NULL) 1451 av = attr->default_val; 1452 else 1453 av = get_attr_value (value, attr, id->insn_code); 1454 1455 ie = oballoc (struct insn_ent); 1456 ie->def = id; 1457 insert_insn_ent (av, ie); 1458 } 1459} 1460 1461/* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a 1462 test that checks relative positions of insns (uses MATCH_DUP or PC). 1463 If so, replace it with what is obtained by passing the expression to 1464 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine 1465 recursively on each value (including the default value). Otherwise, 1466 return the value returned by NO_ADDRESS_FN applied to EXP. */ 1467 1468static rtx 1469substitute_address (rtx exp, rtx (*no_address_fn) (rtx), 1470 rtx (*address_fn) (rtx)) 1471{ 1472 int i; 1473 rtx newexp; 1474 1475 if (GET_CODE (exp) == COND) 1476 { 1477 /* See if any tests use addresses. */ 1478 address_used = 0; 1479 for (i = 0; i < XVECLEN (exp, 0); i += 2) 1480 walk_attr_value (XVECEXP (exp, 0, i)); 1481 1482 if (address_used) 1483 return (*address_fn) (exp); 1484 1485 /* Make a new copy of this COND, replacing each element. */ 1486 newexp = rtx_alloc (COND); 1487 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0)); 1488 for (i = 0; i < XVECLEN (exp, 0); i += 2) 1489 { 1490 XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i); 1491 XVECEXP (newexp, 0, i + 1) 1492 = substitute_address (XVECEXP (exp, 0, i + 1), 1493 no_address_fn, address_fn); 1494 } 1495 1496 XEXP (newexp, 1) = substitute_address (XEXP (exp, 1), 1497 no_address_fn, address_fn); 1498 1499 return newexp; 1500 } 1501 1502 else if (GET_CODE (exp) == IF_THEN_ELSE) 1503 { 1504 address_used = 0; 1505 walk_attr_value (XEXP (exp, 0)); 1506 if (address_used) 1507 return (*address_fn) (exp); 1508 1509 return attr_rtx (IF_THEN_ELSE, 1510 substitute_address (XEXP (exp, 0), 1511 no_address_fn, address_fn), 1512 substitute_address (XEXP (exp, 1), 1513 no_address_fn, address_fn), 1514 substitute_address (XEXP (exp, 2), 1515 no_address_fn, address_fn)); 1516 } 1517 1518 return (*no_address_fn) (exp); 1519} 1520 1521/* Make new attributes from the `length' attribute. The following are made, 1522 each corresponding to a function called from `shorten_branches' or 1523 `get_attr_length': 1524 1525 *insn_default_length This is the length of the insn to be returned 1526 by `get_attr_length' before `shorten_branches' 1527 has been called. In each case where the length 1528 depends on relative addresses, the largest 1529 possible is used. This routine is also used 1530 to compute the initial size of the insn. 1531 1532 *insn_variable_length_p This returns 1 if the insn's length depends 1533 on relative addresses, zero otherwise. 1534 1535 *insn_current_length This is only called when it is known that the 1536 insn has a variable length and returns the 1537 current length, based on relative addresses. 1538 */ 1539 1540static void 1541make_length_attrs (void) 1542{ 1543 static const char *new_names[] = 1544 { 1545 "*insn_default_length", 1546 "*insn_min_length", 1547 "*insn_variable_length_p", 1548 "*insn_current_length" 1549 }; 1550 static rtx (*const no_address_fn[]) (rtx) 1551 = {identity_fn,identity_fn, zero_fn, zero_fn}; 1552 static rtx (*const address_fn[]) (rtx) 1553 = {max_fn, min_fn, one_fn, identity_fn}; 1554 size_t i; 1555 struct attr_desc *length_attr, *new_attr; 1556 struct attr_value *av, *new_av; 1557 struct insn_ent *ie, *new_ie; 1558 1559 /* See if length attribute is defined. If so, it must be numeric. Make 1560 it special so we don't output anything for it. */ 1561 length_attr = find_attr (&length_str, 0); 1562 if (length_attr == 0) 1563 return; 1564 1565 if (! length_attr->is_numeric) 1566 fatal ("length attribute must be numeric"); 1567 1568 length_attr->is_const = 0; 1569 length_attr->is_special = 1; 1570 1571 /* Make each new attribute, in turn. */ 1572 for (i = 0; i < ARRAY_SIZE (new_names); i++) 1573 { 1574 make_internal_attr (new_names[i], 1575 substitute_address (length_attr->default_val->value, 1576 no_address_fn[i], address_fn[i]), 1577 ATTR_NONE); 1578 new_attr = find_attr (&new_names[i], 0); 1579 for (av = length_attr->first_value; av; av = av->next) 1580 for (ie = av->first_insn; ie; ie = ie->next) 1581 { 1582 new_av = get_attr_value (substitute_address (av->value, 1583 no_address_fn[i], 1584 address_fn[i]), 1585 new_attr, ie->def->insn_code); 1586 new_ie = oballoc (struct insn_ent); 1587 new_ie->def = ie->def; 1588 insert_insn_ent (new_av, new_ie); 1589 } 1590 } 1591} 1592 1593/* Utility functions called from above routine. */ 1594 1595static rtx 1596identity_fn (rtx exp) 1597{ 1598 return exp; 1599} 1600 1601static rtx 1602zero_fn (rtx exp ATTRIBUTE_UNUSED) 1603{ 1604 return make_numeric_value (0); 1605} 1606 1607static rtx 1608one_fn (rtx exp ATTRIBUTE_UNUSED) 1609{ 1610 return make_numeric_value (1); 1611} 1612 1613static rtx 1614max_fn (rtx exp) 1615{ 1616 int unknown; 1617 return make_numeric_value (max_attr_value (exp, &unknown)); 1618} 1619 1620static rtx 1621min_fn (rtx exp) 1622{ 1623 int unknown; 1624 return make_numeric_value (min_attr_value (exp, &unknown)); 1625} 1626 1627static void 1628write_length_unit_log (FILE *outf) 1629{ 1630 struct attr_desc *length_attr = find_attr (&length_str, 0); 1631 struct attr_value *av; 1632 struct insn_ent *ie; 1633 unsigned int length_unit_log, length_or; 1634 int unknown = 0; 1635 1636 if (length_attr) 1637 { 1638 length_or = or_attr_value (length_attr->default_val->value, &unknown); 1639 for (av = length_attr->first_value; av; av = av->next) 1640 for (ie = av->first_insn; ie; ie = ie->next) 1641 length_or |= or_attr_value (av->value, &unknown); 1642 } 1643 1644 if (length_attr == NULL || unknown) 1645 length_unit_log = 0; 1646 else 1647 { 1648 length_or = ~length_or; 1649 for (length_unit_log = 0; length_or & 1; length_or >>= 1) 1650 length_unit_log++; 1651 } 1652 fprintf (outf, "EXPORTED_CONST int length_unit_log = %u;\n", length_unit_log); 1653} 1654 1655/* Compute approximate cost of the expression. Used to decide whether 1656 expression is cheap enough for inline. */ 1657static int 1658attr_rtx_cost (rtx x) 1659{ 1660 int cost = 1; 1661 enum rtx_code code; 1662 if (!x) 1663 return 0; 1664 code = GET_CODE (x); 1665 switch (code) 1666 { 1667 case MATCH_OPERAND: 1668 if (XSTR (x, 1)[0]) 1669 return 10; 1670 else 1671 return 1; 1672 1673 case EQ_ATTR_ALT: 1674 return 1; 1675 1676 case EQ_ATTR: 1677 /* Alternatives don't result into function call. */ 1678 if (!strcmp_check (XSTR (x, 0), alternative_name)) 1679 return 1; 1680 else 1681 return 5; 1682 default: 1683 { 1684 int i, j; 1685 const char *fmt = GET_RTX_FORMAT (code); 1686 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 1687 { 1688 switch (fmt[i]) 1689 { 1690 case 'V': 1691 case 'E': 1692 for (j = 0; j < XVECLEN (x, i); j++) 1693 cost += attr_rtx_cost (XVECEXP (x, i, j)); 1694 break; 1695 case 'e': 1696 cost += attr_rtx_cost (XEXP (x, i)); 1697 break; 1698 } 1699 } 1700 } 1701 break; 1702 } 1703 return cost; 1704} 1705 1706/* Take a COND expression and see if any of the conditions in it can be 1707 simplified. If any are known true or known false for the particular insn 1708 code, the COND can be further simplified. 1709 1710 Also call ourselves on any COND operations that are values of this COND. 1711 1712 We do not modify EXP; rather, we make and return a new rtx. */ 1713 1714static rtx 1715simplify_cond (rtx exp, int insn_code, int insn_index) 1716{ 1717 int i, j; 1718 /* We store the desired contents here, 1719 then build a new expression if they don't match EXP. */ 1720 rtx defval = XEXP (exp, 1); 1721 rtx new_defval = XEXP (exp, 1); 1722 int len = XVECLEN (exp, 0); 1723 rtx *tests = XNEWVEC (rtx, len); 1724 int allsame = 1; 1725 rtx ret; 1726 1727 /* This lets us free all storage allocated below, if appropriate. */ 1728 obstack_finish (rtl_obstack); 1729 1730 memcpy (tests, XVEC (exp, 0)->elem, len * sizeof (rtx)); 1731 1732 /* See if default value needs simplification. */ 1733 if (GET_CODE (defval) == COND) 1734 new_defval = simplify_cond (defval, insn_code, insn_index); 1735 1736 /* Simplify the subexpressions, and see what tests we can get rid of. */ 1737 1738 for (i = 0; i < len; i += 2) 1739 { 1740 rtx newtest, newval; 1741 1742 /* Simplify this test. */ 1743 newtest = simplify_test_exp_in_temp (tests[i], insn_code, insn_index); 1744 tests[i] = newtest; 1745 1746 newval = tests[i + 1]; 1747 /* See if this value may need simplification. */ 1748 if (GET_CODE (newval) == COND) 1749 newval = simplify_cond (newval, insn_code, insn_index); 1750 1751 /* Look for ways to delete or combine this test. */ 1752 if (newtest == true_rtx) 1753 { 1754 /* If test is true, make this value the default 1755 and discard this + any following tests. */ 1756 len = i; 1757 defval = tests[i + 1]; 1758 new_defval = newval; 1759 } 1760 1761 else if (newtest == false_rtx) 1762 { 1763 /* If test is false, discard it and its value. */ 1764 for (j = i; j < len - 2; j++) 1765 tests[j] = tests[j + 2]; 1766 i -= 2; 1767 len -= 2; 1768 } 1769 1770 else if (i > 0 && attr_equal_p (newval, tests[i - 1])) 1771 { 1772 /* If this value and the value for the prev test are the same, 1773 merge the tests. */ 1774 1775 tests[i - 2] 1776 = insert_right_side (IOR, tests[i - 2], newtest, 1777 insn_code, insn_index); 1778 1779 /* Delete this test/value. */ 1780 for (j = i; j < len - 2; j++) 1781 tests[j] = tests[j + 2]; 1782 len -= 2; 1783 i -= 2; 1784 } 1785 1786 else 1787 tests[i + 1] = newval; 1788 } 1789 1790 /* If the last test in a COND has the same value 1791 as the default value, that test isn't needed. */ 1792 1793 while (len > 0 && attr_equal_p (tests[len - 1], new_defval)) 1794 len -= 2; 1795 1796 /* See if we changed anything. */ 1797 if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1)) 1798 allsame = 0; 1799 else 1800 for (i = 0; i < len; i++) 1801 if (! attr_equal_p (tests[i], XVECEXP (exp, 0, i))) 1802 { 1803 allsame = 0; 1804 break; 1805 } 1806 1807 if (len == 0) 1808 { 1809 if (GET_CODE (defval) == COND) 1810 ret = simplify_cond (defval, insn_code, insn_index); 1811 else 1812 ret = defval; 1813 } 1814 else if (allsame) 1815 ret = exp; 1816 else 1817 { 1818 rtx newexp = rtx_alloc (COND); 1819 1820 XVEC (newexp, 0) = rtvec_alloc (len); 1821 memcpy (XVEC (newexp, 0)->elem, tests, len * sizeof (rtx)); 1822 XEXP (newexp, 1) = new_defval; 1823 ret = newexp; 1824 } 1825 free (tests); 1826 return ret; 1827} 1828 1829/* Remove an insn entry from an attribute value. */ 1830 1831static void 1832remove_insn_ent (struct attr_value *av, struct insn_ent *ie) 1833{ 1834 struct insn_ent *previe; 1835 1836 if (av->first_insn == ie) 1837 av->first_insn = ie->next; 1838 else 1839 { 1840 for (previe = av->first_insn; previe->next != ie; previe = previe->next) 1841 ; 1842 previe->next = ie->next; 1843 } 1844 1845 av->num_insns--; 1846 if (ie->def->insn_code == -1) 1847 av->has_asm_insn = 0; 1848 1849 num_insn_ents--; 1850} 1851 1852/* Insert an insn entry in an attribute value list. */ 1853 1854static void 1855insert_insn_ent (struct attr_value *av, struct insn_ent *ie) 1856{ 1857 ie->next = av->first_insn; 1858 av->first_insn = ie; 1859 av->num_insns++; 1860 if (ie->def->insn_code == -1) 1861 av->has_asm_insn = 1; 1862 1863 num_insn_ents++; 1864} 1865 1866/* This is a utility routine to take an expression that is a tree of either 1867 AND or IOR expressions and insert a new term. The new term will be 1868 inserted at the right side of the first node whose code does not match 1869 the root. A new node will be created with the root's code. Its left 1870 side will be the old right side and its right side will be the new 1871 term. 1872 1873 If the `term' is itself a tree, all its leaves will be inserted. */ 1874 1875static rtx 1876insert_right_side (enum rtx_code code, rtx exp, rtx term, int insn_code, int insn_index) 1877{ 1878 rtx newexp; 1879 1880 /* Avoid consing in some special cases. */ 1881 if (code == AND && term == true_rtx) 1882 return exp; 1883 if (code == AND && term == false_rtx) 1884 return false_rtx; 1885 if (code == AND && exp == true_rtx) 1886 return term; 1887 if (code == AND && exp == false_rtx) 1888 return false_rtx; 1889 if (code == IOR && term == true_rtx) 1890 return true_rtx; 1891 if (code == IOR && term == false_rtx) 1892 return exp; 1893 if (code == IOR && exp == true_rtx) 1894 return true_rtx; 1895 if (code == IOR && exp == false_rtx) 1896 return term; 1897 if (attr_equal_p (exp, term)) 1898 return exp; 1899 1900 if (GET_CODE (term) == code) 1901 { 1902 exp = insert_right_side (code, exp, XEXP (term, 0), 1903 insn_code, insn_index); 1904 exp = insert_right_side (code, exp, XEXP (term, 1), 1905 insn_code, insn_index); 1906 1907 return exp; 1908 } 1909 1910 if (GET_CODE (exp) == code) 1911 { 1912 rtx new_rtx = insert_right_side (code, XEXP (exp, 1), 1913 term, insn_code, insn_index); 1914 if (new_rtx != XEXP (exp, 1)) 1915 /* Make a copy of this expression and call recursively. */ 1916 newexp = attr_rtx (code, XEXP (exp, 0), new_rtx); 1917 else 1918 newexp = exp; 1919 } 1920 else 1921 { 1922 /* Insert the new term. */ 1923 newexp = attr_rtx (code, exp, term); 1924 } 1925 1926 return simplify_test_exp_in_temp (newexp, insn_code, insn_index); 1927} 1928 1929/* If we have an expression which AND's a bunch of 1930 (not (eq_attrq "alternative" "n")) 1931 terms, we may have covered all or all but one of the possible alternatives. 1932 If so, we can optimize. Similarly for IOR's of EQ_ATTR. 1933 1934 This routine is passed an expression and either AND or IOR. It returns a 1935 bitmask indicating which alternatives are mentioned within EXP. */ 1936 1937static uint64_t 1938compute_alternative_mask (rtx exp, enum rtx_code code) 1939{ 1940 const char *string; 1941 if (GET_CODE (exp) == code) 1942 return compute_alternative_mask (XEXP (exp, 0), code) 1943 | compute_alternative_mask (XEXP (exp, 1), code); 1944 1945 else if (code == AND && GET_CODE (exp) == NOT 1946 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR 1947 && XSTR (XEXP (exp, 0), 0) == alternative_name) 1948 string = XSTR (XEXP (exp, 0), 1); 1949 1950 else if (code == IOR && GET_CODE (exp) == EQ_ATTR 1951 && XSTR (exp, 0) == alternative_name) 1952 string = XSTR (exp, 1); 1953 1954 else if (GET_CODE (exp) == EQ_ATTR_ALT) 1955 { 1956 if (code == AND && XINT (exp, 1)) 1957 return XINT (exp, 0); 1958 1959 if (code == IOR && !XINT (exp, 1)) 1960 return XINT (exp, 0); 1961 1962 return 0; 1963 } 1964 else 1965 return 0; 1966 1967 if (string[1] == 0) 1968 return ((uint64_t) 1) << (string[0] - '0'); 1969 return ((uint64_t) 1) << atoi (string); 1970} 1971 1972/* Given I, a single-bit mask, return RTX to compare the `alternative' 1973 attribute with the value represented by that bit. */ 1974 1975static rtx 1976make_alternative_compare (uint64_t mask) 1977{ 1978 return mk_attr_alt (mask); 1979} 1980 1981/* If we are processing an (eq_attr "attr" "value") test, we find the value 1982 of "attr" for this insn code. From that value, we can compute a test 1983 showing when the EQ_ATTR will be true. This routine performs that 1984 computation. If a test condition involves an address, we leave the EQ_ATTR 1985 intact because addresses are only valid for the `length' attribute. 1986 1987 EXP is the EQ_ATTR expression and ATTR is the attribute to which 1988 it refers. VALUE is the value of that attribute for the insn 1989 corresponding to INSN_CODE and INSN_INDEX. */ 1990 1991static rtx 1992evaluate_eq_attr (rtx exp, struct attr_desc *attr, rtx value, 1993 int insn_code, int insn_index) 1994{ 1995 rtx orexp, andexp; 1996 rtx right; 1997 rtx newexp; 1998 int i; 1999 2000 while (GET_CODE (value) == ATTR) 2001 { 2002 struct attr_value *av = NULL; 2003 2004 attr = find_attr (&XSTR (value, 0), 0); 2005 2006 if (insn_code_values) 2007 { 2008 struct attr_value_list *iv; 2009 for (iv = insn_code_values[insn_code]; iv; iv = iv->next) 2010 if (iv->attr == attr) 2011 { 2012 av = iv->av; 2013 break; 2014 } 2015 } 2016 else 2017 { 2018 struct insn_ent *ie; 2019 for (av = attr->first_value; av; av = av->next) 2020 for (ie = av->first_insn; ie; ie = ie->next) 2021 if (ie->def->insn_code == insn_code) 2022 goto got_av; 2023 } 2024 if (av) 2025 { 2026 got_av: 2027 value = av->value; 2028 } 2029 } 2030 2031 switch (GET_CODE (value)) 2032 { 2033 case CONST_STRING: 2034 if (! strcmp_check (XSTR (value, 0), XSTR (exp, 1))) 2035 newexp = true_rtx; 2036 else 2037 newexp = false_rtx; 2038 break; 2039 2040 case SYMBOL_REF: 2041 { 2042 const char *prefix; 2043 char *string, *p; 2044 2045 gcc_assert (GET_CODE (exp) == EQ_ATTR); 2046 prefix = attr->enum_name ? attr->enum_name : attr->name; 2047 string = ACONCAT ((prefix, "_", XSTR (exp, 1), NULL)); 2048 for (p = string; *p; p++) 2049 *p = TOUPPER (*p); 2050 2051 newexp = attr_rtx (EQ, value, 2052 attr_rtx (SYMBOL_REF, 2053 DEF_ATTR_STRING (string))); 2054 break; 2055 } 2056 2057 case COND: 2058 /* We construct an IOR of all the cases for which the 2059 requested attribute value is present. Since we start with 2060 FALSE, if it is not present, FALSE will be returned. 2061 2062 Each case is the AND of the NOT's of the previous conditions with the 2063 current condition; in the default case the current condition is TRUE. 2064 2065 For each possible COND value, call ourselves recursively. 2066 2067 The extra TRUE and FALSE expressions will be eliminated by another 2068 call to the simplification routine. */ 2069 2070 orexp = false_rtx; 2071 andexp = true_rtx; 2072 2073 for (i = 0; i < XVECLEN (value, 0); i += 2) 2074 { 2075 rtx this_cond = simplify_test_exp_in_temp (XVECEXP (value, 0, i), 2076 insn_code, insn_index); 2077 2078 right = insert_right_side (AND, andexp, this_cond, 2079 insn_code, insn_index); 2080 right = insert_right_side (AND, right, 2081 evaluate_eq_attr (exp, attr, 2082 XVECEXP (value, 0, 2083 i + 1), 2084 insn_code, insn_index), 2085 insn_code, insn_index); 2086 orexp = insert_right_side (IOR, orexp, right, 2087 insn_code, insn_index); 2088 2089 /* Add this condition into the AND expression. */ 2090 newexp = attr_rtx (NOT, this_cond); 2091 andexp = insert_right_side (AND, andexp, newexp, 2092 insn_code, insn_index); 2093 } 2094 2095 /* Handle the default case. */ 2096 right = insert_right_side (AND, andexp, 2097 evaluate_eq_attr (exp, attr, XEXP (value, 1), 2098 insn_code, insn_index), 2099 insn_code, insn_index); 2100 newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index); 2101 break; 2102 2103 default: 2104 gcc_unreachable (); 2105 } 2106 2107 /* If uses an address, must return original expression. But set the 2108 ATTR_IND_SIMPLIFIED_P bit so we don't try to simplify it again. */ 2109 2110 address_used = 0; 2111 walk_attr_value (newexp); 2112 2113 if (address_used) 2114 { 2115 if (! ATTR_IND_SIMPLIFIED_P (exp)) 2116 return copy_rtx_unchanging (exp); 2117 return exp; 2118 } 2119 else 2120 return newexp; 2121} 2122 2123/* This routine is called when an AND of a term with a tree of AND's is 2124 encountered. If the term or its complement is present in the tree, it 2125 can be replaced with TRUE or FALSE, respectively. 2126 2127 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both 2128 be true and hence are complementary. 2129 2130 There is one special case: If we see 2131 (and (not (eq_attr "att" "v1")) 2132 (eq_attr "att" "v2")) 2133 this can be replaced by (eq_attr "att" "v2"). To do this we need to 2134 replace the term, not anything in the AND tree. So we pass a pointer to 2135 the term. */ 2136 2137static rtx 2138simplify_and_tree (rtx exp, rtx *pterm, int insn_code, int insn_index) 2139{ 2140 rtx left, right; 2141 rtx newexp; 2142 rtx temp; 2143 int left_eliminates_term, right_eliminates_term; 2144 2145 if (GET_CODE (exp) == AND) 2146 { 2147 left = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index); 2148 right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index); 2149 if (left != XEXP (exp, 0) || right != XEXP (exp, 1)) 2150 { 2151 newexp = attr_rtx (AND, left, right); 2152 2153 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index); 2154 } 2155 } 2156 2157 else if (GET_CODE (exp) == IOR) 2158 { 2159 /* For the IOR case, we do the same as above, except that we can 2160 only eliminate `term' if both sides of the IOR would do so. */ 2161 temp = *pterm; 2162 left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index); 2163 left_eliminates_term = (temp == true_rtx); 2164 2165 temp = *pterm; 2166 right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index); 2167 right_eliminates_term = (temp == true_rtx); 2168 2169 if (left_eliminates_term && right_eliminates_term) 2170 *pterm = true_rtx; 2171 2172 if (left != XEXP (exp, 0) || right != XEXP (exp, 1)) 2173 { 2174 newexp = attr_rtx (IOR, left, right); 2175 2176 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index); 2177 } 2178 } 2179 2180 /* Check for simplifications. Do some extra checking here since this 2181 routine is called so many times. */ 2182 2183 if (exp == *pterm) 2184 return true_rtx; 2185 2186 else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm) 2187 return false_rtx; 2188 2189 else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0)) 2190 return false_rtx; 2191 2192 else if (GET_CODE (exp) == EQ_ATTR_ALT && GET_CODE (*pterm) == EQ_ATTR_ALT) 2193 { 2194 if (attr_alt_subset_p (*pterm, exp)) 2195 return true_rtx; 2196 2197 if (attr_alt_subset_of_compl_p (*pterm, exp)) 2198 return false_rtx; 2199 2200 if (attr_alt_subset_p (exp, *pterm)) 2201 *pterm = true_rtx; 2202 2203 return exp; 2204 } 2205 2206 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR) 2207 { 2208 if (XSTR (exp, 0) != XSTR (*pterm, 0)) 2209 return exp; 2210 2211 if (! strcmp_check (XSTR (exp, 1), XSTR (*pterm, 1))) 2212 return true_rtx; 2213 else 2214 return false_rtx; 2215 } 2216 2217 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT 2218 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR) 2219 { 2220 if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0)) 2221 return exp; 2222 2223 if (! strcmp_check (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1))) 2224 return false_rtx; 2225 else 2226 return true_rtx; 2227 } 2228 2229 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT 2230 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR) 2231 { 2232 if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0)) 2233 return exp; 2234 2235 if (! strcmp_check (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1))) 2236 return false_rtx; 2237 else 2238 *pterm = true_rtx; 2239 } 2240 2241 else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT) 2242 { 2243 if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0))) 2244 return true_rtx; 2245 } 2246 2247 else if (GET_CODE (exp) == NOT) 2248 { 2249 if (attr_equal_p (XEXP (exp, 0), *pterm)) 2250 return false_rtx; 2251 } 2252 2253 else if (GET_CODE (*pterm) == NOT) 2254 { 2255 if (attr_equal_p (XEXP (*pterm, 0), exp)) 2256 return false_rtx; 2257 } 2258 2259 else if (attr_equal_p (exp, *pterm)) 2260 return true_rtx; 2261 2262 return exp; 2263} 2264 2265/* Similar to `simplify_and_tree', but for IOR trees. */ 2266 2267static rtx 2268simplify_or_tree (rtx exp, rtx *pterm, int insn_code, int insn_index) 2269{ 2270 rtx left, right; 2271 rtx newexp; 2272 rtx temp; 2273 int left_eliminates_term, right_eliminates_term; 2274 2275 if (GET_CODE (exp) == IOR) 2276 { 2277 left = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index); 2278 right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index); 2279 if (left != XEXP (exp, 0) || right != XEXP (exp, 1)) 2280 { 2281 newexp = attr_rtx (GET_CODE (exp), left, right); 2282 2283 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index); 2284 } 2285 } 2286 2287 else if (GET_CODE (exp) == AND) 2288 { 2289 /* For the AND case, we do the same as above, except that we can 2290 only eliminate `term' if both sides of the AND would do so. */ 2291 temp = *pterm; 2292 left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index); 2293 left_eliminates_term = (temp == false_rtx); 2294 2295 temp = *pterm; 2296 right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index); 2297 right_eliminates_term = (temp == false_rtx); 2298 2299 if (left_eliminates_term && right_eliminates_term) 2300 *pterm = false_rtx; 2301 2302 if (left != XEXP (exp, 0) || right != XEXP (exp, 1)) 2303 { 2304 newexp = attr_rtx (GET_CODE (exp), left, right); 2305 2306 exp = simplify_test_exp_in_temp (newexp, insn_code, insn_index); 2307 } 2308 } 2309 2310 if (attr_equal_p (exp, *pterm)) 2311 return false_rtx; 2312 2313 else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm)) 2314 return true_rtx; 2315 2316 else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp)) 2317 return true_rtx; 2318 2319 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT 2320 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR 2321 && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0)) 2322 *pterm = false_rtx; 2323 2324 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT 2325 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR 2326 && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0)) 2327 return false_rtx; 2328 2329 return exp; 2330} 2331 2332/* Simplify test expression and use temporary obstack in order to avoid 2333 memory bloat. Use ATTR_IND_SIMPLIFIED to avoid unnecessary simplifications 2334 and avoid unnecessary copying if possible. */ 2335 2336static rtx 2337simplify_test_exp_in_temp (rtx exp, int insn_code, int insn_index) 2338{ 2339 rtx x; 2340 struct obstack *old; 2341 if (ATTR_IND_SIMPLIFIED_P (exp)) 2342 return exp; 2343 old = rtl_obstack; 2344 rtl_obstack = temp_obstack; 2345 x = simplify_test_exp (exp, insn_code, insn_index); 2346 rtl_obstack = old; 2347 if (x == exp || rtl_obstack == temp_obstack) 2348 return x; 2349 return attr_copy_rtx (x); 2350} 2351 2352/* Returns true if S1 is a subset of S2. */ 2353 2354static bool 2355attr_alt_subset_p (rtx s1, rtx s2) 2356{ 2357 switch ((XINT (s1, 1) << 1) | XINT (s2, 1)) 2358 { 2359 case (0 << 1) | 0: 2360 return !(XINT (s1, 0) &~ XINT (s2, 0)); 2361 2362 case (0 << 1) | 1: 2363 return !(XINT (s1, 0) & XINT (s2, 0)); 2364 2365 case (1 << 1) | 0: 2366 return false; 2367 2368 case (1 << 1) | 1: 2369 return !(XINT (s2, 0) &~ XINT (s1, 0)); 2370 2371 default: 2372 gcc_unreachable (); 2373 } 2374} 2375 2376/* Returns true if S1 is a subset of complement of S2. */ 2377 2378static bool 2379attr_alt_subset_of_compl_p (rtx s1, rtx s2) 2380{ 2381 switch ((XINT (s1, 1) << 1) | XINT (s2, 1)) 2382 { 2383 case (0 << 1) | 0: 2384 return !(XINT (s1, 0) & XINT (s2, 0)); 2385 2386 case (0 << 1) | 1: 2387 return !(XINT (s1, 0) & ~XINT (s2, 0)); 2388 2389 case (1 << 1) | 0: 2390 return !(XINT (s2, 0) &~ XINT (s1, 0)); 2391 2392 case (1 << 1) | 1: 2393 return false; 2394 2395 default: 2396 gcc_unreachable (); 2397 } 2398} 2399 2400/* Return EQ_ATTR_ALT expression representing intersection of S1 and S2. */ 2401 2402static rtx 2403attr_alt_intersection (rtx s1, rtx s2) 2404{ 2405 rtx result = rtx_alloc (EQ_ATTR_ALT); 2406 2407 switch ((XINT (s1, 1) << 1) | XINT (s2, 1)) 2408 { 2409 case (0 << 1) | 0: 2410 XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0); 2411 break; 2412 case (0 << 1) | 1: 2413 XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0); 2414 break; 2415 case (1 << 1) | 0: 2416 XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0); 2417 break; 2418 case (1 << 1) | 1: 2419 XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0); 2420 break; 2421 default: 2422 gcc_unreachable (); 2423 } 2424 XINT (result, 1) = XINT (s1, 1) & XINT (s2, 1); 2425 2426 return result; 2427} 2428 2429/* Return EQ_ATTR_ALT expression representing union of S1 and S2. */ 2430 2431static rtx 2432attr_alt_union (rtx s1, rtx s2) 2433{ 2434 rtx result = rtx_alloc (EQ_ATTR_ALT); 2435 2436 switch ((XINT (s1, 1) << 1) | XINT (s2, 1)) 2437 { 2438 case (0 << 1) | 0: 2439 XINT (result, 0) = XINT (s1, 0) | XINT (s2, 0); 2440 break; 2441 case (0 << 1) | 1: 2442 XINT (result, 0) = XINT (s2, 0) & ~XINT (s1, 0); 2443 break; 2444 case (1 << 1) | 0: 2445 XINT (result, 0) = XINT (s1, 0) & ~XINT (s2, 0); 2446 break; 2447 case (1 << 1) | 1: 2448 XINT (result, 0) = XINT (s1, 0) & XINT (s2, 0); 2449 break; 2450 default: 2451 gcc_unreachable (); 2452 } 2453 2454 XINT (result, 1) = XINT (s1, 1) | XINT (s2, 1); 2455 return result; 2456} 2457 2458/* Return EQ_ATTR_ALT expression representing complement of S. */ 2459 2460static rtx 2461attr_alt_complement (rtx s) 2462{ 2463 rtx result = rtx_alloc (EQ_ATTR_ALT); 2464 2465 XINT (result, 0) = XINT (s, 0); 2466 XINT (result, 1) = 1 - XINT (s, 1); 2467 2468 return result; 2469} 2470 2471/* Return EQ_ATTR_ALT expression representing set containing elements set 2472 in E. */ 2473 2474static rtx 2475mk_attr_alt (uint64_t e) 2476{ 2477 rtx result = rtx_alloc (EQ_ATTR_ALT); 2478 2479 XINT (result, 0) = e; 2480 XINT (result, 1) = 0; 2481 2482 return result; 2483} 2484 2485/* Given an expression, see if it can be simplified for a particular insn 2486 code based on the values of other attributes being tested. This can 2487 eliminate nested get_attr_... calls. 2488 2489 Note that if an endless recursion is specified in the patterns, the 2490 optimization will loop. However, it will do so in precisely the cases where 2491 an infinite recursion loop could occur during compilation. It's better that 2492 it occurs here! */ 2493 2494static rtx 2495simplify_test_exp (rtx exp, int insn_code, int insn_index) 2496{ 2497 rtx left, right; 2498 struct attr_desc *attr; 2499 struct attr_value *av; 2500 struct insn_ent *ie; 2501 struct attr_value_list *iv; 2502 uint64_t i; 2503 rtx newexp = exp; 2504 bool left_alt, right_alt; 2505 2506 /* Don't re-simplify something we already simplified. */ 2507 if (ATTR_IND_SIMPLIFIED_P (exp) || ATTR_CURR_SIMPLIFIED_P (exp)) 2508 return exp; 2509 2510 switch (GET_CODE (exp)) 2511 { 2512 case AND: 2513 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index); 2514 if (left == false_rtx) 2515 return false_rtx; 2516 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index); 2517 if (right == false_rtx) 2518 return false_rtx; 2519 2520 if (GET_CODE (left) == EQ_ATTR_ALT 2521 && GET_CODE (right) == EQ_ATTR_ALT) 2522 { 2523 exp = attr_alt_intersection (left, right); 2524 return simplify_test_exp (exp, insn_code, insn_index); 2525 } 2526 2527 /* If either side is an IOR and we have (eq_attr "alternative" ..") 2528 present on both sides, apply the distributive law since this will 2529 yield simplifications. */ 2530 if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR) 2531 && compute_alternative_mask (left, IOR) 2532 && compute_alternative_mask (right, IOR)) 2533 { 2534 if (GET_CODE (left) == IOR) 2535 { 2536 rtx tem = left; 2537 left = right; 2538 right = tem; 2539 } 2540 2541 newexp = attr_rtx (IOR, 2542 attr_rtx (AND, left, XEXP (right, 0)), 2543 attr_rtx (AND, left, XEXP (right, 1))); 2544 2545 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); 2546 } 2547 2548 /* Try with the term on both sides. */ 2549 right = simplify_and_tree (right, &left, insn_code, insn_index); 2550 if (left == XEXP (exp, 0) && right == XEXP (exp, 1)) 2551 left = simplify_and_tree (left, &right, insn_code, insn_index); 2552 2553 if (left == false_rtx || right == false_rtx) 2554 return false_rtx; 2555 else if (left == true_rtx) 2556 { 2557 return right; 2558 } 2559 else if (right == true_rtx) 2560 { 2561 return left; 2562 } 2563 /* See if all or all but one of the insn's alternatives are specified 2564 in this tree. Optimize if so. */ 2565 2566 if (GET_CODE (left) == NOT) 2567 left_alt = (GET_CODE (XEXP (left, 0)) == EQ_ATTR 2568 && XSTR (XEXP (left, 0), 0) == alternative_name); 2569 else 2570 left_alt = (GET_CODE (left) == EQ_ATTR_ALT 2571 && XINT (left, 1)); 2572 2573 if (GET_CODE (right) == NOT) 2574 right_alt = (GET_CODE (XEXP (right, 0)) == EQ_ATTR 2575 && XSTR (XEXP (right, 0), 0) == alternative_name); 2576 else 2577 right_alt = (GET_CODE (right) == EQ_ATTR_ALT 2578 && XINT (right, 1)); 2579 2580 if (insn_code >= 0 2581 && (GET_CODE (left) == AND 2582 || left_alt 2583 || GET_CODE (right) == AND 2584 || right_alt)) 2585 { 2586 i = compute_alternative_mask (exp, AND); 2587 if (i & ~insn_alternatives[insn_code]) 2588 fatal ("invalid alternative specified for pattern number %d", 2589 insn_index); 2590 2591 /* If all alternatives are excluded, this is false. */ 2592 i ^= insn_alternatives[insn_code]; 2593 if (i == 0) 2594 return false_rtx; 2595 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1) 2596 { 2597 /* If just one excluded, AND a comparison with that one to the 2598 front of the tree. The others will be eliminated by 2599 optimization. We do not want to do this if the insn has one 2600 alternative and we have tested none of them! */ 2601 left = make_alternative_compare (i); 2602 right = simplify_and_tree (exp, &left, insn_code, insn_index); 2603 newexp = attr_rtx (AND, left, right); 2604 2605 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); 2606 } 2607 } 2608 2609 if (left != XEXP (exp, 0) || right != XEXP (exp, 1)) 2610 { 2611 newexp = attr_rtx (AND, left, right); 2612 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); 2613 } 2614 break; 2615 2616 case IOR: 2617 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index); 2618 if (left == true_rtx) 2619 return true_rtx; 2620 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index); 2621 if (right == true_rtx) 2622 return true_rtx; 2623 2624 if (GET_CODE (left) == EQ_ATTR_ALT 2625 && GET_CODE (right) == EQ_ATTR_ALT) 2626 { 2627 exp = attr_alt_union (left, right); 2628 return simplify_test_exp (exp, insn_code, insn_index); 2629 } 2630 2631 right = simplify_or_tree (right, &left, insn_code, insn_index); 2632 if (left == XEXP (exp, 0) && right == XEXP (exp, 1)) 2633 left = simplify_or_tree (left, &right, insn_code, insn_index); 2634 2635 if (right == true_rtx || left == true_rtx) 2636 return true_rtx; 2637 else if (left == false_rtx) 2638 { 2639 return right; 2640 } 2641 else if (right == false_rtx) 2642 { 2643 return left; 2644 } 2645 2646 /* Test for simple cases where the distributive law is useful. I.e., 2647 convert (ior (and (x) (y)) 2648 (and (x) (z))) 2649 to (and (x) 2650 (ior (y) (z))) 2651 */ 2652 2653 else if (GET_CODE (left) == AND && GET_CODE (right) == AND 2654 && attr_equal_p (XEXP (left, 0), XEXP (right, 0))) 2655 { 2656 newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1)); 2657 2658 left = XEXP (left, 0); 2659 right = newexp; 2660 newexp = attr_rtx (AND, left, right); 2661 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); 2662 } 2663 2664 /* Similarly, 2665 convert (ior (and (y) (x)) 2666 (and (z) (x))) 2667 to (and (ior (y) (z)) 2668 (x)) 2669 Note that we want the common term to stay at the end. 2670 */ 2671 2672 else if (GET_CODE (left) == AND && GET_CODE (right) == AND 2673 && attr_equal_p (XEXP (left, 1), XEXP (right, 1))) 2674 { 2675 newexp = attr_rtx (IOR, XEXP (left, 0), XEXP (right, 0)); 2676 2677 left = newexp; 2678 right = XEXP (right, 1); 2679 newexp = attr_rtx (AND, left, right); 2680 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); 2681 } 2682 2683 /* See if all or all but one of the insn's alternatives are specified 2684 in this tree. Optimize if so. */ 2685 2686 else if (insn_code >= 0 2687 && (GET_CODE (left) == IOR 2688 || (GET_CODE (left) == EQ_ATTR_ALT 2689 && !XINT (left, 1)) 2690 || (GET_CODE (left) == EQ_ATTR 2691 && XSTR (left, 0) == alternative_name) 2692 || GET_CODE (right) == IOR 2693 || (GET_CODE (right) == EQ_ATTR_ALT 2694 && !XINT (right, 1)) 2695 || (GET_CODE (right) == EQ_ATTR 2696 && XSTR (right, 0) == alternative_name))) 2697 { 2698 i = compute_alternative_mask (exp, IOR); 2699 if (i & ~insn_alternatives[insn_code]) 2700 fatal ("invalid alternative specified for pattern number %d", 2701 insn_index); 2702 2703 /* If all alternatives are included, this is true. */ 2704 i ^= insn_alternatives[insn_code]; 2705 if (i == 0) 2706 return true_rtx; 2707 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1) 2708 { 2709 /* If just one excluded, IOR a comparison with that one to the 2710 front of the tree. The others will be eliminated by 2711 optimization. We do not want to do this if the insn has one 2712 alternative and we have tested none of them! */ 2713 left = make_alternative_compare (i); 2714 right = simplify_and_tree (exp, &left, insn_code, insn_index); 2715 newexp = attr_rtx (IOR, attr_rtx (NOT, left), right); 2716 2717 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); 2718 } 2719 } 2720 2721 if (left != XEXP (exp, 0) || right != XEXP (exp, 1)) 2722 { 2723 newexp = attr_rtx (IOR, left, right); 2724 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); 2725 } 2726 break; 2727 2728 case NOT: 2729 if (GET_CODE (XEXP (exp, 0)) == NOT) 2730 { 2731 left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0), 2732 insn_code, insn_index); 2733 return left; 2734 } 2735 2736 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index); 2737 if (GET_CODE (left) == NOT) 2738 return XEXP (left, 0); 2739 2740 if (left == false_rtx) 2741 return true_rtx; 2742 if (left == true_rtx) 2743 return false_rtx; 2744 2745 if (GET_CODE (left) == EQ_ATTR_ALT) 2746 { 2747 exp = attr_alt_complement (left); 2748 return simplify_test_exp (exp, insn_code, insn_index); 2749 } 2750 2751 /* Try to apply De`Morgan's laws. */ 2752 if (GET_CODE (left) == IOR) 2753 { 2754 newexp = attr_rtx (AND, 2755 attr_rtx (NOT, XEXP (left, 0)), 2756 attr_rtx (NOT, XEXP (left, 1))); 2757 2758 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); 2759 } 2760 else if (GET_CODE (left) == AND) 2761 { 2762 newexp = attr_rtx (IOR, 2763 attr_rtx (NOT, XEXP (left, 0)), 2764 attr_rtx (NOT, XEXP (left, 1))); 2765 2766 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); 2767 } 2768 else if (left != XEXP (exp, 0)) 2769 { 2770 newexp = attr_rtx (NOT, left); 2771 } 2772 break; 2773 2774 case EQ_ATTR_ALT: 2775 if (!XINT (exp, 0)) 2776 return XINT (exp, 1) ? true_rtx : false_rtx; 2777 break; 2778 2779 case EQ_ATTR: 2780 if (XSTR (exp, 0) == alternative_name) 2781 { 2782 newexp = mk_attr_alt (((uint64_t) 1) << atoi (XSTR (exp, 1))); 2783 break; 2784 } 2785 2786 /* Look at the value for this insn code in the specified attribute. 2787 We normally can replace this comparison with the condition that 2788 would give this insn the values being tested for. */ 2789 if (insn_code >= 0 2790 && (attr = find_attr (&XSTR (exp, 0), 0)) != NULL) 2791 { 2792 rtx x; 2793 2794 av = NULL; 2795 if (insn_code_values) 2796 { 2797 for (iv = insn_code_values[insn_code]; iv; iv = iv->next) 2798 if (iv->attr == attr) 2799 { 2800 av = iv->av; 2801 break; 2802 } 2803 } 2804 else 2805 { 2806 for (av = attr->first_value; av; av = av->next) 2807 for (ie = av->first_insn; ie; ie = ie->next) 2808 if (ie->def->insn_code == insn_code) 2809 goto got_av; 2810 } 2811 2812 if (av) 2813 { 2814 got_av: 2815 x = evaluate_eq_attr (exp, attr, av->value, 2816 insn_code, insn_index); 2817 x = SIMPLIFY_TEST_EXP (x, insn_code, insn_index); 2818 if (attr_rtx_cost (x) < 7) 2819 return x; 2820 } 2821 } 2822 break; 2823 2824 default: 2825 break; 2826 } 2827 2828 /* We have already simplified this expression. Simplifying it again 2829 won't buy anything unless we weren't given a valid insn code 2830 to process (i.e., we are canonicalizing something.). */ 2831 if (insn_code != -2 2832 && ! ATTR_IND_SIMPLIFIED_P (newexp)) 2833 return copy_rtx_unchanging (newexp); 2834 2835 return newexp; 2836} 2837 2838/* Return 1 if any EQ_ATTR subexpression of P refers to ATTR, 2839 otherwise return 0. */ 2840 2841static int 2842tests_attr_p (rtx p, struct attr_desc *attr) 2843{ 2844 const char *fmt; 2845 int i, ie, j, je; 2846 2847 if (GET_CODE (p) == EQ_ATTR) 2848 { 2849 if (XSTR (p, 0) != attr->name) 2850 return 0; 2851 return 1; 2852 } 2853 2854 fmt = GET_RTX_FORMAT (GET_CODE (p)); 2855 ie = GET_RTX_LENGTH (GET_CODE (p)); 2856 for (i = 0; i < ie; i++) 2857 { 2858 switch (*fmt++) 2859 { 2860 case 'e': 2861 if (tests_attr_p (XEXP (p, i), attr)) 2862 return 1; 2863 break; 2864 2865 case 'E': 2866 je = XVECLEN (p, i); 2867 for (j = 0; j < je; ++j) 2868 if (tests_attr_p (XVECEXP (p, i, j), attr)) 2869 return 1; 2870 break; 2871 } 2872 } 2873 2874 return 0; 2875} 2876 2877/* Calculate a topological sorting of all attributes so that 2878 all attributes only depend on attributes in front of it. 2879 Place the result in *RET (which is a pointer to an array of 2880 attr_desc pointers), and return the size of that array. */ 2881 2882static int 2883get_attr_order (struct attr_desc ***ret) 2884{ 2885 int i, j; 2886 int num = 0; 2887 struct attr_desc *attr; 2888 struct attr_desc **all, **sorted; 2889 char *handled; 2890 for (i = 0; i < MAX_ATTRS_INDEX; i++) 2891 for (attr = attrs[i]; attr; attr = attr->next) 2892 num++; 2893 all = XNEWVEC (struct attr_desc *, num); 2894 sorted = XNEWVEC (struct attr_desc *, num); 2895 handled = XCNEWVEC (char, num); 2896 num = 0; 2897 for (i = 0; i < MAX_ATTRS_INDEX; i++) 2898 for (attr = attrs[i]; attr; attr = attr->next) 2899 all[num++] = attr; 2900 2901 j = 0; 2902 for (i = 0; i < num; i++) 2903 if (all[i]->is_const) 2904 handled[i] = 1, sorted[j++] = all[i]; 2905 2906 /* We have only few attributes hence we can live with the inner 2907 loop being O(n^2), unlike the normal fast variants of topological 2908 sorting. */ 2909 while (j < num) 2910 { 2911 for (i = 0; i < num; i++) 2912 if (!handled[i]) 2913 { 2914 /* Let's see if I depends on anything interesting. */ 2915 int k; 2916 for (k = 0; k < num; k++) 2917 if (!handled[k]) 2918 { 2919 struct attr_value *av; 2920 for (av = all[i]->first_value; av; av = av->next) 2921 if (av->num_insns != 0) 2922 if (tests_attr_p (av->value, all[k])) 2923 break; 2924 2925 if (av) 2926 /* Something in I depends on K. */ 2927 break; 2928 } 2929 if (k == num) 2930 { 2931 /* Nothing in I depended on anything intersting, so 2932 it's done. */ 2933 handled[i] = 1; 2934 sorted[j++] = all[i]; 2935 } 2936 } 2937 } 2938 2939 if (DEBUG) 2940 for (j = 0; j < num; j++) 2941 { 2942 struct attr_desc *attr2; 2943 struct attr_value *av; 2944 2945 attr = sorted[j]; 2946 fprintf (stderr, "%s depends on: ", attr->name); 2947 for (i = 0; i < MAX_ATTRS_INDEX; ++i) 2948 for (attr2 = attrs[i]; attr2; attr2 = attr2->next) 2949 if (!attr2->is_const) 2950 for (av = attr->first_value; av; av = av->next) 2951 if (av->num_insns != 0) 2952 if (tests_attr_p (av->value, attr2)) 2953 { 2954 fprintf (stderr, "%s, ", attr2->name); 2955 break; 2956 } 2957 fprintf (stderr, "\n"); 2958 } 2959 2960 free (all); 2961 *ret = sorted; 2962 return num; 2963} 2964 2965/* Optimize the attribute lists by seeing if we can determine conditional 2966 values from the known values of other attributes. This will save subroutine 2967 calls during the compilation. */ 2968 2969static void 2970optimize_attrs (void) 2971{ 2972 struct attr_desc *attr; 2973 struct attr_value *av; 2974 struct insn_ent *ie; 2975 rtx newexp; 2976 int i; 2977 struct attr_value_list *ivbuf; 2978 struct attr_value_list *iv; 2979 struct attr_desc **topsort; 2980 int topnum; 2981 2982 /* For each insn code, make a list of all the insn_ent's for it, 2983 for all values for all attributes. */ 2984 2985 if (num_insn_ents == 0) 2986 return; 2987 2988 /* Make 2 extra elements, for "code" values -2 and -1. */ 2989 insn_code_values = XCNEWVEC (struct attr_value_list *, insn_code_number + 2); 2990 2991 /* Offset the table address so we can index by -2 or -1. */ 2992 insn_code_values += 2; 2993 2994 iv = ivbuf = XNEWVEC (struct attr_value_list, num_insn_ents); 2995 2996 /* Create the chain of insn*attr values such that we see dependend 2997 attributes after their dependencies. As we use a stack via the 2998 next pointers start from the end of the topological order. */ 2999 topnum = get_attr_order (&topsort); 3000 for (i = topnum - 1; i >= 0; i--) 3001 for (av = topsort[i]->first_value; av; av = av->next) 3002 for (ie = av->first_insn; ie; ie = ie->next) 3003 { 3004 iv->attr = topsort[i]; 3005 iv->av = av; 3006 iv->ie = ie; 3007 iv->next = insn_code_values[ie->def->insn_code]; 3008 insn_code_values[ie->def->insn_code] = iv; 3009 iv++; 3010 } 3011 free (topsort); 3012 3013 /* Sanity check on num_insn_ents. */ 3014 gcc_assert (iv == ivbuf + num_insn_ents); 3015 3016 /* Process one insn code at a time. */ 3017 for (i = -2; i < insn_code_number; i++) 3018 { 3019 /* Clear the ATTR_CURR_SIMPLIFIED_P flag everywhere relevant. 3020 We use it to mean "already simplified for this insn". */ 3021 for (iv = insn_code_values[i]; iv; iv = iv->next) 3022 clear_struct_flag (iv->av->value); 3023 3024 for (iv = insn_code_values[i]; iv; iv = iv->next) 3025 { 3026 struct obstack *old = rtl_obstack; 3027 3028 attr = iv->attr; 3029 av = iv->av; 3030 ie = iv->ie; 3031 if (GET_CODE (av->value) != COND) 3032 continue; 3033 3034 rtl_obstack = temp_obstack; 3035 newexp = av->value; 3036 while (GET_CODE (newexp) == COND) 3037 { 3038 rtx newexp2 = simplify_cond (newexp, ie->def->insn_code, 3039 ie->def->insn_index); 3040 if (newexp2 == newexp) 3041 break; 3042 newexp = newexp2; 3043 } 3044 3045 rtl_obstack = old; 3046 /* If we created a new value for this instruction, and it's 3047 cheaper than the old value, and overall cheap, use that 3048 one as specific value for the current instruction. 3049 The last test is to avoid exploding the get_attr_ function 3050 sizes for no much gain. */ 3051 if (newexp != av->value 3052 && attr_rtx_cost (newexp) < attr_rtx_cost (av->value) 3053 && attr_rtx_cost (newexp) < 26 3054 ) 3055 { 3056 newexp = attr_copy_rtx (newexp); 3057 remove_insn_ent (av, ie); 3058 av = get_attr_value (newexp, attr, ie->def->insn_code); 3059 iv->av = av; 3060 insert_insn_ent (av, ie); 3061 } 3062 } 3063 } 3064 3065 free (ivbuf); 3066 free (insn_code_values - 2); 3067 insn_code_values = NULL; 3068} 3069 3070/* Clear the ATTR_CURR_SIMPLIFIED_P flag in EXP and its subexpressions. */ 3071 3072static void 3073clear_struct_flag (rtx x) 3074{ 3075 int i; 3076 int j; 3077 enum rtx_code code; 3078 const char *fmt; 3079 3080 ATTR_CURR_SIMPLIFIED_P (x) = 0; 3081 if (ATTR_IND_SIMPLIFIED_P (x)) 3082 return; 3083 3084 code = GET_CODE (x); 3085 3086 switch (code) 3087 { 3088 case REG: 3089 CASE_CONST_ANY: 3090 case MATCH_TEST: 3091 case SYMBOL_REF: 3092 case CODE_LABEL: 3093 case PC: 3094 case CC0: 3095 case EQ_ATTR: 3096 case ATTR_FLAG: 3097 return; 3098 3099 default: 3100 break; 3101 } 3102 3103 /* Compare the elements. If any pair of corresponding elements 3104 fail to match, return 0 for the whole things. */ 3105 3106 fmt = GET_RTX_FORMAT (code); 3107 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 3108 { 3109 switch (fmt[i]) 3110 { 3111 case 'V': 3112 case 'E': 3113 for (j = 0; j < XVECLEN (x, i); j++) 3114 clear_struct_flag (XVECEXP (x, i, j)); 3115 break; 3116 3117 case 'e': 3118 clear_struct_flag (XEXP (x, i)); 3119 break; 3120 } 3121 } 3122} 3123 3124/* Add attribute value NAME to the beginning of ATTR's list. */ 3125 3126static void 3127add_attr_value (struct attr_desc *attr, const char *name) 3128{ 3129 struct attr_value *av; 3130 3131 av = oballoc (struct attr_value); 3132 av->value = attr_rtx (CONST_STRING, name); 3133 av->next = attr->first_value; 3134 attr->first_value = av; 3135 av->first_insn = NULL; 3136 av->num_insns = 0; 3137 av->has_asm_insn = 0; 3138} 3139 3140/* Create table entries for DEFINE_ATTR or DEFINE_ENUM_ATTR. */ 3141 3142static void 3143gen_attr (rtx exp, int lineno) 3144{ 3145 struct enum_type *et; 3146 struct enum_value *ev; 3147 struct attr_desc *attr; 3148 const char *name_ptr; 3149 char *p; 3150 3151 /* Make a new attribute structure. Check for duplicate by looking at 3152 attr->default_val, since it is initialized by this routine. */ 3153 attr = find_attr (&XSTR (exp, 0), 1); 3154 if (attr->default_val) 3155 { 3156 error_with_line (lineno, "duplicate definition for attribute %s", 3157 attr->name); 3158 message_with_line (attr->lineno, "previous definition"); 3159 return; 3160 } 3161 attr->lineno = lineno; 3162 3163 if (GET_CODE (exp) == DEFINE_ENUM_ATTR) 3164 { 3165 attr->enum_name = XSTR (exp, 1); 3166 et = lookup_enum_type (XSTR (exp, 1)); 3167 if (!et || !et->md_p) 3168 error_with_line (lineno, "No define_enum called `%s' defined", 3169 attr->name); 3170 if (et) 3171 for (ev = et->values; ev; ev = ev->next) 3172 add_attr_value (attr, ev->name); 3173 } 3174 else if (*XSTR (exp, 1) == '\0') 3175 attr->is_numeric = 1; 3176 else 3177 { 3178 name_ptr = XSTR (exp, 1); 3179 while ((p = next_comma_elt (&name_ptr)) != NULL) 3180 add_attr_value (attr, p); 3181 } 3182 3183 if (GET_CODE (XEXP (exp, 2)) == CONST) 3184 { 3185 attr->is_const = 1; 3186 if (attr->is_numeric) 3187 error_with_line (lineno, 3188 "constant attributes may not take numeric values"); 3189 3190 /* Get rid of the CONST node. It is allowed only at top-level. */ 3191 XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0); 3192 } 3193 3194 if (! strcmp_check (attr->name, length_str) && ! attr->is_numeric) 3195 error_with_line (lineno, "`length' attribute must take numeric values"); 3196 3197 /* Set up the default value. */ 3198 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr); 3199 attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2); 3200} 3201 3202/* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of 3203 alternatives in the constraints. Assume all MATCH_OPERANDs have the same 3204 number of alternatives as this should be checked elsewhere. */ 3205 3206static int 3207count_alternatives (rtx exp) 3208{ 3209 int i, j, n; 3210 const char *fmt; 3211 3212 if (GET_CODE (exp) == MATCH_OPERAND) 3213 return n_comma_elts (XSTR (exp, 2)); 3214 3215 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp)); 3216 i < GET_RTX_LENGTH (GET_CODE (exp)); i++) 3217 switch (*fmt++) 3218 { 3219 case 'e': 3220 case 'u': 3221 n = count_alternatives (XEXP (exp, i)); 3222 if (n) 3223 return n; 3224 break; 3225 3226 case 'E': 3227 case 'V': 3228 if (XVEC (exp, i) != NULL) 3229 for (j = 0; j < XVECLEN (exp, i); j++) 3230 { 3231 n = count_alternatives (XVECEXP (exp, i, j)); 3232 if (n) 3233 return n; 3234 } 3235 } 3236 3237 return 0; 3238} 3239 3240/* Returns nonzero if the given expression contains an EQ_ATTR with the 3241 `alternative' attribute. */ 3242 3243static int 3244compares_alternatives_p (rtx exp) 3245{ 3246 int i, j; 3247 const char *fmt; 3248 3249 if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name) 3250 return 1; 3251 3252 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp)); 3253 i < GET_RTX_LENGTH (GET_CODE (exp)); i++) 3254 switch (*fmt++) 3255 { 3256 case 'e': 3257 case 'u': 3258 if (compares_alternatives_p (XEXP (exp, i))) 3259 return 1; 3260 break; 3261 3262 case 'E': 3263 for (j = 0; j < XVECLEN (exp, i); j++) 3264 if (compares_alternatives_p (XVECEXP (exp, i, j))) 3265 return 1; 3266 break; 3267 } 3268 3269 return 0; 3270} 3271 3272/* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */ 3273 3274static void 3275gen_insn (rtx exp, int lineno) 3276{ 3277 struct insn_def *id; 3278 3279 id = oballoc (struct insn_def); 3280 id->next = defs; 3281 defs = id; 3282 id->def = exp; 3283 id->filename = read_md_filename; 3284 id->lineno = lineno; 3285 3286 switch (GET_CODE (exp)) 3287 { 3288 case DEFINE_INSN: 3289 id->insn_code = insn_code_number; 3290 id->insn_index = insn_index_number; 3291 id->num_alternatives = count_alternatives (exp); 3292 if (id->num_alternatives == 0) 3293 id->num_alternatives = 1; 3294 id->vec_idx = 4; 3295 break; 3296 3297 case DEFINE_PEEPHOLE: 3298 id->insn_code = insn_code_number; 3299 id->insn_index = insn_index_number; 3300 id->num_alternatives = count_alternatives (exp); 3301 if (id->num_alternatives == 0) 3302 id->num_alternatives = 1; 3303 id->vec_idx = 3; 3304 break; 3305 3306 case DEFINE_ASM_ATTRIBUTES: 3307 id->insn_code = -1; 3308 id->insn_index = -1; 3309 id->num_alternatives = 1; 3310 id->vec_idx = 0; 3311 got_define_asm_attributes = 1; 3312 break; 3313 3314 default: 3315 gcc_unreachable (); 3316 } 3317} 3318 3319/* Process a DEFINE_DELAY. Validate the vector length, check if annul 3320 true or annul false is specified, and make a `struct delay_desc'. */ 3321 3322static void 3323gen_delay (rtx def, int lineno) 3324{ 3325 struct delay_desc *delay; 3326 int i; 3327 3328 if (XVECLEN (def, 1) % 3 != 0) 3329 { 3330 error_with_line (lineno, 3331 "number of elements in DEFINE_DELAY must" 3332 " be multiple of three"); 3333 return; 3334 } 3335 3336 for (i = 0; i < XVECLEN (def, 1); i += 3) 3337 { 3338 if (XVECEXP (def, 1, i + 1)) 3339 have_annul_true = 1; 3340 if (XVECEXP (def, 1, i + 2)) 3341 have_annul_false = 1; 3342 } 3343 3344 delay = oballoc (struct delay_desc); 3345 delay->def = def; 3346 delay->num = ++num_delays; 3347 delay->next = delays; 3348 delay->lineno = lineno; 3349 delays = delay; 3350} 3351 3352/* Names of attributes that could be possibly cached. */ 3353static const char *cached_attrs[32]; 3354/* Number of such attributes. */ 3355static int cached_attr_count; 3356/* Bitmasks of possibly cached attributes. */ 3357static unsigned int attrs_seen_once, attrs_seen_more_than_once; 3358static unsigned int attrs_to_cache; 3359static unsigned int attrs_cached_inside, attrs_cached_after; 3360 3361/* Finds non-const attributes that could be possibly cached. 3362 When create is TRUE, fills in cached_attrs array. 3363 Computes ATTRS_SEEN_ONCE and ATTRS_SEEN_MORE_THAN_ONCE 3364 bitmasks. */ 3365 3366static void 3367find_attrs_to_cache (rtx exp, bool create) 3368{ 3369 int i; 3370 const char *name; 3371 struct attr_desc *attr; 3372 3373 if (exp == NULL) 3374 return; 3375 3376 switch (GET_CODE (exp)) 3377 { 3378 case NOT: 3379 if (GET_CODE (XEXP (exp, 0)) == EQ_ATTR) 3380 find_attrs_to_cache (XEXP (exp, 0), create); 3381 return; 3382 3383 case EQ_ATTR: 3384 name = XSTR (exp, 0); 3385 if (name == alternative_name) 3386 return; 3387 for (i = 0; i < cached_attr_count; i++) 3388 if (name == cached_attrs[i]) 3389 { 3390 if ((attrs_seen_once & (1U << i)) != 0) 3391 attrs_seen_more_than_once |= (1U << i); 3392 else 3393 attrs_seen_once |= (1U << i); 3394 return; 3395 } 3396 if (!create) 3397 return; 3398 attr = find_attr (&name, 0); 3399 gcc_assert (attr); 3400 if (attr->is_const) 3401 return; 3402 if (cached_attr_count == 32) 3403 return; 3404 cached_attrs[cached_attr_count] = XSTR (exp, 0); 3405 attrs_seen_once |= (1U << cached_attr_count); 3406 cached_attr_count++; 3407 return; 3408 3409 case AND: 3410 case IOR: 3411 find_attrs_to_cache (XEXP (exp, 0), create); 3412 find_attrs_to_cache (XEXP (exp, 1), create); 3413 return; 3414 3415 case COND: 3416 for (i = 0; i < XVECLEN (exp, 0); i += 2) 3417 find_attrs_to_cache (XVECEXP (exp, 0, i), create); 3418 return; 3419 3420 default: 3421 return; 3422 } 3423} 3424 3425/* Given a piece of RTX, print a C expression to test its truth value to OUTF. 3426 We use AND and IOR both for logical and bit-wise operations, so 3427 interpret them as logical unless they are inside a comparison expression. */ 3428 3429/* Interpret AND/IOR as bit-wise operations instead of logical. */ 3430#define FLG_BITWISE 1 3431/* Set if cached attribute will be known initialized in else block after 3432 this condition. This is true for LHS of toplevel && and || and 3433 even for RHS of ||, but not for RHS of &&. */ 3434#define FLG_AFTER 2 3435/* Set if cached attribute will be known initialized in then block after 3436 this condition. This is true for LHS of toplevel && and || and 3437 even for RHS of &&, but not for RHS of ||. */ 3438#define FLG_INSIDE 4 3439/* Cleared when an operand of &&. */ 3440#define FLG_OUTSIDE_AND 8 3441 3442static unsigned int 3443write_test_expr (FILE *outf, rtx exp, unsigned int attrs_cached, int flags) 3444{ 3445 int comparison_operator = 0; 3446 RTX_CODE code; 3447 struct attr_desc *attr; 3448 3449 /* In order not to worry about operator precedence, surround our part of 3450 the expression with parentheses. */ 3451 3452 fprintf (outf, "("); 3453 code = GET_CODE (exp); 3454 switch (code) 3455 { 3456 /* Binary operators. */ 3457 case GEU: case GTU: 3458 case LEU: case LTU: 3459 fprintf (outf, "(unsigned) "); 3460 /* Fall through. */ 3461 3462 case EQ: case NE: 3463 case GE: case GT: 3464 case LE: case LT: 3465 comparison_operator = FLG_BITWISE; 3466 3467 case PLUS: case MINUS: case MULT: case DIV: case MOD: 3468 case AND: case IOR: case XOR: 3469 case ASHIFT: case LSHIFTRT: case ASHIFTRT: 3470 if ((code != AND && code != IOR) || (flags & FLG_BITWISE)) 3471 { 3472 flags &= ~(FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND); 3473 write_test_expr (outf, XEXP (exp, 0), attrs_cached, 3474 flags | comparison_operator); 3475 } 3476 else 3477 { 3478 if (code == AND) 3479 flags &= ~FLG_OUTSIDE_AND; 3480 if (GET_CODE (XEXP (exp, 0)) == code 3481 || GET_CODE (XEXP (exp, 0)) == EQ_ATTR 3482 || (GET_CODE (XEXP (exp, 0)) == NOT 3483 && GET_CODE (XEXP (XEXP (exp, 0), 0)) == EQ_ATTR)) 3484 attrs_cached 3485 = write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags); 3486 else 3487 write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags); 3488 } 3489 switch (code) 3490 { 3491 case EQ: 3492 fprintf (outf, " == "); 3493 break; 3494 case NE: 3495 fprintf (outf, " != "); 3496 break; 3497 case GE: 3498 fprintf (outf, " >= "); 3499 break; 3500 case GT: 3501 fprintf (outf, " > "); 3502 break; 3503 case GEU: 3504 fprintf (outf, " >= (unsigned) "); 3505 break; 3506 case GTU: 3507 fprintf (outf, " > (unsigned) "); 3508 break; 3509 case LE: 3510 fprintf (outf, " <= "); 3511 break; 3512 case LT: 3513 fprintf (outf, " < "); 3514 break; 3515 case LEU: 3516 fprintf (outf, " <= (unsigned) "); 3517 break; 3518 case LTU: 3519 fprintf (outf, " < (unsigned) "); 3520 break; 3521 case PLUS: 3522 fprintf (outf, " + "); 3523 break; 3524 case MINUS: 3525 fprintf (outf, " - "); 3526 break; 3527 case MULT: 3528 fprintf (outf, " * "); 3529 break; 3530 case DIV: 3531 fprintf (outf, " / "); 3532 break; 3533 case MOD: 3534 fprintf (outf, " %% "); 3535 break; 3536 case AND: 3537 if (flags & FLG_BITWISE) 3538 fprintf (outf, " & "); 3539 else 3540 fprintf (outf, " && "); 3541 break; 3542 case IOR: 3543 if (flags & FLG_BITWISE) 3544 fprintf (outf, " | "); 3545 else 3546 fprintf (outf, " || "); 3547 break; 3548 case XOR: 3549 fprintf (outf, " ^ "); 3550 break; 3551 case ASHIFT: 3552 fprintf (outf, " << "); 3553 break; 3554 case LSHIFTRT: 3555 case ASHIFTRT: 3556 fprintf (outf, " >> "); 3557 break; 3558 default: 3559 gcc_unreachable (); 3560 } 3561 3562 if (code == AND) 3563 { 3564 /* For if (something && (cached_x = get_attr_x (insn)) == X) 3565 cached_x is only known to be initialized in then block. */ 3566 flags &= ~FLG_AFTER; 3567 } 3568 else if (code == IOR) 3569 { 3570 if (flags & FLG_OUTSIDE_AND) 3571 /* For if (something || (cached_x = get_attr_x (insn)) == X) 3572 cached_x is only known to be initialized in else block 3573 and else if conditions. */ 3574 flags &= ~FLG_INSIDE; 3575 else 3576 /* For if ((something || (cached_x = get_attr_x (insn)) == X) 3577 && something_else) 3578 cached_x is not know to be initialized anywhere. */ 3579 flags &= ~(FLG_AFTER | FLG_INSIDE); 3580 } 3581 if ((code == AND || code == IOR) 3582 && (GET_CODE (XEXP (exp, 1)) == code 3583 || GET_CODE (XEXP (exp, 1)) == EQ_ATTR 3584 || (GET_CODE (XEXP (exp, 1)) == NOT 3585 && GET_CODE (XEXP (XEXP (exp, 1), 0)) == EQ_ATTR))) 3586 attrs_cached 3587 = write_test_expr (outf, XEXP (exp, 1), attrs_cached, flags); 3588 else 3589 write_test_expr (outf, XEXP (exp, 1), attrs_cached, 3590 flags | comparison_operator); 3591 break; 3592 3593 case NOT: 3594 /* Special-case (not (eq_attrq "alternative" "x")) */ 3595 if (! (flags & FLG_BITWISE) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR) 3596 { 3597 if (XSTR (XEXP (exp, 0), 0) == alternative_name) 3598 { 3599 fprintf (outf, "which_alternative != %s", 3600 XSTR (XEXP (exp, 0), 1)); 3601 break; 3602 } 3603 3604 fprintf (outf, "! "); 3605 attrs_cached = 3606 write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags); 3607 break; 3608 } 3609 3610 /* Otherwise, fall through to normal unary operator. */ 3611 3612 /* Unary operators. */ 3613 case ABS: case NEG: 3614 switch (code) 3615 { 3616 case NOT: 3617 if (flags & FLG_BITWISE) 3618 fprintf (outf, "~ "); 3619 else 3620 fprintf (outf, "! "); 3621 break; 3622 case ABS: 3623 fprintf (outf, "abs "); 3624 break; 3625 case NEG: 3626 fprintf (outf, "-"); 3627 break; 3628 default: 3629 gcc_unreachable (); 3630 } 3631 3632 flags &= ~(FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND); 3633 write_test_expr (outf, XEXP (exp, 0), attrs_cached, flags); 3634 break; 3635 3636 case EQ_ATTR_ALT: 3637 { 3638 int set = XINT (exp, 0), bit = 0; 3639 3640 if (flags & FLG_BITWISE) 3641 fatal ("EQ_ATTR_ALT not valid inside comparison"); 3642 3643 if (!set) 3644 fatal ("Empty EQ_ATTR_ALT should be optimized out"); 3645 3646 if (!(set & (set - 1))) 3647 { 3648 if (!(set & 0xffff)) 3649 { 3650 bit += 16; 3651 set >>= 16; 3652 } 3653 if (!(set & 0xff)) 3654 { 3655 bit += 8; 3656 set >>= 8; 3657 } 3658 if (!(set & 0xf)) 3659 { 3660 bit += 4; 3661 set >>= 4; 3662 } 3663 if (!(set & 0x3)) 3664 { 3665 bit += 2; 3666 set >>= 2; 3667 } 3668 if (!(set & 1)) 3669 bit++; 3670 3671 fprintf (outf, "which_alternative %s= %d", 3672 XINT (exp, 1) ? "!" : "=", bit); 3673 } 3674 else 3675 { 3676 fprintf (outf, "%s((1 << which_alternative) & %#x)", 3677 XINT (exp, 1) ? "!" : "", set); 3678 } 3679 } 3680 break; 3681 3682 /* Comparison test of an attribute with a value. Most of these will 3683 have been removed by optimization. Handle "alternative" 3684 specially and give error if EQ_ATTR present inside a comparison. */ 3685 case EQ_ATTR: 3686 if (flags & FLG_BITWISE) 3687 fatal ("EQ_ATTR not valid inside comparison"); 3688 3689 if (XSTR (exp, 0) == alternative_name) 3690 { 3691 fprintf (outf, "which_alternative == %s", XSTR (exp, 1)); 3692 break; 3693 } 3694 3695 attr = find_attr (&XSTR (exp, 0), 0); 3696 gcc_assert (attr); 3697 3698 /* Now is the time to expand the value of a constant attribute. */ 3699 if (attr->is_const) 3700 { 3701 write_test_expr (outf, 3702 evaluate_eq_attr (exp, attr, 3703 attr->default_val->value, 3704 -2, -2), 3705 attrs_cached, 0); 3706 } 3707 else 3708 { 3709 int i; 3710 for (i = 0; i < cached_attr_count; i++) 3711 if (attr->name == cached_attrs[i]) 3712 break; 3713 if (i < cached_attr_count && (attrs_cached & (1U << i)) != 0) 3714 fprintf (outf, "cached_%s", attr->name); 3715 else if (i < cached_attr_count && (attrs_to_cache & (1U << i)) != 0) 3716 { 3717 fprintf (outf, "(cached_%s = get_attr_%s (insn))", 3718 attr->name, attr->name); 3719 if (flags & FLG_AFTER) 3720 attrs_cached_after |= (1U << i); 3721 if (flags & FLG_INSIDE) 3722 attrs_cached_inside |= (1U << i); 3723 attrs_cached |= (1U << i); 3724 } 3725 else 3726 fprintf (outf, "get_attr_%s (insn)", attr->name); 3727 fprintf (outf, " == "); 3728 write_attr_valueq (outf, attr, XSTR (exp, 1)); 3729 } 3730 break; 3731 3732 /* Comparison test of flags for define_delays. */ 3733 case ATTR_FLAG: 3734 if (flags & FLG_BITWISE) 3735 fatal ("ATTR_FLAG not valid inside comparison"); 3736 fprintf (outf, "(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0)); 3737 break; 3738 3739 /* See if an operand matches a predicate. */ 3740 case MATCH_OPERAND: 3741 /* If only a mode is given, just ensure the mode matches the operand. 3742 If neither a mode nor predicate is given, error. */ 3743 if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0') 3744 { 3745 if (GET_MODE (exp) == VOIDmode) 3746 fatal ("null MATCH_OPERAND specified as test"); 3747 else 3748 fprintf (outf, "GET_MODE (operands[%d]) == %smode", 3749 XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp))); 3750 } 3751 else 3752 fprintf (outf, "%s (operands[%d], %smode)", 3753 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp))); 3754 break; 3755 3756 /* Constant integer. */ 3757 case CONST_INT: 3758 fprintf (outf, HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0)); 3759 break; 3760 3761 case MATCH_TEST: 3762 fprint_c_condition (outf, XSTR (exp, 0)); 3763 if (flags & FLG_BITWISE) 3764 fprintf (outf, " != 0"); 3765 break; 3766 3767 /* A random C expression. */ 3768 case SYMBOL_REF: 3769 fprint_c_condition (outf, XSTR (exp, 0)); 3770 break; 3771 3772 /* The address of the branch target. */ 3773 case MATCH_DUP: 3774 fprintf (outf, 3775 "INSN_ADDRESSES_SET_P () ? INSN_ADDRESSES (INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])) : 0", 3776 XINT (exp, 0), XINT (exp, 0), XINT (exp, 0)); 3777 break; 3778 3779 case PC: 3780 /* The address of the current insn. We implement this actually as the 3781 address of the current insn for backward branches, but the last 3782 address of the next insn for forward branches, and both with 3783 adjustments that account for the worst-case possible stretching of 3784 intervening alignments between this insn and its destination. */ 3785 fprintf (outf, "insn_current_reference_address (insn)"); 3786 break; 3787 3788 case CONST_STRING: 3789 fprintf (outf, "%s", XSTR (exp, 0)); 3790 break; 3791 3792 case IF_THEN_ELSE: 3793 write_test_expr (outf, XEXP (exp, 0), attrs_cached, 0); 3794 fprintf (outf, " ? "); 3795 write_test_expr (outf, XEXP (exp, 1), attrs_cached, FLG_BITWISE); 3796 fprintf (outf, " : "); 3797 write_test_expr (outf, XEXP (exp, 2), attrs_cached, FLG_BITWISE); 3798 break; 3799 3800 default: 3801 fatal ("bad RTX code `%s' in attribute calculation\n", 3802 GET_RTX_NAME (code)); 3803 } 3804 3805 fprintf (outf, ")"); 3806 return attrs_cached; 3807} 3808 3809/* Given an attribute value, return the maximum CONST_STRING argument 3810 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */ 3811 3812static int 3813max_attr_value (rtx exp, int *unknownp) 3814{ 3815 int current_max; 3816 int i, n; 3817 3818 switch (GET_CODE (exp)) 3819 { 3820 case CONST_STRING: 3821 current_max = atoi (XSTR (exp, 0)); 3822 break; 3823 3824 case COND: 3825 current_max = max_attr_value (XEXP (exp, 1), unknownp); 3826 for (i = 0; i < XVECLEN (exp, 0); i += 2) 3827 { 3828 n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp); 3829 if (n > current_max) 3830 current_max = n; 3831 } 3832 break; 3833 3834 case IF_THEN_ELSE: 3835 current_max = max_attr_value (XEXP (exp, 1), unknownp); 3836 n = max_attr_value (XEXP (exp, 2), unknownp); 3837 if (n > current_max) 3838 current_max = n; 3839 break; 3840 3841 default: 3842 *unknownp = 1; 3843 current_max = INT_MAX; 3844 break; 3845 } 3846 3847 return current_max; 3848} 3849 3850/* Given an attribute value, return the minimum CONST_STRING argument 3851 encountered. Set *UNKNOWNP and return 0 if the value is unknown. */ 3852 3853static int 3854min_attr_value (rtx exp, int *unknownp) 3855{ 3856 int current_min; 3857 int i, n; 3858 3859 switch (GET_CODE (exp)) 3860 { 3861 case CONST_STRING: 3862 current_min = atoi (XSTR (exp, 0)); 3863 break; 3864 3865 case COND: 3866 current_min = min_attr_value (XEXP (exp, 1), unknownp); 3867 for (i = 0; i < XVECLEN (exp, 0); i += 2) 3868 { 3869 n = min_attr_value (XVECEXP (exp, 0, i + 1), unknownp); 3870 if (n < current_min) 3871 current_min = n; 3872 } 3873 break; 3874 3875 case IF_THEN_ELSE: 3876 current_min = min_attr_value (XEXP (exp, 1), unknownp); 3877 n = min_attr_value (XEXP (exp, 2), unknownp); 3878 if (n < current_min) 3879 current_min = n; 3880 break; 3881 3882 default: 3883 *unknownp = 1; 3884 current_min = INT_MAX; 3885 break; 3886 } 3887 3888 return current_min; 3889} 3890 3891/* Given an attribute value, return the result of ORing together all 3892 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1 3893 if the numeric value is not known. */ 3894 3895static int 3896or_attr_value (rtx exp, int *unknownp) 3897{ 3898 int current_or; 3899 int i; 3900 3901 switch (GET_CODE (exp)) 3902 { 3903 case CONST_STRING: 3904 current_or = atoi (XSTR (exp, 0)); 3905 break; 3906 3907 case COND: 3908 current_or = or_attr_value (XEXP (exp, 1), unknownp); 3909 for (i = 0; i < XVECLEN (exp, 0); i += 2) 3910 current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp); 3911 break; 3912 3913 case IF_THEN_ELSE: 3914 current_or = or_attr_value (XEXP (exp, 1), unknownp); 3915 current_or |= or_attr_value (XEXP (exp, 2), unknownp); 3916 break; 3917 3918 default: 3919 *unknownp = 1; 3920 current_or = -1; 3921 break; 3922 } 3923 3924 return current_or; 3925} 3926 3927/* Scan an attribute value, possibly a conditional, and record what actions 3928 will be required to do any conditional tests in it. 3929 3930 Specifically, set 3931 `must_extract' if we need to extract the insn operands 3932 `must_constrain' if we must compute `which_alternative' 3933 `address_used' if an address expression was used 3934 `length_used' if an (eq_attr "length" ...) was used 3935 */ 3936 3937static void 3938walk_attr_value (rtx exp) 3939{ 3940 int i, j; 3941 const char *fmt; 3942 RTX_CODE code; 3943 3944 if (exp == NULL) 3945 return; 3946 3947 code = GET_CODE (exp); 3948 switch (code) 3949 { 3950 case SYMBOL_REF: 3951 if (! ATTR_IND_SIMPLIFIED_P (exp)) 3952 /* Since this is an arbitrary expression, it can look at anything. 3953 However, constant expressions do not depend on any particular 3954 insn. */ 3955 must_extract = must_constrain = 1; 3956 return; 3957 3958 case MATCH_OPERAND: 3959 must_extract = 1; 3960 return; 3961 3962 case MATCH_TEST: 3963 case EQ_ATTR_ALT: 3964 must_extract = must_constrain = 1; 3965 break; 3966 3967 case EQ_ATTR: 3968 if (XSTR (exp, 0) == alternative_name) 3969 must_extract = must_constrain = 1; 3970 else if (strcmp_check (XSTR (exp, 0), length_str) == 0) 3971 length_used = 1; 3972 return; 3973 3974 case MATCH_DUP: 3975 must_extract = 1; 3976 address_used = 1; 3977 return; 3978 3979 case PC: 3980 address_used = 1; 3981 return; 3982 3983 case ATTR_FLAG: 3984 return; 3985 3986 default: 3987 break; 3988 } 3989 3990 for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++) 3991 switch (*fmt++) 3992 { 3993 case 'e': 3994 case 'u': 3995 walk_attr_value (XEXP (exp, i)); 3996 break; 3997 3998 case 'E': 3999 if (XVEC (exp, i) != NULL) 4000 for (j = 0; j < XVECLEN (exp, i); j++) 4001 walk_attr_value (XVECEXP (exp, i, j)); 4002 break; 4003 } 4004} 4005 4006/* Write out a function to obtain the attribute for a given INSN. */ 4007 4008static void 4009write_attr_get (FILE *outf, struct attr_desc *attr) 4010{ 4011 struct attr_value *av, *common_av; 4012 int i, j; 4013 4014 /* Find the most used attribute value. Handle that as the `default' of the 4015 switch we will generate. */ 4016 common_av = find_most_used (attr); 4017 4018 /* Write out start of function, then all values with explicit `case' lines, 4019 then a `default', then the value with the most uses. */ 4020 if (attr->enum_name) 4021 fprintf (outf, "enum %s\n", attr->enum_name); 4022 else if (!attr->is_numeric) 4023 fprintf (outf, "enum attr_%s\n", attr->name); 4024 else 4025 fprintf (outf, "int\n"); 4026 4027 /* If the attribute name starts with a star, the remainder is the name of 4028 the subroutine to use, instead of `get_attr_...'. */ 4029 if (attr->name[0] == '*') 4030 fprintf (outf, "%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", &attr->name[1]); 4031 else if (attr->is_const == 0) 4032 fprintf (outf, "get_attr_%s (rtx_insn *insn ATTRIBUTE_UNUSED)\n", attr->name); 4033 else 4034 { 4035 fprintf (outf, "get_attr_%s (void)\n", attr->name); 4036 fprintf (outf, "{\n"); 4037 4038 for (av = attr->first_value; av; av = av->next) 4039 if (av->num_insns == 1) 4040 write_attr_set (outf, attr, 2, av->value, "return", ";", 4041 true_rtx, av->first_insn->def->insn_code, 4042 av->first_insn->def->insn_index, 0); 4043 else if (av->num_insns != 0) 4044 write_attr_set (outf, attr, 2, av->value, "return", ";", 4045 true_rtx, -2, 0, 0); 4046 4047 fprintf (outf, "}\n\n"); 4048 return; 4049 } 4050 4051 fprintf (outf, "{\n"); 4052 4053 /* Find attributes that are worth caching in the conditions. */ 4054 cached_attr_count = 0; 4055 attrs_seen_more_than_once = 0; 4056 for (av = attr->first_value; av; av = av->next) 4057 { 4058 attrs_seen_once = 0; 4059 find_attrs_to_cache (av->value, true); 4060 } 4061 /* Remove those that aren't worth caching from the array. */ 4062 for (i = 0, j = 0; i < cached_attr_count; i++) 4063 if ((attrs_seen_more_than_once & (1U << i)) != 0) 4064 { 4065 const char *name = cached_attrs[i]; 4066 struct attr_desc *cached_attr; 4067 if (i != j) 4068 cached_attrs[j] = name; 4069 cached_attr = find_attr (&name, 0); 4070 gcc_assert (cached_attr && cached_attr->is_const == 0); 4071 if (cached_attr->enum_name) 4072 fprintf (outf, " enum %s", cached_attr->enum_name); 4073 else if (!cached_attr->is_numeric) 4074 fprintf (outf, " enum attr_%s", cached_attr->name); 4075 else 4076 fprintf (outf, " int"); 4077 fprintf (outf, " cached_%s ATTRIBUTE_UNUSED;\n", name); 4078 j++; 4079 } 4080 cached_attr_count = j; 4081 if (cached_attr_count) 4082 fprintf (outf, "\n"); 4083 4084 fprintf (outf, " switch (recog_memoized (insn))\n"); 4085 fprintf (outf, " {\n"); 4086 4087 for (av = attr->first_value; av; av = av->next) 4088 if (av != common_av) 4089 write_attr_case (outf, attr, av, 1, "return", ";", 4, true_rtx); 4090 4091 write_attr_case (outf, attr, common_av, 0, "return", ";", 4, true_rtx); 4092 fprintf (outf, " }\n}\n\n"); 4093 cached_attr_count = 0; 4094} 4095 4096/* Given an AND tree of known true terms (because we are inside an `if' with 4097 that as the condition or are in an `else' clause) and an expression, 4098 replace any known true terms with TRUE. Use `simplify_and_tree' to do 4099 the bulk of the work. */ 4100 4101static rtx 4102eliminate_known_true (rtx known_true, rtx exp, int insn_code, int insn_index) 4103{ 4104 rtx term; 4105 4106 known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index); 4107 4108 if (GET_CODE (known_true) == AND) 4109 { 4110 exp = eliminate_known_true (XEXP (known_true, 0), exp, 4111 insn_code, insn_index); 4112 exp = eliminate_known_true (XEXP (known_true, 1), exp, 4113 insn_code, insn_index); 4114 } 4115 else 4116 { 4117 term = known_true; 4118 exp = simplify_and_tree (exp, &term, insn_code, insn_index); 4119 } 4120 4121 return exp; 4122} 4123 4124/* Write out a series of tests and assignment statements to perform tests and 4125 sets of an attribute value. We are passed an indentation amount and prefix 4126 and suffix strings to write around each attribute value (e.g., "return" 4127 and ";"). */ 4128 4129static void 4130write_attr_set (FILE *outf, struct attr_desc *attr, int indent, rtx value, 4131 const char *prefix, const char *suffix, rtx known_true, 4132 int insn_code, int insn_index, unsigned int attrs_cached) 4133{ 4134 if (GET_CODE (value) == COND) 4135 { 4136 /* Assume the default value will be the default of the COND unless we 4137 find an always true expression. */ 4138 rtx default_val = XEXP (value, 1); 4139 rtx our_known_true = known_true; 4140 rtx newexp; 4141 int first_if = 1; 4142 int i; 4143 4144 if (cached_attr_count) 4145 { 4146 attrs_seen_once = 0; 4147 attrs_seen_more_than_once = 0; 4148 for (i = 0; i < XVECLEN (value, 0); i += 2) 4149 find_attrs_to_cache (XVECEXP (value, 0, i), false); 4150 attrs_to_cache |= attrs_seen_more_than_once; 4151 } 4152 4153 for (i = 0; i < XVECLEN (value, 0); i += 2) 4154 { 4155 rtx testexp; 4156 rtx inner_true; 4157 4158 /* Reset our_known_true after some time to not accumulate 4159 too much cruft (slowing down genattrtab). */ 4160 if ((i & 31) == 0) 4161 our_known_true = known_true; 4162 testexp = eliminate_known_true (our_known_true, 4163 XVECEXP (value, 0, i), 4164 insn_code, insn_index); 4165 newexp = attr_rtx (NOT, testexp); 4166 newexp = insert_right_side (AND, our_known_true, newexp, 4167 insn_code, insn_index); 4168 4169 /* If the test expression is always true or if the next `known_true' 4170 expression is always false, this is the last case, so break 4171 out and let this value be the `else' case. */ 4172 if (testexp == true_rtx || newexp == false_rtx) 4173 { 4174 default_val = XVECEXP (value, 0, i + 1); 4175 break; 4176 } 4177 4178 /* Compute the expression to pass to our recursive call as being 4179 known true. */ 4180 inner_true = insert_right_side (AND, our_known_true, 4181 testexp, insn_code, insn_index); 4182 4183 /* If this is always false, skip it. */ 4184 if (inner_true == false_rtx) 4185 continue; 4186 4187 attrs_cached_inside = attrs_cached; 4188 attrs_cached_after = attrs_cached; 4189 write_indent (outf, indent); 4190 fprintf (outf, "%sif ", first_if ? "" : "else "); 4191 first_if = 0; 4192 write_test_expr (outf, testexp, attrs_cached, 4193 (FLG_AFTER | FLG_INSIDE | FLG_OUTSIDE_AND)); 4194 attrs_cached = attrs_cached_after; 4195 fprintf (outf, "\n"); 4196 write_indent (outf, indent + 2); 4197 fprintf (outf, "{\n"); 4198 4199 write_attr_set (outf, attr, indent + 4, 4200 XVECEXP (value, 0, i + 1), prefix, suffix, 4201 inner_true, insn_code, insn_index, 4202 attrs_cached_inside); 4203 write_indent (outf, indent + 2); 4204 fprintf (outf, "}\n"); 4205 our_known_true = newexp; 4206 } 4207 4208 if (! first_if) 4209 { 4210 write_indent (outf, indent); 4211 fprintf (outf, "else\n"); 4212 write_indent (outf, indent + 2); 4213 fprintf (outf, "{\n"); 4214 } 4215 4216 write_attr_set (outf, attr, first_if ? indent : indent + 4, default_val, 4217 prefix, suffix, our_known_true, insn_code, insn_index, 4218 attrs_cached); 4219 4220 if (! first_if) 4221 { 4222 write_indent (outf, indent + 2); 4223 fprintf (outf, "}\n"); 4224 } 4225 } 4226 else 4227 { 4228 write_indent (outf, indent); 4229 fprintf (outf, "%s ", prefix); 4230 write_attr_value (outf, attr, value); 4231 fprintf (outf, "%s\n", suffix); 4232 } 4233} 4234 4235/* Write a series of case statements for every instruction in list IE. 4236 INDENT is the amount of indentation to write before each case. */ 4237 4238static void 4239write_insn_cases (FILE *outf, struct insn_ent *ie, int indent) 4240{ 4241 for (; ie != 0; ie = ie->next) 4242 if (ie->def->insn_code != -1) 4243 { 4244 write_indent (outf, indent); 4245 if (GET_CODE (ie->def->def) == DEFINE_PEEPHOLE) 4246 fprintf (outf, "case %d: /* define_peephole, line %d */\n", 4247 ie->def->insn_code, ie->def->lineno); 4248 else 4249 fprintf (outf, "case %d: /* %s */\n", 4250 ie->def->insn_code, XSTR (ie->def->def, 0)); 4251 } 4252} 4253 4254/* Write out the computation for one attribute value. */ 4255 4256static void 4257write_attr_case (FILE *outf, struct attr_desc *attr, struct attr_value *av, 4258 int write_case_lines, const char *prefix, const char *suffix, 4259 int indent, rtx known_true) 4260{ 4261 if (av->num_insns == 0) 4262 return; 4263 4264 if (av->has_asm_insn) 4265 { 4266 write_indent (outf, indent); 4267 fprintf (outf, "case -1:\n"); 4268 write_indent (outf, indent + 2); 4269 fprintf (outf, "if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n"); 4270 write_indent (outf, indent + 2); 4271 fprintf (outf, " && asm_noperands (PATTERN (insn)) < 0)\n"); 4272 write_indent (outf, indent + 2); 4273 fprintf (outf, " fatal_insn_not_found (insn);\n"); 4274 } 4275 4276 if (write_case_lines) 4277 write_insn_cases (outf, av->first_insn, indent); 4278 else 4279 { 4280 write_indent (outf, indent); 4281 fprintf (outf, "default:\n"); 4282 } 4283 4284 /* See what we have to do to output this value. */ 4285 must_extract = must_constrain = address_used = 0; 4286 walk_attr_value (av->value); 4287 4288 if (must_constrain) 4289 { 4290 write_indent (outf, indent + 2); 4291 fprintf (outf, "extract_constrain_insn_cached (insn);\n"); 4292 } 4293 else if (must_extract) 4294 { 4295 write_indent (outf, indent + 2); 4296 fprintf (outf, "extract_insn_cached (insn);\n"); 4297 } 4298 4299 attrs_to_cache = 0; 4300 if (av->num_insns == 1) 4301 write_attr_set (outf, attr, indent + 2, av->value, prefix, suffix, 4302 known_true, av->first_insn->def->insn_code, 4303 av->first_insn->def->insn_index, 0); 4304 else 4305 write_attr_set (outf, attr, indent + 2, av->value, prefix, suffix, 4306 known_true, -2, 0, 0); 4307 4308 if (strncmp (prefix, "return", 6)) 4309 { 4310 write_indent (outf, indent + 2); 4311 fprintf (outf, "break;\n"); 4312 } 4313 fprintf (outf, "\n"); 4314} 4315 4316/* Utilities to write in various forms. */ 4317 4318static void 4319write_attr_valueq (FILE *outf, struct attr_desc *attr, const char *s) 4320{ 4321 if (attr->is_numeric) 4322 { 4323 int num = atoi (s); 4324 4325 fprintf (outf, "%d", num); 4326 4327 if (num > 9 || num < 0) 4328 fprintf (outf, " /* %#x */", num); 4329 } 4330 else 4331 { 4332 write_upcase (outf, attr->enum_name ? attr->enum_name : attr->name); 4333 fprintf (outf, "_"); 4334 write_upcase (outf, s); 4335 } 4336} 4337 4338static void 4339write_attr_value (FILE *outf, struct attr_desc *attr, rtx value) 4340{ 4341 int op; 4342 4343 switch (GET_CODE (value)) 4344 { 4345 case CONST_STRING: 4346 write_attr_valueq (outf, attr, XSTR (value, 0)); 4347 break; 4348 4349 case CONST_INT: 4350 fprintf (outf, HOST_WIDE_INT_PRINT_DEC, INTVAL (value)); 4351 break; 4352 4353 case SYMBOL_REF: 4354 fprint_c_condition (outf, XSTR (value, 0)); 4355 break; 4356 4357 case ATTR: 4358 { 4359 struct attr_desc *attr2 = find_attr (&XSTR (value, 0), 0); 4360 if (attr->enum_name) 4361 fprintf (outf, "(enum %s)", attr->enum_name); 4362 else if (!attr->is_numeric) 4363 fprintf (outf, "(enum attr_%s)", attr->name); 4364 else if (!attr2->is_numeric) 4365 fprintf (outf, "(int)"); 4366 4367 fprintf (outf, "get_attr_%s (%s)", attr2->name, 4368 (attr2->is_const ? "" : "insn")); 4369 } 4370 break; 4371 4372 case PLUS: 4373 op = '+'; 4374 goto do_operator; 4375 case MINUS: 4376 op = '-'; 4377 goto do_operator; 4378 case MULT: 4379 op = '*'; 4380 goto do_operator; 4381 case DIV: 4382 op = '/'; 4383 goto do_operator; 4384 case MOD: 4385 op = '%'; 4386 goto do_operator; 4387 4388 do_operator: 4389 write_attr_value (outf, attr, XEXP (value, 0)); 4390 fputc (' ', outf); 4391 fputc (op, outf); 4392 fputc (' ', outf); 4393 write_attr_value (outf, attr, XEXP (value, 1)); 4394 break; 4395 4396 default: 4397 gcc_unreachable (); 4398 } 4399} 4400 4401static void 4402write_upcase (FILE *outf, const char *str) 4403{ 4404 while (*str) 4405 { 4406 /* The argument of TOUPPER should not have side effects. */ 4407 fputc (TOUPPER (*str), outf); 4408 str++; 4409 } 4410} 4411 4412static void 4413write_indent (FILE *outf, int indent) 4414{ 4415 for (; indent > 8; indent -= 8) 4416 fprintf (outf, "\t"); 4417 4418 for (; indent; indent--) 4419 fprintf (outf, " "); 4420} 4421 4422/* Write a subroutine that is given an insn that requires a delay slot, a 4423 delay slot ordinal, and a candidate insn. It returns nonzero if the 4424 candidate can be placed in the specified delay slot of the insn. 4425 4426 We can write as many as three subroutines. `eligible_for_delay' 4427 handles normal delay slots, `eligible_for_annul_true' indicates that 4428 the specified insn can be annulled if the branch is true, and likewise 4429 for `eligible_for_annul_false'. 4430 4431 KIND is a string distinguishing these three cases ("delay", "annul_true", 4432 or "annul_false"). */ 4433 4434static void 4435write_eligible_delay (FILE *outf, const char *kind) 4436{ 4437 struct delay_desc *delay; 4438 int max_slots; 4439 char str[50]; 4440 const char *pstr; 4441 struct attr_desc *attr; 4442 struct attr_value *av, *common_av; 4443 int i; 4444 4445 /* Compute the maximum number of delay slots required. We use the delay 4446 ordinal times this number plus one, plus the slot number as an index into 4447 the appropriate predicate to test. */ 4448 4449 for (delay = delays, max_slots = 0; delay; delay = delay->next) 4450 if (XVECLEN (delay->def, 1) / 3 > max_slots) 4451 max_slots = XVECLEN (delay->def, 1) / 3; 4452 4453 /* Write function prelude. */ 4454 4455 fprintf (outf, "int\n"); 4456 fprintf (outf, "eligible_for_%s (rtx_insn *delay_insn ATTRIBUTE_UNUSED, int slot, \n" 4457 " rtx_insn *candidate_insn, int flags ATTRIBUTE_UNUSED)\n", 4458 kind); 4459 fprintf (outf, "{\n"); 4460 fprintf (outf, " rtx_insn *insn;\n"); 4461 fprintf (outf, "\n"); 4462 fprintf (outf, " gcc_assert (slot < %d);\n", max_slots); 4463 fprintf (outf, "\n"); 4464 /* Allow dbr_schedule to pass labels, etc. This can happen if try_split 4465 converts a compound instruction into a loop. */ 4466 fprintf (outf, " if (!INSN_P (candidate_insn))\n"); 4467 fprintf (outf, " return 0;\n"); 4468 fprintf (outf, "\n"); 4469 4470 /* If more than one delay type, find out which type the delay insn is. */ 4471 4472 if (num_delays > 1) 4473 { 4474 attr = find_attr (&delay_type_str, 0); 4475 gcc_assert (attr); 4476 common_av = find_most_used (attr); 4477 4478 fprintf (outf, " insn = delay_insn;\n"); 4479 fprintf (outf, " switch (recog_memoized (insn))\n"); 4480 fprintf (outf, " {\n"); 4481 4482 sprintf (str, " * %d;\n break;", max_slots); 4483 for (av = attr->first_value; av; av = av->next) 4484 if (av != common_av) 4485 write_attr_case (outf, attr, av, 1, "slot +=", str, 4, true_rtx); 4486 4487 write_attr_case (outf, attr, common_av, 0, "slot +=", str, 4, true_rtx); 4488 fprintf (outf, " }\n\n"); 4489 4490 /* Ensure matched. Otherwise, shouldn't have been called. */ 4491 fprintf (outf, " gcc_assert (slot >= %d);\n\n", max_slots); 4492 } 4493 4494 /* If just one type of delay slot, write simple switch. */ 4495 if (num_delays == 1 && max_slots == 1) 4496 { 4497 fprintf (outf, " insn = candidate_insn;\n"); 4498 fprintf (outf, " switch (recog_memoized (insn))\n"); 4499 fprintf (outf, " {\n"); 4500 4501 attr = find_attr (&delay_1_0_str, 0); 4502 gcc_assert (attr); 4503 common_av = find_most_used (attr); 4504 4505 for (av = attr->first_value; av; av = av->next) 4506 if (av != common_av) 4507 write_attr_case (outf, attr, av, 1, "return", ";", 4, true_rtx); 4508 4509 write_attr_case (outf, attr, common_av, 0, "return", ";", 4, true_rtx); 4510 fprintf (outf, " }\n"); 4511 } 4512 4513 else 4514 { 4515 /* Write a nested CASE. The first indicates which condition we need to 4516 test, and the inner CASE tests the condition. */ 4517 fprintf (outf, " insn = candidate_insn;\n"); 4518 fprintf (outf, " switch (slot)\n"); 4519 fprintf (outf, " {\n"); 4520 4521 for (delay = delays; delay; delay = delay->next) 4522 for (i = 0; i < XVECLEN (delay->def, 1); i += 3) 4523 { 4524 fprintf (outf, " case %d:\n", 4525 (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots)); 4526 fprintf (outf, " switch (recog_memoized (insn))\n"); 4527 fprintf (outf, "\t{\n"); 4528 4529 sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3); 4530 pstr = str; 4531 attr = find_attr (&pstr, 0); 4532 gcc_assert (attr); 4533 common_av = find_most_used (attr); 4534 4535 for (av = attr->first_value; av; av = av->next) 4536 if (av != common_av) 4537 write_attr_case (outf, attr, av, 1, "return", ";", 8, true_rtx); 4538 4539 write_attr_case (outf, attr, common_av, 0, "return", ";", 8, true_rtx); 4540 fprintf (outf, " }\n"); 4541 } 4542 4543 fprintf (outf, " default:\n"); 4544 fprintf (outf, " gcc_unreachable ();\n"); 4545 fprintf (outf, " }\n"); 4546 } 4547 4548 fprintf (outf, "}\n\n"); 4549} 4550 4551/* This page contains miscellaneous utility routines. */ 4552 4553/* Given a pointer to a (char *), return a malloc'ed string containing the 4554 next comma-separated element. Advance the pointer to after the string 4555 scanned, or the end-of-string. Return NULL if at end of string. */ 4556 4557static char * 4558next_comma_elt (const char **pstr) 4559{ 4560 const char *start; 4561 4562 start = scan_comma_elt (pstr); 4563 4564 if (start == NULL) 4565 return NULL; 4566 4567 return attr_string (start, *pstr - start); 4568} 4569 4570/* Return a `struct attr_desc' pointer for a given named attribute. If CREATE 4571 is nonzero, build a new attribute, if one does not exist. *NAME_P is 4572 replaced by a pointer to a canonical copy of the string. */ 4573 4574static struct attr_desc * 4575find_attr (const char **name_p, int create) 4576{ 4577 struct attr_desc *attr; 4578 int index; 4579 const char *name = *name_p; 4580 4581 /* Before we resort to using `strcmp', see if the string address matches 4582 anywhere. In most cases, it should have been canonicalized to do so. */ 4583 if (name == alternative_name) 4584 return NULL; 4585 4586 index = name[0] & (MAX_ATTRS_INDEX - 1); 4587 for (attr = attrs[index]; attr; attr = attr->next) 4588 if (name == attr->name) 4589 return attr; 4590 4591 /* Otherwise, do it the slow way. */ 4592 for (attr = attrs[index]; attr; attr = attr->next) 4593 if (name[0] == attr->name[0] && ! strcmp (name, attr->name)) 4594 { 4595 *name_p = attr->name; 4596 return attr; 4597 } 4598 4599 if (! create) 4600 return NULL; 4601 4602 attr = oballoc (struct attr_desc); 4603 attr->name = DEF_ATTR_STRING (name); 4604 attr->enum_name = 0; 4605 attr->first_value = attr->default_val = NULL; 4606 attr->is_numeric = attr->is_const = attr->is_special = 0; 4607 attr->next = attrs[index]; 4608 attrs[index] = attr; 4609 4610 *name_p = attr->name; 4611 4612 return attr; 4613} 4614 4615/* Create internal attribute with the given default value. */ 4616 4617static void 4618make_internal_attr (const char *name, rtx value, int special) 4619{ 4620 struct attr_desc *attr; 4621 4622 attr = find_attr (&name, 1); 4623 gcc_assert (!attr->default_val); 4624 4625 attr->is_numeric = 1; 4626 attr->is_const = 0; 4627 attr->is_special = (special & ATTR_SPECIAL) != 0; 4628 attr->default_val = get_attr_value (value, attr, -2); 4629} 4630 4631/* Find the most used value of an attribute. */ 4632 4633static struct attr_value * 4634find_most_used (struct attr_desc *attr) 4635{ 4636 struct attr_value *av; 4637 struct attr_value *most_used; 4638 int nuses; 4639 4640 most_used = NULL; 4641 nuses = -1; 4642 4643 for (av = attr->first_value; av; av = av->next) 4644 if (av->num_insns > nuses) 4645 nuses = av->num_insns, most_used = av; 4646 4647 return most_used; 4648} 4649 4650/* Return (attr_value "n") */ 4651 4652static rtx 4653make_numeric_value (int n) 4654{ 4655 static rtx int_values[20]; 4656 rtx exp; 4657 char *p; 4658 4659 gcc_assert (n >= 0); 4660 4661 if (n < 20 && int_values[n]) 4662 return int_values[n]; 4663 4664 p = attr_printf (MAX_DIGITS, "%d", n); 4665 exp = attr_rtx (CONST_STRING, p); 4666 4667 if (n < 20) 4668 int_values[n] = exp; 4669 4670 return exp; 4671} 4672 4673static rtx 4674copy_rtx_unchanging (rtx orig) 4675{ 4676 if (ATTR_IND_SIMPLIFIED_P (orig) || ATTR_CURR_SIMPLIFIED_P (orig)) 4677 return orig; 4678 4679 ATTR_CURR_SIMPLIFIED_P (orig) = 1; 4680 return orig; 4681} 4682 4683/* Determine if an insn has a constant number of delay slots, i.e., the 4684 number of delay slots is not a function of the length of the insn. */ 4685 4686static void 4687write_const_num_delay_slots (FILE *outf) 4688{ 4689 struct attr_desc *attr = find_attr (&num_delay_slots_str, 0); 4690 struct attr_value *av; 4691 4692 if (attr) 4693 { 4694 fprintf (outf, "int\nconst_num_delay_slots (rtx_insn *insn)\n"); 4695 fprintf (outf, "{\n"); 4696 fprintf (outf, " switch (recog_memoized (insn))\n"); 4697 fprintf (outf, " {\n"); 4698 4699 for (av = attr->first_value; av; av = av->next) 4700 { 4701 length_used = 0; 4702 walk_attr_value (av->value); 4703 if (length_used) 4704 write_insn_cases (outf, av->first_insn, 4); 4705 } 4706 4707 fprintf (outf, " default:\n"); 4708 fprintf (outf, " return 1;\n"); 4709 fprintf (outf, " }\n}\n\n"); 4710 } 4711} 4712 4713/* Synthetic attributes used by insn-automata.c and the scheduler. 4714 These are primarily concerned with (define_insn_reservation) 4715 patterns. */ 4716 4717struct insn_reserv 4718{ 4719 struct insn_reserv *next; 4720 4721 const char *name; 4722 int default_latency; 4723 rtx condexp; 4724 4725 /* Sequence number of this insn. */ 4726 int insn_num; 4727 4728 /* Whether a (define_bypass) construct names this insn in its 4729 output list. */ 4730 bool bypassed; 4731}; 4732 4733static struct insn_reserv *all_insn_reservs = 0; 4734static struct insn_reserv **last_insn_reserv_p = &all_insn_reservs; 4735static size_t n_insn_reservs; 4736 4737/* Store information from a DEFINE_INSN_RESERVATION for future 4738 attribute generation. */ 4739static void 4740gen_insn_reserv (rtx def) 4741{ 4742 struct insn_reserv *decl = oballoc (struct insn_reserv); 4743 4744 decl->name = DEF_ATTR_STRING (XSTR (def, 0)); 4745 decl->default_latency = XINT (def, 1); 4746 decl->condexp = check_attr_test (XEXP (def, 2), 0, 0); 4747 decl->insn_num = n_insn_reservs; 4748 decl->bypassed = false; 4749 decl->next = 0; 4750 4751 *last_insn_reserv_p = decl; 4752 last_insn_reserv_p = &decl->next; 4753 n_insn_reservs++; 4754} 4755 4756/* Store information from a DEFINE_BYPASS for future attribute 4757 generation. The only thing we care about is the list of output 4758 insns, which will later be used to tag reservation structures with 4759 a 'bypassed' bit. */ 4760 4761struct bypass_list 4762{ 4763 struct bypass_list *next; 4764 const char *pattern; 4765}; 4766 4767static struct bypass_list *all_bypasses; 4768static size_t n_bypasses; 4769static size_t n_bypassed; 4770 4771static void 4772gen_bypass_1 (const char *s, size_t len) 4773{ 4774 struct bypass_list *b; 4775 4776 if (len == 0) 4777 return; 4778 4779 s = attr_string (s, len); 4780 for (b = all_bypasses; b; b = b->next) 4781 if (s == b->pattern) 4782 return; /* already got that one */ 4783 4784 b = oballoc (struct bypass_list); 4785 b->pattern = s; 4786 b->next = all_bypasses; 4787 all_bypasses = b; 4788 n_bypasses++; 4789} 4790 4791static void 4792gen_bypass (rtx def) 4793{ 4794 const char *p, *base; 4795 4796 for (p = base = XSTR (def, 1); *p; p++) 4797 if (*p == ',') 4798 { 4799 gen_bypass_1 (base, p - base); 4800 do 4801 p++; 4802 while (ISSPACE (*p)); 4803 base = p; 4804 } 4805 gen_bypass_1 (base, p - base); 4806} 4807 4808/* Find and mark all of the bypassed insns. */ 4809static void 4810process_bypasses (void) 4811{ 4812 struct bypass_list *b; 4813 struct insn_reserv *r; 4814 4815 n_bypassed = 0; 4816 4817 /* The reservation list is likely to be much longer than the bypass 4818 list. */ 4819 for (r = all_insn_reservs; r; r = r->next) 4820 for (b = all_bypasses; b; b = b->next) 4821 if (fnmatch (b->pattern, r->name, 0) == 0) 4822 { 4823 n_bypassed++; 4824 r->bypassed = true; 4825 break; 4826 } 4827} 4828 4829/* Check that attribute NAME is used in define_insn_reservation condition 4830 EXP. Return true if it is. */ 4831static bool 4832check_tune_attr (const char *name, rtx exp) 4833{ 4834 switch (GET_CODE (exp)) 4835 { 4836 case AND: 4837 if (check_tune_attr (name, XEXP (exp, 0))) 4838 return true; 4839 return check_tune_attr (name, XEXP (exp, 1)); 4840 4841 case IOR: 4842 return (check_tune_attr (name, XEXP (exp, 0)) 4843 && check_tune_attr (name, XEXP (exp, 1))); 4844 4845 case EQ_ATTR: 4846 return XSTR (exp, 0) == name; 4847 4848 default: 4849 return false; 4850 } 4851} 4852 4853/* Try to find a const attribute (usually cpu or tune) that is used 4854 in all define_insn_reservation conditions. */ 4855static struct attr_desc * 4856find_tune_attr (rtx exp) 4857{ 4858 struct attr_desc *attr; 4859 4860 switch (GET_CODE (exp)) 4861 { 4862 case AND: 4863 case IOR: 4864 attr = find_tune_attr (XEXP (exp, 0)); 4865 if (attr) 4866 return attr; 4867 return find_tune_attr (XEXP (exp, 1)); 4868 4869 case EQ_ATTR: 4870 if (XSTR (exp, 0) == alternative_name) 4871 return NULL; 4872 4873 attr = find_attr (&XSTR (exp, 0), 0); 4874 gcc_assert (attr); 4875 4876 if (attr->is_const && !attr->is_special) 4877 { 4878 struct insn_reserv *decl; 4879 4880 for (decl = all_insn_reservs; decl; decl = decl->next) 4881 if (! check_tune_attr (attr->name, decl->condexp)) 4882 return NULL; 4883 return attr; 4884 } 4885 return NULL; 4886 4887 default: 4888 return NULL; 4889 } 4890} 4891 4892/* Create all of the attributes that describe automaton properties. 4893 Write the DFA and latency function prototypes to the files that 4894 need to have them, and write the init_sched_attrs(). */ 4895 4896static void 4897make_automaton_attrs (void) 4898{ 4899 int i; 4900 struct insn_reserv *decl; 4901 rtx code_exp, lats_exp, byps_exp; 4902 struct attr_desc *tune_attr; 4903 4904 if (n_insn_reservs == 0) 4905 return; 4906 4907 tune_attr = find_tune_attr (all_insn_reservs->condexp); 4908 if (tune_attr != NULL) 4909 { 4910 rtx *condexps = XNEWVEC (rtx, n_insn_reservs * 3); 4911 struct attr_value *val; 4912 bool first = true; 4913 4914 gcc_assert (tune_attr->is_const 4915 && !tune_attr->is_special 4916 && !tune_attr->is_numeric); 4917 4918 /* Write the prototypes for all DFA functions. */ 4919 for (val = tune_attr->first_value; val; val = val->next) 4920 { 4921 if (val == tune_attr->default_val) 4922 continue; 4923 gcc_assert (GET_CODE (val->value) == CONST_STRING); 4924 fprintf (dfa_file, 4925 "extern int internal_dfa_insn_code_%s (rtx_insn *);\n", 4926 XSTR (val->value, 0)); 4927 } 4928 fprintf (dfa_file, "\n"); 4929 4930 /* Write the prototypes for all latency functions. */ 4931 for (val = tune_attr->first_value; val; val = val->next) 4932 { 4933 if (val == tune_attr->default_val) 4934 continue; 4935 gcc_assert (GET_CODE (val->value) == CONST_STRING); 4936 fprintf (latency_file, 4937 "extern int insn_default_latency_%s (rtx_insn *);\n", 4938 XSTR (val->value, 0)); 4939 } 4940 fprintf (latency_file, "\n"); 4941 4942 /* Write the prototypes for all automaton functions. */ 4943 for (val = tune_attr->first_value; val; val = val->next) 4944 { 4945 if (val == tune_attr->default_val) 4946 continue; 4947 gcc_assert (GET_CODE (val->value) == CONST_STRING); 4948 fprintf (attr_file, 4949 "extern int internal_dfa_insn_code_%s (rtx_insn *);\n" 4950 "extern int insn_default_latency_%s (rtx_insn *);\n", 4951 XSTR (val->value, 0), XSTR (val->value, 0)); 4952 } 4953 fprintf (attr_file, "\n"); 4954 fprintf (attr_file, "int (*internal_dfa_insn_code) (rtx_insn *);\n"); 4955 fprintf (attr_file, "int (*insn_default_latency) (rtx_insn *);\n"); 4956 fprintf (attr_file, "\n"); 4957 fprintf (attr_file, "void\n"); 4958 fprintf (attr_file, "init_sched_attrs (void)\n"); 4959 fprintf (attr_file, "{\n"); 4960 4961 for (val = tune_attr->first_value; val; val = val->next) 4962 { 4963 int j; 4964 char *name; 4965 rtx test = attr_rtx (EQ_ATTR, tune_attr->name, XSTR (val->value, 0)); 4966 4967 if (val == tune_attr->default_val) 4968 continue; 4969 for (decl = all_insn_reservs, i = 0; 4970 decl; 4971 decl = decl->next) 4972 { 4973 rtx ctest = test; 4974 rtx condexp 4975 = simplify_and_tree (decl->condexp, &ctest, -2, 0); 4976 if (condexp == false_rtx) 4977 continue; 4978 if (condexp == true_rtx) 4979 break; 4980 condexps[i] = condexp; 4981 condexps[i + 1] = make_numeric_value (decl->insn_num); 4982 condexps[i + 2] = make_numeric_value (decl->default_latency); 4983 i += 3; 4984 } 4985 4986 code_exp = rtx_alloc (COND); 4987 lats_exp = rtx_alloc (COND); 4988 4989 j = i / 3 * 2; 4990 XVEC (code_exp, 0) = rtvec_alloc (j); 4991 XVEC (lats_exp, 0) = rtvec_alloc (j); 4992 4993 if (decl) 4994 { 4995 XEXP (code_exp, 1) = make_numeric_value (decl->insn_num); 4996 XEXP (lats_exp, 1) = make_numeric_value (decl->default_latency); 4997 } 4998 else 4999 { 5000 XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1); 5001 XEXP (lats_exp, 1) = make_numeric_value (0); 5002 } 5003 5004 while (i > 0) 5005 { 5006 i -= 3; 5007 j -= 2; 5008 XVECEXP (code_exp, 0, j) = condexps[i]; 5009 XVECEXP (lats_exp, 0, j) = condexps[i]; 5010 5011 XVECEXP (code_exp, 0, j + 1) = condexps[i + 1]; 5012 XVECEXP (lats_exp, 0, j + 1) = condexps[i + 2]; 5013 } 5014 5015 name = XNEWVEC (char, 5016 sizeof ("*internal_dfa_insn_code_") 5017 + strlen (XSTR (val->value, 0))); 5018 strcpy (name, "*internal_dfa_insn_code_"); 5019 strcat (name, XSTR (val->value, 0)); 5020 make_internal_attr (name, code_exp, ATTR_NONE); 5021 strcpy (name, "*insn_default_latency_"); 5022 strcat (name, XSTR (val->value, 0)); 5023 make_internal_attr (name, lats_exp, ATTR_NONE); 5024 XDELETEVEC (name); 5025 5026 if (first) 5027 { 5028 fprintf (attr_file, " if ("); 5029 first = false; 5030 } 5031 else 5032 fprintf (attr_file, " else if ("); 5033 write_test_expr (attr_file, test, 0, 0); 5034 fprintf (attr_file, ")\n"); 5035 fprintf (attr_file, " {\n"); 5036 fprintf (attr_file, " internal_dfa_insn_code\n"); 5037 fprintf (attr_file, " = internal_dfa_insn_code_%s;\n", 5038 XSTR (val->value, 0)); 5039 fprintf (attr_file, " insn_default_latency\n"); 5040 fprintf (attr_file, " = insn_default_latency_%s;\n", 5041 XSTR (val->value, 0)); 5042 fprintf (attr_file, " }\n"); 5043 } 5044 5045 fprintf (attr_file, " else\n"); 5046 fprintf (attr_file, " gcc_unreachable ();\n"); 5047 fprintf (attr_file, "}\n"); 5048 fprintf (attr_file, "\n"); 5049 5050 XDELETEVEC (condexps); 5051 } 5052 else 5053 { 5054 code_exp = rtx_alloc (COND); 5055 lats_exp = rtx_alloc (COND); 5056 5057 XVEC (code_exp, 0) = rtvec_alloc (n_insn_reservs * 2); 5058 XVEC (lats_exp, 0) = rtvec_alloc (n_insn_reservs * 2); 5059 5060 XEXP (code_exp, 1) = make_numeric_value (n_insn_reservs + 1); 5061 XEXP (lats_exp, 1) = make_numeric_value (0); 5062 5063 for (decl = all_insn_reservs, i = 0; 5064 decl; 5065 decl = decl->next, i += 2) 5066 { 5067 XVECEXP (code_exp, 0, i) = decl->condexp; 5068 XVECEXP (lats_exp, 0, i) = decl->condexp; 5069 5070 XVECEXP (code_exp, 0, i+1) = make_numeric_value (decl->insn_num); 5071 XVECEXP (lats_exp, 0, i+1) 5072 = make_numeric_value (decl->default_latency); 5073 } 5074 make_internal_attr ("*internal_dfa_insn_code", code_exp, ATTR_NONE); 5075 make_internal_attr ("*insn_default_latency", lats_exp, ATTR_NONE); 5076 } 5077 5078 if (n_bypasses == 0) 5079 byps_exp = make_numeric_value (0); 5080 else 5081 { 5082 process_bypasses (); 5083 5084 byps_exp = rtx_alloc (COND); 5085 XVEC (byps_exp, 0) = rtvec_alloc (n_bypassed * 2); 5086 XEXP (byps_exp, 1) = make_numeric_value (0); 5087 for (decl = all_insn_reservs, i = 0; 5088 decl; 5089 decl = decl->next) 5090 if (decl->bypassed) 5091 { 5092 XVECEXP (byps_exp, 0, i) = decl->condexp; 5093 XVECEXP (byps_exp, 0, i+1) = make_numeric_value (1); 5094 i += 2; 5095 } 5096 } 5097 5098 make_internal_attr ("*bypass_p", byps_exp, ATTR_NONE); 5099} 5100 5101static void 5102write_header (FILE *outf) 5103{ 5104 fprintf (outf, "/* Generated automatically by the program `genattrtab'\n" 5105 " from the machine description file `md'. */\n\n"); 5106 5107 fprintf (outf, "#include \"config.h\"\n"); 5108 fprintf (outf, "#include \"system.h\"\n"); 5109 fprintf (outf, "#include \"coretypes.h\"\n"); 5110 fprintf (outf, "#include \"tm.h\"\n"); 5111 fprintf (outf, "#include \"hash-set.h\"\n"); 5112 fprintf (outf, "#include \"machmode.h\"\n"); 5113 fprintf (outf, "#include \"vec.h\"\n"); 5114 fprintf (outf, "#include \"double-int.h\"\n"); 5115 fprintf (outf, "#include \"input.h\"\n"); 5116 fprintf (outf, "#include \"alias.h\"\n"); 5117 fprintf (outf, "#include \"symtab.h\"\n"); 5118 fprintf (outf, "#include \"options.h\"\n"); 5119 fprintf (outf, "#include \"wide-int.h\"\n"); 5120 fprintf (outf, "#include \"inchash.h\"\n"); 5121 fprintf (outf, "#include \"tree.h\"\n"); 5122 fprintf (outf, "#include \"varasm.h\"\n"); 5123 fprintf (outf, "#include \"stor-layout.h\"\n"); 5124 fprintf (outf, "#include \"calls.h\"\n"); 5125 fprintf (outf, "#include \"rtl.h\"\n"); 5126 fprintf (outf, "#include \"insn-attr.h\"\n"); 5127 fprintf (outf, "#include \"tm_p.h\"\n"); 5128 fprintf (outf, "#include \"insn-config.h\"\n"); 5129 fprintf (outf, "#include \"recog.h\"\n"); 5130 fprintf (outf, "#include \"regs.h\"\n"); 5131 fprintf (outf, "#include \"real.h\"\n"); 5132 fprintf (outf, "#include \"output.h\"\n"); 5133 fprintf (outf, "#include \"toplev.h\"\n"); 5134 fprintf (outf, "#include \"flags.h\"\n"); 5135 fprintf (outf, "#include \"function.h\"\n"); 5136 fprintf (outf, "#include \"predict.h\"\n"); 5137 fprintf (outf, "\n"); 5138 fprintf (outf, "#define operands recog_data.operand\n\n"); 5139} 5140 5141static FILE * 5142open_outfile (const char *file_name) 5143{ 5144 FILE *outf; 5145 outf = fopen (file_name, "w"); 5146 if (! outf) 5147 fatal ("cannot open file %s: %s", file_name, xstrerror (errno)); 5148 write_header (outf); 5149 return outf; 5150} 5151 5152static bool 5153handle_arg (const char *arg) 5154{ 5155 switch (arg[1]) 5156 { 5157 case 'A': 5158 attr_file_name = &arg[2]; 5159 return true; 5160 case 'D': 5161 dfa_file_name = &arg[2]; 5162 return true; 5163 case 'L': 5164 latency_file_name = &arg[2]; 5165 return true; 5166 default: 5167 return false; 5168 } 5169} 5170 5171int 5172main (int argc, char **argv) 5173{ 5174 rtx desc; 5175 struct attr_desc *attr; 5176 struct insn_def *id; 5177 rtx tem; 5178 int i; 5179 5180 progname = "genattrtab"; 5181 5182 if (!init_rtx_reader_args_cb (argc, argv, handle_arg)) 5183 return FATAL_EXIT_CODE; 5184 5185 attr_file = open_outfile (attr_file_name); 5186 dfa_file = open_outfile (dfa_file_name); 5187 latency_file = open_outfile (latency_file_name); 5188 5189 obstack_init (hash_obstack); 5190 obstack_init (temp_obstack); 5191 5192 /* Set up true and false rtx's */ 5193 true_rtx = rtx_alloc (CONST_INT); 5194 XWINT (true_rtx, 0) = 1; 5195 false_rtx = rtx_alloc (CONST_INT); 5196 XWINT (false_rtx, 0) = 0; 5197 ATTR_IND_SIMPLIFIED_P (true_rtx) = ATTR_IND_SIMPLIFIED_P (false_rtx) = 1; 5198 ATTR_PERMANENT_P (true_rtx) = ATTR_PERMANENT_P (false_rtx) = 1; 5199 5200 alternative_name = DEF_ATTR_STRING ("alternative"); 5201 length_str = DEF_ATTR_STRING ("length"); 5202 delay_type_str = DEF_ATTR_STRING ("*delay_type"); 5203 delay_1_0_str = DEF_ATTR_STRING ("*delay_1_0"); 5204 num_delay_slots_str = DEF_ATTR_STRING ("*num_delay_slots"); 5205 5206 /* Read the machine description. */ 5207 5208 while (1) 5209 { 5210 int lineno; 5211 5212 desc = read_md_rtx (&lineno, &insn_code_number); 5213 if (desc == NULL) 5214 break; 5215 5216 switch (GET_CODE (desc)) 5217 { 5218 case DEFINE_INSN: 5219 case DEFINE_PEEPHOLE: 5220 case DEFINE_ASM_ATTRIBUTES: 5221 gen_insn (desc, lineno); 5222 break; 5223 5224 case DEFINE_ATTR: 5225 case DEFINE_ENUM_ATTR: 5226 gen_attr (desc, lineno); 5227 break; 5228 5229 case DEFINE_DELAY: 5230 gen_delay (desc, lineno); 5231 break; 5232 5233 case DEFINE_INSN_RESERVATION: 5234 gen_insn_reserv (desc); 5235 break; 5236 5237 case DEFINE_BYPASS: 5238 gen_bypass (desc); 5239 break; 5240 5241 default: 5242 break; 5243 } 5244 if (GET_CODE (desc) != DEFINE_ASM_ATTRIBUTES) 5245 insn_index_number++; 5246 } 5247 5248 if (have_error) 5249 return FATAL_EXIT_CODE; 5250 5251 insn_code_number++; 5252 5253 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */ 5254 if (! got_define_asm_attributes) 5255 { 5256 tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES); 5257 XVEC (tem, 0) = rtvec_alloc (0); 5258 gen_insn (tem, 0); 5259 } 5260 5261 /* Expand DEFINE_DELAY information into new attribute. */ 5262 if (num_delays) 5263 expand_delays (); 5264 5265 /* Make `insn_alternatives'. */ 5266 insn_alternatives = oballocvec (uint64_t, insn_code_number); 5267 for (id = defs; id; id = id->next) 5268 if (id->insn_code >= 0) 5269 insn_alternatives[id->insn_code] 5270 = (((uint64_t) 1) << id->num_alternatives) - 1; 5271 5272 /* Make `insn_n_alternatives'. */ 5273 insn_n_alternatives = oballocvec (int, insn_code_number); 5274 for (id = defs; id; id = id->next) 5275 if (id->insn_code >= 0) 5276 insn_n_alternatives[id->insn_code] = id->num_alternatives; 5277 5278 /* Construct extra attributes for automata. */ 5279 make_automaton_attrs (); 5280 5281 /* Prepare to write out attribute subroutines by checking everything stored 5282 away and building the attribute cases. */ 5283 5284 check_defs (); 5285 5286 for (i = 0; i < MAX_ATTRS_INDEX; i++) 5287 for (attr = attrs[i]; attr; attr = attr->next) 5288 attr->default_val->value 5289 = check_attr_value (attr->default_val->value, attr); 5290 5291 if (have_error) 5292 return FATAL_EXIT_CODE; 5293 5294 for (i = 0; i < MAX_ATTRS_INDEX; i++) 5295 for (attr = attrs[i]; attr; attr = attr->next) 5296 fill_attr (attr); 5297 5298 /* Construct extra attributes for `length'. */ 5299 make_length_attrs (); 5300 5301 /* Perform any possible optimizations to speed up compilation. */ 5302 optimize_attrs (); 5303 5304 /* Now write out all the `gen_attr_...' routines. Do these before the 5305 special routines so that they get defined before they are used. */ 5306 5307 for (i = 0; i < MAX_ATTRS_INDEX; i++) 5308 for (attr = attrs[i]; attr; attr = attr->next) 5309 { 5310 FILE *outf; 5311 5312#define IS_ATTR_GROUP(X) (!strncmp (attr->name, X, strlen (X))) 5313 if (IS_ATTR_GROUP ("*internal_dfa_insn_code")) 5314 outf = dfa_file; 5315 else if (IS_ATTR_GROUP ("*insn_default_latency")) 5316 outf = latency_file; 5317 else 5318 outf = attr_file; 5319#undef IS_ATTR_GROUP 5320 5321 if (! attr->is_special && ! attr->is_const) 5322 write_attr_get (outf, attr); 5323 } 5324 5325 /* Write out delay eligibility information, if DEFINE_DELAY present. 5326 (The function to compute the number of delay slots will be written 5327 below.) */ 5328 if (num_delays) 5329 { 5330 write_eligible_delay (attr_file, "delay"); 5331 if (have_annul_true) 5332 write_eligible_delay (attr_file, "annul_true"); 5333 if (have_annul_false) 5334 write_eligible_delay (attr_file, "annul_false"); 5335 } 5336 5337 /* Write out constant delay slot info. */ 5338 write_const_num_delay_slots (attr_file); 5339 5340 write_length_unit_log (attr_file); 5341 5342 if (fclose (attr_file) != 0) 5343 fatal ("cannot close file %s: %s", attr_file_name, xstrerror (errno)); 5344 if (fclose (dfa_file) != 0) 5345 fatal ("cannot close file %s: %s", dfa_file_name, xstrerror (errno)); 5346 if (fclose (latency_file) != 0) 5347 fatal ("cannot close file %s: %s", latency_file_name, xstrerror (errno)); 5348 5349 return SUCCESS_EXIT_CODE; 5350} 5351 5352