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