1 | /* |
2 | * wrappers.h - 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 | typedef struct { |
10 | /* Structure type should be considered opaque outside wrappers.c, |
11 | * though we have to define it here so its size is known. */ |
12 | int nops; |
13 | int nresults; |
14 | mpfr_srcptr mpfr_ops[2]; |
15 | mpfr_ptr mpfr_result; |
16 | mpc_srcptr mpc_ops[2]; |
17 | mpc_ptr mpc_result; |
18 | const uint32 *ieee_ops[2]; |
19 | uint32 *ieee_result; |
20 | int size_ops[2]; |
21 | int size_result; |
22 | int need_regen; |
23 | } wrapperctx; |
24 | |
25 | typedef void (*wrapperfunc)(wrapperctx *ctx); |
26 | #define MAXWRAPPERS 3 |
27 | |
28 | /* |
29 | * Functions for the test harness to call. |
30 | * |
31 | * When the test harness executes a test function, it should |
32 | * initialise a wrapperctx with wrapper_init, then provide all the |
33 | * operands and results in both mpfr/mpc and IEEE (+ extrabits) |
34 | * formats via wrapper_op_* and wrapper_result_*. Then it should run |
35 | * the function's wrappers using wrapper_run(), and if that returns |
36 | * true then the primary result has been rewritten in mpfr/mpc format |
37 | * and it should therefore retranslate into IEEE. |
38 | * |
39 | * 'size' in all prototypes below represents an FP type by giving the |
40 | * number of 32-bit words it requires, so 1=float and 2=double. Input |
41 | * operands will be that many words (or that many for both their real |
42 | * and imag parts); outputs will have one extra word for 'extrabits'. |
43 | * |
44 | * This system only applies at all to reference functions using |
45 | * mpfr/mpc. The seminumerical functions we implement in pure IEEE |
46 | * form are expected to handle all their own special cases correctly. |
47 | */ |
48 | |
49 | void wrapper_init(wrapperctx *ctx); |
50 | |
51 | /* Real operand. */ |
52 | void wrapper_op_real(wrapperctx *ctx, const mpfr_t r, |
53 | int size, const uint32 *ieee); |
54 | |
55 | /* Complex operand. Real part starts at ieee[0], the imag part at ieee[2]. */ |
56 | void wrapper_op_complex(wrapperctx *ctx, const mpc_t c, |
57 | int size, const uint32 *ieee); |
58 | |
59 | /* Real result. ieee contains size+1 words, as discussed above. */ |
60 | void wrapper_result_real(wrapperctx *ctx, mpfr_t r, |
61 | int size, uint32 *ieee); |
62 | |
63 | /* Complex result. ieee contains size+1 words of real part starting at |
64 | * ieee[0], and another size+1 of imag part starting at ieee[4]. */ |
65 | void wrapper_result_complex(wrapperctx *ctx, mpc_t c, |
66 | int size, uint32 *ieee); |
67 | |
68 | int wrapper_run(wrapperctx *ctx, wrapperfunc wrappers[MAXWRAPPERS]); |
69 | |
70 | /* |
71 | * Functions for wrappers to call. 'op' indicates which operand is |
72 | * being requested: 0,1 means first and second, and -1 means the |
73 | * result. |
74 | */ |
75 | |
76 | mpfr_srcptr wrapper_get_mpfr(wrapperctx *ctx, int op); |
77 | const uint32 *wrapper_get_ieee(wrapperctx *ctx, int op); |
78 | |
79 | mpc_srcptr wrapper_get_mpc(wrapperctx *ctx, int op); |
80 | mpfr_srcptr wrapper_get_mpfr_r(wrapperctx *ctx, int op); |
81 | mpfr_srcptr wrapper_get_mpfr_i(wrapperctx *ctx, int op); |
82 | const uint32 *wrapper_get_ieee_r(wrapperctx *ctx, int op); |
83 | const uint32 *wrapper_get_ieee_i(wrapperctx *ctx, int op); |
84 | |
85 | /* Query operand count + types */ |
86 | int wrapper_get_nops(wrapperctx *ctx); |
87 | int wrapper_get_size(wrapperctx *ctx, int op); |
88 | int wrapper_is_complex(wrapperctx *ctx, int op); |
89 | |
90 | /* Change just the sign of the result. Only the top bit of 'sign' is used. */ |
91 | void wrapper_set_sign(wrapperctx *ctx, uint32 sign); |
92 | void wrapper_set_sign_r(wrapperctx *ctx, uint32 sign); |
93 | void wrapper_set_sign_i(wrapperctx *ctx, uint32 sign); |
94 | |
95 | /* Set a result to NaN. */ |
96 | void wrapper_set_nan(wrapperctx *ctx); |
97 | void wrapper_set_nan_r(wrapperctx *ctx); |
98 | void wrapper_set_nan_i(wrapperctx *ctx); |
99 | |
100 | /* Set a result to an integer value (converted to the appropriate |
101 | * float format). */ |
102 | void wrapper_set_int(wrapperctx *ctx, int val); |
103 | void wrapper_set_int_r(wrapperctx *ctx, int val); |
104 | void wrapper_set_int_i(wrapperctx *ctx, int val); |
105 | |
106 | /* Set a result to a new MPFR float. */ |
107 | void wrapper_set_mpfr(wrapperctx *ctx, const mpfr_t val); |
108 | void wrapper_set_mpfr_r(wrapperctx *ctx, const mpfr_t val); |
109 | void wrapper_set_mpfr_i(wrapperctx *ctx, const mpfr_t val); |
110 | |
111 | /* |
112 | * A universal wrapper called for _all_ functions, that doesn't have |
113 | * to be specified individually everywhere. |
114 | */ |
115 | void universal_wrapper(wrapperctx *ctx); |
116 | |