@@ -59,9 +59,9 @@ as_cosf_big (float x)
int ia;
double z = RBIG_SINCOSF (t, &ia);
double z2 = z * z, z4 = z2 * z2;
- double aa = (A[0] + z2 * A[1]) + z4 * (A[2] + z2 * A[3]);
- double bb = (B[0] + z2 * B[1]) + z4 * (B[2] + z2 * B[3]);
- double s0 = TB_COSF[(ia + 8u) & 31], c0 = TB_COSF[ia & 31];
+ double aa = (A (0) + z2 * A (1)) + z4 * (A (2) + z2 * A (3));
+ double bb = (B (0) + z2 * B (1)) + z4 * (B (2) + z2 * B (3));
+ double c0 = CS[ia & 31][0], s0 = CS[ia & 31][1];
double r = c0 + z * (aa * s0 - bb * (z * c0));
uint32_t tr = asuint64 (r);
uint64_t tail = (tr + 6) & (~UINT64_C(0) >> 36);
@@ -109,9 +109,9 @@ COSF_FUNC (float x)
z = rltl (z0, &ia);
}
double z2 = z * z, z4 = z2 * z2;
- double aa = (A[0] + z2 * A[1]) + z4 * (A[2] + z2 * A[3]);
- double bb = (B[0] + z2 * B[1]) + z4 * (B[2] + z2 * B[3]);
- double c0 = TB_COSF[ia & 31], s0 = TB_COSF[(ia + 8) & 31];
+ double aa = (A (0) + z2 * A (1)) + z4 * (A (2) + z2 * A (3));
+ double bb = (B (0) + z2 * B (1)) + z4 * (B (2) + z2 * B (3));
+ double c0 = CS[ia & 31][0], s0 = CS[ia & 31][1];
double r = c0 + aa * (z * s0) - bb * (z2 * c0);
return r;
}
@@ -76,10 +76,12 @@ as_sincosf_big (float x, float *sout, float *cout)
int ia;
double z = RBIG_SINCOSF (t, &ia);
double z2 = z * z, z4 = z2 * z2;
- double aa = (A[0] + z2 * A[1]) + z4 * (A[2] + z2 * A[3]);
- double bb = (B[0] + z2 * B[1]) + z4 * (B[2] + z2 * B[3]);
+ double aa = (A (0) + z2 * A (1)) + z4 * (A (2) + z2 * A (3));
+ double bb = (B (0) + z2 * B (1)) + z4 * (B (2) + z2 * B (3));
bb *= z;
- double s0 = TB[ia & 31], c0 = TB[(ia + 8u) & 31];
+ /* CS[(ia + 24) & 31] = { sin(ia*pi/16), cos(ia*pi/16) }. */
+ unsigned int k = (ia + 24u) & 31;
+ double s0 = CS[k][0], c0 = CS[k][1];
double s = s0 + z * (aa * c0 - bb * s0);
double c = c0 - z * (aa * s0 + bb * c0);
*sout = s;
@@ -133,15 +135,23 @@ SINCOSF_FUNC (float x, float *sout, float *cout)
z = rltl (z0, &ia);
}
double z2 = z * z, z4 = z2 * z2;
- double aa = (A[0] + z2 * A[1]) + z4 * (A[2] + z2 * A[3]);
- double bb = (B[0] + z2 * B[1]) + z4 * (B[2] + z2 * B[3]);
- aa *= z;
- bb *= z2;
- double s0 = TB[ia & 31], c0 = TB[(ia + 8) & 31];
- double rs = s0 + (aa * c0 - bb * s0);
- double rc = c0 - (aa * s0 + bb * c0);
- *sout = rs;
- *cout = rc;
+ /* The sine and the cosine are evaluated together, lane 0 and lane 1
+ of the vectors, as
+ sin = s0 + (aa * c0 - bb * s0)
+ cos = c0 - (aa * s0 + bb * c0)
+ with { aa, bb } = q, m = CS[ia] = { c0, -s0 } and
+ w = CS[ia + 8] = { -s0, -c0 }: t = aa * m + bb * w and r = t - w.
+ Each lane performs the operations of the scalar formula, the cosine
+ up to exact negations, so the results do not depend on whether the
+ compiler uses vector instructions. */
+ sincosf_v2df_t p = (AB[0] + z2 * AB[1]) + z4 * (AB[2] + z2 * AB[3]);
+ sincosf_v2df_t q = p * (sincosf_v2df_t) { z, z2 };
+ const sincosf_v2df_t *cs = CS + (ia & 31);
+ sincosf_v2df_t m = cs[0], w = cs[8];
+ sincosf_v2df_t t = q[0] * m + q[1] * w;
+ sincosf_v2df_t r = t - w;
+ *sout = r[0];
+ *cout = r[1];
}
#ifndef SINCOSF
@@ -35,44 +35,57 @@ const uint64_t __sinf_ipi[] =
const sincosf_tables_t __sincosf_tables =
{
- .b =
+ .cs =
{
- 0x1.3bd3cc9be45dcp-6, -0x1.03c1f081b0833p-14, 0x1.55d3c6fc9ac1fp-24,
- -0x1.e1d3ff281b40dp-35
+ { 0x1p+0, 0x0p+0 },
+ { 0x1.f6297cff75cbp-1, -0x1.8f8b83c69a60bp-3 },
+ { 0x1.d906bcf328d46p-1, -0x1.87de2a6aea963p-2 },
+ { 0x1.a9b66290ea1a3p-1, -0x1.1c73b39ae68c8p-1 },
+ { 0x1.6a09e667f3bcdp-1, -0x1.6a09e667f3bcdp-1 },
+ { 0x1.1c73b39ae68c8p-1, -0x1.a9b66290ea1a3p-1 },
+ { 0x1.87de2a6aea963p-2, -0x1.d906bcf328d46p-1 },
+ { 0x1.8f8b83c69a60bp-3, -0x1.f6297cff75cbp-1 },
+ { 0x0p+0, -0x1p+0 },
+ { -0x1.8f8b83c69a60bp-3, -0x1.f6297cff75cbp-1 },
+ { -0x1.87de2a6aea963p-2, -0x1.d906bcf328d46p-1 },
+ { -0x1.1c73b39ae68c8p-1, -0x1.a9b66290ea1a3p-1 },
+ { -0x1.6a09e667f3bcdp-1, -0x1.6a09e667f3bcdp-1 },
+ { -0x1.a9b66290ea1a3p-1, -0x1.1c73b39ae68c8p-1 },
+ { -0x1.d906bcf328d46p-1, -0x1.87de2a6aea963p-2 },
+ { -0x1.f6297cff75cbp-1, -0x1.8f8b83c69a60bp-3 },
+ { -0x1p+0, 0x0p+0 },
+ { -0x1.f6297cff75cbp-1, 0x1.8f8b83c69a60bp-3 },
+ { -0x1.d906bcf328d46p-1, 0x1.87de2a6aea963p-2 },
+ { -0x1.a9b66290ea1a3p-1, 0x1.1c73b39ae68c8p-1 },
+ { -0x1.6a09e667f3bcdp-1, 0x1.6a09e667f3bcdp-1 },
+ { -0x1.1c73b39ae68c8p-1, 0x1.a9b66290ea1a3p-1 },
+ { -0x1.87de2a6aea963p-2, 0x1.d906bcf328d46p-1 },
+ { -0x1.8f8b83c69a60bp-3, 0x1.f6297cff75cbp-1 },
+ { 0x0p+0, 0x1p+0 },
+ { 0x1.8f8b83c69a60bp-3, 0x1.f6297cff75cbp-1 },
+ { 0x1.87de2a6aea963p-2, 0x1.d906bcf328d46p-1 },
+ { 0x1.1c73b39ae68c8p-1, 0x1.a9b66290ea1a3p-1 },
+ { 0x1.6a09e667f3bcdp-1, 0x1.6a09e667f3bcdp-1 },
+ { 0x1.a9b66290ea1a3p-1, 0x1.1c73b39ae68c8p-1 },
+ { 0x1.d906bcf328d46p-1, 0x1.87de2a6aea963p-2 },
+ { 0x1.f6297cff75cbp-1, 0x1.8f8b83c69a60bp-3 },
+ { 0x1p+0, 0x0p+0 },
+ { 0x1.f6297cff75cbp-1, -0x1.8f8b83c69a60bp-3 },
+ { 0x1.d906bcf328d46p-1, -0x1.87de2a6aea963p-2 },
+ { 0x1.a9b66290ea1a3p-1, -0x1.1c73b39ae68c8p-1 },
+ { 0x1.6a09e667f3bcdp-1, -0x1.6a09e667f3bcdp-1 },
+ { 0x1.1c73b39ae68c8p-1, -0x1.a9b66290ea1a3p-1 },
+ { 0x1.87de2a6aea963p-2, -0x1.d906bcf328d46p-1 },
+ { 0x1.8f8b83c69a60bp-3, -0x1.f6297cff75cbp-1 },
},
- .a =
+ .ab =
{
- 0x1.921fb54442d17p-3, -0x1.4abbce6256a39p-10, 0x1.466bc5a518c16p-19,
- -0x1.32bdc61074ff6p-29
- },
- .tb =
- {
- 0x0p+0, 0x1.8f8b83c69a60bp-3, 0x1.87de2a6aea963p-2,
- 0x1.1c73b39ae68c8p-1, 0x1.6a09e667f3bcdp-1, 0x1.a9b66290ea1a3p-1,
- 0x1.d906bcf328d46p-1, 0x1.f6297cff75cbp-1, 0x1p+0,
- 0x1.f6297cff75cbp-1, 0x1.d906bcf328d46p-1, 0x1.a9b66290ea1a3p-1,
- 0x1.6a09e667f3bcdp-1, 0x1.1c73b39ae68c8p-1, 0x1.87de2a6aea963p-2,
- 0x1.8f8b83c69a60bp-3, 0x0p+0, -0x1.8f8b83c69a60bp-3,
- -0x1.87de2a6aea963p-2, -0x1.1c73b39ae68c8p-1, -0x1.6a09e667f3bcdp-1,
- -0x1.a9b66290ea1a3p-1, -0x1.d906bcf328d46p-1, -0x1.f6297cff75cbp-1,
- -0x1p+0, -0x1.f6297cff75cbp-1, -0x1.d906bcf328d46p-1,
- -0x1.a9b66290ea1a3p-1, -0x1.6a09e667f3bcdp-1, -0x1.1c73b39ae68c8p-1,
- -0x1.87de2a6aea963p-2, -0x1.8f8b83c69a60bp-3
- },
- .tb_cosf =
- {
- 0x1p+0, 0x1.f6297cff75cbp-1, 0x1.d906bcf328d46p-1,
- 0x1.a9b66290ea1a3p-1, 0x1.6a09e667f3bcdp-1, 0x1.1c73b39ae68c8p-1,
- 0x1.87de2a6aea963p-2, 0x1.8f8b83c69a60bp-3, 0x0p+0,
- -0x1.8f8b83c69a60bp-3, -0x1.87de2a6aea963p-2, -0x1.1c73b39ae68c8p-1,
- -0x1.6a09e667f3bcdp-1, -0x1.a9b66290ea1a3p-1, -0x1.d906bcf328d46p-1,
- -0x1.f6297cff75cbp-1, -0x1p+0, -0x1.f6297cff75cbp-1,
- -0x1.d906bcf328d46p-1, -0x1.a9b66290ea1a3p-1, -0x1.6a09e667f3bcdp-1,
- -0x1.1c73b39ae68c8p-1, -0x1.87de2a6aea963p-2, -0x1.8f8b83c69a60bp-3,
- 0x0p+0, 0x1.8f8b83c69a60bp-3, 0x1.87de2a6aea963p-2,
- 0x1.1c73b39ae68c8p-1, 0x1.6a09e667f3bcdp-1, 0x1.a9b66290ea1a3p-1,
- 0x1.d906bcf328d46p-1, 0x1.f6297cff75cbp-1
+ { 0x1.921fb54442d17p-3, 0x1.3bd3cc9be45dcp-6 },
+ { -0x1.4abbce6256a39p-10, -0x1.03c1f081b0833p-14 },
+ { 0x1.466bc5a518c16p-19, 0x1.55d3c6fc9ac1fp-24 },
+ { -0x1.32bdc61074ff6p-29, -0x1.e1d3ff281b40dp-35 },
},
+
};
const sincosf_database_t __sinf_st[] =
@@ -24,18 +24,21 @@
extern const uint64_t __sinf_ipi[] attribute_hidden;
#define IPI __sinf_ipi
+typedef double sincosf_v2df_t __attribute__ ((__vector_size__ (16)));
+
typedef struct
{
- double b[4];
- double a[4];
- double tb[32];
- double tb_cosf[32];
+ /* { cos(k*pi/16), -sin(k*pi/16) }, with the first 8 entries repeated
+ at the end so CS[(i & 31) + 8] needs no wrap around. */
+ sincosf_v2df_t cs[40];
+ /* The coefficients { a[k], b[k] } of the two polynomials in z^2. */
+ sincosf_v2df_t ab[4];
} sincosf_tables_t;
extern const sincosf_tables_t __sincosf_tables attribute_hidden;
-#define B __sincosf_tables.b
-#define A __sincosf_tables.a
-#define TB __sincosf_tables.tb
-#define TB_COSF __sincosf_tables.tb_cosf
+#define AB __sincosf_tables.ab
+#define A(k) AB[k][0]
+#define B(k) AB[k][1]
+#define CS __sincosf_tables.cs
typedef struct
{
@@ -68,9 +68,11 @@ as_sinf_big (float x)
int ia;
double z = RBIG_SINCOSF (t, &ia);
double z2 = z * z, z4 = z2 * z2;
- double aa = (A[0] + z2 * A[1]) + z4 * (A[2] + z2 * A[3]);
- double bb = (B[0] + z2 * B[1]) + z4 * (B[2] + z2 * B[3]);
- double s0 = TB[ia & 31], c0 = TB[(ia + 8u) & 31];
+ double aa = (A (0) + z2 * A (1)) + z4 * (A (2) + z2 * A (3));
+ double bb = (B (0) + z2 * B (1)) + z4 * (B (2) + z2 * B (3));
+ /* CS[(ia + 24) & 31] = { sin(ia*pi/16), cos(ia*pi/16) }. */
+ unsigned int k = (ia + 24u) & 31;
+ double s0 = CS[k][0], c0 = CS[k][1];
double r = s0 + z * (aa * c0 - bb * (z * s0));
return r;
}
@@ -119,9 +121,11 @@ SINF_FUNC (float x)
z = rltl (z0, &ia);
}
double z2 = z * z, z4 = z2 * z2;
- double aa = (A[0] + z2 * A[1]) + z4 * (A[2] + z2 * A[3]);
- double bb = (B[0] + z2 * B[1]) + z4 * (B[2] + z2 * B[3]);
- double s0 = TB[ia & 31], c0 = TB[(ia + 8) & 31];
+ double aa = (A (0) + z2 * A (1)) + z4 * (A (2) + z2 * A (3));
+ double bb = (B (0) + z2 * B (1)) + z4 * (B (2) + z2 * B (3));
+ /* CS[(ia + 24) & 31] = { sin(ia*pi/16), cos(ia*pi/16) }. */
+ unsigned int k = (ia + 24u) & 31;
+ double s0 = CS[k][0], c0 = CS[k][1];
double r = s0 + aa * (z * c0) - bb * (z2 * s0);
return r;
}