1 /*
2  * wrappers.c - wrappers to modify output of MPFR/MPC test functions
3  *
4  * Copyright (c) 2014-2018, Arm Limited.
5  * SPDX-License-Identifier: MIT
6  */
7 
8 #include <assert.h>
9 #include <stddef.h>
10 #include <stdint.h>
11 
12 #include "intern.h"
13 
14 void wrapper_init(wrapperctx *ctx)
15 {
16     int i;
17     ctx->nops = ctx->nresults = 0;
18     for (i = 0; i < 2; i++) {
19         ctx->mpfr_ops[i] = NULL;
20         ctx->mpc_ops[i] = NULL;
21         ctx->ieee_ops[i] = NULL;
22     }
23     ctx->mpfr_result = NULL;
24     ctx->mpc_result = NULL;
25     ctx->ieee_result = NULL;
26     ctx->need_regen = 0;
27 }
28 
29 void wrapper_op_real(wrapperctx *ctx, const mpfr_t r,
30                      int size, const uint32 *ieee)
31 {
32     assert(ctx->nops < 2);
33     ctx->mpfr_ops[ctx->nops] = r;
34     ctx->ieee_ops[ctx->nops] = ieee;
35     ctx->size_ops[ctx->nops] = size;
36     ctx->nops++;
37 }
38 
39 void wrapper_op_complex(wrapperctx *ctx, const mpc_t c,
40                         int size, const uint32 *ieee)
41 {
42     assert(ctx->nops < 2);
43     ctx->mpc_ops[ctx->nops] = c;
44     ctx->ieee_ops[ctx->nops] = ieee;
45     ctx->size_ops[ctx->nops] = size;
46     ctx->nops++;
47 }
48 
49 void wrapper_result_real(wrapperctx *ctx, mpfr_t r,
50                          int size, uint32 *ieee)
51 {
52     assert(ctx->nresults < 1);
53     ctx->mpfr_result = r;
54     ctx->ieee_result = ieee;
55     ctx->size_result = size;
56     ctx->nresults++;
57 }
58 
59 void wrapper_result_complex(wrapperctx *ctx, mpc_t c,
60                             int size, uint32 *ieee)
61 {
62     assert(ctx->nresults < 1);
63     ctx->mpc_result = c;
64     ctx->ieee_result = ieee;
65     ctx->size_result = size;
66     ctx->nresults++;
67 }
68 
69 int wrapper_run(wrapperctx *ctx, wrapperfunc wrappers[MAXWRAPPERS])
70 {
71     int i;
72     for (i = 0; i < MAXWRAPPERS && wrappers[i]; i++)
73         wrappers[i](ctx);
74     universal_wrapper(ctx);
75     return ctx->need_regen;
76 }
77 
78 mpfr_srcptr wrapper_get_mpfr(wrapperctx *ctx, int op)
79 {
80     if (op < 0) {
81         assert(ctx->mpfr_result);
82         return ctx->mpfr_result;
83     } else {
84         assert(ctx->mpfr_ops[op]);
85         return ctx->mpfr_ops[op];
86     }
87 }
88 
89 const uint32 *wrapper_get_ieee(wrapperctx *ctx, int op)
90 {
91     if (op < 0) {
92         assert(ctx->mpfr_result);
93         return ctx->ieee_result;
94     } else {
95         assert(ctx->mpfr_ops[op]);
96         return ctx->ieee_ops[op];
97     }
98 }
99 
100 int wrapper_get_nops(wrapperctx *ctx)
101 {
102     return ctx->nops;
103 }
104 
105 int wrapper_get_size(wrapperctx *ctx, int op)
106 {
107     if (op < 0) {
108         assert(ctx->mpfr_result || ctx->mpc_result);
109         return ctx->size_result;
110     } else {
111         assert(ctx->mpfr_ops[op] || ctx->mpc_ops[op]);
112         return ctx->size_ops[op];
113     }
114 }
115 
116 int wrapper_is_complex(wrapperctx *ctx, int op)
117 {
118     if (op < 0) {
119         assert(ctx->mpfr_result || ctx->mpc_result);
120         return ctx->mpc_result != NULL;
121     } else {
122         assert(ctx->mpfr_ops[op] || ctx->mpc_ops[op]);
123         return ctx->mpc_ops[op] != NULL;
124     }
125 }
126 
127 mpc_srcptr wrapper_get_mpc(wrapperctx *ctx, int op)
128 {
129     if (op < 0) {
130         assert(ctx->mpc_result);
131         return ctx->mpc_result;
132     } else {
133         assert(ctx->mpc_ops[op]);
134         return ctx->mpc_ops[op];
135     }
136 }
137 
138 mpfr_srcptr wrapper_get_mpfr_r(wrapperctx *ctx, int op)
139 {
140     if (op < 0) {
141         assert(ctx->mpc_result);
142         return mpc_realref(ctx->mpc_result);
143     } else {
144         assert(ctx->mpc_ops[op]);
145         return mpc_realref(ctx->mpc_ops[op]);
146     }
147 }
148 
149 mpfr_srcptr wrapper_get_mpfr_i(wrapperctx *ctx, int op)
150 {
151     if (op < 0) {
152         assert(ctx->mpc_result);
153         return mpc_imagref(ctx->mpc_result);
154     } else {
155         assert(ctx->mpc_ops[op]);
156         return mpc_imagref(ctx->mpc_ops[op]);
157     }
158 }
159 
160 const uint32 *wrapper_get_ieee_r(wrapperctx *ctx, int op)
161 {
162     if (op < 0) {
163         assert(ctx->mpc_result);
164         return ctx->ieee_result;
165     } else {
166         assert(ctx->mpc_ops[op]);
167         return ctx->ieee_ops[op];
168     }
169 }
170 
171 const uint32 *wrapper_get_ieee_i(wrapperctx *ctx, int op)
172 {
173     if (op < 0) {
174         assert(ctx->mpc_result);
175         return ctx->ieee_result + 4;
176     } else {
177         assert(ctx->mpc_ops[op]);
178         return ctx->ieee_ops[op] + 2;
179     }
180 }
181 
182 void wrapper_set_sign(wrapperctx *ctx, uint32 sign)
183 {
184     assert(ctx->mpfr_result);
185     ctx->ieee_result[0] |= (sign & 0x80000000U);
186 }
187 
188 void wrapper_set_sign_r(wrapperctx *ctx, uint32 sign)
189 {
190     assert(ctx->mpc_result);
191     ctx->ieee_result[0] |= (sign & 0x80000000U);
192 }
193 
194 void wrapper_set_sign_i(wrapperctx *ctx, uint32 sign)
195 {
196     assert(ctx->mpc_result);
197     ctx->ieee_result[4] |= (sign & 0x80000000U);
198 }
199 
200 void wrapper_set_nan(wrapperctx *ctx)
201 {
202     assert(ctx->mpfr_result);
203     mpfr_set_nan(ctx->mpfr_result);
204     ctx->need_regen = 1;
205 }
206 
207 void wrapper_set_nan_r(wrapperctx *ctx)
208 {
209     assert(ctx->mpc_result);
210     mpfr_set_nan(mpc_realref(ctx->mpc_result)); /* FIXME: better way? */
211     ctx->need_regen = 1;
212 }
213 
214 void wrapper_set_nan_i(wrapperctx *ctx)
215 {
216     assert(ctx->mpc_result);
217     mpfr_set_nan(mpc_imagref(ctx->mpc_result)); /* FIXME: better way? */
218     ctx->need_regen = 1;
219 }
220 
221 void wrapper_set_int(wrapperctx *ctx, int val)
222 {
223     assert(ctx->mpfr_result);
224     mpfr_set_si(ctx->mpfr_result, val, GMP_RNDN);
225     ctx->need_regen = 1;
226 }
227 
228 void wrapper_set_int_r(wrapperctx *ctx, int val)
229 {
230     assert(ctx->mpc_result);
231     mpfr_set_si(mpc_realref(ctx->mpc_result), val, GMP_RNDN);
232     ctx->need_regen = 1;
233 }
234 
235 void wrapper_set_int_i(wrapperctx *ctx, int val)
236 {
237     assert(ctx->mpc_result);
238     mpfr_set_si(mpc_realref(ctx->mpc_result), val, GMP_RNDN);
239     ctx->need_regen = 1;
240 }
241 
242 void wrapper_set_mpfr(wrapperctx *ctx, const mpfr_t val)
243 {
244     assert(ctx->mpfr_result);
245     mpfr_set(ctx->mpfr_result, val, GMP_RNDN);
246     ctx->need_regen = 1;
247 }
248 
249 void wrapper_set_mpfr_r(wrapperctx *ctx, const mpfr_t val)
250 {
251     assert(ctx->mpc_result);
252     mpfr_set(mpc_realref(ctx->mpc_result), val, GMP_RNDN);
253     ctx->need_regen = 1;
254 }
255 
256 void wrapper_set_mpfr_i(wrapperctx *ctx, const mpfr_t val)
257 {
258     assert(ctx->mpc_result);
259     mpfr_set(mpc_realref(ctx->mpc_result), val, GMP_RNDN);
260     ctx->need_regen = 1;
261 }
262