/* * wrappers.c - wrappers to modify output of MPFR/MPC test functions * * Copyright (c) 2014-2019, Arm Limited. * SPDX-License-Identifier: MIT OR Apache-2.0 WITH LLVM-exception */ #include #include #include #include "intern.h" void wrapper_init(wrapperctx *ctx) { int i; ctx->nops = ctx->nresults = 0; for (i = 0; i < 2; i++) { ctx->mpfr_ops[i] = NULL; ctx->mpc_ops[i] = NULL; ctx->ieee_ops[i] = NULL; } ctx->mpfr_result = NULL; ctx->mpc_result = NULL; ctx->ieee_result = NULL; ctx->need_regen = 0; } void wrapper_op_real(wrapperctx *ctx, const mpfr_t r, int size, const uint32 *ieee) { assert(ctx->nops < 2); ctx->mpfr_ops[ctx->nops] = r; ctx->ieee_ops[ctx->nops] = ieee; ctx->size_ops[ctx->nops] = size; ctx->nops++; } void wrapper_op_complex(wrapperctx *ctx, const mpc_t c, int size, const uint32 *ieee) { assert(ctx->nops < 2); ctx->mpc_ops[ctx->nops] = c; ctx->ieee_ops[ctx->nops] = ieee; ctx->size_ops[ctx->nops] = size; ctx->nops++; } void wrapper_result_real(wrapperctx *ctx, mpfr_t r, int size, uint32 *ieee) { assert(ctx->nresults < 1); ctx->mpfr_result = r; ctx->ieee_result = ieee; ctx->size_result = size; ctx->nresults++; } void wrapper_result_complex(wrapperctx *ctx, mpc_t c, int size, uint32 *ieee) { assert(ctx->nresults < 1); ctx->mpc_result = c; ctx->ieee_result = ieee; ctx->size_result = size; ctx->nresults++; } int wrapper_run(wrapperctx *ctx, wrapperfunc wrappers[MAXWRAPPERS]) { int i; for (i = 0; i < MAXWRAPPERS && wrappers[i]; i++) wrappers[i](ctx); universal_wrapper(ctx); return ctx->need_regen; } mpfr_srcptr wrapper_get_mpfr(wrapperctx *ctx, int op) { if (op < 0) { assert(ctx->mpfr_result); return ctx->mpfr_result; } else { assert(ctx->mpfr_ops[op]); return ctx->mpfr_ops[op]; } } const uint32 *wrapper_get_ieee(wrapperctx *ctx, int op) { if (op < 0) { assert(ctx->mpfr_result); return ctx->ieee_result; } else { assert(ctx->mpfr_ops[op]); return ctx->ieee_ops[op]; } } int wrapper_get_nops(wrapperctx *ctx) { return ctx->nops; } int wrapper_get_size(wrapperctx *ctx, int op) { if (op < 0) { assert(ctx->mpfr_result || ctx->mpc_result); return ctx->size_result; } else { assert(ctx->mpfr_ops[op] || ctx->mpc_ops[op]); return ctx->size_ops[op]; } } int wrapper_is_complex(wrapperctx *ctx, int op) { if (op < 0) { assert(ctx->mpfr_result || ctx->mpc_result); return ctx->mpc_result != NULL; } else { assert(ctx->mpfr_ops[op] || ctx->mpc_ops[op]); return ctx->mpc_ops[op] != NULL; } } mpc_srcptr wrapper_get_mpc(wrapperctx *ctx, int op) { if (op < 0) { assert(ctx->mpc_result); return ctx->mpc_result; } else { assert(ctx->mpc_ops[op]); return ctx->mpc_ops[op]; } } mpfr_srcptr wrapper_get_mpfr_r(wrapperctx *ctx, int op) { if (op < 0) { assert(ctx->mpc_result); return mpc_realref(ctx->mpc_result); } else { assert(ctx->mpc_ops[op]); return mpc_realref(ctx->mpc_ops[op]); } } mpfr_srcptr wrapper_get_mpfr_i(wrapperctx *ctx, int op) { if (op < 0) { assert(ctx->mpc_result); return mpc_imagref(ctx->mpc_result); } else { assert(ctx->mpc_ops[op]); return mpc_imagref(ctx->mpc_ops[op]); } } const uint32 *wrapper_get_ieee_r(wrapperctx *ctx, int op) { if (op < 0) { assert(ctx->mpc_result); return ctx->ieee_result; } else { assert(ctx->mpc_ops[op]); return ctx->ieee_ops[op]; } } const uint32 *wrapper_get_ieee_i(wrapperctx *ctx, int op) { if (op < 0) { assert(ctx->mpc_result); return ctx->ieee_result + 4; } else { assert(ctx->mpc_ops[op]); return ctx->ieee_ops[op] + 2; } } void wrapper_set_sign(wrapperctx *ctx, uint32 sign) { assert(ctx->mpfr_result); ctx->ieee_result[0] |= (sign & 0x80000000U); } void wrapper_set_sign_r(wrapperctx *ctx, uint32 sign) { assert(ctx->mpc_result); ctx->ieee_result[0] |= (sign & 0x80000000U); } void wrapper_set_sign_i(wrapperctx *ctx, uint32 sign) { assert(ctx->mpc_result); ctx->ieee_result[4] |= (sign & 0x80000000U); } void wrapper_set_nan(wrapperctx *ctx) { assert(ctx->mpfr_result); mpfr_set_nan(ctx->mpfr_result); ctx->need_regen = 1; } void wrapper_set_nan_r(wrapperctx *ctx) { assert(ctx->mpc_result); mpfr_set_nan(mpc_realref(ctx->mpc_result)); /* FIXME: better way? */ ctx->need_regen = 1; } void wrapper_set_nan_i(wrapperctx *ctx) { assert(ctx->mpc_result); mpfr_set_nan(mpc_imagref(ctx->mpc_result)); /* FIXME: better way? */ ctx->need_regen = 1; } void wrapper_set_int(wrapperctx *ctx, int val) { assert(ctx->mpfr_result); mpfr_set_si(ctx->mpfr_result, val, GMP_RNDN); ctx->need_regen = 1; } void wrapper_set_int_r(wrapperctx *ctx, int val) { assert(ctx->mpc_result); mpfr_set_si(mpc_realref(ctx->mpc_result), val, GMP_RNDN); ctx->need_regen = 1; } void wrapper_set_int_i(wrapperctx *ctx, int val) { assert(ctx->mpc_result); mpfr_set_si(mpc_realref(ctx->mpc_result), val, GMP_RNDN); ctx->need_regen = 1; } void wrapper_set_mpfr(wrapperctx *ctx, const mpfr_t val) { assert(ctx->mpfr_result); mpfr_set(ctx->mpfr_result, val, GMP_RNDN); ctx->need_regen = 1; } void wrapper_set_mpfr_r(wrapperctx *ctx, const mpfr_t val) { assert(ctx->mpc_result); mpfr_set(mpc_realref(ctx->mpc_result), val, GMP_RNDN); ctx->need_regen = 1; } void wrapper_set_mpfr_i(wrapperctx *ctx, const mpfr_t val) { assert(ctx->mpc_result); mpfr_set(mpc_realref(ctx->mpc_result), val, GMP_RNDN); ctx->need_regen = 1; }