/*****************************************************************************

  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
  more contributor license agreements.  See the NOTICE file distributed
  with this work for additional information regarding copyright ownership.
  Accellera licenses this file to you under the Apache License, Version 2.0
  (the "License"); you may not use this file except in compliance with the
  License.  You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

  Unless required by applicable law or agreed to in writing, software
  distributed under the License is distributed on an "AS IS" BASIS,
  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
  implied.  See the License for the specific language governing
  permissions and limitations under the License.

 *****************************************************************************/

/*****************************************************************************

  sc_fxnum.cpp -

  Original Author: Martin Janssen, Synopsys, Inc.

 *****************************************************************************/

/*****************************************************************************

  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
  changes you are making here.

      Name, Affiliation, Date:
  Description of Modification:

 *****************************************************************************/


// $Log: sc_fxnum.cpp,v $
// Revision 1.3  2011/01/19 18:57:40  acg
//  Andy Goodrich: changes for IEEE_1666_2011.
//
// Revision 1.2  2010/12/07 20:09:08  acg
// Andy Goodrich: Philipp Hartmann's constructor disambiguation fix
//
// Revision 1.1.1.1  2006/12/15 20:20:04  acg
// SystemC 2.3
//
// Revision 1.3  2006/01/13 18:53:57  acg
// Andy Goodrich: added $Log command so that CVS comments are reproduced in
// the source.
//

#include <cmath>

#include "systemc/ext/dt/fx/messages.hh"
#include "systemc/ext/dt/fx/sc_fxnum.hh"

