112853Sgabeblack@google.com/*****************************************************************************
212853Sgabeblack@google.com
312853Sgabeblack@google.com  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
412853Sgabeblack@google.com  more contributor license agreements.  See the NOTICE file distributed
512853Sgabeblack@google.com  with this work for additional information regarding copyright ownership.
612853Sgabeblack@google.com  Accellera licenses this file to you under the Apache License, Version 2.0
712853Sgabeblack@google.com  (the "License"); you may not use this file except in compliance with the
812853Sgabeblack@google.com  License.  You may obtain a copy of the License at
912853Sgabeblack@google.com
1012853Sgabeblack@google.com    http://www.apache.org/licenses/LICENSE-2.0
1112853Sgabeblack@google.com
1212853Sgabeblack@google.com  Unless required by applicable law or agreed to in writing, software
1312853Sgabeblack@google.com  distributed under the License is distributed on an "AS IS" BASIS,
1412853Sgabeblack@google.com  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
1512853Sgabeblack@google.com  implied.  See the License for the specific language governing
1612853Sgabeblack@google.com  permissions and limitations under the License.
1712853Sgabeblack@google.com
1812853Sgabeblack@google.com *****************************************************************************/
1912853Sgabeblack@google.com
2012853Sgabeblack@google.com/*****************************************************************************
2112853Sgabeblack@google.com
2212853Sgabeblack@google.com  scfx_rep.h -
2312853Sgabeblack@google.com
2412853Sgabeblack@google.com  Original Author: Robert Graulich, Synopsys, Inc.
2512853Sgabeblack@google.com                   Martin Janssen,  Synopsys, Inc.
2612853Sgabeblack@google.com
2712853Sgabeblack@google.com *****************************************************************************/
2812853Sgabeblack@google.com
2912853Sgabeblack@google.com/*****************************************************************************
3012853Sgabeblack@google.com
3112853Sgabeblack@google.com  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
3212853Sgabeblack@google.com  changes you are making here.
3312853Sgabeblack@google.com
3412853Sgabeblack@google.com      Name, Affiliation, Date:
3512853Sgabeblack@google.com  Description of Modification:
3612853Sgabeblack@google.com
3712853Sgabeblack@google.com *****************************************************************************/
3812853Sgabeblack@google.com
3912853Sgabeblack@google.com// $Log: scfx_rep.h,v $
4012853Sgabeblack@google.com// Revision 1.6  2011/08/24 22:05:43  acg
4112853Sgabeblack@google.com//  Torsten Maehne: initialization changes to remove warnings.
4212853Sgabeblack@google.com//
4312853Sgabeblack@google.com// Revision 1.5  2011/07/25 10:20:29  acg
4412853Sgabeblack@google.com//  Andy Goodrich: check in aftermath of call to automake.
4512853Sgabeblack@google.com//
4612853Sgabeblack@google.com// Revision 1.4  2010/12/07 20:09:08  acg
4712853Sgabeblack@google.com// Andy Goodrich: Philipp Hartmann's constructor disambiguation fix
4812853Sgabeblack@google.com//
4912853Sgabeblack@google.com// Revision 1.3  2010/08/03 15:54:52  acg
5012853Sgabeblack@google.com//  Andy Goodrich: formatting.
5112853Sgabeblack@google.com//
5212853Sgabeblack@google.com// Revision 1.2  2010/03/15 18:29:01  acg
5312853Sgabeblack@google.com//  Andy Goodrich: Moved default argument specifications from friend
5412853Sgabeblack@google.com//  declarations to the actual function signatures.
5512853Sgabeblack@google.com//
5612853Sgabeblack@google.com// Revision 1.1.1.1  2006/12/15 20:20:04  acg
5712853Sgabeblack@google.com// SystemC 2.3
5812853Sgabeblack@google.com//
5912853Sgabeblack@google.com// Revision 1.4  2006/03/13 20:24:27  acg
6012853Sgabeblack@google.com//  Andy Goodrich: Addition of function declarations, e.g., neg_scfx_rep(),
6112853Sgabeblack@google.com//  to keep gcc 4.x happy.
6212853Sgabeblack@google.com//
6312853Sgabeblack@google.com// Revision 1.3  2006/01/13 18:53:58  acg
6412853Sgabeblack@google.com// Andy Goodrich: added $Log command so that CVS comments are reproduced in
6512853Sgabeblack@google.com// the source.
6612853Sgabeblack@google.com//
6712853Sgabeblack@google.com
6812853Sgabeblack@google.com#ifndef __SYSTEMC_EXT_DT_FX_SCFX_REP_HH__
6912853Sgabeblack@google.com#define __SYSTEMC_EXT_DT_FX_SCFX_REP_HH__
7012853Sgabeblack@google.com
7112853Sgabeblack@google.com#include <climits>
7212853Sgabeblack@google.com
7312853Sgabeblack@google.com#include "scfx_mant.hh"
7412853Sgabeblack@google.com#include "scfx_params.hh"
7512853Sgabeblack@google.com#include "scfx_string.hh"
7612853Sgabeblack@google.com
7712853Sgabeblack@google.comnamespace sc_dt
7812853Sgabeblack@google.com{
7912853Sgabeblack@google.com
8012853Sgabeblack@google.com// classes defined in this module
8112853Sgabeblack@google.comclass scfx_index;
8212853Sgabeblack@google.comclass scfx_rep;
8312853Sgabeblack@google.com
8412853Sgabeblack@google.com// forward class declarations
8512853Sgabeblack@google.comclass sc_bv_base;
8612853Sgabeblack@google.comclass sc_signed;
8712853Sgabeblack@google.comclass sc_unsigned;
8812853Sgabeblack@google.com
8912853Sgabeblack@google.com// function declarations
9012853Sgabeblack@google.comvoid multiply(scfx_rep &, const scfx_rep &, const scfx_rep &,
9112853Sgabeblack@google.com              int max_wl=SC_DEFAULT_MAX_WL_);
9212853Sgabeblack@google.comscfx_rep *neg_scfx_rep(const scfx_rep &);
9312853Sgabeblack@google.comscfx_rep *mult_scfx_rep(const scfx_rep &, const scfx_rep &,
9412853Sgabeblack@google.com                        int max_wl=SC_DEFAULT_MAX_WL_);
9512853Sgabeblack@google.comscfx_rep *div_scfx_rep(const scfx_rep &, const scfx_rep &,
9612853Sgabeblack@google.com                       int max_wl=SC_DEFAULT_DIV_WL_);
9712853Sgabeblack@google.comscfx_rep *add_scfx_rep(const scfx_rep &, const scfx_rep &,
9812853Sgabeblack@google.com                       int max_wl=SC_DEFAULT_MAX_WL_);
9912853Sgabeblack@google.comscfx_rep *sub_scfx_rep(const scfx_rep &, const scfx_rep &,
10012853Sgabeblack@google.com                       int max_wl=SC_DEFAULT_MAX_WL_);
10112853Sgabeblack@google.comscfx_rep *lsh_scfx_rep(const scfx_rep &, int);
10212853Sgabeblack@google.comscfx_rep *rsh_scfx_rep(const scfx_rep &, int);
10312853Sgabeblack@google.comint cmp_scfx_rep(const scfx_rep &, const scfx_rep &);
10412853Sgabeblack@google.com
10512853Sgabeblack@google.comconst int min_mant = 4;
10612853Sgabeblack@google.com
10712853Sgabeblack@google.comconst int bits_in_int = sizeof(int) * CHAR_BIT;
10812853Sgabeblack@google.comconst int bits_in_word = sizeof(word) * CHAR_BIT;
10912853Sgabeblack@google.com
11012853Sgabeblack@google.com
11112853Sgabeblack@google.com// ----------------------------------------------------------------------------
11212853Sgabeblack@google.com//  CLASS : scfx_index
11312853Sgabeblack@google.com// ----------------------------------------------------------------------------
11412853Sgabeblack@google.com
11512853Sgabeblack@google.comclass scfx_index
11612853Sgabeblack@google.com{
11712853Sgabeblack@google.com  public:
11812853Sgabeblack@google.com    scfx_index(int wi_, int bi_) : m_wi(wi_), m_bi(bi_) {}
11912853Sgabeblack@google.com
12012853Sgabeblack@google.com    int wi() const { return m_wi; }
12112853Sgabeblack@google.com    int bi() const { return m_bi; }
12212853Sgabeblack@google.com
12312853Sgabeblack@google.com    void wi(int wi_) { m_wi = wi_; }
12412853Sgabeblack@google.com
12512853Sgabeblack@google.com  private:
12612853Sgabeblack@google.com    int m_wi;
12712853Sgabeblack@google.com    int m_bi;
12812853Sgabeblack@google.com};
12912853Sgabeblack@google.com
13012853Sgabeblack@google.com
13112853Sgabeblack@google.com// ----------------------------------------------------------------------------
13212853Sgabeblack@google.com//  CLASS : scfx_rep
13312853Sgabeblack@google.com//
13412853Sgabeblack@google.com//  Arbitrary-precision fixed-point implementation class.
13512853Sgabeblack@google.com// ----------------------------------------------------------------------------
13612853Sgabeblack@google.com
13712853Sgabeblack@google.comclass scfx_rep
13812853Sgabeblack@google.com{
13912853Sgabeblack@google.com    enum state
14012853Sgabeblack@google.com    {
14112853Sgabeblack@google.com        normal,
14212853Sgabeblack@google.com        infinity,
14312853Sgabeblack@google.com        not_a_number
14412853Sgabeblack@google.com    };
14512853Sgabeblack@google.com
14612853Sgabeblack@google.com  public:
14712853Sgabeblack@google.com    // constructors
14812853Sgabeblack@google.com    scfx_rep();
14912853Sgabeblack@google.com    explicit scfx_rep(int);
15012853Sgabeblack@google.com    explicit scfx_rep(unsigned int);
15112853Sgabeblack@google.com    explicit scfx_rep(long);
15212853Sgabeblack@google.com    explicit scfx_rep(unsigned long);
15312853Sgabeblack@google.com    explicit scfx_rep(double);
15412853Sgabeblack@google.com    explicit scfx_rep(const char *);
15512853Sgabeblack@google.com    explicit scfx_rep(int64);
15612853Sgabeblack@google.com    explicit scfx_rep(uint64);
15712853Sgabeblack@google.com    explicit scfx_rep(const sc_signed &);
15812853Sgabeblack@google.com    explicit scfx_rep(const sc_unsigned &);
15912853Sgabeblack@google.com
16012853Sgabeblack@google.com    // copy constructor
16112853Sgabeblack@google.com    scfx_rep(const scfx_rep &);
16212853Sgabeblack@google.com
16312853Sgabeblack@google.com    // destructor
16412853Sgabeblack@google.com    ~scfx_rep();
16512853Sgabeblack@google.com
16612853Sgabeblack@google.com    void *operator new (std::size_t);
16712853Sgabeblack@google.com    void operator delete (void *, std::size_t);
16812853Sgabeblack@google.com
16912853Sgabeblack@google.com    void from_string(const char *, int);
17012853Sgabeblack@google.com
17112853Sgabeblack@google.com    double to_double() const;
17212853Sgabeblack@google.com    uint64 to_uint64() const;
17312853Sgabeblack@google.com
17412853Sgabeblack@google.com    const char *to_string(sc_numrep, int, sc_fmt,
17512853Sgabeblack@google.com                          const scfx_params * =0) const;
17612853Sgabeblack@google.com
17712853Sgabeblack@google.com    // assignment operator
17812853Sgabeblack@google.com    void operator = (const scfx_rep &);
17912853Sgabeblack@google.com
18012853Sgabeblack@google.com    friend void multiply( scfx_rep&, const scfx_rep&, const scfx_rep&, int );
18112853Sgabeblack@google.com
18212853Sgabeblack@google.com    friend scfx_rep *neg_scfx_rep(const scfx_rep &);
18312853Sgabeblack@google.com    friend scfx_rep *mult_scfx_rep(const scfx_rep &, const scfx_rep &, int);
18412853Sgabeblack@google.com    friend scfx_rep *div_scfx_rep(const scfx_rep &, const scfx_rep &, int);
18512853Sgabeblack@google.com    friend scfx_rep *add_scfx_rep(const scfx_rep &, const scfx_rep &, int);
18612853Sgabeblack@google.com    friend scfx_rep *sub_scfx_rep(const scfx_rep &, const scfx_rep &, int);
18712853Sgabeblack@google.com    friend scfx_rep *lsh_scfx_rep(const scfx_rep &, int);
18812853Sgabeblack@google.com    friend scfx_rep *rsh_scfx_rep(const scfx_rep &, int);
18912853Sgabeblack@google.com
19012853Sgabeblack@google.com    void lshift(int);
19112853Sgabeblack@google.com    void rshift(int);
19212853Sgabeblack@google.com
19312853Sgabeblack@google.com    friend int cmp_scfx_rep(const scfx_rep &, const scfx_rep &);
19412853Sgabeblack@google.com
19512853Sgabeblack@google.com    void cast(const scfx_params &, bool &, bool &);
19612853Sgabeblack@google.com
19712853Sgabeblack@google.com    bool is_neg() const;
19812853Sgabeblack@google.com    bool is_zero() const;
19912853Sgabeblack@google.com    bool is_nan() const;
20012853Sgabeblack@google.com    bool is_inf() const;
20112853Sgabeblack@google.com    bool is_normal() const;
20212853Sgabeblack@google.com
20312853Sgabeblack@google.com    void set_zero(int=1);
20412853Sgabeblack@google.com    void set_nan();
20512853Sgabeblack@google.com    void set_inf(int);
20612853Sgabeblack@google.com
20712853Sgabeblack@google.com    bool get_bit(int) const;
20812853Sgabeblack@google.com    bool set(int, const scfx_params &);
20912853Sgabeblack@google.com    bool clear(int, const scfx_params &);
21012853Sgabeblack@google.com
21112853Sgabeblack@google.com    bool get_slice(int, int, const scfx_params &, sc_bv_base &) const;
21212853Sgabeblack@google.com    bool set_slice(int, int, const scfx_params &, const sc_bv_base &);
21312853Sgabeblack@google.com
21412853Sgabeblack@google.com    void print(::std::ostream &) const;
21512853Sgabeblack@google.com    void dump(::std::ostream &) const;
21612853Sgabeblack@google.com
21712853Sgabeblack@google.com    void get_type(int &, int &, sc_enc &) const;
21812853Sgabeblack@google.com
21912853Sgabeblack@google.com    friend scfx_rep *quantization_scfx_rep(
22012853Sgabeblack@google.com            const scfx_rep &, const scfx_params &, bool &);
22112853Sgabeblack@google.com    friend scfx_rep *overflow_scfx_rep(
22212853Sgabeblack@google.com            const scfx_rep &, const scfx_params &, bool &);
22312853Sgabeblack@google.com
22412853Sgabeblack@google.com    bool rounding_flag() const;
22512853Sgabeblack@google.com
22612853Sgabeblack@google.com  private:
22712853Sgabeblack@google.com    friend void align(const scfx_rep &, const scfx_rep &, int &, int &,
22812853Sgabeblack@google.com                      scfx_mant_ref &, scfx_mant_ref &);
22912853Sgabeblack@google.com    friend int compare_msw(const scfx_rep &, const scfx_rep &);
23012853Sgabeblack@google.com    friend int compare_msw_ff(const scfx_rep &lhs, const scfx_rep &rhs);
23112853Sgabeblack@google.com    unsigned int divide_by_ten();
23212853Sgabeblack@google.com    int find_lsw() const;
23312853Sgabeblack@google.com    int find_msw() const;
23412853Sgabeblack@google.com    void find_sw();
23512853Sgabeblack@google.com    void multiply_by_ten();
23612853Sgabeblack@google.com    void normalize(int);
23712853Sgabeblack@google.com    scfx_mant *resize(int, int) const;
23812853Sgabeblack@google.com    void set_bin(int);
23912853Sgabeblack@google.com    void set_oct(int, int);
24012853Sgabeblack@google.com    void set_hex(int, int);
24112853Sgabeblack@google.com    void shift_left(int);
24212853Sgabeblack@google.com    void shift_right(int);
24312853Sgabeblack@google.com
24412853Sgabeblack@google.com    const scfx_index calc_indices(int) const;
24512853Sgabeblack@google.com
24612853Sgabeblack@google.com    void o_extend(const scfx_index &, sc_enc);
24712853Sgabeblack@google.com    bool o_bit_at(const scfx_index &) const;
24812853Sgabeblack@google.com    bool o_zero_left(const scfx_index &) const;
24912853Sgabeblack@google.com    bool o_zero_right(const scfx_index &) const;
25012853Sgabeblack@google.com    void o_set_low(const scfx_index &, sc_enc);
25112853Sgabeblack@google.com    void o_set_high(const scfx_index &, const scfx_index &, sc_enc, int=1);
25212853Sgabeblack@google.com    void o_set(const scfx_index &, const scfx_index &, sc_enc, bool);
25312853Sgabeblack@google.com    void o_invert(const scfx_index &);
25412853Sgabeblack@google.com    bool q_bit(const scfx_index &) const;
25512853Sgabeblack@google.com    void q_clear(const scfx_index &);
25612853Sgabeblack@google.com    void q_incr(const scfx_index &);
25712853Sgabeblack@google.com    bool q_odd(const scfx_index &) const;
25812853Sgabeblack@google.com    bool q_zero(const scfx_index &) const;
25912853Sgabeblack@google.com
26012853Sgabeblack@google.com    void resize_to(int, int=0);
26112853Sgabeblack@google.com    int  size() const;
26212853Sgabeblack@google.com    void toggle_tc();
26312853Sgabeblack@google.com
26412853Sgabeblack@google.com    friend void print_dec(scfx_string &, const scfx_rep &, int, sc_fmt);
26512853Sgabeblack@google.com    friend void print_other(scfx_string &, const scfx_rep &, sc_numrep, int,
26612853Sgabeblack@google.com                            sc_fmt, const scfx_params *);
26712853Sgabeblack@google.com
26812853Sgabeblack@google.com    void quantization(const scfx_params &, bool &);
26912853Sgabeblack@google.com    void overflow(const scfx_params &, bool &);
27012853Sgabeblack@google.com
27112853Sgabeblack@google.com    friend int compare_abs(const scfx_rep &, const scfx_rep &);
27212853Sgabeblack@google.com
27312853Sgabeblack@google.com    void round(int);
27412853Sgabeblack@google.com
27512853Sgabeblack@google.com  private:
27612853Sgabeblack@google.com    scfx_mant m_mant; // mantissa (bits of the value).
27712853Sgabeblack@google.com    int m_wp; // index of highest order word in value.
27812853Sgabeblack@google.com    int m_sign; // sign of value.
27912853Sgabeblack@google.com    state m_state; // value state, e.g., normal, inf, etc.
28012853Sgabeblack@google.com    int m_msw; // index of most significant non-zero word.
28112853Sgabeblack@google.com    int m_lsw; // index of least significant non-zero word.
28212853Sgabeblack@google.com    bool m_r_flag; // true if rounding occurred.
28312853Sgabeblack@google.com};
28412853Sgabeblack@google.com
28512853Sgabeblack@google.com
28612853Sgabeblack@google.com// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
28712853Sgabeblack@google.com
28812853Sgabeblack@google.cominline void
28912853Sgabeblack@google.comscfx_rep::set_zero(int sign)
29012853Sgabeblack@google.com{
29112853Sgabeblack@google.com    m_mant.clear();
29212853Sgabeblack@google.com    m_wp = m_msw = m_lsw = 0;
29312853Sgabeblack@google.com    m_sign = sign;
29412853Sgabeblack@google.com    m_state = normal;
29512853Sgabeblack@google.com}
29612853Sgabeblack@google.com
29712853Sgabeblack@google.cominline void
29812853Sgabeblack@google.comscfx_rep::set_nan()
29912853Sgabeblack@google.com{
30012853Sgabeblack@google.com    m_mant.resize_to(min_mant);
30112853Sgabeblack@google.com    m_state = not_a_number;
30212853Sgabeblack@google.com}
30312853Sgabeblack@google.com
30412853Sgabeblack@google.cominline void
30512853Sgabeblack@google.comscfx_rep::set_inf(int sign)
30612853Sgabeblack@google.com{
30712853Sgabeblack@google.com    m_mant.resize_to(min_mant);
30812853Sgabeblack@google.com    m_state = infinity;
30912853Sgabeblack@google.com    m_sign = sign;
31012853Sgabeblack@google.com}
31112853Sgabeblack@google.com
31212853Sgabeblack@google.com// constructors
31312853Sgabeblack@google.cominline scfx_rep::scfx_rep(const char *s) :
31412853Sgabeblack@google.com    m_mant(min_mant), m_wp(2), m_sign(1), m_state(normal),
31512853Sgabeblack@google.com    m_msw(0), m_lsw(0), m_r_flag(false)
31612853Sgabeblack@google.com{
31712853Sgabeblack@google.com    from_string(s, SC_DEFAULT_CTE_WL_);
31812853Sgabeblack@google.com}
31912853Sgabeblack@google.com
32012853Sgabeblack@google.com// destructor
32112853Sgabeblack@google.cominline scfx_rep::~scfx_rep() {}
32212853Sgabeblack@google.com
32312853Sgabeblack@google.com// assignment operator
32412853Sgabeblack@google.cominline void
32512853Sgabeblack@google.comscfx_rep::operator = (const scfx_rep &f)
32612853Sgabeblack@google.com{
32712853Sgabeblack@google.com    if (&f != this) {
32812853Sgabeblack@google.com        m_mant = f.m_mant;
32912853Sgabeblack@google.com        m_wp = f.m_wp;
33012853Sgabeblack@google.com        m_sign = f.m_sign;
33112853Sgabeblack@google.com        m_state = f.m_state;
33212853Sgabeblack@google.com        m_msw = f.m_msw;
33312853Sgabeblack@google.com        m_lsw = f.m_lsw;
33412853Sgabeblack@google.com        round(SC_DEFAULT_MAX_WL_);
33512853Sgabeblack@google.com    }
33612853Sgabeblack@google.com}
33712853Sgabeblack@google.com
33812853Sgabeblack@google.cominline scfx_rep *
33912853Sgabeblack@google.comneg_scfx_rep(const scfx_rep &a)
34012853Sgabeblack@google.com{
34112853Sgabeblack@google.com    scfx_rep &c = *new scfx_rep(a);
34212853Sgabeblack@google.com    c.m_sign = - c.m_sign;
34312853Sgabeblack@google.com    return &c;
34412853Sgabeblack@google.com}
34512853Sgabeblack@google.com
34612853Sgabeblack@google.cominline scfx_rep *
34712853Sgabeblack@google.commult_scfx_rep(const scfx_rep &a, const scfx_rep &b, int max_wl)
34812853Sgabeblack@google.com{
34912853Sgabeblack@google.com    scfx_rep &c = *new scfx_rep;
35012853Sgabeblack@google.com    sc_dt::multiply(c, a, b, max_wl);
35112853Sgabeblack@google.com    return &c;
35212853Sgabeblack@google.com}
35312853Sgabeblack@google.com
35412853Sgabeblack@google.cominline scfx_rep *
35512853Sgabeblack@google.comlsh_scfx_rep(const scfx_rep &a, int b)
35612853Sgabeblack@google.com{
35712853Sgabeblack@google.com    scfx_rep &c = *new scfx_rep(a);
35812853Sgabeblack@google.com    c.lshift(b);
35912853Sgabeblack@google.com    return &c;
36012853Sgabeblack@google.com}
36112853Sgabeblack@google.com
36212853Sgabeblack@google.cominline scfx_rep *
36312853Sgabeblack@google.comrsh_scfx_rep(const scfx_rep &a, int b)
36412853Sgabeblack@google.com{
36512853Sgabeblack@google.com    scfx_rep &c = *new scfx_rep(a);
36612853Sgabeblack@google.com    c.rshift(b);
36712853Sgabeblack@google.com    return &c;
36812853Sgabeblack@google.com}
36912853Sgabeblack@google.com
37012853Sgabeblack@google.cominline int scfx_rep::size() const { return m_mant.size(); }
37112853Sgabeblack@google.com
37212853Sgabeblack@google.cominline bool scfx_rep::is_neg() const { return (m_sign == -1); }
37312853Sgabeblack@google.com
37412853Sgabeblack@google.cominline bool
37512853Sgabeblack@google.comscfx_rep::is_zero() const
37612853Sgabeblack@google.com{
37712853Sgabeblack@google.com    if (m_state != normal)
37812853Sgabeblack@google.com        return false;
37912853Sgabeblack@google.com
38012853Sgabeblack@google.com    for (int i = 0; i < size(); i++) {
38112853Sgabeblack@google.com        if (m_mant[i])
38212853Sgabeblack@google.com            return false;
38312853Sgabeblack@google.com    }
38412853Sgabeblack@google.com
38512853Sgabeblack@google.com    return true;
38612853Sgabeblack@google.com}
38712853Sgabeblack@google.com
38812853Sgabeblack@google.cominline bool scfx_rep::is_nan() const { return (m_state == not_a_number); }
38912853Sgabeblack@google.com
39012853Sgabeblack@google.cominline bool scfx_rep::is_inf() const { return (m_state == infinity); }
39112853Sgabeblack@google.com
39212853Sgabeblack@google.cominline bool scfx_rep::is_normal() const { return (m_state == normal); }
39312853Sgabeblack@google.com
39412853Sgabeblack@google.cominline scfx_rep *
39512853Sgabeblack@google.comquantization_scfx_rep(const scfx_rep &a, const scfx_params &params,
39612853Sgabeblack@google.com                      bool &q_flag)
39712853Sgabeblack@google.com{
39812853Sgabeblack@google.com    scfx_rep &c = *new scfx_rep(a);
39912853Sgabeblack@google.com    c.quantization(params, q_flag);
40012853Sgabeblack@google.com    return &c;
40112853Sgabeblack@google.com}
40212853Sgabeblack@google.com
40312853Sgabeblack@google.cominline scfx_rep *
40412853Sgabeblack@google.comoverflow_scfx_rep(const scfx_rep &a, const scfx_params &params, bool &o_flag)
40512853Sgabeblack@google.com{
40612853Sgabeblack@google.com    scfx_rep& c = *new scfx_rep(a);
40712853Sgabeblack@google.com    c.overflow(params, o_flag);
40812853Sgabeblack@google.com    return &c;
40912853Sgabeblack@google.com}
41012853Sgabeblack@google.com
41112853Sgabeblack@google.cominline bool scfx_rep::rounding_flag() const { return m_r_flag; }
41212853Sgabeblack@google.com
41312853Sgabeblack@google.cominline void
41412853Sgabeblack@google.comscfx_rep::resize_to(int new_size, int restore)
41512853Sgabeblack@google.com{
41612853Sgabeblack@google.com    if (restore == -1) {
41712853Sgabeblack@google.com        int size_incr = new_size - size();
41812853Sgabeblack@google.com        m_wp += size_incr;
41912853Sgabeblack@google.com        m_msw += size_incr;
42012853Sgabeblack@google.com        m_lsw += size_incr;
42112853Sgabeblack@google.com    }
42212853Sgabeblack@google.com    m_mant.resize_to(new_size, restore);
42312853Sgabeblack@google.com}
42412853Sgabeblack@google.com
42512853Sgabeblack@google.cominline const scfx_index
42612853Sgabeblack@google.comscfx_rep::calc_indices(int n) const
42712853Sgabeblack@google.com{
42812853Sgabeblack@google.com    int wi = n / bits_in_word + m_wp;
42912853Sgabeblack@google.com    int bi = n % bits_in_word;
43012853Sgabeblack@google.com
43112853Sgabeblack@google.com    if (bi < 0) {
43212853Sgabeblack@google.com        bi += bits_in_word;
43312853Sgabeblack@google.com        -- wi;
43412853Sgabeblack@google.com    }
43512853Sgabeblack@google.com
43612853Sgabeblack@google.com    return scfx_index(wi, bi);
43712853Sgabeblack@google.com}
43812853Sgabeblack@google.com
43912853Sgabeblack@google.cominline void
44012853Sgabeblack@google.comscfx_rep::o_extend(const scfx_index &x, sc_enc enc)
44112853Sgabeblack@google.com{
44212853Sgabeblack@google.com    int wi = x.wi();
44312853Sgabeblack@google.com    int bi = x.bi();
44412853Sgabeblack@google.com
44512853Sgabeblack@google.com    SC_ASSERT_(wi >= 0 && wi < size(), "word index out of range");
44612853Sgabeblack@google.com
44712853Sgabeblack@google.com    if (enc == SC_US_ || (m_mant[wi] & (((word)1) << bi)) == 0) {
44812853Sgabeblack@google.com        if (bi != bits_in_word - 1)
44912853Sgabeblack@google.com            m_mant[wi] &= ~(((word)-1) << (bi + 1));
45012853Sgabeblack@google.com        for (int i = wi + 1; i < size(); ++i)
45112853Sgabeblack@google.com            m_mant[i] = 0;
45212853Sgabeblack@google.com        m_sign = 1;
45312853Sgabeblack@google.com    } else {
45412853Sgabeblack@google.com        if (bi != bits_in_word - 1)
45512853Sgabeblack@google.com            m_mant[wi] |= (((word)-1) << (bi + 1));
45612853Sgabeblack@google.com        for (int i = wi + 1; i < size(); ++i)
45712853Sgabeblack@google.com            m_mant[i] = static_cast<word>(-1);
45812853Sgabeblack@google.com        m_sign = -1;
45912853Sgabeblack@google.com    }
46012853Sgabeblack@google.com}
46112853Sgabeblack@google.com
46212853Sgabeblack@google.cominline bool
46312853Sgabeblack@google.comscfx_rep::o_bit_at(const scfx_index &x) const
46412853Sgabeblack@google.com{
46512853Sgabeblack@google.com    int wi = x.wi();
46612853Sgabeblack@google.com    int bi = x.bi();
46712853Sgabeblack@google.com
46812853Sgabeblack@google.com    SC_ASSERT_(wi >= 0 && wi < size(), "word index out of range");
46912853Sgabeblack@google.com
47012853Sgabeblack@google.com    return (m_mant[wi] & (((word)1) << bi)) != 0;
47112853Sgabeblack@google.com}
47212853Sgabeblack@google.com
47312853Sgabeblack@google.cominline bool
47412853Sgabeblack@google.comscfx_rep::o_zero_left(const scfx_index &x) const
47512853Sgabeblack@google.com{
47612853Sgabeblack@google.com    int wi = x.wi();
47712853Sgabeblack@google.com    int bi = x.bi();
47812853Sgabeblack@google.com
47912853Sgabeblack@google.com    SC_ASSERT_(wi >= 0 && wi < size(), "word index out of range");
48012853Sgabeblack@google.com
48112853Sgabeblack@google.com    bool zero = true;
48212853Sgabeblack@google.com    if (bi != bits_in_word - 1)
48312853Sgabeblack@google.com        zero = (m_mant[wi] & (((word)-1) << (bi + 1))) == 0;
48412853Sgabeblack@google.com    for (int i = wi + 1; i < size(); ++i)
48512853Sgabeblack@google.com        zero = zero && m_mant[i] == 0;
48612853Sgabeblack@google.com
48712853Sgabeblack@google.com    return zero;
48812853Sgabeblack@google.com}
48912853Sgabeblack@google.com
49012853Sgabeblack@google.cominline bool
49112853Sgabeblack@google.comscfx_rep::o_zero_right(const scfx_index &x) const
49212853Sgabeblack@google.com{
49312853Sgabeblack@google.com    int wi = x.wi();
49412853Sgabeblack@google.com    int bi = x.bi();
49512853Sgabeblack@google.com
49612853Sgabeblack@google.com    SC_ASSERT_(wi >= 0 && wi < size(), "word index out of range");
49712853Sgabeblack@google.com
49812853Sgabeblack@google.com    bool zero = (m_mant[wi] & ~(((word)-1) << bi)) == 0;
49912853Sgabeblack@google.com    for (int i = wi - 1; i >= 0; --i)
50012853Sgabeblack@google.com        zero = zero && m_mant[i] == 0;
50112853Sgabeblack@google.com
50212853Sgabeblack@google.com    return zero;
50312853Sgabeblack@google.com}
50412853Sgabeblack@google.com
50512853Sgabeblack@google.cominline void
50612853Sgabeblack@google.comscfx_rep::o_set_low(const scfx_index &x, sc_enc enc)
50712853Sgabeblack@google.com{
50812853Sgabeblack@google.com    int wi = x.wi();
50912853Sgabeblack@google.com    int bi = x.bi();
51012853Sgabeblack@google.com
51112853Sgabeblack@google.com    SC_ASSERT_(wi >= 0 && wi < size(), "word index out of range");
51212853Sgabeblack@google.com
51312853Sgabeblack@google.com    m_mant.clear();
51412853Sgabeblack@google.com
51512853Sgabeblack@google.com    if (enc == SC_TC_) {
51612853Sgabeblack@google.com        m_mant[wi] |= (((word)1) << bi);
51712853Sgabeblack@google.com        m_sign = -1;
51812853Sgabeblack@google.com    } else {
51912853Sgabeblack@google.com        m_sign = 1;
52012853Sgabeblack@google.com    }
52112853Sgabeblack@google.com}
52212853Sgabeblack@google.com
52312853Sgabeblack@google.cominline void
52412853Sgabeblack@google.comscfx_rep::o_set_high(const scfx_index &x, const scfx_index &x2,
52512853Sgabeblack@google.com                     sc_enc enc, int sign)
52612853Sgabeblack@google.com{
52712853Sgabeblack@google.com    int wi = x.wi();
52812853Sgabeblack@google.com    int bi = x.bi();
52912853Sgabeblack@google.com    int wi2 = x2.wi();
53012853Sgabeblack@google.com    int bi2 = x2.bi();
53112853Sgabeblack@google.com
53212853Sgabeblack@google.com    SC_ASSERT_(wi >= 0 && wi < size(), "word index out of range");
53312853Sgabeblack@google.com    SC_ASSERT_(wi2 >= 0 && wi2 < size(), "word index out of range");
53412853Sgabeblack@google.com
53512853Sgabeblack@google.com    int i;
53612853Sgabeblack@google.com
53712853Sgabeblack@google.com    for (i = 0; i < size(); ++i)
53812853Sgabeblack@google.com        m_mant[i] = static_cast<word>(-1);
53912853Sgabeblack@google.com
54012853Sgabeblack@google.com    m_mant[wi] &= ~(((word)-1) << bi);
54112853Sgabeblack@google.com    for (i = wi + 1; i < size(); ++i)
54212853Sgabeblack@google.com        m_mant[i] = 0;
54312853Sgabeblack@google.com
54412853Sgabeblack@google.com    m_mant[wi2] &= (((word)-1) << bi2);
54512853Sgabeblack@google.com    for (i = wi2 - 1; i >= 0; --i)
54612853Sgabeblack@google.com        m_mant[i] = 0;
54712853Sgabeblack@google.com
54812853Sgabeblack@google.com    if (enc == SC_TC_) {
54912853Sgabeblack@google.com        m_sign = sign;
55012853Sgabeblack@google.com    } else {
55112853Sgabeblack@google.com        m_mant[wi] |= (((word)1) << bi);
55212853Sgabeblack@google.com        m_sign = 1;
55312853Sgabeblack@google.com    }
55412853Sgabeblack@google.com}
55512853Sgabeblack@google.com
55612853Sgabeblack@google.cominline void
55712853Sgabeblack@google.comscfx_rep::o_set(const scfx_index &x, const scfx_index &x3, sc_enc enc,
55812853Sgabeblack@google.com                bool under)
55912853Sgabeblack@google.com{
56012853Sgabeblack@google.com    int wi = x.wi();
56112853Sgabeblack@google.com    int bi = x.bi();
56212853Sgabeblack@google.com    int wi3 = x3.wi();
56312853Sgabeblack@google.com    int bi3 = x3.bi();
56412853Sgabeblack@google.com
56512853Sgabeblack@google.com    SC_ASSERT_(wi >= 0 && wi < size(), "word index out of range");
56612853Sgabeblack@google.com    SC_ASSERT_(wi3 >= 0 && wi3 < size(), "word index out of range");
56712853Sgabeblack@google.com
56812853Sgabeblack@google.com    if (bi3 != bits_in_word - 1) {
56912853Sgabeblack@google.com        if (under)
57012853Sgabeblack@google.com            m_mant[wi3] &= ~(((word)-1) << (bi3 + 1));
57112853Sgabeblack@google.com        else
57212853Sgabeblack@google.com            m_mant[wi3] |= (((word)-1) << (bi3 + 1));
57312853Sgabeblack@google.com    }
57412853Sgabeblack@google.com    for (int i = wi3 + 1; i < size(); ++i) {
57512853Sgabeblack@google.com        if (under)
57612853Sgabeblack@google.com            m_mant[i] = 0;
57712853Sgabeblack@google.com        else
57812853Sgabeblack@google.com            m_mant[i] = static_cast<word>(-1);
57912853Sgabeblack@google.com    }
58012853Sgabeblack@google.com
58112853Sgabeblack@google.com    if (enc == SC_TC_) {
58212853Sgabeblack@google.com        if (under)
58312853Sgabeblack@google.com            m_mant[wi] |= (((word)1) << bi);
58412853Sgabeblack@google.com        else
58512853Sgabeblack@google.com            m_mant[wi] &= ~(((word)1) << bi);
58612853Sgabeblack@google.com    }
58712853Sgabeblack@google.com}
58812853Sgabeblack@google.com
58912853Sgabeblack@google.cominline void
59012853Sgabeblack@google.comscfx_rep::o_invert(const scfx_index &x2)
59112853Sgabeblack@google.com{
59212853Sgabeblack@google.com    int wi2 = x2.wi();
59312853Sgabeblack@google.com    int bi2 = x2.bi();
59412853Sgabeblack@google.com
59512853Sgabeblack@google.com    m_mant[wi2] ^= (((word)-1) << bi2);
59612853Sgabeblack@google.com    for (int i = wi2 + 1; i < size(); ++i)
59712853Sgabeblack@google.com        m_mant[i] = ~ m_mant[i];
59812853Sgabeblack@google.com}
59912853Sgabeblack@google.com
60012853Sgabeblack@google.cominline bool
60112853Sgabeblack@google.comscfx_rep::q_bit(const scfx_index &x) const
60212853Sgabeblack@google.com{
60312853Sgabeblack@google.com    int wi = x.wi();
60412853Sgabeblack@google.com    int bi = x.bi();
60512853Sgabeblack@google.com
60612853Sgabeblack@google.com    SC_ASSERT_(wi >= 0 && wi < size(), "word index out of range");
60712853Sgabeblack@google.com
60812853Sgabeblack@google.com    if (bi != 0)
60912853Sgabeblack@google.com        return (m_mant[wi] & (((word)1) << (bi - 1))) != 0;
61012853Sgabeblack@google.com    else if (wi != 0)
61112853Sgabeblack@google.com        return (m_mant[wi - 1] & (((word)1) << (bits_in_word - 1))) != 0;
61212853Sgabeblack@google.com    else
61312853Sgabeblack@google.com        return false;
61412853Sgabeblack@google.com}
61512853Sgabeblack@google.com
61612853Sgabeblack@google.cominline void
61712853Sgabeblack@google.comscfx_rep::q_clear(const scfx_index &x)
61812853Sgabeblack@google.com{
61912853Sgabeblack@google.com    int wi = x.wi();
62012853Sgabeblack@google.com    int bi = x.bi();
62112853Sgabeblack@google.com
62212853Sgabeblack@google.com    SC_ASSERT_(wi >= 0 && wi < size(), "word index out of range");
62312853Sgabeblack@google.com
62412853Sgabeblack@google.com    m_mant[wi] &= (((word)-1) << bi);
62512853Sgabeblack@google.com    for (int i = wi - 1; i >= 0; --i)
62612853Sgabeblack@google.com        m_mant[i] = 0;
62712853Sgabeblack@google.com}
62812853Sgabeblack@google.com
62912853Sgabeblack@google.cominline void
63012853Sgabeblack@google.comscfx_rep::q_incr(const scfx_index &x)
63112853Sgabeblack@google.com{
63212853Sgabeblack@google.com    int wi = x.wi();
63312853Sgabeblack@google.com    int bi = x.bi();
63412853Sgabeblack@google.com
63512853Sgabeblack@google.com    SC_ASSERT_(wi >= 0 && wi < size(), "word index out of range");
63612853Sgabeblack@google.com
63712853Sgabeblack@google.com    word old_val = m_mant[wi];
63812853Sgabeblack@google.com    m_mant[wi] += (((word)1) << bi);
63912853Sgabeblack@google.com    if (m_mant[wi] <= old_val) {
64012853Sgabeblack@google.com        if (wi + 1 == size())
64112853Sgabeblack@google.com            resize_to(size() + 1, 1);
64212853Sgabeblack@google.com
64312853Sgabeblack@google.com        for (int i = wi + 1; i < size(); ++i) {
64412853Sgabeblack@google.com            if (++m_mant[i] != 0)
64512853Sgabeblack@google.com                break;
64612853Sgabeblack@google.com        }
64712853Sgabeblack@google.com    }
64812853Sgabeblack@google.com}
64912853Sgabeblack@google.com
65012853Sgabeblack@google.cominline bool
65112853Sgabeblack@google.comscfx_rep::q_odd(const scfx_index &x) const
65212853Sgabeblack@google.com{
65312853Sgabeblack@google.com    int wi = x.wi();
65412853Sgabeblack@google.com    int bi = x.bi();
65512853Sgabeblack@google.com
65612853Sgabeblack@google.com    SC_ASSERT_(wi >= 0 && wi < size(), "word index out of range");
65712853Sgabeblack@google.com
65812853Sgabeblack@google.com    return (m_mant[wi] & (((word)1) << bi)) != 0;
65912853Sgabeblack@google.com}
66012853Sgabeblack@google.com
66112853Sgabeblack@google.cominline bool
66212853Sgabeblack@google.comscfx_rep::q_zero(const scfx_index &x) const
66312853Sgabeblack@google.com{
66412853Sgabeblack@google.com    int wi = x.wi();
66512853Sgabeblack@google.com    int bi = x.bi();
66612853Sgabeblack@google.com
66712853Sgabeblack@google.com    SC_ASSERT_(wi >= 0 && wi < size(), "word index out of range");
66812853Sgabeblack@google.com
66912853Sgabeblack@google.com    bool zero;
67012853Sgabeblack@google.com
67112853Sgabeblack@google.com    if (bi != 0) {
67212853Sgabeblack@google.com        zero = (m_mant[wi] & ~(((word)-1) << (bi - 1))) == 0;
67312853Sgabeblack@google.com        for (int i = wi - 1; i >= 0; --i)
67412853Sgabeblack@google.com            zero = zero && m_mant[i] == 0;
67512853Sgabeblack@google.com    } else if (wi != 0) {
67612853Sgabeblack@google.com        zero = (m_mant[wi - 1] & ~( ((word)-1) << (bits_in_word - 1))) == 0;
67712853Sgabeblack@google.com        for (int i = wi - 2; i >= 0; --i)
67812853Sgabeblack@google.com            zero = zero && m_mant[i] == 0;
67912853Sgabeblack@google.com    } else {
68012853Sgabeblack@google.com        zero = true;
68112853Sgabeblack@google.com    }
68212853Sgabeblack@google.com
68312853Sgabeblack@google.com    return zero;
68412853Sgabeblack@google.com}
68512853Sgabeblack@google.com
68612853Sgabeblack@google.cominline int
68712853Sgabeblack@google.comscfx_rep::find_lsw() const
68812853Sgabeblack@google.com{
68912853Sgabeblack@google.com    for (int i = 0; i < size(); i++) {
69012853Sgabeblack@google.com        if (m_mant[i])
69112853Sgabeblack@google.com            return i;
69212853Sgabeblack@google.com    }
69312853Sgabeblack@google.com    return 0;
69412853Sgabeblack@google.com}
69512853Sgabeblack@google.com
69612853Sgabeblack@google.cominline int
69712853Sgabeblack@google.comscfx_rep::find_msw() const
69812853Sgabeblack@google.com{
69912853Sgabeblack@google.com    for (int i = size() - 1; i >= 0; i--) {
70012853Sgabeblack@google.com        if (m_mant[i])
70112853Sgabeblack@google.com            return i;
70212853Sgabeblack@google.com    }
70312853Sgabeblack@google.com    return 0;
70412853Sgabeblack@google.com}
70512853Sgabeblack@google.com
70612853Sgabeblack@google.cominline void
70712853Sgabeblack@google.comscfx_rep::find_sw()
70812853Sgabeblack@google.com{
70912853Sgabeblack@google.com    m_lsw = find_lsw();
71012853Sgabeblack@google.com    m_msw = find_msw();
71112853Sgabeblack@google.com}
71212853Sgabeblack@google.com
71312853Sgabeblack@google.cominline void
71412853Sgabeblack@google.comscfx_rep::toggle_tc()
71512853Sgabeblack@google.com{
71612853Sgabeblack@google.com    if (is_neg()) {
71712853Sgabeblack@google.com        complement(m_mant, m_mant, m_mant.size());
71812853Sgabeblack@google.com        inc(m_mant);
71912853Sgabeblack@google.com    }
72012853Sgabeblack@google.com}
72112853Sgabeblack@google.com
72212853Sgabeblack@google.com} // namespace sc_dt
72312853Sgabeblack@google.com
72412853Sgabeblack@google.com#endif // __SYSTEMC_EXT_DT_FX_SCFX_REP_HH__
725