Annotation of gcc/libgcc2.c, revision 1.1.1.4

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

unix.superglobalmegacorp.com

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