9 /* Whether we're looking at 32-bit or 64-bit floats */
10 typedef enum { P_SINGLE
, P_DOUBLE
} precision
;
12 /* What type of arguments we expect, and what we'll give back. */
19 /* Types of functions we could call */
20 typedef float (*f__f32__f32
)(float);
21 typedef double (*f__f64__f64
)(double);
23 /* Wrapper around a function pointer */
43 fprintf(stderr
, "usage: impl-libc [-s|-d] -f <function_name> -n <num_inputs>\n");
57 void determine_function(const char *f
, action
*a
)
59 if (!strcmp(f
, "zzzzzz")) {
61 } else if (!strcmp(f
, "id")) {
63 a
->f32
.f32__f32
= idf
;
64 a
->f64
.f64__f64
= idd
;
65 } else if (!strcmp(f
, "ceil")) {
67 a
->f32
.f32__f32
= ceilf
;
68 a
->f64
.f64__f64
= ceil
;
69 } else if (!strcmp(f
, "cos")) {
71 a
->f32
.f32__f32
= cosf
;
72 a
->f64
.f64__f64
= cos
;
73 } else if (!strcmp(f
, "floor")) {
75 a
->f32
.f32__f32
= floorf
;
76 a
->f64
.f64__f64
= floor
;
77 } else if (!strcmp(f
, "sin")) {
79 a
->f32
.f32__f32
= sinf
;
80 a
->f64
.f64__f64
= sin
;
81 } else if (!strcmp(f
, "trunc")) {
83 a
->f32
.f32__f32
= truncf
;
84 a
->f64
.f64__f64
= trunc
;
86 fprintf(stderr
, "impl-libc: unknown function \"%s\"\n", f
);
91 void read_buf(char *b
, ssize_t len
)
97 r
= read(0, (b
+ total
), (len
- total
));
102 } else if (r
== -1) {
103 perror("impl-libc: read");
111 void write_buf(const char *b
, ssize_t len
)
116 while (total
< len
) {
117 r
= write(1, (b
+ total
), (len
- total
));
120 perror("impl-libc: write");
128 size_t input_width(argtype a
, precision p
)
130 size_t w
= (p
== P_SINGLE
) ? 4 : 8;
143 size_t output_width(argtype a
, precision p
)
145 size_t w
= (p
== P_SINGLE
) ? 4 : 8;
158 void io_loop(action a
, size_t n
)
162 size_t in_sz
= input_width(a
.a
, a
.p
);
163 size_t out_sz
= output_width(a
.a
, a
.p
);
165 if ((in_sz
* n
) / n
!= in_sz
) {
166 fprintf(stderr
, "impl-libc: input length overflow\n");
170 if ((out_sz
* n
) / n
!= out_sz
) {
171 fprintf(stderr
, "impl-libc: output length overflow\n");
175 if (!(in_buf
= malloc(in_sz
* n
))) {
176 perror("impl-libc: malloc");
180 if (!(out_buf
= malloc(out_sz
* n
))) {
181 perror("impl-libc: malloc");
186 read_buf(in_buf
, in_sz
* n
);
190 fprintf(stderr
, "impl-libc: impossible\n");
198 for (size_t j
= 0; j
< n
; ++j
) {
199 float *x
= (float *) (in_buf
+ (in_sz
*
201 float *y
= (float *) (out_buf
+
204 *y
= a
.f32
.f32__f32(*x
);
210 for (size_t j
= 0; j
< n
; ++j
) {
211 double *x
= (double *) (in_buf
+
213 double *y
= (double *) (out_buf
+
216 *y
= a
.f64
.f64__f64(*x
);
225 write_buf(out_buf
, out_sz
* n
);
229 int main(int argc
, char **argv
)
232 action a
= { .p
= P_SINGLE
};
235 while ((c
= getopt(argc
, argv
, "sdf:n:")) != -1) {
244 determine_function(optarg
, &a
);
248 n
= strtoll(optarg
, 0, 0);
251 perror("impl-libc: unparsable");
263 if (a
.a
== A_UNKNOWN
) {