Commit d5eea0f7 by Michael Meissner

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
parent a4f759de
...@@ -23,12 +23,12 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ...@@ -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. */ /* This is a temporary specialization of code from libgcc/libgcc2.c. */
typedef float KFtype __attribute__ ((mode (KF))); #include "soft-fp.h"
typedef __complex float KCtype __attribute__ ((mode (KC))); #include "quad-float128.h"
#define COPYSIGN(x,y) __builtin_copysignq (x, y) #define COPYSIGN(x,y) __builtin_copysignf128 (x, y)
#define INFINITY __builtin_infq () #define INFINITY __builtin_inff128 ()
#define FABS __builtin_fabsq #define FABS __builtin_fabsf128
#define isnan __builtin_isnan #define isnan __builtin_isnan
#define isinf __builtin_isinf #define isinf __builtin_isinf
#define isfinite __builtin_isfinite #define isfinite __builtin_isfinite
...@@ -37,13 +37,11 @@ typedef __complex float KCtype __attribute__ ((mode (KC))); ...@@ -37,13 +37,11 @@ typedef __complex float KCtype __attribute__ ((mode (KC)));
#define __divkc3 __divkc3_sw #define __divkc3 __divkc3_sw
#endif #endif
extern KCtype __divkc3 (KFtype, KFtype, KFtype, KFtype); TCtype
__divkc3 (TFtype a, TFtype b, TFtype c, TFtype d)
KCtype
__divkc3 (KFtype a, KFtype b, KFtype c, KFtype d)
{ {
KFtype denom, ratio, x, y; TFtype denom, ratio, x, y;
KCtype res; TCtype res;
/* ??? We can get better behavior from logarithmic scaling instead of /* ??? We can get better behavior from logarithmic scaling instead of
the division. But that would mean starting to link libgcc against 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 ...@@ -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. */ /* This is a temporary specialization of code from libgcc/libgcc2.c. */
typedef float KFtype __attribute__ ((mode (KF))); #include "soft-fp.h"
typedef __complex float KCtype __attribute__ ((mode (KC))); #include "quad-float128.h"
#define COPYSIGN(x,y) __builtin_copysignq (x, y) #define COPYSIGN(x,y) __builtin_copysignf128 (x, y)
#define INFINITY __builtin_infq () #define INFINITY __builtin_inff128 ()
#define isnan __builtin_isnan #define isnan __builtin_isnan
#define isinf __builtin_isinf #define isinf __builtin_isinf
...@@ -35,13 +35,11 @@ typedef __complex float KCtype __attribute__ ((mode (KC))); ...@@ -35,13 +35,11 @@ typedef __complex float KCtype __attribute__ ((mode (KC)));
#define __mulkc3 __mulkc3_sw #define __mulkc3 __mulkc3_sw
#endif #endif
extern KCtype __mulkc3 (KFtype, KFtype, KFtype, KFtype); TCtype
__mulkc3 (TFtype a, TFtype b, TFtype c, TFtype d)
KCtype
__mulkc3 (KFtype a, KFtype b, KFtype c, KFtype d)
{ {
KFtype ac, bd, ad, bc, x, y; TFtype ac, bd, ad, bc, x, y;
KCtype res; TCtype res;
ac = a * c; ac = a * c;
bd = b * d; bd = b * d;
......
...@@ -44,7 +44,7 @@ ...@@ -44,7 +44,7 @@
#endif #endif
IBM128_TYPE IBM128_TYPE
__extendkftf2_sw (__float128 value) __extendkftf2_sw (TFtype value)
{ {
IBM128_TYPE ret; IBM128_TYPE ret;
......
...@@ -56,6 +56,15 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ...@@ -56,6 +56,15 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
#define nonfinite(a) unlikely (! isless (fabs (a), inf ())) #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 ALIASNAME as a strong alias for NAME. */
# define strong_alias(name, aliasname) _strong_alias(name, aliasname) # define strong_alias(name, aliasname) _strong_alias(name, aliasname)
# define _strong_alias(name, aliasname) \ # define _strong_alias(name, aliasname) \
...@@ -65,10 +74,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see ...@@ -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 but GCC currently generates poor code when a union is used to turn
a long double into a pair of doubles. */ a long double into a pair of doubles. */
long double __gcc_qadd (double, double, double, double); IBM128_TYPE __gcc_qadd (double, double, double, double);
long double __gcc_qsub (double, double, double, double); IBM128_TYPE __gcc_qsub (double, double, double, double);
long double __gcc_qmul (double, double, double, double); IBM128_TYPE __gcc_qmul (double, double, double, double);
long double __gcc_qdiv (double, double, double, double); IBM128_TYPE __gcc_qdiv (double, double, double, double);
#if defined __ELF__ && defined SHARED \ #if defined __ELF__ && defined SHARED \
&& (defined __powerpc64__ || !(defined __linux__ || defined __gnu_hurd__)) && (defined __powerpc64__ || !(defined __linux__ || defined __gnu_hurd__))
...@@ -88,17 +97,17 @@ __asm__ (".symver __gcc_qadd,_xlqadd@GCC_3.4\n\t" ...@@ -88,17 +97,17 @@ __asm__ (".symver __gcc_qadd,_xlqadd@GCC_3.4\n\t"
".symver .__gcc_qdiv,._xlqdiv@GCC_3.4"); ".symver .__gcc_qdiv,._xlqdiv@GCC_3.4");
#endif #endif
/* Combine two 'double' values into one 'long double' and return the result. */ /* Combine two 'double' values into one 'IBM128_TYPE' and return the result. */
static inline long double static inline IBM128_TYPE
pack_ldouble (double dh, double dl) 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__)) && !(defined (_SOFT_FLOAT) || defined (__NO_FPRS__))
return __builtin_pack_longdouble (dh, dl); return __builtin_pack_longdouble (dh, dl);
#else #else
union union
{ {
long double ldval; IBM128_TYPE ldval;
double dval[2]; double dval[2];
} x; } x;
x.dval[0] = dh; x.dval[0] = dh;
...@@ -107,8 +116,8 @@ pack_ldouble (double dh, double dl) ...@@ -107,8 +116,8 @@ pack_ldouble (double dh, double dl)
#endif #endif
} }
/* Add two 'long double' values and return the result. */ /* Add two 'IBM128_TYPE' values and return the result. */
long double IBM128_TYPE
__gcc_qadd (double a, double aa, double c, double cc) __gcc_qadd (double a, double aa, double c, double cc)
{ {
double xh, xl, z, q, zz; double xh, xl, z, q, zz;
...@@ -147,7 +156,7 @@ __gcc_qadd (double a, double aa, double c, double cc) ...@@ -147,7 +156,7 @@ __gcc_qadd (double a, double aa, double c, double cc)
return pack_ldouble (xh, xl); return pack_ldouble (xh, xl);
} }
long double IBM128_TYPE
__gcc_qsub (double a, double b, double c, double d) __gcc_qsub (double a, double b, double c, double d)
{ {
return __gcc_qadd (a, b, -c, -d); return __gcc_qadd (a, b, -c, -d);
...@@ -157,7 +166,7 @@ __gcc_qsub (double a, double b, double c, double d) ...@@ -157,7 +166,7 @@ __gcc_qsub (double a, double b, double c, double d)
static double fmsub (double, double, double); static double fmsub (double, double, double);
#endif #endif
long double IBM128_TYPE
__gcc_qmul (double a, double b, double c, double d) __gcc_qmul (double a, double b, double c, double d)
{ {
double xh, xl, t, tau, u, v, w; double xh, xl, t, tau, u, v, w;
...@@ -181,7 +190,7 @@ __gcc_qmul (double a, double b, double c, double d) ...@@ -181,7 +190,7 @@ __gcc_qmul (double a, double b, double c, double d)
tau += v + w; /* Add in other second-order terms. */ tau += v + w; /* Add in other second-order terms. */
u = t + tau; u = t + tau;
/* Construct long double result. */ /* Construct IBM128_TYPE result. */
if (nonfinite (u)) if (nonfinite (u))
return u; return u;
xh = u; xh = u;
...@@ -189,7 +198,7 @@ __gcc_qmul (double a, double b, double c, double d) ...@@ -189,7 +198,7 @@ __gcc_qmul (double a, double b, double c, double d)
return pack_ldouble (xh, xl); return pack_ldouble (xh, xl);
} }
long double IBM128_TYPE
__gcc_qdiv (double a, double b, double c, double d) __gcc_qdiv (double a, double b, double c, double d)
{ {
double xh, xl, s, sigma, t, tau, u, v, w; double xh, xl, s, sigma, t, tau, u, v, w;
...@@ -226,7 +235,7 @@ __gcc_qdiv (double a, double b, double c, double d) ...@@ -226,7 +235,7 @@ __gcc_qdiv (double a, double b, double c, double d)
tau = ((v-sigma)+w)/c; /* Correction to t. */ tau = ((v-sigma)+w)/c; /* Correction to t. */
u = t + tau; u = t + tau;
/* Construct long double result. */ /* Construct IBM128_TYPE result. */
if (nonfinite (u)) if (nonfinite (u))
return u; return u;
xh = u; xh = u;
...@@ -236,32 +245,32 @@ __gcc_qdiv (double a, double b, double c, double d) ...@@ -236,32 +245,32 @@ __gcc_qdiv (double a, double b, double c, double d)
#if defined (_SOFT_DOUBLE) && defined (__LONG_DOUBLE_128__) #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_qeq (double, double, double, double);
int __gcc_qne (double, double, double, double); int __gcc_qne (double, double, double, double);
int __gcc_qge (double, double, double, double); int __gcc_qge (double, double, double, double);
int __gcc_qle (double, double, double, double); int __gcc_qle (double, double, double, double);
long double __gcc_stoq (float); IBM128_TYPE __gcc_stoq (float);
long double __gcc_dtoq (double); IBM128_TYPE __gcc_dtoq (double);
float __gcc_qtos (double, double); float __gcc_qtos (double, double);
double __gcc_qtod (double, double); double __gcc_qtod (double, double);
int __gcc_qtoi (double, double); int __gcc_qtoi (double, double);
unsigned int __gcc_qtou (double, double); unsigned int __gcc_qtou (double, double);
long double __gcc_itoq (int); IBM128_TYPE __gcc_itoq (int);
long double __gcc_utoq (unsigned int); IBM128_TYPE __gcc_utoq (unsigned int);
extern int __eqdf2 (double, double); extern int __eqdf2 (double, double);
extern int __ledf2 (double, double); extern int __ledf2 (double, double);
extern int __gedf2 (double, double); extern int __gedf2 (double, double);
/* Negate 'long double' value and return the result. */ /* Negate 'IBM128_TYPE' value and return the result. */
long double IBM128_TYPE
__gcc_qneg (double a, double aa) __gcc_qneg (double a, double aa)
{ {
return pack_ldouble (-a, -aa); return pack_ldouble (-a, -aa);
} }
/* Compare two 'long double' values for equality. */ /* Compare two 'IBM128_TYPE' values for equality. */
int int
__gcc_qeq (double a, double aa, double c, double cc) __gcc_qeq (double a, double aa, double c, double cc)
{ {
...@@ -272,7 +281,7 @@ __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); 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 int
__gcc_qle (double a, double aa, double c, double cc) __gcc_qle (double a, double aa, double c, double cc)
{ {
...@@ -283,7 +292,7 @@ __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); 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 int
__gcc_qge (double a, double aa, double c, double cc) __gcc_qge (double a, double aa, double c, double cc)
{ {
...@@ -294,35 +303,35 @@ __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); strong_alias (__gcc_qge, __gcc_qgt);
/* Convert single to long double. */ /* Convert single to IBM128_TYPE. */
long double IBM128_TYPE
__gcc_stoq (float a) __gcc_stoq (float a)
{ {
return pack_ldouble ((double) a, 0.0); return pack_ldouble ((double) a, 0.0);
} }
/* Convert double to long double. */ /* Convert double to IBM128_TYPE. */
long double IBM128_TYPE
__gcc_dtoq (double a) __gcc_dtoq (double a)
{ {
return pack_ldouble (a, 0.0); return pack_ldouble (a, 0.0);
} }
/* Convert long double to single. */ /* Convert IBM128_TYPE to single. */
float float
__gcc_qtos (double a, double aa __attribute__ ((__unused__))) __gcc_qtos (double a, double aa __attribute__ ((__unused__)))
{ {
return (float) a; return (float) a;
} }
/* Convert long double to double. */ /* Convert IBM128_TYPE to double. */
double double
__gcc_qtod (double a, double aa __attribute__ ((__unused__))) __gcc_qtod (double a, double aa __attribute__ ((__unused__)))
{ {
return a; return a;
} }
/* Convert long double to int. */ /* Convert IBM128_TYPE to int. */
int int
__gcc_qtoi (double a, double aa) __gcc_qtoi (double a, double aa)
{ {
...@@ -330,7 +339,7 @@ __gcc_qtoi (double a, double aa) ...@@ -330,7 +339,7 @@ __gcc_qtoi (double a, double aa)
return (int) z; return (int) z;
} }
/* Convert long double to unsigned int. */ /* Convert IBM128_TYPE to unsigned int. */
unsigned int unsigned int
__gcc_qtou (double a, double aa) __gcc_qtou (double a, double aa)
{ {
...@@ -338,15 +347,15 @@ __gcc_qtou (double a, double aa) ...@@ -338,15 +347,15 @@ __gcc_qtou (double a, double aa)
return (unsigned int) z; return (unsigned int) z;
} }
/* Convert int to long double. */ /* Convert int to IBM128_TYPE. */
long double IBM128_TYPE
__gcc_itoq (int a) __gcc_itoq (int a)
{ {
return __gcc_dtoq ((double) a); return __gcc_dtoq ((double) a);
} }
/* Convert unsigned int to long double. */ /* Convert unsigned int to IBM128_TYPE. */
long double IBM128_TYPE
__gcc_utoq (unsigned int a) __gcc_utoq (unsigned int a)
{ {
return __gcc_dtoq ((double) a); return __gcc_dtoq ((double) a);
...@@ -361,7 +370,7 @@ int __gcc_qunord (double, double, double, double); ...@@ -361,7 +370,7 @@ int __gcc_qunord (double, double, double, double);
extern int __eqdf2 (double, double); extern int __eqdf2 (double, double);
extern int __unorddf2 (double, double); extern int __unorddf2 (double, double);
/* Compare two 'long double' values for unordered. */ /* Compare two 'IBM128_TYPE' values for unordered. */
int int
__gcc_qunord (double a, double aa, double c, double cc) __gcc_qunord (double a, double aa, double c, double cc)
{ {
...@@ -389,7 +398,7 @@ fmsub (double a, double b, double c) ...@@ -389,7 +398,7 @@ fmsub (double a, double b, double c)
FP_DECL_Q(V); FP_DECL_Q(V);
FP_DECL_D(R); FP_DECL_D(R);
double r; double r;
long double u, x, y, z; IBM128_TYPE u, x, y, z;
FP_INIT_ROUNDMODE; FP_INIT_ROUNDMODE;
FP_UNPACK_RAW_D (A, a); FP_UNPACK_RAW_D (A, a);
......
...@@ -51,12 +51,7 @@ typedef __complex float TCtype __attribute__ ((mode (TC))); ...@@ -51,12 +51,7 @@ typedef __complex float TCtype __attribute__ ((mode (TC)));
#include <quad.h> #include <quad.h>
#ifdef __LONG_DOUBLE_IEEE128__ #define IBM128_TYPE __ibm128
#define IBM128_TYPE __ibm128
#else
#define IBM128_TYPE long double
#endif
/* Add prototypes of the library functions created. In case the appropriate /* 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, int/long types are not declared in scope by the time quad.h is included,
...@@ -185,7 +180,7 @@ union ibm128_union { ...@@ -185,7 +180,7 @@ union ibm128_union {
#define CVT_FLOAT128_TO_IBM128(RESULT, VALUE) \ #define CVT_FLOAT128_TO_IBM128(RESULT, VALUE) \
{ \ { \
double __high, __low; \ double __high, __low; \
__float128 __value = (VALUE); \ TFtype __value = (VALUE); \
union ibm128_union u; \ union ibm128_union u; \
\ \
__high = (double) __value; \ __high = (double) __value; \
...@@ -196,7 +191,7 @@ union ibm128_union { ...@@ -196,7 +191,7 @@ union ibm128_union {
{ \ { \
double __high_temp; \ double __high_temp; \
\ \
__low = (double) (__value - (__float128) __high); \ __low = (double) (__value - (TFtype) __high); \
/* Renormalize low/high and move them into canonical IBM long \ /* Renormalize low/high and move them into canonical IBM long \
double form. */ \ double form. */ \
__high_temp = __high + __low; \ __high_temp = __high + __low; \
...@@ -220,13 +215,13 @@ union ibm128_union { ...@@ -220,13 +215,13 @@ union ibm128_union {
\ \
/* Handle the special cases of NAN and infinity. */ \ /* Handle the special cases of NAN and infinity. */ \
if (__builtin_isnan (__high) || __builtin_isinf (__high)) \ 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, \ /* 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. */ \ avoiding the add produces the correct sign if high is -0.0. */ \
else if (__low == 0.0) \ else if (__low == 0.0) \
RESULT = (__float128) __high; \ RESULT = (TFtype) __high; \
\ \
else \ else \
RESULT = ((__float128) __high) + ((__float128) __low); \ RESULT = ((TFtype) __high) + ((TFtype) __low); \
} }
...@@ -43,10 +43,10 @@ ...@@ -43,10 +43,10 @@
#define __trunctfkf2_sw __trunctfkf2 #define __trunctfkf2_sw __trunctfkf2
#endif #endif
__float128 TFtype
__trunctfkf2_sw (IBM128_TYPE value) __trunctfkf2_sw (IBM128_TYPE value)
{ {
__float128 ret; TFtype ret;
CVT_IBM128_TO_FLOAT128 (ret, value); CVT_IBM128_TO_FLOAT128 (ret, value);
return ret; return ret;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment