1/* Generate code from machine description to compute values of attributes. 2 Copyright (C) 1991, 93-98, 1999 Free Software Foundation, Inc. 3 Contributed by Richard Kenner (kenner@vlsi1.ultra.nyu.edu) 4 5This file is part of GNU CC. 6 7GNU CC is free software; you can redistribute it and/or modify 8it under the terms of the GNU General Public License as published by 9the Free Software Foundation; either version 2, or (at your option) 10any later version. 11 12GNU CC is distributed in the hope that it will be useful, 13but WITHOUT ANY WARRANTY; without even the implied warranty of 14MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15GNU General Public License for more details. 16 17You should have received a copy of the GNU General Public License 18along with GNU CC; see the file COPYING. If not, write to 19the Free Software Foundation, 59 Temple Place - Suite 330, 20Boston, MA 02111-1307, USA. */ 21 22/* This program handles insn attributes and the DEFINE_DELAY and 23 DEFINE_FUNCTION_UNIT definitions. 24 25 It produces a series of functions named `get_attr_...', one for each insn 26 attribute. Each of these is given the rtx for an insn and returns a member 27 of the enum for the attribute. 28 29 These subroutines have the form of a `switch' on the INSN_CODE (via 30 `recog_memoized'). Each case either returns a constant attribute value 31 or a value that depends on tests on other attributes, the form of 32 operands, or some random C expression (encoded with a SYMBOL_REF 33 expression). 34 35 If the attribute `alternative', or a random C expression is present, 36 `constrain_operands' is called. If either of these cases of a reference to 37 an operand is found, `extract_insn' is called. 38 39 The special attribute `length' is also recognized. For this operand, 40 expressions involving the address of an operand or the current insn, 41 (address (pc)), are valid. In this case, an initial pass is made to 42 set all lengths that do not depend on address. Those that do are set to 43 the maximum length. Then each insn that depends on an address is checked 44 and possibly has its length changed. The process repeats until no further 45 changed are made. The resulting lengths are saved for use by 46 `get_attr_length'. 47 48 A special form of DEFINE_ATTR, where the expression for default value is a 49 CONST expression, indicates an attribute that is constant for a given run 50 of the compiler. The subroutine generated for these attributes has no 51 parameters as it does not depend on any particular insn. Constant 52 attributes are typically used to specify which variety of processor is 53 used. 54 55 Internal attributes are defined to handle DEFINE_DELAY and 56 DEFINE_FUNCTION_UNIT. Special routines are output for these cases. 57 58 This program works by keeping a list of possible values for each attribute. 59 These include the basic attribute choices, default values for attribute, and 60 all derived quantities. 61 62 As the description file is read, the definition for each insn is saved in a 63 `struct insn_def'. When the file reading is complete, a `struct insn_ent' 64 is created for each insn and chained to the corresponding attribute value, 65 either that specified, or the default. 66 67 An optimization phase is then run. This simplifies expressions for each 68 insn. EQ_ATTR tests are resolved, whenever possible, to a test that 69 indicates when the attribute has the specified value for the insn. This 70 avoids recursive calls during compilation. 71 72 The strategy used when processing DEFINE_DELAY and DEFINE_FUNCTION_UNIT 73 definitions is to create arbitrarily complex expressions and have the 74 optimization simplify them. 75 76 Once optimization is complete, any required routines and definitions 77 will be written. 78 79 An optimization that is not yet implemented is to hoist the constant 80 expressions entirely out of the routines and definitions that are written. 81 A way to do this is to iterate over all possible combinations of values 82 for constant attributes and generate a set of functions for that given 83 combination. An initialization function would be written that evaluates 84 the attributes and installs the corresponding set of routines and 85 definitions (each would be accessed through a pointer). 86 87 We use the flags in an RTX as follows: 88 `unchanging' (RTX_UNCHANGING_P): This rtx is fully simplified 89 independent of the insn code. 90 `in_struct' (MEM_IN_STRUCT_P): This rtx is fully simplified 91 for the insn code currently being processed (see optimize_attrs). 92 `integrated' (RTX_INTEGRATED_P): This rtx is permanent and unique 93 (see attr_rtx). 94 `volatil' (MEM_VOLATILE_P): During simplify_by_exploding the value of an 95 EQ_ATTR rtx is true if !volatil and false if volatil. */ 96 97 98#include "hconfig.h" 99#include "system.h" 100#include "rtl.h" 101#include "insn-config.h" /* For REGISTER_CONSTRAINTS */ 102 103#ifdef HAVE_SYS_RESOURCE_H 104# include <sys/resource.h> 105#endif 106 107/* We must include obstack.h after <sys/time.h>, to avoid lossage with 108 /usr/include/sys/stdtypes.h on Sun OS 4.x. */ 109#include "obstack.h" 110 111static struct obstack obstack, obstack1, obstack2; 112struct obstack *rtl_obstack = &obstack; 113struct obstack *hash_obstack = &obstack1; 114struct obstack *temp_obstack = &obstack2; 115 116#define obstack_chunk_alloc xmalloc 117#define obstack_chunk_free free 118 119/* Define this so we can link with print-rtl.o to get debug_rtx function. */ 120char **insn_name_ptr = 0; 121 122void fatal PVPROTO ((const char *, ...)) 123 ATTRIBUTE_PRINTF_1 ATTRIBUTE_NORETURN; 124void fancy_abort PROTO((void)) ATTRIBUTE_NORETURN; 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 136struct insn_def 137{ 138 int insn_code; /* Instruction number. */ 139 int insn_index; /* Expression numer in file, for errors. */ 140 struct insn_def *next; /* Next insn in chain. */ 141 rtx def; /* The DEFINE_... */ 142 int num_alternatives; /* Number of alternatives. */ 143 int vec_idx; /* Index of attribute vector in `def'. */ 144}; 145 146/* Once everything has been read in, we store in each attribute value a list 147 of insn codes that have that value. Here is the structure used for the 148 list. */ 149 150struct insn_ent 151{ 152 int insn_code; /* Instruction number. */ 153 int insn_index; /* Index of definition in file */ 154 struct insn_ent *next; /* Next in chain. */ 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 161struct 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 172struct attr_desc 173{ 174 char *name; /* Name of attribute. */ 175 struct attr_desc *next; /* Next attribute. */ 176 unsigned is_numeric : 1; /* Values of this attribute are numeric. */ 177 unsigned negative_ok : 1; /* Allow negative numeric values. */ 178 unsigned unsigned_p : 1; /* Make the output function unsigned int. */ 179 unsigned is_const : 1; /* Attribute value constant for each run. */ 180 unsigned is_special : 1; /* Don't call `write_attr_set'. */ 181 unsigned func_units_p : 1; /* this is the function_units attribute */ 182 unsigned blockage_p : 1; /* this is the blockage range function */ 183 struct attr_value *first_value; /* First value of this attribute. */ 184 struct attr_value *default_val; /* Default value for this attribute. */ 185}; 186 187#define NULL_ATTR (struct attr_desc *) NULL 188 189/* A range of values. */ 190 191struct range 192{ 193 int min; 194 int max; 195}; 196 197/* Structure for each DEFINE_DELAY. */ 198 199struct delay_desc 200{ 201 rtx def; /* DEFINE_DELAY expression. */ 202 struct delay_desc *next; /* Next DEFINE_DELAY. */ 203 int num; /* Number of DEFINE_DELAY, starting at 1. */ 204}; 205 206/* Record information about each DEFINE_FUNCTION_UNIT. */ 207 208struct function_unit_op 209{ 210 rtx condexp; /* Expression TRUE for applicable insn. */ 211 struct function_unit_op *next; /* Next operation for this function unit. */ 212 int num; /* Ordinal for this operation type in unit. */ 213 int ready; /* Cost until data is ready. */ 214 int issue_delay; /* Cost until unit can accept another insn. */ 215 rtx conflict_exp; /* Expression TRUE for insns incurring issue delay. */ 216 rtx issue_exp; /* Expression computing issue delay. */ 217}; 218 219/* Record information about each function unit mentioned in a 220 DEFINE_FUNCTION_UNIT. */ 221 222struct function_unit 223{ 224 char *name; /* Function unit name. */ 225 struct function_unit *next; /* Next function unit. */ 226 int num; /* Ordinal of this unit type. */ 227 int multiplicity; /* Number of units of this type. */ 228 int simultaneity; /* Maximum number of simultaneous insns 229 on this function unit or 0 if unlimited. */ 230 rtx condexp; /* Expression TRUE for insn needing unit. */ 231 int num_opclasses; /* Number of different operation types. */ 232 struct function_unit_op *ops; /* Pointer to first operation type. */ 233 int needs_conflict_function; /* Nonzero if a conflict function required. */ 234 int needs_blockage_function; /* Nonzero if a blockage function required. */ 235 int needs_range_function; /* Nonzero if blockage range function needed.*/ 236 rtx default_cost; /* Conflict cost, if constant. */ 237 struct range issue_delay; /* Range of issue delay values. */ 238 int max_blockage; /* Maximum time an insn blocks the unit. */ 239}; 240 241/* Listheads of above structures. */ 242 243/* This one is indexed by the first character of the attribute name. */ 244#define MAX_ATTRS_INDEX 256 245static struct attr_desc *attrs[MAX_ATTRS_INDEX]; 246static struct insn_def *defs; 247static struct delay_desc *delays; 248static struct function_unit *units; 249 250/* An expression where all the unknown terms are EQ_ATTR tests can be 251 rearranged into a COND provided we can enumerate all possible 252 combinations of the unknown values. The set of combinations become the 253 tests of the COND; the value of the expression given that combination is 254 computed and becomes the corresponding value. To do this, we must be 255 able to enumerate all values for each attribute used in the expression 256 (currently, we give up if we find a numeric attribute). 257 258 If the set of EQ_ATTR tests used in an expression tests the value of N 259 different attributes, the list of all possible combinations can be made 260 by walking the N-dimensional attribute space defined by those 261 attributes. We record each of these as a struct dimension. 262 263 The algorithm relies on sharing EQ_ATTR nodes: if two nodes in an 264 expression are the same, the will also have the same address. We find 265 all the EQ_ATTR nodes by marking them MEM_VOLATILE_P. This bit later 266 represents the value of an EQ_ATTR node, so once all nodes are marked, 267 they are also given an initial value of FALSE. 268 269 We then separate the set of EQ_ATTR nodes into dimensions for each 270 attribute and put them on the VALUES list. Terms are added as needed by 271 `add_values_to_cover' so that all possible values of the attribute are 272 tested. 273 274 Each dimension also has a current value. This is the node that is 275 currently considered to be TRUE. If this is one of the nodes added by 276 `add_values_to_cover', all the EQ_ATTR tests in the original expression 277 will be FALSE. Otherwise, only the CURRENT_VALUE will be true. 278 279 NUM_VALUES is simply the length of the VALUES list and is there for 280 convenience. 281 282 Once the dimensions are created, the algorithm enumerates all possible 283 values and computes the current value of the given expression. */ 284 285struct dimension 286{ 287 struct attr_desc *attr; /* Attribute for this dimension. */ 288 rtx values; /* List of attribute values used. */ 289 rtx current_value; /* Position in the list for the TRUE value. */ 290 int num_values; /* Length of the values list. */ 291}; 292 293/* Other variables. */ 294 295static int insn_code_number; 296static int insn_index_number; 297static int got_define_asm_attributes; 298static int must_extract; 299static int must_constrain; 300static int address_used; 301static int length_used; 302static int num_delays; 303static int have_annul_true, have_annul_false; 304static int num_units, num_unit_opclasses; 305static int num_insn_ents; 306 307/* Used as operand to `operate_exp': */ 308 309enum operator {PLUS_OP, MINUS_OP, POS_MINUS_OP, EQ_OP, OR_OP, ORX_OP, MAX_OP, MIN_OP, RANGE_OP}; 310 311/* Stores, for each insn code, the number of constraint alternatives. */ 312 313static int *insn_n_alternatives; 314 315/* Stores, for each insn code, a bitmap that has bits on for each possible 316 alternative. */ 317 318static int *insn_alternatives; 319 320/* If nonzero, assume that the `alternative' attr has this value. 321 This is the hashed, unique string for the numeral 322 whose value is chosen alternative. */ 323 324static char *current_alternative_string; 325 326/* Used to simplify expressions. */ 327 328static rtx true_rtx, false_rtx; 329 330/* Used to reduce calls to `strcmp' */ 331 332static char *alternative_name; 333 334/* Indicate that REG_DEAD notes are valid if dead_or_set_p is ever 335 called. */ 336 337int reload_completed = 0; 338 339/* Some machines test `optimize' in macros called from rtlanal.c, so we need 340 to define it here. */ 341 342int optimize = 0; 343 344/* Simplify an expression. Only call the routine if there is something to 345 simplify. */ 346#define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX) \ 347 (RTX_UNCHANGING_P (EXP) || MEM_IN_STRUCT_P (EXP) ? (EXP) \ 348 : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX)) 349 350/* Simplify (eq_attr ("alternative") ...) 351 when we are working with a particular alternative. */ 352#define SIMPLIFY_ALTERNATIVE(EXP) \ 353 if (current_alternative_string \ 354 && GET_CODE ((EXP)) == EQ_ATTR \ 355 && XSTR ((EXP), 0) == alternative_name) \ 356 (EXP) = (XSTR ((EXP), 1) == current_alternative_string \ 357 ? true_rtx : false_rtx); 358 359/* These are referenced by rtlanal.c and hence need to be defined somewhere. 360 They won't actually be used. */ 361 362struct _global_rtl global_rtl; 363rtx pic_offset_table_rtx; 364 365static void attr_hash_add_rtx PROTO((int, rtx)); 366static void attr_hash_add_string PROTO((int, char *)); 367static rtx attr_rtx PVPROTO((enum rtx_code, ...)); 368static char *attr_printf PVPROTO((int, const char *, ...)) 369 ATTRIBUTE_PRINTF_2; 370static char *attr_string PROTO((const char *, int)); 371static rtx check_attr_test PROTO((rtx, int)); 372static rtx check_attr_value PROTO((rtx, struct attr_desc *)); 373static rtx convert_set_attr_alternative PROTO((rtx, int, int)); 374static rtx convert_set_attr PROTO((rtx, int, int)); 375static void check_defs PROTO((void)); 376#if 0 377static rtx convert_const_symbol_ref PROTO((rtx, struct attr_desc *)); 378#endif 379static rtx make_canonical PROTO((struct attr_desc *, rtx)); 380static struct attr_value *get_attr_value PROTO((rtx, struct attr_desc *, int)); 381static rtx copy_rtx_unchanging PROTO((rtx)); 382static rtx copy_boolean PROTO((rtx)); 383static void expand_delays PROTO((void)); 384static rtx operate_exp PROTO((enum operator, rtx, rtx)); 385static void expand_units PROTO((void)); 386static rtx simplify_knowing PROTO((rtx, rtx)); 387static rtx encode_units_mask PROTO((rtx)); 388static void fill_attr PROTO((struct attr_desc *)); 389/* dpx2 compiler chokes if we specify the arg types of the args. */ 390static rtx substitute_address PROTO((rtx, rtx (*) (), rtx (*) ())); 391static void make_length_attrs PROTO((void)); 392static rtx identity_fn PROTO((rtx)); 393static rtx zero_fn PROTO((rtx)); 394static rtx one_fn PROTO((rtx)); 395static rtx max_fn PROTO((rtx)); 396static void write_length_unit_log PROTO ((void)); 397static rtx simplify_cond PROTO((rtx, int, int)); 398#if 0 399static rtx simplify_by_alternatives PROTO((rtx, int, int)); 400#endif 401static rtx simplify_by_exploding PROTO((rtx)); 402static int find_and_mark_used_attributes PROTO((rtx, rtx *, int *)); 403static void unmark_used_attributes PROTO((rtx, struct dimension *, int)); 404static int add_values_to_cover PROTO((struct dimension *)); 405static int increment_current_value PROTO((struct dimension *, int)); 406static rtx test_for_current_value PROTO((struct dimension *, int)); 407static rtx simplify_with_current_value PROTO((rtx, struct dimension *, int)); 408static rtx simplify_with_current_value_aux PROTO((rtx)); 409static void clear_struct_flag PROTO((rtx)); 410static int count_sub_rtxs PROTO((rtx, int)); 411static void remove_insn_ent PROTO((struct attr_value *, struct insn_ent *)); 412static void insert_insn_ent PROTO((struct attr_value *, struct insn_ent *)); 413static rtx insert_right_side PROTO((enum rtx_code, rtx, rtx, int, int)); 414static rtx make_alternative_compare PROTO((int)); 415static int compute_alternative_mask PROTO((rtx, enum rtx_code)); 416static rtx evaluate_eq_attr PROTO((rtx, rtx, int, int)); 417static rtx simplify_and_tree PROTO((rtx, rtx *, int, int)); 418static rtx simplify_or_tree PROTO((rtx, rtx *, int, int)); 419static rtx simplify_test_exp PROTO((rtx, int, int)); 420static void optimize_attrs PROTO((void)); 421static void gen_attr PROTO((rtx)); 422static int count_alternatives PROTO((rtx)); 423static int compares_alternatives_p PROTO((rtx)); 424static int contained_in_p PROTO((rtx, rtx)); 425static void gen_insn PROTO((rtx)); 426static void gen_delay PROTO((rtx)); 427static void gen_unit PROTO((rtx)); 428static void write_test_expr PROTO((rtx, int)); 429static int max_attr_value PROTO((rtx, int*)); 430static int or_attr_value PROTO((rtx, int*)); 431static void walk_attr_value PROTO((rtx)); 432static void write_attr_get PROTO((struct attr_desc *)); 433static rtx eliminate_known_true PROTO((rtx, rtx, int, int)); 434static void write_attr_set PROTO((struct attr_desc *, int, rtx, 435 const char *, const char *, rtx, 436 int, int)); 437static void write_attr_case PROTO((struct attr_desc *, struct attr_value *, 438 int, const char *, const char *, int, rtx)); 439static void write_unit_name PROTO((const char *, int, const char *)); 440static void write_attr_valueq PROTO((struct attr_desc *, char *)); 441static void write_attr_value PROTO((struct attr_desc *, rtx)); 442static void write_upcase PROTO((char *)); 443static void write_indent PROTO((int)); 444static void write_eligible_delay PROTO((const char *)); 445static void write_function_unit_info PROTO((void)); 446static void write_complex_function PROTO((struct function_unit *, const char *, 447 const char *)); 448static int write_expr_attr_cache PROTO((rtx, struct attr_desc *)); 449static void write_toplevel_expr PROTO((rtx)); 450static int n_comma_elts PROTO((char *)); 451static char *next_comma_elt PROTO((char **)); 452static struct attr_desc *find_attr PROTO((const char *, int)); 453static void make_internal_attr PROTO((const char *, rtx, int)); 454static struct attr_value *find_most_used PROTO((struct attr_desc *)); 455static rtx find_single_value PROTO((struct attr_desc *)); 456static rtx make_numeric_value PROTO((int)); 457static void extend_range PROTO((struct range *, int, int)); 458 459#define oballoc(size) obstack_alloc (hash_obstack, size) 460 461 462/* Hash table for sharing RTL and strings. */ 463 464/* Each hash table slot is a bucket containing a chain of these structures. 465 Strings are given negative hash codes; RTL expressions are given positive 466 hash codes. */ 467 468struct attr_hash 469{ 470 struct attr_hash *next; /* Next structure in the bucket. */ 471 int hashcode; /* Hash code of this rtx or string. */ 472 union 473 { 474 char *str; /* The string (negative hash codes) */ 475 rtx rtl; /* or the RTL recorded here. */ 476 } u; 477}; 478 479/* Now here is the hash table. When recording an RTL, it is added to 480 the slot whose index is the hash code mod the table size. Note 481 that the hash table is used for several kinds of RTL (see attr_rtx) 482 and for strings. While all these live in the same table, they are 483 completely independent, and the hash code is computed differently 484 for each. */ 485 486#define RTL_HASH_SIZE 4093 487struct attr_hash *attr_hash_table[RTL_HASH_SIZE]; 488 489/* Here is how primitive or already-shared RTL's hash 490 codes are made. */ 491#define RTL_HASH(RTL) ((long) (RTL) & 0777777) 492 493/* Add an entry to the hash table for RTL with hash code HASHCODE. */ 494 495static void 496attr_hash_add_rtx (hashcode, rtl) 497 int hashcode; 498 rtx rtl; 499{ 500 register struct attr_hash *h; 501 502 h = (struct attr_hash *) obstack_alloc (hash_obstack, 503 sizeof (struct attr_hash)); 504 h->hashcode = hashcode; 505 h->u.rtl = rtl; 506 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE]; 507 attr_hash_table[hashcode % RTL_HASH_SIZE] = h; 508} 509 510/* Add an entry to the hash table for STRING with hash code HASHCODE. */ 511 512static void 513attr_hash_add_string (hashcode, str) 514 int hashcode; 515 char *str; 516{ 517 register struct attr_hash *h; 518 519 h = (struct attr_hash *) obstack_alloc (hash_obstack, 520 sizeof (struct attr_hash)); 521 h->hashcode = -hashcode; 522 h->u.str = str; 523 h->next = attr_hash_table[hashcode % RTL_HASH_SIZE]; 524 attr_hash_table[hashcode % RTL_HASH_SIZE] = h; 525} 526 527/* Generate an RTL expression, but avoid duplicates. 528 Set the RTX_INTEGRATED_P flag for these permanent objects. 529 530 In some cases we cannot uniquify; then we return an ordinary 531 impermanent rtx with RTX_INTEGRATED_P clear. 532 533 Args are like gen_rtx, but without the mode: 534 535 rtx attr_rtx (code, [element1, ..., elementn]) */ 536 537/*VARARGS1*/ 538static rtx 539attr_rtx VPROTO((enum rtx_code code, ...)) 540{ 541#ifndef ANSI_PROTOTYPES 542 enum rtx_code code; 543#endif 544 va_list p; 545 register int i; /* Array indices... */ 546 register char *fmt; /* Current rtx's format... */ 547 register rtx rt_val; /* RTX to return to caller... */ 548 int hashcode; 549 register struct attr_hash *h; 550 struct obstack *old_obstack = rtl_obstack; 551 552 VA_START (p, code); 553 554#ifndef ANSI_PROTOTYPES 555 code = va_arg (p, enum rtx_code); 556#endif 557 558 /* For each of several cases, search the hash table for an existing entry. 559 Use that entry if one is found; otherwise create a new RTL and add it 560 to the table. */ 561 562 if (GET_RTX_CLASS (code) == '1') 563 { 564 rtx arg0 = va_arg (p, rtx); 565 566 /* A permanent object cannot point to impermanent ones. */ 567 if (! RTX_INTEGRATED_P (arg0)) 568 { 569 rt_val = rtx_alloc (code); 570 XEXP (rt_val, 0) = arg0; 571 va_end (p); 572 return rt_val; 573 } 574 575 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0)); 576 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next) 577 if (h->hashcode == hashcode 578 && GET_CODE (h->u.rtl) == code 579 && XEXP (h->u.rtl, 0) == arg0) 580 goto found; 581 582 if (h == 0) 583 { 584 rtl_obstack = hash_obstack; 585 rt_val = rtx_alloc (code); 586 XEXP (rt_val, 0) = arg0; 587 } 588 } 589 else if (GET_RTX_CLASS (code) == 'c' 590 || GET_RTX_CLASS (code) == '2' 591 || GET_RTX_CLASS (code) == '<') 592 { 593 rtx arg0 = va_arg (p, rtx); 594 rtx arg1 = va_arg (p, rtx); 595 596 /* A permanent object cannot point to impermanent ones. */ 597 if (! RTX_INTEGRATED_P (arg0) || ! RTX_INTEGRATED_P (arg1)) 598 { 599 rt_val = rtx_alloc (code); 600 XEXP (rt_val, 0) = arg0; 601 XEXP (rt_val, 1) = arg1; 602 va_end (p); 603 return rt_val; 604 } 605 606 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1)); 607 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next) 608 if (h->hashcode == hashcode 609 && GET_CODE (h->u.rtl) == code 610 && XEXP (h->u.rtl, 0) == arg0 611 && XEXP (h->u.rtl, 1) == arg1) 612 goto found; 613 614 if (h == 0) 615 { 616 rtl_obstack = hash_obstack; 617 rt_val = rtx_alloc (code); 618 XEXP (rt_val, 0) = arg0; 619 XEXP (rt_val, 1) = arg1; 620 } 621 } 622 else if (GET_RTX_LENGTH (code) == 1 623 && GET_RTX_FORMAT (code)[0] == 's') 624 { 625 char * arg0 = va_arg (p, char *); 626 627 if (code == SYMBOL_REF) 628 arg0 = attr_string (arg0, strlen (arg0)); 629 630 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0)); 631 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next) 632 if (h->hashcode == hashcode 633 && GET_CODE (h->u.rtl) == code 634 && XSTR (h->u.rtl, 0) == arg0) 635 goto found; 636 637 if (h == 0) 638 { 639 rtl_obstack = hash_obstack; 640 rt_val = rtx_alloc (code); 641 XSTR (rt_val, 0) = arg0; 642 } 643 } 644 else if (GET_RTX_LENGTH (code) == 2 645 && GET_RTX_FORMAT (code)[0] == 's' 646 && GET_RTX_FORMAT (code)[1] == 's') 647 { 648 char *arg0 = va_arg (p, char *); 649 char *arg1 = va_arg (p, char *); 650 651 hashcode = ((HOST_WIDE_INT) code + RTL_HASH (arg0) + RTL_HASH (arg1)); 652 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next) 653 if (h->hashcode == hashcode 654 && GET_CODE (h->u.rtl) == code 655 && XSTR (h->u.rtl, 0) == arg0 656 && XSTR (h->u.rtl, 1) == arg1) 657 goto found; 658 659 if (h == 0) 660 { 661 rtl_obstack = hash_obstack; 662 rt_val = rtx_alloc (code); 663 XSTR (rt_val, 0) = arg0; 664 XSTR (rt_val, 1) = arg1; 665 } 666 } 667 else if (code == CONST_INT) 668 { 669 HOST_WIDE_INT arg0 = va_arg (p, HOST_WIDE_INT); 670 if (arg0 == 0) 671 return false_rtx; 672 if (arg0 == 1) 673 return true_rtx; 674 goto nohash; 675 } 676 else 677 { 678 nohash: 679 rt_val = rtx_alloc (code); /* Allocate the storage space. */ 680 681 fmt = GET_RTX_FORMAT (code); /* Find the right format... */ 682 for (i = 0; i < GET_RTX_LENGTH (code); i++) 683 { 684 switch (*fmt++) 685 { 686 case '0': /* Unused field. */ 687 break; 688 689 case 'i': /* An integer? */ 690 XINT (rt_val, i) = va_arg (p, int); 691 break; 692 693 case 'w': /* A wide integer? */ 694 XWINT (rt_val, i) = va_arg (p, HOST_WIDE_INT); 695 break; 696 697 case 's': /* A string? */ 698 XSTR (rt_val, i) = va_arg (p, char *); 699 break; 700 701 case 'e': /* An expression? */ 702 case 'u': /* An insn? Same except when printing. */ 703 XEXP (rt_val, i) = va_arg (p, rtx); 704 break; 705 706 case 'E': /* An RTX vector? */ 707 XVEC (rt_val, i) = va_arg (p, rtvec); 708 break; 709 710 default: 711 abort(); 712 } 713 } 714 va_end (p); 715 return rt_val; 716 } 717 718 rtl_obstack = old_obstack; 719 va_end (p); 720 attr_hash_add_rtx (hashcode, rt_val); 721 RTX_INTEGRATED_P (rt_val) = 1; 722 return rt_val; 723 724 found: 725 va_end (p); 726 return h->u.rtl; 727} 728 729/* Create a new string printed with the printf line arguments into a space 730 of at most LEN bytes: 731 732 rtx attr_printf (len, format, [arg1, ..., argn]) */ 733 734/*VARARGS2*/ 735static char * 736attr_printf VPROTO((register int len, const char *fmt, ...)) 737{ 738#ifndef ANSI_PROTOTYPES 739 register int len; 740 const char *fmt; 741#endif 742 va_list p; 743 register char *str; 744 745 VA_START (p, fmt); 746 747#ifndef ANSI_PROTOTYPES 748 len = va_arg (p, int); 749 fmt = va_arg (p, const char *); 750#endif 751 752 /* Print the string into a temporary location. */ 753 str = (char *) alloca (len); 754 vsprintf (str, fmt, p); 755 va_end (p); 756 757 return attr_string (str, strlen (str)); 758} 759 760rtx 761attr_eq (name, value) 762 char *name, *value; 763{ 764 return attr_rtx (EQ_ATTR, attr_string (name, strlen (name)), 765 attr_string (value, strlen (value))); 766} 767 768char * 769attr_numeral (n) 770 int n; 771{ 772 return XSTR (make_numeric_value (n), 0); 773} 774 775/* Return a permanent (possibly shared) copy of a string STR (not assumed 776 to be null terminated) with LEN bytes. */ 777 778static char * 779attr_string (str, len) 780 const char *str; 781 int len; 782{ 783 register struct attr_hash *h; 784 int hashcode; 785 int i; 786 register char *new_str; 787 788 /* Compute the hash code. */ 789 hashcode = (len + 1) * 613 + (unsigned)str[0]; 790 for (i = 1; i <= len; i += 2) 791 hashcode = ((hashcode * 613) + (unsigned)str[i]); 792 if (hashcode < 0) 793 hashcode = -hashcode; 794 795 /* Search the table for the string. */ 796 for (h = attr_hash_table[hashcode % RTL_HASH_SIZE]; h; h = h->next) 797 if (h->hashcode == -hashcode && h->u.str[0] == str[0] 798 && !strncmp (h->u.str, str, len)) 799 return h->u.str; /* <-- return if found. */ 800 801 /* Not found; create a permanent copy and add it to the hash table. */ 802 new_str = (char *) obstack_alloc (hash_obstack, len + 1); 803 bcopy (str, new_str, len); 804 new_str[len] = '\0'; 805 attr_hash_add_string (hashcode, new_str); 806 807 return new_str; /* Return the new string. */ 808} 809 810/* Check two rtx's for equality of contents, 811 taking advantage of the fact that if both are hashed 812 then they can't be equal unless they are the same object. */ 813 814int 815attr_equal_p (x, y) 816 rtx x, y; 817{ 818 return (x == y || (! (RTX_INTEGRATED_P (x) && RTX_INTEGRATED_P (y)) 819 && rtx_equal_p (x, y))); 820} 821 822/* Copy an attribute value expression, 823 descending to all depths, but not copying any 824 permanent hashed subexpressions. */ 825 826rtx 827attr_copy_rtx (orig) 828 register rtx orig; 829{ 830 register rtx copy; 831 register int i, j; 832 register RTX_CODE code; 833 register char *format_ptr; 834 835 /* No need to copy a permanent object. */ 836 if (RTX_INTEGRATED_P (orig)) 837 return orig; 838 839 code = GET_CODE (orig); 840 841 switch (code) 842 { 843 case REG: 844 case QUEUED: 845 case CONST_INT: 846 case CONST_DOUBLE: 847 case SYMBOL_REF: 848 case CODE_LABEL: 849 case PC: 850 case CC0: 851 return orig; 852 853 default: 854 break; 855 } 856 857 copy = rtx_alloc (code); 858 PUT_MODE (copy, GET_MODE (orig)); 859 copy->in_struct = orig->in_struct; 860 copy->volatil = orig->volatil; 861 copy->unchanging = orig->unchanging; 862 copy->integrated = orig->integrated; 863 864 format_ptr = GET_RTX_FORMAT (GET_CODE (copy)); 865 866 for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++) 867 { 868 switch (*format_ptr++) 869 { 870 case 'e': 871 XEXP (copy, i) = XEXP (orig, i); 872 if (XEXP (orig, i) != NULL) 873 XEXP (copy, i) = attr_copy_rtx (XEXP (orig, i)); 874 break; 875 876 case 'E': 877 case 'V': 878 XVEC (copy, i) = XVEC (orig, i); 879 if (XVEC (orig, i) != NULL) 880 { 881 XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i)); 882 for (j = 0; j < XVECLEN (copy, i); j++) 883 XVECEXP (copy, i, j) = attr_copy_rtx (XVECEXP (orig, i, j)); 884 } 885 break; 886 887 case 'n': 888 case 'i': 889 XINT (copy, i) = XINT (orig, i); 890 break; 891 892 case 'w': 893 XWINT (copy, i) = XWINT (orig, i); 894 break; 895 896 case 's': 897 case 'S': 898 XSTR (copy, i) = XSTR (orig, i); 899 break; 900 901 default: 902 abort (); 903 } 904 } 905 return copy; 906} 907 908/* Given a test expression for an attribute, ensure it is validly formed. 909 IS_CONST indicates whether the expression is constant for each compiler 910 run (a constant expression may not test any particular insn). 911 912 Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..)) 913 and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")). Do the latter 914 test first so that (eq_attr "att" "!a1,a2,a3") works as expected. 915 916 Update the string address in EQ_ATTR expression to be the same used 917 in the attribute (or `alternative_name') to speed up subsequent 918 `find_attr' calls and eliminate most `strcmp' calls. 919 920 Return the new expression, if any. */ 921 922static rtx 923check_attr_test (exp, is_const) 924 rtx exp; 925 int is_const; 926{ 927 struct attr_desc *attr; 928 struct attr_value *av; 929 char *name_ptr, *p; 930 rtx orexp, newexp; 931 932 switch (GET_CODE (exp)) 933 { 934 case EQ_ATTR: 935 /* Handle negation test. */ 936 if (XSTR (exp, 1)[0] == '!') 937 return check_attr_test (attr_rtx (NOT, 938 attr_eq (XSTR (exp, 0), 939 &XSTR (exp, 1)[1])), 940 is_const); 941 942 else if (n_comma_elts (XSTR (exp, 1)) == 1) 943 { 944 attr = find_attr (XSTR (exp, 0), 0); 945 if (attr == NULL) 946 { 947 if (! strcmp (XSTR (exp, 0), "alternative")) 948 { 949 XSTR (exp, 0) = alternative_name; 950 /* This can't be simplified any further. */ 951 RTX_UNCHANGING_P (exp) = 1; 952 return exp; 953 } 954 else 955 fatal ("Unknown attribute `%s' in EQ_ATTR", XSTR (exp, 0)); 956 } 957 958 if (is_const && ! attr->is_const) 959 fatal ("Constant expression uses insn attribute `%s' in EQ_ATTR", 960 XSTR (exp, 0)); 961 962 /* Copy this just to make it permanent, 963 so expressions using it can be permanent too. */ 964 exp = attr_eq (XSTR (exp, 0), XSTR (exp, 1)); 965 966 /* It shouldn't be possible to simplify the value given to a 967 constant attribute, so don't expand this until it's time to 968 write the test expression. */ 969 if (attr->is_const) 970 RTX_UNCHANGING_P (exp) = 1; 971 972 if (attr->is_numeric) 973 { 974 for (p = XSTR (exp, 1); *p; p++) 975 if (*p < '0' || *p > '9') 976 fatal ("Attribute `%s' takes only numeric values", 977 XSTR (exp, 0)); 978 } 979 else 980 { 981 for (av = attr->first_value; av; av = av->next) 982 if (GET_CODE (av->value) == CONST_STRING 983 && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0))) 984 break; 985 986 if (av == NULL) 987 fatal ("Unknown value `%s' for `%s' attribute", 988 XSTR (exp, 1), XSTR (exp, 0)); 989 } 990 } 991 else 992 { 993 /* Make an IOR tree of the possible values. */ 994 orexp = false_rtx; 995 name_ptr = XSTR (exp, 1); 996 while ((p = next_comma_elt (&name_ptr)) != NULL) 997 { 998 newexp = attr_eq (XSTR (exp, 0), p); 999 orexp = insert_right_side (IOR, orexp, newexp, -2, -2); 1000 } 1001 1002 return check_attr_test (orexp, is_const); 1003 } 1004 break; 1005 1006 case ATTR_FLAG: 1007 break; 1008 1009 case CONST_INT: 1010 /* Either TRUE or FALSE. */ 1011 if (XWINT (exp, 0)) 1012 return true_rtx; 1013 else 1014 return false_rtx; 1015 1016 case IOR: 1017 case AND: 1018 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const); 1019 XEXP (exp, 1) = check_attr_test (XEXP (exp, 1), is_const); 1020 break; 1021 1022 case NOT: 1023 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), is_const); 1024 break; 1025 1026 case MATCH_INSN: 1027 case MATCH_OPERAND: 1028 if (is_const) 1029 fatal ("RTL operator \"%s\" not valid in constant attribute test", 1030 GET_RTX_NAME (GET_CODE (exp))); 1031 /* These cases can't be simplified. */ 1032 RTX_UNCHANGING_P (exp) = 1; 1033 break; 1034 1035 case LE: case LT: case GT: case GE: 1036 case LEU: case LTU: case GTU: case GEU: 1037 case NE: case EQ: 1038 if (GET_CODE (XEXP (exp, 0)) == SYMBOL_REF 1039 && GET_CODE (XEXP (exp, 1)) == SYMBOL_REF) 1040 exp = attr_rtx (GET_CODE (exp), 1041 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 0), 0)), 1042 attr_rtx (SYMBOL_REF, XSTR (XEXP (exp, 1), 0))); 1043 /* These cases can't be simplified. */ 1044 RTX_UNCHANGING_P (exp) = 1; 1045 break; 1046 1047 case SYMBOL_REF: 1048 if (is_const) 1049 { 1050 /* These cases are valid for constant attributes, but can't be 1051 simplified. */ 1052 exp = attr_rtx (SYMBOL_REF, XSTR (exp, 0)); 1053 RTX_UNCHANGING_P (exp) = 1; 1054 break; 1055 } 1056 default: 1057 fatal ("RTL operator \"%s\" not valid in attribute test", 1058 GET_RTX_NAME (GET_CODE (exp))); 1059 } 1060 1061 return exp; 1062} 1063 1064/* Given an expression, ensure that it is validly formed and that all named 1065 attribute values are valid for the given attribute. Issue a fatal error 1066 if not. If no attribute is specified, assume a numeric attribute. 1067 1068 Return a perhaps modified replacement expression for the value. */ 1069 1070static rtx 1071check_attr_value (exp, attr) 1072 rtx exp; 1073 struct attr_desc *attr; 1074{ 1075 struct attr_value *av; 1076 char *p; 1077 int i; 1078 1079 switch (GET_CODE (exp)) 1080 { 1081 case CONST_INT: 1082 if (attr && ! attr->is_numeric) 1083 fatal ("CONST_INT not valid for non-numeric `%s' attribute", 1084 attr->name); 1085 1086 if (INTVAL (exp) < 0 && ! attr->negative_ok) 1087 fatal ("Negative numeric value specified for `%s' attribute", 1088 attr->name); 1089 1090 break; 1091 1092 case CONST_STRING: 1093 if (! strcmp (XSTR (exp, 0), "*")) 1094 break; 1095 1096 if (attr == 0 || attr->is_numeric) 1097 { 1098 p = XSTR (exp, 0); 1099 if (attr && attr->negative_ok && *p == '-') 1100 p++; 1101 for (; *p; p++) 1102 if (*p > '9' || *p < '0') 1103 fatal ("Non-numeric value for numeric `%s' attribute", 1104 attr ? attr->name : "internal"); 1105 break; 1106 } 1107 1108 for (av = attr->first_value; av; av = av->next) 1109 if (GET_CODE (av->value) == CONST_STRING 1110 && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0))) 1111 break; 1112 1113 if (av == NULL) 1114 fatal ("Unknown value `%s' for `%s' attribute", 1115 XSTR (exp, 0), attr ? attr->name : "internal"); 1116 1117 break; 1118 1119 case IF_THEN_ELSE: 1120 XEXP (exp, 0) = check_attr_test (XEXP (exp, 0), 1121 attr ? attr->is_const : 0); 1122 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr); 1123 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr); 1124 break; 1125 1126 case PLUS: 1127 case MINUS: 1128 case MULT: 1129 case DIV: 1130 case MOD: 1131 if (attr && !attr->is_numeric) 1132 fatal ("Invalid operation `%s' for non-numeric attribute value", 1133 GET_RTX_NAME (GET_CODE (exp))); 1134 /* FALLTHRU */ 1135 1136 case IOR: 1137 case AND: 1138 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr); 1139 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr); 1140 break; 1141 1142 case FFS: 1143 XEXP (exp, 0) = check_attr_value (XEXP (exp, 0), attr); 1144 break; 1145 1146 case COND: 1147 if (XVECLEN (exp, 0) % 2 != 0) 1148 fatal ("First operand of COND must have even length"); 1149 1150 for (i = 0; i < XVECLEN (exp, 0); i += 2) 1151 { 1152 XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i), 1153 attr ? attr->is_const : 0); 1154 XVECEXP (exp, 0, i + 1) 1155 = check_attr_value (XVECEXP (exp, 0, i + 1), attr); 1156 } 1157 1158 XEXP (exp, 1) = check_attr_value (XEXP (exp, 1), attr); 1159 break; 1160 1161 case ATTR: 1162 { 1163 struct attr_desc *attr2 = find_attr (XSTR (exp, 0), 0); 1164 if (attr2 == NULL) 1165 fatal ("Unknown attribute `%s' in ATTR", XSTR (exp, 0)); 1166 else if ((attr && attr->is_const) && ! attr2->is_const) 1167 fatal ("Non-constant attribute `%s' referenced from `%s'", 1168 XSTR (exp, 0), attr->name); 1169 else if (attr 1170 && (attr->is_numeric != attr2->is_numeric 1171 || (! attr->negative_ok && attr2->negative_ok))) 1172 fatal ("Numeric attribute mismatch calling `%s' from `%s'", 1173 XSTR (exp, 0), attr->name); 1174 } 1175 break; 1176 1177 case SYMBOL_REF: 1178 /* A constant SYMBOL_REF is valid as a constant attribute test and 1179 is expanded later by make_canonical into a COND. In a non-constant 1180 attribute test, it is left be. */ 1181 return attr_rtx (SYMBOL_REF, XSTR (exp, 0)); 1182 1183 default: 1184 fatal ("Invalid operation `%s' for attribute value", 1185 GET_RTX_NAME (GET_CODE (exp))); 1186 } 1187 1188 return exp; 1189} 1190 1191/* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET. 1192 It becomes a COND with each test being (eq_attr "alternative "n") */ 1193 1194static rtx 1195convert_set_attr_alternative (exp, num_alt, insn_index) 1196 rtx exp; 1197 int num_alt; 1198 int insn_index; 1199{ 1200 rtx condexp; 1201 int i; 1202 1203 if (XVECLEN (exp, 1) != num_alt) 1204 fatal ("Bad number of entries in SET_ATTR_ALTERNATIVE for insn %d", 1205 insn_index); 1206 1207 /* Make a COND with all tests but the last. Select the last value via the 1208 default. */ 1209 condexp = rtx_alloc (COND); 1210 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2); 1211 1212 for (i = 0; i < num_alt - 1; i++) 1213 { 1214 char *p; 1215 p = attr_numeral (i); 1216 1217 XVECEXP (condexp, 0, 2 * i) = attr_eq (alternative_name, p); 1218#if 0 1219 /* Sharing this EQ_ATTR rtl causes trouble. */ 1220 XVECEXP (condexp, 0, 2 * i) = rtx_alloc (EQ_ATTR); 1221 XSTR (XVECEXP (condexp, 0, 2 * i), 0) = alternative_name; 1222 XSTR (XVECEXP (condexp, 0, 2 * i), 1) = p; 1223#endif 1224 XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i); 1225 } 1226 1227 XEXP (condexp, 1) = XVECEXP (exp, 1, i); 1228 1229 return attr_rtx (SET, attr_rtx (ATTR, XSTR (exp, 0)), condexp); 1230} 1231 1232/* Given a SET_ATTR, convert to the appropriate SET. If a comma-separated 1233 list of values is given, convert to SET_ATTR_ALTERNATIVE first. */ 1234 1235static rtx 1236convert_set_attr (exp, num_alt, insn_index) 1237 rtx exp; 1238 int num_alt; 1239 int insn_index; 1240{ 1241 rtx newexp; 1242 char *name_ptr; 1243 char *p; 1244 int n; 1245 1246 /* See how many alternative specified. */ 1247 n = n_comma_elts (XSTR (exp, 1)); 1248 if (n == 1) 1249 return attr_rtx (SET, 1250 attr_rtx (ATTR, XSTR (exp, 0)), 1251 attr_rtx (CONST_STRING, XSTR (exp, 1))); 1252 1253 newexp = rtx_alloc (SET_ATTR_ALTERNATIVE); 1254 XSTR (newexp, 0) = XSTR (exp, 0); 1255 XVEC (newexp, 1) = rtvec_alloc (n); 1256 1257 /* Process each comma-separated name. */ 1258 name_ptr = XSTR (exp, 1); 1259 n = 0; 1260 while ((p = next_comma_elt (&name_ptr)) != NULL) 1261 XVECEXP (newexp, 1, n++) = attr_rtx (CONST_STRING, p); 1262 1263 return convert_set_attr_alternative (newexp, num_alt, insn_index); 1264} 1265 1266/* Scan all definitions, checking for validity. Also, convert any SET_ATTR 1267 and SET_ATTR_ALTERNATIVE expressions to the corresponding SET 1268 expressions. */ 1269 1270static void 1271check_defs () 1272{ 1273 struct insn_def *id; 1274 struct attr_desc *attr; 1275 int i; 1276 rtx value; 1277 1278 for (id = defs; id; id = id->next) 1279 { 1280 if (XVEC (id->def, id->vec_idx) == NULL) 1281 continue; 1282 1283 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++) 1284 { 1285 value = XVECEXP (id->def, id->vec_idx, i); 1286 switch (GET_CODE (value)) 1287 { 1288 case SET: 1289 if (GET_CODE (XEXP (value, 0)) != ATTR) 1290 fatal ("Bad attribute set in pattern %d", id->insn_index); 1291 break; 1292 1293 case SET_ATTR_ALTERNATIVE: 1294 value = convert_set_attr_alternative (value, 1295 id->num_alternatives, 1296 id->insn_index); 1297 break; 1298 1299 case SET_ATTR: 1300 value = convert_set_attr (value, id->num_alternatives, 1301 id->insn_index); 1302 break; 1303 1304 default: 1305 fatal ("Invalid attribute code `%s' for pattern %d", 1306 GET_RTX_NAME (GET_CODE (value)), id->insn_index); 1307 } 1308 1309 if ((attr = find_attr (XSTR (XEXP (value, 0), 0), 0)) == NULL) 1310 fatal ("Unknown attribute `%s' for pattern number %d", 1311 XSTR (XEXP (value, 0), 0), id->insn_index); 1312 1313 XVECEXP (id->def, id->vec_idx, i) = value; 1314 XEXP (value, 1) = check_attr_value (XEXP (value, 1), attr); 1315 } 1316 } 1317} 1318 1319#if 0 1320/* Given a constant SYMBOL_REF expression, convert to a COND that 1321 explicitly tests each enumerated value. */ 1322 1323static rtx 1324convert_const_symbol_ref (exp, attr) 1325 rtx exp; 1326 struct attr_desc *attr; 1327{ 1328 rtx condexp; 1329 struct attr_value *av; 1330 int i; 1331 int num_alt = 0; 1332 1333 for (av = attr->first_value; av; av = av->next) 1334 num_alt++; 1335 1336 /* Make a COND with all tests but the last, and in the original order. 1337 Select the last value via the default. Note that the attr values 1338 are constructed in reverse order. */ 1339 1340 condexp = rtx_alloc (COND); 1341 XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2); 1342 av = attr->first_value; 1343 XEXP (condexp, 1) = av->value; 1344 1345 for (i = num_alt - 2; av = av->next, i >= 0; i--) 1346 { 1347 char *p, *string; 1348 rtx value; 1349 1350 string = p = (char *) oballoc (2 1351 + strlen (attr->name) 1352 + strlen (XSTR (av->value, 0))); 1353 strcpy (p, attr->name); 1354 strcat (p, "_"); 1355 strcat (p, XSTR (av->value, 0)); 1356 for (; *p != '\0'; p++) 1357 if (*p >= 'a' && *p <= 'z') 1358 *p -= 'a' - 'A'; 1359 1360 value = attr_rtx (SYMBOL_REF, string); 1361 RTX_UNCHANGING_P (value) = 1; 1362 1363 XVECEXP (condexp, 0, 2 * i) = attr_rtx (EQ, exp, value); 1364 1365 XVECEXP (condexp, 0, 2 * i + 1) = av->value; 1366 } 1367 1368 return condexp; 1369} 1370#endif 1371 1372/* Given a valid expression for an attribute value, remove any IF_THEN_ELSE 1373 expressions by converting them into a COND. This removes cases from this 1374 program. Also, replace an attribute value of "*" with the default attribute 1375 value. */ 1376 1377static rtx 1378make_canonical (attr, exp) 1379 struct attr_desc *attr; 1380 rtx exp; 1381{ 1382 int i; 1383 rtx newexp; 1384 1385 switch (GET_CODE (exp)) 1386 { 1387 case CONST_INT: 1388 exp = make_numeric_value (INTVAL (exp)); 1389 break; 1390 1391 case CONST_STRING: 1392 if (! strcmp (XSTR (exp, 0), "*")) 1393 { 1394 if (attr == 0 || attr->default_val == 0) 1395 fatal ("(attr_value \"*\") used in invalid context."); 1396 exp = attr->default_val->value; 1397 } 1398 1399 break; 1400 1401 case SYMBOL_REF: 1402 if (!attr->is_const || RTX_UNCHANGING_P (exp)) 1403 break; 1404 /* The SYMBOL_REF is constant for a given run, so mark it as unchanging. 1405 This makes the COND something that won't be considered an arbitrary 1406 expression by walk_attr_value. */ 1407 RTX_UNCHANGING_P (exp) = 1; 1408#if 0 1409 /* ??? Why do we do this? With attribute values { A B C D E }, this 1410 tends to generate (!(x==A) && !(x==B) && !(x==C) && !(x==D)) rather 1411 than (x==E). */ 1412 exp = convert_const_symbol_ref (exp, attr); 1413 RTX_UNCHANGING_P (exp) = 1; 1414 exp = check_attr_value (exp, attr); 1415 /* Goto COND case since this is now a COND. Note that while the 1416 new expression is rescanned, all symbol_ref notes are marked as 1417 unchanging. */ 1418 goto cond; 1419#else 1420 exp = check_attr_value (exp, attr); 1421 break; 1422#endif 1423 1424 case IF_THEN_ELSE: 1425 newexp = rtx_alloc (COND); 1426 XVEC (newexp, 0) = rtvec_alloc (2); 1427 XVECEXP (newexp, 0, 0) = XEXP (exp, 0); 1428 XVECEXP (newexp, 0, 1) = XEXP (exp, 1); 1429 1430 XEXP (newexp, 1) = XEXP (exp, 2); 1431 1432 exp = newexp; 1433 /* Fall through to COND case since this is now a COND. */ 1434 1435 case COND: 1436 { 1437 int allsame = 1; 1438 rtx defval; 1439 1440 /* First, check for degenerate COND. */ 1441 if (XVECLEN (exp, 0) == 0) 1442 return make_canonical (attr, XEXP (exp, 1)); 1443 defval = XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1)); 1444 1445 for (i = 0; i < XVECLEN (exp, 0); i += 2) 1446 { 1447 XVECEXP (exp, 0, i) = copy_boolean (XVECEXP (exp, 0, i)); 1448 XVECEXP (exp, 0, i + 1) 1449 = make_canonical (attr, XVECEXP (exp, 0, i + 1)); 1450 if (! rtx_equal_p (XVECEXP (exp, 0, i + 1), defval)) 1451 allsame = 0; 1452 } 1453 if (allsame) 1454 return defval; 1455 } 1456 break; 1457 1458 default: 1459 break; 1460 } 1461 1462 return exp; 1463} 1464 1465static rtx 1466copy_boolean (exp) 1467 rtx exp; 1468{ 1469 if (GET_CODE (exp) == AND || GET_CODE (exp) == IOR) 1470 return attr_rtx (GET_CODE (exp), copy_boolean (XEXP (exp, 0)), 1471 copy_boolean (XEXP (exp, 1))); 1472 return exp; 1473} 1474 1475/* Given a value and an attribute description, return a `struct attr_value *' 1476 that represents that value. This is either an existing structure, if the 1477 value has been previously encountered, or a newly-created structure. 1478 1479 `insn_code' is the code of an insn whose attribute has the specified 1480 value (-2 if not processing an insn). We ensure that all insns for 1481 a given value have the same number of alternatives if the value checks 1482 alternatives. */ 1483 1484static struct attr_value * 1485get_attr_value (value, attr, insn_code) 1486 rtx value; 1487 struct attr_desc *attr; 1488 int insn_code; 1489{ 1490 struct attr_value *av; 1491 int num_alt = 0; 1492 1493 value = make_canonical (attr, value); 1494 if (compares_alternatives_p (value)) 1495 { 1496 if (insn_code < 0 || insn_alternatives == NULL) 1497 fatal ("(eq_attr \"alternatives\" ...) used in non-insn context"); 1498 else 1499 num_alt = insn_alternatives[insn_code]; 1500 } 1501 1502 for (av = attr->first_value; av; av = av->next) 1503 if (rtx_equal_p (value, av->value) 1504 && (num_alt == 0 || av->first_insn == NULL 1505 || insn_alternatives[av->first_insn->insn_code])) 1506 return av; 1507 1508 av = (struct attr_value *) oballoc (sizeof (struct attr_value)); 1509 av->value = value; 1510 av->next = attr->first_value; 1511 attr->first_value = av; 1512 av->first_insn = NULL; 1513 av->num_insns = 0; 1514 av->has_asm_insn = 0; 1515 1516 return av; 1517} 1518 1519/* After all DEFINE_DELAYs have been read in, create internal attributes 1520 to generate the required routines. 1521 1522 First, we compute the number of delay slots for each insn (as a COND of 1523 each of the test expressions in DEFINE_DELAYs). Then, if more than one 1524 delay type is specified, we compute a similar function giving the 1525 DEFINE_DELAY ordinal for each insn. 1526 1527 Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that 1528 tells whether a given insn can be in that delay slot. 1529 1530 Normal attribute filling and optimization expands these to contain the 1531 information needed to handle delay slots. */ 1532 1533static void 1534expand_delays () 1535{ 1536 struct delay_desc *delay; 1537 rtx condexp; 1538 rtx newexp; 1539 int i; 1540 char *p; 1541 1542 /* First, generate data for `num_delay_slots' function. */ 1543 1544 condexp = rtx_alloc (COND); 1545 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2); 1546 XEXP (condexp, 1) = make_numeric_value (0); 1547 1548 for (i = 0, delay = delays; delay; i += 2, delay = delay->next) 1549 { 1550 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0); 1551 XVECEXP (condexp, 0, i + 1) 1552 = make_numeric_value (XVECLEN (delay->def, 1) / 3); 1553 } 1554 1555 make_internal_attr ("*num_delay_slots", condexp, 0); 1556 1557 /* If more than one delay type, do the same for computing the delay type. */ 1558 if (num_delays > 1) 1559 { 1560 condexp = rtx_alloc (COND); 1561 XVEC (condexp, 0) = rtvec_alloc (num_delays * 2); 1562 XEXP (condexp, 1) = make_numeric_value (0); 1563 1564 for (i = 0, delay = delays; delay; i += 2, delay = delay->next) 1565 { 1566 XVECEXP (condexp, 0, i) = XEXP (delay->def, 0); 1567 XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num); 1568 } 1569 1570 make_internal_attr ("*delay_type", condexp, 1); 1571 } 1572 1573 /* For each delay possibility and delay slot, compute an eligibility 1574 attribute for non-annulled insns and for each type of annulled (annul 1575 if true and annul if false). */ 1576 for (delay = delays; delay; delay = delay->next) 1577 { 1578 for (i = 0; i < XVECLEN (delay->def, 1); i += 3) 1579 { 1580 condexp = XVECEXP (delay->def, 1, i); 1581 if (condexp == 0) condexp = false_rtx; 1582 newexp = attr_rtx (IF_THEN_ELSE, condexp, 1583 make_numeric_value (1), make_numeric_value (0)); 1584 1585 p = attr_printf (sizeof ("*delay__") + MAX_DIGITS*2, "*delay_%d_%d", 1586 delay->num, i / 3); 1587 make_internal_attr (p, newexp, 1); 1588 1589 if (have_annul_true) 1590 { 1591 condexp = XVECEXP (delay->def, 1, i + 1); 1592 if (condexp == 0) condexp = false_rtx; 1593 newexp = attr_rtx (IF_THEN_ELSE, condexp, 1594 make_numeric_value (1), 1595 make_numeric_value (0)); 1596 p = attr_printf (sizeof ("*annul_true__") + MAX_DIGITS*2, 1597 "*annul_true_%d_%d", delay->num, i / 3); 1598 make_internal_attr (p, newexp, 1); 1599 } 1600 1601 if (have_annul_false) 1602 { 1603 condexp = XVECEXP (delay->def, 1, i + 2); 1604 if (condexp == 0) condexp = false_rtx; 1605 newexp = attr_rtx (IF_THEN_ELSE, condexp, 1606 make_numeric_value (1), 1607 make_numeric_value (0)); 1608 p = attr_printf (sizeof ("*annul_false__") + MAX_DIGITS*2, 1609 "*annul_false_%d_%d", delay->num, i / 3); 1610 make_internal_attr (p, newexp, 1); 1611 } 1612 } 1613 } 1614} 1615 1616/* This function is given a left and right side expression and an operator. 1617 Each side is a conditional expression, each alternative of which has a 1618 numerical value. The function returns another conditional expression 1619 which, for every possible set of condition values, returns a value that is 1620 the operator applied to the values of the two sides. 1621 1622 Since this is called early, it must also support IF_THEN_ELSE. */ 1623 1624static rtx 1625operate_exp (op, left, right) 1626 enum operator op; 1627 rtx left, right; 1628{ 1629 int left_value, right_value; 1630 rtx newexp; 1631 int i; 1632 1633 /* If left is a string, apply operator to it and the right side. */ 1634 if (GET_CODE (left) == CONST_STRING) 1635 { 1636 /* If right is also a string, just perform the operation. */ 1637 if (GET_CODE (right) == CONST_STRING) 1638 { 1639 left_value = atoi (XSTR (left, 0)); 1640 right_value = atoi (XSTR (right, 0)); 1641 switch (op) 1642 { 1643 case PLUS_OP: 1644 i = left_value + right_value; 1645 break; 1646 1647 case MINUS_OP: 1648 i = left_value - right_value; 1649 break; 1650 1651 case POS_MINUS_OP: /* The positive part of LEFT - RIGHT. */ 1652 if (left_value > right_value) 1653 i = left_value - right_value; 1654 else 1655 i = 0; 1656 break; 1657 1658 case OR_OP: 1659 case ORX_OP: 1660 i = left_value | right_value; 1661 break; 1662 1663 case EQ_OP: 1664 i = left_value == right_value; 1665 break; 1666 1667 case RANGE_OP: 1668 i = (left_value << (HOST_BITS_PER_INT / 2)) | right_value; 1669 break; 1670 1671 case MAX_OP: 1672 if (left_value > right_value) 1673 i = left_value; 1674 else 1675 i = right_value; 1676 break; 1677 1678 case MIN_OP: 1679 if (left_value < right_value) 1680 i = left_value; 1681 else 1682 i = right_value; 1683 break; 1684 1685 default: 1686 abort (); 1687 } 1688 1689 if (i == left_value) 1690 return left; 1691 if (i == right_value) 1692 return right; 1693 return make_numeric_value (i); 1694 } 1695 else if (GET_CODE (right) == IF_THEN_ELSE) 1696 { 1697 /* Apply recursively to all values within. */ 1698 rtx newleft = operate_exp (op, left, XEXP (right, 1)); 1699 rtx newright = operate_exp (op, left, XEXP (right, 2)); 1700 if (rtx_equal_p (newleft, newright)) 1701 return newleft; 1702 return attr_rtx (IF_THEN_ELSE, XEXP (right, 0), newleft, newright); 1703 } 1704 else if (GET_CODE (right) == COND) 1705 { 1706 int allsame = 1; 1707 rtx defval; 1708 1709 newexp = rtx_alloc (COND); 1710 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (right, 0)); 1711 defval = XEXP (newexp, 1) = operate_exp (op, left, XEXP (right, 1)); 1712 1713 for (i = 0; i < XVECLEN (right, 0); i += 2) 1714 { 1715 XVECEXP (newexp, 0, i) = XVECEXP (right, 0, i); 1716 XVECEXP (newexp, 0, i + 1) 1717 = operate_exp (op, left, XVECEXP (right, 0, i + 1)); 1718 if (! rtx_equal_p (XVECEXP (newexp, 0, i + 1), 1719 defval)) 1720 allsame = 0; 1721 } 1722 1723 /* If the resulting cond is trivial (all alternatives 1724 give the same value), optimize it away. */ 1725 if (allsame) 1726 { 1727 obstack_free (rtl_obstack, newexp); 1728 return operate_exp (op, left, XEXP (right, 1)); 1729 } 1730 1731 /* If the result is the same as the RIGHT operand, 1732 just use that. */ 1733 if (rtx_equal_p (newexp, right)) 1734 { 1735 obstack_free (rtl_obstack, newexp); 1736 return right; 1737 } 1738 1739 return newexp; 1740 } 1741 else 1742 fatal ("Badly formed attribute value"); 1743 } 1744 1745 /* A hack to prevent expand_units from completely blowing up: ORX_OP does 1746 not associate through IF_THEN_ELSE. */ 1747 else if (op == ORX_OP && GET_CODE (right) == IF_THEN_ELSE) 1748 { 1749 return attr_rtx (IOR, left, right); 1750 } 1751 1752 /* Otherwise, do recursion the other way. */ 1753 else if (GET_CODE (left) == IF_THEN_ELSE) 1754 { 1755 rtx newleft = operate_exp (op, XEXP (left, 1), right); 1756 rtx newright = operate_exp (op, XEXP (left, 2), right); 1757 if (rtx_equal_p (newleft, newright)) 1758 return newleft; 1759 return attr_rtx (IF_THEN_ELSE, XEXP (left, 0), newleft, newright); 1760 } 1761 else if (GET_CODE (left) == COND) 1762 { 1763 int allsame = 1; 1764 rtx defval; 1765 1766 newexp = rtx_alloc (COND); 1767 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (left, 0)); 1768 defval = XEXP (newexp, 1) = operate_exp (op, XEXP (left, 1), right); 1769 1770 for (i = 0; i < XVECLEN (left, 0); i += 2) 1771 { 1772 XVECEXP (newexp, 0, i) = XVECEXP (left, 0, i); 1773 XVECEXP (newexp, 0, i + 1) 1774 = operate_exp (op, XVECEXP (left, 0, i + 1), right); 1775 if (! rtx_equal_p (XVECEXP (newexp, 0, i + 1), 1776 defval)) 1777 allsame = 0; 1778 } 1779 1780 /* If the cond is trivial (all alternatives give the same value), 1781 optimize it away. */ 1782 if (allsame) 1783 { 1784 obstack_free (rtl_obstack, newexp); 1785 return operate_exp (op, XEXP (left, 1), right); 1786 } 1787 1788 /* If the result is the same as the LEFT operand, 1789 just use that. */ 1790 if (rtx_equal_p (newexp, left)) 1791 { 1792 obstack_free (rtl_obstack, newexp); 1793 return left; 1794 } 1795 1796 return newexp; 1797 } 1798 1799 else 1800 fatal ("Badly formed attribute value."); 1801 /* NOTREACHED */ 1802 return NULL; 1803} 1804 1805/* Once all attributes and DEFINE_FUNCTION_UNITs have been read, we 1806 construct a number of attributes. 1807 1808 The first produces a function `function_units_used' which is given an 1809 insn and produces an encoding showing which function units are required 1810 for the execution of that insn. If the value is non-negative, the insn 1811 uses that unit; otherwise, the value is a one's compliment mask of units 1812 used. 1813 1814 The second produces a function `result_ready_cost' which is used to 1815 determine the time that the result of an insn will be ready and hence 1816 a worst-case schedule. 1817 1818 Both of these produce quite complex expressions which are then set as the 1819 default value of internal attributes. Normal attribute simplification 1820 should produce reasonable expressions. 1821 1822 For each unit, a `<name>_unit_ready_cost' function will take an 1823 insn and give the delay until that unit will be ready with the result 1824 and a `<name>_unit_conflict_cost' function is given an insn already 1825 executing on the unit and a candidate to execute and will give the 1826 cost from the time the executing insn started until the candidate 1827 can start (ignore limitations on the number of simultaneous insns). 1828 1829 For each unit, a `<name>_unit_blockage' function is given an insn 1830 already executing on the unit and a candidate to execute and will 1831 give the delay incurred due to function unit conflicts. The range of 1832 blockage cost values for a given executing insn is given by the 1833 `<name>_unit_blockage_range' function. These values are encoded in 1834 an int where the upper half gives the minimum value and the lower 1835 half gives the maximum value. */ 1836 1837static void 1838expand_units () 1839{ 1840 struct function_unit *unit, **unit_num; 1841 struct function_unit_op *op, **op_array, ***unit_ops; 1842 rtx unitsmask; 1843 rtx readycost; 1844 rtx newexp; 1845 const char *str; 1846 int i, j, u, num, nvalues; 1847 1848 /* Rebuild the condition for the unit to share the RTL expressions. 1849 Sharing is required by simplify_by_exploding. Build the issue delay 1850 expressions. Validate the expressions we were given for the conditions 1851 and conflict vector. Then make attributes for use in the conflict 1852 function. */ 1853 1854 for (unit = units; unit; unit = unit->next) 1855 { 1856 unit->condexp = check_attr_test (unit->condexp, 0); 1857 1858 for (op = unit->ops; op; op = op->next) 1859 { 1860 rtx issue_delay = make_numeric_value (op->issue_delay); 1861 rtx issue_exp = issue_delay; 1862 1863 /* Build, validate, and simplify the issue delay expression. */ 1864 if (op->conflict_exp != true_rtx) 1865 issue_exp = attr_rtx (IF_THEN_ELSE, op->conflict_exp, 1866 issue_exp, make_numeric_value (0)); 1867 issue_exp = check_attr_value (make_canonical (NULL_ATTR, 1868 issue_exp), 1869 NULL_ATTR); 1870 issue_exp = simplify_knowing (issue_exp, unit->condexp); 1871 op->issue_exp = issue_exp; 1872 1873 /* Make an attribute for use in the conflict function if needed. */ 1874 unit->needs_conflict_function = (unit->issue_delay.min 1875 != unit->issue_delay.max); 1876 if (unit->needs_conflict_function) 1877 { 1878 str = attr_printf (strlen (unit->name) + sizeof ("*_cost_") + MAX_DIGITS, 1879 "*%s_cost_%d", unit->name, op->num); 1880 make_internal_attr (str, issue_exp, 1); 1881 } 1882 1883 /* Validate the condition. */ 1884 op->condexp = check_attr_test (op->condexp, 0); 1885 } 1886 } 1887 1888 /* Compute the mask of function units used. Initially, the unitsmask is 1889 zero. Set up a conditional to compute each unit's contribution. */ 1890 unitsmask = make_numeric_value (0); 1891 newexp = rtx_alloc (IF_THEN_ELSE); 1892 XEXP (newexp, 2) = make_numeric_value (0); 1893 1894 /* If we have just a few units, we may be all right expanding the whole 1895 thing. But the expansion is 2**N in space on the number of opclasses, 1896 so we can't do this for very long -- Alpha and MIPS in particular have 1897 problems with this. So in that situation, we fall back on an alternate 1898 implementation method. */ 1899#define NUM_UNITOP_CUTOFF 20 1900 1901 if (num_unit_opclasses < NUM_UNITOP_CUTOFF) 1902 { 1903 /* Merge each function unit into the unit mask attributes. */ 1904 for (unit = units; unit; unit = unit->next) 1905 { 1906 XEXP (newexp, 0) = unit->condexp; 1907 XEXP (newexp, 1) = make_numeric_value (1 << unit->num); 1908 unitsmask = operate_exp (OR_OP, unitsmask, newexp); 1909 } 1910 } 1911 else 1912 { 1913 /* Merge each function unit into the unit mask attributes. */ 1914 for (unit = units; unit; unit = unit->next) 1915 { 1916 XEXP (newexp, 0) = unit->condexp; 1917 XEXP (newexp, 1) = make_numeric_value (1 << unit->num); 1918 unitsmask = operate_exp (ORX_OP, unitsmask, attr_copy_rtx (newexp)); 1919 } 1920 } 1921 1922 /* Simplify the unit mask expression, encode it, and make an attribute 1923 for the function_units_used function. */ 1924 unitsmask = simplify_by_exploding (unitsmask); 1925 1926 if (num_unit_opclasses < NUM_UNITOP_CUTOFF) 1927 unitsmask = encode_units_mask (unitsmask); 1928 else 1929 { 1930 /* We can no longer encode unitsmask at compile time, so emit code to 1931 calculate it at runtime. Rather, put a marker for where we'd do 1932 the code, and actually output it in write_attr_get(). */ 1933 unitsmask = attr_rtx (FFS, unitsmask); 1934 } 1935 1936 make_internal_attr ("*function_units_used", unitsmask, 10); 1937 1938 /* Create an array of ops for each unit. Add an extra unit for the 1939 result_ready_cost function that has the ops of all other units. */ 1940 unit_ops = (struct function_unit_op ***) 1941 alloca ((num_units + 1) * sizeof (struct function_unit_op **)); 1942 unit_num = (struct function_unit **) 1943 alloca ((num_units + 1) * sizeof (struct function_unit *)); 1944 1945 unit_num[num_units] = unit = (struct function_unit *) 1946 alloca (sizeof (struct function_unit)); 1947 unit->num = num_units; 1948 unit->num_opclasses = 0; 1949 1950 for (unit = units; unit; unit = unit->next) 1951 { 1952 unit_num[num_units]->num_opclasses += unit->num_opclasses; 1953 unit_num[unit->num] = unit; 1954 unit_ops[unit->num] = op_array = (struct function_unit_op **) 1955 alloca (unit->num_opclasses * sizeof (struct function_unit_op *)); 1956 1957 for (op = unit->ops; op; op = op->next) 1958 op_array[op->num] = op; 1959 } 1960 1961 /* Compose the array of ops for the extra unit. */ 1962 unit_ops[num_units] = op_array = (struct function_unit_op **) 1963 alloca (unit_num[num_units]->num_opclasses 1964 * sizeof (struct function_unit_op *)); 1965 1966 for (unit = units, i = 0; unit; i += unit->num_opclasses, unit = unit->next) 1967 bcopy ((char *) unit_ops[unit->num], (char *) &op_array[i], 1968 unit->num_opclasses * sizeof (struct function_unit_op *)); 1969 1970 /* Compute the ready cost function for each unit by computing the 1971 condition for each non-default value. */ 1972 for (u = 0; u <= num_units; u++) 1973 { 1974 rtx orexp; 1975 int value; 1976 1977 unit = unit_num[u]; 1978 op_array = unit_ops[unit->num]; 1979 num = unit->num_opclasses; 1980 1981 /* Sort the array of ops into increasing ready cost order. */ 1982 for (i = 0; i < num; i++) 1983 for (j = num - 1; j > i; j--) 1984 if (op_array[j-1]->ready < op_array[j]->ready) 1985 { 1986 op = op_array[j]; 1987 op_array[j] = op_array[j-1]; 1988 op_array[j-1] = op; 1989 } 1990 1991 /* Determine how many distinct non-default ready cost values there 1992 are. We use a default ready cost value of 1. */ 1993 nvalues = 0; value = 1; 1994 for (i = num - 1; i >= 0; i--) 1995 if (op_array[i]->ready > value) 1996 { 1997 value = op_array[i]->ready; 1998 nvalues++; 1999 } 2000 2001 if (nvalues == 0) 2002 readycost = make_numeric_value (1); 2003 else 2004 { 2005 /* Construct the ready cost expression as a COND of each value from 2006 the largest to the smallest. */ 2007 readycost = rtx_alloc (COND); 2008 XVEC (readycost, 0) = rtvec_alloc (nvalues * 2); 2009 XEXP (readycost, 1) = make_numeric_value (1); 2010 2011 nvalues = 0; orexp = false_rtx; value = op_array[0]->ready; 2012 for (i = 0; i < num; i++) 2013 { 2014 op = op_array[i]; 2015 if (op->ready <= 1) 2016 break; 2017 else if (op->ready == value) 2018 orexp = insert_right_side (IOR, orexp, op->condexp, -2, -2); 2019 else 2020 { 2021 XVECEXP (readycost, 0, nvalues * 2) = orexp; 2022 XVECEXP (readycost, 0, nvalues * 2 + 1) 2023 = make_numeric_value (value); 2024 nvalues++; 2025 value = op->ready; 2026 orexp = op->condexp; 2027 } 2028 } 2029 XVECEXP (readycost, 0, nvalues * 2) = orexp; 2030 XVECEXP (readycost, 0, nvalues * 2 + 1) = make_numeric_value (value); 2031 } 2032 2033 if (u < num_units) 2034 { 2035 rtx max_blockage = 0, min_blockage = 0; 2036 2037 /* Simplify the readycost expression by only considering insns 2038 that use the unit. */ 2039 readycost = simplify_knowing (readycost, unit->condexp); 2040 2041 /* Determine the blockage cost the executing insn (E) given 2042 the candidate insn (C). This is the maximum of the issue 2043 delay, the pipeline delay, and the simultaneity constraint. 2044 Each function_unit_op represents the characteristics of the 2045 candidate insn, so in the expressions below, C is a known 2046 term and E is an unknown term. 2047 2048 We compute the blockage cost for each E for every possible C. 2049 Thus OP represents E, and READYCOST is a list of values for 2050 every possible C. 2051 2052 The issue delay function for C is op->issue_exp and is used to 2053 write the `<name>_unit_conflict_cost' function. Symbolicly 2054 this is "ISSUE-DELAY (E,C)". 2055 2056 The pipeline delay results form the FIFO constraint on the 2057 function unit and is "READY-COST (E) + 1 - READY-COST (C)". 2058 2059 The simultaneity constraint is based on how long it takes to 2060 fill the unit given the minimum issue delay. FILL-TIME is the 2061 constant "MIN (ISSUE-DELAY (*,*)) * (SIMULTANEITY - 1)", and 2062 the simultaneity constraint is "READY-COST (E) - FILL-TIME" 2063 if SIMULTANEITY is non-zero and zero otherwise. 2064 2065 Thus, BLOCKAGE (E,C) when SIMULTANEITY is zero is 2066 2067 MAX (ISSUE-DELAY (E,C), 2068 READY-COST (E) - (READY-COST (C) - 1)) 2069 2070 and otherwise 2071 2072 MAX (ISSUE-DELAY (E,C), 2073 READY-COST (E) - (READY-COST (C) - 1), 2074 READY-COST (E) - FILL-TIME) 2075 2076 The `<name>_unit_blockage' function is computed by determining 2077 this value for each candidate insn. As these values are 2078 computed, we also compute the upper and lower bounds for 2079 BLOCKAGE (E,*). These are combined to form the function 2080 `<name>_unit_blockage_range'. Finally, the maximum blockage 2081 cost, MAX (BLOCKAGE (*,*)), is computed. */ 2082 2083 for (op = unit->ops; op; op = op->next) 2084 { 2085#ifdef HAIFA 2086 rtx blockage = op->issue_exp; 2087#else 2088 rtx blockage = operate_exp (POS_MINUS_OP, readycost, 2089 make_numeric_value (1)); 2090 2091 if (unit->simultaneity != 0) 2092 { 2093 rtx filltime = make_numeric_value ((unit->simultaneity - 1) 2094 * unit->issue_delay.min); 2095 blockage = operate_exp (MIN_OP, blockage, filltime); 2096 } 2097 2098 blockage = operate_exp (POS_MINUS_OP, 2099 make_numeric_value (op->ready), 2100 blockage); 2101 2102 blockage = operate_exp (MAX_OP, blockage, op->issue_exp); 2103#endif 2104 blockage = simplify_knowing (blockage, unit->condexp); 2105 2106 /* Add this op's contribution to MAX (BLOCKAGE (E,*)) and 2107 MIN (BLOCKAGE (E,*)). */ 2108 if (max_blockage == 0) 2109 max_blockage = min_blockage = blockage; 2110 else 2111 { 2112 max_blockage 2113 = simplify_knowing (operate_exp (MAX_OP, max_blockage, 2114 blockage), 2115 unit->condexp); 2116 min_blockage 2117 = simplify_knowing (operate_exp (MIN_OP, min_blockage, 2118 blockage), 2119 unit->condexp); 2120 } 2121 2122 /* Make an attribute for use in the blockage function. */ 2123 str = attr_printf (strlen (unit->name) + sizeof ("*_block_") + MAX_DIGITS, 2124 "*%s_block_%d", unit->name, op->num); 2125 make_internal_attr (str, blockage, 1); 2126 } 2127 2128 /* Record MAX (BLOCKAGE (*,*)). */ 2129 { 2130 int unknown; 2131 unit->max_blockage = max_attr_value (max_blockage, &unknown); 2132 } 2133 2134 /* See if the upper and lower bounds of BLOCKAGE (E,*) are the 2135 same. If so, the blockage function carries no additional 2136 information and is not written. */ 2137 newexp = operate_exp (EQ_OP, max_blockage, min_blockage); 2138 newexp = simplify_knowing (newexp, unit->condexp); 2139 unit->needs_blockage_function 2140 = (GET_CODE (newexp) != CONST_STRING 2141 || atoi (XSTR (newexp, 0)) != 1); 2142 2143 /* If the all values of BLOCKAGE (E,C) have the same value, 2144 neither blockage function is written. */ 2145 unit->needs_range_function 2146 = (unit->needs_blockage_function 2147 || GET_CODE (max_blockage) != CONST_STRING); 2148 2149 if (unit->needs_range_function) 2150 { 2151 /* Compute the blockage range function and make an attribute 2152 for writing its value. */ 2153 newexp = operate_exp (RANGE_OP, min_blockage, max_blockage); 2154 newexp = simplify_knowing (newexp, unit->condexp); 2155 2156 str = attr_printf (strlen (unit->name) + sizeof ("*_unit_blockage_range"), 2157 "*%s_unit_blockage_range", unit->name); 2158 make_internal_attr (str, newexp, 20); 2159 } 2160 2161 str = attr_printf (strlen (unit->name) + sizeof ("*_unit_ready_cost"), 2162 "*%s_unit_ready_cost", unit->name); 2163 } 2164 else 2165 str = "*result_ready_cost"; 2166 2167 /* Make an attribute for the ready_cost function. Simplifying 2168 further with simplify_by_exploding doesn't win. */ 2169 make_internal_attr (str, readycost, 0); 2170 } 2171 2172 /* For each unit that requires a conflict cost function, make an attribute 2173 that maps insns to the operation number. */ 2174 for (unit = units; unit; unit = unit->next) 2175 { 2176 rtx caseexp; 2177 2178 if (! unit->needs_conflict_function 2179 && ! unit->needs_blockage_function) 2180 continue; 2181 2182 caseexp = rtx_alloc (COND); 2183 XVEC (caseexp, 0) = rtvec_alloc ((unit->num_opclasses - 1) * 2); 2184 2185 for (op = unit->ops; op; op = op->next) 2186 { 2187 /* Make our adjustment to the COND being computed. If we are the 2188 last operation class, place our values into the default of the 2189 COND. */ 2190 if (op->num == unit->num_opclasses - 1) 2191 { 2192 XEXP (caseexp, 1) = make_numeric_value (op->num); 2193 } 2194 else 2195 { 2196 XVECEXP (caseexp, 0, op->num * 2) = op->condexp; 2197 XVECEXP (caseexp, 0, op->num * 2 + 1) 2198 = make_numeric_value (op->num); 2199 } 2200 } 2201 2202 /* Simplifying caseexp with simplify_by_exploding doesn't win. */ 2203 str = attr_printf (strlen (unit->name) + sizeof ("*_cases"), 2204 "*%s_cases", unit->name); 2205 make_internal_attr (str, caseexp, 1); 2206 } 2207} 2208 2209/* Simplify EXP given KNOWN_TRUE. */ 2210 2211static rtx 2212simplify_knowing (exp, known_true) 2213 rtx exp, known_true; 2214{ 2215 if (GET_CODE (exp) != CONST_STRING) 2216 { 2217 int unknown = 0, max; 2218 max = max_attr_value (exp, &unknown); 2219 if (! unknown) 2220 { 2221 exp = attr_rtx (IF_THEN_ELSE, known_true, exp, 2222 make_numeric_value (max)); 2223 exp = simplify_by_exploding (exp); 2224 } 2225 } 2226 return exp; 2227} 2228 2229/* Translate the CONST_STRING expressions in X to change the encoding of 2230 value. On input, the value is a bitmask with a one bit for each unit 2231 used; on output, the value is the unit number (zero based) if one 2232 and only one unit is used or the one's compliment of the bitmask. */ 2233 2234static rtx 2235encode_units_mask (x) 2236 rtx x; 2237{ 2238 register int i; 2239 register int j; 2240 register enum rtx_code code; 2241 register char *fmt; 2242 2243 code = GET_CODE (x); 2244 2245 switch (code) 2246 { 2247 case CONST_STRING: 2248 i = atoi (XSTR (x, 0)); 2249 if (i < 0) 2250 abort (); /* The sign bit encodes a one's compliment mask. */ 2251 else if (i != 0 && i == (i & -i)) 2252 /* Only one bit is set, so yield that unit number. */ 2253 for (j = 0; (i >>= 1) != 0; j++) 2254 ; 2255 else 2256 j = ~i; 2257 return attr_rtx (CONST_STRING, attr_printf (MAX_DIGITS, "%d", j)); 2258 2259 case REG: 2260 case QUEUED: 2261 case CONST_INT: 2262 case CONST_DOUBLE: 2263 case SYMBOL_REF: 2264 case CODE_LABEL: 2265 case PC: 2266 case CC0: 2267 case EQ_ATTR: 2268 return x; 2269 2270 default: 2271 break; 2272 } 2273 2274 /* Compare the elements. If any pair of corresponding elements 2275 fail to match, return 0 for the whole things. */ 2276 2277 fmt = GET_RTX_FORMAT (code); 2278 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 2279 { 2280 switch (fmt[i]) 2281 { 2282 case 'V': 2283 case 'E': 2284 for (j = 0; j < XVECLEN (x, i); j++) 2285 XVECEXP (x, i, j) = encode_units_mask (XVECEXP (x, i, j)); 2286 break; 2287 2288 case 'e': 2289 XEXP (x, i) = encode_units_mask (XEXP (x, i)); 2290 break; 2291 } 2292 } 2293 return x; 2294} 2295 2296/* Once all attributes and insns have been read and checked, we construct for 2297 each attribute value a list of all the insns that have that value for 2298 the attribute. */ 2299 2300static void 2301fill_attr (attr) 2302 struct attr_desc *attr; 2303{ 2304 struct attr_value *av; 2305 struct insn_ent *ie; 2306 struct insn_def *id; 2307 int i; 2308 rtx value; 2309 2310 /* Don't fill constant attributes. The value is independent of 2311 any particular insn. */ 2312 if (attr->is_const) 2313 return; 2314 2315 for (id = defs; id; id = id->next) 2316 { 2317 /* If no value is specified for this insn for this attribute, use the 2318 default. */ 2319 value = NULL; 2320 if (XVEC (id->def, id->vec_idx)) 2321 for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++) 2322 if (! strcmp (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0), 2323 attr->name)) 2324 value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1); 2325 2326 if (value == NULL) 2327 av = attr->default_val; 2328 else 2329 av = get_attr_value (value, attr, id->insn_code); 2330 2331 ie = (struct insn_ent *) oballoc (sizeof (struct insn_ent)); 2332 ie->insn_code = id->insn_code; 2333 ie->insn_index = id->insn_code; 2334 insert_insn_ent (av, ie); 2335 } 2336} 2337 2338/* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a 2339 test that checks relative positions of insns (uses MATCH_DUP or PC). 2340 If so, replace it with what is obtained by passing the expression to 2341 ADDRESS_FN. If not but it is a COND or IF_THEN_ELSE, call this routine 2342 recursively on each value (including the default value). Otherwise, 2343 return the value returned by NO_ADDRESS_FN applied to EXP. */ 2344 2345static rtx 2346substitute_address (exp, no_address_fn, address_fn) 2347 rtx exp; 2348 rtx (*no_address_fn) (); 2349 rtx (*address_fn) (); 2350{ 2351 int i; 2352 rtx newexp; 2353 2354 if (GET_CODE (exp) == COND) 2355 { 2356 /* See if any tests use addresses. */ 2357 address_used = 0; 2358 for (i = 0; i < XVECLEN (exp, 0); i += 2) 2359 walk_attr_value (XVECEXP (exp, 0, i)); 2360 2361 if (address_used) 2362 return (*address_fn) (exp); 2363 2364 /* Make a new copy of this COND, replacing each element. */ 2365 newexp = rtx_alloc (COND); 2366 XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0)); 2367 for (i = 0; i < XVECLEN (exp, 0); i += 2) 2368 { 2369 XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i); 2370 XVECEXP (newexp, 0, i + 1) 2371 = substitute_address (XVECEXP (exp, 0, i + 1), 2372 no_address_fn, address_fn); 2373 } 2374 2375 XEXP (newexp, 1) = substitute_address (XEXP (exp, 1), 2376 no_address_fn, address_fn); 2377 2378 return newexp; 2379 } 2380 2381 else if (GET_CODE (exp) == IF_THEN_ELSE) 2382 { 2383 address_used = 0; 2384 walk_attr_value (XEXP (exp, 0)); 2385 if (address_used) 2386 return (*address_fn) (exp); 2387 2388 return attr_rtx (IF_THEN_ELSE, 2389 substitute_address (XEXP (exp, 0), 2390 no_address_fn, address_fn), 2391 substitute_address (XEXP (exp, 1), 2392 no_address_fn, address_fn), 2393 substitute_address (XEXP (exp, 2), 2394 no_address_fn, address_fn)); 2395 } 2396 2397 return (*no_address_fn) (exp); 2398} 2399 2400/* Make new attributes from the `length' attribute. The following are made, 2401 each corresponding to a function called from `shorten_branches' or 2402 `get_attr_length': 2403 2404 *insn_default_length This is the length of the insn to be returned 2405 by `get_attr_length' before `shorten_branches' 2406 has been called. In each case where the length 2407 depends on relative addresses, the largest 2408 possible is used. This routine is also used 2409 to compute the initial size of the insn. 2410 2411 *insn_variable_length_p This returns 1 if the insn's length depends 2412 on relative addresses, zero otherwise. 2413 2414 *insn_current_length This is only called when it is known that the 2415 insn has a variable length and returns the 2416 current length, based on relative addresses. 2417 */ 2418 2419static void 2420make_length_attrs () 2421{ 2422 static const char *new_names[] = {"*insn_default_length", 2423 "*insn_variable_length_p", 2424 "*insn_current_length"}; 2425 static rtx (*no_address_fn[]) PROTO((rtx)) = {identity_fn, zero_fn, zero_fn}; 2426 static rtx (*address_fn[]) PROTO((rtx)) = {max_fn, one_fn, identity_fn}; 2427 size_t i; 2428 struct attr_desc *length_attr, *new_attr; 2429 struct attr_value *av, *new_av; 2430 struct insn_ent *ie, *new_ie; 2431 2432 /* See if length attribute is defined. If so, it must be numeric. Make 2433 it special so we don't output anything for it. */ 2434 length_attr = find_attr ("length", 0); 2435 if (length_attr == 0) 2436 return; 2437 2438 if (! length_attr->is_numeric) 2439 fatal ("length attribute must be numeric."); 2440 2441 length_attr->is_const = 0; 2442 length_attr->is_special = 1; 2443 2444 /* Make each new attribute, in turn. */ 2445 for (i = 0; i < sizeof new_names / sizeof new_names[0]; i++) 2446 { 2447 make_internal_attr (new_names[i], 2448 substitute_address (length_attr->default_val->value, 2449 no_address_fn[i], address_fn[i]), 2450 0); 2451 new_attr = find_attr (new_names[i], 0); 2452 for (av = length_attr->first_value; av; av = av->next) 2453 for (ie = av->first_insn; ie; ie = ie->next) 2454 { 2455 new_av = get_attr_value (substitute_address (av->value, 2456 no_address_fn[i], 2457 address_fn[i]), 2458 new_attr, ie->insn_code); 2459 new_ie = (struct insn_ent *) oballoc (sizeof (struct insn_ent)); 2460 new_ie->insn_code = ie->insn_code; 2461 new_ie->insn_index = ie->insn_index; 2462 insert_insn_ent (new_av, new_ie); 2463 } 2464 } 2465} 2466 2467/* Utility functions called from above routine. */ 2468 2469static rtx 2470identity_fn (exp) 2471 rtx exp; 2472{ 2473 return exp; 2474} 2475 2476static rtx 2477zero_fn (exp) 2478 rtx exp ATTRIBUTE_UNUSED; 2479{ 2480 return make_numeric_value (0); 2481} 2482 2483static rtx 2484one_fn (exp) 2485 rtx exp ATTRIBUTE_UNUSED; 2486{ 2487 return make_numeric_value (1); 2488} 2489 2490static rtx 2491max_fn (exp) 2492 rtx exp; 2493{ 2494 int unknown; 2495 return make_numeric_value (max_attr_value (exp, &unknown)); 2496} 2497 2498static void 2499write_length_unit_log () 2500{ 2501 struct attr_desc *length_attr = find_attr ("length", 0); 2502 struct attr_value *av; 2503 struct insn_ent *ie; 2504 unsigned int length_unit_log, length_or; 2505 int unknown = 0; 2506 2507 if (length_attr == 0) 2508 return; 2509 length_or = or_attr_value (length_attr->default_val->value, &unknown); 2510 for (av = length_attr->first_value; av; av = av->next) 2511 for (ie = av->first_insn; ie; ie = ie->next) 2512 length_or |= or_attr_value (av->value, &unknown); 2513 2514 if (unknown) 2515 length_unit_log = 0; 2516 else 2517 { 2518 length_or = ~length_or; 2519 for (length_unit_log = 0; length_or & 1; length_or >>= 1) 2520 length_unit_log++; 2521 } 2522 printf ("int length_unit_log = %u;\n", length_unit_log); 2523} 2524 2525/* Take a COND expression and see if any of the conditions in it can be 2526 simplified. If any are known true or known false for the particular insn 2527 code, the COND can be further simplified. 2528 2529 Also call ourselves on any COND operations that are values of this COND. 2530 2531 We do not modify EXP; rather, we make and return a new rtx. */ 2532 2533static rtx 2534simplify_cond (exp, insn_code, insn_index) 2535 rtx exp; 2536 int insn_code, insn_index; 2537{ 2538 int i, j; 2539 /* We store the desired contents here, 2540 then build a new expression if they don't match EXP. */ 2541 rtx defval = XEXP (exp, 1); 2542 rtx new_defval = XEXP (exp, 1); 2543 int len = XVECLEN (exp, 0); 2544 rtunion *tests = (rtunion *) alloca (len * sizeof (rtunion)); 2545 int allsame = 1; 2546 char *first_spacer; 2547 2548 /* This lets us free all storage allocated below, if appropriate. */ 2549 first_spacer = (char *) obstack_finish (rtl_obstack); 2550 2551 bcopy ((char *) XVEC (exp, 0)->elem, (char *) tests, len * sizeof (rtunion)); 2552 2553 /* See if default value needs simplification. */ 2554 if (GET_CODE (defval) == COND) 2555 new_defval = simplify_cond (defval, insn_code, insn_index); 2556 2557 /* Simplify the subexpressions, and see what tests we can get rid of. */ 2558 2559 for (i = 0; i < len; i += 2) 2560 { 2561 rtx newtest, newval; 2562 2563 /* Simplify this test. */ 2564 newtest = SIMPLIFY_TEST_EXP (tests[i].rtx, insn_code, insn_index); 2565 tests[i].rtx = newtest; 2566 2567 newval = tests[i + 1].rtx; 2568 /* See if this value may need simplification. */ 2569 if (GET_CODE (newval) == COND) 2570 newval = simplify_cond (newval, insn_code, insn_index); 2571 2572 /* Look for ways to delete or combine this test. */ 2573 if (newtest == true_rtx) 2574 { 2575 /* If test is true, make this value the default 2576 and discard this + any following tests. */ 2577 len = i; 2578 defval = tests[i + 1].rtx; 2579 new_defval = newval; 2580 } 2581 2582 else if (newtest == false_rtx) 2583 { 2584 /* If test is false, discard it and its value. */ 2585 for (j = i; j < len - 2; j++) 2586 tests[j].rtx = tests[j + 2].rtx; 2587 len -= 2; 2588 } 2589 2590 else if (i > 0 && attr_equal_p (newval, tests[i - 1].rtx)) 2591 { 2592 /* If this value and the value for the prev test are the same, 2593 merge the tests. */ 2594 2595 tests[i - 2].rtx 2596 = insert_right_side (IOR, tests[i - 2].rtx, newtest, 2597 insn_code, insn_index); 2598 2599 /* Delete this test/value. */ 2600 for (j = i; j < len - 2; j++) 2601 tests[j].rtx = tests[j + 2].rtx; 2602 len -= 2; 2603 } 2604 2605 else 2606 tests[i + 1].rtx = newval; 2607 } 2608 2609 /* If the last test in a COND has the same value 2610 as the default value, that test isn't needed. */ 2611 2612 while (len > 0 && attr_equal_p (tests[len - 1].rtx, new_defval)) 2613 len -= 2; 2614 2615 /* See if we changed anything. */ 2616 if (len != XVECLEN (exp, 0) || new_defval != XEXP (exp, 1)) 2617 allsame = 0; 2618 else 2619 for (i = 0; i < len; i++) 2620 if (! attr_equal_p (tests[i].rtx, XVECEXP (exp, 0, i))) 2621 { 2622 allsame = 0; 2623 break; 2624 } 2625 2626 if (len == 0) 2627 { 2628 obstack_free (rtl_obstack, first_spacer); 2629 if (GET_CODE (defval) == COND) 2630 return simplify_cond (defval, insn_code, insn_index); 2631 return defval; 2632 } 2633 else if (allsame) 2634 { 2635 obstack_free (rtl_obstack, first_spacer); 2636 return exp; 2637 } 2638 else 2639 { 2640 rtx newexp = rtx_alloc (COND); 2641 2642 XVEC (newexp, 0) = rtvec_alloc (len); 2643 bcopy ((char *) tests, (char *) XVEC (newexp, 0)->elem, 2644 len * sizeof (rtunion)); 2645 XEXP (newexp, 1) = new_defval; 2646 return newexp; 2647 } 2648} 2649 2650/* Remove an insn entry from an attribute value. */ 2651 2652static void 2653remove_insn_ent (av, ie) 2654 struct attr_value *av; 2655 struct insn_ent *ie; 2656{ 2657 struct insn_ent *previe; 2658 2659 if (av->first_insn == ie) 2660 av->first_insn = ie->next; 2661 else 2662 { 2663 for (previe = av->first_insn; previe->next != ie; previe = previe->next) 2664 ; 2665 previe->next = ie->next; 2666 } 2667 2668 av->num_insns--; 2669 if (ie->insn_code == -1) 2670 av->has_asm_insn = 0; 2671 2672 num_insn_ents--; 2673} 2674 2675/* Insert an insn entry in an attribute value list. */ 2676 2677static void 2678insert_insn_ent (av, ie) 2679 struct attr_value *av; 2680 struct insn_ent *ie; 2681{ 2682 ie->next = av->first_insn; 2683 av->first_insn = ie; 2684 av->num_insns++; 2685 if (ie->insn_code == -1) 2686 av->has_asm_insn = 1; 2687 2688 num_insn_ents++; 2689} 2690 2691/* This is a utility routine to take an expression that is a tree of either 2692 AND or IOR expressions and insert a new term. The new term will be 2693 inserted at the right side of the first node whose code does not match 2694 the root. A new node will be created with the root's code. Its left 2695 side will be the old right side and its right side will be the new 2696 term. 2697 2698 If the `term' is itself a tree, all its leaves will be inserted. */ 2699 2700static rtx 2701insert_right_side (code, exp, term, insn_code, insn_index) 2702 enum rtx_code code; 2703 rtx exp; 2704 rtx term; 2705 int insn_code, insn_index; 2706{ 2707 rtx newexp; 2708 2709 /* Avoid consing in some special cases. */ 2710 if (code == AND && term == true_rtx) 2711 return exp; 2712 if (code == AND && term == false_rtx) 2713 return false_rtx; 2714 if (code == AND && exp == true_rtx) 2715 return term; 2716 if (code == AND && exp == false_rtx) 2717 return false_rtx; 2718 if (code == IOR && term == true_rtx) 2719 return true_rtx; 2720 if (code == IOR && term == false_rtx) 2721 return exp; 2722 if (code == IOR && exp == true_rtx) 2723 return true_rtx; 2724 if (code == IOR && exp == false_rtx) 2725 return term; 2726 if (attr_equal_p (exp, term)) 2727 return exp; 2728 2729 if (GET_CODE (term) == code) 2730 { 2731 exp = insert_right_side (code, exp, XEXP (term, 0), 2732 insn_code, insn_index); 2733 exp = insert_right_side (code, exp, XEXP (term, 1), 2734 insn_code, insn_index); 2735 2736 return exp; 2737 } 2738 2739 if (GET_CODE (exp) == code) 2740 { 2741 rtx new = insert_right_side (code, XEXP (exp, 1), 2742 term, insn_code, insn_index); 2743 if (new != XEXP (exp, 1)) 2744 /* Make a copy of this expression and call recursively. */ 2745 newexp = attr_rtx (code, XEXP (exp, 0), new); 2746 else 2747 newexp = exp; 2748 } 2749 else 2750 { 2751 /* Insert the new term. */ 2752 newexp = attr_rtx (code, exp, term); 2753 } 2754 2755 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); 2756} 2757 2758/* If we have an expression which AND's a bunch of 2759 (not (eq_attrq "alternative" "n")) 2760 terms, we may have covered all or all but one of the possible alternatives. 2761 If so, we can optimize. Similarly for IOR's of EQ_ATTR. 2762 2763 This routine is passed an expression and either AND or IOR. It returns a 2764 bitmask indicating which alternatives are mentioned within EXP. */ 2765 2766static int 2767compute_alternative_mask (exp, code) 2768 rtx exp; 2769 enum rtx_code code; 2770{ 2771 char *string; 2772 if (GET_CODE (exp) == code) 2773 return compute_alternative_mask (XEXP (exp, 0), code) 2774 | compute_alternative_mask (XEXP (exp, 1), code); 2775 2776 else if (code == AND && GET_CODE (exp) == NOT 2777 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR 2778 && XSTR (XEXP (exp, 0), 0) == alternative_name) 2779 string = XSTR (XEXP (exp, 0), 1); 2780 2781 else if (code == IOR && GET_CODE (exp) == EQ_ATTR 2782 && XSTR (exp, 0) == alternative_name) 2783 string = XSTR (exp, 1); 2784 2785 else 2786 return 0; 2787 2788 if (string[1] == 0) 2789 return 1 << (string[0] - '0'); 2790 return 1 << atoi (string); 2791} 2792 2793/* Given I, a single-bit mask, return RTX to compare the `alternative' 2794 attribute with the value represented by that bit. */ 2795 2796static rtx 2797make_alternative_compare (mask) 2798 int mask; 2799{ 2800 rtx newexp; 2801 int i; 2802 2803 /* Find the bit. */ 2804 for (i = 0; (mask & (1 << i)) == 0; i++) 2805 ; 2806 2807 newexp = attr_rtx (EQ_ATTR, alternative_name, attr_numeral (i)); 2808 RTX_UNCHANGING_P (newexp) = 1; 2809 2810 return newexp; 2811} 2812 2813/* If we are processing an (eq_attr "attr" "value") test, we find the value 2814 of "attr" for this insn code. From that value, we can compute a test 2815 showing when the EQ_ATTR will be true. This routine performs that 2816 computation. If a test condition involves an address, we leave the EQ_ATTR 2817 intact because addresses are only valid for the `length' attribute. 2818 2819 EXP is the EQ_ATTR expression and VALUE is the value of that attribute 2820 for the insn corresponding to INSN_CODE and INSN_INDEX. */ 2821 2822static rtx 2823evaluate_eq_attr (exp, value, insn_code, insn_index) 2824 rtx exp; 2825 rtx value; 2826 int insn_code, insn_index; 2827{ 2828 rtx orexp, andexp; 2829 rtx right; 2830 rtx newexp; 2831 int i; 2832 2833 if (GET_CODE (value) == CONST_STRING) 2834 { 2835 if (! strcmp (XSTR (value, 0), XSTR (exp, 1))) 2836 newexp = true_rtx; 2837 else 2838 newexp = false_rtx; 2839 } 2840 else if (GET_CODE (value) == SYMBOL_REF) 2841 { 2842 char *p, *string; 2843 2844 if (GET_CODE (exp) != EQ_ATTR) 2845 abort(); 2846 2847 string = (char *) alloca (2 + strlen (XSTR (exp, 0)) 2848 + strlen (XSTR (exp, 1))); 2849 strcpy (string, XSTR (exp, 0)); 2850 strcat (string, "_"); 2851 strcat (string, XSTR (exp, 1)); 2852 for (p = string; *p ; p++) 2853 if (*p >= 'a' && *p <= 'z') 2854 *p -= 'a' - 'A'; 2855 2856 newexp = attr_rtx (EQ, value, 2857 attr_rtx (SYMBOL_REF, 2858 attr_string(string, strlen(string)))); 2859 } 2860 else if (GET_CODE (value) == COND) 2861 { 2862 /* We construct an IOR of all the cases for which the requested attribute 2863 value is present. Since we start with FALSE, if it is not present, 2864 FALSE will be returned. 2865 2866 Each case is the AND of the NOT's of the previous conditions with the 2867 current condition; in the default case the current condition is TRUE. 2868 2869 For each possible COND value, call ourselves recursively. 2870 2871 The extra TRUE and FALSE expressions will be eliminated by another 2872 call to the simplification routine. */ 2873 2874 orexp = false_rtx; 2875 andexp = true_rtx; 2876 2877 if (current_alternative_string) 2878 clear_struct_flag (value); 2879 2880 for (i = 0; i < XVECLEN (value, 0); i += 2) 2881 { 2882 rtx this = SIMPLIFY_TEST_EXP (XVECEXP (value, 0, i), 2883 insn_code, insn_index); 2884 2885 SIMPLIFY_ALTERNATIVE (this); 2886 2887 right = insert_right_side (AND, andexp, this, 2888 insn_code, insn_index); 2889 right = insert_right_side (AND, right, 2890 evaluate_eq_attr (exp, 2891 XVECEXP (value, 0, 2892 i + 1), 2893 insn_code, insn_index), 2894 insn_code, insn_index); 2895 orexp = insert_right_side (IOR, orexp, right, 2896 insn_code, insn_index); 2897 2898 /* Add this condition into the AND expression. */ 2899 newexp = attr_rtx (NOT, this); 2900 andexp = insert_right_side (AND, andexp, newexp, 2901 insn_code, insn_index); 2902 } 2903 2904 /* Handle the default case. */ 2905 right = insert_right_side (AND, andexp, 2906 evaluate_eq_attr (exp, XEXP (value, 1), 2907 insn_code, insn_index), 2908 insn_code, insn_index); 2909 newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index); 2910 } 2911 else 2912 abort (); 2913 2914 /* If uses an address, must return original expression. But set the 2915 RTX_UNCHANGING_P bit so we don't try to simplify it again. */ 2916 2917 address_used = 0; 2918 walk_attr_value (newexp); 2919 2920 if (address_used) 2921 { 2922 /* This had `&& current_alternative_string', which seems to be wrong. */ 2923 if (! RTX_UNCHANGING_P (exp)) 2924 return copy_rtx_unchanging (exp); 2925 return exp; 2926 } 2927 else 2928 return newexp; 2929} 2930 2931/* This routine is called when an AND of a term with a tree of AND's is 2932 encountered. If the term or its complement is present in the tree, it 2933 can be replaced with TRUE or FALSE, respectively. 2934 2935 Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both 2936 be true and hence are complementary. 2937 2938 There is one special case: If we see 2939 (and (not (eq_attr "att" "v1")) 2940 (eq_attr "att" "v2")) 2941 this can be replaced by (eq_attr "att" "v2"). To do this we need to 2942 replace the term, not anything in the AND tree. So we pass a pointer to 2943 the term. */ 2944 2945static rtx 2946simplify_and_tree (exp, pterm, insn_code, insn_index) 2947 rtx exp; 2948 rtx *pterm; 2949 int insn_code, insn_index; 2950{ 2951 rtx left, right; 2952 rtx newexp; 2953 rtx temp; 2954 int left_eliminates_term, right_eliminates_term; 2955 2956 if (GET_CODE (exp) == AND) 2957 { 2958 left = simplify_and_tree (XEXP (exp, 0), pterm, insn_code, insn_index); 2959 right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index); 2960 if (left != XEXP (exp, 0) || right != XEXP (exp, 1)) 2961 { 2962 newexp = attr_rtx (GET_CODE (exp), left, right); 2963 2964 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); 2965 } 2966 } 2967 2968 else if (GET_CODE (exp) == IOR) 2969 { 2970 /* For the IOR case, we do the same as above, except that we can 2971 only eliminate `term' if both sides of the IOR would do so. */ 2972 temp = *pterm; 2973 left = simplify_and_tree (XEXP (exp, 0), &temp, insn_code, insn_index); 2974 left_eliminates_term = (temp == true_rtx); 2975 2976 temp = *pterm; 2977 right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index); 2978 right_eliminates_term = (temp == true_rtx); 2979 2980 if (left_eliminates_term && right_eliminates_term) 2981 *pterm = true_rtx; 2982 2983 if (left != XEXP (exp, 0) || right != XEXP (exp, 1)) 2984 { 2985 newexp = attr_rtx (GET_CODE (exp), left, right); 2986 2987 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); 2988 } 2989 } 2990 2991 /* Check for simplifications. Do some extra checking here since this 2992 routine is called so many times. */ 2993 2994 if (exp == *pterm) 2995 return true_rtx; 2996 2997 else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm) 2998 return false_rtx; 2999 3000 else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0)) 3001 return false_rtx; 3002 3003 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR) 3004 { 3005 if (XSTR (exp, 0) != XSTR (*pterm, 0)) 3006 return exp; 3007 3008 if (! strcmp (XSTR (exp, 1), XSTR (*pterm, 1))) 3009 return true_rtx; 3010 else 3011 return false_rtx; 3012 } 3013 3014 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT 3015 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR) 3016 { 3017 if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0)) 3018 return exp; 3019 3020 if (! strcmp (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1))) 3021 return false_rtx; 3022 else 3023 return true_rtx; 3024 } 3025 3026 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT 3027 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR) 3028 { 3029 if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0)) 3030 return exp; 3031 3032 if (! strcmp (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1))) 3033 return false_rtx; 3034 else 3035 *pterm = true_rtx; 3036 } 3037 3038 else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT) 3039 { 3040 if (attr_equal_p (XEXP (exp, 0), XEXP (*pterm, 0))) 3041 return true_rtx; 3042 } 3043 3044 else if (GET_CODE (exp) == NOT) 3045 { 3046 if (attr_equal_p (XEXP (exp, 0), *pterm)) 3047 return false_rtx; 3048 } 3049 3050 else if (GET_CODE (*pterm) == NOT) 3051 { 3052 if (attr_equal_p (XEXP (*pterm, 0), exp)) 3053 return false_rtx; 3054 } 3055 3056 else if (attr_equal_p (exp, *pterm)) 3057 return true_rtx; 3058 3059 return exp; 3060} 3061 3062/* Similar to `simplify_and_tree', but for IOR trees. */ 3063 3064static rtx 3065simplify_or_tree (exp, pterm, insn_code, insn_index) 3066 rtx exp; 3067 rtx *pterm; 3068 int insn_code, insn_index; 3069{ 3070 rtx left, right; 3071 rtx newexp; 3072 rtx temp; 3073 int left_eliminates_term, right_eliminates_term; 3074 3075 if (GET_CODE (exp) == IOR) 3076 { 3077 left = simplify_or_tree (XEXP (exp, 0), pterm, insn_code, insn_index); 3078 right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index); 3079 if (left != XEXP (exp, 0) || right != XEXP (exp, 1)) 3080 { 3081 newexp = attr_rtx (GET_CODE (exp), left, right); 3082 3083 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); 3084 } 3085 } 3086 3087 else if (GET_CODE (exp) == AND) 3088 { 3089 /* For the AND case, we do the same as above, except that we can 3090 only eliminate `term' if both sides of the AND would do so. */ 3091 temp = *pterm; 3092 left = simplify_or_tree (XEXP (exp, 0), &temp, insn_code, insn_index); 3093 left_eliminates_term = (temp == false_rtx); 3094 3095 temp = *pterm; 3096 right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index); 3097 right_eliminates_term = (temp == false_rtx); 3098 3099 if (left_eliminates_term && right_eliminates_term) 3100 *pterm = false_rtx; 3101 3102 if (left != XEXP (exp, 0) || right != XEXP (exp, 1)) 3103 { 3104 newexp = attr_rtx (GET_CODE (exp), left, right); 3105 3106 exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); 3107 } 3108 } 3109 3110 if (attr_equal_p (exp, *pterm)) 3111 return false_rtx; 3112 3113 else if (GET_CODE (exp) == NOT && attr_equal_p (XEXP (exp, 0), *pterm)) 3114 return true_rtx; 3115 3116 else if (GET_CODE (*pterm) == NOT && attr_equal_p (XEXP (*pterm, 0), exp)) 3117 return true_rtx; 3118 3119 else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT 3120 && GET_CODE (XEXP (exp, 0)) == EQ_ATTR 3121 && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0)) 3122 *pterm = false_rtx; 3123 3124 else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT 3125 && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR 3126 && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0)) 3127 return false_rtx; 3128 3129 return exp; 3130} 3131 3132/* Given an expression, see if it can be simplified for a particular insn 3133 code based on the values of other attributes being tested. This can 3134 eliminate nested get_attr_... calls. 3135 3136 Note that if an endless recursion is specified in the patterns, the 3137 optimization will loop. However, it will do so in precisely the cases where 3138 an infinite recursion loop could occur during compilation. It's better that 3139 it occurs here! */ 3140 3141static rtx 3142simplify_test_exp (exp, insn_code, insn_index) 3143 rtx exp; 3144 int insn_code, insn_index; 3145{ 3146 rtx left, right; 3147 struct attr_desc *attr; 3148 struct attr_value *av; 3149 struct insn_ent *ie; 3150 int i; 3151 rtx newexp = exp; 3152 char *spacer = (char *) obstack_finish (rtl_obstack); 3153 3154 /* Don't re-simplify something we already simplified. */ 3155 if (RTX_UNCHANGING_P (exp) || MEM_IN_STRUCT_P (exp)) 3156 return exp; 3157 3158 switch (GET_CODE (exp)) 3159 { 3160 case AND: 3161 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index); 3162 SIMPLIFY_ALTERNATIVE (left); 3163 if (left == false_rtx) 3164 { 3165 obstack_free (rtl_obstack, spacer); 3166 return false_rtx; 3167 } 3168 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index); 3169 SIMPLIFY_ALTERNATIVE (right); 3170 if (left == false_rtx) 3171 { 3172 obstack_free (rtl_obstack, spacer); 3173 return false_rtx; 3174 } 3175 3176 /* If either side is an IOR and we have (eq_attr "alternative" ..") 3177 present on both sides, apply the distributive law since this will 3178 yield simplifications. */ 3179 if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR) 3180 && compute_alternative_mask (left, IOR) 3181 && compute_alternative_mask (right, IOR)) 3182 { 3183 if (GET_CODE (left) == IOR) 3184 { 3185 rtx tem = left; 3186 left = right; 3187 right = tem; 3188 } 3189 3190 newexp = attr_rtx (IOR, 3191 attr_rtx (AND, left, XEXP (right, 0)), 3192 attr_rtx (AND, left, XEXP (right, 1))); 3193 3194 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); 3195 } 3196 3197 /* Try with the term on both sides. */ 3198 right = simplify_and_tree (right, &left, insn_code, insn_index); 3199 if (left == XEXP (exp, 0) && right == XEXP (exp, 1)) 3200 left = simplify_and_tree (left, &right, insn_code, insn_index); 3201 3202 if (left == false_rtx || right == false_rtx) 3203 { 3204 obstack_free (rtl_obstack, spacer); 3205 return false_rtx; 3206 } 3207 else if (left == true_rtx) 3208 { 3209 return right; 3210 } 3211 else if (right == true_rtx) 3212 { 3213 return left; 3214 } 3215 /* See if all or all but one of the insn's alternatives are specified 3216 in this tree. Optimize if so. */ 3217 3218 else if (insn_code >= 0 3219 && (GET_CODE (left) == AND 3220 || (GET_CODE (left) == NOT 3221 && GET_CODE (XEXP (left, 0)) == EQ_ATTR 3222 && XSTR (XEXP (left, 0), 0) == alternative_name) 3223 || GET_CODE (right) == AND 3224 || (GET_CODE (right) == NOT 3225 && GET_CODE (XEXP (right, 0)) == EQ_ATTR 3226 && XSTR (XEXP (right, 0), 0) == alternative_name))) 3227 { 3228 i = compute_alternative_mask (exp, AND); 3229 if (i & ~insn_alternatives[insn_code]) 3230 fatal ("Invalid alternative specified for pattern number %d", 3231 insn_index); 3232 3233 /* If all alternatives are excluded, this is false. */ 3234 i ^= insn_alternatives[insn_code]; 3235 if (i == 0) 3236 return false_rtx; 3237 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1) 3238 { 3239 /* If just one excluded, AND a comparison with that one to the 3240 front of the tree. The others will be eliminated by 3241 optimization. We do not want to do this if the insn has one 3242 alternative and we have tested none of them! */ 3243 left = make_alternative_compare (i); 3244 right = simplify_and_tree (exp, &left, insn_code, insn_index); 3245 newexp = attr_rtx (AND, left, right); 3246 3247 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); 3248 } 3249 } 3250 3251 if (left != XEXP (exp, 0) || right != XEXP (exp, 1)) 3252 { 3253 newexp = attr_rtx (AND, left, right); 3254 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); 3255 } 3256 break; 3257 3258 case IOR: 3259 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index); 3260 SIMPLIFY_ALTERNATIVE (left); 3261 if (left == true_rtx) 3262 { 3263 obstack_free (rtl_obstack, spacer); 3264 return true_rtx; 3265 } 3266 right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index); 3267 SIMPLIFY_ALTERNATIVE (right); 3268 if (right == true_rtx) 3269 { 3270 obstack_free (rtl_obstack, spacer); 3271 return true_rtx; 3272 } 3273 3274 right = simplify_or_tree (right, &left, insn_code, insn_index); 3275 if (left == XEXP (exp, 0) && right == XEXP (exp, 1)) 3276 left = simplify_or_tree (left, &right, insn_code, insn_index); 3277 3278 if (right == true_rtx || left == true_rtx) 3279 { 3280 obstack_free (rtl_obstack, spacer); 3281 return true_rtx; 3282 } 3283 else if (left == false_rtx) 3284 { 3285 return right; 3286 } 3287 else if (right == false_rtx) 3288 { 3289 return left; 3290 } 3291 3292 /* Test for simple cases where the distributive law is useful. I.e., 3293 convert (ior (and (x) (y)) 3294 (and (x) (z))) 3295 to (and (x) 3296 (ior (y) (z))) 3297 */ 3298 3299 else if (GET_CODE (left) == AND && GET_CODE (right) == AND 3300 && attr_equal_p (XEXP (left, 0), XEXP (right, 0))) 3301 { 3302 newexp = attr_rtx (IOR, XEXP (left, 1), XEXP (right, 1)); 3303 3304 left = XEXP (left, 0); 3305 right = newexp; 3306 newexp = attr_rtx (AND, left, right); 3307 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); 3308 } 3309 3310 /* See if all or all but one of the insn's alternatives are specified 3311 in this tree. Optimize if so. */ 3312 3313 else if (insn_code >= 0 3314 && (GET_CODE (left) == IOR 3315 || (GET_CODE (left) == EQ_ATTR 3316 && XSTR (left, 0) == alternative_name) 3317 || GET_CODE (right) == IOR 3318 || (GET_CODE (right) == EQ_ATTR 3319 && XSTR (right, 0) == alternative_name))) 3320 { 3321 i = compute_alternative_mask (exp, IOR); 3322 if (i & ~insn_alternatives[insn_code]) 3323 fatal ("Invalid alternative specified for pattern number %d", 3324 insn_index); 3325 3326 /* If all alternatives are included, this is true. */ 3327 i ^= insn_alternatives[insn_code]; 3328 if (i == 0) 3329 return true_rtx; 3330 else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1) 3331 { 3332 /* If just one excluded, IOR a comparison with that one to the 3333 front of the tree. The others will be eliminated by 3334 optimization. We do not want to do this if the insn has one 3335 alternative and we have tested none of them! */ 3336 left = make_alternative_compare (i); 3337 right = simplify_and_tree (exp, &left, insn_code, insn_index); 3338 newexp = attr_rtx (IOR, attr_rtx (NOT, left), right); 3339 3340 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); 3341 } 3342 } 3343 3344 if (left != XEXP (exp, 0) || right != XEXP (exp, 1)) 3345 { 3346 newexp = attr_rtx (IOR, left, right); 3347 return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); 3348 } 3349 break; 3350 3351 case NOT: 3352 if (GET_CODE (XEXP (exp, 0)) == NOT) 3353 { 3354 left = SIMPLIFY_TEST_EXP (XEXP (XEXP (exp, 0), 0), 3355 insn_code, insn_index); 3356 SIMPLIFY_ALTERNATIVE (left); 3357 return left; 3358 } 3359 3360 left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index); 3361 SIMPLIFY_ALTERNATIVE (left); 3362 if (GET_CODE (left) == NOT) 3363 return XEXP (left, 0); 3364 3365 if (left == false_rtx) 3366 { 3367 obstack_free (rtl_obstack, spacer); 3368 return true_rtx; 3369 } 3370 else if (left == true_rtx) 3371 { 3372 obstack_free (rtl_obstack, spacer); 3373 return false_rtx; 3374 } 3375 3376 /* Try to apply De`Morgan's laws. */ 3377 else if (GET_CODE (left) == IOR) 3378 { 3379 newexp = attr_rtx (AND, 3380 attr_rtx (NOT, XEXP (left, 0)), 3381 attr_rtx (NOT, XEXP (left, 1))); 3382 3383 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); 3384 } 3385 else if (GET_CODE (left) == AND) 3386 { 3387 newexp = attr_rtx (IOR, 3388 attr_rtx (NOT, XEXP (left, 0)), 3389 attr_rtx (NOT, XEXP (left, 1))); 3390 3391 newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index); 3392 } 3393 else if (left != XEXP (exp, 0)) 3394 { 3395 newexp = attr_rtx (NOT, left); 3396 } 3397 break; 3398 3399 case EQ_ATTR: 3400 if (current_alternative_string && XSTR (exp, 0) == alternative_name) 3401 return (XSTR (exp, 1) == current_alternative_string 3402 ? true_rtx : false_rtx); 3403 3404 /* Look at the value for this insn code in the specified attribute. 3405 We normally can replace this comparison with the condition that 3406 would give this insn the values being tested for. */ 3407 if (XSTR (exp, 0) != alternative_name 3408 && (attr = find_attr (XSTR (exp, 0), 0)) != NULL) 3409 for (av = attr->first_value; av; av = av->next) 3410 for (ie = av->first_insn; ie; ie = ie->next) 3411 if (ie->insn_code == insn_code) 3412 return evaluate_eq_attr (exp, av->value, insn_code, insn_index); 3413 break; 3414 3415 default: 3416 break; 3417 } 3418 3419 /* We have already simplified this expression. Simplifying it again 3420 won't buy anything unless we weren't given a valid insn code 3421 to process (i.e., we are canonicalizing something.). */ 3422 if (insn_code != -2 /* Seems wrong: && current_alternative_string. */ 3423 && ! RTX_UNCHANGING_P (newexp)) 3424 return copy_rtx_unchanging (newexp); 3425 3426 return newexp; 3427} 3428 3429/* Optimize the attribute lists by seeing if we can determine conditional 3430 values from the known values of other attributes. This will save subroutine 3431 calls during the compilation. */ 3432 3433static void 3434optimize_attrs () 3435{ 3436 struct attr_desc *attr; 3437 struct attr_value *av; 3438 struct insn_ent *ie; 3439 rtx newexp; 3440 int something_changed = 1; 3441 int i; 3442 struct attr_value_list { struct attr_value *av; 3443 struct insn_ent *ie; 3444 struct attr_desc * attr; 3445 struct attr_value_list *next; }; 3446 struct attr_value_list **insn_code_values; 3447 struct attr_value_list *ivbuf; 3448 struct attr_value_list *iv; 3449 3450 /* For each insn code, make a list of all the insn_ent's for it, 3451 for all values for all attributes. */ 3452 3453 if (num_insn_ents == 0) 3454 return; 3455 3456 /* Make 2 extra elements, for "code" values -2 and -1. */ 3457 insn_code_values 3458 = (struct attr_value_list **) alloca ((insn_code_number + 2) 3459 * sizeof (struct attr_value_list *)); 3460 bzero ((char *) insn_code_values, 3461 (insn_code_number + 2) * sizeof (struct attr_value_list *)); 3462 3463 /* Offset the table address so we can index by -2 or -1. */ 3464 insn_code_values += 2; 3465 3466 /* Allocate the attr_value_list structures using xmalloc rather than 3467 alloca, because using alloca can overflow the maximum permitted 3468 stack limit on SPARC Lynx. */ 3469 iv = ivbuf = ((struct attr_value_list *) 3470 xmalloc (num_insn_ents * sizeof (struct attr_value_list))); 3471 3472 for (i = 0; i < MAX_ATTRS_INDEX; i++) 3473 for (attr = attrs[i]; attr; attr = attr->next) 3474 for (av = attr->first_value; av; av = av->next) 3475 for (ie = av->first_insn; ie; ie = ie->next) 3476 { 3477 iv->attr = attr; 3478 iv->av = av; 3479 iv->ie = ie; 3480 iv->next = insn_code_values[ie->insn_code]; 3481 insn_code_values[ie->insn_code] = iv; 3482 iv++; 3483 } 3484 3485 /* Sanity check on num_insn_ents. */ 3486 if (iv != ivbuf + num_insn_ents) 3487 abort (); 3488 3489 /* Process one insn code at a time. */ 3490 for (i = -2; i < insn_code_number; i++) 3491 { 3492 /* Clear the MEM_IN_STRUCT_P flag everywhere relevant. 3493 We use it to mean "already simplified for this insn". */ 3494 for (iv = insn_code_values[i]; iv; iv = iv->next) 3495 clear_struct_flag (iv->av->value); 3496 3497 /* Loop until nothing changes for one iteration. */ 3498 something_changed = 1; 3499 while (something_changed) 3500 { 3501 something_changed = 0; 3502 for (iv = insn_code_values[i]; iv; iv = iv->next) 3503 { 3504 struct obstack *old = rtl_obstack; 3505 char *spacer = (char *) obstack_finish (temp_obstack); 3506 3507 attr = iv->attr; 3508 av = iv->av; 3509 ie = iv->ie; 3510 if (GET_CODE (av->value) != COND) 3511 continue; 3512 3513 rtl_obstack = temp_obstack; 3514#if 0 /* This was intended as a speed up, but it was slower. */ 3515 if (insn_n_alternatives[ie->insn_code] > 6 3516 && count_sub_rtxs (av->value, 200) >= 200) 3517 newexp = simplify_by_alternatives (av->value, ie->insn_code, 3518 ie->insn_index); 3519 else 3520#endif 3521 newexp = simplify_cond (av->value, ie->insn_code, 3522 ie->insn_index); 3523 3524 rtl_obstack = old; 3525 if (newexp != av->value) 3526 { 3527 newexp = attr_copy_rtx (newexp); 3528 remove_insn_ent (av, ie); 3529 av = get_attr_value (newexp, attr, ie->insn_code); 3530 iv->av = av; 3531 insert_insn_ent (av, ie); 3532 something_changed = 1; 3533 } 3534 obstack_free (temp_obstack, spacer); 3535 } 3536 } 3537 } 3538 3539 free (ivbuf); 3540} 3541 3542#if 0 3543static rtx 3544simplify_by_alternatives (exp, insn_code, insn_index) 3545 rtx exp; 3546 int insn_code, insn_index; 3547{ 3548 int i; 3549 int len = insn_n_alternatives[insn_code]; 3550 rtx newexp = rtx_alloc (COND); 3551 rtx ultimate; 3552 3553 3554 XVEC (newexp, 0) = rtvec_alloc (len * 2); 3555 3556 /* It will not matter what value we use as the default value 3557 of the new COND, since that default will never be used. 3558 Choose something of the right type. */ 3559 for (ultimate = exp; GET_CODE (ultimate) == COND;) 3560 ultimate = XEXP (ultimate, 1); 3561 XEXP (newexp, 1) = ultimate; 3562 3563 for (i = 0; i < insn_n_alternatives[insn_code]; i++) 3564 { 3565 current_alternative_string = attr_numeral (i); 3566 XVECEXP (newexp, 0, i * 2) = make_alternative_compare (1 << i); 3567 XVECEXP (newexp, 0, i * 2 + 1) 3568 = simplify_cond (exp, insn_code, insn_index); 3569 } 3570 3571 current_alternative_string = 0; 3572 return simplify_cond (newexp, insn_code, insn_index); 3573} 3574#endif 3575 3576/* If EXP is a suitable expression, reorganize it by constructing an 3577 equivalent expression that is a COND with the tests being all combinations 3578 of attribute values and the values being simple constants. */ 3579 3580static rtx 3581simplify_by_exploding (exp) 3582 rtx exp; 3583{ 3584 rtx list = 0, link, condexp, defval = NULL_RTX; 3585 struct dimension *space; 3586 rtx *condtest, *condval; 3587 int i, j, total, ndim = 0; 3588 int most_tests, num_marks, new_marks; 3589 3590 /* Locate all the EQ_ATTR expressions. */ 3591 if (! find_and_mark_used_attributes (exp, &list, &ndim) || ndim == 0) 3592 { 3593 unmark_used_attributes (list, 0, 0); 3594 return exp; 3595 } 3596 3597 /* Create an attribute space from the list of used attributes. For each 3598 dimension in the attribute space, record the attribute, list of values 3599 used, and number of values used. Add members to the list of values to 3600 cover the domain of the attribute. This makes the expanded COND form 3601 order independent. */ 3602 3603 space = (struct dimension *) alloca (ndim * sizeof (struct dimension)); 3604 3605 total = 1; 3606 for (ndim = 0; list; ndim++) 3607 { 3608 /* Pull the first attribute value from the list and record that 3609 attribute as another dimension in the attribute space. */ 3610 char *name = XSTR (XEXP (list, 0), 0); 3611 rtx *prev; 3612 3613 if ((space[ndim].attr = find_attr (name, 0)) == 0 3614 || space[ndim].attr->is_numeric) 3615 { 3616 unmark_used_attributes (list, space, ndim); 3617 return exp; 3618 } 3619 3620 /* Add all remaining attribute values that refer to this attribute. */ 3621 space[ndim].num_values = 0; 3622 space[ndim].values = 0; 3623 prev = &list; 3624 for (link = list; link; link = *prev) 3625 if (! strcmp (XSTR (XEXP (link, 0), 0), name)) 3626 { 3627 space[ndim].num_values++; 3628 *prev = XEXP (link, 1); 3629 XEXP (link, 1) = space[ndim].values; 3630 space[ndim].values = link; 3631 } 3632 else 3633 prev = &XEXP (link, 1); 3634 3635 /* Add sufficient members to the list of values to make the list 3636 mutually exclusive and record the total size of the attribute 3637 space. */ 3638 total *= add_values_to_cover (&space[ndim]); 3639 } 3640 3641 /* Sort the attribute space so that the attributes go from non-constant 3642 to constant and from most values to least values. */ 3643 for (i = 0; i < ndim; i++) 3644 for (j = ndim - 1; j > i; j--) 3645 if ((space[j-1].attr->is_const && !space[j].attr->is_const) 3646 || space[j-1].num_values < space[j].num_values) 3647 { 3648 struct dimension tmp; 3649 tmp = space[j]; 3650 space[j] = space[j-1]; 3651 space[j-1] = tmp; 3652 } 3653 3654 /* Establish the initial current value. */ 3655 for (i = 0; i < ndim; i++) 3656 space[i].current_value = space[i].values; 3657 3658 condtest = (rtx *) alloca (total * sizeof (rtx)); 3659 condval = (rtx *) alloca (total * sizeof (rtx)); 3660 3661 /* Expand the tests and values by iterating over all values in the 3662 attribute space. */ 3663 for (i = 0;; i++) 3664 { 3665 condtest[i] = test_for_current_value (space, ndim); 3666 condval[i] = simplify_with_current_value (exp, space, ndim); 3667 if (! increment_current_value (space, ndim)) 3668 break; 3669 } 3670 if (i != total - 1) 3671 abort (); 3672 3673 /* We are now finished with the original expression. */ 3674 unmark_used_attributes (0, space, ndim); 3675 3676 /* Find the most used constant value and make that the default. */ 3677 most_tests = -1; 3678 for (i = num_marks = 0; i < total; i++) 3679 if (GET_CODE (condval[i]) == CONST_STRING 3680 && ! MEM_VOLATILE_P (condval[i])) 3681 { 3682 /* Mark the unmarked constant value and count how many are marked. */ 3683 MEM_VOLATILE_P (condval[i]) = 1; 3684 for (j = new_marks = 0; j < total; j++) 3685 if (GET_CODE (condval[j]) == CONST_STRING 3686 && MEM_VOLATILE_P (condval[j])) 3687 new_marks++; 3688 if (new_marks - num_marks > most_tests) 3689 { 3690 most_tests = new_marks - num_marks; 3691 defval = condval[i]; 3692 } 3693 num_marks = new_marks; 3694 } 3695 /* Clear all the marks. */ 3696 for (i = 0; i < total; i++) 3697 MEM_VOLATILE_P (condval[i]) = 0; 3698 3699 /* Give up if nothing is constant. */ 3700 if (num_marks == 0) 3701 return exp; 3702 3703 /* If all values are the default, use that. */ 3704 if (total == most_tests) 3705 return defval; 3706 3707 /* Make a COND with the most common constant value the default. (A more 3708 complex method where tests with the same value were combined didn't 3709 seem to improve things.) */ 3710 condexp = rtx_alloc (COND); 3711 XVEC (condexp, 0) = rtvec_alloc ((total - most_tests) * 2); 3712 XEXP (condexp, 1) = defval; 3713 for (i = j = 0; i < total; i++) 3714 if (condval[i] != defval) 3715 { 3716 XVECEXP (condexp, 0, 2 * j) = condtest[i]; 3717 XVECEXP (condexp, 0, 2 * j + 1) = condval[i]; 3718 j++; 3719 } 3720 3721 return condexp; 3722} 3723 3724/* Set the MEM_VOLATILE_P flag for all EQ_ATTR expressions in EXP and 3725 verify that EXP can be simplified to a constant term if all the EQ_ATTR 3726 tests have known value. */ 3727 3728static int 3729find_and_mark_used_attributes (exp, terms, nterms) 3730 rtx exp, *terms; 3731 int *nterms; 3732{ 3733 int i; 3734 3735 switch (GET_CODE (exp)) 3736 { 3737 case EQ_ATTR: 3738 if (! MEM_VOLATILE_P (exp)) 3739 { 3740 rtx link = rtx_alloc (EXPR_LIST); 3741 XEXP (link, 0) = exp; 3742 XEXP (link, 1) = *terms; 3743 *terms = link; 3744 *nterms += 1; 3745 MEM_VOLATILE_P (exp) = 1; 3746 } 3747 return 1; 3748 3749 case CONST_STRING: 3750 case CONST_INT: 3751 return 1; 3752 3753 case IF_THEN_ELSE: 3754 if (! find_and_mark_used_attributes (XEXP (exp, 2), terms, nterms)) 3755 return 0; 3756 case IOR: 3757 case AND: 3758 if (! find_and_mark_used_attributes (XEXP (exp, 1), terms, nterms)) 3759 return 0; 3760 case NOT: 3761 if (! find_and_mark_used_attributes (XEXP (exp, 0), terms, nterms)) 3762 return 0; 3763 return 1; 3764 3765 case COND: 3766 for (i = 0; i < XVECLEN (exp, 0); i++) 3767 if (! find_and_mark_used_attributes (XVECEXP (exp, 0, i), terms, nterms)) 3768 return 0; 3769 if (! find_and_mark_used_attributes (XEXP (exp, 1), terms, nterms)) 3770 return 0; 3771 return 1; 3772 3773 default: 3774 return 0; 3775 } 3776} 3777 3778/* Clear the MEM_VOLATILE_P flag in all EQ_ATTR expressions on LIST and 3779 in the values of the NDIM-dimensional attribute space SPACE. */ 3780 3781static void 3782unmark_used_attributes (list, space, ndim) 3783 rtx list; 3784 struct dimension *space; 3785 int ndim; 3786{ 3787 rtx link, exp; 3788 int i; 3789 3790 for (i = 0; i < ndim; i++) 3791 unmark_used_attributes (space[i].values, 0, 0); 3792 3793 for (link = list; link; link = XEXP (link, 1)) 3794 { 3795 exp = XEXP (link, 0); 3796 if (GET_CODE (exp) == EQ_ATTR) 3797 MEM_VOLATILE_P (exp) = 0; 3798 } 3799} 3800 3801/* Update the attribute dimension DIM so that all values of the attribute 3802 are tested. Return the updated number of values. */ 3803 3804static int 3805add_values_to_cover (dim) 3806 struct dimension *dim; 3807{ 3808 struct attr_value *av; 3809 rtx exp, link, *prev; 3810 int nalt = 0; 3811 3812 for (av = dim->attr->first_value; av; av = av->next) 3813 if (GET_CODE (av->value) == CONST_STRING) 3814 nalt++; 3815 3816 if (nalt < dim->num_values) 3817 abort (); 3818 else if (nalt == dim->num_values) 3819 ; /* Ok. */ 3820 else if (nalt * 2 < dim->num_values * 3) 3821 { 3822 /* Most all the values of the attribute are used, so add all the unused 3823 values. */ 3824 prev = &dim->values; 3825 for (link = dim->values; link; link = *prev) 3826 prev = &XEXP (link, 1); 3827 3828 for (av = dim->attr->first_value; av; av = av->next) 3829 if (GET_CODE (av->value) == CONST_STRING) 3830 { 3831 exp = attr_eq (dim->attr->name, XSTR (av->value, 0)); 3832 if (MEM_VOLATILE_P (exp)) 3833 continue; 3834 3835 link = rtx_alloc (EXPR_LIST); 3836 XEXP (link, 0) = exp; 3837 XEXP (link, 1) = 0; 3838 *prev = link; 3839 prev = &XEXP (link, 1); 3840 } 3841 dim->num_values = nalt; 3842 } 3843 else 3844 { 3845 rtx orexp = false_rtx; 3846 3847 /* Very few values are used, so compute a mutually exclusive 3848 expression. (We could do this for numeric values if that becomes 3849 important.) */ 3850 prev = &dim->values; 3851 for (link = dim->values; link; link = *prev) 3852 { 3853 orexp = insert_right_side (IOR, orexp, XEXP (link, 0), -2, -2); 3854 prev = &XEXP (link, 1); 3855 } 3856 link = rtx_alloc (EXPR_LIST); 3857 XEXP (link, 0) = attr_rtx (NOT, orexp); 3858 XEXP (link, 1) = 0; 3859 *prev = link; 3860 dim->num_values++; 3861 } 3862 return dim->num_values; 3863} 3864 3865/* Increment the current value for the NDIM-dimensional attribute space SPACE 3866 and return FALSE if the increment overflowed. */ 3867 3868static int 3869increment_current_value (space, ndim) 3870 struct dimension *space; 3871 int ndim; 3872{ 3873 int i; 3874 3875 for (i = ndim - 1; i >= 0; i--) 3876 { 3877 if ((space[i].current_value = XEXP (space[i].current_value, 1)) == 0) 3878 space[i].current_value = space[i].values; 3879 else 3880 return 1; 3881 } 3882 return 0; 3883} 3884 3885/* Construct an expression corresponding to the current value for the 3886 NDIM-dimensional attribute space SPACE. */ 3887 3888static rtx 3889test_for_current_value (space, ndim) 3890 struct dimension *space; 3891 int ndim; 3892{ 3893 int i; 3894 rtx exp = true_rtx; 3895 3896 for (i = 0; i < ndim; i++) 3897 exp = insert_right_side (AND, exp, XEXP (space[i].current_value, 0), 3898 -2, -2); 3899 3900 return exp; 3901} 3902 3903/* Given the current value of the NDIM-dimensional attribute space SPACE, 3904 set the corresponding EQ_ATTR expressions to that value and reduce 3905 the expression EXP as much as possible. On input [and output], all 3906 known EQ_ATTR expressions are set to FALSE. */ 3907 3908static rtx 3909simplify_with_current_value (exp, space, ndim) 3910 rtx exp; 3911 struct dimension *space; 3912 int ndim; 3913{ 3914 int i; 3915 rtx x; 3916 3917 /* Mark each current value as TRUE. */ 3918 for (i = 0; i < ndim; i++) 3919 { 3920 x = XEXP (space[i].current_value, 0); 3921 if (GET_CODE (x) == EQ_ATTR) 3922 MEM_VOLATILE_P (x) = 0; 3923 } 3924 3925 exp = simplify_with_current_value_aux (exp); 3926 3927 /* Change each current value back to FALSE. */ 3928 for (i = 0; i < ndim; i++) 3929 { 3930 x = XEXP (space[i].current_value, 0); 3931 if (GET_CODE (x) == EQ_ATTR) 3932 MEM_VOLATILE_P (x) = 1; 3933 } 3934 3935 return exp; 3936} 3937 3938/* Reduce the expression EXP based on the MEM_VOLATILE_P settings of 3939 all EQ_ATTR expressions. */ 3940 3941static rtx 3942simplify_with_current_value_aux (exp) 3943 rtx exp; 3944{ 3945 register int i; 3946 rtx cond; 3947 3948 switch (GET_CODE (exp)) 3949 { 3950 case EQ_ATTR: 3951 if (MEM_VOLATILE_P (exp)) 3952 return false_rtx; 3953 else 3954 return true_rtx; 3955 case CONST_STRING: 3956 case CONST_INT: 3957 return exp; 3958 3959 case IF_THEN_ELSE: 3960 cond = simplify_with_current_value_aux (XEXP (exp, 0)); 3961 if (cond == true_rtx) 3962 return simplify_with_current_value_aux (XEXP (exp, 1)); 3963 else if (cond == false_rtx) 3964 return simplify_with_current_value_aux (XEXP (exp, 2)); 3965 else 3966 return attr_rtx (IF_THEN_ELSE, cond, 3967 simplify_with_current_value_aux (XEXP (exp, 1)), 3968 simplify_with_current_value_aux (XEXP (exp, 2))); 3969 3970 case IOR: 3971 cond = simplify_with_current_value_aux (XEXP (exp, 1)); 3972 if (cond == true_rtx) 3973 return cond; 3974 else if (cond == false_rtx) 3975 return simplify_with_current_value_aux (XEXP (exp, 0)); 3976 else 3977 return attr_rtx (IOR, cond, 3978 simplify_with_current_value_aux (XEXP (exp, 0))); 3979 3980 case AND: 3981 cond = simplify_with_current_value_aux (XEXP (exp, 1)); 3982 if (cond == true_rtx) 3983 return simplify_with_current_value_aux (XEXP (exp, 0)); 3984 else if (cond == false_rtx) 3985 return cond; 3986 else 3987 return attr_rtx (AND, cond, 3988 simplify_with_current_value_aux (XEXP (exp, 0))); 3989 3990 case NOT: 3991 cond = simplify_with_current_value_aux (XEXP (exp, 0)); 3992 if (cond == true_rtx) 3993 return false_rtx; 3994 else if (cond == false_rtx) 3995 return true_rtx; 3996 else 3997 return attr_rtx (NOT, cond); 3998 3999 case COND: 4000 for (i = 0; i < XVECLEN (exp, 0); i += 2) 4001 { 4002 cond = simplify_with_current_value_aux (XVECEXP (exp, 0, i)); 4003 if (cond == true_rtx) 4004 return simplify_with_current_value_aux (XVECEXP (exp, 0, i + 1)); 4005 else if (cond == false_rtx) 4006 continue; 4007 else 4008 abort (); /* With all EQ_ATTR's of known value, a case should 4009 have been selected. */ 4010 } 4011 return simplify_with_current_value_aux (XEXP (exp, 1)); 4012 4013 default: 4014 abort (); 4015 } 4016} 4017 4018/* Clear the MEM_IN_STRUCT_P flag in EXP and its subexpressions. */ 4019 4020static void 4021clear_struct_flag (x) 4022 rtx x; 4023{ 4024 register int i; 4025 register int j; 4026 register enum rtx_code code; 4027 register char *fmt; 4028 4029 MEM_IN_STRUCT_P (x) = 0; 4030 if (RTX_UNCHANGING_P (x)) 4031 return; 4032 4033 code = GET_CODE (x); 4034 4035 switch (code) 4036 { 4037 case REG: 4038 case QUEUED: 4039 case CONST_INT: 4040 case CONST_DOUBLE: 4041 case SYMBOL_REF: 4042 case CODE_LABEL: 4043 case PC: 4044 case CC0: 4045 case EQ_ATTR: 4046 case ATTR_FLAG: 4047 return; 4048 4049 default: 4050 break; 4051 } 4052 4053 /* Compare the elements. If any pair of corresponding elements 4054 fail to match, return 0 for the whole things. */ 4055 4056 fmt = GET_RTX_FORMAT (code); 4057 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 4058 { 4059 switch (fmt[i]) 4060 { 4061 case 'V': 4062 case 'E': 4063 for (j = 0; j < XVECLEN (x, i); j++) 4064 clear_struct_flag (XVECEXP (x, i, j)); 4065 break; 4066 4067 case 'e': 4068 clear_struct_flag (XEXP (x, i)); 4069 break; 4070 } 4071 } 4072} 4073 4074/* Return the number of RTX objects making up the expression X. 4075 But if we count more than MAX objects, stop counting. */ 4076 4077static int 4078count_sub_rtxs (x, max) 4079 rtx x; 4080 int max; 4081{ 4082 register int i; 4083 register int j; 4084 register enum rtx_code code; 4085 register char *fmt; 4086 int total = 0; 4087 4088 code = GET_CODE (x); 4089 4090 switch (code) 4091 { 4092 case REG: 4093 case QUEUED: 4094 case CONST_INT: 4095 case CONST_DOUBLE: 4096 case SYMBOL_REF: 4097 case CODE_LABEL: 4098 case PC: 4099 case CC0: 4100 case EQ_ATTR: 4101 case ATTR_FLAG: 4102 return 1; 4103 4104 default: 4105 break; 4106 } 4107 4108 /* Compare the elements. If any pair of corresponding elements 4109 fail to match, return 0 for the whole things. */ 4110 4111 fmt = GET_RTX_FORMAT (code); 4112 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--) 4113 { 4114 if (total >= max) 4115 return total; 4116 4117 switch (fmt[i]) 4118 { 4119 case 'V': 4120 case 'E': 4121 for (j = 0; j < XVECLEN (x, i); j++) 4122 total += count_sub_rtxs (XVECEXP (x, i, j), max); 4123 break; 4124 4125 case 'e': 4126 total += count_sub_rtxs (XEXP (x, i), max); 4127 break; 4128 } 4129 } 4130 return total; 4131 4132} 4133 4134/* Create table entries for DEFINE_ATTR. */ 4135 4136static void 4137gen_attr (exp) 4138 rtx exp; 4139{ 4140 struct attr_desc *attr; 4141 struct attr_value *av; 4142 char *name_ptr; 4143 char *p; 4144 4145 /* Make a new attribute structure. Check for duplicate by looking at 4146 attr->default_val, since it is initialized by this routine. */ 4147 attr = find_attr (XSTR (exp, 0), 1); 4148 if (attr->default_val) 4149 fatal ("Duplicate definition for `%s' attribute", attr->name); 4150 4151 if (*XSTR (exp, 1) == '\0') 4152 attr->is_numeric = 1; 4153 else 4154 { 4155 name_ptr = XSTR (exp, 1); 4156 while ((p = next_comma_elt (&name_ptr)) != NULL) 4157 { 4158 av = (struct attr_value *) oballoc (sizeof (struct attr_value)); 4159 av->value = attr_rtx (CONST_STRING, p); 4160 av->next = attr->first_value; 4161 attr->first_value = av; 4162 av->first_insn = NULL; 4163 av->num_insns = 0; 4164 av->has_asm_insn = 0; 4165 } 4166 } 4167 4168 if (GET_CODE (XEXP (exp, 2)) == CONST) 4169 { 4170 attr->is_const = 1; 4171 if (attr->is_numeric) 4172 fatal ("Constant attributes may not take numeric values"); 4173 /* Get rid of the CONST node. It is allowed only at top-level. */ 4174 XEXP (exp, 2) = XEXP (XEXP (exp, 2), 0); 4175 } 4176 4177 if (! strcmp (attr->name, "length") && ! attr->is_numeric) 4178 fatal ("`length' attribute must take numeric values"); 4179 4180 /* Set up the default value. */ 4181 XEXP (exp, 2) = check_attr_value (XEXP (exp, 2), attr); 4182 attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2); 4183} 4184 4185/* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of 4186 alternatives in the constraints. Assume all MATCH_OPERANDs have the same 4187 number of alternatives as this should be checked elsewhere. */ 4188 4189static int 4190count_alternatives (exp) 4191 rtx exp; 4192{ 4193 int i, j, n; 4194 char *fmt; 4195 4196 if (GET_CODE (exp) == MATCH_OPERAND) 4197 return n_comma_elts (XSTR (exp, 2)); 4198 4199 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp)); 4200 i < GET_RTX_LENGTH (GET_CODE (exp)); i++) 4201 switch (*fmt++) 4202 { 4203 case 'e': 4204 case 'u': 4205 n = count_alternatives (XEXP (exp, i)); 4206 if (n) 4207 return n; 4208 break; 4209 4210 case 'E': 4211 case 'V': 4212 if (XVEC (exp, i) != NULL) 4213 for (j = 0; j < XVECLEN (exp, i); j++) 4214 { 4215 n = count_alternatives (XVECEXP (exp, i, j)); 4216 if (n) 4217 return n; 4218 } 4219 } 4220 4221 return 0; 4222} 4223 4224/* Returns non-zero if the given expression contains an EQ_ATTR with the 4225 `alternative' attribute. */ 4226 4227static int 4228compares_alternatives_p (exp) 4229 rtx exp; 4230{ 4231 int i, j; 4232 char *fmt; 4233 4234 if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name) 4235 return 1; 4236 4237 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp)); 4238 i < GET_RTX_LENGTH (GET_CODE (exp)); i++) 4239 switch (*fmt++) 4240 { 4241 case 'e': 4242 case 'u': 4243 if (compares_alternatives_p (XEXP (exp, i))) 4244 return 1; 4245 break; 4246 4247 case 'E': 4248 for (j = 0; j < XVECLEN (exp, i); j++) 4249 if (compares_alternatives_p (XVECEXP (exp, i, j))) 4250 return 1; 4251 break; 4252 } 4253 4254 return 0; 4255} 4256 4257/* Returns non-zero is INNER is contained in EXP. */ 4258 4259static int 4260contained_in_p (inner, exp) 4261 rtx inner; 4262 rtx exp; 4263{ 4264 int i, j; 4265 char *fmt; 4266 4267 if (rtx_equal_p (inner, exp)) 4268 return 1; 4269 4270 for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp)); 4271 i < GET_RTX_LENGTH (GET_CODE (exp)); i++) 4272 switch (*fmt++) 4273 { 4274 case 'e': 4275 case 'u': 4276 if (contained_in_p (inner, XEXP (exp, i))) 4277 return 1; 4278 break; 4279 4280 case 'E': 4281 for (j = 0; j < XVECLEN (exp, i); j++) 4282 if (contained_in_p (inner, XVECEXP (exp, i, j))) 4283 return 1; 4284 break; 4285 } 4286 4287 return 0; 4288} 4289 4290/* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES. */ 4291 4292static void 4293gen_insn (exp) 4294 rtx exp; 4295{ 4296 struct insn_def *id; 4297 4298 id = (struct insn_def *) oballoc (sizeof (struct insn_def)); 4299 id->next = defs; 4300 defs = id; 4301 id->def = exp; 4302 4303 switch (GET_CODE (exp)) 4304 { 4305 case DEFINE_INSN: 4306 id->insn_code = insn_code_number++; 4307 id->insn_index = insn_index_number++; 4308 id->num_alternatives = count_alternatives (exp); 4309 if (id->num_alternatives == 0) 4310 id->num_alternatives = 1; 4311 id->vec_idx = 4; 4312 break; 4313 4314 case DEFINE_PEEPHOLE: 4315 id->insn_code = insn_code_number++; 4316 id->insn_index = insn_index_number++; 4317 id->num_alternatives = count_alternatives (exp); 4318 if (id->num_alternatives == 0) 4319 id->num_alternatives = 1; 4320 id->vec_idx = 3; 4321 break; 4322 4323 case DEFINE_ASM_ATTRIBUTES: 4324 id->insn_code = -1; 4325 id->insn_index = -1; 4326 id->num_alternatives = 1; 4327 id->vec_idx = 0; 4328 got_define_asm_attributes = 1; 4329 break; 4330 4331 default: 4332 abort (); 4333 } 4334} 4335 4336/* Process a DEFINE_DELAY. Validate the vector length, check if annul 4337 true or annul false is specified, and make a `struct delay_desc'. */ 4338 4339static void 4340gen_delay (def) 4341 rtx def; 4342{ 4343 struct delay_desc *delay; 4344 int i; 4345 4346 if (XVECLEN (def, 1) % 3 != 0) 4347 fatal ("Number of elements in DEFINE_DELAY must be multiple of three."); 4348 4349 for (i = 0; i < XVECLEN (def, 1); i += 3) 4350 { 4351 if (XVECEXP (def, 1, i + 1)) 4352 have_annul_true = 1; 4353 if (XVECEXP (def, 1, i + 2)) 4354 have_annul_false = 1; 4355 } 4356 4357 delay = (struct delay_desc *) oballoc (sizeof (struct delay_desc)); 4358 delay->def = def; 4359 delay->num = ++num_delays; 4360 delay->next = delays; 4361 delays = delay; 4362} 4363 4364/* Process a DEFINE_FUNCTION_UNIT. 4365 4366 This gives information about a function unit contained in the CPU. 4367 We fill in a `struct function_unit_op' and a `struct function_unit' 4368 with information used later by `expand_unit'. */ 4369 4370static void 4371gen_unit (def) 4372 rtx def; 4373{ 4374 struct function_unit *unit; 4375 struct function_unit_op *op; 4376 char *name = XSTR (def, 0); 4377 int multiplicity = XINT (def, 1); 4378 int simultaneity = XINT (def, 2); 4379 rtx condexp = XEXP (def, 3); 4380 int ready_cost = MAX (XINT (def, 4), 1); 4381 int issue_delay = MAX (XINT (def, 5), 1); 4382 4383 /* See if we have already seen this function unit. If so, check that 4384 the multiplicity and simultaneity values are the same. If not, make 4385 a structure for this function unit. */ 4386 for (unit = units; unit; unit = unit->next) 4387 if (! strcmp (unit->name, name)) 4388 { 4389 if (unit->multiplicity != multiplicity 4390 || unit->simultaneity != simultaneity) 4391 fatal ("Differing specifications given for `%s' function unit.", 4392 unit->name); 4393 break; 4394 } 4395 4396 if (unit == 0) 4397 { 4398 unit = (struct function_unit *) oballoc (sizeof (struct function_unit)); 4399 unit->name = name; 4400 unit->multiplicity = multiplicity; 4401 unit->simultaneity = simultaneity; 4402 unit->issue_delay.min = unit->issue_delay.max = issue_delay; 4403 unit->num = num_units++; 4404 unit->num_opclasses = 0; 4405 unit->condexp = false_rtx; 4406 unit->ops = 0; 4407 unit->next = units; 4408 units = unit; 4409 } 4410 4411 /* Make a new operation class structure entry and initialize it. */ 4412 op = (struct function_unit_op *) oballoc (sizeof (struct function_unit_op)); 4413 op->condexp = condexp; 4414 op->num = unit->num_opclasses++; 4415 op->ready = ready_cost; 4416 op->issue_delay = issue_delay; 4417 op->next = unit->ops; 4418 unit->ops = op; 4419 num_unit_opclasses++; 4420 4421 /* Set our issue expression based on whether or not an optional conflict 4422 vector was specified. */ 4423 if (XVEC (def, 6)) 4424 { 4425 /* Compute the IOR of all the specified expressions. */ 4426 rtx orexp = false_rtx; 4427 int i; 4428 4429 for (i = 0; i < XVECLEN (def, 6); i++) 4430 orexp = insert_right_side (IOR, orexp, XVECEXP (def, 6, i), -2, -2); 4431 4432 op->conflict_exp = orexp; 4433 extend_range (&unit->issue_delay, 1, issue_delay); 4434 } 4435 else 4436 { 4437 op->conflict_exp = true_rtx; 4438 extend_range (&unit->issue_delay, issue_delay, issue_delay); 4439 } 4440 4441 /* Merge our conditional into that of the function unit so we can determine 4442 which insns are used by the function unit. */ 4443 unit->condexp = insert_right_side (IOR, unit->condexp, op->condexp, -2, -2); 4444} 4445 4446/* Given a piece of RTX, print a C expression to test its truth value. 4447 We use AND and IOR both for logical and bit-wise operations, so 4448 interpret them as logical unless they are inside a comparison expression. 4449 The first bit of FLAGS will be non-zero in that case. 4450 4451 Set the second bit of FLAGS to make references to attribute values use 4452 a cached local variable instead of calling a function. */ 4453 4454static void 4455write_test_expr (exp, flags) 4456 rtx exp; 4457 int flags; 4458{ 4459 int comparison_operator = 0; 4460 RTX_CODE code; 4461 struct attr_desc *attr; 4462 4463 /* In order not to worry about operator precedence, surround our part of 4464 the expression with parentheses. */ 4465 4466 printf ("("); 4467 code = GET_CODE (exp); 4468 switch (code) 4469 { 4470 /* Binary operators. */ 4471 case EQ: case NE: 4472 case GE: case GT: case GEU: case GTU: 4473 case LE: case LT: case LEU: case LTU: 4474 comparison_operator = 1; 4475 4476 case PLUS: case MINUS: case MULT: case DIV: case MOD: 4477 case AND: case IOR: case XOR: 4478 case ASHIFT: case LSHIFTRT: case ASHIFTRT: 4479 write_test_expr (XEXP (exp, 0), flags | comparison_operator); 4480 switch (code) 4481 { 4482 case EQ: 4483 printf (" == "); 4484 break; 4485 case NE: 4486 printf (" != "); 4487 break; 4488 case GE: 4489 printf (" >= "); 4490 break; 4491 case GT: 4492 printf (" > "); 4493 break; 4494 case GEU: 4495 printf (" >= (unsigned) "); 4496 break; 4497 case GTU: 4498 printf (" > (unsigned) "); 4499 break; 4500 case LE: 4501 printf (" <= "); 4502 break; 4503 case LT: 4504 printf (" < "); 4505 break; 4506 case LEU: 4507 printf (" <= (unsigned) "); 4508 break; 4509 case LTU: 4510 printf (" < (unsigned) "); 4511 break; 4512 case PLUS: 4513 printf (" + "); 4514 break; 4515 case MINUS: 4516 printf (" - "); 4517 break; 4518 case MULT: 4519 printf (" * "); 4520 break; 4521 case DIV: 4522 printf (" / "); 4523 break; 4524 case MOD: 4525 printf (" %% "); 4526 break; 4527 case AND: 4528 if (flags & 1) 4529 printf (" & "); 4530 else 4531 printf (" && "); 4532 break; 4533 case IOR: 4534 if (flags & 1) 4535 printf (" | "); 4536 else 4537 printf (" || "); 4538 break; 4539 case XOR: 4540 printf (" ^ "); 4541 break; 4542 case ASHIFT: 4543 printf (" << "); 4544 break; 4545 case LSHIFTRT: 4546 case ASHIFTRT: 4547 printf (" >> "); 4548 break; 4549 default: 4550 abort (); 4551 } 4552 4553 write_test_expr (XEXP (exp, 1), flags | comparison_operator); 4554 break; 4555 4556 case NOT: 4557 /* Special-case (not (eq_attrq "alternative" "x")) */ 4558 if (! (flags & 1) && GET_CODE (XEXP (exp, 0)) == EQ_ATTR 4559 && XSTR (XEXP (exp, 0), 0) == alternative_name) 4560 { 4561 printf ("which_alternative != %s", XSTR (XEXP (exp, 0), 1)); 4562 break; 4563 } 4564 4565 /* Otherwise, fall through to normal unary operator. */ 4566 4567 /* Unary operators. */ 4568 case ABS: case NEG: 4569 switch (code) 4570 { 4571 case NOT: 4572 if (flags & 1) 4573 printf ("~ "); 4574 else 4575 printf ("! "); 4576 break; 4577 case ABS: 4578 printf ("abs "); 4579 break; 4580 case NEG: 4581 printf ("-"); 4582 break; 4583 default: 4584 abort (); 4585 } 4586 4587 write_test_expr (XEXP (exp, 0), flags); 4588 break; 4589 4590 /* Comparison test of an attribute with a value. Most of these will 4591 have been removed by optimization. Handle "alternative" 4592 specially and give error if EQ_ATTR present inside a comparison. */ 4593 case EQ_ATTR: 4594 if (flags & 1) 4595 fatal ("EQ_ATTR not valid inside comparison"); 4596 4597 if (XSTR (exp, 0) == alternative_name) 4598 { 4599 printf ("which_alternative == %s", XSTR (exp, 1)); 4600 break; 4601 } 4602 4603 attr = find_attr (XSTR (exp, 0), 0); 4604 if (! attr) abort (); 4605 4606 /* Now is the time to expand the value of a constant attribute. */ 4607 if (attr->is_const) 4608 { 4609 write_test_expr (evaluate_eq_attr (exp, attr->default_val->value, 4610 -2, -2), 4611 flags); 4612 } 4613 else 4614 { 4615 if (flags & 2) 4616 printf ("attr_%s", attr->name); 4617 else 4618 printf ("get_attr_%s (insn)", attr->name); 4619 printf (" == "); 4620 write_attr_valueq (attr, XSTR (exp, 1)); 4621 } 4622 break; 4623 4624 /* Comparison test of flags for define_delays. */ 4625 case ATTR_FLAG: 4626 if (flags & 1) 4627 fatal ("ATTR_FLAG not valid inside comparison"); 4628 printf ("(flags & ATTR_FLAG_%s) != 0", XSTR (exp, 0)); 4629 break; 4630 4631 /* See if an operand matches a predicate. */ 4632 case MATCH_OPERAND: 4633 /* If only a mode is given, just ensure the mode matches the operand. 4634 If neither a mode nor predicate is given, error. */ 4635 if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0') 4636 { 4637 if (GET_MODE (exp) == VOIDmode) 4638 fatal ("Null MATCH_OPERAND specified as test"); 4639 else 4640 printf ("GET_MODE (operands[%d]) == %smode", 4641 XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp))); 4642 } 4643 else 4644 printf ("%s (operands[%d], %smode)", 4645 XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp))); 4646 break; 4647 4648 case MATCH_INSN: 4649 printf ("%s (insn)", XSTR (exp, 0)); 4650 break; 4651 4652 /* Constant integer. */ 4653 case CONST_INT: 4654 printf (HOST_WIDE_INT_PRINT_DEC, XWINT (exp, 0)); 4655 break; 4656 4657 /* A random C expression. */ 4658 case SYMBOL_REF: 4659 printf ("%s", XSTR (exp, 0)); 4660 break; 4661 4662 /* The address of the branch target. */ 4663 case MATCH_DUP: 4664 printf ("insn_addresses[INSN_UID (GET_CODE (operands[%d]) == LABEL_REF ? XEXP (operands[%d], 0) : operands[%d])]", 4665 XINT (exp, 0), XINT (exp, 0), XINT (exp, 0)); 4666 break; 4667 4668 case PC: 4669 /* The address of the current insn. We implement this actually as the 4670 address of the current insn for backward branches, but the last 4671 address of the next insn for forward branches, and both with 4672 adjustments that account for the worst-case possible stretching of 4673 intervening alignments between this insn and its destination. */ 4674 printf("insn_current_reference_address (insn)"); 4675 break; 4676 4677 case CONST_STRING: 4678 printf ("%s", XSTR (exp, 0)); 4679 break; 4680 4681 case IF_THEN_ELSE: 4682 write_test_expr (XEXP (exp, 0), flags & 2); 4683 printf (" ? "); 4684 write_test_expr (XEXP (exp, 1), flags | 1); 4685 printf (" : "); 4686 write_test_expr (XEXP (exp, 2), flags | 1); 4687 break; 4688 4689 default: 4690 fatal ("bad RTX code `%s' in attribute calculation\n", 4691 GET_RTX_NAME (code)); 4692 } 4693 4694 printf (")"); 4695} 4696 4697/* Given an attribute value, return the maximum CONST_STRING argument 4698 encountered. Set *UNKNOWNP and return INT_MAX if the value is unknown. */ 4699 4700static int 4701max_attr_value (exp, unknownp) 4702 rtx exp; 4703 int *unknownp; 4704{ 4705 int current_max; 4706 int i, n; 4707 4708 switch (GET_CODE (exp)) 4709 { 4710 case CONST_STRING: 4711 current_max = atoi (XSTR (exp, 0)); 4712 break; 4713 4714 case COND: 4715 current_max = max_attr_value (XEXP (exp, 1), unknownp); 4716 for (i = 0; i < XVECLEN (exp, 0); i += 2) 4717 { 4718 n = max_attr_value (XVECEXP (exp, 0, i + 1), unknownp); 4719 if (n > current_max) 4720 current_max = n; 4721 } 4722 break; 4723 4724 case IF_THEN_ELSE: 4725 current_max = max_attr_value (XEXP (exp, 1), unknownp); 4726 n = max_attr_value (XEXP (exp, 2), unknownp); 4727 if (n > current_max) 4728 current_max = n; 4729 break; 4730 4731 default: 4732 *unknownp = 1; 4733 current_max = INT_MAX; 4734 break; 4735 } 4736 4737 return current_max; 4738} 4739 4740/* Given an attribute value, return the result of ORing together all 4741 CONST_STRING arguments encountered. Set *UNKNOWNP and return -1 4742 if the numeric value is not known. */ 4743 4744static int 4745or_attr_value (exp, unknownp) 4746 rtx exp; 4747 int *unknownp; 4748{ 4749 int current_or; 4750 int i; 4751 4752 switch (GET_CODE (exp)) 4753 { 4754 case CONST_STRING: 4755 current_or = atoi (XSTR (exp, 0)); 4756 break; 4757 4758 case COND: 4759 current_or = or_attr_value (XEXP (exp, 1), unknownp); 4760 for (i = 0; i < XVECLEN (exp, 0); i += 2) 4761 current_or |= or_attr_value (XVECEXP (exp, 0, i + 1), unknownp); 4762 break; 4763 4764 case IF_THEN_ELSE: 4765 current_or = or_attr_value (XEXP (exp, 1), unknownp); 4766 current_or |= or_attr_value (XEXP (exp, 2), unknownp); 4767 break; 4768 4769 default: 4770 *unknownp = 1; 4771 current_or = -1; 4772 break; 4773 } 4774 4775 return current_or; 4776} 4777 4778/* Scan an attribute value, possibly a conditional, and record what actions 4779 will be required to do any conditional tests in it. 4780 4781 Specifically, set 4782 `must_extract' if we need to extract the insn operands 4783 `must_constrain' if we must compute `which_alternative' 4784 `address_used' if an address expression was used 4785 `length_used' if an (eq_attr "length" ...) was used 4786 */ 4787 4788static void 4789walk_attr_value (exp) 4790 rtx exp; 4791{ 4792 register int i, j; 4793 register char *fmt; 4794 RTX_CODE code; 4795 4796 if (exp == NULL) 4797 return; 4798 4799 code = GET_CODE (exp); 4800 switch (code) 4801 { 4802 case SYMBOL_REF: 4803 if (! RTX_UNCHANGING_P (exp)) 4804 /* Since this is an arbitrary expression, it can look at anything. 4805 However, constant expressions do not depend on any particular 4806 insn. */ 4807 must_extract = must_constrain = 1; 4808 return; 4809 4810 case MATCH_OPERAND: 4811 must_extract = 1; 4812 return; 4813 4814 case EQ_ATTR: 4815 if (XSTR (exp, 0) == alternative_name) 4816 must_extract = must_constrain = 1; 4817 else if (strcmp (XSTR (exp, 0), "length") == 0) 4818 length_used = 1; 4819 return; 4820 4821 case MATCH_DUP: 4822 must_extract = 1; 4823 address_used = 1; 4824 return; 4825 4826 case PC: 4827 address_used = 1; 4828 return; 4829 4830 case ATTR_FLAG: 4831 return; 4832 4833 default: 4834 break; 4835 } 4836 4837 for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++) 4838 switch (*fmt++) 4839 { 4840 case 'e': 4841 case 'u': 4842 walk_attr_value (XEXP (exp, i)); 4843 break; 4844 4845 case 'E': 4846 if (XVEC (exp, i) != NULL) 4847 for (j = 0; j < XVECLEN (exp, i); j++) 4848 walk_attr_value (XVECEXP (exp, i, j)); 4849 break; 4850 } 4851} 4852 4853/* Write out a function to obtain the attribute for a given INSN. */ 4854 4855static void 4856write_attr_get (attr) 4857 struct attr_desc *attr; 4858{ 4859 struct attr_value *av, *common_av; 4860 4861 /* Find the most used attribute value. Handle that as the `default' of the 4862 switch we will generate. */ 4863 common_av = find_most_used (attr); 4864 4865 /* Write out start of function, then all values with explicit `case' lines, 4866 then a `default', then the value with the most uses. */ 4867 if (!attr->is_numeric) 4868 printf ("enum attr_%s\n", attr->name); 4869 else if (attr->unsigned_p) 4870 printf ("unsigned int\n"); 4871 else 4872 printf ("int\n"); 4873 4874 /* If the attribute name starts with a star, the remainder is the name of 4875 the subroutine to use, instead of `get_attr_...'. */ 4876 if (attr->name[0] == '*') 4877 printf ("%s (insn)\n", &attr->name[1]); 4878 else if (attr->is_const == 0) 4879 printf ("get_attr_%s (insn)\n", attr->name); 4880 else 4881 { 4882 printf ("get_attr_%s ()\n", attr->name); 4883 printf ("{\n"); 4884 4885 for (av = attr->first_value; av; av = av->next) 4886 if (av->num_insns != 0) 4887 write_attr_set (attr, 2, av->value, "return", ";", 4888 true_rtx, av->first_insn->insn_code, 4889 av->first_insn->insn_index); 4890 4891 printf ("}\n\n"); 4892 return; 4893 } 4894 4895 printf (" rtx insn;\n"); 4896 printf ("{\n"); 4897 4898 if (GET_CODE (common_av->value) == FFS) 4899 { 4900 rtx p = XEXP (common_av->value, 0); 4901 4902 /* No need to emit code to abort if the insn is unrecognized; the 4903 other get_attr_foo functions will do that when we call them. */ 4904 4905 write_toplevel_expr (p); 4906 4907 printf ("\n if (accum && accum == (accum & -accum))\n"); 4908 printf (" {\n"); 4909 printf (" int i;\n"); 4910 printf (" for (i = 0; accum >>= 1; ++i) continue;\n"); 4911 printf (" accum = i;\n"); 4912 printf (" }\n else\n"); 4913 printf (" accum = ~accum;\n"); 4914 printf (" return accum;\n}\n\n"); 4915 } 4916 else 4917 { 4918 printf (" switch (recog_memoized (insn))\n"); 4919 printf (" {\n"); 4920 4921 for (av = attr->first_value; av; av = av->next) 4922 if (av != common_av) 4923 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx); 4924 4925 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx); 4926 printf (" }\n}\n\n"); 4927 } 4928} 4929 4930/* Given an AND tree of known true terms (because we are inside an `if' with 4931 that as the condition or are in an `else' clause) and an expression, 4932 replace any known true terms with TRUE. Use `simplify_and_tree' to do 4933 the bulk of the work. */ 4934 4935static rtx 4936eliminate_known_true (known_true, exp, insn_code, insn_index) 4937 rtx known_true; 4938 rtx exp; 4939 int insn_code, insn_index; 4940{ 4941 rtx term; 4942 4943 known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index); 4944 4945 if (GET_CODE (known_true) == AND) 4946 { 4947 exp = eliminate_known_true (XEXP (known_true, 0), exp, 4948 insn_code, insn_index); 4949 exp = eliminate_known_true (XEXP (known_true, 1), exp, 4950 insn_code, insn_index); 4951 } 4952 else 4953 { 4954 term = known_true; 4955 exp = simplify_and_tree (exp, &term, insn_code, insn_index); 4956 } 4957 4958 return exp; 4959} 4960 4961/* Write out a series of tests and assignment statements to perform tests and 4962 sets of an attribute value. We are passed an indentation amount and prefix 4963 and suffix strings to write around each attribute value (e.g., "return" 4964 and ";"). */ 4965 4966static void 4967write_attr_set (attr, indent, value, prefix, suffix, known_true, 4968 insn_code, insn_index) 4969 struct attr_desc *attr; 4970 int indent; 4971 rtx value; 4972 const char *prefix; 4973 const char *suffix; 4974 rtx known_true; 4975 int insn_code, insn_index; 4976{ 4977 if (GET_CODE (value) == COND) 4978 { 4979 /* Assume the default value will be the default of the COND unless we 4980 find an always true expression. */ 4981 rtx default_val = XEXP (value, 1); 4982 rtx our_known_true = known_true; 4983 rtx newexp; 4984 int first_if = 1; 4985 int i; 4986 4987 for (i = 0; i < XVECLEN (value, 0); i += 2) 4988 { 4989 rtx testexp; 4990 rtx inner_true; 4991 4992 testexp = eliminate_known_true (our_known_true, 4993 XVECEXP (value, 0, i), 4994 insn_code, insn_index); 4995 newexp = attr_rtx (NOT, testexp); 4996 newexp = insert_right_side (AND, our_known_true, newexp, 4997 insn_code, insn_index); 4998 4999 /* If the test expression is always true or if the next `known_true' 5000 expression is always false, this is the last case, so break 5001 out and let this value be the `else' case. */ 5002 if (testexp == true_rtx || newexp == false_rtx) 5003 { 5004 default_val = XVECEXP (value, 0, i + 1); 5005 break; 5006 } 5007 5008 /* Compute the expression to pass to our recursive call as being 5009 known true. */ 5010 inner_true = insert_right_side (AND, our_known_true, 5011 testexp, insn_code, insn_index); 5012 5013 /* If this is always false, skip it. */ 5014 if (inner_true == false_rtx) 5015 continue; 5016 5017 write_indent (indent); 5018 printf ("%sif ", first_if ? "" : "else "); 5019 first_if = 0; 5020 write_test_expr (testexp, 0); 5021 printf ("\n"); 5022 write_indent (indent + 2); 5023 printf ("{\n"); 5024 5025 write_attr_set (attr, indent + 4, 5026 XVECEXP (value, 0, i + 1), prefix, suffix, 5027 inner_true, insn_code, insn_index); 5028 write_indent (indent + 2); 5029 printf ("}\n"); 5030 our_known_true = newexp; 5031 } 5032 5033 if (! first_if) 5034 { 5035 write_indent (indent); 5036 printf ("else\n"); 5037 write_indent (indent + 2); 5038 printf ("{\n"); 5039 } 5040 5041 write_attr_set (attr, first_if ? indent : indent + 4, default_val, 5042 prefix, suffix, our_known_true, insn_code, insn_index); 5043 5044 if (! first_if) 5045 { 5046 write_indent (indent + 2); 5047 printf ("}\n"); 5048 } 5049 } 5050 else 5051 { 5052 write_indent (indent); 5053 printf ("%s ", prefix); 5054 write_attr_value (attr, value); 5055 printf ("%s\n", suffix); 5056 } 5057} 5058 5059/* Write out the computation for one attribute value. */ 5060 5061static void 5062write_attr_case (attr, av, write_case_lines, prefix, suffix, indent, 5063 known_true) 5064 struct attr_desc *attr; 5065 struct attr_value *av; 5066 int write_case_lines; 5067 const char *prefix, *suffix; 5068 int indent; 5069 rtx known_true; 5070{ 5071 struct insn_ent *ie; 5072 5073 if (av->num_insns == 0) 5074 return; 5075 5076 if (av->has_asm_insn) 5077 { 5078 write_indent (indent); 5079 printf ("case -1:\n"); 5080 write_indent (indent + 2); 5081 printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n"); 5082 write_indent (indent + 2); 5083 printf (" && asm_noperands (PATTERN (insn)) < 0)\n"); 5084 write_indent (indent + 2); 5085 printf (" fatal_insn_not_found (insn);\n"); 5086 } 5087 5088 if (write_case_lines) 5089 { 5090 for (ie = av->first_insn; ie; ie = ie->next) 5091 if (ie->insn_code != -1) 5092 { 5093 write_indent (indent); 5094 printf ("case %d:\n", ie->insn_code); 5095 } 5096 } 5097 else 5098 { 5099 write_indent (indent); 5100 printf ("default:\n"); 5101 } 5102 5103 /* See what we have to do to output this value. */ 5104 must_extract = must_constrain = address_used = 0; 5105 walk_attr_value (av->value); 5106 5107 if (must_extract) 5108 { 5109 write_indent (indent + 2); 5110 printf ("extract_insn (insn);\n"); 5111 } 5112 5113 if (must_constrain) 5114 { 5115#ifdef REGISTER_CONSTRAINTS 5116 write_indent (indent + 2); 5117 printf ("if (! constrain_operands (reload_completed))\n"); 5118 write_indent (indent + 2); 5119 printf (" fatal_insn_not_found (insn);\n"); 5120#endif 5121 } 5122 5123 write_attr_set (attr, indent + 2, av->value, prefix, suffix, 5124 known_true, av->first_insn->insn_code, 5125 av->first_insn->insn_index); 5126 5127 if (strncmp (prefix, "return", 6)) 5128 { 5129 write_indent (indent + 2); 5130 printf ("break;\n"); 5131 } 5132 printf ("\n"); 5133} 5134 5135/* Search for uses of non-const attributes and write code to cache them. */ 5136 5137static int 5138write_expr_attr_cache (p, attr) 5139 rtx p; 5140 struct attr_desc *attr; 5141{ 5142 char *fmt; 5143 int i, ie, j, je; 5144 5145 if (GET_CODE (p) == EQ_ATTR) 5146 { 5147 if (XSTR (p, 0) != attr->name) 5148 return 0; 5149 5150 if (!attr->is_numeric) 5151 printf (" register enum attr_%s ", attr->name); 5152 else if (attr->unsigned_p) 5153 printf (" register unsigned int "); 5154 else 5155 printf (" register int "); 5156 5157 printf ("attr_%s = get_attr_%s (insn);\n", attr->name, attr->name); 5158 return 1; 5159 } 5160 5161 fmt = GET_RTX_FORMAT (GET_CODE (p)); 5162 ie = GET_RTX_LENGTH (GET_CODE (p)); 5163 for (i = 0; i < ie; i++) 5164 { 5165 switch (*fmt++) 5166 { 5167 case 'e': 5168 if (write_expr_attr_cache (XEXP (p, i), attr)) 5169 return 1; 5170 break; 5171 5172 case 'E': 5173 je = XVECLEN (p, i); 5174 for (j = 0; j < je; ++j) 5175 if (write_expr_attr_cache (XVECEXP (p, i, j), attr)) 5176 return 1; 5177 break; 5178 } 5179 } 5180 5181 return 0; 5182} 5183 5184/* Evaluate an expression at top level. A front end to write_test_expr, 5185 in which we cache attribute values and break up excessively large 5186 expressions to cater to older compilers. */ 5187 5188static void 5189write_toplevel_expr (p) 5190 rtx p; 5191{ 5192 struct attr_desc *attr; 5193 int i; 5194 5195 for (i = 0; i < MAX_ATTRS_INDEX; ++i) 5196 for (attr = attrs[i]; attr ; attr = attr->next) 5197 if (!attr->is_const) 5198 write_expr_attr_cache (p, attr); 5199 5200 printf(" register unsigned long accum = 0;\n\n"); 5201 5202 while (GET_CODE (p) == IOR) 5203 { 5204 rtx e; 5205 if (GET_CODE (XEXP (p, 0)) == IOR) 5206 e = XEXP (p, 1), p = XEXP (p, 0); 5207 else 5208 e = XEXP (p, 0), p = XEXP (p, 1); 5209 5210 printf (" accum |= "); 5211 write_test_expr (e, 3); 5212 printf (";\n"); 5213 } 5214 printf (" accum |= "); 5215 write_test_expr (p, 3); 5216 printf (";\n"); 5217} 5218 5219/* Utilities to write names in various forms. */ 5220 5221static void 5222write_unit_name (prefix, num, suffix) 5223 const char *prefix; 5224 int num; 5225 const char *suffix; 5226{ 5227 struct function_unit *unit; 5228 5229 for (unit = units; unit; unit = unit->next) 5230 if (unit->num == num) 5231 { 5232 printf ("%s%s%s", prefix, unit->name, suffix); 5233 return; 5234 } 5235 5236 printf ("%s<unknown>%s", prefix, suffix); 5237} 5238 5239static void 5240write_attr_valueq (attr, s) 5241 struct attr_desc *attr; 5242 char *s; 5243{ 5244 if (attr->is_numeric) 5245 { 5246 int num = atoi (s); 5247 5248 printf ("%d", num); 5249 5250 /* Make the blockage range values and function units used values easier 5251 to read. */ 5252 if (attr->func_units_p) 5253 { 5254 if (num == -1) 5255 printf (" /* units: none */"); 5256 else if (num >= 0) 5257 write_unit_name (" /* units: ", num, " */"); 5258 else 5259 { 5260 int i; 5261 const char *sep = " /* units: "; 5262 for (i = 0, num = ~num; num; i++, num >>= 1) 5263 if (num & 1) 5264 { 5265 write_unit_name (sep, i, (num == 1) ? " */" : ""); 5266 sep = ", "; 5267 } 5268 } 5269 } 5270 5271 else if (attr->blockage_p) 5272 printf (" /* min %d, max %d */", num >> (HOST_BITS_PER_INT / 2), 5273 num & ((1 << (HOST_BITS_PER_INT / 2)) - 1)); 5274 5275 else if (num > 9 || num < 0) 5276 printf (" /* 0x%x */", num); 5277 } 5278 else 5279 { 5280 write_upcase (attr->name); 5281 printf ("_"); 5282 write_upcase (s); 5283 } 5284} 5285 5286static void 5287write_attr_value (attr, value) 5288 struct attr_desc *attr; 5289 rtx value; 5290{ 5291 int op; 5292 5293 switch (GET_CODE (value)) 5294 { 5295 case CONST_STRING: 5296 write_attr_valueq (attr, XSTR (value, 0)); 5297 break; 5298 5299 case SYMBOL_REF: 5300 fputs (XSTR (value, 0), stdout); 5301 break; 5302 5303 case ATTR: 5304 { 5305 struct attr_desc *attr2 = find_attr (XSTR (value, 0), 0); 5306 printf ("get_attr_%s (%s)", attr2->name, 5307 (attr2->is_const ? "" : "insn")); 5308 } 5309 break; 5310 5311 case PLUS: 5312 op = '+'; 5313 goto do_operator; 5314 case MINUS: 5315 op = '-'; 5316 goto do_operator; 5317 case MULT: 5318 op = '*'; 5319 goto do_operator; 5320 case DIV: 5321 op = '/'; 5322 goto do_operator; 5323 case MOD: 5324 op = '%'; 5325 goto do_operator; 5326 5327 do_operator: 5328 write_attr_value (attr, XEXP (value, 0)); 5329 putchar (' '); 5330 putchar (op); 5331 putchar (' '); 5332 write_attr_value (attr, XEXP (value, 1)); 5333 break; 5334 5335 default: 5336 abort (); 5337 } 5338} 5339 5340static void 5341write_upcase (str) 5342 char *str; 5343{ 5344 while (*str) 5345 if (*str < 'a' || *str > 'z') 5346 printf ("%c", *str++); 5347 else 5348 printf ("%c", *str++ - 'a' + 'A'); 5349} 5350 5351static void 5352write_indent (indent) 5353 int indent; 5354{ 5355 for (; indent > 8; indent -= 8) 5356 printf ("\t"); 5357 5358 for (; indent; indent--) 5359 printf (" "); 5360} 5361 5362/* Write a subroutine that is given an insn that requires a delay slot, a 5363 delay slot ordinal, and a candidate insn. It returns non-zero if the 5364 candidate can be placed in the specified delay slot of the insn. 5365 5366 We can write as many as three subroutines. `eligible_for_delay' 5367 handles normal delay slots, `eligible_for_annul_true' indicates that 5368 the specified insn can be annulled if the branch is true, and likewise 5369 for `eligible_for_annul_false'. 5370 5371 KIND is a string distinguishing these three cases ("delay", "annul_true", 5372 or "annul_false"). */ 5373 5374static void 5375write_eligible_delay (kind) 5376 const char *kind; 5377{ 5378 struct delay_desc *delay; 5379 int max_slots; 5380 char str[50]; 5381 struct attr_desc *attr; 5382 struct attr_value *av, *common_av; 5383 int i; 5384 5385 /* Compute the maximum number of delay slots required. We use the delay 5386 ordinal times this number plus one, plus the slot number as an index into 5387 the appropriate predicate to test. */ 5388 5389 for (delay = delays, max_slots = 0; delay; delay = delay->next) 5390 if (XVECLEN (delay->def, 1) / 3 > max_slots) 5391 max_slots = XVECLEN (delay->def, 1) / 3; 5392 5393 /* Write function prelude. */ 5394 5395 printf ("int\n"); 5396 printf ("eligible_for_%s (delay_insn, slot, candidate_insn, flags)\n", 5397 kind); 5398 printf (" rtx delay_insn;\n"); 5399 printf (" int slot;\n"); 5400 printf (" rtx candidate_insn;\n"); 5401 printf (" int flags;\n"); 5402 printf ("{\n"); 5403 printf (" rtx insn;\n"); 5404 printf ("\n"); 5405 printf (" if (slot >= %d)\n", max_slots); 5406 printf (" abort ();\n"); 5407 printf ("\n"); 5408 5409 /* If more than one delay type, find out which type the delay insn is. */ 5410 5411 if (num_delays > 1) 5412 { 5413 attr = find_attr ("*delay_type", 0); 5414 if (! attr) abort (); 5415 common_av = find_most_used (attr); 5416 5417 printf (" insn = delay_insn;\n"); 5418 printf (" switch (recog_memoized (insn))\n"); 5419 printf (" {\n"); 5420 5421 sprintf (str, " * %d;\n break;", max_slots); 5422 for (av = attr->first_value; av; av = av->next) 5423 if (av != common_av) 5424 write_attr_case (attr, av, 1, "slot +=", str, 4, true_rtx); 5425 5426 write_attr_case (attr, common_av, 0, "slot +=", str, 4, true_rtx); 5427 printf (" }\n\n"); 5428 5429 /* Ensure matched. Otherwise, shouldn't have been called. */ 5430 printf (" if (slot < %d)\n", max_slots); 5431 printf (" abort ();\n\n"); 5432 } 5433 5434 /* If just one type of delay slot, write simple switch. */ 5435 if (num_delays == 1 && max_slots == 1) 5436 { 5437 printf (" insn = candidate_insn;\n"); 5438 printf (" switch (recog_memoized (insn))\n"); 5439 printf (" {\n"); 5440 5441 attr = find_attr ("*delay_1_0", 0); 5442 if (! attr) abort (); 5443 common_av = find_most_used (attr); 5444 5445 for (av = attr->first_value; av; av = av->next) 5446 if (av != common_av) 5447 write_attr_case (attr, av, 1, "return", ";", 4, true_rtx); 5448 5449 write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx); 5450 printf (" }\n"); 5451 } 5452 5453 else 5454 { 5455 /* Write a nested CASE. The first indicates which condition we need to 5456 test, and the inner CASE tests the condition. */ 5457 printf (" insn = candidate_insn;\n"); 5458 printf (" switch (slot)\n"); 5459 printf (" {\n"); 5460 5461 for (delay = delays; delay; delay = delay->next) 5462 for (i = 0; i < XVECLEN (delay->def, 1); i += 3) 5463 { 5464 printf (" case %d:\n", 5465 (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots)); 5466 printf (" switch (recog_memoized (insn))\n"); 5467 printf ("\t{\n"); 5468 5469 sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3); 5470 attr = find_attr (str, 0); 5471 if (! attr) abort (); 5472 common_av = find_most_used (attr); 5473 5474 for (av = attr->first_value; av; av = av->next) 5475 if (av != common_av) 5476 write_attr_case (attr, av, 1, "return", ";", 8, true_rtx); 5477 5478 write_attr_case (attr, common_av, 0, "return", ";", 8, true_rtx); 5479 printf (" }\n"); 5480 } 5481 5482 printf (" default:\n"); 5483 printf (" abort ();\n"); 5484 printf (" }\n"); 5485 } 5486 5487 printf ("}\n\n"); 5488} 5489 5490/* Write routines to compute conflict cost for function units. Then write a 5491 table describing the available function units. */ 5492 5493static void 5494write_function_unit_info () 5495{ 5496 struct function_unit *unit; 5497 int i; 5498 5499 /* Write out conflict routines for function units. Don't bother writing 5500 one if there is only one issue delay value. */ 5501 5502 for (unit = units; unit; unit = unit->next) 5503 { 5504 if (unit->needs_blockage_function) 5505 write_complex_function (unit, "blockage", "block"); 5506 5507 /* If the minimum and maximum conflict costs are the same, there 5508 is only one value, so we don't need a function. */ 5509 if (! unit->needs_conflict_function) 5510 { 5511 unit->default_cost = make_numeric_value (unit->issue_delay.max); 5512 continue; 5513 } 5514 5515 /* The function first computes the case from the candidate insn. */ 5516 unit->default_cost = make_numeric_value (0); 5517 write_complex_function (unit, "conflict_cost", "cost"); 5518 } 5519 5520 /* Now that all functions have been written, write the table describing 5521 the function units. The name is included for documentation purposes 5522 only. */ 5523 5524 printf ("struct function_unit_desc function_units[] = {\n"); 5525 5526 /* Write out the descriptions in numeric order, but don't force that order 5527 on the list. Doing so increases the runtime of genattrtab.c. */ 5528 for (i = 0; i < num_units; i++) 5529 { 5530 for (unit = units; unit; unit = unit->next) 5531 if (unit->num == i) 5532 break; 5533 5534 printf (" {\"%s\", %d, %d, %d, %s, %d, %s_unit_ready_cost, ", 5535 unit->name, 1 << unit->num, unit->multiplicity, 5536 unit->simultaneity, XSTR (unit->default_cost, 0), 5537 unit->issue_delay.max, unit->name); 5538 5539 if (unit->needs_conflict_function) 5540 printf ("%s_unit_conflict_cost, ", unit->name); 5541 else 5542 printf ("0, "); 5543 5544 printf ("%d, ", unit->max_blockage); 5545 5546 if (unit->needs_range_function) 5547 printf ("%s_unit_blockage_range, ", unit->name); 5548 else 5549 printf ("0, "); 5550 5551 if (unit->needs_blockage_function) 5552 printf ("%s_unit_blockage", unit->name); 5553 else 5554 printf ("0"); 5555 5556 printf ("}, \n"); 5557 } 5558 5559 printf ("};\n\n"); 5560} 5561 5562static void 5563write_complex_function (unit, name, connection) 5564 struct function_unit *unit; 5565 const char *name, *connection; 5566{ 5567 struct attr_desc *case_attr, *attr; 5568 struct attr_value *av, *common_av; 5569 rtx value; 5570 char *str; 5571 int using_case; 5572 int i; 5573 5574 printf ("static int\n"); 5575 printf ("%s_unit_%s (executing_insn, candidate_insn)\n", 5576 unit->name, name); 5577 printf (" rtx executing_insn;\n"); 5578 printf (" rtx candidate_insn;\n"); 5579 printf ("{\n"); 5580 printf (" rtx insn;\n"); 5581 printf (" int casenum;\n\n"); 5582 printf (" insn = executing_insn;\n"); 5583 printf (" switch (recog_memoized (insn))\n"); 5584 printf (" {\n"); 5585 5586 /* Write the `switch' statement to get the case value. */ 5587 str = (char *) alloca (strlen (unit->name) + strlen (name) + strlen (connection) + 10); 5588 sprintf (str, "*%s_cases", unit->name); 5589 case_attr = find_attr (str, 0); 5590 if (! case_attr) abort (); 5591 common_av = find_most_used (case_attr); 5592 5593 for (av = case_attr->first_value; av; av = av->next) 5594 if (av != common_av) 5595 write_attr_case (case_attr, av, 1, 5596 "casenum =", ";", 4, unit->condexp); 5597 5598 write_attr_case (case_attr, common_av, 0, 5599 "casenum =", ";", 4, unit->condexp); 5600 printf (" }\n\n"); 5601 5602 /* Now write an outer switch statement on each case. Then write 5603 the tests on the executing function within each. */ 5604 printf (" insn = candidate_insn;\n"); 5605 printf (" switch (casenum)\n"); 5606 printf (" {\n"); 5607 5608 for (i = 0; i < unit->num_opclasses; i++) 5609 { 5610 /* Ensure using this case. */ 5611 using_case = 0; 5612 for (av = case_attr->first_value; av; av = av->next) 5613 if (av->num_insns 5614 && contained_in_p (make_numeric_value (i), av->value)) 5615 using_case = 1; 5616 5617 if (! using_case) 5618 continue; 5619 5620 printf (" case %d:\n", i); 5621 sprintf (str, "*%s_%s_%d", unit->name, connection, i); 5622 attr = find_attr (str, 0); 5623 if (! attr) abort (); 5624 5625 /* If single value, just write it. */ 5626 value = find_single_value (attr); 5627 if (value) 5628 write_attr_set (attr, 6, value, "return", ";\n", true_rtx, -2, -2); 5629 else 5630 { 5631 common_av = find_most_used (attr); 5632 printf (" switch (recog_memoized (insn))\n"); 5633 printf ("\t{\n"); 5634 5635 for (av = attr->first_value; av; av = av->next) 5636 if (av != common_av) 5637 write_attr_case (attr, av, 1, 5638 "return", ";", 8, unit->condexp); 5639 5640 write_attr_case (attr, common_av, 0, 5641 "return", ";", 8, unit->condexp); 5642 printf (" }\n\n"); 5643 } 5644 } 5645 5646 /* This default case should not be needed, but gcc's analysis is not 5647 good enough to realize that the default case is not needed for the 5648 second switch statement. */ 5649 printf (" default:\n abort ();\n"); 5650 printf (" }\n}\n\n"); 5651} 5652 5653/* This page contains miscellaneous utility routines. */ 5654 5655/* Given a string, return the number of comma-separated elements in it. 5656 Return 0 for the null string. */ 5657 5658static int 5659n_comma_elts (s) 5660 char *s; 5661{ 5662 int n; 5663 5664 if (*s == '\0') 5665 return 0; 5666 5667 for (n = 1; *s; s++) 5668 if (*s == ',') 5669 n++; 5670 5671 return n; 5672} 5673 5674/* Given a pointer to a (char *), return a malloc'ed string containing the 5675 next comma-separated element. Advance the pointer to after the string 5676 scanned, or the end-of-string. Return NULL if at end of string. */ 5677 5678static char * 5679next_comma_elt (pstr) 5680 char **pstr; 5681{ 5682 char *out_str; 5683 char *p; 5684 5685 if (**pstr == '\0') 5686 return NULL; 5687 5688 /* Find end of string to compute length. */ 5689 for (p = *pstr; *p != ',' && *p != '\0'; p++) 5690 ; 5691 5692 out_str = attr_string (*pstr, p - *pstr); 5693 *pstr = p; 5694 5695 if (**pstr == ',') 5696 (*pstr)++; 5697 5698 return out_str; 5699} 5700 5701/* Return a `struct attr_desc' pointer for a given named attribute. If CREATE 5702 is non-zero, build a new attribute, if one does not exist. */ 5703 5704static struct attr_desc * 5705find_attr (name, create) 5706 const char *name; 5707 int create; 5708{ 5709 struct attr_desc *attr; 5710 int index; 5711 5712 /* Before we resort to using `strcmp', see if the string address matches 5713 anywhere. In most cases, it should have been canonicalized to do so. */ 5714 if (name == alternative_name) 5715 return NULL; 5716 5717 index = name[0] & (MAX_ATTRS_INDEX - 1); 5718 for (attr = attrs[index]; attr; attr = attr->next) 5719 if (name == attr->name) 5720 return attr; 5721 5722 /* Otherwise, do it the slow way. */ 5723 for (attr = attrs[index]; attr; attr = attr->next) 5724 if (name[0] == attr->name[0] && ! strcmp (name, attr->name)) 5725 return attr; 5726 5727 if (! create) 5728 return NULL; 5729 5730 attr = (struct attr_desc *) oballoc (sizeof (struct attr_desc)); 5731 attr->name = attr_string (name, strlen (name)); 5732 attr->first_value = attr->default_val = NULL; 5733 attr->is_numeric = attr->negative_ok = attr->is_const = attr->is_special = 0; 5734 attr->next = attrs[index]; 5735 attrs[index] = attr; 5736 5737 return attr; 5738} 5739 5740/* Create internal attribute with the given default value. */ 5741 5742static void 5743make_internal_attr (name, value, special) 5744 const char *name; 5745 rtx value; 5746 int special; 5747{ 5748 struct attr_desc *attr; 5749 5750 attr = find_attr (name, 1); 5751 if (attr->default_val) 5752 abort (); 5753 5754 attr->is_numeric = 1; 5755 attr->is_const = 0; 5756 attr->is_special = (special & 1) != 0; 5757 attr->negative_ok = (special & 2) != 0; 5758 attr->unsigned_p = (special & 4) != 0; 5759 attr->func_units_p = (special & 8) != 0; 5760 attr->blockage_p = (special & 16) != 0; 5761 attr->default_val = get_attr_value (value, attr, -2); 5762} 5763 5764/* Find the most used value of an attribute. */ 5765 5766static struct attr_value * 5767find_most_used (attr) 5768 struct attr_desc *attr; 5769{ 5770 struct attr_value *av; 5771 struct attr_value *most_used; 5772 int nuses; 5773 5774 most_used = NULL; 5775 nuses = -1; 5776 5777 for (av = attr->first_value; av; av = av->next) 5778 if (av->num_insns > nuses) 5779 nuses = av->num_insns, most_used = av; 5780 5781 return most_used; 5782} 5783 5784/* If an attribute only has a single value used, return it. Otherwise 5785 return NULL. */ 5786 5787static rtx 5788find_single_value (attr) 5789 struct attr_desc *attr; 5790{ 5791 struct attr_value *av; 5792 rtx unique_value; 5793 5794 unique_value = NULL; 5795 for (av = attr->first_value; av; av = av->next) 5796 if (av->num_insns) 5797 { 5798 if (unique_value) 5799 return NULL; 5800 else 5801 unique_value = av->value; 5802 } 5803 5804 return unique_value; 5805} 5806 5807/* Return (attr_value "n") */ 5808 5809static rtx 5810make_numeric_value (n) 5811 int n; 5812{ 5813 static rtx int_values[20]; 5814 rtx exp; 5815 char *p; 5816 5817 if (n < 0) 5818 abort (); 5819 5820 if (n < 20 && int_values[n]) 5821 return int_values[n]; 5822 5823 p = attr_printf (MAX_DIGITS, "%d", n); 5824 exp = attr_rtx (CONST_STRING, p); 5825 5826 if (n < 20) 5827 int_values[n] = exp; 5828 5829 return exp; 5830} 5831 5832static void 5833extend_range (range, min, max) 5834 struct range *range; 5835 int min; 5836 int max; 5837{ 5838 if (range->min > min) range->min = min; 5839 if (range->max < max) range->max = max; 5840} 5841 5842PTR 5843xrealloc (old, size) 5844 PTR old; 5845 size_t size; 5846{ 5847 register PTR ptr; 5848 if (old) 5849 ptr = (PTR) realloc (old, size); 5850 else 5851 ptr = (PTR) malloc (size); 5852 if (!ptr) 5853 fatal ("virtual memory exhausted"); 5854 return ptr; 5855} 5856 5857PTR 5858xmalloc (size) 5859 size_t size; 5860{ 5861 register PTR val = (PTR) malloc (size); 5862 5863 if (val == 0) 5864 fatal ("virtual memory exhausted"); 5865 return val; 5866} 5867 5868static rtx 5869copy_rtx_unchanging (orig) 5870 register rtx orig; 5871{ 5872#if 0 5873 register rtx copy; 5874 register RTX_CODE code; 5875#endif 5876 5877 if (RTX_UNCHANGING_P (orig) || MEM_IN_STRUCT_P (orig)) 5878 return orig; 5879 5880 MEM_IN_STRUCT_P (orig) = 1; 5881 return orig; 5882 5883#if 0 5884 code = GET_CODE (orig); 5885 switch (code) 5886 { 5887 case CONST_INT: 5888 case CONST_DOUBLE: 5889 case SYMBOL_REF: 5890 case CODE_LABEL: 5891 return orig; 5892 5893 default: 5894 break; 5895 } 5896 5897 copy = rtx_alloc (code); 5898 PUT_MODE (copy, GET_MODE (orig)); 5899 RTX_UNCHANGING_P (copy) = 1; 5900 5901 bcopy ((char *) &XEXP (orig, 0), (char *) &XEXP (copy, 0), 5902 GET_RTX_LENGTH (GET_CODE (copy)) * sizeof (rtx)); 5903 return copy; 5904#endif 5905} 5906 5907void 5908fatal VPROTO ((const char *format, ...)) 5909{ 5910#ifndef ANSI_PROTOTYPES 5911 const char *format; 5912#endif 5913 va_list ap; 5914 5915 VA_START (ap, format); 5916 5917#ifndef ANSI_PROTOTYPES 5918 format = va_arg (ap, const char *); 5919#endif 5920 5921 fprintf (stderr, "genattrtab: "); 5922 vfprintf (stderr, format, ap); 5923 va_end (ap); 5924 fprintf (stderr, "\n"); 5925 exit (FATAL_EXIT_CODE); 5926} 5927 5928/* More 'friendly' abort that prints the line and file. 5929 config.h can #define abort fancy_abort if you like that sort of thing. */ 5930 5931void 5932fancy_abort () 5933{ 5934 fatal ("Internal gcc abort."); 5935} 5936 5937/* Determine if an insn has a constant number of delay slots, i.e., the 5938 number of delay slots is not a function of the length of the insn. */ 5939 5940void 5941write_const_num_delay_slots () 5942{ 5943 struct attr_desc *attr = find_attr ("*num_delay_slots", 0); 5944 struct attr_value *av; 5945 struct insn_ent *ie; 5946 5947 if (attr) 5948 { 5949 printf ("int\nconst_num_delay_slots (insn)\n"); 5950 printf (" rtx insn;\n"); 5951 printf ("{\n"); 5952 printf (" switch (recog_memoized (insn))\n"); 5953 printf (" {\n"); 5954 5955 for (av = attr->first_value; av; av = av->next) 5956 { 5957 length_used = 0; 5958 walk_attr_value (av->value); 5959 if (length_used) 5960 { 5961 for (ie = av->first_insn; ie; ie = ie->next) 5962 if (ie->insn_code != -1) 5963 printf (" case %d:\n", ie->insn_code); 5964 printf (" return 0;\n"); 5965 } 5966 } 5967 5968 printf (" default:\n"); 5969 printf (" return 1;\n"); 5970 printf (" }\n}\n\n"); 5971 } 5972} 5973 5974 5975int 5976main (argc, argv) 5977 int argc; 5978 char **argv; 5979{ 5980 rtx desc; 5981 FILE *infile; 5982 register int c; 5983 struct attr_desc *attr; 5984 struct insn_def *id; 5985 rtx tem; 5986 int i; 5987 5988#if defined (RLIMIT_STACK) && defined (HAVE_GETRLIMIT) && defined (HAVE_SETRLIMIT) 5989 /* Get rid of any avoidable limit on stack size. */ 5990 { 5991 struct rlimit rlim; 5992 5993 /* Set the stack limit huge so that alloca does not fail. */ 5994 getrlimit (RLIMIT_STACK, &rlim); 5995 rlim.rlim_cur = rlim.rlim_max; 5996 setrlimit (RLIMIT_STACK, &rlim); 5997 } 5998#endif 5999 6000 obstack_init (rtl_obstack); 6001 obstack_init (hash_obstack); 6002 obstack_init (temp_obstack); 6003 6004 if (argc <= 1) 6005 fatal ("No input file name."); 6006 6007 infile = fopen (argv[1], "r"); 6008 if (infile == 0) 6009 { 6010 perror (argv[1]); 6011 exit (FATAL_EXIT_CODE); 6012 } 6013 6014 init_rtl (); 6015 6016 /* Set up true and false rtx's */ 6017 true_rtx = rtx_alloc (CONST_INT); 6018 XWINT (true_rtx, 0) = 1; 6019 false_rtx = rtx_alloc (CONST_INT); 6020 XWINT (false_rtx, 0) = 0; 6021 RTX_UNCHANGING_P (true_rtx) = RTX_UNCHANGING_P (false_rtx) = 1; 6022 RTX_INTEGRATED_P (true_rtx) = RTX_INTEGRATED_P (false_rtx) = 1; 6023 6024 alternative_name = attr_string ("alternative", strlen ("alternative")); 6025 6026 printf ("/* Generated automatically by the program `genattrtab'\n\ 6027from the machine description file `md'. */\n\n"); 6028 6029 /* Read the machine description. */ 6030 6031 while (1) 6032 { 6033 c = read_skip_spaces (infile); 6034 if (c == EOF) 6035 break; 6036 ungetc (c, infile); 6037 6038 desc = read_rtx (infile); 6039 if (GET_CODE (desc) == DEFINE_INSN 6040 || GET_CODE (desc) == DEFINE_PEEPHOLE 6041 || GET_CODE (desc) == DEFINE_ASM_ATTRIBUTES) 6042 gen_insn (desc); 6043 6044 else if (GET_CODE (desc) == DEFINE_EXPAND) 6045 insn_code_number++, insn_index_number++; 6046 6047 else if (GET_CODE (desc) == DEFINE_SPLIT) 6048 insn_code_number++, insn_index_number++; 6049 6050 else if (GET_CODE (desc) == DEFINE_ATTR) 6051 { 6052 gen_attr (desc); 6053 insn_index_number++; 6054 } 6055 6056 else if (GET_CODE (desc) == DEFINE_DELAY) 6057 { 6058 gen_delay (desc); 6059 insn_index_number++; 6060 } 6061 6062 else if (GET_CODE (desc) == DEFINE_FUNCTION_UNIT) 6063 { 6064 gen_unit (desc); 6065 insn_index_number++; 6066 } 6067 } 6068 6069 /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one. */ 6070 if (! got_define_asm_attributes) 6071 { 6072 tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES); 6073 XVEC (tem, 0) = rtvec_alloc (0); 6074 gen_insn (tem); 6075 } 6076 6077 /* Expand DEFINE_DELAY information into new attribute. */ 6078 if (num_delays) 6079 expand_delays (); 6080 6081 /* Expand DEFINE_FUNCTION_UNIT information into new attributes. */ 6082 if (num_units) 6083 expand_units (); 6084 6085 printf ("#include \"config.h\"\n"); 6086 printf ("#include \"system.h\"\n"); 6087 printf ("#include \"rtl.h\"\n"); 6088 printf ("#include \"insn-config.h\"\n"); 6089 printf ("#include \"recog.h\"\n"); 6090 printf ("#include \"regs.h\"\n"); 6091 printf ("#include \"real.h\"\n"); 6092 printf ("#include \"output.h\"\n"); 6093 printf ("#include \"insn-attr.h\"\n"); 6094 printf ("#include \"toplev.h\"\n"); 6095 printf ("\n"); 6096 printf ("#define operands recog_operand\n\n"); 6097 6098 /* Make `insn_alternatives'. */ 6099 insn_alternatives = (int *) oballoc (insn_code_number * sizeof (int)); 6100 for (id = defs; id; id = id->next) 6101 if (id->insn_code >= 0) 6102 insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1; 6103 6104 /* Make `insn_n_alternatives'. */ 6105 insn_n_alternatives = (int *) oballoc (insn_code_number * sizeof (int)); 6106 for (id = defs; id; id = id->next) 6107 if (id->insn_code >= 0) 6108 insn_n_alternatives[id->insn_code] = id->num_alternatives; 6109 6110 /* Prepare to write out attribute subroutines by checking everything stored 6111 away and building the attribute cases. */ 6112 6113 check_defs (); 6114 for (i = 0; i < MAX_ATTRS_INDEX; i++) 6115 for (attr = attrs[i]; attr; attr = attr->next) 6116 { 6117 attr->default_val->value 6118 = check_attr_value (attr->default_val->value, attr); 6119 fill_attr (attr); 6120 } 6121 6122 /* Construct extra attributes for `length'. */ 6123 make_length_attrs (); 6124 6125 /* Perform any possible optimizations to speed up compilation. */ 6126 optimize_attrs (); 6127 6128 /* Now write out all the `gen_attr_...' routines. Do these before the 6129 special routines (specifically before write_function_unit_info), so 6130 that they get defined before they are used. */ 6131 6132 for (i = 0; i < MAX_ATTRS_INDEX; i++) 6133 for (attr = attrs[i]; attr; attr = attr->next) 6134 { 6135 if (! attr->is_special && ! attr->is_const) 6136 write_attr_get (attr); 6137 } 6138 6139 /* Write out delay eligibility information, if DEFINE_DELAY present. 6140 (The function to compute the number of delay slots will be written 6141 below.) */ 6142 if (num_delays) 6143 { 6144 write_eligible_delay ("delay"); 6145 if (have_annul_true) 6146 write_eligible_delay ("annul_true"); 6147 if (have_annul_false) 6148 write_eligible_delay ("annul_false"); 6149 } 6150 6151 /* Write out information about function units. */ 6152 if (num_units) 6153 write_function_unit_info (); 6154 6155 /* Write out constant delay slot info */ 6156 write_const_num_delay_slots (); 6157 6158 write_length_unit_log (); 6159 6160 fflush (stdout); 6161 exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE); 6162 /* NOTREACHED */ 6163 return 0; 6164} 6165