quad-float128.h (IBM128_TYPE): Explicitly use __ibm128, instead of trying to use long double.
2018-01-08 Michael Meissner <meissner@linux.vnet.ibm.com> * config/rs6000/quad-float128.h (IBM128_TYPE): Explicitly use __ibm128, instead of trying to use long double. (CVT_FLOAT128_TO_IBM128): Use TFtype instead of __float128 to accomidate -mabi=ieeelongdouble multilibs. (CVT_IBM128_TO_FLOAT128): Likewise. * config/rs6000/ibm-ldouble.c (IBM128_TYPE): New macro to define the appropriate IBM extended double type. (__gcc_qadd): Change all occurances of long double to IBM128_TYPE. (__gcc_qsub): Likewise. (__gcc_qmul): Likewise. (__gcc_qdiv): Likewise. (pack_ldouble): Likewise. (__gcc_qneg): Likewise. (__gcc_qeq): Likewise. (__gcc_qne): Likewise. (__gcc_qge): Likewise. (__gcc_qle): Likewise. (__gcc_stoq): Likewise. (__gcc_dtoq): Likewise. (__gcc_itoq): Likewise. (__gcc_utoq): Likewise. (__gcc_qunord): Likewise. * config/rs6000/_mulkc3.c (toplevel): Include soft-fp.h and quad-float128.h for the definitions. (COPYSIGN): Use the f128 version instead of the q version. (INFINITY): Likewise. (__mulkc3): Use TFmode/TCmode for float128 scalar/complex types. * config/rs6000/_divkc3.c (toplevel): Include soft-fp.h and quad-float128.h for the definitions. (COPYSIGN): Use the f128 version instead of the q version. (INFINITY): Likewise. (FABS): Likewise. (__divkc3): Use TFmode/TCmode for float128 scalar/complex types. * config/rs6000/extendkftf2-sw.c (__extendkftf2_sw): Likewise. * config/rs6000/trunctfkf2-sw.c (__trunctfkf2_sw): Likewise. From-SVN: r256353
This commit is contained in:
parent
a4f759de23
commit
d5eea0f7cc
|
@ -23,12 +23,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|||
|
||||
/* This is a temporary specialization of code from libgcc/libgcc2.c. */
|
||||
|
||||
typedef float KFtype __attribute__ ((mode (KF)));
|
||||
typedef __complex float KCtype __attribute__ ((mode (KC)));
|
||||
#include "soft-fp.h"
|
||||
#include "quad-float128.h"
|
||||
|
||||
#define COPYSIGN(x,y) __builtin_copysignq (x, y)
|
||||
#define INFINITY __builtin_infq ()
|
||||
#define FABS __builtin_fabsq
|
||||
#define COPYSIGN(x,y) __builtin_copysignf128 (x, y)
|
||||
#define INFINITY __builtin_inff128 ()
|
||||
#define FABS __builtin_fabsf128
|
||||
#define isnan __builtin_isnan
|
||||
#define isinf __builtin_isinf
|
||||
#define isfinite __builtin_isfinite
|
||||
|
@ -37,13 +37,11 @@ typedef __complex float KCtype __attribute__ ((mode (KC)));
|
|||
#define __divkc3 __divkc3_sw
|
||||
#endif
|
||||
|
||||
extern KCtype __divkc3 (KFtype, KFtype, KFtype, KFtype);
|
||||
|
||||
KCtype
|
||||
__divkc3 (KFtype a, KFtype b, KFtype c, KFtype d)
|
||||
TCtype
|
||||
__divkc3 (TFtype a, TFtype b, TFtype c, TFtype d)
|
||||
{
|
||||
KFtype denom, ratio, x, y;
|
||||
KCtype res;
|
||||
TFtype denom, ratio, x, y;
|
||||
TCtype res;
|
||||
|
||||
/* ??? We can get better behavior from logarithmic scaling instead of
|
||||
the division. But that would mean starting to link libgcc against
|
||||
|
|
|
@ -23,11 +23,11 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|||
|
||||
/* This is a temporary specialization of code from libgcc/libgcc2.c. */
|
||||
|
||||
typedef float KFtype __attribute__ ((mode (KF)));
|
||||
typedef __complex float KCtype __attribute__ ((mode (KC)));
|
||||
#include "soft-fp.h"
|
||||
#include "quad-float128.h"
|
||||
|
||||
#define COPYSIGN(x,y) __builtin_copysignq (x, y)
|
||||
#define INFINITY __builtin_infq ()
|
||||
#define COPYSIGN(x,y) __builtin_copysignf128 (x, y)
|
||||
#define INFINITY __builtin_inff128 ()
|
||||
#define isnan __builtin_isnan
|
||||
#define isinf __builtin_isinf
|
||||
|
||||
|
@ -35,13 +35,11 @@ typedef __complex float KCtype __attribute__ ((mode (KC)));
|
|||
#define __mulkc3 __mulkc3_sw
|
||||
#endif
|
||||
|
||||
extern KCtype __mulkc3 (KFtype, KFtype, KFtype, KFtype);
|
||||
|
||||
KCtype
|
||||
__mulkc3 (KFtype a, KFtype b, KFtype c, KFtype d)
|
||||
TCtype
|
||||
__mulkc3 (TFtype a, TFtype b, TFtype c, TFtype d)
|
||||
{
|
||||
KFtype ac, bd, ad, bc, x, y;
|
||||
KCtype res;
|
||||
TFtype ac, bd, ad, bc, x, y;
|
||||
TCtype res;
|
||||
|
||||
ac = a * c;
|
||||
bd = b * d;
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
#endif
|
||||
|
||||
IBM128_TYPE
|
||||
__extendkftf2_sw (__float128 value)
|
||||
__extendkftf2_sw (TFtype value)
|
||||
{
|
||||
IBM128_TYPE ret;
|
||||
|
||||
|
|
|
@ -56,6 +56,15 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|||
|
||||
#define nonfinite(a) unlikely (! isless (fabs (a), inf ()))
|
||||
|
||||
/* If we have __float128/_Float128, use __ibm128 instead of long double. On
|
||||
other systems, use long double, because __ibm128 might not have been
|
||||
created. */
|
||||
#ifdef __FLOAT128__
|
||||
#define IBM128_TYPE __ibm128
|
||||
#else
|
||||
#define IBM128_TYPE long double
|
||||
#endif
|
||||
|
||||
/* Define ALIASNAME as a strong alias for NAME. */
|
||||
# define strong_alias(name, aliasname) _strong_alias(name, aliasname)
|
||||
# define _strong_alias(name, aliasname) \
|
||||
|
@ -65,10 +74,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|||
but GCC currently generates poor code when a union is used to turn
|
||||
a long double into a pair of doubles. */
|
||||
|
||||
long double __gcc_qadd (double, double, double, double);
|
||||
long double __gcc_qsub (double, double, double, double);
|
||||
long double __gcc_qmul (double, double, double, double);
|
||||
long double __gcc_qdiv (double, double, double, double);
|
||||
IBM128_TYPE __gcc_qadd (double, double, double, double);
|
||||
IBM128_TYPE __gcc_qsub (double, double, double, double);
|
||||
IBM128_TYPE __gcc_qmul (double, double, double, double);
|
||||
IBM128_TYPE __gcc_qdiv (double, double, double, double);
|
||||
|
||||
#if defined __ELF__ && defined SHARED \
|
||||
&& (defined __powerpc64__ || !(defined __linux__ || defined __gnu_hurd__))
|
||||
|
@ -88,17 +97,17 @@ __asm__ (".symver __gcc_qadd,_xlqadd@GCC_3.4\n\t"
|
|||
".symver .__gcc_qdiv,._xlqdiv@GCC_3.4");
|
||||
#endif
|
||||
|
||||
/* Combine two 'double' values into one 'long double' and return the result. */
|
||||
static inline long double
|
||||
/* Combine two 'double' values into one 'IBM128_TYPE' and return the result. */
|
||||
static inline IBM128_TYPE
|
||||
pack_ldouble (double dh, double dl)
|
||||
{
|
||||
#if defined (__LONG_DOUBLE_128__) \
|
||||
#if defined (__LONG_DOUBLE_128__) && defined (__LONG_DOUBLE_IBM128__) \
|
||||
&& !(defined (_SOFT_FLOAT) || defined (__NO_FPRS__))
|
||||
return __builtin_pack_longdouble (dh, dl);
|
||||
#else
|
||||
union
|
||||
{
|
||||
long double ldval;
|
||||
IBM128_TYPE ldval;
|
||||
double dval[2];
|
||||
} x;
|
||||
x.dval[0] = dh;
|
||||
|
@ -107,8 +116,8 @@ pack_ldouble (double dh, double dl)
|
|||
#endif
|
||||
}
|
||||
|
||||
/* Add two 'long double' values and return the result. */
|
||||
long double
|
||||
/* Add two 'IBM128_TYPE' values and return the result. */
|
||||
IBM128_TYPE
|
||||
__gcc_qadd (double a, double aa, double c, double cc)
|
||||
{
|
||||
double xh, xl, z, q, zz;
|
||||
|
@ -147,7 +156,7 @@ __gcc_qadd (double a, double aa, double c, double cc)
|
|||
return pack_ldouble (xh, xl);
|
||||
}
|
||||
|
||||
long double
|
||||
IBM128_TYPE
|
||||
__gcc_qsub (double a, double b, double c, double d)
|
||||
{
|
||||
return __gcc_qadd (a, b, -c, -d);
|
||||
|
@ -157,7 +166,7 @@ __gcc_qsub (double a, double b, double c, double d)
|
|||
static double fmsub (double, double, double);
|
||||
#endif
|
||||
|
||||
long double
|
||||
IBM128_TYPE
|
||||
__gcc_qmul (double a, double b, double c, double d)
|
||||
{
|
||||
double xh, xl, t, tau, u, v, w;
|
||||
|
@ -181,7 +190,7 @@ __gcc_qmul (double a, double b, double c, double d)
|
|||
tau += v + w; /* Add in other second-order terms. */
|
||||
u = t + tau;
|
||||
|
||||
/* Construct long double result. */
|
||||
/* Construct IBM128_TYPE result. */
|
||||
if (nonfinite (u))
|
||||
return u;
|
||||
xh = u;
|
||||
|
@ -189,7 +198,7 @@ __gcc_qmul (double a, double b, double c, double d)
|
|||
return pack_ldouble (xh, xl);
|
||||
}
|
||||
|
||||
long double
|
||||
IBM128_TYPE
|
||||
__gcc_qdiv (double a, double b, double c, double d)
|
||||
{
|
||||
double xh, xl, s, sigma, t, tau, u, v, w;
|
||||
|
@ -226,7 +235,7 @@ __gcc_qdiv (double a, double b, double c, double d)
|
|||
tau = ((v-sigma)+w)/c; /* Correction to t. */
|
||||
u = t + tau;
|
||||
|
||||
/* Construct long double result. */
|
||||
/* Construct IBM128_TYPE result. */
|
||||
if (nonfinite (u))
|
||||
return u;
|
||||
xh = u;
|
||||
|
@ -236,32 +245,32 @@ __gcc_qdiv (double a, double b, double c, double d)
|
|||
|
||||
#if defined (_SOFT_DOUBLE) && defined (__LONG_DOUBLE_128__)
|
||||
|
||||
long double __gcc_qneg (double, double);
|
||||
IBM128_TYPE __gcc_qneg (double, double);
|
||||
int __gcc_qeq (double, double, double, double);
|
||||
int __gcc_qne (double, double, double, double);
|
||||
int __gcc_qge (double, double, double, double);
|
||||
int __gcc_qle (double, double, double, double);
|
||||
long double __gcc_stoq (float);
|
||||
long double __gcc_dtoq (double);
|
||||
IBM128_TYPE __gcc_stoq (float);
|
||||
IBM128_TYPE __gcc_dtoq (double);
|
||||
float __gcc_qtos (double, double);
|
||||
double __gcc_qtod (double, double);
|
||||
int __gcc_qtoi (double, double);
|
||||
unsigned int __gcc_qtou (double, double);
|
||||
long double __gcc_itoq (int);
|
||||
long double __gcc_utoq (unsigned int);
|
||||
IBM128_TYPE __gcc_itoq (int);
|
||||
IBM128_TYPE __gcc_utoq (unsigned int);
|
||||
|
||||
extern int __eqdf2 (double, double);
|
||||
extern int __ledf2 (double, double);
|
||||
extern int __gedf2 (double, double);
|
||||
|
||||
/* Negate 'long double' value and return the result. */
|
||||
long double
|
||||
/* Negate 'IBM128_TYPE' value and return the result. */
|
||||
IBM128_TYPE
|
||||
__gcc_qneg (double a, double aa)
|
||||
{
|
||||
return pack_ldouble (-a, -aa);
|
||||
}
|
||||
|
||||
/* Compare two 'long double' values for equality. */
|
||||
/* Compare two 'IBM128_TYPE' values for equality. */
|
||||
int
|
||||
__gcc_qeq (double a, double aa, double c, double cc)
|
||||
{
|
||||
|
@ -272,7 +281,7 @@ __gcc_qeq (double a, double aa, double c, double cc)
|
|||
|
||||
strong_alias (__gcc_qeq, __gcc_qne);
|
||||
|
||||
/* Compare two 'long double' values for less than or equal. */
|
||||
/* Compare two 'IBM128_TYPE' values for less than or equal. */
|
||||
int
|
||||
__gcc_qle (double a, double aa, double c, double cc)
|
||||
{
|
||||
|
@ -283,7 +292,7 @@ __gcc_qle (double a, double aa, double c, double cc)
|
|||
|
||||
strong_alias (__gcc_qle, __gcc_qlt);
|
||||
|
||||
/* Compare two 'long double' values for greater than or equal. */
|
||||
/* Compare two 'IBM128_TYPE' values for greater than or equal. */
|
||||
int
|
||||
__gcc_qge (double a, double aa, double c, double cc)
|
||||
{
|
||||
|
@ -294,35 +303,35 @@ __gcc_qge (double a, double aa, double c, double cc)
|
|||
|
||||
strong_alias (__gcc_qge, __gcc_qgt);
|
||||
|
||||
/* Convert single to long double. */
|
||||
long double
|
||||
/* Convert single to IBM128_TYPE. */
|
||||
IBM128_TYPE
|
||||
__gcc_stoq (float a)
|
||||
{
|
||||
return pack_ldouble ((double) a, 0.0);
|
||||
}
|
||||
|
||||
/* Convert double to long double. */
|
||||
long double
|
||||
/* Convert double to IBM128_TYPE. */
|
||||
IBM128_TYPE
|
||||
__gcc_dtoq (double a)
|
||||
{
|
||||
return pack_ldouble (a, 0.0);
|
||||
}
|
||||
|
||||
/* Convert long double to single. */
|
||||
/* Convert IBM128_TYPE to single. */
|
||||
float
|
||||
__gcc_qtos (double a, double aa __attribute__ ((__unused__)))
|
||||
{
|
||||
return (float) a;
|
||||
}
|
||||
|
||||
/* Convert long double to double. */
|
||||
/* Convert IBM128_TYPE to double. */
|
||||
double
|
||||
__gcc_qtod (double a, double aa __attribute__ ((__unused__)))
|
||||
{
|
||||
return a;
|
||||
}
|
||||
|
||||
/* Convert long double to int. */
|
||||
/* Convert IBM128_TYPE to int. */
|
||||
int
|
||||
__gcc_qtoi (double a, double aa)
|
||||
{
|
||||
|
@ -330,7 +339,7 @@ __gcc_qtoi (double a, double aa)
|
|||
return (int) z;
|
||||
}
|
||||
|
||||
/* Convert long double to unsigned int. */
|
||||
/* Convert IBM128_TYPE to unsigned int. */
|
||||
unsigned int
|
||||
__gcc_qtou (double a, double aa)
|
||||
{
|
||||
|
@ -338,15 +347,15 @@ __gcc_qtou (double a, double aa)
|
|||
return (unsigned int) z;
|
||||
}
|
||||
|
||||
/* Convert int to long double. */
|
||||
long double
|
||||
/* Convert int to IBM128_TYPE. */
|
||||
IBM128_TYPE
|
||||
__gcc_itoq (int a)
|
||||
{
|
||||
return __gcc_dtoq ((double) a);
|
||||
}
|
||||
|
||||
/* Convert unsigned int to long double. */
|
||||
long double
|
||||
/* Convert unsigned int to IBM128_TYPE. */
|
||||
IBM128_TYPE
|
||||
__gcc_utoq (unsigned int a)
|
||||
{
|
||||
return __gcc_dtoq ((double) a);
|
||||
|
@ -361,7 +370,7 @@ int __gcc_qunord (double, double, double, double);
|
|||
extern int __eqdf2 (double, double);
|
||||
extern int __unorddf2 (double, double);
|
||||
|
||||
/* Compare two 'long double' values for unordered. */
|
||||
/* Compare two 'IBM128_TYPE' values for unordered. */
|
||||
int
|
||||
__gcc_qunord (double a, double aa, double c, double cc)
|
||||
{
|
||||
|
@ -389,7 +398,7 @@ fmsub (double a, double b, double c)
|
|||
FP_DECL_Q(V);
|
||||
FP_DECL_D(R);
|
||||
double r;
|
||||
long double u, x, y, z;
|
||||
IBM128_TYPE u, x, y, z;
|
||||
|
||||
FP_INIT_ROUNDMODE;
|
||||
FP_UNPACK_RAW_D (A, a);
|
||||
|
|
|
@ -51,12 +51,7 @@ typedef __complex float TCtype __attribute__ ((mode (TC)));
|
|||
|
||||
#include <quad.h>
|
||||
|
||||
#ifdef __LONG_DOUBLE_IEEE128__
|
||||
#define IBM128_TYPE __ibm128
|
||||
|
||||
#else
|
||||
#define IBM128_TYPE long double
|
||||
#endif
|
||||
#define IBM128_TYPE __ibm128
|
||||
|
||||
/* Add prototypes of the library functions created. In case the appropriate
|
||||
int/long types are not declared in scope by the time quad.h is included,
|
||||
|
@ -185,7 +180,7 @@ union ibm128_union {
|
|||
#define CVT_FLOAT128_TO_IBM128(RESULT, VALUE) \
|
||||
{ \
|
||||
double __high, __low; \
|
||||
__float128 __value = (VALUE); \
|
||||
TFtype __value = (VALUE); \
|
||||
union ibm128_union u; \
|
||||
\
|
||||
__high = (double) __value; \
|
||||
|
@ -196,7 +191,7 @@ union ibm128_union {
|
|||
{ \
|
||||
double __high_temp; \
|
||||
\
|
||||
__low = (double) (__value - (__float128) __high); \
|
||||
__low = (double) (__value - (TFtype) __high); \
|
||||
/* Renormalize low/high and move them into canonical IBM long \
|
||||
double form. */ \
|
||||
__high_temp = __high + __low; \
|
||||
|
@ -220,13 +215,13 @@ union ibm128_union {
|
|||
\
|
||||
/* Handle the special cases of NAN and infinity. */ \
|
||||
if (__builtin_isnan (__high) || __builtin_isinf (__high)) \
|
||||
RESULT = (__float128) __high; \
|
||||
RESULT = (TFtype) __high; \
|
||||
\
|
||||
/* If low is 0.0, there no need to do the add. In addition, \
|
||||
avoiding the add produces the correct sign if high is -0.0. */ \
|
||||
else if (__low == 0.0) \
|
||||
RESULT = (__float128) __high; \
|
||||
RESULT = (TFtype) __high; \
|
||||
\
|
||||
else \
|
||||
RESULT = ((__float128) __high) + ((__float128) __low); \
|
||||
RESULT = ((TFtype) __high) + ((TFtype) __low); \
|
||||
}
|
||||
|
|
|
@ -43,10 +43,10 @@
|
|||
#define __trunctfkf2_sw __trunctfkf2
|
||||
#endif
|
||||
|
||||
__float128
|
||||
TFtype
|
||||
__trunctfkf2_sw (IBM128_TYPE value)
|
||||
{
|
||||
__float128 ret;
|
||||
TFtype ret;
|
||||
|
||||
CVT_IBM128_TO_FLOAT128 (ret, value);
|
||||
return ret;
|
||||
|
|
Loading…
Reference in New Issue