/*
 * QEMU float support - standalone helpers
 *
 * This is provided for files that don't need the access to the full
 * set of softfloat functions. Typically this is cpu initialisation
 * code which wants to set default rounding and exceptions modes.
 *
 * The code in this source file is derived from release 2a of the SoftFloat
 * IEC/IEEE Floating-point Arithmetic Package. Those parts of the code (and
 * some later contributions) are provided under that license, as detailed below.
 * It has subsequently been modified by contributors to the QEMU Project,
 * so some portions are provided under:
 *  the SoftFloat-2a license
 *  the BSD license
 *  GPL-v2-or-later
 *
 * Any future contributions to this file after December 1st 2014 will be
 * taken to be licensed under the Softfloat-2a license unless specifically
 * indicated otherwise.
 */

/*
===============================================================================
This C header file is part of the SoftFloat IEC/IEEE Floating-point
Arithmetic Package, Release 2a.

Written by John R. Hauser.  This work was made possible in part by the
International Computer Science Institute, located at Suite 600, 1947 Center
Street, Berkeley, California 94704.  Funding was partially provided by the
National Science Foundation under grant MIP-9311980.  The original version
of this code was written as part of a project to build a fixed-point vector
processor in collaboration with the University of California at Berkeley,
overseen by Profs. Nelson Morgan and John Wawrzynek.  More information
is available through the Web page `http://HTTP.CS.Berkeley.EDU/~jhauser/
arithmetic/SoftFloat.html'.

THIS SOFTWARE IS DISTRIBUTED AS IS, FOR FREE.  Although reasonable effort
has been made to avoid it, THIS SOFTWARE MAY CONTAIN FAULTS THAT WILL AT
TIMES RESULT IN INCORRECT BEHAVIOR.  USE OF THIS SOFTWARE IS RESTRICTED TO
PERSONS AND ORGANIZATIONS WHO CAN AND WILL TAKE FULL RESPONSIBILITY FOR ANY
AND ALL LOSSES, COSTS, OR OTHER PROBLEMS ARISING FROM ITS USE.

Derivative works are acceptable, even for commercial purposes, so long as
(1) they include prominent notice that the work is derivative, and (2) they
include prominent notice akin to these four paragraphs for those parts of
this code that are retained.

===============================================================================
*/

#ifndef SOFTFLOAT_HELPERS_H
#define SOFTFLOAT_HELPERS_H

#include "fpu/softfloat-types.h"

static inline void set_float_detect_tininess(bool val, float_status *status)
{
    status->tininess_before_rounding = val;
}

static inline void set_float_rounding_mode(FloatRoundMode val,
                                           float_status *status)
{
    status->float_rounding_mode = val;
}

static inline void
set_float_exception_flags(FloatExceptionFlags val, float_status *status)
{
    status->float_exception_flags = val;
}

static inline void set_floatx80_rounding_precision(FloatX80RoundPrec val,
                                                   float_status *status)
{
    status->floatx80_rounding_precision = val;
}

static inline void set_floatx80_behaviour(FloatX80Behaviour b,
                                          float_status *status)
{
    status->floatx80_behaviour = b;
}

static inline void set_float_2nan_prop_rule(Float2NaNPropRule rule,
                                            float_status *status)
{
    status->float_2nan_prop_rule = rule;
}

static inline void set_float_3nan_prop_rule(Float3NaNPropRule rule,
                                            float_status *status)
{
    status->float_3nan_prop_rule = rule;
}

static inline void set_float_infzeronan_rule(FloatInfZeroNaNRule rule,
                                             float_status *status)
{
    status->float_infzeronan_rule = rule;
}

static inline void set_float_default_nan_pattern(uint8_t dnan_pattern,
                                                 float_status *status)
{
    status->default_nan_pattern = dnan_pattern;
}

static inline void set_flush_to_zero(bool val, float_status *status)
{
    status->flush_to_zero = val;
}

static inline void set_flush_inputs_to_zero(bool val, float_status *status)
{
    status->flush_inputs_to_zero = val;
}

static inline void set_float_ftz_detection(bool val, float_status *status)
{
    status->ftz_before_rounding = val;
}

static inline void set_default_nan_mode(bool val, float_status *status)
{
    status->default_nan_mode = val;
}

static inline void set_snan_rule(FloatSNaNRule val, float_status *status)
{
    status->float_snan_rule = val;
}

static inline void set_float_e4m3_nan_is_snan(bool val, float_status *status)
{
    status->e4m3_nan_is_snan = val;
}

static inline void set_float_rebias_overflow(bool val, float_status *status)
{
    status->rebias_overflow = val;
}

static inline void set_float_rebias_underflow(bool val, float_status *status)
{
    status->rebias_underflow = val;
}

static inline FloatRoundMode get_float_rounding_mode(const float_status *status)
{
    return status->float_rounding_mode;
}

static inline FloatExceptionFlags
get_float_exception_flags(const float_status *status)
{
    return status->float_exception_flags;
}

static inline FloatX80RoundPrec
get_floatx80_rounding_precision(const float_status *status)
{
    return status->floatx80_rounding_precision;
}

static inline FloatX80Behaviour
get_floatx80_behaviour(const float_status *status)
{
    return status->floatx80_behaviour;
}

static inline Float2NaNPropRule
get_float_2nan_prop_rule(const float_status *status)
{
    return status->float_2nan_prop_rule;
}

static inline Float3NaNPropRule
get_float_3nan_prop_rule(const float_status *status)
{
    return status->float_3nan_prop_rule;
}

static inline FloatInfZeroNaNRule
get_float_infzeronan_rule(const float_status *status)
{
    return status->float_infzeronan_rule;
}

static inline bool get_flush_to_zero(const float_status *status)
{
    return status->flush_to_zero;
}

static inline bool get_flush_inputs_to_zero(const float_status *status)
{
    return status->flush_inputs_to_zero;
}

static inline bool get_default_nan_mode(const float_status *status)
{
    return status->default_nan_mode;
}

static inline FloatSNaNRule get_snan_rule(float_status *status)
{
    return status->float_snan_rule;
}

#endif /* SOFTFLOAT_HELPERS_H */
