1 /*
2 * wrappers.c - wrappers to modify output of MPFR/MPC test functions
3 *
4 * Copyright (c) 2014-2019, 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
wrapper_init(wrapperctx * ctx)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
wrapper_op_real(wrapperctx * ctx,const mpfr_t r,int size,const uint32 * ieee)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
wrapper_op_complex(wrapperctx * ctx,const mpc_t c,int size,const uint32 * ieee)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
wrapper_result_real(wrapperctx * ctx,mpfr_t r,int size,uint32 * ieee)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
wrapper_result_complex(wrapperctx * ctx,mpc_t c,int size,uint32 * ieee)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
wrapper_run(wrapperctx * ctx,wrapperfunc wrappers[MAXWRAPPERS])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
wrapper_get_mpfr(wrapperctx * ctx,int op)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
wrapper_get_ieee(wrapperctx * ctx,int op)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
wrapper_get_nops(wrapperctx * ctx)100 int wrapper_get_nops(wrapperctx *ctx)
101 {
102 return ctx->nops;
103 }
104
wrapper_get_size(wrapperctx * ctx,int op)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
wrapper_is_complex(wrapperctx * ctx,int op)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
wrapper_get_mpc(wrapperctx * ctx,int op)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
wrapper_get_mpfr_r(wrapperctx * ctx,int op)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
wrapper_get_mpfr_i(wrapperctx * ctx,int op)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
wrapper_get_ieee_r(wrapperctx * ctx,int op)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
wrapper_get_ieee_i(wrapperctx * ctx,int op)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
wrapper_set_sign(wrapperctx * ctx,uint32 sign)182 void wrapper_set_sign(wrapperctx *ctx, uint32 sign)
183 {
184 assert(ctx->mpfr_result);
185 ctx->ieee_result[0] |= (sign & 0x80000000U);
186 }
187
wrapper_set_sign_r(wrapperctx * ctx,uint32 sign)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
wrapper_set_sign_i(wrapperctx * ctx,uint32 sign)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
wrapper_set_nan(wrapperctx * ctx)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
wrapper_set_nan_r(wrapperctx * ctx)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
wrapper_set_nan_i(wrapperctx * ctx)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
wrapper_set_int(wrapperctx * ctx,int val)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
wrapper_set_int_r(wrapperctx * ctx,int val)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
wrapper_set_int_i(wrapperctx * ctx,int val)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
wrapper_set_mpfr(wrapperctx * ctx,const mpfr_t val)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
wrapper_set_mpfr_r(wrapperctx * ctx,const mpfr_t val)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
wrapper_set_mpfr_i(wrapperctx * ctx,const mpfr_t val)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