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