Annotation of gcc/libgcc2.c, revision 1.1.1.7

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

unix.superglobalmegacorp.com

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