xref: /freebsd-src/contrib/arm-optimized-routines/math/test/rtest/wrappers.h (revision 072a4ba82a01476eaee33781ccd241033eefcf0b)
131914882SAlex Richardson /*
231914882SAlex Richardson  * wrappers.h - wrappers to modify output of MPFR/MPC test functions
331914882SAlex Richardson  *
431914882SAlex Richardson  * Copyright (c) 2014-2019, Arm Limited.
5*072a4ba8SAndrew Turner  * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception
631914882SAlex Richardson  */
731914882SAlex Richardson 
831914882SAlex Richardson typedef struct {
931914882SAlex Richardson     /* Structure type should be considered opaque outside wrappers.c,
1031914882SAlex Richardson      * though we have to define it here so its size is known. */
1131914882SAlex Richardson     int nops;
1231914882SAlex Richardson     int nresults;
1331914882SAlex Richardson     mpfr_srcptr mpfr_ops[2];
1431914882SAlex Richardson     mpfr_ptr mpfr_result;
1531914882SAlex Richardson     mpc_srcptr mpc_ops[2];
1631914882SAlex Richardson     mpc_ptr mpc_result;
1731914882SAlex Richardson     const uint32 *ieee_ops[2];
1831914882SAlex Richardson     uint32 *ieee_result;
1931914882SAlex Richardson     int size_ops[2];
2031914882SAlex Richardson     int size_result;
2131914882SAlex Richardson     int need_regen;
2231914882SAlex Richardson } wrapperctx;
2331914882SAlex Richardson 
2431914882SAlex Richardson typedef void (*wrapperfunc)(wrapperctx *ctx);
2531914882SAlex Richardson #define MAXWRAPPERS 3
2631914882SAlex Richardson 
2731914882SAlex Richardson /*
2831914882SAlex Richardson  * Functions for the test harness to call.
2931914882SAlex Richardson  *
3031914882SAlex Richardson  * When the test harness executes a test function, it should
3131914882SAlex Richardson  * initialise a wrapperctx with wrapper_init, then provide all the
3231914882SAlex Richardson  * operands and results in both mpfr/mpc and IEEE (+ extrabits)
3331914882SAlex Richardson  * formats via wrapper_op_* and wrapper_result_*. Then it should run
3431914882SAlex Richardson  * the function's wrappers using wrapper_run(), and if that returns
3531914882SAlex Richardson  * true then the primary result has been rewritten in mpfr/mpc format
3631914882SAlex Richardson  * and it should therefore retranslate into IEEE.
3731914882SAlex Richardson  *
3831914882SAlex Richardson  * 'size' in all prototypes below represents an FP type by giving the
3931914882SAlex Richardson  * number of 32-bit words it requires, so 1=float and 2=double. Input
4031914882SAlex Richardson  * operands will be that many words (or that many for both their real
4131914882SAlex Richardson  * and imag parts); outputs will have one extra word for 'extrabits'.
4231914882SAlex Richardson  *
4331914882SAlex Richardson  * This system only applies at all to reference functions using
4431914882SAlex Richardson  * mpfr/mpc. The seminumerical functions we implement in pure IEEE
4531914882SAlex Richardson  * form are expected to handle all their own special cases correctly.
4631914882SAlex Richardson  */
4731914882SAlex Richardson 
4831914882SAlex Richardson void wrapper_init(wrapperctx *ctx);
4931914882SAlex Richardson 
5031914882SAlex Richardson /* Real operand. */
5131914882SAlex Richardson void wrapper_op_real(wrapperctx *ctx, const mpfr_t r,
5231914882SAlex Richardson                      int size, const uint32 *ieee);
5331914882SAlex Richardson 
5431914882SAlex Richardson /* Complex operand. Real part starts at ieee[0], the imag part at ieee[2]. */
5531914882SAlex Richardson void wrapper_op_complex(wrapperctx *ctx, const mpc_t c,
5631914882SAlex Richardson                         int size, const uint32 *ieee);
5731914882SAlex Richardson 
5831914882SAlex Richardson /* Real result. ieee contains size+1 words, as discussed above. */
5931914882SAlex Richardson void wrapper_result_real(wrapperctx *ctx, mpfr_t r,
6031914882SAlex Richardson                          int size, uint32 *ieee);
6131914882SAlex Richardson 
6231914882SAlex Richardson /* Complex result. ieee contains size+1 words of real part starting at
6331914882SAlex Richardson  * ieee[0], and another size+1 of imag part starting at ieee[4]. */
6431914882SAlex Richardson void wrapper_result_complex(wrapperctx *ctx, mpc_t c,
6531914882SAlex Richardson                             int size, uint32 *ieee);
6631914882SAlex Richardson 
6731914882SAlex Richardson int wrapper_run(wrapperctx *ctx, wrapperfunc wrappers[MAXWRAPPERS]);
6831914882SAlex Richardson 
6931914882SAlex Richardson /*
7031914882SAlex Richardson  * Functions for wrappers to call. 'op' indicates which operand is
7131914882SAlex Richardson  * being requested: 0,1 means first and second, and -1 means the
7231914882SAlex Richardson  * result.
7331914882SAlex Richardson  */
7431914882SAlex Richardson 
7531914882SAlex Richardson mpfr_srcptr wrapper_get_mpfr(wrapperctx *ctx, int op);
7631914882SAlex Richardson const uint32 *wrapper_get_ieee(wrapperctx *ctx, int op);
7731914882SAlex Richardson 
7831914882SAlex Richardson mpc_srcptr wrapper_get_mpc(wrapperctx *ctx, int op);
7931914882SAlex Richardson mpfr_srcptr wrapper_get_mpfr_r(wrapperctx *ctx, int op);
8031914882SAlex Richardson mpfr_srcptr wrapper_get_mpfr_i(wrapperctx *ctx, int op);
8131914882SAlex Richardson const uint32 *wrapper_get_ieee_r(wrapperctx *ctx, int op);
8231914882SAlex Richardson const uint32 *wrapper_get_ieee_i(wrapperctx *ctx, int op);
8331914882SAlex Richardson 
8431914882SAlex Richardson /* Query operand count + types */
8531914882SAlex Richardson int wrapper_get_nops(wrapperctx *ctx);
8631914882SAlex Richardson int wrapper_get_size(wrapperctx *ctx, int op);
8731914882SAlex Richardson int wrapper_is_complex(wrapperctx *ctx, int op);
8831914882SAlex Richardson 
8931914882SAlex Richardson /* Change just the sign of the result. Only the top bit of 'sign' is used. */
9031914882SAlex Richardson void wrapper_set_sign(wrapperctx *ctx, uint32 sign);
9131914882SAlex Richardson void wrapper_set_sign_r(wrapperctx *ctx, uint32 sign);
9231914882SAlex Richardson void wrapper_set_sign_i(wrapperctx *ctx, uint32 sign);
9331914882SAlex Richardson 
9431914882SAlex Richardson /* Set a result to NaN. */
9531914882SAlex Richardson void wrapper_set_nan(wrapperctx *ctx);
9631914882SAlex Richardson void wrapper_set_nan_r(wrapperctx *ctx);
9731914882SAlex Richardson void wrapper_set_nan_i(wrapperctx *ctx);
9831914882SAlex Richardson 
9931914882SAlex Richardson /* Set a result to an integer value (converted to the appropriate
10031914882SAlex Richardson  * float format). */
10131914882SAlex Richardson void wrapper_set_int(wrapperctx *ctx, int val);
10231914882SAlex Richardson void wrapper_set_int_r(wrapperctx *ctx, int val);
10331914882SAlex Richardson void wrapper_set_int_i(wrapperctx *ctx, int val);
10431914882SAlex Richardson 
10531914882SAlex Richardson /* Set a result to a new MPFR float. */
10631914882SAlex Richardson void wrapper_set_mpfr(wrapperctx *ctx, const mpfr_t val);
10731914882SAlex Richardson void wrapper_set_mpfr_r(wrapperctx *ctx, const mpfr_t val);
10831914882SAlex Richardson void wrapper_set_mpfr_i(wrapperctx *ctx, const mpfr_t val);
10931914882SAlex Richardson 
11031914882SAlex Richardson /*
11131914882SAlex Richardson  * A universal wrapper called for _all_ functions, that doesn't have
11231914882SAlex Richardson  * to be specified individually everywhere.
11331914882SAlex Richardson  */
11431914882SAlex Richardson void universal_wrapper(wrapperctx *ctx);
115