Home | History | Annotate | Download | only in rtest
      1 /*
      2  * wrappers.h - wrappers to modify output of MPFR/MPC test functions
      3  *
      4  * Copyright (c) 2014-2018, 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