Annotation of gcc/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 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 "tm.h"
        !            32: #include "gstddef.h"
        !            33: 
        !            34: /* Don't use `fancy_abort' here even if config.h says to use it.  */
        !            35: #ifdef abort
        !            36: #undef abort
        !            37: #endif
        !            38: 
        !            39: /* Need to undef this because LONG_TYPE_SIZE may rely upon GCC's
        !            40:    internal `target_flags' variable.  */
        !            41: #undef LONG_TYPE_SIZE
        !            42: 
        !            43: #define LONG_TYPE_SIZE (sizeof (long) * BITS_PER_UNIT)
        !            44: 
        !            45: #ifndef SItype
        !            46: #define SItype long int
        !            47: #endif
        !            48: 
        !            49: /* long long ints are pairs of long ints in the order determined by
        !            50:    WORDS_BIG_ENDIAN.  */
        !            51: 
        !            52: #if WORDS_BIG_ENDIAN
        !            53:   struct longlong {long high, low;};
        !            54: #else
        !            55:   struct longlong {long low, high;};
        !            56: #endif
        !            57: 
        !            58: /* We need this union to unpack/pack longlongs, since we don't have
        !            59:    any arithmetic yet.  Incoming long long parameters are stored
        !            60:    into the `ll' field, and the unpacked result is read from the struct
        !            61:    longlong.  */
        !            62: 
        !            63: typedef union
        !            64: {
        !            65:   struct longlong s;
        !            66:   long long ll;
        !            67: } long_long;
        !            68: 
        !            69: #if defined (L_udivmoddi4) || defined (L_muldi3)
        !            70: 
        !            71: #include "longlong.h"
        !            72: 
        !            73: #endif /* udiv or mul */
        !            74: 
        !            75: extern long long __fixunssfdi (float a);
        !            76: extern long long __fixunsdfdi (double a);
        !            77: 
        !            78: #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
        !            79: #if defined (L_divdi3) || defined (L_moddi3)
        !            80: static inline
        !            81: #endif
        !            82: long long
        !            83: __negdi2 (u)
        !            84:      long long u;
        !            85: {
        !            86:   long_long w;
        !            87:   long_long uu;
        !            88: 
        !            89:   uu.ll = u;
        !            90: 
        !            91:   w.s.low = -uu.s.low;
        !            92:   w.s.high = -uu.s.high - ((unsigned long) w.s.low > 0);
        !            93: 
        !            94:   return w.ll;
        !            95: }
        !            96: #endif
        !            97: 
        !            98: #ifdef L_lshldi3
        !            99: long long
        !           100: __lshldi3 (u, b)
        !           101:      long long u;
        !           102:      int b;
        !           103: {
        !           104:   long_long w;
        !           105:   long bm;
        !           106:   long_long uu;
        !           107: 
        !           108:   if (b == 0)
        !           109:     return u;
        !           110: 
        !           111:   uu.ll = u;
        !           112: 
        !           113:   bm = (sizeof (long) * BITS_PER_UNIT) - b;
        !           114:   if (bm <= 0)
        !           115:     {
        !           116:       w.s.low = 0;
        !           117:       w.s.high = (unsigned long)uu.s.low << -bm;
        !           118:     }
        !           119:   else
        !           120:     {
        !           121:       unsigned long carries = (unsigned long)uu.s.low >> bm;
        !           122:       w.s.low = (unsigned long)uu.s.low << b;
        !           123:       w.s.high = ((unsigned long)uu.s.high << b) | carries;
        !           124:     }
        !           125: 
        !           126:   return w.ll;
        !           127: }
        !           128: #endif
        !           129: 
        !           130: #ifdef L_lshrdi3
        !           131: long long
        !           132: __lshrdi3 (u, b)
        !           133:      long long u;
        !           134:      int b;
        !           135: {
        !           136:   long_long w;
        !           137:   long bm;
        !           138:   long_long uu;
        !           139: 
        !           140:   if (b == 0)
        !           141:     return u;
        !           142: 
        !           143:   uu.ll = u;
        !           144: 
        !           145:   bm = (sizeof (long) * BITS_PER_UNIT) - b;
        !           146:   if (bm <= 0)
        !           147:     {
        !           148:       w.s.high = 0;
        !           149:       w.s.low = (unsigned long)uu.s.high >> -bm;
        !           150:     }
        !           151:   else
        !           152:     {
        !           153:       unsigned long carries = (unsigned long)uu.s.high << bm;
        !           154:       w.s.high = (unsigned long)uu.s.high >> b;
        !           155:       w.s.low = ((unsigned long)uu.s.low >> b) | carries;
        !           156:     }
        !           157: 
        !           158:   return w.ll;
        !           159: }
        !           160: #endif
        !           161: 
        !           162: #ifdef L_ashldi3
        !           163: long long
        !           164: __ashldi3 (u, b)
        !           165:      long long u;
        !           166:      int b;
        !           167: {
        !           168:   long_long w;
        !           169:   long bm;
        !           170:   long_long uu;
        !           171: 
        !           172:   if (b == 0)
        !           173:     return u;
        !           174: 
        !           175:   uu.ll = u;
        !           176: 
        !           177:   bm = (sizeof (long) * BITS_PER_UNIT) - b;
        !           178:   if (bm <= 0)
        !           179:     {
        !           180:       w.s.low = 0;
        !           181:       w.s.high = (unsigned long)uu.s.low << -bm;
        !           182:     }
        !           183:   else
        !           184:     {
        !           185:       unsigned long carries = (unsigned long)uu.s.low >> bm;
        !           186:       w.s.low = (unsigned long)uu.s.low << b;
        !           187:       w.s.high = ((unsigned long)uu.s.high << b) | carries;
        !           188:     }
        !           189: 
        !           190:   return w.ll;
        !           191: }
        !           192: #endif
        !           193: 
        !           194: #ifdef L_ashrdi3
        !           195: long long
        !           196: __ashrdi3 (u, b)
        !           197:      long long u;
        !           198:      int b;
        !           199: {
        !           200:   long_long w;
        !           201:   long bm;
        !           202:   long_long uu;
        !           203: 
        !           204:   if (b == 0)
        !           205:     return u;
        !           206: 
        !           207:   uu.ll = u;
        !           208: 
        !           209:   bm = (sizeof (long) * BITS_PER_UNIT) - b;
        !           210:   if (bm <= 0)
        !           211:     {
        !           212:       /* w.s.high = 1..1 or 0..0 */
        !           213:       w.s.high = uu.s.high >> (sizeof (long) * BITS_PER_UNIT - 1);
        !           214:       w.s.low = uu.s.high >> -bm;
        !           215:     }
        !           216:   else
        !           217:     {
        !           218:       unsigned long carries = (unsigned long)uu.s.high << bm;
        !           219:       w.s.high = uu.s.high >> b;
        !           220:       w.s.low = ((unsigned long)uu.s.low >> b) | carries;
        !           221:     }
        !           222: 
        !           223:   return w.ll;
        !           224: }
        !           225: #endif
        !           226: 
        !           227: #ifdef L_muldi3
        !           228: long long
        !           229: __muldi3 (u, v)
        !           230:      long long u, v;
        !           231: {
        !           232:   long_long w;
        !           233:   long_long uu, vv;
        !           234: 
        !           235:   uu.ll = u,
        !           236:   vv.ll = v;
        !           237: 
        !           238:   w.ll = __umulsidi3 (uu.s.low, vv.s.low);
        !           239:   w.s.high += ((unsigned long) uu.s.low * (unsigned long) vv.s.high
        !           240:               + (unsigned long) uu.s.high * (unsigned long) vv.s.low);
        !           241: 
        !           242:   return w.ll;
        !           243: }
        !           244: #endif
        !           245: 
        !           246: #ifdef L_udivmoddi4
        !           247: static const unsigned char __clz_tab[] =
        !           248: {
        !           249:   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,
        !           250:   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,
        !           251:   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,
        !           252:   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,
        !           253:   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,
        !           254:   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,
        !           255:   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,
        !           256:   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,
        !           257: };
        !           258: 
        !           259: unsigned long long
        !           260: __udivmoddi4 (n, d, rp)
        !           261:      unsigned long long n, d;
        !           262:      unsigned long long int *rp;
        !           263: {
        !           264:   long_long ww;
        !           265:   long_long nn, dd;
        !           266:   long_long rr;
        !           267:   unsigned long d0, d1, n0, n1, n2;
        !           268:   unsigned long q0, q1;
        !           269:   unsigned b, bm;
        !           270: 
        !           271:   nn.ll = n;
        !           272:   dd.ll = d;
        !           273: 
        !           274:   d0 = dd.s.low;
        !           275:   d1 = dd.s.high;
        !           276:   n0 = nn.s.low;
        !           277:   n1 = nn.s.high;
        !           278: 
        !           279: #if !UDIV_NEEDS_NORMALIZATION
        !           280:   if (d1 == 0)
        !           281:     {
        !           282:       if (d0 > n1)
        !           283:        {
        !           284:          /* 0q = nn / 0D */
        !           285: 
        !           286:          udiv_qrnnd (q0, n0, n1, n0, d0);
        !           287:          q1 = 0;
        !           288: 
        !           289:          /* Remainder in n0.  */
        !           290:        }
        !           291:       else
        !           292:        {
        !           293:          /* qq = NN / 0d */
        !           294: 
        !           295:          if (d0 == 0)
        !           296:            d0 = 1 / d0;        /* Divide intentionally by zero.  */
        !           297: 
        !           298:          udiv_qrnnd (q1, n1, 0, n1, d0);
        !           299:          udiv_qrnnd (q0, n0, n1, n0, d0);
        !           300: 
        !           301:          /* Remainder in n0.  */
        !           302:        }
        !           303: 
        !           304:       if (rp != 0)
        !           305:        {
        !           306:          rr.s.low = n0;
        !           307:          rr.s.high = 0;
        !           308:          *rp = rr.ll;
        !           309:        }
        !           310:     }
        !           311: 
        !           312: #else /* UDIV_NEEDS_NORMALIZATION */
        !           313: 
        !           314:   if (d1 == 0)
        !           315:     {
        !           316:       if (d0 > n1)
        !           317:        {
        !           318:          /* 0q = nn / 0D */
        !           319: 
        !           320:          count_leading_zeros (bm, d0);
        !           321: 
        !           322:          if (bm != 0)
        !           323:            {
        !           324:              /* Normalize, i.e. make the most significant bit of the
        !           325:                 denominator set.  */
        !           326: 
        !           327:              d0 = d0 << bm;
        !           328:              n1 = (n1 << bm) | (n0 >> (LONG_TYPE_SIZE - bm));
        !           329:              n0 = n0 << bm;
        !           330:            }
        !           331: 
        !           332:          udiv_qrnnd (q0, n0, n1, n0, d0);
        !           333:          q1 = 0;
        !           334: 
        !           335:          /* Remainder in n0 >> bm.  */
        !           336:        }
        !           337:       else
        !           338:        {
        !           339:          /* qq = NN / 0d */
        !           340: 
        !           341:          if (d0 == 0)
        !           342:            d0 = 1 / d0;        /* Divide intentionally by zero.  */
        !           343: 
        !           344:          count_leading_zeros (bm, d0);
        !           345: 
        !           346:          if (bm == 0)
        !           347:            {
        !           348:              /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
        !           349:                 conclude (the most significant bit of n1 is set) /\ (the
        !           350:                 leading quotient digit q1 = 1).
        !           351: 
        !           352:                 This special case is necessary, not an optimization.
        !           353:                 (Shifts counts of LONG_TYPE_SIZE are undefined.)  */
        !           354: 
        !           355:              n1 -= d0;
        !           356:              q1 = 1;
        !           357:            }
        !           358:          else
        !           359:            {
        !           360:              /* Normalize.  */
        !           361: 
        !           362:              b = LONG_TYPE_SIZE - bm;
        !           363: 
        !           364:              d0 = d0 << bm;
        !           365:              n2 = n1 >> b;
        !           366:              n1 = (n1 << bm) | (n0 >> b);
        !           367:              n0 = n0 << bm;
        !           368: 
        !           369:              udiv_qrnnd (q1, n1, n2, n1, d0);
        !           370:            }
        !           371: 
        !           372:          /* n1 != d0... */
        !           373: 
        !           374:          udiv_qrnnd (q0, n0, n1, n0, d0);
        !           375: 
        !           376:          /* Remainder in n0 >> bm.  */
        !           377:        }
        !           378: 
        !           379:       if (rp != 0)
        !           380:        {
        !           381:          rr.s.low = n0 >> bm;
        !           382:          rr.s.high = 0;
        !           383:          *rp = rr.ll;
        !           384:        }
        !           385:     }
        !           386: #endif /* UDIV_NEEDS_NORMALIZATION */
        !           387: 
        !           388:   else
        !           389:     {
        !           390:       if (d1 > n1)
        !           391:        {
        !           392:          /* 00 = nn / DD */
        !           393: 
        !           394:          q0 = 0;
        !           395:          q1 = 0;
        !           396: 
        !           397:          /* Remainder in n1n0.  */
        !           398:          if (rp != 0)
        !           399:            {
        !           400:              rr.s.low = n0;
        !           401:              rr.s.high = n1;
        !           402:              *rp = rr.ll;
        !           403:            }
        !           404:        }
        !           405:       else
        !           406:        {
        !           407:          /* 0q = NN / dd */
        !           408: 
        !           409:          count_leading_zeros (bm, d1);
        !           410:          if (bm == 0)
        !           411:            {
        !           412:              /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
        !           413:                 conclude (the most significant bit of n1 is set) /\ (the
        !           414:                 quotient digit q0 = 0 or 1).
        !           415: 
        !           416:                 This special case is necessary, not an optimization.  */
        !           417: 
        !           418:              /* The condition on the next line takes advantage of that
        !           419:                 n1 >= d1 (true due to program flow).  */
        !           420:              if (n1 > d1 || n0 >= d0)
        !           421:                {
        !           422:                  q0 = 1;
        !           423:                  sub_ddmmss (n1, n0, n1, n0, d1, d0);
        !           424:                }
        !           425:              else
        !           426:                q0 = 0;
        !           427: 
        !           428:              q1 = 0;
        !           429: 
        !           430:              if (rp != 0)
        !           431:                {
        !           432:                  rr.s.low = n0;
        !           433:                  rr.s.high = n1;
        !           434:                  *rp = rr.ll;
        !           435:                }
        !           436:            }
        !           437:          else
        !           438:            {
        !           439:              unsigned long m1, m0;
        !           440:              /* Normalize.  */
        !           441: 
        !           442:              b = LONG_TYPE_SIZE - bm;
        !           443: 
        !           444:              d1 = (d1 << bm) | (d0 >> b);
        !           445:              d0 = d0 << bm;
        !           446:              n2 = n1 >> b;
        !           447:              n1 = (n1 << bm) | (n0 >> b);
        !           448:              n0 = n0 << bm;
        !           449: 
        !           450:              udiv_qrnnd (q0, n1, n2, n1, d1);
        !           451:              umul_ppmm (m1, m0, q0, d0);
        !           452: 
        !           453:              if (m1 > n1 || (m1 == n1 && m0 > n0))
        !           454:                {
        !           455:                  q0--;
        !           456:                  sub_ddmmss (m1, m0, m1, m0, d1, d0);
        !           457:                }
        !           458: 
        !           459:              q1 = 0;
        !           460: 
        !           461:              /* Remainder in (n1n0 - m1m0) >> bm.  */
        !           462:              if (rp != 0)
        !           463:                {
        !           464:                  sub_ddmmss (n1, n0, n1, n0, m1, m0);
        !           465:                  rr.s.low = (n1 << b) | (n0 >> bm);
        !           466:                  rr.s.high = n1 >> bm;
        !           467:                  *rp = rr.ll;
        !           468:                }
        !           469:            }
        !           470:        }
        !           471:     }
        !           472: 
        !           473:   ww.s.low = q0;
        !           474:   ww.s.high = q1;
        !           475:   return ww.ll;
        !           476: }
        !           477: #endif
        !           478: 
        !           479: #ifdef L_divdi3
        !           480: unsigned long long __udivmoddi4 ();
        !           481: long long
        !           482: __divdi3 (u, v)
        !           483:      long long u, v;
        !           484: {
        !           485:   int c = 0;
        !           486:   long_long uu, vv;
        !           487:   long long w;
        !           488: 
        !           489:   uu.ll = u;
        !           490:   vv.ll = v;
        !           491: 
        !           492:   if (uu.s.high < 0)
        !           493:     c = ~c,
        !           494:     uu.ll = __negdi2 (uu.ll);
        !           495:   if (vv.s.high < 0)
        !           496:     c = ~c,
        !           497:     vv.ll = __negdi2 (vv.ll);
        !           498: 
        !           499:   w = __udivmoddi4 (uu.ll, vv.ll, (unsigned long long *) 0);
        !           500:   if (c)
        !           501:     w = __negdi2 (w);
        !           502: 
        !           503:   return w;
        !           504: }
        !           505: #endif
        !           506: 
        !           507: #ifdef L_moddi3
        !           508: unsigned long long __udivmoddi4 ();
        !           509: long long
        !           510: __moddi3 (u, v)
        !           511:      long long u, v;
        !           512: {
        !           513:   int c = 0;
        !           514:   long_long uu, vv;
        !           515:   long long w;
        !           516: 
        !           517:   uu.ll = u;
        !           518:   vv.ll = v;
        !           519: 
        !           520:   if (uu.s.high < 0)
        !           521:     c = ~c,
        !           522:     uu.ll = __negdi2 (uu.ll);
        !           523:   if (vv.s.high < 0)
        !           524:     vv.ll = __negdi2 (vv.ll);
        !           525: 
        !           526:   (void) __udivmoddi4 (uu.ll, vv.ll, &w);
        !           527:   if (c)
        !           528:     w = __negdi2 (w);
        !           529: 
        !           530:   return w;
        !           531: }
        !           532: #endif
        !           533: 
        !           534: #ifdef L_umoddi3
        !           535: unsigned long long __udivmoddi4 ();
        !           536: unsigned long long
        !           537: __umoddi3 (u, v)
        !           538:      unsigned long long u, v;
        !           539: {
        !           540:   long long w;
        !           541: 
        !           542:   (void) __udivmoddi4 (u, v, &w);
        !           543: 
        !           544:   return w;
        !           545: }
        !           546: #endif
        !           547: 
        !           548: #ifdef L_udivdi3
        !           549: unsigned long long __udivmoddi4 ();
        !           550: unsigned long long
        !           551: __udivdi3 (n, d)
        !           552:      unsigned long long n, d;
        !           553: {
        !           554:   return __udivmoddi4 (n, d, (unsigned long long *) 0);
        !           555: }
        !           556: #endif
        !           557: 
        !           558: #ifdef L_cmpdi2
        !           559: SItype
        !           560: __cmpdi2 (a, b)
        !           561:      long long a, b;
        !           562: {
        !           563:   long_long au, bu;
        !           564: 
        !           565:   au.ll = a, bu.ll = b;
        !           566: 
        !           567:   if (au.s.high < bu.s.high)
        !           568:     return 0;
        !           569:   else if (au.s.high > bu.s.high)
        !           570:     return 2;
        !           571:   if ((unsigned long) au.s.low < (unsigned long) bu.s.low)
        !           572:     return 0;
        !           573:   else if ((unsigned long) au.s.low > (unsigned long) bu.s.low)
        !           574:     return 2;
        !           575:   return 1;
        !           576: }
        !           577: #endif
        !           578: 
        !           579: #ifdef L_ucmpdi2
        !           580: SItype
        !           581: __ucmpdi2 (a, b)
        !           582:      long long a, b;
        !           583: {
        !           584:   long_long au, bu;
        !           585: 
        !           586:   au.ll = a, bu.ll = b;
        !           587: 
        !           588:   if ((unsigned long) au.s.high < (unsigned long) bu.s.high)
        !           589:     return 0;
        !           590:   else if ((unsigned long) au.s.high > (unsigned long) bu.s.high)
        !           591:     return 2;
        !           592:   if ((unsigned long) au.s.low < (unsigned long) bu.s.low)
        !           593:     return 0;
        !           594:   else if ((unsigned long) au.s.low > (unsigned long) bu.s.low)
        !           595:     return 2;
        !           596:   return 1;
        !           597: }
        !           598: #endif
        !           599: 
        !           600: #ifdef L_fixunsdfdi
        !           601: #define WORD_SIZE (sizeof (long) * BITS_PER_UNIT)
        !           602: #define HIGH_WORD_COEFF (((long long) 1) << WORD_SIZE)
        !           603: 
        !           604: long long
        !           605: __fixunsdfdi (a)
        !           606:      double a;
        !           607: {
        !           608:   double b;
        !           609:   unsigned long long v;
        !           610: 
        !           611:   if (a < 0)
        !           612:     return 0;
        !           613: 
        !           614:   /* Compute high word of result, as a flonum.  */
        !           615:   b = (a / HIGH_WORD_COEFF);
        !           616:   /* Convert that to fixed (but not to long long!),
        !           617:      and shift it into the high word.  */
        !           618:   v = (unsigned long int) b;
        !           619:   v <<= WORD_SIZE;
        !           620:   /* Remove high part from the double, leaving the low part as flonum.  */
        !           621:   a -= (double)v;
        !           622:   /* Convert that to fixed (but not to long long!) and add it in.
        !           623:      Sometimes A comes out negative.  This is significant, since
        !           624:      A has more bits than a long int does.  */
        !           625:   if (a < 0)
        !           626:     v -= (unsigned long int) (- a);
        !           627:   else
        !           628:     v += (unsigned long int) a;
        !           629:   return v;
        !           630: }
        !           631: #endif
        !           632: 
        !           633: #ifdef L_fixdfdi
        !           634: long long
        !           635: __fixdfdi (a)
        !           636:      double a;
        !           637: {
        !           638:   if (a < 0)
        !           639:     return - __fixunsdfdi (-a);
        !           640:   return __fixunsdfdi (a);
        !           641: }
        !           642: #endif
        !           643: 
        !           644: #ifdef L_fixunssfdi
        !           645: #define WORD_SIZE (sizeof (long) * BITS_PER_UNIT)
        !           646: #define HIGH_WORD_COEFF (((long long) 1) << WORD_SIZE)
        !           647: 
        !           648: long long
        !           649: __fixunssfdi (float original_a)
        !           650: {
        !           651:   /* Convert the float to a double, because that is surely not going
        !           652:      to lose any bits.  Some day someone else can write a faster version
        !           653:      that avoids converting to double, and verify it really works right.  */
        !           654:   double a = original_a;
        !           655:   double b;
        !           656:   unsigned long long v;
        !           657: 
        !           658:   if (a < 0)
        !           659:     return 0;
        !           660: 
        !           661:   /* Compute high word of result, as a flonum.  */
        !           662:   b = (a / HIGH_WORD_COEFF);
        !           663:   /* Convert that to fixed (but not to long long!),
        !           664:      and shift it into the high word.  */
        !           665:   v = (unsigned long int) b;
        !           666:   v <<= WORD_SIZE;
        !           667:   /* Remove high part from the double, leaving the low part as flonum.  */
        !           668:   a -= (double)v;
        !           669:   /* Convert that to fixed (but not to long long!) and add it in.
        !           670:      Sometimes A comes out negative.  This is significant, since
        !           671:      A has more bits than a long int does.  */
        !           672:   if (a < 0)
        !           673:     v -= (unsigned long int) (- a);
        !           674:   else
        !           675:     v += (unsigned long int) a;
        !           676:   return v;
        !           677: }
        !           678: #endif
        !           679: 
        !           680: #ifdef L_fixsfdi
        !           681: long long
        !           682: __fixsfdi (float a)
        !           683: {
        !           684:   if (a < 0)
        !           685:     return - __fixunssfdi (-a);
        !           686:   return __fixunssfdi (a);
        !           687: }
        !           688: #endif
        !           689: 
        !           690: #ifdef L_floatdidf
        !           691: #define WORD_SIZE (sizeof (long) * BITS_PER_UNIT)
        !           692: #define HIGH_HALFWORD_COEFF (((long long) 1) << (WORD_SIZE / 2))
        !           693: #define HIGH_WORD_COEFF (((long long) 1) << WORD_SIZE)
        !           694: 
        !           695: double
        !           696: __floatdidf (u)
        !           697:      long long u;
        !           698: {
        !           699:   double d;
        !           700:   int negate = 0;
        !           701: 
        !           702:   if (u < 0)
        !           703:     u = -u, negate = 1;
        !           704: 
        !           705:   d = (unsigned int) (u >> WORD_SIZE);
        !           706:   d *= HIGH_HALFWORD_COEFF;
        !           707:   d *= HIGH_HALFWORD_COEFF;
        !           708:   d += (unsigned int) (u & (HIGH_WORD_COEFF - 1));
        !           709: 
        !           710:   return (negate ? -d : d);
        !           711: }
        !           712: #endif
        !           713: 
        !           714: #ifdef L_floatdisf
        !           715: #define WORD_SIZE (sizeof (long) * BITS_PER_UNIT)
        !           716: #define HIGH_HALFWORD_COEFF (((long long) 1) << (WORD_SIZE / 2))
        !           717: #define HIGH_WORD_COEFF (((long long) 1) << WORD_SIZE)
        !           718: 
        !           719: float
        !           720: __floatdisf (u)
        !           721:      long long u;
        !           722: {
        !           723:   float f;
        !           724:   int negate = 0;
        !           725: 
        !           726:   if (u < 0)
        !           727:     u = -u, negate = 1;
        !           728: 
        !           729:   f = (unsigned int) (u >> WORD_SIZE);
        !           730:   f *= HIGH_HALFWORD_COEFF;
        !           731:   f *= HIGH_HALFWORD_COEFF;
        !           732:   f += (unsigned int) (u & (HIGH_WORD_COEFF - 1));
        !           733: 
        !           734:   return (negate ? -f : f);
        !           735: }
        !           736: #endif
        !           737: 
        !           738: #ifdef L_fixunsdfsi
        !           739: #include "limits.h"
        !           740: 
        !           741: unsigned SItype
        !           742: __fixunsdfsi (a)
        !           743:      double a;
        !           744: {
        !           745:   if (a >= - (double) LONG_MIN)
        !           746:     return (SItype) (a + LONG_MIN) - LONG_MIN;
        !           747:   return (SItype) a;
        !           748: }
        !           749: #endif
        !           750: 
        !           751: #ifdef L_fixunssfsi
        !           752: #include "limits.h"
        !           753: 
        !           754: unsigned SItype
        !           755: __fixunssfsi (float a)
        !           756: {
        !           757:   if (a >= - (float) LONG_MIN)
        !           758:     return (SItype) (a + LONG_MIN) - LONG_MIN;
        !           759:   return (SItype) a;
        !           760: }
        !           761: #endif
        !           762: 
        !           763: #ifdef L_varargs
        !           764: #ifdef __i860__
        !           765: #ifdef SVR4
        !           766:        asm ("  .text");
        !           767:        asm ("  .align  4");
        !           768: 
        !           769:        asm (".globl    __builtin_saveregs");
        !           770: asm ("__builtin_saveregs:");
        !           771:        asm ("  andnot  0x0f,%sp,%sp"); /* round down to 16-byte boundary */
        !           772:        asm ("  adds    -96,%sp,%sp");  /* allocate stack space for reg save
        !           773:                                           area and also for a new va_list
        !           774:                                           structure */
        !           775:        /* Save all argument registers in the arg reg save area.  The
        !           776:           arg reg save area must have the following layout (according
        !           777:           to the svr4 ABI):
        !           778: 
        !           779:                struct {
        !           780:                  union  {
        !           781:                    float freg[8];
        !           782:                    double dreg[4];
        !           783:                  } float_regs;
        !           784:                  long  ireg[12];
        !           785:                };
        !           786:        */
        !           787: 
        !           788:        asm ("  fst.q   %f8,  0(%sp)"); /* save floating regs (f8-f15)  */
        !           789:        asm ("  fst.q   %f12,16(%sp)"); 
        !           790: 
        !           791:        asm ("  st.l    %r16,32(%sp)"); /* save integer regs (r16-r27) */
        !           792:        asm ("  st.l    %r17,36(%sp)"); 
        !           793:        asm ("  st.l    %r18,40(%sp)");
        !           794:        asm ("  st.l    %r19,44(%sp)");
        !           795:        asm ("  st.l    %r20,48(%sp)");
        !           796:        asm ("  st.l    %r21,52(%sp)");
        !           797:        asm ("  st.l    %r22,56(%sp)");
        !           798:        asm ("  st.l    %r23,60(%sp)");
        !           799:        asm ("  st.l    %r24,64(%sp)");
        !           800:        asm ("  st.l    %r25,68(%sp)");
        !           801:        asm ("  st.l    %r26,72(%sp)");
        !           802:        asm ("  st.l    %r27,76(%sp)");
        !           803: 
        !           804:        asm ("  adds    80,%sp,%r16");  /* compute the address of the new
        !           805:                                           va_list structure.  Put in into
        !           806:                                           r16 so that it will be returned
        !           807:                                           to the caller.  */
        !           808: 
        !           809:        /* Initialize all fields of the new va_list structure.  This
        !           810:           structure looks like:
        !           811: 
        !           812:                typedef struct {
        !           813:                    unsigned long       ireg_used;
        !           814:                    unsigned long       freg_used;
        !           815:                    long                *reg_base;
        !           816:                    long                *mem_ptr;
        !           817:                } va_list;
        !           818:        */
        !           819: 
        !           820:        asm ("  st.l    %r0, 0(%r16)"); /* nfixed */
        !           821:        asm ("  st.l    %r0, 4(%r16)"); /* nfloating */
        !           822:        asm ("  st.l    %sp, 8(%r16)"); /* __va_ctl points to __va_struct.  */
        !           823:        asm ("  bri     %r1");          /* delayed return */
        !           824:        asm ("  st.l    %r28,12(%r16)"); /* pointer to overflow args */
        !           825: 
        !           826: #else /* not SVR4 */
        !           827:        asm ("  .text");
        !           828:        asm ("  .align  4");
        !           829: 
        !           830:        asm (".globl    ___builtin_saveregs");
        !           831:        asm ("___builtin_saveregs:");
        !           832:        asm ("  mov     sp,r30");
        !           833:        asm ("  andnot  0x0f,sp,sp");
        !           834:        asm ("  adds    -96,sp,sp");  /* allocate sufficient space on the stack */
        !           835: 
        !           836: /* Fill in the __va_struct.  */
        !           837:        asm ("  st.l    r16, 0(sp)"); /* save integer regs (r16-r27) */
        !           838:        asm ("  st.l    r17, 4(sp)"); /* int    fixed[12] */
        !           839:        asm ("  st.l    r18, 8(sp)");
        !           840:        asm ("  st.l    r19,12(sp)");
        !           841:        asm ("  st.l    r20,16(sp)");
        !           842:        asm ("  st.l    r21,20(sp)");
        !           843:        asm ("  st.l    r22,24(sp)");
        !           844:        asm ("  st.l    r23,28(sp)");
        !           845:        asm ("  st.l    r24,32(sp)");
        !           846:        asm ("  st.l    r25,36(sp)");
        !           847:        asm ("  st.l    r26,40(sp)");
        !           848:        asm ("  st.l    r27,44(sp)");
        !           849: 
        !           850:        asm ("  fst.q   f8, 48(sp)"); /* save floating regs (f8-f15) */
        !           851:        asm ("  fst.q   f12,64(sp)"); /* int floating[8] */
        !           852: 
        !           853: /* Fill in the __va_ctl.  */
        !           854:        asm ("  st.l    sp, 80(sp)"); /* __va_ctl points to __va_struct.  */
        !           855:        asm ("  st.l    r28,84(sp)"); /* pointer to more args */
        !           856:        asm ("  st.l    r0, 88(sp)"); /* nfixed */
        !           857:        asm ("  st.l    r0, 92(sp)"); /* nfloating */
        !           858: 
        !           859:        asm ("  adds    80,sp,r16");  /* return address of the __va_ctl.  */
        !           860:        asm ("  bri     r1");
        !           861:        asm ("  mov     r30,sp");
        !           862:                                /* recover stack and pass address to start 
        !           863:                                   of data.  */
        !           864: #endif /* not SVR4 */
        !           865: #else /* not __i860__ */
        !           866: #ifdef __sparc__
        !           867:        asm (".global ___builtin_saveregs");
        !           868:        asm ("___builtin_saveregs:");
        !           869:        asm ("st %i0,[%fp+68]");
        !           870:        asm ("st %i1,[%fp+72]");
        !           871:        asm ("st %i2,[%fp+76]");
        !           872:        asm ("st %i3,[%fp+80]");
        !           873:        asm ("st %i4,[%fp+84]");
        !           874:        asm ("retl");
        !           875:        asm ("st %i5,[%fp+88]");
        !           876: #else /* not __sparc__ */
        !           877: #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
        !           878: 
        !           879:   asm ("       .text");
        !           880:   asm ("       .ent __builtin_saveregs");
        !           881:   asm ("       .globl __builtin_saveregs");
        !           882:   asm ("__builtin_saveregs:");
        !           883:   asm ("       sw      $4,0($30)");
        !           884:   asm ("       sw      $5,4($30)");
        !           885:   asm ("       sw      $6,8($30)");
        !           886:   asm ("       sw      $7,12($30)");
        !           887:   asm ("       j       $31");
        !           888:   asm ("       .end __builtin_saveregs");
        !           889: #else /* not __mips__, etc. */
        !           890: __builtin_saveregs ()
        !           891: {
        !           892:   abort ();
        !           893: }
        !           894: #endif /* not __mips__ */
        !           895: #endif /* not __sparc__ */
        !           896: #endif /* not __i860__ */
        !           897: #endif
        !           898: 
        !           899: #ifdef L_eprintf
        !           900: #undef NULL /* Avoid errors if stdio.h and our stddef.h mismatch.  */
        !           901: #include <stdio.h>
        !           902: /* This is used by the `assert' macro.  */
        !           903: void
        !           904: __eprintf (string, expression, line, filename)
        !           905:      char *string;
        !           906:      char *expression;
        !           907:      int line;
        !           908:      char *filename;
        !           909: {
        !           910:   fprintf (stderr, string, expression, line, filename);
        !           911:   fflush (stderr);
        !           912:   abort ();
        !           913: }
        !           914: #endif
        !           915: 
        !           916: #ifdef L_bb
        !           917: /* Avoid warning from ranlib about empty object file.  */
        !           918: void
        !           919: __bb_avoid_warning ()
        !           920: {}
        !           921: 
        !           922: #if defined (__sun__) && defined (__mc68000__)
        !           923: struct bb
        !           924: {
        !           925:   int initialized;
        !           926:   char *filename;
        !           927:   int *counts;
        !           928:   int ncounts;
        !           929:   int zero_word;
        !           930:   int *addresses;
        !           931: };
        !           932: 
        !           933: extern int ___tcov_init;
        !           934: 
        !           935: __bb_init_func (blocks)
        !           936:        struct bb *blocks;
        !           937: {
        !           938:   if (! ___tcov_init)
        !           939:     ___tcov_init_func ();
        !           940: 
        !           941:   ___bb_link (blocks->filename, blocks->counts, blocks->ncounts);
        !           942: }
        !           943: 
        !           944: #endif
        !           945: #endif
        !           946: 
        !           947: /* frills for C++ */
        !           948: 
        !           949: #ifdef L_builtin_new
        !           950: typedef void (*vfp)(void);
        !           951: 
        !           952: extern vfp __new_handler;
        !           953: 
        !           954: void *
        !           955: __builtin_new (sz)
        !           956:      long sz;
        !           957: {
        !           958:   void *p;
        !           959: 
        !           960:   p = (void *) malloc (sz);
        !           961:   if (p == 0)
        !           962:     (*__new_handler) ();
        !           963:   return p;
        !           964: }
        !           965: #endif
        !           966: 
        !           967: #ifdef L_builtin_New
        !           968: typedef void (*vfp)(void);
        !           969: 
        !           970: static void default_new_handler ();
        !           971: 
        !           972: vfp __new_handler = default_new_handler;
        !           973: 
        !           974: void *
        !           975: __builtin_vec_new (p, maxindex, size, ctor)
        !           976:      void *p;
        !           977:      int maxindex, size;
        !           978:      void (*ctor)(void *);
        !           979: {
        !           980:   int i, nelts = maxindex + 1;
        !           981:   void *rval;
        !           982: 
        !           983:   if (p == 0)
        !           984:     p = (void *)__builtin_new (nelts * size);
        !           985: 
        !           986:   rval = p;
        !           987: 
        !           988:   for (i = 0; i < nelts; i++)
        !           989:     {
        !           990:       (*ctor) (p);
        !           991:       p += size;
        !           992:     }
        !           993: 
        !           994:   return rval;
        !           995: }
        !           996: 
        !           997: vfp
        !           998: __set_new_handler (handler)
        !           999:      vfp handler;
        !          1000: {
        !          1001:   vfp prev_handler;
        !          1002: 
        !          1003:   prev_handler = __new_handler;
        !          1004:   if (handler == 0) handler = default_new_handler;
        !          1005:   __new_handler = handler;
        !          1006:   return prev_handler;
        !          1007: }
        !          1008: 
        !          1009: vfp
        !          1010: set_new_handler (handler)
        !          1011:      vfp handler;
        !          1012: {
        !          1013:   return __set_new_handler (handler);
        !          1014: }
        !          1015: 
        !          1016: static void
        !          1017: default_new_handler ()
        !          1018: {
        !          1019:   /* don't use fprintf (stderr, ...) because it may need to call malloc.  */
        !          1020:   /* This should really print the name of the program, but that is hard to
        !          1021:      do.  We need a standard, clean way to get at the name.  */
        !          1022:   write (2, "Virtual memory exceeded in `new'\n", 33);
        !          1023:   /* don't call exit () because that may call global destructors which
        !          1024:      may cause a loop.  */
        !          1025:   _exit (-1);
        !          1026: }
        !          1027: #endif
        !          1028: 
        !          1029: #ifdef L_builtin_del
        !          1030: typedef void (*vfp)(void);
        !          1031: 
        !          1032: void
        !          1033: __builtin_delete (ptr)
        !          1034:      void *ptr;
        !          1035: {
        !          1036:   if (ptr)
        !          1037:     free (ptr);
        !          1038: }
        !          1039: 
        !          1040: void
        !          1041: __builtin_vec_delete (ptr, maxindex, size, dtor, auto_delete_vec, auto_delete)
        !          1042:      void *ptr;
        !          1043:      int maxindex, size;
        !          1044:      void (*dtor)();
        !          1045:      int auto_delete;
        !          1046: {
        !          1047:   int i, nelts = maxindex + 1;
        !          1048:   void *p = ptr;
        !          1049: 
        !          1050:   ptr += nelts * size;
        !          1051: 
        !          1052:   for (i = 0; i < nelts; i++)
        !          1053:     {
        !          1054:       ptr -= size;
        !          1055:       (*dtor) (ptr, auto_delete);
        !          1056:     }
        !          1057: 
        !          1058:   if (auto_delete_vec)
        !          1059:     __builtin_delete (p);
        !          1060: }
        !          1061: 
        !          1062: #endif
        !          1063: 
        !          1064: #ifdef L_shtab
        !          1065: unsigned int __shtab[] = {
        !          1066:     0x00000001, 0x00000002, 0x00000004, 0x00000008,
        !          1067:     0x00000010, 0x00000020, 0x00000040, 0x00000080,
        !          1068:     0x00000100, 0x00000200, 0x00000400, 0x00000800,
        !          1069:     0x00001000, 0x00002000, 0x00004000, 0x00008000,
        !          1070:     0x00010000, 0x00020000, 0x00040000, 0x00080000,
        !          1071:     0x00100000, 0x00200000, 0x00400000, 0x00800000,
        !          1072:     0x01000000, 0x02000000, 0x04000000, 0x08000000,
        !          1073:     0x10000000, 0x20000000, 0x40000000, 0x80000000
        !          1074:   };
        !          1075: #endif
        !          1076: 
        !          1077: #ifdef L_clear_cache
        !          1078: /* Clear part of an instruction cache.  */
        !          1079: 
        !          1080: #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
        !          1081: 
        !          1082: void
        !          1083: __clear_cache (beg, end)
        !          1084:      char *beg, *end;
        !          1085: {
        !          1086: #ifdef INSN_CACHE_SIZE
        !          1087:   static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
        !          1088:   static int initialized = 0;
        !          1089:   int offset;
        !          1090:   unsigned int start_addr, end_addr;
        !          1091:   typedef (*function_ptr) ();
        !          1092: 
        !          1093: #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
        !          1094:   /* It's cheaper to clear the whole cache.
        !          1095:      Put in a series of jump instructions so that calling the beginning
        !          1096:      of the cache will clear the whole thing.  */
        !          1097: 
        !          1098:   if (! initialized)
        !          1099:     {
        !          1100:       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
        !          1101:                 & -INSN_CACHE_LINE_WIDTH);
        !          1102:       int end_ptr = ptr + INSN_CACHE_SIZE;
        !          1103: 
        !          1104:       while (ptr < end_ptr)
        !          1105:        {
        !          1106:          *(INSTRUCTION_TYPE *)ptr
        !          1107:            = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
        !          1108:          ptr += INSN_CACHE_LINE_WIDTH;
        !          1109:        }
        !          1110:       *(INSTRUCTION_TYPE *)(ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
        !          1111: 
        !          1112:       initialized = 1;
        !          1113:     }
        !          1114: 
        !          1115:   /* Call the beginning of the sequence.  */
        !          1116:   (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
        !          1117:                    & -INSN_CACHE_LINE_WIDTH))
        !          1118:    ());
        !          1119: 
        !          1120: #else /* Cache is large.  */
        !          1121: 
        !          1122:   if (! initialized)
        !          1123:     {
        !          1124:       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
        !          1125:                 & -INSN_CACHE_LINE_WIDTH);
        !          1126: 
        !          1127:       while (ptr < (int) array + sizeof array)
        !          1128:        {
        !          1129:          *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
        !          1130:          ptr += INSN_CACHE_LINE_WIDTH;
        !          1131:        }
        !          1132: 
        !          1133:       initialized = 1;
        !          1134:     }
        !          1135: 
        !          1136:   /* Find the location in array that occupies the same cache line as BEG.  */
        !          1137: 
        !          1138:   offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
        !          1139:   start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
        !          1140:                 & -INSN_CACHE_PLANE_SIZE)
        !          1141:                + offset);
        !          1142: 
        !          1143:   /* Compute the cache alignment of the place to stop clearing.  */
        !          1144: #if 0  /* This is not needed for gcc's purposes.  */
        !          1145:   /* If the block to clear is bigger than a cache plane,
        !          1146:      we clear the entire cache, and OFFSET is already correct.  */ 
        !          1147:   if (end < beg + INSN_CACHE_PLANE_SIZE)
        !          1148: #endif
        !          1149:     offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
        !          1150:               & -INSN_CACHE_LINE_WIDTH)
        !          1151:              & (INSN_CACHE_PLANE_SIZE - 1));
        !          1152: 
        !          1153: #if INSN_CACHE_DEPTH > 1
        !          1154:   end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
        !          1155:   if (end_addr <= start_addr)
        !          1156:     end_addr += INSN_CACHE_PLANE_SIZE;
        !          1157: 
        !          1158:   for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
        !          1159:     {
        !          1160:       int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
        !          1161:       int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
        !          1162: 
        !          1163:       while (addr != stop)
        !          1164:        {
        !          1165:          /* Call the return instruction at ADDR.  */
        !          1166:          ((function_ptr) addr) ();
        !          1167: 
        !          1168:          addr += INSN_CACHE_LINE_WIDTH;
        !          1169:        }
        !          1170:     }
        !          1171: #else /* just one plane */
        !          1172:   do
        !          1173:     {
        !          1174:       /* Call the return instruction at START_ADDR.  */
        !          1175:       ((function_ptr) start_addr) ();
        !          1176: 
        !          1177:       start_addr += INSN_CACHE_LINE_WIDTH;
        !          1178:     }
        !          1179:   while ((start_addr % INSN_CACHE_SIZE) != offset);
        !          1180: #endif /* just one plane */
        !          1181: #endif /* Cache is large */
        !          1182: #endif /* Cache exists */
        !          1183: }
        !          1184: 
        !          1185: #endif /* L_clear_cache */
        !          1186: 
        !          1187: #ifdef L_trampoline
        !          1188: 
        !          1189: /* Jump to a trampoline, loading the static chain address.  */
        !          1190: 
        !          1191: #ifdef TRANSFER_FROM_TRAMPOLINE 
        !          1192: TRANSFER_FROM_TRAMPOLINE 
        !          1193: #endif
        !          1194: 
        !          1195: #ifdef __convex__
        !          1196: 
        !          1197: /* Make stack executable so we can call trampolines on stack.
        !          1198:    This is called from INITIALIZE_TRAMPOLINE in convex.h.  */
        !          1199: 
        !          1200: #include <sys/mman.h>
        !          1201: #include <sys/vmparam.h>
        !          1202: #include <machine/machparam.h>
        !          1203: 
        !          1204: void
        !          1205: __enable_execute_stack ()
        !          1206: {
        !          1207:   int fp;
        !          1208:   static unsigned lowest = USRSTACK;
        !          1209:   unsigned current = (unsigned) &fp & -NBPG;
        !          1210: 
        !          1211:   if (lowest > current)
        !          1212:     {
        !          1213:       unsigned len = lowest - current;
        !          1214:       mremap (current, &len, PROT_READ | PROT_WRITE | PROT_EXEC, MAP_PRIVATE);
        !          1215:       lowest = current;
        !          1216:     }
        !          1217: 
        !          1218:   /* Clear instruction cache in case an old trampoline is in it. */
        !          1219:   asm ("pich");
        !          1220: }
        !          1221: #endif /* __convex__ */
        !          1222: #endif /* L_trampoline */
        !          1223: 
        !          1224: #ifdef L__main
        !          1225: 
        !          1226: #include "gbl-ctors.h"
        !          1227: 
        !          1228: /* Run all the global destructors on exit from the program.  */
        !          1229: 
        !          1230: void
        !          1231: __do_global_dtors ()
        !          1232: {
        !          1233: #ifdef DO_GLOBAL_DTORS_BODY
        !          1234:   DO_GLOBAL_DTORS_BODY;
        !          1235: #else
        !          1236:   int nptrs = *(int *)__DTOR_LIST__;
        !          1237:   int i;
        !          1238: 
        !          1239:   /* Some systems place the number of pointers
        !          1240:      in the first word of the table.
        !          1241:      On other systems, that word is -1.
        !          1242:      In all cases, the table is null-terminated.  */
        !          1243: 
        !          1244:   /* If the length is not recorded, count up to the null.  */
        !          1245:   if (nptrs == -1)
        !          1246:     for (nptrs = 0; __DTOR_LIST__[nptrs + 1] != 0; nptrs++);
        !          1247: 
        !          1248:   /* GNU LD format.  */
        !          1249:   for (i = nptrs; i >= 1; i--)
        !          1250:     __DTOR_LIST__[i] ();
        !          1251: #endif
        !          1252: }
        !          1253: 
        !          1254: #ifndef INIT_SECTION_ASM_OP
        !          1255: /* Run all the global constructors on entry to the program.  */
        !          1256: 
        !          1257: #ifndef ON_EXIT /* DO_GLOBAL_CTORS_BODY uses ON_EXIT */
        !          1258: #define ON_EXIT(a, b)
        !          1259: #else
        !          1260: /* Make sure the exit routine is pulled in to define the globals as
        !          1261:    bss symbols, just in case the linker does not automatically pull
        !          1262:    bss definitions from the library.  */
        !          1263: 
        !          1264: extern int _exit_dummy_decl;
        !          1265: int *_exit_dummy_ref = &_exit_dummy_decl;
        !          1266: #endif /* ON_EXIT */
        !          1267: 
        !          1268: void
        !          1269: __do_global_ctors ()
        !          1270: {
        !          1271:   DO_GLOBAL_CTORS_BODY;
        !          1272: }
        !          1273: 
        !          1274: /* Subroutine called automatically by `main'.
        !          1275:    Compiling a global function named `main'
        !          1276:    produces an automatic call to this function at the beginning.
        !          1277: 
        !          1278:    For many systems, this routine calls __do_global_ctors.
        !          1279:    For systems which support a .init section we use the .init section
        !          1280:    to run __do_global_ctors, so we need not do anything here.  */
        !          1281: 
        !          1282: void
        !          1283: __main ()
        !          1284: {
        !          1285:   /* Support recursive calls to `main': run initializers just once.  */
        !          1286:   static initialized = 0;
        !          1287:   if (! initialized)
        !          1288:     {
        !          1289:       initialized = 1;
        !          1290:       __do_global_ctors ();
        !          1291:     }
        !          1292: }
        !          1293: #endif /* no INIT_SECTION_ASM_OP */
        !          1294: 
        !          1295: #endif /* L__main */
        !          1296: 
        !          1297: #ifdef L_exit
        !          1298: 
        !          1299: #include "gbl-ctors.h"
        !          1300: 
        !          1301: /* Provide default definitions for the lists of constructors and
        !          1302:    destructors, so that we don't get linker errors.  These symbols are
        !          1303:    intentionally bss symbols, so that gld and/or collect will provide
        !          1304:    the right values.  */
        !          1305: 
        !          1306: /* We declare the lists here with two elements each,
        !          1307:    so that they are valid empty lists if no other definition is loaded.  */
        !          1308: #ifndef INIT_SECTION_ASM_OP
        !          1309: func_ptr __CTOR_LIST__[2];
        !          1310: func_ptr __DTOR_LIST__[2];
        !          1311: #endif /* INIT_SECTION_ASM_OP */
        !          1312: 
        !          1313: #ifndef ON_EXIT
        !          1314: 
        !          1315: /* If we have no known way of registering our own __do_global_dtors
        !          1316:    routine so that it will be invoked at program exit time, then we
        !          1317:    have to define our own exit routine which will get this to happen.  */
        !          1318: 
        !          1319: extern void __do_global_dtors ();
        !          1320: extern void _cleanup ();
        !          1321: extern void _exit ();
        !          1322: 
        !          1323: void 
        !          1324: exit (status)
        !          1325:      int status;
        !          1326: {
        !          1327:   __do_global_dtors ();
        !          1328: #ifdef EXIT_BODY
        !          1329:   EXIT_BODY;
        !          1330: #else
        !          1331:   _cleanup ();
        !          1332: #endif
        !          1333:   _exit (status);
        !          1334: }
        !          1335: 
        !          1336: #else
        !          1337: int _exit_dummy_decl = 0;      /* prevent compiler & linker warnings */
        !          1338: #endif
        !          1339: 
        !          1340: #endif /* L_exit */
        !          1341: 
        !          1342: /* In a.out systems, we need to have these dummy constructor and destructor
        !          1343:    lists in the library.
        !          1344: 
        !          1345:    When using `collect', the first link will resolve __CTOR_LIST__
        !          1346:    and __DTOR_LIST__ to these symbols.  We will then run "nm" on the
        !          1347:    result, build the correct __CTOR_LIST__ and __DTOR_LIST__, and relink.
        !          1348:    Since we don't do the second link if no constructors existed, these
        !          1349:    dummies must be fully functional empty lists.
        !          1350: 
        !          1351:    When using `gnu ld', these symbols will be used if there are no
        !          1352:    constructors.  If there are constructors, the N_SETV symbol defined
        !          1353:    by the linker from the N_SETT's in input files will define __CTOR_LIST__
        !          1354:    and __DTOR_LIST__ rather than its being allocated as common storage
        !          1355:    by the definitions below.
        !          1356: 
        !          1357:    When using a linker that supports constructor and destructor segments,
        !          1358:    these definitions will not be used, since crtbegin.o and crtend.o
        !          1359:    (from crtstuff.c) will have already defined __CTOR_LIST__ and
        !          1360:     __DTOR_LIST__.  The crt*.o files are passed directly to the linker
        !          1361:    on its command line, by gcc.  */
        !          1362: 
        !          1363: /* The list needs two elements:  one is ignored (the old count); the
        !          1364:    second is the terminating zero.  Since both values are zero, this
        !          1365:    declaration is not initialized, and it becomes `common'.  */
        !          1366: 
        !          1367: #ifdef L_ctor_list
        !          1368: #include "gbl-ctors.h"
        !          1369: func_ptr __CTOR_LIST__[2];
        !          1370: #endif
        !          1371: 
        !          1372: #ifdef L_dtor_list
        !          1373: #include "gbl-ctors.h"
        !          1374: func_ptr __DTOR_LIST__[2];
        !          1375: #endif

unix.superglobalmegacorp.com

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