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

  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/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_WRAP_SM not defined for unsigned numbers");

                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(), "invalid fixed-point 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
