From ab49538861468caa8bb7d1cd6df050e614ffab1c Mon Sep 17 00:00:00 2001 From: Richard Stallman Date: Tue, 7 Jul 1992 19:46:10 +0000 Subject: [PATCH] *** empty log message *** From-SVN: r1503 --- gcc/libgcc2.c | 467 +++++++++++++++++++++++++++++++------------------- 1 file changed, 288 insertions(+), 179 deletions(-) diff --git a/gcc/libgcc2.c b/gcc/libgcc2.c index 01db80f3b75..8e9ed05875b 100644 --- a/gcc/libgcc2.c +++ b/gcc/libgcc2.c @@ -38,35 +38,59 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #undef abort #endif -/* Need to undef this because LONG_TYPE_SIZE may rely upon GCC's - internal `target_flags' variable. */ -#undef LONG_TYPE_SIZE - -#define LONG_TYPE_SIZE (sizeof (long) * BITS_PER_UNIT) - -#ifndef SItype -#define SItype long int -#endif - -/* long long ints are pairs of long ints in the order determined by +/* In the first part of this file, we are interfacing to calls generated + by the compiler itself. These calls pass values into these routines + which have very specific modes (rather than very specific types), and + these compiler-generated calls also expect any return values to have + very specific modes (rather than very specific types). Thus, we need + to avoid using regular C language type names in this part of the file + because the sizes for those types can be configured to be anything. + Instead we use the following special type names. */ + +typedef unsigned int UQItype __attribute__ ((mode (QI))); +typedef int SItype __attribute__ ((mode (SI))); +typedef unsigned int USItype __attribute__ ((mode (SI))); +typedef int DItype __attribute__ ((mode (DI))); +typedef unsigned int UDItype __attribute__ ((mode (DI))); +typedef float SFtype __attribute__ ((mode (SF))); +typedef float DFtype __attribute__ ((mode (DF))); +typedef float XFtype __attribute__ ((mode (XF))); +typedef float TFtype __attribute__ ((mode (TF))); + +/* Make sure that we don't accidentaly use any normal C language built-in + type names in the first part of this file. Instead we want to use *only* + the type names defined above. The following macro definitions insure + that if we *do* accidently use soem normal C language built-in type name, + we will get a syntax error. */ + +#define char bogus_type +#define short bogus_type +#define int bogus_type +#define long bogus_type +#define unsigned bogus_type +#define float bogus_type +#define double bogus_type + +#define SI_TYPE_SIZE (sizeof (SItype) * BITS_PER_UNIT) + +/* DIstructs are pairs of SItype values in the order determined by WORDS_BIG_ENDIAN. */ #if WORDS_BIG_ENDIAN - struct longlong {long high, low;}; + struct DIstruct {SItype high, low;}; #else - struct longlong {long low, high;}; + struct DIstruct {SItype low, high;}; #endif -/* We need this union to unpack/pack longlongs, since we don't have - any arithmetic yet. Incoming long long parameters are stored - into the `ll' field, and the unpacked result is read from the struct - longlong. */ +/* We need this union to unpack/pack DImode values, since we don't have + any arithmetic yet. Incoming DImode parameters are stored into the + `ll' field, and the unpacked result is read from the struct `s'. */ typedef union { - struct longlong s; - long long ll; -} long_long; + struct DIstruct s; + DItype ll; +} DIunion; #if defined (L_udivmoddi4) || defined (L_muldi3) @@ -74,55 +98,55 @@ typedef union #endif /* udiv or mul */ -extern long long __fixunssfdi (float a); -extern long long __fixunsdfdi (double a); +extern DItype __fixunssfdi (SFtype a); +extern DItype __fixunsdfdi (DFtype a); #if defined (L_negdi2) || defined (L_divdi3) || defined (L_moddi3) #if defined (L_divdi3) || defined (L_moddi3) static inline #endif -long long +DItype __negdi2 (u) - long long u; + DItype u; { - long_long w; - long_long uu; + DIunion w; + DIunion uu; uu.ll = u; w.s.low = -uu.s.low; - w.s.high = -uu.s.high - ((unsigned long) w.s.low > 0); + w.s.high = -uu.s.high - ((USItype) w.s.low > 0); return w.ll; } #endif #ifdef L_lshldi3 -long long +DItype __lshldi3 (u, b) - long long u; - int b; + DItype u; + SItype b; { - long_long w; - long bm; - long_long uu; + DIunion w; + SItype bm; + DIunion uu; if (b == 0) return u; uu.ll = u; - bm = (sizeof (long) * BITS_PER_UNIT) - b; + bm = (sizeof (SItype) * BITS_PER_UNIT) - b; if (bm <= 0) { w.s.low = 0; - w.s.high = (unsigned long)uu.s.low << -bm; + w.s.high = (USItype)uu.s.low << -bm; } else { - unsigned long carries = (unsigned long)uu.s.low >> bm; - w.s.low = (unsigned long)uu.s.low << b; - w.s.high = ((unsigned long)uu.s.high << b) | carries; + USItype carries = (USItype)uu.s.low >> bm; + w.s.low = (USItype)uu.s.low << b; + w.s.high = ((USItype)uu.s.high << b) | carries; } return w.ll; @@ -130,31 +154,31 @@ __lshldi3 (u, b) #endif #ifdef L_lshrdi3 -long long +DItype __lshrdi3 (u, b) - long long u; - int b; + DItype u; + SItype b; { - long_long w; - long bm; - long_long uu; + DIunion w; + SItype bm; + DIunion uu; if (b == 0) return u; uu.ll = u; - bm = (sizeof (long) * BITS_PER_UNIT) - b; + bm = (sizeof (SItype) * BITS_PER_UNIT) - b; if (bm <= 0) { w.s.high = 0; - w.s.low = (unsigned long)uu.s.high >> -bm; + w.s.low = (USItype)uu.s.high >> -bm; } else { - unsigned long carries = (unsigned long)uu.s.high << bm; - w.s.high = (unsigned long)uu.s.high >> b; - w.s.low = ((unsigned long)uu.s.low >> b) | carries; + USItype carries = (USItype)uu.s.high << bm; + w.s.high = (USItype)uu.s.high >> b; + w.s.low = ((USItype)uu.s.low >> b) | carries; } return w.ll; @@ -162,31 +186,31 @@ __lshrdi3 (u, b) #endif #ifdef L_ashldi3 -long long +DItype __ashldi3 (u, b) - long long u; - int b; + DItype u; + SItype b; { - long_long w; - long bm; - long_long uu; + DIunion w; + SItype bm; + DIunion uu; if (b == 0) return u; uu.ll = u; - bm = (sizeof (long) * BITS_PER_UNIT) - b; + bm = (sizeof (SItype) * BITS_PER_UNIT) - b; if (bm <= 0) { w.s.low = 0; - w.s.high = (unsigned long)uu.s.low << -bm; + w.s.high = (USItype)uu.s.low << -bm; } else { - unsigned long carries = (unsigned long)uu.s.low >> bm; - w.s.low = (unsigned long)uu.s.low << b; - w.s.high = ((unsigned long)uu.s.high << b) | carries; + USItype carries = (USItype)uu.s.low >> bm; + w.s.low = (USItype)uu.s.low << b; + w.s.high = ((USItype)uu.s.high << b) | carries; } return w.ll; @@ -194,32 +218,32 @@ __ashldi3 (u, b) #endif #ifdef L_ashrdi3 -long long +DItype __ashrdi3 (u, b) - long long u; - int b; + DItype u; + SItype b; { - long_long w; - long bm; - long_long uu; + DIunion w; + SItype bm; + DIunion uu; if (b == 0) return u; uu.ll = u; - bm = (sizeof (long) * BITS_PER_UNIT) - b; + bm = (sizeof (SItype) * BITS_PER_UNIT) - b; if (bm <= 0) { /* w.s.high = 1..1 or 0..0 */ - w.s.high = uu.s.high >> (sizeof (long) * BITS_PER_UNIT - 1); + w.s.high = uu.s.high >> (sizeof (SItype) * BITS_PER_UNIT - 1); w.s.low = uu.s.high >> -bm; } else { - unsigned long carries = (unsigned long)uu.s.high << bm; + USItype carries = (USItype)uu.s.high << bm; w.s.high = uu.s.high >> b; - w.s.low = ((unsigned long)uu.s.low >> b) | carries; + w.s.low = ((USItype)uu.s.low >> b) | carries; } return w.ll; @@ -227,26 +251,26 @@ __ashrdi3 (u, b) #endif #ifdef L_muldi3 -long long +DItype __muldi3 (u, v) - long long u, v; + DItype u, v; { - long_long w; - long_long uu, vv; + DIunion w; + DIunion uu, vv; uu.ll = u, vv.ll = v; w.ll = __umulsidi3 (uu.s.low, vv.s.low); - w.s.high += ((unsigned long) uu.s.low * (unsigned long) vv.s.high - + (unsigned long) uu.s.high * (unsigned long) vv.s.low); + w.s.high += ((USItype) uu.s.low * (USItype) vv.s.high + + (USItype) uu.s.high * (USItype) vv.s.low); return w.ll; } #endif #ifdef L_udivmoddi4 -static const unsigned char __clz_tab[] = +static const UQItype __clz_tab[] = { 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, 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, @@ -258,17 +282,17 @@ static const unsigned char __clz_tab[] = 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, }; -unsigned long long +UDItype __udivmoddi4 (n, d, rp) - unsigned long long n, d; - unsigned long long int *rp; + UDItype n, d; + UDItype *rp; { - long_long ww; - long_long nn, dd; - long_long rr; - unsigned long d0, d1, n0, n1, n2; - unsigned long q0, q1; - unsigned b, bm; + DIunion ww; + DIunion nn, dd; + DIunion rr; + USItype d0, d1, n0, n1, n2; + USItype q0, q1; + USItype b, bm; nn.ll = n; dd.ll = d; @@ -327,7 +351,7 @@ __udivmoddi4 (n, d, rp) denominator set. */ d0 = d0 << bm; - n1 = (n1 << bm) | (n0 >> (LONG_TYPE_SIZE - bm)); + n1 = (n1 << bm) | (n0 >> (SI_TYPE_SIZE - bm)); n0 = n0 << bm; } @@ -352,7 +376,7 @@ __udivmoddi4 (n, d, rp) leading quotient digit q1 = 1). This special case is necessary, not an optimization. - (Shifts counts of LONG_TYPE_SIZE are undefined.) */ + (Shifts counts of SI_TYPE_SIZE are undefined.) */ n1 -= d0; q1 = 1; @@ -361,7 +385,7 @@ __udivmoddi4 (n, d, rp) { /* Normalize. */ - b = LONG_TYPE_SIZE - bm; + b = SI_TYPE_SIZE - bm; d0 = d0 << bm; n2 = n1 >> b; @@ -438,10 +462,10 @@ __udivmoddi4 (n, d, rp) } else { - unsigned long m1, m0; + USItype m1, m0; /* Normalize. */ - b = LONG_TYPE_SIZE - bm; + b = SI_TYPE_SIZE - bm; d1 = (d1 << bm) | (d0 >> b); d0 = d0 << bm; @@ -479,14 +503,14 @@ __udivmoddi4 (n, d, rp) #endif #ifdef L_divdi3 -unsigned long long __udivmoddi4 (); -long long +UDItype __udivmoddi4 (); +DItype __divdi3 (u, v) - long long u, v; + DItype u, v; { - int c = 0; - long_long uu, vv; - long long w; + SItype c = 0; + DIunion uu, vv; + DItype w; uu.ll = u; vv.ll = v; @@ -498,7 +522,7 @@ __divdi3 (u, v) c = ~c, vv.ll = __negdi2 (vv.ll); - w = __udivmoddi4 (uu.ll, vv.ll, (unsigned long long *) 0); + w = __udivmoddi4 (uu.ll, vv.ll, (UDItype *) 0); if (c) w = __negdi2 (w); @@ -507,14 +531,14 @@ __divdi3 (u, v) #endif #ifdef L_moddi3 -unsigned long long __udivmoddi4 (); -long long +UDItype __udivmoddi4 (); +DItype __moddi3 (u, v) - long long u, v; + DItype u, v; { - int c = 0; - long_long uu, vv; - long long w; + SItype c = 0; + DIunion uu, vv; + DItype w; uu.ll = u; vv.ll = v; @@ -534,12 +558,12 @@ __moddi3 (u, v) #endif #ifdef L_umoddi3 -unsigned long long __udivmoddi4 (); -unsigned long long +UDItype __udivmoddi4 (); +UDItype __umoddi3 (u, v) - unsigned long long u, v; + UDItype u, v; { - long long w; + DItype w; (void) __udivmoddi4 (u, v, &w); @@ -548,21 +572,21 @@ __umoddi3 (u, v) #endif #ifdef L_udivdi3 -unsigned long long __udivmoddi4 (); -unsigned long long +UDItype __udivmoddi4 (); +UDItype __udivdi3 (n, d) - unsigned long long n, d; + UDItype n, d; { - return __udivmoddi4 (n, d, (unsigned long long *) 0); + return __udivmoddi4 (n, d, (UDItype *) 0); } #endif #ifdef L_cmpdi2 SItype __cmpdi2 (a, b) - long long a, b; + DItype a, b; { - long_long au, bu; + DIunion au, bu; au.ll = a, bu.ll = b; @@ -570,9 +594,9 @@ __cmpdi2 (a, b) return 0; else if (au.s.high > bu.s.high) return 2; - if ((unsigned long) au.s.low < (unsigned long) bu.s.low) + if ((USItype) au.s.low < (USItype) bu.s.low) return 0; - else if ((unsigned long) au.s.low > (unsigned long) bu.s.low) + else if ((USItype) au.s.low > (USItype) bu.s.low) return 2; return 1; } @@ -581,61 +605,105 @@ __cmpdi2 (a, b) #ifdef L_ucmpdi2 SItype __ucmpdi2 (a, b) - long long a, b; + DItype a, b; { - long_long au, bu; + DIunion au, bu; au.ll = a, bu.ll = b; - if ((unsigned long) au.s.high < (unsigned long) bu.s.high) + if ((USItype) au.s.high < (USItype) bu.s.high) return 0; - else if ((unsigned long) au.s.high > (unsigned long) bu.s.high) + else if ((USItype) au.s.high > (USItype) bu.s.high) return 2; - if ((unsigned long) au.s.low < (unsigned long) bu.s.low) + if ((USItype) au.s.low < (USItype) bu.s.low) return 0; - else if ((unsigned long) au.s.low > (unsigned long) bu.s.low) + else if ((USItype) au.s.low > (USItype) bu.s.low) return 2; return 1; } #endif +#if defined(L_fixunstfdi) && (LONG_DOUBLE_TYPE_SIZE == 128) +#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT) +#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE) + +DItype +__fixunstfdi (a) + TFtype a; +{ + TFtype b; + UDItype v; + + if (a < 0) + return 0; + + /* Compute high word of result, as a flonum. */ + b = (a / HIGH_WORD_COEFF); + /* Convert that to fixed (but not to DItype!), + and shift it into the high word. */ + v = (USItype) b; + v <<= WORD_SIZE; + /* Remove high part from the TFtype, leaving the low part as flonum. */ + a -= (TFtype)v; + /* Convert that to fixed (but not to DItype!) and add it in. + Sometimes A comes out negative. This is significant, since + A has more bits than a long int does. */ + if (a < 0) + v -= (USItype) (- a); + else + v += (USItype) a; + return v; +} +#endif + +#if defined(L_fixtfdi) && (LONG_DOUBLE_TYPE_SIZE == 128) +DItype +__fixtfdi (a) + TFtype a; +{ + if (a < 0) + return - __fixunstfdi (-a); + return __fixunstfdi (a); +} +#endif + #ifdef L_fixunsdfdi -#define WORD_SIZE (sizeof (long) * BITS_PER_UNIT) -#define HIGH_WORD_COEFF (((long long) 1) << WORD_SIZE) +#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT) +#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE) -long long +DItype __fixunsdfdi (a) - double a; + DFtype a; { - double b; - unsigned long long v; + DFtype b; + UDItype v; if (a < 0) return 0; /* Compute high word of result, as a flonum. */ b = (a / HIGH_WORD_COEFF); - /* Convert that to fixed (but not to long long!), + /* Convert that to fixed (but not to DItype!), and shift it into the high word. */ - v = (unsigned long int) b; + v = (USItype) b; v <<= WORD_SIZE; - /* Remove high part from the double, leaving the low part as flonum. */ - a -= (double)v; - /* Convert that to fixed (but not to long long!) and add it in. + /* Remove high part from the DFtype, leaving the low part as flonum. */ + a -= (DFtype)v; + /* Convert that to fixed (but not to DItype!) and add it in. Sometimes A comes out negative. This is significant, since A has more bits than a long int does. */ if (a < 0) - v -= (unsigned long int) (- a); + v -= (USItype) (- a); else - v += (unsigned long int) a; + v += (USItype) a; return v; } #endif #ifdef L_fixdfdi -long long +DItype __fixdfdi (a) - double a; + DFtype a; { if (a < 0) return - __fixunsdfdi (-a); @@ -644,44 +712,44 @@ __fixdfdi (a) #endif #ifdef L_fixunssfdi -#define WORD_SIZE (sizeof (long) * BITS_PER_UNIT) -#define HIGH_WORD_COEFF (((long long) 1) << WORD_SIZE) +#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT) +#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE) -long long -__fixunssfdi (float original_a) +DItype +__fixunssfdi (SFtype original_a) { - /* Convert the float to a double, because that is surely not going + /* Convert the SFtype to a DFtype, because that is surely not going to lose any bits. Some day someone else can write a faster version - that avoids converting to double, and verify it really works right. */ - double a = original_a; - double b; - unsigned long long v; + that avoids converting to DFtype, and verify it really works right. */ + DFtype a = original_a; + DFtype b; + UDItype v; if (a < 0) return 0; /* Compute high word of result, as a flonum. */ b = (a / HIGH_WORD_COEFF); - /* Convert that to fixed (but not to long long!), + /* Convert that to fixed (but not to DItype!), and shift it into the high word. */ - v = (unsigned long int) b; + v = (USItype) b; v <<= WORD_SIZE; - /* Remove high part from the double, leaving the low part as flonum. */ - a -= (double)v; - /* Convert that to fixed (but not to long long!) and add it in. + /* Remove high part from the DFtype, leaving the low part as flonum. */ + a -= (DFtype)v; + /* Convert that to fixed (but not to DItype!) and add it in. Sometimes A comes out negative. This is significant, since A has more bits than a long int does. */ if (a < 0) - v -= (unsigned long int) (- a); + v -= (USItype) (- a); else - v += (unsigned long int) a; + v += (USItype) a; return v; } #endif #ifdef L_fixsfdi -long long -__fixsfdi (float a) +DItype +__fixsfdi (SFtype a) { if (a < 0) return - __fixunssfdi (-a); @@ -689,49 +757,73 @@ __fixsfdi (float a) } #endif +#if defined(L_floatditf) && (LONG_DOUBLE_TYPE_SIZE == 128) +#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT) +#define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2)) +#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE) + +TFtype +__floatditf (u) + DItype u; +{ + TFtype d; + SItype negate = 0; + + if (u < 0) + u = -u, negate = 1; + + d = (USItype) (u >> WORD_SIZE); + d *= HIGH_HALFWORD_COEFF; + d *= HIGH_HALFWORD_COEFF; + d += (USItype) (u & (HIGH_WORD_COEFF - 1)); + + return (negate ? -d : d); +} +#endif + #ifdef L_floatdidf -#define WORD_SIZE (sizeof (long) * BITS_PER_UNIT) -#define HIGH_HALFWORD_COEFF (((long long) 1) << (WORD_SIZE / 2)) -#define HIGH_WORD_COEFF (((long long) 1) << WORD_SIZE) +#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT) +#define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2)) +#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE) -double +DFtype __floatdidf (u) - long long u; + DItype u; { - double d; - int negate = 0; + DFtype d; + SItype negate = 0; if (u < 0) u = -u, negate = 1; - d = (unsigned int) (u >> WORD_SIZE); + d = (USItype) (u >> WORD_SIZE); d *= HIGH_HALFWORD_COEFF; d *= HIGH_HALFWORD_COEFF; - d += (unsigned int) (u & (HIGH_WORD_COEFF - 1)); + d += (USItype) (u & (HIGH_WORD_COEFF - 1)); return (negate ? -d : d); } #endif #ifdef L_floatdisf -#define WORD_SIZE (sizeof (long) * BITS_PER_UNIT) -#define HIGH_HALFWORD_COEFF (((long long) 1) << (WORD_SIZE / 2)) -#define HIGH_WORD_COEFF (((long long) 1) << WORD_SIZE) +#define WORD_SIZE (sizeof (SItype) * BITS_PER_UNIT) +#define HIGH_HALFWORD_COEFF (((UDItype) 1) << (WORD_SIZE / 2)) +#define HIGH_WORD_COEFF (((UDItype) 1) << WORD_SIZE) -float +SFtype __floatdisf (u) - long long u; + DItype u; { - float f; - int negate = 0; + SFtype f; + SItype negate = 0; if (u < 0) u = -u, negate = 1; - f = (unsigned int) (u >> WORD_SIZE); + f = (USItype) (u >> WORD_SIZE); f *= HIGH_HALFWORD_COEFF; f *= HIGH_HALFWORD_COEFF; - f += (unsigned int) (u & (HIGH_WORD_COEFF - 1)); + f += (USItype) (u & (HIGH_WORD_COEFF - 1)); return (negate ? -f : f); } @@ -740,11 +832,11 @@ __floatdisf (u) #ifdef L_fixunsdfsi #include "limits.h" -unsigned SItype +USItype __fixunsdfsi (a) - double a; + DFtype a; { - if (a >= - (double) LONG_MIN) + if (a >= - (DFtype) LONG_MIN) return (SItype) (a + LONG_MIN) - LONG_MIN; return (SItype) a; } @@ -753,15 +845,32 @@ __fixunsdfsi (a) #ifdef L_fixunssfsi #include "limits.h" -unsigned SItype -__fixunssfsi (float a) +USItype +__fixunssfsi (SFtype a) { - if (a >= - (float) LONG_MIN) + if (a >= - (SFtype) LONG_MIN) return (SItype) (a + LONG_MIN) - LONG_MIN; return (SItype) a; } #endif +/* From here on down, the routines use normal data types. */ + +#define SItype bogus_type +#define USItype bogus_type +#define DItype bogus_type +#define UDItype bogus_type +#define SFtype bogus_type +#define DFtype bogus_type + +#undef char +#undef short +#undef int +#undef long +#undef unsigned +#undef float +#undef double + #ifdef L_varargs #ifdef __i860__ #if defined(__svr4__) || defined(__alliant__) -- 2.30.2