sc_fxnum.hh revision 12853
18840Sandreas.hansson@arm.com/*****************************************************************************
28840Sandreas.hansson@arm.com
38840Sandreas.hansson@arm.com  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
48840Sandreas.hansson@arm.com  more contributor license agreements.  See the NOTICE file distributed
58840Sandreas.hansson@arm.com  with this work for additional information regarding copyright ownership.
68840Sandreas.hansson@arm.com  Accellera licenses this file to you under the Apache License, Version 2.0
78840Sandreas.hansson@arm.com  (the "License"); you may not use this file except in compliance with the
88840Sandreas.hansson@arm.com  License.  You may obtain a copy of the License at
98840Sandreas.hansson@arm.com
108840Sandreas.hansson@arm.com    http://www.apache.org/licenses/LICENSE-2.0
118840Sandreas.hansson@arm.com
128840Sandreas.hansson@arm.com  Unless required by applicable law or agreed to in writing, software
132740SN/A  distributed under the License is distributed on an "AS IS" BASIS,
149983Sstever@gmail.com  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
159983Sstever@gmail.com  implied.  See the License for the specific language governing
161046SN/A  permissions and limitations under the License.
171046SN/A
181046SN/A *****************************************************************************/
191046SN/A
201046SN/A/*****************************************************************************
211046SN/A
221046SN/A  sc_fxnum.h -
231046SN/A
241046SN/A  Original Author: Martin Janssen, Synopsys, Inc.
251046SN/A
261046SN/A *****************************************************************************/
271046SN/A
281046SN/A/*****************************************************************************
291046SN/A
301046SN/A  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
311046SN/A  changes you are making here.
321046SN/A
331046SN/A      Name, Affiliation, Date:
341046SN/A  Description of Modification:
351046SN/A
361046SN/A *****************************************************************************/
371046SN/A
381046SN/A// $Log: sc_fxnum.h,v $
391046SN/A// Revision 1.5  2011/08/29 18:04:32  acg
402665SN/A//  Philipp A. Hartmann: miscellaneous clean ups.
412665SN/A//
422665SN/A// Revision 1.4  2011/08/24 22:05:43  acg
438840Sandreas.hansson@arm.com//  Torsten Maehne: initialization changes to remove warnings.
441046SN/A//
455766Snate@binkert.org// Revision 1.3  2011/01/19 18:57:40  acg
468331Ssteve.reinhardt@amd.com//  Andy Goodrich: changes for IEEE_1666_2011.
471438SN/A//
484762Snate@binkert.org// Revision 1.2  2009/03/09 17:26:46  acg
496654Snate@binkert.org//  Andy Goodrich: removed ; from namespace { }
503102Sstever@eecs.umich.edu//
513102Sstever@eecs.umich.edu// Revision 1.1.1.1  2006/12/15 20:20:04  acg
523102Sstever@eecs.umich.edu// SystemC 2.3
533102Sstever@eecs.umich.edu//
546654Snate@binkert.org// Revision 1.3  2006/01/13 18:53:58  acg
553102Sstever@eecs.umich.edu// Andy Goodrich: added $Log command so that CVS comments are reproduced in
563102Sstever@eecs.umich.edu// the source.
577528Ssteve.reinhardt@amd.com//
588839Sandreas.hansson@arm.com
593102Sstever@eecs.umich.edu#ifndef __SYSTEMC_EXT_DT_FX_SC_FXNUM_HH__
606654Snate@binkert.org#define __SYSTEMC_EXT_DT_FX_SC_FXNUM_HH__
616654Snate@binkert.org
62679SN/A#include <iostream>
63679SN/A
64679SN/A#include "../bit/sc_lv_base.hh"
65679SN/A#include "sc_fxnum_observer.hh"
66679SN/A#include "sc_fxval.hh"
67679SN/A#include "scfx_params.hh"
681692SN/A
69679SN/Anamespace sc_core
70679SN/A{
71679SN/A
72679SN/Aclass vcd_sc_fxnum_trace;
73679SN/Aclass vcd_sc_fxnum_fast_trace;
74679SN/Aclass wif_sc_fxnum_trace;
75679SN/Aclass wif_sc_fxnum_fast_trace;
76679SN/A
77679SN/A} // namespace sc_core
78679SN/A
79679SN/A
80679SN/Anamespace sc_dt
81679SN/A{
82679SN/A
831692SN/A// classes defined in this module
84679SN/Aclass sc_fxnum_bitref;
85679SN/Aclass sc_fxnum_fast_bitref;
86679SN/Aclass sc_fxnum_subref;
87679SN/Aclass sc_fxnum_fast_subref;
88679SN/Aclass sc_fxnum;
89679SN/Aclass sc_fxnum_fast;
90679SN/A
91679SN/A
92679SN/A// ----------------------------------------------------------------------------
93679SN/A// CLASS : sc_fxnum_bitref
94679SN/A//
95679SN/A// Proxy class for bit-selection in class sc_fxnum, behaves like sc_bit.
96679SN/A// ----------------------------------------------------------------------------
97679SN/A
98679SN/Aclass sc_fxnum_bitref
992740SN/A{
100679SN/A    friend class sc_fxnum;
101679SN/A    friend class sc_fxnum_fast_bitref;
102679SN/A
1034762Snate@binkert.org    bool get() const;
1044762Snate@binkert.org    void set(bool);
1054762Snate@binkert.org
1062738SN/A    // constructor
1072738SN/A    sc_fxnum_bitref(sc_fxnum &, int);
1082738SN/A
1099338SAndreas.Sandberg@arm.com  public:
1109338SAndreas.Sandberg@arm.com    // copy constructor
1119338SAndreas.Sandberg@arm.com    sc_fxnum_bitref(const sc_fxnum_bitref &);
1127673Snate@binkert.org
1137673Snate@binkert.org    // assignment operators
1148331Ssteve.reinhardt@amd.com#define DECL_ASN_OP_T(op, tp) \
1158331Ssteve.reinhardt@amd.com    sc_fxnum_bitref &operator op (tp);
1167673Snate@binkert.org
11710458Sandreas.hansson@arm.com#define DECL_ASN_OP(op) \
11810458Sandreas.hansson@arm.com    DECL_ASN_OP_T(op, const sc_fxnum_bitref &) \
11910458Sandreas.hansson@arm.com    DECL_ASN_OP_T(op, const sc_fxnum_fast_bitref &) \
12010458Sandreas.hansson@arm.com    DECL_ASN_OP_T(op, const sc_bit &) \
12110458Sandreas.hansson@arm.com    DECL_ASN_OP_T(op, bool)
12210458Sandreas.hansson@arm.com
12310458Sandreas.hansson@arm.com    DECL_ASN_OP(=)
12410458Sandreas.hansson@arm.com
12510458Sandreas.hansson@arm.com    DECL_ASN_OP(&=)
12610458Sandreas.hansson@arm.com    DECL_ASN_OP(|=)
12710458Sandreas.hansson@arm.com    DECL_ASN_OP(^=)
12810458Sandreas.hansson@arm.com
12910458Sandreas.hansson@arm.com#undef DECL_ASN_OP_T
13010458Sandreas.hansson@arm.com#undef DECL_ASN_OP
13110458Sandreas.hansson@arm.com
13210458Sandreas.hansson@arm.com    // implicit conversion
13310458Sandreas.hansson@arm.com    operator bool() const;
13410458Sandreas.hansson@arm.com
13510458Sandreas.hansson@arm.com    // print or dump content
13610458Sandreas.hansson@arm.com    void print(::std::ostream & =::std::cout) const;
13710458Sandreas.hansson@arm.com    void scan(::std::istream & =::std::cin);
13810458Sandreas.hansson@arm.com    void dump(::std::ostream & =::std::cout) const;
13910458Sandreas.hansson@arm.com
14010458Sandreas.hansson@arm.com  private:
14110458Sandreas.hansson@arm.com    sc_fxnum &m_num;
14210458Sandreas.hansson@arm.com    int m_idx;
14310458Sandreas.hansson@arm.com
14410458Sandreas.hansson@arm.com  private:
14510458Sandreas.hansson@arm.com    // disabled
14610458Sandreas.hansson@arm.com    sc_fxnum_bitref();
14710458Sandreas.hansson@arm.com};
14810458Sandreas.hansson@arm.com
14910458Sandreas.hansson@arm.com
15010458Sandreas.hansson@arm.com// ----------------------------------------------------------------------------
15110458Sandreas.hansson@arm.com// CLASS : sc_fxnum_fast_bitref
15210458Sandreas.hansson@arm.com//
15310458Sandreas.hansson@arm.com// Proxy class for bit-selection in class sc_fxnum_fast, behaves like sc_bit.
15410458Sandreas.hansson@arm.com// ----------------------------------------------------------------------------
15510458Sandreas.hansson@arm.com
15610458Sandreas.hansson@arm.comclass sc_fxnum_fast_bitref
15710458Sandreas.hansson@arm.com{
15810458Sandreas.hansson@arm.com    friend class sc_fxnum_fast;
15910458Sandreas.hansson@arm.com    friend class sc_fxnum_bitref;
16010458Sandreas.hansson@arm.com
16110458Sandreas.hansson@arm.com    bool get() const;
16210458Sandreas.hansson@arm.com    void set(bool);
16310458Sandreas.hansson@arm.com
16410458Sandreas.hansson@arm.com    // constructor
16510458Sandreas.hansson@arm.com    sc_fxnum_fast_bitref(sc_fxnum_fast &, int);
16610458Sandreas.hansson@arm.com
16710458Sandreas.hansson@arm.com  public:
16810458Sandreas.hansson@arm.com    // copy constructor
16910458Sandreas.hansson@arm.com    sc_fxnum_fast_bitref(const sc_fxnum_fast_bitref &);
17010458Sandreas.hansson@arm.com
17110458Sandreas.hansson@arm.com    // assignment operators
17210458Sandreas.hansson@arm.com#define DECL_ASN_OP_T(op, tp) sc_fxnum_fast_bitref &operator op (tp);
17310458Sandreas.hansson@arm.com
17410458Sandreas.hansson@arm.com#define DECL_ASN_OP(op) \
17510458Sandreas.hansson@arm.com    DECL_ASN_OP_T(op, const sc_fxnum_bitref &) \
17610458Sandreas.hansson@arm.com    DECL_ASN_OP_T(op, const sc_fxnum_fast_bitref &) \
17710458Sandreas.hansson@arm.com    DECL_ASN_OP_T(op, const sc_bit &) \
17810458Sandreas.hansson@arm.com    DECL_ASN_OP_T(op, bool)
17910458Sandreas.hansson@arm.com
18010458Sandreas.hansson@arm.com    DECL_ASN_OP(=)
18110458Sandreas.hansson@arm.com
18210458Sandreas.hansson@arm.com    DECL_ASN_OP(&=)
18310458Sandreas.hansson@arm.com    DECL_ASN_OP(|=)
18410458Sandreas.hansson@arm.com    DECL_ASN_OP(^=)
18510458Sandreas.hansson@arm.com
18610458Sandreas.hansson@arm.com#undef DECL_ASN_OP_T
18710458Sandreas.hansson@arm.com#undef DECL_ASN_OP
18810458Sandreas.hansson@arm.com
18910458Sandreas.hansson@arm.com    // implicit conversion
19010458Sandreas.hansson@arm.com    operator bool() const;
19110458Sandreas.hansson@arm.com
19210458Sandreas.hansson@arm.com    // print or dump content
19310458Sandreas.hansson@arm.com    void print(::std::ostream & =::std::cout) const;
19410458Sandreas.hansson@arm.com    void scan(::std::istream & =::std::cin);
19510458Sandreas.hansson@arm.com    void dump(::std::ostream & =::std::cout) const;
19610458Sandreas.hansson@arm.com
19710458Sandreas.hansson@arm.com  private:
19810458Sandreas.hansson@arm.com    sc_fxnum_fast &m_num;
19910458Sandreas.hansson@arm.com    int m_idx;
20010458Sandreas.hansson@arm.com
20110458Sandreas.hansson@arm.com  private:
20210458Sandreas.hansson@arm.com    // Disabled
20310458Sandreas.hansson@arm.com    sc_fxnum_fast_bitref();
20410458Sandreas.hansson@arm.com};
20510458Sandreas.hansson@arm.com
20610458Sandreas.hansson@arm.com
20710458Sandreas.hansson@arm.com// ----------------------------------------------------------------------------
20810458Sandreas.hansson@arm.com// CLASS : sc_fxnum_subref
20910458Sandreas.hansson@arm.com//
21010458Sandreas.hansson@arm.com// Proxy class for part-selection in class sc_fxnum,
21110458Sandreas.hansson@arm.com// behaves like sc_bv_base.
21210458Sandreas.hansson@arm.com// ----------------------------------------------------------------------------
21310458Sandreas.hansson@arm.com
21410458Sandreas.hansson@arm.comclass sc_fxnum_subref
21510458Sandreas.hansson@arm.com{
21610458Sandreas.hansson@arm.com    friend class sc_fxnum;
21710458Sandreas.hansson@arm.com    friend class sc_fxnum_fast_subref;
21810458Sandreas.hansson@arm.com
21910458Sandreas.hansson@arm.com    bool get() const;
22010458Sandreas.hansson@arm.com    bool set();
22110458Sandreas.hansson@arm.com
22210458Sandreas.hansson@arm.com    // constructor
22310458Sandreas.hansson@arm.com    sc_fxnum_subref(sc_fxnum &, int, int);
22410458Sandreas.hansson@arm.com
22510458Sandreas.hansson@arm.com  public:
22610458Sandreas.hansson@arm.com    // copy constructor
22710458Sandreas.hansson@arm.com    sc_fxnum_subref(const sc_fxnum_subref &);
22810458Sandreas.hansson@arm.com
22910458Sandreas.hansson@arm.com    // destructor
23010458Sandreas.hansson@arm.com    ~sc_fxnum_subref();
23110458Sandreas.hansson@arm.com
23210458Sandreas.hansson@arm.com    // assignment operators
23310458Sandreas.hansson@arm.com#define DECL_ASN_OP_T(tp) \
23410458Sandreas.hansson@arm.com    sc_fxnum_subref &operator = (tp);
23510458Sandreas.hansson@arm.com
23610458Sandreas.hansson@arm.com    DECL_ASN_OP_T(const sc_fxnum_subref &)
23710458Sandreas.hansson@arm.com    DECL_ASN_OP_T(const sc_fxnum_fast_subref &)
23810458Sandreas.hansson@arm.com    DECL_ASN_OP_T(const sc_bv_base &)
23910458Sandreas.hansson@arm.com    DECL_ASN_OP_T(const sc_lv_base &)
24010458Sandreas.hansson@arm.com    DECL_ASN_OP_T(const char *)
24110458Sandreas.hansson@arm.com    DECL_ASN_OP_T(const bool *)
24210458Sandreas.hansson@arm.com    DECL_ASN_OP_T(const sc_signed &)
24310458Sandreas.hansson@arm.com    DECL_ASN_OP_T(const sc_unsigned &)
24410458Sandreas.hansson@arm.com    DECL_ASN_OP_T(const sc_int_base &)
24510458Sandreas.hansson@arm.com    DECL_ASN_OP_T(const sc_uint_base &)
24610458Sandreas.hansson@arm.com    DECL_ASN_OP_T(int64)
24710458Sandreas.hansson@arm.com    DECL_ASN_OP_T(uint64)
24810458Sandreas.hansson@arm.com    DECL_ASN_OP_T(int)
24910458Sandreas.hansson@arm.com    DECL_ASN_OP_T(unsigned int)
25010458Sandreas.hansson@arm.com    DECL_ASN_OP_T(long)
25110458Sandreas.hansson@arm.com    DECL_ASN_OP_T(unsigned long)
25210458Sandreas.hansson@arm.com    DECL_ASN_OP_T(char)
25310458Sandreas.hansson@arm.com
25410458Sandreas.hansson@arm.com#undef DECL_ASN_OP_T
25510458Sandreas.hansson@arm.com
25610458Sandreas.hansson@arm.com#define DECL_ASN_OP_T_A(op, tp) \
25710458Sandreas.hansson@arm.com    sc_fxnum_subref &operator op ## = (tp);
25810458Sandreas.hansson@arm.com
25910458Sandreas.hansson@arm.com#define DECL_ASN_OP_A(op) \
26010458Sandreas.hansson@arm.com    DECL_ASN_OP_T_A(op, const sc_fxnum_subref &) \
26110458Sandreas.hansson@arm.com    DECL_ASN_OP_T_A(op, const sc_fxnum_fast_subref &) \
26210458Sandreas.hansson@arm.com    DECL_ASN_OP_T_A(op, const sc_bv_base &) \
26310458Sandreas.hansson@arm.com    DECL_ASN_OP_T_A(op, const sc_lv_base &)
26410458Sandreas.hansson@arm.com
26510458Sandreas.hansson@arm.com    DECL_ASN_OP_A( &)
26610458Sandreas.hansson@arm.com    DECL_ASN_OP_A(|)
26710458Sandreas.hansson@arm.com    DECL_ASN_OP_A(^)
26810458Sandreas.hansson@arm.com
26910458Sandreas.hansson@arm.com#undef DECL_ASN_OP_T_A
27010458Sandreas.hansson@arm.com#undef DECL_ASN_OP_A
27110458Sandreas.hansson@arm.com
27210458Sandreas.hansson@arm.com    // relational operators
27310458Sandreas.hansson@arm.com#define DECL_REL_OP_T(op, tp) \
27410458Sandreas.hansson@arm.com    friend bool operator op (const sc_fxnum_subref &, tp); \
27510458Sandreas.hansson@arm.com    friend bool operator op (tp, const sc_fxnum_subref &);
27610458Sandreas.hansson@arm.com
27710458Sandreas.hansson@arm.com#define DECL_REL_OP(op) \
27810458Sandreas.hansson@arm.com    friend bool operator op (const sc_fxnum_subref &, \
27910458Sandreas.hansson@arm.com                             const sc_fxnum_subref &); \
28010458Sandreas.hansson@arm.com    friend bool operator op (const sc_fxnum_subref &, \
28110458Sandreas.hansson@arm.com                             const sc_fxnum_fast_subref &); \
28210458Sandreas.hansson@arm.com    DECL_REL_OP_T(op, const sc_bv_base &) \
28310458Sandreas.hansson@arm.com    DECL_REL_OP_T(op, const sc_lv_base &) \
28410458Sandreas.hansson@arm.com    DECL_REL_OP_T(op, const char *) \
28510458Sandreas.hansson@arm.com    DECL_REL_OP_T(op, const bool *) \
28610458Sandreas.hansson@arm.com    DECL_REL_OP_T(op, const sc_signed &) \
28710458Sandreas.hansson@arm.com    DECL_REL_OP_T(op, const sc_unsigned &) \
28810458Sandreas.hansson@arm.com    DECL_REL_OP_T(op, int) \
28910458Sandreas.hansson@arm.com    DECL_REL_OP_T(op, unsigned int) \
29010458Sandreas.hansson@arm.com    DECL_REL_OP_T(op, long) \
29110458Sandreas.hansson@arm.com    DECL_REL_OP_T(op, unsigned long)
29210458Sandreas.hansson@arm.com
29310458Sandreas.hansson@arm.com    DECL_REL_OP(==)
29410458Sandreas.hansson@arm.com    DECL_REL_OP(!=)
29510458Sandreas.hansson@arm.com
29610458Sandreas.hansson@arm.com#undef DECL_REL_OP_T
29710458Sandreas.hansson@arm.com#undef DECL_REL_OP
29810458Sandreas.hansson@arm.com
29910458Sandreas.hansson@arm.com    // reduce functions
30010458Sandreas.hansson@arm.com    bool and_reduce() const;
30110458Sandreas.hansson@arm.com    bool nand_reduce() const;
30210458Sandreas.hansson@arm.com    bool or_reduce() const;
30310458Sandreas.hansson@arm.com    bool nor_reduce() const;
30410458Sandreas.hansson@arm.com    bool xor_reduce() const;
30510458Sandreas.hansson@arm.com    bool xnor_reduce() const;
30610458Sandreas.hansson@arm.com
30710458Sandreas.hansson@arm.com    // query parameter
30810458Sandreas.hansson@arm.com    int length() const;
30910458Sandreas.hansson@arm.com
31010458Sandreas.hansson@arm.com    // explicit conversions
31110458Sandreas.hansson@arm.com    int to_int() const;
31210458Sandreas.hansson@arm.com    unsigned int to_uint() const;
31310458Sandreas.hansson@arm.com    long to_long() const;
31410458Sandreas.hansson@arm.com    unsigned long to_ulong() const;
31510458Sandreas.hansson@arm.com    int64 to_int64() const;
31610458Sandreas.hansson@arm.com    uint64 to_uint64() const;
31710458Sandreas.hansson@arm.com
31810458Sandreas.hansson@arm.com    const std::string to_string() const;
31910458Sandreas.hansson@arm.com    const std::string to_string(sc_numrep) const;
32010458Sandreas.hansson@arm.com    const std::string to_string(sc_numrep, bool) const;
32110458Sandreas.hansson@arm.com
32210458Sandreas.hansson@arm.com    // implicit conversion
32310458Sandreas.hansson@arm.com    operator sc_bv_base() const;
32410458Sandreas.hansson@arm.com
32510458Sandreas.hansson@arm.com    // print or dump content
32610458Sandreas.hansson@arm.com    void print(::std::ostream & =::std::cout) const;
32710458Sandreas.hansson@arm.com    void scan(::std::istream & =::std::cin);
32810458Sandreas.hansson@arm.com    void dump(::std::ostream & =::std::cout) const;
32910458Sandreas.hansson@arm.com
33010458Sandreas.hansson@arm.com  private:
33110458Sandreas.hansson@arm.com    sc_fxnum &m_num;
33210458Sandreas.hansson@arm.com    int m_from;
33310458Sandreas.hansson@arm.com    int m_to;
33410458Sandreas.hansson@arm.com
33510458Sandreas.hansson@arm.com    sc_bv_base &m_bv;
33610458Sandreas.hansson@arm.com
33710458Sandreas.hansson@arm.com  private:
33810458Sandreas.hansson@arm.com    // Disabled
33910458Sandreas.hansson@arm.com    sc_fxnum_subref();
34010458Sandreas.hansson@arm.com};
34110458Sandreas.hansson@arm.com
34210458Sandreas.hansson@arm.com
34310458Sandreas.hansson@arm.com// ----------------------------------------------------------------------------
34410458Sandreas.hansson@arm.com// CLASS : sc_fxnum_fast_subref
34510458Sandreas.hansson@arm.com//
34610458Sandreas.hansson@arm.com// Proxy class for part-selection in class sc_fxnum_fast,
34710458Sandreas.hansson@arm.com// behaves like sc_bv_base.
34810458Sandreas.hansson@arm.com// ----------------------------------------------------------------------------
34910458Sandreas.hansson@arm.com
35010458Sandreas.hansson@arm.comclass sc_fxnum_fast_subref
35110458Sandreas.hansson@arm.com{
35210458Sandreas.hansson@arm.com    friend class sc_fxnum_fast;
35310458Sandreas.hansson@arm.com    friend class sc_fxnum_subref;
35410458Sandreas.hansson@arm.com
35510458Sandreas.hansson@arm.com    bool get() const;
35610458Sandreas.hansson@arm.com    bool set();
35710458Sandreas.hansson@arm.com
35810458Sandreas.hansson@arm.com    // constructor
35910458Sandreas.hansson@arm.com    sc_fxnum_fast_subref(sc_fxnum_fast &, int, int);
36010458Sandreas.hansson@arm.com
36110458Sandreas.hansson@arm.com  public:
36210458Sandreas.hansson@arm.com    // copy constructor
36310458Sandreas.hansson@arm.com    sc_fxnum_fast_subref(const sc_fxnum_fast_subref &);
36410458Sandreas.hansson@arm.com
36510458Sandreas.hansson@arm.com    // destructor
36610458Sandreas.hansson@arm.com    ~sc_fxnum_fast_subref();
36710458Sandreas.hansson@arm.com
36810458Sandreas.hansson@arm.com    // assignment operators
36910458Sandreas.hansson@arm.com#define DECL_ASN_OP_T(tp) \
37010458Sandreas.hansson@arm.com    sc_fxnum_fast_subref &operator = (tp);
37110458Sandreas.hansson@arm.com
37210458Sandreas.hansson@arm.com    DECL_ASN_OP_T(const sc_fxnum_subref &)
37310458Sandreas.hansson@arm.com    DECL_ASN_OP_T(const sc_fxnum_fast_subref &)
37410458Sandreas.hansson@arm.com    DECL_ASN_OP_T(const sc_bv_base &)
37510458Sandreas.hansson@arm.com    DECL_ASN_OP_T(const sc_lv_base &)
37610458Sandreas.hansson@arm.com    DECL_ASN_OP_T(const char *)
37710458Sandreas.hansson@arm.com    DECL_ASN_OP_T(const bool *)
37810458Sandreas.hansson@arm.com    DECL_ASN_OP_T(const sc_signed &)
37910458Sandreas.hansson@arm.com    DECL_ASN_OP_T(const sc_unsigned &)
38010458Sandreas.hansson@arm.com    DECL_ASN_OP_T(const sc_int_base &)
38110458Sandreas.hansson@arm.com    DECL_ASN_OP_T(const sc_uint_base &)
38210458Sandreas.hansson@arm.com    DECL_ASN_OP_T(int64)
38310458Sandreas.hansson@arm.com    DECL_ASN_OP_T(uint64)
38410458Sandreas.hansson@arm.com    DECL_ASN_OP_T(int)
38510458Sandreas.hansson@arm.com    DECL_ASN_OP_T(unsigned int)
38610458Sandreas.hansson@arm.com    DECL_ASN_OP_T(long)
38710458Sandreas.hansson@arm.com    DECL_ASN_OP_T(unsigned long)
38810458Sandreas.hansson@arm.com    DECL_ASN_OP_T(char)
38910458Sandreas.hansson@arm.com
3902740SN/A#undef DECL_ASN_OP_T
3912740SN/A
3922740SN/A#define DECL_ASN_OP_T_A(op, tp) sc_fxnum_fast_subref &operator op ## = (tp);
3932740SN/A
3941692SN/A#define DECL_ASN_OP_A(op) \
3951427SN/A    DECL_ASN_OP_T_A(op, const sc_fxnum_subref &) \
3967493Ssteve.reinhardt@amd.com    DECL_ASN_OP_T_A(op, const sc_fxnum_fast_subref &) \
3977493Ssteve.reinhardt@amd.com    DECL_ASN_OP_T_A(op, const sc_bv_base &) \
3987493Ssteve.reinhardt@amd.com    DECL_ASN_OP_T_A(op, const sc_lv_base &)
3999338SAndreas.Sandberg@arm.com
4009342SAndreas.Sandberg@arm.com    DECL_ASN_OP_A(&)
4019342SAndreas.Sandberg@arm.com    DECL_ASN_OP_A(|)
4021427SN/A    DECL_ASN_OP_A(^)
4037493Ssteve.reinhardt@amd.com
404679SN/A#undef DECL_ASN_OP_T_A
405679SN/A#undef DECL_ASN_OP_A
406679SN/A
4072740SN/A    // relational operators
408679SN/A#define DECL_REL_OP_T(op, tp) \
409679SN/A    friend bool operator op (const sc_fxnum_fast_subref &, tp); \
4101310SN/A    friend bool operator op (tp, const sc_fxnum_fast_subref &);
4116654Snate@binkert.org
4124762Snate@binkert.org#define DECL_REL_OP(op) \
4132740SN/A    friend bool operator op (const sc_fxnum_fast_subref &, \
4142740SN/A                             const sc_fxnum_fast_subref &); \
4152740SN/A    friend bool operator op (const sc_fxnum_fast_subref &, \
4162740SN/A                             const sc_fxnum_subref &); \
4172740SN/A    DECL_REL_OP_T(op, const sc_bv_base &) \
4182740SN/A    DECL_REL_OP_T(op, const sc_lv_base &) \
4197673Snate@binkert.org    DECL_REL_OP_T(op, const char *) \
4202740SN/A    DECL_REL_OP_T(op, const bool *) \
4212740SN/A    DECL_REL_OP_T(op, const sc_signed &) \
4222740SN/A    DECL_REL_OP_T(op, const sc_unsigned &) \
4232740SN/A    DECL_REL_OP_T(op, int) \
4244762Snate@binkert.org    DECL_REL_OP_T(op, unsigned int) \
4254762Snate@binkert.org    DECL_REL_OP_T(op, long) \
4269342SAndreas.Sandberg@arm.com    DECL_REL_OP_T(op, unsigned long)
4279342SAndreas.Sandberg@arm.com
4282740SN/A    DECL_REL_OP(==)
4294762Snate@binkert.org    DECL_REL_OP(!=)
4304762Snate@binkert.org
4314762Snate@binkert.org#undef DECL_REL_OP_T
4324762Snate@binkert.org#undef DECL_REL_OP
433679SN/A
4342711SN/A    // reduce functions
435679SN/A    bool and_reduce() const;
4362711SN/A    bool nand_reduce() const;
4372711SN/A    bool or_reduce() const;
4381692SN/A    bool nor_reduce() const;
4391310SN/A    bool xor_reduce() const;
4401427SN/A    bool xnor_reduce() const;
4412740SN/A
4422740SN/A    // query parameter
4432740SN/A    int length() const;
4442740SN/A
4452740SN/A    // explicit conversions
4462740SN/A    int to_int() const;
4472740SN/A    unsigned int to_uint() const;
44810267SGeoffrey.Blake@arm.com    long to_long() const;
4497528Ssteve.reinhardt@amd.com    unsigned long to_ulong() const;
4503105Sstever@eecs.umich.edu    int64 to_int64() const;
4512740SN/A    uint64 to_uint64() const;
4521310SN/A
4539100SBrad.Beckmann@amd.com    const std::string to_string() const;
4549100SBrad.Beckmann@amd.com    const std::string to_string(sc_numrep) const;
4559100SBrad.Beckmann@amd.com    const std::string to_string(sc_numrep, bool) const;
4569100SBrad.Beckmann@amd.com
4579100SBrad.Beckmann@amd.com    // implicit conversion
4589100SBrad.Beckmann@amd.com    operator sc_bv_base() const;
4599100SBrad.Beckmann@amd.com
4609100SBrad.Beckmann@amd.com    // print or dump content
4619100SBrad.Beckmann@amd.com    void print(::std::ostream & =::std::cout) const;
4621692SN/A    void scan(::std::istream & =::std::cin);
4631692SN/A    void dump(::std::ostream & =::std::cout) const;
4641692SN/A
4652740SN/A  private:
4662740SN/A    sc_fxnum_fast &m_num;
4672740SN/A    int m_from;
4682740SN/A    int m_to;
4691692SN/A
4705610Snate@binkert.org    sc_bv_base &m_bv;
4711692SN/A
4722740SN/A  private:
4731692SN/A    // Disabled
47410267SGeoffrey.Blake@arm.com    sc_fxnum_fast_subref();
4757528Ssteve.reinhardt@amd.com};
4763105Sstever@eecs.umich.edu
4772740SN/A
4782712SN/A// ----------------------------------------------------------------------------
4795610Snate@binkert.org// CLASS : sc_fxnum
4805610Snate@binkert.org//
4811692SN/A// Base class for the fixed-point types; arbitrary precision.
4824762Snate@binkert.org// ----------------------------------------------------------------------------
4834762Snate@binkert.org
4844762Snate@binkert.orgclass sc_fxnum
4855610Snate@binkert.org{
4864762Snate@binkert.org    friend class sc_fxval;
4875610Snate@binkert.org
4884859Snate@binkert.org    friend class sc_fxnum_bitref;
4899338SAndreas.Sandberg@arm.com    friend class sc_fxnum_subref;
4909338SAndreas.Sandberg@arm.com    friend class sc_fxnum_fast_bitref;
4919338SAndreas.Sandberg@arm.com    friend class sc_fxnum_fast_subref;
4929528Ssascha.bischoff@arm.com
4939338SAndreas.Sandberg@arm.com    friend class sc_core::vcd_sc_fxnum_trace;
4948597Ssteve.reinhardt@amd.com    friend class sc_core::wif_sc_fxnum_trace;
4958597Ssteve.reinhardt@amd.com
4968597Ssteve.reinhardt@amd.com  protected:
4978597Ssteve.reinhardt@amd.com    sc_fxnum_observer *observer() const;
4988597Ssteve.reinhardt@amd.com
4998597Ssteve.reinhardt@amd.com    void cast();
5008597Ssteve.reinhardt@amd.com
5018597Ssteve.reinhardt@amd.com    // constructors
5028597Ssteve.reinhardt@amd.com    sc_fxnum(const sc_fxtype_params &, sc_enc, const sc_fxcast_switch &,
5038597Ssteve.reinhardt@amd.com             sc_fxnum_observer *);
5048597Ssteve.reinhardt@amd.com
5058597Ssteve.reinhardt@amd.com#define DECL_CTOR_T(tp) \
5068597Ssteve.reinhardt@amd.com    sc_fxnum(tp, const sc_fxtype_params &, sc_enc, const sc_fxcast_switch &, \
5078597Ssteve.reinhardt@amd.com             sc_fxnum_observer *);
5082740SN/A
5092740SN/A    DECL_CTOR_T(int)
5102740SN/A    DECL_CTOR_T(unsigned int)
5112740SN/A    DECL_CTOR_T(long)
5122740SN/A    DECL_CTOR_T(unsigned long)
5132740SN/A    DECL_CTOR_T(float)
5142740SN/A    DECL_CTOR_T(double)
5152740SN/A    DECL_CTOR_T(const char *)
5161527SN/A    DECL_CTOR_T(const sc_fxval &)
5172740SN/A    DECL_CTOR_T(const sc_fxval_fast &)
5181585SN/A    DECL_CTOR_T(const sc_fxnum &)
5191427SN/A    DECL_CTOR_T(const sc_fxnum_fast &)
5202738SN/A
5212738SN/A    DECL_CTOR_T(int64)
5223105Sstever@eecs.umich.edu    DECL_CTOR_T(uint64)
5232738SN/A    DECL_CTOR_T(const sc_int_base &)
5241427SN/A    DECL_CTOR_T(const sc_uint_base &)
5251427SN/A    DECL_CTOR_T(const sc_signed &)
5261427SN/A    DECL_CTOR_T(const sc_unsigned &)
5271427SN/A
5281427SN/A#undef DECL_CTOR_T
5291427SN/A
5301427SN/A    ~sc_fxnum();
5311427SN/A
5321427SN/A    // internal use only;
5331427SN/A    const scfx_rep *get_rep() const;
5341427SN/A
5351427SN/A  public:
5367493Ssteve.reinhardt@amd.com    // unary operators
5371427SN/A    const sc_fxval operator - () const;
5381427SN/A    const sc_fxval operator + () const;
5391427SN/A
5403100SN/A    // unary functions
5413100SN/A    friend void neg(sc_fxval &, const sc_fxnum &);
5423100SN/A    friend void neg(sc_fxnum &, const sc_fxnum &);
5433100SN/A
5443100SN/A    // binary operators
5453100SN/A#define DECL_BIN_OP_T(op, tp) \
5463105Sstever@eecs.umich.edu    friend const sc_fxval operator op (const sc_fxnum &, tp); \
5473105Sstever@eecs.umich.edu    friend const sc_fxval operator op (tp, const sc_fxnum &);
5483105Sstever@eecs.umich.edu
5493105Sstever@eecs.umich.edu#define DECL_BIN_OP_OTHER(op) \
5503105Sstever@eecs.umich.edu    DECL_BIN_OP_T(op, int64) \
55110267SGeoffrey.Blake@arm.com    DECL_BIN_OP_T(op, uint64) \
5528321Ssteve.reinhardt@amd.com    DECL_BIN_OP_T(op, const sc_int_base &) \
5533105Sstever@eecs.umich.edu    DECL_BIN_OP_T(op, const sc_uint_base &) \
5543105Sstever@eecs.umich.edu    DECL_BIN_OP_T(op, const sc_signed &) \
5553105Sstever@eecs.umich.edu    DECL_BIN_OP_T(op, const sc_unsigned &)
5563105Sstever@eecs.umich.edu
5573105Sstever@eecs.umich.edu#define DECL_BIN_OP(op, dummy) \
5588321Ssteve.reinhardt@amd.com    friend const sc_fxval operator op (const sc_fxnum &, const sc_fxnum &); \
5598321Ssteve.reinhardt@amd.com    DECL_BIN_OP_T(op, int) \
5608321Ssteve.reinhardt@amd.com    DECL_BIN_OP_T(op, unsigned int) \
5618321Ssteve.reinhardt@amd.com    DECL_BIN_OP_T(op, long) \
5628321Ssteve.reinhardt@amd.com    DECL_BIN_OP_T(op, unsigned long) \
56310267SGeoffrey.Blake@arm.com    DECL_BIN_OP_T(op, float) \
56410267SGeoffrey.Blake@arm.com    DECL_BIN_OP_T(op, double) \
56510267SGeoffrey.Blake@arm.com    DECL_BIN_OP_T(op, const char *) \
56610267SGeoffrey.Blake@arm.com    DECL_BIN_OP_T(op, const sc_fxval &) \
56710267SGeoffrey.Blake@arm.com    DECL_BIN_OP_T(op, const sc_fxval_fast &) \
5688321Ssteve.reinhardt@amd.com    DECL_BIN_OP_T(op, const sc_fxnum_fast &) \
5698321Ssteve.reinhardt@amd.com    DECL_BIN_OP_OTHER(op)
5708321Ssteve.reinhardt@amd.com
5718321Ssteve.reinhardt@amd.com    DECL_BIN_OP(*, mult)
5728321Ssteve.reinhardt@amd.com    DECL_BIN_OP(+, add)
5738321Ssteve.reinhardt@amd.com    DECL_BIN_OP(-, sub)
5748321Ssteve.reinhardt@amd.com// don't use macros
5758321Ssteve.reinhardt@amd.com// DECL_BIN_OP(/, div)
5768321Ssteve.reinhardt@amd.com    friend const sc_fxval operator / (const sc_fxnum &, const sc_fxnum &);
5773105Sstever@eecs.umich.edu    DECL_BIN_OP_T(/, int)
5783105Sstever@eecs.umich.edu    DECL_BIN_OP_T(/, unsigned int)
5793105Sstever@eecs.umich.edu    DECL_BIN_OP_T(/, long)
5803105Sstever@eecs.umich.edu    DECL_BIN_OP_T(/, unsigned long)
5813105Sstever@eecs.umich.edu    DECL_BIN_OP_T(/, float)
5823105Sstever@eecs.umich.edu    DECL_BIN_OP_T(/, double)
5833105Sstever@eecs.umich.edu    DECL_BIN_OP_T(/, const char *)
5843105Sstever@eecs.umich.edu    DECL_BIN_OP_T(/, const sc_fxval &)
5853105Sstever@eecs.umich.edu    DECL_BIN_OP_T(/, const sc_fxval_fast &)
5863105Sstever@eecs.umich.edu    DECL_BIN_OP_T(/, const sc_fxnum_fast &)
5873105Sstever@eecs.umich.edu// DECL_BIN_OP_OTHER(op)
5883105Sstever@eecs.umich.edu
5893105Sstever@eecs.umich.edu    DECL_BIN_OP_T(/, int64)
5903105Sstever@eecs.umich.edu    DECL_BIN_OP_T(/, uint64)
5913105Sstever@eecs.umich.edu    DECL_BIN_OP_T(/, const sc_int_base &)
5923105Sstever@eecs.umich.edu    DECL_BIN_OP_T(/, const sc_uint_base &)
5933105Sstever@eecs.umich.edu    DECL_BIN_OP_T(/, const sc_signed &)
5941585SN/A    DECL_BIN_OP_T(/, const sc_unsigned &)
5951310SN/A
5961310SN/A#undef DECL_BIN_OP_T
5971310SN/A#undef DECL_BIN_OP_OTHER
5981310SN/A#undef DECL_BIN_OP
5997673Snate@binkert.org
6001310SN/A    friend const sc_fxval operator << (const sc_fxnum &, int);
6011310SN/A    friend const sc_fxval operator >> (const sc_fxnum &, int);
6021310SN/A
6031310SN/A    // binary functions
6041427SN/A#define DECL_BIN_FNC_T(fnc, tp) \
6051310SN/A    friend void fnc (sc_fxval &, const sc_fxnum &, tp); \
6061310SN/A    friend void fnc (sc_fxval &, tp, const sc_fxnum &); \
6072738SN/A    friend void fnc (sc_fxnum &, const sc_fxnum &, tp); \
6083105Sstever@eecs.umich.edu    friend void fnc (sc_fxnum &, tp, const sc_fxnum &);
6092738SN/A
6102738SN/A#define DECL_BIN_FNC_OTHER(fnc) \
6112740SN/A    DECL_BIN_FNC_T(fnc, int64) \
6122740SN/A    DECL_BIN_FNC_T(fnc, uint64) \
6132740SN/A    DECL_BIN_FNC_T(fnc, const sc_int_base &) \
6142740SN/A    DECL_BIN_FNC_T(fnc, const sc_uint_base &) \
6152740SN/A    DECL_BIN_FNC_T(fnc, const sc_signed &) \
6162740SN/A    DECL_BIN_FNC_T(fnc, const sc_unsigned &)
6172740SN/A
6183105Sstever@eecs.umich.edu#define DECL_BIN_FNC(fnc) \
6191310SN/A    friend void fnc (sc_fxval &, const sc_fxnum &, const sc_fxnum &); \
6203105Sstever@eecs.umich.edu    friend void fnc (sc_fxnum &, const sc_fxnum &, const sc_fxnum &); \
6213105Sstever@eecs.umich.edu    DECL_BIN_FNC_T(fnc, int) \
6223105Sstever@eecs.umich.edu    DECL_BIN_FNC_T(fnc, unsigned int) \
6233105Sstever@eecs.umich.edu    DECL_BIN_FNC_T(fnc, long) \
6243105Sstever@eecs.umich.edu    DECL_BIN_FNC_T(fnc, unsigned long) \
6258321Ssteve.reinhardt@amd.com    DECL_BIN_FNC_T(fnc, float) \
6263105Sstever@eecs.umich.edu    DECL_BIN_FNC_T(fnc, double) \
6273105Sstever@eecs.umich.edu    DECL_BIN_FNC_T(fnc, const char *) \
6283105Sstever@eecs.umich.edu    DECL_BIN_FNC_T(fnc, const sc_fxval &) \
6293105Sstever@eecs.umich.edu    DECL_BIN_FNC_T(fnc, const sc_fxval_fast &) \
6303105Sstever@eecs.umich.edu    DECL_BIN_FNC_T(fnc, const sc_fxnum_fast &) \
6311310SN/A    DECL_BIN_FNC_OTHER(fnc)
6321585SN/A
6337675Snate@binkert.org    DECL_BIN_FNC(mult)
6347675Snate@binkert.org    DECL_BIN_FNC(div)
6357675Snate@binkert.org    DECL_BIN_FNC(add)
6367675Snate@binkert.org    DECL_BIN_FNC(sub)
6377675Snate@binkert.org
6387675Snate@binkert.org#undef DECL_BIN_FNC_T
6397675Snate@binkert.org#undef DECL_BIN_FNC_OTHER
6407675Snate@binkert.org#undef DECL_BIN_FNC
6417675Snate@binkert.org
6421692SN/A    friend void lshift(sc_fxval &, const sc_fxnum &, int);
6431692SN/A    friend void rshift(sc_fxval &, const sc_fxnum &, int);
6441585SN/A    friend void lshift(sc_fxnum &, const sc_fxnum &, int);
6457528Ssteve.reinhardt@amd.com    friend void rshift(sc_fxnum &, const sc_fxnum &, int);
6467528Ssteve.reinhardt@amd.com
6477528Ssteve.reinhardt@amd.com    // relational (including equality) operators
6481585SN/A#define DECL_REL_OP_T(op, tp) \
6491585SN/A    friend bool operator op (const sc_fxnum &, tp); \
6501585SN/A    friend bool operator op (tp, const sc_fxnum &);
6513100SN/A
6523100SN/A#define DECL_REL_OP_OTHER(op) \
6533100SN/A    DECL_REL_OP_T(op, int64) \
6548596Ssteve.reinhardt@amd.com    DECL_REL_OP_T(op, uint64) \
6558596Ssteve.reinhardt@amd.com    DECL_REL_OP_T(op, const sc_int_base &) \
6568596Ssteve.reinhardt@amd.com    DECL_REL_OP_T(op, const sc_uint_base &) \
6578596Ssteve.reinhardt@amd.com    DECL_REL_OP_T(op, const sc_signed &) \
6588596Ssteve.reinhardt@amd.com    DECL_REL_OP_T(op, const sc_unsigned &)
6598596Ssteve.reinhardt@amd.com
6608596Ssteve.reinhardt@amd.com#define DECL_REL_OP(op) \
6618596Ssteve.reinhardt@amd.com    friend bool operator op (const sc_fxnum &, const sc_fxnum &); \
6628597Ssteve.reinhardt@amd.com    DECL_REL_OP_T(op, int) \
6638597Ssteve.reinhardt@amd.com    DECL_REL_OP_T(op, unsigned int) \
6648597Ssteve.reinhardt@amd.com    DECL_REL_OP_T(op, long) \
6658597Ssteve.reinhardt@amd.com    DECL_REL_OP_T(op, unsigned long) \
6668597Ssteve.reinhardt@amd.com    DECL_REL_OP_T(op, float) \
6678597Ssteve.reinhardt@amd.com    DECL_REL_OP_T(op, double) \
6688597Ssteve.reinhardt@amd.com    DECL_REL_OP_T(op, const char *) \
6698597Ssteve.reinhardt@amd.com    DECL_REL_OP_T(op, const sc_fxval &) \
6708597Ssteve.reinhardt@amd.com    DECL_REL_OP_T(op, const sc_fxval_fast &) \
6718597Ssteve.reinhardt@amd.com    DECL_REL_OP_T(op, const sc_fxnum_fast &) \
6728597Ssteve.reinhardt@amd.com    DECL_REL_OP_OTHER(op)
6738597Ssteve.reinhardt@amd.com
6748597Ssteve.reinhardt@amd.com    DECL_REL_OP(<)
6758597Ssteve.reinhardt@amd.com    DECL_REL_OP(<=)
6768597Ssteve.reinhardt@amd.com    DECL_REL_OP(>)
6778597Ssteve.reinhardt@amd.com    DECL_REL_OP(>=)
6788597Ssteve.reinhardt@amd.com    DECL_REL_OP(==)
6798597Ssteve.reinhardt@amd.com    DECL_REL_OP(!=)
6808597Ssteve.reinhardt@amd.com
6818597Ssteve.reinhardt@amd.com#undef DECL_REL_OP_T
6828597Ssteve.reinhardt@amd.com#undef DECL_REL_OP_OTHER
6838596Ssteve.reinhardt@amd.com#undef DECL_REL_OP
6848596Ssteve.reinhardt@amd.com
6858596Ssteve.reinhardt@amd.com    // assignment operators
6868596Ssteve.reinhardt@amd.com#define DECL_ASN_OP_T(op, tp) \
6878596Ssteve.reinhardt@amd.com    sc_fxnum &operator op(tp);
6888596Ssteve.reinhardt@amd.com
6898596Ssteve.reinhardt@amd.com#define DECL_ASN_OP_OTHER(op) \
6908596Ssteve.reinhardt@amd.com    DECL_ASN_OP_T(op, int64) \
6918596Ssteve.reinhardt@amd.com    DECL_ASN_OP_T(op, uint64) \
6928596Ssteve.reinhardt@amd.com    DECL_ASN_OP_T(op, const sc_int_base &) \
6938596Ssteve.reinhardt@amd.com    DECL_ASN_OP_T(op, const sc_uint_base &) \
6948596Ssteve.reinhardt@amd.com    DECL_ASN_OP_T(op, const sc_signed &) \
6958596Ssteve.reinhardt@amd.com    DECL_ASN_OP_T(op, const sc_unsigned &)
6968840Sandreas.hansson@arm.com
6978596Ssteve.reinhardt@amd.com#define DECL_ASN_OP(op) \
6988596Ssteve.reinhardt@amd.com    DECL_ASN_OP_T(op, int) \
6998596Ssteve.reinhardt@amd.com    DECL_ASN_OP_T(op, unsigned int) \
7008596Ssteve.reinhardt@amd.com    DECL_ASN_OP_T(op, long) \
7019342SAndreas.Sandberg@arm.com    DECL_ASN_OP_T(op, unsigned long) \
7028596Ssteve.reinhardt@amd.com    DECL_ASN_OP_T(op, float) \
7038596Ssteve.reinhardt@amd.com    DECL_ASN_OP_T(op, double) \
7048596Ssteve.reinhardt@amd.com    DECL_ASN_OP_T(op, const char *) \
7059338SAndreas.Sandberg@arm.com    DECL_ASN_OP_T(op, const sc_fxval &) \
7068597Ssteve.reinhardt@amd.com    DECL_ASN_OP_T(op, const sc_fxval_fast &) \
7078860Sandreas.hansson@arm.com    DECL_ASN_OP_T(op, const sc_fxnum &) \
7088860Sandreas.hansson@arm.com    DECL_ASN_OP_T(op, const sc_fxnum_fast &) \
7098860Sandreas.hansson@arm.com    DECL_ASN_OP_OTHER(op)
7108860Sandreas.hansson@arm.com
7118860Sandreas.hansson@arm.com    DECL_ASN_OP(=)
7128860Sandreas.hansson@arm.com
7138860Sandreas.hansson@arm.com    DECL_ASN_OP(*=)
7148860Sandreas.hansson@arm.com    DECL_ASN_OP(/=)
7158860Sandreas.hansson@arm.com    DECL_ASN_OP(+=)
7168860Sandreas.hansson@arm.com    DECL_ASN_OP(-=)
7178860Sandreas.hansson@arm.com
7188860Sandreas.hansson@arm.com    DECL_ASN_OP_T(<<=, int)
7198860Sandreas.hansson@arm.com    DECL_ASN_OP_T(>>=, int)
7208596Ssteve.reinhardt@amd.com
7218596Ssteve.reinhardt@amd.com#undef DECL_ASN_OP_T
7228596Ssteve.reinhardt@amd.com#undef DECL_ASN_OP_OTHER
7238596Ssteve.reinhardt@amd.com#undef DECL_ASN_OP
7248596Ssteve.reinhardt@amd.com
7258597Ssteve.reinhardt@amd.com    // auto-increment and auto-decrement
7268596Ssteve.reinhardt@amd.com    const sc_fxval operator ++ (int);
7278596Ssteve.reinhardt@amd.com    const sc_fxval operator -- (int);
7288596Ssteve.reinhardt@amd.com
7298596Ssteve.reinhardt@amd.com    sc_fxnum &operator ++ ();
7308596Ssteve.reinhardt@amd.com    sc_fxnum &operator -- ();
7318596Ssteve.reinhardt@amd.com
7328596Ssteve.reinhardt@amd.com    // bit selection
7338596Ssteve.reinhardt@amd.com    const sc_fxnum_bitref operator [] (int) const;
7348596Ssteve.reinhardt@amd.com    sc_fxnum_bitref operator [] (int);
7358596Ssteve.reinhardt@amd.com
7368596Ssteve.reinhardt@amd.com    const sc_fxnum_bitref bit(int) const;
7378596Ssteve.reinhardt@amd.com    sc_fxnum_bitref bit(int);
7388596Ssteve.reinhardt@amd.com
7398596Ssteve.reinhardt@amd.com    // part selection
7408596Ssteve.reinhardt@amd.com    const sc_fxnum_subref operator () (int, int) const;
7418597Ssteve.reinhardt@amd.com    sc_fxnum_subref operator () (int, int);
7428597Ssteve.reinhardt@amd.com
7438597Ssteve.reinhardt@amd.com    const sc_fxnum_subref range(int, int) const;
7448597Ssteve.reinhardt@amd.com    sc_fxnum_subref range(int, int);
7458597Ssteve.reinhardt@amd.com
7469342SAndreas.Sandberg@arm.com    const sc_fxnum_subref operator () () const;
7479342SAndreas.Sandberg@arm.com    sc_fxnum_subref operator () ();
7489342SAndreas.Sandberg@arm.com
7499342SAndreas.Sandberg@arm.com    const sc_fxnum_subref range() const;
7509342SAndreas.Sandberg@arm.com    sc_fxnum_subref range();
7519342SAndreas.Sandberg@arm.com
7529342SAndreas.Sandberg@arm.com    // implicit conversion
7539342SAndreas.Sandberg@arm.com    operator double() const; // necessary evil!
7549342SAndreas.Sandberg@arm.com
7559342SAndreas.Sandberg@arm.com    // explicit conversion to primitive types
7569342SAndreas.Sandberg@arm.com    short to_short() const;
7578597Ssteve.reinhardt@amd.com    unsigned short to_ushort() const;
7588597Ssteve.reinhardt@amd.com    int to_int() const;
7598597Ssteve.reinhardt@amd.com    unsigned int to_uint() const;
7608597Ssteve.reinhardt@amd.com    long to_long() const;
7618596Ssteve.reinhardt@amd.com    unsigned long to_ulong() const;
7628596Ssteve.reinhardt@amd.com    int64 to_int64() const;
7638596Ssteve.reinhardt@amd.com    uint64 to_uint64() const;
7648596Ssteve.reinhardt@amd.com    float to_float() const;
7658596Ssteve.reinhardt@amd.com    double to_double() const;
7668596Ssteve.reinhardt@amd.com
7678596Ssteve.reinhardt@amd.com    // explicit conversion to character string
7688596Ssteve.reinhardt@amd.com    const std::string to_string() const;
7698596Ssteve.reinhardt@amd.com    const std::string to_string(sc_numrep) const;
7708596Ssteve.reinhardt@amd.com    const std::string to_string(sc_numrep, bool) const;
7718596Ssteve.reinhardt@amd.com    const std::string to_string(sc_fmt) const;
7728596Ssteve.reinhardt@amd.com    const std::string to_string(sc_numrep, sc_fmt) const;
7733100SN/A    const std::string to_string(sc_numrep, bool, sc_fmt) const;
7743100SN/A
7753100SN/A    const std::string to_dec() const;
7764762Snate@binkert.org    const std::string to_bin() const;
7778840Sandreas.hansson@arm.com    const std::string to_oct() const;
7783100SN/A    const std::string to_hex() const;
7793100SN/A
7803100SN/A    // query value
7813100SN/A    bool is_neg() const;
7823100SN/A    bool is_zero() const;
7833100SN/A
7843100SN/A    // internal use only;
7857675Snate@binkert.org    bool is_normal() const;
7867675Snate@binkert.org
7877675Snate@binkert.org    bool quantization_flag() const;
7887675Snate@binkert.org    bool overflow_flag() const;
7897675Snate@binkert.org
7907675Snate@binkert.org    const sc_fxval value() const;
7917675Snate@binkert.org
7927675Snate@binkert.org    // query parameters
7937675Snate@binkert.org    int wl() const;
7947675Snate@binkert.org    int iwl() const;
7957675Snate@binkert.org    sc_q_mode q_mode() const;
7967675Snate@binkert.org    sc_o_mode o_mode() const;
7977675Snate@binkert.org    int n_bits() const;
7987675Snate@binkert.org
7997811Ssteve.reinhardt@amd.com    const sc_fxtype_params &type_params() const;
8007675Snate@binkert.org
8017675Snate@binkert.org    const sc_fxcast_switch &cast_switch() const;
8028597Ssteve.reinhardt@amd.com
8038597Ssteve.reinhardt@amd.com    // print or dump content
8048597Ssteve.reinhardt@amd.com    void print(::std::ostream & =::std::cout) const;
8058597Ssteve.reinhardt@amd.com    void scan(::std::istream & =::std::cin);
8068597Ssteve.reinhardt@amd.com    void dump(::std::ostream & =::std::cout) const;
8078597Ssteve.reinhardt@amd.com
8088597Ssteve.reinhardt@amd.com    // internal use only;
8098597Ssteve.reinhardt@amd.com    void observer_read() const;
8108597Ssteve.reinhardt@amd.com
8118597Ssteve.reinhardt@amd.com    // internal use only;
8128597Ssteve.reinhardt@amd.com    bool get_bit(int) const;
8138597Ssteve.reinhardt@amd.com
8147673Snate@binkert.org  protected:
8157673Snate@binkert.org    bool set_bit(int, bool);
8168840Sandreas.hansson@arm.com
8178840Sandreas.hansson@arm.com    bool get_slice(int, int, sc_bv_base &) const;
8187673Snate@binkert.org    bool set_slice(int, int, const sc_bv_base &);
8194762Snate@binkert.org
8205610Snate@binkert.org    sc_fxnum_observer *lock_observer() const;
8217673Snate@binkert.org    void unlock_observer(sc_fxnum_observer *) const;
8227673Snate@binkert.org
8234762Snate@binkert.org  private:
8244762Snate@binkert.org    scfx_rep *m_rep;
8254762Snate@binkert.org
8267673Snate@binkert.org    scfx_params m_params;
8277673Snate@binkert.org    bool m_q_flag;
8284762Snate@binkert.org    bool m_o_flag;
8298596Ssteve.reinhardt@amd.com
8308597Ssteve.reinhardt@amd.com    mutable sc_fxnum_observer *m_observer;
8318597Ssteve.reinhardt@amd.com
8328597Ssteve.reinhardt@amd.com  private:
8338597Ssteve.reinhardt@amd.com    // disabled
8348597Ssteve.reinhardt@amd.com    sc_fxnum();
8358597Ssteve.reinhardt@amd.com    sc_fxnum(const sc_fxnum &);
8368597Ssteve.reinhardt@amd.com};
8378597Ssteve.reinhardt@amd.com
8388597Ssteve.reinhardt@amd.com
8398596Ssteve.reinhardt@amd.com// ----------------------------------------------------------------------------
8408597Ssteve.reinhardt@amd.com// CLASS : sc_fxnum_fast
8419983Sstever@gmail.com//
8428597Ssteve.reinhardt@amd.com// Base class for the fixed-point types; limited precision.
8438596Ssteve.reinhardt@amd.com// ----------------------------------------------------------------------------
8448597Ssteve.reinhardt@amd.com
8458597Ssteve.reinhardt@amd.comclass sc_fxnum_fast
8468597Ssteve.reinhardt@amd.com{
8478597Ssteve.reinhardt@amd.com    friend class sc_fxval_fast;
8488597Ssteve.reinhardt@amd.com
8498840Sandreas.hansson@arm.com    friend class sc_fxnum_bitref;
8508840Sandreas.hansson@arm.com    friend class sc_fxnum_subref;
8518840Sandreas.hansson@arm.com    friend class sc_fxnum_fast_bitref;
8528597Ssteve.reinhardt@amd.com    friend class sc_fxnum_fast_subref;
8538597Ssteve.reinhardt@amd.com
8545488Snate@binkert.org    friend class sc_core::vcd_sc_fxnum_fast_trace;
8557673Snate@binkert.org    friend class sc_core::wif_sc_fxnum_fast_trace;
8567673Snate@binkert.org
8575488Snate@binkert.org  protected:
8585488Snate@binkert.org    sc_fxnum_fast_observer *observer() const;
85910458Sandreas.hansson@arm.com
86010458Sandreas.hansson@arm.com    void cast();
86110458Sandreas.hansson@arm.com
86210458Sandreas.hansson@arm.com    // constructors
86310458Sandreas.hansson@arm.com    sc_fxnum_fast(const sc_fxtype_params &, sc_enc, const sc_fxcast_switch &,
8645488Snate@binkert.org                  sc_fxnum_fast_observer *);
8659983Sstever@gmail.com
8669983Sstever@gmail.com#define DECL_CTOR_T(tp) \
8679983Sstever@gmail.com    sc_fxnum_fast(tp, const sc_fxtype_params &, sc_enc, \
8689983Sstever@gmail.com                  const sc_fxcast_switch &, sc_fxnum_fast_observer *);
8699983Sstever@gmail.com
8709983Sstever@gmail.com    DECL_CTOR_T(int)
8719983Sstever@gmail.com    DECL_CTOR_T(unsigned int)
8729983Sstever@gmail.com    DECL_CTOR_T(long)
8733100SN/A    DECL_CTOR_T(unsigned long)
87410267SGeoffrey.Blake@arm.com    DECL_CTOR_T(float)
87510267SGeoffrey.Blake@arm.com    DECL_CTOR_T(double)
87610267SGeoffrey.Blake@arm.com    DECL_CTOR_T(const char *)
87710267SGeoffrey.Blake@arm.com    DECL_CTOR_T(const sc_fxval &)
87810267SGeoffrey.Blake@arm.com    DECL_CTOR_T(const sc_fxval_fast &)
87910267SGeoffrey.Blake@arm.com    DECL_CTOR_T(const sc_fxnum &)
88010267SGeoffrey.Blake@arm.com    DECL_CTOR_T(const sc_fxnum_fast &)
88110267SGeoffrey.Blake@arm.com
88210267SGeoffrey.Blake@arm.com    DECL_CTOR_T(int64)
88310267SGeoffrey.Blake@arm.com    DECL_CTOR_T(uint64)
88410267SGeoffrey.Blake@arm.com    DECL_CTOR_T(const sc_int_base &)
88510267SGeoffrey.Blake@arm.com    DECL_CTOR_T(const sc_uint_base &)
88610267SGeoffrey.Blake@arm.com    DECL_CTOR_T(const sc_signed &)
88710267SGeoffrey.Blake@arm.com    DECL_CTOR_T(const sc_unsigned &)
88810267SGeoffrey.Blake@arm.com
88910267SGeoffrey.Blake@arm.com#undef DECL_CTOR_T
89010267SGeoffrey.Blake@arm.com    ~sc_fxnum_fast();
89110267SGeoffrey.Blake@arm.com
89210267SGeoffrey.Blake@arm.com    // internal use only;
89310267SGeoffrey.Blake@arm.com    double get_val() const;
89410267SGeoffrey.Blake@arm.com
89510267SGeoffrey.Blake@arm.com  public:
8962740SN/A    // unary operators
897679SN/A    const sc_fxval_fast operator - () const;
898679SN/A    const sc_fxval_fast operator + () const;
8991692SN/A
9001692SN/A    // unary functions
901679SN/A    friend void neg(sc_fxval_fast &, const sc_fxnum_fast &);
9021692SN/A    friend void neg(sc_fxnum_fast &, const sc_fxnum_fast &);
9033100SN/A
9044762Snate@binkert.org
9059983Sstever@gmail.com    // binary operators
9069338SAndreas.Sandberg@arm.com#define DECL_BIN_OP_T(op, tp) \
9079345SAndreas.Sandberg@ARM.com    friend const sc_fxval_fast operator op (const sc_fxnum_fast &, tp); \
9089983Sstever@gmail.com    friend const sc_fxval_fast operator op (tp, const sc_fxnum_fast &);
9099342SAndreas.Sandberg@arm.com
9108597Ssteve.reinhardt@amd.com#define DECL_BIN_OP_OTHER(op) \
9118597Ssteve.reinhardt@amd.com    DECL_BIN_OP_T(op, int64) \
9128597Ssteve.reinhardt@amd.com    DECL_BIN_OP_T(op, uint64) \
9138597Ssteve.reinhardt@amd.com    DECL_BIN_OP_T(op, const sc_int_base &) \
9149342SAndreas.Sandberg@arm.com    DECL_BIN_OP_T(op, const sc_uint_base &) \
9159342SAndreas.Sandberg@arm.com    DECL_BIN_OP_T(op, const sc_signed &) \
9169345SAndreas.Sandberg@ARM.com    DECL_BIN_OP_T(op, const sc_unsigned &)
9178597Ssteve.reinhardt@amd.com
9188597Ssteve.reinhardt@amd.com#define DECL_BIN_OP(op, dummy) \
9198597Ssteve.reinhardt@amd.com    friend const sc_fxval_fast operator op (const sc_fxnum_fast &, \
9208597Ssteve.reinhardt@amd.com                                            const sc_fxnum_fast &); \
9218597Ssteve.reinhardt@amd.com    DECL_BIN_OP_T(op, int) \
9228597Ssteve.reinhardt@amd.com    DECL_BIN_OP_T(op, unsigned int) \
9238597Ssteve.reinhardt@amd.com    DECL_BIN_OP_T(op, long) \
9248597Ssteve.reinhardt@amd.com    DECL_BIN_OP_T(op, unsigned long) \
9258597Ssteve.reinhardt@amd.com    DECL_BIN_OP_T(op, float) \
9268597Ssteve.reinhardt@amd.com    DECL_BIN_OP_T(op, double) \
92710023Smatt.horsnell@ARM.com    DECL_BIN_OP_T(op, const char *) \
92810023Smatt.horsnell@ARM.com    DECL_BIN_OP_T(op, const sc_fxval_fast &) \
9298597Ssteve.reinhardt@amd.com    DECL_BIN_OP_OTHER(op)
9308597Ssteve.reinhardt@amd.com
9318597Ssteve.reinhardt@amd.com    DECL_BIN_OP(*, mult)
93210267SGeoffrey.Blake@arm.com    DECL_BIN_OP(+, add)
93310267SGeoffrey.Blake@arm.com    DECL_BIN_OP(-, sub)
93410267SGeoffrey.Blake@arm.com// DECL_BIN_OP(/, div)
93510267SGeoffrey.Blake@arm.com    friend const sc_fxval_fast operator / (const sc_fxnum_fast &,
93610267SGeoffrey.Blake@arm.com                                           const sc_fxnum_fast &);
93710267SGeoffrey.Blake@arm.com    DECL_BIN_OP_T(/, int)
93810267SGeoffrey.Blake@arm.com    DECL_BIN_OP_T(/, unsigned int)
93910267SGeoffrey.Blake@arm.com    DECL_BIN_OP_T(/, long)
94010267SGeoffrey.Blake@arm.com    DECL_BIN_OP_T(/, unsigned long)
94110267SGeoffrey.Blake@arm.com    DECL_BIN_OP_T(/, float)
94210267SGeoffrey.Blake@arm.com    DECL_BIN_OP_T(/, double)
94310267SGeoffrey.Blake@arm.com    DECL_BIN_OP_T(/, const char *)
94410267SGeoffrey.Blake@arm.com    DECL_BIN_OP_T(/, const sc_fxval_fast &)
94510267SGeoffrey.Blake@arm.com// DECL_BIN_OP_OTHER(op)
94610267SGeoffrey.Blake@arm.com
94710267SGeoffrey.Blake@arm.com    DECL_BIN_OP_T(/, int64) \
94810267SGeoffrey.Blake@arm.com    DECL_BIN_OP_T(/, uint64) \
94910267SGeoffrey.Blake@arm.com    DECL_BIN_OP_T(/, const sc_int_base &) \
95010267SGeoffrey.Blake@arm.com    DECL_BIN_OP_T(/, const sc_uint_base &) \
95110267SGeoffrey.Blake@arm.com    DECL_BIN_OP_T(/, const sc_signed &) \
95210267SGeoffrey.Blake@arm.com    DECL_BIN_OP_T(/, const sc_unsigned &)
95310267SGeoffrey.Blake@arm.com
95410267SGeoffrey.Blake@arm.com#undef DECL_BIN_OP_T
95510267SGeoffrey.Blake@arm.com#undef DECL_BIN_OP_OTHER
95610267SGeoffrey.Blake@arm.com#undef DECL_BIN_OP
95710267SGeoffrey.Blake@arm.com
95810267SGeoffrey.Blake@arm.com    friend const sc_fxval_fast operator << (const sc_fxnum_fast &, int);
95910267SGeoffrey.Blake@arm.com    friend const sc_fxval_fast operator >> (const sc_fxnum_fast &, int);
96010267SGeoffrey.Blake@arm.com
96110267SGeoffrey.Blake@arm.com    // binary functions
96210267SGeoffrey.Blake@arm.com#define DECL_BIN_FNC_T(fnc, tp) \
96310267SGeoffrey.Blake@arm.com    friend void fnc (sc_fxval_fast &, const sc_fxnum_fast &, tp); \
96410267SGeoffrey.Blake@arm.com    friend void fnc (sc_fxval_fast &, tp, const sc_fxnum_fast &); \
96510267SGeoffrey.Blake@arm.com    friend void fnc (sc_fxnum_fast &, const sc_fxnum_fast &, tp); \
96610267SGeoffrey.Blake@arm.com    friend void fnc (sc_fxnum_fast &, tp, const sc_fxnum_fast &);
96710267SGeoffrey.Blake@arm.com
96810267SGeoffrey.Blake@arm.com#define DECL_BIN_FNC_OTHER(fnc) \
96910267SGeoffrey.Blake@arm.com    DECL_BIN_FNC_T(fnc, int64) \
97010267SGeoffrey.Blake@arm.com    DECL_BIN_FNC_T(fnc, uint64) \
97110267SGeoffrey.Blake@arm.com    DECL_BIN_FNC_T(fnc, const sc_int_base &) \
97210267SGeoffrey.Blake@arm.com    DECL_BIN_FNC_T(fnc, const sc_uint_base &) \
97310267SGeoffrey.Blake@arm.com    DECL_BIN_FNC_T(fnc, const sc_signed &) \
97410267SGeoffrey.Blake@arm.com    DECL_BIN_FNC_T(fnc, const sc_unsigned &)
97510267SGeoffrey.Blake@arm.com
97610267SGeoffrey.Blake@arm.com#define DECL_BIN_FNC(fnc) \
97710267SGeoffrey.Blake@arm.com    friend void fnc (sc_fxval_fast &, const sc_fxnum_fast &, \
97810267SGeoffrey.Blake@arm.com                                      const sc_fxnum_fast &); \
97910267SGeoffrey.Blake@arm.com    friend void fnc (sc_fxnum_fast &, const sc_fxnum_fast &, \
98010267SGeoffrey.Blake@arm.com                                      const sc_fxnum_fast &); \
98110267SGeoffrey.Blake@arm.com    DECL_BIN_FNC_T(fnc, int) \
98210267SGeoffrey.Blake@arm.com    DECL_BIN_FNC_T(fnc, unsigned int) \
98310267SGeoffrey.Blake@arm.com    DECL_BIN_FNC_T(fnc, long) \
98410267SGeoffrey.Blake@arm.com    DECL_BIN_FNC_T(fnc, unsigned long) \
98510267SGeoffrey.Blake@arm.com    DECL_BIN_FNC_T(fnc, float) \
98610267SGeoffrey.Blake@arm.com    DECL_BIN_FNC_T(fnc, double) \
98710267SGeoffrey.Blake@arm.com    DECL_BIN_FNC_T(fnc, const char *) \
98810267SGeoffrey.Blake@arm.com    DECL_BIN_FNC_T(fnc, const sc_fxval &) \
98910267SGeoffrey.Blake@arm.com    DECL_BIN_FNC_T(fnc, const sc_fxval_fast &) \
9902740SN/A    DECL_BIN_FNC_T(fnc, const sc_fxnum &) \
9912740SN/A    DECL_BIN_FNC_OTHER(fnc)
9922740SN/A
9932740SN/A    DECL_BIN_FNC(mult)
9942740SN/A    DECL_BIN_FNC(div)
9952740SN/A    DECL_BIN_FNC(add)
9962740SN/A    DECL_BIN_FNC(sub)
9972740SN/A
9982740SN/A#undef DECL_BIN_FNC_T
9992740SN/A#undef DECL_BIN_FNC_OTHER
10002740SN/A#undef DECL_BIN_FNC
10012740SN/A
10022740SN/A    friend void lshift(sc_fxval_fast &, const sc_fxnum_fast &, int);
10032740SN/A    friend void rshift(sc_fxval_fast &, const sc_fxnum_fast &, int);
10042740SN/A    friend void lshift(sc_fxnum_fast &, const sc_fxnum_fast &, int);
10052740SN/A    friend void rshift(sc_fxnum_fast &, const sc_fxnum_fast &, int);
10062711SN/A
10072740SN/A    // relational (including equality) operators
10082740SN/A#define DECL_REL_OP_T(op, tp) \
10092740SN/A    friend bool operator op (const sc_fxnum_fast &, tp); \
10102711SN/A    friend bool operator op (tp, const sc_fxnum_fast &);
10112740SN/A
10122740SN/A#define DECL_REL_OP_OTHER(op) \
10137528Ssteve.reinhardt@amd.com    DECL_REL_OP_T(op, int64) \
10142740SN/A    DECL_REL_OP_T(op, uint64) \
10154762Snate@binkert.org    DECL_REL_OP_T(op, const sc_int_base &) \
10162740SN/A    DECL_REL_OP_T(op, const sc_uint_base &) \
10172712SN/A    DECL_REL_OP_T(op, const sc_signed &) \
10188321Ssteve.reinhardt@amd.com    DECL_REL_OP_T(op, const sc_unsigned &)
10198321Ssteve.reinhardt@amd.com
10208321Ssteve.reinhardt@amd.com#define DECL_REL_OP(op) \
10218321Ssteve.reinhardt@amd.com    friend bool operator op (const sc_fxnum_fast &, const sc_fxnum_fast &); \
10228321Ssteve.reinhardt@amd.com    DECL_REL_OP_T(op, int) \
10238321Ssteve.reinhardt@amd.com    DECL_REL_OP_T(op, unsigned int) \
10248321Ssteve.reinhardt@amd.com    DECL_REL_OP_T(op, long) \
10258321Ssteve.reinhardt@amd.com    DECL_REL_OP_T(op, unsigned long) \
10262711SN/A    DECL_REL_OP_T(op, float) \
10277528Ssteve.reinhardt@amd.com    DECL_REL_OP_T(op, double) \
10287528Ssteve.reinhardt@amd.com    DECL_REL_OP_T(op, const char *) \
10292740SN/A    DECL_REL_OP_T(op, const sc_fxval_fast &) \
103010267SGeoffrey.Blake@arm.com    DECL_REL_OP_OTHER(op)
10312740SN/A
10322740SN/A    DECL_REL_OP(<)
10337528Ssteve.reinhardt@amd.com    DECL_REL_OP(<=)
10347528Ssteve.reinhardt@amd.com    DECL_REL_OP(>)
10357528Ssteve.reinhardt@amd.com    DECL_REL_OP(>=)
10367528Ssteve.reinhardt@amd.com    DECL_REL_OP(==)
10372740SN/A    DECL_REL_OP(!=)
10382740SN/A
10393105Sstever@eecs.umich.edu#undef DECL_REL_OP_T
10403105Sstever@eecs.umich.edu#undef DECL_REL_OP_OTHER
10413105Sstever@eecs.umich.edu#undef DECL_REL_OP
10421692SN/A
10431692SN/A    // assignment operators
10441692SN/A#define DECL_ASN_OP_T(op, tp) sc_fxnum_fast &operator op(tp);
1045679SN/A
10462740SN/A#define DECL_ASN_OP_OTHER(op) \
10472740SN/A    DECL_ASN_OP_T(op, int64) \
10482740SN/A    DECL_ASN_OP_T(op, uint64) \
10492740SN/A    DECL_ASN_OP_T(op, const sc_int_base &) \
10502740SN/A    DECL_ASN_OP_T(op, const sc_uint_base &) \
10511692SN/A    DECL_ASN_OP_T(op, const sc_signed &) \
10522740SN/A    DECL_ASN_OP_T(op, const sc_unsigned &)
10532740SN/A
10542740SN/A#define DECL_ASN_OP(op) \
10552740SN/A    DECL_ASN_OP_T(op, int) \
10562740SN/A    DECL_ASN_OP_T(op, unsigned int) \
10572740SN/A    DECL_ASN_OP_T(op, long) \
10582740SN/A    DECL_ASN_OP_T(op, unsigned long) \
10592740SN/A    DECL_ASN_OP_T(op, float) \
10602740SN/A    DECL_ASN_OP_T(op, double) \
10612740SN/A    DECL_ASN_OP_T(op, const char *) \
10622740SN/A    DECL_ASN_OP_T(op, const sc_fxval &) \
10632740SN/A    DECL_ASN_OP_T(op, const sc_fxval_fast &) \
10642740SN/A    DECL_ASN_OP_T(op, const sc_fxnum &) \
10652740SN/A    DECL_ASN_OP_T(op, const sc_fxnum_fast &) \
10662740SN/A    DECL_ASN_OP_OTHER(op)
10671343SN/A
10683105Sstever@eecs.umich.edu    DECL_ASN_OP(=)
10693105Sstever@eecs.umich.edu
10703105Sstever@eecs.umich.edu    DECL_ASN_OP(*=)
10713105Sstever@eecs.umich.edu    DECL_ASN_OP(/=)
10723105Sstever@eecs.umich.edu    DECL_ASN_OP(+=)
10739940SGeoffrey.Blake@arm.com    DECL_ASN_OP(-=)
10743105Sstever@eecs.umich.edu
10753105Sstever@eecs.umich.edu    DECL_ASN_OP_T(<<=, int)
10763105Sstever@eecs.umich.edu    DECL_ASN_OP_T(>>=, int)
10773105Sstever@eecs.umich.edu
10781692SN/A#undef DECL_ASN_OP_T
10792738SN/A#undef DECL_ASN_OP_OTHER
10803105Sstever@eecs.umich.edu#undef DECL_ASN_OP
10812738SN/A
10821692SN/A    // auto-increment and auto-decrement
10831692SN/A    const sc_fxval_fast operator ++ (int);
10841427SN/A    const sc_fxval_fast operator -- (int);
10857528Ssteve.reinhardt@amd.com
10867528Ssteve.reinhardt@amd.com    sc_fxnum_fast &operator ++ ();
10877528Ssteve.reinhardt@amd.com    sc_fxnum_fast &operator -- ();
10887500Ssteve.reinhardt@amd.com
10897500Ssteve.reinhardt@amd.com    // bit selection
10907500Ssteve.reinhardt@amd.com    const sc_fxnum_fast_bitref operator [] (int) const;
10919195SAndreas.Sandberg@arm.com    sc_fxnum_fast_bitref operator [] (int);
10927527Ssteve.reinhardt@amd.com
10937500Ssteve.reinhardt@amd.com    const sc_fxnum_fast_bitref bit(int) const;
10947500Ssteve.reinhardt@amd.com    sc_fxnum_fast_bitref bit(int);
10957500Ssteve.reinhardt@amd.com
109610002Ssteve.reinhardt@amd.com    // part selection
10971692SN/A    const sc_fxnum_fast_subref operator () (int, int) const;
10981427SN/A    sc_fxnum_fast_subref operator () (int, int);
109910002Ssteve.reinhardt@amd.com
110010002Ssteve.reinhardt@amd.com    const sc_fxnum_fast_subref range(int, int) const;
110110002Ssteve.reinhardt@amd.com    sc_fxnum_fast_subref range(int, int);
110210002Ssteve.reinhardt@amd.com
110310002Ssteve.reinhardt@amd.com
110410002Ssteve.reinhardt@amd.com    const sc_fxnum_fast_subref operator () () const;
11051692SN/A    sc_fxnum_fast_subref operator () ();
11061692SN/A
11071692SN/A    const sc_fxnum_fast_subref range() const;
11081692SN/A    sc_fxnum_fast_subref range();
11091692SN/A
11101692SN/A    // implicit conversion
11111692SN/A    operator double() const; // necessary evil!
11121427SN/A
11132738SN/A    // explicit conversion to primitive types
11142738SN/A    short to_short() const;
11153105Sstever@eecs.umich.edu    unsigned short to_ushort() const;
11162738SN/A    int to_int() const;
11172738SN/A    unsigned int to_uint() const;
11183105Sstever@eecs.umich.edu    long to_long() const;
11191692SN/A    unsigned long to_ulong() const;
11201310SN/A    int64 to_int64() const;
112110267SGeoffrey.Blake@arm.com    uint64 to_uint64() const;
11221692SN/A    float to_float() const;
11231587SN/A    double to_double() const;
11241692SN/A
11251692SN/A    // explicit conversion to character string
11261605SN/A    const std::string to_string() const;
11271605SN/A    const std::string to_string(sc_numrep) const;
11287528Ssteve.reinhardt@amd.com    const std::string to_string(sc_numrep, bool) const;
11298321Ssteve.reinhardt@amd.com    const std::string to_string(sc_fmt) const;
11308321Ssteve.reinhardt@amd.com    const std::string to_string(sc_numrep, sc_fmt) const;
11318321Ssteve.reinhardt@amd.com    const std::string to_string(sc_numrep, bool, sc_fmt) const;
113210267SGeoffrey.Blake@arm.com
113310267SGeoffrey.Blake@arm.com    const std::string to_dec() const;
113410267SGeoffrey.Blake@arm.com    const std::string to_bin() const;
113510267SGeoffrey.Blake@arm.com    const std::string to_oct() const;
113610267SGeoffrey.Blake@arm.com    const std::string to_hex() const;
113710267SGeoffrey.Blake@arm.com
113810267SGeoffrey.Blake@arm.com    // query value
11393105Sstever@eecs.umich.edu    bool is_neg() const;
11401310SN/A    bool is_zero() const;
11417528Ssteve.reinhardt@amd.com
11423105Sstever@eecs.umich.edu    // internal use only;
11437528Ssteve.reinhardt@amd.com    bool is_normal() const;
11443105Sstever@eecs.umich.edu
11451693SN/A    bool quantization_flag() const;
11463105Sstever@eecs.umich.edu    bool overflow_flag() const;
11473105Sstever@eecs.umich.edu
11483105Sstever@eecs.umich.edu    const sc_fxval_fast value() const;
11491310SN/A
11501310SN/A    // query parameters
11511692SN/A    int wl() const;
11521692SN/A    int iwl() const;
11531692SN/A    sc_q_mode q_mode() const;
11541692SN/A    sc_o_mode o_mode() const;
11551692SN/A    int n_bits() const;
115610267SGeoffrey.Blake@arm.com
115710267SGeoffrey.Blake@arm.com    const sc_fxtype_params &type_params() const;
115810267SGeoffrey.Blake@arm.com
115910267SGeoffrey.Blake@arm.com    const sc_fxcast_switch &cast_switch() const;
116010267SGeoffrey.Blake@arm.com
116110267SGeoffrey.Blake@arm.com    // print or dump content
116210267SGeoffrey.Blake@arm.com    void print(::std::ostream & =::std::cout) const;
11631310SN/A    void scan(::std::istream & =::std::cin);
11647528Ssteve.reinhardt@amd.com    void dump(::std::ostream & =::std::cout) const;
11657528Ssteve.reinhardt@amd.com
11667528Ssteve.reinhardt@amd.com    // internal use only;
11677528Ssteve.reinhardt@amd.com    void observer_read() const;
11687528Ssteve.reinhardt@amd.com
11697528Ssteve.reinhardt@amd.com    // internal use only;
11707528Ssteve.reinhardt@amd.com    bool get_bit(int) const;
11717528Ssteve.reinhardt@amd.com
11727528Ssteve.reinhardt@amd.com  protected:
11737528Ssteve.reinhardt@amd.com    bool set_bit(int, bool);
11749953Sgeoffrey.blake@arm.com
11759953Sgeoffrey.blake@arm.com    bool get_slice(int, int, sc_bv_base &) const;
11769953Sgeoffrey.blake@arm.com    bool set_slice(int, int, const sc_bv_base &);
11779953Sgeoffrey.blake@arm.com
11789953Sgeoffrey.blake@arm.com    sc_fxnum_fast_observer *lock_observer() const;
11797528Ssteve.reinhardt@amd.com    void unlock_observer(sc_fxnum_fast_observer *) const;
11807528Ssteve.reinhardt@amd.com
11817528Ssteve.reinhardt@amd.com  private:
11827528Ssteve.reinhardt@amd.com    double m_val;
11838321Ssteve.reinhardt@amd.com
11848321Ssteve.reinhardt@amd.com    scfx_params m_params;
11858321Ssteve.reinhardt@amd.com    bool m_q_flag;
11867528Ssteve.reinhardt@amd.com    bool m_o_flag;
11877742Sgblack@eecs.umich.edu
11887742Sgblack@eecs.umich.edu    mutable sc_fxnum_fast_observer *m_observer;
11891693SN/A
11901693SN/A  private:
11917528Ssteve.reinhardt@amd.com    // Disabled
11921693SN/A    sc_fxnum_fast();
11931693SN/A    sc_fxnum_fast(const sc_fxnum_fast &);
11947528Ssteve.reinhardt@amd.com};
11957528Ssteve.reinhardt@amd.com
11967528Ssteve.reinhardt@amd.com
11978321Ssteve.reinhardt@amd.com// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
11989528Ssascha.bischoff@arm.com
11999528Ssascha.bischoff@arm.com// ----------------------------------------------------------------------------
12007528Ssteve.reinhardt@amd.com// CLASS : sc_fxnum_bitref
12017742Sgblack@eecs.umich.edu//
12027742Sgblack@eecs.umich.edu// Proxy class for bit-selection in class sc_fxnum, behaves like sc_bit.
12037742Sgblack@eecs.umich.edu// ----------------------------------------------------------------------------
12047742Sgblack@eecs.umich.edu
12057738Sgblack@eecs.umich.edu// constructor
12067528Ssteve.reinhardt@amd.com
12077528Ssteve.reinhardt@amd.cominline
12081310SN/Asc_fxnum_bitref::sc_fxnum_bitref(sc_fxnum &num_, int idx_) :
12097528Ssteve.reinhardt@amd.com        m_num(num_), m_idx(idx_)
12107528Ssteve.reinhardt@amd.com{}
12117528Ssteve.reinhardt@amd.com
12127528Ssteve.reinhardt@amd.com// copy constructor
12137528Ssteve.reinhardt@amd.cominline sc_fxnum_bitref::sc_fxnum_bitref(const sc_fxnum_bitref &a) :
12147528Ssteve.reinhardt@amd.com        m_num(a.m_num), m_idx(a.m_idx)
12157528Ssteve.reinhardt@amd.com{}
12167528Ssteve.reinhardt@amd.com
12177528Ssteve.reinhardt@amd.com// assignment operators
12188321Ssteve.reinhardt@amd.cominline sc_fxnum_bitref &
12197528Ssteve.reinhardt@amd.comsc_fxnum_bitref::operator = (const sc_fxnum_bitref &a)
12207528Ssteve.reinhardt@amd.com{
12218321Ssteve.reinhardt@amd.com    if (&a != this) {
12229528Ssascha.bischoff@arm.com        SC_FXNUM_OBSERVER_READ_(a.m_num)
12237528Ssteve.reinhardt@amd.com        set(a.get());
12243105Sstever@eecs.umich.edu        SC_FXNUM_OBSERVER_WRITE_(m_num)
12251692SN/A    }
12262740SN/A    return *this;
12278321Ssteve.reinhardt@amd.com}
12281692SN/A
12291692SN/Ainline sc_fxnum_bitref &
12301692SN/Asc_fxnum_bitref::operator = (const sc_fxnum_fast_bitref &a)
12311692SN/A{
12321310SN/A    SC_FXNUM_FAST_OBSERVER_READ_(a.m_num)
12331692SN/A    set(a.get());
12341692SN/A    SC_FXNUM_OBSERVER_WRITE_(m_num)
12351310SN/A    return *this;
123610380SAndrew.Bardsley@arm.com}
123710380SAndrew.Bardsley@arm.com
123810380SAndrew.Bardsley@arm.cominline sc_fxnum_bitref &
12391692SN/Asc_fxnum_bitref::operator = (const sc_bit &a)
12401692SN/A{
12411310SN/A    set(static_cast<bool>(a));
12421692SN/A    SC_FXNUM_OBSERVER_WRITE_(m_num)
12431692SN/A    return *this;
12441692SN/A}
12451310SN/A
12461692SN/Ainline sc_fxnum_bitref &
12471692SN/Asc_fxnum_bitref::operator = (bool a)
124810195SGeoffrey.Blake@arm.com{
124910195SGeoffrey.Blake@arm.com    set(a);
125010195SGeoffrey.Blake@arm.com    SC_FXNUM_OBSERVER_WRITE_(m_num)
125110195SGeoffrey.Blake@arm.com    return *this;
125210195SGeoffrey.Blake@arm.com}
12531692SN/A
12541692SN/Ainline sc_fxnum_bitref &
12551692SN/Asc_fxnum_bitref::operator &= (const sc_fxnum_bitref &b)
12561814SN/A{
12571692SN/A    SC_FXNUM_OBSERVER_READ_(m_num)
12581692SN/A    SC_FXNUM_OBSERVER_READ_(b.m_num)
12591692SN/A    set(get() && b.get());
12601692SN/A    SC_FXNUM_OBSERVER_WRITE_(m_num)
12611692SN/A    return *this;
12621692SN/A}
12631692SN/A
12645952Ssaidi@eecs.umich.eduinline sc_fxnum_bitref &
12651692SN/Asc_fxnum_bitref::operator &= (const sc_fxnum_fast_bitref &b)
12661692SN/A{
12671692SN/A    SC_FXNUM_OBSERVER_READ_(m_num)
12688459SAli.Saidi@ARM.com    SC_FXNUM_FAST_OBSERVER_READ_(b.m_num)
12698459SAli.Saidi@ARM.com    set(get() && b.get());
12708459SAli.Saidi@ARM.com    SC_FXNUM_OBSERVER_WRITE_(m_num)
12718459SAli.Saidi@ARM.com    return *this;
12729410Sandreas.hansson@arm.com}
12739410Sandreas.hansson@arm.com
12749410Sandreas.hansson@arm.cominline sc_fxnum_bitref &
12759410Sandreas.hansson@arm.comsc_fxnum_bitref::operator &= (const sc_bit &b)
12769410Sandreas.hansson@arm.com{
12779410Sandreas.hansson@arm.com    SC_FXNUM_OBSERVER_READ_(m_num)
12789410Sandreas.hansson@arm.com    set(get() && static_cast<bool>(b));
12799410Sandreas.hansson@arm.com    SC_FXNUM_OBSERVER_WRITE_(m_num)
12809410Sandreas.hansson@arm.com    return *this;
12819410Sandreas.hansson@arm.com}
12829410Sandreas.hansson@arm.com
12839410Sandreas.hansson@arm.cominline sc_fxnum_bitref &
12849410Sandreas.hansson@arm.comsc_fxnum_bitref::operator &= (bool b)
12859410Sandreas.hansson@arm.com{
12868459SAli.Saidi@ARM.com    SC_FXNUM_OBSERVER_READ_(m_num)
12878459SAli.Saidi@ARM.com    set(get() && b);
12888459SAli.Saidi@ARM.com    SC_FXNUM_OBSERVER_WRITE_(m_num)
12898459SAli.Saidi@ARM.com    return *this;
12908459SAli.Saidi@ARM.com}
12918459SAli.Saidi@ARM.com
12928459SAli.Saidi@ARM.com
12938459SAli.Saidi@ARM.cominline sc_fxnum_bitref &
12941815SN/Asc_fxnum_bitref::operator |= (const sc_fxnum_bitref &b)
12951815SN/A{
12961815SN/A    SC_FXNUM_OBSERVER_READ_(m_num)
12977527Ssteve.reinhardt@amd.com    SC_FXNUM_OBSERVER_READ_(b.m_num)
12983105Sstever@eecs.umich.edu    set(get() || b.get());
12993105Sstever@eecs.umich.edu    SC_FXNUM_OBSERVER_WRITE_(m_num)
13006654Snate@binkert.org    return *this;
13013105Sstever@eecs.umich.edu}
13023105Sstever@eecs.umich.edu
13033105Sstever@eecs.umich.eduinline sc_fxnum_bitref &
13043105Sstever@eecs.umich.edusc_fxnum_bitref::operator |= (const sc_fxnum_fast_bitref &b)
13053105Sstever@eecs.umich.edu{
13063105Sstever@eecs.umich.edu    SC_FXNUM_OBSERVER_READ_(m_num)
13073105Sstever@eecs.umich.edu    SC_FXNUM_FAST_OBSERVER_READ_(b.m_num)
13083105Sstever@eecs.umich.edu    set(get() || b.get());
13093107Sstever@eecs.umich.edu    SC_FXNUM_OBSERVER_WRITE_(m_num)
13103107Sstever@eecs.umich.edu    return *this;
13113107Sstever@eecs.umich.edu}
13123107Sstever@eecs.umich.edu
13133107Sstever@eecs.umich.eduinline sc_fxnum_bitref &
13143105Sstever@eecs.umich.edusc_fxnum_bitref::operator |= (const sc_bit &b)
13153105Sstever@eecs.umich.edu{
13163105Sstever@eecs.umich.edu    SC_FXNUM_OBSERVER_READ_(m_num)
13173105Sstever@eecs.umich.edu    set(get() || static_cast<bool>(b));
13185037Smilesck@eecs.umich.edu    SC_FXNUM_OBSERVER_WRITE_(m_num)
13195543Ssaidi@eecs.umich.edu    return *this;
13201692SN/A}
13212738SN/A
13222738SN/Ainline sc_fxnum_bitref &
13234081Sbinkertn@umich.edusc_fxnum_bitref::operator |= (bool b)
13245037Smilesck@eecs.umich.edu{
13251692SN/A    SC_FXNUM_OBSERVER_READ_(m_num)
13268664SAli.Saidi@ARM.com    set(get() || b);
13277528Ssteve.reinhardt@amd.com    SC_FXNUM_OBSERVER_WRITE_(m_num)
13288664SAli.Saidi@ARM.com    return *this;
13298664SAli.Saidi@ARM.com}
13301692SN/A
13318664SAli.Saidi@ARM.com
13323105Sstever@eecs.umich.eduinline sc_fxnum_bitref &
13331692SN/Asc_fxnum_bitref::operator ^= (const sc_fxnum_bitref &b)
13345037Smilesck@eecs.umich.edu{
13355037Smilesck@eecs.umich.edu    SC_FXNUM_OBSERVER_READ_(m_num)
13361692SN/A    SC_FXNUM_OBSERVER_READ_(b.m_num)
13378664SAli.Saidi@ARM.com    set(get() != b.get());
13383105Sstever@eecs.umich.edu    SC_FXNUM_OBSERVER_WRITE_(m_num)
13393105Sstever@eecs.umich.edu    return *this;
13405037Smilesck@eecs.umich.edu}
13413103Sstever@eecs.umich.edu
13425543Ssaidi@eecs.umich.eduinline sc_fxnum_bitref &
13431692SN/Asc_fxnum_bitref::operator ^= (const sc_fxnum_fast_bitref &b)
13448664SAli.Saidi@ARM.com{
13458664SAli.Saidi@ARM.com    SC_FXNUM_OBSERVER_READ_(m_num)
13468664SAli.Saidi@ARM.com    SC_FXNUM_FAST_OBSERVER_READ_(b.m_num)
13478664SAli.Saidi@ARM.com    set(get() != b.get());
13488664SAli.Saidi@ARM.com    SC_FXNUM_OBSERVER_WRITE_(m_num)
13498664SAli.Saidi@ARM.com    return *this;
13508664SAli.Saidi@ARM.com}
13518664SAli.Saidi@ARM.com
13528664SAli.Saidi@ARM.cominline sc_fxnum_bitref &
13539017Sandreas.hansson@arm.comsc_fxnum_bitref::operator ^= (const sc_bit &b)
13549017Sandreas.hansson@arm.com{
13559017Sandreas.hansson@arm.com    SC_FXNUM_OBSERVER_READ_(m_num)
13569017Sandreas.hansson@arm.com    set(get() != static_cast<bool>(b));
13578664SAli.Saidi@ARM.com    SC_FXNUM_OBSERVER_WRITE_(m_num)
13588664SAli.Saidi@ARM.com    return *this;
13598664SAli.Saidi@ARM.com}
13608848Ssteve.reinhardt@amd.com
136110380SAndrew.Bardsley@arm.cominline sc_fxnum_bitref &
13628664SAli.Saidi@ARM.comsc_fxnum_bitref::operator ^= (bool b)
13638664SAli.Saidi@ARM.com{
13649017Sandreas.hansson@arm.com    SC_FXNUM_OBSERVER_READ_(m_num)
13659017Sandreas.hansson@arm.com    set(get() != b);
13669017Sandreas.hansson@arm.com    SC_FXNUM_OBSERVER_WRITE_(m_num)
13679017Sandreas.hansson@arm.com    return *this;
13689017Sandreas.hansson@arm.com}
13698664SAli.Saidi@ARM.com
13708664SAli.Saidi@ARM.com// implicit conversion
13718664SAli.Saidi@ARM.cominline sc_fxnum_bitref::operator bool() const
13728664SAli.Saidi@ARM.com{
13739017Sandreas.hansson@arm.com    SC_FXNUM_OBSERVER_READ_(m_num)
13749017Sandreas.hansson@arm.com    return get();
13759017Sandreas.hansson@arm.com}
13768664SAli.Saidi@ARM.com
13778664SAli.Saidi@ARM.cominline ::std::ostream &
13788664SAli.Saidi@ARM.comoperator << (::std::ostream &os, const sc_fxnum_bitref &a)
13794762Snate@binkert.org{
13804762Snate@binkert.org    a.print(os);
13814762Snate@binkert.org    return os;
13824762Snate@binkert.org}
13837677Snate@binkert.org
13844762Snate@binkert.orginline ::std::istream &
13855488Snate@binkert.orgoperator >> (::std::istream &is, sc_fxnum_bitref &a)
13864762Snate@binkert.org{
13874762Snate@binkert.org    a.scan(is);
13884762Snate@binkert.org    return is;
13894762Snate@binkert.org}
13904762Snate@binkert.org
13914762Snate@binkert.org
13924762Snate@binkert.org// ----------------------------------------------------------------------------
13936654Snate@binkert.org// CLASS : sc_fxnum_fast_bitref
13946654Snate@binkert.org//
13954762Snate@binkert.org// Proxy class for bit-selection in class sc_fxnum_fast, behaves like sc_bit.
13964762Snate@binkert.org// ----------------------------------------------------------------------------
13974762Snate@binkert.org
13984762Snate@binkert.org// constructor
13994762Snate@binkert.orginline sc_fxnum_fast_bitref::sc_fxnum_fast_bitref(
14004762Snate@binkert.org        sc_fxnum_fast &num_, int idx_) : m_num(num_), m_idx(idx_)
14014762Snate@binkert.org{}
14024762Snate@binkert.org
14034762Snate@binkert.org// copy constructor
14044762Snate@binkert.orginline sc_fxnum_fast_bitref::sc_fxnum_fast_bitref(
14054762Snate@binkert.org        const sc_fxnum_fast_bitref &a) : m_num(a.m_num), m_idx(a.m_idx)
14064762Snate@binkert.org{}
14074762Snate@binkert.org
14084762Snate@binkert.org// assignment operators
14094762Snate@binkert.orginline sc_fxnum_fast_bitref &
14108912Sandreas.hansson@arm.comsc_fxnum_fast_bitref::operator = (const sc_fxnum_bitref &a)
14118912Sandreas.hansson@arm.com{
14128912Sandreas.hansson@arm.com    SC_FXNUM_OBSERVER_READ_(a.m_num)
14138912Sandreas.hansson@arm.com    set(a.get());
14148900Sandreas.hansson@arm.com    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
14158912Sandreas.hansson@arm.com    return *this;
14164762Snate@binkert.org}
14174762Snate@binkert.org
14182738SN/Ainline sc_fxnum_fast_bitref &
14192740SN/Asc_fxnum_fast_bitref::operator = (const sc_fxnum_fast_bitref &a)
14202740SN/A{
14212740SN/A    if (&a != this) {
14222740SN/A        SC_FXNUM_FAST_OBSERVER_READ_(a.m_num)
14232740SN/A        set(a.get());
14247526Ssteve.reinhardt@amd.com        SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
14257526Ssteve.reinhardt@amd.com    }
14267526Ssteve.reinhardt@amd.com    return *this;
14277526Ssteve.reinhardt@amd.com}
14285244Sgblack@eecs.umich.edu
14295244Sgblack@eecs.umich.eduinline sc_fxnum_fast_bitref &
143010267SGeoffrey.Blake@arm.comsc_fxnum_fast_bitref::operator = (const sc_bit &a)
143110267SGeoffrey.Blake@arm.com{
143210267SGeoffrey.Blake@arm.com    set(static_cast<bool>(a));
14332740SN/A    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
14347526Ssteve.reinhardt@amd.com    return *this;
14352740SN/A}
14362740SN/A
14372740SN/Ainline sc_fxnum_fast_bitref &
14387527Ssteve.reinhardt@amd.comsc_fxnum_fast_bitref::operator = (bool a)
14397527Ssteve.reinhardt@amd.com{
14407527Ssteve.reinhardt@amd.com    set(a);
14417527Ssteve.reinhardt@amd.com    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
14427527Ssteve.reinhardt@amd.com    return *this;
14437527Ssteve.reinhardt@amd.com}
14447527Ssteve.reinhardt@amd.com
14454762Snate@binkert.org
14464762Snate@binkert.orginline sc_fxnum_fast_bitref &
14474762Snate@binkert.orgsc_fxnum_fast_bitref::operator &= (const sc_fxnum_bitref &b)
14484762Snate@binkert.org{
14494762Snate@binkert.org    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
14504762Snate@binkert.org    SC_FXNUM_OBSERVER_READ_(b.m_num)
14514762Snate@binkert.org    set(get() && b.get());
14522738SN/A    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
14537527Ssteve.reinhardt@amd.com    return *this;
14542738SN/A}
14553105Sstever@eecs.umich.edu
14563105Sstever@eecs.umich.eduinline sc_fxnum_fast_bitref &
14572797SN/Asc_fxnum_fast_bitref::operator &= (const sc_fxnum_fast_bitref &b)
14583101Sstever@eecs.umich.edu{
14593101Sstever@eecs.umich.edu    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
14603101Sstever@eecs.umich.edu    SC_FXNUM_FAST_OBSERVER_READ_(b.m_num)
14613101Sstever@eecs.umich.edu    set(get() && b.get());
1462679SN/A    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
14636654Snate@binkert.org    return *this;
14646654Snate@binkert.org}
14656654Snate@binkert.org
14666654Snate@binkert.orginline sc_fxnum_fast_bitref &
14676654Snate@binkert.orgsc_fxnum_fast_bitref::operator &= (const sc_bit &b)
14686654Snate@binkert.org{
14697528Ssteve.reinhardt@amd.com    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
14707528Ssteve.reinhardt@amd.com    set(get() && static_cast<bool>(b));
14717528Ssteve.reinhardt@amd.com    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
14726654Snate@binkert.org    return *this;
14736654Snate@binkert.org}
14746654Snate@binkert.org
14756654Snate@binkert.orginline sc_fxnum_fast_bitref &
14766654Snate@binkert.orgsc_fxnum_fast_bitref::operator &= (bool b)
14776654Snate@binkert.org{
14786654Snate@binkert.org    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
14796654Snate@binkert.org    set(get() && b);
14806654Snate@binkert.org    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
14816654Snate@binkert.org    return *this;
14826654Snate@binkert.org}
14836654Snate@binkert.org
14846654Snate@binkert.org
14857526Ssteve.reinhardt@amd.cominline sc_fxnum_fast_bitref &
14867526Ssteve.reinhardt@amd.comsc_fxnum_fast_bitref::operator |= (const sc_fxnum_bitref &b)
14877526Ssteve.reinhardt@amd.com{
14887526Ssteve.reinhardt@amd.com    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
14897528Ssteve.reinhardt@amd.com    SC_FXNUM_OBSERVER_READ_(b.m_num)
14907528Ssteve.reinhardt@amd.com    set(get() || b.get());
14917528Ssteve.reinhardt@amd.com    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
14927528Ssteve.reinhardt@amd.com    return *this;
14937528Ssteve.reinhardt@amd.com}
14947528Ssteve.reinhardt@amd.com
14957528Ssteve.reinhardt@amd.cominline sc_fxnum_fast_bitref &
14967528Ssteve.reinhardt@amd.comsc_fxnum_fast_bitref::operator |= (const sc_fxnum_fast_bitref &b)
14977528Ssteve.reinhardt@amd.com{
14987528Ssteve.reinhardt@amd.com    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
14997528Ssteve.reinhardt@amd.com    SC_FXNUM_FAST_OBSERVER_READ_(b.m_num)
15007528Ssteve.reinhardt@amd.com    set(get() || b.get());
15017528Ssteve.reinhardt@amd.com    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
15027528Ssteve.reinhardt@amd.com    return *this;
15037528Ssteve.reinhardt@amd.com}
15047528Ssteve.reinhardt@amd.com
15056654Snate@binkert.orginline sc_fxnum_fast_bitref &
15066654Snate@binkert.orgsc_fxnum_fast_bitref::operator |= (const sc_bit &b)
15076654Snate@binkert.org{
15086654Snate@binkert.org    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
15099338SAndreas.Sandberg@arm.com    set(get() || static_cast<bool>(b));
15106654Snate@binkert.org    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
15116654Snate@binkert.org    return *this;
15126654Snate@binkert.org}
15139338SAndreas.Sandberg@arm.com
15146654Snate@binkert.orginline sc_fxnum_fast_bitref &
15151528SN/Asc_fxnum_fast_bitref::operator |= (bool b)
15161528SN/A{
15171528SN/A    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
15184762Snate@binkert.org    set(get() || b);
1519    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1520    return *this;
1521}
1522
1523
1524inline sc_fxnum_fast_bitref &
1525sc_fxnum_fast_bitref::operator ^= (const sc_fxnum_bitref &b)
1526{
1527    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1528    SC_FXNUM_OBSERVER_READ_(b.m_num)
1529    set(get() != b.get());
1530    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1531    return *this;
1532}
1533
1534inline sc_fxnum_fast_bitref &
1535sc_fxnum_fast_bitref::operator ^= (const sc_fxnum_fast_bitref &b)
1536{
1537    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1538    SC_FXNUM_FAST_OBSERVER_READ_(b.m_num)
1539    set(get() != b.get());
1540    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1541    return *this;
1542}
1543
1544inline sc_fxnum_fast_bitref &
1545sc_fxnum_fast_bitref::operator ^= (const sc_bit &b)
1546{
1547    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1548    set(get() != static_cast<bool>(b));
1549    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1550    return *this;
1551}
1552
1553inline sc_fxnum_fast_bitref &
1554sc_fxnum_fast_bitref::operator ^= (bool b)
1555{
1556    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1557    set(get() != b);
1558    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1559    return *this;
1560}
1561
1562
1563// implicit conversion
1564inline sc_fxnum_fast_bitref::operator bool() const
1565{
1566    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1567    return get();
1568}
1569
1570inline ::std::ostream &
1571operator << (::std::ostream &os, const sc_fxnum_fast_bitref &a)
1572{
1573    a.print(os);
1574    return os;
1575}
1576
1577inline ::std::istream &
1578operator >> (::std::istream &is, sc_fxnum_fast_bitref &a)
1579{
1580    a.scan(is);
1581    return is;
1582}
1583
1584
1585// ----------------------------------------------------------------------------
1586// CLASS : sc_fxnum_subref
1587//
1588// Proxy class for part-selection in class sc_fxnum,
1589// behaves like sc_bv_base.
1590// ----------------------------------------------------------------------------
1591
1592// constructor
1593inline sc_fxnum_subref::sc_fxnum_subref(sc_fxnum &num_, int from_, int to_) :
1594        m_num(num_), m_from(from_), m_to(to_),
1595        m_bv(*new sc_bv_base(sc_max(m_from, m_to) - sc_min(m_from, m_to) + 1))
1596{}
1597
1598// copy constructor
1599inline sc_fxnum_subref::sc_fxnum_subref(const sc_fxnum_subref &a) :
1600        m_num(a.m_num), m_from(a.m_from), m_to(a.m_to),
1601        m_bv(*new sc_bv_base(a.m_bv))
1602{}
1603
1604// destructor
1605inline sc_fxnum_subref::~sc_fxnum_subref()
1606{
1607    delete &m_bv;
1608}
1609
1610// assignment operators
1611inline sc_fxnum_subref &
1612sc_fxnum_subref::operator = (const sc_fxnum_subref &a)
1613{
1614    if (&a != this) {
1615        m_bv = static_cast<sc_bv_base>(a);
1616        set();
1617        SC_FXNUM_OBSERVER_WRITE_(m_num)
1618    }
1619    return *this;
1620}
1621
1622inline sc_fxnum_subref &
1623sc_fxnum_subref::operator = (const sc_fxnum_fast_subref &a)
1624{
1625    m_bv = static_cast<sc_bv_base>(a);
1626    set();
1627    SC_FXNUM_OBSERVER_WRITE_(m_num)
1628    return *this;
1629}
1630
1631#define DEFN_ASN_OP_T(tp) \
1632inline sc_fxnum_subref & \
1633sc_fxnum_subref::operator = (tp a) \
1634{ \
1635    m_bv = a; \
1636    set(); \
1637    SC_FXNUM_OBSERVER_WRITE_(m_num) \
1638    return *this; \
1639}
1640
1641DEFN_ASN_OP_T(const sc_bv_base &)
1642DEFN_ASN_OP_T(const sc_lv_base &)
1643DEFN_ASN_OP_T(const char *)
1644DEFN_ASN_OP_T(const bool *)
1645DEFN_ASN_OP_T(const sc_signed &)
1646DEFN_ASN_OP_T(const sc_unsigned &)
1647DEFN_ASN_OP_T(const sc_int_base &)
1648DEFN_ASN_OP_T(const sc_uint_base &)
1649DEFN_ASN_OP_T(int64)
1650DEFN_ASN_OP_T(uint64)
1651DEFN_ASN_OP_T(int)
1652DEFN_ASN_OP_T(unsigned int)
1653DEFN_ASN_OP_T(long)
1654DEFN_ASN_OP_T(unsigned long)
1655DEFN_ASN_OP_T(char)
1656
1657#undef DEFN_ASN_OP_T
1658
1659#define DEFN_ASN_OP_T(op, tp) \
1660inline sc_fxnum_subref & \
1661sc_fxnum_subref::operator op ## = (tp a) \
1662{ \
1663    SC_FXNUM_OBSERVER_READ_(m_num) \
1664    get(); \
1665    m_bv = m_bv op a; \
1666    set(); \
1667    SC_FXNUM_OBSERVER_WRITE_(m_num) \
1668    return *this; \
1669}
1670
1671#define DEFN_ASN_OP(op) \
1672inline sc_fxnum_subref & \
1673sc_fxnum_subref::operator op ## = (const sc_fxnum_subref &a) \
1674{ \
1675    SC_FXNUM_OBSERVER_READ_(m_num) \
1676    get(); \
1677    m_bv = m_bv op static_cast<sc_bv_base>(a); \
1678    set(); \
1679    SC_FXNUM_OBSERVER_WRITE_(m_num) \
1680    return *this; \
1681} \
1682 \
1683inline sc_fxnum_subref & \
1684sc_fxnum_subref::operator op ## = (const sc_fxnum_fast_subref &a) \
1685{ \
1686    SC_FXNUM_OBSERVER_READ_(m_num) \
1687    get(); \
1688    m_bv = m_bv op static_cast<sc_bv_base>(a); \
1689    set(); \
1690    SC_FXNUM_OBSERVER_WRITE_(m_num) \
1691    return *this; \
1692} \
1693 \
1694DEFN_ASN_OP_T(op, const sc_bv_base &) \
1695DEFN_ASN_OP_T(op, const sc_lv_base &)
1696
1697DEFN_ASN_OP( &)
1698DEFN_ASN_OP(|)
1699DEFN_ASN_OP(^)
1700
1701#undef DEFN_ASN_OP_T
1702#undef DEFN_ASN_OP
1703
1704// relational operators
1705#define DEFN_REL_OP_T(op, tp) \
1706inline bool \
1707operator op (const sc_fxnum_subref &a, tp b) \
1708{ \
1709    return (static_cast<sc_bv_base>(a) op b); \
1710} \
1711 \
1712inline bool \
1713operator op (tp a, const sc_fxnum_subref &b) \
1714{ \
1715    return (static_cast<sc_bv_base>(b) op a); \
1716}
1717
1718#define DEFN_REL_OP(op) \
1719inline bool \
1720operator op (const sc_fxnum_subref &a, const sc_fxnum_subref &b) \
1721{ \
1722    return (static_cast<sc_bv_base>(a) op static_cast<sc_bv_base>(b)); \
1723} \
1724 \
1725inline bool \
1726operator op (const sc_fxnum_subref &a, const sc_fxnum_fast_subref &b) \
1727{ \
1728    return (static_cast<sc_bv_base>(a) op static_cast<sc_bv_base>(b)); \
1729} \
1730 \
1731DEFN_REL_OP_T(op, const sc_bv_base &) \
1732DEFN_REL_OP_T(op, const sc_lv_base &) \
1733DEFN_REL_OP_T(op, const char *) \
1734DEFN_REL_OP_T(op, const bool *) \
1735DEFN_REL_OP_T(op, const sc_signed &) \
1736DEFN_REL_OP_T(op, const sc_unsigned &) \
1737DEFN_REL_OP_T(op, int) \
1738DEFN_REL_OP_T(op, unsigned int) \
1739DEFN_REL_OP_T(op, long) \
1740DEFN_REL_OP_T(op, unsigned long)
1741
1742DEFN_REL_OP(==)
1743DEFN_REL_OP(!=)
1744
1745#undef DEFN_REL_OP_T
1746#undef DEFN_REL_OP
1747
1748
1749// reduce functions
1750
1751#define DEFN_RED_FNC(fnc) \
1752inline bool \
1753sc_fxnum_subref::fnc() const \
1754{ \
1755    SC_FXNUM_OBSERVER_READ_(m_num) \
1756    get(); \
1757    return static_cast<bool>(m_bv.fnc()); \
1758}
1759
1760DEFN_RED_FNC(and_reduce)
1761DEFN_RED_FNC(nand_reduce)
1762DEFN_RED_FNC(or_reduce)
1763DEFN_RED_FNC(nor_reduce)
1764DEFN_RED_FNC(xor_reduce)
1765DEFN_RED_FNC(xnor_reduce)
1766
1767#undef DEFN_RED_FNC
1768
1769// query parameter
1770inline int
1771sc_fxnum_subref::length() const
1772{
1773    return m_bv.length();
1774}
1775
1776// explicit conversions
1777inline int
1778sc_fxnum_subref::to_int() const
1779{
1780    SC_FXNUM_OBSERVER_READ_(m_num)
1781    get();
1782    return m_bv.to_int();
1783}
1784
1785inline int64
1786sc_fxnum_subref::to_int64() const
1787{
1788    SC_FXNUM_OBSERVER_READ_(m_num)
1789    get();
1790    return m_bv.to_int64();
1791}
1792
1793inline unsigned int
1794sc_fxnum_subref::to_uint() const
1795{
1796    SC_FXNUM_OBSERVER_READ_(m_num)
1797    get();
1798    return m_bv.to_uint();
1799}
1800
1801inline uint64
1802sc_fxnum_subref::to_uint64() const
1803{
1804    SC_FXNUM_OBSERVER_READ_(m_num)
1805    get();
1806    return m_bv.to_uint64();
1807}
1808
1809inline long
1810sc_fxnum_subref::to_long() const
1811{
1812    SC_FXNUM_OBSERVER_READ_(m_num)
1813    get();
1814    return m_bv.to_long();
1815}
1816
1817inline unsigned long
1818sc_fxnum_subref::to_ulong() const
1819{
1820    SC_FXNUM_OBSERVER_READ_(m_num)
1821    get();
1822    return m_bv.to_ulong();
1823}
1824
1825
1826inline const std::string
1827sc_fxnum_subref::to_string() const
1828{
1829    get();
1830    return m_bv.to_string();
1831}
1832
1833inline const std::string
1834sc_fxnum_subref::to_string(sc_numrep numrep) const
1835{
1836    get();
1837    return m_bv.to_string(numrep);
1838}
1839
1840inline const std::string
1841sc_fxnum_subref::to_string(sc_numrep numrep, bool w_prefix) const
1842{
1843    get();
1844    return m_bv.to_string(numrep, w_prefix);
1845}
1846
1847
1848// implicit conversion
1849inline sc_fxnum_subref::operator sc_bv_base () const
1850{
1851    SC_FXNUM_OBSERVER_READ_(m_num)
1852    get();
1853    return m_bv;
1854}
1855
1856
1857inline ::std::ostream &
1858operator << (::std::ostream &os, const sc_fxnum_subref &a)
1859{
1860    a.print(os);
1861    return os;
1862}
1863
1864inline ::std::istream &
1865operator >> (::std::istream &is, sc_fxnum_subref &a)
1866{
1867    a.scan(is);
1868    return is;
1869}
1870
1871
1872// ----------------------------------------------------------------------------
1873// CLASS : sc_fxnum_fast_subref
1874//
1875// Proxy class for part-selection in class sc_fxnum_fast,
1876// behaves like sc_bv_base.
1877// ----------------------------------------------------------------------------
1878
1879// constructor
1880
1881inline sc_fxnum_fast_subref::sc_fxnum_fast_subref(
1882        sc_fxnum_fast &num_, int from_, int to_) :
1883    m_num(num_), m_from(from_), m_to(to_),
1884    m_bv(*new sc_bv_base(sc_max(m_from, m_to) - sc_min(m_from, m_to) + 1))
1885{}
1886
1887
1888// copy constructor
1889inline sc_fxnum_fast_subref::sc_fxnum_fast_subref(
1890        const sc_fxnum_fast_subref &a) :
1891    m_num(a.m_num), m_from(a.m_from), m_to(a.m_to),
1892    m_bv(*new sc_bv_base(a.m_bv))
1893{}
1894
1895
1896// destructor
1897inline sc_fxnum_fast_subref::~sc_fxnum_fast_subref()
1898{
1899    delete &m_bv;
1900}
1901
1902
1903// assignment operators
1904inline sc_fxnum_fast_subref &
1905sc_fxnum_fast_subref::operator = (const sc_fxnum_subref &a)
1906{
1907    m_bv = static_cast<sc_bv_base>(a);
1908    set();
1909    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1910    return *this;
1911}
1912
1913inline sc_fxnum_fast_subref &
1914sc_fxnum_fast_subref::operator = (const sc_fxnum_fast_subref &a)
1915{
1916    if (&a != this) {
1917        m_bv = static_cast<sc_bv_base>(a);
1918        set();
1919        SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1920    }
1921    return *this;
1922}
1923
1924#define DEFN_ASN_OP_T(tp) \
1925inline sc_fxnum_fast_subref & \
1926sc_fxnum_fast_subref::operator = (tp a) \
1927{ \
1928    m_bv = a; \
1929    set(); \
1930    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num) \
1931    return *this; \
1932}
1933
1934DEFN_ASN_OP_T(const sc_bv_base &)
1935DEFN_ASN_OP_T(const sc_lv_base &)
1936DEFN_ASN_OP_T(const char *)
1937DEFN_ASN_OP_T(const bool *)
1938DEFN_ASN_OP_T(const sc_signed &)
1939DEFN_ASN_OP_T(const sc_unsigned &)
1940DEFN_ASN_OP_T(const sc_int_base &)
1941DEFN_ASN_OP_T(const sc_uint_base &)
1942DEFN_ASN_OP_T(int64)
1943DEFN_ASN_OP_T(uint64)
1944DEFN_ASN_OP_T(int)
1945DEFN_ASN_OP_T(unsigned int)
1946DEFN_ASN_OP_T(long)
1947DEFN_ASN_OP_T(unsigned long)
1948DEFN_ASN_OP_T(char)
1949
1950#undef DEFN_ASN_OP_T
1951
1952
1953#define DEFN_ASN_OP_T(op, tp) \
1954inline sc_fxnum_fast_subref & \
1955sc_fxnum_fast_subref::operator op ## = (tp a) \
1956{ \
1957    SC_FXNUM_FAST_OBSERVER_READ_(m_num) \
1958    get(); \
1959    m_bv = m_bv op a; \
1960    set(); \
1961    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num) \
1962    return *this; \
1963}
1964
1965#define DEFN_ASN_OP(op) \
1966inline sc_fxnum_fast_subref & \
1967sc_fxnum_fast_subref::operator op ## = (const sc_fxnum_subref &a) \
1968{ \
1969    SC_FXNUM_FAST_OBSERVER_READ_(m_num) \
1970    get(); \
1971    m_bv = m_bv op static_cast<sc_bv_base>(a); \
1972    set(); \
1973    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num) \
1974    return *this; \
1975} \
1976 \
1977inline sc_fxnum_fast_subref & \
1978sc_fxnum_fast_subref::operator op ## = (const sc_fxnum_fast_subref &a) \
1979{ \
1980    SC_FXNUM_FAST_OBSERVER_READ_(m_num) \
1981    get(); \
1982    m_bv = m_bv op static_cast<sc_bv_base>(a); \
1983    set(); \
1984    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num) \
1985    return *this; \
1986} \
1987 \
1988DEFN_ASN_OP_T(op, const sc_bv_base &) \
1989DEFN_ASN_OP_T(op, const sc_lv_base &)
1990
1991DEFN_ASN_OP(&)
1992DEFN_ASN_OP(|)
1993DEFN_ASN_OP(^)
1994
1995#undef DEFN_ASN_OP_T
1996#undef DEFN_ASN_OP
1997
1998
1999// relational operators
2000
2001#define DEFN_REL_OP_T(op, tp) \
2002inline bool \
2003operator op (const sc_fxnum_fast_subref &a, tp b) \
2004{ \
2005    return (static_cast<sc_bv_base>(a) op b); \
2006} \
2007 \
2008inline bool \
2009operator op (tp a, const sc_fxnum_fast_subref &b) \
2010{ \
2011    return (static_cast<sc_bv_base>(b) op a); \
2012}
2013
2014#define DEFN_REL_OP(op) \
2015inline bool \
2016operator op (const sc_fxnum_fast_subref &a, const sc_fxnum_fast_subref &b) \
2017{ \
2018    return (static_cast<sc_bv_base>(a) op static_cast<sc_bv_base>(b)); \
2019} \
2020 \
2021inline bool \
2022operator op (const sc_fxnum_fast_subref &a, const sc_fxnum_subref &b) \
2023{ \
2024    return (static_cast<sc_bv_base>(a) op static_cast<sc_bv_base>(b)); \
2025} \
2026 \
2027DEFN_REL_OP_T(op, const sc_bv_base &) \
2028DEFN_REL_OP_T(op, const sc_lv_base &) \
2029DEFN_REL_OP_T(op, const char *) \
2030DEFN_REL_OP_T(op, const bool *) \
2031DEFN_REL_OP_T(op, const sc_signed &) \
2032DEFN_REL_OP_T(op, const sc_unsigned &) \
2033DEFN_REL_OP_T(op, int) \
2034DEFN_REL_OP_T(op, unsigned int) \
2035DEFN_REL_OP_T(op, long) \
2036DEFN_REL_OP_T(op, unsigned long)
2037
2038DEFN_REL_OP(==)
2039DEFN_REL_OP(!=)
2040
2041#undef DEFN_REL_OP_T
2042#undef DEFN_REL_OP
2043
2044// reduce functions
2045#define DEFN_RED_FNC(fnc) \
2046inline bool \
2047sc_fxnum_fast_subref::fnc() const \
2048{ \
2049    SC_FXNUM_FAST_OBSERVER_READ_(m_num) \
2050    get(); \
2051    return static_cast<bool>(m_bv.fnc()); \
2052}
2053
2054DEFN_RED_FNC(and_reduce)
2055DEFN_RED_FNC(nand_reduce)
2056DEFN_RED_FNC(or_reduce)
2057DEFN_RED_FNC(nor_reduce)
2058DEFN_RED_FNC(xor_reduce)
2059DEFN_RED_FNC(xnor_reduce)
2060
2061#undef DEFN_RED_FNC
2062
2063// query parameter
2064inline int
2065sc_fxnum_fast_subref::length() const
2066{
2067    return m_bv.length();
2068}
2069
2070// explicit conversions
2071inline int
2072sc_fxnum_fast_subref::to_int() const
2073{
2074    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
2075    get();
2076    return m_bv.to_int();
2077}
2078
2079inline int64
2080sc_fxnum_fast_subref::to_int64() const
2081{
2082    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
2083    get();
2084    return m_bv.to_int64();
2085}
2086
2087inline unsigned int
2088sc_fxnum_fast_subref::to_uint() const
2089{
2090    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
2091    get();
2092    return m_bv.to_uint();
2093}
2094
2095inline uint64
2096sc_fxnum_fast_subref::to_uint64() const
2097{
2098    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
2099    get();
2100    return m_bv.to_uint64();
2101}
2102
2103inline long
2104sc_fxnum_fast_subref::to_long() const
2105{
2106    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
2107    get();
2108    return m_bv.to_long();
2109}
2110
2111inline unsigned long
2112sc_fxnum_fast_subref::to_ulong() const
2113{
2114    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
2115    get();
2116    return m_bv.to_ulong();
2117}
2118
2119inline const std::string
2120sc_fxnum_fast_subref::to_string() const
2121{
2122    get();
2123    return m_bv.to_string();
2124}
2125
2126inline const std::string
2127sc_fxnum_fast_subref::to_string(sc_numrep numrep) const
2128{
2129    get();
2130    return m_bv.to_string(numrep);
2131}
2132
2133inline const std::string
2134sc_fxnum_fast_subref::to_string(sc_numrep numrep, bool w_prefix) const
2135{
2136    get();
2137    return m_bv.to_string(numrep, w_prefix);
2138}
2139
2140
2141// implicit conversion
2142inline sc_fxnum_fast_subref::operator sc_bv_base () const
2143{
2144    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
2145    get();
2146    return m_bv;
2147}
2148
2149inline ::std::ostream &
2150operator << (::std::ostream &os, const sc_fxnum_fast_subref &a)
2151{
2152    a.print(os);
2153    return os;
2154}
2155
2156inline ::std::istream &
2157operator >> (::std::istream &is, sc_fxnum_fast_subref &a)
2158{
2159    a.scan(is);
2160    return is;
2161}
2162
2163
2164// ----------------------------------------------------------------------------
2165// CLASS : sc_fxnum
2166//
2167// Base class for the fixed-point types; arbitrary precision.
2168// ----------------------------------------------------------------------------
2169
2170inline sc_fxnum_observer *
2171sc_fxnum::observer() const
2172{
2173    return m_observer;
2174}
2175
2176inline void
2177sc_fxnum::cast()
2178{
2179    SC_ERROR_IF_(!m_rep->is_normal(), "invalid fixed-point value");
2180
2181    if (m_params.cast_switch() == SC_ON)
2182        m_rep->cast(m_params, m_q_flag, m_o_flag);
2183}
2184
2185// constructors
2186inline sc_fxnum::sc_fxnum(const sc_fxtype_params &type_params_,
2187                          sc_enc enc_, const sc_fxcast_switch &cast_sw,
2188                          sc_fxnum_observer *observer_) :
2189    m_rep(new scfx_rep), m_params(type_params_, enc_, cast_sw),
2190    m_q_flag(false), m_o_flag(false), m_observer(observer_)
2191{
2192    SC_FXNUM_OBSERVER_DEFAULT_
2193    SC_FXNUM_OBSERVER_CONSTRUCT_(*this)
2194}
2195
2196#define DEFN_CTOR_T(tp, arg) \
2197inline sc_fxnum::sc_fxnum(tp a, const sc_fxtype_params &type_params_, \
2198                          sc_enc enc_, const sc_fxcast_switch &cast_sw, \
2199                          sc_fxnum_observer *observer_) : \
2200    m_rep(new scfx_rep(arg)), m_params(type_params_, enc_, cast_sw), \
2201    m_q_flag(false), m_o_flag(false), m_observer(observer_) \
2202{ \
2203    SC_FXNUM_OBSERVER_DEFAULT_ \
2204    cast(); \
2205    SC_FXNUM_OBSERVER_CONSTRUCT_(*this) \
2206    SC_FXNUM_OBSERVER_WRITE_(*this) \
2207}
2208
2209#define DEFN_CTOR_T_A(tp) DEFN_CTOR_T(tp, a)
2210#define DEFN_CTOR_T_B(tp) DEFN_CTOR_T(tp, *a.m_rep)
2211#define DEFN_CTOR_T_C(tp) DEFN_CTOR_T(tp, a.to_double())
2212#define DEFN_CTOR_T_D(tp) DEFN_CTOR_T(tp, a.value())
2213
2214DEFN_CTOR_T_A(int)
2215DEFN_CTOR_T_A(unsigned int)
2216DEFN_CTOR_T_A(long)
2217DEFN_CTOR_T_A(unsigned long)
2218DEFN_CTOR_T_A(float)
2219DEFN_CTOR_T_A(double)
2220DEFN_CTOR_T_A(const char *)
2221DEFN_CTOR_T_B(const sc_fxval &)
2222DEFN_CTOR_T_C(const sc_fxval_fast &)
2223DEFN_CTOR_T_B(const sc_fxnum &)
2224DEFN_CTOR_T_C(const sc_fxnum_fast &)
2225#ifndef SC_FX_EXCLUDE_OTHER
2226DEFN_CTOR_T_A(int64)
2227DEFN_CTOR_T_A(uint64)
2228DEFN_CTOR_T_D(const sc_int_base &)
2229DEFN_CTOR_T_D(const sc_uint_base &)
2230DEFN_CTOR_T_A(const sc_signed &)
2231DEFN_CTOR_T_A(const sc_unsigned &)
2232#endif
2233
2234#undef DEFN_CTOR_T
2235#undef DEFN_CTOR_T_A
2236#undef DEFN_CTOR_T_B
2237#undef DEFN_CTOR_T_C
2238#undef DEFN_CTOR_T_D
2239
2240inline sc_fxnum::~sc_fxnum()
2241{
2242    SC_FXNUM_OBSERVER_DESTRUCT_(*this)
2243    delete m_rep;
2244}
2245
2246// internal use only;
2247inline const scfx_rep *
2248sc_fxnum::get_rep() const
2249{
2250    SC_FXNUM_OBSERVER_READ_(*this)
2251    return m_rep;
2252}
2253
2254// unary operators
2255inline const sc_fxval
2256sc_fxnum::operator - () const
2257{
2258    SC_FXNUM_OBSERVER_READ_(*this)
2259    return sc_fxval(sc_dt::neg_scfx_rep(*m_rep));
2260}
2261
2262inline const sc_fxval
2263sc_fxnum::operator + () const
2264{
2265    SC_FXNUM_OBSERVER_READ_(*this)
2266    return sc_fxval(new scfx_rep(*m_rep));
2267}
2268
2269// unary functions
2270inline void
2271neg(sc_fxval &c, const sc_fxnum &a)
2272{
2273    SC_FXNUM_OBSERVER_READ_(a)
2274    c.set_rep(sc_dt::neg_scfx_rep(*a.m_rep));
2275}
2276
2277inline void
2278neg(sc_fxnum &c, const sc_fxnum &a)
2279{
2280    SC_FXNUM_OBSERVER_READ_(a)
2281    delete c.m_rep;
2282    c.m_rep = sc_dt::neg_scfx_rep(*a.m_rep);
2283    c.cast();
2284    SC_FXNUM_OBSERVER_WRITE_(c)
2285}
2286
2287// binary operators
2288#define DEFN_BIN_OP_T(op, fnc, tp) \
2289inline const sc_fxval \
2290operator op (const sc_fxnum &a, tp b) \
2291{ \
2292    SC_FXNUM_OBSERVER_READ_(a) \
2293    sc_fxval tmp(b); \
2294    return sc_fxval(sc_dt::fnc ## _scfx_rep(*a.m_rep, *tmp.get_rep())); \
2295} \
2296 \
2297inline const sc_fxval \
2298operator op (tp a, const sc_fxnum &b) \
2299{ \
2300    SC_FXNUM_OBSERVER_READ_(b) \
2301    sc_fxval tmp(a); \
2302    return sc_fxval(sc_dt::fnc ## _scfx_rep(*tmp.get_rep(), *b.m_rep)); \
2303}
2304
2305#ifndef SC_FX_EXCLUDE_OTHER
2306#define DEFN_BIN_OP_OTHER(op, fnc) \
2307DEFN_BIN_OP_T(op, fnc, int64) \
2308DEFN_BIN_OP_T(op, fnc, uint64) \
2309DEFN_BIN_OP_T(op, fnc, const sc_int_base &) \
2310DEFN_BIN_OP_T(op, fnc, const sc_uint_base &) \
2311DEFN_BIN_OP_T(op, fnc, const sc_signed &) \
2312DEFN_BIN_OP_T(op, fnc, const sc_unsigned &)
2313#else
2314#define DEFN_BIN_OP_OTHER(op, fnc)
2315#endif
2316
2317#define DEFN_BIN_OP(op, fnc) \
2318inline const sc_fxval \
2319operator op (const sc_fxnum &a, const sc_fxnum &b) \
2320{ \
2321    SC_FXNUM_OBSERVER_READ_(a) \
2322    SC_FXNUM_OBSERVER_READ_(b) \
2323    return sc_fxval(sc_dt::fnc ## _scfx_rep(*a.m_rep, *b.m_rep)); \
2324} \
2325 \
2326inline const sc_fxval \
2327operator op (const sc_fxnum &a, const sc_fxval &b) \
2328{ \
2329    SC_FXNUM_OBSERVER_READ_(a) \
2330    return sc_fxval(sc_dt::fnc ## _scfx_rep(*a.m_rep, *b.get_rep())); \
2331} \
2332 \
2333inline const sc_fxval \
2334operator op (const sc_fxval &a, const sc_fxnum &b) \
2335{ \
2336    SC_FXNUM_OBSERVER_READ_(b) \
2337    return sc_fxval(sc_dt::fnc ## _scfx_rep(*a.get_rep(), *b.m_rep)); \
2338} \
2339 \
2340DEFN_BIN_OP_T(op, fnc, int) \
2341DEFN_BIN_OP_T(op, fnc, unsigned int) \
2342DEFN_BIN_OP_T(op, fnc, long) \
2343DEFN_BIN_OP_T(op, fnc, unsigned long) \
2344DEFN_BIN_OP_T(op, fnc, float) \
2345DEFN_BIN_OP_T(op, fnc, double) \
2346DEFN_BIN_OP_T(op, fnc, const char *) \
2347DEFN_BIN_OP_T(op, fnc, const sc_fxval_fast &) \
2348DEFN_BIN_OP_T(op, fnc, const sc_fxnum_fast &) \
2349DEFN_BIN_OP_OTHER(op, fnc)
2350
2351DEFN_BIN_OP(*, mult)
2352DEFN_BIN_OP(+, add)
2353DEFN_BIN_OP(-, sub)
2354// don't use macros
2355//DEFN_BIN_OP(/, div)
2356inline const sc_fxval
2357operator / (const sc_fxnum &a, const sc_fxnum &b)
2358{
2359    SC_FXNUM_OBSERVER_READ_(a)
2360    SC_FXNUM_OBSERVER_READ_(b)
2361    return sc_fxval(sc_dt::div_scfx_rep(*a.m_rep, *b.m_rep));
2362}
2363
2364inline const sc_fxval
2365operator / (const sc_fxnum &a, const sc_fxval &b)
2366{
2367    SC_FXNUM_OBSERVER_READ_(a)
2368    return sc_fxval(sc_dt::div_scfx_rep(*a.m_rep, *b.get_rep()));
2369}
2370
2371inline const sc_fxval
2372operator / (const sc_fxval &a, const sc_fxnum &b)
2373{
2374    SC_FXNUM_OBSERVER_READ_(b)
2375    return sc_fxval(sc_dt::div_scfx_rep(*a.get_rep(), *b.m_rep));
2376}
2377
2378DEFN_BIN_OP_T(/, div, int)
2379DEFN_BIN_OP_T(/, div, unsigned int)
2380DEFN_BIN_OP_T(/, div, long)
2381DEFN_BIN_OP_T(/, div, unsigned long)
2382DEFN_BIN_OP_T(/, div, float)
2383DEFN_BIN_OP_T(/, div, double)
2384DEFN_BIN_OP_T(/, div, const char *)
2385DEFN_BIN_OP_T(/, div, const sc_fxval_fast &)
2386DEFN_BIN_OP_T(/, div, const sc_fxnum_fast &)
2387//DEFN_BIN_OP_OTHER(/, div)
2388
2389DEFN_BIN_OP_T(/, div, int64)
2390DEFN_BIN_OP_T(/, div, uint64)
2391DEFN_BIN_OP_T(/, div, const sc_int_base &)
2392DEFN_BIN_OP_T(/, div, const sc_uint_base &)
2393DEFN_BIN_OP_T(/, div, const sc_signed &)
2394DEFN_BIN_OP_T(/, div, const sc_unsigned &)
2395
2396#undef DEFN_BIN_OP_T
2397#undef DEFN_BIN_OP_OTHER
2398#undef DEFN_BIN_OP
2399
2400inline const sc_fxval
2401operator << (const sc_fxnum &a, int b)
2402{
2403    SC_FXNUM_OBSERVER_READ_(a)
2404    return sc_fxval(sc_dt::lsh_scfx_rep(*a.m_rep, b));
2405}
2406
2407inline const sc_fxval
2408operator >> (const sc_fxnum &a, int b)
2409{
2410    SC_FXNUM_OBSERVER_READ_(a)
2411    return sc_fxval(sc_dt::rsh_scfx_rep(*a.m_rep, b));
2412}
2413
2414// binary functions
2415#define DEFN_BIN_FNC_T(fnc, tp) \
2416inline void \
2417fnc (sc_fxval &c, const sc_fxnum &a, tp b) \
2418{ \
2419    SC_FXNUM_OBSERVER_READ_(a) \
2420    sc_fxval tmp(b); \
2421    c.set_rep(sc_dt::fnc ## _scfx_rep(*a.m_rep, *tmp.get_rep())); \
2422} \
2423 \
2424inline void \
2425fnc (sc_fxval &c, tp a, const sc_fxnum &b) \
2426{ \
2427    SC_FXNUM_OBSERVER_READ_(b) \
2428    sc_fxval tmp(a); \
2429    c.set_rep(sc_dt::fnc ## _scfx_rep(*tmp.get_rep(), *b.m_rep)); \
2430} \
2431 \
2432inline void \
2433fnc (sc_fxnum &c, const sc_fxnum &a, tp b) \
2434{ \
2435    SC_FXNUM_OBSERVER_READ_(a) \
2436    sc_fxval tmp(b); \
2437    delete c.m_rep; \
2438    c.m_rep = sc_dt::fnc ## _scfx_rep(*a.m_rep, *tmp.get_rep()); \
2439    c.cast(); \
2440    SC_FXNUM_OBSERVER_WRITE_(c) \
2441} \
2442 \
2443inline void \
2444fnc (sc_fxnum &c, tp a, const sc_fxnum &b) \
2445{ \
2446    SC_FXNUM_OBSERVER_READ_(b) \
2447    sc_fxval tmp(a); \
2448    delete c.m_rep; \
2449    c.m_rep = sc_dt::fnc ## _scfx_rep(*tmp.get_rep(), *b.m_rep); \
2450    c.cast(); \
2451    SC_FXNUM_OBSERVER_WRITE_(c) \
2452}
2453
2454#define DEFN_BIN_FNC_OTHER(fnc) \
2455DEFN_BIN_FNC_T(fnc, int64) \
2456DEFN_BIN_FNC_T(fnc, uint64) \
2457DEFN_BIN_FNC_T(fnc, const sc_int_base &) \
2458DEFN_BIN_FNC_T(fnc, const sc_uint_base &) \
2459DEFN_BIN_FNC_T(fnc, const sc_signed &) \
2460DEFN_BIN_FNC_T(fnc, const sc_unsigned &)
2461
2462#define DEFN_BIN_FNC(fnc) \
2463inline void \
2464fnc (sc_fxval &c, const sc_fxnum &a, const sc_fxnum &b) \
2465{ \
2466    SC_FXNUM_OBSERVER_READ_(a) \
2467    SC_FXNUM_OBSERVER_READ_(b) \
2468    c.set_rep(sc_dt::fnc ## _scfx_rep(*a.m_rep, *b.m_rep)); \
2469} \
2470 \
2471inline void \
2472fnc (sc_fxnum &c, const sc_fxnum &a, const sc_fxnum &b) \
2473{ \
2474    SC_FXNUM_OBSERVER_READ_(a) \
2475    SC_FXNUM_OBSERVER_READ_(b) \
2476    delete c.m_rep; \
2477    c.m_rep = sc_dt::fnc ## _scfx_rep(*a.m_rep, *b.m_rep); \
2478    c.cast(); \
2479    SC_FXNUM_OBSERVER_WRITE_(c) \
2480} \
2481 \
2482inline void \
2483fnc (sc_fxval &c, const sc_fxnum &a, const sc_fxval &b) \
2484{ \
2485    SC_FXNUM_OBSERVER_READ_(a) \
2486    c.set_rep(sc_dt::fnc ## _scfx_rep(*a.m_rep, *b.get_rep())); \
2487} \
2488 \
2489inline void \
2490fnc (sc_fxval &c, const sc_fxval &a, const sc_fxnum &b) \
2491{ \
2492    SC_FXNUM_OBSERVER_READ_(b) \
2493    c.set_rep(sc_dt::fnc ## _scfx_rep(*a.get_rep(), *b.m_rep)); \
2494} \
2495 \
2496inline void \
2497fnc (sc_fxnum &c, const sc_fxnum &a, const sc_fxval &b) \
2498{ \
2499    SC_FXNUM_OBSERVER_READ_(a) \
2500    delete c.m_rep; \
2501    c.m_rep = sc_dt::fnc ## _scfx_rep(*a.m_rep, *b.get_rep()); \
2502    c.cast(); \
2503    SC_FXNUM_OBSERVER_WRITE_(c) \
2504} \
2505 \
2506inline void \
2507fnc (sc_fxnum &c, const sc_fxval &a, const sc_fxnum &b) \
2508{ \
2509    SC_FXNUM_OBSERVER_READ_(b) \
2510    delete c.m_rep; \
2511    c.m_rep = sc_dt::fnc ## _scfx_rep(*a.get_rep(), *b.m_rep); \
2512    c.cast(); \
2513    SC_FXNUM_OBSERVER_WRITE_(c) \
2514} \
2515 \
2516DEFN_BIN_FNC_T(fnc, int) \
2517DEFN_BIN_FNC_T(fnc, unsigned int) \
2518DEFN_BIN_FNC_T(fnc, long) \
2519DEFN_BIN_FNC_T(fnc, unsigned long) \
2520DEFN_BIN_FNC_T(fnc, float) \
2521DEFN_BIN_FNC_T(fnc, double) \
2522DEFN_BIN_FNC_T(fnc, const char *) \
2523DEFN_BIN_FNC_T(fnc, const sc_fxval_fast &) \
2524DEFN_BIN_FNC_T(fnc, const sc_fxnum_fast &) \
2525DEFN_BIN_FNC_OTHER(fnc)
2526
2527DEFN_BIN_FNC(mult)
2528DEFN_BIN_FNC(div)
2529DEFN_BIN_FNC(add)
2530DEFN_BIN_FNC(sub)
2531
2532#undef DEFN_BIN_FNC_T
2533#undef DEFN_BIN_FNC_OTHER
2534#undef DEFN_BIN_FNC
2535
2536inline void
2537lshift(sc_fxval &c, const sc_fxnum &a, int b)
2538{
2539    SC_FXNUM_OBSERVER_READ_(a)
2540    c.set_rep(sc_dt::lsh_scfx_rep(*a.m_rep, b));
2541}
2542
2543inline void
2544rshift(sc_fxval &c, const sc_fxnum &a, int b)
2545{
2546    SC_FXNUM_OBSERVER_READ_(a)
2547    c.set_rep(sc_dt::rsh_scfx_rep(*a.m_rep, b));
2548}
2549
2550inline void
2551lshift(sc_fxnum &c, const sc_fxnum &a, int b)
2552{
2553    SC_FXNUM_OBSERVER_READ_(a)
2554    delete c.m_rep;
2555    c.m_rep = sc_dt::lsh_scfx_rep(*a.m_rep, b);
2556    c.cast();
2557    SC_FXNUM_OBSERVER_WRITE_(c)
2558}
2559
2560inline void
2561rshift(sc_fxnum &c, const sc_fxnum &a, int b)
2562{
2563    SC_FXNUM_OBSERVER_READ_(a)
2564    delete c.m_rep;
2565    c.m_rep = sc_dt::rsh_scfx_rep(*a.m_rep, b);
2566    c.cast();
2567    SC_FXNUM_OBSERVER_WRITE_(c)
2568}
2569
2570// relational (including equality) operators
2571#define DEFN_REL_OP_T(op, ret, tp) \
2572inline bool \
2573operator op (const sc_fxnum &a, tp b) \
2574{ \
2575    SC_FXNUM_OBSERVER_READ_(a) \
2576    sc_fxval tmp(b); \
2577    int result = sc_dt::cmp_scfx_rep(*a.m_rep, *tmp.get_rep()); \
2578    return (ret); \
2579} \
2580 \
2581inline bool \
2582operator op (tp a, const sc_fxnum &b) \
2583{ \
2584    SC_FXNUM_OBSERVER_READ_(b) \
2585    sc_fxval tmp(a); \
2586    int result = sc_dt::cmp_scfx_rep(*tmp.get_rep(), *b.m_rep); \
2587    return (ret); \
2588}
2589
2590#define DEFN_REL_OP_OTHER(op, ret) \
2591DEFN_REL_OP_T(op, ret, int64) \
2592DEFN_REL_OP_T(op, ret, uint64) \
2593DEFN_REL_OP_T(op, ret, const sc_int_base &) \
2594DEFN_REL_OP_T(op, ret, const sc_uint_base &) \
2595DEFN_REL_OP_T(op, ret, const sc_signed &) \
2596DEFN_REL_OP_T(op, ret, const sc_unsigned &)
2597
2598#define DEFN_REL_OP(op, ret) \
2599inline bool \
2600operator op (const sc_fxnum &a, const sc_fxnum &b) \
2601{ \
2602    SC_FXNUM_OBSERVER_READ_(a) \
2603    SC_FXNUM_OBSERVER_READ_(b) \
2604    int result = sc_dt::cmp_scfx_rep(*a.m_rep, *b.m_rep); \
2605    return (ret); \
2606} \
2607 \
2608inline bool \
2609operator op (const sc_fxnum &a, const sc_fxval &b) \
2610{ \
2611    SC_FXNUM_OBSERVER_READ_(a) \
2612    int result = sc_dt::cmp_scfx_rep(*a.m_rep, *b.get_rep()); \
2613    return (ret); \
2614} \
2615 \
2616inline bool \
2617operator op (const sc_fxval &a, const sc_fxnum &b) \
2618{ \
2619    SC_FXNUM_OBSERVER_READ_(b) \
2620    int result = sc_dt::cmp_scfx_rep(*a.get_rep(), *b.m_rep); \
2621    return (ret); \
2622} \
2623 \
2624DEFN_REL_OP_T(op, ret, int) \
2625DEFN_REL_OP_T(op, ret, unsigned int) \
2626DEFN_REL_OP_T(op, ret, long) \
2627DEFN_REL_OP_T(op, ret, unsigned long) \
2628DEFN_REL_OP_T(op, ret, float) \
2629DEFN_REL_OP_T(op, ret, double) \
2630DEFN_REL_OP_T(op, ret, const char *) \
2631DEFN_REL_OP_T(op, ret, const sc_fxval_fast &) \
2632DEFN_REL_OP_T(op, ret, const sc_fxnum_fast &) \
2633DEFN_REL_OP_OTHER(op, ret)
2634
2635DEFN_REL_OP(<, result < 0)
2636DEFN_REL_OP(<=, result <= 0)
2637DEFN_REL_OP(>, result > 0 && result != 2)
2638DEFN_REL_OP(>=, result >= 0 && result != 2)
2639DEFN_REL_OP(==, result == 0)
2640DEFN_REL_OP(!=, result != 0)
2641
2642#undef DEFN_REL_OP_T
2643#undef DEFN_REL_OP_OTHER
2644#undef DEFN_REL_OP
2645
2646// assignment operators
2647inline sc_fxnum &
2648sc_fxnum::operator = (const sc_fxnum &a)
2649{
2650    if (&a != this) {
2651        SC_FXNUM_OBSERVER_READ_(a)
2652        *m_rep = *a.m_rep;
2653        cast();
2654        SC_FXNUM_OBSERVER_WRITE_(*this)
2655    }
2656    return *this;
2657}
2658
2659inline sc_fxnum &
2660sc_fxnum::operator = (const sc_fxval &a)
2661{
2662    *m_rep = *a.get_rep();
2663    cast();
2664    SC_FXNUM_OBSERVER_WRITE_(*this)
2665    return *this;
2666}
2667
2668#define DEFN_ASN_OP_T(tp) \
2669inline sc_fxnum & \
2670sc_fxnum::operator = (tp a) \
2671{ \
2672    sc_fxval tmp(a); \
2673    *m_rep = *tmp.get_rep(); \
2674    cast(); \
2675    SC_FXNUM_OBSERVER_WRITE_(*this) \
2676    return *this; \
2677}
2678
2679DEFN_ASN_OP_T(int)
2680DEFN_ASN_OP_T(unsigned int)
2681DEFN_ASN_OP_T(long)
2682DEFN_ASN_OP_T(unsigned long)
2683DEFN_ASN_OP_T(float)
2684DEFN_ASN_OP_T(double)
2685DEFN_ASN_OP_T(const char *)
2686DEFN_ASN_OP_T(const sc_fxval_fast &)
2687DEFN_ASN_OP_T(const sc_fxnum_fast &)
2688
2689DEFN_ASN_OP_T(int64)
2690DEFN_ASN_OP_T(uint64)
2691DEFN_ASN_OP_T(const sc_int_base &)
2692DEFN_ASN_OP_T(const sc_uint_base &)
2693DEFN_ASN_OP_T(const sc_signed &)
2694DEFN_ASN_OP_T(const sc_unsigned &)
2695
2696#undef DEFN_ASN_OP_T
2697
2698
2699#define DEFN_ASN_OP_T(op, fnc, tp) \
2700inline sc_fxnum & \
2701sc_fxnum::operator op (tp b) \
2702{ \
2703    SC_FXNUM_OBSERVER_READ_(*this) \
2704    sc_fxval tmp(b); \
2705    scfx_rep *new_rep = sc_dt::fnc ## _scfx_rep(*m_rep, *tmp.get_rep()); \
2706    delete m_rep; \
2707    m_rep = new_rep; \
2708    cast(); \
2709    SC_FXNUM_OBSERVER_WRITE_(*this) \
2710    return *this; \
2711}
2712
2713#define DEFN_ASN_OP_OTHER(op, fnc) \
2714DEFN_ASN_OP_T(op, fnc, int64) \
2715DEFN_ASN_OP_T(op, fnc, uint64) \
2716DEFN_ASN_OP_T(op, fnc, const sc_int_base &) \
2717DEFN_ASN_OP_T(op, fnc, const sc_uint_base &) \
2718DEFN_ASN_OP_T(op, fnc, const sc_signed &) \
2719DEFN_ASN_OP_T(op, fnc, const sc_unsigned &)
2720
2721#define DEFN_ASN_OP(op, fnc) \
2722inline sc_fxnum & \
2723sc_fxnum::operator op (const sc_fxnum &b) \
2724{ \
2725    SC_FXNUM_OBSERVER_READ_(*this) \
2726    SC_FXNUM_OBSERVER_READ_(b) \
2727    scfx_rep *new_rep = sc_dt::fnc ## _scfx_rep(*m_rep, *b.m_rep); \
2728    delete m_rep; \
2729    m_rep = new_rep; \
2730    cast(); \
2731    SC_FXNUM_OBSERVER_WRITE_(*this) \
2732    return *this; \
2733} \
2734 \
2735inline sc_fxnum & \
2736sc_fxnum::operator op (const sc_fxval &b) \
2737{ \
2738    SC_FXNUM_OBSERVER_READ_(*this) \
2739    scfx_rep *new_rep = sc_dt::fnc ## _scfx_rep(*m_rep, *b.get_rep()); \
2740    delete m_rep; \
2741    m_rep = new_rep; \
2742    cast(); \
2743    SC_FXNUM_OBSERVER_WRITE_(*this) \
2744    return *this; \
2745} \
2746 \
2747DEFN_ASN_OP_T(op, fnc, int) \
2748DEFN_ASN_OP_T(op, fnc, unsigned int) \
2749DEFN_ASN_OP_T(op, fnc, long) \
2750DEFN_ASN_OP_T(op, fnc, unsigned long) \
2751DEFN_ASN_OP_T(op, fnc, float) \
2752DEFN_ASN_OP_T(op, fnc, double) \
2753DEFN_ASN_OP_T(op, fnc, const char *) \
2754DEFN_ASN_OP_T(op, fnc, const sc_fxval_fast &) \
2755DEFN_ASN_OP_T(op, fnc, const sc_fxnum_fast &) \
2756DEFN_ASN_OP_OTHER(op, fnc)
2757
2758DEFN_ASN_OP(*=, mult)
2759DEFN_ASN_OP(/=, div)
2760DEFN_ASN_OP(+=, add)
2761DEFN_ASN_OP(-=, sub)
2762
2763#undef DEFN_ASN_OP_T
2764#undef DEFN_ASN_OP_OTHER
2765#undef DEFN_ASN_OP
2766
2767
2768inline sc_fxnum &
2769sc_fxnum::operator <<= (int b)
2770{
2771    SC_FXNUM_OBSERVER_READ_(*this)
2772    m_rep->lshift(b);
2773    cast();
2774    SC_FXNUM_OBSERVER_WRITE_(*this)
2775    return *this;
2776}
2777
2778inline sc_fxnum &
2779sc_fxnum::operator >>= (int b)
2780{
2781    SC_FXNUM_OBSERVER_READ_(*this)
2782    m_rep->rshift(b);
2783    cast();
2784    SC_FXNUM_OBSERVER_WRITE_(*this)
2785    return *this;
2786}
2787
2788// auto-increment and auto-decrement
2789inline const sc_fxval
2790sc_fxnum::operator ++ (int)
2791{
2792    sc_fxval c(*this);
2793    (*this) += 1;
2794    return c;
2795}
2796
2797inline const sc_fxval
2798sc_fxnum::operator -- (int)
2799{
2800    sc_fxval c(*this);
2801    (*this) -= 1;
2802    return c;
2803}
2804
2805inline sc_fxnum &
2806sc_fxnum::operator ++ ()
2807{
2808    (*this) += 1;
2809    return *this;
2810}
2811
2812inline sc_fxnum &
2813sc_fxnum::operator -- ()
2814{
2815    (*this) -= 1;
2816    return *this;
2817}
2818
2819// bit selection
2820inline const sc_fxnum_bitref
2821sc_fxnum::operator [] (int i) const
2822{
2823    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2824    return sc_fxnum_bitref(const_cast<sc_fxnum &>(*this),
2825                           i - m_params.fwl());
2826}
2827
2828inline sc_fxnum_bitref
2829sc_fxnum::operator [] (int i)
2830{
2831    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2832    return sc_fxnum_bitref(*this, i - m_params.fwl());
2833}
2834
2835inline const sc_fxnum_bitref
2836sc_fxnum::bit(int i) const
2837{
2838    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2839    return sc_fxnum_bitref(const_cast<sc_fxnum &>(*this),
2840                            i - m_params.fwl());
2841}
2842
2843inline sc_fxnum_bitref
2844sc_fxnum::bit(int i)
2845{
2846    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2847    return sc_fxnum_bitref(*this, i - m_params.fwl());
2848}
2849
2850// part selection
2851
2852inline const sc_fxnum_subref
2853sc_fxnum::operator () (int i, int j) const
2854{
2855    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2856    SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
2857
2858    return sc_fxnum_subref(const_cast<sc_fxnum &>(*this),
2859                           i - m_params.fwl(), j - m_params.fwl());
2860}
2861
2862inline sc_fxnum_subref
2863sc_fxnum::operator () (int i, int j)
2864{
2865    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2866    SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
2867
2868    return sc_fxnum_subref(*this, i - m_params.fwl(), j - m_params.fwl());
2869}
2870
2871inline const sc_fxnum_subref
2872sc_fxnum::range(int i, int j) const
2873{
2874    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2875    SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
2876
2877    return sc_fxnum_subref(const_cast<sc_fxnum &>(*this),
2878                           i - m_params.fwl(), j - m_params.fwl());
2879}
2880
2881inline sc_fxnum_subref
2882sc_fxnum::range(int i, int j)
2883{
2884    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2885    SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
2886
2887    return sc_fxnum_subref(*this, i - m_params.fwl(), j - m_params.fwl());
2888}
2889
2890
2891inline const sc_fxnum_subref
2892sc_fxnum::operator () () const
2893{
2894    return this->operator () (m_params.wl() - 1, 0);
2895}
2896
2897inline sc_fxnum_subref
2898sc_fxnum::operator () ()
2899{
2900    return this->operator () (m_params.wl() - 1, 0);
2901}
2902
2903inline const sc_fxnum_subref
2904sc_fxnum::range() const
2905{
2906    return this->range(m_params.wl() - 1, 0);
2907}
2908
2909inline sc_fxnum_subref
2910sc_fxnum::range()
2911{
2912    return this->range(m_params.wl() - 1, 0);
2913}
2914
2915// implicit conversion
2916inline sc_fxnum::operator double() const
2917{
2918    SC_FXNUM_OBSERVER_READ_(*this)
2919    return m_rep->to_double();
2920}
2921
2922// explicit conversion to primitive types
2923inline short
2924sc_fxnum::to_short() const
2925{
2926    SC_FXNUM_OBSERVER_READ_(*this)
2927    return static_cast<short>(m_rep->to_uint64());
2928}
2929
2930inline unsigned short
2931sc_fxnum::to_ushort() const
2932{
2933    SC_FXNUM_OBSERVER_READ_(*this)
2934    return static_cast<unsigned short>(m_rep->to_uint64());
2935}
2936
2937inline int
2938sc_fxnum::to_int() const
2939{
2940    SC_FXNUM_OBSERVER_READ_(*this)
2941    return static_cast<int>(m_rep->to_uint64());
2942}
2943
2944inline int64
2945sc_fxnum::to_int64() const
2946{
2947    SC_FXNUM_OBSERVER_READ_(*this)
2948    return static_cast<int64>(m_rep->to_uint64());
2949}
2950
2951inline unsigned int
2952sc_fxnum::to_uint() const
2953{
2954    SC_FXNUM_OBSERVER_READ_(*this)
2955    return static_cast<unsigned int>(m_rep->to_uint64());
2956}
2957
2958inline uint64
2959sc_fxnum::to_uint64() const
2960{
2961    SC_FXNUM_OBSERVER_READ_(*this)
2962    return m_rep->to_uint64();
2963}
2964
2965inline long
2966sc_fxnum::to_long() const
2967{
2968    SC_FXNUM_OBSERVER_READ_(*this)
2969    return static_cast<long>(m_rep->to_uint64());
2970}
2971
2972inline unsigned long
2973sc_fxnum::to_ulong() const
2974{
2975    SC_FXNUM_OBSERVER_READ_(*this)
2976    return static_cast<unsigned long>(m_rep->to_uint64());
2977}
2978
2979inline float
2980sc_fxnum::to_float() const
2981{
2982    SC_FXNUM_OBSERVER_READ_(*this)
2983    return static_cast<float>(m_rep->to_double());
2984}
2985
2986inline double
2987sc_fxnum::to_double() const
2988{
2989    SC_FXNUM_OBSERVER_READ_(*this)
2990    return m_rep->to_double();
2991}
2992
2993// query value
2994inline bool
2995sc_fxnum::is_neg() const
2996{
2997    SC_FXNUM_OBSERVER_READ_(*this)
2998    return m_rep->is_neg();
2999}
3000
3001inline bool
3002sc_fxnum::is_zero() const
3003{
3004    SC_FXNUM_OBSERVER_READ_(*this)
3005    return m_rep->is_zero();
3006}
3007
3008// internal use only;
3009inline bool
3010sc_fxnum::is_normal() const
3011{
3012    SC_FXNUM_OBSERVER_READ_(*this)
3013    return m_rep->is_normal();
3014}
3015
3016inline bool
3017sc_fxnum::quantization_flag() const
3018{
3019    return m_q_flag;
3020}
3021
3022inline bool
3023sc_fxnum::overflow_flag() const
3024{
3025    return m_o_flag;
3026}
3027
3028
3029inline const sc_fxval
3030sc_fxnum::value() const
3031{
3032    SC_FXNUM_OBSERVER_READ_(*this)
3033    return sc_fxval(new scfx_rep(*m_rep));
3034}
3035
3036// query parameters
3037inline int
3038sc_fxnum::wl() const
3039{
3040    return m_params.wl();
3041}
3042
3043inline int
3044sc_fxnum::iwl() const
3045{
3046    return m_params.iwl();
3047}
3048
3049inline sc_q_mode
3050sc_fxnum::q_mode() const
3051{
3052    return m_params.q_mode();
3053}
3054
3055inline sc_o_mode
3056sc_fxnum::o_mode() const
3057{
3058    return m_params.o_mode();
3059}
3060
3061inline int
3062sc_fxnum::n_bits() const
3063{
3064    return m_params.n_bits();
3065}
3066
3067inline const sc_fxtype_params &
3068sc_fxnum::type_params() const
3069{
3070    return m_params.type_params();
3071}
3072
3073inline const sc_fxcast_switch &
3074sc_fxnum::cast_switch() const
3075{
3076    return m_params.cast_switch();
3077}
3078
3079// internal use only;
3080inline void
3081sc_fxnum::observer_read() const
3082{
3083    SC_FXNUM_OBSERVER_READ_(*this);
3084}
3085
3086// internal use only;
3087inline bool
3088sc_fxnum::get_bit(int i) const
3089{
3090    return m_rep->get_bit(i);
3091}
3092
3093// protected methods and friend functions
3094inline bool
3095sc_fxnum::set_bit(int i, bool high)
3096{
3097    if (high)
3098        return m_rep->set(i, m_params);
3099    else
3100        return m_rep->clear(i, m_params);
3101}
3102
3103inline bool
3104sc_fxnum::get_slice(int i, int j, sc_bv_base &bv) const
3105{
3106    return m_rep->get_slice(i, j, m_params, bv);
3107}
3108
3109inline bool
3110sc_fxnum::set_slice(int i, int j, const sc_bv_base &bv)
3111{
3112    return m_rep->set_slice(i, j, m_params, bv);
3113}
3114
3115inline ::std::ostream &
3116operator << (::std::ostream &os, const sc_fxnum &a)
3117{
3118    a.print(os);
3119    return os;
3120}
3121
3122inline ::std::istream &
3123operator >> (::std::istream &is, sc_fxnum &a)
3124{
3125    a.scan(is);
3126    return is;
3127}
3128
3129
3130// ----------------------------------------------------------------------------
3131// CLASS : sc_fxnum_fast
3132//
3133// Base class for the fixed-point types; limited precision.
3134// ----------------------------------------------------------------------------
3135
3136inline sc_fxnum_fast_observer *
3137sc_fxnum_fast::observer() const
3138{
3139    return m_observer;
3140}
3141
3142
3143// constructors
3144inline sc_fxnum_fast::sc_fxnum_fast(const sc_fxtype_params &type_params_,
3145                                    sc_enc enc_,
3146                                    const sc_fxcast_switch &cast_sw,
3147                                    sc_fxnum_fast_observer *observer_) :
3148    m_val(0.0), m_params(type_params_, enc_, cast_sw), m_q_flag(false),
3149    m_o_flag(false), m_observer(observer_)
3150{
3151    SC_FXNUM_FAST_OBSERVER_DEFAULT_
3152    SC_FXNUM_FAST_OBSERVER_CONSTRUCT_(*this)
3153}
3154
3155inline sc_fxnum_fast::sc_fxnum_fast(const sc_fxnum_fast &a,
3156                                    const sc_fxtype_params &type_params_,
3157                                    sc_enc enc_,
3158                                    const sc_fxcast_switch &cast_sw,
3159                                    sc_fxnum_fast_observer *observer_) :
3160    m_val(a.m_val), m_params(type_params_, enc_, cast_sw), m_q_flag(false),
3161    m_o_flag(false), m_observer(observer_)
3162{
3163    SC_FXNUM_FAST_OBSERVER_DEFAULT_
3164    SC_FXNUM_FAST_OBSERVER_READ_(a)
3165    cast();
3166    SC_FXNUM_FAST_OBSERVER_CONSTRUCT_(*this)
3167    SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3168}
3169
3170#define DEFN_CTOR_T(tp, arg) \
3171inline sc_fxnum_fast::sc_fxnum_fast( \
3172        tp a, const sc_fxtype_params &type_params_, sc_enc enc_, \
3173        const sc_fxcast_switch &cast_sw, \
3174        sc_fxnum_fast_observer *observer_) : \
3175    m_val(arg), m_params(type_params_, enc_, cast_sw), m_q_flag(false), \
3176    m_o_flag(false), m_observer(observer_) \
3177{ \
3178    SC_FXNUM_FAST_OBSERVER_DEFAULT_ \
3179    cast(); \
3180    SC_FXNUM_FAST_OBSERVER_CONSTRUCT_(*this) \
3181    SC_FXNUM_FAST_OBSERVER_WRITE_(*this) \
3182}
3183
3184#define DEFN_CTOR_T_A(tp) DEFN_CTOR_T(tp, static_cast<double>(a))
3185#define DEFN_CTOR_T_B(tp) DEFN_CTOR_T(tp, sc_fxval_fast::from_string(a))
3186#define DEFN_CTOR_T_C(tp) DEFN_CTOR_T(tp, a.to_double())
3187
3188DEFN_CTOR_T_A(int)
3189DEFN_CTOR_T_A(unsigned int)
3190DEFN_CTOR_T_A(long)
3191DEFN_CTOR_T_A(unsigned long)
3192DEFN_CTOR_T_A(float)
3193DEFN_CTOR_T_A(double)
3194DEFN_CTOR_T_B(const char *)
3195DEFN_CTOR_T_C(const sc_fxval &)
3196DEFN_CTOR_T_C(const sc_fxval_fast &)
3197DEFN_CTOR_T_C(const sc_fxnum &)
3198
3199DEFN_CTOR_T_A(int64)
3200DEFN_CTOR_T_A(uint64)
3201DEFN_CTOR_T_C(const sc_int_base &)
3202DEFN_CTOR_T_C(const sc_uint_base &)
3203DEFN_CTOR_T_C(const sc_signed &)
3204DEFN_CTOR_T_C(const sc_unsigned &)
3205
3206#undef DEFN_CTOR_T
3207#undef DEFN_CTOR_T_A
3208#undef DEFN_CTOR_T_B
3209#undef DEFN_CTOR_T_C
3210#undef DEFN_CTOR_T_D
3211#undef DEFN_CTOR_T_E
3212
3213inline sc_fxnum_fast::~sc_fxnum_fast()
3214{
3215    SC_FXNUM_FAST_OBSERVER_DESTRUCT_(*this)
3216}
3217
3218// internal use only;
3219inline double
3220sc_fxnum_fast::get_val() const
3221{
3222    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3223    return m_val;
3224}
3225
3226// unary operators
3227inline const sc_fxval_fast
3228sc_fxnum_fast::operator - () const
3229{
3230    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3231    return sc_fxval_fast(- m_val);
3232}
3233
3234inline const sc_fxval_fast
3235sc_fxnum_fast::operator + () const
3236{
3237    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3238    return sc_fxval_fast(m_val);
3239}
3240
3241// unary functions
3242inline void
3243neg(sc_fxval_fast &c, const sc_fxnum_fast &a)
3244{
3245    SC_FXNUM_FAST_OBSERVER_READ_(a)
3246    c.set_val(- a.m_val);
3247}
3248
3249inline void
3250neg(sc_fxnum_fast &c, const sc_fxnum_fast &a)
3251{
3252    SC_FXNUM_FAST_OBSERVER_READ_(a)
3253    c.m_val = - a.m_val;
3254    c.cast();
3255    SC_FXNUM_FAST_OBSERVER_WRITE_(c)
3256}
3257
3258// binary operators
3259#define DEFN_BIN_OP_T(op, tp) \
3260inline const sc_fxval_fast \
3261operator op (const sc_fxnum_fast &a, tp b) \
3262{ \
3263    SC_FXNUM_FAST_OBSERVER_READ_(a) \
3264    sc_fxval_fast tmp(b); \
3265    return sc_fxval_fast(a.m_val op tmp.get_val()); \
3266} \
3267 \
3268inline const sc_fxval_fast \
3269operator op (tp a, const sc_fxnum_fast &b) \
3270{ \
3271    SC_FXNUM_FAST_OBSERVER_READ_(b) \
3272    sc_fxval_fast tmp(a); \
3273    return sc_fxval_fast(tmp.get_val() op b.m_val); \
3274}
3275
3276#define DEFN_BIN_OP_OTHER(op) \
3277DEFN_BIN_OP_T(op, int64) \
3278DEFN_BIN_OP_T(op, uint64) \
3279DEFN_BIN_OP_T(op, const sc_int_base &) \
3280DEFN_BIN_OP_T(op, const sc_uint_base &) \
3281DEFN_BIN_OP_T(op, const sc_signed &) \
3282DEFN_BIN_OP_T(op, const sc_unsigned &)
3283
3284#define DEFN_BIN_OP(op, dummy) \
3285inline const sc_fxval_fast \
3286operator op (const sc_fxnum_fast &a, const sc_fxnum_fast &b) \
3287{ \
3288    SC_FXNUM_FAST_OBSERVER_READ_(a) \
3289    SC_FXNUM_FAST_OBSERVER_READ_(b) \
3290    return sc_fxval_fast(a.m_val op b.m_val); \
3291} \
3292 \
3293inline const sc_fxval_fast \
3294operator op (const sc_fxnum_fast &a, const sc_fxval_fast &b) \
3295{ \
3296    SC_FXNUM_FAST_OBSERVER_READ_(a) \
3297    return sc_fxval_fast(a.m_val op b.get_val()); \
3298} \
3299 \
3300inline const sc_fxval_fast \
3301operator op (const sc_fxval_fast &a, const sc_fxnum_fast &b) \
3302{ \
3303    SC_FXNUM_FAST_OBSERVER_READ_(b) \
3304    return sc_fxval_fast(a.get_val() op b.m_val); \
3305} \
3306 \
3307DEFN_BIN_OP_T(op, int) \
3308DEFN_BIN_OP_T(op, unsigned int) \
3309DEFN_BIN_OP_T(op, long) \
3310DEFN_BIN_OP_T(op, unsigned long) \
3311DEFN_BIN_OP_T(op, float) \
3312DEFN_BIN_OP_T(op, double) \
3313DEFN_BIN_OP_T(op, const char *) \
3314DEFN_BIN_OP_OTHER(op)
3315
3316DEFN_BIN_OP(*, mult)
3317DEFN_BIN_OP(+, add)
3318DEFN_BIN_OP(-, sub)
3319//DEFN_BIN_OP(/, div)
3320inline const sc_fxval_fast
3321operator / (const sc_fxnum_fast &a, const sc_fxnum_fast &b)
3322{
3323    SC_FXNUM_FAST_OBSERVER_READ_(a)
3324    SC_FXNUM_FAST_OBSERVER_READ_(b)
3325    return sc_fxval_fast(a.m_val / b.m_val);
3326}
3327
3328inline const sc_fxval_fast
3329operator / (const sc_fxnum_fast &a, const sc_fxval_fast &b)
3330{
3331    SC_FXNUM_FAST_OBSERVER_READ_(a)
3332    return sc_fxval_fast(a.m_val / b.get_val());
3333}
3334
3335inline const sc_fxval_fast
3336operator / (const sc_fxval_fast &a, const sc_fxnum_fast &b)
3337{
3338    SC_FXNUM_FAST_OBSERVER_READ_(b)
3339    return sc_fxval_fast(a.get_val() / b.m_val);
3340}
3341
3342DEFN_BIN_OP_T(/, int)
3343DEFN_BIN_OP_T(/, unsigned int)
3344DEFN_BIN_OP_T(/, long)
3345DEFN_BIN_OP_T(/, unsigned long)
3346DEFN_BIN_OP_T(/, float)
3347DEFN_BIN_OP_T(/, double)
3348DEFN_BIN_OP_T(/, const char *)
3349//DEFN_BIN_OP_OTHER(/)
3350
3351DEFN_BIN_OP_T(/, int64)
3352DEFN_BIN_OP_T(/, uint64)
3353DEFN_BIN_OP_T(/, const sc_int_base &)
3354DEFN_BIN_OP_T(/, const sc_uint_base &)
3355DEFN_BIN_OP_T(/, const sc_signed &)
3356DEFN_BIN_OP_T(/, const sc_unsigned &)
3357
3358#undef DEFN_BIN_OP_T
3359#undef DEFN_BIN_OP_OTHER
3360#undef DEFN_BIN_OP
3361
3362inline const sc_fxval_fast
3363operator << (const sc_fxnum_fast &a, int b)
3364{
3365    SC_FXNUM_FAST_OBSERVER_READ_(a)
3366    return sc_fxval_fast(a.m_val  *scfx_pow2(b));
3367}
3368
3369inline const sc_fxval_fast
3370operator >> (const sc_fxnum_fast &a, int b)
3371{
3372    SC_FXNUM_FAST_OBSERVER_READ_(a)
3373    return sc_fxval_fast(a.m_val  *scfx_pow2(-b));
3374}
3375
3376// binary functions
3377#define DEFN_BIN_FNC_T(fnc, op, tp) \
3378inline void \
3379fnc (sc_fxval_fast &c, const sc_fxnum_fast &a, tp b) \
3380{ \
3381    SC_FXNUM_FAST_OBSERVER_READ_(a) \
3382    sc_fxval_fast tmp(b); \
3383    c.set_val(a.m_val op tmp.get_val()); \
3384} \
3385 \
3386inline void \
3387fnc (sc_fxval_fast &c, tp a, const sc_fxnum_fast &b) \
3388{ \
3389    SC_FXNUM_FAST_OBSERVER_READ_(b) \
3390    sc_fxval_fast tmp(a); \
3391    c.set_val(tmp.get_val() op b.m_val); \
3392} \
3393 \
3394inline void \
3395fnc (sc_fxnum_fast &c, const sc_fxnum_fast &a, tp b) \
3396{ \
3397    SC_FXNUM_FAST_OBSERVER_READ_(a) \
3398    sc_fxval_fast tmp(b); \
3399    c.m_val = a.m_val op tmp.get_val(); \
3400    c.cast(); \
3401    SC_FXNUM_FAST_OBSERVER_WRITE_(c) \
3402} \
3403 \
3404inline void \
3405fnc (sc_fxnum_fast &c, tp a, const sc_fxnum_fast &b) \
3406{ \
3407    SC_FXNUM_FAST_OBSERVER_READ_(b) \
3408    sc_fxval_fast tmp(a); \
3409    c.m_val = tmp.get_val() op b.m_val; \
3410    c.cast(); \
3411    SC_FXNUM_FAST_OBSERVER_WRITE_(c) \
3412}
3413
3414#define DEFN_BIN_FNC_OTHER(fnc, op) \
3415DEFN_BIN_FNC_T(fnc, op, int64) \
3416DEFN_BIN_FNC_T(fnc, op, uint64) \
3417DEFN_BIN_FNC_T(fnc, op, const sc_int_base &) \
3418DEFN_BIN_FNC_T(fnc, op, const sc_uint_base &) \
3419DEFN_BIN_FNC_T(fnc, op, const sc_signed &) \
3420DEFN_BIN_FNC_T(fnc, op, const sc_unsigned &)
3421
3422#define DEFN_BIN_FNC(fnc, op) \
3423inline void \
3424fnc (sc_fxval_fast &c, const sc_fxnum_fast &a, const sc_fxnum_fast &b) \
3425{ \
3426    SC_FXNUM_FAST_OBSERVER_READ_(a) \
3427    SC_FXNUM_FAST_OBSERVER_READ_(b) \
3428    c.set_val(a.m_val op b.m_val); \
3429} \
3430 \
3431inline void \
3432fnc (sc_fxnum_fast &c, const sc_fxnum_fast &a, const sc_fxnum_fast &b) \
3433{ \
3434    SC_FXNUM_FAST_OBSERVER_READ_(a) \
3435    SC_FXNUM_FAST_OBSERVER_READ_(b) \
3436    c.m_val = a.m_val op b.m_val; \
3437    c.cast(); \
3438    SC_FXNUM_FAST_OBSERVER_WRITE_(c) \
3439} \
3440 \
3441inline void \
3442fnc (sc_fxval_fast &c, const sc_fxnum_fast &a, const sc_fxval_fast &b) \
3443{ \
3444    SC_FXNUM_FAST_OBSERVER_READ_(a) \
3445    c.set_val(a.m_val op b.get_val()); \
3446} \
3447 \
3448inline void \
3449fnc (sc_fxval_fast &c, const sc_fxval_fast &a, const sc_fxnum_fast &b) \
3450{ \
3451    SC_FXNUM_FAST_OBSERVER_READ_(b) \
3452    c.set_val(a.get_val() op b.m_val); \
3453} \
3454 \
3455inline void \
3456fnc (sc_fxnum_fast &c, const sc_fxnum_fast &a, const sc_fxval_fast &b) \
3457{ \
3458    SC_FXNUM_FAST_OBSERVER_READ_(a) \
3459    c.m_val = a.m_val op b.get_val(); \
3460    c.cast(); \
3461    SC_FXNUM_FAST_OBSERVER_WRITE_(c) \
3462} \
3463 \
3464inline void \
3465fnc (sc_fxnum_fast &c, const sc_fxval_fast &a, const sc_fxnum_fast &b) \
3466{ \
3467    SC_FXNUM_FAST_OBSERVER_READ_(b) \
3468    c.m_val = a.get_val() op b.m_val; \
3469    c.cast(); \
3470    SC_FXNUM_FAST_OBSERVER_WRITE_(c) \
3471} \
3472 \
3473DEFN_BIN_FNC_T(fnc, op, int) \
3474DEFN_BIN_FNC_T(fnc, op, unsigned int) \
3475DEFN_BIN_FNC_T(fnc, op, long) \
3476DEFN_BIN_FNC_T(fnc, op, unsigned long) \
3477DEFN_BIN_FNC_T(fnc, op, float) \
3478DEFN_BIN_FNC_T(fnc, op, double) \
3479DEFN_BIN_FNC_T(fnc, op, const char *) \
3480DEFN_BIN_FNC_T(fnc, op, const sc_fxval &) \
3481DEFN_BIN_FNC_T(fnc, op, const sc_fxnum &) \
3482DEFN_BIN_FNC_OTHER(fnc, op)
3483
3484DEFN_BIN_FNC(mult, *)
3485DEFN_BIN_FNC(div, /)
3486DEFN_BIN_FNC(add, +)
3487DEFN_BIN_FNC(sub, -)
3488
3489#undef DEFN_BIN_FNC_T
3490#undef DEFN_BIN_FNC_OTHER
3491#undef DEFN_BIN_FNC
3492
3493inline void
3494lshift(sc_fxval_fast &c, const sc_fxnum_fast &a, int b)
3495{
3496    SC_FXNUM_FAST_OBSERVER_READ_(a)
3497    c.set_val(a.m_val * scfx_pow2(b));
3498}
3499
3500inline void
3501rshift(sc_fxval_fast &c, const sc_fxnum_fast &a, int b)
3502{
3503    SC_FXNUM_FAST_OBSERVER_READ_(a)
3504    c.set_val(a.m_val * scfx_pow2(-b));
3505}
3506
3507inline void
3508lshift(sc_fxnum_fast &c, const sc_fxnum_fast &a, int b)
3509{
3510    SC_FXNUM_FAST_OBSERVER_READ_(a)
3511    c.m_val = a.m_val * scfx_pow2(b);
3512    c.cast();
3513    SC_FXNUM_FAST_OBSERVER_WRITE_(c)
3514}
3515
3516inline void
3517rshift(sc_fxnum_fast &c, const sc_fxnum_fast &a, int b)
3518{
3519    SC_FXNUM_FAST_OBSERVER_READ_(a)
3520    c.m_val = a.m_val * scfx_pow2(-b);
3521    c.cast();
3522    SC_FXNUM_FAST_OBSERVER_WRITE_(c)
3523}
3524
3525// relational (including equality) operators
3526#define DEFN_REL_OP_T(op, tp) \
3527inline bool \
3528operator op (const sc_fxnum_fast &a, tp b) \
3529{ \
3530    SC_FXNUM_FAST_OBSERVER_READ_(a) \
3531    sc_fxval_fast tmp(b); \
3532    return (a.m_val op tmp.get_val()); \
3533} \
3534 \
3535inline bool \
3536operator op (tp a, const sc_fxnum_fast &b) \
3537{ \
3538    SC_FXNUM_FAST_OBSERVER_READ_(b) \
3539    sc_fxval_fast tmp(a); \
3540    return (tmp.get_val() op b.m_val); \
3541}
3542
3543#define DEFN_REL_OP_OTHER(op) \
3544DEFN_REL_OP_T(op, int64) \
3545DEFN_REL_OP_T(op, uint64) \
3546DEFN_REL_OP_T(op, const sc_int_base &) \
3547DEFN_REL_OP_T(op, const sc_uint_base &) \
3548DEFN_REL_OP_T(op, const sc_signed &) \
3549DEFN_REL_OP_T(op, const sc_unsigned &)
3550
3551#define DEFN_REL_OP(op) \
3552inline bool \
3553operator op (const sc_fxnum_fast &a, const sc_fxnum_fast &b) \
3554{ \
3555    SC_FXNUM_FAST_OBSERVER_READ_(a) \
3556    SC_FXNUM_FAST_OBSERVER_READ_(b) \
3557    return (a.m_val op b.m_val); \
3558} \
3559 \
3560inline bool \
3561operator op (const sc_fxnum_fast &a, const sc_fxval_fast &b) \
3562{ \
3563    SC_FXNUM_FAST_OBSERVER_READ_(a) \
3564    return (a.m_val op b.get_val()); \
3565} \
3566 \
3567inline bool \
3568operator op (const sc_fxval_fast &a, const sc_fxnum_fast &b) \
3569{ \
3570    SC_FXNUM_FAST_OBSERVER_READ_(b) \
3571    return (a.get_val() op b.m_val); \
3572} \
3573 \
3574DEFN_REL_OP_T(op, int) \
3575DEFN_REL_OP_T(op, unsigned int) \
3576DEFN_REL_OP_T(op, long) \
3577DEFN_REL_OP_T(op, unsigned long) \
3578DEFN_REL_OP_T(op, float) \
3579DEFN_REL_OP_T(op, double) \
3580DEFN_REL_OP_T(op, const char *) \
3581DEFN_REL_OP_OTHER(op)
3582
3583DEFN_REL_OP(<)
3584DEFN_REL_OP(<=)
3585DEFN_REL_OP(>)
3586DEFN_REL_OP(>=)
3587DEFN_REL_OP(==)
3588DEFN_REL_OP(!=)
3589
3590#undef DEFN_REL_OP_T
3591#undef DEFN_REL_OP_OTHER
3592#undef DEFN_REL_OP
3593
3594// assignment operators
3595
3596inline sc_fxnum_fast &
3597sc_fxnum_fast::operator = (const sc_fxnum_fast &a)
3598{
3599    if (&a != this) {
3600        SC_FXNUM_FAST_OBSERVER_READ_(a)
3601        m_val = a.m_val;
3602        cast();
3603        SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3604    }
3605    return *this;
3606}
3607
3608inline sc_fxnum_fast &
3609sc_fxnum_fast::operator = (const sc_fxval_fast &a)
3610{
3611    m_val = a.get_val();
3612    cast();
3613    SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3614    return *this;
3615}
3616
3617#define DEFN_ASN_OP_T(tp) \
3618inline sc_fxnum_fast & \
3619sc_fxnum_fast::operator = (tp a) \
3620{ \
3621    sc_fxval_fast tmp(a); \
3622    m_val = tmp.get_val(); \
3623    cast(); \
3624    SC_FXNUM_FAST_OBSERVER_WRITE_(*this) \
3625    return *this; \
3626}
3627
3628DEFN_ASN_OP_T(int)
3629DEFN_ASN_OP_T(unsigned int)
3630DEFN_ASN_OP_T(long)
3631DEFN_ASN_OP_T(unsigned long)
3632DEFN_ASN_OP_T(float)
3633DEFN_ASN_OP_T(double)
3634DEFN_ASN_OP_T(const char *)
3635DEFN_ASN_OP_T(const sc_fxval &)
3636DEFN_ASN_OP_T(const sc_fxnum &)
3637
3638DEFN_ASN_OP_T(int64)
3639DEFN_ASN_OP_T(uint64)
3640DEFN_ASN_OP_T(const sc_int_base &)
3641DEFN_ASN_OP_T(const sc_uint_base &)
3642DEFN_ASN_OP_T(const sc_signed &)
3643DEFN_ASN_OP_T(const sc_unsigned &)
3644
3645#undef DEFN_ASN_OP_T
3646
3647#define DEFN_ASN_OP_T(op, tp) \
3648inline sc_fxnum_fast & \
3649sc_fxnum_fast::operator op (tp b) \
3650{ \
3651    SC_FXNUM_FAST_OBSERVER_READ_(*this) \
3652    sc_fxval_fast tmp(b); \
3653    m_val op tmp.get_val(); \
3654    cast(); \
3655    SC_FXNUM_FAST_OBSERVER_WRITE_(*this) \
3656    return *this; \
3657}
3658
3659#define DEFN_ASN_OP_OTHER(op) \
3660DEFN_ASN_OP_T(op, int64) \
3661DEFN_ASN_OP_T(op, uint64) \
3662DEFN_ASN_OP_T(op, const sc_int_base &) \
3663DEFN_ASN_OP_T(op, const sc_uint_base &) \
3664DEFN_ASN_OP_T(op, const sc_signed &) \
3665DEFN_ASN_OP_T(op, const sc_unsigned &)
3666
3667#define DEFN_ASN_OP(op) \
3668inline sc_fxnum_fast & \
3669sc_fxnum_fast::operator op (const sc_fxnum_fast &b) \
3670{ \
3671    SC_FXNUM_FAST_OBSERVER_READ_(*this) \
3672    SC_FXNUM_FAST_OBSERVER_READ_(b) \
3673    m_val op b.m_val; \
3674    cast(); \
3675    SC_FXNUM_FAST_OBSERVER_WRITE_(*this) \
3676    return *this; \
3677} \
3678 \
3679inline sc_fxnum_fast & \
3680sc_fxnum_fast::operator op (const sc_fxval_fast &b) \
3681{ \
3682    SC_FXNUM_FAST_OBSERVER_READ_(*this) \
3683    m_val op b.get_val(); \
3684    cast(); \
3685    SC_FXNUM_FAST_OBSERVER_WRITE_(*this) \
3686    return *this; \
3687} \
3688 \
3689DEFN_ASN_OP_T(op, int) \
3690DEFN_ASN_OP_T(op, unsigned int) \
3691DEFN_ASN_OP_T(op, long) \
3692DEFN_ASN_OP_T(op, unsigned long) \
3693DEFN_ASN_OP_T(op, float) \
3694DEFN_ASN_OP_T(op, double) \
3695DEFN_ASN_OP_T(op, const char *) \
3696DEFN_ASN_OP_T(op, const sc_fxval &) \
3697DEFN_ASN_OP_T(op, const sc_fxnum &) \
3698DEFN_ASN_OP_OTHER(op)
3699
3700DEFN_ASN_OP(*=)
3701DEFN_ASN_OP(/=)
3702DEFN_ASN_OP(+=)
3703DEFN_ASN_OP(-=)
3704
3705#undef DEFN_ASN_OP_T
3706#undef DEFN_ASN_OP_OTHER
3707#undef DEFN_ASN_OP
3708
3709inline sc_fxnum_fast &
3710sc_fxnum_fast::operator <<= (int b)
3711{
3712    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3713    m_val *= scfx_pow2(b);
3714    cast();
3715    SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3716    return *this;
3717}
3718
3719inline sc_fxnum_fast &
3720sc_fxnum_fast::operator >>= (int b)
3721{
3722    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3723    m_val *= scfx_pow2(-b);
3724    cast();
3725    SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3726    return *this;
3727}
3728
3729// auto-increment and auto-decrement
3730inline const sc_fxval_fast
3731sc_fxnum_fast::operator ++ (int)
3732{
3733    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3734    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3735    double c = m_val;
3736    m_val = m_val + 1;
3737    cast();
3738    SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3739    return sc_fxval_fast(c);
3740}
3741
3742inline const sc_fxval_fast
3743sc_fxnum_fast::operator -- (int)
3744{
3745    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3746    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3747    double c = m_val;
3748    m_val = m_val - 1;
3749    cast();
3750    SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3751    return sc_fxval_fast(c);
3752}
3753
3754inline sc_fxnum_fast &
3755sc_fxnum_fast::operator ++ ()
3756{
3757    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3758    m_val = m_val + 1;
3759    cast();
3760    SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3761    return *this;
3762}
3763
3764inline sc_fxnum_fast &
3765sc_fxnum_fast::operator -- ()
3766{
3767    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3768    m_val = m_val - 1;
3769    cast();
3770    SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3771    return *this;
3772}
3773
3774// bit selection
3775inline const sc_fxnum_fast_bitref
3776sc_fxnum_fast::operator [] (int i) const
3777{
3778    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3779    return sc_fxnum_fast_bitref(const_cast<sc_fxnum_fast &>(*this),
3780                                i - m_params.fwl());
3781}
3782
3783inline sc_fxnum_fast_bitref
3784sc_fxnum_fast::operator [] (int i)
3785{
3786    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3787    return sc_fxnum_fast_bitref(*this, i - m_params.fwl());
3788}
3789
3790inline const sc_fxnum_fast_bitref
3791sc_fxnum_fast::bit(int i) const
3792{
3793    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3794    return sc_fxnum_fast_bitref(const_cast<sc_fxnum_fast &>(*this),
3795                                i - m_params.fwl());
3796}
3797
3798inline sc_fxnum_fast_bitref
3799sc_fxnum_fast::bit(int i)
3800{
3801    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3802    return sc_fxnum_fast_bitref(*this, i - m_params.fwl());
3803}
3804
3805// part selection
3806inline const sc_fxnum_fast_subref
3807sc_fxnum_fast::operator () (int i, int j) const
3808{
3809    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3810    SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
3811
3812    return sc_fxnum_fast_subref(const_cast<sc_fxnum_fast &>(*this),
3813                                i - m_params.fwl(), j - m_params.fwl());
3814}
3815
3816inline sc_fxnum_fast_subref
3817sc_fxnum_fast::operator () (int i, int j)
3818{
3819    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3820    SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
3821
3822    return sc_fxnum_fast_subref(*this, i - m_params.fwl(), j - m_params.fwl());
3823}
3824
3825inline const sc_fxnum_fast_subref
3826sc_fxnum_fast::range(int i, int j) const
3827{
3828    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3829    SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
3830
3831    return sc_fxnum_fast_subref(const_cast<sc_fxnum_fast &>(*this),
3832                                i - m_params.fwl(), j - m_params.fwl());
3833}
3834
3835inline sc_fxnum_fast_subref
3836sc_fxnum_fast::range(int i, int j)
3837{
3838    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3839    SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
3840
3841    return sc_fxnum_fast_subref(*this, i - m_params.fwl(), j - m_params.fwl());
3842}
3843
3844inline const sc_fxnum_fast_subref
3845sc_fxnum_fast::operator () () const
3846{
3847    return this->operator () (m_params.wl() - 1, 0);
3848}
3849
3850inline sc_fxnum_fast_subref
3851sc_fxnum_fast::operator () ()
3852{
3853    return this->operator () (m_params.wl() - 1, 0);
3854}
3855
3856inline const sc_fxnum_fast_subref
3857sc_fxnum_fast::range() const
3858{
3859    return this->range(m_params.wl() - 1, 0);
3860}
3861
3862inline sc_fxnum_fast_subref
3863sc_fxnum_fast::range()
3864{
3865    return this->range(m_params.wl() - 1, 0);
3866}
3867
3868// implicit conversion
3869inline sc_fxnum_fast::operator double() const
3870{
3871    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3872    return m_val;
3873}
3874
3875// explicit conversion to primitive types
3876inline short
3877sc_fxnum_fast::to_short() const
3878{
3879    // SC_FXNUM_FAST_OBSERVER_READ_ in to_uint64
3880    return static_cast<short>(to_uint64());
3881}
3882
3883inline unsigned short
3884sc_fxnum_fast::to_ushort() const
3885{
3886    // SC_FXNUM_FAST_OBSERVER_READ_ in to_uint64
3887    return static_cast<unsigned short>(to_uint64());
3888}
3889
3890inline int
3891sc_fxnum_fast::to_int() const
3892{
3893    // SC_FXNUM_FAST_OBSERVER_READ_ in to_uint64
3894    return static_cast<int>(to_uint64());
3895}
3896
3897inline int64
3898sc_fxnum_fast::to_int64() const
3899{
3900    // SC_FXNUM_FAST_OBSERVER_READ_ in to_uint64
3901    return static_cast<int64>(to_uint64());
3902}
3903
3904inline unsigned int
3905sc_fxnum_fast::to_uint() const
3906{
3907    // SC_FXNUM_FAST_OBSERVER_READ_ in to_uint64
3908    return static_cast<unsigned int>(to_uint64());
3909}
3910
3911inline uint64
3912sc_fxnum_fast::to_uint64() const
3913{
3914    // SC_FXNUM_FAST_OBSERVER_READ_ in is_normal
3915    if (!is_normal()) {
3916        return 0;
3917    }
3918
3919    int exponent;
3920    double mantissa_dbl = frexp(m_val, &exponent);
3921
3922    uint64 mantissa = static_cast<uint64>(fabs(mantissa_dbl) *
3923                                          (UINT64_ONE << 53));
3924    exponent -= 53;
3925
3926    if (!(-64 < exponent && exponent < 64)) {
3927        return 0;
3928    }
3929
3930    mantissa = exponent >= 0 ? mantissa << exponent : mantissa >> -exponent;
3931    return mantissa_dbl >= 0 ? mantissa : -mantissa;
3932}
3933
3934inline long
3935sc_fxnum_fast::to_long() const
3936{
3937    // SC_FXNUM_FAST_OBSERVER_READ_ in to_uint64
3938    return static_cast<long>(to_uint64());
3939}
3940
3941inline unsigned long
3942sc_fxnum_fast::to_ulong() const
3943{
3944    // SC_FXNUM_FAST_OBSERVER_READ_ in to_uint64
3945    return static_cast<unsigned long>(to_uint64());
3946}
3947
3948inline float
3949sc_fxnum_fast::to_float() const
3950{
3951    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3952    return static_cast<float>(m_val);
3953}
3954
3955inline double
3956sc_fxnum_fast::to_double() const
3957{
3958    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3959    return m_val;
3960}
3961
3962// query value
3963inline bool
3964sc_fxnum_fast::is_neg() const
3965{
3966    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3967    scfx_ieee_double id(m_val);
3968    return (id.negative() != 0);
3969}
3970
3971inline bool
3972sc_fxnum_fast::is_zero() const
3973{
3974    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3975    scfx_ieee_double id(m_val);
3976    return id.is_zero();
3977}
3978
3979// internal use only;
3980inline bool
3981sc_fxnum_fast::is_normal() const
3982{
3983    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3984    scfx_ieee_double id(m_val);
3985    return (id.is_normal() || id.is_subnormal() || id.is_zero());
3986}
3987
3988inline bool
3989sc_fxnum_fast::quantization_flag() const
3990{
3991    return m_q_flag;
3992}
3993
3994inline bool
3995sc_fxnum_fast::overflow_flag() const
3996{
3997    return m_o_flag;
3998}
3999
4000inline const sc_fxval_fast
4001sc_fxnum_fast::value() const
4002{
4003    SC_FXNUM_FAST_OBSERVER_READ_(*this)
4004    return sc_fxval_fast(m_val);
4005}
4006
4007// query parameters
4008inline int
4009sc_fxnum_fast::wl() const
4010{
4011    return m_params.wl();
4012}
4013
4014inline int
4015sc_fxnum_fast::iwl() const
4016{
4017    return m_params.iwl();
4018}
4019
4020inline sc_q_mode
4021sc_fxnum_fast::q_mode() const
4022{
4023    return m_params.q_mode();
4024}
4025
4026inline sc_o_mode
4027sc_fxnum_fast::o_mode() const
4028{
4029    return m_params.o_mode();
4030}
4031
4032inline int
4033sc_fxnum_fast::n_bits() const
4034{
4035    return m_params.n_bits();
4036}
4037
4038inline const sc_fxtype_params &
4039sc_fxnum_fast::type_params() const
4040{
4041    return m_params.type_params();
4042}
4043
4044inline const sc_fxcast_switch &
4045sc_fxnum_fast::cast_switch() const
4046{
4047    return m_params.cast_switch();
4048}
4049
4050// internal use only;
4051inline void
4052sc_fxnum_fast::observer_read() const
4053{
4054    SC_FXNUM_FAST_OBSERVER_READ_(*this);
4055}
4056
4057inline ::std::ostream &
4058operator << (::std::ostream &os, const sc_fxnum_fast &a)
4059{
4060    a.print(os);
4061    return os;
4062}
4063
4064inline ::std::istream &
4065operator >> (::std::istream &is, sc_fxnum_fast &a)
4066{
4067    a.scan(is);
4068    return is;
4069}
4070
4071
4072// ----------------------------------------------------------------------------
4073// CLASS : sc_fxval
4074//
4075// Fixed-point value type; arbitrary precision.
4076// ----------------------------------------------------------------------------
4077
4078// public constructors
4079inline sc_fxval::sc_fxval(const sc_fxnum &a, sc_fxval_observer *observer_) :
4080        m_rep(new scfx_rep(*a.get_rep())), m_observer(observer_)
4081{
4082    SC_FXVAL_OBSERVER_DEFAULT_
4083    SC_FXVAL_OBSERVER_CONSTRUCT_(*this)
4084    SC_FXVAL_OBSERVER_WRITE_(*this)
4085}
4086
4087inline sc_fxval::sc_fxval(const sc_fxnum_fast &a,
4088                          sc_fxval_observer *observer_) :
4089    m_rep(new scfx_rep(a.to_double())), m_observer(observer_)
4090{
4091    SC_FXVAL_OBSERVER_DEFAULT_
4092    SC_FXVAL_OBSERVER_CONSTRUCT_(*this)
4093    SC_FXVAL_OBSERVER_WRITE_(*this)
4094}
4095
4096// binary operators
4097#define DEFN_BIN_OP_T(op, fnc, tp) \
4098inline const sc_fxval \
4099operator op (const sc_fxval &a, tp b) \
4100{ \
4101    SC_FXVAL_OBSERVER_READ_(a) \
4102    sc_fxval tmp(b); \
4103    return sc_fxval(sc_dt::fnc ## _scfx_rep(*a.m_rep, *tmp.m_rep)); \
4104} \
4105 \
4106inline const sc_fxval \
4107operator op (tp a, const sc_fxval &b) \
4108{ \
4109    SC_FXVAL_OBSERVER_READ_(b) \
4110    sc_fxval tmp(a); \
4111    return sc_fxval(sc_dt::fnc ## _scfx_rep(*tmp.m_rep, *b.m_rep)); \
4112}
4113
4114#define DEFN_BIN_OP(op, fnc) \
4115DEFN_BIN_OP_T(op, fnc, const sc_fxnum_fast &)
4116
4117DEFN_BIN_OP(*, mult)
4118DEFN_BIN_OP(+, add)
4119DEFN_BIN_OP(-, sub)
4120//DEFN_BIN_OP(/, div)
4121DEFN_BIN_OP_T(/, div, const sc_fxnum_fast &)
4122
4123#undef DEFN_BIN_OP_T
4124#undef DEFN_BIN_OP
4125
4126
4127// binary functions
4128#define DEFN_BIN_FNC_T(fnc, tp) \
4129inline void \
4130fnc (sc_fxval &c, const sc_fxval &a, tp b) \
4131{ \
4132    SC_FXVAL_OBSERVER_READ_(a) \
4133    sc_fxval tmp(b); \
4134    delete c.m_rep; \
4135    c.m_rep = sc_dt::fnc ## _scfx_rep(*a.m_rep, *tmp.m_rep); \
4136    SC_FXVAL_OBSERVER_WRITE_(c) \
4137} \
4138 \
4139inline void \
4140fnc (sc_fxval &c, tp a, const sc_fxval &b) \
4141{ \
4142    SC_FXVAL_OBSERVER_READ_(b) \
4143    sc_fxval tmp(a); \
4144    delete c.m_rep; \
4145    c.m_rep = sc_dt::fnc ## _scfx_rep(*tmp.m_rep, *b.m_rep); \
4146    SC_FXVAL_OBSERVER_WRITE_(c) \
4147}
4148
4149#define DEFN_BIN_FNC(fnc) \
4150DEFN_BIN_FNC_T(fnc, const sc_fxnum_fast &)
4151
4152DEFN_BIN_FNC(mult)
4153DEFN_BIN_FNC(div)
4154DEFN_BIN_FNC(add)
4155DEFN_BIN_FNC(sub)
4156
4157#undef DEFN_BIN_FNC_T
4158#undef DEFN_BIN_FNC
4159
4160
4161// relational (including equality) operators
4162#define DEFN_REL_OP_T(op, ret, tp) \
4163inline bool \
4164operator op (const sc_fxval &a, tp b) \
4165{ \
4166    SC_FXVAL_OBSERVER_READ_(a) \
4167    sc_fxval tmp(b); \
4168    int result = sc_dt::cmp_scfx_rep(*a.m_rep, *tmp.m_rep); \
4169    return (ret); \
4170} \
4171 \
4172inline bool \
4173operator op (tp a, const sc_fxval &b) \
4174{ \
4175    SC_FXVAL_OBSERVER_READ_(b) \
4176    sc_fxval tmp(a); \
4177    int result = sc_dt::cmp_scfx_rep(*tmp.m_rep, *b.m_rep); \
4178    return (ret); \
4179}
4180
4181#define DEFN_REL_OP(op, ret) \
4182DEFN_REL_OP_T(op, ret, const sc_fxnum_fast &)
4183
4184DEFN_REL_OP(<, result < 0)
4185DEFN_REL_OP(<=, result <= 0)
4186DEFN_REL_OP(>, result > 0 && result != 2)
4187DEFN_REL_OP(>=, result >= 0 && result != 2)
4188DEFN_REL_OP(==, result == 0)
4189DEFN_REL_OP(!=, result != 0)
4190
4191#undef DEFN_REL_OP_T
4192#undef DEFN_REL_OP
4193
4194// assignment operators
4195inline sc_fxval &
4196sc_fxval::operator = (const sc_fxnum &a)
4197{
4198    *m_rep = *a.get_rep();
4199    SC_FXVAL_OBSERVER_WRITE_(*this)
4200    return *this;
4201}
4202
4203#define DEFN_ASN_OP_T(tp) \
4204inline sc_fxval & \
4205sc_fxval::operator = (tp b) \
4206{ \
4207    sc_fxval tmp(b); \
4208    *m_rep = *tmp.m_rep; \
4209    SC_FXVAL_OBSERVER_WRITE_(*this) \
4210    return *this; \
4211}
4212
4213DEFN_ASN_OP_T(const sc_fxnum_fast &)
4214
4215#undef DEFN_ASN_OP_T
4216
4217#define DEFN_ASN_OP_T(op, fnc, tp) \
4218inline sc_fxval & \
4219sc_fxval::operator op (tp b) \
4220{ \
4221    SC_FXVAL_OBSERVER_READ_(*this) \
4222    sc_fxval tmp(b); \
4223    scfx_rep *new_rep = sc_dt::fnc ## _scfx_rep(*m_rep, *tmp.m_rep); \
4224    delete m_rep; \
4225    m_rep = new_rep; \
4226    SC_FXVAL_OBSERVER_WRITE_(*this) \
4227    return *this; \
4228}
4229
4230#define DEFN_ASN_OP(op, fnc) \
4231inline sc_fxval & \
4232sc_fxval::operator op (const sc_fxnum &b) \
4233{ \
4234    SC_FXVAL_OBSERVER_READ_(*this) \
4235    scfx_rep *new_rep = sc_dt::fnc ## _scfx_rep(*m_rep, *b.get_rep()); \
4236    delete m_rep; \
4237    m_rep = new_rep; \
4238    SC_FXVAL_OBSERVER_WRITE_(*this) \
4239    return *this; \
4240} \
4241 \
4242DEFN_ASN_OP_T(op, fnc, const sc_fxnum_fast &)
4243
4244DEFN_ASN_OP(*=, mult)
4245DEFN_ASN_OP(/=, div)
4246DEFN_ASN_OP(+=, add)
4247DEFN_ASN_OP(-=, sub)
4248
4249#undef DEFN_ASN_OP_T
4250#undef DEFN_ASN_OP
4251
4252
4253// ----------------------------------------------------------------------------
4254// CLASS : sc_fxval_fast
4255//
4256// Fixed-point value types; limited precision.
4257// ----------------------------------------------------------------------------
4258
4259// public constructors
4260
4261inline
4262sc_fxval_fast::sc_fxval_fast(const sc_fxnum &a,
4263                              sc_fxval_fast_observer *observer_) :
4264    m_val(a.to_double()), m_observer(observer_)
4265{
4266    SC_FXVAL_FAST_OBSERVER_DEFAULT_
4267    SC_FXVAL_FAST_OBSERVER_CONSTRUCT_(*this)
4268    SC_FXVAL_FAST_OBSERVER_WRITE_(*this)
4269}
4270
4271inline sc_fxval_fast::sc_fxval_fast(const sc_fxnum_fast &a,
4272                                    sc_fxval_fast_observer *observer_) :
4273    m_val(a.get_val()), m_observer(observer_)
4274{
4275    SC_FXVAL_FAST_OBSERVER_DEFAULT_
4276    SC_FXVAL_FAST_OBSERVER_CONSTRUCT_(*this)
4277    SC_FXVAL_FAST_OBSERVER_WRITE_(*this)
4278}
4279
4280
4281// binary functions
4282#define DEFN_BIN_FNC_T(fnc, op, tp) \
4283inline void \
4284fnc (sc_fxval_fast &c, const sc_fxval_fast &a, tp b) \
4285{ \
4286    SC_FXVAL_FAST_OBSERVER_READ_(a) \
4287    sc_fxval_fast tmp(b); \
4288    c.m_val = a.m_val op tmp.m_val; \
4289    SC_FXVAL_FAST_OBSERVER_WRITE_(c) \
4290} \
4291 \
4292inline void \
4293fnc (sc_fxval_fast &c, tp a, const sc_fxval_fast &b) \
4294{ \
4295    SC_FXVAL_FAST_OBSERVER_READ_(b) \
4296    sc_fxval_fast tmp(a); \
4297    c.m_val = tmp.m_val op b.m_val; \
4298    SC_FXVAL_FAST_OBSERVER_WRITE_(c) \
4299}
4300
4301#define DEFN_BIN_FNC(fnc, op) \
4302DEFN_BIN_FNC_T(fnc, op, const sc_fxval &) \
4303DEFN_BIN_FNC_T(fnc, op, const sc_fxnum &)
4304
4305DEFN_BIN_FNC(mult, *)
4306DEFN_BIN_FNC(div, /)
4307DEFN_BIN_FNC(add, +)
4308DEFN_BIN_FNC(sub, -)
4309
4310#undef DEFN_BIN_FNC_T
4311#undef DEFN_BIN_FNC
4312
4313
4314// assignment operators
4315inline sc_fxval_fast &
4316sc_fxval_fast::operator = (const sc_fxnum_fast &a)
4317{
4318    m_val = a.get_val();
4319    SC_FXVAL_FAST_OBSERVER_WRITE_(*this)
4320    return *this;
4321}
4322
4323#define DEFN_ASN_OP_T(tp) \
4324inline sc_fxval_fast & \
4325sc_fxval_fast::operator = (tp a) \
4326{ \
4327    sc_fxval_fast tmp(a); \
4328    m_val = tmp.m_val; \
4329    SC_FXVAL_FAST_OBSERVER_WRITE_(*this) \
4330    return *this; \
4331}
4332
4333DEFN_ASN_OP_T(const sc_fxnum &)
4334
4335#undef DEFN_ASN_OP_T
4336
4337#define DEFN_ASN_OP_T(op, tp) \
4338inline sc_fxval_fast & \
4339sc_fxval_fast::operator op (tp b) \
4340{ \
4341    SC_FXVAL_FAST_OBSERVER_READ_(*this) \
4342    sc_fxval_fast tmp(b); \
4343    m_val op tmp.m_val; \
4344    SC_FXVAL_FAST_OBSERVER_WRITE_(*this) \
4345    return *this; \
4346}
4347
4348#define DEFN_ASN_OP(op) \
4349inline sc_fxval_fast & \
4350sc_fxval_fast::operator op (const sc_fxnum_fast &b) \
4351{ \
4352    SC_FXVAL_FAST_OBSERVER_READ_(*this) \
4353    m_val op b.get_val(); \
4354    SC_FXVAL_FAST_OBSERVER_WRITE_(*this) \
4355    return *this; \
4356} \
4357 \
4358DEFN_ASN_OP_T(op, const sc_fxnum &)
4359
4360DEFN_ASN_OP(*=)
4361DEFN_ASN_OP(/=)
4362DEFN_ASN_OP(+=)
4363DEFN_ASN_OP(-=)
4364
4365#undef DEFN_ASN_OP_T
4366#undef DEFN_ASN_OP
4367
4368} // namespace sc_dt
4369
4370#endif // __SYSTEMC_EXT_DT_FX_SC_FXNUM_HH__
4371