home *** CD-ROM | disk | FTP | other *** search
/ Education Sampler 1992 [NeXTSTEP] / Education_1992_Sampler.iso / NeXT / GnuSource / cc-61.0.1 / cc / gnulib2.c < prev    next >
C/C++ Source or Header  |  1991-06-03  |  22KB  |  1,124 lines

  1. /* More subroutines needed by GCC output code on some machines.  */
  2. /* Compile this one with gcc.  */
  3. /* Copyright (C) 1989, 1990 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. #include "config.h"
  28. #include <stddef.h>
  29.  
  30. /* In case config.h defined it.  */
  31. #undef abort
  32.  
  33. #ifndef LONG_TYPE_SIZE
  34. #define LONG_TYPE_SIZE (sizeof (long) * BITS_PER_UNIT)
  35. #endif
  36.  
  37. #ifndef SItype
  38. #define SItype long int
  39. #endif
  40.  
  41. /* long long ints are pairs of long ints in the order determined by
  42.    WORDS_BIG_ENDIAN.  */
  43.  
  44. #if WORDS_BIG_ENDIAN
  45.   struct longlong {long high, low;};
  46. #else
  47.   struct longlong {long low, high;};
  48. #endif
  49.  
  50. /* We need this union to unpack/pack longlongs, since we don't have
  51.    any arithmetic yet.  Incoming long long parameters are stored
  52.    into the `ll' field, and the unpacked result is read from the struct
  53.    longlong.  */
  54.  
  55. typedef union
  56. {
  57.   struct longlong s;
  58.   long long ll;
  59. } long_long;
  60.  
  61. #if defined (L_udivdi3) || defined (L_muldi3)
  62. #include "longlong.h"
  63. #endif /* udiv or mul */
  64.  
  65. #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3)
  66. #if defined (L_divdi3) || defined (L_moddi3)
  67. static inline
  68. #endif
  69. long long
  70. __negdi2 (u)
  71.      long long u;
  72. {
  73.   long_long w;
  74.   long_long uu;
  75.  
  76.   uu.ll = u;
  77.  
  78.   w.s.low = -uu.s.low;
  79.   w.s.high = w.s.low == 0 ? -uu.s.high : ~uu.s.high;
  80.  
  81.   return w.ll;
  82. }
  83. #endif
  84.  
  85. #ifdef L_anddi3
  86. long long 
  87. __anddi3 (u, v)
  88.      long long u, v;
  89. {
  90.   long_long w;
  91.   long_long uu, vv;
  92.  
  93.   uu.ll = u;
  94.   vv.ll = v;
  95.  
  96.   w.s.high = uu.s.high & vv.s.high;
  97.   w.s.low = uu.s.low & vv.s.low;
  98.  
  99.   return w.ll;
  100. }
  101. #endif
  102.  
  103. #ifdef L_iordi3
  104. long long
  105. __iordi3 (u, v)
  106.      long long u, v;
  107. {
  108.   long_long w;
  109.   long_long uu, vv;
  110.  
  111.   uu.ll = u;
  112.   vv.ll = v;
  113.  
  114.   w.s.high = uu.s.high | vv.s.high;
  115.   w.s.low = uu.s.low | vv.s.low;
  116.  
  117.   return w.ll;
  118. }
  119. #endif
  120.  
  121. #ifdef L_xordi3
  122. long long
  123. __xordi3 (u, v)
  124.      long long u, v;
  125. {
  126.   long_long w;
  127.   long_long uu, vv;
  128.  
  129.   uu.ll = u;
  130.   vv.ll = v;
  131.  
  132.   w.s.high = uu.s.high ^ vv.s.high;
  133.   w.s.low = uu.s.low ^ vv.s.low;
  134.  
  135.   return w.ll;
  136. }
  137. #endif
  138.  
  139. #ifdef L_one_cmpldi2
  140. long long
  141. __one_cmpldi2 (u)
  142.      long long u;
  143. {
  144.   long_long w;
  145.   long_long uu;
  146.  
  147.   uu.ll = u;
  148.  
  149.   w.s.high = ~uu.s.high;
  150.   w.s.low = ~uu.s.low;
  151.  
  152.   return w.ll;
  153. }
  154. #endif
  155.  
  156. #ifdef L_lshldi3
  157. long long
  158. __lshldi3 (u, b1)
  159.      long long u;
  160.      long long b1;
  161. {
  162.   long_long w;
  163.   long bm;
  164.   long_long uu;
  165.   int b = b1;
  166.  
  167.   if (b == 0)
  168.     return u;
  169.  
  170.   uu.ll = u;
  171.  
  172.   bm = (sizeof (long) * BITS_PER_UNIT) - b;
  173.   if (bm <= 0)
  174.     {
  175.       w.s.low = 0;
  176.       w.s.high = (unsigned long)uu.s.low << -bm;
  177.     }
  178.   else
  179.     {
  180.       unsigned long carries = (unsigned long)uu.s.low >> bm;
  181.       w.s.low = (unsigned long)uu.s.low << b;
  182.       w.s.high = ((unsigned long)uu.s.high << b) | carries;
  183.     }
  184.  
  185.   return w.ll;
  186. }
  187. #endif
  188.  
  189. #ifdef L_lshrdi3
  190. long long
  191. __lshrdi3 (u, b1)
  192.      long long u;
  193.      long long b1;
  194. {
  195.   long_long w;
  196.   long bm;
  197.   long_long uu;
  198.   int b = b1;
  199.  
  200.   if (b == 0)
  201.     return u;
  202.  
  203.   uu.ll = u;
  204.  
  205.   bm = (sizeof (long) * BITS_PER_UNIT) - b;
  206.   if (bm <= 0)
  207.     {
  208.       w.s.high = 0;
  209.       w.s.low = (unsigned long)uu.s.high >> -bm;
  210.     }
  211.   else
  212.     {
  213.       unsigned long carries = (unsigned long)uu.s.high << bm;
  214.       w.s.high = (unsigned long)uu.s.high >> b;
  215.       w.s.low = ((unsigned long)uu.s.low >> b) | carries;
  216.     }
  217.  
  218.   return w.ll;
  219. }
  220. #endif
  221.  
  222. #ifdef L_ashldi3
  223. long long
  224. __ashldi3 (u, b1)
  225.      long long u;
  226.      long long b1;
  227. {
  228.   long_long w;
  229.   long bm;
  230.   long_long uu;
  231.   int b = b1;
  232.  
  233.   if (b == 0)
  234.     return u;
  235.  
  236.   uu.ll = u;
  237.  
  238.   bm = (sizeof (long) * BITS_PER_UNIT) - b;
  239.   if (bm <= 0)
  240.     {
  241.       w.s.low = 0;
  242.       w.s.high = (unsigned long)uu.s.low << -bm;
  243.     }
  244.   else
  245.     {
  246.       unsigned long carries = (unsigned long)uu.s.low >> bm;
  247.       w.s.low = (unsigned long)uu.s.low << b;
  248.       w.s.high = ((unsigned long)uu.s.high << b) | carries;
  249.     }
  250.  
  251.   return w.ll;
  252. }
  253. #endif
  254.  
  255. #ifdef L_ashrdi3
  256. long long
  257. __ashrdi3 (u, b1)
  258.      long long u;
  259.      long long b1;
  260. {
  261.   long_long w;
  262.   long bm;
  263.   long_long uu;
  264.   int b = b1;
  265.  
  266.   if (b == 0)
  267.     return u;
  268.  
  269.   uu.ll = u;
  270.  
  271.   bm = (sizeof (long) * BITS_PER_UNIT) - b;
  272.   if (bm <= 0)
  273.     {
  274.       w.s.high = uu.s.high >> 31; /* just to make w.s.high 1..1 or 0..0 */
  275.       w.s.low = uu.s.high >> -bm;
  276.     }
  277.   else
  278.     {
  279.       unsigned long carries = (unsigned long)uu.s.high << bm;
  280.       w.s.high = uu.s.high >> b;
  281.       w.s.low = ((unsigned long)uu.s.low >> b) | carries;
  282.     }
  283.  
  284.   return w.ll;
  285. }
  286. #endif
  287.  
  288. #ifdef L_adddi3
  289. long long
  290. __adddi3 (u, v)
  291.      long long u, v;
  292. {
  293.   long_long w;
  294.   long_long uu, vv;
  295.  
  296.   uu.ll = u;
  297.   vv.ll = v;
  298.  
  299.   w.s.low = uu.s.low + vv.s.low;
  300.   w.s.high = uu.s.high + vv.s.high + ((unsigned long) w.s.low < uu.s.low);
  301.  
  302.   return w.ll;
  303. }
  304. #endif
  305.  
  306. #ifdef L_subdi3
  307. long long
  308. __subdi3 (u, v)
  309.      long long u, v;
  310. {
  311.   long_long w;
  312.   long_long uu, vv;
  313.  
  314.   uu.ll = u;
  315.   vv.ll = v;
  316.  
  317.   w.s.low = uu.s.low - vv.s.low;
  318.   w.s.high = uu.s.high - vv.s.high - ((unsigned long) w.s.low > uu.s.low);
  319.  
  320.   return w.ll;
  321. }
  322. #endif
  323.  
  324. #ifdef L_divdi3
  325. long long
  326. __divdi3 (u, v)
  327.      long long u, v;
  328. {
  329.   int c = 0;
  330.   long_long uu, vv;
  331.   long_long w;
  332.  
  333.   uu.ll = u, vv.ll = v;
  334.  
  335.   if (uu.s.high < 0)
  336.     c = ~c,
  337.     uu.ll = __negdi2 (uu.ll);
  338.   if (vv.s.high < 0)
  339.     c = ~c,
  340.     vv.ll = __negdi2 (vv.ll);
  341.  
  342.   w.ll = (unsigned long long) uu.ll / vv.ll;
  343.   if (c)
  344.     w.ll = __negdi2 (w.ll);
  345.  
  346.   return w.ll;
  347. }
  348. #endif
  349.  
  350. #ifdef L_moddi3
  351. long long
  352. __moddi3 (u, v)
  353.      long long u, v;
  354. {
  355.   int c = 0;
  356.   long_long uu, vv;
  357.   long_long w;
  358.  
  359.   uu.ll = u, vv.ll = v;
  360.  
  361.   if (uu.s.high < 0)
  362.     c = ~c,
  363.     uu.ll = __negdi2 (uu.ll);
  364.   if (vv.s.high < 0)
  365.     c = ~c,
  366.     vv.ll = __negdi2 (vv.ll);
  367.  
  368.   w.ll = (unsigned long long) uu.ll % vv.ll;
  369.   if (c)
  370.     w.ll = __negdi2 (w.ll);
  371.  
  372.   return w.ll;
  373. }
  374. #endif
  375.  
  376. #ifdef L_umoddi3
  377. unsigned long long
  378. __umoddi3 (u, v)
  379.      unsigned long long u, v;
  380. {
  381.   /* This ought to be done better.  The division routine calculates the
  382.      remainder, so we should not make a multiplication here.  */
  383.   return u - (u / v) * v;
  384. }
  385. #endif
  386.  
  387. #ifdef L_muldi3
  388. long long
  389. __muldi3 (u, v)
  390.      long long u, v;
  391. {
  392.   long_long w;
  393.   long_long uu, vv;
  394.  
  395.   uu.ll = u, vv.ll = v;
  396.  
  397.   w.ll = __umulsidi3 (uu.s.low, vv.s.low);
  398.   w.s.high += uu.s.low * vv.s.high + uu.s.high * vv.s.low;
  399.  
  400.   return w.ll;
  401. }
  402. #endif
  403.  
  404. #ifdef L_udivdi3
  405. unsigned long long
  406. __udivdi3 (n, d)
  407.      unsigned long long n, d;
  408. {
  409.   long_long ww;
  410.   long_long nn, dd;
  411.   unsigned long d0, d1, n0, n1, n2;
  412.   unsigned long q0, q1;
  413.   unsigned b, bm;
  414.  
  415.   nn.ll = n;
  416.   dd.ll = d;
  417.  
  418.   d0 = dd.s.low;
  419.   d1 = dd.s.high;
  420.   n0 = nn.s.low;
  421.   n1 = nn.s.high;
  422.  
  423.   if (d1 == 0)
  424.     {
  425.       if (d0 > n1)
  426.     {
  427.       /* 0q = nn / 0D */
  428.  
  429.       count_leading_zeros (bm, d0);
  430.  
  431.       if (bm != 0)
  432.         {
  433.           /* Normalize, i.e. make the most significant bit of the
  434.          denominator set.  */
  435.  
  436.           d0 = d0 << bm;
  437.           n1 = (n1 << bm) | (n0 >> (LONG_TYPE_SIZE - bm));
  438.           n0 = n0 << bm;
  439.         }
  440.  
  441.       udiv_qrnnd (q0, n0, n1, n0, d0);
  442.       q1 = 0;
  443.  
  444.       /* Remainder in n0 >> bm.  */
  445.     }
  446.       else
  447.     {
  448.       /* qq = NN / 0d */
  449.  
  450.       if (d0 == 0)
  451.         d0 = 1 / d0;    /* Divide intentionally by zero.  */
  452.  
  453.       count_leading_zeros (bm, d0);
  454.  
  455.       if (bm == 0)
  456.         {
  457.           /* From (n1 >= d0) /\ (the most significant bit of d0 is set),
  458.          conclude (the most significant bit of n1 is set) /\ (the
  459.          leading quotient digit q1 = 1).
  460.  
  461.          This special case is necessary, not an optimization.
  462.          (Shifts counts of LONG_TYPE_SIZE are undefined.)  */
  463.  
  464.           n1 -= d0;
  465.           q1 = 1;
  466.         }
  467.       else
  468.         {
  469.           /* Normalize.  */
  470.  
  471.           b = LONG_TYPE_SIZE - bm;
  472.  
  473.           d0 = d0 << bm;
  474.           n2 = n1 >> b;
  475.           n1 = (n1 << bm) | (n0 >> b);
  476.           n0 = n0 << bm;
  477.  
  478.           udiv_qrnnd (q1, n1, n2, n1, d0);
  479.         }
  480.  
  481.       /* n1 != d0... */
  482.  
  483.       udiv_qrnnd (q0, n0, n1, n0, d0);
  484.  
  485.       /* Remainder in n0.  */
  486.     }
  487.     }
  488.   else
  489.     {
  490.       if (d1 > n1)
  491.     {
  492.       /* 00 = nn / DD */
  493.  
  494.       q0 = 0;
  495.       q1 = 0;
  496.  
  497.       /* Remainder in n1n0.  */
  498.     }
  499.       else
  500.     {
  501.       /* 0q = NN / dd */
  502.  
  503.       count_leading_zeros (bm, d1);
  504.       if (bm == 0)
  505.         {
  506.           /* From (n1 >= d1) /\ (the most significant bit of d1 is set),
  507.          conclude (the most significant bit of n1 is set) /\ (the
  508.          quotient digit q0 = 0 or 1).
  509.  
  510.          This special case is necessary, not an optimization.  */
  511.  
  512.           q0 = (n1 > d1) | (n1 == d1 && n0 >= d0);
  513.           q1 = 0;
  514.         }
  515.       else
  516.         {
  517.           unsigned long m1, m0;
  518.           /* Normalize.  */
  519.  
  520.           b = LONG_TYPE_SIZE - bm;
  521.  
  522.           d1 = (d1 << bm) | (d0 >> b);
  523.           d0 = d0 << bm;
  524.           n2 = n1 >> b;
  525.           n1 = (n1 << bm) | (n0 >> b);
  526.           n0 = n0 << bm;
  527.  
  528.           udiv_qrnnd (q0, n1, n2, n1, d1);
  529.           umul_ppmm (m1, m0, q0, d0);
  530.  
  531.           if (m1 > n1 || (m1 == n1 && m0 > n0))
  532.         q0--;
  533.  
  534.           q1 = 0;
  535.  
  536.           /* Remainder in m1m0 - n1n0 (unless q0 was decremented).  */
  537.         }
  538.     }
  539.     }
  540.  
  541.   ww.s.low = q0;
  542.   ww.s.high = q1;
  543.   return ww.ll;
  544. }
  545. #endif
  546.  
  547. #ifdef L_cmpdi2
  548. SItype
  549. __cmpdi2 (a, b)
  550.      long long a, b;
  551. {
  552.   long_long au, bu;
  553.  
  554.   au.ll = a, bu.ll = b;
  555.  
  556.   if (au.s.high < bu.s.high)
  557.     return 0;
  558.   else if (au.s.high > bu.s.high)
  559.     return 2;
  560.   if ((unsigned) au.s.low < (unsigned) bu.s.low)
  561.     return 0;
  562.   else if ((unsigned) au.s.low > (unsigned) bu.s.low)
  563.     return 2;
  564.   return 1;
  565. }
  566. #endif
  567.  
  568. #ifdef L_ucmpdi2
  569. SItype
  570. __ucmpdi2 (a, b)
  571.      long long a, b;
  572. {
  573.   long_long au, bu;
  574.  
  575.   au.ll = a, bu.ll = b;
  576.  
  577.   if ((unsigned) au.s.high < (unsigned) bu.s.high)
  578.     return 0;
  579.   else if ((unsigned) au.s.high > (unsigned) bu.s.high)
  580.     return 2;
  581.   if ((unsigned) au.s.low < (unsigned) bu.s.low)
  582.     return 0;
  583.   else if ((unsigned) au.s.low > (unsigned) bu.s.low)
  584.     return 2;
  585.   return 1;
  586. }
  587. #endif
  588.  
  589. #ifdef L_fixunsdfdi
  590. #define WORD_SIZE (sizeof (long) * BITS_PER_UNIT)
  591. #define HIGH_WORD_COEFF (((long long) 1) << WORD_SIZE)
  592.  
  593. long long
  594. __fixunsdfdi (a)
  595.      double a;
  596. {
  597.   double b;
  598.   unsigned long long v;
  599.  
  600.   if (a < 0)
  601.     return 0;
  602.  
  603.   /* Compute high word of result, as a flonum.  */
  604.   b = (a / HIGH_WORD_COEFF);
  605.   /* Convert that to fixed (but not to long long!),
  606.      and shift it into the high word.  */
  607.   v = (unsigned long int) b;
  608.   v <<= WORD_SIZE;
  609.   /* Remove high part from the double, leaving the low part as flonum.  */
  610.   a -= (double)v;
  611.   /* Convert that to fixed (but not to long long!) and add it in.
  612.      Sometimes A comes out negative.  This is significant, since
  613.      A has more bits than a long int does.  */
  614.   if (a < 0)
  615.     v -= (unsigned long int) (- a);
  616.   else
  617.     v += (unsigned long int) a;
  618.   return v;
  619. }
  620. #endif
  621.  
  622. #ifdef L_fixdfdi
  623. long long
  624. __fixdfdi (a)
  625.      double a;
  626. {
  627.   long long __fixunsdfdi (double a);
  628.  
  629.   if (a < 0)
  630.     return - __fixunsdfdi (-a);
  631.   return __fixunsdfdi (a);
  632. }
  633. #endif
  634.  
  635. #ifdef L_fixunssfdi
  636. #define WORD_SIZE (sizeof (long) * BITS_PER_UNIT)
  637. #define HIGH_WORD_COEFF (((long long) 1) << WORD_SIZE)
  638.  
  639. long long
  640. __fixunssfdi (float original_a)
  641. {
  642.   /* Convert the float to a double, because that is surely not going
  643.      to lose any bits.  Some day someone else can write a faster version
  644.      that avoids converting to double, and verify it really works right.  */
  645.   double a = original_a;
  646.   double b;
  647.   unsigned long long v;
  648.  
  649.   if (a < 0)
  650.     return 0;
  651.  
  652.   /* Compute high word of result, as a flonum.  */
  653.   b = (a / HIGH_WORD_COEFF);
  654.   /* Convert that to fixed (but not to long long!),
  655.      and shift it into the high word.  */
  656.   v = (unsigned long int) b;
  657.   v <<= WORD_SIZE;
  658.   /* Remove high part from the double, leaving the low part as flonum.  */
  659.   a -= (double)v;
  660.   /* Convert that to fixed (but not to long long!) and add it in.
  661.      Sometimes A comes out negative.  This is significant, since
  662.      A has more bits than a long int does.  */
  663.   if (a < 0)
  664.     v -= (unsigned long int) (- a);
  665.   else
  666.     v += (unsigned long int) a;
  667.   return v;
  668. }
  669. #endif
  670.  
  671. #ifdef L_fixsfdi
  672. long long
  673. __fixsfdi (float a)
  674. {
  675.   long long __fixunssfdi (float a);
  676.  
  677.   if (a < 0)
  678.     return - __fixunssfdi (-a);
  679.   return __fixunssfdi (a);
  680. }
  681. #endif
  682.  
  683. #ifdef L_floatdidf
  684. #define WORD_SIZE (sizeof (long) * BITS_PER_UNIT)
  685. #define HIGH_HALFWORD_COEFF (((long long) 1) << (WORD_SIZE / 2))
  686. #define HIGH_WORD_COEFF (((long long) 1) << WORD_SIZE)
  687.  
  688. double
  689. __floatdidf (u)
  690.      long long u;
  691. {
  692.   double d;
  693.   int negate = 0;
  694.  
  695.   if (u < 0)
  696.     u = -u, negate = 1;
  697.  
  698.   d = (unsigned int) (u >> WORD_SIZE);
  699.   d *= HIGH_HALFWORD_COEFF;
  700.   d *= HIGH_HALFWORD_COEFF;
  701.   d += (unsigned int) (u & (HIGH_WORD_COEFF - 1));
  702.  
  703.   return (negate ? -d : d);
  704. }
  705. #endif
  706.  
  707. #ifdef L_floatdisf
  708. #define WORD_SIZE (sizeof (long) * BITS_PER_UNIT)
  709. #define HIGH_HALFWORD_COEFF (((long long) 1) << (WORD_SIZE / 2))
  710. #define HIGH_WORD_COEFF (((long long) 1) << WORD_SIZE)
  711.  
  712. float
  713. __floatdisf (u)
  714.      long long u;
  715. {
  716.   float f;
  717.   int negate = 0;
  718.  
  719.   if (u < 0)
  720.     u = -u, negate = 1;
  721.  
  722.   f = (unsigned int) (u >> WORD_SIZE);
  723.   f *= HIGH_HALFWORD_COEFF;
  724.   f *= HIGH_HALFWORD_COEFF;
  725.   f += (unsigned int) (u & (HIGH_WORD_COEFF - 1));
  726.  
  727.   return (negate ? -f : f);
  728. }
  729. #endif
  730.  
  731. #ifdef L_fixunsdfsi
  732. #include "limits.h"
  733.  
  734. unsigned SItype
  735. __fixunsdfsi (a)
  736.      double a;
  737. {
  738.   if (a >= - (double) LONG_MIN)
  739.     return (SItype) (a + LONG_MIN) - LONG_MIN;
  740.   return (SItype) a;
  741. }
  742. #endif
  743.  
  744. #ifdef L_fixunssfsi
  745. #include "limits.h"
  746.  
  747. unsigned SItype
  748. __fixunssfsi (float a)
  749. {
  750.   if (a >= - (float) LONG_MIN)
  751.     return (SItype) (a + LONG_MIN) - LONG_MIN;
  752.   return (SItype) a;
  753. }
  754. #endif
  755.  
  756. #ifdef L_varargs
  757. #ifdef i860
  758.     asm ("    .text");
  759.     asm ("    .align    4");
  760.  
  761.     asm ("___builtin_saveregs::");
  762.     asm ("    mov    sp,r30");
  763.     asm ("    andnot    0x0f,sp,sp");
  764.     asm ("    adds    -96,sp,sp");  /* allocate sufficient space on the stack */
  765.  
  766.     asm ("    st.l    r16, 0(sp)"); /* save integer regs (r16-r27) */
  767.     asm ("    st.l    r17, 4(sp)"); /* int    fixed[12] */
  768.     asm ("    st.l    r18, 8(sp)");
  769.     asm ("    st.l    r19,12(sp)");
  770.     asm ("    st.l    r20,16(sp)");
  771.     asm ("    st.l    r21,20(sp)");
  772.     asm ("    st.l    r22,24(sp)");
  773.     asm ("    st.l    r23,28(sp)");
  774.     asm ("    st.l    r24,32(sp)");
  775.     asm ("    st.l    r25,36(sp)");
  776.     asm ("    st.l    r26,40(sp)");
  777.     asm ("    st.l    r27,44(sp)");
  778.  
  779.     asm ("    fst.q    f8, 48(sp)"); /* save floating regs (f8-f15) */
  780.     asm ("    fst.q    f12,64(sp)"); /* int floating[8] */
  781.  
  782.     asm ("    st.l    r28,80(sp)"); /* pointer to more args */
  783.     asm ("    st.l    r0, 84(sp)"); /* nfixed */
  784.     asm ("    st.l    r0, 88(sp)"); /* nfloating */
  785.     asm ("    st.l    r0, 92(sp)"); /* pad */
  786.  
  787.     asm ("    mov    sp,r16");
  788.     asm ("    bri    r1");
  789.     asm ("    mov    r30,sp");
  790.                 /* recover stack and pass address to start 
  791.                    of data.  */
  792. #endif
  793. #ifdef __sparc__
  794.     asm (".global ___builtin_saveregs");
  795.     asm ("___builtin_saveregs:");
  796.     asm ("st %i0,[%fp+68]");
  797.     asm ("st %i1,[%fp+72]");
  798.     asm ("st %i2,[%fp+76]");
  799.     asm ("st %i3,[%fp+80]");
  800.     asm ("st %i4,[%fp+84]");
  801.     asm ("retl");
  802.     asm ("st %i5,[%fp+88]");
  803. #else /* not __sparc__ */
  804. #if defined(__MIPSEL__) | defined(__R3000__) | defined(__R2000__) | defined(__mips__)
  805.  
  806.   asm ("    .text");
  807.   asm ("    .ent __builtin_saveregs");
  808.   asm ("    .globl __builtin_saveregs");
  809.   asm ("__builtin_saveregs:");
  810.   asm ("    sw    $4,0($30)");
  811.   asm ("    sw    $5,4($30)");
  812.   asm ("    sw    $6,8($30)");
  813.   asm ("    sw    $7,12($30)");
  814.   asm ("    j    $31");
  815.   asm ("    .end __builtin_saveregs");
  816. #else /* not mips */
  817. __builtin_saveregs ()
  818. {
  819.   abort ();
  820. }
  821. #endif /* not mips */
  822. #endif /* not __sparc__ */
  823. #endif
  824.  
  825. #ifdef L_eprintf
  826. #include <stdio.h>
  827. /* This is used by the `assert' macro.  */
  828. void
  829. __eprintf (string, expression, line, filename)
  830.      char *string;
  831.      char *expression;
  832.      int line;
  833.      char *filename;
  834. {
  835.   fprintf (stderr, string, expression, line, filename);
  836.   fflush (stderr);
  837.   abort ();
  838. }
  839. #endif
  840.  
  841. #ifdef L_bb
  842. /* Avoid warning from ranlib about empty object file.  */
  843. __bb_avoid_warning ()
  844. {}
  845.  
  846. #if defined (sun) && defined (mc68000)
  847. struct bb
  848. {
  849.   int initialized;
  850.   char *filename;
  851.   int *counts;
  852.   int ncounts;
  853.   int zero_word;
  854.   int *addresses;
  855. };
  856.  
  857. __bb_init_func (blocks)
  858.     struct bb *blocks;
  859. {
  860.   extern int ___tcov_init;
  861.  
  862.   if (! ___tcov_init)
  863.     ___tcov_init_func ();
  864.  
  865.   ___bb_link (blocks->filename, blocks->counts, blocks->ncounts);
  866. }
  867.  
  868. #endif
  869. #endif
  870.  
  871. /* frills for C++ */
  872.  
  873. #ifdef L_builtin_new
  874. typedef void (*vfp)();
  875.  
  876. extern vfp __new_handler;
  877.  
  878. char *
  879. __builtin_new (sz)
  880.      long sz;
  881. {
  882.   char *p;
  883.  
  884.   p = (char *)malloc (sz);
  885.   if (p == 0)
  886.     (*__new_handler) ();
  887.   return p;
  888. }
  889. #endif
  890.  
  891. #ifdef L_builtin_New
  892. typedef void (*vfp)();
  893.  
  894. static void
  895. default_new_handler ();
  896.  
  897. vfp __new_handler = default_new_handler;
  898.  
  899. char *
  900. __builtin_vec_new (p, maxindex, size, ctor)
  901.      char *p;
  902.      int maxindex, size;
  903.      void (*ctor)();
  904. {
  905.   int i, nelts = maxindex + 1;
  906.   char *rval;
  907.  
  908.   if (p == 0)
  909.     p = (char *)__builtin_new (nelts * size);
  910.  
  911.   rval = p;
  912.  
  913.   for (i = 0; i < nelts; i++)
  914.     {
  915.       (*ctor) (p);
  916.       p += size;
  917.     }
  918.  
  919.   return rval;
  920. }
  921.  
  922. vfp
  923. __set_new_handler (handler)
  924.      vfp handler;
  925. {
  926.   vfp prev_handler;
  927.  
  928.   prev_handler = __new_handler;
  929.   if (handler == 0) handler = default_new_handler;
  930.   __new_handler = handler;
  931.   return prev_handler;
  932. }
  933.  
  934. vfp
  935. set_new_handler (handler)
  936.      vfp handler;
  937. {
  938.   return __set_new_handler (handler);
  939. }
  940.  
  941. static void
  942. default_new_handler ()
  943. {
  944.   /* don't use fprintf (stderr, ...) because it may need to call malloc.  */
  945.   write (2, "default_new_handler: out of memory... aaaiiiiiieeeeeeeeeeeeee!\n", 65);
  946.   /* don't call exit () because that may call global destructors which
  947.      may cause a loop.  */
  948.   _exit (-1);
  949. }
  950. #endif
  951.  
  952. #ifdef L_builtin_del
  953. typedef void (*vfp)();
  954.  
  955. void
  956. __builtin_delete (ptr)
  957.      char *ptr;
  958. {
  959.   if (ptr)
  960.     free (ptr);
  961. }
  962.  
  963. void
  964. __builtin_vec_delete (ptr, maxindex, size, dtor, auto_delete_vec, auto_delete)
  965.      char *ptr;
  966.      int maxindex, size;
  967.      void (*dtor)();
  968.      int auto_delete;
  969. {
  970.   int i, nelts = maxindex + 1;
  971.   char *p = ptr;
  972.  
  973.   ptr += nelts * size;
  974.  
  975.   for (i = 0; i < nelts; i++)
  976.     {
  977.       ptr -= size;
  978.       (*dtor) (ptr, auto_delete);
  979.     }
  980.  
  981.   if (auto_delete_vec)
  982.     __builtin_delete (p);
  983. }
  984.  
  985. #endif
  986.  
  987. #ifdef L_shtab
  988. unsigned int __shtab[] = {
  989.     0x00000001, 0x00000002, 0x00000004, 0x00000008,
  990.     0x00000010, 0x00000020, 0x00000040, 0x00000080,
  991.     0x00000100, 0x00000200, 0x00000400, 0x00000800,
  992.     0x00001000, 0x00002000, 0x00004000, 0x00008000,
  993.     0x00010000, 0x00020000, 0x00040000, 0x00080000,
  994.     0x00100000, 0x00200000, 0x00400000, 0x00800000,
  995.     0x01000000, 0x02000000, 0x04000000, 0x08000000,
  996.     0x10000000, 0x20000000, 0x40000000, 0x80000000
  997.   };
  998. #endif
  999.  
  1000. #ifdef L_clear_cache
  1001. /* Clear part of an instruction cache.  */
  1002.  
  1003. #define INSN_CACHE_PLANE_SIZE (INSN_CACHE_SIZE / INSN_CACHE_DEPTH)
  1004.  
  1005. void
  1006. __clear_cache (beg, end)
  1007.      char *beg, *end;
  1008. {
  1009. #ifdef INSN_CACHE_SIZE
  1010.   static char array[INSN_CACHE_SIZE + INSN_CACHE_PLANE_SIZE + INSN_CACHE_LINE_WIDTH];
  1011.   static int initialized = 0;
  1012.   int offset;
  1013.   unsigned int start_addr, end_addr;
  1014.   typedef (*function_ptr) ();
  1015.  
  1016. #if (INSN_CACHE_SIZE / INSN_CACHE_LINE_WIDTH) < 16
  1017.   /* It's cheaper to clear the whole cache.
  1018.      Put in a series of jump instructions so that calling the beginning
  1019.      of the cache will clear the whole thing.  */
  1020.  
  1021.   if (! initialized)
  1022.     {
  1023.       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
  1024.          & -INSN_CACHE_LINE_WIDTH);
  1025.       int end_ptr = ptr + INSN_CACHE_SIZE;
  1026.  
  1027.       while (ptr < end_ptr)
  1028.     {
  1029.       *(INSTRUCTION_TYPE *)ptr
  1030.         = JUMP_AHEAD_INSTRUCTION + INSN_CACHE_LINE_WIDTH;
  1031.       ptr += INSN_CACHE_LINE_WIDTH;
  1032.     }
  1033.       *(INSTRUCTION_TYPE *)(ptr - INSN_CACHE_LINE_WIDTH) = RETURN_INSTRUCTION;
  1034.  
  1035.       initialized = 1;
  1036.     }
  1037.  
  1038.   /* Call the beginning of the sequence.  */
  1039.   (((function_ptr) (((int) array + INSN_CACHE_LINE_WIDTH - 1)
  1040.             & -INSN_CACHE_LINE_WIDTH))
  1041.    ());
  1042.  
  1043. #else /* Cache is large.  */
  1044.  
  1045.   if (! initialized)
  1046.     {
  1047.       int ptr = (((int) array + INSN_CACHE_LINE_WIDTH - 1)
  1048.          & -INSN_CACHE_LINE_WIDTH);
  1049.  
  1050.       while (ptr < (int) array + sizeof array)
  1051.     {
  1052.       *(INSTRUCTION_TYPE *)ptr = RETURN_INSTRUCTION;
  1053.       ptr += INSN_CACHE_LINE_WIDTH;
  1054.     }
  1055.  
  1056.       initialized = 1;
  1057.     }
  1058.  
  1059.   /* Find the location in array that occupies the same cache line as BEG.  */
  1060.  
  1061.   offset = ((int) beg & -INSN_CACHE_LINE_WIDTH) & (INSN_CACHE_PLANE_SIZE - 1);
  1062.   start_addr = (((int) (array + INSN_CACHE_PLANE_SIZE - 1)
  1063.          & -INSN_CACHE_PLANE_SIZE)
  1064.         + offset);
  1065.  
  1066.   /* Compute the cache alignment of the place to stop clearing.  */
  1067. #if 0  /* This is not needed for gcc's purposes.  */
  1068.   /* If the block to clear is bigger than a cache plane,
  1069.      we clear the entire cache, and OFFSET is already correct.  */ 
  1070.   if (end < beg + INSN_CACHE_PLANE_SIZE)
  1071. #endif
  1072.     offset = (((int) (end + INSN_CACHE_LINE_WIDTH - 1)
  1073.            & -INSN_CACHE_LINE_WIDTH)
  1074.           & (INSN_CACHE_PLANE_SIZE - 1));
  1075.  
  1076. #if INSN_CACHE_DEPTH > 1
  1077.   end_addr = (start_addr & -INSN_CACHE_PLANE_SIZE) + offset;
  1078.   if (end_addr <= start_addr)
  1079.     end_addr += INSN_CACHE_PLANE_SIZE;
  1080.  
  1081.   for (plane = 0; plane < INSN_CACHE_DEPTH; plane++)
  1082.     {
  1083.       int addr = start_addr + plane * INSN_CACHE_PLANE_SIZE;
  1084.       int stop = end_addr + plane * INSN_CACHE_PLANE_SIZE;
  1085.  
  1086.       while (addr != stop)
  1087.     {
  1088.       /* Call the return instruction at ADDR.  */
  1089.       ((function_ptr) addr) ();
  1090.  
  1091.       addr += INSN_CACHE_LINE_WIDTH;
  1092.     }
  1093.     }
  1094. #else /* just one plane */
  1095.   do
  1096.     {
  1097.       /* Call the return instruction at START_ADDR.  */
  1098.       ((function_ptr) start_addr) ();
  1099.  
  1100.       start_addr += INSN_CACHE_LINE_WIDTH;
  1101.     }
  1102.   while ((start_addr % INSN_CACHE_SIZE) != offset);
  1103. #endif /* just one plane */
  1104. #endif /* Cache is large */
  1105. #endif /* Cache exists */
  1106. }
  1107.  
  1108. #endif /* L_clear_cache */
  1109.  
  1110. #ifdef L_trampoline
  1111.  
  1112. /* Jump to a trampoline, loading the static chain address.  */
  1113.  
  1114. /* asm with operands is permitted only within a function.  */
  1115. void
  1116. __transfer_from_trampoline ()
  1117. {
  1118. #ifdef TRANSFER_FROM_TRAMPOLINE 
  1119.   TRANSFER_FROM_TRAMPOLINE 
  1120. #endif
  1121. }
  1122.  
  1123. #endif
  1124.