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