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