Skip to content

Commit 5d6cb09

Browse files
committed
Change existing code to use CMPLX*() instead of cpack*() where possible.
I am currently working on building openlibm against stock copies of <math.h>, instead of the openlibm.h header. It seems that a C compliant <math.h> header can be used as a drop-in replacement for openlibm.h, with the exception that it lacks cpack*(). In FreeBSD SVN r275819 I patched up the math library by replacing cpack*() by CMPLX*(). That way many functions become less tied to the intrinsics of the math library. Make the same change to openlibm.
1 parent 0b2a647 commit 5d6cb09

20 files changed

Lines changed: 143 additions & 127 deletions

src/k_exp.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,6 @@ __ldexp_cexp(double complex z, int expt)
103103
half_expt = expt - half_expt;
104104
INSERT_WORDS(scale2, (0x3ff + half_expt) << 20, 0);
105105

106-
return (cpack(cos(y) * exp_x * scale1 * scale2,
106+
return (CMPLX(cos(y) * exp_x * scale1 * scale2,
107107
sin(y) * exp_x * scale1 * scale2));
108108
}

src/k_expf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,6 @@ __ldexp_cexpf(float complex z, int expt)
8282
half_expt = expt - half_expt;
8383
SET_FLOAT_WORD(scale2, (0x7f + half_expt) << 23);
8484

85-
return (cpackf(cosf(y) * exp_x * scale1 * scale2,
85+
return (CMPLXF(cosf(y) * exp_x * scale1 * scale2,
8686
sinf(y) * exp_x * scale1 * scale2));
8787
}

src/openlibm.h

Lines changed: 30 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -204,7 +204,7 @@ typedef union {
204204
#define IMAGPART(z) ((z).a[1])
205205

206206
/*
207-
* Inline functions that can be used to construct complex values.
207+
* Macros that can be used to construct complex values.
208208
*
209209
* The C99 standard intends x+I*y to be used for this, but x+I*y is
210210
* currently unusable in general since gcc introduces many overflow,
@@ -217,46 +217,62 @@ typedef union {
217217
* and gcc 4.7 added a __builtin_complex feature to simplify implementation
218218
* of CMPLX in libc, so we can take advantage of these features if they
219219
* are available.
220+
*
221+
* If __builtin_complex is not available, resort to using inline
222+
* functions instead. These can unfortunately not be used to construct
223+
* compile-time constants.
220224
*/
221-
#if defined(CMPLXF) && defined(CMPLX) && defined(CMPLXL) /* C11 */
222-
# define cpackf(x,y) CMPLXF(x,y)
223-
# define cpack(x,y) CMPLX(x,y)
224-
# define cpackl(x,y) CMPLXL(x,y)
225-
#elif (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__INTEL_COMPILER)
226-
# define cpackf(x,y) __builtin_complex ((float) (x), (float) (y))
227-
# define cpack(x,y) __builtin_complex ((double) (x), (double) (y))
228-
# define cpackl(x,y) __builtin_complex ((long double) (x), (long double) (y))
229-
#else /* define our own cpack functions */
225+
226+
#define HAVE_BUILTIN_COMPLEX (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7)) && !defined(__INTEL_COMPILER)
227+
228+
#ifndef CMPLXF
229+
#if HAVE_BUILTIN_COMPLEX
230+
# define CMPLXF(x,y) __builtin_complex ((float) (x), (float) (y))
231+
#else
230232
static __inline float complex
231-
cpackf(float x, float y)
233+
CMPLXF(float x, float y)
232234
{
233235
float_complex z;
234236

235237
REALPART(z) = x;
236238
IMAGPART(z) = y;
237239
return (z.f);
238240
}
241+
#endif
242+
#endif
239243

244+
#ifndef CMPLX
245+
#if HAVE_BUILTIN_COMPLEX
246+
# define CMPLX(x,y) __builtin_complex ((double) (x), (double) (y))
247+
#else
240248
static __inline double complex
241-
cpack(double x, double y)
249+
CMPLX(double x, double y)
242250
{
243251
double_complex z;
244252

245253
REALPART(z) = x;
246254
IMAGPART(z) = y;
247255
return (z.f);
248256
}
257+
#endif
258+
#endif
249259

260+
#ifndef CMPLXL
261+
#if HAVE_BUILTIN_COMPLEX
262+
# define CMPLXL(x,y) __builtin_complex ((long double) (x), (long double) (y))
263+
#else
250264
static __inline long double complex
251-
cpackl(long double x, long double y)
265+
CMPLXL(long double x, long double y)
252266
{
253267
long_double_complex z;
254268

255269
REALPART(z) = x;
256270
IMAGPART(z) = y;
257271
return (z.f);
258272
}
259-
#endif /* define our own cpack functions */
273+
#endif
274+
#endif
275+
260276
//VBS
261277
//#endif /* _COMPLEX_H */
262278

src/s_ccosh.c

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -62,23 +62,23 @@ ccosh(double complex z)
6262
/* Handle the nearly-non-exceptional cases where x and y are finite. */
6363
if (ix < 0x7ff00000 && iy < 0x7ff00000) {
6464
if ((iy | ly) == 0)
65-
return (cpack(cosh(x), x * y));
65+
return (CMPLX(cosh(x), x * y));
6666
if (ix < 0x40360000) /* small x: normal case */
67-
return (cpack(cosh(x) * cos(y), sinh(x) * sin(y)));
67+
return (CMPLX(cosh(x) * cos(y), sinh(x) * sin(y)));
6868

6969
/* |x| >= 22, so cosh(x) ~= exp(|x|) */
7070
if (ix < 0x40862e42) {
7171
/* x < 710: exp(|x|) won't overflow */
7272
h = exp(fabs(x)) * 0.5;
73-
return (cpack(h * cos(y), copysign(h, x) * sin(y)));
73+
return (CMPLX(h * cos(y), copysign(h, x) * sin(y)));
7474
} else if (ix < 0x4096bbaa) {
7575
/* x < 1455: scale to avoid overflow */
76-
z = __ldexp_cexp(cpack(fabs(x), y), -1);
77-
return (cpack(creal(z), cimag(z) * copysign(1, x)));
76+
z = __ldexp_cexp(CMPLX(fabs(x), y), -1);
77+
return (CMPLX(creal(z), cimag(z) * copysign(1, x)));
7878
} else {
7979
/* x >= 1455: the result always overflows */
8080
h = huge * x;
81-
return (cpack(h * h * cos(y), h * sin(y)));
81+
return (CMPLX(h * h * cos(y), h * sin(y)));
8282
}
8383
}
8484

@@ -92,7 +92,7 @@ ccosh(double complex z)
9292
* the same as d(NaN).
9393
*/
9494
if ((ix | lx) == 0 && iy >= 0x7ff00000)
95-
return (cpack(y - y, copysign(0, x * (y - y))));
95+
return (CMPLX(y - y, copysign(0, x * (y - y))));
9696

9797
/*
9898
* cosh(+-Inf +- I 0) = +Inf + I (+-)(+-)0.
@@ -102,8 +102,8 @@ ccosh(double complex z)
102102
*/
103103
if ((iy | ly) == 0 && ix >= 0x7ff00000) {
104104
if (((hx & 0xfffff) | lx) == 0)
105-
return (cpack(x * x, copysign(0, x) * y));
106-
return (cpack(x * x, copysign(0, (x + x) * y)));
105+
return (CMPLX(x * x, copysign(0, x) * y));
106+
return (CMPLX(x * x, copysign(0, (x + x) * y)));
107107
}
108108

109109
/*
@@ -115,7 +115,7 @@ ccosh(double complex z)
115115
* nonzero x. Choice = don't raise (except for signaling NaNs).
116116
*/
117117
if (ix < 0x7ff00000 && iy >= 0x7ff00000)
118-
return (cpack(y - y, x * (y - y)));
118+
return (CMPLX(y - y, x * (y - y)));
119119

120120
/*
121121
* cosh(+-Inf + I NaN) = +Inf + I d(NaN).
@@ -128,8 +128,8 @@ ccosh(double complex z)
128128
*/
129129
if (ix >= 0x7ff00000 && ((hx & 0xfffff) | lx) == 0) {
130130
if (iy >= 0x7ff00000)
131-
return (cpack(x * x, x * (y - y)));
132-
return (cpack((x * x) * cos(y), x * sin(y)));
131+
return (CMPLX(x * x, x * (y - y)));
132+
return (CMPLX((x * x) * cos(y), x * sin(y)));
133133
}
134134

135135
/*
@@ -143,13 +143,13 @@ ccosh(double complex z)
143143
* Optionally raises the invalid floating-point exception for finite
144144
* nonzero y. Choice = don't raise (except for signaling NaNs).
145145
*/
146-
return (cpack((x * x) * (y - y), (x + x) * (y - y)));
146+
return (CMPLX((x * x) * (y - y), (x + x) * (y - y)));
147147
}
148148

149149
DLLEXPORT double complex
150150
ccos(double complex z)
151151
{
152152

153153
/* ccos(z) = ccosh(I * z) */
154-
return (ccosh(cpack(-cimag(z), creal(z))));
154+
return (ccosh(CMPLX(-cimag(z), creal(z))));
155155
}

src/s_ccoshf.c

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -55,50 +55,50 @@ ccoshf(float complex z)
5555

5656
if (ix < 0x7f800000 && iy < 0x7f800000) {
5757
if (iy == 0)
58-
return (cpackf(coshf(x), x * y));
58+
return (CMPLXF(coshf(x), x * y));
5959
if (ix < 0x41100000) /* small x: normal case */
60-
return (cpackf(coshf(x) * cosf(y), sinhf(x) * sinf(y)));
60+
return (CMPLXF(coshf(x) * cosf(y), sinhf(x) * sinf(y)));
6161

6262
/* |x| >= 9, so cosh(x) ~= exp(|x|) */
6363
if (ix < 0x42b17218) {
6464
/* x < 88.7: expf(|x|) won't overflow */
6565
h = expf(fabsf(x)) * 0.5f;
66-
return (cpackf(h * cosf(y), copysignf(h, x) * sinf(y)));
66+
return (CMPLXF(h * cosf(y), copysignf(h, x) * sinf(y)));
6767
} else if (ix < 0x4340b1e7) {
6868
/* x < 192.7: scale to avoid overflow */
69-
z = __ldexp_cexpf(cpackf(fabsf(x), y), -1);
70-
return (cpackf(crealf(z), cimagf(z) * copysignf(1, x)));
69+
z = __ldexp_cexpf(CMPLXF(fabsf(x), y), -1);
70+
return (CMPLXF(crealf(z), cimagf(z) * copysignf(1, x)));
7171
} else {
7272
/* x >= 192.7: the result always overflows */
7373
h = huge * x;
74-
return (cpackf(h * h * cosf(y), h * sinf(y)));
74+
return (CMPLXF(h * h * cosf(y), h * sinf(y)));
7575
}
7676
}
7777

7878
if (ix == 0 && iy >= 0x7f800000)
79-
return (cpackf(y - y, copysignf(0, x * (y - y))));
79+
return (CMPLXF(y - y, copysignf(0, x * (y - y))));
8080

8181
if (iy == 0 && ix >= 0x7f800000) {
8282
if ((hx & 0x7fffff) == 0)
83-
return (cpackf(x * x, copysignf(0, x) * y));
84-
return (cpackf(x * x, copysignf(0, (x + x) * y)));
83+
return (CMPLXF(x * x, copysignf(0, x) * y));
84+
return (CMPLXF(x * x, copysignf(0, (x + x) * y)));
8585
}
8686

8787
if (ix < 0x7f800000 && iy >= 0x7f800000)
88-
return (cpackf(y - y, x * (y - y)));
88+
return (CMPLXF(y - y, x * (y - y)));
8989

9090
if (ix >= 0x7f800000 && (hx & 0x7fffff) == 0) {
9191
if (iy >= 0x7f800000)
92-
return (cpackf(x * x, x * (y - y)));
93-
return (cpackf((x * x) * cosf(y), x * sinf(y)));
92+
return (CMPLXF(x * x, x * (y - y)));
93+
return (CMPLXF((x * x) * cosf(y), x * sinf(y)));
9494
}
9595

96-
return (cpackf((x * x) * (y - y), (x + x) * (y - y)));
96+
return (CMPLXF((x * x) * (y - y), (x + x) * (y - y)));
9797
}
9898

9999
DLLEXPORT float complex
100100
ccosf(float complex z)
101101
{
102102

103-
return (ccoshf(cpackf(-cimagf(z), crealf(z))));
103+
return (ccoshf(CMPLXF(-cimagf(z), crealf(z))));
104104
}

src/s_cexp.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,22 +50,22 @@ cexp(double complex z)
5050

5151
/* cexp(x + I 0) = exp(x) + I 0 */
5252
if ((hy | ly) == 0)
53-
return (cpack(exp(x), y));
53+
return (CMPLX(exp(x), y));
5454
EXTRACT_WORDS(hx, lx, x);
5555
/* cexp(0 + I y) = cos(y) + I sin(y) */
5656
if (((hx & 0x7fffffff) | lx) == 0)
57-
return (cpack(cos(y), sin(y)));
57+
return (CMPLX(cos(y), sin(y)));
5858

5959
if (hy >= 0x7ff00000) {
6060
if (lx != 0 || (hx & 0x7fffffff) != 0x7ff00000) {
6161
/* cexp(finite|NaN +- I Inf|NaN) = NaN + I NaN */
62-
return (cpack(y - y, y - y));
62+
return (CMPLX(y - y, y - y));
6363
} else if (hx & 0x80000000) {
6464
/* cexp(-Inf +- I Inf|NaN) = 0 + I 0 */
65-
return (cpack(0.0, 0.0));
65+
return (CMPLX(0.0, 0.0));
6666
} else {
6767
/* cexp(+Inf +- I Inf|NaN) = Inf + I NaN */
68-
return (cpack(x, y - y));
68+
return (CMPLX(x, y - y));
6969
}
7070
}
7171

@@ -84,6 +84,6 @@ cexp(double complex z)
8484
* - x = NaN (spurious inexact exception from y)
8585
*/
8686
exp_x = exp(x);
87-
return (cpack(exp_x * cos(y), exp_x * sin(y)));
87+
return (CMPLX(exp_x * cos(y), exp_x * sin(y)));
8888
}
8989
}