namespace sc_dt
{

// ----------------------------------------------------------------------------
//  CLASS : sc_fxnum_bitref
//
//  Proxy class for bit-selection in class sc_fxnum, behaves like sc_bit.
// ----------------------------------------------------------------------------

bool sc_fxnum_bitref::get() const { return m_num.get_bit(m_idx); }
void sc_fxnum_bitref::set(bool high) { m_num.set_bit(m_idx, high); }

// print or dump content
void sc_fxnum_bitref::print(::std::ostream &os) const { os << get(); }

void
sc_fxnum_bitref::scan(::std::istream &is)
{
    bool b;
    is >> b;
    *this = b;
}

void
sc_fxnum_bitref::dump(::std::ostream &os) const
{
    os << "sc_fxnum_bitref" << ::std::endl;
    os << "(" << ::std::endl;
    os << "num = ";
    m_num.dump(os);
    os << "idx = " << m_idx << ::std::endl;
    os << ")" << ::std::endl;
}


// ----------------------------------------------------------------------------
//  CLASS : sc_fxnum_fast_bitref
//
//  Proxy class for bit-selection in class sc_fxnum_fast, behaves like sc_bit.
// ----------------------------------------------------------------------------

bool sc_fxnum_fast_bitref::get() const { return m_num.get_bit(m_idx); }
void sc_fxnum_fast_bitref::set(bool high) { m_num.set_bit(m_idx, high); }

// print or dump content
void sc_fxnum_fast_bitref::print(::std::ostream &os) const { os << get(); }

void
sc_fxnum_fast_bitref::scan(::std::istream &is)
{
    bool b;
    is >> b;
    *this = b;
}

void
sc_fxnum_fast_bitref::dump(::std::ostream &os) const
{
    os << "sc_fxnum_fast_bitref" << ::std::endl;
    os << "(" << ::std::endl;
    os << "num = ";
    m_num.dump(os);
    os << "idx = " << m_idx << ::std::endl;
    os << ")" << ::std::endl;
}

// ----------------------------------------------------------------------------
//  CLASS : sc_fxnum_subref
//
//  Proxy class for part-selection in class sc_fxnum,
//  behaves like sc_bv_base.
// ----------------------------------------------------------------------------

bool
sc_fxnum_subref::get() const
{
    return m_num.get_slice(m_from, m_to, m_bv);
}

bool
sc_fxnum_subref::set()
{
    return m_num.set_slice(m_from, m_to, m_bv);
}

// print or dump content
void
sc_fxnum_subref::print(::std::ostream &os) const
{
    get();
    m_bv.print(os);
}

void
sc_fxnum_subref::scan(::std::istream &is)
{
    m_bv.scan(is);
    set();
}

void
sc_fxnum_subref::dump(::std::ostream &os) const
{
    os << "sc_fxnum_subref" << ::std::endl;
    os << "(" << ::std::endl;
    os << "num  = ";
    m_num.dump(os);
    os << "from = " << m_from << ::std::endl;
    os << "to   = " << m_to << ::std::endl;
    os << ")" << ::std::endl;
}


// ----------------------------------------------------------------------------
//  CLASS : sc_fxnum_fast_subref
//
//  Proxy class for part-selection in class sc_fxnum_fast,
//  behaves like sc_bv_base.
// ----------------------------------------------------------------------------

bool
sc_fxnum_fast_subref::get() const
{
    return m_num.get_slice(m_from, m_to, m_bv);
}

bool
sc_fxnum_fast_subref::set()
{
    return m_num.set_slice(m_from, m_to, m_bv);
}

// print or dump content
void
sc_fxnum_fast_subref::print(::std::ostream &os) const
{
    get();
    m_bv.print(os);
}

void
sc_fxnum_fast_subref::scan(::std::istream &is)
{
    m_bv.scan(is);
    set();
}

void
sc_fxnum_fast_subref::dump(::std::ostream &os) const
{
    os << "sc_fxnum_fast_subref" << ::std::endl;
    os << "(" << ::std::endl;
    os << "num  = ";
    m_num.dump(os);
    os << "from = " << m_from << ::std::endl;
    os << "to   = " << m_to << ::std::endl;
    os << ")" << ::std::endl;
}


// ----------------------------------------------------------------------------
//  CLASS : sc_fxnum
//
//  Base class for the fixed-point types; arbitrary precision.
// ----------------------------------------------------------------------------

// explicit conversion to character string

const std::string
sc_fxnum::to_string() const
{
    return std::string(m_rep->to_string(SC_DEC, -1, SC_F, &m_params));
}

const std::string
sc_fxnum::to_string(sc_numrep numrep) const
{
    return std::string(m_rep->to_string(numrep, -1, SC_F, &m_params));
}

const std::string
sc_fxnum::to_string(sc_numrep numrep, bool w_prefix) const
{
    return std::string(m_rep->to_string(numrep, (w_prefix ? 1 : 0),
                                        SC_F, &m_params));
}

const std::string
sc_fxnum::to_string(sc_fmt fmt) const
{
    return std::string(m_rep->to_string(SC_DEC, -1, fmt, &m_params));
}

const std::string
sc_fxnum::to_string(sc_numrep numrep, sc_fmt fmt) const
{
    return std::string(m_rep->to_string(numrep, -1, fmt, &m_params));
}

const std::string
sc_fxnum::to_string(sc_numrep numrep, bool w_prefix, sc_fmt fmt) const
{
    return std::string(m_rep->to_string(numrep, (w_prefix ? 1 : 0),
                                        fmt, &m_params));
}


const std::string
sc_fxnum::to_dec() const
{
    return std::string(m_rep->to_string(SC_DEC, -1, SC_F, &m_params));
}

const std::string
sc_fxnum::to_bin() const
{
    return std::string(m_rep->to_string(SC_BIN, -1, SC_F, &m_params));
}

const std::string
sc_fxnum::to_oct() const
{
    return std::string(m_rep->to_string(SC_OCT, -1, SC_F, &m_params));
}

const std::string
sc_fxnum::to_hex() const
{
    return std::string(m_rep->to_string(SC_HEX, -1, SC_F, &m_params));
}


// print or dump content
void
sc_fxnum::print(::std::ostream &os) const
{
    os << m_rep->to_string(SC_DEC, -1, SC_F, &m_params);
}

void
sc_fxnum::scan(::std::istream &is)
{
    std::string s;
    is >> s;
    *this = s.c_str();
}

void
sc_fxnum::dump(::std::ostream &os) const
{
    os << "sc_fxnum" << ::std::endl;
    os << "(" << ::std::endl;
    os << "rep      = ";
    m_rep->dump(os);
    os << "params   = ";
    m_params.dump(os);
    os << "q_flag   = " << m_q_flag << ::std::endl;
    os << "o_flag   = " << m_o_flag << ::std::endl;
    // TO BE COMPLETED
    // os << "observer = ";
    // if (m_observer != 0)
    //     m_observer->dump(os);
    // else
    //     os << "0" << ::std::endl;
    os << ")" << ::std::endl;
}


sc_fxnum_observer *
sc_fxnum::lock_observer() const
{
    SC_ASSERT_(m_observer != 0, "lock observer failed");
    sc_fxnum_observer * tmp = m_observer;
    m_observer = 0;
    return tmp;
}

void
sc_fxnum::unlock_observer(sc_fxnum_observer *observer_) const
{
    SC_ASSERT_(observer_ != 0, "unlock observer failed");
    m_observer = observer_;
}


// ----------------------------------------------------------------------------
//  CLASS : sc_fxnum_fast
//
//  Base class for the fixed-point types; limited precision.
// ----------------------------------------------------------------------------

static void
quantization(double &c, const scfx_params &params, bool &q_flag)
{
    int fwl = params.wl() - params.iwl();
    double scale = scfx_pow2(fwl);
    double val = scale * c;
    double int_part;
    double frac_part = modf(val, &int_part);

    q_flag = (frac_part != 0.0);

    if (q_flag) {
        val = int_part;

        switch (params.q_mode()) {
          case SC_TRN: // truncation
            {
                if (c < 0.0)
                    val -= 1.0;
                break;
            }
          case SC_RND: // rounding to plus infinity
            {
                if (frac_part >= 0.5)
                    val += 1.0;
                else if (frac_part < -0.5)
                    val -= 1.0;
                break;
            }
          case SC_TRN_ZERO: // truncation to zero
            {
                break;
            }
          case SC_RND_INF: // rounding to infinity
            {
                if (frac_part >= 0.5)
                    val += 1.0;
                else if (frac_part <= -0.5)
                    val -= 1.0;
                break;
            }
          case SC_RND_CONV: // convergent rounding
            {
                if (frac_part > 0.5 ||
                    (frac_part == 0.5 && fmod(int_part, 2.0) != 0.0)) {
                    val += 1.0;
                } else if (frac_part < -0.5 ||
                           (frac_part == -0.5 && fmod(int_part, 2.0) != 0.0)) {
                    val -= 1.0;
                }
                break;
            }
          case SC_RND_ZERO: // rounding to zero
            {
                if (frac_part > 0.5)
                    val += 1.0;
                else if (frac_part < -0.5)
                    val -= 1.0;
                break;
            }
          case SC_RND_MIN_INF: // rounding to minus infinity
            {
                if (frac_part > 0.5)
                    val += 1.0;
                else if (frac_part <= -0.5)
                    val -= 1.0;
                break;
            }
          default:
            ;
        }
    }

    val /= scale;
    c = val;
}

static void
overflow(double &c, const scfx_params &params, bool &o_flag)
{
    int iwl = params.iwl();
    int fwl = params.wl() - iwl;
    double full_circle = scfx_pow2(iwl);
    double resolution = scfx_pow2(-fwl);
    double low, high;
    if (params.enc() == SC_TC_) {
        high = full_circle / 2.0 - resolution;
        if (params.o_mode() == SC_SAT_SYM)
            low = - high;
        else
            low = - full_circle / 2.0;
    } else {
        low = 0.0;
        high = full_circle - resolution;
    }
    double val = c;
    sc_fxval_fast c2(c);

    bool under = (val < low);
    bool over = (val > high);

    o_flag = (under || over);

    if (o_flag) {
        switch (params.o_mode()) {
          case SC_WRAP: // wrap-around
            {
                int n_bits = params.n_bits();

                if (n_bits == 0) {
                    // wrap-around all 'wl' bits
                    val -= floor(val / full_circle) * full_circle;
                    if (val > high)
                        val -= full_circle;
                } else if (n_bits < params.wl()) {
                    double X = scfx_pow2(iwl - n_bits);

                    // wrap-around least significant 'wl - n_bits' bits
                    val -= floor(val / X) * X;
                    if (val > (X - resolution))
                        val -= X;

                    // saturate most significant 'n_bits' bits
                    if (under) {
                        val += low;
                    } else {
                        if (params.enc() == SC_TC_)
                            val += full_circle / 2.0 - X;
                        else
                            val += full_circle - X;
                    }
                } else {
                    // saturate all 'wl' bits
                    if (under)
                        val = low;
                    else
                        val = high;
                }
                break;
            }
          case SC_SAT: // saturation
          case SC_SAT_SYM: // symmetrical saturation
            {
                if (under)
                    val = low;
                else
                    val = high;
                break;
            }
          case SC_SAT_ZERO: // saturation to zero
            {
                val = 0.0;
                break;
            }
          case SC_WRAP_SM: // sign magnitude wrap-around
            {
                SC_ERROR_IF_(params.enc() == SC_US_,
                             sc_core::SC_ID_WRAP_SM_NOT_DEFINED_);

                int n_bits = params.n_bits();

                if (n_bits == 0) {
                    // invert conditionally
                    if (c2.get_bit(iwl) != c2.get_bit(iwl - 1))
                        val = -val - resolution;

                    // wrap-around all 'wl' bits
                    val -= floor(val / full_circle) * full_circle;
                    if (val > high)
                        val -= full_circle;
                } else if (n_bits == 1) {
                    // invert conditionally
                    if (c2.is_neg() != c2.get_bit(iwl - 1))
                        val = -val - resolution;

                    // wrap-around all 'wl' bits
                    val -= floor(val / full_circle) * full_circle;
                    if (val > high)
                        val -= full_circle;
                } else if (n_bits < params.wl()) {
                    // invert conditionally
                    if (c2.is_neg() == c2.get_bit(iwl - n_bits))
                        val = -val - resolution;

                    double X = scfx_pow2(iwl - n_bits);

                    // wrap-around least significant 'wl - n_bits' bits
                    val -= floor(val / X) * X;
                    if (val > (X - resolution))
                        val -= X;

                    // saturate most significant 'n_bits' bits
                    if (under)
                        val += low;
                    else
                        val += full_circle / 2.0 - X;
                } else {
                    // saturate all 'wl' bits
                    if (under)
                        val = low;
                    else
                        val = high;
                }
                break;
            }
            default:
                ;
        }

        c = val;
    }
}


void
sc_fxnum_fast::cast()
{
    scfx_ieee_double id(m_val);
    SC_ERROR_IF_(id.is_nan() || id.is_inf(), sc_core::SC_ID_INVALID_FX_VALUE_);

    if (m_params.cast_switch() == SC_ON) {
        m_q_flag = false;
        m_o_flag = false;

        // check for special cases

        if (id.is_zero()) {
            if (id.negative() != 0)
                m_val = -m_val;
            return;
        }

        // perform casting
        sc_dt::quantization(m_val, m_params, m_q_flag);
        sc_dt::overflow(m_val, m_params, m_o_flag);

        // check for special case: -0
        id = m_val;
        if (id.is_zero() && id.negative() != 0) {
            m_val = -m_val;
        }

        // check for special case: NaN of Inf
        if (id.is_nan() || id.is_inf()) {
            m_val = 0.0;
        }
    }
}


// defined in sc_fxval.cpp;
extern const char* to_string(const scfx_ieee_double &, sc_numrep, int, sc_fmt,
                             const scfx_params * =0);


// explicit conversion to character string

const std::string
sc_fxnum_fast::to_string() const
{
    return std::string(sc_dt::to_string(m_val, SC_DEC, -1, SC_F, &m_params));
}

const std::string
sc_fxnum_fast::to_string(sc_numrep numrep) const
{
    return std::string(sc_dt::to_string(m_val, numrep, -1, SC_F, &m_params));
}

const std::string
sc_fxnum_fast::to_string(sc_numrep numrep, bool w_prefix) const
{
    return std::string(sc_dt::to_string(m_val, numrep, (w_prefix ? 1 : 0),
                                        SC_F, &m_params));
}

const std::string
sc_fxnum_fast::to_string(sc_fmt fmt) const
{
    return std::string(sc_dt::to_string(m_val, SC_DEC, -1, fmt, &m_params));
}

const std::string
sc_fxnum_fast::to_string(sc_numrep numrep, sc_fmt fmt) const
{
    return std::string(sc_dt::to_string(m_val, numrep, -1, fmt, &m_params));
}

const std::string
sc_fxnum_fast::to_string(sc_numrep numrep, bool w_prefix, sc_fmt fmt) const
{
    return std::string(sc_dt::to_string(m_val, numrep, (w_prefix ? 1 : 0),
                                        fmt, &m_params));
}


const std::string
sc_fxnum_fast::to_dec() const
{
    return std::string(sc_dt::to_string(m_val, SC_DEC, -1, SC_F, &m_params));
}

const std::string
sc_fxnum_fast::to_bin() const
{
    return std::string(sc_dt::to_string(m_val, SC_BIN, -1, SC_F, &m_params));
}

const std::string
sc_fxnum_fast::to_oct() const
{
    return std::string(sc_dt::to_string(m_val, SC_OCT, -1, SC_F, &m_params));
}

const std::string
sc_fxnum_fast::to_hex() const
{
    return std::string(sc_dt::to_string(m_val, SC_HEX, -1, SC_F, &m_params));
}

// print or dump content
void
sc_fxnum_fast::print(::std::ostream &os) const
{
    os << sc_dt::to_string(m_val, SC_DEC, -1, SC_F, &m_params);
}

void
sc_fxnum_fast::scan(::std::istream &is)
{
    std::string s;
    is >> s;
    *this = s.c_str();
}

void
sc_fxnum_fast::dump(::std::ostream &os) const
{
    os << "sc_fxnum_fast" << ::std::endl;
    os << "(" << ::std::endl;
    os << "val      = " << m_val << ::std::endl;
    os << "params   = ";
    m_params.dump(os);
    os << "q_flag   = " << m_q_flag << ::std::endl;
    os << "o_flag   = " << m_o_flag << ::std::endl;
    // TO BE COMPLETED
    // os << "observer = ";
    // if (m_observer != 0)
    //     m_observer->dump(os);
    // else
    //     os << "0" << ::std::endl;
    os << ")" << ::std::endl;
}

// internal use only;
bool
sc_fxnum_fast::get_bit(int i) const
{
    scfx_ieee_double id(m_val);
    if (id.is_zero() || id.is_nan() || id.is_inf())
        return false;

    // convert to two's complement
    unsigned int m0 = id.mantissa0();
    unsigned int m1 = id.mantissa1();

    if (id.is_normal())
        m0 += 1U << 20;

    if (id.negative() != 0) {
        m0 = ~ m0;
        m1 = ~ m1;
        unsigned int tmp = m1;
        m1 += 1U;
        if (m1 <= tmp)
            m0 += 1U;
    }

    // get the right bit
    int j = i - id.exponent();
    if ((j += 20) >= 32)
        return ((m0 & 1U << 31) != 0);
    else if (j >= 0)
        return ((m0 & 1U << j) != 0);
    else if ((j += 32) >= 0)
        return ((m1 & 1U << j) != 0);
    else
        return false;
}


bool
sc_fxnum_fast::set_bit(int i, bool high)
{
    scfx_ieee_double id(m_val);
    if (id.is_nan() || id.is_inf())
        return false;

    if (high) {
        if (get_bit(i))
            return true;

        if (m_params.enc() == SC_TC_ && i == m_params.iwl() - 1)
            m_val -= scfx_pow2(i);
        else
            m_val += scfx_pow2(i);
    } else {
        if (!get_bit(i))
            return true;

        if (m_params.enc() == SC_TC_ && i == m_params.iwl() - 1)
            m_val += scfx_pow2(i);
        else
            m_val -= scfx_pow2(i);
    }

    return true;
}


bool
sc_fxnum_fast::get_slice(int i, int j, sc_bv_base &bv) const
{
    scfx_ieee_double id(m_val);
    if (id.is_nan() || id.is_inf())
        return false;

    // convert to two's complement
    unsigned int m0 = id.mantissa0();
    unsigned int m1 = id.mantissa1();

    if (id.is_normal())
        m0 += 1U << 20;

    if (id.negative() != 0) {
        m0 = ~ m0;
        m1 = ~ m1;
        unsigned int tmp = m1;
        m1 += 1U;
        if (m1 <= tmp)
            m0 += 1U;
    }

    // get the bits
    int l = j;
    for (int k = 0; k < bv.length(); ++ k) {
        bool b = false;

        int n = l - id.exponent();
        if ((n += 20) >= 32)
            b = ((m0 & 1U << 31) != 0);
        else if (n >= 0)
            b = ((m0 & 1U << n) != 0);
        else if ((n += 32) >= 0)
            b = ((m1 & 1U << n) != 0);

        bv[k] = b;

        if (i >= j)
            ++l;
        else
            --l;
    }

    return true;
}

bool
sc_fxnum_fast::set_slice(int i, int j, const sc_bv_base &bv)
{
    scfx_ieee_double id(m_val);
    if (id.is_nan() || id.is_inf())
        return false;

    // set the bits
    int l = j;
    for (int k = 0; k < bv.length(); ++k) {
        if (bv[k].to_bool()) {
            if (!get_bit(l)) {
                if (m_params.enc() == SC_TC_ && l == m_params.iwl() - 1)
                    m_val -= scfx_pow2(l);
                else
                    m_val += scfx_pow2(l);
            }
        } else {
            if (get_bit(l)) {
                if (m_params.enc() == SC_TC_ && l == m_params.iwl() - 1)
                    m_val += scfx_pow2(l);
                else
                    m_val -= scfx_pow2(l);
            }
        }

        if (i >= j)
            ++l;
        else
            --l;
    }

    return true;
}

sc_fxnum_fast_observer *
sc_fxnum_fast::lock_observer() const
{
    SC_ASSERT_(m_observer != 0, "lock observer failed");
    sc_fxnum_fast_observer *tmp = m_observer;
    m_observer = 0;
    return tmp;
}

void
sc_fxnum_fast::unlock_observer(sc_fxnum_fast_observer *observer_) const
{
    SC_ASSERT_(observer_ != 0, "unlock observer failed");
    m_observer = observer_;
}

} // namespace sc_dt
