blob: 5804935b9246958fe9e369760b0ca59f5c9edd06 [file] [log] [blame]
George Landerda55ef92015-11-19 12:05:06 +00001/*
Szabolcs Nagy1b945972018-05-14 14:46:40 +01002 * wrappers.h - wrappers to modify output of MPFR/MPC test functions
George Landerda55ef92015-11-19 12:05:06 +00003 *
Szabolcs Nagy11253b02018-11-12 11:10:57 +00004 * Copyright (c) 2014-2018, Arm Limited.
5 * SPDX-License-Identifier: MIT
George Landerda55ef92015-11-19 12:05:06 +00006 */
7
8typedef 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
24typedef 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
48void wrapper_init(wrapperctx *ctx);
49
50/* Real operand. */
51void 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]. */
55void 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. */
59void 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]. */
64void wrapper_result_complex(wrapperctx *ctx, mpc_t c,
65 int size, uint32 *ieee);
66
67int 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
75mpfr_srcptr wrapper_get_mpfr(wrapperctx *ctx, int op);
76const uint32 *wrapper_get_ieee(wrapperctx *ctx, int op);
77
78mpc_srcptr wrapper_get_mpc(wrapperctx *ctx, int op);
79mpfr_srcptr wrapper_get_mpfr_r(wrapperctx *ctx, int op);
80mpfr_srcptr wrapper_get_mpfr_i(wrapperctx *ctx, int op);
81const uint32 *wrapper_get_ieee_r(wrapperctx *ctx, int op);
82const uint32 *wrapper_get_ieee_i(wrapperctx *ctx, int op);
83
84/* Query operand count + types */
85int wrapper_get_nops(wrapperctx *ctx);
86int wrapper_get_size(wrapperctx *ctx, int op);
87int wrapper_is_complex(wrapperctx *ctx, int op);
88
89/* Change just the sign of the result. Only the top bit of 'sign' is used. */
90void wrapper_set_sign(wrapperctx *ctx, uint32 sign);
91void wrapper_set_sign_r(wrapperctx *ctx, uint32 sign);
92void wrapper_set_sign_i(wrapperctx *ctx, uint32 sign);
93
94/* Set a result to NaN. */
95void wrapper_set_nan(wrapperctx *ctx);
96void wrapper_set_nan_r(wrapperctx *ctx);
97void wrapper_set_nan_i(wrapperctx *ctx);
98
99/* Set a result to an integer value (converted to the appropriate
100 * float format). */
101void wrapper_set_int(wrapperctx *ctx, int val);
102void wrapper_set_int_r(wrapperctx *ctx, int val);
103void wrapper_set_int_i(wrapperctx *ctx, int val);
104
105/* Set a result to a new MPFR float. */
106void wrapper_set_mpfr(wrapperctx *ctx, const mpfr_t val);
107void wrapper_set_mpfr_r(wrapperctx *ctx, const mpfr_t val);
108void 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 */
114void universal_wrapper(wrapperctx *ctx);