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