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