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 OR Apache-2.0 WITH LLVM-exception
6 */
7
8#include <assert.h>
9#include <stddef.h>
10#include <stdint.h>
11
12#include "intern.h"
13
14void 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
29void 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
39void 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
49void 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
59void 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
69int 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
78mpfr_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
89const 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
100int wrapper_get_nops(wrapperctx *ctx)
101{
102    return ctx->nops;
103}
104
105int 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
116int 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
127mpc_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
138mpfr_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
149mpfr_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
160const 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
171const 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
182void wrapper_set_sign(wrapperctx *ctx, uint32 sign)
183{
184    assert(ctx->mpfr_result);
185    ctx->ieee_result[0] |= (sign & 0x80000000U);
186}
187
188void wrapper_set_sign_r(wrapperctx *ctx, uint32 sign)
189{
190    assert(ctx->mpc_result);
191    ctx->ieee_result[0] |= (sign & 0x80000000U);
192}
193
194void wrapper_set_sign_i(wrapperctx *ctx, uint32 sign)
195{
196    assert(ctx->mpc_result);
197    ctx->ieee_result[4] |= (sign & 0x80000000U);
198}
199
200void 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
207void 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
214void 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
221void 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
228void 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
235void 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
242void 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
249void 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
256void 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