10 /* Whether we're looking at 32-bit or 64-bit floats */
11 typedef enum { P_SINGLE
, P_DOUBLE
} precision
;
13 /* What type of arguments we expect, and what we'll give back. */
18 A__FLT_FLT_FLT_RND__FLT
,
22 /* Types of functions we could call */
23 typedef int (*f__flt__flt
)(mpfr_ptr
, mpfr_srcptr
);
24 typedef int (*f__flt_flt_flt_rnd__flt
)(mpfr_ptr
, mpfr_srcptr
, mpfr_srcptr
,
25 mpfr_srcptr
, mpfr_rnd_t
);
26 typedef int (*f__flt_rnd__flt
)(mpfr_ptr
, mpfr_srcptr
, mpfr_rnd_t
);
28 /* Wrapper around a function pointer */
37 f__flt_flt_flt_rnd__flt flt_flt_flt_rnd__flt
;
38 f__flt_rnd__flt flt_rnd__flt
;
46 "usage: impl-mpfr [-s|-d] -f <function_name> -n <num_inputs>\n");
50 void determine_function(const char *f
, action
*a
)
52 if (!strcmp(f
, "zzzzzzzzz")) {
54 } else if (!strcmp(f
, "id")) {
55 a
->a
= A__FLT_RND__FLT
;
56 a
->f
.flt_rnd__flt
= mpfr_set
;
57 } else if (!strcmp(f
, "ceil")) {
59 a
->f
.flt__flt
= mpfr_ceil
;
60 } else if (!strcmp(f
, "cos")) {
61 a
->a
= A__FLT_RND__FLT
;
62 a
->f
.flt_rnd__flt
= mpfr_cos
;
63 } else if (!strcmp(f
, "floor")) {
65 a
->f
.flt__flt
= mpfr_floor
;
66 } else if (!strcmp(f
, "sin")) {
67 a
->a
= A__FLT_RND__FLT
;
68 a
->f
.flt_rnd__flt
= mpfr_sin
;
69 } else if (!strcmp(f
, "trunc")) {
71 a
->f
.flt__flt
= mpfr_trunc
;
72 } else if (!strcmp(f
, "fma")) {
73 a
->a
= A__FLT_FLT_FLT_RND__FLT
;
74 a
->f
.flt_flt_flt_rnd__flt
= mpfr_fma
;
75 } else if (!strcmp(f
, "sqrt")) {
76 a
->a
= A__FLT_RND__FLT
;
77 a
->f
.flt_rnd__flt
= mpfr_sqrt
;
79 fprintf(stderr
, "impl-mpfr: unknown function \"%s\"\n", f
);
84 void read_buf(char *b
, ssize_t len
)
90 r
= read(0, (b
+ total
), (len
- total
));
96 perror("impl-mpfr: read");
104 void write_buf(const char *b
, ssize_t len
)
109 while (total
< len
) {
110 r
= write(1, (b
+ total
), (len
- total
));
113 perror("impl-mpfr: write");
121 size_t input_width(argtype a
, precision p
)
123 size_t w
= (p
== P_SINGLE
) ? 4 : 8;
131 case A__FLT_FLT_FLT_RND__FLT
:
134 case A__FLT_RND__FLT
:
142 size_t output_width(argtype a
, precision p
)
144 size_t w
= (p
== P_SINGLE
) ? 4 : 8;
152 case A__FLT_FLT_FLT_RND__FLT
:
155 case A__FLT_RND__FLT
:
163 void io_loop(action a
, size_t n
)
167 size_t in_sz
= input_width(a
.a
, a
.p
);
168 size_t out_sz
= output_width(a
.a
, a
.p
);
174 if ((in_sz
* n
) / n
!= in_sz
) {
175 fprintf(stderr
, "impl-libc: input length overflow\n");
179 if ((out_sz
* n
) / n
!= out_sz
) {
180 fprintf(stderr
, "impl-libc: output length overflow\n");
184 if (!(in_buf
= malloc(in_sz
* n
))) {
185 perror("impl-libc: malloc");
189 if (!(out_buf
= malloc(out_sz
* n
))) {
190 perror("impl-libc: malloc");
194 /* I'm pretty sure 53 precision would be enough */
201 read_buf(in_buf
, in_sz
* n
);
205 fprintf(stderr
, "impl-libc: impossible\n");
213 for (size_t j
= 0; j
< n
; ++j
) {
214 float *xf1
= (float *) (in_buf
+
216 float *yf
= (float *) (out_buf
+
219 mpfr_set_flt(x1
, *xf1
, MPFR_RNDN
);
221 *yf
= mpfr_get_flt(y
, MPFR_RNDN
);
227 for (size_t j
= 0; j
< n
; ++j
) {
228 double *xf1
= (double *) (in_buf
+
230 double *yf
= (double *) (out_buf
+
233 mpfr_set_d(x1
, *xf1
, MPFR_RNDN
);
235 *yf
= mpfr_get_d(y
, MPFR_RNDN
);
242 case A__FLT_FLT_FLT_RND__FLT
:
247 for (size_t j
= 0; j
< n
; ++j
) {
248 float *xf1
= (float *) (in_buf
+
250 float *xf2
= (float *) (in_buf
+
253 float *xf3
= (float *) (in_buf
+
256 float *yf
= (float *) (out_buf
+
259 mpfr_set_flt(x1
, *xf1
, MPFR_RNDN
);
260 mpfr_set_flt(x2
, *xf2
, MPFR_RNDN
);
261 mpfr_set_flt(x3
, *xf3
, MPFR_RNDN
);
262 a
.f
.flt_flt_flt_rnd__flt(y
, x1
, x2
, x3
,
264 *yf
= mpfr_get_flt(y
, MPFR_RNDN
);
270 for (size_t j
= 0; j
< n
; ++j
) {
271 double *xf1
= (double *) (in_buf
+
273 double *xf2
= (double *) (in_buf
+
276 double *xf3
= (double *) (in_buf
+
279 double *yf
= (double *) (out_buf
+
282 mpfr_set_d(x1
, *xf1
, MPFR_RNDN
);
283 mpfr_set_d(x2
, *xf2
, MPFR_RNDN
);
284 mpfr_set_d(x3
, *xf3
, MPFR_RNDN
);
285 a
.f
.flt_flt_flt_rnd__flt(y
, x1
, x2
, x3
,
287 *yf
= mpfr_get_d(y
, MPFR_RNDN
);
294 case A__FLT_RND__FLT
:
299 for (size_t j
= 0; j
< n
; ++j
) {
300 float *xf1
= (float *) (in_buf
+
302 float *yf
= (float *) (out_buf
+
305 mpfr_set_flt(x1
, *xf1
, MPFR_RNDN
);
306 a
.f
.flt_rnd__flt(y
, x1
, MPFR_RNDN
);
307 *yf
= mpfr_get_flt(y
, MPFR_RNDN
);
313 for (size_t j
= 0; j
< n
; ++j
) {
314 double *xf1
= (double *) (in_buf
+
316 double *yf
= (double *) (out_buf
+
319 mpfr_set_d(x1
, *xf1
, MPFR_RNDN
);
320 a
.f
.flt_rnd__flt(y
, x1
, MPFR_RNDN
);
321 *yf
= mpfr_get_d(y
, MPFR_RNDN
);
330 write_buf(out_buf
, out_sz
* n
);
334 int main(int argc
, char **argv
)
337 action a
= { .p
= P_SINGLE
};
340 while ((c
= getopt(argc
, argv
, "sdf:n:")) != -1) {
349 determine_function(optarg
, &a
);
353 n
= strtoll(optarg
, 0, 0);
356 perror("impl-libc: unparsable");
368 if (a
.a
== A_UNKNOWN
) {