Annotation of researchv10dc/cmd/gcc/emit-rtl.c, revision 1.1.1.1

1.1       root        1: /* Emit RTL for the GNU C-Compiler expander.
                      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: /* Middle-to-low level generation of rtx code and insns.
                     23: 
                     24:    This file contains the functions `gen_rtx', `gen_reg_rtx'
                     25:    and `gen_label_rtx' that are the usual ways of creating rtl
                     26:    expressions for most purposes.
                     27: 
                     28:    It also has the functions for creating insns and linking
                     29:    them in the doubly-linked chain.
                     30: 
                     31:    The patterns of the insns are created by machine-dependent
                     32:    routines in insn-emit.c, which is generated automatically from
                     33:    the machine description.  These routines use `gen_rtx' to make
                     34:    the individual rtx's of the pattern; what is machine dependent
                     35:    is the kind of rtx's they make and what arguments they use.  */
                     36: 
                     37: #include "config.h"
                     38: #include <stdio.h>
                     39: #include "varargs.h"
                     40: #include "rtl.h"
                     41: #include "regs.h"
                     42: #include "insn-config.h"
                     43: 
                     44: #define max(A,B) ((A) > (B) ? (A) : (B))
                     45: #define min(A,B) ((A) < (B) ? (A) : (B))
                     46: 
                     47: /* This is reset to FIRST_PSEUDO_REGISTER at the start each function.
                     48:    After rtl generation, it is 1 plus the largest register number used.  */
                     49: 
                     50: int reg_rtx_no = FIRST_PSEUDO_REGISTER;
                     51: 
                     52: /* This is *not* reset after each function.  It gives each CODE_LABEL
                     53:    in the entire compilation a unique label number.  */
                     54: 
                     55: static int label_num = 1;
                     56: 
                     57: /* Value of `label_num' at start of current function.  */
                     58: 
                     59: static int first_label_num;
                     60: 
                     61: /* Nonzero means do not generate NOTEs for source line numbers.  */
                     62: 
                     63: static int no_line_numbers;
                     64: 
                     65: /* Commonly used rtx's, so that we only need space for one copy.
                     66:    These are initialized once for the entire compilation.
                     67:    All of these except perhaps fconst0_rtx and dconst0_rtx
                     68:    are unique; no other rtx-object will be equal to any of these.  */
                     69: 
                     70: rtx pc_rtx;                    /* (PC) */
                     71: rtx cc0_rtx;                   /* (CC0) */
                     72: rtx cc1_rtx;                   /* (CC1) (not actually used nowadays) */
                     73: rtx const0_rtx;                        /* (CONST_INT 0) */
                     74: rtx const1_rtx;                        /* (CONST_INT 1) */
                     75: rtx fconst0_rtx;               /* (CONST_DOUBLE:SF 0) */
                     76: rtx dconst0_rtx;               /* (CONST_DOUBLE:DF 0) */
                     77: 
                     78: /* All references to the following fixed hard registers go through
                     79:    these unique rtl objects.  On machines where the frame-pointer and
                     80:    arg-pointer are the same register, they use the same unique object.
                     81: 
                     82:    After register allocation, other rtl objects which used to be pseudo-regs
                     83:    may be clobbered to refer to the frame-pointer register.
                     84:    But references that were originally to the frame-pointer can be
                     85:    distinguished from the others because they contain frame_pointer_rtx.
                     86: 
                     87:    In an inline procedure, the stack and frame pointer rtxs may not be
                     88:    used for anything else.  */
                     89: rtx stack_pointer_rtx;         /* (REG:Pmode STACK_POINTER_REGNUM) */
                     90: rtx frame_pointer_rtx;         /* (REG:Pmode FRAME_POINTER_REGNUM) */
                     91: rtx arg_pointer_rtx;           /* (REG:Pmode ARG_POINTER_REGNUM) */
                     92: rtx struct_value_rtx;          /* (REG:Pmode STRUCT_VALUE_REGNUM) */
                     93: rtx struct_value_incoming_rtx; /* (REG:Pmode STRUCT_VALUE_INCOMING_REGNUM) */
                     94: rtx static_chain_rtx;          /* (REG:Pmode STATIC_CHAIN_REGNUM) */
                     95: rtx static_chain_incoming_rtx; /* (REG:Pmode STATIC_CHAIN_INCOMING_REGNUM) */
                     96: 
                     97: /* The ends of the doubly-linked chain of rtl for the current function.
                     98:    Both are reset to null at the start of rtl generation for the function.  */
                     99: 
                    100: static rtx first_insn = NULL;
                    101: static rtx last_insn = NULL;
                    102: 
                    103: /* The ends of a similar chain of rtl insns to become part
                    104:    of the SEQUENCE returned by a gen_... function (in insn-emit.c).
                    105:    This allows define_expand to use subroutines that call emit_insn.  */
                    106: static rtx sequence_first_insn = NULL;
                    107: static rtx sequence_last_insn = NULL;
                    108: 
                    109: /* Nonzero if emit_insn should add to the sequence_first_insn chain
                    110:    instead of the ordinary chain.  */
                    111: int emit_to_sequence;
                    112: 
                    113: /* First insn used for something other than copying parms or changing their modes.  */
                    114: static rtx first_noninit_insn = NULL;
                    115: 
                    116: /* INSN_UID for next insn emitted.
                    117:    Reset to 1 for each function compiled.  */
                    118: 
                    119: static int cur_insn_uid = 1;
                    120: 
                    121: /* Line number and source file of the last line-number NOTE emitted.
                    122:    This is used to avoid generating duplicates.  */
                    123: 
                    124: static int last_linenum = 0;
                    125: static char *last_filename = 0;
                    126: 
                    127: /* A vector indexed by pseudo reg number.  The allocated length
                    128:    of this vector is regno_pointer_flag_length.  Since this
                    129:    vector is needed during the expansion phase when the total
                    130:    number of registers in the function is not yet known,
                    131:    it is copied and made bigger when necessary.  */
                    132: 
                    133: char *regno_pointer_flag;
                    134: int regno_pointer_flag_length;
                    135: 
                    136: /* Indexed by pseudo register number, gives the rtx for that pseudo.
                    137:    Allocated in parallel with regno_pointer_flag.  */
                    138: 
                    139: rtx *regno_reg_rtx;
                    140: 
                    141: /* Chain of all CONST_DOUBLEs made for this function;
                    142:    so we can uniquize them.  */
                    143: 
                    144: rtx real_constant_chain;
                    145: 
                    146: /* rtx gen_rtx (code, mode, [element1, ..., elementn])
                    147: **
                    148: **         This routine generates an RTX of the size specified by
                    149: **     <code>, which is an RTX code.   The RTX structure is initialized
                    150: **     from the arguments <element1> through <elementn>, which are
                    151: **     interpreted according to the specific RTX type's format.   The
                    152: **     special machine mode associated with the rtx (if any) is specified
                    153: **     in <mode>.
                    154: **
                    155: **         gen_rtx() can be invoked in a way which resembles the lisp-like
                    156: **     rtx it will generate.   For example, the following rtx structure:
                    157: **
                    158: **           (plus:QI (mem:QI (reg:SI 1))
                    159: **                    (mem:QI (plusw:SI (reg:SI 2) (reg:SI 3))))
                    160: **
                    161: **             ...would be generated by the following C code:
                    162: **
                    163: **             gen_rtx (PLUS, QImode,
                    164: **                 gen_rtx (MEM, QImode,
                    165: **                     gen_rtx (REG, SImode, 1)),
                    166: **                 gen_rtx (MEM, QImode,
                    167: **                     gen_rtx (PLUS, SImode,
                    168: **                         gen_rtx (REG, SImode, 2),
                    169: **                         gen_rtx (REG, SImode, 3)))),
                    170: */
                    171: 
                    172: /*VARARGS2*/
                    173: rtx
                    174: gen_rtx (va_alist)
                    175:      va_dcl
                    176: {
                    177:   va_list p;
                    178:   enum rtx_code code;
                    179:   enum machine_mode mode;
                    180:   register char *argp;         /* Pointer to arguments...              */
                    181:   register int i;              /* Array indices...                     */
                    182:   register char *fmt;          /* Current rtx's format...              */
                    183:   register rtx rt_val;         /* RTX to return to caller...           */
                    184: 
                    185:   va_start (p);
                    186:   code = va_arg (p, enum rtx_code);
                    187:   mode = va_arg (p, enum machine_mode);
                    188: 
                    189:   if (code == CONST_INT)
                    190:     {
                    191:       int arg = va_arg (p, int);
                    192:       if (arg == 0)
                    193:        return const0_rtx;
                    194:       if (arg == 1)
                    195:        return const1_rtx;
                    196:       rt_val = rtx_alloc (code);
                    197:       INTVAL (rt_val) = arg;
                    198:     }
                    199:   else if (code == CONST_DOUBLE)
                    200:     {
                    201:       int arg0 = va_arg (p, int);
                    202:       int arg1 = va_arg (p, int);
                    203:       if (arg0 == XINT (fconst0_rtx, 0)
                    204:          && arg1 == XINT (fconst0_rtx, 1))
                    205:        return (mode == DFmode ? dconst0_rtx : fconst0_rtx);
                    206:       rt_val = rtx_alloc (code);
                    207:       rt_val->mode = mode;
                    208:       XINT (rt_val, 0) = arg0;
                    209:       XINT (rt_val, 1) = arg1;
                    210:     }
                    211:   else
                    212:     {
                    213:       rt_val = rtx_alloc (code);       /* Allocate the storage space.  */
                    214:       rt_val->mode = mode;             /* Store the machine mode...  */
                    215: 
                    216:       fmt = GET_RTX_FORMAT (code);     /* Find the right format...  */
                    217:       for (i = 0; i < GET_RTX_LENGTH (code); i++)
                    218:        {
                    219:          switch (*fmt++)
                    220:            {
                    221:            case '0':           /* Unused field.  */
                    222:              break;
                    223: 
                    224:            case 'i':           /* An integer?  */
                    225:              XINT (rt_val, i) = va_arg (p, int);
                    226:              break;
                    227: 
                    228:            case 's':           /* A string?  */
                    229:              XSTR (rt_val, i) = va_arg (p, char *);
                    230:              break;
                    231: 
                    232:            case 'e':           /* An expression?  */
                    233:            case 'u':           /* An insn?  Same except when printing.  */
                    234:              XEXP (rt_val, i) = va_arg (p, rtx);
                    235:              break;
                    236: 
                    237:            case 'E':           /* An RTX vector?  */
                    238:              XVEC (rt_val, i) = va_arg (p, rtvec);
                    239:              break;
                    240: 
                    241:            default:
                    242:              abort();
                    243:            }
                    244:        }
                    245:     }
                    246:   va_end (p);
                    247:   return rt_val;               /* Return the new RTX...                */
                    248: }
                    249: 
                    250: /* gen_rtvec (n, [rt1, ..., rtn])
                    251: **
                    252: **         This routine creates an rtvec and stores within it the
                    253: **     pointers to rtx's which are its arguments.
                    254: */
                    255: 
                    256: /*VARARGS1*/
                    257: rtvec
                    258: gen_rtvec (va_alist)
                    259:      va_dcl
                    260: {
                    261:   int n, i;
                    262:   rtx first;
                    263:   va_list p;
                    264:   rtx *vector;
                    265: 
                    266:   va_start (p);
                    267:   n = va_arg (p, int);
                    268: 
                    269:   if (n == 0)
                    270:     return NULL_RTVEC;         /* Don't allocate an empty rtvec...     */
                    271: 
                    272:   vector = (rtx *) alloca (n * sizeof (rtx));
                    273:   for (i = 0; i < n; i++)
                    274:     vector[i] = va_arg (p, rtx);
                    275:   va_end (p);
                    276: 
                    277:   return gen_rtvec_v (n, vector);
                    278: }
                    279: 
                    280: rtvec
                    281: gen_rtvec_v (n, argp)
                    282:      int n;
                    283:      rtx *argp;
                    284: {
                    285:   register int i;
                    286:   register rtvec rt_val;
                    287: 
                    288:   if (n == 0)
                    289:     return NULL_RTVEC;         /* Don't allocate an empty rtvec...     */
                    290: 
                    291:   rt_val = rtvec_alloc (n);    /* Allocate an rtvec...                 */
                    292: 
                    293:   for (i = 0; i < n; i++)
                    294:     rt_val->elem[i].rtx = *argp++;
                    295: 
                    296:   return rt_val;
                    297: }
                    298: 
                    299: /* Generate a REG rtx for a new pseudo register of mode MODE.
                    300:    This pseudo is assigned the next sequential register number.  */
                    301: 
                    302: rtx
                    303: gen_reg_rtx (mode)
                    304:      enum machine_mode mode;
                    305: {
                    306:   register rtx val;
                    307: 
                    308:   /* Make sure regno_pointer_flag and regno_reg_rtx are large
                    309:      enough to have an element for this pseudo reg number.  */
                    310: 
                    311:   if (reg_rtx_no == regno_pointer_flag_length)
                    312:     {
                    313:       rtx *new1;
                    314:       char *new =
                    315:        (char *) oballoc (regno_pointer_flag_length * 2);
                    316:       bzero (new, regno_pointer_flag_length * 2);
                    317:       bcopy (regno_pointer_flag, new, regno_pointer_flag_length);
                    318:       regno_pointer_flag = new;
                    319: 
                    320:       new1 = (rtx *) oballoc (regno_pointer_flag_length * 2 * sizeof (rtx));
                    321:       bzero (new1, regno_pointer_flag_length * 2 * sizeof (rtx));
                    322:       bcopy (regno_reg_rtx, new1, regno_pointer_flag_length * sizeof (rtx));
                    323:       regno_reg_rtx = new1;
                    324: 
                    325:       regno_pointer_flag_length *= 2;
                    326:     }
                    327: 
                    328:   val = gen_rtx (REG, mode, reg_rtx_no);
                    329:   regno_reg_rtx[reg_rtx_no++] = val;
                    330:   return val;
                    331: }
                    332: 
                    333: /* Identify REG as a probable pointer register.  */
                    334: 
                    335: void
                    336: mark_reg_pointer (reg)
                    337:      rtx reg;
                    338: {
                    339:   REGNO_POINTER_FLAG (REGNO (reg)) = 1;
                    340: }
                    341: 
                    342: /* Return 1 plus largest pseudo reg number used in the current function.  */
                    343: 
                    344: int
                    345: max_reg_num ()
                    346: {
                    347:   return reg_rtx_no;
                    348: }
                    349: 
                    350: /* Return 1 + the largest label number used so far.  */
                    351: 
                    352: int
                    353: max_label_num ()
                    354: {
                    355:   return label_num;
                    356: }
                    357: 
                    358: /* Return first label number used in this function (if any were used).  */
                    359: 
                    360: int
                    361: get_first_label_num ()
                    362: {
                    363:   return first_label_num;
                    364: }
                    365: 
                    366: /* Assuming that X is an rtx (MEM, REG or SUBREG) for a fixed-point number,
                    367:    return a MEM or SUBREG rtx that refers to the least-significant part of X.
                    368:    MODE specifies how big a part of X to return;
                    369:    it must not be larger than a word.
                    370:    If X is a MEM whose address is a QUEUED, the value may be so also.  */
                    371: 
                    372: rtx
                    373: gen_lowpart (mode, x)
                    374:      enum machine_mode mode;
                    375:      register rtx x;
                    376: {
                    377:   /* This case loses if X is a subreg.  To catch bugs early,
                    378:      complain if an invalid MODE is used even in other cases.  */
                    379:   if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
                    380:     abort ();
                    381:   if (GET_CODE (x) == SUBREG)
                    382:     return (GET_MODE (SUBREG_REG (x)) == mode && SUBREG_WORD (x) == 0
                    383:            ? SUBREG_REG (x)
                    384:            : gen_rtx (SUBREG, mode, SUBREG_REG (x), SUBREG_WORD (x)));
                    385:   if (GET_MODE (x) == mode)
                    386:     return x;
                    387:   if (GET_CODE (x) == CONST_INT)
                    388:     return gen_rtx (CONST_INT, VOIDmode, INTVAL (x) & GET_MODE_MASK (mode));
                    389:   if (GET_CODE (x) == MEM)
                    390:     {
                    391:       register int offset = 0;
                    392: #ifdef WORDS_BIG_ENDIAN
                    393:       offset = (max (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD)
                    394:                - max (GET_MODE_SIZE (mode), UNITS_PER_WORD));
                    395: #endif
                    396: #ifdef BYTES_BIG_ENDIAN
                    397:       /* Adjust the address so that the address-after-the-data
                    398:         is unchanged.  */
                    399:       offset -= (min (UNITS_PER_WORD, GET_MODE_SIZE (mode))
                    400:                 - min (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x))));
                    401: #endif
                    402:       return gen_rtx (MEM, mode,
                    403:                      memory_address (mode,
                    404:                                      plus_constant (XEXP (x, 0), offset)));
                    405:     }
                    406:   else if (GET_CODE (x) == REG)
                    407:     {
                    408: #ifdef WORDS_BIG_ENDIAN
                    409:       if (GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD)
                    410:        {
                    411:          return gen_rtx (SUBREG, mode, x,
                    412:                          ((GET_MODE_SIZE (GET_MODE (x))
                    413:                            - max (GET_MODE_SIZE (mode), UNITS_PER_WORD))
                    414:                           / UNITS_PER_WORD));
                    415:        }
                    416: #endif
                    417:       return gen_rtx (SUBREG, mode, x, 0);
                    418:     }
                    419:   else
                    420:     abort ();
                    421: }
                    422: 
                    423: /* Like `gen_lowpart', but refer to the most significant part.  */
                    424: 
                    425: rtx
                    426: gen_highpart (mode, x)
                    427:      enum machine_mode mode;
                    428:      register rtx x;
                    429: {
                    430:   if (GET_CODE (x) == MEM)
                    431:     {
                    432:       register int offset = 0;
                    433: #ifndef WORDS_BIG_ENDIAN
                    434:       offset = (max (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD)
                    435:                - max (GET_MODE_SIZE (mode), UNITS_PER_WORD));
                    436: #endif
                    437: #ifndef BYTES_BIG_ENDIAN
                    438:       if (GET_MODE_SIZE (mode) < UNITS_PER_WORD)
                    439:        offset -= (GET_MODE_SIZE (mode)
                    440:                   - min (UNITS_PER_WORD,
                    441:                          GET_MODE_SIZE (GET_MODE (x))));
                    442: #endif
                    443:       return gen_rtx (MEM, mode,
                    444:                      memory_address (mode,
                    445:                                      plus_constant (XEXP (x, 0), offset)));
                    446:     }
                    447:   else if (GET_CODE (x) == REG)
                    448:     {
                    449: #ifndef WORDS_BIG_ENDIAN
                    450:       if (GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD)
                    451:        {
                    452:          return gen_rtx (SUBREG, mode, x,
                    453:                          ((GET_MODE_SIZE (GET_MODE (x))
                    454:                            - max (GET_MODE_SIZE (mode), UNITS_PER_WORD))
                    455:                           / UNITS_PER_WORD));
                    456:        }
                    457: #endif
                    458:       return gen_rtx (SUBREG, mode, x, 0);
                    459:     }
                    460:   else
                    461:     abort ();
                    462: }
                    463: 
                    464: /* Return 1 iff X, assumed to be a SUBREG,
                    465:    refers to the least significant part of its containing reg.
                    466:    If X is not a SUBREG, always return 1 (it is its own low part!).  */
                    467: 
                    468: int
                    469: subreg_lowpart_p (x)
                    470:      rtx x;
                    471: {
                    472:   if (GET_CODE (x) != SUBREG)
                    473:     return 1;
                    474: #ifdef WORDS_BIG_ENDIAN
                    475:   if (GET_MODE_SIZE (GET_MODE (x)) > UNITS_PER_WORD)
                    476:     {
                    477:       register enum machine_mode mode = GET_MODE (SUBREG_REG (x));
                    478:       return (SUBREG_WORD (x)
                    479:              == ((GET_MODE_SIZE (GET_MODE (x))
                    480:                   - max (GET_MODE_SIZE (mode), UNITS_PER_WORD))
                    481:                  / UNITS_PER_WORD));
                    482:     }
                    483: #endif 
                    484:   return SUBREG_WORD (x) == 0;
                    485: }
                    486: 
                    487: /* Return a memory reference like MEMREF, but with its mode changed
                    488:    to MODE and its address changed to ADDR.
                    489:    (VOIDmode means don't change the mode.
                    490:    NULL for ADDR means don't change the address.)  */
                    491: 
                    492: rtx
                    493: change_address (memref, mode, addr)
                    494:      rtx memref;
                    495:      enum machine_mode mode;
                    496:      rtx addr;
                    497: {
                    498:   rtx new;
                    499: 
                    500:   if (mode == VOIDmode)
                    501:     mode = GET_MODE (memref);
                    502:   if (addr == 0)
                    503:     addr = XEXP (memref, 0);
                    504: 
                    505:   new = gen_rtx (MEM, mode, memory_address (mode, addr));
                    506:   new->volatil = memref->volatil;
                    507:   new->unchanging = memref->unchanging;
                    508:   new->in_struct = memref->in_struct;
                    509:   return new;
                    510: }
                    511: 
                    512: /* Return a newly created CODE_LABEL rtx with a unique label number.  */
                    513: 
                    514: rtx
                    515: gen_label_rtx ()
                    516: {
                    517:   register rtx label = gen_rtx (CODE_LABEL, VOIDmode, 0, 0, 0, label_num++);
                    518:   LABEL_NUSES (label) = 0;
                    519:   return label;
                    520: }
                    521: 
                    522: /* For procedure integration.  */
                    523: 
                    524: /* Return a newly created INLINE_HEADER rtx.  Should allocate this
                    525:    from a permanent obstack when the opportunity arises.  */
                    526: 
                    527: rtx
                    528: gen_inline_header_rtx (insn, last_insn,
                    529:                       first_labelno, last_labelno,
                    530:                       max_parm_regnum, max_regnum, args_size)
                    531:      rtx insn, last_insn;
                    532:      int first_labelno, last_labelno, max_parm_regnum, max_regnum, args_size;
                    533: {
                    534:   rtx header = gen_rtx (INLINE_HEADER, VOIDmode,
                    535:                        cur_insn_uid++, NULL,
                    536:                        insn, last_insn,
                    537:                        first_labelno, last_labelno,
                    538:                        max_parm_regnum, max_regnum, args_size);
                    539:   return header;
                    540: }
                    541: 
                    542: /* Install new pointers to the first and last insns in the chain.
                    543:    Used for an inline-procedure after copying the insn chain.  */
                    544: 
                    545: void
                    546: set_new_first_and_last_insn (first, last)
                    547:      rtx first, last;
                    548: {
                    549:   first_insn = first;
                    550:   last_insn = last;
                    551: }
                    552: 
                    553: /* Go through all the RTL insn bodies and copy any invalid shared structure.
                    554:    It does not work to do this twice, because the mark bits set here
                    555:    are not cleared afterwards.  */
                    556: 
                    557: static int unshare_copies = 0; /* Count rtx's that were copied.  */
                    558: 
                    559: static rtx copy_rtx_if_shared ();
                    560: 
                    561: void
                    562: unshare_all_rtl (insn)
                    563:      register rtx insn;
                    564: {
                    565:   for (; insn; insn = NEXT_INSN (insn))
                    566:     if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
                    567:        || GET_CODE (insn) == CALL_INSN)
                    568:       {
                    569:        rtx tail;
                    570:        PATTERN (insn) = copy_rtx_if_shared (PATTERN (insn));
                    571:        /* Copy the contents of the reg-notes */
                    572:        for (tail = REG_NOTES (insn); tail; tail = XEXP (tail, 1))
                    573:          /* But if contents are an insn, don't copy that.  */
                    574:          if (GET_CODE (tail) == EXPR_LIST)
                    575:            XEXP (tail, 0) = copy_rtx_if_shared (XEXP (tail, 0));
                    576:       }
                    577: }
                    578: 
                    579: /* Mark ORIG as in use, and return a copy of it if it was already in use.
                    580:    Recursively does the same for subexpressions.  */
                    581: 
                    582: static rtx
                    583: copy_rtx_if_shared (orig)
                    584:      rtx orig;
                    585: {
                    586:   register rtx x = orig;
                    587:   register int i;
                    588:   register enum rtx_code code;
                    589:   register char *format_ptr;
                    590:   int copied = 0;
                    591: 
                    592:   code = GET_CODE (x);
                    593: 
                    594:   /* These types may be freely shared.  */
                    595: 
                    596:   switch (code)
                    597:     {
                    598:     case REG:
                    599:     case QUEUED:
                    600:     case CONST_INT:
                    601:     case CONST_DOUBLE:
                    602:     case SYMBOL_REF:
                    603:     case CODE_LABEL:
                    604:     case PC:
                    605:     case CC0:
                    606:       return x;
                    607: 
                    608:     case MEM:
                    609:       /* A MEM is allowed to be shared if its address is constant
                    610:         or is a constant plus one of the special registers.  */
                    611:       if (CONSTANT_ADDRESS_P (XEXP (x, 0)))
                    612:        return x;
                    613:       if (GET_CODE (XEXP (x, 0)) == PLUS
                    614:          && GET_CODE (XEXP (XEXP (x, 0), 0)) == REG
                    615:          && (REGNO (XEXP (XEXP (x, 0), 0)) == FRAME_POINTER_REGNUM
                    616:              || REGNO (XEXP (XEXP (x, 0), 0)) == ARG_POINTER_REGNUM)
                    617:          && CONSTANT_ADDRESS_P (XEXP (XEXP (x, 0), 1)))
                    618:       if (GET_CODE (XEXP (x, 0)) == REG
                    619:          && (REGNO (XEXP (x, 0)) == FRAME_POINTER_REGNUM
                    620:              || REGNO (XEXP (x, 0)) == ARG_POINTER_REGNUM)
                    621:          && CONSTANT_ADDRESS_P (XEXP (x, 1)))
                    622:        return x;
                    623:     }
                    624: 
                    625:   /* This rtx may not be shared.  If it has already been seen,
                    626:      replace it with a copy of itself.  */
                    627: 
                    628:   if (x->used)
                    629:     {
                    630:       register rtx copy;
                    631: 
                    632:       unshare_copies++;
                    633: 
                    634:       copy = rtx_alloc (code);
                    635:       bcopy (x, copy, sizeof (int) * (GET_RTX_LENGTH (code) + 1));
                    636:       x = copy;
                    637:       copied = 1;
                    638:     }
                    639:   x->used = 1;
                    640: 
                    641:   /* Now scan the subexpressions recursively.
                    642:      We can store any replaced subexpressions directly into X
                    643:      since we know X is not shared!  Any vectors in X
                    644:      must be copied if X was copied.  */
                    645: 
                    646:   format_ptr = GET_RTX_FORMAT (code);
                    647: 
                    648:   for (i = 0; i < GET_RTX_LENGTH (code); i++)
                    649:     {
                    650:       switch (*format_ptr++)
                    651:        {
                    652:        case 'e':
                    653:          XEXP (x, i) = copy_rtx_if_shared (XEXP (x, i));
                    654:          break;
                    655: 
                    656:        case 'E':
                    657:          if (XVEC (x, i) != NULL)
                    658:            {
                    659:              register int j;
                    660: 
                    661:              if (copied)
                    662:                XVEC (x, i) = gen_rtvec_v (XVECLEN (x, i), &XVECEXP (x, i, 0));
                    663:              for (j = 0; j < XVECLEN (x, i); j++)
                    664:                XVECEXP (x, i, j)
                    665:                  = copy_rtx_if_shared (XVECEXP (x, i, j));
                    666:            }
                    667:          break;
                    668:        }
                    669:     }
                    670:   return x;
                    671: }
                    672: 
                    673: /* Copy X if necessary so that it won't be altered by changes in OTHER.
                    674:    Return X or the rtx for the pseudo reg the value of X was copied into.
                    675:    OTHER must be valid as a SET_DEST.  */
                    676: 
                    677: rtx
                    678: make_safe_from (x, other)
                    679:      rtx x, other;
                    680: {
                    681:   rtx out = other;
                    682:   while (1)
                    683:     switch (GET_CODE (other))
                    684:       {
                    685:       case SUBREG:
                    686:        other = SUBREG_REG (other);
                    687:        break;
                    688:       case STRICT_LOW_PART:
                    689:       case SIGN_EXTEND:
                    690:       case ZERO_EXTEND:
                    691:        other = XEXP (other, 0);
                    692:        break;
                    693:       default:
                    694:        goto done;
                    695:       }
                    696:  done:
                    697:   if ((GET_CODE (other) == MEM
                    698:        && ! CONSTANT_P (x)
                    699:        && GET_CODE (x) != CONST_DOUBLE
                    700:        && GET_CODE (x) != REG)
                    701:       || (GET_CODE (other) == REG
                    702:          && (REGNO (other) < FIRST_PSEUDO_REGISTER
                    703:              || reg_mentioned_p (other, x))))
                    704:     {
                    705:       rtx temp = gen_reg_rtx (GET_MODE (x));
                    706:       emit_move_insn (temp, x);
                    707:       return temp;
                    708:     }
                    709:   return x;
                    710: }
                    711: 
                    712: /* Emission of insns (adding them to the doubly-linked list).  */
                    713: 
                    714: /* Return the first insn of the current function.  */
                    715: 
                    716: rtx
                    717: get_insns ()
                    718: {
                    719:   return first_insn;
                    720: }
                    721: 
                    722: /* Return the last insn of the current function.  */
                    723: 
                    724: rtx
                    725: get_last_insn ()
                    726: {
                    727:   return last_insn;
                    728: }
                    729: 
                    730: /* Return a number larger than any instruction's uid in this function.  */
                    731: 
                    732: int
                    733: get_max_uid ()
                    734: {
                    735:   return cur_insn_uid;
                    736: }
                    737: 
                    738: /* Make and return an INSN rtx, initializing all its slots.
                    739:    Store PATTERN in the pattern slots.
                    740:    PAT_FORMALS is an idea that never really went anywhere.  */
                    741: 
                    742: static rtx
                    743: make_insn_raw (pattern, pat_formals)
                    744:      rtx pattern;
                    745:      rtvec pat_formals;
                    746: {
                    747:   register rtx insn;
                    748: 
                    749:   insn = rtx_alloc(INSN);
                    750:   INSN_UID(insn) = cur_insn_uid++;
                    751: 
                    752:   PATTERN (insn) = pattern;
                    753:   INSN_CODE (insn) = -1;
                    754:   LOG_LINKS(insn) = NULL;
                    755:   REG_NOTES(insn) = NULL;
                    756: 
                    757:   return insn;
                    758: }
                    759: 
                    760: /* Like `make_insn' but make a JUMP_INSN instead of an insn.  */
                    761: 
                    762: static rtx
                    763: make_jump_insn_raw (pattern, pat_formals)
                    764:      rtx pattern;
                    765:      rtvec pat_formals;
                    766: {
                    767:   register rtx insn;
                    768: 
                    769:   insn = rtx_alloc(JUMP_INSN);
                    770:   INSN_UID(insn) = cur_insn_uid++;
                    771: 
                    772:   PATTERN (insn) = pattern;
                    773:   INSN_CODE (insn) = -1;
                    774:   LOG_LINKS(insn) = NULL;
                    775:   REG_NOTES(insn) = NULL;
                    776:   JUMP_LABEL(insn) = NULL;
                    777: 
                    778:   return insn;
                    779: }
                    780: 
                    781: /* Add INSN to the end of the doubly-linked list.
                    782:    INSN may be an INSN, JUMP_INSN, CALL_INSN, CODE_LABEL, BARRIER or NOTE.  */
                    783: 
                    784: static void
                    785: add_insn (insn)
                    786:      register rtx insn;
                    787: {
                    788:   if (emit_to_sequence)
                    789:     {
                    790:       PREV_INSN (insn) = sequence_last_insn;
                    791:       NEXT_INSN (insn) = 0;
                    792: 
                    793:       if (NULL != sequence_last_insn)
                    794:        NEXT_INSN (sequence_last_insn) = insn;
                    795: 
                    796:       if (NULL == sequence_first_insn)
                    797:        sequence_first_insn = insn;
                    798: 
                    799:       sequence_last_insn = insn;
                    800:     }
                    801:   else
                    802:     {
                    803:       PREV_INSN (insn) = last_insn;
                    804:       NEXT_INSN (insn) = 0;
                    805: 
                    806:       if (NULL != last_insn)
                    807:        NEXT_INSN (last_insn) = insn;
                    808: 
                    809:       if (NULL == first_insn)
                    810:        first_insn = insn;
                    811: 
                    812:       last_insn = insn;
                    813:     }
                    814: }
                    815: 
                    816: /* Add INSN, an rtx of code INSN, into the doubly-linked list
                    817:    after insn AFTER.  */
                    818: 
                    819: static void
                    820: add_insn_after (insn, after)
                    821:      rtx insn, after;
                    822: {
                    823:   NEXT_INSN (insn) = NEXT_INSN (after);
                    824:   PREV_INSN (insn) = after;
                    825: 
                    826:   if (NEXT_INSN (insn))
                    827:     PREV_INSN (NEXT_INSN (insn)) = insn;
                    828:   else
                    829:     last_insn = insn;
                    830:   NEXT_INSN (after) = insn;
                    831: }
                    832: 
                    833: /* Delete all insns made since FROM.
                    834:    FROM becomes the new last instruction.  */
                    835: 
                    836: void
                    837: delete_insns_since (from)
                    838:      rtx from;
                    839: {
                    840:   NEXT_INSN (from) = 0;
                    841:   last_insn = from;
                    842: }
                    843: 
                    844: /* Move a consecutive bunch of insns to a different place in the chain.
                    845:    The insns to be moved are those between FROM and TO.
                    846:    They are moved to a new position after the insn AFTER.  */
                    847: 
                    848: void
                    849: reorder_insns (from, to, after)
                    850:      rtx from, to, after;
                    851: {
                    852:   /* Splice this bunch out of where it is now.  */
                    853:   if (PREV_INSN (from))
                    854:     NEXT_INSN (PREV_INSN (from)) = NEXT_INSN (to);
                    855:   if (NEXT_INSN (to))
                    856:     PREV_INSN (NEXT_INSN (to)) = PREV_INSN (from);
                    857:   if (last_insn == to)
                    858:     last_insn = PREV_INSN (from);
                    859:   if (first_insn == from)
                    860:     first_insn = NEXT_INSN (to);
                    861: 
                    862:   /* Make the new neighbors point to it and it to them.  */
                    863:   if (NEXT_INSN (after))
                    864:     {
                    865:       PREV_INSN (NEXT_INSN (after)) = to;
                    866:       NEXT_INSN (to) = NEXT_INSN (after);
                    867:     }
                    868:   PREV_INSN (from) = after;
                    869:   NEXT_INSN (after) = from;
                    870:   if (after == last_insn)
                    871:     last_insn = to;
                    872: }
                    873: 
                    874: /* Emit an insn of given code and pattern
                    875:    at a specified place within the doubly-linked list.  */
                    876: 
                    877: /* Make an instruction with body PATTERN
                    878:    and output it before the instruction BEFORE.  */
                    879: 
                    880: rtx
                    881: emit_insn_before (pattern, before)
                    882:      register rtx pattern, before;
                    883: {
                    884:   register rtx insn;
                    885: 
                    886:   if (GET_CODE (pattern) == SEQUENCE)
                    887:     {
                    888:       register int i;
                    889:       /* For an empty sequence, emit nothing.  */
                    890:       if (XVEC (pattern, 0))
                    891:        for (i = 0; i < XVECLEN (pattern, 0); i++)
                    892:          add_insn_after (XVECEXP (pattern, 0, i), PREV_INSN (before));
                    893:       return PREV_INSN (before);
                    894:     }
                    895: 
                    896:   insn = make_insn_raw (pattern, 0);
                    897: 
                    898:   PREV_INSN (insn) = PREV_INSN (before);
                    899:   NEXT_INSN (insn) = before;
                    900: 
                    901:   if (PREV_INSN (insn))
                    902:     NEXT_INSN (PREV_INSN (insn)) = insn;
                    903:   else
                    904:     first_insn = insn;
                    905:   PREV_INSN (before) = insn;
                    906: 
                    907:   return insn;
                    908: }
                    909: 
                    910: /* Make an instruction with body PATTERN and code JUMP_INSN
                    911:    and output it before the instruction BEFORE.  */
                    912: 
                    913: rtx
                    914: emit_jump_insn_before (pattern, before)
                    915:      register rtx pattern, before;
                    916: {
                    917:   register rtx insn = make_jump_insn_raw (pattern, 0);
                    918: 
                    919:   PREV_INSN (insn) = PREV_INSN (before);
                    920:   NEXT_INSN (insn) = before;
                    921: 
                    922:   if (PREV_INSN (insn))
                    923:     NEXT_INSN (PREV_INSN (insn)) = insn;
                    924:   else
                    925:     first_insn = insn;
                    926:   PREV_INSN (before) = insn;
                    927: 
                    928:   return insn;
                    929: }
                    930: 
                    931: /* Make an insn of code INSN with body PATTERN
                    932:    and output it after the insn AFTER.  */
                    933: 
                    934: rtx
                    935: emit_insn_after (pattern, after)
                    936:      register rtx pattern, after;
                    937: {
                    938:   if (GET_CODE (pattern) == SEQUENCE)
                    939:     {
                    940:       register int i;
                    941:       /* For an empty sequence, emit nothing.  */
                    942:       if (XVEC (pattern, 0))
                    943:        for (i = 0; i < XVECLEN (pattern, 0); i++)
                    944:          {
                    945:            add_insn_after (XVECEXP (pattern, 0, i), after);
                    946:            after = NEXT_INSN (after);
                    947:          }
                    948:       return after;
                    949:     }
                    950:   else
                    951:     {
                    952:       register rtx insn = make_insn_raw (pattern, 0);
                    953:       add_insn_after (insn, after);
                    954:       return insn;
                    955:     }
                    956: }
                    957: 
                    958: /* Make an insn of code JUMP_INSN with body PATTERN
                    959:    and output it after the insn AFTER.  */
                    960: 
                    961: rtx
                    962: emit_jump_insn_after (pattern, after)
                    963:      register rtx pattern, after;
                    964: {
                    965:   register rtx insn = make_jump_insn_raw (pattern, 0);
                    966: 
                    967:   add_insn_after (insn, after);
                    968:   return insn;
                    969: }
                    970: 
                    971: /* Make an insn of code BARRIER
                    972:    and output it after the insn AFTER.  */
                    973: 
                    974: rtx
                    975: emit_barrier_after (after)
                    976:      register rtx after;
                    977: {
                    978:   register rtx insn = rtx_alloc (BARRIER);
                    979: 
                    980:   INSN_UID (insn) = cur_insn_uid++;
                    981: 
                    982:   add_insn_after (insn, after);
                    983:   return insn;
                    984: }
                    985: 
                    986: /* Emit the label LABEL after the insn AFTER.  */
                    987: 
                    988: void
                    989: emit_label_after (label, after)
                    990:      rtx label, after;
                    991: {
                    992:   /* This can be called twice for the same label
                    993:      as a result of the confusion that follows a syntax error!
                    994:      So make it harmless.  */
                    995:   if (INSN_UID (label) == 0)
                    996:     {
                    997:       INSN_UID (label) = cur_insn_uid++;
                    998:       add_insn_after (label, after);
                    999:     }
                   1000: }
                   1001: 
                   1002: /* Emit a note of subtype SUBTYPE after the insn AFTER.  */
                   1003: 
                   1004: void
                   1005: emit_note_after (subtype, after)
                   1006:      int subtype;
                   1007:      rtx after;
                   1008: {
                   1009:   register rtx note = rtx_alloc (NOTE);
                   1010:   INSN_UID (note) = cur_insn_uid++;
                   1011:   XSTR (note, 3) = 0;
                   1012:   XINT (note, 4) = subtype;
                   1013:   add_insn_after (note, after);
                   1014: }
                   1015: 
                   1016: /* Make an insn of code INSN with pattern PATTERN
                   1017:    and add it to the end of the doubly-linked list.
                   1018:    If PATTERN is a SEQUENCE, take the elements of it
                   1019:    and emit an insn for each element.
                   1020: 
                   1021:    Returns the last insn emitted.  */
                   1022: 
                   1023: rtx
                   1024: emit_insn (pattern)
                   1025:      rtx pattern;
                   1026: {
                   1027:   rtx insn;
                   1028: 
                   1029:   if (GET_CODE (pattern) == SEQUENCE)
                   1030:     {
                   1031:       register int i;
                   1032:       /* For an empty sequence, emit nothing.  */
                   1033:       if (XVEC (pattern, 0))
                   1034:        for (i = 0; i < XVECLEN (pattern, 0); i++)
                   1035:          add_insn (insn = XVECEXP (pattern, 0, i));
                   1036:     }
                   1037:   else
                   1038:     {
                   1039:       insn = make_insn_raw (pattern, NULL);
                   1040:       add_insn (insn);
                   1041:     }
                   1042:   return insn;
                   1043: }
                   1044: 
                   1045: /* Make an insn of code JUMP_INSN with pattern PATTERN
                   1046:    and add it to the end of the doubly-linked list.  */
                   1047: 
                   1048: rtx
                   1049: emit_jump_insn (pattern)
                   1050:      rtx pattern;
                   1051: {
                   1052:   if (GET_CODE (pattern) == SEQUENCE)
                   1053:     return emit_insn (pattern);
                   1054:   else
                   1055:     {
                   1056:       register rtx insn = make_jump_insn_raw (pattern, NULL);
                   1057:       add_insn (insn);
                   1058:       return insn;
                   1059:     }
                   1060: }
                   1061: 
                   1062: /* Make an insn of code CALL_INSN with pattern PATTERN
                   1063:    and add it to the end of the doubly-linked list.  */
                   1064: 
                   1065: rtx
                   1066: emit_call_insn (pattern)
                   1067:      rtx pattern;
                   1068: {
                   1069:   if (GET_CODE (pattern) == SEQUENCE)
                   1070:     return emit_insn (pattern);
                   1071:   else
                   1072:     {
                   1073:       register rtx insn = make_insn_raw (pattern, NULL);
                   1074:       add_insn (insn);
                   1075:       PUT_CODE (insn, CALL_INSN);
                   1076:       return insn;
                   1077:     }
                   1078: }
                   1079: 
                   1080: /* Add the label LABEL to the end of the doubly-linked list.  */
                   1081: 
                   1082: void
                   1083: emit_label (label)
                   1084:      rtx label;
                   1085: {
                   1086:   /* This can be called twice for the same label
                   1087:      as a result of the confusion that follows a syntax error!
                   1088:      So make it harmless.  */
                   1089:   if (INSN_UID (label) == 0)
                   1090:     {
                   1091:       INSN_UID (label) = cur_insn_uid++;
                   1092:       add_insn (label);
                   1093:     }
                   1094: }
                   1095: 
                   1096: /* Make an insn of code BARRIER
                   1097:    and add it to the end of the doubly-linked list.  */
                   1098: 
                   1099: void
                   1100: emit_barrier ()
                   1101: {
                   1102:   register rtx barrier = rtx_alloc (BARRIER);
                   1103:   INSN_UID (barrier) = cur_insn_uid++;
                   1104:   add_insn (barrier);
                   1105: }
                   1106: 
                   1107: /* Make an insn of code NOTE
                   1108:    with data-fields specified by FILE and LINE
                   1109:    and add it to the end of the doubly-linked list.  */
                   1110: 
                   1111: rtx
                   1112: emit_note (file, line)
                   1113:      char *file;
                   1114:      int line;
                   1115: {
                   1116:   register rtx note;
                   1117: 
                   1118:   if (no_line_numbers && line > 0)
                   1119:     return 0;
                   1120: 
                   1121:   if (line > 0)
                   1122:     {
                   1123:       if (file && last_filename && !strcmp (file, last_filename)
                   1124:          && line == last_linenum)
                   1125:        return 0;
                   1126:       last_filename = file;
                   1127:       last_linenum = line;
                   1128:     }
                   1129: 
                   1130:   note = rtx_alloc (NOTE);
                   1131:   INSN_UID (note) = cur_insn_uid++;
                   1132:   XSTR (note, 3) = file;
                   1133:   XINT (note, 4) = line;
                   1134:   add_insn (note);
                   1135:   return note;
                   1136: }
                   1137: 
                   1138: /* Return an indication of which type of insn should have X as a body.
                   1139:    The value is CODE_LABEL, INSN, CALL_INSN or JUMP_INSN.  */
                   1140: 
                   1141: enum rtx_code
                   1142: classify_insn (x)
                   1143:      rtx x;
                   1144: {
                   1145:   if (GET_CODE (x) == CODE_LABEL)
                   1146:     return CODE_LABEL;
                   1147:   if (GET_CODE (x) == CALL)
                   1148:     return CALL_INSN;
                   1149:   if (GET_CODE (x) == RETURN)
                   1150:     return JUMP_INSN;
                   1151:   if (GET_CODE (x) == SET)
                   1152:     {
                   1153:       if (SET_DEST (x) == pc_rtx)
                   1154:        return JUMP_INSN;
                   1155:       else if (GET_CODE (SET_SRC (x)) == CALL)
                   1156:        return CALL_INSN;
                   1157:       else
                   1158:        return INSN;
                   1159:     }
                   1160:   if (GET_CODE (x) == PARALLEL)
                   1161:     {
                   1162:       register int j;
                   1163:       for (j = XVECLEN (x, 0) - 1; j >= 0; j--)
                   1164:        if (GET_CODE (XVECEXP (x, 0, j)) == CALL)
                   1165:          return CALL_INSN;
                   1166:        else if (GET_CODE (XVECEXP (x, 0, j)) == SET
                   1167:                 && SET_DEST (XVECEXP (x, 0, j)) == pc_rtx)
                   1168:          return JUMP_INSN;
                   1169:        else if (GET_CODE (XVECEXP (x, 0, j)) == SET
                   1170:                 && GET_CODE (SET_SRC (XVECEXP (x, 0, j))) == CALL)
                   1171:          return CALL_INSN;
                   1172:     }
                   1173:   return INSN;
                   1174: }
                   1175: 
                   1176: /* Emit the rtl pattern X as an appropriate kind of insn.
                   1177:    If X is a label, it is simply added into the insn chain.  */
                   1178: 
                   1179: rtx
                   1180: emit (x)
                   1181:      rtx x;
                   1182: {
                   1183:   enum rtx_code code = classify_insn (x);
                   1184: 
                   1185:   if (code == CODE_LABEL)
                   1186:     emit_label (x);
                   1187:   else if (code == INSN)
                   1188:     emit_insn (x);
                   1189:   else if (code == JUMP_INSN)
                   1190:     {
                   1191:       emit_jump_insn (x);
                   1192:       if (simplejump_p (x) || GET_CODE (x) == RETURN)
                   1193:        emit_barrier ();
                   1194:     }
                   1195:   else if (code == CALL_INSN)
                   1196:     emit_call_insn (x);
                   1197: }
                   1198: 
                   1199: /* Generate a SEQUENCE rtx containing the insn-patterns in VEC
                   1200:    following any insns previously placed on sequence_first_insn.
                   1201:    This is how the gen_... function from a DEFINE_EXPAND
                   1202:    constructs the SEQUENCE that it returns.  */
                   1203: 
                   1204: rtx
                   1205: gen_sequence ()
                   1206: {
                   1207:   rtx tem;
                   1208:   rtvec newvec;
                   1209:   int i;
                   1210:   int len;
                   1211: 
                   1212:   /* Count the insns in the chain.  */
                   1213:   len = 0;
                   1214:   for (tem = sequence_first_insn; tem; tem = NEXT_INSN (tem))
                   1215:     len++;
                   1216: 
                   1217:   /* For an empty sequence... */
                   1218:   if (len == 0)
                   1219:     return gen_rtx (SEQUENCE, VOIDmode, NULL);
                   1220: 
                   1221:   /* If only one insn, return its pattern rather than a SEQUENCE.  */
                   1222:   if (len == 1)
                   1223:     {
                   1224:       tem = PATTERN (sequence_first_insn);
                   1225:       sequence_first_insn = 0;
                   1226:       sequence_last_insn = 0;
                   1227:       return tem;
                   1228:     }
                   1229: 
                   1230:   /* Put them in a vector.  */
                   1231:   newvec = rtvec_alloc (len);
                   1232:   i = 0;
                   1233:   for (tem = sequence_first_insn; tem; tem = NEXT_INSN (tem), i++)
                   1234:     newvec->elem[i].rtx = tem;
                   1235: 
                   1236:   /* Clear the chain and make a SEQUENCE from this vector.  */
                   1237:   sequence_first_insn = 0;
                   1238:   sequence_last_insn = 0;
                   1239:   return gen_rtx (SEQUENCE, VOIDmode, newvec);
                   1240: }
                   1241: 
                   1242: /* Set up regno_reg_rtx, reg_rtx_no and regno_pointer_flag
                   1243:    according to the chain of insns starting with FIRST.
                   1244: 
                   1245:    This is used when an inline function's rtl is saved
                   1246:    and passed to rest_of_compilation later.  */
                   1247: 
                   1248: static void restore_reg_data_1 ();
                   1249: 
                   1250: void
                   1251: restore_reg_data (first)
                   1252:      rtx first;
                   1253: {
                   1254:   rtx insn;
                   1255:   int i;
                   1256: 
                   1257:   for (insn = first; insn; insn = NEXT_INSN (insn))
                   1258:     {
                   1259:       switch (GET_CODE (insn))
                   1260:        {
                   1261:        case NOTE:
                   1262:        case CODE_LABEL:
                   1263:        case BARRIER:
                   1264:          break;
                   1265: 
                   1266:        case JUMP_INSN:
                   1267:        case CALL_INSN:
                   1268:        case INSN:
                   1269:          restore_reg_data_1 (PATTERN (insn));
                   1270:          break;
                   1271:        }
                   1272:     }
                   1273:   
                   1274:   /* If any regs are missing, make them up.  */
                   1275:   for (i = FIRST_PSEUDO_REGISTER; i < reg_rtx_no; i++)
                   1276:     if (regno_reg_rtx[i] == 0)
                   1277:       regno_reg_rtx[i] = gen_rtx (REG, SImode, i);
                   1278: }
                   1279: 
                   1280: static void
                   1281: restore_reg_data_1 (orig)
                   1282:      rtx orig;
                   1283: {
                   1284:   register rtx x = orig;
                   1285:   register int i;
                   1286:   register enum rtx_code code;
                   1287:   register char *format_ptr;
                   1288: 
                   1289:   code = GET_CODE (x);
                   1290: 
                   1291:   switch (code)
                   1292:     {
                   1293:     case QUEUED:
                   1294:     case CONST_INT:
                   1295:     case CONST_DOUBLE:
                   1296:     case SYMBOL_REF:
                   1297:     case CODE_LABEL:
                   1298:     case PC:
                   1299:     case CC0:
                   1300:     case LABEL_REF:
                   1301:       return;
                   1302: 
                   1303:     case REG:
                   1304:       if (REGNO (x) >= FIRST_PSEUDO_REGISTER)
                   1305:        {
                   1306:          /* Make sure regno_pointer_flag and regno_reg_rtx are large
                   1307:             enough to have an element for this pseudo reg number.  */
                   1308:          if (REGNO (x) >= reg_rtx_no)
                   1309:            {
                   1310:              reg_rtx_no = REGNO (x);
                   1311: 
                   1312:              if (reg_rtx_no == regno_pointer_flag_length)
                   1313:                {
                   1314:                  rtx *new1;
                   1315:                  char *new =
                   1316:                    (char *) oballoc (regno_pointer_flag_length * 2);
                   1317:                  bzero (new, regno_pointer_flag_length * 2);
                   1318:                  bcopy (regno_pointer_flag, new, regno_pointer_flag_length);
                   1319:                  regno_pointer_flag = new;
                   1320: 
                   1321:                  new1 = (rtx *) oballoc (regno_pointer_flag_length * 2 * sizeof (rtx));
                   1322:                  bzero (new1, regno_pointer_flag_length * 2 * sizeof (rtx));
                   1323:                  bcopy (regno_reg_rtx, new1, regno_pointer_flag_length * sizeof (rtx));
                   1324:                  regno_reg_rtx = new1;
                   1325: 
                   1326:                  regno_pointer_flag_length *= 2;
                   1327:                }
                   1328:              reg_rtx_no ++;
                   1329:            }
                   1330:          regno_reg_rtx[REGNO (x)] = x;
                   1331:        }
                   1332:       return;
                   1333: 
                   1334:     case MEM:
                   1335:       restore_reg_data_1 (XEXP (x, 0));
                   1336:       return;
                   1337:     }
                   1338: 
                   1339:   /* Now scan the subexpressions recursively.  */
                   1340: 
                   1341:   format_ptr = GET_RTX_FORMAT (code);
                   1342: 
                   1343:   for (i = 0; i < GET_RTX_LENGTH (code); i++)
                   1344:     {
                   1345:       switch (*format_ptr++)
                   1346:        {
                   1347:        case 'e':
                   1348:          restore_reg_data_1 (XEXP (x, i));
                   1349:          break;
                   1350: 
                   1351:        case 'E':
                   1352:          if (XVEC (x, i) != NULL)
                   1353:            {
                   1354:              register int j;
                   1355: 
                   1356:              for (j = 0; j < XVECLEN (x, i); j++)
                   1357:                restore_reg_data_1 (XVECEXP (x, i, j));
                   1358:            }
                   1359:          break;
                   1360:        }
                   1361:     }
                   1362: }
                   1363: 
                   1364: /* Initialize data structures and variables in this file
                   1365:    before generating rtl for each function.
                   1366:    WRITE_SYMBOLS is nonzero if any kind of debugging info
                   1367:    is to be generated.  */
                   1368: 
                   1369: void
                   1370: init_emit (write_symbols)
                   1371:      int write_symbols;
                   1372: {
                   1373:   first_insn = NULL;
                   1374:   last_insn = NULL;
                   1375:   cur_insn_uid = 1;
                   1376:   reg_rtx_no = FIRST_PSEUDO_REGISTER;
                   1377:   last_linenum = 0;
                   1378:   last_filename = 0;
                   1379:   real_constant_chain = 0;
                   1380:   first_label_num = label_num;
                   1381:   sequence_first_insn = NULL;
                   1382:   sequence_last_insn = NULL;
                   1383:   emit_to_sequence = 0;
                   1384: 
                   1385:   no_line_numbers = ! write_symbols;
                   1386:   
                   1387:   /* Init the tables that describe all the pseudo regs.  */
                   1388: 
                   1389:   regno_pointer_flag_length = 100;
                   1390: 
                   1391:   regno_pointer_flag 
                   1392:     = (char *) oballoc (regno_pointer_flag_length);
                   1393:   bzero (regno_pointer_flag, regno_pointer_flag_length);
                   1394: 
                   1395:   regno_reg_rtx 
                   1396:     = (rtx *) oballoc (regno_pointer_flag_length * sizeof (rtx));
                   1397:   bzero (regno_reg_rtx, regno_pointer_flag_length * sizeof (rtx));
                   1398: }
                   1399: 
                   1400: /* Create some permanent unique rtl objects shared between all functions.  */
                   1401: 
                   1402: void
                   1403: init_emit_once ()
                   1404: {
                   1405:   /* Create the unique rtx's for certain rtx codes and operand values.  */
                   1406: 
                   1407:   pc_rtx = gen_rtx (PC, VOIDmode);
                   1408:   cc0_rtx = gen_rtx (CC0, VOIDmode);
                   1409: 
                   1410:   /* Don't use gen_rtx here since gen_rtx in this case
                   1411:      tries to use these variables.  */
                   1412:   const0_rtx = rtx_alloc (CONST_INT);
                   1413:   INTVAL (const0_rtx) = 0;
                   1414:   const1_rtx = rtx_alloc (CONST_INT);
                   1415:   INTVAL (const1_rtx) = 1;
                   1416: 
                   1417:   fconst0_rtx = rtx_alloc (CONST_DOUBLE);
                   1418:   {
                   1419:     union { double d; int i[2]; } u;
                   1420:     u.d = 0;
                   1421:     XINT (fconst0_rtx, 0) = u.i[0];
                   1422:     XINT (fconst0_rtx, 1) = u.i[1];
                   1423:     XEXP (fconst0_rtx, 2) = const0_rtx;
                   1424:   }
                   1425:   PUT_MODE (fconst0_rtx, SFmode);
                   1426: 
                   1427:   dconst0_rtx = rtx_alloc (CONST_DOUBLE);
                   1428:   {
                   1429:     union { double d; int i[2]; } u;
                   1430:     u.d = 0;
                   1431:     XINT (dconst0_rtx, 0) = u.i[0];
                   1432:     XINT (dconst0_rtx, 1) = u.i[1];
                   1433:     XEXP (dconst0_rtx, 2) = const0_rtx;
                   1434:   }
                   1435:   PUT_MODE (dconst0_rtx, DFmode);
                   1436: 
                   1437:   stack_pointer_rtx = gen_rtx (REG, Pmode, STACK_POINTER_REGNUM);
                   1438:   frame_pointer_rtx = gen_rtx (REG, Pmode, FRAME_POINTER_REGNUM);
                   1439:   struct_value_rtx = gen_rtx (REG, Pmode, STRUCT_VALUE_REGNUM);
                   1440: 
                   1441: #ifdef STRUCT_VALUE_INCOMING_REGNUM
                   1442:   if (STRUCT_VALUE_INCOMING_REGNUM != STRUCT_VALUE_REGNUM)
                   1443:     struct_value_incoming_rtx = gen_rtx (REG, Pmode, STRUCT_VALUE_INCOMING_REGNUM);
                   1444:   else
                   1445: #endif
                   1446:     struct_value_incoming_rtx = struct_value_rtx;
                   1447: 
                   1448:   static_chain_rtx = gen_rtx (REG, Pmode, STATIC_CHAIN_REGNUM);
                   1449: 
                   1450: #ifdef STATIC_CHAIN_INCOMING_REGNUM
                   1451:   if (STATIC_CHAIN_INCOMING_REGNUM != STATIC_CHAIN_REGNUM)
                   1452:     static_chain_incoming_rtx = gen_rtx (REG, Pmode, STATIC_CHAIN_INCOMING_REGNUM);
                   1453:   else
                   1454: #endif
                   1455:     static_chain_incoming_rtx = static_chain_rtx;
                   1456: 
                   1457:   if (FRAME_POINTER_REGNUM == ARG_POINTER_REGNUM)
                   1458:     arg_pointer_rtx = frame_pointer_rtx;
                   1459:   else
                   1460:     arg_pointer_rtx = gen_rtx (REG, Pmode, ARG_POINTER_REGNUM);
                   1461: }

unix.superglobalmegacorp.com

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