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

1.1     ! root        1: /* More subroutines needed by GCC output code on some machines.  */
        !             2: /* Compile this one with gcc.  */
        !             3: /* Copyright (C) 1989, 1992, 1993 Free Software Foundation, Inc.
        !             4: 
        !             5: This file is part of GNU CC.
        !             6: 
        !             7: GNU CC is free software; you can redistribute it and/or modify
        !             8: it under the terms of the GNU General Public License as published by
        !             9: the Free Software Foundation; either version 2, or (at your option)
        !            10: any later version.
        !            11: 
        !            12: GNU CC is distributed in the hope that it will be useful,
        !            13: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            15: GNU General Public License for more details.
        !            16: 
        !            17: You should have received a copy of the GNU General Public License
        !            18: along with GNU CC; see the file COPYING.  If not, write to
        !            19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
        !            20: 
        !            21: /* As a special exception, if you link this library with files
        !            22:    compiled with GCC to produce an executable, this does not cause
        !            23:    the resulting executable to be covered by the GNU General Public License.
        !            24:    This exception does not however invalidate any other reasons why
        !            25:    the executable file might be covered by the GNU General Public License.  */
        !            26: 
        !            27: /* It is incorrect to include config.h here, because this file is being
        !            28:    compiled for the target, and hence definitions concerning only the host
        !            29:    do not apply.  */
        !            30: 
        !            31: #include "tconfig.h"
        !            32: #include "machmode.h"
        !            33: #ifndef L_trampoline
        !            34: #include "gstddef.h"
        !            35: #endif
        !            36: #ifdef SHLIB
        !            37: #include <libsys/shlib.h>
        !            38: extern void* malloc (int);
        !            39: extern int write (int, const char*, int);
        !            40: extern void free (void*);
        !            41: #endif
        !            42: 
        !            43: /* Don't use `fancy_abort' here even if config.h says to use it.  */
        !            44: #ifdef abort
        !            45: #undef abort
        !            46: #endif
        !            47: 
        !            48: /* In the first part of this file, we are interfacing to calls generated
        !            49:    by the compiler itself.  These calls pass values into these routines
        !            50:    which have very specific modes (rather than very specific types), and
        !            51:    these compiler-generated calls also expect any return values to have
        !            52:    very specific modes (rather than very specific types).  Thus, we need
        !            53:    to avoid using regular C language type names in this part of the file
        !            54:    because the sizes for those types can be configured to be anything.
        !            55:    Instead we use the following special type names.  */
        !            56: 
        !            57: typedef unsigned int UQItype   __attribute__ ((mode (QI)));
        !            58: typedef         int SItype     __attribute__ ((mode (SI)));
        !            59: typedef unsigned int USItype   __attribute__ ((mode (SI)));
        !            60: typedef                 int DItype     __attribute__ ((mode (DI)));
        !            61: typedef unsigned int UDItype   __attribute__ ((mode (DI)));
        !            62: typedef        float SFtype    __attribute__ ((mode (SF)));
        !            63: typedef                float DFtype    __attribute__ ((mode (DF)));
        !            64: #if LONG_DOUBLE_TYPE_SIZE == 96
        !            65: typedef                float XFtype    __attribute__ ((mode (XF)));
        !            66: #endif
        !            67: #if LONG_DOUBLE_TYPE_SIZE == 128
        !            68: typedef                float TFtype    __attribute__ ((mode (TF)));
        !            69: #endif
        !            70: 
        !            71: #if BITS_PER_WORD==16
        !            72: typedef int word_type __attribute__ ((mode (HI)));
        !            73: #endif
        !            74: #if BITS_PER_WORD==32
        !            75: typedef int word_type __attribute__ ((mode (SI)));
        !            76: #endif
        !            77: #if BITS_PER_WORD==64
        !            78: typedef int word_type __attribute__ ((mode (DI)));
        !            79: #endif
        !            80: 
        !            81: /* Make sure that we don't accidentally use any normal C language built-in
        !            82:    type names in the first part of this file.  Instead we want to use *only*
        !            83:    the type names defined above.  The following macro definitions insure
        !            84:    that if we *do* accidentally use some normal C language built-in type name,
        !            85:    we will get a syntax error.  */
        !            86: 
        !            87: #define char bogus_type
        !            88: #define short bogus_type
        !            89: #define int bogus_type
        !            90: #define long bogus_type
        !            91: #define unsigned bogus_type
        !            92: #define float bogus_type
        !            93: #define double bogus_type
        !            94: 
        !            95: #define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT)
        !            96: 
        !            97: /* DIstructs are pairs of SItype values in the order determined by
        !            98:    WORDS_BIG_ENDIAN.  */
        !            99: 
        !           100: #if WORDS_BIG_ENDIAN
        !           101:   struct DIstruct {SItype high, low;};
        !           102: #else
        !           103:   struct DIstruct {SItype low, high;};
        !           104: #endif
        !           105: 
        !           106: /* We need this union to unpack/pack DImode values, since we don't have
        !           107:    any arithmetic yet.  Incoming DImode parameters are stored into the
        !           108:    `ll' field, and the unpacked result is read from the struct `s'.  */
        !           109: 
        !           110: typedef union
        !           111: {
        !           112:   struct DIstruct s;
        !           113:   DItype ll;
        !           114: } DIunion;
        !           115: 
        !           116: #if defined (L_udivmoddi4) || defined (L_muldi3) || defined (L_udiv_w_sdiv)
        !           117: 
        !           118: #include "longlong.h"
        !           119: 
        !           120: #endif /* udiv or mul */
        !           121: 
        !           122: extern DItype __fixunssfdi (SFtype a);
        !           123: extern DItype __fixunsdfdi (DFtype a);
        !           124: #if LONG_DOUBLE_TYPE_SIZE == 96
        !           125: extern DItype __fixunsxfdi (XFtype a);
        !           126: #endif
        !           127: #if LONG_DOUBLE_TYPE_SIZE == 128
        !           128: extern DItype __fixunstfdi (TFtype a);
        !           129: #endif
        !           130: 
        !           131: #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
        !           132: #if defined (L_divdi3) || defined (L_moddi3)
        !           133: static inline
        !           134: #endif
        !           135: DItype
        !           136: __negdi2 (u)
        !           137:      DItype u;
        !           138: {
        !           139:   DIunion w;
        !           140:   DIunion uu;
        !           141: 
        !           142:   uu.ll = u;
        !           143: 
        !           144:   w.s.low = -uu.s.low;
        !           145:   w.s.high = -uu.s.high - ((USItype) w.s.low > 0);
        !           146: 
        !           147:   return w.ll;
        !           148: }
        !           149: #endif
        !           150: 
        !           151: #ifdef L_lshldi3
        !           152: DItype
        !           153: __lshldi3 (u, b)
        !           154:      DItype u;
        !           155:      SItype b;
        !           156: {
        !           157:   DIunion w;
        !           158:   SItype bm;
        !           159:   DIunion uu;
        !           160: 
        !           161:   if (b == 0)
        !           162:     return u;
        !           163: 
        !           164:   uu.ll = u;
        !           165: 
        !           166:   bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
        !           167:   if (bm <= 0)
        !           168:     {
        !           169:       w.s.low = 0;
        !           170:       w.s.high = (USItype)uu.s.low << -bm;
        !           171:     }
        !           172:   else
        !           173:     {
        !           174:       USItype carries = (USItype)uu.s.low >> bm;
        !           175:       w.s.low = (USItype)uu.s.low << b;
        !           176:       w.s.high = ((USItype)uu.s.high << b) | carries;
        !           177:     }
        !           178: 
        !           179:   return w.ll;
        !           180: }
        !           181: #endif
        !           182: 
        !           183: #ifdef L_lshrdi3
        !           184: DItype
        !           185: __lshrdi3 (u, b)
        !           186:      DItype u;
        !           187:      SItype b;
        !           188: {
        !           189:   DIunion w;
        !           190:   SItype bm;
        !           191:   DIunion uu;
        !           192: 
        !           193:   if (b == 0)
        !           194:     return u;
        !           195: 
        !           196:   uu.ll = u;
        !           197: 
        !           198:   bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
        !           199:   if (bm <= 0)
        !           200:     {
        !           201:       w.s.high = 0;
        !           202:       w.s.low = (USItype)uu.s.high >> -bm;
        !           203:     }
        !           204:   else
        !           205:     {
        !           206:       USItype carries = (USItype)uu.s.high << bm;
        !           207:       w.s.high = (USItype)uu.s.high >> b;
        !           208:       w.s.low = ((USItype)uu.s.low >> b) | carries;
        !           209:     }
        !           210: 
        !           211:   return w.ll;
        !           212: }
        !           213: #endif
        !           214: 
        !           215: #ifdef L_ashldi3
        !           216: DItype
        !           217: __ashldi3 (u, b)
        !           218:      DItype u;
        !           219:      SItype b;
        !           220: {
        !           221:   DIunion w;
        !           222:   SItype bm;
        !           223:   DIunion uu;
        !           224: 
        !           225:   if (b == 0)
        !           226:     return u;
        !           227: 
        !           228:   uu.ll = u;
        !           229: 
        !           230:   bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
        !           231:   if (bm <= 0)
        !           232:     {
        !           233:       w.s.low = 0;
        !           234:       w.s.high = (USItype)uu.s.low << -bm;
        !           235:     }
        !           236:   else
        !           237:     {
        !           238:       USItype carries = (USItype)uu.s.low >> bm;
        !           239:       w.s.low = (USItype)uu.s.low << b;
        !           240:       w.s.high = ((USItype)uu.s.high << b) | carries;
        !           241:     }
        !           242: 
        !           243:   return w.ll;
        !           244: }
        !           245: #endif
        !           246: 
        !           247: #ifdef L_ashrdi3
        !           248: DItype
        !           249: __ashrdi3 (u, b)
        !           250:      DItype u;
        !           251:      SItype b;
        !           252: {
        !           253:   DIunion w;
        !           254:   SItype bm;
        !           255:   DIunion uu;
        !           256: 
        !           257:   if (b == 0)
        !           258:     return u;
        !           259: 
        !           260:   uu.ll = u;
        !           261: 
        !           262:   bm = (sizeof (SItype) * BITS_PER_UNIT) - b;
        !           263:   if (bm <= 0)
        !           264:     {
        !           265:       /* w.s.high = 1..1 or 0..0 */
        !           266:       w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1);
        !           267:       w.s.low = uu.s.high >> -bm;
        !           268:     }
        !           269:   else
        !           270:     {
        !           271:       USItype carries = (USItype)uu.s.high << bm;
        !           272:       w.s.high = uu.s.high >> b;
        !           273:       w.s.low = ((USItype)uu.s.low >> b) | carries;
        !           274:     }
        !           275: 
        !           276:   return w.ll;
        !           277: }
        !           278: #endif
        !           279: 
        !           280: #ifdef L_ffsdi2
        !           281: DItype
        !           282: __ffsdi2 (u)
        !           283:      DItype u;
        !           284: {
        !           285:   DIunion uu, w;
        !           286:   uu.ll = u;
        !           287:   w.s.high = 0;
        !           288:   w.s.low = ffs (uu.s.low);
        !           289:   if (w.s.low != 0)
        !           290:     return w.ll;
        !           291:   w.s.low = ffs (uu.s.high);
        !           292:   if (w.s.low != 0)
        !           293:     {
        !           294:       w.s.low += BITS_PER_UNIT * sizeof (SItype);
        !           295:       return w.ll;
        !           296:     }
        !           297:   return w.ll;
        !           298: }
        !           299: #endif
        !           300: 
        !           301: #ifdef L_muldi3
        !           302: DItype
        !           303: __muldi3 (u, v)
        !           304:      DItype u, v;
        !           305: {
        !           306:   DIunion w;
        !           307:   DIunion uu, vv;
        !           308: 
        !           309:   uu.ll = u,
        !           310:   vv.ll = v;
        !           311: 
        !           312:   w.ll = __umulsidi3 (uu.s.low, vv.s.low);
        !           313:   w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high
        !           314:               + (USItype) uu.s.high * (USItype) vv.s.low);
        !           315: 
        !           316:   return w.ll;
        !           317: }
        !           318: #endif
        !           319: 
        !           320: #ifdef L_udiv_w_sdiv
        !           321: USItype
        !           322: __udiv_w_sdiv (rp, a1, a0, d)
        !           323:      USItype *rp, a1, a0, d;
        !           324: {
        !           325:   USItype q, r;
        !           326:   USItype c0, c1, b1;
        !           327: 
        !           328:   if ((SItype) d >= 0)
        !           329:     {
        !           330:       if (a1 < d - a1 - (a0 >> (SI_TYPE_SIZE - 1)))
        !           331:        {
        !           332:          /* dividend, divisor, and quotient are nonnegative */
        !           333:          sdiv_qrnnd (q, r, a1, a0, d);
        !           334:        }
        !           335:       else
        !           336:        {
        !           337:          /* Compute c1*2^32 + c0 = a1*2^32 + a0 - 2^31*d */
        !           338:          sub_ddmmss (c1, c0, a1, a0, d >> 1, d << (SI_TYPE_SIZE - 1));
        !           339:          /* Divide (c1*2^32 + c0) by d */
        !           340:          sdiv_qrnnd (q, r, c1, c0, d);
        !           341:          /* Add 2^31 to quotient */
        !           342:          q += (USItype) 1 << (SI_TYPE_SIZE - 1);
        !           343:        }
        !           344:     }
        !           345:   else
        !           346:     {
        !           347:       b1 = d >> 1;                     /* d/2, between 2^30 and 2^31 - 1 */
        !           348:       c1 = a1 >> 1;                    /* A/2 */
        !           349:       c0 = (a1 << (SI_TYPE_SIZE - 1)) + (a0 >> 1);
        !           350: 
        !           351:       if (a1 < b1)                     /* A < 2^32*b1, so A/2 < 2^31*b1 */
        !           352:        {
        !           353:          sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
        !           354: 
        !           355:          r = 2*r + (a0 & 1);           /* Remainder from A/(2*b1) */
        !           356:          if ((d & 1) != 0)
        !           357:            {
        !           358:              if (r >= q)
        !           359:                r = r - q;
        !           360:              else if (q - r <= d)
        !           361:                {
        !           362:                  r = r - q + d;
        !           363:                  q--;
        !           364:                }
        !           365:              else
        !           366:                {
        !           367:                  r = r - q + 2*d;
        !           368:                  q -= 2;
        !           369:                }
        !           370:            }
        !           371:        }
        !           372:       else if (c1 < b1)                        /* So 2^31 <= (A/2)/b1 < 2^32 */
        !           373:        {
        !           374:          c1 = (b1 - 1) - c1;
        !           375:          c0 = ~c0;                     /* logical NOT */
        !           376: 
        !           377:          sdiv_qrnnd (q, r, c1, c0, b1); /* (A/2) / (d/2) */
        !           378: 
        !           379:          q = ~q;                       /* (A/2)/b1 */
        !           380:          r = (b1 - 1) - r;
        !           381: 
        !           382:          r = 2*r + (a0 & 1);           /* A/(2*b1) */
        !           383: 
        !           384:          if ((d & 1) != 0)
        !           385:            {
        !           386:              if (r >= q)
        !           387:                r = r - q;
        !           388:              else if (q - r <= d)
        !           389:                {
        !           390:                  r = r - q + d;
        !           391:                  q--;
        !           392:                }
        !           393:              else
        !           394:                {
        !           395:                  r = r - q + 2*d;
        !           396:                  q -= 2;
        !           397:                }
        !           398:            }
        !           399:        }
        !           400:       else                             /* Implies c1 = b1 */
        !           401:        {                               /* Hence a1 = d - 1 = 2*b1 - 1 */
        !           402:          if (a0 >= -d)
        !           403:            {
        !           404:              q = -1;
        !           405:              r = a0 + d;
        !           406:            }
        !           407:          else
        !           408:            {
        !           409:              q = -2;
        !           410:              r = a0 + 2*d;
        !           411:            }
        !           412:        }
        !           413:     }
        !           414: 
        !           415:   *rp = r;
        !           416:   return q;
        !           417: }
        !           418: #endif
        !           419: 
        !           420: #ifdef L_udivmoddi4
        !           421: static const UQItype __clz_tab[] =
        !           422: {
        !           423:   0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
        !           424:   6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
        !           425:   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
        !           426:   7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
        !           427:   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
        !           428:   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
        !           429:   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
        !           430:   8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
        !           431: };
        !           432: 
        !           433: UDItype
        !           434: __udivmoddi4 (n, d, rp)
        !           435:      UDItype n, d;
        !           436:      UDItype *rp;
        !           437: {
        !           438:   DIunion ww;
        !           439:   DIunion nn, dd;
        !           440:   DIunion rr;
        !           441:   USItype d0, d1, n0, n1, n2;
        !           442:   USItype q0, q1;
        !           443:   USItype b, bm;
        !           444: 
        !           445:   nn.ll = n;
        !           446:   dd.ll = d;
        !           447: 
        !           448:   d0 = dd.s.low;
        !           449:   d1 = dd.s.high;
        !           450:   n0 = nn.s.low;
        !           451:   n1 = nn.s.high;
        !           452: 
        !           453: #if !UDIV_NEEDS_NORMALIZATION
        !           454:   if (d1 == 0)
        !           455:     {
        !           456:       if (d0 > n1)
        !           457:        {
        !           458:          /* 0q = nn / 0D */
        !           459: 
        !           460:          udiv_qrnnd (q0, n0, n1, n0, d0);
        !           461:          q1 = 0;
        !           462: 
        !           463:          /* Remainder in n0.  */
        !           464:        }
        !           465:       else
        !           466:        {
        !           467:          /* qq = NN / 0d */
        !           468: 
        !           469:          if (d0 == 0)
        !           470:            d0 = 1 / d0;        /* Divide intentionally by zero.  */
        !           471: 
        !           472:          udiv_qrnnd (q1, n1, 0, n1, d0);
        !           473:          udiv_qrnnd (q0, n0, n1, n0, d0);
        !           474: 
        !           475:          /* Remainder in n0.  */
        !           476:        }
        !           477: 
        !           478:       if (rp != 0)
        !           479:        {
        !           480:          rr.s.low = n0;
        !           481:          rr.s.high = 0;
        !           482:          *rp = rr.ll;
        !           483:        }
        !           484:     }
        !           485: 
        !           486: #else /* UDIV_NEEDS_NORMALIZATION */
        !           487: 
        !           488:   if (d1 == 0)
        !           489:     {
        !           490:       if (d0 > n1)
        !           491:        {
        !           492:          /* 0q = nn / 0D */
        !           493: 
        !           494:          count_leading_zeros (bm, d0);
        !           495: 
        !           496:          if (bm != 0)
        !           497:            {
        !           498:              /* Normalize, i.e. make the most significant bit of the
        !           499:                 denominator set.  */
        !           500: 
        !           501:              d0 = d0 << bm;
        !           502:              n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm));
        !           503:              n0 = n0 << bm;
        !           504:            }
        !           505: 
        !           506:          udiv_qrnnd (q0, n0, n1, n0, d0);
        !           507:          q1 = 0;
        !           508: 
        !           509:          /* Remainder in n0 >> bm.  */
        !           510:        }
        !           511:       else
        !           512:        {
        !           513:          /* qq = NN / 0d */
        !           514: 
        !           515:          if (d0 == 0)
        !           516:            d0 = 1 / d0;        /* Divide intentionally by zero.  */
        !           517: 
        !           518:          count_leading_zeros (bm, d0);
        !           519: 
        !           520:          if (bm == 0)
        !           521:            {
        !           522:              /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
        !           523:                 conclude (the most significant bit of n1 is set) /\ (the
        !           524:                 leading quotient digit q1 = 1).
        !           525: 
        !           526:                 This special case is necessary, not an optimization.
        !           527:                 (Shifts counts of SI_TYPE_SIZE are undefined.)  */
        !           528: 
        !           529:              n1 -= d0;
        !           530:              q1 = 1;
        !           531:            }
        !           532:          else
        !           533:            {
        !           534:              /* Normalize.  */
        !           535: 
        !           536:              b = SI_TYPE_SIZE - bm;
        !           537: 
        !           538:              d0 = d0 << bm;
        !           539:              n2 = n1 >> b;
        !           540:              n1 = (n1 << bm) | (n0 >> b);
        !           541:              n0 = n0 << bm;
        !           542: 
        !           543:              udiv_qrnnd (q1, n1, n2, n1, d0);
        !           544:            }
        !           545: 
        !           546:          /* n1 != d0... */
        !           547: 
        !           548:          udiv_qrnnd (q0, n0, n1, n0, d0);
        !           549: 
        !           550:          /* Remainder in n0 >> bm.  */
        !           551:        }
        !           552: 
        !           553:       if (rp != 0)
        !           554:        {
        !           555:          rr.s.low = n0 >> bm;
        !           556:          rr.s.high = 0;
        !           557:          *rp = rr.ll;
        !           558:        }
        !           559:     }
        !           560: #endif /* UDIV_NEEDS_NORMALIZATION */
        !           561: 
        !           562:   else
        !           563:     {
        !           564:       if (d1 > n1)
        !           565:        {
        !           566:          /* 00 = nn / DD */
        !           567: 
        !           568:          q0 = 0;
        !           569:          q1 = 0;
        !           570: 
        !           571:          /* Remainder in n1n0.  */
        !           572:          if (rp != 0)
        !           573:            {
        !           574:              rr.s.low = n0;
        !           575:              rr.s.high = n1;
        !           576:              *rp = rr.ll;
        !           577:            }
        !           578:        }
        !           579:       else
        !           580:        {
        !           581:          /* 0q = NN / dd */
        !           582: 
        !           583:          count_leading_zeros (bm, d1);
        !           584:          if (bm == 0)
        !           585:            {
        !           586:              /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
        !           587:                 conclude (the most significant bit of n1 is set) /\ (the
        !           588:                 quotient digit q0 = 0 or 1).
        !           589: 
        !           590:                 This special case is necessary, not an optimization.  */
        !           591: 
        !           592:              /* The condition on the next line takes advantage of that
        !           593:                 n1 >= d1 (true due to program flow).  */
        !           594:              if (n1 > d1 || n0 >= d0)
        !           595:                {
        !           596:                  q0 = 1;
        !           597:                  sub_ddmmss (n1, n0, n1, n0, d1, d0);
        !           598:                }
        !           599:              else
        !           600:                q0 = 0;
        !           601: 
        !           602:              q1 = 0;
        !           603: 
        !           604:              if (rp != 0)
        !           605:                {
        !           606:                  rr.s.low = n0;
        !           607:                  rr.s.high = n1;
        !           608:                  *rp = rr.ll;
        !           609:                }
        !           610:            }
        !           611:          else
        !           612:            {
        !           613:              USItype m1, m0;
        !           614:              /* Normalize.  */
        !           615: 
        !           616:              b = SI_TYPE_SIZE - bm;
        !           617: 
        !           618:              d1 = (d1 << bm) | (d0 >> b);
        !           619:              d0 = d0 << bm;
        !           620:              n2 = n1 >> b;
        !           621:              n1 = (n1 << bm) | (n0 >> b);
        !           622:              n0 = n0 << bm;
        !           623: 
        !           624:              udiv_qrnnd (q0, n1, n2, n1, d1);
        !           625:              umul_ppmm (m1, m0, q0, d0);
        !           626: 
        !           627:              if (m1 > n1 || (m1 == n1 && m0 > n0))
        !           628:                {
        !           629:                  q0--;
        !           630:                  sub_ddmmss (m1, m0, m1, m0, d1, d0);
        !           631:                }
        !           632: 
        !           633:              q1 = 0;
        !           634: 
        !           635:              /* Remainder in (n1n0 - m1m0) >> bm.  */
        !           636:              if (rp != 0)
        !           637:                {
        !           638:                  sub_ddmmss (n1, n0, n1, n0, m1, m0);
        !           639:                  rr.s.low = (n1 << b) | (n0 >> bm);
        !           640:                  rr.s.high = n1 >> bm;
        !           641:                  *rp = rr.ll;
        !           642:                }
        !           643:            }
        !           644:        }
        !           645:     }
        !           646: 
        !           647:   ww.s.low = q0;
        !           648:   ww.s.high = q1;
        !           649:   return ww.ll;
        !           650: }
        !           651: #endif
        !           652: 
        !           653: #ifdef L_divdi3
        !           654: UDItype __udivmoddi4 ();
        !           655: 
        !           656: DItype
        !           657: __divdi3 (u, v)
        !           658:      DItype u, v;
        !           659: {
        !           660:   SItype c = 0;
        !           661:   DIunion uu, vv;
        !           662:   DItype w;
        !           663: 
        !           664:   uu.ll = u;
        !           665:   vv.ll = v;
        !           666: 
        !           667:   if (uu.s.high < 0)
        !           668:     c = ~c,
        !           669:     uu.ll = __negdi2 (uu.ll);
        !           670:   if (vv.s.high < 0)
        !           671:     c = ~c,
        !           672:     vv.ll = __negdi2 (vv.ll);
        !           673: 
        !           674:   w = __udivmoddi4 (uu.ll, vv.ll, (UDItype *) 0);
        !           675:   if (c)
        !           676:     w = __negdi2 (w);
        !           677: 
        !           678:   return w;
        !           679: }
        !           680: #endif
        !           681: 
        !           682: #ifdef L_moddi3
        !           683: UDItype __udivmoddi4 ();
        !           684: DItype
        !           685: __moddi3 (u, v)
        !           686:      DItype u, v;
        !           687: {
        !           688:   SItype c = 0;
        !           689:   DIunion uu, vv;
        !           690:   DItype w;
        !           691: 
        !           692:   uu.ll = u;
        !           693:   vv.ll = v;
        !           694: 
        !           695:   if (uu.s.high < 0)
        !           696:     c = ~c,
        !           697:     uu.ll = __negdi2 (uu.ll);
        !           698:   if (vv.s.high < 0)
        !           699:     vv.ll = __negdi2 (vv.ll);
        !           700: 
        !           701:   (void) __udivmoddi4 (uu.ll, vv.ll, &w);
        !           702:   if (c)
        !           703:     w = __negdi2 (w);
        !           704: 
        !           705:   return w;
        !           706: }
        !           707: #endif
        !           708: 
        !           709: #ifdef L_umoddi3
        !           710: UDItype __udivmoddi4 ();
        !           711: UDItype
        !           712: __umoddi3 (u, v)
        !           713:      UDItype u, v;
        !           714: {
        !           715:   DItype w;
        !           716: 
        !           717:   (void) __udivmoddi4 (u, v, &w);
        !           718: 
        !           719:   return w;
        !           720: }
        !           721: #endif
        !           722: 
        !           723: #ifdef L_udivdi3
        !           724: UDItype __udivmoddi4 ();
        !           725: UDItype
        !           726: __udivdi3 (n, d)
        !           727:      UDItype n, d;
        !           728: {
        !           729:   return __udivmoddi4 (n, d, (UDItype *) 0);
        !           730: }
        !           731: #endif
        !           732: 
        !           733: #ifdef L_cmpdi2
        !           734: word_type
        !           735: __cmpdi2 (a, b)
        !           736:      DItype a, b;
        !           737: {
        !           738:   DIunion au, bu;
        !           739: 
        !           740:   au.ll = a, bu.ll = b;
        !           741: 
        !           742:   if (au.s.high < bu.s.high)
        !           743:     return 0;
        !           744:   else if (au.s.high > bu.s.high)
        !           745:     return 2;
        !           746:   if ((USItype) au.s.low < (USItype) bu.s.low)
        !           747:     return 0;
        !           748:   else if ((USItype) au.s.low > (USItype) bu.s.low)
        !           749:     return 2;
        !           750:   return 1;
        !           751: }
        !           752: #endif
        !           753: 
        !           754: #ifdef L_ucmpdi2
        !           755: word_type
        !           756: __ucmpdi2 (a, b)
        !           757:      DItype a, b;
        !           758: {
        !           759:   DIunion au, bu;
        !           760: 
        !           761:   au.ll = a, bu.ll = b;
        !           762: 
        !           763:   if ((USItype) au.s.high < (USItype) bu.s.high)
        !           764:     return 0;
        !           765:   else if ((USItype) au.s.high > (USItype) bu.s.high)
        !           766:     return 2;
        !           767:   if ((USItype) au.s.low < (USItype) bu.s.low)
        !           768:     return 0;
        !           769:   else if ((USItype) au.s.low > (USItype) bu.s.low)
        !           770:     return 2;
        !           771:   return 1;
        !           772: }
        !           773: #endif
        !           774: 
        !           775: #if defined(L_fixunstfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
        !           776: #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
        !           777: #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
        !           778: 
        !           779: DItype
        !           780: __fixunstfdi (a)
        !           781:      TFtype a;
        !           782: {
        !           783:   TFtype b;
        !           784:   UDItype v;
        !           785: 
        !           786:   if (a < 0)
        !           787:     return 0;
        !           788: 
        !           789:   /* Compute high word of result, as a flonum.  */
        !           790:   b = (a / HIGH_WORD_COEFF);
        !           791:   /* Convert that to fixed (but not to DItype!),
        !           792:      and shift it into the high word.  */
        !           793:   v = (USItype) b;
        !           794:   v <<= WORD_SIZE;
        !           795:   /* Remove high part from the TFtype, leaving the low part as flonum.  */
        !           796:   a -= (TFtype)v;
        !           797:   /* Convert that to fixed (but not to DItype!) and add it in.
        !           798:      Sometimes A comes out negative.  This is significant, since
        !           799:      A has more bits than a long int does.  */
        !           800:   if (a < 0)
        !           801:     v -= (USItype) (- a);
        !           802:   else
        !           803:     v += (USItype) a;
        !           804:   return v;
        !           805: }
        !           806: #endif
        !           807: 
        !           808: #if defined(L_fixtfdi) && (LONG_DOUBLE_TYPE_SIZE == 128)
        !           809: DItype
        !           810: __fixtfdi (a)
        !           811:      TFtype a;
        !           812: {
        !           813:   if (a < 0)
        !           814:     return - __fixunstfdi (-a);
        !           815:   return __fixunstfdi (a);
        !           816: }
        !           817: #endif
        !           818: 
        !           819: #if defined(L_fixunsxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
        !           820: #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
        !           821: #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
        !           822: 
        !           823: DItype
        !           824: __fixunsxfdi (a)
        !           825:      XFtype a;
        !           826: {
        !           827:   XFtype b;
        !           828:   UDItype v;
        !           829: 
        !           830:   if (a < 0)
        !           831:     return 0;
        !           832: 
        !           833:   /* Compute high word of result, as a flonum.  */
        !           834:   b = (a / HIGH_WORD_COEFF);
        !           835:   /* Convert that to fixed (but not to DItype!),
        !           836:      and shift it into the high word.  */
        !           837:   v = (USItype) b;
        !           838:   v <<= WORD_SIZE;
        !           839:   /* Remove high part from the XFtype, leaving the low part as flonum.  */
        !           840:   a -= (XFtype)v;
        !           841:   /* Convert that to fixed (but not to DItype!) and add it in.
        !           842:      Sometimes A comes out negative.  This is significant, since
        !           843:      A has more bits than a long int does.  */
        !           844:   if (a < 0)
        !           845:     v -= (USItype) (- a);
        !           846:   else
        !           847:     v += (USItype) a;
        !           848:   return v;
        !           849: }
        !           850: #endif
        !           851: 
        !           852: #if defined(L_fixxfdi) && (LONG_DOUBLE_TYPE_SIZE == 96)
        !           853: DItype
        !           854: __fixxfdi (a)
        !           855:      XFtype a;
        !           856: {
        !           857:   if (a < 0)
        !           858:     return - __fixunsxfdi (-a);
        !           859:   return __fixunsxfdi (a);
        !           860: }
        !           861: #endif
        !           862: 
        !           863: #ifdef L_fixunsdfdi
        !           864: #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
        !           865: #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
        !           866: 
        !           867: DItype
        !           868: __fixunsdfdi (a)
        !           869:      DFtype a;
        !           870: {
        !           871:   DFtype b;
        !           872:   UDItype v;
        !           873: 
        !           874:   if (a < 0)
        !           875:     return 0;
        !           876: 
        !           877:   /* Compute high word of result, as a flonum.  */
        !           878:   b = (a / HIGH_WORD_COEFF);
        !           879:   /* Convert that to fixed (but not to DItype!),
        !           880:      and shift it into the high word.  */
        !           881:   v = (USItype) b;
        !           882:   v <<= WORD_SIZE;
        !           883:   /* Remove high part from the DFtype, leaving the low part as flonum.  */
        !           884:   a -= (DFtype)v;
        !           885:   /* Convert that to fixed (but not to DItype!) and add it in.
        !           886:      Sometimes A comes out negative.  This is significant, since
        !           887:      A has more bits than a long int does.  */
        !           888:   if (a < 0)
        !           889:     v -= (USItype) (- a);
        !           890:   else
        !           891:     v += (USItype) a;
        !           892:   return v;
        !           893: }
        !           894: #endif
        !           895: 
        !           896: #ifdef L_fixdfdi
        !           897: DItype
        !           898: __fixdfdi (a)
        !           899:      DFtype a;
        !           900: {
        !           901:   if (a < 0)
        !           902:     return - __fixunsdfdi (-a);
        !           903:   return __fixunsdfdi (a);
        !           904: }
        !           905: #endif
        !           906: 
        !           907: #ifdef L_fixunssfdi
        !           908: #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
        !           909: #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
        !           910: 
        !           911: DItype
        !           912: __fixunssfdi (SFtype original_a)
        !           913: {
        !           914:   /* Convert the SFtype to a DFtype, because that is surely not going
        !           915:      to lose any bits.  Some day someone else can write a faster version
        !           916:      that avoids converting to DFtype, and verify it really works right.  */
        !           917:   DFtype a = original_a;
        !           918:   DFtype b;
        !           919:   UDItype v;
        !           920: 
        !           921:   if (a < 0)
        !           922:     return 0;
        !           923: 
        !           924:   /* Compute high word of result, as a flonum.  */
        !           925:   b = (a / HIGH_WORD_COEFF);
        !           926:   /* Convert that to fixed (but not to DItype!),
        !           927:      and shift it into the high word.  */
        !           928:   v = (USItype) b;
        !           929:   v <<= WORD_SIZE;
        !           930:   /* Remove high part from the DFtype, leaving the low part as flonum.  */
        !           931:   a -= (DFtype)v;
        !           932:   /* Convert that to fixed (but not to DItype!) and add it in.
        !           933:      Sometimes A comes out negative.  This is significant, since
        !           934:      A has more bits than a long int does.  */
        !           935:   if (a < 0)
        !           936:     v -= (USItype) (- a);
        !           937:   else
        !           938:     v += (USItype) a;
        !           939:   return v;
        !           940: }
        !           941: #endif
        !           942: 
        !           943: #ifdef L_fixsfdi
        !           944: DItype
        !           945: __fixsfdi (SFtype a)
        !           946: {
        !           947:   if (a < 0)
        !           948:     return - __fixunssfdi (-a);
        !           949:   return __fixunssfdi (a);
        !           950: }
        !           951: #endif
        !           952: 
        !           953: #if defined(L_floatdixf) && (LONG_DOUBLE_TYPE_SIZE == 96)
        !           954: #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
        !           955: #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
        !           956: #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
        !           957: 
        !           958: XFtype
        !           959: __floatdixf (u)
        !           960:      DItype u;
        !           961: {
        !           962:   XFtype d;
        !           963:   SItype negate = 0;
        !           964: 
        !           965:   if (u < 0)
        !           966:     u = -u, negate = 1;
        !           967: 
        !           968:   d = (USItype) (u >> WORD_SIZE);
        !           969:   d *= HIGH_HALFWORD_COEFF;
        !           970:   d *= HIGH_HALFWORD_COEFF;
        !           971:   d += (USItype) (u & (HIGH_WORD_COEFF - 1));
        !           972: 
        !           973:   return (negate ? -d : d);
        !           974: }
        !           975: #endif
        !           976: 
        !           977: #if defined(L_floatditf) && (LONG_DOUBLE_TYPE_SIZE == 128)
        !           978: #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
        !           979: #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
        !           980: #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
        !           981: 
        !           982: TFtype
        !           983: __floatditf (u)
        !           984:      DItype u;
        !           985: {
        !           986:   TFtype d;
        !           987:   SItype negate = 0;
        !           988: 
        !           989:   if (u < 0)
        !           990:     u = -u, negate = 1;
        !           991: 
        !           992:   d = (USItype) (u >> WORD_SIZE);
        !           993:   d *= HIGH_HALFWORD_COEFF;
        !           994:   d *= HIGH_HALFWORD_COEFF;
        !           995:   d += (USItype) (u & (HIGH_WORD_COEFF - 1));
        !           996: 
        !           997:   return (negate ? -d : d);
        !           998: }
        !           999: #endif
        !          1000: 
        !          1001: #ifdef L_floatdidf
        !          1002: #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
        !          1003: #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
        !          1004: #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
        !          1005: 
        !          1006: DFtype
        !          1007: __floatdidf (u)
        !          1008:      DItype u;
        !          1009: {
        !          1010:   DFtype d;
        !          1011:   SItype negate = 0;
        !          1012: 
        !          1013:   if (u < 0)
        !          1014:     u = -u, negate = 1;
        !          1015: 
        !          1016:   d = (USItype) (u >> WORD_SIZE);
        !          1017:   d *= HIGH_HALFWORD_COEFF;
        !          1018:   d *= HIGH_HALFWORD_COEFF;
        !          1019:   d += (USItype) (u & (HIGH_WORD_COEFF - 1));
        !          1020: 
        !          1021:   return (negate ? -d : d);
        !          1022: }
        !          1023: #endif
        !          1024: 
        !          1025: #ifdef L_floatdisf
        !          1026: #define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT)
        !          1027: #define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2))
        !          1028: #define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE)
        !          1029: 
        !          1030: SFtype
        !          1031: __floatdisf (u)
        !          1032:      DItype u;
        !          1033: {
        !          1034:   /* Do the calculation in DFmode
        !          1035:      so that we don't lose any of the precision of the high word
        !          1036:      while multiplying it.  */
        !          1037:   DFtype f;
        !          1038:   SItype negate = 0;
        !          1039: 
        !          1040:   if (u < 0)
        !          1041:     u = -u, negate = 1;
        !          1042: 
        !          1043:   f = (USItype) (u >> WORD_SIZE);
        !          1044:   f *= HIGH_HALFWORD_COEFF;
        !          1045:   f *= HIGH_HALFWORD_COEFF;
        !          1046:   f += (USItype) (u & (HIGH_WORD_COEFF - 1));
        !          1047: 
        !          1048:   return (SFtype) (negate ? -f : f);
        !          1049: }
        !          1050: #endif
        !          1051: 
        !          1052: #if defined(L_fixunsxfsi) && LONG_DOUBLE_TYPE_SIZE == 96
        !          1053: #include "glimits.h"
        !          1054: 
        !          1055: USItype
        !          1056: __fixunsxfsi (a)
        !          1057:      XFtype a;
        !          1058: {
        !          1059:   if (a >= - (DFtype) LONG_MIN)
        !          1060:     return (SItype) (a + LONG_MIN) - LONG_MIN;
        !          1061:   return (SItype) a;
        !          1062: }
        !          1063: #endif
        !          1064: 
        !          1065: #ifdef L_fixunsdfsi
        !          1066: #include "glimits.h"
        !          1067: 
        !          1068: USItype
        !          1069: __fixunsdfsi (a)
        !          1070:      DFtype a;
        !          1071: {
        !          1072:   if (a >= - (DFtype) LONG_MIN)
        !          1073:     return (SItype) (a + LONG_MIN) - LONG_MIN;
        !          1074:   return (SItype) a;
        !          1075: }
        !          1076: #endif
        !          1077: 
        !          1078: #ifdef L_fixunssfsi
        !          1079: #include "glimits.h"
        !          1080: 
        !          1081: USItype
        !          1082: __fixunssfsi (SFtype a)
        !          1083: {
        !          1084:   if (a >= - (SFtype) LONG_MIN)
        !          1085:     return (SItype) (a + LONG_MIN) - LONG_MIN;
        !          1086:   return (SItype) a;
        !          1087: }
        !          1088: #endif
        !          1089: 
        !          1090: /* From here on down, the routines use normal data types.  */
        !          1091: 
        !          1092: #define SItype bogus_type
        !          1093: #define USItype bogus_type
        !          1094: #define DItype bogus_type
        !          1095: #define UDItype bogus_type
        !          1096: #define SFtype bogus_type
        !          1097: #define DFtype bogus_type
        !          1098: 
        !          1099: #undef char
        !          1100: #undef short
        !          1101: #undef int
        !          1102: #undef long
        !          1103: #undef unsigned
        !          1104: #undef float
        !          1105: #undef double
        !          1106: 
        !          1107: #ifdef L__gcc_bcmp
        !          1108: 
        !          1109: /* Like bcmp except the sign is meaningful.
        !          1110:    Reult is negative if S1 is less than S2,
        !          1111:    positive if S1 is greater, 0 if S1 and S2 are equal.  */
        !          1112: 
        !          1113: int
        !          1114: __gcc_bcmp (s1, s2, size)
        !          1115:      unsigned char *s1, *s2;
        !          1116:      size_t size;
        !          1117: {
        !          1118:   while (size > 0)
        !          1119:     {
        !          1120:       unsigned char c1 = *s1++, c2 = *s2++;
        !          1121:       if (c1 != c2)
        !          1122:        return c1 - c2;
        !          1123:       size--;
        !          1124:     }
        !          1125:   return 0;
        !          1126: }
        !          1127: 
        !          1128: #endif
        !          1129: 
        !          1130: #ifdef L_varargs
        !          1131: #ifdef __i860__
        !          1132: #if defined(__svr4__) || defined(__alliant__)
        !          1133:        asm ("  .text");
        !          1134:        asm ("  .align  4");
        !          1135: 
        !          1136: /* The Alliant needs the added underscore.  */
        !          1137:        asm (".globl    __builtin_saveregs");
        !          1138: asm ("__builtin_saveregs:");
        !          1139:        asm (".globl    ___builtin_saveregs");
        !          1140: asm ("___builtin_saveregs:");
        !          1141: 
        !          1142:         asm (" andnot  0x0f,%sp,%sp"); /* round down to 16-byte boundary */
        !          1143:        asm ("  adds    -96,%sp,%sp");  /* allocate stack space for reg save
        !          1144:                                           area and also for a new va_list
        !          1145:                                           structure */
        !          1146:        /* Save all argument registers in the arg reg save area.  The
        !          1147:           arg reg save area must have the following layout (according
        !          1148:           to the svr4 ABI):
        !          1149: 
        !          1150:                struct {
        !          1151:                  union  {
        !          1152:                    float freg[8];
        !          1153:                    double dreg[4];
        !          1154:                  } float_regs;
        !          1155:                  long  ireg[12];
        !          1156:                };
        !          1157:        */
        !          1158: 
        !          1159:        asm ("  fst.q   %f8,  0(%sp)"); /* save floating regs (f8-f15)  */
        !          1160:        asm ("  fst.q   %f12,16(%sp)"); 
        !          1161: 
        !          1162:        asm ("  st.l    %r16,32(%sp)"); /* save integer regs (r16-r27) */
        !          1163:        asm ("  st.l    %r17,36(%sp)"); 
        !          1164:        asm ("  st.l    %r18,40(%sp)");
        !          1165:        asm ("  st.l    %r19,44(%sp)");
        !          1166:        asm ("  st.l    %r20,48(%sp)");
        !          1167:        asm ("  st.l    %r21,52(%sp)");
        !          1168:        asm ("  st.l    %r22,56(%sp)");
        !          1169:        asm ("  st.l    %r23,60(%sp)");
        !          1170:        asm ("  st.l    %r24,64(%sp)");
        !          1171:        asm ("  st.l    %r25,68(%sp)");
        !          1172:        asm ("  st.l    %r26,72(%sp)");
        !          1173:        asm ("  st.l    %r27,76(%sp)");
        !          1174: 
        !          1175:        asm ("  adds    80,%sp,%r16");  /* compute the address of the new
        !          1176:                                           va_list structure.  Put in into
        !          1177:                                           r16 so that it will be returned
        !          1178:                                           to the caller.  */
        !          1179: 
        !          1180:        /* Initialize all fields of the new va_list structure.  This
        !          1181:           structure looks like:
        !          1182: 
        !          1183:                typedef struct {
        !          1184:                    unsigned long       ireg_used;
        !          1185:                    unsigned long       freg_used;
        !          1186:                    long                *reg_base;
        !          1187:                    long                *mem_ptr;
        !          1188:                } va_list;
        !          1189:        */
        !          1190: 
        !          1191:        asm ("  st.l    %r0, 0(%r16)"); /* nfixed */
        !          1192:        asm ("  st.l    %r0, 4(%r16)"); /* nfloating */
        !          1193:        asm ("  st.l    %sp, 8(%r16)"); /* __va_ctl points to __va_struct.  */
        !          1194:        asm ("  bri     %r1");          /* delayed return */
        !          1195:        asm ("  st.l    %r28,12(%r16)"); /* pointer to overflow args */
        !          1196: 
        !          1197: #else /* not __svr4__ */
        !          1198: #if defined(__PARAGON__)
        !          1199:        /*
        !          1200:         *      we'll use SVR4-ish varargs but need SVR3.2 assembler syntax,
        !          1201:         *      and we stand a better chance of hooking into libraries
        !          1202:         *      compiled by PGI.  [[email protected]]
        !          1203:         */
        !          1204:        asm ("  .text");
        !          1205:        asm ("  .align  4");
        !          1206:        asm (".globl    __builtin_saveregs");
        !          1207: asm ("__builtin_saveregs:");
        !          1208:        asm (".globl    ___builtin_saveregs");
        !          1209: asm ("___builtin_saveregs:");
        !          1210: 
        !          1211:         asm (" andnot  0x0f,sp,sp");   /* round down to 16-byte boundary */
        !          1212:        asm ("  adds    -96,sp,sp");    /* allocate stack space for reg save
        !          1213:                                           area and also for a new va_list
        !          1214:                                           structure */
        !          1215:        /* Save all argument registers in the arg reg save area.  The
        !          1216:           arg reg save area must have the following layout (according
        !          1217:           to the svr4 ABI):
        !          1218: 
        !          1219:                struct {
        !          1220:                  union  {
        !          1221:                    float freg[8];
        !          1222:                    double dreg[4];
        !          1223:                  } float_regs;
        !          1224:                  long  ireg[12];
        !          1225:                };
        !          1226:        */
        !          1227: 
        !          1228:        asm ("  fst.q   f8,  0(sp)");
        !          1229:        asm ("  fst.q   f12,16(sp)"); 
        !          1230:        asm ("  st.l    r16,32(sp)");
        !          1231:        asm ("  st.l    r17,36(sp)"); 
        !          1232:        asm ("  st.l    r18,40(sp)");
        !          1233:        asm ("  st.l    r19,44(sp)");
        !          1234:        asm ("  st.l    r20,48(sp)");
        !          1235:        asm ("  st.l    r21,52(sp)");
        !          1236:        asm ("  st.l    r22,56(sp)");
        !          1237:        asm ("  st.l    r23,60(sp)");
        !          1238:        asm ("  st.l    r24,64(sp)");
        !          1239:        asm ("  st.l    r25,68(sp)");
        !          1240:        asm ("  st.l    r26,72(sp)");
        !          1241:        asm ("  st.l    r27,76(sp)");
        !          1242: 
        !          1243:        asm ("  adds    80,sp,r16");  /* compute the address of the new
        !          1244:                                           va_list structure.  Put in into
        !          1245:                                           r16 so that it will be returned
        !          1246:                                           to the caller.  */
        !          1247: 
        !          1248:        /* Initialize all fields of the new va_list structure.  This
        !          1249:           structure looks like:
        !          1250: 
        !          1251:                typedef struct {
        !          1252:                    unsigned long       ireg_used;
        !          1253:                    unsigned long       freg_used;
        !          1254:                    long                *reg_base;
        !          1255:                    long                *mem_ptr;
        !          1256:                } va_list;
        !          1257:        */
        !          1258: 
        !          1259:        asm ("  st.l    r0, 0(r16)"); /* nfixed */
        !          1260:        asm ("  st.l    r0, 4(r16)"); /* nfloating */
        !          1261:        asm ("  st.l    sp, 8(r16)"); /* __va_ctl points to __va_struct.  */
        !          1262:        asm ("  bri     r1");           /* delayed return */
        !          1263:        asm ("   st.l   r28,12(r16)"); /* pointer to overflow args */
        !          1264: #else /* not __PARAGON__ */
        !          1265:        asm ("  .text");
        !          1266:        asm ("  .align  4");
        !          1267: 
        !          1268:        asm (".globl    ___builtin_saveregs");
        !          1269:        asm ("___builtin_saveregs:");
        !          1270:        asm ("  mov     sp,r30");
        !          1271:        asm ("  andnot  0x0f,sp,sp");
        !          1272:        asm ("  adds    -96,sp,sp");  /* allocate sufficient space on the stack */
        !          1273: 
        !          1274: /* Fill in the __va_struct.  */
        !          1275:        asm ("  st.l    r16, 0(sp)"); /* save integer regs (r16-r27) */
        !          1276:        asm ("  st.l    r17, 4(sp)"); /* int    fixed[12] */
        !          1277:        asm ("  st.l    r18, 8(sp)");
        !          1278:        asm ("  st.l    r19,12(sp)");
        !          1279:        asm ("  st.l    r20,16(sp)");
        !          1280:        asm ("  st.l    r21,20(sp)");
        !          1281:        asm ("  st.l    r22,24(sp)");
        !          1282:        asm ("  st.l    r23,28(sp)");
        !          1283:        asm ("  st.l    r24,32(sp)");
        !          1284:        asm ("  st.l    r25,36(sp)");
        !          1285:        asm ("  st.l    r26,40(sp)");
        !          1286:        asm ("  st.l    r27,44(sp)");
        !          1287: 
        !          1288:        asm ("  fst.q   f8, 48(sp)"); /* save floating regs (f8-f15) */
        !          1289:        asm ("  fst.q   f12,64(sp)"); /* int floating[8] */
        !          1290: 
        !          1291: /* Fill in the __va_ctl.  */
        !          1292:        asm ("  st.l    sp, 80(sp)"); /* __va_ctl points to __va_struct.  */
        !          1293:        asm ("  st.l    r28,84(sp)"); /* pointer to more args */
        !          1294:        asm ("  st.l    r0, 88(sp)"); /* nfixed */
        !          1295:        asm ("  st.l    r0, 92(sp)"); /* nfloating */
        !          1296: 
        !          1297:        asm ("  adds    80,sp,r16");  /* return address of the __va_ctl.  */
        !          1298:        asm ("  bri     r1");
        !          1299:        asm ("  mov     r30,sp");
        !          1300:                                /* recover stack and pass address to start 
        !          1301:                                   of data.  */
        !          1302: #endif /* not __PARAGON__ */
        !          1303: #endif /* not __svr4__ */
        !          1304: #else /* not __i860__ */
        !          1305: #ifdef __sparc__
        !          1306:        asm (".global __builtin_saveregs");
        !          1307:        asm ("__builtin_saveregs:");
        !          1308:        asm (".global ___builtin_saveregs");
        !          1309:        asm ("___builtin_saveregs:");
        !          1310: #ifdef NEED_PROC_COMMAND
        !          1311:        asm (".proc 020");
        !          1312: #endif
        !          1313:        asm ("st %i0,[%fp+68]");
        !          1314:        asm ("st %i1,[%fp+72]");
        !          1315:        asm ("st %i2,[%fp+76]");
        !          1316:        asm ("st %i3,[%fp+80]");
        !          1317:        asm ("st %i4,[%fp+84]");
        !          1318:        asm ("retl");
        !          1319:        asm ("st %i5,[%fp+88]");
        !          1320: #ifdef NEED_TYPE_COMMAND
        !          1321:        asm (".type __builtin_saveregs,#function");
        !          1322:        asm (".size __builtin_saveregs,.-__builtin_saveregs");
        !          1323: #endif
        !          1324: #else /* not __sparc__ */
        !          1325: #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
        !          1326: 
        !          1327:   asm ("       .text");
        !          1328:   asm ("       .ent __builtin_saveregs");
        !          1329:   asm ("       .globl __builtin_saveregs");
        !          1330:   asm ("__builtin_saveregs:");
        !          1331:   asm ("       sw      $4,0($30)");
        !          1332:   asm ("       sw      $5,4($30)");
        !          1333:   asm ("       sw      $6,8($30)");
        !          1334:   asm ("       sw      $7,12($30)");
        !          1335:   asm ("       j       $31");
        !          1336:   asm ("       .end __builtin_saveregs");
        !          1337: #else /* not __mips__, etc. */
        !          1338: __builtin_saveregs ()
        !          1339: {
        !          1340:   abort ();
        !          1341: }
        !          1342: #endif /* not __mips__ */
        !          1343: #endif /* not __sparc__ */
        !          1344: #endif /* not __i860__ */
        !          1345: #endif
        !          1346: 
        !          1347: #ifdef L_eprintf
        !          1348: #ifndef inhibit_libc
        !          1349: 
        !          1350: #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
        !          1351: #include <stdio.h>
        !          1352: /* This is used by the `assert' macro.  */
        !          1353: void
        !          1354: __eprintf (string, expression, line, filename)
        !          1355:      const char *string;
        !          1356:      const char *expression;
        !          1357:      int line;
        !          1358:      const char *filename;
        !          1359: {
        !          1360:   fprintf (stderr, string, expression, line, filename);
        !          1361:   fflush (stderr);
        !          1362:   abort ();
        !          1363: }
        !          1364: 
        !          1365: #endif
        !          1366: #endif
        !          1367: 
        !          1368: #ifdef L_bb
        !          1369: 
        !          1370: /* Structure emitted by -a  */
        !          1371: struct bb
        !          1372: {
        !          1373:   long zero_word;
        !          1374:   const char *filename;
        !          1375:   long *counts;
        !          1376:   long ncounts;
        !          1377:   struct bb *next;
        !          1378:   const unsigned long *addresses;
        !          1379: 
        !          1380:   /* Older GCC's did not emit these fields.  */
        !          1381:   long nwords;
        !          1382:   const char **functions;
        !          1383:   const long *line_nums;
        !          1384:   const char **filenames;
        !          1385: };
        !          1386: 
        !          1387: #ifdef BLOCK_PROFILER_CODE
        !          1388: BLOCK_PROFILER_CODE
        !          1389: #else
        !          1390: #ifndef inhibit_libc
        !          1391: 
        !          1392: /* Simple minded basic block profiling output dumper for
        !          1393:    systems that don't provde tcov support.  At present,
        !          1394:    it requires atexit and stdio.  */
        !          1395: 
        !          1396: #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
        !          1397: #include <stdio.h>
        !          1398: 
        !          1399: #ifdef HAVE_ATEXIT
        !          1400: extern void atexit (void (*) (void));
        !          1401: #define ON_EXIT(FUNC,ARG) atexit ((FUNC))
        !          1402: #else
        !          1403: #ifdef sun
        !          1404: extern void on_exit (void*, void*);
        !          1405: #define ON_EXIT(FUNC,ARG) on_exit ((FUNC), (ARG))
        !          1406: #endif
        !          1407: #endif
        !          1408: 
        !          1409: static struct bb *bb_head = (struct bb *)0;
        !          1410: 
        !          1411: /* Return the number of digits needed to print a value */
        !          1412: /* __inline__ */ static int num_digits (long value, int base)
        !          1413: {
        !          1414:   int minus = (value < 0 && base != 16);
        !          1415:   unsigned long v = (minus) ? -value : value;
        !          1416:   int ret = minus;
        !          1417: 
        !          1418:   do
        !          1419:     {
        !          1420:       v /= base;
        !          1421:       ret++;
        !          1422:     }
        !          1423:   while (v);
        !          1424: 
        !          1425:   return ret;
        !          1426: }
        !          1427: 
        !          1428: void
        !          1429: __bb_exit_func (void)
        !          1430: {
        !          1431:   FILE *file = fopen ("bb.out", "a");
        !          1432:   long time_value;
        !          1433: 
        !          1434:   if (!file)
        !          1435:     perror ("bb.out");
        !          1436: 
        !          1437:   else
        !          1438:     {
        !          1439:       struct bb *ptr;
        !          1440: 
        !          1441:       /* This is somewhat type incorrect, but it avoids worrying about
        !          1442:         exactly where time.h is included from.  It should be ok unless
        !          1443:         a void * differs from other pointer formats, or if sizeof(long)
        !          1444:         is < sizeof (time_t).  It would be nice if we could assume the
        !          1445:         use of rationale standards here.  */
        !          1446: 
        !          1447:       time((void *) &time_value);
        !          1448:       fprintf (file, "Basic block profiling finished on %s\n", ctime ((void *) &time_value));
        !          1449: 
        !          1450:       /* We check the length field explicitly in order to allow compatibility
        !          1451:         with older GCC's which did not provide it.  */
        !          1452: 
        !          1453:       for (ptr = bb_head; ptr != (struct bb *)0; ptr = ptr->next)
        !          1454:        {
        !          1455:          int i;
        !          1456:          int func_p    = (ptr->nwords >= sizeof (struct bb) && ptr->nwords <= 1000);
        !          1457:          int line_p    = (func_p && ptr->line_nums);
        !          1458:          int file_p    = (func_p && ptr->filenames);
        !          1459:          long ncounts  = ptr->ncounts;
        !          1460:          long cnt_max  = 0;
        !          1461:          long line_max = 0;
        !          1462:          long addr_max = 0;
        !          1463:          int file_len  = 0;
        !          1464:          int func_len  = 0;
        !          1465:          int blk_len   = num_digits (ncounts, 10);
        !          1466:          int cnt_len;
        !          1467:          int line_len;
        !          1468:          int addr_len;
        !          1469: 
        !          1470:          fprintf (file, "File %s, %ld basic blocks \n\n",
        !          1471:                   ptr->filename, ncounts);
        !          1472: 
        !          1473:          /* Get max values for each field.  */
        !          1474:          for (i = 0; i < ncounts; i++)
        !          1475:            {
        !          1476:              const char *p;
        !          1477:              int len;
        !          1478: 
        !          1479:              if (cnt_max < ptr->counts[i])
        !          1480:                cnt_max = ptr->counts[i];
        !          1481: 
        !          1482:              if (addr_max < ptr->addresses[i])
        !          1483:                addr_max = ptr->addresses[i];
        !          1484: 
        !          1485:              if (line_p && line_max < ptr->line_nums[i])
        !          1486:                line_max = ptr->line_nums[i];
        !          1487: 
        !          1488:              if (func_p)
        !          1489:                {
        !          1490:                  p = (ptr->functions[i]) ? (ptr->functions[i]) : "<none>";
        !          1491:                  len = strlen (p);
        !          1492:                  if (func_len < len)
        !          1493:                    func_len = len;
        !          1494:                }
        !          1495: 
        !          1496:              if (file_p)
        !          1497:                {
        !          1498:                  p = (ptr->filenames[i]) ? (ptr->filenames[i]) : "<none>";
        !          1499:                  len = strlen (p);
        !          1500:                  if (file_len < len)
        !          1501:                    file_len = len;
        !          1502:                }
        !          1503:            }
        !          1504: 
        !          1505:          addr_len = num_digits (addr_max, 16);
        !          1506:          cnt_len  = num_digits (cnt_max, 10);
        !          1507:          line_len = num_digits (line_max, 10);
        !          1508: 
        !          1509:          /* Now print out the basic block information.  */
        !          1510:          for (i = 0; i < ncounts; i++)
        !          1511:            {
        !          1512:              fprintf (file,
        !          1513:                       "    Block #%*d: executed %*ld time(s) address= 0x%.*lx",
        !          1514:                       blk_len, i+1,
        !          1515:                       cnt_len, ptr->counts[i],
        !          1516:                       addr_len, ptr->addresses[i]);
        !          1517: 
        !          1518:              if (func_p)
        !          1519:                fprintf (file, " function= %-*s", func_len,
        !          1520:                         (ptr->functions[i]) ? ptr->functions[i] : "<none>");
        !          1521: 
        !          1522:              if (line_p)
        !          1523:                fprintf (file, " line= %*ld", line_len, ptr->line_nums[i]);
        !          1524: 
        !          1525:              if (file_p)
        !          1526:                fprintf (file, " file= %s",
        !          1527:                         (ptr->filenames[i]) ? ptr->filenames[i] : "<none>");
        !          1528: 
        !          1529:              fprintf (file, "\n");
        !          1530:            }
        !          1531: 
        !          1532:          fprintf (file, "\n");
        !          1533:          fflush (file);
        !          1534:        }
        !          1535: 
        !          1536:       fprintf (file, "\n\n");
        !          1537:       fclose (file);
        !          1538:     }
        !          1539: }
        !          1540: 
        !          1541: void
        !          1542: __bb_init_func (struct bb *blocks)
        !          1543: {
        !          1544:   /* User is supposed to check whether the first word is non-0,
        !          1545:      but just in case.... */
        !          1546: 
        !          1547:   if (blocks->zero_word)
        !          1548:     return;
        !          1549: 
        !          1550: #ifdef ON_EXIT
        !          1551:   /* Initialize destructor.  */
        !          1552:   if (!bb_head)
        !          1553:     ON_EXIT (__bb_exit_func, 0);
        !          1554: #endif
        !          1555: 
        !          1556:   /* Set up linked list.  */
        !          1557:   blocks->zero_word = 1;
        !          1558:   blocks->next = bb_head;
        !          1559:   bb_head = blocks;
        !          1560: }
        !          1561: 
        !          1562: #endif /* not inhibit_libc */
        !          1563: #endif /* not BLOCK_PROFILER_CODE */
        !          1564: #endif /* L_bb */
        !          1565: 
        !          1566: /* frills for C++ */
        !          1567: 
        !          1568: #ifdef L_op_new
        !          1569: typedef void (*vfp)(void);
        !          1570: 
        !          1571: #ifdef NEXT_SEMANTICS
        !          1572: extern vfp __get_new_handler ();
        !          1573: #else
        !          1574: extern vfp __new_handler;
        !          1575: #endif
        !          1576: 
        !          1577: /* void * operator new (size_t sz) */
        !          1578: void *
        !          1579: __builtin_new (size_t sz)
        !          1580: {
        !          1581:   void *p;
        !          1582: 
        !          1583:   /* malloc (0) is unpredictable; avoid it.  */
        !          1584:   if (sz == 0)
        !          1585:     sz = 1;
        !          1586:   p = (void *) malloc (sz);
        !          1587:   if (p == 0)
        !          1588: #ifdef NEXT_SEMANTICS
        !          1589:     (*__get_new_handler ()) ();
        !          1590: #else
        !          1591:     (*__new_handler) ();
        !          1592: #endif
        !          1593:   return p;
        !          1594: }
        !          1595: #endif /* L_op_new */
        !          1596: 
        !          1597: #ifdef L_new_handler
        !          1598: 
        !          1599: #ifndef inhibit_libc
        !          1600: /* This gets us __GNU_LIBRARY__.  */
        !          1601: #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
        !          1602: #include <stdio.h>
        !          1603: 
        !          1604: #ifdef __GNU_LIBRARY__
        !          1605:   /* Avoid forcing the library's meaning of `write' on the user program
        !          1606:      by using the "internal" name (for use within the library)  */
        !          1607: #define write(fd, buf, n)      __write((fd), (buf), (n))
        !          1608: #endif
        !          1609: #endif /* inhibit_libc */
        !          1610: 
        !          1611: typedef void (*vfp)(void);
        !          1612: 
        !          1613: extern void *__builtin_new (size_t);
        !          1614: static void default_new_handler (void);
        !          1615: 
        !          1616: #ifdef NEXT_SEMANTICS
        !          1617: static 
        !          1618: #endif
        !          1619: vfp __new_handler = default_new_handler;
        !          1620: 
        !          1621: #ifdef NEXT_SEMANTICS
        !          1622: vfp 
        !          1623: __get_new_handler ()
        !          1624: {
        !          1625:   return __new_handler;
        !          1626: }
        !          1627: #endif
        !          1628: 
        !          1629: vfp
        !          1630: __set_new_handler (handler)
        !          1631:      vfp handler;
        !          1632: {
        !          1633:   vfp prev_handler;
        !          1634: 
        !          1635:   prev_handler = __new_handler;
        !          1636:   if (handler == 0) handler = default_new_handler;
        !          1637:   __new_handler = handler;
        !          1638:   return prev_handler;
        !          1639: }
        !          1640: 
        !          1641: vfp
        !          1642: set_new_handler (handler)
        !          1643:      vfp handler;
        !          1644: {
        !          1645:   return __set_new_handler (handler);
        !          1646: }
        !          1647: 
        !          1648: #define MESSAGE "Virtual memory exceeded in `new'\n"
        !          1649: 
        !          1650: static void
        !          1651: default_new_handler ()
        !          1652: {
        !          1653:   /* don't use fprintf (stderr, ...) because it may need to call malloc.  */
        !          1654:   /* This should really print the name of the program, but that is hard to
        !          1655:      do.  We need a standard, clean way to get at the name.  */
        !          1656:   write (2, MESSAGE, sizeof (MESSAGE));
        !          1657:   /* don't call exit () because that may call global destructors which
        !          1658:      may cause a loop.  */
        !          1659:   _exit (-1);
        !          1660: }
        !          1661: #endif
        !          1662: 
        !          1663: #ifdef L_op_delete
        !          1664: /* void operator delete (void *ptr) */
        !          1665: void
        !          1666: __builtin_delete (void *ptr)
        !          1667: {
        !          1668:   if (ptr)
        !          1669:     free (ptr);
        !          1670: }
        !          1671: #endif
        !          1672: 
        !          1673: #ifdef L_shtab
        !          1674: const unsigned int __shtab[] = {
        !          1675:     0x00000001, 0x00000002, 0x00000004, 0x00000008,
        !          1676:     0x00000010, 0x00000020, 0x00000040, 0x00000080,
        !          1677:     0x00000100, 0x00000200, 0x00000400, 0x00000800,
        !          1678:     0x00001000, 0x00002000, 0x00004000, 0x00008000,
        !          1679:     0x00010000, 0x00020000, 0x00040000, 0x00080000,
        !          1680:     0x00100000, 0x00200000, 0x00400000, 0x00800000,
        !          1681:     0x01000000, 0x02000000, 0x04000000, 0x08000000,
        !          1682:     0x10000000, 0x20000000, 0x40000000, 0x80000000
        !          1683:   };
        !          1684: #endif
        !          1685: 
        !          1686: #ifdef L_clear_cache
        !          1687: /* Clear part of an instruction cache.  */
        !          1688: 
        !          1689: #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
        !          1690: 
        !          1691: void
        !          1692: __clear_cache (beg, end)
        !          1693:      char *beg, *end;
        !          1694: {
        !          1695: #ifdef CLEAR_INSN_CACHE 
        !          1696:   CLEAR_INSN_CACHE (beg, end);
        !          1697: #else
        !          1698: #ifdef INSN_CACHE_SIZE
        !          1699:   static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
        !          1700:   static int initialized = 0;
        !          1701:   int offset;
        !          1702:   void *start_addr
        !          1703:   void *end_addr;
        !          1704:   typedef (*function_ptr) ();
        !          1705: 
        !          1706: #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
        !          1707:   /* It's cheaper to clear the whole cache.
        !          1708:      Put in a series of jump instructions so that calling the beginning
        !          1709:      of the cache will clear the whole thing.  */
        !          1710: 
        !          1711:   if (! initialized)
        !          1712:     {
        !          1713:       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
        !          1714:                 & -INSN_CACHE_LINE_WIDTH);
        !          1715:       int end_ptr = ptr + INSN_CACHE_SIZE;
        !          1716: 
        !          1717:       while (ptr < end_ptr)
        !          1718:        {
        !          1719:          *(INSTRUCTION_TYPE *)ptr
        !          1720:            = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
        !          1721:          ptr += INSN_CACHE_LINE_WIDTH;
        !          1722:        }
        !          1723:       *(INSTRUCTION_TYPE *)(ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
        !          1724: 
        !          1725:       initialized = 1;
        !          1726:     }
        !          1727: 
        !          1728:   /* Call the beginning of the sequence.  */
        !          1729:   (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
        !          1730:                    & -INSN_CACHE_LINE_WIDTH))
        !          1731:    ());
        !          1732: 
        !          1733: #else /* Cache is large.  */
        !          1734: 
        !          1735:   if (! initialized)
        !          1736:     {
        !          1737:       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
        !          1738:                 & -INSN_CACHE_LINE_WIDTH);
        !          1739: 
        !          1740:       while (ptr < (int) array + sizeof array)
        !          1741:        {
        !          1742:          *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
        !          1743:          ptr += INSN_CACHE_LINE_WIDTH;
        !          1744:        }
        !          1745: 
        !          1746:       initialized = 1;
        !          1747:     }
        !          1748: 
        !          1749:   /* Find the location in array that occupies the same cache line as BEG.  */
        !          1750: 
        !          1751:   offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
        !          1752:   start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
        !          1753:                 & -INSN_CACHE_PLANE_SIZE)
        !          1754:                + offset);
        !          1755: 
        !          1756:   /* Compute the cache alignment of the place to stop clearing.  */
        !          1757: #if 0  /* This is not needed for gcc's purposes.  */
        !          1758:   /* If the block to clear is bigger than a cache plane,
        !          1759:      we clear the entire cache, and OFFSET is already correct.  */ 
        !          1760:   if (end < beg + INSN_CACHE_PLANE_SIZE)
        !          1761: #endif
        !          1762:     offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
        !          1763:               & -INSN_CACHE_LINE_WIDTH)
        !          1764:              & (INSN_CACHE_PLANE_SIZE - 1));
        !          1765: 
        !          1766: #if INSN_CACHE_DEPTH > 1
        !          1767:   end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
        !          1768:   if (end_addr <= start_addr)
        !          1769:     end_addr += INSN_CACHE_PLANE_SIZE;
        !          1770: 
        !          1771:   for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
        !          1772:     {
        !          1773:       int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
        !          1774:       int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
        !          1775: 
        !          1776:       while (addr != stop)
        !          1777:        {
        !          1778:          /* Call the return instruction at ADDR.  */
        !          1779:          ((function_ptr) addr) ();
        !          1780: 
        !          1781:          addr += INSN_CACHE_LINE_WIDTH;
        !          1782:        }
        !          1783:     }
        !          1784: #else /* just one plane */
        !          1785:   do
        !          1786:     {
        !          1787:       /* Call the return instruction at START_ADDR.  */
        !          1788:       ((function_ptr) start_addr) ();
        !          1789: 
        !          1790:       start_addr += INSN_CACHE_LINE_WIDTH;
        !          1791:     }
        !          1792:   while ((start_addr % INSN_CACHE_SIZE) != offset);
        !          1793: #endif /* just one plane */
        !          1794: #endif /* Cache is large */
        !          1795: #endif /* Cache exists */
        !          1796: #endif /* CLEAR_INSN_CACHE */
        !          1797: }
        !          1798: 
        !          1799: #endif /* L_clear_cache */
        !          1800: 
        !          1801: #ifdef L_trampoline
        !          1802: 
        !          1803: /* Jump to a trampoline, loading the static chain address.  */
        !          1804: 
        !          1805: #ifdef TRANSFER_FROM_TRAMPOLINE 
        !          1806: TRANSFER_FROM_TRAMPOLINE 
        !          1807: #endif
        !          1808: 
        !          1809: #if defined (NeXT) && defined (__MACH__) 
        !          1810: 
        !          1811: /* Make stack executable so we can call trampolines on stack.
        !          1812:    This is called from INITIALIZE_TRAMPOLINE in next.h.  */
        !          1813: 
        !          1814: void
        !          1815: __enable_execute_stack (addr)
        !          1816:      char *addr;
        !          1817: {
        !          1818:   char *eaddr = addr + TRAMPOLINE_SIZE;
        !          1819: 
        !          1820: #ifdef CLEAR_INSN_CACHE
        !          1821:   CLEAR_INSN_CACHE (addr, eaddr);
        !          1822: #else
        !          1823:   __clear_cache ((int) addr, (int) eaddr);
        !          1824: #endif
        !          1825: } 
        !          1826: 
        !          1827: #endif /* defined (NeXT) && defined (__MACH__) */
        !          1828: 
        !          1829: #ifdef __convex__
        !          1830: 
        !          1831: /* Make stack executable so we can call trampolines on stack.
        !          1832:    This is called from INITIALIZE_TRAMPOLINE in convex.h.  */
        !          1833: 
        !          1834: #include <sys/mman.h>
        !          1835: #include <sys/vmparam.h>
        !          1836: #include <machine/machparam.h>
        !          1837: 
        !          1838: void
        !          1839: __enable_execute_stack ()
        !          1840: {
        !          1841:   int fp;
        !          1842:   static unsigned lowest = USRSTACK;
        !          1843:   unsigned current = (unsigned) &fp & -NBPG;
        !          1844: 
        !          1845:   if (lowest > current)
        !          1846:     {
        !          1847:       unsigned len = lowest - current;
        !          1848:       mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
        !          1849:       lowest = current;
        !          1850:     }
        !          1851: 
        !          1852:   /* Clear instruction cache in case an old trampoline is in it. */
        !          1853:   asm ("pich");
        !          1854: }
        !          1855: #endif /* __convex__ */
        !          1856: 
        !          1857: #ifdef __DOLPHIN__
        !          1858: 
        !          1859: /* Modified from the convex -code above. */
        !          1860: 
        !          1861: #include <sys/param.h>
        !          1862: #include <errno.h>
        !          1863: #include <sys/m88kbcs.h>
        !          1864: 
        !          1865: void
        !          1866: __enable_execute_stack ()
        !          1867: {
        !          1868:   int save_errno;
        !          1869:   static unsigned long lowest = USRSTACK;
        !          1870:   unsigned long current = (unsigned long) &save_errno & -NBPC;
        !          1871:   
        !          1872:   /* Ignore errno being set. memctl sets errno to EINVAL whenever the
        !          1873:      address is seen as 'negative'. That is the case with the stack.   */
        !          1874: 
        !          1875:   save_errno=errno;
        !          1876:   if (lowest > current)
        !          1877:     {
        !          1878:       unsigned len=lowest-current;
        !          1879:       memctl(current,len,MCT_TEXT);
        !          1880:       lowest = current;
        !          1881:     }
        !          1882:   else
        !          1883:     memctl(current,NBPC,MCT_TEXT);
        !          1884:   errno=save_errno;
        !          1885: }
        !          1886: 
        !          1887: #endif /* __DOLPHIN__ */
        !          1888: 
        !          1889: #ifdef __pyr__
        !          1890: 
        !          1891: #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
        !          1892: #include <stdio.h>
        !          1893: #include <sys/mman.h>
        !          1894: #include <sys/types.h>
        !          1895: #include <sys/param.h>
        !          1896: #include <sys/vmmac.h>
        !          1897: 
        !          1898: /* Modified from the convex -code above.
        !          1899:    mremap promises to clear the i-cache. */
        !          1900: 
        !          1901: void
        !          1902: __enable_execute_stack ()
        !          1903: {
        !          1904:   int fp;
        !          1905:   if (mprotect (((unsigned int)&fp/PAGSIZ)*PAGSIZ, PAGSIZ,
        !          1906:                PROT_READ|PROT_WRITE|PROT_EXEC))
        !          1907:     {
        !          1908:       perror ("mprotect in __enable_execute_stack");
        !          1909:       fflush (stderr);
        !          1910:       abort ();
        !          1911:     }
        !          1912: }
        !          1913: #endif /* __pyr__ */
        !          1914: #endif /* L_trampoline */
        !          1915: 
        !          1916: #ifdef L__main
        !          1917: 
        !          1918: #include "gbl-ctors.h"
        !          1919: /* Some systems use __main in a way incompatible with its use in gcc, in these
        !          1920:    cases use the macros NAME__MAIN to give a quoted symbol and SYMBOL__MAIN to
        !          1921:    give the same symbol without quotes for an alternative entry point.  You
        !          1922:    must define both, or niether. */
        !          1923: #ifndef NAME__MAIN
        !          1924: #define NAME__MAIN "__main"
        !          1925: #define SYMBOL__MAIN __main
        !          1926: #endif
        !          1927: 
        !          1928: /* Run all the global destructors on exit from the program.  */
        !          1929: 
        !          1930: void
        !          1931: __do_global_dtors ()
        !          1932: {
        !          1933: #ifdef DO_GLOBAL_DTORS_BODY
        !          1934:   DO_GLOBAL_DTORS_BODY;
        !          1935: #else
        !          1936:   unsigned nptrs = (unsigned HOST_WIDE_INT) __DTOR_LIST__[0];
        !          1937:   unsigned i;
        !          1938: 
        !          1939:   /* Some systems place the number of pointers
        !          1940:      in the first word of the table.
        !          1941:      On other systems, that word is -1.
        !          1942:      In all cases, the table is null-terminated.  */
        !          1943: 
        !          1944:   /* If the length is not recorded, count up to the null.  */
        !          1945:   if (nptrs == -1)
        !          1946:     for (nptrs = 0; __DTOR_LIST__[nptrs + 1] != 0; nptrs++);
        !          1947: 
        !          1948:   /* GNU LD format.  */
        !          1949:   for (i = nptrs; i >= 1; i--)
        !          1950:     __DTOR_LIST__[i] ();
        !          1951: #endif
        !          1952: }
        !          1953: 
        !          1954: #ifndef INIT_SECTION_ASM_OP
        !          1955: /* Run all the global constructors on entry to the program.  */
        !          1956: 
        !          1957: #ifndef ON_EXIT
        !          1958: #define ON_EXIT(a, b)
        !          1959: #else
        !          1960: /* Make sure the exit routine is pulled in to define the globals as
        !          1961:    bss symbols, just in case the linker does not automatically pull
        !          1962:    bss definitions from the library.  */
        !          1963: 
        !          1964: #ifndef NEXT_SEMANTICS
        !          1965: extern int _exit_dummy_decl;
        !          1966: int *_exit_dummy_ref = &_exit_dummy_decl;
        !          1967: #endif
        !          1968: #endif /* ON_EXIT */
        !          1969: 
        !          1970: void
        !          1971: __do_global_ctors ()
        !          1972: {
        !          1973:   DO_GLOBAL_CTORS_BODY;
        !          1974:   ON_EXIT (__do_global_dtors, 0);
        !          1975: }
        !          1976: #endif /* no INIT_SECTION_ASM_OP */
        !          1977: 
        !          1978: #if !defined (INIT_SECTION_ASM_OP) || defined (INVOKE__main)
        !          1979: /* Subroutine called automatically by `main'.
        !          1980:    Compiling a global function named `main'
        !          1981:    produces an automatic call to this function at the beginning.
        !          1982: 
        !          1983:    For many systems, this routine calls __do_global_ctors.
        !          1984:    For systems which support a .init section we use the .init section
        !          1985:    to run __do_global_ctors, so we need not do anything here.  */
        !          1986: 
        !          1987: #ifdef NEXT_PDO
        !          1988: /* do some hokey stuff to get automatic _objcInit to work */
        !          1989: /* this data location is referenced in the NeXT_PDO runtime  */
        !          1990: /* so that we can do the magic rondevaux */
        !          1991: int _objcInit_addr;
        !          1992: #endif
        !          1993: 
        !          1994: #ifdef NEXT_EXTENSION
        !          1995: int __gnuc_argc;
        !          1996: const char **__gnuc_argv;
        !          1997: #endif
        !          1998: 
        !          1999: void
        !          2000: #ifdef NEXT_EXTENSION
        !          2001: SYMBOL__MAIN (int argc, const char **argv)
        !          2002: #else
        !          2003: SYMBOL__MAIN ()
        !          2004: #endif
        !          2005: {
        !          2006:   /* Support recursive calls to `main': run initializers just once.  */
        !          2007:   static int initialized = 0;
        !          2008: 
        !          2009: #ifdef NEXT_EXTENSION
        !          2010:   __gnuc_argc = argc;
        !          2011:   __gnuc_argv = argv;
        !          2012: #endif
        !          2013: 
        !          2014:   if (! initialized)
        !          2015:     {
        !          2016:       initialized = 1;
        !          2017:       __do_global_ctors ();
        !          2018: #ifdef NEXT_PDO
        !          2019:       if (_objcInit_addr)
        !          2020:        ((void (*)())_objcInit_addr)();
        !          2021: #endif
        !          2022:     }
        !          2023: }
        !          2024: #endif /* no INIT_SECTION_ASM_OP or INVOKE__main */
        !          2025: 
        !          2026: #endif /* L__main */
        !          2027: 
        !          2028: #ifdef L_ctors
        !          2029: 
        !          2030: #include "gbl-ctors.h"
        !          2031: 
        !          2032: /* Provide default definitions for the lists of constructors and
        !          2033:    destructors, so that we don't get linker errors.  These symbols are
        !          2034:    intentionally bss symbols, so that gld and/or collect will provide
        !          2035:    the right values.  */
        !          2036: 
        !          2037: /* We declare the lists here with two elements each,
        !          2038:    so that they are valid empty lists if no other definition is loaded.  */
        !          2039: #if !defined(INIT_SECTION_ASM_OP) && !defined(CTOR_LISTS_DEFINED_EXTERNALLY)
        !          2040: #ifdef __NeXT__
        !          2041: /* After 2.3, try this definition on all systems.  */
        !          2042: func_ptr __CTOR_LIST__[2] = {0, 0};
        !          2043: func_ptr __DTOR_LIST__[2] = {0, 0};
        !          2044: #else
        !          2045: func_ptr __CTOR_LIST__[2];
        !          2046: func_ptr __DTOR_LIST__[2];
        !          2047: #endif
        !          2048: #endif /* no INIT_SECTION_ASM_OP and not CTOR_LISTS_DEFINED_EXTERNALLY */
        !          2049: #endif /* L_ctors */
        !          2050: 
        !          2051: #ifdef L_exit
        !          2052: 
        !          2053: #include "gbl-ctors.h"
        !          2054: 
        !          2055: #ifndef ON_EXIT
        !          2056: 
        !          2057: /* If we have no known way of registering our own __do_global_dtors
        !          2058:    routine so that it will be invoked at program exit time, then we
        !          2059:    have to define our own exit routine which will get this to happen.  */
        !          2060: 
        !          2061: extern void __do_global_dtors ();
        !          2062: extern void _cleanup ();
        !          2063: extern void _exit () __attribute__ ((noreturn));
        !          2064: 
        !          2065: void 
        !          2066: exit (status)
        !          2067:      int status;
        !          2068: {
        !          2069:   __do_global_dtors ();
        !          2070: #ifdef EXIT_BODY
        !          2071:   EXIT_BODY;
        !          2072: #else
        !          2073:   _cleanup ();
        !          2074: #endif
        !          2075:   _exit (status);
        !          2076: }
        !          2077: 
        !          2078: #else
        !          2079: int _exit_dummy_decl = 0;      /* prevent compiler & linker warnings */
        !          2080: #endif
        !          2081: 
        !          2082: #endif /* L_exit */
        !          2083: 
        !          2084: /* In a.out systems, we need to have these dummy constructor and destructor
        !          2085:    lists in the library.
        !          2086: 
        !          2087:    When using `collect', the first link will resolve __CTOR_LIST__
        !          2088:    and __DTOR_LIST__ to these symbols.  We will then run "nm" on the
        !          2089:    result, build the correct __CTOR_LIST__ and __DTOR_LIST__, and relink.
        !          2090:    Since we don't do the second link if no constructors existed, these
        !          2091:    dummies must be fully functional empty lists.
        !          2092: 
        !          2093:    When using `gnu ld', these symbols will be used if there are no
        !          2094:    constructors.  If there are constructors, the N_SETV symbol defined
        !          2095:    by the linker from the N_SETT's in input files will define __CTOR_LIST__
        !          2096:    and __DTOR_LIST__ rather than its being allocated as common storage
        !          2097:    by the definitions below.
        !          2098: 
        !          2099:    When using a linker that supports constructor and destructor segments,
        !          2100:    these definitions will not be used, since crtbegin.o and crtend.o
        !          2101:    (from crtstuff.c) will have already defined __CTOR_LIST__ and
        !          2102:     __DTOR_LIST__.  The crt*.o files are passed directly to the linker
        !          2103:    on its command line, by gcc.  */
        !          2104: 
        !          2105: /* The list needs two elements:  one is ignored (the old count); the
        !          2106:    second is the terminating zero.  Since both values are zero, this
        !          2107:    declaration is not initialized, and it becomes `common'.  */
        !          2108: 
        !          2109: #ifdef L_ctor_list
        !          2110: #include "gbl-ctors.h"
        !          2111: func_ptr __CTOR_LIST__[2];
        !          2112: #endif
        !          2113: 
        !          2114: #ifdef L_dtor_list
        !          2115: #include "gbl-ctors.h"
        !          2116: func_ptr __DTOR_LIST__[2];
        !          2117: #endif
        !          2118: 

unix.superglobalmegacorp.com

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