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