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