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
, "exp")) {
67 a
->a
= A__FLT_RND__FLT
;
68 a
->f
.flt_rnd__flt
= mpfr_exp
;
69 } else if (!strcmp(f
, "expm1")) {
70 a
->a
= A__FLT_RND__FLT
;
71 a
->f
.flt_rnd__flt
= mpfr_expm1
;
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
, "log")) {
76 a
->a
= A__FLT_RND__FLT
;
77 a
->f
.flt_rnd__flt
= mpfr_log
;
78 } else if (!strcmp(f
, "log1p")) {
79 a
->a
= A__FLT_RND__FLT
;
80 a
->f
.flt_rnd__flt
= mpfr_log1p
;
81 } else if (!strcmp(f
, "sin")) {
82 a
->a
= A__FLT_RND__FLT
;
83 a
->f
.flt_rnd__flt
= mpfr_sin
;
84 } else if (!strcmp(f
, "sqrt")) {
85 a
->a
= A__FLT_RND__FLT
;
86 a
->f
.flt_rnd__flt
= mpfr_sqrt
;
87 } else if (!strcmp(f
, "trunc")) {
89 a
->f
.flt__flt
= mpfr_trunc
;
91 fprintf(stderr
, "impl-mpfr: unknown function \"%s\"\n", f
);
96 void read_buf(char *b
, ssize_t len
)
101 while (total
< len
) {
102 r
= read(0, (b
+ total
), (len
- total
));
107 } else if (r
== -1) {
108 perror("impl-mpfr: read");
116 void write_buf(const char *b
, ssize_t len
)
121 while (total
< len
) {
122 r
= write(1, (b
+ total
), (len
- total
));
125 perror("impl-mpfr: write");
133 size_t input_width(argtype a
, precision p
)
135 size_t w
= (p
== P_SINGLE
) ? 4 : 8;
143 case A__FLT_FLT_FLT_RND__FLT
:
146 case A__FLT_RND__FLT
:
154 size_t output_width(argtype a
, precision p
)
156 size_t w
= (p
== P_SINGLE
) ? 4 : 8;
164 case A__FLT_FLT_FLT_RND__FLT
:
167 case A__FLT_RND__FLT
:
175 void io_loop(action a
, size_t n
)
179 size_t in_sz
= input_width(a
.a
, a
.p
);
180 size_t out_sz
= output_width(a
.a
, a
.p
);
186 if ((in_sz
* n
) / n
!= in_sz
) {
187 fprintf(stderr
, "impl-libc: input length overflow\n");
191 if ((out_sz
* n
) / n
!= out_sz
) {
192 fprintf(stderr
, "impl-libc: output length overflow\n");
196 if (!(in_buf
= malloc(in_sz
* n
))) {
197 perror("impl-libc: malloc");
201 if (!(out_buf
= malloc(out_sz
* n
))) {
202 perror("impl-libc: malloc");
206 /* I'm pretty sure 53 precision would be enough */
213 read_buf(in_buf
, in_sz
* n
);
217 fprintf(stderr
, "impl-libc: impossible\n");
225 for (size_t j
= 0; j
< n
; ++j
) {
226 float *xf1
= (float *) (in_buf
+
228 float *yf
= (float *) (out_buf
+
231 mpfr_set_flt(x1
, *xf1
, MPFR_RNDN
);
233 *yf
= mpfr_get_flt(y
, MPFR_RNDN
);
239 for (size_t j
= 0; j
< n
; ++j
) {
240 double *xf1
= (double *) (in_buf
+
242 double *yf
= (double *) (out_buf
+
245 mpfr_set_d(x1
, *xf1
, MPFR_RNDN
);
247 *yf
= mpfr_get_d(y
, MPFR_RNDN
);
254 case A__FLT_FLT_FLT_RND__FLT
:
259 for (size_t j
= 0; j
< n
; ++j
) {
260 float *xf1
= (float *) (in_buf
+
262 float *xf2
= (float *) (in_buf
+
265 float *xf3
= (float *) (in_buf
+
268 float *yf
= (float *) (out_buf
+
271 mpfr_set_flt(x1
, *xf1
, MPFR_RNDN
);
272 mpfr_set_flt(x2
, *xf2
, MPFR_RNDN
);
273 mpfr_set_flt(x3
, *xf3
, MPFR_RNDN
);
274 a
.f
.flt_flt_flt_rnd__flt(y
, x1
, x2
, x3
,
276 *yf
= mpfr_get_flt(y
, MPFR_RNDN
);
282 for (size_t j
= 0; j
< n
; ++j
) {
283 double *xf1
= (double *) (in_buf
+
285 double *xf2
= (double *) (in_buf
+
288 double *xf3
= (double *) (in_buf
+
291 double *yf
= (double *) (out_buf
+
294 mpfr_set_d(x1
, *xf1
, MPFR_RNDN
);
295 mpfr_set_d(x2
, *xf2
, MPFR_RNDN
);
296 mpfr_set_d(x3
, *xf3
, MPFR_RNDN
);
297 a
.f
.flt_flt_flt_rnd__flt(y
, x1
, x2
, x3
,
299 *yf
= mpfr_get_d(y
, MPFR_RNDN
);
306 case A__FLT_RND__FLT
:
311 for (size_t j
= 0; j
< n
; ++j
) {
312 float *xf1
= (float *) (in_buf
+
314 float *yf
= (float *) (out_buf
+
317 mpfr_set_flt(x1
, *xf1
, MPFR_RNDN
);
318 a
.f
.flt_rnd__flt(y
, x1
, MPFR_RNDN
);
319 *yf
= mpfr_get_flt(y
, MPFR_RNDN
);
325 for (size_t j
= 0; j
< n
; ++j
) {
326 double *xf1
= (double *) (in_buf
+
328 double *yf
= (double *) (out_buf
+
331 mpfr_set_d(x1
, *xf1
, MPFR_RNDN
);
332 a
.f
.flt_rnd__flt(y
, x1
, MPFR_RNDN
);
333 *yf
= mpfr_get_d(y
, MPFR_RNDN
);
342 write_buf(out_buf
, out_sz
* n
);
346 int main(int argc
, char **argv
)
349 action a
= { .p
= P_SINGLE
};
352 while ((c
= getopt(argc
, argv
, "sdf:n:")) != -1) {
361 determine_function(optarg
, &a
);
365 n
= strtoll(optarg
, 0, 0);
368 perror("impl-libc: unparsable");
380 if (a
.a
== A_UNKNOWN
) {