src/s_cexpf.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,22 +50,22 @@ cexpf(float complex z)
5050

5151
/* cexp(x + I 0) = exp(x) + I 0 */
5252
if (hy == 0)
53-
return (cpackf(expf(x), y));
53+
return (CMPLXF(expf(x), y));
5454
GET_FLOAT_WORD(hx, x);
5555
/* cexp(0 + I y) = cos(y) + I sin(y) */
5656
if ((hx & 0x7fffffff) == 0)
57-
return (cpackf(cosf(y), sinf(y)));
57+
return (CMPLXF(cosf(y), sinf(y)));
5858

5959
if (hy >= 0x7f800000) {
6060
if ((hx & 0x7fffffff) != 0x7f800000) {
6161
/* cexp(finite|NaN +- I Inf|NaN) = NaN + I NaN */
62-
return (cpackf(y - y, y - y));
62+
return (CMPLXF(y - y, y - y));
6363
} else if (hx & 0x80000000) {
6464
/* cexp(-Inf +- I Inf|NaN) = 0 + I 0 */
65-
return (cpackf(0.0, 0.0));
65+
return (CMPLXF(0.0, 0.0));
6666
} else {
6767
/* cexp(+Inf +- I Inf|NaN) = Inf + I NaN */
68-
return (cpackf(x, y - y));
68+
return (CMPLXF(x, y - y));
6969
}
7070
}
7171

@@ -84,6 +84,6 @@ cexpf(float complex z)
8484
* - x = NaN (spurious inexact exception from y)
8585
*/
8686
exp_x = expf(x);
87-
return (cpackf(exp_x * cosf(y), exp_x * sinf(y)));
87+
return (CMPLXF(exp_x * cosf(y), exp_x * sinf(y)));
8888
}
8989
}

src/s_conj.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,5 @@ DLLEXPORT double complex
3535
conj(double complex z)
3636
{
3737

38-
return (cpack(creal(z), -cimag(z)));
38+
return (CMPLX(creal(z), -cimag(z)));
3939
}

src/s_conjf.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,5 @@ DLLEXPORT float complex
3535
conjf(float complex z)
3636
{
3737

38-
return (cpackf(crealf(z), -cimagf(z)));
38+
return (CMPLXF(crealf(z), -cimagf(z)));
3939
}

src/s_conjl.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,5 +35,5 @@ DLLEXPORT long double complex
3535
conjl(long double complex z)
3636
{
3737

38-
return (cpackl(creall(z), -cimagl(z)));
38+
return (CMPLXL(creall(z), -cimagl(z)));
3939
}

0 commit comments

Comments
 (0)