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