Annotation of gcc/libgcc2.c, revision 1.1.1.2

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

unix.superglobalmegacorp.com

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