Annotation of gcc/genattrtab.c, revision 1.1.1.4

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

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.