Annotation of researchv10dc/cmd/gcc/recog.c, revision 1.1.1.1

1.1       root        1: /* Subroutines used by or related to instruction recognition.
                      2:    Copyright (C) 1987, 1988 Free Software Foundation, Inc.
                      3: 
                      4: This file is part of GNU CC.
                      5: 
                      6: GNU CC is distributed in the hope that it will be useful,
                      7: but WITHOUT ANY WARRANTY.  No author or distributor
                      8: accepts responsibility to anyone for the consequences of using it
                      9: or for whether it serves any particular purpose or works at all,
                     10: unless he says so in writing.  Refer to the GNU CC General Public
                     11: License for full details.
                     12: 
                     13: Everyone is granted permission to copy, modify and redistribute
                     14: GNU CC, but only under the conditions described in the
                     15: GNU CC General Public License.   A copy of this license is
                     16: supposed to have been given to you along with GNU CC so you
                     17: can know your rights and responsibilities.  It should be in a
                     18: file named COPYING.  Among other things, the copyright notice
                     19: and this notice must be preserved on all copies.  */
                     20: 
                     21: 
                     22: #include "config.h"
                     23: #include "rtl.h"
                     24: #include <stdio.h>
                     25: #include "insn-config.h"
                     26: #include "recog.h"
                     27: #include "regs.h"
                     28: #include "hard-reg-set.h"
                     29: 
                     30: static int inequality_comparisons_p ();
                     31: 
                     32: /* Nonzero means allow operands to be volatile.
                     33:    This is 1 if you use recog_memoized, 0 if you don't.
                     34:    init_recog and recog_memoized are responsible for setting it.
                     35:    This way of handling it is not really clean and will be change later.  */
                     36: 
                     37: int volatile_ok;
                     38: 
                     39: rtx recog_addr_dummy;
                     40: 
                     41: /* On return from `constrain_operands', indicate which alternative
                     42:    was satisfied.  */
                     43: 
                     44: int which_alternative;
                     45: 
                     46: /* Initialize data used by the function `recog'.
                     47:    This must be called once in the compilation of a function
                     48:    before any insn recognition may be done in the function.  */
                     49: 
                     50: void
                     51: init_recog ()
                     52: {
                     53:   volatile_ok = 0;
                     54:   recog_addr_dummy = gen_rtx (MEM, VOIDmode, 0);
                     55: }
                     56: 
                     57: /* Try recognizing the instruction INSN,
                     58:    and return the code number that results.
                     59:    Remeber the code so that repeated calls do not
                     60:    need to spend the time for actual rerecognition.
                     61: 
                     62:    This function is the normal interface to instruction recognition.
                     63:    The automatically-generated function `recog' is normally called
                     64:    through this one.  (The only exception is in combine.c.)  */
                     65: 
                     66: int
                     67: recog_memoized (insn)
                     68:      rtx insn;
                     69: {
                     70:   volatile_ok = 1;
                     71:   if (INSN_CODE (insn) < 0)
                     72:     INSN_CODE (insn) = recog (PATTERN (insn), insn);
                     73:   return INSN_CODE (insn);
                     74: }
                     75: 
                     76: /* Return 1 if the insn following INSN does not contain
                     77:    any ordered tests applied to the condition codes.
                     78:    EQ and NE tests do not count.  */
                     79: 
                     80: int
                     81: next_insn_tests_no_inequality (insn)
                     82:      rtx insn;
                     83: {
                     84:   register rtx next = NEXT_INSN (insn);
                     85: 
                     86:   return ((GET_CODE (next) == JUMP_INSN
                     87:           || GET_CODE (next) == INSN
                     88:           || GET_CODE (next) == CALL_INSN)
                     89:          && ! inequality_comparisons_p (PATTERN (next)));
                     90: }
                     91: 
                     92: static int
                     93: inequality_comparisons_p (x)
                     94:      rtx x;
                     95: {
                     96:   register char *fmt;
                     97:   register int len, i;
                     98:   register enum rtx_code code = GET_CODE (x);
                     99: 
                    100:   switch (code)
                    101:     {
                    102:     case REG:
                    103:     case PC:
                    104:     case CC0:
                    105:     case CONST_INT:
                    106:     case CONST_DOUBLE:
                    107:     case CONST:
                    108:     case LABEL_REF:
                    109:     case SYMBOL_REF:
                    110:       return 0;
                    111: 
                    112:     case LT:
                    113:     case LTU:
                    114:     case GT:
                    115:     case GTU:
                    116:     case LE:
                    117:     case LEU:
                    118:     case GE:
                    119:     case GEU:
                    120:       return (XEXP (x, 0) == cc0_rtx || XEXP (x, 1) == cc0_rtx);
                    121:     }
                    122: 
                    123:   len = GET_RTX_LENGTH (code);
                    124:   fmt = GET_RTX_FORMAT (code);
                    125: 
                    126:   for (i = 0; i < len; i++)
                    127:     {
                    128:       if (fmt[i] == 'e')
                    129:        {
                    130:          if (inequality_comparisons_p (XEXP (x, i)))
                    131:            return 1;
                    132:        }
                    133:       else if (fmt[i] == 'E')
                    134:        {
                    135:          register int j;
                    136:          for (j = XVECLEN (x, i) - 1; j >= 0; j--)
                    137:            if (inequality_comparisons_p (XVECEXP (x, i, j)))
                    138:              return 1;
                    139:        }
                    140:     }
                    141:            
                    142:   return 0;
                    143: }
                    144: 
                    145: /* Return 1 if OP is a valid general operand for machine mode MODE.
                    146:    This is either a register reference, a memory reference,
                    147:    or a constant.  In the case of a memory reference, the address
                    148:    is checked for general validity for the target machine.
                    149: 
                    150:    Register and memory references must have mode MODE in order to be valid,
                    151:    but some constants have no machine mode and are valid for any mode.
                    152: 
                    153:    If MODE is VOIDmode, OP is checked for validity for whatever mode
                    154:    it has.
                    155: 
                    156:    The main use of this function is as a predicate in match_operand
                    157:    expressions in the machine description.  */
                    158: 
                    159: int
                    160: general_operand (op, mode)
                    161:      register rtx op;
                    162:      enum machine_mode mode;
                    163: {
                    164:   register enum rtx_code code = GET_CODE (op);
                    165:   int mode_altering_drug = 0;
                    166: 
                    167:   if (mode == VOIDmode)
                    168:     mode = GET_MODE (op);
                    169: 
                    170:   if (CONSTANT_P (op))
                    171:     return ((GET_MODE (op) == VOIDmode || GET_MODE (op) == mode)
                    172:            && LEGITIMATE_CONSTANT_P (op));
                    173: 
                    174:   /* Except for certain constants with VOIDmode, already checked for,
                    175:      OP's mode must match MODE if MODE specifies a mode.  */
                    176: 
                    177:   if (GET_MODE (op) != mode)
                    178:     return 0;
                    179: 
                    180:   while (code == SUBREG)
                    181:     {
                    182:       op = SUBREG_REG (op);
                    183:       code = GET_CODE (op);
                    184:       mode_altering_drug = 1;
                    185:     }
                    186:   if (code == REG)
                    187:     return 1;
                    188:   if (code == CONST_DOUBLE)
                    189:     return LEGITIMATE_CONSTANT_P (op);
                    190:   if (code == MEM)
                    191:     {
                    192:       register rtx y = XEXP (op, 0);
                    193:       if (! volatile_ok && op->volatil)
                    194:        return 0;
                    195:       GO_IF_LEGITIMATE_ADDRESS (mode, y, win);
                    196:     }
                    197:   return 0;
                    198: 
                    199:  win:
                    200:   if (mode_altering_drug)
                    201:     return ! mode_dependent_address_p (XEXP (op, 0));
                    202:   return 1;
                    203: }
                    204: 
                    205: /* Return 1 if OP is a valid memory address for a memory reference
                    206:    of mode MODE.
                    207: 
                    208:    The main use of this function is as a predicate in match_operand
                    209:    expressions in the machine description.  */
                    210: 
                    211: int
                    212: address_operand (op, mode)
                    213:      register rtx op;
                    214:      enum machine_mode mode;
                    215: {
                    216:   return memory_address_p (mode, op);
                    217: }
                    218: 
                    219: /* Return 1 if OP is a register reference of mode MODE.
                    220:    If MODE is VOIDmode, accept a register in any mode.
                    221: 
                    222:    The main use of this function is as a predicate in match_operand
                    223:    expressions in the machine description.  */
                    224: 
                    225: int
                    226: register_operand (op, mode)
                    227:      register rtx op;
                    228:      enum machine_mode mode;
                    229: {
                    230:   if (GET_MODE (op) != mode && mode != VOIDmode)
                    231:     return 0;
                    232: 
                    233:   while (GET_CODE (op) == SUBREG)
                    234:     op = SUBREG_REG (op);
                    235: 
                    236:   return GET_CODE (op) == REG;
                    237: }
                    238: 
                    239: /* Return 1 if OP is a valid immediate operand for mode MODE.
                    240: 
                    241:    The main use of this function is as a predicate in match_operand
                    242:    expressions in the machine description.  */
                    243: 
                    244: int
                    245: immediate_operand (op, mode)
                    246:      register rtx op;
                    247:      enum machine_mode mode;
                    248: {
                    249:   return ((CONSTANT_P (op)
                    250:           || (GET_CODE (op) == CONST_DOUBLE
                    251:               && (GET_MODE (op) == mode || mode == VOIDmode)))
                    252:          && LEGITIMATE_CONSTANT_P (op));
                    253: }
                    254: 
                    255: /* Return 1 if OP is a register reference or immediate value of mode MODE.  */
                    256: 
                    257: int
                    258: nonmemory_operand (op, mode)
                    259:      register rtx op;
                    260:      enum machine_mode mode;
                    261: {
                    262:   if (CONSTANT_P (op)
                    263:       || (GET_CODE (op) == CONST_DOUBLE
                    264:          && (GET_MODE (op) == mode || mode == VOIDmode)))
                    265:     return LEGITIMATE_CONSTANT_P (op);
                    266: 
                    267:   if (GET_MODE (op) != mode && mode != VOIDmode)
                    268:     return 0;
                    269: 
                    270:   while (GET_CODE (op) == SUBREG)
                    271:     op = SUBREG_REG (op);
                    272: 
                    273:   return GET_CODE (op) == REG;
                    274: }
                    275: 
                    276: /* Return 1 if OP is a valid operand that stands for pushing a
                    277:    value of mode MODE onto the stack.
                    278: 
                    279:    The main use of this function is as a predicate in match_operand
                    280:    expressions in the machine description.  */
                    281: 
                    282: int
                    283: push_operand (op, mode)
                    284:      rtx op;
                    285:      enum machine_mode mode;
                    286: {
                    287:   if (GET_CODE (op) != MEM)
                    288:     return 0;
                    289: 
                    290:   if (GET_MODE (op) != mode)
                    291:     return 0;
                    292: 
                    293:   op = XEXP (op, 0);
                    294: 
                    295: #ifdef STACK_GROWS_DOWNWARD
                    296:   if (GET_CODE (op) != PRE_DEC)
                    297:     return 0;
                    298: #else
                    299:   if (GET_CODE (op) != PRE_INC)
                    300:     return 0;
                    301: #endif
                    302:   return REGNO (XEXP (op, 0)) == STACK_POINTER_REGNUM;
                    303: }
                    304: 
                    305: /* Return 1 if ADDR is a valid memory address for mode MODE.  */
                    306: 
                    307: int
                    308: memory_address_p (mode, addr)
                    309:      enum machine_mode mode;
                    310:      register rtx addr;
                    311: {
                    312:   GO_IF_LEGITIMATE_ADDRESS (mode, addr, win);
                    313:   return 0;
                    314: 
                    315:  win:
                    316:   return 1;
                    317: }
                    318: 
                    319: /* Return 1 if OP is a valid memory reference with mode MODE,
                    320:    including a valid address.
                    321: 
                    322:    The main use of this function is as a predicate in match_operand
                    323:    expressions in the machine description.  */
                    324: 
                    325: int
                    326: memory_operand (op, mode)
                    327:      register rtx op;
                    328:      enum machine_mode mode;
                    329: {
                    330:   return GET_CODE (op) == MEM && general_operand (op, mode);
                    331: }
                    332: 
                    333: /* If BODY is an insn body that uses ASM_OPERANDS,
                    334:    return the number of operands (both input and output) in the insn.
                    335:    Otherwise return 0.  */
                    336: 
                    337: int
                    338: asm_noperands (body)
                    339:      rtx body;
                    340: {
                    341:   int noperands;
                    342: 
                    343:   if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
                    344:     /* Single output operand: BODY is (set OUTPUT (asm_operands ...)).  */
                    345:     return XVECLEN (SET_SRC (body), 3) + 1;
                    346:   else if (GET_CODE (body) == PARALLEL
                    347:           && GET_CODE (XVECEXP (body, 0, 0)) == SET
                    348:           && GET_CODE (SET_SRC (XVECEXP (body, 0, 0))) == ASM_OPERANDS)
                    349:     /* Multiple outputs: BODY is
                    350:        (parallel [(set OUTPUT0 (asm_operands ...)) ...]).  */
                    351:     return XVECLEN (SET_SRC (XVECEXP (body, 0, 0)), 3) + XVECLEN (body, 0);
                    352:   else
                    353:     return 0;
                    354: }
                    355: 
                    356: /* Assuming BODY is an insn body that uses ASM_OPERANDS,
                    357:    copy its operands (both input and output) into the vector OPERANDS,
                    358:    the locations of the operands within the insn into the vector OPERAND_LOCS,
                    359:    and the constraints for the operands into CONSTRAINTS.
                    360:    Write the modes of the operands into MODES.
                    361:    Return the assembler-template.
                    362: 
                    363:    If MODES, OPERAND_LOCS, CONSTRAINTS or OPERANDS is 0,
                    364:    we don't store that info.  */
                    365: 
                    366: char *
                    367: decode_asm_operands (body, operands, operand_locs, constraints, modes)
                    368:      rtx body;
                    369:      rtx *operands;
                    370:      rtx **operand_locs;
                    371:      char **constraints;
                    372:      enum machine_mode *modes;
                    373: {
                    374:   register int i;
                    375:   int noperands;
                    376:   char *template;
                    377: 
                    378:   if (GET_CODE (body) == SET && GET_CODE (SET_SRC (body)) == ASM_OPERANDS)
                    379:     {
                    380:       rtx asmop = SET_SRC (body);
                    381:       /* Single output operand: BODY is (set OUTPUT (asm_operands ....)).  */
                    382: 
                    383:       noperands = XVECLEN (asmop, 3) + 1;
                    384: 
                    385:       /* The input operands are found in the 1st element vector.  */
                    386:       /* Constraints for inputs are in the 2nd element vector.  */
                    387:       for (i = 1; i < noperands; i++)
                    388:        {
                    389:          if (operand_locs)
                    390:            operand_locs[i] = &XVECEXP (asmop, 3, i - 1);
                    391:          if (operands)
                    392:            operands[i] = XVECEXP (asmop, 3, i - 1);
                    393:          if (constraints)
                    394:            constraints[i] = XSTR (XVECEXP (asmop, 4, i - 1), 0);
                    395:          if (modes)
                    396:            modes[i] = GET_MODE (XVECEXP (asmop, 4, i - 1));
                    397:        }
                    398: 
                    399:       /* The output is in the SET.
                    400:         Its constraint is in the ASM_OPERANDS itself.  */
                    401:       if (operands)
                    402:        operands[0] = SET_DEST (body);
                    403:       if (operand_locs)
                    404:        operand_locs[0] = &SET_DEST (body);
                    405:       if (constraints)
                    406:        constraints[0] = XSTR (asmop, 1);
                    407:       if (modes)
                    408:        modes[0] = GET_MODE (SET_DEST (body));
                    409:       template = XSTR (asmop, 0);
                    410:     }
                    411:   else
                    412:     {
                    413:       rtx asmop = SET_SRC (XVECEXP (body, 0, 0));
                    414:       int nout = XVECLEN (body, 0);
                    415:       int nin = XVECLEN (asmop, 3);
                    416: 
                    417:       noperands = XVECLEN (asmop, 3) + XVECLEN (body, 0);
                    418: 
                    419:       /* The input operands are found in the 1st element vector.  */
                    420:       /* Constraints for inputs are in the 2nd element vector.  */
                    421:       for (i = 0; i < nin; i++)
                    422:        {
                    423:          if (operand_locs)
                    424:            operand_locs[i + nout] = &XVECEXP (asmop, 3, i);
                    425:          if (operands)
                    426:            operands[i + nout] = XVECEXP (asmop, 3, i);
                    427:          if (constraints)
                    428:            constraints[i + nout] = XSTR (XVECEXP (asmop, 4, i), 0);
                    429:          if (modes)
                    430:            modes[i + nout] = GET_MODE (XVECEXP (asmop, 4, i));
                    431:        }
                    432:       /* The outputs are in the SETs.
                    433:         Their constraints are in the ASM_OPERANDS itself.  */
                    434:       for (i = 0; i < nout; i++)
                    435:        {
                    436:          if (operands)
                    437:            operands[i] = SET_DEST (XVECEXP (body, 0, i));
                    438:          if (operand_locs)
                    439:            operand_locs[i] = &SET_DEST (XVECEXP (body, 0, i));
                    440:          if (constraints)
                    441:            constraints[i] = XSTR (SET_SRC (XVECEXP (body, 0, i)), 1);
                    442:          if (modes)
                    443:            modes[i] = GET_MODE (SET_DEST (XVECEXP (body, 0, i)));
                    444:        }
                    445:       template = XSTR (asmop, 0);
                    446:     }
                    447: 
                    448:   return template;
                    449: }
                    450: 
                    451: extern rtx plus_constant ();
                    452: extern rtx copy_rtx ();
                    453: 
                    454: /* Given an rtx *P, if it is a sum containing an integer constant term,
                    455:    return the location (type rtx *) of the pointer to that constant term.
                    456:    Otherwise, return a null pointer.  */
                    457: 
                    458: static rtx *
                    459: find_constant_term_loc (p)
                    460:      rtx *p;
                    461: {
                    462:   register rtx *tem;
                    463:   register enum rtx_code code = GET_CODE (*p);
                    464: 
                    465:   /* If *P IS such a constant term, P is its location.  */
                    466: 
                    467:   if (code == CONST_INT || code == SYMBOL_REF || code == LABEL_REF
                    468:       || code == CONST)
                    469:     return p;
                    470: 
                    471:   /* Otherwise, if not a sum, it has no constant term.  */
                    472: 
                    473:   if (GET_CODE (*p) != PLUS)
                    474:     return 0;
                    475: 
                    476:   /* If one of the summands is constant, return its location.  */
                    477: 
                    478:   if (XEXP (*p, 0) && CONSTANT_P (XEXP (*p, 0))
                    479:       && XEXP (*p, 1) && CONSTANT_P (XEXP (*p, 1)))
                    480:     return p;
                    481: 
                    482:   /* Otherwise, check each summand for containing a constant term.  */
                    483: 
                    484:   if (XEXP (*p, 0) != 0)
                    485:     {
                    486:       tem = find_constant_term_loc (&XEXP (*p, 0));
                    487:       if (tem != 0)
                    488:        return tem;
                    489:     }
                    490: 
                    491:   if (XEXP (*p, 1) != 0)
                    492:     {
                    493:       tem = find_constant_term_loc (&XEXP (*p, 1));
                    494:       if (tem != 0)
                    495:        return tem;
                    496:     }
                    497: 
                    498:   return 0;
                    499: }
                    500: 
                    501: /* Return 1 if OP is a memory reference
                    502:    whose address contains no side effects
                    503:    and remains valid after the addition
                    504:    of a positive integer less than the
                    505:    size of the object being referenced.
                    506: 
                    507:    We assume that the original address is valid and do not check it.  */
                    508: 
                    509: int
                    510: offsetable_memref_p (op)
                    511:      rtx op;
                    512: {
                    513:   return ((GET_CODE (op) == MEM)
                    514:          && offsetable_address_p (GET_MODE (op), XEXP (op, 0)));
                    515: }
                    516: 
                    517: /* Return 1 if Y is a memory address which contains no side effects
                    518:    and would remain valid for mode MODE
                    519:    after the addition of a positive integer less than the
                    520:    size of that mode.
                    521: 
                    522:    We assume that the original address is valid and do not check it.  */
                    523: 
                    524: int
                    525: offsetable_address_p (mode, y)
                    526:      enum machine_mode mode;
                    527:      register rtx y;
                    528: {
                    529:   register enum rtx_code ycode = GET_CODE (y);
                    530:   register rtx z;
                    531:   rtx y1 = y;
                    532:   rtx *y2;
                    533: 
                    534:   if (CONSTANT_ADDRESS_P (y))
                    535:     return 1;
                    536:       
                    537:   /* If the expression contains a constant term,
                    538:      see if it remains valid when max possible offset is added.  */
                    539: 
                    540:   if ((ycode == PLUS) && (y2 = find_constant_term_loc (&y1)))
                    541:     {
                    542:       int old = INTVAL (y1 = *y2);
                    543:       int good;
                    544:       INTVAL (y1) += GET_MODE_SIZE (mode) - 1;
                    545:       good = memory_address_p (mode, y);
                    546:       /* In any case, restore old contents of memory.  */
                    547:       INTVAL (y1) = old;
                    548:       return good;
                    549:     }
                    550: 
                    551:   if (ycode == PRE_DEC || ycode == PRE_INC
                    552:       || ycode == POST_DEC || ycode == POST_INC)
                    553:     return 0;
                    554: 
                    555:   /* The offset added here is chosen as the maximum offset that
                    556:      any instruction could need to add when operating on something
                    557:      of the specified mode.  We assume that if Y and Y+c are
                    558:      valid addresses then so is Y+d for all 0<d<c.  */
                    559: 
                    560:   z = plus_constant (y, GET_MODE_SIZE (mode) - 1);
                    561: 
                    562:   return memory_address_p (mode, z);
                    563: }
                    564: 
                    565: /* Return 1 if ADDR is an address-expression whose effect depends
                    566:    on the mode of the memory reference it is used in.
                    567: 
                    568:    Autoincrement addressing is a typical example of mode-dependence
                    569:    because the amount of the increment depends on the mode.  */
                    570: 
                    571: int
                    572: mode_dependent_address_p (addr)
                    573:      rtx addr;
                    574: {
                    575:   GO_IF_MODE_DEPENDENT_ADDRESS (addr, win);
                    576:   return 0;
                    577:  win:
                    578:   return 1;
                    579: }
                    580: 
                    581: /* Return 1 if OP is a general operand
                    582:    other than a memory ref with a mode dependent address.  */
                    583: 
                    584: int
                    585: mode_independent_operand (mode, op)
                    586:      rtx op;
                    587: {
                    588:   rtx addr;
                    589: 
                    590:   if (! general_operand (mode, op))
                    591:     return 0;
                    592: 
                    593:   if (GET_CODE (op) != MEM)
                    594:     return 1;
                    595: 
                    596:   addr = XEXP (op, 0);
                    597:   GO_IF_MODE_DEPENDENT_ADDRESS (addr, lose);
                    598:   return 1;
                    599:  lose:
                    600:   return 0;
                    601: }
                    602: 
                    603: /* Given an operand OP that is a valid memory reference
                    604:    which satisfies offsetable_memref_p,
                    605:    return a new memory reference whose address has been adjusted by OFFSET.
                    606:    OFFSET should be positive and less than the size of the object referenced.
                    607: */
                    608: 
                    609: rtx
                    610: adj_offsetable_operand (op, offset)
                    611:      rtx op;
                    612:      int offset;
                    613: {
                    614:   register enum rtx_code code = GET_CODE (op);
                    615: 
                    616:   if (code == MEM) 
                    617:     {
                    618:       register rtx y = XEXP (op, 0);
                    619: 
                    620:       if (CONSTANT_ADDRESS_P (y))
                    621:        return gen_rtx (MEM, GET_MODE (op), plus_constant (y, offset));
                    622: 
                    623:       if (GET_CODE (y) == PLUS)
                    624:        {
                    625:          rtx z = y;
                    626:          register rtx *const_loc;
                    627: 
                    628:          op = copy_rtx (op);
                    629:          z = XEXP (op, 0);
                    630:          const_loc = find_constant_term_loc (&z);
                    631:          if (const_loc)
                    632:            {
                    633:              *const_loc = plus_constant (*const_loc, offset);
                    634:              return op;
                    635:            }
                    636:        }
                    637: 
                    638:       return gen_rtx (MEM, GET_MODE (op), plus_constant (y, offset));
                    639:     }
                    640:   abort ();
                    641: }
                    642: 
                    643: #ifdef REGISTER_CONSTRAINTS
                    644: 
                    645: /* Check the operands of an insn (found in recog_operands)
                    646:    against the insn's operand constraints (found via INSN_CODE_NUM)
                    647:    and return 1 if they are valid.
                    648: 
                    649:    WHICH_ALTERNATIVE is set to a number which indicates which
                    650:    alternative of constraints was matched: 0 for the first alternative,
                    651:    1 for the next, etc.
                    652: 
                    653:    In addition, when two operands are match
                    654:    and it happens that the output operand is (reg) while the
                    655:    input operand is --(reg) or ++(reg) (a pre-inc or pre-dec),
                    656:    make the output operand look like the input.
                    657:    This is because the output operand is the one the template will print.
                    658: 
                    659:    This is used in final, just before printing the assembler code.  */
                    660: 
                    661: struct funny_match
                    662: {
                    663:   int this, other;
                    664: };
                    665: 
                    666: int
                    667: constrain_operands (insn_code_num)
                    668:      int insn_code_num;
                    669: {
                    670:   char *constraints[MAX_RECOG_OPERANDS];
                    671:   register int c;
                    672:   int noperands = insn_n_operands[insn_code_num];
                    673: 
                    674:   struct funny_match funny_match[MAX_RECOG_OPERANDS];
                    675:   int funny_match_index;
                    676: 
                    677:   if (noperands == 0)
                    678:     return 1;
                    679: 
                    680:   for (c = 0; c < noperands; c++)
                    681:     constraints[c] = insn_operand_constraint[insn_code_num][c];
                    682: 
                    683:   which_alternative = 0;
                    684: 
                    685:   while (*constraints[0])
                    686:     {
                    687:       register int opno;
                    688:       int lose = 0;
                    689:       funny_match_index = 0;
                    690: 
                    691:       for (opno = 0; opno < noperands; opno++)
                    692:        {
                    693:          register rtx op = recog_operand[opno];
                    694:          register char *p = constraints[opno];
                    695:          int win = 0;
                    696:          int val;
                    697: 
                    698:          /* `alter_subreg' should already have converted any SUBREG
                    699:             that appears at the level of an operand.  */
                    700:          while (GET_CODE (op) == SUBREG)
                    701:            abort ();
                    702: 
                    703:          while (*p && (c = *p++) != ',')
                    704:            switch (c)
                    705:              {
                    706:              case '=':
                    707:              case '+':
                    708:              case '?':
                    709:              case '#':
                    710:              case '!':
                    711:              case '*':
                    712:              case '%':
                    713:                break;
                    714: 
                    715:              case '0':
                    716:              case '1':
                    717:              case '2':
                    718:              case '3':
                    719:              case '4':
                    720:                /* This operand must be the same as a previous one.  */
                    721:                /* This kind of constraint is used for instructions such
                    722:                   as add when they take only two operands.  */
                    723:                /* Note that the lower-numbered operand is passed first.  */
                    724:                val = operands_match_p (recog_operand[c - '0'],
                    725:                                        recog_operand[opno]);
                    726:                if (val != 0)
                    727:                  win = 1;
                    728:                /* If output is *x and input is *--x,
                    729:                   arrange later to change the output to *--x as well,
                    730:                   since the output op is the one that will be printed.  */
                    731:                if (val == 2)
                    732:                  {
                    733:                    funny_match[funny_match_index].this = opno;
                    734:                    funny_match[funny_match_index++].other = c - '0';
                    735:                  }
                    736:                break;
                    737: 
                    738:              case 'p':
                    739:                /* p is used for address_operands, and everything
                    740:                   that must be checked was checked already.  */
                    741:                win = 1;
                    742:                break;
                    743: 
                    744:                /* No need to check general_operand again;
                    745:                   it was done in insn-recog.c.  */
                    746:              case 'g':
                    747:                /* Anything goes unless it is a REG and really has a hard reg
                    748:                   but the hard reg is not in the class GENERAL_REGS.  */
                    749:                if (GENERAL_REGS == ALL_REGS
                    750:                    || GET_CODE (op) != REG
                    751:                    || (REGNO (op) >= FIRST_PSEUDO_REGISTER
                    752:                        && reg_renumber[REGNO (op)] < 0)
                    753:                    || reg_renumbered_fits_class_p (op, GENERAL_REGS, 0,
                    754:                                                    GET_MODE (op)))
                    755:                  win = 1;
                    756:                break;
                    757: 
                    758:              case 'r':
                    759:                if (GET_CODE (op) == REG
                    760:                    && (GENERAL_REGS == ALL_REGS
                    761:                        || reg_renumbered_fits_class_p (op, GENERAL_REGS,
                    762:                                                        0, GET_MODE (op))))
                    763:                  win = 1;
                    764:                break;
                    765: 
                    766:              case 'm':
                    767:                if (GET_CODE (op) == MEM)
                    768:                  win = 1;
                    769:                break;
                    770: 
                    771:              case '<':
                    772:                if (GET_CODE (op) == MEM
                    773:                    && (GET_CODE (XEXP (op, 0)) == PRE_DEC
                    774:                        || GET_CODE (XEXP (op, 0)) == POST_DEC))
                    775:                  win = 1;
                    776:                break;
                    777: 
                    778:              case '>':
                    779:                if (GET_CODE (op) == MEM
                    780:                    && (GET_CODE (XEXP (op, 0)) == PRE_INC
                    781:                        || GET_CODE (XEXP (op, 0)) == POST_INC))
                    782:                  win = 1;
                    783:                break;
                    784: 
                    785:              case 'F':
                    786:                if (GET_CODE (op) == CONST_DOUBLE)
                    787:                  win = 1;
                    788:                break;
                    789: 
                    790:              case 'G':
                    791:              case 'H':
                    792:                if (GET_CODE (op) == CONST_DOUBLE
                    793:                    && CONST_DOUBLE_OK_FOR_LETTER_P (op, c))
                    794:                  win = 1;
                    795:                break;
                    796: 
                    797:              case 's':
                    798:                if (GET_CODE (op) == CONST_INT)
                    799:                  break;
                    800:              case 'i':
                    801:                if (CONSTANT_P (op))
                    802:                  win = 1;
                    803:                break;
                    804: 
                    805:              case 'n':
                    806:                if (GET_CODE (op) == CONST_INT)
                    807:                  win = 1;
                    808:                break;
                    809: 
                    810:              case 'I':
                    811:              case 'J':
                    812:              case 'K':
                    813:              case 'L':
                    814:              case 'M':
                    815:                if (GET_CODE (op) == CONST_INT
                    816:                    && CONST_OK_FOR_LETTER_P (INTVAL (op), c))
                    817:                  win = 1;
                    818:                break;
                    819: 
                    820:              case 'o':
                    821:                if (offsetable_memref_p (op))
                    822:                  win = 1;
                    823:                break;
                    824: 
                    825:              default:
                    826:                if (GET_CODE (op) == REG
                    827:                    && reg_renumbered_fits_class_p (op,
                    828:                                                    REG_CLASS_FROM_LETTER (c),
                    829:                                                    0, GET_MODE (op)))
                    830:                  win = 1;
                    831:              }
                    832: 
                    833:          constraints[opno] = p;
                    834:          /* If this operand did not win somehow,
                    835:             this alternative loses.  */
                    836:          if (! win)
                    837:            lose = 1;
                    838:        }
                    839:       /* This alternative won; the operands are ok.
                    840:         Change whichever operands this alternative says to change.  */
                    841:       if (! lose)
                    842:        {
                    843:          while (--funny_match_index >= 0)
                    844:            {
                    845:              recog_operand[funny_match[funny_match_index].other]
                    846:                = recog_operand[funny_match[funny_match_index].this];
                    847:            }
                    848:          return 1;
                    849:        }
                    850: 
                    851:       which_alternative++;
                    852:     }
                    853:   return 0;
                    854: }
                    855: 
                    856: /* Return 1 iff OPERAND (assumed to be a REG rtx)
                    857:    is a hard reg in class CLASS when its regno is offsetted by OFFSET
                    858:    and changed to mode MODE,
                    859:    or is a pseudo reg allocated into such a hard reg.
                    860:    If REG occupies multiple hard regs, all of them must by in CLASS.  */
                    861: 
                    862: int
                    863: reg_renumbered_fits_class_p (operand, class, offset, mode)
                    864:      rtx operand;
                    865:      register enum reg_class class;
                    866:      int offset;
                    867:      enum machine_mode mode;
                    868: {
                    869:   if (GET_CODE (operand) == REG)
                    870:     {
                    871:       register int regno = REGNO (operand);
                    872:       if (reg_renumber[regno] >= 0)
                    873:        regno = reg_renumber[regno];
                    874:       if (regno < FIRST_PSEUDO_REGISTER
                    875:          && TEST_HARD_REG_BIT (reg_class_contents[(int) class],
                    876:                                regno + offset))
                    877:        {
                    878:          register int sr;
                    879:          regno += offset;
                    880:          for (sr = HARD_REGNO_NREGS (regno, mode) - 1;
                    881:               sr > 0; sr--)
                    882:            if (! TEST_HARD_REG_BIT (reg_class_contents[(int) class],
                    883:                                     regno + sr))
                    884:              break;
                    885:          return sr == 0;
                    886:        }
                    887:     }
                    888:   return 0;
                    889: }
                    890: 
                    891: #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.