Annotation of GNUtools/cc/recog.c, revision 1.1.1.1

1.1       root        1: /* Subroutines used by or related to instruction recognition.
                      2:    Copyright (C) 1987, 1988, 1991, 1992, 1993 Free Software Foundation, Inc.
                      3: 
                      4: This file is part of GNU CC.
                      5: 
                      6: GNU CC is free software; you can redistribute it and/or modify
                      7: it under the terms of the GNU General Public License as published by
                      8: the Free Software Foundation; either version 2, or (at your option)
                      9: any later version.
                     10: 
                     11: GNU CC is distributed in the hope that it will be useful,
                     12: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     14: GNU General Public License for more details.
                     15: 
                     16: You should have received a copy of the GNU General Public License
                     17: along with GNU CC; see the file COPYING.  If not, write to
                     18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
                     19: 
                     20: 
                     21: #include "config.h"
                     22: #include "rtl.h"
                     23: #include <stdio.h>
                     24: #include "insn-config.h"
                     25: #include "insn-attr.h"
                     26: #include "insn-flags.h"
                     27: #include "insn-codes.h"
                     28: #include "recog.h"
                     29: #include "regs.h"
                     30: #include "hard-reg-set.h"
                     31: #include "flags.h"
                     32: #include "real.h"
                     33: 
                     34: #ifndef STACK_PUSH_CODE
                     35: #ifdef STACK_GROWS_DOWNWARD
                     36: #define STACK_PUSH_CODE PRE_DEC
                     37: #else
                     38: #define STACK_PUSH_CODE PRE_INC
                     39: #endif
                     40: #endif
                     41: 
                     42: /* Import from final.c: */
                     43: extern rtx alter_subreg ();
                     44: 
                     45: int strict_memory_address_p ();
                     46: int memory_address_p ();
                     47: 
                     48: /* Nonzero means allow operands to be volatile.
                     49:    This should be 0 if you are generating rtl, such as if you are calling
                     50:    the functions in optabs.c and expmed.c (most of the time).
                     51:    This should be 1 if all valid insns need to be recognized,
                     52:    such as in regclass.c and final.c and reload.c.
                     53: 
                     54:    init_recog and init_recog_no_volatile are responsible for setting this.  */
                     55: 
                     56: int volatile_ok;
                     57: 
                     58: /* On return from `constrain_operands', indicate which alternative
                     59:    was satisfied.  */
                     60: 
                     61: int which_alternative;
                     62: 
                     63: /* Nonzero after end of reload pass.
                     64:    Set to 1 or 0 by toplev.c.
                     65:    Controls the significance of (SUBREG (MEM)).  */
                     66: 
                     67: int reload_completed;
                     68: 
                     69: /* Initialize data used by the function `recog'.
                     70:    This must be called once in the compilation of a function
                     71:    before any insn recognition may be done in the function.  */
                     72: 
                     73: void
                     74: init_recog_no_volatile ()
                     75: {
                     76:   volatile_ok = 0;
                     77: }
                     78: 
                     79: void
                     80: init_recog ()
                     81: {
                     82:   volatile_ok = 1;
                     83: }
                     84: 
                     85: /* Try recognizing the instruction INSN,
                     86:    and return the code number that results.
                     87:    Remeber the code so that repeated calls do not
                     88:    need to spend the time for actual rerecognition.
                     89: 
                     90:    This function is the normal interface to instruction recognition.
                     91:    The automatically-generated function `recog' is normally called
                     92:    through this one.  (The only exception is in combine.c.)  */
                     93: 
                     94: int
                     95: recog_memoized (insn)
                     96:      rtx insn;
                     97: {
                     98:   if (INSN_CODE (insn) < 0)
                     99:     INSN_CODE (insn) = recog (PATTERN (insn), insn, NULL_PTR);
                    100:   return INSN_CODE (insn);
                    101: }
                    102: 
                    103: /* Check that X is an insn-body for an `asm' with operands
                    104:    and that the operands mentioned in it are legitimate.  */
                    105: 
                    106: int
                    107: check_asm_operands (x)
                    108:      rtx x;
                    109: {
                    110:   int noperands = asm_noperands (x);
                    111:   rtx *operands;
                    112:   int i;
                    113: 
                    114:   if (noperands < 0)
                    115:     return 0;
                    116:   if (noperands == 0)
                    117:     return 1;
                    118: 
                    119:   operands = (rtx *) alloca (noperands * sizeof (rtx));
                    120:   decode_asm_operands (x, operands, NULL_PTR, NULL_PTR, NULL_PTR);
                    121: 
                    122:   for (i = 0; i < noperands; i++)
                    123:     if (!general_operand (operands[i], VOIDmode))
                    124:       return 0;
                    125: 
                    126:   return 1;
                    127: }
                    128: 
                    129: /* Static data for the next two routines.
                    130: 
                    131:    The maximum number of changes supported is defined as the maximum
                    132:    number of operands times 5.  This allows for repeated substitutions
                    133:    inside complex indexed address, or, alternatively, changes in up
                    134:    to 5 insns.  */
                    135: 
                    136: #define MAX_CHANGE_LOCS        (MAX_RECOG_OPERANDS * 5)
                    137: 
                    138: static rtx change_objects[MAX_CHANGE_LOCS];
                    139: static int change_old_codes[MAX_CHANGE_LOCS];
                    140: static rtx *change_locs[MAX_CHANGE_LOCS];
                    141: static rtx change_olds[MAX_CHANGE_LOCS];
                    142: 
                    143: static int num_changes = 0;
                    144: 
                    145: /* Validate a proposed change to OBJECT.  LOC is the location in the rtl for
                    146:    at which NEW will be placed.  If OBJECT is zero, no validation is done,
                    147:    the change is simply made.
                    148: 
                    149:    Two types of objects are supported:  If OBJECT is a MEM, memory_address_p
                    150:    will be called with the address and mode as parameters.  If OBJECT is
                    151:    an INSN, CALL_INSN, or JUMP_INSN, the insn will be re-recognized with
                    152:    the change in place.
                    153: 
                    154:    IN_GROUP is non-zero if this is part of a group of changes that must be
                    155:    performed as a group.  In that case, the changes will be stored.  The
                    156:    function `apply_change_group' will validate and apply the changes.
                    157: 
                    158:    If IN_GROUP is zero, this is a single change.  Try to recognize the insn
                    159:    or validate the memory reference with the change applied.  If the result
                    160:    is not valid for the machine, suppress the change and return zero.
                    161:    Otherwise, perform the change and return 1.  */
                    162: 
                    163: int
                    164: validate_change (object, loc, new, in_group)
                    165:     rtx object;
                    166:     rtx *loc;
                    167:     rtx new;
                    168:     int in_group;
                    169: {
                    170:   rtx old = *loc;
                    171: 
                    172:   if (old == new || rtx_equal_p (old, new))
                    173:     return 1;
                    174: 
                    175:   if (num_changes >= MAX_CHANGE_LOCS
                    176:       || (in_group == 0 && num_changes != 0))
                    177:     abort ();
                    178: 
                    179:   *loc = new;
                    180: 
                    181:   /* Save the information describing this change.  */
                    182:   change_objects[num_changes] = object;
                    183:   change_locs[num_changes] = loc;
                    184:   change_olds[num_changes] = old;
                    185: 
                    186:   if (object && GET_CODE (object) != MEM)
                    187:     {
                    188:       /* Set INSN_CODE to force rerecognition of insn.  Save old code in
                    189:         case invalid.  */
                    190:       change_old_codes[num_changes] = INSN_CODE (object);
                    191:       INSN_CODE (object) = -1;
                    192:     }
                    193: 
                    194:   num_changes++;
                    195: 
                    196:   /* If we are making a group of changes, return 1.  Otherwise, validate the
                    197:      change group we made.  */
                    198: 
                    199:   if (in_group)
                    200:     return 1;
                    201:   else
                    202:     return apply_change_group ();
                    203: }
                    204: 
                    205: /* Apply a group of changes previously issued with `validate_change'.
                    206:    Return 1 if all changes are valid, zero otherwise.  */
                    207: 
                    208: int
                    209: apply_change_group ()
                    210: {
                    211:   int i;
                    212: 
                    213:   /* The changes have been applied and all INSN_CODEs have been reset to force
                    214:      rerecognition.
                    215: 
                    216:      The changes are valid if we aren't given an object, or if we are
                    217:      given a MEM and it still is a valid address, or if this is in insn
                    218:      and it is recognized.  In the latter case, if reload has completed,
                    219:      we also require that the operands meet the constraints for
                    220:      the insn.  We do not allow modifying an ASM_OPERANDS after reload
                    221:      has completed because verifying the constraints is too difficult.  */
                    222: 
                    223:   for (i = 0; i < num_changes; i++)
                    224:     {
                    225:       rtx object = change_objects[i];
                    226: 
                    227:       if (object == 0)
                    228:        continue;
                    229: 
                    230:       if (GET_CODE (object) == MEM)
                    231:        {
                    232:          if (! memory_address_p (GET_MODE (object), XEXP (object, 0)))
                    233:            break;
                    234:        }
                    235:       else if ((recog_memoized (object) < 0
                    236:                && (asm_noperands (PATTERN (object)) < 0
                    237:                    || ! check_asm_operands (PATTERN (object))
                    238:                    || reload_completed))
                    239:               || (reload_completed
                    240:                   && (insn_extract (object),
                    241:                       ! constrain_operands (INSN_CODE (object), 1))))
                    242:        {
                    243:          rtx pat = PATTERN (object);
                    244: 
                    245:          /* Perhaps we couldn't recognize the insn because there were
                    246:             extra CLOBBERs at the end.  If so, try to re-recognize
                    247:             without the last CLOBBER (later iterations will cause each of
                    248:             them to be eliminated, in turn).  But don't do this if we
                    249:             have an ASM_OPERAND.  */
                    250:          if (GET_CODE (pat) == PARALLEL
                    251:              && GET_CODE (XVECEXP (pat, 0, XVECLEN (pat, 0) - 1)) == CLOBBER
                    252:              && asm_noperands (PATTERN (object)) < 0)
                    253:            {
                    254:               rtx newpat;
                    255: 
                    256:               if (XVECLEN (pat, 0) == 2)
                    257:                 newpat = XVECEXP (pat, 0, 0);
                    258:               else
                    259:                 {
                    260:                   int j;
                    261: 
                    262:                   newpat = gen_rtx (PARALLEL, VOIDmode, 
                    263:                                     gen_rtvec (XVECLEN (pat, 0) - 1));
                    264:                   for (j = 0; j < XVECLEN (newpat, 0); j++)
                    265:                     XVECEXP (newpat, 0, j) = XVECEXP (pat, 0, j);
                    266:                 }
                    267: 
                    268:               /* Add a new change to this group to replace the pattern
                    269:                  with this new pattern.  Then consider this change
                    270:                  as having succeeded.  The change we added will
                    271:                  cause the entire call to fail if things remain invalid.
                    272: 
                    273:                  Note that this can lose if a later change than the one
                    274:                  we are processing specified &XVECEXP (PATTERN (object), 0, X)
                    275:                  but this shouldn't occur.  */
                    276: 
                    277:               validate_change (object, &PATTERN (object), newpat, 1);
                    278:             }
                    279:          else if (GET_CODE (pat) == USE || GET_CODE (pat) == CLOBBER)
                    280:            /* If this insn is a CLOBBER or USE, it is always valid, but is
                    281:               never recognized.  */
                    282:            continue;
                    283:          else
                    284:            break;
                    285:        }
                    286:     }
                    287: 
                    288:   if (i == num_changes)
                    289:     {
                    290:       num_changes = 0;
                    291:       return 1;
                    292:     }
                    293:   else
                    294:     {
                    295:       cancel_changes (0);
                    296:       return 0;
                    297:     }
                    298: }
                    299: 
                    300: /* Return the number of changes so far in the current group.   */
                    301: 
                    302: int
                    303: num_validated_changes ()
                    304: {
                    305:   return num_changes;
                    306: }
                    307: 
                    308: /* Retract the changes numbered NUM and up.  */
                    309: 
                    310: void
                    311: cancel_changes (num)
                    312:      int num;
                    313: {
                    314:   int i;
                    315: 
                    316:   /* Back out all the changes.  Do this in the opposite order in which
                    317:      they were made.  */
                    318:   for (i = num_changes - 1; i >= num; i--)
                    319:     {
                    320:       *change_locs[i] = change_olds[i];
                    321:       if (change_objects[i] && GET_CODE (change_objects[i]) != MEM)
                    322:        INSN_CODE (change_objects[i]) = change_old_codes[i];
                    323:     }
                    324:   num_changes = num;
                    325: }
                    326: 
                    327: /* Replace every occurrence of FROM in X with TO.  Mark each change with
                    328:    validate_change passing OBJECT.  */
                    329: 
                    330: static void
                    331: validate_replace_rtx_1 (loc, from, to, object)
                    332:      rtx *loc;
                    333:      rtx from, to, object;
                    334: {
                    335:   register int i, j;
                    336:   register char *fmt;
                    337:   register rtx x = *loc;
                    338:   enum rtx_code code = GET_CODE (x);
                    339: 
                    340:   /* X matches FROM if it is the same rtx or they are both referring to the
                    341:      same register in the same mode.  Avoid calling rtx_equal_p unless the
                    342:      operands look similar.  */
                    343: 
                    344:   if (x == from
                    345:       || (GET_CODE (x) == REG && GET_CODE (from) == REG
                    346:          && GET_MODE (x) == GET_MODE (from)
                    347:          && REGNO (x) == REGNO (from))
                    348:       || (GET_CODE (x) == GET_CODE (from) && GET_MODE (x) == GET_MODE (from)
                    349:          && rtx_equal_p (x, from)))
                    350:     {
                    351:       validate_change (object, loc, to, 1);
                    352:       return;
                    353:     }
                    354: 
                    355:   /* For commutative or comparison operations, try replacing each argument
                    356:      separately and seeing if we made any changes.  If so, put a constant
                    357:      argument last.*/
                    358:   if (GET_RTX_CLASS (code) == '<' || GET_RTX_CLASS (code) == 'c')
                    359:     {
                    360:       int prev_changes = num_changes;
                    361: 
                    362:       validate_replace_rtx_1 (&XEXP (x, 0), from, to, object);
                    363:       validate_replace_rtx_1 (&XEXP (x, 1), from, to, object);
                    364:       if (prev_changes != num_changes && CONSTANT_P (XEXP (x, 0)))
                    365:        {
                    366:          validate_change (object, loc,
                    367:                           gen_rtx (GET_RTX_CLASS (code) == 'c' ? code
                    368:                                    : swap_condition (code),
                    369:                                    GET_MODE (x), XEXP (x, 1), XEXP (x, 0)),
                    370:                           1);
                    371:          x = *loc;
                    372:          code = GET_CODE (x);
                    373:        }
                    374:     }
                    375: 
                    376:   switch (code)
                    377:     {
                    378:     case PLUS:
                    379:       /* If we have have a PLUS whose second operand is now a CONST_INT, use
                    380:         plus_constant to try to simplify it.  */
                    381:       if (GET_CODE (XEXP (x, 1)) == CONST_INT && XEXP (x, 1) == to)
                    382:        validate_change (object, loc, 
                    383:                         plus_constant (XEXP (x, 0), INTVAL (XEXP (x, 1))), 1);
                    384:       return;
                    385:       
                    386:     case ZERO_EXTEND:
                    387:     case SIGN_EXTEND:
                    388:       /* In these cases, the operation to be performed depends on the mode
                    389:         of the operand.  If we are replacing the operand with a VOIDmode
                    390:         constant, we lose the information.  So try to simplify the operation
                    391:         in that case.  If it fails, substitute in something that we know
                    392:         won't be recognized.  */
                    393:       if (GET_MODE (to) == VOIDmode
                    394:          && (XEXP (x, 0) == from
                    395:              || (GET_CODE (XEXP (x, 0)) == REG && GET_CODE (from) == REG
                    396:                  && GET_MODE (XEXP (x, 0)) == GET_MODE (from)
                    397:                  && REGNO (XEXP (x, 0)) == REGNO (from))))
                    398:        {
                    399:          rtx new = simplify_unary_operation (code, GET_MODE (x), to,
                    400:                                              GET_MODE (from));
                    401:          if (new == 0)
                    402:            new = gen_rtx (CLOBBER, GET_MODE (x), const0_rtx);
                    403: 
                    404:          validate_change (object, loc, new, 1);
                    405:          return;
                    406:        }
                    407:       break;
                    408:        
                    409:     case SUBREG:
                    410:       /* If we have a SUBREG of a register that we are replacing and we are
                    411:         replacing it with a MEM, make a new MEM and try replacing the
                    412:         SUBREG with it.  Don't do this if the MEM has a mode-dependent address
                    413:         or if we would be widening it.  */
                    414: 
                    415:       if (SUBREG_REG (x) == from
                    416:          && GET_CODE (from) == REG
                    417:          && GET_CODE (to) == MEM
                    418:          && ! mode_dependent_address_p (XEXP (to, 0))
                    419:          && ! MEM_VOLATILE_P (to)
                    420:          && GET_MODE_SIZE (GET_MODE (x)) <= GET_MODE_SIZE (GET_MODE (to)))
                    421:        {
                    422:          int offset = SUBREG_WORD (x) * UNITS_PER_WORD;
                    423:          enum machine_mode mode = GET_MODE (x);
                    424:          rtx new;
                    425: 
                    426: #if BYTES_BIG_ENDIAN
                    427:          offset += (MIN (UNITS_PER_WORD,
                    428:                          GET_MODE_SIZE (GET_MODE (SUBREG_REG (x))))
                    429:                     - MIN (UNITS_PER_WORD, GET_MODE_SIZE (mode)));
                    430: #endif
                    431: 
                    432:          new = gen_rtx (MEM, mode, plus_constant (XEXP (to, 0), offset));
                    433:          MEM_VOLATILE_P (new) = MEM_VOLATILE_P (to);
                    434:          RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (to);
                    435:          MEM_IN_STRUCT_P (new) = MEM_IN_STRUCT_P (to);
                    436:          validate_change (object, loc, new, 1);
                    437:          return;
                    438:        }
                    439:       break;
                    440: 
                    441:     case ZERO_EXTRACT:
                    442:     case SIGN_EXTRACT:
                    443:       /* If we are replacing a register with memory, try to change the memory
                    444:         to be the mode required for memory in extract operations (this isn't
                    445:         likely to be an insertion operation; if it was, nothing bad will
                    446:         happen, we might just fail in some cases).  */
                    447: 
                    448:       if (XEXP (x, 0) == from && GET_CODE (from) == REG && GET_CODE (to) == MEM
                    449:          && GET_CODE (XEXP (x, 1)) == CONST_INT
                    450:          && GET_CODE (XEXP (x, 2)) == CONST_INT
                    451:          && ! mode_dependent_address_p (XEXP (to, 0))
                    452:          && ! MEM_VOLATILE_P (to))
                    453:        {
                    454:          enum machine_mode wanted_mode = VOIDmode;
                    455:          enum machine_mode is_mode = GET_MODE (to);
                    456:          int width = INTVAL (XEXP (x, 1));
                    457:          int pos = INTVAL (XEXP (x, 2));
                    458: 
                    459: #ifdef HAVE_extzv
                    460:          if (code == ZERO_EXTRACT)
                    461:            wanted_mode = insn_operand_mode[(int) CODE_FOR_extzv][1];
                    462: #endif
                    463: #ifdef HAVE_extv
                    464:          if (code == SIGN_EXTRACT)
                    465:            wanted_mode = insn_operand_mode[(int) CODE_FOR_extv][1];
                    466: #endif
                    467: 
                    468:          /* If we have a narrower mode, we can do something.  */
                    469:          if (wanted_mode != VOIDmode
                    470:              && GET_MODE_SIZE (wanted_mode) < GET_MODE_SIZE (is_mode))
                    471:            {
                    472:              int offset = pos / BITS_PER_UNIT;
                    473:              rtx newmem;
                    474: 
                    475:                  /* If the bytes and bits are counted differently, we
                    476:                     must adjust the offset.  */
                    477: #if BYTES_BIG_ENDIAN != BITS_BIG_ENDIAN
                    478:              offset = (GET_MODE_SIZE (is_mode) - GET_MODE_SIZE (wanted_mode)
                    479:                        - offset);
                    480: #endif
                    481: 
                    482:              pos %= GET_MODE_BITSIZE (wanted_mode);
                    483: 
                    484:              newmem = gen_rtx (MEM, wanted_mode,
                    485:                                plus_constant (XEXP (to, 0), offset));
                    486:              RTX_UNCHANGING_P (newmem) = RTX_UNCHANGING_P (to);
                    487:              MEM_VOLATILE_P (newmem) = MEM_VOLATILE_P (to);
                    488:              MEM_IN_STRUCT_P (newmem) = MEM_IN_STRUCT_P (to);
                    489: 
                    490:              validate_change (object, &XEXP (x, 2), GEN_INT (pos), 1);
                    491:              validate_change (object, &XEXP (x, 0), newmem, 1);
                    492:            }
                    493:        }
                    494: 
                    495:       break;
                    496:     }
                    497:       
                    498:   fmt = GET_RTX_FORMAT (code);
                    499:   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
                    500:     {
                    501:       if (fmt[i] == 'e')
                    502:        validate_replace_rtx_1 (&XEXP (x, i), from, to, object);
                    503:       else if (fmt[i] == 'E')
                    504:        for (j = XVECLEN (x, i) - 1; j >= 0; j--)
                    505:          validate_replace_rtx_1 (&XVECEXP (x, i, j), from, to, object);
                    506:     }
                    507: }
                    508: 
                    509: /* Try replacing every occurrence of FROM in INSN with TO.  After all
                    510:    changes have been made, validate by seeing if INSN is still valid.  */
                    511: 
                    512: int
                    513: validate_replace_rtx (from, to, insn)
                    514:      rtx from, to, insn;
                    515: {
                    516:   validate_replace_rtx_1 (&PATTERN (insn), from, to, insn);
                    517:   return apply_change_group ();
                    518: }
                    519: 
                    520: #ifdef HAVE_cc0
                    521: /* Return 1 if the insn using CC0 set by INSN does not contain
                    522:    any ordered tests applied to the condition codes.
                    523:    EQ and NE tests do not count.  */
                    524: 
                    525: int
                    526: next_insn_tests_no_inequality (insn)
                    527:      rtx insn;
                    528: {
                    529:   register rtx next = next_cc0_user (insn);
                    530: 
                    531:   /* If there is no next insn, we have to take the conservative choice.  */
                    532:   if (next == 0)
                    533:     return 0;
                    534: 
                    535:   return ((GET_CODE (next) == JUMP_INSN
                    536:           || GET_CODE (next) == INSN
                    537:           || GET_CODE (next) == CALL_INSN)
                    538:          && ! inequality_comparisons_p (PATTERN (next)));
                    539: }
                    540: 
                    541: #if 0  /* This is useless since the insn that sets the cc's
                    542:          must be followed immediately by the use of them.  */
                    543: /* Return 1 if the CC value set up by INSN is not used.  */
                    544: 
                    545: int
                    546: next_insns_test_no_inequality (insn)
                    547:      rtx insn;
                    548: {
                    549:   register rtx next = NEXT_INSN (insn);
                    550: 
                    551:   for (; next != 0; next = NEXT_INSN (next))
                    552:     {
                    553:       if (GET_CODE (next) == CODE_LABEL
                    554:          || GET_CODE (next) == BARRIER)
                    555:        return 1;
                    556:       if (GET_CODE (next) == NOTE)
                    557:        continue;
                    558:       if (inequality_comparisons_p (PATTERN (next)))
                    559:        return 0;
                    560:       if (sets_cc0_p (PATTERN (next)) == 1)
                    561:        return 1;
                    562:       if (! reg_mentioned_p (cc0_rtx, PATTERN (next)))
                    563:        return 1;
                    564:     }
                    565:   return 1;
                    566: }
                    567: #endif
                    568: #endif
                    569: 
                    570: /* This is used by find_single_use to locate an rtx that contains exactly one
                    571:    use of DEST, which is typically either a REG or CC0.  It returns a
                    572:    pointer to the innermost rtx expression containing DEST.  Appearances of
                    573:    DEST that are being used to totally replace it are not counted.  */
                    574: 
                    575: static rtx *
                    576: find_single_use_1 (dest, loc)
                    577:      rtx dest;
                    578:      rtx *loc;
                    579: {
                    580:   rtx x = *loc;
                    581:   enum rtx_code code = GET_CODE (x);
                    582:   rtx *result = 0;
                    583:   rtx *this_result;
                    584:   int i;
                    585:   char *fmt;
                    586: 
                    587:   switch (code)
                    588:     {
                    589:     case CONST_INT:
                    590:     case CONST:
                    591:     case LABEL_REF:
                    592:     case SYMBOL_REF:
                    593:     case CONST_DOUBLE:
                    594:     case CLOBBER:
                    595:       return 0;
                    596: 
                    597:     case SET:
                    598:       /* If the destination is anything other than CC0, PC, a REG or a SUBREG
                    599:         of a REG that occupies all of the REG, the insn uses DEST if
                    600:         it is mentioned in the destination or the source.  Otherwise, we
                    601:         need just check the source.  */
                    602:       if (GET_CODE (SET_DEST (x)) != CC0
                    603:          && GET_CODE (SET_DEST (x)) != PC
                    604:          && GET_CODE (SET_DEST (x)) != REG
                    605:          && ! (GET_CODE (SET_DEST (x)) == SUBREG
                    606:                && GET_CODE (SUBREG_REG (SET_DEST (x))) == REG
                    607:                && (((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (x))))
                    608:                      + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
                    609:                    == ((GET_MODE_SIZE (GET_MODE (SET_DEST (x)))
                    610:                         + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD))))
                    611:        break;
                    612: 
                    613:       return find_single_use_1 (dest, &SET_SRC (x));
                    614: 
                    615:     case MEM:
                    616:     case SUBREG:
                    617:       return find_single_use_1 (dest, &XEXP (x, 0));
                    618:     }
                    619: 
                    620:   /* If it wasn't one of the common cases above, check each expression and
                    621:      vector of this code.  Look for a unique usage of DEST.  */
                    622: 
                    623:   fmt = GET_RTX_FORMAT (code);
                    624:   for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
                    625:     {
                    626:       if (fmt[i] == 'e')
                    627:        {
                    628:          if (dest == XEXP (x, i)
                    629:              || (GET_CODE (dest) == REG && GET_CODE (XEXP (x, i)) == REG
                    630:                  && REGNO (dest) == REGNO (XEXP (x, i))))
                    631:            this_result = loc;
                    632:          else
                    633:            this_result = find_single_use_1 (dest, &XEXP (x, i));
                    634: 
                    635:          if (result == 0)
                    636:            result = this_result;
                    637:          else if (this_result)
                    638:            /* Duplicate usage.  */
                    639:            return 0;
                    640:        }
                    641:       else if (fmt[i] == 'E')
                    642:        {
                    643:          int j;
                    644: 
                    645:          for (j = XVECLEN (x, i) - 1; j >= 0; j--)
                    646:            {
                    647:              if (XVECEXP (x, i, j) == dest
                    648:                  || (GET_CODE (dest) == REG
                    649:                      && GET_CODE (XVECEXP (x, i, j)) == REG
                    650:                      && REGNO (XVECEXP (x, i, j)) == REGNO (dest)))
                    651:                this_result = loc;
                    652:              else
                    653:                this_result = find_single_use_1 (dest, &XVECEXP (x, i, j));
                    654: 
                    655:              if (result == 0)
                    656:                result = this_result;
                    657:              else if (this_result)
                    658:                return 0;
                    659:            }
                    660:        }
                    661:     }
                    662: 
                    663:   return result;
                    664: }
                    665: 
                    666: /* See if DEST, produced in INSN, is used only a single time in the
                    667:    sequel.  If so, return a pointer to the innermost rtx expression in which
                    668:    it is used.
                    669: 
                    670:    If PLOC is non-zero, *PLOC is set to the insn containing the single use.
                    671: 
                    672:    This routine will return usually zero either before flow is called (because
                    673:    there will be no LOG_LINKS notes) or after reload (because the REG_DEAD
                    674:    note can't be trusted).
                    675: 
                    676:    If DEST is cc0_rtx, we look only at the next insn.  In that case, we don't
                    677:    care about REG_DEAD notes or LOG_LINKS.
                    678: 
                    679:    Otherwise, we find the single use by finding an insn that has a
                    680:    LOG_LINKS pointing at INSN and has a REG_DEAD note for DEST.  If DEST is
                    681:    only referenced once in that insn, we know that it must be the first
                    682:    and last insn referencing DEST.  */
                    683: 
                    684: rtx *
                    685: find_single_use (dest, insn, ploc)
                    686:      rtx dest;
                    687:      rtx insn;
                    688:      rtx *ploc;
                    689: {
                    690:   rtx next;
                    691:   rtx *result;
                    692:   rtx link;
                    693: 
                    694: #ifdef HAVE_cc0
                    695:   if (dest == cc0_rtx)
                    696:     {
                    697:       next = NEXT_INSN (insn);
                    698:       if (next == 0
                    699:          || (GET_CODE (next) != INSN && GET_CODE (next) != JUMP_INSN))
                    700:        return 0;
                    701: 
                    702:       result = find_single_use_1 (dest, &PATTERN (next));
                    703:       if (result && ploc)
                    704:        *ploc = next;
                    705:       return result;
                    706:     }
                    707: #endif
                    708: 
                    709:   if (reload_completed || reload_in_progress || GET_CODE (dest) != REG)
                    710:     return 0;
                    711: 
                    712:   for (next = next_nonnote_insn (insn);
                    713:        next != 0 && GET_CODE (next) != CODE_LABEL;
                    714:        next = next_nonnote_insn (next))
                    715:     if (GET_RTX_CLASS (GET_CODE (next)) == 'i' && dead_or_set_p (next, dest))
                    716:       {
                    717:        for (link = LOG_LINKS (next); link; link = XEXP (link, 1))
                    718:          if (XEXP (link, 0) == insn)
                    719:            break;
                    720: 
                    721:        if (link)
                    722:          {
                    723:            result = find_single_use_1 (dest, &PATTERN (next));
                    724:            if (ploc)
                    725:              *ploc = next;
                    726:            return result;
                    727:          }
                    728:       }
                    729: 
                    730:   return 0;
                    731: }
                    732: 
                    733: /* Return 1 if OP is a valid general operand for machine mode MODE.
                    734:    This is either a register reference, a memory reference,
                    735:    or a constant.  In the case of a memory reference, the address
                    736:    is checked for general validity for the target machine.
                    737: 
                    738:    Register and memory references must have mode MODE in order to be valid,
                    739:    but some constants have no machine mode and are valid for any mode.
                    740: 
                    741:    If MODE is VOIDmode, OP is checked for validity for whatever mode
                    742:    it has.
                    743: 
                    744:    The main use of this function is as a predicate in match_operand
                    745:    expressions in the machine description.
                    746: 
                    747:    For an explanation of this function's behavior for registers of
                    748:    class NO_REGS, see the comment for `register_operand'.  */
                    749: 
                    750: int
                    751: general_operand (op, mode)
                    752:      register rtx op;
                    753:      enum machine_mode mode;
                    754: {
                    755:   register enum rtx_code code = GET_CODE (op);
                    756:   int mode_altering_drug = 0;
                    757: 
                    758:   if (mode == VOIDmode)
                    759:     mode = GET_MODE (op);
                    760: 
                    761:   /* Don't accept CONST_INT or anything similar
                    762:      if the caller wants something floating.  */
                    763:   if (GET_MODE (op) == VOIDmode && mode != VOIDmode
                    764:       && GET_MODE_CLASS (mode) != MODE_INT
                    765:       && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
                    766:     return 0;
                    767: 
                    768:   if (CONSTANT_P (op))
                    769:     return ((GET_MODE (op) == VOIDmode || GET_MODE (op) == mode)
                    770: #ifdef LEGITIMATE_PIC_OPERAND_P
                    771:            && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))
                    772: #endif
                    773:            && LEGITIMATE_CONSTANT_P (op));
                    774: 
                    775:   /* Except for certain constants with VOIDmode, already checked for,
                    776:      OP's mode must match MODE if MODE specifies a mode.  */
                    777: 
                    778:   if (GET_MODE (op) != mode)
                    779:     return 0;
                    780: 
                    781:   if (code == SUBREG)
                    782:     {
                    783: #ifdef INSN_SCHEDULING
                    784:       /* On machines that have insn scheduling, we want all memory
                    785:         reference to be explicit, so outlaw paradoxical SUBREGs.  */
                    786:       if (GET_CODE (SUBREG_REG (op)) == MEM
                    787:          && GET_MODE_SIZE (mode) > GET_MODE_SIZE (GET_MODE (SUBREG_REG (op))))
                    788:        return 0;
                    789: #endif
                    790: 
                    791:       op = SUBREG_REG (op);
                    792:       code = GET_CODE (op);
                    793: #if 0
                    794:       /* No longer needed, since (SUBREG (MEM...))
                    795:         will load the MEM into a reload reg in the MEM's own mode.  */
                    796:       mode_altering_drug = 1;
                    797: #endif
                    798:     }
                    799: 
                    800:   if (code == REG)
                    801:     /* A register whose class is NO_REGS is not a general operand.  */
                    802:     return (REGNO (op) >= FIRST_PSEUDO_REGISTER
                    803:            || REGNO_REG_CLASS (REGNO (op)) != NO_REGS);
                    804: 
                    805:   if (code == MEM)
                    806:     {
                    807:       register rtx y = XEXP (op, 0);
                    808:       if (! volatile_ok && MEM_VOLATILE_P (op))
                    809:        return 0;
                    810:       /* Use the mem's mode, since it will be reloaded thus.  */
                    811:       mode = GET_MODE (op);
                    812:       GO_IF_LEGITIMATE_ADDRESS (mode, y, win);
                    813:     }
                    814:   return 0;
                    815: 
                    816:  win:
                    817:   if (mode_altering_drug)
                    818:     return ! mode_dependent_address_p (XEXP (op, 0));
                    819:   return 1;
                    820: }
                    821: 
                    822: /* Return 1 if OP is a valid memory address for a memory reference
                    823:    of mode MODE.
                    824: 
                    825:    The main use of this function is as a predicate in match_operand
                    826:    expressions in the machine description.  */
                    827: 
                    828: int
                    829: address_operand (op, mode)
                    830:      register rtx op;
                    831:      enum machine_mode mode;
                    832: {
                    833:   return memory_address_p (mode, op);
                    834: }
                    835: 
                    836: /* Return 1 if OP is a register reference of mode MODE.
                    837:    If MODE is VOIDmode, accept a register in any mode.
                    838: 
                    839:    The main use of this function is as a predicate in match_operand
                    840:    expressions in the machine description.
                    841: 
                    842:    As a special exception, registers whose class is NO_REGS are
                    843:    not accepted by `register_operand'.  The reason for this change
                    844:    is to allow the representation of special architecture artifacts
                    845:    (such as a condition code register) without extending the rtl
                    846:    definitions.  Since registers of class NO_REGS cannot be used
                    847:    as registers in any case where register classes are examined,
                    848:    it is most consistent to keep this function from accepting them.  */
                    849: 
                    850: int
                    851: register_operand (op, mode)
                    852:      register rtx op;
                    853:      enum machine_mode mode;
                    854: {
                    855:   if (GET_MODE (op) != mode && mode != VOIDmode)
                    856:     return 0;
                    857: 
                    858:   if (GET_CODE (op) == SUBREG)
                    859:     {
                    860:       /* Before reload, we can allow (SUBREG (MEM...)) as a register operand
                    861:         because it is guaranteed to be reloaded into one.
                    862:         Just make sure the MEM is valid in itself.
                    863:         (Ideally, (SUBREG (MEM)...) should not exist after reload,
                    864:         but currently it does result from (SUBREG (REG)...) where the
                    865:         reg went on the stack.)  */
                    866:       if (! reload_completed && GET_CODE (SUBREG_REG (op)) == MEM)
                    867:        return general_operand (op, mode);
                    868:       op = SUBREG_REG (op);
                    869:     }
                    870: 
                    871:   /* We don't consider registers whose class is NO_REGS
                    872:      to be a register operand.  */
                    873:   return (GET_CODE (op) == REG
                    874:          && (REGNO (op) >= FIRST_PSEUDO_REGISTER
                    875:              || REGNO_REG_CLASS (REGNO (op)) != NO_REGS));
                    876: }
                    877: 
                    878: /* Return 1 if OP should match a MATCH_SCRATCH, i.e., if it is a SCRATCH
                    879:    or a hard register.  */
                    880: 
                    881: int
                    882: scratch_operand (op, mode)
                    883:      register rtx op;
                    884:      enum machine_mode mode;
                    885: {
                    886:   return (GET_MODE (op) == mode
                    887:          && (GET_CODE (op) == SCRATCH
                    888:              || (GET_CODE (op) == REG
                    889:                  && REGNO (op) < FIRST_PSEUDO_REGISTER)));
                    890: }
                    891: 
                    892: /* Return 1 if OP is a valid immediate operand for mode MODE.
                    893: 
                    894:    The main use of this function is as a predicate in match_operand
                    895:    expressions in the machine description.  */
                    896: 
                    897: int
                    898: immediate_operand (op, mode)
                    899:      register rtx op;
                    900:      enum machine_mode mode;
                    901: {
                    902:   /* Don't accept CONST_INT or anything similar
                    903:      if the caller wants something floating.  */
                    904:   if (GET_MODE (op) == VOIDmode && mode != VOIDmode
                    905:       && GET_MODE_CLASS (mode) != MODE_INT
                    906:       && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
                    907:     return 0;
                    908: 
                    909:   return (CONSTANT_P (op)
                    910:          && (GET_MODE (op) == mode || mode == VOIDmode
                    911:              || GET_MODE (op) == VOIDmode)
                    912: #ifdef LEGITIMATE_PIC_OPERAND_P
                    913:          && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))
                    914: #endif
                    915:          && LEGITIMATE_CONSTANT_P (op));
                    916: }
                    917: 
                    918: /* Returns 1 if OP is an operand that is a CONST_INT.  */
                    919: 
                    920: int
                    921: const_int_operand (op, mode)
                    922:      register rtx op;
                    923:      enum machine_mode mode;
                    924: {
                    925:   return GET_CODE (op) == CONST_INT;
                    926: }
                    927: 
                    928: /* Returns 1 if OP is an operand that is a constant integer or constant
                    929:    floating-point number.  */
                    930: 
                    931: int
                    932: const_double_operand (op, mode)
                    933:      register rtx op;
                    934:      enum machine_mode mode;
                    935: {
                    936:   /* Don't accept CONST_INT or anything similar
                    937:      if the caller wants something floating.  */
                    938:   if (GET_MODE (op) == VOIDmode && mode != VOIDmode
                    939:       && GET_MODE_CLASS (mode) != MODE_INT
                    940:       && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
                    941:     return 0;
                    942: 
                    943:   return ((GET_CODE (op) == CONST_DOUBLE || GET_CODE (op) == CONST_INT)
                    944:          && (mode == VOIDmode || GET_MODE (op) == mode
                    945:              || GET_MODE (op) == VOIDmode));
                    946: }
                    947: 
                    948: /* Return 1 if OP is a general operand that is not an immediate operand.  */
                    949: 
                    950: int
                    951: nonimmediate_operand (op, mode)
                    952:      register rtx op;
                    953:      enum machine_mode mode;
                    954: {
                    955:   return (general_operand (op, mode) && ! CONSTANT_P (op));
                    956: }
                    957: 
                    958: /* Return 1 if OP is a register reference or immediate value of mode MODE.  */
                    959: 
                    960: int
                    961: nonmemory_operand (op, mode)
                    962:      register rtx op;
                    963:      enum machine_mode mode;
                    964: {
                    965:   if (CONSTANT_P (op))
                    966:     {
                    967:       /* Don't accept CONST_INT or anything similar
                    968:         if the caller wants something floating.  */
                    969:       if (GET_MODE (op) == VOIDmode && mode != VOIDmode
                    970:          && GET_MODE_CLASS (mode) != MODE_INT
                    971:          && GET_MODE_CLASS (mode) != MODE_PARTIAL_INT)
                    972:        return 0;
                    973: 
                    974:       return ((GET_MODE (op) == VOIDmode || GET_MODE (op) == mode)
                    975: #ifdef LEGITIMATE_PIC_OPERAND_P
                    976:              && (! flag_pic || LEGITIMATE_PIC_OPERAND_P (op))
                    977: #endif
                    978:              && LEGITIMATE_CONSTANT_P (op));
                    979:     }
                    980: 
                    981:   if (GET_MODE (op) != mode && mode != VOIDmode)
                    982:     return 0;
                    983: 
                    984:   if (GET_CODE (op) == SUBREG)
                    985:     {
                    986:       /* Before reload, we can allow (SUBREG (MEM...)) as a register operand
                    987:         because it is guaranteed to be reloaded into one.
                    988:         Just make sure the MEM is valid in itself.
                    989:         (Ideally, (SUBREG (MEM)...) should not exist after reload,
                    990:         but currently it does result from (SUBREG (REG)...) where the
                    991:         reg went on the stack.)  */
                    992:       if (! reload_completed && GET_CODE (SUBREG_REG (op)) == MEM)
                    993:        return general_operand (op, mode);
                    994:       op = SUBREG_REG (op);
                    995:     }
                    996: 
                    997:   /* We don't consider registers whose class is NO_REGS
                    998:      to be a register operand.  */
                    999:   return (GET_CODE (op) == REG
                   1000:          && (REGNO (op) >= FIRST_PSEUDO_REGISTER
                   1001:              || REGNO_REG_CLASS (REGNO (op)) != NO_REGS));
                   1002: }
                   1003: 
                   1004: /* Return 1 if OP is a valid operand that stands for pushing a
                   1005:    value of mode MODE onto the stack.
                   1006: 
                   1007:    The main use of this function is as a predicate in match_operand
                   1008:    expressions in the machine description.  */
                   1009: 
                   1010: int
                   1011: push_operand (op, mode)
                   1012:      rtx op;
                   1013:      enum machine_mode mode;
                   1014: {
                   1015:   if (GET_CODE (op) != MEM)
                   1016:     return 0;
                   1017: 
                   1018:   if (GET_MODE (op) != mode)
                   1019:     return 0;
                   1020: 
                   1021:   op = XEXP (op, 0);
                   1022: 
                   1023:   if (GET_CODE (op) != STACK_PUSH_CODE)
                   1024:     return 0;
                   1025: 
                   1026:   return XEXP (op, 0) == stack_pointer_rtx;
                   1027: }
                   1028: 
                   1029: /* Return 1 if ADDR is a valid memory address for mode MODE.  */
                   1030: 
                   1031: int
                   1032: memory_address_p (mode, addr)
                   1033:      enum machine_mode mode;
                   1034:      register rtx addr;
                   1035: {
                   1036:   GO_IF_LEGITIMATE_ADDRESS (mode, addr, win);
                   1037:   return 0;
                   1038: 
                   1039:  win:
                   1040:   return 1;
                   1041: }
                   1042: 
                   1043: /* Return 1 if OP is a valid memory reference with mode MODE,
                   1044:    including a valid address.
                   1045: 
                   1046:    The main use of this function is as a predicate in match_operand
                   1047:    expressions in the machine description.  */
                   1048: 
                   1049: int
                   1050: memory_operand (op, mode)
                   1051:      register rtx op;
                   1052:      enum machine_mode mode;
                   1053: {
                   1054:   rtx inner;
                   1055: 
                   1056:   if (! reload_completed)
                   1057:     /* Note that no SUBREG is a memory operand before end of reload pass,
                   1058:        because (SUBREG (MEM...)) forces reloading into a register.  */
                   1059:     return GET_CODE (op) == MEM && general_operand (op, mode);
                   1060: 
                   1061:   if (mode != VOIDmode && GET_MODE (op) != mode)
                   1062:     return 0;
                   1063: 
                   1064:   inner = op;
                   1065: #ifdef MACHO_PIC
                   1066:   if (GET_CODE (inner) == CONST)
                   1067:     inner = XEXP (inner, 0);
                   1068: #endif
                   1069:   if (GET_CODE (inner) == SUBREG)
                   1070:     inner = SUBREG_REG (inner);
                   1071: 
                   1072:   return (GET_CODE (inner) == MEM && general_operand (op, mode));
                   1073: }
                   1074: 
                   1075: /* Return 1 if OP is a valid indirect memory reference with mode MODE;
                   1076:    that is, a memory reference whose address is a general_operand.  */
                   1077: 
                   1078: int
                   1079: indirect_operand (op, mode)
                   1080:      register rtx op;
                   1081:      enum machine_mode mode;
                   1082: {
                   1083:   /* Before reload, a SUBREG isn't in memory (see memory_operand, above).  */
                   1084:   if (! reload_completed
                   1085:       && GET_CODE (op) == SUBREG && GET_CODE (SUBREG_REG (op)) == MEM)
                   1086:     {
                   1087:       register int offset = SUBREG_WORD (op) * UNITS_PER_WORD;
                   1088:       rtx inner = SUBREG_REG (op);
                   1089: 
                   1090: #if BYTES_BIG_ENDIAN
                   1091:       offset -= (MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (op)))
                   1092:                 - MIN (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (inner))));
                   1093: #endif
                   1094: 
                   1095:       /* The only way that we can have a general_operand as the resulting
                   1096:         address is if OFFSET is zero and the address already is an operand
                   1097:         or if the address is (plus Y (const_int -OFFSET)) and Y is an
                   1098:         operand.  */
                   1099: 
                   1100:       return ((offset == 0 && general_operand (XEXP (inner, 0), Pmode))
                   1101:              || (GET_CODE (XEXP (inner, 0)) == PLUS
                   1102:                  && GET_CODE (XEXP (XEXP (inner, 0), 1)) == CONST_INT
                   1103:                  && INTVAL (XEXP (XEXP (inner, 0), 1)) == -offset
                   1104:                  && general_operand (XEXP (XEXP (inner, 0), 0), Pmode)));
                   1105:     }
                   1106: 
                   1107:   return (GET_CODE (op) == MEM
                   1108:          && memory_operand (op, mode)
                   1109:          && general_operand (XEXP (op, 0), Pmode));
                   1110: }
                   1111: 
                   1112: /* Return 1 if this is a comparison operator.  This allows the use of
                   1113:    MATCH_OPERATOR to recognize all the branch insns.  */
                   1114: 
                   1115: int
                   1116: comparison_operator (op, mode)
                   1117:     register rtx op;
                   1118:     enum machine_mode mode;
                   1119: {
                   1120:   return ((mode == VOIDmode || GET_MODE (op) == mode)
                   1121:          && GET_RTX_CLASS (GET_CODE (op)) == '<');
                   1122: }
                   1123: 
                   1124: /* If BODY is an insn body that uses ASM_OPERANDS,
                   1125:    return the number of operands (both input and output) in the insn.
                   1126:    Otherwise return -1.  */
                   1127: 
                   1128: int
                   1129: asm_noperands (body)
                   1130:      rtx body;
                   1131: {
                   1132:   if (GET_CODE (body) == ASM_OPERANDS)
                   1133:     /* No output operands: return number of input operands.  */
                   1134:     return ASM_OPERANDS_INPUT_LENGTH (body);
                   1135:   if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
                   1136:     /* Single output operand: BODY is (set OUTPUT (asm_operands ...)).  */
                   1137:     return ASM_OPERANDS_INPUT_LENGTH (SET_SRC (body)) + 1;
                   1138:   else if (GET_CODE (body) == PARALLEL
                   1139:           && GET_CODE (XVECEXP (body, 0, 0)) == SET
                   1140:           && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) == ASM_OPERANDS)
                   1141:     {
                   1142:       /* Multiple output operands, or 1 output plus some clobbers:
                   1143:         body is [(set OUTPUT (asm_operands ...))... (clobber (reg ...))...].  */
                   1144:       int i;
                   1145:       int n_sets;
                   1146: 
                   1147:       /* Count backwards through CLOBBERs to determine number of SETs.  */
                   1148:       for (i = XVECLEN (body, 0); i > 0; i--)
                   1149:        {
                   1150:          if (GET_CODE (XVECEXP (body, 0, i - 1)) == SET)
                   1151:            break;
                   1152:          if (GET_CODE (XVECEXP (body, 0, i - 1)) != CLOBBER)
                   1153:            return -1;
                   1154:        }
                   1155: 
                   1156:       /* N_SETS is now number of output operands.  */
                   1157:       n_sets = i;
                   1158: 
                   1159:       /* Verify that all the SETs we have
                   1160:         came from a single original asm_operands insn
                   1161:         (so that invalid combinations are blocked).  */
                   1162:       for (i = 0; i < n_sets; i++)
                   1163:        {
                   1164:          rtx elt = XVECEXP (body, 0, i);
                   1165:          if (GET_CODE (elt) != SET)
                   1166:            return -1;
                   1167:          if (GET_CODE (SET_SRC (elt)) != ASM_OPERANDS)
                   1168:            return -1;
                   1169:          /* If these ASM_OPERANDS rtx's came from different original insns
                   1170:             then they aren't allowed together.  */
                   1171:          if (ASM_OPERANDS_INPUT_VEC (SET_SRC (elt))
                   1172:              != ASM_OPERANDS_INPUT_VEC (SET_SRC (XVECEXP (body, 0, 0))))
                   1173:            return -1;
                   1174:        }
                   1175:       return (ASM_OPERANDS_INPUT_LENGTH (SET_SRC (XVECEXP (body, 0, 0)))
                   1176:              + n_sets);
                   1177:     }
                   1178:   else if (GET_CODE (body) == PARALLEL
                   1179:           && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS)
                   1180:     {
                   1181:       /* 0 outputs, but some clobbers:
                   1182:         body is [(asm_operands ...) (clobber (reg ...))...].  */
                   1183:       int i;
                   1184: 
                   1185:       /* Make sure all the other parallel things really are clobbers.  */
                   1186:       for (i = XVECLEN (body, 0) - 1; i > 0; i--)
                   1187:        if (GET_CODE (XVECEXP (body, 0, i)) != CLOBBER)
                   1188:          return -1;
                   1189: 
                   1190:       return ASM_OPERANDS_INPUT_LENGTH (XVECEXP (body, 0, 0));
                   1191:     }
                   1192:   else
                   1193:     return -1;
                   1194: }
                   1195: 
                   1196: /* Assuming BODY is an insn body that uses ASM_OPERANDS,
                   1197:    copy its operands (both input and output) into the vector OPERANDS,
                   1198:    the locations of the operands within the insn into the vector OPERAND_LOCS,
                   1199:    and the constraints for the operands into CONSTRAINTS.
                   1200:    Write the modes of the operands into MODES.
                   1201:    Return the assembler-template.
                   1202: 
                   1203:    If MODES, OPERAND_LOCS, CONSTRAINTS or OPERANDS is 0,
                   1204:    we don't store that info.  */
                   1205: 
                   1206: char *
                   1207: decode_asm_operands (body, operands, operand_locs, constraints, modes)
                   1208:      rtx body;
                   1209:      rtx *operands;
                   1210:      rtx **operand_locs;
                   1211:      char **constraints;
                   1212:      enum machine_mode *modes;
                   1213: {
                   1214:   register int i;
                   1215:   int noperands;
                   1216:   char *template = 0;
                   1217: 
                   1218:   if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
                   1219:     {
                   1220:       rtx asmop = SET_SRC (body);
                   1221:       /* Single output operand: BODY is (set OUTPUT (asm_operands ....)).  */
                   1222: 
                   1223:       noperands = ASM_OPERANDS_INPUT_LENGTH (asmop) + 1;
                   1224: 
                   1225:       for (i = 1; i < noperands; i++)
                   1226:        {
                   1227:          if (operand_locs)
                   1228:            operand_locs[i] = &ASM_OPERANDS_INPUT (asmop, i - 1);
                   1229:          if (operands)
                   1230:            operands[i] = ASM_OPERANDS_INPUT (asmop, i - 1);
                   1231:          if (constraints)
                   1232:            constraints[i] = ASM_OPERANDS_INPUT_CONSTRAINT (asmop, i - 1);
                   1233:          if (modes)
                   1234:            modes[i] = ASM_OPERANDS_INPUT_MODE (asmop, i - 1);
                   1235:        }
                   1236: 
                   1237:       /* The output is in the SET.
                   1238:         Its constraint is in the ASM_OPERANDS itself.  */
                   1239:       if (operands)
                   1240:        operands[0] = SET_DEST (body);
                   1241:       if (operand_locs)
                   1242:        operand_locs[0] = &SET_DEST (body);
                   1243:       if (constraints)
                   1244:        constraints[0] = ASM_OPERANDS_OUTPUT_CONSTRAINT (asmop);
                   1245:       if (modes)
                   1246:        modes[0] = GET_MODE (SET_DEST (body));
                   1247:       template = ASM_OPERANDS_TEMPLATE (asmop);
                   1248:     }
                   1249:   else if (GET_CODE (body) == ASM_OPERANDS)
                   1250:     {
                   1251:       rtx asmop = body;
                   1252:       /* No output operands: BODY is (asm_operands ....).  */
                   1253: 
                   1254:       noperands = ASM_OPERANDS_INPUT_LENGTH (asmop);
                   1255: 
                   1256:       /* The input operands are found in the 1st element vector.  */
                   1257:       /* Constraints for inputs are in the 2nd element vector.  */
                   1258:       for (i = 0; i < noperands; i++)
                   1259:        {
                   1260:          if (operand_locs)
                   1261:            operand_locs[i] = &ASM_OPERANDS_INPUT (asmop, i);
                   1262:          if (operands)
                   1263:            operands[i] = ASM_OPERANDS_INPUT (asmop, i);
                   1264:          if (constraints)
                   1265:            constraints[i] = ASM_OPERANDS_INPUT_CONSTRAINT (asmop, i);
                   1266:          if (modes)
                   1267:            modes[i] = ASM_OPERANDS_INPUT_MODE (asmop, i);
                   1268:        }
                   1269:       template = ASM_OPERANDS_TEMPLATE (asmop);
                   1270:     }
                   1271:   else if (GET_CODE (body) == PARALLEL
                   1272:           && GET_CODE (XVECEXP (body, 0, 0)) == SET)
                   1273:     {
                   1274:       rtx asmop = SET_SRC (XVECEXP (body, 0, 0));
                   1275:       int nparallel = XVECLEN (body, 0); /* Includes CLOBBERs.  */
                   1276:       int nin = ASM_OPERANDS_INPUT_LENGTH (asmop);
                   1277:       int nout = 0;            /* Does not include CLOBBERs.  */
                   1278: 
                   1279:       /* At least one output, plus some CLOBBERs.  */
                   1280: 
                   1281:       /* The outputs are in the SETs.
                   1282:         Their constraints are in the ASM_OPERANDS itself.  */
                   1283:       for (i = 0; i < nparallel; i++)
                   1284:        {
                   1285:          if (GET_CODE (XVECEXP (body, 0, i)) == CLOBBER)
                   1286:            break;              /* Past last SET */
                   1287:          
                   1288:          if (operands)
                   1289:            operands[i] = SET_DEST (XVECEXP (body, 0, i));
                   1290:          if (operand_locs)
                   1291:            operand_locs[i] = &SET_DEST (XVECEXP (body, 0, i));
                   1292:          if (constraints)
                   1293:            constraints[i] = XSTR (SET_SRC (XVECEXP (body, 0, i)), 1);
                   1294:          if (modes)
                   1295:            modes[i] = GET_MODE (SET_DEST (XVECEXP (body, 0, i)));
                   1296:          nout++;
                   1297:        }
                   1298: 
                   1299:       for (i = 0; i < nin; i++)
                   1300:        {
                   1301:          if (operand_locs)
                   1302:            operand_locs[i + nout] = &ASM_OPERANDS_INPUT (asmop, i);
                   1303:          if (operands)
                   1304:            operands[i + nout] = ASM_OPERANDS_INPUT (asmop, i);
                   1305:          if (constraints)
                   1306:            constraints[i + nout] = ASM_OPERANDS_INPUT_CONSTRAINT (asmop, i);
                   1307:          if (modes)
                   1308:            modes[i + nout] = ASM_OPERANDS_INPUT_MODE (asmop, i);
                   1309:        }
                   1310: 
                   1311:       template = ASM_OPERANDS_TEMPLATE (asmop);
                   1312:     }
                   1313:   else if (GET_CODE (body) == PARALLEL
                   1314:           && GET_CODE (XVECEXP (body, 0, 0)) == ASM_OPERANDS)
                   1315:     {
                   1316:       /* No outputs, but some CLOBBERs.  */
                   1317: 
                   1318:       rtx asmop = XVECEXP (body, 0, 0);
                   1319:       int nin = ASM_OPERANDS_INPUT_LENGTH (asmop);
                   1320: 
                   1321:       for (i = 0; i < nin; i++)
                   1322:        {
                   1323:          if (operand_locs)
                   1324:            operand_locs[i] = &ASM_OPERANDS_INPUT (asmop, i);
                   1325:          if (operands)
                   1326:            operands[i] = ASM_OPERANDS_INPUT (asmop, i);
                   1327:          if (constraints)
                   1328:            constraints[i] = ASM_OPERANDS_INPUT_CONSTRAINT (asmop, i);
                   1329:          if (modes)
                   1330:            modes[i] = ASM_OPERANDS_INPUT_MODE (asmop, i);
                   1331:        }
                   1332: 
                   1333:       template = ASM_OPERANDS_TEMPLATE (asmop);
                   1334:     }
                   1335: 
                   1336:   return template;
                   1337: }
                   1338: 
                   1339: /* Given an rtx *P, if it is a sum containing an integer constant term,
                   1340:    return the location (type rtx *) of the pointer to that constant term.
                   1341:    Otherwise, return a null pointer.  */
                   1342: 
                   1343: static rtx *
                   1344: find_constant_term_loc (p)
                   1345:      rtx *p;
                   1346: {
                   1347:   register rtx *tem;
                   1348:   register enum rtx_code code = GET_CODE (*p);
                   1349: 
                   1350:   /* If *P IS such a constant term, P is its location.  */
                   1351: 
                   1352:   if (code == CONST_INT || code == SYMBOL_REF || code == LABEL_REF
                   1353:       || code == CONST)
                   1354:     return p;
                   1355: 
                   1356:   /* Otherwise, if not a sum, it has no constant term.  */
                   1357: 
                   1358:   if (GET_CODE (*p) != PLUS)
                   1359:     return 0;
                   1360: 
                   1361:   /* If one of the summands is constant, return its location.  */
                   1362: 
                   1363:   if (XEXP (*p, 0) && CONSTANT_P (XEXP (*p, 0))
                   1364:       && XEXP (*p, 1) && CONSTANT_P (XEXP (*p, 1)))
                   1365:     return p;
                   1366: 
                   1367:   /* Otherwise, check each summand for containing a constant term.  */
                   1368: 
                   1369:   if (XEXP (*p, 0) != 0)
                   1370:     {
                   1371:       tem = find_constant_term_loc (&XEXP (*p, 0));
                   1372:       if (tem != 0)
                   1373:        return tem;
                   1374:     }
                   1375: 
                   1376:   if (XEXP (*p, 1) != 0)
                   1377:     {
                   1378:       tem = find_constant_term_loc (&XEXP (*p, 1));
                   1379:       if (tem != 0)
                   1380:        return tem;
                   1381:     }
                   1382: 
                   1383:   return 0;
                   1384: }
                   1385: 
                   1386: /* Return 1 if OP is a memory reference
                   1387:    whose address contains no side effects
                   1388:    and remains valid after the addition
                   1389:    of a positive integer less than the
                   1390:    size of the object being referenced.
                   1391: 
                   1392:    We assume that the original address is valid and do not check it.
                   1393: 
                   1394:    This uses strict_memory_address_p as a subroutine, so
                   1395:    don't use it before reload.  */
                   1396: 
                   1397: int
                   1398: offsettable_memref_p (op)
                   1399:      rtx op;
                   1400: {
                   1401:   return ((GET_CODE (op) == MEM)
                   1402:          && offsettable_address_p (1, GET_MODE (op), XEXP (op, 0)));
                   1403: }
                   1404: 
                   1405: /* Similar, but don't require a strictly valid mem ref:
                   1406:    consider pseudo-regs valid as index or base regs.  */
                   1407: 
                   1408: int
                   1409: offsettable_nonstrict_memref_p (op)
                   1410:      rtx op;
                   1411: {
                   1412:   return ((GET_CODE (op) == MEM)
                   1413:          && offsettable_address_p (0, GET_MODE (op), XEXP (op, 0)));
                   1414: }
                   1415: 
                   1416: /* Return 1 if Y is a memory address which contains no side effects
                   1417:    and would remain valid after the addition of a positive integer
                   1418:    less than the size of that mode.
                   1419: 
                   1420:    We assume that the original address is valid and do not check it.
                   1421:    We do check that it is valid for narrower modes.
                   1422: 
                   1423:    If STRICTP is nonzero, we require a strictly valid address,
                   1424:    for the sake of use in reload.c.  */
                   1425: 
                   1426: int
                   1427: offsettable_address_p (strictp, mode, y)
                   1428:      int strictp;
                   1429:      enum machine_mode mode;
                   1430:      register rtx y;
                   1431: {
                   1432:   register enum rtx_code ycode = GET_CODE (y);
                   1433:   register rtx z;
                   1434:   rtx y1 = y;
                   1435:   rtx *y2;
                   1436:   int (*addressp) () = (strictp ? strict_memory_address_p : memory_address_p);
                   1437: 
                   1438:   if (CONSTANT_ADDRESS_P (y))
                   1439:     return 1;
                   1440: 
                   1441:   /* Adjusting an offsettable address involves changing to a narrower mode.
                   1442:      Make sure that's OK.  */
                   1443: 
                   1444:   if (mode_dependent_address_p (y))
                   1445:     return 0;
                   1446: 
                   1447:   /* If the expression contains a constant term,
                   1448:      see if it remains valid when max possible offset is added.  */
                   1449: 
                   1450:   if ((ycode == PLUS) && (y2 = find_constant_term_loc (&y1)))
                   1451:     {
                   1452:       int good;
                   1453: 
                   1454:       y1 = *y2;
                   1455:       *y2 = plus_constant (*y2, GET_MODE_SIZE (mode) - 1);
                   1456:       /* Use QImode because an odd displacement may be automatically invalid
                   1457:         for any wider mode.  But it should be valid for a single byte.  */
                   1458:       good = (*addressp) (QImode, y);
                   1459: 
                   1460:       /* In any case, restore old contents of memory.  */
                   1461:       *y2 = y1;
                   1462:       return good;
                   1463:     }
                   1464: 
                   1465:   if (ycode == PRE_DEC || ycode == PRE_INC
                   1466:       || ycode == POST_DEC || ycode == POST_INC)
                   1467:     return 0;
                   1468: 
                   1469:   /* The offset added here is chosen as the maximum offset that
                   1470:      any instruction could need to add when operating on something
                   1471:      of the specified mode.  We assume that if Y and Y+c are
                   1472:      valid addresses then so is Y+d for all 0<d<c.  */
                   1473: 
                   1474:   z = plus_constant_for_output (y, GET_MODE_SIZE (mode) - 1);
                   1475: 
                   1476:   /* Use QImode because an odd displacement may be automatically invalid
                   1477:      for any wider mode.  But it should be valid for a single byte.  */
                   1478:   return (*addressp) (QImode, z);
                   1479: }
                   1480: 
                   1481: /* Return 1 if ADDR is an address-expression whose effect depends
                   1482:    on the mode of the memory reference it is used in.
                   1483: 
                   1484:    Autoincrement addressing is a typical example of mode-dependence
                   1485:    because the amount of the increment depends on the mode.  */
                   1486: 
                   1487: int
                   1488: mode_dependent_address_p (addr)
                   1489:      rtx addr;
                   1490: {
                   1491:   GO_IF_MODE_DEPENDENT_ADDRESS (addr, win);
                   1492:   return 0;
                   1493:  win:
                   1494:   return 1;
                   1495: }
                   1496: 
                   1497: /* Return 1 if OP is a general operand
                   1498:    other than a memory ref with a mode dependent address.  */
                   1499: 
                   1500: int
                   1501: mode_independent_operand (op, mode)
                   1502:      enum machine_mode mode;
                   1503:      rtx op;
                   1504: {
                   1505:   rtx addr;
                   1506: 
                   1507:   if (! general_operand (op, mode))
                   1508:     return 0;
                   1509: 
                   1510:   if (GET_CODE (op) != MEM)
                   1511:     return 1;
                   1512: 
                   1513:   addr = XEXP (op, 0);
                   1514:   GO_IF_MODE_DEPENDENT_ADDRESS (addr, lose);
                   1515:   return 1;
                   1516:  lose:
                   1517:   return 0;
                   1518: }
                   1519: 
                   1520: /* Given an operand OP that is a valid memory reference
                   1521:    which satisfies offsettable_memref_p,
                   1522:    return a new memory reference whose address has been adjusted by OFFSET.
                   1523:    OFFSET should be positive and less than the size of the object referenced.
                   1524: */
                   1525: 
                   1526: rtx
                   1527: adj_offsettable_operand (op, offset)
                   1528:      rtx op;
                   1529:      int offset;
                   1530: {
                   1531:   register enum rtx_code code = GET_CODE (op);
                   1532: 
                   1533:   if (code == MEM) 
                   1534:     {
                   1535:       register rtx y = XEXP (op, 0);
                   1536:       register rtx new;
                   1537: 
                   1538:       if (CONSTANT_ADDRESS_P (y))
                   1539:        {
                   1540:          new = gen_rtx (MEM, GET_MODE (op), plus_constant_for_output (y, offset));
                   1541:          RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (op);
                   1542:          return new;
                   1543:        }
                   1544: 
                   1545:       if (GET_CODE (y) == PLUS)
                   1546:        {
                   1547:          rtx z = y;
                   1548:          register rtx *const_loc;
                   1549: 
                   1550:          op = copy_rtx (op);
                   1551:          z = XEXP (op, 0);
                   1552:          const_loc = find_constant_term_loc (&z);
                   1553:          if (const_loc)
                   1554:            {
                   1555:              *const_loc = plus_constant_for_output (*const_loc, offset);
                   1556:              return op;
                   1557:            }
                   1558:        }
                   1559: 
                   1560:       new = gen_rtx (MEM, GET_MODE (op), plus_constant_for_output (y, offset));
                   1561:       RTX_UNCHANGING_P (new) = RTX_UNCHANGING_P (op);
                   1562:       return new;
                   1563:     }
                   1564:   abort ();
                   1565: }
                   1566: 
                   1567: #ifdef REGISTER_CONSTRAINTS
                   1568: 
                   1569: /* Check the operands of an insn (found in recog_operands)
                   1570:    against the insn's operand constraints (found via INSN_CODE_NUM)
                   1571:    and return 1 if they are valid.
                   1572: 
                   1573:    WHICH_ALTERNATIVE is set to a number which indicates which
                   1574:    alternative of constraints was matched: 0 for the first alternative,
                   1575:    1 for the next, etc.
                   1576: 
                   1577:    In addition, when two operands are match
                   1578:    and it happens that the output operand is (reg) while the
                   1579:    input operand is --(reg) or ++(reg) (a pre-inc or pre-dec),
                   1580:    make the output operand look like the input.
                   1581:    This is because the output operand is the one the template will print.
                   1582: 
                   1583:    This is used in final, just before printing the assembler code and by
                   1584:    the routines that determine an insn's attribute.
                   1585: 
                   1586:    If STRICT is a positive non-zero value, it means that we have been
                   1587:    called after reload has been completed.  In that case, we must
                   1588:    do all checks strictly.  If it is zero, it means that we have been called
                   1589:    before reload has completed.  In that case, we first try to see if we can
                   1590:    find an alternative that matches strictly.  If not, we try again, this
                   1591:    time assuming that reload will fix up the insn.  This provides a "best
                   1592:    guess" for the alternative and is used to compute attributes of insns prior
                   1593:    to reload.  A negative value of STRICT is used for this internal call.  */
                   1594: 
                   1595: struct funny_match
                   1596: {
                   1597:   int this, other;
                   1598: };
                   1599: 
                   1600: int
                   1601: constrain_operands (insn_code_num, strict)
                   1602:      int insn_code_num;
                   1603:      int strict;
                   1604: {
                   1605:   char *constraints[MAX_RECOG_OPERANDS];
                   1606:   int matching_operands[MAX_RECOG_OPERANDS];
                   1607:   enum op_type {OP_IN, OP_OUT, OP_INOUT} op_types[MAX_RECOG_OPERANDS];
                   1608:   int earlyclobber[MAX_RECOG_OPERANDS];
                   1609:   register int c;
                   1610:   int noperands = insn_n_operands[insn_code_num];
                   1611: 
                   1612:   struct funny_match funny_match[MAX_RECOG_OPERANDS];
                   1613:   int funny_match_index;
                   1614:   int nalternatives = insn_n_alternatives[insn_code_num];
                   1615: 
                   1616:   if (noperands == 0 || nalternatives == 0)
                   1617:     return 1;
                   1618: 
                   1619:   for (c = 0; c < noperands; c++)
                   1620:     {
                   1621:       constraints[c] = insn_operand_constraint[insn_code_num][c];
                   1622:       matching_operands[c] = -1;
                   1623:       op_types[c] = OP_IN;
                   1624:     }
                   1625: 
                   1626:   which_alternative = 0;
                   1627: 
                   1628:   while (which_alternative < nalternatives)
                   1629:     {
                   1630:       register int opno;
                   1631:       int lose = 0;
                   1632:       funny_match_index = 0;
                   1633: 
                   1634:       for (opno = 0; opno < noperands; opno++)
                   1635:        {
                   1636:          register rtx op = recog_operand[opno];
                   1637:          enum machine_mode mode = GET_MODE (op);
                   1638:          register char *p = constraints[opno];
                   1639:          int offset = 0;
                   1640:          int win = 0;
                   1641:          int val;
                   1642: 
                   1643:          earlyclobber[opno] = 0;
                   1644: 
                   1645:          if (GET_CODE (op) == SUBREG)
                   1646:            {
                   1647:              if (GET_CODE (SUBREG_REG (op)) == REG
                   1648:                  && REGNO (SUBREG_REG (op)) < FIRST_PSEUDO_REGISTER)
                   1649:                offset = SUBREG_WORD (op);
                   1650:              op = SUBREG_REG (op);
                   1651:            }
                   1652: 
                   1653:          /* An empty constraint or empty alternative
                   1654:             allows anything which matched the pattern.  */
                   1655:          if (*p == 0 || *p == ',')
                   1656:            win = 1;
                   1657: 
                   1658:          while (*p && (c = *p++) != ',')
                   1659:            switch (c)
                   1660:              {
                   1661:              case '?':
                   1662:              case '#':
                   1663:              case '!':
                   1664:              case '*':
                   1665:              case '%':
                   1666:                break;
                   1667: 
                   1668:              case '=':
                   1669:                op_types[opno] = OP_OUT;
                   1670:                break;
                   1671: 
                   1672:              case '+':
                   1673:                op_types[opno] = OP_INOUT;
                   1674:                break;
                   1675: 
                   1676:              case '&':
                   1677:                earlyclobber[opno] = 1;
                   1678:                break;
                   1679: 
                   1680:              case '0':
                   1681:              case '1':
                   1682:              case '2':
                   1683:              case '3':
                   1684:              case '4':
                   1685:                /* This operand must be the same as a previous one.
                   1686:                   This kind of constraint is used for instructions such
                   1687:                   as add when they take only two operands.
                   1688: 
                   1689:                   Note that the lower-numbered operand is passed first.
                   1690: 
                   1691:                   If we are not testing strictly, assume that this constraint
                   1692:                   will be satisfied.  */
                   1693:                if (strict < 0)
                   1694:                  val = 1;
                   1695:                else
                   1696:                  val = operands_match_p (recog_operand[c - '0'],
                   1697:                                          recog_operand[opno]);
                   1698: 
                   1699:                matching_operands[opno] = c - '0';
                   1700:                matching_operands[c - '0'] = opno;
                   1701: 
                   1702:                if (val != 0)
                   1703:                  win = 1;
                   1704:                /* If output is *x and input is *--x,
                   1705:                   arrange later to change the output to *--x as well,
                   1706:                   since the output op is the one that will be printed.  */
                   1707:                if (val == 2 && strict > 0)
                   1708:                  {
                   1709:                    funny_match[funny_match_index].this = opno;
                   1710:                    funny_match[funny_match_index++].other = c - '0';
                   1711:                  }
                   1712:                break;
                   1713: 
                   1714:              case 'p':
                   1715:                /* p is used for address_operands.  When we are called by
                   1716:                   gen_input_reload, no one will have checked that the
                   1717:                   address is strictly valid, i.e., that all pseudos
                   1718:                   requiring hard regs have gotten them.  */
                   1719:                if (strict <= 0
                   1720:                    || (strict_memory_address_p
                   1721:                        (insn_operand_mode[insn_code_num][opno], op)))
                   1722:                  win = 1;
                   1723:                break;
                   1724: 
                   1725:                /* No need to check general_operand again;
                   1726:                   it was done in insn-recog.c.  */
                   1727:              case 'g':
                   1728:                /* Anything goes unless it is a REG and really has a hard reg
                   1729:                   but the hard reg is not in the class GENERAL_REGS.  */
                   1730:                if (strict < 0
                   1731:                    || GENERAL_REGS == ALL_REGS
                   1732:                    || GET_CODE (op) != REG
                   1733:                    || (reload_in_progress
                   1734:                        && REGNO (op) >= FIRST_PSEUDO_REGISTER)
                   1735:                    || reg_fits_class_p (op, GENERAL_REGS, offset, mode))
                   1736:                  win = 1;
                   1737:                break;
                   1738: 
                   1739:              case 'r':
                   1740:                if (strict < 0
                   1741:                    || (strict == 0
                   1742:                        && GET_CODE (op) == REG
                   1743:                        && REGNO (op) >= FIRST_PSEUDO_REGISTER)
                   1744:                    || (strict == 0 && GET_CODE (op) == SCRATCH)
                   1745:                    || (GET_CODE (op) == REG
                   1746:                        && ((GENERAL_REGS == ALL_REGS
                   1747:                             && REGNO (op) < FIRST_PSEUDO_REGISTER)
                   1748:                            || reg_fits_class_p (op, GENERAL_REGS,
                   1749:                                                 offset, mode))))
                   1750:                  win = 1;
                   1751:                break;
                   1752: 
                   1753:              case 'X':
                   1754:                /* This is used for a MATCH_SCRATCH in the cases when we
                   1755:                   don't actually need anything.  So anything goes any time. */
                   1756:                win = 1;
                   1757:                break;
                   1758: 
                   1759:              case 'm':
                   1760:                if (GET_CODE (op) == MEM
                   1761:                    /* Before reload, accept what reload can turn into mem.  */
                   1762:                    || (strict < 0 && CONSTANT_P (op))
                   1763:                    /* During reload, accept a pseudo  */
                   1764:                    || (reload_in_progress && GET_CODE (op) == REG
                   1765:                        && REGNO (op) >= FIRST_PSEUDO_REGISTER))
                   1766:                  win = 1;
                   1767:                break;
                   1768: 
                   1769:              case '<':
                   1770:                if (GET_CODE (op) == MEM
                   1771:                    && (GET_CODE (XEXP (op, 0)) == PRE_DEC
                   1772:                        || GET_CODE (XEXP (op, 0)) == POST_DEC))
                   1773:                  win = 1;
                   1774:                break;
                   1775: 
                   1776:              case '>':
                   1777:                if (GET_CODE (op) == MEM
                   1778:                    && (GET_CODE (XEXP (op, 0)) == PRE_INC
                   1779:                        || GET_CODE (XEXP (op, 0)) == POST_INC))
                   1780:                  win = 1;
                   1781:                break;
                   1782: 
                   1783:              case 'E':
                   1784:                /* Match any CONST_DOUBLE, but only if
                   1785:                   we can examine the bits of it reliably.  */
                   1786:                if ((HOST_FLOAT_FORMAT != TARGET_FLOAT_FORMAT
                   1787:                     || HOST_BITS_PER_WIDE_INT != BITS_PER_WORD)
                   1788:                    && GET_MODE (op) != VOIDmode && ! flag_pretend_float)
                   1789:                  break;
                   1790:                if (GET_CODE (op) == CONST_DOUBLE)
                   1791:                  win = 1;
                   1792:                break;
                   1793: 
                   1794:              case 'F':
                   1795:                if (GET_CODE (op) == CONST_DOUBLE)
                   1796:                  win = 1;
                   1797:                break;
                   1798: 
                   1799:              case 'G':
                   1800:              case 'H':
                   1801:                if (GET_CODE (op) == CONST_DOUBLE
                   1802:                    && CONST_DOUBLE_OK_FOR_LETTER_P (op, c))
                   1803:                  win = 1;
                   1804:                break;
                   1805: 
                   1806:              case 's':
                   1807:                if (GET_CODE (op) == CONST_INT
                   1808:                    || (GET_CODE (op) == CONST_DOUBLE
                   1809:                        && GET_MODE (op) == VOIDmode))
                   1810:                  break;
                   1811:              case 'i':
                   1812:                if (CONSTANT_P (op))
                   1813:                  win = 1;
                   1814:                break;
                   1815: 
                   1816:              case 'n':
                   1817:                if (GET_CODE (op) == CONST_INT
                   1818:                    || (GET_CODE (op) == CONST_DOUBLE
                   1819:                        && GET_MODE (op) == VOIDmode))
                   1820:                  win = 1;
                   1821:                break;
                   1822: 
                   1823:              case 'I':
                   1824:              case 'J':
                   1825:              case 'K':
                   1826:              case 'L':
                   1827:              case 'M':
                   1828:              case 'N':
                   1829:              case 'O':
                   1830:              case 'P':
                   1831:                if (GET_CODE (op) == CONST_INT
                   1832:                    && CONST_OK_FOR_LETTER_P (INTVAL (op), c))
                   1833:                  win = 1;
                   1834:                break;
                   1835: 
                   1836: #ifdef EXTRA_CONSTRAINT
                   1837:               case 'Q':
                   1838:               case 'R':
                   1839:               case 'S':
                   1840:               case 'T':
                   1841:               case 'U':
                   1842:                if (EXTRA_CONSTRAINT (op, c))
                   1843:                  win = 1;
                   1844:                break;
                   1845: #endif
                   1846: 
                   1847:              case 'V':
                   1848:                if (GET_CODE (op) == MEM
                   1849:                    && ! offsettable_memref_p (op))
                   1850:                  win = 1;
                   1851:                break;
                   1852: 
                   1853:              case 'o':
                   1854:                if ((strict > 0 && offsettable_memref_p (op))
                   1855:                    || (strict == 0 && offsettable_nonstrict_memref_p (op))
                   1856:                    /* Before reload, accept what reload can handle.  */
                   1857:                    || (strict < 0
                   1858:                        && (CONSTANT_P (op) || GET_CODE (op) == MEM))
                   1859:                    /* During reload, accept a pseudo  */
                   1860:                    || (reload_in_progress && GET_CODE (op) == REG
                   1861:                        && REGNO (op) >= FIRST_PSEUDO_REGISTER))
                   1862:                  win = 1;
                   1863:                break;
                   1864: 
                   1865:              default:
                   1866:                if (strict < 0
                   1867:                    || (strict == 0
                   1868:                        && GET_CODE (op) == REG
                   1869:                        && REGNO (op) >= FIRST_PSEUDO_REGISTER)
                   1870:                    || (strict == 0 && GET_CODE (op) == SCRATCH)
                   1871:                    || (GET_CODE (op) == REG
                   1872:                        && reg_fits_class_p (op, REG_CLASS_FROM_LETTER (c),
                   1873:                                             offset, mode)))
                   1874:                  win = 1;
                   1875:              }
                   1876: 
                   1877:          constraints[opno] = p;
                   1878:          /* If this operand did not win somehow,
                   1879:             this alternative loses.  */
                   1880:          if (! win)
                   1881:            lose = 1;
                   1882:        }
                   1883:       /* This alternative won; the operands are ok.
                   1884:         Change whichever operands this alternative says to change.  */
                   1885:       if (! lose)
                   1886:        {
                   1887:          int opno, eopno;
                   1888: 
                   1889:          /* See if any earlyclobber operand conflicts with some other
                   1890:             operand.  */
                   1891: 
                   1892:          if (strict > 0)
                   1893:            for (eopno = 0; eopno < noperands; eopno++)
                   1894:              /* Ignore earlyclobber operands now in memory,
                   1895:                 because we would often report failure when we have
                   1896:                 two memory operands, one of which was formerly a REG.  */
                   1897:              if (earlyclobber[eopno]
                   1898:                  && GET_CODE (recog_operand[eopno]) == REG)
                   1899:                for (opno = 0; opno < noperands; opno++)
                   1900:                  if ((GET_CODE (recog_operand[opno]) == MEM
                   1901:                       || op_types[opno] != OP_OUT)
                   1902:                      && opno != eopno
                   1903:                      /* Ignore things like match_operator operands. */
                   1904:                      && *constraints[opno] != 0
                   1905:                      && ! (matching_operands[opno] == eopno
                   1906:                            && rtx_equal_p (recog_operand[opno],
                   1907:                                            recog_operand[eopno]))
                   1908:                      && ! safe_from_earlyclobber (recog_operand[opno],
                   1909:                                                   recog_operand[eopno]))
                   1910:                    lose = 1;
                   1911: 
                   1912:          if (! lose)
                   1913:            {
                   1914:              while (--funny_match_index >= 0)
                   1915:                {
                   1916:                  recog_operand[funny_match[funny_match_index].other]
                   1917:                    = recog_operand[funny_match[funny_match_index].this];
                   1918:                }
                   1919: 
                   1920:              return 1;
                   1921:            }
                   1922:        }
                   1923: 
                   1924:       which_alternative++;
                   1925:     }
                   1926: 
                   1927:   /* If we are about to reject this, but we are not to test strictly,
                   1928:      try a very loose test.  Only return failure if it fails also.  */
                   1929:   if (strict == 0)
                   1930:     return constrain_operands (insn_code_num, -1);
                   1931:   else
                   1932:     return 0;
                   1933: }
                   1934: 
                   1935: /* Return 1 iff OPERAND (assumed to be a REG rtx)
                   1936:    is a hard reg in class CLASS when its regno is offsetted by OFFSET
                   1937:    and changed to mode MODE.
                   1938:    If REG occupies multiple hard regs, all of them must be in CLASS.  */
                   1939: 
                   1940: int
                   1941: reg_fits_class_p (operand, class, offset, mode)
                   1942:      rtx operand;
                   1943:      register enum reg_class class;
                   1944:      int offset;
                   1945:      enum machine_mode mode;
                   1946: {
                   1947:   register int regno = REGNO (operand);
                   1948:   if (regno < FIRST_PSEUDO_REGISTER
                   1949:       && TEST_HARD_REG_BIT (reg_class_contents[(int) class],
                   1950:                            regno + offset))
                   1951:     {
                   1952:       register int sr;
                   1953:       regno += offset;
                   1954:       for (sr = HARD_REGNO_NREGS (regno, mode) - 1;
                   1955:           sr > 0; sr--)
                   1956:        if (! TEST_HARD_REG_BIT (reg_class_contents[(int) class],
                   1957:                                 regno + sr))
                   1958:          break;
                   1959:       return sr == 0;
                   1960:     }
                   1961: 
                   1962:   return 0;
                   1963: }
                   1964: 
                   1965: #endif /* REGISTER_CONSTRAINTS */

unix.superglobalmegacorp.com

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