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