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