Annotation of gcc/libgcc2.c, revision 1.1.1.6

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

unix.superglobalmegacorp.com

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