public inbox for gcc-cvs@sourceware.org
help / color / mirror / Atom feed
* [gcc(refs/users/ibuclaw/heads/darwin)] D, Math, IBM128 : Use GCC builtins for floor and exp.
@ 2021-03-14 22:02 Iain Buclaw
0 siblings, 0 replies; 8+ messages in thread
From: Iain Buclaw @ 2021-03-14 22:02 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:9f1634e116a24f9646e8bc94c830ed9babb5f97b
commit 9f1634e116a24f9646e8bc94c830ed9babb5f97b
Author: Iain Sandoe <iain@sandoe.co.uk>
Date: Fri Dec 11 00:59:19 2020 +0000
D, Math, IBM128 : Use GCC builtins for floor and exp.
This makes use of GCC's long double format builtins, which
in turn will call out to a libc implementation where needed.
Diff:
---
libphobos/src/std/math.d | 183 ++++++++++++++++++++++++++---------------------
1 file changed, 101 insertions(+), 82 deletions(-)
diff --git a/libphobos/src/std/math.d b/libphobos/src/std/math.d
index ff368b79f9d..ac4a93d313b 100644
--- a/libphobos/src/std/math.d
+++ b/libphobos/src/std/math.d
@@ -460,108 +460,118 @@ else
T floorImpl(T)(const T x) @trusted pure nothrow @nogc
{
alias F = floatTraits!(T);
- // Take care not to trigger library calls from the compiler,
- // while ensuring that we don't get defeated by some optimizers.
- union floatBits
- {
- T rv;
- ushort[T.sizeof/2] vu;
- // Other kinds of extractors for real formats.
- static if (F.realFormat == RealFormat.ieeeSingle)
- int vi;
- }
- floatBits y = void;
- y.rv = x;
-
- // Find the exponent (power of 2)
- // Do this by shifting the raw value so that the exponent lies in the low bits,
- // then mask out the sign bit, and subtract the bias.
- static if (F.realFormat == RealFormat.ieeeSingle)
+ static if (F.realFormat == RealFormat.ibmExtended)
{
- int exp = ((y.vi >> (T.mant_dig - 1)) & 0xff) - 0x7f;
+ import gcc.builtins;
+ return __builtin_floorl(x);
}
- else static if (F.realFormat == RealFormat.ieeeDouble)
+ else
{
- int exp = ((y.vu[F.EXPPOS_SHORT] >> 4) & 0x7ff) - 0x3ff;
+ // Take care not to trigger library calls from the compiler,
+ // while ensuring that we don't get defeated by some optimizers.
+ union floatBits
+ {
+ T rv;
+ ushort[T.sizeof/2] vu;
- version (LittleEndian)
- int pos = 0;
- else
- int pos = 3;
- }
- else static if (F.realFormat == RealFormat.ieeeExtended ||
- F.realFormat == RealFormat.ieeeExtended53)
- {
- int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
+ // Other kinds of extractors for real formats.
+ static if (F.realFormat == RealFormat.ieeeSingle)
+ int vi;
+ }
+ floatBits y = void;
+ y.rv = x;
- version (LittleEndian)
- int pos = 0;
- else
- int pos = 4;
- }
- else static if (F.realFormat == RealFormat.ieeeQuadruple)
- {
- int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
+ // Find the exponent (power of 2)
+ // Do this by shifting the raw value so that the exponent lies in the
+ // low bits, then mask out the sign bit, and subtract the bias.
+ static if (F.realFormat == RealFormat.ieeeSingle)
+ {
+ int exp = ((y.vi >> (T.mant_dig - 1)) & 0xff) - 0x7f;
+ }
+ else static if (F.realFormat == RealFormat.ieeeDouble)
+ {
+ int exp = ((y.vu[F.EXPPOS_SHORT] >> 4) & 0x7ff) - 0x3ff;
- version (LittleEndian)
- int pos = 0;
- else
- int pos = 7;
+ version (LittleEndian)
+ int pos = 0;
+ else
+ int pos = 3;
}
- else
- static assert(false, "Not implemented for this architecture");
+ else static if (F.realFormat == RealFormat.ieeeExtended ||
+ F.realFormat == RealFormat.ieeeExtended53)
+ {
+ int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
- if (exp < 0)
- {
- if (x < 0.0)
- return -1.0;
+ version (LittleEndian)
+ int pos = 0;
+ else
+ int pos = 4;
+ }
+ else static if (F.realFormat == RealFormat.ieeeQuadruple)
+ {
+ int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
+
+ version (LittleEndian)
+ int pos = 0;
+ else
+ int pos = 7;
+ }
else
- return 0.0;
- }
+ static assert(false, "Not implemented for this architecture");
- static if (F.realFormat == RealFormat.ieeeSingle)
- {
- if (exp < (T.mant_dig - 1))
+ if (exp < 0)
{
- // Clear all bits representing the fraction part.
- const uint fraction_mask = F.MANTISSAMASK_INT >> exp;
+ if (x < 0.0)
+ return -1.0;
+ else
+ return 0.0;
+ }
- if ((y.vi & fraction_mask) != 0)
+ static if (F.realFormat == RealFormat.ieeeSingle)
+ {
+ if (exp < (T.mant_dig - 1))
{
- // If 'x' is negative, then first substract 1.0 from the value.
- if (y.vi < 0)
- y.vi += 0x00800000 >> exp;
- y.vi &= ~fraction_mask;
+ // Clear all bits representing the fraction part.
+ const uint fraction_mask = F.MANTISSAMASK_INT >> exp;
+
+ if ((y.vi & fraction_mask) != 0)
+ {
+ // If 'x' is negative, then first substract 1.0 from
+ // the value.
+ if (y.vi < 0)
+ y.vi += 0x00800000 >> exp;
+ y.vi &= ~fraction_mask;
+ }
}
}
- }
- else
- {
- static if (F.realFormat == RealFormat.ieeeExtended53)
- exp = (T.mant_dig + 11 - 1) - exp; // mant_dig is really 64
else
- exp = (T.mant_dig - 1) - exp;
-
- // Zero 16 bits at a time.
- while (exp >= 16)
{
- version (LittleEndian)
- y.vu[pos++] = 0;
+ static if (F.realFormat == RealFormat.ieeeExtended53)
+ exp = (T.mant_dig + 11 - 1) - exp; // mant_dig is really 64
else
- y.vu[pos--] = 0;
- exp -= 16;
- }
+ exp = (T.mant_dig - 1) - exp;
+
+ // Zero 16 bits at a time.
+ while (exp >= 16)
+ {
+ version (LittleEndian)
+ y.vu[pos++] = 0;
+ else
+ y.vu[pos--] = 0;
+ exp -= 16;
+ }
- // Clear the remaining bits.
- if (exp > 0)
- y.vu[pos] &= 0xffff ^ ((1 << exp) - 1);
+ // Clear the remaining bits.
+ if (exp > 0)
+ y.vu[pos] &= 0xffff ^ ((1 << exp) - 1);
- if ((x < 0.0) && (x != y.rv))
- y.rv -= 1.0;
- }
+ if ((x < 0.0) && (x != y.rv))
+ y.rv -= 1.0;
+ }
- return y.rv;
+ return y.rv;
+ }
}
public:
@@ -1767,6 +1777,13 @@ real exp(real x) @trusted pure nothrow @nogc
else
{
alias F = floatTraits!real;
+ static if (F.realFormat == RealFormat.ibmExtended)
+ {
+ import gcc.builtins;
+ return __builtin_expl(x);
+ }
+ else
+ {
static if (F.realFormat == RealFormat.ieeeDouble)
{
// Coefficients for exp(x)
@@ -1872,6 +1889,7 @@ real exp(real x) @trusted pure nothrow @nogc
return x;
}
+ }
}
/// ditto
@@ -3897,7 +3915,8 @@ real hypot(real x, real y) @safe pure nothrow @nogc
static assert(2*(SQRTMAX/2)*(SQRTMAX/2) <= real.max);
// Proves that sqrt(real.max) ~~ 0.5/sqrt(real.min_normal)
- static assert(real.min_normal*real.max > 2 && real.min_normal*real.max <= 4);
+ static assert((real.min_normal*real.max > 2 && real.min_normal*real.max <= 4)
+ || floatTraits!real.realFormat == RealFormat.ibmExtended);
real u = fabs(x);
real v = fabs(y);
@@ -4524,7 +4543,7 @@ long lrint(real x) @trusted pure nothrow @nogc
}
else
{
- static assert(false, "real type not supported by lrint()");
+ assert(false, "real type not supported by lrint()");
}
}
}
^ permalink raw reply [flat|nested] 8+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] D, Math, IBM128 : Use GCC builtins for floor and exp.
@ 2021-09-17 14:35 Iain Buclaw
0 siblings, 0 replies; 8+ messages in thread
From: Iain Buclaw @ 2021-09-17 14:35 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:fb06e91ebcc6e61f67518f481499f9e25eeb9b76
commit fb06e91ebcc6e61f67518f481499f9e25eeb9b76
Author: Iain Sandoe <iain@sandoe.co.uk>
Date: Fri Dec 11 00:59:19 2020 +0000
D, Math, IBM128 : Use GCC builtins for floor and exp.
This makes use of GCC's long double format builtins, which
in turn will call out to a libc implementation where needed.
Diff:
---
libphobos/src/std/math.d | 183 ++++++++++++++++++++++++++---------------------
1 file changed, 101 insertions(+), 82 deletions(-)
diff --git a/libphobos/src/std/math.d b/libphobos/src/std/math.d
index 336c11a55e2..0aecbc42388 100644
--- a/libphobos/src/std/math.d
+++ b/libphobos/src/std/math.d
@@ -460,108 +460,118 @@ else
T floorImpl(T)(const T x) @trusted pure nothrow @nogc
{
alias F = floatTraits!(T);
- // Take care not to trigger library calls from the compiler,
- // while ensuring that we don't get defeated by some optimizers.
- union floatBits
- {
- T rv;
- ushort[T.sizeof/2] vu;
- // Other kinds of extractors for real formats.
- static if (F.realFormat == RealFormat.ieeeSingle)
- int vi;
- }
- floatBits y = void;
- y.rv = x;
-
- // Find the exponent (power of 2)
- // Do this by shifting the raw value so that the exponent lies in the low bits,
- // then mask out the sign bit, and subtract the bias.
- static if (F.realFormat == RealFormat.ieeeSingle)
+ static if (F.realFormat == RealFormat.ibmExtended)
{
- int exp = ((y.vi >> (T.mant_dig - 1)) & 0xff) - 0x7f;
+ import gcc.builtins;
+ return __builtin_floorl(x);
}
- else static if (F.realFormat == RealFormat.ieeeDouble)
+ else
{
- int exp = ((y.vu[F.EXPPOS_SHORT] >> 4) & 0x7ff) - 0x3ff;
+ // Take care not to trigger library calls from the compiler,
+ // while ensuring that we don't get defeated by some optimizers.
+ union floatBits
+ {
+ T rv;
+ ushort[T.sizeof/2] vu;
- version (LittleEndian)
- int pos = 0;
- else
- int pos = 3;
- }
- else static if (F.realFormat == RealFormat.ieeeExtended ||
- F.realFormat == RealFormat.ieeeExtended53)
- {
- int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
+ // Other kinds of extractors for real formats.
+ static if (F.realFormat == RealFormat.ieeeSingle)
+ int vi;
+ }
+ floatBits y = void;
+ y.rv = x;
- version (LittleEndian)
- int pos = 0;
- else
- int pos = 4;
- }
- else static if (F.realFormat == RealFormat.ieeeQuadruple)
- {
- int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
+ // Find the exponent (power of 2)
+ // Do this by shifting the raw value so that the exponent lies in the
+ // low bits, then mask out the sign bit, and subtract the bias.
+ static if (F.realFormat == RealFormat.ieeeSingle)
+ {
+ int exp = ((y.vi >> (T.mant_dig - 1)) & 0xff) - 0x7f;
+ }
+ else static if (F.realFormat == RealFormat.ieeeDouble)
+ {
+ int exp = ((y.vu[F.EXPPOS_SHORT] >> 4) & 0x7ff) - 0x3ff;
- version (LittleEndian)
- int pos = 0;
- else
- int pos = 7;
+ version (LittleEndian)
+ int pos = 0;
+ else
+ int pos = 3;
}
- else
- static assert(false, "Not implemented for this architecture");
+ else static if (F.realFormat == RealFormat.ieeeExtended ||
+ F.realFormat == RealFormat.ieeeExtended53)
+ {
+ int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
- if (exp < 0)
- {
- if (x < 0.0)
- return -1.0;
+ version (LittleEndian)
+ int pos = 0;
+ else
+ int pos = 4;
+ }
+ else static if (F.realFormat == RealFormat.ieeeQuadruple)
+ {
+ int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
+
+ version (LittleEndian)
+ int pos = 0;
+ else
+ int pos = 7;
+ }
else
- return 0.0;
- }
+ static assert(false, "Not implemented for this architecture");
- static if (F.realFormat == RealFormat.ieeeSingle)
- {
- if (exp < (T.mant_dig - 1))
+ if (exp < 0)
{
- // Clear all bits representing the fraction part.
- const uint fraction_mask = F.MANTISSAMASK_INT >> exp;
+ if (x < 0.0)
+ return -1.0;
+ else
+ return 0.0;
+ }
- if ((y.vi & fraction_mask) != 0)
+ static if (F.realFormat == RealFormat.ieeeSingle)
+ {
+ if (exp < (T.mant_dig - 1))
{
- // If 'x' is negative, then first substract 1.0 from the value.
- if (y.vi < 0)
- y.vi += 0x00800000 >> exp;
- y.vi &= ~fraction_mask;
+ // Clear all bits representing the fraction part.
+ const uint fraction_mask = F.MANTISSAMASK_INT >> exp;
+
+ if ((y.vi & fraction_mask) != 0)
+ {
+ // If 'x' is negative, then first substract 1.0 from
+ // the value.
+ if (y.vi < 0)
+ y.vi += 0x00800000 >> exp;
+ y.vi &= ~fraction_mask;
+ }
}
}
- }
- else
- {
- static if (F.realFormat == RealFormat.ieeeExtended53)
- exp = (T.mant_dig + 11 - 1) - exp; // mant_dig is really 64
else
- exp = (T.mant_dig - 1) - exp;
-
- // Zero 16 bits at a time.
- while (exp >= 16)
{
- version (LittleEndian)
- y.vu[pos++] = 0;
+ static if (F.realFormat == RealFormat.ieeeExtended53)
+ exp = (T.mant_dig + 11 - 1) - exp; // mant_dig is really 64
else
- y.vu[pos--] = 0;
- exp -= 16;
- }
+ exp = (T.mant_dig - 1) - exp;
+
+ // Zero 16 bits at a time.
+ while (exp >= 16)
+ {
+ version (LittleEndian)
+ y.vu[pos++] = 0;
+ else
+ y.vu[pos--] = 0;
+ exp -= 16;
+ }
- // Clear the remaining bits.
- if (exp > 0)
- y.vu[pos] &= 0xffff ^ ((1 << exp) - 1);
+ // Clear the remaining bits.
+ if (exp > 0)
+ y.vu[pos] &= 0xffff ^ ((1 << exp) - 1);
- if ((x < 0.0) && (x != y.rv))
- y.rv -= 1.0;
- }
+ if ((x < 0.0) && (x != y.rv))
+ y.rv -= 1.0;
+ }
- return y.rv;
+ return y.rv;
+ }
}
public:
@@ -1767,6 +1777,13 @@ real exp(real x) @trusted pure nothrow @nogc
else
{
alias F = floatTraits!real;
+ static if (F.realFormat == RealFormat.ibmExtended)
+ {
+ import gcc.builtins;
+ return __builtin_expl(x);
+ }
+ else
+ {
static if (F.realFormat == RealFormat.ieeeDouble)
{
// Coefficients for exp(x)
@@ -1872,6 +1889,7 @@ real exp(real x) @trusted pure nothrow @nogc
return x;
}
+ }
}
/// ditto
@@ -3897,7 +3915,8 @@ real hypot(real x, real y) @safe pure nothrow @nogc
static assert(2*(SQRTMAX/2)*(SQRTMAX/2) <= real.max);
// Proves that sqrt(real.max) ~~ 0.5/sqrt(real.min_normal)
- static assert(real.min_normal*real.max > 2 && real.min_normal*real.max <= 4);
+ static assert((real.min_normal*real.max > 2 && real.min_normal*real.max <= 4)
+ || floatTraits!real.realFormat == RealFormat.ibmExtended);
real u = fabs(x);
real v = fabs(y);
@@ -4524,7 +4543,7 @@ long lrint(real x) @trusted pure nothrow @nogc
}
else
{
- static assert(false, "real type not supported by lrint()");
+ assert(false, "real type not supported by lrint()");
}
}
}
^ permalink raw reply [flat|nested] 8+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] D, Math, IBM128 : Use GCC builtins for floor and exp.
@ 2021-04-19 18:06 Iain Buclaw
0 siblings, 0 replies; 8+ messages in thread
From: Iain Buclaw @ 2021-04-19 18:06 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:848073267d5aaf027a9843a76f24c115b9524d91
commit 848073267d5aaf027a9843a76f24c115b9524d91
Author: Iain Sandoe <iain@sandoe.co.uk>
Date: Fri Dec 11 00:59:19 2020 +0000
D, Math, IBM128 : Use GCC builtins for floor and exp.
This makes use of GCC's long double format builtins, which
in turn will call out to a libc implementation where needed.
Diff:
---
libphobos/src/std/math.d | 183 ++++++++++++++++++++++++++---------------------
1 file changed, 101 insertions(+), 82 deletions(-)
diff --git a/libphobos/src/std/math.d b/libphobos/src/std/math.d
index 336c11a55e2..0aecbc42388 100644
--- a/libphobos/src/std/math.d
+++ b/libphobos/src/std/math.d
@@ -460,108 +460,118 @@ else
T floorImpl(T)(const T x) @trusted pure nothrow @nogc
{
alias F = floatTraits!(T);
- // Take care not to trigger library calls from the compiler,
- // while ensuring that we don't get defeated by some optimizers.
- union floatBits
- {
- T rv;
- ushort[T.sizeof/2] vu;
- // Other kinds of extractors for real formats.
- static if (F.realFormat == RealFormat.ieeeSingle)
- int vi;
- }
- floatBits y = void;
- y.rv = x;
-
- // Find the exponent (power of 2)
- // Do this by shifting the raw value so that the exponent lies in the low bits,
- // then mask out the sign bit, and subtract the bias.
- static if (F.realFormat == RealFormat.ieeeSingle)
+ static if (F.realFormat == RealFormat.ibmExtended)
{
- int exp = ((y.vi >> (T.mant_dig - 1)) & 0xff) - 0x7f;
+ import gcc.builtins;
+ return __builtin_floorl(x);
}
- else static if (F.realFormat == RealFormat.ieeeDouble)
+ else
{
- int exp = ((y.vu[F.EXPPOS_SHORT] >> 4) & 0x7ff) - 0x3ff;
+ // Take care not to trigger library calls from the compiler,
+ // while ensuring that we don't get defeated by some optimizers.
+ union floatBits
+ {
+ T rv;
+ ushort[T.sizeof/2] vu;
- version (LittleEndian)
- int pos = 0;
- else
- int pos = 3;
- }
- else static if (F.realFormat == RealFormat.ieeeExtended ||
- F.realFormat == RealFormat.ieeeExtended53)
- {
- int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
+ // Other kinds of extractors for real formats.
+ static if (F.realFormat == RealFormat.ieeeSingle)
+ int vi;
+ }
+ floatBits y = void;
+ y.rv = x;
- version (LittleEndian)
- int pos = 0;
- else
- int pos = 4;
- }
- else static if (F.realFormat == RealFormat.ieeeQuadruple)
- {
- int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
+ // Find the exponent (power of 2)
+ // Do this by shifting the raw value so that the exponent lies in the
+ // low bits, then mask out the sign bit, and subtract the bias.
+ static if (F.realFormat == RealFormat.ieeeSingle)
+ {
+ int exp = ((y.vi >> (T.mant_dig - 1)) & 0xff) - 0x7f;
+ }
+ else static if (F.realFormat == RealFormat.ieeeDouble)
+ {
+ int exp = ((y.vu[F.EXPPOS_SHORT] >> 4) & 0x7ff) - 0x3ff;
- version (LittleEndian)
- int pos = 0;
- else
- int pos = 7;
+ version (LittleEndian)
+ int pos = 0;
+ else
+ int pos = 3;
}
- else
- static assert(false, "Not implemented for this architecture");
+ else static if (F.realFormat == RealFormat.ieeeExtended ||
+ F.realFormat == RealFormat.ieeeExtended53)
+ {
+ int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
- if (exp < 0)
- {
- if (x < 0.0)
- return -1.0;
+ version (LittleEndian)
+ int pos = 0;
+ else
+ int pos = 4;
+ }
+ else static if (F.realFormat == RealFormat.ieeeQuadruple)
+ {
+ int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
+
+ version (LittleEndian)
+ int pos = 0;
+ else
+ int pos = 7;
+ }
else
- return 0.0;
- }
+ static assert(false, "Not implemented for this architecture");
- static if (F.realFormat == RealFormat.ieeeSingle)
- {
- if (exp < (T.mant_dig - 1))
+ if (exp < 0)
{
- // Clear all bits representing the fraction part.
- const uint fraction_mask = F.MANTISSAMASK_INT >> exp;
+ if (x < 0.0)
+ return -1.0;
+ else
+ return 0.0;
+ }
- if ((y.vi & fraction_mask) != 0)
+ static if (F.realFormat == RealFormat.ieeeSingle)
+ {
+ if (exp < (T.mant_dig - 1))
{
- // If 'x' is negative, then first substract 1.0 from the value.
- if (y.vi < 0)
- y.vi += 0x00800000 >> exp;
- y.vi &= ~fraction_mask;
+ // Clear all bits representing the fraction part.
+ const uint fraction_mask = F.MANTISSAMASK_INT >> exp;
+
+ if ((y.vi & fraction_mask) != 0)
+ {
+ // If 'x' is negative, then first substract 1.0 from
+ // the value.
+ if (y.vi < 0)
+ y.vi += 0x00800000 >> exp;
+ y.vi &= ~fraction_mask;
+ }
}
}
- }
- else
- {
- static if (F.realFormat == RealFormat.ieeeExtended53)
- exp = (T.mant_dig + 11 - 1) - exp; // mant_dig is really 64
else
- exp = (T.mant_dig - 1) - exp;
-
- // Zero 16 bits at a time.
- while (exp >= 16)
{
- version (LittleEndian)
- y.vu[pos++] = 0;
+ static if (F.realFormat == RealFormat.ieeeExtended53)
+ exp = (T.mant_dig + 11 - 1) - exp; // mant_dig is really 64
else
- y.vu[pos--] = 0;
- exp -= 16;
- }
+ exp = (T.mant_dig - 1) - exp;
+
+ // Zero 16 bits at a time.
+ while (exp >= 16)
+ {
+ version (LittleEndian)
+ y.vu[pos++] = 0;
+ else
+ y.vu[pos--] = 0;
+ exp -= 16;
+ }
- // Clear the remaining bits.
- if (exp > 0)
- y.vu[pos] &= 0xffff ^ ((1 << exp) - 1);
+ // Clear the remaining bits.
+ if (exp > 0)
+ y.vu[pos] &= 0xffff ^ ((1 << exp) - 1);
- if ((x < 0.0) && (x != y.rv))
- y.rv -= 1.0;
- }
+ if ((x < 0.0) && (x != y.rv))
+ y.rv -= 1.0;
+ }
- return y.rv;
+ return y.rv;
+ }
}
public:
@@ -1767,6 +1777,13 @@ real exp(real x) @trusted pure nothrow @nogc
else
{
alias F = floatTraits!real;
+ static if (F.realFormat == RealFormat.ibmExtended)
+ {
+ import gcc.builtins;
+ return __builtin_expl(x);
+ }
+ else
+ {
static if (F.realFormat == RealFormat.ieeeDouble)
{
// Coefficients for exp(x)
@@ -1872,6 +1889,7 @@ real exp(real x) @trusted pure nothrow @nogc
return x;
}
+ }
}
/// ditto
@@ -3897,7 +3915,8 @@ real hypot(real x, real y) @safe pure nothrow @nogc
static assert(2*(SQRTMAX/2)*(SQRTMAX/2) <= real.max);
// Proves that sqrt(real.max) ~~ 0.5/sqrt(real.min_normal)
- static assert(real.min_normal*real.max > 2 && real.min_normal*real.max <= 4);
+ static assert((real.min_normal*real.max > 2 && real.min_normal*real.max <= 4)
+ || floatTraits!real.realFormat == RealFormat.ibmExtended);
real u = fabs(x);
real v = fabs(y);
@@ -4524,7 +4543,7 @@ long lrint(real x) @trusted pure nothrow @nogc
}
else
{
- static assert(false, "real type not supported by lrint()");
+ assert(false, "real type not supported by lrint()");
}
}
}
^ permalink raw reply [flat|nested] 8+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] D, Math, IBM128 : Use GCC builtins for floor and exp.
@ 2021-04-10 17:02 Iain Buclaw
0 siblings, 0 replies; 8+ messages in thread
From: Iain Buclaw @ 2021-04-10 17:02 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:21e01521b1ad706604f31e5c8210b883cd1b7461
commit 21e01521b1ad706604f31e5c8210b883cd1b7461
Author: Iain Sandoe <iain@sandoe.co.uk>
Date: Fri Dec 11 00:59:19 2020 +0000
D, Math, IBM128 : Use GCC builtins for floor and exp.
This makes use of GCC's long double format builtins, which
in turn will call out to a libc implementation where needed.
Diff:
---
libphobos/src/std/math.d | 183 ++++++++++++++++++++++++++---------------------
1 file changed, 101 insertions(+), 82 deletions(-)
diff --git a/libphobos/src/std/math.d b/libphobos/src/std/math.d
index 336c11a55e2..0aecbc42388 100644
--- a/libphobos/src/std/math.d
+++ b/libphobos/src/std/math.d
@@ -460,108 +460,118 @@ else
T floorImpl(T)(const T x) @trusted pure nothrow @nogc
{
alias F = floatTraits!(T);
- // Take care not to trigger library calls from the compiler,
- // while ensuring that we don't get defeated by some optimizers.
- union floatBits
- {
- T rv;
- ushort[T.sizeof/2] vu;
- // Other kinds of extractors for real formats.
- static if (F.realFormat == RealFormat.ieeeSingle)
- int vi;
- }
- floatBits y = void;
- y.rv = x;
-
- // Find the exponent (power of 2)
- // Do this by shifting the raw value so that the exponent lies in the low bits,
- // then mask out the sign bit, and subtract the bias.
- static if (F.realFormat == RealFormat.ieeeSingle)
+ static if (F.realFormat == RealFormat.ibmExtended)
{
- int exp = ((y.vi >> (T.mant_dig - 1)) & 0xff) - 0x7f;
+ import gcc.builtins;
+ return __builtin_floorl(x);
}
- else static if (F.realFormat == RealFormat.ieeeDouble)
+ else
{
- int exp = ((y.vu[F.EXPPOS_SHORT] >> 4) & 0x7ff) - 0x3ff;
+ // Take care not to trigger library calls from the compiler,
+ // while ensuring that we don't get defeated by some optimizers.
+ union floatBits
+ {
+ T rv;
+ ushort[T.sizeof/2] vu;
- version (LittleEndian)
- int pos = 0;
- else
- int pos = 3;
- }
- else static if (F.realFormat == RealFormat.ieeeExtended ||
- F.realFormat == RealFormat.ieeeExtended53)
- {
- int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
+ // Other kinds of extractors for real formats.
+ static if (F.realFormat == RealFormat.ieeeSingle)
+ int vi;
+ }
+ floatBits y = void;
+ y.rv = x;
- version (LittleEndian)
- int pos = 0;
- else
- int pos = 4;
- }
- else static if (F.realFormat == RealFormat.ieeeQuadruple)
- {
- int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
+ // Find the exponent (power of 2)
+ // Do this by shifting the raw value so that the exponent lies in the
+ // low bits, then mask out the sign bit, and subtract the bias.
+ static if (F.realFormat == RealFormat.ieeeSingle)
+ {
+ int exp = ((y.vi >> (T.mant_dig - 1)) & 0xff) - 0x7f;
+ }
+ else static if (F.realFormat == RealFormat.ieeeDouble)
+ {
+ int exp = ((y.vu[F.EXPPOS_SHORT] >> 4) & 0x7ff) - 0x3ff;
- version (LittleEndian)
- int pos = 0;
- else
- int pos = 7;
+ version (LittleEndian)
+ int pos = 0;
+ else
+ int pos = 3;
}
- else
- static assert(false, "Not implemented for this architecture");
+ else static if (F.realFormat == RealFormat.ieeeExtended ||
+ F.realFormat == RealFormat.ieeeExtended53)
+ {
+ int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
- if (exp < 0)
- {
- if (x < 0.0)
- return -1.0;
+ version (LittleEndian)
+ int pos = 0;
+ else
+ int pos = 4;
+ }
+ else static if (F.realFormat == RealFormat.ieeeQuadruple)
+ {
+ int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
+
+ version (LittleEndian)
+ int pos = 0;
+ else
+ int pos = 7;
+ }
else
- return 0.0;
- }
+ static assert(false, "Not implemented for this architecture");
- static if (F.realFormat == RealFormat.ieeeSingle)
- {
- if (exp < (T.mant_dig - 1))
+ if (exp < 0)
{
- // Clear all bits representing the fraction part.
- const uint fraction_mask = F.MANTISSAMASK_INT >> exp;
+ if (x < 0.0)
+ return -1.0;
+ else
+ return 0.0;
+ }
- if ((y.vi & fraction_mask) != 0)
+ static if (F.realFormat == RealFormat.ieeeSingle)
+ {
+ if (exp < (T.mant_dig - 1))
{
- // If 'x' is negative, then first substract 1.0 from the value.
- if (y.vi < 0)
- y.vi += 0x00800000 >> exp;
- y.vi &= ~fraction_mask;
+ // Clear all bits representing the fraction part.
+ const uint fraction_mask = F.MANTISSAMASK_INT >> exp;
+
+ if ((y.vi & fraction_mask) != 0)
+ {
+ // If 'x' is negative, then first substract 1.0 from
+ // the value.
+ if (y.vi < 0)
+ y.vi += 0x00800000 >> exp;
+ y.vi &= ~fraction_mask;
+ }
}
}
- }
- else
- {
- static if (F.realFormat == RealFormat.ieeeExtended53)
- exp = (T.mant_dig + 11 - 1) - exp; // mant_dig is really 64
else
- exp = (T.mant_dig - 1) - exp;
-
- // Zero 16 bits at a time.
- while (exp >= 16)
{
- version (LittleEndian)
- y.vu[pos++] = 0;
+ static if (F.realFormat == RealFormat.ieeeExtended53)
+ exp = (T.mant_dig + 11 - 1) - exp; // mant_dig is really 64
else
- y.vu[pos--] = 0;
- exp -= 16;
- }
+ exp = (T.mant_dig - 1) - exp;
+
+ // Zero 16 bits at a time.
+ while (exp >= 16)
+ {
+ version (LittleEndian)
+ y.vu[pos++] = 0;
+ else
+ y.vu[pos--] = 0;
+ exp -= 16;
+ }
- // Clear the remaining bits.
- if (exp > 0)
- y.vu[pos] &= 0xffff ^ ((1 << exp) - 1);
+ // Clear the remaining bits.
+ if (exp > 0)
+ y.vu[pos] &= 0xffff ^ ((1 << exp) - 1);
- if ((x < 0.0) && (x != y.rv))
- y.rv -= 1.0;
- }
+ if ((x < 0.0) && (x != y.rv))
+ y.rv -= 1.0;
+ }
- return y.rv;
+ return y.rv;
+ }
}
public:
@@ -1767,6 +1777,13 @@ real exp(real x) @trusted pure nothrow @nogc
else
{
alias F = floatTraits!real;
+ static if (F.realFormat == RealFormat.ibmExtended)
+ {
+ import gcc.builtins;
+ return __builtin_expl(x);
+ }
+ else
+ {
static if (F.realFormat == RealFormat.ieeeDouble)
{
// Coefficients for exp(x)
@@ -1872,6 +1889,7 @@ real exp(real x) @trusted pure nothrow @nogc
return x;
}
+ }
}
/// ditto
@@ -3897,7 +3915,8 @@ real hypot(real x, real y) @safe pure nothrow @nogc
static assert(2*(SQRTMAX/2)*(SQRTMAX/2) <= real.max);
// Proves that sqrt(real.max) ~~ 0.5/sqrt(real.min_normal)
- static assert(real.min_normal*real.max > 2 && real.min_normal*real.max <= 4);
+ static assert((real.min_normal*real.max > 2 && real.min_normal*real.max <= 4)
+ || floatTraits!real.realFormat == RealFormat.ibmExtended);
real u = fabs(x);
real v = fabs(y);
@@ -4524,7 +4543,7 @@ long lrint(real x) @trusted pure nothrow @nogc
}
else
{
- static assert(false, "real type not supported by lrint()");
+ assert(false, "real type not supported by lrint()");
}
}
}
^ permalink raw reply [flat|nested] 8+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] D, Math, IBM128 : Use GCC builtins for floor and exp.
@ 2021-04-10 15:05 Iain Buclaw
0 siblings, 0 replies; 8+ messages in thread
From: Iain Buclaw @ 2021-04-10 15:05 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:6a516c1da2d719f2c81451028fceaabfd2cfce46
commit 6a516c1da2d719f2c81451028fceaabfd2cfce46
Author: Iain Sandoe <iain@sandoe.co.uk>
Date: Fri Dec 11 00:59:19 2020 +0000
D, Math, IBM128 : Use GCC builtins for floor and exp.
This makes use of GCC's long double format builtins, which
in turn will call out to a libc implementation where needed.
Diff:
---
libphobos/src/std/math.d | 183 ++++++++++++++++++++++++++---------------------
1 file changed, 101 insertions(+), 82 deletions(-)
diff --git a/libphobos/src/std/math.d b/libphobos/src/std/math.d
index 336c11a55e2..0aecbc42388 100644
--- a/libphobos/src/std/math.d
+++ b/libphobos/src/std/math.d
@@ -460,108 +460,118 @@ else
T floorImpl(T)(const T x) @trusted pure nothrow @nogc
{
alias F = floatTraits!(T);
- // Take care not to trigger library calls from the compiler,
- // while ensuring that we don't get defeated by some optimizers.
- union floatBits
- {
- T rv;
- ushort[T.sizeof/2] vu;
- // Other kinds of extractors for real formats.
- static if (F.realFormat == RealFormat.ieeeSingle)
- int vi;
- }
- floatBits y = void;
- y.rv = x;
-
- // Find the exponent (power of 2)
- // Do this by shifting the raw value so that the exponent lies in the low bits,
- // then mask out the sign bit, and subtract the bias.
- static if (F.realFormat == RealFormat.ieeeSingle)
+ static if (F.realFormat == RealFormat.ibmExtended)
{
- int exp = ((y.vi >> (T.mant_dig - 1)) & 0xff) - 0x7f;
+ import gcc.builtins;
+ return __builtin_floorl(x);
}
- else static if (F.realFormat == RealFormat.ieeeDouble)
+ else
{
- int exp = ((y.vu[F.EXPPOS_SHORT] >> 4) & 0x7ff) - 0x3ff;
+ // Take care not to trigger library calls from the compiler,
+ // while ensuring that we don't get defeated by some optimizers.
+ union floatBits
+ {
+ T rv;
+ ushort[T.sizeof/2] vu;
- version (LittleEndian)
- int pos = 0;
- else
- int pos = 3;
- }
- else static if (F.realFormat == RealFormat.ieeeExtended ||
- F.realFormat == RealFormat.ieeeExtended53)
- {
- int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
+ // Other kinds of extractors for real formats.
+ static if (F.realFormat == RealFormat.ieeeSingle)
+ int vi;
+ }
+ floatBits y = void;
+ y.rv = x;
- version (LittleEndian)
- int pos = 0;
- else
- int pos = 4;
- }
- else static if (F.realFormat == RealFormat.ieeeQuadruple)
- {
- int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
+ // Find the exponent (power of 2)
+ // Do this by shifting the raw value so that the exponent lies in the
+ // low bits, then mask out the sign bit, and subtract the bias.
+ static if (F.realFormat == RealFormat.ieeeSingle)
+ {
+ int exp = ((y.vi >> (T.mant_dig - 1)) & 0xff) - 0x7f;
+ }
+ else static if (F.realFormat == RealFormat.ieeeDouble)
+ {
+ int exp = ((y.vu[F.EXPPOS_SHORT] >> 4) & 0x7ff) - 0x3ff;
- version (LittleEndian)
- int pos = 0;
- else
- int pos = 7;
+ version (LittleEndian)
+ int pos = 0;
+ else
+ int pos = 3;
}
- else
- static assert(false, "Not implemented for this architecture");
+ else static if (F.realFormat == RealFormat.ieeeExtended ||
+ F.realFormat == RealFormat.ieeeExtended53)
+ {
+ int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
- if (exp < 0)
- {
- if (x < 0.0)
- return -1.0;
+ version (LittleEndian)
+ int pos = 0;
+ else
+ int pos = 4;
+ }
+ else static if (F.realFormat == RealFormat.ieeeQuadruple)
+ {
+ int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
+
+ version (LittleEndian)
+ int pos = 0;
+ else
+ int pos = 7;
+ }
else
- return 0.0;
- }
+ static assert(false, "Not implemented for this architecture");
- static if (F.realFormat == RealFormat.ieeeSingle)
- {
- if (exp < (T.mant_dig - 1))
+ if (exp < 0)
{
- // Clear all bits representing the fraction part.
- const uint fraction_mask = F.MANTISSAMASK_INT >> exp;
+ if (x < 0.0)
+ return -1.0;
+ else
+ return 0.0;
+ }
- if ((y.vi & fraction_mask) != 0)
+ static if (F.realFormat == RealFormat.ieeeSingle)
+ {
+ if (exp < (T.mant_dig - 1))
{
- // If 'x' is negative, then first substract 1.0 from the value.
- if (y.vi < 0)
- y.vi += 0x00800000 >> exp;
- y.vi &= ~fraction_mask;
+ // Clear all bits representing the fraction part.
+ const uint fraction_mask = F.MANTISSAMASK_INT >> exp;
+
+ if ((y.vi & fraction_mask) != 0)
+ {
+ // If 'x' is negative, then first substract 1.0 from
+ // the value.
+ if (y.vi < 0)
+ y.vi += 0x00800000 >> exp;
+ y.vi &= ~fraction_mask;
+ }
}
}
- }
- else
- {
- static if (F.realFormat == RealFormat.ieeeExtended53)
- exp = (T.mant_dig + 11 - 1) - exp; // mant_dig is really 64
else
- exp = (T.mant_dig - 1) - exp;
-
- // Zero 16 bits at a time.
- while (exp >= 16)
{
- version (LittleEndian)
- y.vu[pos++] = 0;
+ static if (F.realFormat == RealFormat.ieeeExtended53)
+ exp = (T.mant_dig + 11 - 1) - exp; // mant_dig is really 64
else
- y.vu[pos--] = 0;
- exp -= 16;
- }
+ exp = (T.mant_dig - 1) - exp;
+
+ // Zero 16 bits at a time.
+ while (exp >= 16)
+ {
+ version (LittleEndian)
+ y.vu[pos++] = 0;
+ else
+ y.vu[pos--] = 0;
+ exp -= 16;
+ }
- // Clear the remaining bits.
- if (exp > 0)
- y.vu[pos] &= 0xffff ^ ((1 << exp) - 1);
+ // Clear the remaining bits.
+ if (exp > 0)
+ y.vu[pos] &= 0xffff ^ ((1 << exp) - 1);
- if ((x < 0.0) && (x != y.rv))
- y.rv -= 1.0;
- }
+ if ((x < 0.0) && (x != y.rv))
+ y.rv -= 1.0;
+ }
- return y.rv;
+ return y.rv;
+ }
}
public:
@@ -1767,6 +1777,13 @@ real exp(real x) @trusted pure nothrow @nogc
else
{
alias F = floatTraits!real;
+ static if (F.realFormat == RealFormat.ibmExtended)
+ {
+ import gcc.builtins;
+ return __builtin_expl(x);
+ }
+ else
+ {
static if (F.realFormat == RealFormat.ieeeDouble)
{
// Coefficients for exp(x)
@@ -1872,6 +1889,7 @@ real exp(real x) @trusted pure nothrow @nogc
return x;
}
+ }
}
/// ditto
@@ -3897,7 +3915,8 @@ real hypot(real x, real y) @safe pure nothrow @nogc
static assert(2*(SQRTMAX/2)*(SQRTMAX/2) <= real.max);
// Proves that sqrt(real.max) ~~ 0.5/sqrt(real.min_normal)
- static assert(real.min_normal*real.max > 2 && real.min_normal*real.max <= 4);
+ static assert((real.min_normal*real.max > 2 && real.min_normal*real.max <= 4)
+ || floatTraits!real.realFormat == RealFormat.ibmExtended);
real u = fabs(x);
real v = fabs(y);
@@ -4524,7 +4543,7 @@ long lrint(real x) @trusted pure nothrow @nogc
}
else
{
- static assert(false, "real type not supported by lrint()");
+ assert(false, "real type not supported by lrint()");
}
}
}
^ permalink raw reply [flat|nested] 8+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] D, Math, IBM128 : Use GCC builtins for floor and exp.
@ 2021-03-07 17:03 Iain Buclaw
0 siblings, 0 replies; 8+ messages in thread
From: Iain Buclaw @ 2021-03-07 17:03 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:0d0d4867ab314d41d5942f2bdae8b5032c95f966
commit 0d0d4867ab314d41d5942f2bdae8b5032c95f966
Author: Iain Sandoe <iain@sandoe.co.uk>
Date: Fri Dec 11 00:59:19 2020 +0000
D, Math, IBM128 : Use GCC builtins for floor and exp.
This makes use of GCC's long double format builtins, which
in turn will call out to a libc implementation where needed.
Diff:
---
libphobos/src/std/math.d | 183 ++++++++++++++++++++++++++---------------------
1 file changed, 101 insertions(+), 82 deletions(-)
diff --git a/libphobos/src/std/math.d b/libphobos/src/std/math.d
index ff368b79f9d..ac4a93d313b 100644
--- a/libphobos/src/std/math.d
+++ b/libphobos/src/std/math.d
@@ -460,108 +460,118 @@ else
T floorImpl(T)(const T x) @trusted pure nothrow @nogc
{
alias F = floatTraits!(T);
- // Take care not to trigger library calls from the compiler,
- // while ensuring that we don't get defeated by some optimizers.
- union floatBits
- {
- T rv;
- ushort[T.sizeof/2] vu;
- // Other kinds of extractors for real formats.
- static if (F.realFormat == RealFormat.ieeeSingle)
- int vi;
- }
- floatBits y = void;
- y.rv = x;
-
- // Find the exponent (power of 2)
- // Do this by shifting the raw value so that the exponent lies in the low bits,
- // then mask out the sign bit, and subtract the bias.
- static if (F.realFormat == RealFormat.ieeeSingle)
+ static if (F.realFormat == RealFormat.ibmExtended)
{
- int exp = ((y.vi >> (T.mant_dig - 1)) & 0xff) - 0x7f;
+ import gcc.builtins;
+ return __builtin_floorl(x);
}
- else static if (F.realFormat == RealFormat.ieeeDouble)
+ else
{
- int exp = ((y.vu[F.EXPPOS_SHORT] >> 4) & 0x7ff) - 0x3ff;
+ // Take care not to trigger library calls from the compiler,
+ // while ensuring that we don't get defeated by some optimizers.
+ union floatBits
+ {
+ T rv;
+ ushort[T.sizeof/2] vu;
- version (LittleEndian)
- int pos = 0;
- else
- int pos = 3;
- }
- else static if (F.realFormat == RealFormat.ieeeExtended ||
- F.realFormat == RealFormat.ieeeExtended53)
- {
- int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
+ // Other kinds of extractors for real formats.
+ static if (F.realFormat == RealFormat.ieeeSingle)
+ int vi;
+ }
+ floatBits y = void;
+ y.rv = x;
- version (LittleEndian)
- int pos = 0;
- else
- int pos = 4;
- }
- else static if (F.realFormat == RealFormat.ieeeQuadruple)
- {
- int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
+ // Find the exponent (power of 2)
+ // Do this by shifting the raw value so that the exponent lies in the
+ // low bits, then mask out the sign bit, and subtract the bias.
+ static if (F.realFormat == RealFormat.ieeeSingle)
+ {
+ int exp = ((y.vi >> (T.mant_dig - 1)) & 0xff) - 0x7f;
+ }
+ else static if (F.realFormat == RealFormat.ieeeDouble)
+ {
+ int exp = ((y.vu[F.EXPPOS_SHORT] >> 4) & 0x7ff) - 0x3ff;
- version (LittleEndian)
- int pos = 0;
- else
- int pos = 7;
+ version (LittleEndian)
+ int pos = 0;
+ else
+ int pos = 3;
}
- else
- static assert(false, "Not implemented for this architecture");
+ else static if (F.realFormat == RealFormat.ieeeExtended ||
+ F.realFormat == RealFormat.ieeeExtended53)
+ {
+ int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
- if (exp < 0)
- {
- if (x < 0.0)
- return -1.0;
+ version (LittleEndian)
+ int pos = 0;
+ else
+ int pos = 4;
+ }
+ else static if (F.realFormat == RealFormat.ieeeQuadruple)
+ {
+ int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
+
+ version (LittleEndian)
+ int pos = 0;
+ else
+ int pos = 7;
+ }
else
- return 0.0;
- }
+ static assert(false, "Not implemented for this architecture");
- static if (F.realFormat == RealFormat.ieeeSingle)
- {
- if (exp < (T.mant_dig - 1))
+ if (exp < 0)
{
- // Clear all bits representing the fraction part.
- const uint fraction_mask = F.MANTISSAMASK_INT >> exp;
+ if (x < 0.0)
+ return -1.0;
+ else
+ return 0.0;
+ }
- if ((y.vi & fraction_mask) != 0)
+ static if (F.realFormat == RealFormat.ieeeSingle)
+ {
+ if (exp < (T.mant_dig - 1))
{
- // If 'x' is negative, then first substract 1.0 from the value.
- if (y.vi < 0)
- y.vi += 0x00800000 >> exp;
- y.vi &= ~fraction_mask;
+ // Clear all bits representing the fraction part.
+ const uint fraction_mask = F.MANTISSAMASK_INT >> exp;
+
+ if ((y.vi & fraction_mask) != 0)
+ {
+ // If 'x' is negative, then first substract 1.0 from
+ // the value.
+ if (y.vi < 0)
+ y.vi += 0x00800000 >> exp;
+ y.vi &= ~fraction_mask;
+ }
}
}
- }
- else
- {
- static if (F.realFormat == RealFormat.ieeeExtended53)
- exp = (T.mant_dig + 11 - 1) - exp; // mant_dig is really 64
else
- exp = (T.mant_dig - 1) - exp;
-
- // Zero 16 bits at a time.
- while (exp >= 16)
{
- version (LittleEndian)
- y.vu[pos++] = 0;
+ static if (F.realFormat == RealFormat.ieeeExtended53)
+ exp = (T.mant_dig + 11 - 1) - exp; // mant_dig is really 64
else
- y.vu[pos--] = 0;
- exp -= 16;
- }
+ exp = (T.mant_dig - 1) - exp;
+
+ // Zero 16 bits at a time.
+ while (exp >= 16)
+ {
+ version (LittleEndian)
+ y.vu[pos++] = 0;
+ else
+ y.vu[pos--] = 0;
+ exp -= 16;
+ }
- // Clear the remaining bits.
- if (exp > 0)
- y.vu[pos] &= 0xffff ^ ((1 << exp) - 1);
+ // Clear the remaining bits.
+ if (exp > 0)
+ y.vu[pos] &= 0xffff ^ ((1 << exp) - 1);
- if ((x < 0.0) && (x != y.rv))
- y.rv -= 1.0;
- }
+ if ((x < 0.0) && (x != y.rv))
+ y.rv -= 1.0;
+ }
- return y.rv;
+ return y.rv;
+ }
}
public:
@@ -1767,6 +1777,13 @@ real exp(real x) @trusted pure nothrow @nogc
else
{
alias F = floatTraits!real;
+ static if (F.realFormat == RealFormat.ibmExtended)
+ {
+ import gcc.builtins;
+ return __builtin_expl(x);
+ }
+ else
+ {
static if (F.realFormat == RealFormat.ieeeDouble)
{
// Coefficients for exp(x)
@@ -1872,6 +1889,7 @@ real exp(real x) @trusted pure nothrow @nogc
return x;
}
+ }
}
/// ditto
@@ -3897,7 +3915,8 @@ real hypot(real x, real y) @safe pure nothrow @nogc
static assert(2*(SQRTMAX/2)*(SQRTMAX/2) <= real.max);
// Proves that sqrt(real.max) ~~ 0.5/sqrt(real.min_normal)
- static assert(real.min_normal*real.max > 2 && real.min_normal*real.max <= 4);
+ static assert((real.min_normal*real.max > 2 && real.min_normal*real.max <= 4)
+ || floatTraits!real.realFormat == RealFormat.ibmExtended);
real u = fabs(x);
real v = fabs(y);
@@ -4524,7 +4543,7 @@ long lrint(real x) @trusted pure nothrow @nogc
}
else
{
- static assert(false, "real type not supported by lrint()");
+ assert(false, "real type not supported by lrint()");
}
}
}
^ permalink raw reply [flat|nested] 8+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] D, Math, IBM128 : Use GCC builtins for floor and exp.
@ 2021-01-30 19:10 Iain Buclaw
0 siblings, 0 replies; 8+ messages in thread
From: Iain Buclaw @ 2021-01-30 19:10 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:baef82c664e10dae8958991d75a5d3bf46458df7
commit baef82c664e10dae8958991d75a5d3bf46458df7
Author: Iain Sandoe <iain@sandoe.co.uk>
Date: Fri Dec 11 00:59:19 2020 +0000
D, Math, IBM128 : Use GCC builtins for floor and exp.
This makes use of GCC's long double format builtins, which
in turn will call out to a libc implementation where needed.
Diff:
---
libphobos/src/std/math.d | 183 ++++++++++++++++++++++++++---------------------
1 file changed, 101 insertions(+), 82 deletions(-)
diff --git a/libphobos/src/std/math.d b/libphobos/src/std/math.d
index 3d18cfa528b..ca2905c3a93 100644
--- a/libphobos/src/std/math.d
+++ b/libphobos/src/std/math.d
@@ -465,108 +465,118 @@ else
T floorImpl(T)(const T x) @trusted pure nothrow @nogc
{
alias F = floatTraits!(T);
- // Take care not to trigger library calls from the compiler,
- // while ensuring that we don't get defeated by some optimizers.
- union floatBits
- {
- T rv;
- ushort[T.sizeof/2] vu;
- // Other kinds of extractors for real formats.
- static if (F.realFormat == RealFormat.ieeeSingle)
- int vi;
- }
- floatBits y = void;
- y.rv = x;
-
- // Find the exponent (power of 2)
- // Do this by shifting the raw value so that the exponent lies in the low bits,
- // then mask out the sign bit, and subtract the bias.
- static if (F.realFormat == RealFormat.ieeeSingle)
+ static if (F.realFormat == RealFormat.ibmExtended)
{
- int exp = ((y.vi >> (T.mant_dig - 1)) & 0xff) - 0x7f;
+ import gcc.builtins;
+ return __builtin_floorl(x);
}
- else static if (F.realFormat == RealFormat.ieeeDouble)
+ else
{
- int exp = ((y.vu[F.EXPPOS_SHORT] >> 4) & 0x7ff) - 0x3ff;
+ // Take care not to trigger library calls from the compiler,
+ // while ensuring that we don't get defeated by some optimizers.
+ union floatBits
+ {
+ T rv;
+ ushort[T.sizeof/2] vu;
- version (LittleEndian)
- int pos = 0;
- else
- int pos = 3;
- }
- else static if (F.realFormat == RealFormat.ieeeExtended ||
- F.realFormat == RealFormat.ieeeExtended53)
- {
- int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
+ // Other kinds of extractors for real formats.
+ static if (F.realFormat == RealFormat.ieeeSingle)
+ int vi;
+ }
+ floatBits y = void;
+ y.rv = x;
- version (LittleEndian)
- int pos = 0;
- else
- int pos = 4;
- }
- else static if (F.realFormat == RealFormat.ieeeQuadruple)
- {
- int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
+ // Find the exponent (power of 2)
+ // Do this by shifting the raw value so that the exponent lies in the
+ // low bits, then mask out the sign bit, and subtract the bias.
+ static if (F.realFormat == RealFormat.ieeeSingle)
+ {
+ int exp = ((y.vi >> (T.mant_dig - 1)) & 0xff) - 0x7f;
+ }
+ else static if (F.realFormat == RealFormat.ieeeDouble)
+ {
+ int exp = ((y.vu[F.EXPPOS_SHORT] >> 4) & 0x7ff) - 0x3ff;
- version (LittleEndian)
- int pos = 0;
- else
- int pos = 7;
+ version (LittleEndian)
+ int pos = 0;
+ else
+ int pos = 3;
}
- else
- static assert(false, "Not implemented for this architecture");
+ else static if (F.realFormat == RealFormat.ieeeExtended ||
+ F.realFormat == RealFormat.ieeeExtended53)
+ {
+ int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
- if (exp < 0)
- {
- if (x < 0.0)
- return -1.0;
+ version (LittleEndian)
+ int pos = 0;
+ else
+ int pos = 4;
+ }
+ else static if (F.realFormat == RealFormat.ieeeQuadruple)
+ {
+ int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
+
+ version (LittleEndian)
+ int pos = 0;
+ else
+ int pos = 7;
+ }
else
- return 0.0;
- }
+ static assert(false, "Not implemented for this architecture");
- static if (F.realFormat == RealFormat.ieeeSingle)
- {
- if (exp < (T.mant_dig - 1))
+ if (exp < 0)
{
- // Clear all bits representing the fraction part.
- const uint fraction_mask = F.MANTISSAMASK_INT >> exp;
+ if (x < 0.0)
+ return -1.0;
+ else
+ return 0.0;
+ }
- if ((y.vi & fraction_mask) != 0)
+ static if (F.realFormat == RealFormat.ieeeSingle)
+ {
+ if (exp < (T.mant_dig - 1))
{
- // If 'x' is negative, then first substract 1.0 from the value.
- if (y.vi < 0)
- y.vi += 0x00800000 >> exp;
- y.vi &= ~fraction_mask;
+ // Clear all bits representing the fraction part.
+ const uint fraction_mask = F.MANTISSAMASK_INT >> exp;
+
+ if ((y.vi & fraction_mask) != 0)
+ {
+ // If 'x' is negative, then first substract 1.0 from
+ // the value.
+ if (y.vi < 0)
+ y.vi += 0x00800000 >> exp;
+ y.vi &= ~fraction_mask;
+ }
}
}
- }
- else
- {
- static if (F.realFormat == RealFormat.ieeeExtended53)
- exp = (T.mant_dig + 11 - 1) - exp; // mant_dig is really 64
else
- exp = (T.mant_dig - 1) - exp;
-
- // Zero 16 bits at a time.
- while (exp >= 16)
{
- version (LittleEndian)
- y.vu[pos++] = 0;
+ static if (F.realFormat == RealFormat.ieeeExtended53)
+ exp = (T.mant_dig + 11 - 1) - exp; // mant_dig is really 64
else
- y.vu[pos--] = 0;
- exp -= 16;
- }
+ exp = (T.mant_dig - 1) - exp;
+
+ // Zero 16 bits at a time.
+ while (exp >= 16)
+ {
+ version (LittleEndian)
+ y.vu[pos++] = 0;
+ else
+ y.vu[pos--] = 0;
+ exp -= 16;
+ }
- // Clear the remaining bits.
- if (exp > 0)
- y.vu[pos] &= 0xffff ^ ((1 << exp) - 1);
+ // Clear the remaining bits.
+ if (exp > 0)
+ y.vu[pos] &= 0xffff ^ ((1 << exp) - 1);
- if ((x < 0.0) && (x != y.rv))
- y.rv -= 1.0;
- }
+ if ((x < 0.0) && (x != y.rv))
+ y.rv -= 1.0;
+ }
- return y.rv;
+ return y.rv;
+ }
}
public:
@@ -1772,6 +1782,13 @@ real exp(real x) @trusted pure nothrow @nogc
else
{
alias F = floatTraits!real;
+ static if (F.realFormat == RealFormat.ibmExtended)
+ {
+ import gcc.builtins;
+ return __builtin_expl(x);
+ }
+ else
+ {
static if (F.realFormat == RealFormat.ieeeDouble)
{
// Coefficients for exp(x)
@@ -1877,6 +1894,7 @@ real exp(real x) @trusted pure nothrow @nogc
return x;
}
+ }
}
/// ditto
@@ -3902,7 +3920,8 @@ real hypot(real x, real y) @safe pure nothrow @nogc
static assert(2*(SQRTMAX/2)*(SQRTMAX/2) <= real.max);
// Proves that sqrt(real.max) ~~ 0.5/sqrt(real.min_normal)
- static assert(real.min_normal*real.max > 2 && real.min_normal*real.max <= 4);
+ static assert((real.min_normal*real.max > 2 && real.min_normal*real.max <= 4)
+ || floatTraits!real.realFormat == RealFormat.ibmExtended);
real u = fabs(x);
real v = fabs(y);
@@ -4529,7 +4548,7 @@ long lrint(real x) @trusted pure nothrow @nogc
}
else
{
- static assert(false, "real type not supported by lrint()");
+ assert(false, "real type not supported by lrint()");
}
}
}
^ permalink raw reply [flat|nested] 8+ messages in thread
* [gcc(refs/users/ibuclaw/heads/darwin)] D, Math, IBM128 : Use GCC builtins for floor and exp.
@ 2021-01-28 17:33 Iain Buclaw
0 siblings, 0 replies; 8+ messages in thread
From: Iain Buclaw @ 2021-01-28 17:33 UTC (permalink / raw)
To: gcc-cvs
https://gcc.gnu.org/g:a52cfea0d525fa7f7889745a7dd3afe92f4ec958
commit a52cfea0d525fa7f7889745a7dd3afe92f4ec958
Author: Iain Sandoe <iain@sandoe.co.uk>
Date: Fri Dec 11 00:59:19 2020 +0000
D, Math, IBM128 : Use GCC builtins for floor and exp.
This makes use of GCC's long double format builtins, which
in turn will call out to a libc implementation where needed.
Diff:
---
libphobos/src/std/math.d | 183 ++++++++++++++++++++++++++---------------------
1 file changed, 101 insertions(+), 82 deletions(-)
diff --git a/libphobos/src/std/math.d b/libphobos/src/std/math.d
index 3d18cfa528b..ca2905c3a93 100644
--- a/libphobos/src/std/math.d
+++ b/libphobos/src/std/math.d
@@ -465,108 +465,118 @@ else
T floorImpl(T)(const T x) @trusted pure nothrow @nogc
{
alias F = floatTraits!(T);
- // Take care not to trigger library calls from the compiler,
- // while ensuring that we don't get defeated by some optimizers.
- union floatBits
- {
- T rv;
- ushort[T.sizeof/2] vu;
- // Other kinds of extractors for real formats.
- static if (F.realFormat == RealFormat.ieeeSingle)
- int vi;
- }
- floatBits y = void;
- y.rv = x;
-
- // Find the exponent (power of 2)
- // Do this by shifting the raw value so that the exponent lies in the low bits,
- // then mask out the sign bit, and subtract the bias.
- static if (F.realFormat == RealFormat.ieeeSingle)
+ static if (F.realFormat == RealFormat.ibmExtended)
{
- int exp = ((y.vi >> (T.mant_dig - 1)) & 0xff) - 0x7f;
+ import gcc.builtins;
+ return __builtin_floorl(x);
}
- else static if (F.realFormat == RealFormat.ieeeDouble)
+ else
{
- int exp = ((y.vu[F.EXPPOS_SHORT] >> 4) & 0x7ff) - 0x3ff;
+ // Take care not to trigger library calls from the compiler,
+ // while ensuring that we don't get defeated by some optimizers.
+ union floatBits
+ {
+ T rv;
+ ushort[T.sizeof/2] vu;
- version (LittleEndian)
- int pos = 0;
- else
- int pos = 3;
- }
- else static if (F.realFormat == RealFormat.ieeeExtended ||
- F.realFormat == RealFormat.ieeeExtended53)
- {
- int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
+ // Other kinds of extractors for real formats.
+ static if (F.realFormat == RealFormat.ieeeSingle)
+ int vi;
+ }
+ floatBits y = void;
+ y.rv = x;
- version (LittleEndian)
- int pos = 0;
- else
- int pos = 4;
- }
- else static if (F.realFormat == RealFormat.ieeeQuadruple)
- {
- int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
+ // Find the exponent (power of 2)
+ // Do this by shifting the raw value so that the exponent lies in the
+ // low bits, then mask out the sign bit, and subtract the bias.
+ static if (F.realFormat == RealFormat.ieeeSingle)
+ {
+ int exp = ((y.vi >> (T.mant_dig - 1)) & 0xff) - 0x7f;
+ }
+ else static if (F.realFormat == RealFormat.ieeeDouble)
+ {
+ int exp = ((y.vu[F.EXPPOS_SHORT] >> 4) & 0x7ff) - 0x3ff;
- version (LittleEndian)
- int pos = 0;
- else
- int pos = 7;
+ version (LittleEndian)
+ int pos = 0;
+ else
+ int pos = 3;
}
- else
- static assert(false, "Not implemented for this architecture");
+ else static if (F.realFormat == RealFormat.ieeeExtended ||
+ F.realFormat == RealFormat.ieeeExtended53)
+ {
+ int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
- if (exp < 0)
- {
- if (x < 0.0)
- return -1.0;
+ version (LittleEndian)
+ int pos = 0;
+ else
+ int pos = 4;
+ }
+ else static if (F.realFormat == RealFormat.ieeeQuadruple)
+ {
+ int exp = (y.vu[F.EXPPOS_SHORT] & 0x7fff) - 0x3fff;
+
+ version (LittleEndian)
+ int pos = 0;
+ else
+ int pos = 7;
+ }
else
- return 0.0;
- }
+ static assert(false, "Not implemented for this architecture");
- static if (F.realFormat == RealFormat.ieeeSingle)
- {
- if (exp < (T.mant_dig - 1))
+ if (exp < 0)
{
- // Clear all bits representing the fraction part.
- const uint fraction_mask = F.MANTISSAMASK_INT >> exp;
+ if (x < 0.0)
+ return -1.0;
+ else
+ return 0.0;
+ }
- if ((y.vi & fraction_mask) != 0)
+ static if (F.realFormat == RealFormat.ieeeSingle)
+ {
+ if (exp < (T.mant_dig - 1))
{
- // If 'x' is negative, then first substract 1.0 from the value.
- if (y.vi < 0)
- y.vi += 0x00800000 >> exp;
- y.vi &= ~fraction_mask;
+ // Clear all bits representing the fraction part.
+ const uint fraction_mask = F.MANTISSAMASK_INT >> exp;
+
+ if ((y.vi & fraction_mask) != 0)
+ {
+ // If 'x' is negative, then first substract 1.0 from
+ // the value.
+ if (y.vi < 0)
+ y.vi += 0x00800000 >> exp;
+ y.vi &= ~fraction_mask;
+ }
}
}
- }
- else
- {
- static if (F.realFormat == RealFormat.ieeeExtended53)
- exp = (T.mant_dig + 11 - 1) - exp; // mant_dig is really 64
else
- exp = (T.mant_dig - 1) - exp;
-
- // Zero 16 bits at a time.
- while (exp >= 16)
{
- version (LittleEndian)
- y.vu[pos++] = 0;
+ static if (F.realFormat == RealFormat.ieeeExtended53)
+ exp = (T.mant_dig + 11 - 1) - exp; // mant_dig is really 64
else
- y.vu[pos--] = 0;
- exp -= 16;
- }
+ exp = (T.mant_dig - 1) - exp;
+
+ // Zero 16 bits at a time.
+ while (exp >= 16)
+ {
+ version (LittleEndian)
+ y.vu[pos++] = 0;
+ else
+ y.vu[pos--] = 0;
+ exp -= 16;
+ }
- // Clear the remaining bits.
- if (exp > 0)
- y.vu[pos] &= 0xffff ^ ((1 << exp) - 1);
+ // Clear the remaining bits.
+ if (exp > 0)
+ y.vu[pos] &= 0xffff ^ ((1 << exp) - 1);
- if ((x < 0.0) && (x != y.rv))
- y.rv -= 1.0;
- }
+ if ((x < 0.0) && (x != y.rv))
+ y.rv -= 1.0;
+ }
- return y.rv;
+ return y.rv;
+ }
}
public:
@@ -1772,6 +1782,13 @@ real exp(real x) @trusted pure nothrow @nogc
else
{
alias F = floatTraits!real;
+ static if (F.realFormat == RealFormat.ibmExtended)
+ {
+ import gcc.builtins;
+ return __builtin_expl(x);
+ }
+ else
+ {
static if (F.realFormat == RealFormat.ieeeDouble)
{
// Coefficients for exp(x)
@@ -1877,6 +1894,7 @@ real exp(real x) @trusted pure nothrow @nogc
return x;
}
+ }
}
/// ditto
@@ -3902,7 +3920,8 @@ real hypot(real x, real y) @safe pure nothrow @nogc
static assert(2*(SQRTMAX/2)*(SQRTMAX/2) <= real.max);
// Proves that sqrt(real.max) ~~ 0.5/sqrt(real.min_normal)
- static assert(real.min_normal*real.max > 2 && real.min_normal*real.max <= 4);
+ static assert((real.min_normal*real.max > 2 && real.min_normal*real.max <= 4)
+ || floatTraits!real.realFormat == RealFormat.ibmExtended);
real u = fabs(x);
real v = fabs(y);
@@ -4529,7 +4548,7 @@ long lrint(real x) @trusted pure nothrow @nogc
}
else
{
- static assert(false, "real type not supported by lrint()");
+ assert(false, "real type not supported by lrint()");
}
}
}
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2021-09-17 14:35 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2021-03-14 22:02 [gcc(refs/users/ibuclaw/heads/darwin)] D, Math, IBM128 : Use GCC builtins for floor and exp Iain Buclaw
-- strict thread matches above, loose matches on Subject: below --
2021-09-17 14:35 Iain Buclaw
2021-04-19 18:06 Iain Buclaw
2021-04-10 17:02 Iain Buclaw
2021-04-10 15:05 Iain Buclaw
2021-03-07 17:03 Iain Buclaw
2021-01-30 19:10 Iain Buclaw
2021-01-28 17:33 Iain Buclaw
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).