Annotation of gcc/genattrtab.c, revision 1.1.1.1

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: 
                     21: /* This program handles insn attribues and the DEFINE_DELAY and
                     22:    DEFINE_FUNCTION_UNIT definitions.
                     23: 
                     24:    It produces a series of functions call `get_attr_...', one for each
                     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: 
                     47:    Internal attributes are defined to handle DEFINE_DELAY and
                     48:    DEFINE_FUNCTION_UNIT.  Special routines are output for these cases.
                     49: 
                     50:    This program works by keeping a list of possible values for each attribute.
                     51:    These include the basic attribute choices, default values for attribute, and
                     52:    all derived quantities.
                     53: 
                     54:    As the description file is read, the definition for each insn is saved in a
                     55:    `struct insn_def'.   When the file reading is complete, a `struct insn_ent'
                     56:    is created for each insn and chained to the corresponding attribute value,
                     57:    either that specified, or the default.
                     58: 
                     59:    An optimization phase is then run.  This simplifies expressions for each
                     60:    insn.  EQ_ATTR tests are resolved, whenever possible, to a test that
                     61:    indicates when the attribute has the specified value for the insn.  This
                     62:    avoids recursive calls during compilation.
                     63: 
                     64:    The strategy used when processing DEFINE_DELAY and DEFINE_FUNCTION_UNIT
                     65:    definitions is to create arbitrarily complex expressions and have the
                     66:    optimization simplify them.
                     67: 
                     68:    Once optimization is complete, any required routines and definitions
                     69:    will be written.  */
                     70: 
                     71: #include <stdio.h>
                     72: #include "config.h"
                     73: #include "rtl.h"
                     74: #include "obstack.h"
                     75: #include "insn-config.h"       /* For REGISTER_CONSTRAINTS */
                     76: 
                     77: static struct obstack obstack;
                     78: struct obstack *rtl_obstack = &obstack;
                     79: 
                     80: #define obstack_chunk_alloc xmalloc
                     81: #define obstack_chunk_free free
                     82: 
                     83: extern void free ();
                     84: 
                     85: static void fatal ();
                     86: void fancy_abort ();
                     87: 
                     88: /* Define structures used to record attributes and values.  */
                     89: 
                     90: /* As each DEFINE_INSN, DEFINE_PEEPHOLE, or DEFINE_ASM_ATTRIBUTES is
                     91:    encountered, we store all the relevant information into a
                     92:    `struct insn_def'.  This is done to allow attribute definitions to occur
                     93:    anywhere in the file.  */
                     94: 
                     95: struct insn_def
                     96: {
                     97:   int insn_code;               /* Instruction number. */
                     98:   int insn_index;              /* Expression numer in file, for errors. */
                     99:   struct insn_def *next;       /* Next insn in chain. */
                    100:   rtx def;                     /* The DEFINE_... */
                    101:   int num_alternatives;                /* Number of alternatives.  */
                    102:   int vec_idx;                 /* Index of attribute vector in `def'. */
                    103: };
                    104: 
                    105: /* Once everything has been read in, we store in each attribute value a list
                    106:    of insn codes that have that value.  Here is the structure used for the
                    107:    list.  */
                    108: 
                    109: struct insn_ent
                    110: {
                    111:   int insn_code;               /* Instruction number.  */
                    112:   int insn_index;              /* Index of definition in file */
                    113:   struct insn_ent *next;       /* Next in chain.  */
                    114: };
                    115: 
                    116: /* Each value of an attribute (either constant or computed) is assigned a
                    117:    structure which is used as the listhead of the insns that have that
                    118:    value.  */
                    119: 
                    120: struct attr_value
                    121: {
                    122:   rtx value;                   /* Value of attribute.  */
                    123:   struct attr_value *next;     /* Next attribute value in chain.  */
                    124:   struct insn_ent *first_insn; /* First insn with this value.  */
                    125:   int num_insns;               /* Number of insns with this value.  */
                    126:   int has_asm_insn;            /* True if this value used for `asm' insns */
                    127: };
                    128: 
                    129: /* Structure for each attribute.  */
                    130: 
                    131: struct attr_desc
                    132: {
                    133:   char *name;                  /* Name of attribute. */
                    134:   struct attr_desc *next;      /* Next attribute. */
                    135:   int is_numeric;              /* Values of this attribute are numeric. */
                    136:   int is_special;              /* Don't call `write_attr_set'. */
                    137:   struct attr_value *first_value; /* First value of this attribute. */
                    138:   struct attr_value *default_val; /* Default value for this attribute. */
                    139: };
                    140: 
                    141: /* Structure for each DEFINE_DELAY.  */
                    142: 
                    143: struct delay_desc
                    144: {
                    145:   rtx def;                     /* DEFINE_DELAY expression.  */
                    146:   struct delay_desc *next;     /* Next DEFINE_DELAY. */
                    147:   int num;                     /* Number of DEFINE_DELAY, starting at 1.  */
                    148: };
                    149: 
                    150: /* Record information about each DEFINE_FUNCTION_UNIT.  */
                    151: 
                    152: struct function_unit_op
                    153: {
                    154:   rtx condexp;                 /* Expression TRUE for applicable insn.  */
                    155:   struct function_unit_op *next; /* Next operation for this function unit.  */
                    156:   int num;                     /* Ordinal for this operation type in unit.  */
                    157:   int ready;                   /* Cost until data is ready.  */
                    158:   rtx busyexp;                 /* Expression computing conflict cost.  */
                    159: };
                    160: 
                    161: /* Record information about each function unit mentioned in a
                    162:    DEFINE_FUNCTION_UNIT.  */
                    163: 
                    164: struct function_unit
                    165: {
                    166:   char *name;                  /* Function unit name.  */
                    167:   struct function_unit *next;  /* Next function unit.  */
                    168:   int num;                     /* Ordinal of this unit type.  */
                    169:   int multiplicity;            /* Number of units of this type.  */
                    170:   int simultaneity;            /* Maximum number of simultaneous insns
                    171:                                   on this function unit or 0 if unlimited.  */
                    172:   rtx condexp;                 /* Expression TRUE for insn needing unit. */
                    173:   rtx costexp;                 /* Worst-case cost as function of insn. */
                    174:   int num_opclasses;           /* Number of different operation types.  */
                    175:   struct function_unit_op *ops;        /* Pointer to first operation type.  */
                    176:   int needs_conflict_function; /* Nonzero if a conflict function required.  */
                    177:   rtx default_cost;            /* Conflict cost, if constant.  */
                    178: };
                    179: 
                    180: /* Listheads of above structures.  */
                    181: 
                    182: static struct attr_desc *attrs;
                    183: static struct insn_def *defs;
                    184: static struct delay_desc *delays;
                    185: static struct function_unit *units;
                    186: 
                    187: /* Other variables. */
                    188: 
                    189: static int insn_code_number;
                    190: static int insn_index_number;
                    191: static int got_define_asm_attributes;
                    192: static int must_extract;
                    193: static int must_constrain;
                    194: static int address_used;
                    195: static int num_delays;
                    196: static int have_annul_true, have_annul_false;
                    197: static int num_units;
                    198: 
                    199: /* Used as operand to `operate_exp':  */
                    200: 
                    201: enum operator {PLUS_OP, MINUS_OP, OR_OP, MAX_OP};
                    202: 
                    203: /* Stores, for each insn code, a bitmap that has bits on for each possible
                    204:    alternative.  */
                    205: 
                    206: static int *insn_alternatives;
                    207: 
                    208: /* Used to simplify expressions.  */
                    209: 
                    210: static rtx true_rtx, false_rtx;
                    211: 
                    212: /* Used to reduce calls to `strcmp' */
                    213: 
                    214: static char *alternative_name = "alternative";
                    215: 
                    216: /* Simplify an expression.  Only call the routine if there is something to
                    217:    simplify.  */
                    218: #define SIMPLIFY_TEST_EXP(EXP,INSN_CODE,INSN_INDEX)    \
                    219:   (RTX_UNCHANGING_P (EXP) ? (EXP)                      \
                    220:    : simplify_test_exp (EXP, INSN_CODE, INSN_INDEX))
                    221:   
                    222: /* These are referenced by rtlanal.c and hence need to be defined somewhere.
                    223:    They won't actually be used.  */
                    224: 
                    225: rtx frame_pointer_rtx, stack_pointer_rtx, arg_pointer_rtx;
                    226: 
                    227: static rtx check_attr_test ();
                    228: static void check_attr_value ();
                    229: static rtx convert_set_attr_alternative ();
                    230: static rtx convert_set_attr ();
                    231: static void check_defs ();
                    232: static rtx make_canonical ();
                    233: static struct attr_value *get_attr_value ();
                    234: static void expand_delays ();
                    235: static rtx operate_exp ();
                    236: static void expand_units ();
                    237: static void fill_attr ();
                    238: static rtx substitute_address ();
                    239: static void make_length_attrs ();
                    240: static rtx identity_fn ();
                    241: static rtx zero_fn ();
                    242: static rtx one_fn ();
                    243: static rtx max_fn ();
                    244: static rtx simplify_cond ();
                    245: static void remove_insn_ent ();
                    246: static void insert_insn_ent ();
                    247: static rtx insert_right_side ();
                    248: static rtx make_alternative_compare ();
                    249: static int compute_alternative_mask ();
                    250: static rtx evaluate_eq_attr ();
                    251: static rtx simplify_and_tree ();
                    252: static rtx simplify_or_tree ();
                    253: static rtx simplify_test_exp ();
                    254: static void optimize_attrs ();
                    255: static void gen_attr ();
                    256: static int count_alternatives ();
                    257: static int compares_alternatives_p ();
                    258: static int contained_in_p ();
                    259: static void gen_insn ();
                    260: static void gen_delay ();
                    261: static void gen_unit ();
                    262: static void write_test_expr ();
                    263: static int max_attr_value ();
                    264: static void walk_attr_value ();
                    265: static void write_attr_get ();
                    266: static rtx eliminate_known_true ();
                    267: static void write_attr_set ();
                    268: static void write_attr_case ();
                    269: static void write_attr_value ();
                    270: static void write_attr_valueq ();
                    271: static void write_upcase ();
                    272: static void write_indent ();
                    273: static void write_eligible_delay ();
                    274: static void write_function_unit_info ();
                    275: static int n_comma_elts ();
                    276: static char *next_comma_elt ();
                    277: static struct attr_desc *find_attr ();
                    278: static void make_internal_attr ();
                    279: static struct attr_value *find_most_used ();
                    280: static rtx find_single_value ();
                    281: static rtx make_numeric_value ();
                    282: char *xrealloc ();
                    283: char *xmalloc ();
                    284: static void fatal ();
                    285: 
                    286: /* Given a test expression for an attribute, ensure it is validly formed.
                    287:    Convert (eq_attr "att" "a1,a2") to (ior (eq_attr ... ) (eq_attrq ..))
                    288:    and (eq_attr "att" "!a1") to (not (eq_attr "att" "a1")).  Do the latter
                    289:    test first so that (eq_attr "att" "!a1,a2,a3") works as expected.
                    290: 
                    291:    Update the string address in EQ_ATTR expression to be the same used
                    292:    in the attribute (or `alternative_name') to speed up subsequent
                    293:    `find_attr' calls and eliminate most `strcmp' calls.
                    294: 
                    295:    Return the new expression, if any.   */
                    296: 
                    297: static rtx
                    298: check_attr_test (exp)
                    299:      rtx exp;
                    300: {
                    301:   struct attr_desc *attr;
                    302:   struct attr_value *av;
                    303:   char *name_ptr, *p;
                    304:   rtx orexp, newexp;
                    305: 
                    306:   switch (GET_CODE (exp))
                    307:     {
                    308:     case EQ_ATTR:
                    309:       /* Handle negation test.  */
                    310:       if (XSTR (exp, 1)[0] == '!')
                    311:        {
                    312:          XSTR(exp, 1) = &XSTR(exp, 1)[1];
                    313:          newexp = rtx_alloc (NOT);
                    314:          XEXP (newexp, 0) = exp;
                    315: 
                    316:          return check_attr_test (newexp);
                    317:        }
                    318: 
                    319:       else if (n_comma_elts (XSTR (exp, 1)) == 1)
                    320:        {
                    321:          attr = find_attr (XEXP (exp, 0), 0);
                    322:          if (attr == NULL)
                    323:            {
                    324:              if (! strcmp (XSTR (exp, 0), "alternative"))
                    325:                {
                    326:                  XSTR (exp, 0) = alternative_name;
                    327:                  /* This can't be simplified any further.  */
                    328:                  RTX_UNCHANGING_P (exp) = 1;
                    329:                  return exp;
                    330:                }
                    331:            else
                    332:                fatal ("Unknown attribute `%s' in EQ_ATTR", XEXP (exp, 0));
                    333:            }
                    334: 
                    335:          XSTR (exp, 0) = attr->name;
                    336: 
                    337:          if (attr->is_numeric)
                    338:            {
                    339:              for (p = XSTR (exp, 1); *p; p++)
                    340:                if (*p < '0' || *p > '9')
                    341:                   fatal ("Attribute `%s' takes only numeric values", 
                    342:                          XEXP (exp, 0));
                    343:            }
                    344:          else
                    345:            {
                    346:              for (av = attr->first_value; av; av = av->next)
                    347:                if (GET_CODE (av->value) == CONST_STRING
                    348:                    && ! strcmp (XSTR (exp, 1), XSTR (av->value, 0)))
                    349:                  break;
                    350: 
                    351:              if (av == NULL)
                    352:                fatal ("Unknown value `%s' for `%s' attribute",
                    353:                       XEXP (exp, 1), XEXP (exp, 0));
                    354:            }
                    355:        }
                    356:       else
                    357:        {
                    358:          /* Make an IOR tree of the possible values.  */
                    359:          orexp = false_rtx;
                    360:          name_ptr = XSTR (exp, 1);
                    361:          while ((p = next_comma_elt (&name_ptr)) != NULL)
                    362:            {
                    363:              newexp = rtx_alloc (EQ_ATTR);
                    364:              XSTR (newexp, 0) = XSTR (exp, 0);
                    365:              XSTR (newexp, 1) = p;
                    366:              orexp = insert_right_side (IOR, orexp, newexp, -2);
                    367:            }
                    368: 
                    369:          return check_attr_test (orexp);
                    370:        }
                    371:       break;
                    372: 
                    373:     case CONST_INT:
                    374:       /* Either TRUE or FALSE.  */
                    375:       if (XINT (exp, 0))
                    376:        return true_rtx;
                    377:       else
                    378:        return false_rtx;
                    379: 
                    380:     case IOR:
                    381:     case AND:
                    382:       XEXP (exp, 0) = check_attr_test (XEXP (exp, 0));
                    383:       XEXP (exp, 1) = check_attr_test (XEXP (exp, 1));
                    384:       break;
                    385: 
                    386:     case NOT:
                    387:       XEXP (exp, 0) = check_attr_test (XEXP (exp, 0));
                    388:       break;
                    389: 
                    390:     case MATCH_OPERAND:
                    391:     case LE:  case LT:  case GT:  case GE:
                    392:     case LEU: case LTU: case GTU: case GEU:
                    393:     case NE:  case EQ:
                    394:       /* These cases can't be simplified.  */
                    395:       RTX_UNCHANGING_P (exp) = 1;
                    396:       break;
                    397: 
                    398:     default:
                    399:       fatal ("RTL operator \"%s\" not valid in attribute test",
                    400:             GET_RTX_NAME (GET_CODE (exp)));
                    401:     }
                    402: 
                    403:   return exp;
                    404: }
                    405: 
                    406: /* Given an expression, ensure that it is validly formed and that all named
                    407:    attribute values are valid for the given attribute.  Issue a fatal error
                    408:    if not.  If no attribute is specified, assume a numeric attribute.  */
                    409: 
                    410: static void
                    411: check_attr_value (exp, attr)
                    412:      rtx exp;
                    413:      struct attr_desc *attr;
                    414: {
                    415:   struct attr_value *av;
                    416:   char *p;
                    417:   int i;
                    418: 
                    419:   switch (GET_CODE (exp))
                    420:     {
                    421:     case CONST_INT:
                    422:       if (attr && ! attr->is_numeric)
                    423:        fatal ("CONST_INT not valid for non-numeric `%s' attribute",
                    424:               attr->name);
                    425: 
                    426:       if (INTVAL (exp) < 0)
                    427:        fatal ("Negative numeric value specified for `%s' attribute",
                    428:               attr->name);
                    429: 
                    430:       break;
                    431: 
                    432:     case CONST_STRING:
                    433:       if (! strcmp (XSTR (exp, 0), "*"))
                    434:        break;
                    435: 
                    436:       if (attr == 0 || attr->is_numeric)
                    437:        {
                    438:          for (p = XSTR (exp, 0); *p; p++)
                    439:            if (*p > '9' || *p < '0')
                    440:              fatal ("Non-numeric value for numeric `%s' attribute",
                    441:                     attr ? "internal" : attr->name);
                    442:          break;
                    443:        }
                    444: 
                    445:       for (av = attr->first_value; av; av = av->next)
                    446:        if (GET_CODE (av->value) == CONST_STRING
                    447:            && ! strcmp (XSTR (av->value, 0), XSTR (exp, 0)))
                    448:          break;
                    449: 
                    450:       if (av == NULL)
                    451:        fatal ("Unknown value `%s' for `%s' attribute",
                    452:               XSTR (exp, 0), attr ? "internal" : attr->name);
                    453: 
                    454:       return;
                    455: 
                    456:     case IF_THEN_ELSE:
                    457:       XEXP (exp, 0) = check_attr_test (XEXP (exp, 0));
                    458:       check_attr_value (XEXP (exp, 1), attr);
                    459:       check_attr_value (XEXP (exp, 2), attr);
                    460:       return;
                    461: 
                    462:     case COND:
                    463:       if (XVECLEN (exp, 0) % 2 != 0)
                    464:        fatal ("First operand of COND must have even length");
                    465: 
                    466:       for (i = 0; i < XVECLEN (exp, 0); i += 2)
                    467:        {
                    468:          XVECEXP (exp, 0, i) = check_attr_test (XVECEXP (exp, 0, i));
                    469:          check_attr_value (XVECEXP (exp, 0, i + 1), attr);
                    470:        }
                    471: 
                    472:       check_attr_value (XEXP (exp, 1), attr);
                    473:       return;
                    474: 
                    475:     default:
                    476:       fatal ("Illegal operation `%s' for attribute value",
                    477:             GET_RTX_NAME (GET_CODE (exp)));
                    478:     }
                    479: }
                    480: 
                    481: /* Given an SET_ATTR_ALTERNATIVE expression, convert to the canonical SET.
                    482:    It becomes a COND with each test being (eq_attr "alternative "n") */
                    483: 
                    484: static rtx
                    485: convert_set_attr_alternative (exp, num_alt, insn_code, insn_index)
                    486:      rtx exp;
                    487:      int num_alt;
                    488:      int insn_code, insn_index;
                    489: {
                    490:   rtx newexp;
                    491:   rtx condexp;
                    492:   int i;
                    493: 
                    494:   if (XVECLEN (exp, 1) != num_alt)
                    495:     fatal ("Bad number of entries in SET_ATTR_ALTERNATIVE for insn %d",
                    496:           insn_index);
                    497: 
                    498:   /* Make a COND with all tests but the last.  Select the last value via the
                    499:      default.  */
                    500:   condexp = rtx_alloc (COND);
                    501:   XVEC (condexp, 0) = rtvec_alloc ((num_alt - 1) * 2);
                    502: 
                    503:   for (i = 0; i < num_alt - 1; i++)
                    504:     {
                    505:       XVECEXP (condexp, 0, 2 * i) = rtx_alloc (EQ_ATTR);
                    506:       XSTR (XVECEXP (condexp, 0, 2 * i), 0) = alternative_name;
                    507:       XSTR (XVECEXP (condexp, 0, 2 * i), 1) = (char *) xmalloc (3);
                    508:       sprintf (XSTR (XVECEXP (condexp, 0, 2 * i), 1), "%d", i);
                    509:       XVECEXP (condexp, 0, 2 * i + 1) = XVECEXP (exp, 1, i);
                    510:     }
                    511: 
                    512:   XEXP (condexp, 1) = XVECEXP (exp, 1, i);
                    513: 
                    514:   newexp = rtx_alloc (SET);
                    515:   XEXP (newexp, 0) = rtx_alloc (ATTR);
                    516:   XSTR (XEXP (newexp, 0), 0) = XSTR (exp, 0);
                    517:   XEXP (newexp, 1) = condexp;
                    518: 
                    519:   return newexp;
                    520: }
                    521: 
                    522: /* Given a SET_ATTR, convert to the appropriate SET.  If a comma-separated
                    523:    list of values is given, convert to SET_ATTR_ALTERNATIVE first.  */
                    524: 
                    525: static rtx
                    526: convert_set_attr (exp, num_alt, insn_code, insn_index)
                    527:      rtx exp;
                    528:      int num_alt;
                    529:      int insn_code, insn_index;
                    530: {
                    531:   rtx newexp;
                    532:   char *name_ptr;
                    533:   char *p;
                    534:   int n;
                    535: 
                    536:   /* See how many alternative specified.  */
                    537:   n = n_comma_elts (XSTR (exp, 1));
                    538:   if (n == 1)
                    539:     {
                    540:       newexp = rtx_alloc (SET);
                    541:       XEXP (newexp, 0) = rtx_alloc (ATTR);
                    542:       XSTR (XEXP (newexp, 0), 0) = XSTR (exp, 0);
                    543:       XEXP (newexp, 1) = rtx_alloc (CONST_STRING);
                    544:       XSTR (XEXP (newexp, 1), 0) = XSTR (exp, 1);
                    545: 
                    546:       return newexp;
                    547:     }
                    548: 
                    549:   newexp = rtx_alloc (SET_ATTR_ALTERNATIVE);
                    550:   XSTR (newexp, 0) = XSTR (exp, 0);
                    551:   XVEC (newexp, 1) = rtvec_alloc (n);
                    552: 
                    553:   /* Process each comma-separated name.  */
                    554:   name_ptr = XSTR (exp, 1);
                    555:   n = 0;
                    556:   while ((p = next_comma_elt (&name_ptr)) != NULL)
                    557:     {
                    558:       XVECEXP (newexp, 1, n) = rtx_alloc (CONST_STRING);
                    559:       XSTR (XVECEXP (newexp, 1, n++), 0) = p;
                    560:     }
                    561: 
                    562:   return convert_set_attr_alternative (newexp, num_alt, insn_code, insn_index);
                    563: }
                    564: 
                    565: /* Scan all definitions, checking for validity.  Also, convert any SET_ATTR
                    566:    and SET_ATTR_ALTERNATIVE expressions to the corresponding SET
                    567:    expressions. */
                    568: 
                    569: static void
                    570: check_defs ()
                    571: {
                    572:   struct insn_def *id;
                    573:   struct attr_desc *attr;
                    574:   int i;
                    575:   rtx value;
                    576: 
                    577:   for (id = defs; id; id = id->next)
                    578:     {
                    579:       if (XVEC (id->def, id->vec_idx) == NULL)
                    580:        continue;
                    581: 
                    582:       for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
                    583:        {
                    584:          value = XVECEXP (id->def, id->vec_idx, i);
                    585:          switch (GET_CODE (value))
                    586:            {
                    587:            case SET:
                    588:              if (GET_CODE (XEXP (value, 0)) != ATTR)
                    589:                fatal ("Bad attribute set in pattern %d", id->insn_index);
                    590:              break;
                    591: 
                    592:            case SET_ATTR_ALTERNATIVE:
                    593:              value = convert_set_attr_alternative (value,
                    594:                                                    id->num_alternatives,
                    595:                                                    id->insn_code,
                    596:                                                    id->insn_index);
                    597:              break;
                    598: 
                    599:            case SET_ATTR:
                    600:              value = convert_set_attr (value, id->num_alternatives,
                    601:                                        id->insn_code, id->insn_index);
                    602:              break;
                    603: 
                    604:            default:
                    605:              fatal ("Invalid attribute code `%s' for pattern %d",
                    606:                     GET_RTX_NAME (GET_CODE (value)), id->insn_index);
                    607:            }
                    608: 
                    609:          if ((attr = find_attr (XSTR (XEXP (value, 0), 0), 0)) == NULL)
                    610:            fatal ("Unknown attribute `%s' for pattern number %d",
                    611:                   XSTR (XEXP (value, 0), 0), id->insn_index);
                    612: 
                    613:          XVECEXP (id->def, id->vec_idx, i) = value;
                    614:          check_attr_value (XEXP (value, 1), attr);
                    615:        }
                    616:     }
                    617: }
                    618: 
                    619: /* Given a valid expression for an attribute value, remove any IF_THEN_ELSE
                    620:    expressions by converting them into a COND.  This removes cases from this
                    621:    program.  Also, replace an attribute value of "*" with the default attribute
                    622:    value.  */
                    623: 
                    624: static rtx
                    625: make_canonical (attr, exp)
                    626:      struct attr_desc *attr;
                    627:      rtx exp;
                    628: {
                    629:   int i;
                    630:   rtx newexp;
                    631: 
                    632:   switch (GET_CODE (exp))
                    633:     {
                    634:     case CONST_INT:
                    635:       exp = make_numeric_value (INTVAL (exp));
                    636:       break;
                    637: 
                    638:     case CONST_STRING:
                    639:       if (! strcmp (XSTR (exp, 0), "*"))
                    640:        {
                    641:          if (attr == 0 || attr->default_val == 0)
                    642:            fatal ("(attr_value \"*\") used in invalid context.");
                    643:          exp = attr->default_val->value;
                    644:        }
                    645: 
                    646:       break;
                    647: 
                    648:     case IF_THEN_ELSE:
                    649:       newexp = rtx_alloc (COND);
                    650:       XVEC (newexp, 0) = rtvec_alloc (2);
                    651:       XVECEXP (newexp, 0, 0) = XEXP (exp, 0);
                    652:       XVECEXP (newexp, 0, 1) = XEXP (exp, 1);
                    653: 
                    654:       XEXP (newexp, 1) = XEXP (exp, 2);
                    655: 
                    656:       exp = newexp;
                    657:       /* Fall through to COND case since this is now a COND.  */
                    658: 
                    659:     case COND:
                    660:       /* First, check for degenerate COND. */
                    661:       if (XVECLEN (exp, 0) == 0)
                    662:        return make_canonical (attr, XEXP (exp, 1));
                    663: 
                    664:       for (i = 0; i < XVECLEN (exp, 0); i += 2)
                    665:        XVECEXP (exp, 0, i + 1)
                    666:                = make_canonical (attr, XVECEXP (exp, 0, i + 1));
                    667: 
                    668:       XEXP (exp, 1) = make_canonical (attr, XEXP (exp, 1));
                    669:       break;
                    670:     }
                    671: 
                    672:   return exp;
                    673: }
                    674: 
                    675: /* Given a value and an attribute description, return a `struct attr_value *'
                    676:    that represents that value.  This is either an existing structure, if the
                    677:    value has been previously encountered, or a newly-created structure.
                    678: 
                    679:    `insn_code' is the code of an insn whose attribute has the specified
                    680:    value (-2 if not processing an insn).  We ensure that all insns for
                    681:    a given value have the same number of alternatives if the value checks
                    682:    alternatives.  */
                    683: 
                    684: static struct attr_value *
                    685: get_attr_value (value, attr, insn_code)
                    686:      rtx value;
                    687:      struct attr_desc *attr;
                    688:      int insn_code;
                    689: {
                    690:   struct attr_value *av;
                    691:   int num_alt = 0;
                    692: 
                    693:   value = make_canonical (attr, value);
                    694:   if (compares_alternatives_p (value))
                    695:     {
                    696:       if (insn_code < 0 || insn_alternatives == NULL)
                    697:        fatal ("(eq_attr \"alternatives\" ...) used in non-insn context");
                    698:       else
                    699:        num_alt = insn_alternatives[insn_code];
                    700:     }
                    701: 
                    702:   for (av = attr->first_value; av; av = av->next)
                    703:     if (rtx_equal_p (value, av->value)
                    704:        && (num_alt == 0 || av->first_insn == NULL
                    705:            || insn_alternatives[av->first_insn->insn_code]))
                    706:       return av;
                    707: 
                    708:   av = (struct attr_value *) xmalloc (sizeof (struct attr_value));
                    709:   av->value = value;
                    710:   av->next = attr->first_value;
                    711:   attr->first_value = av;
                    712:   av->first_insn = NULL;
                    713:   av->num_insns = 0;
                    714:   av->has_asm_insn = 0;
                    715: 
                    716:   return av;
                    717: }
                    718: 
                    719: /* After all DEFINE_DELAYs have been read in, create internal attributes
                    720:    to generate the required routines.
                    721: 
                    722:    First, we compute the number of delay slots for each insn (as a COND of
                    723:    each of the test expressions in DEFINE_DELAYs).  Then, if more than one
                    724:    delay type is specified, we compute a similar function giving the
                    725:    DEFINE_DELAY ordinal for each insn.
                    726: 
                    727:    Finally, for each [DEFINE_DELAY, slot #] pair, we compute an attribute that
                    728:    tells whether a given insn can be in that delay slot.
                    729: 
                    730:    Normal attrbute filling and optimization expands these to contain the
                    731:    information needed to handle delay slots.  */
                    732: 
                    733: static void
                    734: expand_delays ()
                    735: {
                    736:   struct delay_desc *delay;
                    737:   rtx condexp;
                    738:   rtx newexp;
                    739:   int i;
                    740:   char *p;
                    741: 
                    742:   /* First, generate data for `num_delay_slots' function.  */
                    743: 
                    744:   condexp = rtx_alloc (COND);
                    745:   XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
                    746:   XEXP (condexp, 1) = make_numeric_value (0);
                    747: 
                    748:   for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
                    749:     {
                    750:       XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
                    751:       XVECEXP (condexp, 0, i + 1)
                    752:        = make_numeric_value (XVECLEN (delay->def, 1) / 3);
                    753:     }
                    754: 
                    755:   make_internal_attr ("*num_delay_slots", condexp, 0);
                    756: 
                    757:   /* If more than one delay type, do the same for computing the delay type.  */
                    758:   if (num_delays > 1)
                    759:     {
                    760:       condexp = rtx_alloc (COND);
                    761:       XVEC (condexp, 0) = rtvec_alloc (num_delays * 2);
                    762:       XEXP (condexp, 1) = make_numeric_value (0);
                    763: 
                    764:       for (i = 0, delay = delays; delay; i += 2, delay = delay->next)
                    765:        {
                    766:          XVECEXP (condexp, 0, i) = XEXP (delay->def, 0);
                    767:          XVECEXP (condexp, 0, i + 1) = make_numeric_value (delay->num);
                    768:        }
                    769: 
                    770:       make_internal_attr ("*delay_type", condexp, 1);
                    771:     }
                    772: 
                    773:   /* For each delay possibility and delay slot, compute an eligability
                    774:      attribute for non-anulled insns and for each type of annulled (annul
                    775:      if true and annul if false).  */
                    776:  for (delay = delays; delay; delay = delay->next)
                    777:    {
                    778:      for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
                    779:        {
                    780:         newexp = rtx_alloc (IF_THEN_ELSE);
                    781:         condexp = XVECEXP (delay->def, 1, i);
                    782:         if (condexp == 0) condexp = false_rtx;
                    783:         XEXP (newexp, 0) = condexp;
                    784:         XEXP (newexp, 1) = make_numeric_value (1);
                    785:         XEXP (newexp, 2) = make_numeric_value (0);
                    786: 
                    787:         p = (char *) xmalloc (13);
                    788:         sprintf (p, "*delay_%d_%d", delay->num, i / 3);
                    789:         make_internal_attr (p, newexp, 1);
                    790: 
                    791:         if (have_annul_true)
                    792:           {
                    793:             newexp = rtx_alloc (IF_THEN_ELSE);
                    794:             condexp = XVECEXP (delay->def, 1, i + 1);
                    795:             if (condexp == 0) condexp = false_rtx;
                    796:             XEXP (newexp, 0) = condexp;
                    797:             XEXP (newexp, 1) = make_numeric_value (1);
                    798:             XEXP (newexp, 2) = make_numeric_value (0);
                    799:             p = (char *) xmalloc (18);
                    800:             sprintf (p, "*annul_true_%d_%d", delay->num, i / 3);
                    801:             make_internal_attr (p, newexp, 1);
                    802:           }
                    803: 
                    804:         if (have_annul_false)
                    805:           {
                    806:             newexp = rtx_alloc (IF_THEN_ELSE);
                    807:             condexp = XVECEXP (delay->def, 1, i + 2);
                    808:             if (condexp == 0) condexp = false_rtx;
                    809:             XEXP (newexp, 0) = condexp;
                    810:             XEXP (newexp, 1) = make_numeric_value (1);
                    811:             XEXP (newexp, 2) = make_numeric_value (0);
                    812:             p = (char *) xmalloc (18);
                    813:             sprintf (p, "*annul_false_%d_%d", delay->num, i / 3);
                    814:             make_internal_attr (p, newexp, 1);
                    815:           }
                    816:        }
                    817:    }
                    818: }
                    819: 
                    820: /* This function is given a left and right side expression and an operator.
                    821:    Each side is a conditional expression, each alternative of which has a
                    822:    numerical value.  The function returns another conditional expression
                    823:    which, for every possible set of condition values, returns a value that is
                    824:    the operator applied to the values of the two sides.
                    825: 
                    826:    Since this is called early, it must also support IF_THEN_ELSE.  */
                    827: 
                    828: static rtx
                    829: operate_exp (op, left, right)
                    830:      enum operator op;
                    831:      rtx left, right;
                    832: {
                    833:   int left_value, right_value;
                    834:   rtx newexp;
                    835:   int i;
                    836: 
                    837:   /* If left is a string, apply operator to it and the right side.  */
                    838:   if (GET_CODE (left) == CONST_STRING)
                    839:     {
                    840:       /* If right is also a string, just perform the operation.  */
                    841:       if (GET_CODE (right) == CONST_STRING)
                    842:        {
                    843:          left_value = atoi (XSTR (left, 0));
                    844:          right_value = atoi (XSTR (right, 0));
                    845:          switch (op)
                    846:            {
                    847:            case PLUS_OP:
                    848:              i = left_value + right_value;
                    849:              break;
                    850: 
                    851:            case MINUS_OP:
                    852:              i = left_value - right_value;
                    853:              break;
                    854: 
                    855:            case OR_OP:
                    856:              i = left_value | right_value;
                    857:              break;
                    858: 
                    859:            case MAX_OP:
                    860:              if (left_value > right_value)
                    861:                i = left_value;
                    862:              else
                    863:                i = right_value;
                    864:              break;
                    865: 
                    866:            default:
                    867:              abort ();
                    868:            }
                    869: 
                    870:          return make_numeric_value (i);
                    871:        }
                    872:       else if (GET_CODE (right) == IF_THEN_ELSE)
                    873:        {
                    874:          /* Apply recursively to all values within.  */
                    875:          newexp = rtx_alloc (IF_THEN_ELSE);
                    876:          XEXP (newexp, 0) = XEXP (right, 0);
                    877:          XEXP (newexp, 1) = operate_exp (op, left, XEXP (right, 1));
                    878:          XEXP (newexp, 2) = operate_exp (op, left, XEXP (right, 2));
                    879: 
                    880:          return newexp;
                    881:        }
                    882:       else if (GET_CODE (right) == COND)
                    883:        {
                    884:          newexp = rtx_alloc (COND);
                    885:          XVEC (newexp, 0) = rtvec_alloc (XVECLEN (right, 0));
                    886:          for (i = 0; i < XVECLEN (right, 0); i += 2)
                    887:            {
                    888:              XVECEXP (newexp, 0, i) = XVECEXP (right, 0, i);
                    889:              XVECEXP (newexp, 0, i + 1)
                    890:                = operate_exp (op, left, XVECEXP (right, 0, i + 1));
                    891:            }
                    892: 
                    893:          XEXP (newexp, 1) = operate_exp (op, left, XEXP (right, 1));
                    894: 
                    895:          return newexp;
                    896:        }
                    897:       else
                    898:        fatal ("Badly formed attribute value");
                    899:     }
                    900: 
                    901:   /* Otherwise, do recursion the other way.  */
                    902:   else if (GET_CODE (left) == IF_THEN_ELSE)
                    903:     {
                    904:       newexp = rtx_alloc (IF_THEN_ELSE);
                    905:       XEXP (newexp, 0) = XEXP (left, 0);
                    906:       XEXP (newexp, 1) = operate_exp (op, XEXP (left, 1), right);
                    907:       XEXP (newexp, 2) = operate_exp (op, XEXP (left, 2), right);
                    908: 
                    909:       return newexp;
                    910:     }
                    911: 
                    912:   else if (GET_CODE (left) == COND)
                    913:     {
                    914:       newexp = rtx_alloc (COND);
                    915:       XVEC (newexp, 0) = rtvec_alloc (XVECLEN (left, 0));
                    916:       for (i = 0; i < XVECLEN (left, 0); i += 2)
                    917:        {
                    918:          XVECEXP (newexp, 0, i) = XVECEXP (left, 0, i);
                    919:          XVECEXP (newexp, 0, i + 1)
                    920:            = operate_exp (op, XVECEXP (left, 0, i + 1), right);
                    921:        }
                    922: 
                    923:       XEXP (newexp, 1) = operate_exp (op, XEXP (left, 1), right);
                    924: 
                    925:       return newexp;
                    926:     }
                    927: 
                    928:   else
                    929:     fatal ("Badly formed attribute value.");
                    930:   /* NOTREACHED */
                    931:   return NULL;
                    932: }
                    933: 
                    934: /* Once all attributes and DEFINE_FUNCTION_UNITs have been read, we
                    935:    construct a number of attributes.
                    936: 
                    937:    The first produces a function `function_units_used' which is given an
                    938:    insn and produces a mask showing which function units are required for
                    939:    the execution of that insn.
                    940: 
                    941:    The second produces a function `result_ready_cost' which is used to
                    942:    determine the time that the result of an insn will be ready and hence
                    943:    a worst-case schedule.
                    944: 
                    945:    Both of these produce quite complex expressions which are then set as the
                    946:    default value of internal attributes.  Normal attribute simplification
                    947:    should produce reasonable expressions.
                    948: 
                    949:    For each unit, a `<name>_unit_ready_cost' function will take an
                    950:    insn and give the delay until that unit will be ready with the result
                    951:    and a `<name>_unit_busy_delay' function is given an insn already
                    952:    executing on the unit and a candidate to execute and will give the
                    953:    cost from the time the executing insn started until the candidate
                    954:    can start (ignore limitations on the number of simultaneous insns).  */
                    955: 
                    956: static void
                    957: expand_units ()
                    958: {
                    959:   struct function_unit *unit;
                    960:   struct function_unit_op *op;
                    961:   rtx unitsmask;
                    962:   rtx readycost;
                    963:   rtx newexp;
                    964:   char *str;
                    965: 
                    966:   /* Initially, cost and masks are zero.  */
                    967:   unitsmask = readycost = make_numeric_value (0);
                    968: 
                    969:   /* Set up a conditional for costs and unit mask.  */
                    970:   newexp = rtx_alloc (IF_THEN_ELSE);
                    971:   XEXP (newexp, 2) = make_numeric_value (0);
                    972: 
                    973:   /* For each unit, insert its contribution to the above three values.  */
                    974:   for (unit = units; unit; unit = unit->next)
                    975:     {
                    976:       /* An expression that computes the ready cost for this unit.  */
                    977:       rtx readyexp = rtx_alloc (COND);
                    978:       /* An expression that maps insns to operation number for conflicts.  */
                    979:       rtx caseexp = rtx_alloc (COND);
                    980: 
                    981:       XVEC (readyexp, 0) = rtvec_alloc ((unit->num_opclasses - 1) * 2);
                    982:       XVEC (caseexp, 0) = rtvec_alloc ((unit->num_opclasses - 1) * 2);
                    983: 
                    984:       for (op = unit->ops; op; op = op->next)
                    985:        {
                    986:          str = (char *) xmalloc (strlen (unit->name) + 11);
                    987: 
                    988:          /* Validate the expressions we were given for the conditions
                    989:             and busy cost.  Then make an attribute for use in the conflict
                    990:             function.  */
                    991:          op->condexp = check_attr_test (op->condexp);
                    992:          check_attr_value (op->busyexp, 0);
                    993:          sprintf (str, "*%s_case_%d", unit->name, op->num);
                    994:          make_internal_attr (str, make_canonical (0, op->busyexp));
                    995: 
                    996:          /* Make our adjustment to the two COND's being computed.  If we are
                    997:             the last operation class, place our values into the default of
                    998:             the COND.  */
                    999:          if (op->num == unit->num_opclasses - 1)
                   1000:            {
                   1001:              XEXP (readyexp, 1) = make_numeric_value (op->ready);
                   1002:              XEXP (caseexp, 1) = make_numeric_value (op->num);
                   1003:            }
                   1004:          else
                   1005:            {
                   1006:              XVECEXP (readyexp, 0, op->num * 2) = op->condexp;
                   1007:              XVECEXP (readyexp, 0, op->num * 2 + 1)
                   1008:                = make_numeric_value (op->ready);
                   1009:              XVECEXP (caseexp, 0, op->num * 2) = op->condexp;
                   1010:              XVECEXP (caseexp, 0, op->num * 2 + 1)
                   1011:                = make_numeric_value (op->num);
                   1012:            }
                   1013:        }
                   1014: 
                   1015:       /* Make an attribute for the case number and ready delay.  */
                   1016:       str = (char *) xmalloc (strlen (unit->name) + 8);
                   1017:       sprintf (str, "*%s_cases", unit->name);
                   1018:       make_internal_attr (str, caseexp, 1);
                   1019: 
                   1020:       str = (char *) xmalloc (strlen (unit->name) + 20);
                   1021:       sprintf (str, "*%s_unit_ready_cost", unit->name);
                   1022:       make_internal_attr (str, readyexp, 0);
                   1023: 
                   1024:       /* Merge this function unit into the ready cost and unit mask
                   1025:         attributes.  */
                   1026:       XEXP (newexp, 0) = check_attr_test (unit->condexp);
                   1027:       XEXP (newexp, 1) = make_numeric_value (1 << unit->num);
                   1028:       unitsmask = operate_exp (OR_OP, unitsmask, newexp);
                   1029: 
                   1030:       XEXP (newexp, 1) = readyexp;
                   1031:       readycost = operate_exp (MAX_OP, readycost, newexp);
                   1032:     }
                   1033: 
                   1034:   make_internal_attr ("*function_units_used", unitsmask, 0);
                   1035:   make_internal_attr ("*result_ready_cost", readycost, 0);
                   1036: }
                   1037: 
                   1038: /* Once all attributes and insns have been read and checked, we construct for
                   1039:    each attribute value a list of all the insns that have that value for
                   1040:    the attribute.  */
                   1041: 
                   1042: static void
                   1043: fill_attr (attr)
                   1044:      struct attr_desc *attr;
                   1045: {
                   1046:   struct attr_value *av;
                   1047:   struct insn_ent *ie;
                   1048:   struct insn_def *id;
                   1049:   int i;
                   1050:   rtx value;
                   1051: 
                   1052:   for (id = defs; id; id = id->next)
                   1053:     {
                   1054:       /* If no value is specified for this insn for this attribute, use the
                   1055:         default.  */
                   1056:       value = NULL;
                   1057:       if (XVEC (id->def, id->vec_idx))
                   1058:        for (i = 0; i < XVECLEN (id->def, id->vec_idx); i++)
                   1059:          if (! strcmp (XSTR (XEXP (XVECEXP (id->def, id->vec_idx, i), 0), 0), 
                   1060:                        attr->name))
                   1061:            value = XEXP (XVECEXP (id->def, id->vec_idx, i), 1);
                   1062: 
                   1063:       if (value == NULL)
                   1064:        av = attr->default_val;
                   1065:       else
                   1066:        av = get_attr_value (value, attr, id->insn_code);
                   1067: 
                   1068:       ie = (struct insn_ent *) xmalloc (sizeof (struct insn_ent));
                   1069:       ie->insn_code = id->insn_code;
                   1070:       ie->insn_index = id->insn_code;
                   1071:       insert_insn_ent (av, ie);
                   1072:     }
                   1073: }
                   1074: 
                   1075: /* Given an expression EXP, see if it is a COND or IF_THEN_ELSE that has a
                   1076:    test that checks relative positions of insns (uses MATCH_DUP or PC).
                   1077:    If so, replace it with what is obtained by passing the expression to
                   1078:    ADDRESS_FN.  If not but it is a COND or IF_THEN_ELSE, call this routine
                   1079:    recursively on each value (including the default value).  Otherwise,
                   1080:    return the value returned by NO_ADDRESS_FN applied to EXP.  */
                   1081: 
                   1082: static rtx
                   1083: substitute_address (exp, no_address_fn, address_fn)
                   1084:      rtx exp;
                   1085:      rtx (*no_address_fn) ();
                   1086:      rtx (*address_fn) ();
                   1087: {
                   1088:   int i;
                   1089:   rtx newexp;
                   1090: 
                   1091:   if (GET_CODE (exp) == COND)
                   1092:     {
                   1093:       /* See if any tests use addresses.  */
                   1094:       address_used = 0;
                   1095:       for (i = 0; i < XVECLEN (exp, 0); i += 2)
                   1096:        walk_attr_value (XVECEXP (exp, 0, i));
                   1097: 
                   1098:       if (address_used)
                   1099:        return (*address_fn) (exp);
                   1100: 
                   1101:       /* Make a new copy of this COND, replacing each element.  */
                   1102:       newexp = rtx_alloc (COND);
                   1103:       XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
                   1104:       for (i = 0; i < XVECLEN (exp, 0); i += 2)
                   1105:        {
                   1106:          XVECEXP (newexp, 0, i) = XVECEXP (exp, 0, i);
                   1107:          XVECEXP (newexp, 0, i + 1)
                   1108:            = substitute_address (XVECEXP (exp, 0, i + 1),
                   1109:                                  no_address_fn, address_fn);
                   1110:        }
                   1111: 
                   1112:       XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
                   1113:                                             no_address_fn, address_fn);
                   1114: 
                   1115:       return newexp;
                   1116:     }
                   1117: 
                   1118:   else if (GET_CODE (exp) == IF_THEN_ELSE)
                   1119:     {
                   1120:       address_used = 0;
                   1121:       walk_attr_value (XEXP (exp, 0));
                   1122:       if (address_used)
                   1123:        return (*address_fn) (exp);
                   1124: 
                   1125:       newexp = rtx_alloc (IF_THEN_ELSE);
                   1126:       XEXP (newexp, 0) = substitute_address (XEXP (exp, 0),
                   1127:                                             no_address_fn, address_fn);
                   1128:       XEXP (newexp, 1) = substitute_address (XEXP (exp, 1),
                   1129:                                             no_address_fn, address_fn);
                   1130:       XEXP (newexp, 2) = substitute_address (XEXP (exp, 2),
                   1131:                                             no_address_fn, address_fn);
                   1132: 
                   1133:       return newexp;
                   1134:     }
                   1135: 
                   1136:   return (*no_address_fn) (exp);
                   1137: }
                   1138: 
                   1139: /* Make new attributes from the `length' attribute.  The following are made,
                   1140:    each corresponding to a function called from `shorten_branches' or
                   1141:    `get_attr_length':
                   1142: 
                   1143:    *insn_default_length                This is the length of the insn to be returned
                   1144:                                by `get_attr_length' before `shorten_branches'
                   1145:                                has been called.  In each case where the length
                   1146:                                depends on relative addresses, the largest
                   1147:                                possible is used.  This routine is also used
                   1148:                                to compute the initial size of the insn.
                   1149: 
                   1150:    *insn_variable_length_p     This returns 1 if the insn's length depends
                   1151:                                on relative addresses, zero otherwise.
                   1152: 
                   1153:    *insn_current_length                This is only called when it is known that the
                   1154:                                insn has a variable length and returns the
                   1155:                                current length, based on relative addresses.
                   1156:   */
                   1157: 
                   1158: static void
                   1159: make_length_attrs ()
                   1160: {
                   1161:   static char *new_names[] = {"*insn_default_length",
                   1162:                              "*insn_variable_length_p",
                   1163:                              "*insn_current_length"};
                   1164:   static rtx (*no_address_fn[]) () = {identity_fn, zero_fn, zero_fn};
                   1165:   static rtx (*address_fn[]) () = {max_fn, one_fn, identity_fn};
                   1166:   int i;
                   1167:   struct attr_desc *length_attr, *new_attr;
                   1168:   struct attr_value *av, *new_av;
                   1169:   struct insn_ent *ie, *new_ie;
                   1170: 
                   1171:   /* See if length attribute is defined.  If so, it must be numeric.  Make
                   1172:      it special so we don't output anything for it.  */
                   1173:   length_attr = find_attr ("length", 0);
                   1174:   if (length_attr == 0)
                   1175:     return;
                   1176: 
                   1177:   if (! length_attr->is_numeric)
                   1178:     fatal ("length attribute must be numeric.");
                   1179: 
                   1180:   length_attr->is_special = 1;
                   1181: 
                   1182:   /* Make each new attribute, in turn.  */
                   1183:   for (i = 0; i < sizeof new_names / sizeof new_names[0]; i++)
                   1184:     {
                   1185:       make_internal_attr (new_names[i],
                   1186:                          substitute_address (length_attr->default_val->value,
                   1187:                                              no_address_fn[i], address_fn[i]),
                   1188:                          0);
                   1189:       new_attr = find_attr (new_names[i], 0);
                   1190:       for (av = length_attr->first_value; av; av = av->next)
                   1191:        for (ie = av->first_insn; ie; ie = ie->next)
                   1192:          {
                   1193:            new_av = get_attr_value (substitute_address (av->value,
                   1194:                                                         no_address_fn[i],
                   1195:                                                         address_fn[i]),
                   1196:                                     new_attr, ie->insn_code);
                   1197:            new_ie = (struct insn_ent *) xmalloc (sizeof (struct insn_ent));
                   1198:            new_ie->insn_code = ie->insn_code;
                   1199:            new_ie->insn_index = ie->insn_index;
                   1200:            insert_insn_ent (new_av, new_ie);
                   1201:          }
                   1202:     }
                   1203: }
                   1204: 
                   1205: /* Utility functions called from above routine.  */
                   1206: 
                   1207: static rtx
                   1208: identity_fn (exp)
                   1209:      rtx exp;
                   1210: {
                   1211:   return exp;
                   1212: }
                   1213: 
                   1214: static rtx
                   1215: zero_fn (exp)
                   1216:      rtx exp;
                   1217: {
                   1218:   return make_numeric_value (0);
                   1219: }
                   1220: 
                   1221: static rtx
                   1222: one_fn (exp)
                   1223:      rtx exp;
                   1224: {
                   1225:   return make_numeric_value (1);
                   1226: }
                   1227: 
                   1228: static rtx
                   1229: max_fn (exp)
                   1230:      rtx exp;
                   1231: {
                   1232:   return make_numeric_value (max_attr_value (exp));
                   1233: }
                   1234: 
                   1235: /* Take a COND expression and see if any of the conditions in it can be
                   1236:    simplified.  If any are known true or known false for the particular insn
                   1237:    code, the COND can be further simplified.
                   1238: 
                   1239:    Also call ourselves on any COND operations that are values of this COND.
                   1240: 
                   1241:    We only do the first replacement found directly and call ourselves
                   1242:    recursively for subsequent replacements.  */
                   1243: 
                   1244: static rtx
                   1245: simplify_cond (exp, insn_code, insn_index)
                   1246:      rtx exp;
                   1247:      int insn_code, insn_index;
                   1248: {
                   1249:   int i, j;
                   1250:   rtx newtest;
                   1251:   rtx value;
                   1252:   rtx newexp = exp;
                   1253: 
                   1254:   for (i = 0; i < XVECLEN (exp, 0); i += 2)
                   1255:     {
                   1256:       newtest = SIMPLIFY_TEST_EXP (XVECEXP (exp, 0, i), insn_code, insn_index);
                   1257:       if (newtest == true_rtx)
                   1258:        {
                   1259:          /* Make a new COND with any previous conditions and the value for
                   1260:             this pair as the default value.  */
                   1261:          newexp = rtx_alloc (COND);
                   1262:          XVEC (newexp, 0) = rtvec_alloc (i);
                   1263:          for (j = 0; j < i; j++)
                   1264:            XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
                   1265: 
                   1266:          XEXP (newexp, 1) = XVECEXP (exp, 0, i + 1);
                   1267:          break;
                   1268:        }
                   1269: 
                   1270:       else if (newtest == false_rtx)
                   1271:        {
                   1272:          /* Build a new COND without this test.  */
                   1273:          newexp = rtx_alloc (COND);
                   1274:          XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0) - 2);
                   1275:          for (j = 0; j < i; j++)
                   1276:            XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
                   1277: 
                   1278:          for (j = i; j < XVECLEN (newexp, 0); j++)
                   1279:            XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j + 2);
                   1280: 
                   1281:          XEXP (newexp, 1) = XEXP (exp, 1);
                   1282:          break;
                   1283:        }
                   1284: 
                   1285:       else if (newtest != XVECEXP (exp, 0, i))
                   1286:        {
                   1287:          newexp = rtx_alloc (COND);
                   1288:          XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
                   1289:          for (j = 0; j < XVECLEN (exp, 0); j++)
                   1290:            XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
                   1291:          XEXP (newexp, 1) = XEXP (exp, 1);
                   1292: 
                   1293:          XVECEXP (newexp, 0, i) = newtest;
                   1294:          break;
                   1295:        }
                   1296: 
                   1297:       /* See if this value may need simplification.  */
                   1298:       if (GET_CODE (XVECEXP (exp, 0, i + 1)) == COND)
                   1299:        {
                   1300:          value = simplify_cond (XVECEXP (exp, 0, i + 1),
                   1301:                                 insn_code, insn_index);
                   1302:          if (value != XVECEXP (exp, 0, i + 1))
                   1303:            {
                   1304:              newexp = rtx_alloc (COND);
                   1305:              XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
                   1306:              for (j = 0; j < XVECLEN (exp, 0); j++)
                   1307:                XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
                   1308:              XEXP (newexp, 1) = XEXP (exp, 1);
                   1309: 
                   1310:              XVECEXP (newexp, 0, i + 1) = value;
                   1311:              break;
                   1312:            }
                   1313:        }
                   1314: 
                   1315:       /* If this is the last condition in a COND and our value is the same
                   1316:         as the default value, our test isn't needed.  */
                   1317:       if (i == XVECLEN (exp, 0) - 2
                   1318:          && rtx_equal_p (XVECEXP (exp, 0, i + 1), XEXP (exp, 1)))
                   1319:        {
                   1320:          newexp = rtx_alloc (COND);
                   1321:          XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0) - 2);
                   1322:          for (j = 0; j < i; j++)
                   1323:            XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
                   1324:          XEXP (newexp, 1) = XEXP (exp, 1);
                   1325:          break;
                   1326:        }
                   1327: 
                   1328:       /* If this value and the value for the next test are the same, merge the
                   1329:          tests.  */
                   1330:       else if (i != XVECLEN (exp, 0) - 2
                   1331:               && rtx_equal_p (XVECEXP (exp, 0, i + 1),
                   1332:                               XVECEXP (exp, 0, i + 3)))
                   1333:        {
                   1334:          newexp = rtx_alloc (COND);
                   1335:          XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0) - 2);
                   1336:          for (j = 0; j < i; j++)
                   1337:            XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
                   1338: 
                   1339:          XVECEXP (newexp, 0, j)
                   1340:            = insert_right_side (IOR, XVECEXP (exp, 0, i),
                   1341:                                 XVECEXP (exp, 0, i + 2),
                   1342:                                 insn_code, insn_index);
                   1343:          XVECEXP (newexp, 0, j + 1) = XVECEXP (exp, 0, i + 1);
                   1344: 
                   1345:          for (j = i + 2; j < XVECLEN (newexp, 0); j++)
                   1346:            XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j + 2);
                   1347: 
                   1348:          XEXP (newexp, 1) = XEXP (exp, 1);
                   1349:          break;
                   1350:        }
                   1351:     }
                   1352: 
                   1353:   /* See if default value needs simplification.  */
                   1354:   if (GET_CODE (XEXP (exp, 1)) == COND)
                   1355:     {
                   1356:       value = simplify_cond (XEXP (exp, 1), insn_code, insn_index);
                   1357:       if (value != XEXP (exp, 1))
                   1358:        {
                   1359:          newexp = rtx_alloc (COND);
                   1360:          XVEC (newexp, 0) = rtvec_alloc (XVECLEN (exp, 0));
                   1361:          for (j = 0; j < XVECLEN (exp, 0); j++)
                   1362:            XVECEXP (newexp, 0, j) = XVECEXP (exp, 0, j);
                   1363:          XEXP (newexp, 1) = value;
                   1364:        }
                   1365:     }
                   1366:   
                   1367:   if (exp == newexp)
                   1368:     return exp;
                   1369:   else if (XVECLEN (newexp, 0) == 1)
                   1370:     return XVECEXP (newexp, 0, 0);
                   1371:   else
                   1372:     return simplify_cond (newexp, insn_code, insn_index);
                   1373: }
                   1374: 
                   1375: /* Remove an insn entry from an attribute value.  */
                   1376: 
                   1377: static void
                   1378: remove_insn_ent (av, ie)
                   1379:      struct attr_value *av;
                   1380:      struct insn_ent *ie;
                   1381: {
                   1382:   struct insn_ent *previe;
                   1383: 
                   1384:   if (av->first_insn == ie)
                   1385:     av->first_insn = ie->next;
                   1386:   else
                   1387:     {
                   1388:       for (previe = av->first_insn; previe->next != ie; previe = previe->next)
                   1389:        ;
                   1390:       previe->next = ie->next;
                   1391:     }
                   1392: 
                   1393:   av->num_insns--;
                   1394:   if (ie->insn_code == -1)
                   1395:     av->has_asm_insn = 0;
                   1396: }
                   1397: 
                   1398: /* Insert an insn entry in an attribute value list.  */
                   1399: 
                   1400: static void
                   1401: insert_insn_ent (av, ie)
                   1402:      struct attr_value *av;
                   1403:      struct insn_ent *ie;
                   1404: {
                   1405:   ie->next = av->first_insn;
                   1406:   av->first_insn = ie;
                   1407:   av->num_insns++;
                   1408:   if (ie->insn_code == -1)
                   1409:     av->has_asm_insn = 1;
                   1410: }
                   1411: 
                   1412: /* This is a utility routine to take an expression that is a tree of either
                   1413:    AND or IOR expressions and insert a new term.  The new term will be
                   1414:    inserted at the right side of the first node whose code does not match
                   1415:    the root.  A new node will be created with the root's code.  Its left
                   1416:    side will be the old right side and its right side will be the new
                   1417:    term.
                   1418: 
                   1419:    If the `term' is itself a tree, all its leaves will be inserted.  */
                   1420: 
                   1421: static rtx
                   1422: insert_right_side (code, exp, term, insn_code, insn_index)
                   1423:      RTX_CODE code;
                   1424:      rtx exp;
                   1425:      rtx term;
                   1426:      int insn_code, insn_index;
                   1427: {
                   1428:   rtx newexp;
                   1429: 
                   1430:   if (GET_CODE (term) == code)
                   1431:     {
                   1432:       exp = insert_right_side (code, exp, XEXP (term, 0),
                   1433:                               insn_code, insn_index);
                   1434:       exp = insert_right_side (code, exp, XEXP (term, 1),
                   1435:                               insn_code, insn_index);
                   1436: 
                   1437:       return exp;
                   1438:     }
                   1439: 
                   1440:   if (GET_CODE (exp) == code)
                   1441:     {
                   1442:       /* Make a copy of this expression and call recursively.  */
                   1443:       newexp = rtx_alloc (code);
                   1444:       XEXP (newexp, 0) = XEXP (exp, 0);
                   1445:       XEXP (newexp, 1) = insert_right_side (code, XEXP (exp, 1),
                   1446:                                            term, insn_code, insn_index);
                   1447:     }
                   1448:   else
                   1449:     {
                   1450:       /* Insert the new term.  */
                   1451:       newexp = rtx_alloc (code);
                   1452:       XEXP (newexp, 0) = exp;
                   1453:       XEXP (newexp, 1) = term;
                   1454:       }
                   1455: 
                   1456:   return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
                   1457: }
                   1458: 
                   1459: /* If we have an expression which AND's a bunch of
                   1460:        (not (eq_attrq "alternative" "n"))
                   1461:    terms, we may have covered all or all but one of the possible alternatives.
                   1462:    If so, we can optimize.  Similarly for IOR's of EQ_ATTR.
                   1463: 
                   1464:    This routine is passed an expression and either AND or IOR.  It returns a
                   1465:    bitmask indicating which alternatives are present.  */
                   1466: 
                   1467: static int
                   1468: compute_alternative_mask (exp, code)
                   1469:      rtx exp;
                   1470:      RTX_CODE code;
                   1471: {
                   1472:   if (GET_CODE (exp) == code)
                   1473:     return compute_alternative_mask (XEXP (exp, 0), code)
                   1474:           | compute_alternative_mask (XEXP (exp, 1), code);
                   1475: 
                   1476:   else if (code == AND && GET_CODE (exp) == NOT
                   1477:           && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
                   1478:           && XSTR (XEXP (exp, 0), 0) == alternative_name)
                   1479:     return 1 << atoi (XSTR (XEXP (exp, 0), 1));
                   1480: 
                   1481:   else if (code == IOR && GET_CODE (exp) == EQ_ATTR
                   1482:           && XSTR (exp, 0) == alternative_name)
                   1483:     return 1 << atoi (XSTR (exp, 1));
                   1484: 
                   1485:   else
                   1486:     return 0;
                   1487: }
                   1488: 
                   1489: /* Given I, a single-bit mask, return RTX to compare the `alternative'
                   1490:    attribute with the value represented by that bit.  */
                   1491: 
                   1492: static rtx
                   1493: make_alternative_compare (mask)
                   1494:      int mask;
                   1495: {
                   1496:   rtx newexp;
                   1497:   int i;
                   1498:   char *alternative;
                   1499: 
                   1500:   /* Find the bit.  */
                   1501:   for (i = 0; (mask & (1 << i)) == 0; i++)
                   1502:     ;
                   1503: 
                   1504:   alternative = (char *) xmalloc (3);
                   1505:   sprintf (alternative, "%d", i);
                   1506: 
                   1507:   newexp = rtx_alloc (EQ_ATTR);
                   1508:   XSTR (newexp, 0) = alternative_name;
                   1509:   XSTR (newexp, 1) = alternative;
                   1510:   RTX_UNCHANGING_P (newexp) = 1;
                   1511: 
                   1512:   return newexp;
                   1513: }
                   1514: 
                   1515: /* If we are processing an (eq_attr "attr" "value") test, we find the value
                   1516:    of "attr" for this insn code.  From that value, we can compute a test
                   1517:    showing when the EQ_ATTR will be true.  This routine performs that
                   1518:    computation.  If a test condition involves an address, we leave the EQ_ATTR
                   1519:    intact because addresses are only valid for the `length' attribute.  */
                   1520: 
                   1521: static rtx
                   1522: evaluate_eq_attr (exp, value, insn_code, insn_index)
                   1523:      rtx exp;
                   1524:      rtx value;
                   1525:      int insn_code, insn_index;
                   1526: {
                   1527:   rtx orexp, andexp;
                   1528:   rtx right;
                   1529:   rtx newexp;
                   1530:   int i;
                   1531: 
                   1532:   if (GET_CODE (value) == CONST_STRING)
                   1533:     {
                   1534:       if (! strcmp (XSTR (value, 0), XSTR (exp, 1)))
                   1535:        newexp = true_rtx;
                   1536:       else
                   1537:        newexp = false_rtx;
                   1538:     }
                   1539:   else if (GET_CODE (value) == COND)
                   1540:     {
                   1541:       /* We construct an IOR of all the cases for which the requested attribute
                   1542:         value is present.  Since we start with FALSE, if it is not present,
                   1543:         FALSE will be returned.
                   1544: 
                   1545:         Each case is the AND of the NOT's of the previous conditions with the
                   1546:         current condition; in the default case the current condition is TRUE. 
                   1547: 
                   1548:         For each possible COND value, call ourselves recursively.
                   1549: 
                   1550:         The extra TRUE and FALSE expressions will be eliminated by another
                   1551:         call to the simplification routine. */
                   1552: 
                   1553:       orexp = false_rtx;
                   1554:       andexp = true_rtx;
                   1555: 
                   1556:       for (i = 0; i < XVECLEN (value, 0); i += 2)
                   1557:        {
                   1558:          right = insert_right_side (AND, andexp,
                   1559:                                     XVECEXP (value, 0, i),
                   1560:                                     insn_code, insn_index);
                   1561:          right = insert_right_side (AND, right,
                   1562:                        evaluate_eq_attr (exp, XVECEXP (value, 0, i + 1),
                   1563:                                           insn_code, insn_index),
                   1564:                                     insn_code, insn_index);
                   1565:          orexp = insert_right_side (IOR, orexp, right,
                   1566:                                     insn_code, insn_index);
                   1567: 
                   1568:          /* Add this condition into the AND expression.  */
                   1569:          newexp = rtx_alloc (NOT);
                   1570:          XEXP (newexp, 0) = XVECEXP (value, 0, i);
                   1571:          andexp = insert_right_side (AND, andexp, newexp,
                   1572:                                      insn_code, insn_index);
                   1573:        }
                   1574: 
                   1575:       /* Handle the default case.  */
                   1576:       right = insert_right_side (AND, andexp,
                   1577:                                 evaluate_eq_attr (exp, XEXP (value, 1),
                   1578:                                                    insn_code, insn_index),
                   1579:                                 insn_code, insn_index);
                   1580:       newexp = insert_right_side (IOR, orexp, right, insn_code, insn_index);
                   1581:     }
                   1582:   else
                   1583:     abort ();
                   1584: 
                   1585:   /* If uses an address, must return original expression.  */
                   1586: 
                   1587:   address_used = 0;
                   1588:   walk_attr_value (newexp);
                   1589: 
                   1590:   if (address_used)
                   1591:     return exp;
                   1592:   else
                   1593:     return newexp;
                   1594: }
                   1595: 
                   1596: /* This routine is called when an AND of a term with a tree of AND's is
                   1597:    encountered.  If the term or its complement is present in the tree, it
                   1598:    can be replaced with TRUE or FALSE, respectively.
                   1599: 
                   1600:    Note that (eq_attr "att" "v1") and (eq_attr "att" "v2") cannot both
                   1601:    be true and hence are complementary.  
                   1602: 
                   1603:    There is one special case:  If we see
                   1604:        (and (not (eq_attr "att" "v1"))
                   1605:             (eq_attr "att" "v2"))
                   1606:    this can be replaced by (eq_attr "att" "v2").  To do this we need to
                   1607:    replace the term, not anything in the AND tree.  So we pass a pointer to
                   1608:    the term.  */
                   1609: 
                   1610: static rtx
                   1611: simplify_and_tree (exp, pterm, insn_code, insn_index)
                   1612:      rtx exp;
                   1613:      rtx *pterm;
                   1614:      int insn_code, insn_index;
                   1615: {
                   1616:   rtx left, right;
                   1617:   rtx newexp;
                   1618:   rtx temp;
                   1619:   int left_eliminates_term, right_eliminates_term;
                   1620: 
                   1621:   if (GET_CODE (exp) == AND)
                   1622:     {
                   1623:       left = simplify_and_tree (XEXP (exp, 0), pterm,  insn_code, insn_index);
                   1624:       right = simplify_and_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
                   1625:       if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
                   1626:        {
                   1627:          newexp = rtx_alloc (GET_CODE (exp));
                   1628:          XEXP (newexp, 0) = left;
                   1629:          XEXP (newexp, 1) = right;
                   1630: 
                   1631:          exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
                   1632:        }
                   1633:     }
                   1634: 
                   1635:   else if (GET_CODE (exp) == IOR)
                   1636:     {
                   1637:       /* For the IOR case, we do the same as above, except that we can
                   1638:          only eliminate `term' if both sides of the IOR would do so.  */
                   1639:       temp = *pterm;
                   1640:       left = simplify_and_tree (XEXP (exp, 0), &temp,  insn_code, insn_index);
                   1641:       left_eliminates_term = (temp == true_rtx);
                   1642: 
                   1643:       temp = *pterm;
                   1644:       right = simplify_and_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
                   1645:       right_eliminates_term = (temp == true_rtx);
                   1646: 
                   1647:       if (left_eliminates_term && right_eliminates_term)
                   1648:        *pterm = true_rtx;
                   1649: 
                   1650:       if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
                   1651:        {
                   1652:          newexp = rtx_alloc (GET_CODE (exp));
                   1653:          XEXP (newexp, 0) = left;
                   1654:          XEXP (newexp, 1) = right;
                   1655: 
                   1656:          exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
                   1657:        }
                   1658:     }
                   1659: 
                   1660:   /* Check for simplifications.  Do some extra checking here since this
                   1661:      routine is called so many times.  */
                   1662: 
                   1663:   if (exp == *pterm)
                   1664:     return true_rtx;
                   1665: 
                   1666:   else if (GET_CODE (exp) == NOT && XEXP (exp, 0) == *pterm)
                   1667:     return false_rtx;
                   1668: 
                   1669:   else if (GET_CODE (*pterm) == NOT && exp == XEXP (*pterm, 0))
                   1670:     return false_rtx;
                   1671: 
                   1672:   else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == EQ_ATTR)
                   1673:     {
                   1674:       if (XSTR (exp, 0) != XSTR (*pterm, 0))
                   1675:        return exp;
                   1676: 
                   1677:       if (! strcmp (XSTR (exp, 1), XSTR (*pterm, 1)))
                   1678:        return true_rtx;
                   1679:       else
                   1680:        return false_rtx;
                   1681:     }
                   1682: 
                   1683:   else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
                   1684:           && GET_CODE (XEXP (exp, 0)) == EQ_ATTR)
                   1685:     {
                   1686:       if (XSTR (*pterm, 0) != XSTR (XEXP (exp, 0), 0))
                   1687:        return exp;
                   1688: 
                   1689:       if (! strcmp (XSTR (*pterm, 1), XSTR (XEXP (exp, 0), 1)))
                   1690:        return false_rtx;
                   1691:       else
                   1692:        return true_rtx;
                   1693:     }
                   1694: 
                   1695:   else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
                   1696:           && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR)
                   1697:     {
                   1698:       if (XSTR (exp, 0) != XSTR (XEXP (*pterm, 0), 0))
                   1699:        return exp;
                   1700: 
                   1701:       if (! strcmp (XSTR (exp, 1), XSTR (XEXP (*pterm, 0), 1)))
                   1702:        return false_rtx;
                   1703:       else
                   1704:        *pterm = true_rtx;
                   1705:     }
                   1706: 
                   1707:   else if (GET_CODE (exp) == NOT && GET_CODE (*pterm) == NOT)
                   1708:     {
                   1709:       if (rtx_equal_p (XEXP (exp, 0), XEXP (*pterm, 0)))
                   1710:        return true_rtx;
                   1711:     }
                   1712: 
                   1713:   else if (GET_CODE (exp) == NOT)
                   1714:     {
                   1715:       if (rtx_equal_p (XEXP (exp, 0), *pterm))
                   1716:        return false_rtx;
                   1717:     }
                   1718: 
                   1719:   else if (GET_CODE (*pterm) == NOT)
                   1720:     {
                   1721:       if (rtx_equal_p (XEXP (*pterm, 0), exp))
                   1722:        return false_rtx;
                   1723:     }
                   1724: 
                   1725:   else if (rtx_equal_p (exp, *pterm))
                   1726:     return true_rtx;
                   1727: 
                   1728:   return exp;
                   1729: }
                   1730: 
                   1731: /* Similiar to `simplify_and_tree', but for IOR trees.  */
                   1732: 
                   1733: static rtx
                   1734: simplify_or_tree (exp, pterm, insn_code, insn_index)
                   1735:      rtx exp;
                   1736:      rtx *pterm;
                   1737:      int insn_code, insn_index;
                   1738: {
                   1739:   rtx left, right;
                   1740:   rtx newexp;
                   1741:   rtx temp;
                   1742:   int left_eliminates_term, right_eliminates_term;
                   1743: 
                   1744:   if (GET_CODE (exp) == IOR)
                   1745:     {
                   1746:       left = simplify_or_tree (XEXP (exp, 0), pterm,  insn_code, insn_index);
                   1747:       right = simplify_or_tree (XEXP (exp, 1), pterm, insn_code, insn_index);
                   1748:       if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
                   1749:        {
                   1750:          newexp = rtx_alloc (GET_CODE (exp));
                   1751:          XEXP (newexp, 0) = left;
                   1752:          XEXP (newexp, 1) = right;
                   1753: 
                   1754:          exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
                   1755:        }
                   1756:     }
                   1757: 
                   1758:   else if (GET_CODE (exp) == AND)
                   1759:     {
                   1760:       /* For the AND case, we do the same as above, except that we can
                   1761:          only eliminate `term' if both sides of the AND would do so.  */
                   1762:       temp = *pterm;
                   1763:       left = simplify_or_tree (XEXP (exp, 0), &temp,  insn_code, insn_index);
                   1764:       left_eliminates_term = (temp == false_rtx);
                   1765: 
                   1766:       temp = *pterm;
                   1767:       right = simplify_or_tree (XEXP (exp, 1), &temp, insn_code, insn_index);
                   1768:       right_eliminates_term = (temp == false_rtx);
                   1769: 
                   1770:       if (left_eliminates_term && right_eliminates_term)
                   1771:        *pterm = false_rtx;
                   1772: 
                   1773:       if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
                   1774:        {
                   1775:          newexp = rtx_alloc (GET_CODE (exp));
                   1776:          XEXP (newexp, 0) = left;
                   1777:          XEXP (newexp, 1) = right;
                   1778: 
                   1779:          exp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
                   1780:        }
                   1781:     }
                   1782: 
                   1783:   if (rtx_equal_p (exp, *pterm))
                   1784:     return false_rtx;
                   1785: 
                   1786:   else if (GET_CODE (exp) == NOT && rtx_equal_p (XEXP (exp, 0), *pterm))
                   1787:     return true_rtx;
                   1788: 
                   1789:   else if (GET_CODE (*pterm) == NOT && rtx_equal_p (XEXP (*pterm, 0), exp))
                   1790:     return true_rtx;
                   1791: 
                   1792:   else if (GET_CODE (*pterm) == EQ_ATTR && GET_CODE (exp) == NOT
                   1793:           && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
                   1794:           && XSTR (*pterm, 0) == XSTR (XEXP (exp, 0), 0))
                   1795:     *pterm = false_rtx;
                   1796: 
                   1797:   else if (GET_CODE (exp) == EQ_ATTR && GET_CODE (*pterm) == NOT
                   1798:           && GET_CODE (XEXP (*pterm, 0)) == EQ_ATTR
                   1799:           && XSTR (exp, 0) == XSTR (XEXP (*pterm, 0), 0))
                   1800:     return false_rtx;
                   1801: 
                   1802:   return exp;
                   1803: }
                   1804: 
                   1805: /* Given an expression, see if it can be simplified for a particular insn
                   1806:    code based on the values of other attributes being tested.  This can
                   1807:    eliminate nested get_attr_... calls.
                   1808: 
                   1809:    Note that if an endless recursion is specified in the patterns, the 
                   1810:    optimization will loop.  However, it will do so in precisely the cases where
                   1811:    an infinite recursion loop could occur during compilation.  It's better that
                   1812:    it occurs here!  */
                   1813: 
                   1814: static rtx
                   1815: simplify_test_exp (exp, insn_code, insn_index)
                   1816:      rtx exp;
                   1817:      int insn_code, insn_index;
                   1818: {
                   1819:   rtx left, right;
                   1820:   struct attr_desc *attr;
                   1821:   struct attr_value *av;
                   1822:   struct insn_ent *ie;
                   1823:   int i;
                   1824:   rtx newexp = exp;
                   1825: 
                   1826:   switch (GET_CODE (exp))
                   1827:     {
                   1828:     case AND:
                   1829:       left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
                   1830:       right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
                   1831: 
                   1832:       /* If either side is an IOR and we have (eq_attr "alternative" ..")
                   1833:         present on both sides, apply the distributive law since this will
                   1834:         yield simplications.  */
                   1835:       if ((GET_CODE (left) == IOR || GET_CODE (right) == IOR)
                   1836:          && compute_alternative_mask (left, IOR)
                   1837:          && compute_alternative_mask (right, IOR))
                   1838:        {
                   1839:          if (GET_CODE (left) == IOR)
                   1840:            {
                   1841:              rtx tem = left;
                   1842:              left = right;
                   1843:              right = tem;
                   1844:            }
                   1845: 
                   1846:          newexp = rtx_alloc (IOR);
                   1847:          XEXP (newexp, 0) = rtx_alloc (AND);
                   1848:          XEXP (newexp, 1) = rtx_alloc (AND);
                   1849:          XEXP (XEXP (newexp, 0), 0) = XEXP (XEXP (newexp, 1), 0) = left;
                   1850:          XEXP (XEXP (newexp, 0), 1) = XEXP (right, 0);
                   1851:          XEXP (XEXP (newexp, 1), 1) = XEXP (right, 1);
                   1852: 
                   1853:          return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
                   1854:        }
                   1855: 
                   1856:       /* Try with the term on both sides.  */
                   1857:       right = simplify_and_tree (right, &left, insn_code, insn_index);
                   1858:       if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
                   1859:        left = simplify_and_tree (left, &right, insn_code, insn_index);
                   1860: 
                   1861:       if (left == false_rtx || right == false_rtx)
                   1862:        return false_rtx;
                   1863:       else if (left == true_rtx)
                   1864:        return right;
                   1865:       else if (right == true_rtx)
                   1866:        return left;
                   1867: 
                   1868:       /* See if all or all but one of the insn's alternatives are specified
                   1869:         in this tree.  Optimize if so.  */
                   1870: 
                   1871:       else if (insn_code >= 0
                   1872:               && (GET_CODE (left) == AND
                   1873:                   || (GET_CODE (left) == NOT
                   1874:                       && GET_CODE (XEXP (left, 0)) == EQ_ATTR
                   1875:                       && XSTR (XEXP (left, 0), 0) == alternative_name)
                   1876:                   || GET_CODE (right) == AND
                   1877:                   || (GET_CODE (right) == NOT
                   1878:                       && GET_CODE (XEXP (right, 0)) == EQ_ATTR
                   1879:                       && XSTR (XEXP (right, 0), 0) == alternative_name)))
                   1880:        {
                   1881:          i = compute_alternative_mask (exp, AND);
                   1882:          if (i & ~insn_alternatives[insn_code])
                   1883:            fatal ("Illegal alternative specified for pattern number %d",
                   1884:                   insn_index);
                   1885: 
                   1886:          /* If all alternatives are excluded, this is false. */
                   1887:          i ^= insn_alternatives[insn_code];
                   1888:          if (i == 0)
                   1889:            return false_rtx;
                   1890:          else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
                   1891:            {
                   1892:              /* If just one excluded, AND a comparison with that one to the
                   1893:                 front of the tree.  The others will be eliminated by
                   1894:                 optimization.  We do not want to do this if the insn has one
                   1895:                 alternative and we have tested none of them!  */
                   1896:              left = make_alternative_compare (i);
                   1897:              right = simplify_and_tree (exp, &left, insn_code, insn_index);
                   1898:              newexp = rtx_alloc (AND);
                   1899:              XEXP (newexp, 0) = left;
                   1900:              XEXP (newexp, 1) = right;
                   1901: 
                   1902:              return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
                   1903:            }
                   1904:        }
                   1905: 
                   1906:       if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
                   1907:        {
                   1908:          newexp = rtx_alloc (AND);
                   1909:          XEXP (newexp, 0) = left;
                   1910:          XEXP (newexp, 1) = right;
                   1911:          return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
                   1912:        }
                   1913:       break;
                   1914: 
                   1915:     case IOR:
                   1916:       left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
                   1917:       right = SIMPLIFY_TEST_EXP (XEXP (exp, 1), insn_code, insn_index);
                   1918: 
                   1919:       right = simplify_or_tree (right, &left, insn_code, insn_index);
                   1920:       if (left == XEXP (exp, 0) && right == XEXP (exp, 1))
                   1921:        left = simplify_or_tree (left, &right, insn_code, insn_index);
                   1922: 
                   1923:       if (right == true_rtx || left == true_rtx)
                   1924:        return true_rtx;
                   1925:       else if (left == false_rtx)
                   1926:        return right;
                   1927:       else if (right == false_rtx)
                   1928:        return left;
                   1929: 
                   1930:       /* Test for simple cases where the distributive law is useful.  I.e.,
                   1931:            convert (ior (and (x) (y))
                   1932:                         (and (x) (z)))
                   1933:            to      (and (x)
                   1934:                         (ior (y) (z)))
                   1935:        */
                   1936: 
                   1937:       else if (GET_CODE (left) == AND && GET_CODE (right) == AND
                   1938:          && rtx_equal_p (XEXP (left, 0), XEXP (right, 0)))
                   1939:        {
                   1940:          newexp = rtx_alloc (IOR);
                   1941:          XEXP (newexp, 0) = XEXP (left, 1);
                   1942:          XEXP (newexp, 1) = XEXP (right, 1);
                   1943: 
                   1944:          left = XEXP (left, 0);
                   1945:          right = newexp;
                   1946:          newexp = rtx_alloc (AND);
                   1947:          XEXP (newexp, 0) = left;
                   1948:          XEXP (newexp, 1) = right;
                   1949:          return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
                   1950:        }
                   1951: 
                   1952:       /* See if all or all but one of the insn's alternatives are specified
                   1953:         in this tree.  Optimize if so.  */
                   1954: 
                   1955:       else if (insn_code >= 0
                   1956:          && (GET_CODE (left) == IOR
                   1957:              || (GET_CODE (left) == EQ_ATTR
                   1958:                  && XSTR (left, 0) == alternative_name)
                   1959:              || GET_CODE (right) == IOR
                   1960:              || (GET_CODE (right) == EQ_ATTR
                   1961:                  && XSTR (right, 0) == alternative_name)))
                   1962:        {
                   1963:          i = compute_alternative_mask (exp, IOR);
                   1964:          if (i & ~insn_alternatives[insn_code])
                   1965:            fatal ("Illegal alternative specified for pattern number %d",
                   1966:                   insn_index);
                   1967: 
                   1968:          /* If all alternatives are included, this is true. */
                   1969:          i ^= insn_alternatives[insn_code];
                   1970:          if (i == 0)
                   1971:            return true_rtx;
                   1972:          else if ((i & (i - 1)) == 0 && insn_alternatives[insn_code] > 1)
                   1973:            {
                   1974:              /* If just one excluded, IOR a comparison with that one to the
                   1975:                 front of the tree.  The others will be eliminated by
                   1976:                 optimization.  We do not want to do this if the insn has one
                   1977:                 alternative and we have tested none of them!  */
                   1978:              left = make_alternative_compare (i);
                   1979:              right = simplify_and_tree (exp, &left, insn_code, insn_index);
                   1980:              newexp = rtx_alloc (IOR);
                   1981:              XEXP (newexp, 0) = rtx_alloc (NOT);
                   1982:              XEXP (XEXP (newexp, 0), 0) = left;
                   1983:              XEXP (newexp, 1) = right;
                   1984: 
                   1985:              return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
                   1986:            }
                   1987:        }
                   1988: 
                   1989:       if (left != XEXP (exp, 0) || right != XEXP (exp, 1))
                   1990:        {
                   1991:          newexp = rtx_alloc (IOR);
                   1992:          XEXP (newexp, 0) = left;
                   1993:          XEXP (newexp, 1) = right;
                   1994:          return SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
                   1995:        }
                   1996:       break;
                   1997: 
                   1998:     case NOT:
                   1999:       left = SIMPLIFY_TEST_EXP (XEXP (exp, 0), insn_code, insn_index);
                   2000:       if (GET_CODE (left) == NOT)
                   2001:        return XEXP (left, 0);
                   2002: 
                   2003:       if (left == false_rtx)
                   2004:        return true_rtx;
                   2005:       else if (left == true_rtx)
                   2006:        return false_rtx;
                   2007: 
                   2008:       /* Try to apply De`Morgan's laws.  */
                   2009:       else if (GET_CODE (left) == IOR)
                   2010:        {
                   2011:          newexp = rtx_alloc (AND);
                   2012:          XEXP (newexp, 0) = rtx_alloc (NOT);
                   2013:          XEXP (XEXP (newexp, 0), 0) = XEXP (left, 0);
                   2014:          XEXP (newexp, 1) = rtx_alloc (NOT);
                   2015:          XEXP (XEXP (newexp, 1), 0) = XEXP (left, 1);
                   2016: 
                   2017:          newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
                   2018:        }
                   2019:       else if (GET_CODE (left) == AND)
                   2020:        {
                   2021:          newexp = rtx_alloc (IOR);
                   2022:          XEXP (newexp, 0) = rtx_alloc (NOT);
                   2023:          XEXP (XEXP (newexp, 0), 0) = XEXP (left, 0);
                   2024:          XEXP (newexp, 1) = rtx_alloc (NOT);
                   2025:          XEXP (XEXP (newexp, 1), 0) = XEXP (left, 1);
                   2026: 
                   2027:          newexp = SIMPLIFY_TEST_EXP (newexp, insn_code, insn_index);
                   2028:        }
                   2029:       else if (left != XEXP (exp, 0))
                   2030:        {
                   2031:          newexp = rtx_alloc (NOT);
                   2032:          XEXP (newexp, 0) = left;
                   2033:        }
                   2034:       break;
                   2035: 
                   2036:     case EQ_ATTR:
                   2037:       /* Look at the value for this insn code in the specified attribute.
                   2038:         We normally can replace this comparison with the condition that
                   2039:         would give this insn the values being tested for.   */
                   2040:       if (XSTR (exp, 0) != alternative_name
                   2041:          && (attr = find_attr (XSTR (exp, 0), 0)) != NULL)
                   2042:        for (av = attr->first_value; av; av = av->next)
                   2043:          for (ie = av->first_insn; ie; ie = ie->next)
                   2044:            if (ie->insn_code == insn_code)
                   2045:              return evaluate_eq_attr (exp, av->value, insn_code, insn_index);
                   2046:     }
                   2047: 
                   2048:   /* We have already simplified this expression.  Simplifying it again
                   2049:      won't buy anything unless we weren't given a valid insn code
                   2050:      to process (i.e., we are canonicalizing something.).  */
                   2051:   if (insn_code != -2)
                   2052:     RTX_UNCHANGING_P (newexp) = 1;
                   2053: 
                   2054:   return newexp;
                   2055: }
                   2056: 
                   2057: /* Optimize the attribute lists by seeing if we can determine conditional
                   2058:    values from the known values of other attributes.  This will save subroutine
                   2059:    calls during the compilation.  */
                   2060: 
                   2061: static void
                   2062: optimize_attrs ()
                   2063: {
                   2064:   struct attr_desc *attr;
                   2065:   struct attr_value *av;
                   2066:   struct insn_ent *ie, *nextie;
                   2067:   rtx newexp;
                   2068:   int something_changed = 1;
                   2069: 
                   2070:   /* Loop until nothing changes for one iteration.  */
                   2071:   while (something_changed)
                   2072:     {
                   2073:       something_changed = 0;
                   2074:       for (attr = attrs; attr; attr = attr->next)
                   2075:        for (av = attr->first_value; av; av = av->next)
                   2076:            for (ie = av->first_insn; ie; ie = nextie)
                   2077:              {
                   2078:                nextie = ie->next;
                   2079:                if (GET_CODE (av->value) != COND)
                   2080:                  continue;
                   2081: 
                   2082:                newexp = simplify_cond (av->value, ie->insn_code,
                   2083:                                        ie->insn_index);
                   2084:                if (newexp != av->value)
                   2085:                  {
                   2086:                    remove_insn_ent (av, ie);
                   2087:                    insert_insn_ent (get_attr_value (newexp, attr,
                   2088:                                                     ie->insn_code), ie);
                   2089:                    something_changed = 1;
                   2090:                  }
                   2091:              }
                   2092:     }
                   2093: }
                   2094: 
                   2095: /* Create table entries for DEFINE_ATTR.  */
                   2096: 
                   2097: static void
                   2098: gen_attr (exp)
                   2099:      rtx exp;
                   2100: {
                   2101:   struct attr_desc *attr;
                   2102:   struct attr_value *av;
                   2103:   char *name_ptr;
                   2104:   char *p;
                   2105: 
                   2106:   /* Make a new attribute structure.  Check for duplicate by looking at
                   2107:      attr->default_val, since it is initialized by this routine.  */
                   2108:   attr = find_attr (XSTR (exp, 0), 1);
                   2109:   if (attr->default_val)
                   2110:     fatal ("Duplicate definition for `%s' attribute", attr->name);
                   2111: 
                   2112:   if (*XSTR (exp, 1) == '\0')
                   2113:       attr->is_numeric = 1;
                   2114:   else
                   2115:     {
                   2116:       name_ptr = XSTR (exp, 1);
                   2117:       while ((p = next_comma_elt (&name_ptr)) != NULL)
                   2118:        {
                   2119:          av = (struct attr_value *) xmalloc (sizeof (struct attr_value));
                   2120:          av->value = rtx_alloc (CONST_STRING);
                   2121:          XSTR (av->value, 0) = p;
                   2122:          av->next = attr->first_value;
                   2123:          attr->first_value = av;
                   2124:          av->first_insn = NULL;
                   2125:          av->num_insns = 0;
                   2126:          av->has_asm_insn = 0;
                   2127:        }
                   2128:     }
                   2129: 
                   2130:   if (! strcmp (attr->name, "length") && ! attr->is_numeric)
                   2131:     fatal ("`length' attribute must take numeric values");
                   2132: 
                   2133:   /* Set up the default value. */
                   2134:   check_attr_value (XEXP (exp, 2), attr);
                   2135:   attr->default_val = get_attr_value (XEXP (exp, 2), attr, -2);
                   2136: }
                   2137: 
                   2138: /* Given a pattern for DEFINE_PEEPHOLE or DEFINE_INSN, return the number of
                   2139:    alternatives in the constraints.  Assume all MATCH_OPERANDs have the same
                   2140:    number of alternatives as this should be checked elsewhere.  */
                   2141: 
                   2142: static int
                   2143: count_alternatives (exp)
                   2144:      rtx exp;
                   2145: {
                   2146:   int i, j, n;
                   2147:   char *fmt;
                   2148:   
                   2149:   if (GET_CODE (exp) == MATCH_OPERAND)
                   2150:     return n_comma_elts (XSTR (exp, 2));
                   2151: 
                   2152:   for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
                   2153:        i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
                   2154:     switch (*fmt++)
                   2155:       {
                   2156:       case 'e':
                   2157:       case 'u':
                   2158:        n = count_alternatives (XEXP (exp, i));
                   2159:        if (n)
                   2160:          return n;
                   2161:        break;
                   2162: 
                   2163:       case 'E':
                   2164:       case 'V':
                   2165:        if (XVEC (exp, i) != NULL)
                   2166:          for (j = 0; j < XVECLEN (exp, i); j++)
                   2167:            {
                   2168:              n = count_alternatives (XVECEXP (exp, i, j));
                   2169:              if (n)
                   2170:                return n;
                   2171:            }
                   2172:       }
                   2173: 
                   2174:   return 0;
                   2175: }
                   2176: 
                   2177: /* Returns non-zero if the given expression contains an EQ_ATTR with the
                   2178:    `alternative' attribute.  */
                   2179: 
                   2180: static int
                   2181: compares_alternatives_p (exp)
                   2182:      rtx exp;
                   2183: {
                   2184:   int i, j;
                   2185:   char *fmt;
                   2186: 
                   2187:   if (GET_CODE (exp) == EQ_ATTR && XSTR (exp, 0) == alternative_name)
                   2188:     return 1;
                   2189: 
                   2190:   for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
                   2191:        i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
                   2192:     switch (*fmt++)
                   2193:       {
                   2194:       case 'e':
                   2195:       case 'u':
                   2196:        if (compares_alternatives_p (XEXP (exp, i)))
                   2197:          return 1;
                   2198:        break;
                   2199: 
                   2200:       case 'E':
                   2201:        for (j = 0; j < XVECLEN (exp, i); j++)
                   2202:          if (compares_alternatives_p (XVECEXP (exp, i, j)))
                   2203:            return 1;
                   2204:        break;
                   2205:       }
                   2206: 
                   2207:   return 0;
                   2208: }
                   2209: 
                   2210: /* Returns non-zero is INNER is contained in EXP.  */
                   2211: 
                   2212: static int
                   2213: contained_in_p (inner, exp)
                   2214:      rtx inner;
                   2215:      rtx exp;
                   2216: {
                   2217:   int i, j;
                   2218:   char *fmt;
                   2219: 
                   2220:   if (rtx_equal_p (inner, exp))
                   2221:     return 1;
                   2222: 
                   2223:   for (i = 0, fmt = GET_RTX_FORMAT (GET_CODE (exp));
                   2224:        i < GET_RTX_LENGTH (GET_CODE (exp)); i++)
                   2225:     switch (*fmt++)
                   2226:       {
                   2227:       case 'e':
                   2228:       case 'u':
                   2229:        if (contained_in_p (inner, XEXP (exp, i)))
                   2230:          return 1;
                   2231:        break;
                   2232: 
                   2233:       case 'E':
                   2234:        for (j = 0; j < XVECLEN (exp, i); j++)
                   2235:          if (contained_in_p (inner, XVECEXP (exp, i, j)))
                   2236:            return 1;
                   2237:        break;
                   2238:       }
                   2239: 
                   2240:   return 0;
                   2241: }
                   2242:       
                   2243: /* Process DEFINE_PEEPHOLE, DEFINE_INSN, and DEFINE_ASM_ATTRIBUTES.  */
                   2244: 
                   2245: static void
                   2246: gen_insn (exp)
                   2247:      rtx exp;
                   2248: {
                   2249:   struct insn_def *id;
                   2250: 
                   2251:   id = (struct insn_def *) xmalloc (sizeof (struct insn_def));
                   2252:   id->next = defs;
                   2253:   defs = id;
                   2254:   id->def = exp;
                   2255: 
                   2256:   switch (GET_CODE (exp))
                   2257:     {
                   2258:     case DEFINE_INSN:
                   2259:       id->insn_code = insn_code_number++;
                   2260:       id->insn_index = insn_index_number++;
                   2261:       id->num_alternatives = count_alternatives (exp);
                   2262:       if (id->num_alternatives == 0)
                   2263:        id->num_alternatives = 1;
                   2264:       id->vec_idx = 4;
                   2265:       break;
                   2266: 
                   2267:     case DEFINE_PEEPHOLE:
                   2268:       id->insn_code = insn_code_number++;
                   2269:       id->insn_index = insn_index_number++;
                   2270:       id->num_alternatives = count_alternatives (exp);
                   2271:       if (id->num_alternatives == 0)
                   2272:        id->num_alternatives = 1;
                   2273:       id->vec_idx = 3;
                   2274:       break;
                   2275: 
                   2276:     case DEFINE_ASM_ATTRIBUTES:
                   2277:       id->insn_code = -1;
                   2278:       id->insn_index = -1;
                   2279:       id->num_alternatives = 1;
                   2280:       id->vec_idx = 0;
                   2281:       got_define_asm_attributes = 1;
                   2282:       break;
                   2283:     }
                   2284: }
                   2285: 
                   2286: /* Process a DEFINE_DELAY.  Validate the vector length, check if annul
                   2287:    true or annul false is specified, and make a `struct delay_desc'.  */
                   2288: 
                   2289: static void
                   2290: gen_delay (def)
                   2291:      rtx def;
                   2292: {
                   2293:   struct delay_desc *delay;
                   2294:   int i;
                   2295: 
                   2296:   if (XVECLEN (def, 1) % 3 != 0)
                   2297:     fatal ("Number of elements in DEFINE_DELAY must be multiple of three.");
                   2298: 
                   2299:   for (i = 0; i < XVECLEN (def, 1); i += 3)
                   2300:     {
                   2301:       if (XVECEXP (def, 1, i + 1))
                   2302:        have_annul_true = 1;
                   2303:       if (XVECEXP (def, 1, i + 2))
                   2304:        have_annul_false = 1;
                   2305:     }
                   2306:   
                   2307:   delay = (struct delay_desc *) xmalloc (sizeof (struct delay_desc));
                   2308:   delay->def = def;
                   2309:   delay->num = ++num_delays;
                   2310:   delay->next = delays;
                   2311:   delays = delay;
                   2312: }
                   2313: 
                   2314: /* Process a DEFINE_FUNCTION_UNIT.  
                   2315: 
                   2316:    This gives information about a function unit contained in the CPU.
                   2317:    We fill in a `struct function_unit_op' and a `struct function_unit'
                   2318:    with information used later by `expand_unit'.  */
                   2319: 
                   2320: static void
                   2321: gen_unit (def)
                   2322:      rtx def;
                   2323: {
                   2324:   struct function_unit *unit;
                   2325:   struct function_unit_op *op;
                   2326: 
                   2327:   /* See if we have already seen this function unit.  If so, check that
                   2328:      the multipicity and simultaneity values are the same.  If not, make
                   2329:      a structure for this function unit.  */
                   2330:   for (unit = units; unit; unit = unit->next)
                   2331:     if (! strcmp (unit->name, XSTR (def, 0)))
                   2332:       {
                   2333:        if (unit->multiplicity != XINT (def, 1)
                   2334:            || unit->simultaneity != XINT (def, 2))
                   2335:          fatal ("Differing specifications given for `%s' function unit.",
                   2336:                 unit->name);
                   2337:        break;
                   2338:       }
                   2339: 
                   2340:   if (unit == 0)
                   2341:     {
                   2342:       unit = (struct function_unit *) xmalloc (sizeof (struct function_unit));
                   2343:       unit->name = XSTR (def, 0);
                   2344:       unit->multiplicity = XINT (def, 1);
                   2345:       unit->simultaneity = XINT (def, 2);
                   2346:       unit->num = num_units++;
                   2347:       unit->num_opclasses = 0;
                   2348:       unit->condexp = false_rtx;
                   2349:       unit->ops = 0;
                   2350:       unit->next = units;
                   2351:       units = unit;
                   2352:     }
                   2353: 
                   2354:   /* Make a new operation class structure entry and initialize it.  */
                   2355:   op = (struct function_unit_op *) xmalloc (sizeof (struct function_unit_op));
                   2356:   op->condexp = XEXP (def, 3);
                   2357:   op->num = unit->num_opclasses++;
                   2358:   op->ready = XINT (def, 4);
                   2359:   op->next = unit->ops;
                   2360:   unit->ops = op;
                   2361: 
                   2362:   /* Set our busy expression based on whether or not an optional conflict
                   2363:      vector was specified.  */
                   2364:   if (XVEC (def, 6))
                   2365:     {
                   2366:       /* Compute the IOR of all the specified expressions.  */
                   2367:       rtx orexp = false_rtx;
                   2368:       int i;
                   2369: 
                   2370:       for (i = 0; i < XVECLEN (def, 6); i++)
                   2371:        orexp = insert_right_side (IOR, orexp, XVECEXP (def, 6, i), -2);
                   2372: 
                   2373:       op->busyexp = rtx_alloc (IF_THEN_ELSE);
                   2374:       XEXP (op->busyexp, 0) = orexp;
                   2375:       XEXP (op->busyexp, 1) = make_numeric_value (XINT (def, 5));
                   2376:       XEXP (op->busyexp, 2) = make_numeric_value (0);
                   2377:     }
                   2378:   else
                   2379:     op->busyexp = make_numeric_value (XINT (def, 5));
                   2380: 
                   2381:   /* Merge our conditional into that of the function unit so we can determine
                   2382:      which insns are used by the function unit.  */
                   2383:   unit->condexp = insert_right_side (IOR, unit->condexp, op->condexp, -2);
                   2384: }
                   2385: 
                   2386: /* Given a piece of RTX, print a C expression to test it's truth value.
                   2387:    We use AND and IOR both for logical and bit-wise operations, so 
                   2388:    interpret them as logical unless they are inside a comparison expression.
                   2389:    The second operand of this function will be non-zero in that case.  */
                   2390: 
                   2391: static void
                   2392: write_test_expr (exp, in_comparison)
                   2393:      rtx exp;
                   2394:      int in_comparison;
                   2395: {
                   2396:   int comparison_operator = 0;
                   2397:   RTX_CODE code;
                   2398:   struct attr_desc *attr;
                   2399: 
                   2400:   /* In order not to worry about operator precedence, surround our part of
                   2401:      the expression with parentheses.  */
                   2402: 
                   2403:   printf ("(");
                   2404:   code = GET_CODE (exp);
                   2405:   switch (code)
                   2406:     {
                   2407:     /* Binary operators.  */
                   2408:     case EQ: case NE:
                   2409:     case GE: case GT: case GEU: case GTU:
                   2410:     case LE: case LT: case LEU: case LTU:
                   2411:       comparison_operator = 1;
                   2412: 
                   2413:     case PLUS:   case MINUS:  case MULT:     case DIV:      case MOD:
                   2414:     case AND:    case IOR:    case XOR:
                   2415:     case LSHIFT: case ASHIFT: case LSHIFTRT: case ASHIFTRT:
                   2416:       write_test_expr (XEXP (exp, 0), in_comparison || comparison_operator);
                   2417:       switch (code)
                   2418:         {
                   2419:        case EQ:
                   2420:          printf (" == ");
                   2421:          break;
                   2422:        case NE:
                   2423:          printf (" != ");
                   2424:          break;
                   2425:        case GE:
                   2426:          printf (" >= ");
                   2427:          break;
                   2428:        case GT:
                   2429:          printf (" > ");
                   2430:          break;
                   2431:        case GEU:
                   2432:          printf (" >= (unsigned) ");
                   2433:          break;
                   2434:        case GTU:
                   2435:          printf (" > (unsigned) ");
                   2436:          break;
                   2437:        case LE:
                   2438:          printf (" <= ");
                   2439:          break;
                   2440:        case LT:
                   2441:          printf (" < ");
                   2442:          break;
                   2443:        case LEU:
                   2444:          printf (" <= (unsigned) ");
                   2445:          break;
                   2446:        case LTU:
                   2447:          printf (" < (unsigned) ");
                   2448:          break;
                   2449:        case PLUS:
                   2450:          printf (" + ");
                   2451:          break;
                   2452:        case MINUS:
                   2453:          printf (" - ");
                   2454:          break;
                   2455:        case MULT:
                   2456:          printf (" * ");
                   2457:          break;
                   2458:        case DIV:
                   2459:          printf (" / ");
                   2460:          break;
                   2461:        case MOD:
                   2462:          printf (" % ");
                   2463:          break;
                   2464:        case AND:
                   2465:          if (in_comparison)
                   2466:            printf (" & ");
                   2467:          else
                   2468:            printf (" && ");
                   2469:          break;
                   2470:        case IOR:
                   2471:          if (in_comparison)
                   2472:            printf (" | ");
                   2473:          else
                   2474:            printf (" || ");
                   2475:          break;
                   2476:        case XOR:
                   2477:          printf (" ^ ");
                   2478:          break;
                   2479:        case LSHIFT:
                   2480:        case ASHIFT:
                   2481:          printf (" << ");
                   2482:          break;
                   2483:        case LSHIFTRT:
                   2484:        case ASHIFTRT:
                   2485:          printf (" >> ");
                   2486:          break;
                   2487:         }
                   2488: 
                   2489:       write_test_expr (XEXP (exp, 1), in_comparison || comparison_operator);
                   2490:       break;
                   2491: 
                   2492:     case NOT:
                   2493:       /* Special-case (not (eq_attrq "alternative" "x")) */
                   2494:       if (! in_comparison && GET_CODE (XEXP (exp, 0)) == EQ_ATTR
                   2495:          && XSTR (XEXP (exp, 0), 0) == alternative_name)
                   2496:        {
                   2497:          printf ("which_alternative != %s", XSTR (XEXP (exp, 0), 1));
                   2498:          break;
                   2499:        }
                   2500: 
                   2501:       /* Otherwise, fall through to normal unary operator.  */
                   2502: 
                   2503:     /* Unary operators.  */   
                   2504:     case ABS:  case NEG:
                   2505:       switch (code)
                   2506:        {
                   2507:        case NOT:
                   2508:          if (in_comparison)
                   2509:            printf ("~ ");
                   2510:          else
                   2511:            printf ("! ");
                   2512:          break;
                   2513:        case ABS:
                   2514:          printf ("abs ");
                   2515:          break;
                   2516:        case NEG:
                   2517:          printf ("-");
                   2518:          break;
                   2519:        }
                   2520: 
                   2521:       write_test_expr (XEXP (exp, 0), in_comparison);
                   2522:       break;
                   2523: 
                   2524:     /* Comparison test of an attribute with a value.  Most of these will
                   2525:        have been removed by optimization.   Handle "alternative"
                   2526:        specially and give error if EQ_ATTR present inside a comparison.  */
                   2527:     case EQ_ATTR:
                   2528:       if (in_comparison)
                   2529:        fatal ("EQ_ATTR not valid inside comparison");
                   2530: 
                   2531:       if (XSTR (exp, 0) == alternative_name)
                   2532:        {
                   2533:          printf ("which_alternative == %s", XSTR (exp, 1));
                   2534:          break;
                   2535:        }
                   2536: 
                   2537:       attr = find_attr (XSTR (exp, 0), 0);
                   2538:       if (! attr) abort ();
                   2539:       printf ("get_attr_%s (insn) == ", attr->name);
                   2540:       write_attr_valueq (attr, XSTR (exp, 1)); 
                   2541:       break;
                   2542: 
                   2543:     /* See if an operand matches a predicate.  */
                   2544:     case MATCH_OPERAND:
                   2545:       /* If only a mode is given, just ensure the mode matches the operand.
                   2546:         If neither a mode nor predicate is given, error.  */
                   2547:      if (XSTR (exp, 1) == NULL || *XSTR (exp, 1) == '\0')
                   2548:        {
                   2549:          if (GET_MODE (exp) == VOIDmode)
                   2550:            fatal ("Null MATCH_OPERAND specified as test");
                   2551:          else
                   2552:            printf ("GET_MODE (operands[%d]) == %smode",
                   2553:                    XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
                   2554:        }
                   2555:       else
                   2556:        printf ("%s (operands[%d], %smode)",
                   2557:                XSTR (exp, 1), XINT (exp, 0), GET_MODE_NAME (GET_MODE (exp)));
                   2558:       break;
                   2559: 
                   2560:     /* Constant integer. */
                   2561:     case CONST_INT:
                   2562:       printf ("%d", XINT (exp, 0));
                   2563:       break;
                   2564: 
                   2565:     /* A random C expression. */
                   2566:     case SYMBOL_REF:
                   2567:       printf ("%s", XSTR (exp, 0));
                   2568:       break;
                   2569: 
                   2570:     /* The address of the branch target.  */
                   2571:     case MATCH_DUP:
                   2572:       printf ("insn_addresses[INSN_UID (JUMP_LABEL (insn))]");
                   2573:       break;
                   2574: 
                   2575:     /* The address of the current insn.  It would be more consistent with
                   2576:        other usage to make this the address of the NEXT insn, but this gets
                   2577:        too confusing because of the ambiguity regarding the length of the
                   2578:        current insn.  */
                   2579:     case PC:
                   2580:       printf ("insn_current_address");
                   2581:       break;
                   2582: 
                   2583:     default:
                   2584:       fatal ("bad RTX code `%s' in attribute calculation\n",
                   2585:             GET_RTX_NAME (code));
                   2586:     }
                   2587: 
                   2588:   printf (")");
                   2589: }
                   2590: 
                   2591: /* Given an attribute value, return the maximum CONST_STRING argument
                   2592:    encountered.  It is assumed that they are all numeric.  */
                   2593: 
                   2594: static int
                   2595: max_attr_value (exp)
                   2596:      rtx exp;
                   2597: {
                   2598:   int current_max = 0;
                   2599:   int n;
                   2600:   int i;
                   2601: 
                   2602:   if (GET_CODE (exp) == CONST_STRING)
                   2603:     return atoi (XSTR (exp, 0));
                   2604: 
                   2605:   else if (GET_CODE (exp) == COND)
                   2606:     {
                   2607:       for (i = 0; i < XVECLEN (exp, 0); i += 2)
                   2608:        {
                   2609:          n = max_attr_value (XVECEXP (exp, 0, i + 1));
                   2610:          if (n > current_max)
                   2611:            current_max = n;
                   2612:        }
                   2613: 
                   2614:       n = max_attr_value (XEXP (exp, 1));
                   2615:       if (n > current_max)
                   2616:        current_max = n;
                   2617:     }
                   2618: 
                   2619:   else
                   2620:     abort ();
                   2621: 
                   2622:   return current_max;
                   2623: }
                   2624: 
                   2625: /* Scan an attribute value, possibly a conditional, and record what actions
                   2626:    will be required to do any conditional tests in it.
                   2627: 
                   2628:    Specifically, set
                   2629:        `must_extract'    if we need to extract the insn operands
                   2630:        `must_constrain'  if we must compute `which_alternative'
                   2631:        `address_used'    if an address expression was used
                   2632:  */
                   2633: 
                   2634: static void
                   2635: walk_attr_value (exp)
                   2636:      rtx exp;
                   2637: {
                   2638:   register int i, j;
                   2639:   register char *fmt;
                   2640:   RTX_CODE code;
                   2641: 
                   2642:   if (exp == NULL)
                   2643:     return;
                   2644: 
                   2645:   code = GET_CODE (exp);
                   2646:   switch (code)
                   2647:     {
                   2648:     case SYMBOL_REF:
                   2649:       /* Since this is an arbitrary expression, it can look at anything. */
                   2650:       must_extract = must_constrain = 1;
                   2651:       return;
                   2652: 
                   2653:     case MATCH_OPERAND:
                   2654:       must_extract = 1;
                   2655:       return;
                   2656: 
                   2657:     case EQ_ATTR:
                   2658:       if (XSTR (exp, 0) == alternative_name)
                   2659:        must_extract = must_constrain = 1;
                   2660:       return;
                   2661: 
                   2662:     case MATCH_DUP:
                   2663:     case PC:
                   2664:       address_used = 1;
                   2665:       return;
                   2666:     }
                   2667: 
                   2668:   for (i = 0, fmt = GET_RTX_FORMAT (code); i < GET_RTX_LENGTH (code); i++)
                   2669:     switch (*fmt++)
                   2670:       {
                   2671:       case 'e':
                   2672:       case 'u':
                   2673:        walk_attr_value (XEXP (exp, i));
                   2674:        break;
                   2675: 
                   2676:       case 'E':
                   2677:        if (XVEC (exp, i) != NULL)
                   2678:          for (j = 0; j < XVECLEN (exp, i); j++)
                   2679:            walk_attr_value (XVECEXP (exp, i, j));
                   2680:        break;
                   2681:       }
                   2682: }
                   2683: 
                   2684: /* Write out a function to obtain the attribute for a given INSN.  */
                   2685: 
                   2686: static void
                   2687: write_attr_get (attr)
                   2688:      struct attr_desc *attr;
                   2689: {
                   2690:   struct attr_value *av, *common_av;
                   2691: 
                   2692:   /* Find the most used attribute value.  Handle that as the `default' of the
                   2693:      switch we will generate. */
                   2694:   common_av = find_most_used (attr);
                   2695: 
                   2696:   /* Write out start of function, then all values with explicit `case' lines,
                   2697:      then a `default', then the value with the most uses.  */
                   2698:   if (attr->is_numeric)
                   2699:     printf ("int\n");
                   2700:   else
                   2701:     printf ("enum attr_%s\n", attr->name);
                   2702: 
                   2703:   /* If the attribute name starts with a star, the remainder is the name of
                   2704:      the subroutine to use, instead of `get_attr_...'.  */
                   2705:   if (attr->name[0] == '*')
                   2706:     printf ("%s (insn)\n", &attr->name[1]);
                   2707:   else
                   2708:     printf ("get_attr_%s (insn)\n", attr->name);
                   2709:   printf ("     rtx insn;\n");
                   2710:   printf ("{\n");
                   2711:   printf ("  switch (recog_memoized (insn))\n");
                   2712:   printf ("    {\n");
                   2713: 
                   2714:   for (av = attr->first_value; av; av = av->next)
                   2715:     if (av != common_av)
                   2716:       write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
                   2717: 
                   2718:   write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
                   2719:   printf ("    }\n}\n\n");
                   2720: }
                   2721: 
                   2722: /* Given an AND tree of known true terms (because we are inside an `if' with
                   2723:    that as the condition or are in an `else' clause) and an expression,
                   2724:    replace any known true terms with TRUE.  Use `simplify_and_tree' to do
                   2725:    the bulk of the work.  */
                   2726: 
                   2727: static rtx
                   2728: eliminate_known_true (known_true, exp, insn_code, insn_index)
                   2729:      rtx known_true;
                   2730:      rtx exp;
                   2731:      int insn_code, insn_index;
                   2732: {
                   2733:   rtx term;
                   2734: 
                   2735:   known_true = SIMPLIFY_TEST_EXP (known_true, insn_code, insn_index);
                   2736: 
                   2737:   if (GET_CODE (known_true) == AND)
                   2738:     {
                   2739:       exp = eliminate_known_true (XEXP (known_true, 0), exp,
                   2740:                                  insn_code, insn_index);
                   2741:       exp = eliminate_known_true (XEXP (known_true, 1), exp,
                   2742:                                  insn_code, insn_index);
                   2743:     }
                   2744:   else
                   2745:     {
                   2746:       term = known_true;
                   2747:       exp = simplify_and_tree (exp, &term, insn_code, insn_index);
                   2748:     }
                   2749: 
                   2750:   return exp;
                   2751: }
                   2752: 
                   2753: /* Write out a series of tests and assignment statements to perform tests and
                   2754:    sets of an attribute value.  We are passed an indentation amount and prefix
                   2755:    and suffix strings to write around each attribute value (e.g., "return"
                   2756:    and ";").  */
                   2757: 
                   2758: static void
                   2759: write_attr_set (attr, indent, value, prefix, suffix, known_true,
                   2760:                insn_code, insn_index)
                   2761:      struct attr_desc *attr;
                   2762:      int indent;
                   2763:      rtx value;
                   2764:      char *prefix;
                   2765:      char *suffix;
                   2766:      rtx known_true;
                   2767:      int insn_code, insn_index;
                   2768: {
                   2769:   if (GET_CODE (value) == CONST_STRING)
                   2770:     {
                   2771:       write_indent (indent);
                   2772:       printf ("%s ", prefix);
                   2773:       write_attr_value (attr, value);
                   2774:       printf ("%s\n", suffix);
                   2775:     }
                   2776:   else if (GET_CODE (value) == COND)
                   2777:     {
                   2778:       /* Assume the default value will be the default of the COND unless we
                   2779:         find an always true expression.  */
                   2780:       rtx default_val = XEXP (value, 1);
                   2781:       rtx our_known_true = known_true;
                   2782:       rtx newexp;
                   2783:       int first_if = 1;
                   2784:       int i;
                   2785: 
                   2786:       for (i = 0; i < XVECLEN (value, 0); i += 2)
                   2787:        {
                   2788:          rtx testexp;
                   2789:          rtx inner_true;
                   2790: 
                   2791:          testexp = eliminate_known_true (our_known_true,
                   2792:                                          XVECEXP (value, 0, i),
                   2793:                                          insn_code, insn_index);
                   2794:          newexp = rtx_alloc (NOT);
                   2795:          XEXP (newexp, 0) = testexp;
                   2796:          newexp  = insert_right_side (AND, our_known_true, newexp,
                   2797:                                       insn_code, insn_index);
                   2798: 
                   2799:          /* If the test expression is always true or if the next `known_true'
                   2800:             expression is always false, this is the last case, so break
                   2801:             out and let this value be the `else' case.  */
                   2802:          if (testexp == true_rtx || newexp == false_rtx)
                   2803:            {
                   2804:              default_val = XVECEXP (value, 0, i + 1);
                   2805:              break;
                   2806:            }
                   2807: 
                   2808:          /* Compute the expression to pass to our recursive call as being
                   2809:             known true.  */
                   2810:          inner_true = insert_right_side (AND, our_known_true,
                   2811:                                          testexp, insn_code, insn_index);
                   2812: 
                   2813:          /* If this is always false, skip it.  */
                   2814:          if (inner_true == false_rtx)
                   2815:            continue;
                   2816: 
                   2817:          write_indent (indent);
                   2818:          printf ("%sif ", first_if ? "" : "else ");
                   2819:          first_if = 0;
                   2820:          write_test_expr (testexp, 0);
                   2821:          printf ("\n");
                   2822:          write_indent (indent + 2);
                   2823:          printf ("{\n");
                   2824: 
                   2825:          write_attr_set (attr, indent + 4,  
                   2826:                          XVECEXP (value, 0, i + 1), prefix, suffix,
                   2827:                          inner_true, insn_code, insn_index);
                   2828:          write_indent (indent + 2);
                   2829:          printf ("}\n");
                   2830:          our_known_true = newexp;
                   2831:        }
                   2832: 
                   2833:       if (! first_if)
                   2834:        {
                   2835:          write_indent (indent);
                   2836:          printf ("else\n");
                   2837:          write_indent (indent + 2);
                   2838:          printf ("{\n");
                   2839:        }
                   2840: 
                   2841:       write_attr_set (attr, first_if ? indent : indent + 4, default_val,
                   2842:                      prefix, suffix, our_known_true, insn_code, insn_index);
                   2843: 
                   2844:       if (! first_if)
                   2845:        {
                   2846:          write_indent (indent + 2);
                   2847:          printf ("}\n");
                   2848:        }
                   2849:     }
                   2850:   else
                   2851:     abort ();
                   2852: }
                   2853: 
                   2854: /* Write out the computation for one attribute value.  */
                   2855: 
                   2856: static void
                   2857: write_attr_case (attr, av, write_case_lines, prefix, suffix, indent, known_true)
                   2858:      struct attr_desc *attr;
                   2859:      struct attr_value *av;
                   2860:      int write_case_lines;
                   2861:      char *prefix, *suffix;
                   2862:      int indent;
                   2863:      rtx known_true;
                   2864: {
                   2865:   struct insn_ent *ie;
                   2866: 
                   2867:   if (av->num_insns == 0)
                   2868:     return;
                   2869: 
                   2870:   if (av->has_asm_insn)
                   2871:     {
                   2872:       write_indent (indent);
                   2873:       printf ("case -1:\n");
                   2874:       write_indent (indent + 2);
                   2875:       printf ("if (GET_CODE (PATTERN (insn)) != ASM_INPUT\n");
                   2876:       write_indent (indent + 2);
                   2877:       printf ("    && asm_noperands (PATTERN (insn)) < 0)\n");
                   2878:       write_indent (indent + 2);
                   2879:       printf ("  fatal_insn_not_found (insn);\n");
                   2880:     }
                   2881: 
                   2882:   if (write_case_lines)
                   2883:     {
                   2884:       for (ie = av->first_insn; ie; ie = ie->next)
                   2885:        if (ie->insn_code != -1)
                   2886:          {
                   2887:            write_indent (indent);
                   2888:            printf ("case %d:\n", ie->insn_code);
                   2889:          }
                   2890:     }
                   2891:   else
                   2892:     {
                   2893:       write_indent (indent);
                   2894:       printf ("default:\n");
                   2895:     }
                   2896: 
                   2897:   /* See what we have to do to handle output this value.  */
                   2898:   must_extract = must_constrain = address_used = 0;
                   2899:   walk_attr_value (av->value);
                   2900: 
                   2901:   if (must_extract)
                   2902:     {
                   2903:       write_indent (indent + 2);
                   2904:       printf ("insn_extract (insn);\n");
                   2905:     }
                   2906: 
                   2907:   if (must_constrain)
                   2908:     {
                   2909: #ifdef REGISTER_CONSTRAINTS
                   2910:       write_indent (indent + 2);
                   2911:       printf ("if (! constrain_operands (INSN_CODE (insn), reload_completed))\n");
                   2912:       write_indent (indent + 2);
                   2913:       printf ("  fatal_insn_not_found (insn);\n");
                   2914: #endif
                   2915:     }
                   2916: 
                   2917:   write_attr_set (attr, indent + 2, av->value, prefix, suffix,
                   2918:                  known_true, av->first_insn->insn_code,
                   2919:                  av->first_insn->insn_index);
                   2920: 
                   2921:   if (strncmp (prefix, "return", 6))
                   2922:     {
                   2923:       write_indent (indent + 2);
                   2924:       printf ("break;\n");
                   2925:     }
                   2926:   printf ("\n");
                   2927: }
                   2928: 
                   2929: /* Utilities to write names in various forms.  */
                   2930: 
                   2931: static void
                   2932: write_attr_valueq (attr, s)
                   2933:      struct attr_desc *attr;
                   2934:      char *s;
                   2935: {
                   2936:   if (attr->is_numeric)
                   2937:     printf ("%s", s);
                   2938:   else
                   2939:     {
                   2940:       write_upcase (attr->name);
                   2941:       printf ("_");
                   2942:       write_upcase (s);
                   2943:     }
                   2944: }
                   2945: 
                   2946: static void
                   2947: write_attr_value (attr, value)
                   2948:      struct attr_desc *attr;
                   2949:      rtx value;
                   2950: {
                   2951:   if (GET_CODE (value) != CONST_STRING)
                   2952:     abort ();
                   2953: 
                   2954:   write_attr_valueq (attr, XSTR (value, 0));
                   2955: }
                   2956: 
                   2957: static void
                   2958: write_upcase (str)
                   2959:      char *str;
                   2960: {
                   2961:   while (*str)
                   2962:     if (*str < 'a' || *str > 'z')
                   2963:       printf ("%c", *str++);
                   2964:     else
                   2965:       printf ("%c", *str++ - 'a' + 'A');
                   2966: }
                   2967: 
                   2968: static void
                   2969: write_indent (indent)
                   2970:      int indent;
                   2971: {
                   2972:   for (; indent > 8; indent -= 8)
                   2973:     printf ("\t");
                   2974: 
                   2975:   for (; indent; indent--)
                   2976:     printf (" ");
                   2977: }
                   2978: 
                   2979: /* Write a subroutine that is given an insn that requires a delay slot, a
                   2980:    delay slot ordinal, and a candidate insn.  It returns non-zero if the
                   2981:    candidate can be placed in the specified delay slot of the insn.
                   2982: 
                   2983:    We can write as many as three subroutines.  `eligible_for_delay'
                   2984:    handles normal delay slots, `eligible_for_annul_true' indicates that
                   2985:    the specified insn can be annulled if the branch is true, and likewise
                   2986:    for `eligible_for_annul_false'.
                   2987: 
                   2988:    KIND is a string distingushing these three cases ("delay", "annul_true",
                   2989:    or "annul_false").  */
                   2990: 
                   2991: static void
                   2992: write_eligible_delay (kind)
                   2993:      char *kind;
                   2994: {
                   2995:   struct delay_desc *delay;
                   2996:   int max_slots;
                   2997:   char str[50];
                   2998:   struct attr_desc *attr;
                   2999:   struct attr_value *av, *common_av;
                   3000:   int i;
                   3001: 
                   3002:   /* Compute the maximum number of delay slots required.  We use the delay
                   3003:      ordinal times this number plus one, plus the slot number as an index into
                   3004:      the appropriate predicate to test.  */
                   3005: 
                   3006:   for (delay = delays, max_slots = 0; delay; delay = delay->next)
                   3007:     if (XVECLEN (delay->def, 1) / 3 > max_slots)
                   3008:       max_slots = XVECLEN (delay->def, 1) / 3;
                   3009: 
                   3010:   /* Write function prelude.  */
                   3011: 
                   3012:   printf ("int\n");
                   3013:   printf ("eligible_for_%s (delay_insn, slot, candidate_insn)\n", kind);
                   3014:   printf ("     rtx delay_insn;\n");
                   3015:   printf ("     int slot;\n");
                   3016:   printf ("     rtx candidate_insn;\n");
                   3017:   printf ("{\n");
                   3018:   printf ("  rtx insn;\n");
                   3019:   printf ("\n");
                   3020:   printf ("  if (slot >= %d)\n", max_slots);
                   3021:   printf ("    abort ();\n");
                   3022:   printf ("\n");
                   3023: 
                   3024:   /* If more than one delay type, find out which type the delay insn is.  */
                   3025: 
                   3026:   if (num_delays > 1)
                   3027:     {
                   3028:       sprintf (str, "*delay_type", kind);
                   3029:       attr = find_attr (str, 0);
                   3030:       if (! attr) abort ();
                   3031:       common_av = find_most_used (attr);
                   3032: 
                   3033:       printf ("  insn = delay_insn;\n");
                   3034:       printf ("  switch (recog_memoized (insn))\n");
                   3035:       printf ("    {\n");
                   3036: 
                   3037:       sprintf (str, " * %d;\n      break;", max_slots);
                   3038:       for (av = attr->first_value; av; av = av->next)
                   3039:        if (av != common_av)
                   3040:          write_attr_case (attr, av, 1, "slot +=", str, 4, true_rtx);
                   3041: 
                   3042:       write_attr_case (attr, common_av, 0, "slot +=", str, 4, true_rtx);
                   3043:       printf ("    }\n\n");
                   3044: 
                   3045:       /* Ensure matched.  Otherwise, shouldn't have been called.  */
                   3046:       printf ("  if (slot < %d)\n", max_slots);
                   3047:       printf ("    abort ();\n\n");
                   3048:     }
                   3049: 
                   3050:   /* If just one type of delay slot, write simple switch.  */
                   3051:   if (num_delays == 1 && max_slots == 1)
                   3052:     {
                   3053:       printf ("  insn = candidate_insn;\n");
                   3054:       printf ("  switch (recog_memoized (insn))\n");
                   3055:       printf ("    {\n");
                   3056: 
                   3057:       attr = find_attr ("*delay_1_0", 0);
                   3058:       if (! attr) abort ();
                   3059:       common_av = find_most_used (attr);
                   3060: 
                   3061:       for (av = attr->first_value; av; av = av->next)
                   3062:        if (av != common_av)
                   3063:          write_attr_case (attr, av, 1, "return", ";", 4, true_rtx);
                   3064: 
                   3065:       write_attr_case (attr, common_av, 0, "return", ";", 4, true_rtx);
                   3066:       printf ("    }\n");
                   3067:     }
                   3068: 
                   3069:   else
                   3070:     {
                   3071:       /* Write a nested CASE.  The first indicates which condition we need to
                   3072:         test, and the inner CASE tests the condition.  */
                   3073:       printf ("  insn = candidate_insn;\n");
                   3074:       printf ("  switch (slot)\n");
                   3075:       printf ("    {\n");
                   3076: 
                   3077:       for (delay = delays; delay; delay = delay->next)
                   3078:        for (i = 0; i < XVECLEN (delay->def, 1); i += 3)
                   3079:          {
                   3080:            printf ("    case %d:\n",
                   3081:                    (i / 3) + (num_delays == 1 ? 0 : delay->num * max_slots));
                   3082:            printf ("      switch (recog_memoized (insn))\n");
                   3083:            printf ("\t{\n");
                   3084: 
                   3085:            sprintf (str, "*%s_%d_%d", kind, delay->num, i / 3);
                   3086:            attr = find_attr (str, 0);
                   3087:            if (! attr) abort ();
                   3088:            common_av = find_most_used (attr);
                   3089: 
                   3090:            for (av = attr->first_value; av; av = av->next)
                   3091:              if (av != common_av)
                   3092:                write_attr_case (attr, av, 1, "return", ";", 8, true_rtx);
                   3093: 
                   3094:            write_attr_case (attr, common_av, 0, "return", ";", 8, true_rtx);
                   3095:            printf ("      }\n");
                   3096:          }
                   3097: 
                   3098:       printf ("    default:\n");
                   3099:       printf ("      abort ();\n");     
                   3100:       printf ("    }\n");
                   3101:     }
                   3102: 
                   3103:   printf ("}\n\n");
                   3104: }
                   3105: 
                   3106: /* Write routines to compute conflict cost for function units.  Then write a
                   3107:    table describing the available function units.  */
                   3108: 
                   3109: static void
                   3110: write_function_unit_info ()
                   3111: {
                   3112:   struct function_unit *unit;
                   3113:   struct attr_desc *case_attr, *attr;
                   3114:   struct attr_value *av, *common_av;
                   3115:   rtx value;
                   3116:   char *str;
                   3117:   int using_case;
                   3118:   int i;
                   3119: 
                   3120:   /* Write out conflict routines for function units.  Don't bother writing
                   3121:      one if there is only one busy value.  */
                   3122: 
                   3123:   for (unit = units; unit; unit = unit->next)
                   3124:     {
                   3125:       /* See if only one case exists and if there is a constant value for
                   3126:         that case.  If so, we don't need a function.  */
                   3127:       str = (char *) xmalloc (strlen (unit->name) + 10);
                   3128:       sprintf (str, "*%s_cases", unit->name);
                   3129:       attr = find_attr (str, 0);
                   3130:       if (! attr) abort ();
                   3131:       value = find_single_value (attr);
                   3132:       if (value && GET_CODE (value) == CONST_STRING)
                   3133:        {
                   3134:          sprintf (str, "*%s_case_%s", unit->name, XSTR (value, 0));
                   3135:          attr = find_attr (str, 0);
                   3136:          if (! attr) abort ();
                   3137:          value = find_single_value (attr);
                   3138:          if (value && GET_CODE (value) == CONST_STRING)
                   3139:            {
                   3140:              unit->needs_conflict_function = 0;
                   3141:              unit->default_cost = value;
                   3142:              continue;
                   3143:            }
                   3144:        }
                   3145: 
                   3146:       /* The function first computes the case from the candidate insn.  */
                   3147:       unit->needs_conflict_function = 1;
                   3148:       unit->default_cost = make_numeric_value (0);
                   3149: 
                   3150:       printf ("static int\n");
                   3151:       printf ("%s_unit_conflict_cost (executing_insn, candidate_insn)\n",
                   3152:              unit->name);
                   3153:       printf ("     rtx executing_insn;\n");
                   3154:       printf ("     rtx candidate_insn;\n");
                   3155:       printf ("{\n");
                   3156:       printf ("  rtx insn;\n");
                   3157:       printf ("  int casenum;\n\n");
                   3158:       printf ("  insn = candidate_insn;\n");
                   3159:       printf ("  switch (recog_memoized (insn))\n");
                   3160:       printf ("    {\n");
                   3161: 
                   3162:       /* Write the `switch' statement to get the case value.  */
                   3163:       sprintf (str, "*%s_cases", unit->name);
                   3164:       case_attr = find_attr (str, 0);
                   3165:       if (! case_attr) abort ();
                   3166:       common_av = find_most_used (case_attr);
                   3167: 
                   3168:       for (av = case_attr->first_value; av; av = av->next)
                   3169:        if (av != common_av)
                   3170:          write_attr_case (case_attr, av, 1,
                   3171:                           "casenum =", ";", 4, unit->condexp);
                   3172: 
                   3173:       write_attr_case (case_attr, common_av, 0,
                   3174:                       "casenum =", ";", 4, unit->condexp);
                   3175:       printf ("    }\n\n");
                   3176: 
                   3177:       /* Now write an outer switch statement on each case.  Then write
                   3178:         the tests on the executing function within each.  */
                   3179:       printf ("  insn = executing_insn;\n");
                   3180:       printf ("  switch (casenum)\n");
                   3181:       printf ("    {\n");
                   3182: 
                   3183:       for (i = 0; i < unit->num_opclasses; i++)
                   3184:        {
                   3185:          /* Ensure using this case.  */
                   3186:          using_case = 0;
                   3187:          for (av = case_attr->first_value; av; av = av->next)
                   3188:            if (av->num_insns
                   3189:                && contained_in_p (make_numeric_value (i), av->value))
                   3190:              using_case = 1;
                   3191: 
                   3192:          if (! using_case)
                   3193:            continue;
                   3194: 
                   3195:          printf ("    case %d:\n", i);
                   3196:          sprintf (str, "*%s_case_%d", unit->name, i);
                   3197:          attr = find_attr (str, 0);
                   3198:          if (! attr) abort ();
                   3199: 
                   3200:          /* If single value, just write it.  */
                   3201:          value = find_single_value (attr);
                   3202:          if (value)
                   3203:            write_attr_set (attr, 6, value, "return", ";\n", true_rtx, -2);
                   3204:          else
                   3205:            {
                   3206:              common_av = find_most_used (attr);
                   3207:              printf ("      switch (recog_memoized (insn))\n");
                   3208:              printf ("\t{\n");
                   3209: 
                   3210:              for (av = attr->first_value; av; av = av->next)
                   3211:                if (av != common_av)
                   3212:                  write_attr_case (attr, av, 1,
                   3213:                                   "return", ";", 8, unit->condexp);
                   3214: 
                   3215:              write_attr_case (attr, common_av, 0,
                   3216:                               "return", ";", 8, unit->condexp);
                   3217:              printf ("      }\n\n");
                   3218:            }
                   3219:        }
                   3220: 
                   3221:       printf ("    }\n}\n\n");
                   3222:     }
                   3223: 
                   3224:   /* Now that all functions have been written, write the table describing
                   3225:      the function units.   The name is included for documenation purposes
                   3226:      only.  */
                   3227: 
                   3228:   printf ("struct function_unit_desc function_units[] = {\n");
                   3229: 
                   3230:   for (unit = units; unit; unit = unit->next)
                   3231:     {
                   3232:       printf ("  {\"%s\", %d, %d, %d, %s, %s_unit_ready_cost, ",
                   3233:              unit->name, 1 << unit->num, unit->multiplicity,
                   3234:              unit->simultaneity, XSTR (unit->default_cost, 0), unit->name);
                   3235: 
                   3236:       if (unit->needs_conflict_function)
                   3237:        printf ("%s_unit_conflict_cost", unit->name);
                   3238:       else
                   3239:        printf ("0");
                   3240: 
                   3241:       printf ("}, \n");
                   3242:     }
                   3243: 
                   3244:   printf ("};\n\n");
                   3245: }
                   3246: 
                   3247: /* This page contains miscellaneous utility routines.  */
                   3248: 
                   3249: /* Given a string, return the number of comma-separated elements in it.
                   3250:    Return 0 for the null string.  */
                   3251: 
                   3252: static int
                   3253: n_comma_elts (s)
                   3254:      char *s;
                   3255: {
                   3256:   int n;
                   3257: 
                   3258:   if (*s == '\0')
                   3259:     return 0;
                   3260: 
                   3261:   for (n = 1; *s; s++)
                   3262:     if (*s == ',')
                   3263:       n++;
                   3264: 
                   3265:   return n;
                   3266: }
                   3267: 
                   3268: /* Given a pointer to a (char *), return a malloc'ed string containing the
                   3269:    next comma-separated element.  Advance the pointer to after the string
                   3270:    scanned, or the end-of-string.  Return NULL if at end of string.  */
                   3271: 
                   3272: static char *
                   3273: next_comma_elt (pstr)
                   3274:      char **pstr;
                   3275: {
                   3276:   char *out_str;
                   3277:   char *p;
                   3278: 
                   3279:   if (**pstr == '\0')
                   3280:     return NULL;
                   3281: 
                   3282:   /* Find end of string to compute length.  */
                   3283:   for (p = *pstr; *p != ',' && *p != '\0'; p++)
                   3284:     ;
                   3285: 
                   3286:   out_str = (char *) xmalloc (p - *pstr + 1);
                   3287:   for (p = out_str; **pstr != ',' && **pstr != '\0'; (*pstr)++)
                   3288:     *p++ = **pstr;
                   3289: 
                   3290:   *p++ = '\0';
                   3291:   if (**pstr == ',')
                   3292:     (*pstr)++;
                   3293: 
                   3294:   return out_str;
                   3295: }
                   3296: 
                   3297: /* Return a `struct attr_desc' pointer for a given named attribute.  If CREATE
                   3298:    is non-zero, build a new attribute, if one does not exist.  */
                   3299: 
                   3300: static struct attr_desc *
                   3301: find_attr (name, create)
                   3302:      char *name;
                   3303:      int create;
                   3304: {
                   3305:   struct attr_desc *attr;
                   3306:   char *new_name;
                   3307: 
                   3308:   /* Before we resort to using `strcmp', see if the string address matches
                   3309:      anywhere.  In most cases, it should have been canonicalized to do so.  */
                   3310:   if (name == alternative_name)
                   3311:     return NULL;
                   3312: 
                   3313:   for (attr = attrs; attr; attr = attr->next)
                   3314:     if (name == attr->name)
                   3315:       return attr;
                   3316: 
                   3317:   /* Otherwise, do it the slow way.  */
                   3318:   for (attr = attrs; attr; attr = attr->next)
                   3319:     if (! strcmp (name, attr->name))
                   3320:       return attr;
                   3321: 
                   3322:   if (! create)
                   3323:     return NULL;
                   3324: 
                   3325:   new_name = (char *) xmalloc (strlen (name) + 1);
                   3326:   strcpy (new_name, name);
                   3327: 
                   3328:   attr = (struct attr_desc *) xmalloc (sizeof (struct attr_desc));
                   3329:   attr->name = new_name;
                   3330:   attr->first_value = attr->default_val = NULL;
                   3331:   attr->is_numeric = attr->is_special = 0;
                   3332:   attr->next = attrs;
                   3333:   attrs = attr;
                   3334: 
                   3335:   return attr;
                   3336: }
                   3337: 
                   3338: /* Create internal attribute with the given default value.  */
                   3339: 
                   3340: static void
                   3341: make_internal_attr (name, value, special)
                   3342:      char *name;
                   3343:      rtx value;
                   3344:      int special;
                   3345: {
                   3346:   struct attr_desc *attr;
                   3347: 
                   3348:   attr = find_attr (name, 1);
                   3349:   if (attr->default_val)
                   3350:     abort ();
                   3351: 
                   3352:   attr->is_numeric = 1;
                   3353:   attr->is_special = special;
                   3354:   attr->default_val = get_attr_value (value, attr, -2);
                   3355: }
                   3356: 
                   3357: /* Find the most used value of an attribute.  */
                   3358: 
                   3359: static struct attr_value *
                   3360: find_most_used (attr)
                   3361:      struct attr_desc *attr;
                   3362: {
                   3363:   struct attr_value *av;
                   3364:   struct attr_value *most_used;
                   3365:   int nuses;
                   3366: 
                   3367:   most_used = NULL;
                   3368:   nuses = -1;
                   3369: 
                   3370:   for (av = attr->first_value; av; av = av->next)
                   3371:     if (av->num_insns > nuses)
                   3372:       nuses = av->num_insns, most_used = av;
                   3373: 
                   3374:   return most_used;
                   3375: }
                   3376: 
                   3377: /* If an attribute only has a single value used, return it.  Otherwise
                   3378:    return NULL.  */
                   3379: 
                   3380: static rtx
                   3381: find_single_value (attr)
                   3382:      struct attr_desc *attr;
                   3383: {
                   3384:   struct attr_value *av;
                   3385:   rtx unique_value;
                   3386: 
                   3387:   unique_value = NULL;
                   3388:   for (av = attr->first_value; av; av = av->next)
                   3389:     if (av->num_insns)
                   3390:       {
                   3391:        if (unique_value)
                   3392:          return NULL;
                   3393:        else
                   3394:          unique_value = av->value;
                   3395:       }
                   3396: 
                   3397:   return unique_value;
                   3398: }
                   3399: 
                   3400: /* Return (attr_value "n") */
                   3401: 
                   3402: static rtx
                   3403: make_numeric_value (n)
                   3404:      int n;
                   3405: {
                   3406:   static rtx int_values[20];
                   3407:   rtx exp;
                   3408: 
                   3409:   if (n < 0)
                   3410:     abort ();
                   3411: 
                   3412:   if (n < 20 && int_values[n])
                   3413:     return int_values[n];
                   3414: 
                   3415:   exp = rtx_alloc (CONST_STRING);
                   3416:   XSTR (exp, 0) = (char *) xmalloc ((n < 1000 ? 4
                   3417:                                     : HOST_BITS_PER_INT * 3 / 10 + 3));
                   3418:   sprintf (XSTR (exp, 0), "%d", n);
                   3419: 
                   3420:   if (n < 20)
                   3421:     int_values[n] = exp;
                   3422: 
                   3423:   return exp;
                   3424: }
                   3425: 
                   3426: char *
                   3427: xrealloc (ptr, size)
                   3428:      char *ptr;
                   3429:      unsigned size;
                   3430: {
                   3431:   char *result = (char *) realloc (ptr, size);
                   3432:   if (!result)
                   3433:     fatal ("virtual memory exhausted");
                   3434:   return result;
                   3435: }
                   3436: 
                   3437: char *
                   3438: xmalloc (size)
                   3439:      unsigned size;
                   3440: {
                   3441:   register char *val = (char *) malloc (size);
                   3442: 
                   3443:   if (val == 0)
                   3444:     fatal ("virtual memory exhausted");
                   3445:   return val;
                   3446: }
                   3447: 
                   3448: static void
                   3449: fatal (s, a1, a2)
                   3450:      char *s;
                   3451: {
                   3452:   fprintf (stderr, "genattrtab: ");
                   3453:   fprintf (stderr, s, a1, a2);
                   3454:   fprintf (stderr, "\n");
                   3455:   exit (FATAL_EXIT_CODE);
                   3456: }
                   3457: 
                   3458: /* More 'friendly' abort that prints the line and file.
                   3459:    config.h can #define abort fancy_abort if you like that sort of thing.  */
                   3460: 
                   3461: void
                   3462: fancy_abort ()
                   3463: {
                   3464:   fatal ("Internal gcc abort.");
                   3465: }
                   3466: 
                   3467: int
                   3468: main (argc, argv)
                   3469:      int argc;
                   3470:      char **argv;
                   3471: {
                   3472:   rtx desc;
                   3473:   FILE *infile;
                   3474:   extern rtx read_rtx ();
                   3475:   register int c;
                   3476:   struct attr_desc *attr;
                   3477:   struct attr_value *av;
                   3478:   struct insn_def *id;
                   3479:   rtx tem;
                   3480: 
                   3481:   obstack_init (rtl_obstack);
                   3482: 
                   3483:   if (argc <= 1)
                   3484:     fatal ("No input file name.");
                   3485: 
                   3486:   infile = fopen (argv[1], "r");
                   3487:   if (infile == 0)
                   3488:     {
                   3489:       perror (argv[1]);
                   3490:       exit (FATAL_EXIT_CODE);
                   3491:     }
                   3492: 
                   3493:   init_rtl ();
                   3494: 
                   3495:   /* Set up true and false rtx's */
                   3496:   true_rtx = rtx_alloc (CONST_INT);
                   3497:   false_rtx = rtx_alloc (CONST_INT);
                   3498:   XINT (true_rtx, 0) = 1;
                   3499:   XINT (false_rtx, 0) = 0;
                   3500:   RTX_UNCHANGING_P (true_rtx) = RTX_UNCHANGING_P (false_rtx) = 1;
                   3501: 
                   3502:   printf ("/* Generated automatically by the program `genattrtab'\n\
                   3503: from the machine description file `md'.  */\n\n");
                   3504: 
                   3505:   /* Read the machine description.  */
                   3506: 
                   3507:   while (1)
                   3508:     {
                   3509:       c = read_skip_spaces (infile);
                   3510:       if (c == EOF)
                   3511:        break;
                   3512:       ungetc (c, infile);
                   3513: 
                   3514:       desc = read_rtx (infile);
                   3515:       if (GET_CODE (desc) == DEFINE_INSN
                   3516:          || GET_CODE (desc) == DEFINE_PEEPHOLE
                   3517:          || GET_CODE (desc) == DEFINE_ASM_ATTRIBUTES)
                   3518:        gen_insn (desc);
                   3519: 
                   3520:       else if (GET_CODE (desc) == DEFINE_EXPAND)
                   3521:        insn_code_number++, insn_index_number++;
                   3522: 
                   3523:       else if (GET_CODE (desc) == DEFINE_SPLIT)
                   3524:        insn_code_number++, insn_index_number++;
                   3525: 
                   3526:       else if (GET_CODE (desc) == DEFINE_ATTR)
                   3527:        {
                   3528:          gen_attr (desc);
                   3529:          insn_index_number++;
                   3530:        }
                   3531: 
                   3532:       else if (GET_CODE (desc) == DEFINE_DELAY)
                   3533:        {
                   3534:          gen_delay (desc);
                   3535:          insn_index_number++;
                   3536:        }
                   3537: 
                   3538:       else if (GET_CODE (desc) == DEFINE_FUNCTION_UNIT)
                   3539:        {
                   3540:          gen_unit (desc);
                   3541:          insn_index_number++;
                   3542:        }
                   3543:     }
                   3544: 
                   3545:   /* If we didn't have a DEFINE_ASM_ATTRIBUTES, make a null one.  */
                   3546:   if (! got_define_asm_attributes)
                   3547:     {
                   3548:       tem = rtx_alloc (DEFINE_ASM_ATTRIBUTES);
                   3549:       XVEC (tem, 0) = rtvec_alloc (0);
                   3550:       gen_insn (tem);
                   3551:     }
                   3552: 
                   3553:   /* Expand DEFINE_DELAY information into new attribute.  */
                   3554:   if (num_delays)
                   3555:     expand_delays ();
                   3556: 
                   3557:   /* Expand DEFINE_FUNCTION_UNIT information into new attributes.  */
                   3558:   if (num_units)
                   3559:     expand_units ();
                   3560: 
                   3561:   printf ("#include \"config.h\"\n");
                   3562:   printf ("#include \"rtl.h\"\n");
                   3563:   printf ("#include \"insn-config.h\"\n");
                   3564:   printf ("#include \"recog.h\"\n");
                   3565:   printf ("#include \"regs.h\"\n");
                   3566:   printf ("#include \"real.h\"\n");
                   3567:   printf ("#include \"output.h\"\n");
                   3568:   printf ("#include \"insn-attr.h\"\n");
                   3569:   printf ("\n");  
                   3570:   printf ("#define operands recog_operand\n\n");
                   3571: 
                   3572:   /* Make `insn_alternatives'.  */
                   3573:   insn_alternatives = (int *) xmalloc (insn_code_number * sizeof (int));
                   3574:   for (id = defs; id; id = id->next)
                   3575:     if (id->insn_code >= 0)
                   3576:       insn_alternatives[id->insn_code] = (1 << id->num_alternatives) - 1;
                   3577: 
                   3578:   /* Prepare to write out attribute subroutines by checking everything stored
                   3579:      away and building the attribute cases.  */
                   3580: 
                   3581:   check_defs ();
                   3582:   for (attr = attrs; attr; attr = attr->next)
                   3583:     {
                   3584:       check_attr_value (attr->default_val->value, attr);
                   3585:       fill_attr (attr);
                   3586:     }
                   3587: 
                   3588:   /* Construct extra attributes for `length'.  */
                   3589:   make_length_attrs ();
                   3590: 
                   3591:   /* Perform any possible optimizations to speed up compilation. */
                   3592:   optimize_attrs ();
                   3593: 
                   3594:   /* Now write out all the `gen_attr_...' routines.  Do these before the
                   3595:      special routines (specifically before write_function_unit_info), so
                   3596:      that they get defined before they are used.  */
                   3597: 
                   3598:   for (attr = attrs; attr; attr = attr->next)
                   3599:     {
                   3600:       if (! attr->is_special)
                   3601:        write_attr_get (attr);
                   3602:     }
                   3603: 
                   3604:   /* Write out delay eligibility information, if DEFINE_DELAY present.
                   3605:      (The function to compute the number of delay slots will be written
                   3606:      below.)  */
                   3607:   if (num_delays)
                   3608:     {
                   3609:       write_eligible_delay ("delay");
                   3610:       if (have_annul_true)
                   3611:        write_eligible_delay ("annul_true");
                   3612:       if (have_annul_false)
                   3613:        write_eligible_delay ("annul_false");
                   3614:     }
                   3615: 
                   3616:   /* Write out information about function units.  */
                   3617:   if (num_units)
                   3618:     write_function_unit_info ();
                   3619: 
                   3620:   fflush (stdout);
                   3621:   exit (ferror (stdout) != 0 ? FATAL_EXIT_CODE : SUCCESS_EXIT_CODE);
                   3622:   /* NOTREACHED */
                   3623:   return 0;
                   3624: }

unix.superglobalmegacorp.com

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