|
|
6693b3 |
2007-01-05 Jakub Jelinek <jakub@redhat.com>
|
|
|
6693b3 |
|
|
|
6693b3 |
PR c/30360
|
|
|
6693b3 |
* libgcc2.c (__divdc3): Compare c and d against 0.0 instead of
|
|
|
6693b3 |
denom against 0.0.
|
|
|
6693b3 |
|
|
|
6693b3 |
2005-11-22 Joseph S. Myers <joseph@codesourcery.com>
|
|
|
6693b3 |
|
|
|
6693b3 |
* libgcc-std.ver (GCC_4.2.0): New version.
|
|
|
6693b3 |
* libgcc2.c (__floatundixf, __floatunditf, __floatundidf,
|
|
|
6693b3 |
__floatundisf): New functions.
|
|
|
6693b3 |
* libgcc2.h (__floatundixf, __floatunditf, __floatundidf,
|
|
|
6693b3 |
__floatundisf): Declare.
|
|
|
6693b3 |
* mklibgcc.in (lib2funcs): Add _floatundidf, _floatundisf,
|
|
|
6693b3 |
_floatundixf, and _floatunditf.
|
|
|
6693b3 |
|
|
|
6693b3 |
2005-03-30 Fariborz Jahanian <fjahanian@apple.com>
|
|
|
6693b3 |
|
|
|
6693b3 |
* libgcc2.h (__powisf2, __powidf2, __powixf2, __powitf2): Change
|
|
|
6693b3 |
2nd argument type to int.
|
|
|
6693b3 |
* libgcc2.c: Change prototype of __powi* functions to use
|
|
|
6693b3 |
int.
|
|
|
6693b3 |
|
|
|
6693b3 |
2005-02-11 Richard Henderson <rth@redhat.com>
|
|
|
6693b3 |
|
|
|
6693b3 |
* libgcc2.c (__divsc3, __divdc3, __divxc3, __divtc3,
|
|
|
6693b3 |
__mulsc3, __muldc3, __mulxc3, __multc3): New.
|
|
|
6693b3 |
* libgcc2.h: Declare them.
|
|
|
6693b3 |
* libgcc-std.ver: Export them.
|
|
|
6693b3 |
* mklibgcc.in (lib2funcs): Build them.
|
|
|
6693b3 |
|
|
|
6693b3 |
2005-02-09 Richard Guenther <rguenth@gcc.gnu.org>
|
|
|
6693b3 |
|
|
|
6693b3 |
PR middle-end/19402
|
|
|
6693b3 |
* libgcc2.h: Add prototypes for __builtin_powi[lf].
|
|
|
6693b3 |
* libgcc2.c: Add __builtin_powi[lf] implementation.
|
|
|
6693b3 |
* mklibgcc.in: Add __builtin_powi[lf] to lib2funcs.
|
|
|
6693b3 |
|
|
|
6693b3 |
--- gcc/libgcc-std.ver.jj 2007-03-02 09:27:16.000000000 +0100
|
|
|
6693b3 |
+++ gcc/libgcc-std.ver 2007-03-02 10:32:27.000000000 +0100
|
|
|
6693b3 |
@@ -235,7 +235,39 @@ GCC_3.4.4 {
|
|
|
6693b3 |
__subvti3
|
|
|
6693b3 |
}
|
|
|
6693b3 |
|
|
|
6693b3 |
-%inherit GCC_4.2.0 GCC_3.4.4
|
|
|
6693b3 |
+%inherit GCC_4.0.0 GCC_3.4.4
|
|
|
6693b3 |
+GCC_4.0.0 {
|
|
|
6693b3 |
+ # libgcc2 __builtin_powi helpers.
|
|
|
6693b3 |
+ __powisf2
|
|
|
6693b3 |
+ __powidf2
|
|
|
6693b3 |
+ __powixf2
|
|
|
6693b3 |
+ __powitf2
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+ # c99 compliant complex arithmetic
|
|
|
6693b3 |
+ __divsc3
|
|
|
6693b3 |
+ __divdc3
|
|
|
6693b3 |
+ __divxc3
|
|
|
6693b3 |
+ __divtc3
|
|
|
6693b3 |
+ __mulsc3
|
|
|
6693b3 |
+ __muldc3
|
|
|
6693b3 |
+ __mulxc3
|
|
|
6693b3 |
+ __multc3
|
|
|
6693b3 |
+}
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+%inherit GCC_4.2.0 GCC_4.0.0
|
|
|
6693b3 |
GCC_4.2.0 {
|
|
|
6693b3 |
+ # unsigned-to-floating conversions
|
|
|
6693b3 |
+ __floatunsisf
|
|
|
6693b3 |
+ __floatunsidf
|
|
|
6693b3 |
+ __floatunsixf
|
|
|
6693b3 |
+ __floatunsitf
|
|
|
6693b3 |
+ __floatundidf
|
|
|
6693b3 |
+ __floatundisf
|
|
|
6693b3 |
+ __floatundixf
|
|
|
6693b3 |
+ __floatunditf
|
|
|
6693b3 |
+ __floatuntidf
|
|
|
6693b3 |
+ __floatuntisf
|
|
|
6693b3 |
+ __floatuntixf
|
|
|
6693b3 |
+ __floatuntitf
|
|
|
6693b3 |
_Unwind_GetIPInfo
|
|
|
6693b3 |
}
|
|
|
6693b3 |
--- gcc/libgcc2.h.jj 2006-10-05 00:37:01.000000000 +0200
|
|
|
6693b3 |
+++ gcc/libgcc2.h 2007-03-02 11:26:31.000000000 +0100
|
|
|
6693b3 |
@@ -88,12 +88,16 @@ typedef unsigned int UTItype __attribute
|
|
|
6693b3 |
|
|
|
6693b3 |
typedef float SFtype __attribute__ ((mode (SF)));
|
|
|
6693b3 |
typedef float DFtype __attribute__ ((mode (DF)));
|
|
|
6693b3 |
+typedef _Complex float SCtype;
|
|
|
6693b3 |
+typedef _Complex double DCtype;
|
|
|
6693b3 |
|
|
|
6693b3 |
#if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
|
|
|
6693b3 |
typedef float XFtype __attribute__ ((mode (XF)));
|
|
|
6693b3 |
+typedef _Complex long double XCtype;
|
|
|
6693b3 |
#endif
|
|
|
6693b3 |
#if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128
|
|
|
6693b3 |
typedef float TFtype __attribute__ ((mode (TF)));
|
|
|
6693b3 |
+typedef _Complex long double TCtype;
|
|
|
6693b3 |
#endif
|
|
|
6693b3 |
|
|
|
6693b3 |
#else /* BITS_PER_UNIT != 8 */
|
|
|
6693b3 |
@@ -216,6 +220,10 @@ typedef int word_type __attribute__ ((mo
|
|
|
6693b3 |
#define __floatditf __NDW(float,tf)
|
|
|
6693b3 |
#define __floatdidf __NDW(float,df)
|
|
|
6693b3 |
#define __floatdisf __NDW(float,sf)
|
|
|
6693b3 |
+#define __floatundixf __NDW(floatun,xf)
|
|
|
6693b3 |
+#define __floatunditf __NDW(floatun,tf)
|
|
|
6693b3 |
+#define __floatundidf __NDW(floatun,df)
|
|
|
6693b3 |
+#define __floatundisf __NDW(floatun,sf)
|
|
|
6693b3 |
#define __fixunsxfSI __NW(fixunsxf,)
|
|
|
6693b3 |
#define __fixunstfSI __NW(fixunstf,)
|
|
|
6693b3 |
#define __fixunsdfSI __NW(fixunsdf,)
|
|
|
6693b3 |
@@ -293,27 +301,47 @@ extern SItype __negvsi2 (SItype);
|
|
|
6693b3 |
#endif /* COMPAT_SIMODE_TRAPPING_ARITHMETIC */
|
|
|
6693b3 |
|
|
|
6693b3 |
#if BITS_PER_UNIT == 8
|
|
|
6693b3 |
+#undef int
|
|
|
6693b3 |
extern DWtype __fixdfdi (DFtype);
|
|
|
6693b3 |
extern DWtype __fixsfdi (SFtype);
|
|
|
6693b3 |
extern DFtype __floatdidf (DWtype);
|
|
|
6693b3 |
extern SFtype __floatdisf (DWtype);
|
|
|
6693b3 |
+extern DFtype __floatundidf (UDWtype);
|
|
|
6693b3 |
+extern SFtype __floatundisf (UDWtype);
|
|
|
6693b3 |
extern UWtype __fixunsdfSI (DFtype);
|
|
|
6693b3 |
extern UWtype __fixunssfSI (SFtype);
|
|
|
6693b3 |
extern DWtype __fixunsdfDI (DFtype);
|
|
|
6693b3 |
extern DWtype __fixunssfDI (SFtype);
|
|
|
6693b3 |
+extern SFtype __powisf2 (SFtype, int);
|
|
|
6693b3 |
+extern DFtype __powidf2 (DFtype, int);
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+extern SCtype __divsc3 (SFtype, SFtype, SFtype, SFtype);
|
|
|
6693b3 |
+extern SCtype __mulsc3 (SFtype, SFtype, SFtype, SFtype);
|
|
|
6693b3 |
+extern DCtype __divdc3 (DFtype, DFtype, DFtype, DFtype);
|
|
|
6693b3 |
+extern DCtype __muldc3 (DFtype, DFtype, DFtype, DFtype);
|
|
|
6693b3 |
|
|
|
6693b3 |
#if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
|
|
|
6693b3 |
extern DWtype __fixxfdi (XFtype);
|
|
|
6693b3 |
extern DWtype __fixunsxfDI (XFtype);
|
|
|
6693b3 |
extern XFtype __floatdixf (DWtype);
|
|
|
6693b3 |
+extern XFtype __floatundixf (UDWtype);
|
|
|
6693b3 |
extern UWtype __fixunsxfSI (XFtype);
|
|
|
6693b3 |
+extern XFtype __powixf2 (XFtype, int);
|
|
|
6693b3 |
+extern XCtype __divxc3 (XFtype, XFtype, XFtype, XFtype);
|
|
|
6693b3 |
+extern XCtype __mulxc3 (XFtype, XFtype, XFtype, XFtype);
|
|
|
6693b3 |
#endif
|
|
|
6693b3 |
|
|
|
6693b3 |
#if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128
|
|
|
6693b3 |
extern DWtype __fixunstfDI (TFtype);
|
|
|
6693b3 |
extern DWtype __fixtfdi (TFtype);
|
|
|
6693b3 |
extern TFtype __floatditf (DWtype);
|
|
|
6693b3 |
+extern TFtype __floatunditf (UDWtype);
|
|
|
6693b3 |
+extern TFtype __powitf2 (TFtype, int);
|
|
|
6693b3 |
+extern TCtype __divtc3 (TFtype, TFtype, TFtype, TFtype);
|
|
|
6693b3 |
+extern TCtype __multc3 (TFtype, TFtype, TFtype, TFtype);
|
|
|
6693b3 |
#endif
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+#define int bogus_type
|
|
|
6693b3 |
#endif /* BITS_PER_UNIT == 8 */
|
|
|
6693b3 |
|
|
|
6693b3 |
/* DWstructs are pairs of Wtype values in the order determined by
|
|
|
6693b3 |
--- gcc/mklibgcc.in.jj 2006-10-05 00:37:01.000000000 +0200
|
|
|
6693b3 |
+++ gcc/mklibgcc.in 2007-03-02 10:31:58.000000000 +0100
|
|
|
6693b3 |
@@ -58,7 +58,9 @@ lib2funcs='_muldi3 _negdi2 _lshrdi3 _ash
|
|
|
6693b3 |
_enable_execute_stack _trampoline __main _absvsi2 _absvdi2 _addvsi3
|
|
|
6693b3 |
_addvdi3 _subvsi3 _subvdi3 _mulvsi3 _mulvdi3 _negvsi2 _negvdi2 _ctors
|
|
|
6693b3 |
_ffssi2 _ffsdi2 _clz _clzsi2 _clzdi2 _ctzsi2 _ctzdi2 _popcount_tab
|
|
|
6693b3 |
- _popcountsi2 _popcountdi2 _paritysi2 _paritydi2'
|
|
|
6693b3 |
+ _popcountsi2 _popcountdi2 _paritysi2 _paritydi2 _powisf2 _powidf2
|
|
|
6693b3 |
+ _powixf2 _powitf2 _mulsc3 _muldc3 _mulxc3 _multc3 _divsc3 _divdc3
|
|
|
6693b3 |
+ _divxc3 _divtc3 _floatundidf _floatundisf _floatundixf _floatunditf'
|
|
|
6693b3 |
|
|
|
6693b3 |
# Disable SHLIB_LINK if shared libgcc not enabled.
|
|
|
6693b3 |
if [ "@enable_shared@" = "no" ]; then
|
|
|
6693b3 |
--- gcc/libgcc2.c.jj 2006-10-05 00:37:01.000000000 +0200
|
|
|
6693b3 |
+++ gcc/libgcc2.c 2007-03-02 10:58:07.000000000 +0100
|
|
|
6693b3 |
@@ -1331,6 +1331,23 @@ __floatdixf (DWtype u)
|
|
|
6693b3 |
}
|
|
|
6693b3 |
#endif
|
|
|
6693b3 |
|
|
|
6693b3 |
+#if defined(L_floatundixf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96)
|
|
|
6693b3 |
+#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
|
|
|
6693b3 |
+#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
|
|
|
6693b3 |
+#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+XFtype
|
|
|
6693b3 |
+__floatundixf (UDWtype u)
|
|
|
6693b3 |
+{
|
|
|
6693b3 |
+ XFtype d = (UWtype) (u >> WORD_SIZE);
|
|
|
6693b3 |
+ d *= HIGH_HALFWORD_COEFF;
|
|
|
6693b3 |
+ d *= HIGH_HALFWORD_COEFF;
|
|
|
6693b3 |
+ d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+ return d;
|
|
|
6693b3 |
+}
|
|
|
6693b3 |
+#endif
|
|
|
6693b3 |
+
|
|
|
6693b3 |
#if defined(L_floatditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
|
|
|
6693b3 |
#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
|
|
|
6693b3 |
#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
|
|
|
6693b3 |
@@ -1348,6 +1365,23 @@ __floatditf (DWtype u)
|
|
|
6693b3 |
}
|
|
|
6693b3 |
#endif
|
|
|
6693b3 |
|
|
|
6693b3 |
+#if defined(L_floatunditf) && (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
|
|
|
6693b3 |
+#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
|
|
|
6693b3 |
+#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
|
|
|
6693b3 |
+#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+TFtype
|
|
|
6693b3 |
+__floatunditf (UDWtype u)
|
|
|
6693b3 |
+{
|
|
|
6693b3 |
+ TFtype d = (UWtype) (u >> WORD_SIZE);
|
|
|
6693b3 |
+ d *= HIGH_HALFWORD_COEFF;
|
|
|
6693b3 |
+ d *= HIGH_HALFWORD_COEFF;
|
|
|
6693b3 |
+ d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+ return d;
|
|
|
6693b3 |
+}
|
|
|
6693b3 |
+#endif
|
|
|
6693b3 |
+
|
|
|
6693b3 |
#ifdef L_floatdidf
|
|
|
6693b3 |
#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
|
|
|
6693b3 |
#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
|
|
|
6693b3 |
@@ -1365,6 +1399,23 @@ __floatdidf (DWtype u)
|
|
|
6693b3 |
}
|
|
|
6693b3 |
#endif
|
|
|
6693b3 |
|
|
|
6693b3 |
+#ifdef L_floatundidf
|
|
|
6693b3 |
+#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
|
|
|
6693b3 |
+#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
|
|
|
6693b3 |
+#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+DFtype
|
|
|
6693b3 |
+__floatundidf (UDWtype u)
|
|
|
6693b3 |
+{
|
|
|
6693b3 |
+ DFtype d = (UWtype) (u >> WORD_SIZE);
|
|
|
6693b3 |
+ d *= HIGH_HALFWORD_COEFF;
|
|
|
6693b3 |
+ d *= HIGH_HALFWORD_COEFF;
|
|
|
6693b3 |
+ d += (UWtype) (u & (HIGH_WORD_COEFF - 1));
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+ return d;
|
|
|
6693b3 |
+}
|
|
|
6693b3 |
+#endif
|
|
|
6693b3 |
+
|
|
|
6693b3 |
#ifdef L_floatdisf
|
|
|
6693b3 |
#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
|
|
|
6693b3 |
#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
|
|
|
6693b3 |
@@ -1409,6 +1460,49 @@ __floatdisf (DWtype u)
|
|
|
6693b3 |
}
|
|
|
6693b3 |
#endif
|
|
|
6693b3 |
|
|
|
6693b3 |
+#ifdef L_floatundisf
|
|
|
6693b3 |
+#define WORD_SIZE (sizeof (Wtype) * BITS_PER_UNIT)
|
|
|
6693b3 |
+#define HIGH_HALFWORD_COEFF (((UDWtype) 1) << (WORD_SIZE / 2))
|
|
|
6693b3 |
+#define HIGH_WORD_COEFF (((UDWtype) 1) << WORD_SIZE)
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+#define DI_SIZE (sizeof (DWtype) * BITS_PER_UNIT)
|
|
|
6693b3 |
+#define DF_SIZE DBL_MANT_DIG
|
|
|
6693b3 |
+#define SF_SIZE FLT_MANT_DIG
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+SFtype
|
|
|
6693b3 |
+__floatundisf (UDWtype u)
|
|
|
6693b3 |
+{
|
|
|
6693b3 |
+ /* Protect against double-rounding error.
|
|
|
6693b3 |
+ Represent any low-order bits, that might be truncated in DFmode,
|
|
|
6693b3 |
+ by a bit that won't be lost. The bit can go in anywhere below the
|
|
|
6693b3 |
+ rounding position of the SFmode. A fixed mask and bit position
|
|
|
6693b3 |
+ handles all usual configurations. It doesn't handle the case
|
|
|
6693b3 |
+ of 128-bit DImode, however. */
|
|
|
6693b3 |
+ if (DF_SIZE < DI_SIZE
|
|
|
6693b3 |
+ && DF_SIZE > (DI_SIZE - DF_SIZE + SF_SIZE))
|
|
|
6693b3 |
+ {
|
|
|
6693b3 |
+#define REP_BIT ((UDWtype) 1 << (DI_SIZE - DF_SIZE))
|
|
|
6693b3 |
+ if (u >= ((UDWtype) 1 << DF_SIZE))
|
|
|
6693b3 |
+ {
|
|
|
6693b3 |
+ if ((UDWtype) u & (REP_BIT - 1))
|
|
|
6693b3 |
+ {
|
|
|
6693b3 |
+ u &= ~ (REP_BIT - 1);
|
|
|
6693b3 |
+ u |= REP_BIT;
|
|
|
6693b3 |
+ }
|
|
|
6693b3 |
+ }
|
|
|
6693b3 |
+ }
|
|
|
6693b3 |
+ /* Do the calculation in DFmode
|
|
|
6693b3 |
+ so that we don't lose any of the precision of the high word
|
|
|
6693b3 |
+ while multiplying it. */
|
|
|
6693b3 |
+ DFtype f = (UWtype) (u >> WORD_SIZE);
|
|
|
6693b3 |
+ f *= HIGH_HALFWORD_COEFF;
|
|
|
6693b3 |
+ f *= HIGH_HALFWORD_COEFF;
|
|
|
6693b3 |
+ f += (UWtype) (u & (HIGH_WORD_COEFF - 1));
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+ return (SFtype) f;
|
|
|
6693b3 |
+}
|
|
|
6693b3 |
+#endif
|
|
|
6693b3 |
+
|
|
|
6693b3 |
#if defined(L_fixunsxfsi) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96
|
|
|
6693b3 |
/* Reenable the normal types, in case limits.h needs them. */
|
|
|
6693b3 |
#undef char
|
|
|
6693b3 |
@@ -1475,6 +1569,246 @@ __fixunssfSI (SFtype a)
|
|
|
6693b3 |
}
|
|
|
6693b3 |
#endif
|
|
|
6693b3 |
|
|
|
6693b3 |
+/* Integer power helper used from __builtin_powi for non-constant
|
|
|
6693b3 |
+ exponents. */
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+#if defined(L_powisf2) || defined(L_powidf2) \
|
|
|
6693b3 |
+ || (defined(L_powixf2) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96) \
|
|
|
6693b3 |
+ || (defined(L_powitf2) && LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128)
|
|
|
6693b3 |
+# if defined(L_powisf2)
|
|
|
6693b3 |
+# define TYPE SFtype
|
|
|
6693b3 |
+# define NAME __powisf2
|
|
|
6693b3 |
+# elif defined(L_powidf2)
|
|
|
6693b3 |
+# define TYPE DFtype
|
|
|
6693b3 |
+# define NAME __powidf2
|
|
|
6693b3 |
+# elif defined(L_powixf2)
|
|
|
6693b3 |
+# define TYPE XFtype
|
|
|
6693b3 |
+# define NAME __powixf2
|
|
|
6693b3 |
+# elif defined(L_powitf2)
|
|
|
6693b3 |
+# define TYPE TFtype
|
|
|
6693b3 |
+# define NAME __powitf2
|
|
|
6693b3 |
+# endif
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+#undef int
|
|
|
6693b3 |
+#undef unsigned
|
|
|
6693b3 |
+TYPE
|
|
|
6693b3 |
+NAME (TYPE x, int m)
|
|
|
6693b3 |
+{
|
|
|
6693b3 |
+ unsigned int n = m < 0 ? -m : m;
|
|
|
6693b3 |
+ TYPE y = n % 2 ? x : 1;
|
|
|
6693b3 |
+ while (n >>= 1)
|
|
|
6693b3 |
+ {
|
|
|
6693b3 |
+ x = x * x;
|
|
|
6693b3 |
+ if (n % 2)
|
|
|
6693b3 |
+ y = y * x;
|
|
|
6693b3 |
+ }
|
|
|
6693b3 |
+ return m < 0 ? 1/y : y;
|
|
|
6693b3 |
+}
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+#endif
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+#if defined(L_mulsc3) || defined(L_divsc3) \
|
|
|
6693b3 |
+ || defined(L_muldc3) || defined(L_divdc3) \
|
|
|
6693b3 |
+ || (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 96 \
|
|
|
6693b3 |
+ && (defined(L_mulxc3) || defined(L_divxc3))) \
|
|
|
6693b3 |
+ || (LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 128 \
|
|
|
6693b3 |
+ && (defined(L_multc3) || defined(L_divtc3)))
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+#undef float
|
|
|
6693b3 |
+#undef double
|
|
|
6693b3 |
+#undef long
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+#if defined(L_mulsc3) || defined(L_divsc3)
|
|
|
6693b3 |
+# define MTYPE SFtype
|
|
|
6693b3 |
+# define CTYPE SCtype
|
|
|
6693b3 |
+# define MODE sc
|
|
|
6693b3 |
+# define CEXT f
|
|
|
6693b3 |
+# define NOTRUNC __FLT_EVAL_METHOD__ == 0
|
|
|
6693b3 |
+#elif defined(L_muldc3) || defined(L_divdc3)
|
|
|
6693b3 |
+# define MTYPE DFtype
|
|
|
6693b3 |
+# define CTYPE DCtype
|
|
|
6693b3 |
+# define MODE dc
|
|
|
6693b3 |
+# if LIBGCC2_LONG_DOUBLE_TYPE_SIZE == 64
|
|
|
6693b3 |
+# define CEXT l
|
|
|
6693b3 |
+# define NOTRUNC 1
|
|
|
6693b3 |
+# else
|
|
|
6693b3 |
+# define CEXT
|
|
|
6693b3 |
+# define NOTRUNC __FLT_EVAL_METHOD__ == 0 || __FLT_EVAL_METHOD__ == 1
|
|
|
6693b3 |
+# endif
|
|
|
6693b3 |
+#elif defined(L_mulxc3) || defined(L_divxc3)
|
|
|
6693b3 |
+# define MTYPE XFtype
|
|
|
6693b3 |
+# define CTYPE XCtype
|
|
|
6693b3 |
+# define MODE xc
|
|
|
6693b3 |
+# define CEXT l
|
|
|
6693b3 |
+# define NOTRUNC 1
|
|
|
6693b3 |
+#elif defined(L_multc3) || defined(L_divtc3)
|
|
|
6693b3 |
+# define MTYPE TFtype
|
|
|
6693b3 |
+# define CTYPE TCtype
|
|
|
6693b3 |
+# define MODE tc
|
|
|
6693b3 |
+# define CEXT l
|
|
|
6693b3 |
+# define NOTRUNC 1
|
|
|
6693b3 |
+#else
|
|
|
6693b3 |
+# error
|
|
|
6693b3 |
+#endif
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+#define CONCAT3(A,B,C) _CONCAT3(A,B,C)
|
|
|
6693b3 |
+#define _CONCAT3(A,B,C) A##B##C
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+#define CONCAT2(A,B) _CONCAT2(A,B)
|
|
|
6693b3 |
+#define _CONCAT2(A,B) A##B
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+/* All of these would be present in a full C99 implementation of <math.h>
|
|
|
6693b3 |
+ and <complex.h>. Our problem is that only a few systems have such full
|
|
|
6693b3 |
+ implementations. Further, libgcc_s.so isn't currently linked against
|
|
|
6693b3 |
+ libm.so, and even for systems that do provide full C99, the extra overhead
|
|
|
6693b3 |
+ of all programs using libgcc having to link against libm. So avoid it. */
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+#define isnan(x) __builtin_expect ((x) != (x), 0)
|
|
|
6693b3 |
+#define isfinite(x) __builtin_expect (!isnan((x) - (x)), 1)
|
|
|
6693b3 |
+#define isinf(x) __builtin_expect (!isnan(x) & !isfinite(x), 0)
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+#define INFINITY CONCAT2(__builtin_inf, CEXT) ()
|
|
|
6693b3 |
+#define I 1i
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+/* Helpers to make the following code slightly less gross. */
|
|
|
6693b3 |
+#define COPYSIGN CONCAT2(__builtin_copysign, CEXT)
|
|
|
6693b3 |
+#define FABS CONCAT2(__builtin_fabs, CEXT)
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+/* Verify that MTYPE matches up with CEXT. */
|
|
|
6693b3 |
+extern void *compile_type_assert[sizeof(INFINITY) == sizeof(MTYPE) ? 1 : -1];
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+/* Ensure that we've lost any extra precision. */
|
|
|
6693b3 |
+#if NOTRUNC
|
|
|
6693b3 |
+# define TRUNC(x)
|
|
|
6693b3 |
+#else
|
|
|
6693b3 |
+# define TRUNC(x) __asm__ ("" : "=m"(x) : "m"(x))
|
|
|
6693b3 |
+#endif
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+#if defined(L_mulsc3) || defined(L_muldc3) \
|
|
|
6693b3 |
+ || defined(L_mulxc3) || defined(L_multc3)
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+CTYPE
|
|
|
6693b3 |
+CONCAT3(__mul,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d)
|
|
|
6693b3 |
+{
|
|
|
6693b3 |
+ MTYPE ac, bd, ad, bc, x, y;
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+ ac = a * c;
|
|
|
6693b3 |
+ bd = b * d;
|
|
|
6693b3 |
+ ad = a * d;
|
|
|
6693b3 |
+ bc = b * c;
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+ TRUNC (ac);
|
|
|
6693b3 |
+ TRUNC (bd);
|
|
|
6693b3 |
+ TRUNC (ad);
|
|
|
6693b3 |
+ TRUNC (bc);
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+ x = ac - bd;
|
|
|
6693b3 |
+ y = ad + bc;
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+ if (isnan (x) && isnan (y))
|
|
|
6693b3 |
+ {
|
|
|
6693b3 |
+ /* Recover infinities that computed as NaN + iNaN. */
|
|
|
6693b3 |
+ _Bool recalc = 0;
|
|
|
6693b3 |
+ if (isinf (a) || isinf (b))
|
|
|
6693b3 |
+ {
|
|
|
6693b3 |
+ /* z is infinite. "Box" the infinity and change NaNs in
|
|
|
6693b3 |
+ the other factor to 0. */
|
|
|
6693b3 |
+ a = COPYSIGN (isinf (a) ? 1 : 0, a);
|
|
|
6693b3 |
+ b = COPYSIGN (isinf (b) ? 1 : 0, b);
|
|
|
6693b3 |
+ if (isnan (c)) c = COPYSIGN (0, c);
|
|
|
6693b3 |
+ if (isnan (d)) d = COPYSIGN (0, d);
|
|
|
6693b3 |
+ recalc = 1;
|
|
|
6693b3 |
+ }
|
|
|
6693b3 |
+ if (isinf (c) || isinf (d))
|
|
|
6693b3 |
+ {
|
|
|
6693b3 |
+ /* w is infinite. "Box" the infinity and change NaNs in
|
|
|
6693b3 |
+ the other factor to 0. */
|
|
|
6693b3 |
+ c = COPYSIGN (isinf (c) ? 1 : 0, c);
|
|
|
6693b3 |
+ d = COPYSIGN (isinf (d) ? 1 : 0, d);
|
|
|
6693b3 |
+ if (isnan (a)) a = COPYSIGN (0, a);
|
|
|
6693b3 |
+ if (isnan (b)) b = COPYSIGN (0, b);
|
|
|
6693b3 |
+ recalc = 1;
|
|
|
6693b3 |
+ }
|
|
|
6693b3 |
+ if (!recalc
|
|
|
6693b3 |
+ && (isinf (ac) || isinf (bd)
|
|
|
6693b3 |
+ || isinf (ad) || isinf (bc)))
|
|
|
6693b3 |
+ {
|
|
|
6693b3 |
+ /* Recover infinities from overflow by changing NaNs to 0. */
|
|
|
6693b3 |
+ if (isnan (a)) a = COPYSIGN (0, a);
|
|
|
6693b3 |
+ if (isnan (b)) b = COPYSIGN (0, b);
|
|
|
6693b3 |
+ if (isnan (c)) c = COPYSIGN (0, c);
|
|
|
6693b3 |
+ if (isnan (d)) d = COPYSIGN (0, d);
|
|
|
6693b3 |
+ recalc = 1;
|
|
|
6693b3 |
+ }
|
|
|
6693b3 |
+ if (recalc)
|
|
|
6693b3 |
+ {
|
|
|
6693b3 |
+ x = INFINITY * (a * c - b * d);
|
|
|
6693b3 |
+ y = INFINITY * (a * d + b * c);
|
|
|
6693b3 |
+ }
|
|
|
6693b3 |
+ }
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+ return x + I * y;
|
|
|
6693b3 |
+}
|
|
|
6693b3 |
+#endif /* complex multiply */
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+#if defined(L_divsc3) || defined(L_divdc3) \
|
|
|
6693b3 |
+ || defined(L_divxc3) || defined(L_divtc3)
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+CTYPE
|
|
|
6693b3 |
+CONCAT3(__div,MODE,3) (MTYPE a, MTYPE b, MTYPE c, MTYPE d)
|
|
|
6693b3 |
+{
|
|
|
6693b3 |
+ MTYPE denom, ratio, x, y;
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+ /* ??? We can get better behavior from logarithmic scaling instead of
|
|
|
6693b3 |
+ the division. But that would mean starting to link libgcc against
|
|
|
6693b3 |
+ libm. We could implement something akin to ldexp/frexp as gcc builtins
|
|
|
6693b3 |
+ fairly easily... */
|
|
|
6693b3 |
+ if (FABS (c) < FABS (d))
|
|
|
6693b3 |
+ {
|
|
|
6693b3 |
+ ratio = c / d;
|
|
|
6693b3 |
+ denom = (c * ratio) + d;
|
|
|
6693b3 |
+ x = ((a * ratio) + b) / denom;
|
|
|
6693b3 |
+ y = ((b * ratio) - a) / denom;
|
|
|
6693b3 |
+ }
|
|
|
6693b3 |
+ else
|
|
|
6693b3 |
+ {
|
|
|
6693b3 |
+ ratio = d / c;
|
|
|
6693b3 |
+ denom = (d * ratio) + c;
|
|
|
6693b3 |
+ x = ((b * ratio) + a) / denom;
|
|
|
6693b3 |
+ y = (b - (a * ratio)) / denom;
|
|
|
6693b3 |
+ }
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+ /* Recover infinities and zeros that computed as NaN+iNaN; the only cases
|
|
|
6693b3 |
+ are nonzero/zero, infinite/finite, and finite/infinite. */
|
|
|
6693b3 |
+ if (isnan (x) && isnan (y))
|
|
|
6693b3 |
+ {
|
|
|
6693b3 |
+ if (c == 0.0 && d == 0.0 && (!isnan (a) || !isnan (b)))
|
|
|
6693b3 |
+ {
|
|
|
6693b3 |
+ x = COPYSIGN (INFINITY, c) * a;
|
|
|
6693b3 |
+ y = COPYSIGN (INFINITY, c) * b;
|
|
|
6693b3 |
+ }
|
|
|
6693b3 |
+ else if ((isinf (a) || isinf (b)) && isfinite (c) && isfinite (d))
|
|
|
6693b3 |
+ {
|
|
|
6693b3 |
+ a = COPYSIGN (isinf (a) ? 1 : 0, a);
|
|
|
6693b3 |
+ b = COPYSIGN (isinf (b) ? 1 : 0, b);
|
|
|
6693b3 |
+ x = INFINITY * (a * c + b * d);
|
|
|
6693b3 |
+ y = INFINITY * (b * c - a * d);
|
|
|
6693b3 |
+ }
|
|
|
6693b3 |
+ else if ((isinf (c) || isinf (d)) && isfinite (a) && isfinite (b))
|
|
|
6693b3 |
+ {
|
|
|
6693b3 |
+ c = COPYSIGN (isinf (c) ? 1 : 0, c);
|
|
|
6693b3 |
+ d = COPYSIGN (isinf (d) ? 1 : 0, d);
|
|
|
6693b3 |
+ x = 0.0 * (a * c + b * d);
|
|
|
6693b3 |
+ y = 0.0 * (b * c - a * d);
|
|
|
6693b3 |
+ }
|
|
|
6693b3 |
+ }
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+ return x + I * y;
|
|
|
6693b3 |
+}
|
|
|
6693b3 |
+#endif /* complex divide */
|
|
|
6693b3 |
+
|
|
|
6693b3 |
+#endif /* all complex float routines */
|
|
|
6693b3 |
+
|
|
|
6693b3 |
/* From here on down, the routines use normal data types. */
|
|
|
6693b3 |
|
|
|
6693b3 |
#define SItype bogus_type
|