Annotation of GNUtools/cc/rtl.c, revision 1.1

1.1     ! root        1: /* Allocate and read RTL for GNU C Compiler.
        !             2:    Copyright (C) 1987, 1988, 1991 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 <ctype.h>
        !            23: #include <stdio.h>
        !            24: #include "rtl.h"
        !            25: #include "real.h"
        !            26: 
        !            27: #include "obstack.h"
        !            28: #define        obstack_chunk_alloc     xmalloc
        !            29: #define        obstack_chunk_free      free
        !            30: 
        !            31: /* Obstack used for allocating RTL objects.
        !            32:    Between functions, this is the permanent_obstack.
        !            33:    While parsing and expanding a function, this is maybepermanent_obstack
        !            34:    so we can save it if it is an inline function.
        !            35:    During optimization and output, this is function_obstack.  */
        !            36: 
        !            37: extern struct obstack *rtl_obstack;
        !            38: 
        !            39: #if HOST_BITS_PER_WIDE_INT != HOST_BITS_PER_INT
        !            40: extern long atol();
        !            41: #endif
        !            42: 
        !            43: /* Indexed by rtx code, gives number of operands for an rtx with that code.
        !            44:    Does NOT include rtx header data (code and links).
        !            45:    This array is initialized in init_rtl.  */
        !            46: 
        !            47: int rtx_length[NUM_RTX_CODE + 1];
        !            48: 
        !            49: /* Indexed by rtx code, gives the name of that kind of rtx, as a C string.  */
        !            50: 
        !            51: #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   NAME ,
        !            52: 
        !            53: char *rtx_name[] = {
        !            54: #include "rtl.def"             /* rtl expressions are documented here */
        !            55: };
        !            56: 
        !            57: #undef DEF_RTL_EXPR
        !            58: 
        !            59: /* Indexed by machine mode, gives the name of that machine mode.
        !            60:    This name does not include the letters "mode".  */
        !            61: 
        !            62: #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER)  NAME,
        !            63: 
        !            64: char *mode_name[(int) MAX_MACHINE_MODE] = {
        !            65: #include "machmode.def"
        !            66: 
        !            67: #ifdef EXTRA_CC_MODES
        !            68:   EXTRA_CC_NAMES
        !            69: #endif
        !            70: 
        !            71: };
        !            72: 
        !            73: #undef DEF_MACHMODE
        !            74: 
        !            75: /* Indexed by machine mode, gives the length of the mode, in bytes.
        !            76:    GET_MODE_CLASS uses this.  */
        !            77: 
        !            78: #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER)  CLASS,
        !            79: 
        !            80: enum mode_class mode_class[(int) MAX_MACHINE_MODE] = {
        !            81: #include "machmode.def"
        !            82: };
        !            83: 
        !            84: #undef DEF_MACHMODE
        !            85: 
        !            86: /* Indexed by machine mode, gives the length of the mode, in bytes.
        !            87:    GET_MODE_SIZE uses this.  */
        !            88: 
        !            89: #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER)  SIZE,
        !            90: 
        !            91: int mode_size[(int) MAX_MACHINE_MODE] = {
        !            92: #include "machmode.def"
        !            93: };
        !            94: 
        !            95: #undef DEF_MACHMODE
        !            96: 
        !            97: /* Indexed by machine mode, gives the length of the mode's subunit.
        !            98:    GET_MODE_UNIT_SIZE uses this.  */
        !            99: 
        !           100: #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER)  UNIT,
        !           101: 
        !           102: int mode_unit_size[(int) MAX_MACHINE_MODE] = {
        !           103: #include "machmode.def"                /* machine modes are documented here */
        !           104: };
        !           105: 
        !           106: #undef DEF_MACHMODE
        !           107: 
        !           108: /* Indexed by machine mode, gives next wider natural mode
        !           109:    (QI -> HI -> SI -> DI, etc.)  Widening multiply instructions
        !           110:    use this.  */
        !           111: 
        !           112: #define DEF_MACHMODE(SYM, NAME, CLASS, SIZE, UNIT, WIDER)  \
        !           113:   (enum machine_mode) WIDER,
        !           114: 
        !           115: enum machine_mode mode_wider_mode[(int) MAX_MACHINE_MODE] = {
        !           116: #include "machmode.def"                /* machine modes are documented here */
        !           117: };
        !           118: 
        !           119: #undef DEF_MACHMODE
        !           120: 
        !           121: /* Indexed by mode class, gives the narrowest mode for each class.  */
        !           122: 
        !           123: enum machine_mode class_narrowest_mode[(int) MAX_MODE_CLASS];
        !           124: 
        !           125: /* Indexed by rtx code, gives a sequence of operand-types for
        !           126:    rtx's of that code.  The sequence is a C string in which
        !           127:    each character describes one operand.  */
        !           128: 
        !           129: char *rtx_format[] = {
        !           130:   /* "*" undefined.
        !           131:          can cause a warning message
        !           132:      "0" field is unused (or used in a phase-dependent manner)
        !           133:          prints nothing
        !           134:      "i" an integer
        !           135:          prints the integer
        !           136:      "n" like "i", but prints entries from `note_insn_name'
        !           137:      "w" an integer of width HOST_BITS_PER_WIDE_INT
        !           138:          prints the integer
        !           139:      "s" a pointer to a string
        !           140:          prints the string
        !           141:      "S" like "s", but optional:
        !           142:         the containing rtx may end before this operand
        !           143:      "e" a pointer to an rtl expression
        !           144:          prints the expression
        !           145:      "E" a pointer to a vector that points to a number of rtl expressions
        !           146:          prints a list of the rtl expressions
        !           147:      "V" like "E", but optional:
        !           148:         the containing rtx may end before this operand
        !           149:      "u" a pointer to another insn
        !           150:          prints the uid of the insn.  */
        !           151: 
        !           152: #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   FORMAT ,
        !           153: #include "rtl.def"             /* rtl expressions are defined here */
        !           154: #undef DEF_RTL_EXPR
        !           155: };
        !           156: 
        !           157: /* Indexed by rtx code, gives a character representing the "class" of
        !           158:    that rtx code.  See rtl.def for documentation on the defined classes.  */
        !           159: 
        !           160: char rtx_class[] = {
        !           161: #define DEF_RTL_EXPR(ENUM, NAME, FORMAT, CLASS)   CLASS, 
        !           162: #include "rtl.def"             /* rtl expressions are defined here */
        !           163: #undef DEF_RTL_EXPR
        !           164: };
        !           165: 
        !           166: /* Names for kinds of NOTEs and REG_NOTEs.  */
        !           167: 
        !           168: char *note_insn_name[] = { 0                    , "NOTE_INSN_DELETED",
        !           169:                           "NOTE_INSN_BLOCK_BEG", "NOTE_INSN_BLOCK_END",
        !           170:                           "NOTE_INSN_LOOP_BEG", "NOTE_INSN_LOOP_END",
        !           171:                           "NOTE_INSN_FUNCTION_END", "NOTE_INSN_SETJMP",
        !           172:                           "NOTE_INSN_LOOP_CONT", "NOTE_INSN_LOOP_VTOP",
        !           173:                           "NOTE_INSN_PROLOGUE_END", "NOTE_INSN_EPILOGUE_BEG",
        !           174:                           "NOTE_INSN_DELETED_LABEL", "NOTE_INSN_FUNCTION_BEG"};
        !           175: 
        !           176: char *reg_note_name[] = { "", "REG_DEAD", "REG_INC", "REG_EQUIV", "REG_WAS_0",
        !           177:                          "REG_EQUAL", "REG_RETVAL", "REG_LIBCALL",
        !           178:                          "REG_NONNEG", "REG_NO_CONFLICT", "REG_UNUSED",
        !           179:                          "REG_CC_SETTER", "REG_CC_USER", "REG_LABEL",
        !           180:                          "REG_DEP_ANTI", "REG_DEP_OUTPUT" };
        !           181: 
        !           182: /* Allocate an rtx vector of N elements.
        !           183:    Store the length, and initialize all elements to zero.  */
        !           184: 
        !           185: rtvec
        !           186: rtvec_alloc (n)
        !           187:      int n;
        !           188: {
        !           189:   rtvec rt;
        !           190:   int i;
        !           191: 
        !           192:   rt = (rtvec) obstack_alloc (rtl_obstack,
        !           193:                              sizeof (struct rtvec_def)
        !           194:                              + (( n - 1) * sizeof (rtunion)));
        !           195: 
        !           196:   /* clear out the vector */
        !           197:   PUT_NUM_ELEM(rt, n);
        !           198:   for (i=0; i < n; i++)
        !           199:     rt->elem[i].rtvec = NULL;  /* @@ not portable due to rtunion */
        !           200: 
        !           201:   return rt;
        !           202: }
        !           203: 
        !           204: /* Allocate an rtx of code CODE.  The CODE is stored in the rtx;
        !           205:    all the rest is initialized to zero.  */
        !           206: 
        !           207: rtx
        !           208: rtx_alloc (code)
        !           209:   RTX_CODE code;
        !           210: {
        !           211:   rtx rt;
        !           212:   register struct obstack *ob = rtl_obstack;
        !           213:   register int nelts = GET_RTX_LENGTH (code);
        !           214:   register int length = sizeof (struct rtx_def)
        !           215:     + (nelts - 1) * sizeof (rtunion);
        !           216: 
        !           217:   /* This function is called more than any other in GCC,
        !           218:      so we manipulate the obstack directly.
        !           219: 
        !           220:      Even though rtx objects are word aligned, we may be sharing an obstack
        !           221:      with tree nodes, which may have to be double-word aligned.  So align
        !           222:      our length to the alignment mask in the obstack.  */
        !           223: 
        !           224:   length = (length + ob->alignment_mask) & ~ ob->alignment_mask;
        !           225: 
        !           226:   if (ob->chunk_limit - ob->next_free < length)
        !           227:     _obstack_newchunk (ob, length);
        !           228:   rt = (rtx)ob->object_base;
        !           229:   ob->next_free += length;
        !           230:   ob->object_base = ob->next_free;
        !           231: 
        !           232:   /* We want to clear everything up to the FLD array.  Normally, this is
        !           233:      one int, but we don't want to assume that and it isn't very portable
        !           234:      anyway; this is.  */
        !           235: 
        !           236:   length = (sizeof (struct rtx_def) - sizeof (rtunion) - 1) / sizeof (int);
        !           237:   for (; length >= 0; length--)
        !           238:     ((int *) rt)[length] = 0;
        !           239: 
        !           240:   PUT_CODE (rt, code);
        !           241: 
        !           242:   return rt;
        !           243: }
        !           244: 
        !           245: /* Free the rtx X and all RTL allocated since X.  */
        !           246: 
        !           247: void
        !           248: rtx_free (x)
        !           249:      rtx x;
        !           250: {
        !           251:   obstack_free (rtl_obstack, x);
        !           252: }
        !           253: 
        !           254: /* Create a new copy of an rtx.
        !           255:    Recursively copies the operands of the rtx,
        !           256:    except for those few rtx codes that are sharable.  */
        !           257: 
        !           258: rtx
        !           259: copy_rtx (orig)
        !           260:      register rtx orig;
        !           261: {
        !           262:   register rtx copy;
        !           263:   register int i, j;
        !           264:   register RTX_CODE code;
        !           265:   register char *format_ptr;
        !           266: 
        !           267:   code = GET_CODE (orig);
        !           268: 
        !           269:   switch (code)
        !           270:     {
        !           271:     case REG:
        !           272:     case QUEUED:
        !           273:     case CONST_INT:
        !           274:     case CONST_DOUBLE:
        !           275:     case SYMBOL_REF:
        !           276:     case CODE_LABEL:
        !           277:     case PC:
        !           278:     case CC0:
        !           279:     case SCRATCH:
        !           280:       /* SCRATCH must be shared because they represent distinct values. */
        !           281:       return orig;
        !           282: 
        !           283:     case CONST:
        !           284:       /* CONST can be shared if it contains a SYMBOL_REF.  If it contains
        !           285:         a LABEL_REF, it isn't sharable.  */
        !           286:       if (GET_CODE (XEXP (orig, 0)) == PLUS
        !           287:          && GET_CODE (XEXP (XEXP (orig, 0), 0)) == SYMBOL_REF
        !           288:          && GET_CODE (XEXP (XEXP (orig, 0), 1)) == CONST_INT)
        !           289:        return orig;
        !           290:       break;
        !           291: 
        !           292:       /* A MEM with a constant address is not sharable.  The problem is that
        !           293:         the constant address may need to be reloaded.  If the mem is shared,
        !           294:         then reloading one copy of this mem will cause all copies to appear
        !           295:         to have been reloaded.  */
        !           296:     }
        !           297: 
        !           298:   copy = rtx_alloc (code);
        !           299:   PUT_MODE (copy, GET_MODE (orig));
        !           300:   copy->in_struct = orig->in_struct;
        !           301:   copy->volatil = orig->volatil;
        !           302:   copy->unchanging = orig->unchanging;
        !           303:   copy->integrated = orig->integrated;
        !           304:   
        !           305:   format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
        !           306: 
        !           307:   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
        !           308:     {
        !           309:       switch (*format_ptr++)
        !           310:        {
        !           311:        case 'e':
        !           312:          XEXP (copy, i) = XEXP (orig, i);
        !           313:          if (XEXP (orig, i) != NULL)
        !           314:            XEXP (copy, i) = copy_rtx (XEXP (orig, i));
        !           315:          break;
        !           316: 
        !           317:        case '0':
        !           318:        case 'u':
        !           319:          XEXP (copy, i) = XEXP (orig, i);
        !           320:          break;
        !           321: 
        !           322:        case 'E':
        !           323:        case 'V':
        !           324:          XVEC (copy, i) = XVEC (orig, i);
        !           325:          if (XVEC (orig, i) != NULL)
        !           326:            {
        !           327:              XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
        !           328:              for (j = 0; j < XVECLEN (copy, i); j++)
        !           329:                XVECEXP (copy, i, j) = copy_rtx (XVECEXP (orig, i, j));
        !           330:            }
        !           331:          break;
        !           332: 
        !           333:        case 'w':
        !           334:          XWINT (copy, i) = XWINT (orig, i);
        !           335:          break;
        !           336: 
        !           337:        case 'i':
        !           338:          XINT (copy, i) = XINT (orig, i);
        !           339:          break;
        !           340: 
        !           341:        case 's':
        !           342:        case 'S':
        !           343:          XSTR (copy, i) = XSTR (orig, i);
        !           344:          break;
        !           345: 
        !           346:        default:
        !           347:          abort ();
        !           348:        }
        !           349:     }
        !           350:   return copy;
        !           351: }
        !           352: 
        !           353: /* Similar to `copy_rtx' except that if MAY_SHARE is present, it is
        !           354:    placed in the result directly, rather than being copied.  */
        !           355: 
        !           356: rtx
        !           357: copy_most_rtx (orig, may_share)
        !           358:      register rtx orig;
        !           359:      register rtx may_share;
        !           360: {
        !           361:   register rtx copy;
        !           362:   register int i, j;
        !           363:   register RTX_CODE code;
        !           364:   register char *format_ptr;
        !           365: 
        !           366:   if (orig == may_share)
        !           367:     return orig;
        !           368: 
        !           369:   code = GET_CODE (orig);
        !           370: 
        !           371:   switch (code)
        !           372:     {
        !           373:     case REG:
        !           374:     case QUEUED:
        !           375:     case CONST_INT:
        !           376:     case CONST_DOUBLE:
        !           377:     case SYMBOL_REF:
        !           378:     case CODE_LABEL:
        !           379:     case PC:
        !           380:     case CC0:
        !           381:       return orig;
        !           382:     }
        !           383: 
        !           384:   copy = rtx_alloc (code);
        !           385:   PUT_MODE (copy, GET_MODE (orig));
        !           386:   copy->in_struct = orig->in_struct;
        !           387:   copy->volatil = orig->volatil;
        !           388:   copy->unchanging = orig->unchanging;
        !           389:   copy->integrated = orig->integrated;
        !           390:   
        !           391:   format_ptr = GET_RTX_FORMAT (GET_CODE (copy));
        !           392: 
        !           393:   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
        !           394:     {
        !           395:       switch (*format_ptr++)
        !           396:        {
        !           397:        case 'e':
        !           398:          XEXP (copy, i) = XEXP (orig, i);
        !           399:          if (XEXP (orig, i) != NULL && XEXP (orig, i) != may_share)
        !           400:            XEXP (copy, i) = copy_most_rtx (XEXP (orig, i), may_share);
        !           401:          break;
        !           402: 
        !           403:        case '0':
        !           404:        case 'u':
        !           405:          XEXP (copy, i) = XEXP (orig, i);
        !           406:          break;
        !           407: 
        !           408:        case 'E':
        !           409:        case 'V':
        !           410:          XVEC (copy, i) = XVEC (orig, i);
        !           411:          if (XVEC (orig, i) != NULL)
        !           412:            {
        !           413:              XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
        !           414:              for (j = 0; j < XVECLEN (copy, i); j++)
        !           415:                XVECEXP (copy, i, j)
        !           416:                  = copy_most_rtx (XVECEXP (orig, i, j), may_share);
        !           417:            }
        !           418:          break;
        !           419: 
        !           420:        case 'w':
        !           421:          XWINT (copy, i) = XWINT (orig, i);
        !           422:          break;
        !           423: 
        !           424:        case 'n':
        !           425:        case 'i':
        !           426:          XINT (copy, i) = XINT (orig, i);
        !           427:          break;
        !           428: 
        !           429:        case 's':
        !           430:        case 'S':
        !           431:          XSTR (copy, i) = XSTR (orig, i);
        !           432:          break;
        !           433: 
        !           434:        default:
        !           435:          abort ();
        !           436:        }
        !           437:     }
        !           438:   return copy;
        !           439: }
        !           440: 
        !           441: /* Subroutines of read_rtx.  */
        !           442: 
        !           443: /* Dump code after printing a message.  Used when read_rtx finds
        !           444:    invalid data.  */
        !           445: 
        !           446: static void
        !           447: dump_and_abort (expected_c, actual_c, infile)
        !           448:      int expected_c, actual_c;
        !           449:      FILE *infile;
        !           450: {
        !           451:   int c, i;
        !           452: 
        !           453:   if (expected_c >= 0)
        !           454:     fprintf (stderr,
        !           455:             "Expected character %c.  Found character %c.",
        !           456:             expected_c, actual_c);
        !           457:   fprintf (stderr, "  At file position: %ld\n", ftell (infile));
        !           458:   fprintf (stderr, "Following characters are:\n\t");
        !           459:   for (i = 0; i < 200; i++)
        !           460:     {
        !           461:       c = getc (infile);
        !           462:       if (EOF == c) break;
        !           463:       putc (c, stderr);
        !           464:     }
        !           465:   fprintf (stderr, "Aborting.\n");
        !           466:   abort ();
        !           467: }
        !           468: 
        !           469: /* Read chars from INFILE until a non-whitespace char
        !           470:    and return that.  Comments, both Lisp style and C style,
        !           471:    are treated as whitespace.
        !           472:    Tools such as genflags use this function.  */
        !           473: 
        !           474: int
        !           475: read_skip_spaces (infile)
        !           476:      FILE *infile;
        !           477: {
        !           478:   register int c;
        !           479:   while (c = getc (infile))
        !           480:     {
        !           481:       if (c == ' ' || c == '\n' || c == '\t' || c == '\f')
        !           482:        ;
        !           483:       else if (c == ';')
        !           484:        {
        !           485:          while ((c = getc (infile)) && c != '\n') ;
        !           486:        }
        !           487:       else if (c == '/')
        !           488:        {
        !           489:          register int prevc;
        !           490:          c = getc (infile);
        !           491:          if (c != '*')
        !           492:            dump_and_abort ('*', c, infile);
        !           493:          
        !           494:          prevc = 0;
        !           495:          while (c = getc (infile))
        !           496:            {
        !           497:              if (prevc == '*' && c == '/')
        !           498:                break;
        !           499:              prevc = c;
        !           500:            }
        !           501:        }
        !           502:       else break;
        !           503:     }
        !           504:   return c;
        !           505: }
        !           506: 
        !           507: /* Read an rtx code name into the buffer STR[].
        !           508:    It is terminated by any of the punctuation chars of rtx printed syntax.  */
        !           509: 
        !           510: static void
        !           511: read_name (str, infile)
        !           512:      char *str;
        !           513:      FILE *infile;
        !           514: {
        !           515:   register char *p;
        !           516:   register int c;
        !           517: 
        !           518:   c = read_skip_spaces(infile);
        !           519: 
        !           520:   p = str;
        !           521:   while (1)
        !           522:     {
        !           523:       if (c == ' ' || c == '\n' || c == '\t' || c == '\f')
        !           524:        break;
        !           525:       if (c == ':' || c == ')' || c == ']' || c == '"' || c == '/'
        !           526:          || c == '(' || c == '[')
        !           527:        {
        !           528:          ungetc (c, infile);
        !           529:          break;
        !           530:        }
        !           531:       *p++ = c;
        !           532:       c = getc (infile);
        !           533:     }
        !           534:   if (p == str)
        !           535:     {
        !           536:       fprintf (stderr, "missing name or number");
        !           537:       dump_and_abort (-1, -1, infile);
        !           538:     }
        !           539: 
        !           540:   *p = 0;
        !           541: }
        !           542: 
        !           543: /* Read an rtx in printed representation from INFILE
        !           544:    and return an actual rtx in core constructed accordingly.
        !           545:    read_rtx is not used in the compiler proper, but rather in
        !           546:    the utilities gen*.c that construct C code from machine descriptions.  */
        !           547: 
        !           548: rtx
        !           549: read_rtx (infile)
        !           550:      FILE *infile;
        !           551: {
        !           552:   register int i, j, list_counter;
        !           553:   RTX_CODE tmp_code;
        !           554:   register char *format_ptr;
        !           555:   /* tmp_char is a buffer used for reading decimal integers
        !           556:      and names of rtx types and machine modes.
        !           557:      Therefore, 256 must be enough.  */
        !           558:   char tmp_char[256];
        !           559:   rtx return_rtx;
        !           560:   register int c;
        !           561:   int tmp_int;
        !           562:   HOST_WIDE_INT tmp_wide;
        !           563: 
        !           564:   /* Linked list structure for making RTXs: */
        !           565:   struct rtx_list
        !           566:     {
        !           567:       struct rtx_list *next;
        !           568:       rtx value;               /* Value of this node...                */
        !           569:     };
        !           570: 
        !           571:   c = read_skip_spaces (infile); /* Should be open paren.  */
        !           572:   if (c != '(')
        !           573:     dump_and_abort ('(', c, infile);
        !           574: 
        !           575:   read_name (tmp_char, infile);
        !           576: 
        !           577:   tmp_code = UNKNOWN;
        !           578: 
        !           579:   for (i=0; i < NUM_RTX_CODE; i++) /* @@ might speed this search up */
        !           580:     {
        !           581:       if (!(strcmp (tmp_char, GET_RTX_NAME (i))))
        !           582:        {
        !           583:          tmp_code = (RTX_CODE) i;      /* get value for name */
        !           584:          break;
        !           585:        }
        !           586:     }
        !           587:   if (tmp_code == UNKNOWN)
        !           588:     {
        !           589:       fprintf (stderr,
        !           590:               "Unknown rtx read in rtl.read_rtx(). Code name was %s .",
        !           591:               tmp_char);
        !           592:     }
        !           593:   /* (NIL) stands for an expression that isn't there.  */
        !           594:   if (tmp_code == NIL)
        !           595:     {
        !           596:       /* Discard the closeparen.  */
        !           597:       while ((c = getc (infile)) && c != ')');
        !           598:       return 0;
        !           599:     }
        !           600: 
        !           601:   return_rtx = rtx_alloc (tmp_code); /* if we end up with an insn expression
        !           602:                                       then we free this space below.  */
        !           603:   format_ptr = GET_RTX_FORMAT (GET_CODE (return_rtx));
        !           604: 
        !           605:   /* If what follows is `: mode ', read it and
        !           606:      store the mode in the rtx.  */
        !           607: 
        !           608:   i = read_skip_spaces (infile);
        !           609:   if (i == ':')
        !           610:     {
        !           611:       register int k;
        !           612:       read_name (tmp_char, infile);
        !           613:       for (k = 0; k < NUM_MACHINE_MODES; k++)
        !           614:        if (!strcmp (GET_MODE_NAME (k), tmp_char))
        !           615:          break;
        !           616: 
        !           617:       PUT_MODE (return_rtx, (enum machine_mode) k );
        !           618:     }
        !           619:   else
        !           620:     ungetc (i, infile);
        !           621: 
        !           622:   for (i = 0; i < GET_RTX_LENGTH (GET_CODE (return_rtx)); i++)
        !           623:     switch (*format_ptr++)
        !           624:       {
        !           625:        /* 0 means a field for internal use only.
        !           626:           Don't expect it to be present in the input.  */
        !           627:       case '0':
        !           628:        break;
        !           629: 
        !           630:       case 'e':
        !           631:       case 'u':
        !           632:        XEXP (return_rtx, i) = read_rtx (infile);
        !           633:        break;
        !           634: 
        !           635:       case 'V':
        !           636:        /* 'V' is an optional vector: if a closeparen follows,
        !           637:           just store NULL for this element.  */
        !           638:        c = read_skip_spaces (infile);
        !           639:        ungetc (c, infile);
        !           640:        if (c == ')')
        !           641:          {
        !           642:            XVEC (return_rtx, i) = 0;
        !           643:            break;
        !           644:          }
        !           645:        /* Now process the vector.  */
        !           646:   
        !           647:       case 'E':
        !           648:        {
        !           649:          register struct rtx_list *next_rtx, *rtx_list_link;
        !           650:          struct rtx_list *list_rtx;
        !           651: 
        !           652:          c = read_skip_spaces (infile);
        !           653:          if (c != '[')
        !           654:            dump_and_abort ('[', c, infile);
        !           655: 
        !           656:          /* add expressions to a list, while keeping a count */
        !           657:          next_rtx = NULL;
        !           658:          list_counter = 0;
        !           659:          while ((c = read_skip_spaces (infile)) && c != ']')
        !           660:            {
        !           661:              ungetc (c, infile);
        !           662:              list_counter++;
        !           663:              rtx_list_link = (struct rtx_list *)
        !           664:                alloca (sizeof (struct rtx_list));
        !           665:              rtx_list_link->value = read_rtx (infile);
        !           666:              if (next_rtx == 0)
        !           667:                list_rtx = rtx_list_link;
        !           668:              else
        !           669:                next_rtx->next = rtx_list_link;
        !           670:              next_rtx = rtx_list_link;
        !           671:              rtx_list_link->next = 0;
        !           672:            }
        !           673:          /* get vector length and allocate it */
        !           674:          XVEC (return_rtx, i) = (list_counter
        !           675:                                  ? rtvec_alloc (list_counter) : NULL_RTVEC);
        !           676:          if (list_counter > 0)
        !           677:            {
        !           678:              next_rtx = list_rtx;
        !           679:              for (j = 0; j < list_counter; j++,
        !           680:                   next_rtx = next_rtx->next)
        !           681:                XVECEXP (return_rtx, i, j) = next_rtx->value;
        !           682:            }
        !           683:          /* close bracket gotten */
        !           684:        }
        !           685:        break;
        !           686: 
        !           687:       case 'S':
        !           688:        /* 'S' is an optional string: if a closeparen follows,
        !           689:           just store NULL for this element.  */
        !           690:        c = read_skip_spaces (infile);
        !           691:        ungetc (c, infile);
        !           692:        if (c == ')')
        !           693:          {
        !           694:            XSTR (return_rtx, i) = 0;
        !           695:            break;
        !           696:          }
        !           697: 
        !           698:       case 's':
        !           699:        {
        !           700:          int saw_paren = 0;
        !           701:          register char *stringbuf;
        !           702:          int stringbufsize;
        !           703: 
        !           704:          c = read_skip_spaces (infile);
        !           705:          if (c == '(')
        !           706:            {
        !           707:              saw_paren = 1;
        !           708:              c = read_skip_spaces (infile);
        !           709:            }
        !           710:          if (c != '"')
        !           711:            dump_and_abort ('"', c, infile);
        !           712: 
        !           713:          while (1)
        !           714:            {
        !           715:              c = getc (infile); /* Read the string  */
        !           716:              if (c == '\\')
        !           717:                {
        !           718:                  c = getc (infile);    /* Read the string  */
        !           719:                  /* \; makes stuff for a C string constant containing
        !           720:                     newline and tab.  */
        !           721:                  if (c == ';')
        !           722:                    {
        !           723:                      obstack_grow (rtl_obstack, "\\n\\t", 4);
        !           724:                      continue;
        !           725:                    }
        !           726:                }
        !           727:              else if (c == '"')
        !           728:                break;
        !           729: 
        !           730:              obstack_1grow (rtl_obstack, c);
        !           731:            }
        !           732: 
        !           733:          obstack_1grow (rtl_obstack, 0);
        !           734:          stringbuf = (char *) obstack_finish (rtl_obstack);
        !           735: 
        !           736:          if (saw_paren)
        !           737:            {
        !           738:              c = read_skip_spaces (infile);
        !           739:              if (c != ')')
        !           740:                dump_and_abort (')', c, infile);
        !           741:            }
        !           742:          XSTR (return_rtx, i) = stringbuf;
        !           743:        }
        !           744:        break;
        !           745: 
        !           746:       case 'w':
        !           747:        read_name (tmp_char, infile);
        !           748: #if HOST_BITS_PER_WIDE_INT == HOST_BITS_PER_INT
        !           749:        tmp_wide = atoi (tmp_char);
        !           750: #else
        !           751:        tmp_wide = atol (tmp_char);
        !           752: #endif
        !           753:        XWINT (return_rtx, i) = tmp_wide;
        !           754:        break;
        !           755: 
        !           756:       case 'i':
        !           757:       case 'n':
        !           758:        read_name (tmp_char, infile);
        !           759:        tmp_int = atoi (tmp_char);
        !           760:        XINT (return_rtx, i) = tmp_int;
        !           761:        break;
        !           762: 
        !           763:       default:
        !           764:        fprintf (stderr,
        !           765:                 "switch format wrong in rtl.read_rtx(). format was: %c.\n",
        !           766:                 format_ptr[-1]);
        !           767:        fprintf (stderr, "\tfile position: %ld\n", ftell (infile));
        !           768:        abort ();
        !           769:       }
        !           770: 
        !           771:   c = read_skip_spaces (infile);
        !           772:   if (c != ')')
        !           773:     dump_and_abort (')', c, infile);
        !           774: 
        !           775:   return return_rtx;
        !           776: }
        !           777: 
        !           778: /* This is called once per compilation, before any rtx's are constructed.
        !           779:    It initializes the vector `rtx_length', the extra CC modes, if any,
        !           780:    and computes certain commonly-used modes.  */
        !           781: 
        !           782: void
        !           783: init_rtl ()
        !           784: {
        !           785:   int min_class_size[(int) MAX_MODE_CLASS];
        !           786:   enum machine_mode mode;
        !           787:   int i;
        !           788: 
        !           789:   for (i = 0; i < NUM_RTX_CODE; i++)
        !           790:     rtx_length[i] = strlen (rtx_format[i]);
        !           791: 
        !           792:   /* Make CONST_DOUBLE bigger, if real values are bigger than
        !           793:      it normally expects to have room for.
        !           794:      Note that REAL_VALUE_TYPE is not defined by default,
        !           795:      since tree.h is not included.  But the default dfn as `double'
        !           796:      would do no harm.  */
        !           797: #ifdef REAL_VALUE_TYPE
        !           798:   i = sizeof (REAL_VALUE_TYPE) / sizeof (rtunion) + 2;
        !           799:   if (rtx_length[(int) CONST_DOUBLE] < i)
        !           800:     {
        !           801:       char *s = (char *) xmalloc (i + 1);
        !           802:       rtx_length[(int) CONST_DOUBLE] = i;
        !           803:       rtx_format[(int) CONST_DOUBLE] = s;
        !           804:       *s++ = 'e';
        !           805:       *s++ = '0';
        !           806:       /* Set the GET_RTX_FORMAT of CONST_DOUBLE to a string
        !           807:         of as many `w's as we now have elements.  Subtract two from
        !           808:         the size to account for the 'e' and the '0'.  */
        !           809:       for (i = 2; i < rtx_length[(int) CONST_DOUBLE]; i++)
        !           810:        *s++ = 'w';
        !           811:       *s++ = 0;
        !           812:     }
        !           813: #endif
        !           814: 
        !           815: #ifdef EXTRA_CC_MODES
        !           816:   for (i = (int) CCmode + 1; i < (int) MAX_MACHINE_MODE; i++)
        !           817:     {
        !           818:       mode_class[i] = MODE_CC;
        !           819:       mode_size[i] = mode_size[(int) CCmode];
        !           820:       mode_unit_size[i] = mode_unit_size[(int) CCmode];
        !           821:       mode_wider_mode[i - 1] = (enum machine_mode) i;
        !           822:       mode_wider_mode[i] = VOIDmode;
        !           823:     }
        !           824: #endif
        !           825: 
        !           826:   /* Find the narrowest mode for each class.  */
        !           827: 
        !           828:   for (i = 0; i < (int) MAX_MODE_CLASS; i++)
        !           829:     min_class_size[i] = 1000;
        !           830: 
        !           831:   for (mode = VOIDmode; (int) mode < (int) MAX_MACHINE_MODE;
        !           832:        mode = (enum machine_mode) ((int) mode + 1))
        !           833:     {
        !           834:       if (GET_MODE_SIZE (mode) < min_class_size[(int) GET_MODE_CLASS (mode)])
        !           835:        {
        !           836:          class_narrowest_mode[(int) GET_MODE_CLASS (mode)] = mode;
        !           837:          min_class_size[(int) GET_MODE_CLASS (mode)] = GET_MODE_SIZE (mode);
        !           838:        }
        !           839:     }
        !           840: }
        !           841: 
        !           842: #ifdef memset
        !           843: gcc_memset (dest, value, len)
        !           844:      char *dest;
        !           845:      int value;
        !           846:      int len;
        !           847: {
        !           848:   while (len-- > 0)
        !           849:     *dest++ = value;
        !           850: }
        !           851: #endif /* memset */

unix.superglobalmegacorp.com

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