Annotation of gcc/libgcc2.c, revision 1.1.1.8

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

unix.superglobalmegacorp.com

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