sc_fxnum.hh revision 13245:c666c5d4996b
1/*****************************************************************************
2
3  Licensed to Accellera Systems Initiative Inc. (Accellera) under one or
4  more contributor license agreements.  See the NOTICE file distributed
5  with this work for additional information regarding copyright ownership.
6  Accellera licenses this file to you under the Apache License, Version 2.0
7  (the "License"); you may not use this file except in compliance with the
8  License.  You may obtain a copy of the License at
9
10    http://www.apache.org/licenses/LICENSE-2.0
11
12  Unless required by applicable law or agreed to in writing, software
13  distributed under the License is distributed on an "AS IS" BASIS,
14  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
15  implied.  See the License for the specific language governing
16  permissions and limitations under the License.
17
18 *****************************************************************************/
19
20/*****************************************************************************
21
22  sc_fxnum.h -
23
24  Original Author: Martin Janssen, Synopsys, Inc.
25
26 *****************************************************************************/
27
28/*****************************************************************************
29
30  MODIFICATION LOG - modifiers, enter your name, affiliation, date and
31  changes you are making here.
32
33      Name, Affiliation, Date:
34  Description of Modification:
35
36 *****************************************************************************/
37
38// $Log: sc_fxnum.h,v $
39// Revision 1.5  2011/08/29 18:04:32  acg
40//  Philipp A. Hartmann: miscellaneous clean ups.
41//
42// Revision 1.4  2011/08/24 22:05:43  acg
43//  Torsten Maehne: initialization changes to remove warnings.
44//
45// Revision 1.3  2011/01/19 18:57:40  acg
46//  Andy Goodrich: changes for IEEE_1666_2011.
47//
48// Revision 1.2  2009/03/09 17:26:46  acg
49//  Andy Goodrich: removed ; from namespace { }
50//
51// Revision 1.1.1.1  2006/12/15 20:20:04  acg
52// SystemC 2.3
53//
54// Revision 1.3  2006/01/13 18:53:58  acg
55// Andy Goodrich: added $Log command so that CVS comments are reproduced in
56// the source.
57//
58
59#ifndef __SYSTEMC_EXT_DT_FX_SC_FXNUM_HH__
60#define __SYSTEMC_EXT_DT_FX_SC_FXNUM_HH__
61
62#include <iostream>
63
64#include "../bit/sc_lv_base.hh"
65#include "sc_fxnum_observer.hh"
66#include "sc_fxval.hh"
67#include "scfx_params.hh"
68
69namespace sc_gem5
70{
71
72template <typename T, typename B>
73class TraceValFxnumBase;
74
75} // namespace sc_core
76
77
78namespace sc_dt
79{
80
81// classes defined in this module
82class sc_fxnum_bitref;
83class sc_fxnum_fast_bitref;
84class sc_fxnum_subref;
85class sc_fxnum_fast_subref;
86class sc_fxnum;
87class sc_fxnum_fast;
88
89
90// ----------------------------------------------------------------------------
91// CLASS : sc_fxnum_bitref
92//
93// Proxy class for bit-selection in class sc_fxnum, behaves like sc_bit.
94// ----------------------------------------------------------------------------
95
96class sc_fxnum_bitref
97{
98    friend class sc_fxnum;
99    friend class sc_fxnum_fast_bitref;
100
101    bool get() const;
102    void set(bool);
103
104    // constructor
105    sc_fxnum_bitref(sc_fxnum &, int);
106
107  public:
108    // copy constructor
109    sc_fxnum_bitref(const sc_fxnum_bitref &);
110
111    // assignment operators
112#define DECL_ASN_OP_T(op, tp) \
113    sc_fxnum_bitref &operator op (tp);
114
115#define DECL_ASN_OP(op) \
116    DECL_ASN_OP_T(op, const sc_fxnum_bitref &) \
117    DECL_ASN_OP_T(op, const sc_fxnum_fast_bitref &) \
118    DECL_ASN_OP_T(op, const sc_bit &) \
119    DECL_ASN_OP_T(op, bool)
120
121    DECL_ASN_OP(=)
122
123    DECL_ASN_OP(&=)
124    DECL_ASN_OP(|=)
125    DECL_ASN_OP(^=)
126
127#undef DECL_ASN_OP_T
128#undef DECL_ASN_OP
129
130    // implicit conversion
131    operator bool() const;
132
133    // print or dump content
134    void print(::std::ostream & =::std::cout) const;
135    void scan(::std::istream & =::std::cin);
136    void dump(::std::ostream & =::std::cout) const;
137
138  private:
139    sc_fxnum &m_num;
140    int m_idx;
141
142  private:
143    // disabled
144    sc_fxnum_bitref();
145};
146
147
148// ----------------------------------------------------------------------------
149// CLASS : sc_fxnum_fast_bitref
150//
151// Proxy class for bit-selection in class sc_fxnum_fast, behaves like sc_bit.
152// ----------------------------------------------------------------------------
153
154class sc_fxnum_fast_bitref
155{
156    friend class sc_fxnum_fast;
157    friend class sc_fxnum_bitref;
158
159    bool get() const;
160    void set(bool);
161
162    // constructor
163    sc_fxnum_fast_bitref(sc_fxnum_fast &, int);
164
165  public:
166    // copy constructor
167    sc_fxnum_fast_bitref(const sc_fxnum_fast_bitref &);
168
169    // assignment operators
170#define DECL_ASN_OP_T(op, tp) sc_fxnum_fast_bitref &operator op (tp);
171
172#define DECL_ASN_OP(op) \
173    DECL_ASN_OP_T(op, const sc_fxnum_bitref &) \
174    DECL_ASN_OP_T(op, const sc_fxnum_fast_bitref &) \
175    DECL_ASN_OP_T(op, const sc_bit &) \
176    DECL_ASN_OP_T(op, bool)
177
178    DECL_ASN_OP(=)
179
180    DECL_ASN_OP(&=)
181    DECL_ASN_OP(|=)
182    DECL_ASN_OP(^=)
183
184#undef DECL_ASN_OP_T
185#undef DECL_ASN_OP
186
187    // implicit conversion
188    operator bool() const;
189
190    // print or dump content
191    void print(::std::ostream & =::std::cout) const;
192    void scan(::std::istream & =::std::cin);
193    void dump(::std::ostream & =::std::cout) const;
194
195  private:
196    sc_fxnum_fast &m_num;
197    int m_idx;
198
199  private:
200    // Disabled
201    sc_fxnum_fast_bitref();
202};
203
204
205// ----------------------------------------------------------------------------
206// CLASS : sc_fxnum_subref
207//
208// Proxy class for part-selection in class sc_fxnum,
209// behaves like sc_bv_base.
210// ----------------------------------------------------------------------------
211
212class sc_fxnum_subref
213{
214    friend class sc_fxnum;
215    friend class sc_fxnum_fast_subref;
216
217    bool get() const;
218    bool set();
219
220    // constructor
221    sc_fxnum_subref(sc_fxnum &, int, int);
222
223  public:
224    // copy constructor
225    sc_fxnum_subref(const sc_fxnum_subref &);
226
227    // destructor
228    ~sc_fxnum_subref();
229
230    // assignment operators
231#define DECL_ASN_OP_T(tp) \
232    sc_fxnum_subref &operator = (tp);
233
234    DECL_ASN_OP_T(const sc_fxnum_subref &)
235    DECL_ASN_OP_T(const sc_fxnum_fast_subref &)
236    DECL_ASN_OP_T(const sc_bv_base &)
237    DECL_ASN_OP_T(const sc_lv_base &)
238    DECL_ASN_OP_T(const char *)
239    DECL_ASN_OP_T(const bool *)
240    DECL_ASN_OP_T(const sc_signed &)
241    DECL_ASN_OP_T(const sc_unsigned &)
242    DECL_ASN_OP_T(const sc_int_base &)
243    DECL_ASN_OP_T(const sc_uint_base &)
244    DECL_ASN_OP_T(int64)
245    DECL_ASN_OP_T(uint64)
246    DECL_ASN_OP_T(int)
247    DECL_ASN_OP_T(unsigned int)
248    DECL_ASN_OP_T(long)
249    DECL_ASN_OP_T(unsigned long)
250    DECL_ASN_OP_T(char)
251
252#undef DECL_ASN_OP_T
253
254#define DECL_ASN_OP_T_A(op, tp) \
255    sc_fxnum_subref &operator op ## = (tp);
256
257#define DECL_ASN_OP_A(op) \
258    DECL_ASN_OP_T_A(op, const sc_fxnum_subref &) \
259    DECL_ASN_OP_T_A(op, const sc_fxnum_fast_subref &) \
260    DECL_ASN_OP_T_A(op, const sc_bv_base &) \
261    DECL_ASN_OP_T_A(op, const sc_lv_base &)
262
263    DECL_ASN_OP_A( &)
264    DECL_ASN_OP_A(|)
265    DECL_ASN_OP_A(^)
266
267#undef DECL_ASN_OP_T_A
268#undef DECL_ASN_OP_A
269
270    // relational operators
271#define DECL_REL_OP_T(op, tp) \
272    friend bool operator op (const sc_fxnum_subref &, tp); \
273    friend bool operator op (tp, const sc_fxnum_subref &);
274
275#define DECL_REL_OP(op) \
276    friend bool operator op (const sc_fxnum_subref &, \
277                             const sc_fxnum_subref &); \
278    friend bool operator op (const sc_fxnum_subref &, \
279                             const sc_fxnum_fast_subref &); \
280    DECL_REL_OP_T(op, const sc_bv_base &) \
281    DECL_REL_OP_T(op, const sc_lv_base &) \
282    DECL_REL_OP_T(op, const char *) \
283    DECL_REL_OP_T(op, const bool *) \
284    DECL_REL_OP_T(op, const sc_signed &) \
285    DECL_REL_OP_T(op, const sc_unsigned &) \
286    DECL_REL_OP_T(op, int) \
287    DECL_REL_OP_T(op, unsigned int) \
288    DECL_REL_OP_T(op, long) \
289    DECL_REL_OP_T(op, unsigned long)
290
291    DECL_REL_OP(==)
292    DECL_REL_OP(!=)
293
294#undef DECL_REL_OP_T
295#undef DECL_REL_OP
296
297    // reduce functions
298    bool and_reduce() const;
299    bool nand_reduce() const;
300    bool or_reduce() const;
301    bool nor_reduce() const;
302    bool xor_reduce() const;
303    bool xnor_reduce() const;
304
305    // query parameter
306    int length() const;
307
308    // explicit conversions
309    int to_int() const;
310    unsigned int to_uint() const;
311    long to_long() const;
312    unsigned long to_ulong() const;
313    int64 to_int64() const;
314    uint64 to_uint64() const;
315
316    const std::string to_string() const;
317    const std::string to_string(sc_numrep) const;
318    const std::string to_string(sc_numrep, bool) const;
319
320    // implicit conversion
321    operator sc_bv_base() const;
322
323    // print or dump content
324    void print(::std::ostream & =::std::cout) const;
325    void scan(::std::istream & =::std::cin);
326    void dump(::std::ostream & =::std::cout) const;
327
328  private:
329    sc_fxnum &m_num;
330    int m_from;
331    int m_to;
332
333    sc_bv_base &m_bv;
334
335  private:
336    // Disabled
337    sc_fxnum_subref();
338};
339
340
341// ----------------------------------------------------------------------------
342// CLASS : sc_fxnum_fast_subref
343//
344// Proxy class for part-selection in class sc_fxnum_fast,
345// behaves like sc_bv_base.
346// ----------------------------------------------------------------------------
347
348class sc_fxnum_fast_subref
349{
350    friend class sc_fxnum_fast;
351    friend class sc_fxnum_subref;
352
353    bool get() const;
354    bool set();
355
356    // constructor
357    sc_fxnum_fast_subref(sc_fxnum_fast &, int, int);
358
359  public:
360    // copy constructor
361    sc_fxnum_fast_subref(const sc_fxnum_fast_subref &);
362
363    // destructor
364    ~sc_fxnum_fast_subref();
365
366    // assignment operators
367#define DECL_ASN_OP_T(tp) \
368    sc_fxnum_fast_subref &operator = (tp);
369
370    DECL_ASN_OP_T(const sc_fxnum_subref &)
371    DECL_ASN_OP_T(const sc_fxnum_fast_subref &)
372    DECL_ASN_OP_T(const sc_bv_base &)
373    DECL_ASN_OP_T(const sc_lv_base &)
374    DECL_ASN_OP_T(const char *)
375    DECL_ASN_OP_T(const bool *)
376    DECL_ASN_OP_T(const sc_signed &)
377    DECL_ASN_OP_T(const sc_unsigned &)
378    DECL_ASN_OP_T(const sc_int_base &)
379    DECL_ASN_OP_T(const sc_uint_base &)
380    DECL_ASN_OP_T(int64)
381    DECL_ASN_OP_T(uint64)
382    DECL_ASN_OP_T(int)
383    DECL_ASN_OP_T(unsigned int)
384    DECL_ASN_OP_T(long)
385    DECL_ASN_OP_T(unsigned long)
386    DECL_ASN_OP_T(char)
387
388#undef DECL_ASN_OP_T
389
390#define DECL_ASN_OP_T_A(op, tp) sc_fxnum_fast_subref &operator op ## = (tp);
391
392#define DECL_ASN_OP_A(op) \
393    DECL_ASN_OP_T_A(op, const sc_fxnum_subref &) \
394    DECL_ASN_OP_T_A(op, const sc_fxnum_fast_subref &) \
395    DECL_ASN_OP_T_A(op, const sc_bv_base &) \
396    DECL_ASN_OP_T_A(op, const sc_lv_base &)
397
398    DECL_ASN_OP_A(&)
399    DECL_ASN_OP_A(|)
400    DECL_ASN_OP_A(^)
401
402#undef DECL_ASN_OP_T_A
403#undef DECL_ASN_OP_A
404
405    // relational operators
406#define DECL_REL_OP_T(op, tp) \
407    friend bool operator op (const sc_fxnum_fast_subref &, tp); \
408    friend bool operator op (tp, const sc_fxnum_fast_subref &);
409
410#define DECL_REL_OP(op) \
411    friend bool operator op (const sc_fxnum_fast_subref &, \
412                             const sc_fxnum_fast_subref &); \
413    friend bool operator op (const sc_fxnum_fast_subref &, \
414                             const sc_fxnum_subref &); \
415    DECL_REL_OP_T(op, const sc_bv_base &) \
416    DECL_REL_OP_T(op, const sc_lv_base &) \
417    DECL_REL_OP_T(op, const char *) \
418    DECL_REL_OP_T(op, const bool *) \
419    DECL_REL_OP_T(op, const sc_signed &) \
420    DECL_REL_OP_T(op, const sc_unsigned &) \
421    DECL_REL_OP_T(op, int) \
422    DECL_REL_OP_T(op, unsigned int) \
423    DECL_REL_OP_T(op, long) \
424    DECL_REL_OP_T(op, unsigned long)
425
426    DECL_REL_OP(==)
427    DECL_REL_OP(!=)
428
429#undef DECL_REL_OP_T
430#undef DECL_REL_OP
431
432    // reduce functions
433    bool and_reduce() const;
434    bool nand_reduce() const;
435    bool or_reduce() const;
436    bool nor_reduce() const;
437    bool xor_reduce() const;
438    bool xnor_reduce() const;
439
440    // query parameter
441    int length() const;
442
443    // explicit conversions
444    int to_int() const;
445    unsigned int to_uint() const;
446    long to_long() const;
447    unsigned long to_ulong() const;
448    int64 to_int64() const;
449    uint64 to_uint64() const;
450
451    const std::string to_string() const;
452    const std::string to_string(sc_numrep) const;
453    const std::string to_string(sc_numrep, bool) const;
454
455    // implicit conversion
456    operator sc_bv_base() const;
457
458    // print or dump content
459    void print(::std::ostream & =::std::cout) const;
460    void scan(::std::istream & =::std::cin);
461    void dump(::std::ostream & =::std::cout) const;
462
463  private:
464    sc_fxnum_fast &m_num;
465    int m_from;
466    int m_to;
467
468    sc_bv_base &m_bv;
469
470  private:
471    // Disabled
472    sc_fxnum_fast_subref();
473};
474
475
476// ----------------------------------------------------------------------------
477// CLASS : sc_fxnum
478//
479// Base class for the fixed-point types; arbitrary precision.
480// ----------------------------------------------------------------------------
481
482class sc_fxnum
483{
484    friend class sc_fxval;
485
486    friend class sc_fxnum_bitref;
487    friend class sc_fxnum_subref;
488    friend class sc_fxnum_fast_bitref;
489    friend class sc_fxnum_fast_subref;
490
491    template <typename T, typename B>
492    friend class sc_gem5::TraceValFxnumBase;
493
494  protected:
495    sc_fxnum_observer *observer() const;
496
497    void cast();
498
499    // constructors
500    sc_fxnum(const sc_fxtype_params &, sc_enc, const sc_fxcast_switch &,
501             sc_fxnum_observer *);
502
503#define DECL_CTOR_T(tp) \
504    sc_fxnum(tp, const sc_fxtype_params &, sc_enc, const sc_fxcast_switch &, \
505             sc_fxnum_observer *);
506
507    DECL_CTOR_T(int)
508    DECL_CTOR_T(unsigned int)
509    DECL_CTOR_T(long)
510    DECL_CTOR_T(unsigned long)
511    DECL_CTOR_T(float)
512    DECL_CTOR_T(double)
513    DECL_CTOR_T(const char *)
514    DECL_CTOR_T(const sc_fxval &)
515    DECL_CTOR_T(const sc_fxval_fast &)
516    DECL_CTOR_T(const sc_fxnum &)
517    DECL_CTOR_T(const sc_fxnum_fast &)
518
519    DECL_CTOR_T(int64)
520    DECL_CTOR_T(uint64)
521    DECL_CTOR_T(const sc_int_base &)
522    DECL_CTOR_T(const sc_uint_base &)
523    DECL_CTOR_T(const sc_signed &)
524    DECL_CTOR_T(const sc_unsigned &)
525
526#undef DECL_CTOR_T
527
528    ~sc_fxnum();
529
530    // internal use only;
531    const scfx_rep *get_rep() const;
532
533  public:
534    // unary operators
535    const sc_fxval operator - () const;
536    const sc_fxval operator + () const;
537
538    // unary functions
539    friend void neg(sc_fxval &, const sc_fxnum &);
540    friend void neg(sc_fxnum &, const sc_fxnum &);
541
542    // binary operators
543#define DECL_BIN_OP_T(op, tp) \
544    friend const sc_fxval operator op (const sc_fxnum &, tp); \
545    friend const sc_fxval operator op (tp, const sc_fxnum &);
546
547#define DECL_BIN_OP_OTHER(op) \
548    DECL_BIN_OP_T(op, int64) \
549    DECL_BIN_OP_T(op, uint64) \
550    DECL_BIN_OP_T(op, const sc_int_base &) \
551    DECL_BIN_OP_T(op, const sc_uint_base &) \
552    DECL_BIN_OP_T(op, const sc_signed &) \
553    DECL_BIN_OP_T(op, const sc_unsigned &)
554
555#define DECL_BIN_OP(op, dummy) \
556    friend const sc_fxval operator op (const sc_fxnum &, const sc_fxnum &); \
557    DECL_BIN_OP_T(op, int) \
558    DECL_BIN_OP_T(op, unsigned int) \
559    DECL_BIN_OP_T(op, long) \
560    DECL_BIN_OP_T(op, unsigned long) \
561    DECL_BIN_OP_T(op, float) \
562    DECL_BIN_OP_T(op, double) \
563    DECL_BIN_OP_T(op, const char *) \
564    DECL_BIN_OP_T(op, const sc_fxval &) \
565    DECL_BIN_OP_T(op, const sc_fxval_fast &) \
566    DECL_BIN_OP_T(op, const sc_fxnum_fast &) \
567    DECL_BIN_OP_OTHER(op)
568
569    DECL_BIN_OP(*, mult)
570    DECL_BIN_OP(+, add)
571    DECL_BIN_OP(-, sub)
572// don't use macros
573// DECL_BIN_OP(/, div)
574    friend const sc_fxval operator / (const sc_fxnum &, const sc_fxnum &);
575    DECL_BIN_OP_T(/, int)
576    DECL_BIN_OP_T(/, unsigned int)
577    DECL_BIN_OP_T(/, long)
578    DECL_BIN_OP_T(/, unsigned long)
579    DECL_BIN_OP_T(/, float)
580    DECL_BIN_OP_T(/, double)
581    DECL_BIN_OP_T(/, const char *)
582    DECL_BIN_OP_T(/, const sc_fxval &)
583    DECL_BIN_OP_T(/, const sc_fxval_fast &)
584    DECL_BIN_OP_T(/, const sc_fxnum_fast &)
585// DECL_BIN_OP_OTHER(op)
586
587    DECL_BIN_OP_T(/, int64)
588    DECL_BIN_OP_T(/, uint64)
589    DECL_BIN_OP_T(/, const sc_int_base &)
590    DECL_BIN_OP_T(/, const sc_uint_base &)
591    DECL_BIN_OP_T(/, const sc_signed &)
592    DECL_BIN_OP_T(/, const sc_unsigned &)
593
594#undef DECL_BIN_OP_T
595#undef DECL_BIN_OP_OTHER
596#undef DECL_BIN_OP
597
598    friend const sc_fxval operator << (const sc_fxnum &, int);
599    friend const sc_fxval operator >> (const sc_fxnum &, int);
600
601    // binary functions
602#define DECL_BIN_FNC_T(fnc, tp) \
603    friend void fnc (sc_fxval &, const sc_fxnum &, tp); \
604    friend void fnc (sc_fxval &, tp, const sc_fxnum &); \
605    friend void fnc (sc_fxnum &, const sc_fxnum &, tp); \
606    friend void fnc (sc_fxnum &, tp, const sc_fxnum &);
607
608#define DECL_BIN_FNC_OTHER(fnc) \
609    DECL_BIN_FNC_T(fnc, int64) \
610    DECL_BIN_FNC_T(fnc, uint64) \
611    DECL_BIN_FNC_T(fnc, const sc_int_base &) \
612    DECL_BIN_FNC_T(fnc, const sc_uint_base &) \
613    DECL_BIN_FNC_T(fnc, const sc_signed &) \
614    DECL_BIN_FNC_T(fnc, const sc_unsigned &)
615
616#define DECL_BIN_FNC(fnc) \
617    friend void fnc (sc_fxval &, const sc_fxnum &, const sc_fxnum &); \
618    friend void fnc (sc_fxnum &, const sc_fxnum &, const sc_fxnum &); \
619    DECL_BIN_FNC_T(fnc, int) \
620    DECL_BIN_FNC_T(fnc, unsigned int) \
621    DECL_BIN_FNC_T(fnc, long) \
622    DECL_BIN_FNC_T(fnc, unsigned long) \
623    DECL_BIN_FNC_T(fnc, float) \
624    DECL_BIN_FNC_T(fnc, double) \
625    DECL_BIN_FNC_T(fnc, const char *) \
626    DECL_BIN_FNC_T(fnc, const sc_fxval &) \
627    DECL_BIN_FNC_T(fnc, const sc_fxval_fast &) \
628    DECL_BIN_FNC_T(fnc, const sc_fxnum_fast &) \
629    DECL_BIN_FNC_OTHER(fnc)
630
631    DECL_BIN_FNC(mult)
632    DECL_BIN_FNC(div)
633    DECL_BIN_FNC(add)
634    DECL_BIN_FNC(sub)
635
636#undef DECL_BIN_FNC_T
637#undef DECL_BIN_FNC_OTHER
638#undef DECL_BIN_FNC
639
640    friend void lshift(sc_fxval &, const sc_fxnum &, int);
641    friend void rshift(sc_fxval &, const sc_fxnum &, int);
642    friend void lshift(sc_fxnum &, const sc_fxnum &, int);
643    friend void rshift(sc_fxnum &, const sc_fxnum &, int);
644
645    // relational (including equality) operators
646#define DECL_REL_OP_T(op, tp) \
647    friend bool operator op (const sc_fxnum &, tp); \
648    friend bool operator op (tp, const sc_fxnum &);
649
650#define DECL_REL_OP_OTHER(op) \
651    DECL_REL_OP_T(op, int64) \
652    DECL_REL_OP_T(op, uint64) \
653    DECL_REL_OP_T(op, const sc_int_base &) \
654    DECL_REL_OP_T(op, const sc_uint_base &) \
655    DECL_REL_OP_T(op, const sc_signed &) \
656    DECL_REL_OP_T(op, const sc_unsigned &)
657
658#define DECL_REL_OP(op) \
659    friend bool operator op (const sc_fxnum &, const sc_fxnum &); \
660    DECL_REL_OP_T(op, int) \
661    DECL_REL_OP_T(op, unsigned int) \
662    DECL_REL_OP_T(op, long) \
663    DECL_REL_OP_T(op, unsigned long) \
664    DECL_REL_OP_T(op, float) \
665    DECL_REL_OP_T(op, double) \
666    DECL_REL_OP_T(op, const char *) \
667    DECL_REL_OP_T(op, const sc_fxval &) \
668    DECL_REL_OP_T(op, const sc_fxval_fast &) \
669    DECL_REL_OP_T(op, const sc_fxnum_fast &) \
670    DECL_REL_OP_OTHER(op)
671
672    DECL_REL_OP(<)
673    DECL_REL_OP(<=)
674    DECL_REL_OP(>)
675    DECL_REL_OP(>=)
676    DECL_REL_OP(==)
677    DECL_REL_OP(!=)
678
679#undef DECL_REL_OP_T
680#undef DECL_REL_OP_OTHER
681#undef DECL_REL_OP
682
683    // assignment operators
684#define DECL_ASN_OP_T(op, tp) \
685    sc_fxnum &operator op(tp);
686
687#define DECL_ASN_OP_OTHER(op) \
688    DECL_ASN_OP_T(op, int64) \
689    DECL_ASN_OP_T(op, uint64) \
690    DECL_ASN_OP_T(op, const sc_int_base &) \
691    DECL_ASN_OP_T(op, const sc_uint_base &) \
692    DECL_ASN_OP_T(op, const sc_signed &) \
693    DECL_ASN_OP_T(op, const sc_unsigned &)
694
695#define DECL_ASN_OP(op) \
696    DECL_ASN_OP_T(op, int) \
697    DECL_ASN_OP_T(op, unsigned int) \
698    DECL_ASN_OP_T(op, long) \
699    DECL_ASN_OP_T(op, unsigned long) \
700    DECL_ASN_OP_T(op, float) \
701    DECL_ASN_OP_T(op, double) \
702    DECL_ASN_OP_T(op, const char *) \
703    DECL_ASN_OP_T(op, const sc_fxval &) \
704    DECL_ASN_OP_T(op, const sc_fxval_fast &) \
705    DECL_ASN_OP_T(op, const sc_fxnum &) \
706    DECL_ASN_OP_T(op, const sc_fxnum_fast &) \
707    DECL_ASN_OP_OTHER(op)
708
709    DECL_ASN_OP(=)
710
711    DECL_ASN_OP(*=)
712    DECL_ASN_OP(/=)
713    DECL_ASN_OP(+=)
714    DECL_ASN_OP(-=)
715
716    DECL_ASN_OP_T(<<=, int)
717    DECL_ASN_OP_T(>>=, int)
718
719#undef DECL_ASN_OP_T
720#undef DECL_ASN_OP_OTHER
721#undef DECL_ASN_OP
722
723    // auto-increment and auto-decrement
724    const sc_fxval operator ++ (int);
725    const sc_fxval operator -- (int);
726
727    sc_fxnum &operator ++ ();
728    sc_fxnum &operator -- ();
729
730    // bit selection
731    const sc_fxnum_bitref operator [] (int) const;
732    sc_fxnum_bitref operator [] (int);
733
734    const sc_fxnum_bitref bit(int) const;
735    sc_fxnum_bitref bit(int);
736
737    // part selection
738    const sc_fxnum_subref operator () (int, int) const;
739    sc_fxnum_subref operator () (int, int);
740
741    const sc_fxnum_subref range(int, int) const;
742    sc_fxnum_subref range(int, int);
743
744    const sc_fxnum_subref operator () () const;
745    sc_fxnum_subref operator () ();
746
747    const sc_fxnum_subref range() const;
748    sc_fxnum_subref range();
749
750    // implicit conversion
751    operator double() const; // necessary evil!
752
753    // explicit conversion to primitive types
754    short to_short() const;
755    unsigned short to_ushort() const;
756    int to_int() const;
757    unsigned int to_uint() const;
758    long to_long() const;
759    unsigned long to_ulong() const;
760    int64 to_int64() const;
761    uint64 to_uint64() const;
762    float to_float() const;
763    double to_double() const;
764
765    // explicit conversion to character string
766    const std::string to_string() const;
767    const std::string to_string(sc_numrep) const;
768    const std::string to_string(sc_numrep, bool) const;
769    const std::string to_string(sc_fmt) const;
770    const std::string to_string(sc_numrep, sc_fmt) const;
771    const std::string to_string(sc_numrep, bool, sc_fmt) const;
772
773    const std::string to_dec() const;
774    const std::string to_bin() const;
775    const std::string to_oct() const;
776    const std::string to_hex() const;
777
778    // query value
779    bool is_neg() const;
780    bool is_zero() const;
781
782    // internal use only;
783    bool is_normal() const;
784
785    bool quantization_flag() const;
786    bool overflow_flag() const;
787
788    const sc_fxval value() const;
789
790    // query parameters
791    int wl() const;
792    int iwl() const;
793    sc_q_mode q_mode() const;
794    sc_o_mode o_mode() const;
795    int n_bits() const;
796
797    const sc_fxtype_params &type_params() const;
798
799    const sc_fxcast_switch &cast_switch() const;
800
801    // print or dump content
802    void print(::std::ostream & =::std::cout) const;
803    void scan(::std::istream & =::std::cin);
804    void dump(::std::ostream & =::std::cout) const;
805
806    // internal use only;
807    void observer_read() const;
808
809    // internal use only;
810    bool get_bit(int) const;
811
812  protected:
813    bool set_bit(int, bool);
814
815    bool get_slice(int, int, sc_bv_base &) const;
816    bool set_slice(int, int, const sc_bv_base &);
817
818    sc_fxnum_observer *lock_observer() const;
819    void unlock_observer(sc_fxnum_observer *) const;
820
821  private:
822    scfx_rep *m_rep;
823
824    scfx_params m_params;
825    bool m_q_flag;
826    bool m_o_flag;
827
828    mutable sc_fxnum_observer *m_observer;
829
830  private:
831    // disabled
832    sc_fxnum();
833    sc_fxnum(const sc_fxnum &);
834};
835
836
837// ----------------------------------------------------------------------------
838// CLASS : sc_fxnum_fast
839//
840// Base class for the fixed-point types; limited precision.
841// ----------------------------------------------------------------------------
842
843class sc_fxnum_fast
844{
845    friend class sc_fxval_fast;
846
847    friend class sc_fxnum_bitref;
848    friend class sc_fxnum_subref;
849    friend class sc_fxnum_fast_bitref;
850    friend class sc_fxnum_fast_subref;
851
852    template <typename T, typename B>
853    friend class sc_gem5::TraceValFxnumBase;
854
855  protected:
856    sc_fxnum_fast_observer *observer() const;
857
858    void cast();
859
860    // constructors
861    sc_fxnum_fast(const sc_fxtype_params &, sc_enc, const sc_fxcast_switch &,
862                  sc_fxnum_fast_observer *);
863
864#define DECL_CTOR_T(tp) \
865    sc_fxnum_fast(tp, const sc_fxtype_params &, sc_enc, \
866                  const sc_fxcast_switch &, sc_fxnum_fast_observer *);
867
868    DECL_CTOR_T(int)
869    DECL_CTOR_T(unsigned int)
870    DECL_CTOR_T(long)
871    DECL_CTOR_T(unsigned long)
872    DECL_CTOR_T(float)
873    DECL_CTOR_T(double)
874    DECL_CTOR_T(const char *)
875    DECL_CTOR_T(const sc_fxval &)
876    DECL_CTOR_T(const sc_fxval_fast &)
877    DECL_CTOR_T(const sc_fxnum &)
878    DECL_CTOR_T(const sc_fxnum_fast &)
879
880    DECL_CTOR_T(int64)
881    DECL_CTOR_T(uint64)
882    DECL_CTOR_T(const sc_int_base &)
883    DECL_CTOR_T(const sc_uint_base &)
884    DECL_CTOR_T(const sc_signed &)
885    DECL_CTOR_T(const sc_unsigned &)
886
887#undef DECL_CTOR_T
888    ~sc_fxnum_fast();
889
890    // internal use only;
891    double get_val() const;
892
893  public:
894    // unary operators
895    const sc_fxval_fast operator - () const;
896    const sc_fxval_fast operator + () const;
897
898    // unary functions
899    friend void neg(sc_fxval_fast &, const sc_fxnum_fast &);
900    friend void neg(sc_fxnum_fast &, const sc_fxnum_fast &);
901
902
903    // binary operators
904#define DECL_BIN_OP_T(op, tp) \
905    friend const sc_fxval_fast operator op (const sc_fxnum_fast &, tp); \
906    friend const sc_fxval_fast operator op (tp, const sc_fxnum_fast &);
907
908#define DECL_BIN_OP_OTHER(op) \
909    DECL_BIN_OP_T(op, int64) \
910    DECL_BIN_OP_T(op, uint64) \
911    DECL_BIN_OP_T(op, const sc_int_base &) \
912    DECL_BIN_OP_T(op, const sc_uint_base &) \
913    DECL_BIN_OP_T(op, const sc_signed &) \
914    DECL_BIN_OP_T(op, const sc_unsigned &)
915
916#define DECL_BIN_OP(op, dummy) \
917    friend const sc_fxval_fast operator op (const sc_fxnum_fast &, \
918                                            const sc_fxnum_fast &); \
919    DECL_BIN_OP_T(op, int) \
920    DECL_BIN_OP_T(op, unsigned int) \
921    DECL_BIN_OP_T(op, long) \
922    DECL_BIN_OP_T(op, unsigned long) \
923    DECL_BIN_OP_T(op, float) \
924    DECL_BIN_OP_T(op, double) \
925    DECL_BIN_OP_T(op, const char *) \
926    DECL_BIN_OP_T(op, const sc_fxval_fast &) \
927    DECL_BIN_OP_OTHER(op)
928
929    DECL_BIN_OP(*, mult)
930    DECL_BIN_OP(+, add)
931    DECL_BIN_OP(-, sub)
932// DECL_BIN_OP(/, div)
933    friend const sc_fxval_fast operator / (const sc_fxnum_fast &,
934                                           const sc_fxnum_fast &);
935    DECL_BIN_OP_T(/, int)
936    DECL_BIN_OP_T(/, unsigned int)
937    DECL_BIN_OP_T(/, long)
938    DECL_BIN_OP_T(/, unsigned long)
939    DECL_BIN_OP_T(/, float)
940    DECL_BIN_OP_T(/, double)
941    DECL_BIN_OP_T(/, const char *)
942    DECL_BIN_OP_T(/, const sc_fxval_fast &)
943// DECL_BIN_OP_OTHER(op)
944
945    DECL_BIN_OP_T(/, int64) \
946    DECL_BIN_OP_T(/, uint64) \
947    DECL_BIN_OP_T(/, const sc_int_base &) \
948    DECL_BIN_OP_T(/, const sc_uint_base &) \
949    DECL_BIN_OP_T(/, const sc_signed &) \
950    DECL_BIN_OP_T(/, const sc_unsigned &)
951
952#undef DECL_BIN_OP_T
953#undef DECL_BIN_OP_OTHER
954#undef DECL_BIN_OP
955
956    friend const sc_fxval_fast operator << (const sc_fxnum_fast &, int);
957    friend const sc_fxval_fast operator >> (const sc_fxnum_fast &, int);
958
959    // binary functions
960#define DECL_BIN_FNC_T(fnc, tp) \
961    friend void fnc (sc_fxval_fast &, const sc_fxnum_fast &, tp); \
962    friend void fnc (sc_fxval_fast &, tp, const sc_fxnum_fast &); \
963    friend void fnc (sc_fxnum_fast &, const sc_fxnum_fast &, tp); \
964    friend void fnc (sc_fxnum_fast &, tp, const sc_fxnum_fast &);
965
966#define DECL_BIN_FNC_OTHER(fnc) \
967    DECL_BIN_FNC_T(fnc, int64) \
968    DECL_BIN_FNC_T(fnc, uint64) \
969    DECL_BIN_FNC_T(fnc, const sc_int_base &) \
970    DECL_BIN_FNC_T(fnc, const sc_uint_base &) \
971    DECL_BIN_FNC_T(fnc, const sc_signed &) \
972    DECL_BIN_FNC_T(fnc, const sc_unsigned &)
973
974#define DECL_BIN_FNC(fnc) \
975    friend void fnc (sc_fxval_fast &, const sc_fxnum_fast &, \
976                                      const sc_fxnum_fast &); \
977    friend void fnc (sc_fxnum_fast &, const sc_fxnum_fast &, \
978                                      const sc_fxnum_fast &); \
979    DECL_BIN_FNC_T(fnc, int) \
980    DECL_BIN_FNC_T(fnc, unsigned int) \
981    DECL_BIN_FNC_T(fnc, long) \
982    DECL_BIN_FNC_T(fnc, unsigned long) \
983    DECL_BIN_FNC_T(fnc, float) \
984    DECL_BIN_FNC_T(fnc, double) \
985    DECL_BIN_FNC_T(fnc, const char *) \
986    DECL_BIN_FNC_T(fnc, const sc_fxval &) \
987    DECL_BIN_FNC_T(fnc, const sc_fxval_fast &) \
988    DECL_BIN_FNC_T(fnc, const sc_fxnum &) \
989    DECL_BIN_FNC_OTHER(fnc)
990
991    DECL_BIN_FNC(mult)
992    DECL_BIN_FNC(div)
993    DECL_BIN_FNC(add)
994    DECL_BIN_FNC(sub)
995
996#undef DECL_BIN_FNC_T
997#undef DECL_BIN_FNC_OTHER
998#undef DECL_BIN_FNC
999
1000    friend void lshift(sc_fxval_fast &, const sc_fxnum_fast &, int);
1001    friend void rshift(sc_fxval_fast &, const sc_fxnum_fast &, int);
1002    friend void lshift(sc_fxnum_fast &, const sc_fxnum_fast &, int);
1003    friend void rshift(sc_fxnum_fast &, const sc_fxnum_fast &, int);
1004
1005    // relational (including equality) operators
1006#define DECL_REL_OP_T(op, tp) \
1007    friend bool operator op (const sc_fxnum_fast &, tp); \
1008    friend bool operator op (tp, const sc_fxnum_fast &);
1009
1010#define DECL_REL_OP_OTHER(op) \
1011    DECL_REL_OP_T(op, int64) \
1012    DECL_REL_OP_T(op, uint64) \
1013    DECL_REL_OP_T(op, const sc_int_base &) \
1014    DECL_REL_OP_T(op, const sc_uint_base &) \
1015    DECL_REL_OP_T(op, const sc_signed &) \
1016    DECL_REL_OP_T(op, const sc_unsigned &)
1017
1018#define DECL_REL_OP(op) \
1019    friend bool operator op (const sc_fxnum_fast &, const sc_fxnum_fast &); \
1020    DECL_REL_OP_T(op, int) \
1021    DECL_REL_OP_T(op, unsigned int) \
1022    DECL_REL_OP_T(op, long) \
1023    DECL_REL_OP_T(op, unsigned long) \
1024    DECL_REL_OP_T(op, float) \
1025    DECL_REL_OP_T(op, double) \
1026    DECL_REL_OP_T(op, const char *) \
1027    DECL_REL_OP_T(op, const sc_fxval_fast &) \
1028    DECL_REL_OP_OTHER(op)
1029
1030    DECL_REL_OP(<)
1031    DECL_REL_OP(<=)
1032    DECL_REL_OP(>)
1033    DECL_REL_OP(>=)
1034    DECL_REL_OP(==)
1035    DECL_REL_OP(!=)
1036
1037#undef DECL_REL_OP_T
1038#undef DECL_REL_OP_OTHER
1039#undef DECL_REL_OP
1040
1041    // assignment operators
1042#define DECL_ASN_OP_T(op, tp) sc_fxnum_fast &operator op(tp);
1043
1044#define DECL_ASN_OP_OTHER(op) \
1045    DECL_ASN_OP_T(op, int64) \
1046    DECL_ASN_OP_T(op, uint64) \
1047    DECL_ASN_OP_T(op, const sc_int_base &) \
1048    DECL_ASN_OP_T(op, const sc_uint_base &) \
1049    DECL_ASN_OP_T(op, const sc_signed &) \
1050    DECL_ASN_OP_T(op, const sc_unsigned &)
1051
1052#define DECL_ASN_OP(op) \
1053    DECL_ASN_OP_T(op, int) \
1054    DECL_ASN_OP_T(op, unsigned int) \
1055    DECL_ASN_OP_T(op, long) \
1056    DECL_ASN_OP_T(op, unsigned long) \
1057    DECL_ASN_OP_T(op, float) \
1058    DECL_ASN_OP_T(op, double) \
1059    DECL_ASN_OP_T(op, const char *) \
1060    DECL_ASN_OP_T(op, const sc_fxval &) \
1061    DECL_ASN_OP_T(op, const sc_fxval_fast &) \
1062    DECL_ASN_OP_T(op, const sc_fxnum &) \
1063    DECL_ASN_OP_T(op, const sc_fxnum_fast &) \
1064    DECL_ASN_OP_OTHER(op)
1065
1066    DECL_ASN_OP(=)
1067
1068    DECL_ASN_OP(*=)
1069    DECL_ASN_OP(/=)
1070    DECL_ASN_OP(+=)
1071    DECL_ASN_OP(-=)
1072
1073    DECL_ASN_OP_T(<<=, int)
1074    DECL_ASN_OP_T(>>=, int)
1075
1076#undef DECL_ASN_OP_T
1077#undef DECL_ASN_OP_OTHER
1078#undef DECL_ASN_OP
1079
1080    // auto-increment and auto-decrement
1081    const sc_fxval_fast operator ++ (int);
1082    const sc_fxval_fast operator -- (int);
1083
1084    sc_fxnum_fast &operator ++ ();
1085    sc_fxnum_fast &operator -- ();
1086
1087    // bit selection
1088    const sc_fxnum_fast_bitref operator [] (int) const;
1089    sc_fxnum_fast_bitref operator [] (int);
1090
1091    const sc_fxnum_fast_bitref bit(int) const;
1092    sc_fxnum_fast_bitref bit(int);
1093
1094    // part selection
1095    const sc_fxnum_fast_subref operator () (int, int) const;
1096    sc_fxnum_fast_subref operator () (int, int);
1097
1098    const sc_fxnum_fast_subref range(int, int) const;
1099    sc_fxnum_fast_subref range(int, int);
1100
1101
1102    const sc_fxnum_fast_subref operator () () const;
1103    sc_fxnum_fast_subref operator () ();
1104
1105    const sc_fxnum_fast_subref range() const;
1106    sc_fxnum_fast_subref range();
1107
1108    // implicit conversion
1109    operator double() const; // necessary evil!
1110
1111    // explicit conversion to primitive types
1112    short to_short() const;
1113    unsigned short to_ushort() const;
1114    int to_int() const;
1115    unsigned int to_uint() const;
1116    long to_long() const;
1117    unsigned long to_ulong() const;
1118    int64 to_int64() const;
1119    uint64 to_uint64() const;
1120    float to_float() const;
1121    double to_double() const;
1122
1123    // explicit conversion to character string
1124    const std::string to_string() const;
1125    const std::string to_string(sc_numrep) const;
1126    const std::string to_string(sc_numrep, bool) const;
1127    const std::string to_string(sc_fmt) const;
1128    const std::string to_string(sc_numrep, sc_fmt) const;
1129    const std::string to_string(sc_numrep, bool, sc_fmt) const;
1130
1131    const std::string to_dec() const;
1132    const std::string to_bin() const;
1133    const std::string to_oct() const;
1134    const std::string to_hex() const;
1135
1136    // query value
1137    bool is_neg() const;
1138    bool is_zero() const;
1139
1140    // internal use only;
1141    bool is_normal() const;
1142
1143    bool quantization_flag() const;
1144    bool overflow_flag() const;
1145
1146    const sc_fxval_fast value() const;
1147
1148    // query parameters
1149    int wl() const;
1150    int iwl() const;
1151    sc_q_mode q_mode() const;
1152    sc_o_mode o_mode() const;
1153    int n_bits() const;
1154
1155    const sc_fxtype_params &type_params() const;
1156
1157    const sc_fxcast_switch &cast_switch() const;
1158
1159    // print or dump content
1160    void print(::std::ostream & =::std::cout) const;
1161    void scan(::std::istream & =::std::cin);
1162    void dump(::std::ostream & =::std::cout) const;
1163
1164    // internal use only;
1165    void observer_read() const;
1166
1167    // internal use only;
1168    bool get_bit(int) const;
1169
1170  protected:
1171    bool set_bit(int, bool);
1172
1173    bool get_slice(int, int, sc_bv_base &) const;
1174    bool set_slice(int, int, const sc_bv_base &);
1175
1176    sc_fxnum_fast_observer *lock_observer() const;
1177    void unlock_observer(sc_fxnum_fast_observer *) const;
1178
1179  private:
1180    double m_val;
1181
1182    scfx_params m_params;
1183    bool m_q_flag;
1184    bool m_o_flag;
1185
1186    mutable sc_fxnum_fast_observer *m_observer;
1187
1188  private:
1189    // Disabled
1190    sc_fxnum_fast();
1191    sc_fxnum_fast(const sc_fxnum_fast &);
1192};
1193
1194
1195// IIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIIII
1196
1197// ----------------------------------------------------------------------------
1198// CLASS : sc_fxnum_bitref
1199//
1200// Proxy class for bit-selection in class sc_fxnum, behaves like sc_bit.
1201// ----------------------------------------------------------------------------
1202
1203// constructor
1204
1205inline
1206sc_fxnum_bitref::sc_fxnum_bitref(sc_fxnum &num_, int idx_) :
1207        m_num(num_), m_idx(idx_)
1208{}
1209
1210// copy constructor
1211inline sc_fxnum_bitref::sc_fxnum_bitref(const sc_fxnum_bitref &a) :
1212        m_num(a.m_num), m_idx(a.m_idx)
1213{}
1214
1215// assignment operators
1216inline sc_fxnum_bitref &
1217sc_fxnum_bitref::operator = (const sc_fxnum_bitref &a)
1218{
1219    if (&a != this) {
1220        SC_FXNUM_OBSERVER_READ_(a.m_num)
1221        set(a.get());
1222        SC_FXNUM_OBSERVER_WRITE_(m_num)
1223    }
1224    return *this;
1225}
1226
1227inline sc_fxnum_bitref &
1228sc_fxnum_bitref::operator = (const sc_fxnum_fast_bitref &a)
1229{
1230    SC_FXNUM_FAST_OBSERVER_READ_(a.m_num)
1231    set(a.get());
1232    SC_FXNUM_OBSERVER_WRITE_(m_num)
1233    return *this;
1234}
1235
1236inline sc_fxnum_bitref &
1237sc_fxnum_bitref::operator = (const sc_bit &a)
1238{
1239    set(static_cast<bool>(a));
1240    SC_FXNUM_OBSERVER_WRITE_(m_num)
1241    return *this;
1242}
1243
1244inline sc_fxnum_bitref &
1245sc_fxnum_bitref::operator = (bool a)
1246{
1247    set(a);
1248    SC_FXNUM_OBSERVER_WRITE_(m_num)
1249    return *this;
1250}
1251
1252inline sc_fxnum_bitref &
1253sc_fxnum_bitref::operator &= (const sc_fxnum_bitref &b)
1254{
1255    SC_FXNUM_OBSERVER_READ_(m_num)
1256    SC_FXNUM_OBSERVER_READ_(b.m_num)
1257    set(get() && b.get());
1258    SC_FXNUM_OBSERVER_WRITE_(m_num)
1259    return *this;
1260}
1261
1262inline sc_fxnum_bitref &
1263sc_fxnum_bitref::operator &= (const sc_fxnum_fast_bitref &b)
1264{
1265    SC_FXNUM_OBSERVER_READ_(m_num)
1266    SC_FXNUM_FAST_OBSERVER_READ_(b.m_num)
1267    set(get() && b.get());
1268    SC_FXNUM_OBSERVER_WRITE_(m_num)
1269    return *this;
1270}
1271
1272inline sc_fxnum_bitref &
1273sc_fxnum_bitref::operator &= (const sc_bit &b)
1274{
1275    SC_FXNUM_OBSERVER_READ_(m_num)
1276    set(get() && static_cast<bool>(b));
1277    SC_FXNUM_OBSERVER_WRITE_(m_num)
1278    return *this;
1279}
1280
1281inline sc_fxnum_bitref &
1282sc_fxnum_bitref::operator &= (bool b)
1283{
1284    SC_FXNUM_OBSERVER_READ_(m_num)
1285    set(get() && b);
1286    SC_FXNUM_OBSERVER_WRITE_(m_num)
1287    return *this;
1288}
1289
1290
1291inline sc_fxnum_bitref &
1292sc_fxnum_bitref::operator |= (const sc_fxnum_bitref &b)
1293{
1294    SC_FXNUM_OBSERVER_READ_(m_num)
1295    SC_FXNUM_OBSERVER_READ_(b.m_num)
1296    set(get() || b.get());
1297    SC_FXNUM_OBSERVER_WRITE_(m_num)
1298    return *this;
1299}
1300
1301inline sc_fxnum_bitref &
1302sc_fxnum_bitref::operator |= (const sc_fxnum_fast_bitref &b)
1303{
1304    SC_FXNUM_OBSERVER_READ_(m_num)
1305    SC_FXNUM_FAST_OBSERVER_READ_(b.m_num)
1306    set(get() || b.get());
1307    SC_FXNUM_OBSERVER_WRITE_(m_num)
1308    return *this;
1309}
1310
1311inline sc_fxnum_bitref &
1312sc_fxnum_bitref::operator |= (const sc_bit &b)
1313{
1314    SC_FXNUM_OBSERVER_READ_(m_num)
1315    set(get() || static_cast<bool>(b));
1316    SC_FXNUM_OBSERVER_WRITE_(m_num)
1317    return *this;
1318}
1319
1320inline sc_fxnum_bitref &
1321sc_fxnum_bitref::operator |= (bool b)
1322{
1323    SC_FXNUM_OBSERVER_READ_(m_num)
1324    set(get() || b);
1325    SC_FXNUM_OBSERVER_WRITE_(m_num)
1326    return *this;
1327}
1328
1329
1330inline sc_fxnum_bitref &
1331sc_fxnum_bitref::operator ^= (const sc_fxnum_bitref &b)
1332{
1333    SC_FXNUM_OBSERVER_READ_(m_num)
1334    SC_FXNUM_OBSERVER_READ_(b.m_num)
1335    set(get() != b.get());
1336    SC_FXNUM_OBSERVER_WRITE_(m_num)
1337    return *this;
1338}
1339
1340inline sc_fxnum_bitref &
1341sc_fxnum_bitref::operator ^= (const sc_fxnum_fast_bitref &b)
1342{
1343    SC_FXNUM_OBSERVER_READ_(m_num)
1344    SC_FXNUM_FAST_OBSERVER_READ_(b.m_num)
1345    set(get() != b.get());
1346    SC_FXNUM_OBSERVER_WRITE_(m_num)
1347    return *this;
1348}
1349
1350inline sc_fxnum_bitref &
1351sc_fxnum_bitref::operator ^= (const sc_bit &b)
1352{
1353    SC_FXNUM_OBSERVER_READ_(m_num)
1354    set(get() != static_cast<bool>(b));
1355    SC_FXNUM_OBSERVER_WRITE_(m_num)
1356    return *this;
1357}
1358
1359inline sc_fxnum_bitref &
1360sc_fxnum_bitref::operator ^= (bool b)
1361{
1362    SC_FXNUM_OBSERVER_READ_(m_num)
1363    set(get() != b);
1364    SC_FXNUM_OBSERVER_WRITE_(m_num)
1365    return *this;
1366}
1367
1368// implicit conversion
1369inline sc_fxnum_bitref::operator bool() const
1370{
1371    SC_FXNUM_OBSERVER_READ_(m_num)
1372    return get();
1373}
1374
1375inline ::std::ostream &
1376operator << (::std::ostream &os, const sc_fxnum_bitref &a)
1377{
1378    a.print(os);
1379    return os;
1380}
1381
1382inline ::std::istream &
1383operator >> (::std::istream &is, sc_fxnum_bitref &a)
1384{
1385    a.scan(is);
1386    return is;
1387}
1388
1389
1390// ----------------------------------------------------------------------------
1391// CLASS : sc_fxnum_fast_bitref
1392//
1393// Proxy class for bit-selection in class sc_fxnum_fast, behaves like sc_bit.
1394// ----------------------------------------------------------------------------
1395
1396// constructor
1397inline sc_fxnum_fast_bitref::sc_fxnum_fast_bitref(
1398        sc_fxnum_fast &num_, int idx_) : m_num(num_), m_idx(idx_)
1399{}
1400
1401// copy constructor
1402inline sc_fxnum_fast_bitref::sc_fxnum_fast_bitref(
1403        const sc_fxnum_fast_bitref &a) : m_num(a.m_num), m_idx(a.m_idx)
1404{}
1405
1406// assignment operators
1407inline sc_fxnum_fast_bitref &
1408sc_fxnum_fast_bitref::operator = (const sc_fxnum_bitref &a)
1409{
1410    SC_FXNUM_OBSERVER_READ_(a.m_num)
1411    set(a.get());
1412    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1413    return *this;
1414}
1415
1416inline sc_fxnum_fast_bitref &
1417sc_fxnum_fast_bitref::operator = (const sc_fxnum_fast_bitref &a)
1418{
1419    if (&a != this) {
1420        SC_FXNUM_FAST_OBSERVER_READ_(a.m_num)
1421        set(a.get());
1422        SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1423    }
1424    return *this;
1425}
1426
1427inline sc_fxnum_fast_bitref &
1428sc_fxnum_fast_bitref::operator = (const sc_bit &a)
1429{
1430    set(static_cast<bool>(a));
1431    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1432    return *this;
1433}
1434
1435inline sc_fxnum_fast_bitref &
1436sc_fxnum_fast_bitref::operator = (bool a)
1437{
1438    set(a);
1439    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1440    return *this;
1441}
1442
1443
1444inline sc_fxnum_fast_bitref &
1445sc_fxnum_fast_bitref::operator &= (const sc_fxnum_bitref &b)
1446{
1447    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1448    SC_FXNUM_OBSERVER_READ_(b.m_num)
1449    set(get() && b.get());
1450    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1451    return *this;
1452}
1453
1454inline sc_fxnum_fast_bitref &
1455sc_fxnum_fast_bitref::operator &= (const sc_fxnum_fast_bitref &b)
1456{
1457    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1458    SC_FXNUM_FAST_OBSERVER_READ_(b.m_num)
1459    set(get() && b.get());
1460    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1461    return *this;
1462}
1463
1464inline sc_fxnum_fast_bitref &
1465sc_fxnum_fast_bitref::operator &= (const sc_bit &b)
1466{
1467    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1468    set(get() && static_cast<bool>(b));
1469    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1470    return *this;
1471}
1472
1473inline sc_fxnum_fast_bitref &
1474sc_fxnum_fast_bitref::operator &= (bool b)
1475{
1476    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1477    set(get() && b);
1478    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1479    return *this;
1480}
1481
1482
1483inline sc_fxnum_fast_bitref &
1484sc_fxnum_fast_bitref::operator |= (const sc_fxnum_bitref &b)
1485{
1486    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1487    SC_FXNUM_OBSERVER_READ_(b.m_num)
1488    set(get() || b.get());
1489    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1490    return *this;
1491}
1492
1493inline sc_fxnum_fast_bitref &
1494sc_fxnum_fast_bitref::operator |= (const sc_fxnum_fast_bitref &b)
1495{
1496    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1497    SC_FXNUM_FAST_OBSERVER_READ_(b.m_num)
1498    set(get() || b.get());
1499    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1500    return *this;
1501}
1502
1503inline sc_fxnum_fast_bitref &
1504sc_fxnum_fast_bitref::operator |= (const sc_bit &b)
1505{
1506    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1507    set(get() || static_cast<bool>(b));
1508    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1509    return *this;
1510}
1511
1512inline sc_fxnum_fast_bitref &
1513sc_fxnum_fast_bitref::operator |= (bool b)
1514{
1515    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1516    set(get() || b);
1517    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1518    return *this;
1519}
1520
1521
1522inline sc_fxnum_fast_bitref &
1523sc_fxnum_fast_bitref::operator ^= (const sc_fxnum_bitref &b)
1524{
1525    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1526    SC_FXNUM_OBSERVER_READ_(b.m_num)
1527    set(get() != b.get());
1528    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1529    return *this;
1530}
1531
1532inline sc_fxnum_fast_bitref &
1533sc_fxnum_fast_bitref::operator ^= (const sc_fxnum_fast_bitref &b)
1534{
1535    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1536    SC_FXNUM_FAST_OBSERVER_READ_(b.m_num)
1537    set(get() != b.get());
1538    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1539    return *this;
1540}
1541
1542inline sc_fxnum_fast_bitref &
1543sc_fxnum_fast_bitref::operator ^= (const sc_bit &b)
1544{
1545    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1546    set(get() != static_cast<bool>(b));
1547    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1548    return *this;
1549}
1550
1551inline sc_fxnum_fast_bitref &
1552sc_fxnum_fast_bitref::operator ^= (bool b)
1553{
1554    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1555    set(get() != b);
1556    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1557    return *this;
1558}
1559
1560
1561// implicit conversion
1562inline sc_fxnum_fast_bitref::operator bool() const
1563{
1564    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
1565    return get();
1566}
1567
1568inline ::std::ostream &
1569operator << (::std::ostream &os, const sc_fxnum_fast_bitref &a)
1570{
1571    a.print(os);
1572    return os;
1573}
1574
1575inline ::std::istream &
1576operator >> (::std::istream &is, sc_fxnum_fast_bitref &a)
1577{
1578    a.scan(is);
1579    return is;
1580}
1581
1582
1583// ----------------------------------------------------------------------------
1584// CLASS : sc_fxnum_subref
1585//
1586// Proxy class for part-selection in class sc_fxnum,
1587// behaves like sc_bv_base.
1588// ----------------------------------------------------------------------------
1589
1590// constructor
1591inline sc_fxnum_subref::sc_fxnum_subref(sc_fxnum &num_, int from_, int to_) :
1592        m_num(num_), m_from(from_), m_to(to_),
1593        m_bv(*new sc_bv_base(sc_max(m_from, m_to) - sc_min(m_from, m_to) + 1))
1594{}
1595
1596// copy constructor
1597inline sc_fxnum_subref::sc_fxnum_subref(const sc_fxnum_subref &a) :
1598        m_num(a.m_num), m_from(a.m_from), m_to(a.m_to),
1599        m_bv(*new sc_bv_base(a.m_bv))
1600{}
1601
1602// destructor
1603inline sc_fxnum_subref::~sc_fxnum_subref()
1604{
1605    delete &m_bv;
1606}
1607
1608// assignment operators
1609inline sc_fxnum_subref &
1610sc_fxnum_subref::operator = (const sc_fxnum_subref &a)
1611{
1612    if (&a != this) {
1613        m_bv = static_cast<sc_bv_base>(a);
1614        set();
1615        SC_FXNUM_OBSERVER_WRITE_(m_num)
1616    }
1617    return *this;
1618}
1619
1620inline sc_fxnum_subref &
1621sc_fxnum_subref::operator = (const sc_fxnum_fast_subref &a)
1622{
1623    m_bv = static_cast<sc_bv_base>(a);
1624    set();
1625    SC_FXNUM_OBSERVER_WRITE_(m_num)
1626    return *this;
1627}
1628
1629#define DEFN_ASN_OP_T(tp) \
1630inline sc_fxnum_subref & \
1631sc_fxnum_subref::operator = (tp a) \
1632{ \
1633    m_bv = a; \
1634    set(); \
1635    SC_FXNUM_OBSERVER_WRITE_(m_num) \
1636    return *this; \
1637}
1638
1639DEFN_ASN_OP_T(const sc_bv_base &)
1640DEFN_ASN_OP_T(const sc_lv_base &)
1641DEFN_ASN_OP_T(const char *)
1642DEFN_ASN_OP_T(const bool *)
1643DEFN_ASN_OP_T(const sc_signed &)
1644DEFN_ASN_OP_T(const sc_unsigned &)
1645DEFN_ASN_OP_T(const sc_int_base &)
1646DEFN_ASN_OP_T(const sc_uint_base &)
1647DEFN_ASN_OP_T(int64)
1648DEFN_ASN_OP_T(uint64)
1649DEFN_ASN_OP_T(int)
1650DEFN_ASN_OP_T(unsigned int)
1651DEFN_ASN_OP_T(long)
1652DEFN_ASN_OP_T(unsigned long)
1653DEFN_ASN_OP_T(char)
1654
1655#undef DEFN_ASN_OP_T
1656
1657#define DEFN_ASN_OP_T(op, tp) \
1658inline sc_fxnum_subref & \
1659sc_fxnum_subref::operator op ## = (tp a) \
1660{ \
1661    SC_FXNUM_OBSERVER_READ_(m_num) \
1662    get(); \
1663    m_bv = m_bv op a; \
1664    set(); \
1665    SC_FXNUM_OBSERVER_WRITE_(m_num) \
1666    return *this; \
1667}
1668
1669#define DEFN_ASN_OP(op) \
1670inline sc_fxnum_subref & \
1671sc_fxnum_subref::operator op ## = (const sc_fxnum_subref &a) \
1672{ \
1673    SC_FXNUM_OBSERVER_READ_(m_num) \
1674    get(); \
1675    m_bv = m_bv op static_cast<sc_bv_base>(a); \
1676    set(); \
1677    SC_FXNUM_OBSERVER_WRITE_(m_num) \
1678    return *this; \
1679} \
1680 \
1681inline sc_fxnum_subref & \
1682sc_fxnum_subref::operator op ## = (const sc_fxnum_fast_subref &a) \
1683{ \
1684    SC_FXNUM_OBSERVER_READ_(m_num) \
1685    get(); \
1686    m_bv = m_bv op static_cast<sc_bv_base>(a); \
1687    set(); \
1688    SC_FXNUM_OBSERVER_WRITE_(m_num) \
1689    return *this; \
1690} \
1691 \
1692DEFN_ASN_OP_T(op, const sc_bv_base &) \
1693DEFN_ASN_OP_T(op, const sc_lv_base &)
1694
1695DEFN_ASN_OP( &)
1696DEFN_ASN_OP(|)
1697DEFN_ASN_OP(^)
1698
1699#undef DEFN_ASN_OP_T
1700#undef DEFN_ASN_OP
1701
1702// relational operators
1703#define DEFN_REL_OP_T(op, tp) \
1704inline bool \
1705operator op (const sc_fxnum_subref &a, tp b) \
1706{ \
1707    return (static_cast<sc_bv_base>(a) op b); \
1708} \
1709 \
1710inline bool \
1711operator op (tp a, const sc_fxnum_subref &b) \
1712{ \
1713    return (static_cast<sc_bv_base>(b) op a); \
1714}
1715
1716#define DEFN_REL_OP(op) \
1717inline bool \
1718operator op (const sc_fxnum_subref &a, const sc_fxnum_subref &b) \
1719{ \
1720    return (static_cast<sc_bv_base>(a) op static_cast<sc_bv_base>(b)); \
1721} \
1722 \
1723inline bool \
1724operator op (const sc_fxnum_subref &a, const sc_fxnum_fast_subref &b) \
1725{ \
1726    return (static_cast<sc_bv_base>(a) op static_cast<sc_bv_base>(b)); \
1727} \
1728 \
1729DEFN_REL_OP_T(op, const sc_bv_base &) \
1730DEFN_REL_OP_T(op, const sc_lv_base &) \
1731DEFN_REL_OP_T(op, const char *) \
1732DEFN_REL_OP_T(op, const bool *) \
1733DEFN_REL_OP_T(op, const sc_signed &) \
1734DEFN_REL_OP_T(op, const sc_unsigned &) \
1735DEFN_REL_OP_T(op, int) \
1736DEFN_REL_OP_T(op, unsigned int) \
1737DEFN_REL_OP_T(op, long) \
1738DEFN_REL_OP_T(op, unsigned long)
1739
1740DEFN_REL_OP(==)
1741DEFN_REL_OP(!=)
1742
1743#undef DEFN_REL_OP_T
1744#undef DEFN_REL_OP
1745
1746
1747// reduce functions
1748
1749#define DEFN_RED_FNC(fnc) \
1750inline bool \
1751sc_fxnum_subref::fnc() const \
1752{ \
1753    SC_FXNUM_OBSERVER_READ_(m_num) \
1754    get(); \
1755    return static_cast<bool>(m_bv.fnc()); \
1756}
1757
1758DEFN_RED_FNC(and_reduce)
1759DEFN_RED_FNC(nand_reduce)
1760DEFN_RED_FNC(or_reduce)
1761DEFN_RED_FNC(nor_reduce)
1762DEFN_RED_FNC(xor_reduce)
1763DEFN_RED_FNC(xnor_reduce)
1764
1765#undef DEFN_RED_FNC
1766
1767// query parameter
1768inline int
1769sc_fxnum_subref::length() const
1770{
1771    return m_bv.length();
1772}
1773
1774// explicit conversions
1775inline int
1776sc_fxnum_subref::to_int() const
1777{
1778    SC_FXNUM_OBSERVER_READ_(m_num)
1779    get();
1780    return m_bv.to_int();
1781}
1782
1783inline int64
1784sc_fxnum_subref::to_int64() const
1785{
1786    SC_FXNUM_OBSERVER_READ_(m_num)
1787    get();
1788    return m_bv.to_int64();
1789}
1790
1791inline unsigned int
1792sc_fxnum_subref::to_uint() const
1793{
1794    SC_FXNUM_OBSERVER_READ_(m_num)
1795    get();
1796    return m_bv.to_uint();
1797}
1798
1799inline uint64
1800sc_fxnum_subref::to_uint64() const
1801{
1802    SC_FXNUM_OBSERVER_READ_(m_num)
1803    get();
1804    return m_bv.to_uint64();
1805}
1806
1807inline long
1808sc_fxnum_subref::to_long() const
1809{
1810    SC_FXNUM_OBSERVER_READ_(m_num)
1811    get();
1812    return m_bv.to_long();
1813}
1814
1815inline unsigned long
1816sc_fxnum_subref::to_ulong() const
1817{
1818    SC_FXNUM_OBSERVER_READ_(m_num)
1819    get();
1820    return m_bv.to_ulong();
1821}
1822
1823
1824inline const std::string
1825sc_fxnum_subref::to_string() const
1826{
1827    get();
1828    return m_bv.to_string();
1829}
1830
1831inline const std::string
1832sc_fxnum_subref::to_string(sc_numrep numrep) const
1833{
1834    get();
1835    return m_bv.to_string(numrep);
1836}
1837
1838inline const std::string
1839sc_fxnum_subref::to_string(sc_numrep numrep, bool w_prefix) const
1840{
1841    get();
1842    return m_bv.to_string(numrep, w_prefix);
1843}
1844
1845
1846// implicit conversion
1847inline sc_fxnum_subref::operator sc_bv_base () const
1848{
1849    SC_FXNUM_OBSERVER_READ_(m_num)
1850    get();
1851    return m_bv;
1852}
1853
1854
1855inline ::std::ostream &
1856operator << (::std::ostream &os, const sc_fxnum_subref &a)
1857{
1858    a.print(os);
1859    return os;
1860}
1861
1862inline ::std::istream &
1863operator >> (::std::istream &is, sc_fxnum_subref &a)
1864{
1865    a.scan(is);
1866    return is;
1867}
1868
1869
1870// ----------------------------------------------------------------------------
1871// CLASS : sc_fxnum_fast_subref
1872//
1873// Proxy class for part-selection in class sc_fxnum_fast,
1874// behaves like sc_bv_base.
1875// ----------------------------------------------------------------------------
1876
1877// constructor
1878
1879inline sc_fxnum_fast_subref::sc_fxnum_fast_subref(
1880        sc_fxnum_fast &num_, int from_, int to_) :
1881    m_num(num_), m_from(from_), m_to(to_),
1882    m_bv(*new sc_bv_base(sc_max(m_from, m_to) - sc_min(m_from, m_to) + 1))
1883{}
1884
1885
1886// copy constructor
1887inline sc_fxnum_fast_subref::sc_fxnum_fast_subref(
1888        const sc_fxnum_fast_subref &a) :
1889    m_num(a.m_num), m_from(a.m_from), m_to(a.m_to),
1890    m_bv(*new sc_bv_base(a.m_bv))
1891{}
1892
1893
1894// destructor
1895inline sc_fxnum_fast_subref::~sc_fxnum_fast_subref()
1896{
1897    delete &m_bv;
1898}
1899
1900
1901// assignment operators
1902inline sc_fxnum_fast_subref &
1903sc_fxnum_fast_subref::operator = (const sc_fxnum_subref &a)
1904{
1905    m_bv = static_cast<sc_bv_base>(a);
1906    set();
1907    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1908    return *this;
1909}
1910
1911inline sc_fxnum_fast_subref &
1912sc_fxnum_fast_subref::operator = (const sc_fxnum_fast_subref &a)
1913{
1914    if (&a != this) {
1915        m_bv = static_cast<sc_bv_base>(a);
1916        set();
1917        SC_FXNUM_FAST_OBSERVER_WRITE_(m_num)
1918    }
1919    return *this;
1920}
1921
1922#define DEFN_ASN_OP_T(tp) \
1923inline sc_fxnum_fast_subref & \
1924sc_fxnum_fast_subref::operator = (tp a) \
1925{ \
1926    m_bv = a; \
1927    set(); \
1928    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num) \
1929    return *this; \
1930}
1931
1932DEFN_ASN_OP_T(const sc_bv_base &)
1933DEFN_ASN_OP_T(const sc_lv_base &)
1934DEFN_ASN_OP_T(const char *)
1935DEFN_ASN_OP_T(const bool *)
1936DEFN_ASN_OP_T(const sc_signed &)
1937DEFN_ASN_OP_T(const sc_unsigned &)
1938DEFN_ASN_OP_T(const sc_int_base &)
1939DEFN_ASN_OP_T(const sc_uint_base &)
1940DEFN_ASN_OP_T(int64)
1941DEFN_ASN_OP_T(uint64)
1942DEFN_ASN_OP_T(int)
1943DEFN_ASN_OP_T(unsigned int)
1944DEFN_ASN_OP_T(long)
1945DEFN_ASN_OP_T(unsigned long)
1946DEFN_ASN_OP_T(char)
1947
1948#undef DEFN_ASN_OP_T
1949
1950
1951#define DEFN_ASN_OP_T(op, tp) \
1952inline sc_fxnum_fast_subref & \
1953sc_fxnum_fast_subref::operator op ## = (tp a) \
1954{ \
1955    SC_FXNUM_FAST_OBSERVER_READ_(m_num) \
1956    get(); \
1957    m_bv = m_bv op a; \
1958    set(); \
1959    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num) \
1960    return *this; \
1961}
1962
1963#define DEFN_ASN_OP(op) \
1964inline sc_fxnum_fast_subref & \
1965sc_fxnum_fast_subref::operator op ## = (const sc_fxnum_subref &a) \
1966{ \
1967    SC_FXNUM_FAST_OBSERVER_READ_(m_num) \
1968    get(); \
1969    m_bv = m_bv op static_cast<sc_bv_base>(a); \
1970    set(); \
1971    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num) \
1972    return *this; \
1973} \
1974 \
1975inline sc_fxnum_fast_subref & \
1976sc_fxnum_fast_subref::operator op ## = (const sc_fxnum_fast_subref &a) \
1977{ \
1978    SC_FXNUM_FAST_OBSERVER_READ_(m_num) \
1979    get(); \
1980    m_bv = m_bv op static_cast<sc_bv_base>(a); \
1981    set(); \
1982    SC_FXNUM_FAST_OBSERVER_WRITE_(m_num) \
1983    return *this; \
1984} \
1985 \
1986DEFN_ASN_OP_T(op, const sc_bv_base &) \
1987DEFN_ASN_OP_T(op, const sc_lv_base &)
1988
1989DEFN_ASN_OP(&)
1990DEFN_ASN_OP(|)
1991DEFN_ASN_OP(^)
1992
1993#undef DEFN_ASN_OP_T
1994#undef DEFN_ASN_OP
1995
1996
1997// relational operators
1998
1999#define DEFN_REL_OP_T(op, tp) \
2000inline bool \
2001operator op (const sc_fxnum_fast_subref &a, tp b) \
2002{ \
2003    return (static_cast<sc_bv_base>(a) op b); \
2004} \
2005 \
2006inline bool \
2007operator op (tp a, const sc_fxnum_fast_subref &b) \
2008{ \
2009    return (static_cast<sc_bv_base>(b) op a); \
2010}
2011
2012#define DEFN_REL_OP(op) \
2013inline bool \
2014operator op (const sc_fxnum_fast_subref &a, const sc_fxnum_fast_subref &b) \
2015{ \
2016    return (static_cast<sc_bv_base>(a) op static_cast<sc_bv_base>(b)); \
2017} \
2018 \
2019inline bool \
2020operator op (const sc_fxnum_fast_subref &a, const sc_fxnum_subref &b) \
2021{ \
2022    return (static_cast<sc_bv_base>(a) op static_cast<sc_bv_base>(b)); \
2023} \
2024 \
2025DEFN_REL_OP_T(op, const sc_bv_base &) \
2026DEFN_REL_OP_T(op, const sc_lv_base &) \
2027DEFN_REL_OP_T(op, const char *) \
2028DEFN_REL_OP_T(op, const bool *) \
2029DEFN_REL_OP_T(op, const sc_signed &) \
2030DEFN_REL_OP_T(op, const sc_unsigned &) \
2031DEFN_REL_OP_T(op, int) \
2032DEFN_REL_OP_T(op, unsigned int) \
2033DEFN_REL_OP_T(op, long) \
2034DEFN_REL_OP_T(op, unsigned long)
2035
2036DEFN_REL_OP(==)
2037DEFN_REL_OP(!=)
2038
2039#undef DEFN_REL_OP_T
2040#undef DEFN_REL_OP
2041
2042// reduce functions
2043#define DEFN_RED_FNC(fnc) \
2044inline bool \
2045sc_fxnum_fast_subref::fnc() const \
2046{ \
2047    SC_FXNUM_FAST_OBSERVER_READ_(m_num) \
2048    get(); \
2049    return static_cast<bool>(m_bv.fnc()); \
2050}
2051
2052DEFN_RED_FNC(and_reduce)
2053DEFN_RED_FNC(nand_reduce)
2054DEFN_RED_FNC(or_reduce)
2055DEFN_RED_FNC(nor_reduce)
2056DEFN_RED_FNC(xor_reduce)
2057DEFN_RED_FNC(xnor_reduce)
2058
2059#undef DEFN_RED_FNC
2060
2061// query parameter
2062inline int
2063sc_fxnum_fast_subref::length() const
2064{
2065    return m_bv.length();
2066}
2067
2068// explicit conversions
2069inline int
2070sc_fxnum_fast_subref::to_int() const
2071{
2072    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
2073    get();
2074    return m_bv.to_int();
2075}
2076
2077inline int64
2078sc_fxnum_fast_subref::to_int64() const
2079{
2080    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
2081    get();
2082    return m_bv.to_int64();
2083}
2084
2085inline unsigned int
2086sc_fxnum_fast_subref::to_uint() const
2087{
2088    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
2089    get();
2090    return m_bv.to_uint();
2091}
2092
2093inline uint64
2094sc_fxnum_fast_subref::to_uint64() const
2095{
2096    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
2097    get();
2098    return m_bv.to_uint64();
2099}
2100
2101inline long
2102sc_fxnum_fast_subref::to_long() const
2103{
2104    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
2105    get();
2106    return m_bv.to_long();
2107}
2108
2109inline unsigned long
2110sc_fxnum_fast_subref::to_ulong() const
2111{
2112    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
2113    get();
2114    return m_bv.to_ulong();
2115}
2116
2117inline const std::string
2118sc_fxnum_fast_subref::to_string() const
2119{
2120    get();
2121    return m_bv.to_string();
2122}
2123
2124inline const std::string
2125sc_fxnum_fast_subref::to_string(sc_numrep numrep) const
2126{
2127    get();
2128    return m_bv.to_string(numrep);
2129}
2130
2131inline const std::string
2132sc_fxnum_fast_subref::to_string(sc_numrep numrep, bool w_prefix) const
2133{
2134    get();
2135    return m_bv.to_string(numrep, w_prefix);
2136}
2137
2138
2139// implicit conversion
2140inline sc_fxnum_fast_subref::operator sc_bv_base () const
2141{
2142    SC_FXNUM_FAST_OBSERVER_READ_(m_num)
2143    get();
2144    return m_bv;
2145}
2146
2147inline ::std::ostream &
2148operator << (::std::ostream &os, const sc_fxnum_fast_subref &a)
2149{
2150    a.print(os);
2151    return os;
2152}
2153
2154inline ::std::istream &
2155operator >> (::std::istream &is, sc_fxnum_fast_subref &a)
2156{
2157    a.scan(is);
2158    return is;
2159}
2160
2161
2162// ----------------------------------------------------------------------------
2163// CLASS : sc_fxnum
2164//
2165// Base class for the fixed-point types; arbitrary precision.
2166// ----------------------------------------------------------------------------
2167
2168inline sc_fxnum_observer *
2169sc_fxnum::observer() const
2170{
2171    return m_observer;
2172}
2173
2174inline void
2175sc_fxnum::cast()
2176{
2177    SC_ERROR_IF_(!m_rep->is_normal(), "invalid fixed-point value");
2178
2179    if (m_params.cast_switch() == SC_ON)
2180        m_rep->cast(m_params, m_q_flag, m_o_flag);
2181}
2182
2183// constructors
2184inline sc_fxnum::sc_fxnum(const sc_fxtype_params &type_params_,
2185                          sc_enc enc_, const sc_fxcast_switch &cast_sw,
2186                          sc_fxnum_observer *observer_) :
2187    m_rep(new scfx_rep), m_params(type_params_, enc_, cast_sw),
2188    m_q_flag(false), m_o_flag(false), m_observer(observer_)
2189{
2190    SC_FXNUM_OBSERVER_DEFAULT_
2191    SC_FXNUM_OBSERVER_CONSTRUCT_(*this)
2192}
2193
2194#define DEFN_CTOR_T(tp, arg) \
2195inline sc_fxnum::sc_fxnum(tp a, const sc_fxtype_params &type_params_, \
2196                          sc_enc enc_, const sc_fxcast_switch &cast_sw, \
2197                          sc_fxnum_observer *observer_) : \
2198    m_rep(new scfx_rep(arg)), m_params(type_params_, enc_, cast_sw), \
2199    m_q_flag(false), m_o_flag(false), m_observer(observer_) \
2200{ \
2201    SC_FXNUM_OBSERVER_DEFAULT_ \
2202    cast(); \
2203    SC_FXNUM_OBSERVER_CONSTRUCT_(*this) \
2204    SC_FXNUM_OBSERVER_WRITE_(*this) \
2205}
2206
2207#define DEFN_CTOR_T_A(tp) DEFN_CTOR_T(tp, a)
2208#define DEFN_CTOR_T_B(tp) DEFN_CTOR_T(tp, *a.m_rep)
2209#define DEFN_CTOR_T_C(tp) DEFN_CTOR_T(tp, a.to_double())
2210#define DEFN_CTOR_T_D(tp) DEFN_CTOR_T(tp, a.value())
2211
2212DEFN_CTOR_T_A(int)
2213DEFN_CTOR_T_A(unsigned int)
2214DEFN_CTOR_T_A(long)
2215DEFN_CTOR_T_A(unsigned long)
2216DEFN_CTOR_T_A(float)
2217DEFN_CTOR_T_A(double)
2218DEFN_CTOR_T_A(const char *)
2219DEFN_CTOR_T_B(const sc_fxval &)
2220DEFN_CTOR_T_C(const sc_fxval_fast &)
2221DEFN_CTOR_T_B(const sc_fxnum &)
2222DEFN_CTOR_T_C(const sc_fxnum_fast &)
2223#ifndef SC_FX_EXCLUDE_OTHER
2224DEFN_CTOR_T_A(int64)
2225DEFN_CTOR_T_A(uint64)
2226DEFN_CTOR_T_D(const sc_int_base &)
2227DEFN_CTOR_T_D(const sc_uint_base &)
2228DEFN_CTOR_T_A(const sc_signed &)
2229DEFN_CTOR_T_A(const sc_unsigned &)
2230#endif
2231
2232#undef DEFN_CTOR_T
2233#undef DEFN_CTOR_T_A
2234#undef DEFN_CTOR_T_B
2235#undef DEFN_CTOR_T_C
2236#undef DEFN_CTOR_T_D
2237
2238inline sc_fxnum::~sc_fxnum()
2239{
2240    SC_FXNUM_OBSERVER_DESTRUCT_(*this)
2241    delete m_rep;
2242}
2243
2244// internal use only;
2245inline const scfx_rep *
2246sc_fxnum::get_rep() const
2247{
2248    SC_FXNUM_OBSERVER_READ_(*this)
2249    return m_rep;
2250}
2251
2252// unary operators
2253inline const sc_fxval
2254sc_fxnum::operator - () const
2255{
2256    SC_FXNUM_OBSERVER_READ_(*this)
2257    return sc_fxval(sc_dt::neg_scfx_rep(*m_rep));
2258}
2259
2260inline const sc_fxval
2261sc_fxnum::operator + () const
2262{
2263    SC_FXNUM_OBSERVER_READ_(*this)
2264    return sc_fxval(new scfx_rep(*m_rep));
2265}
2266
2267// unary functions
2268inline void
2269neg(sc_fxval &c, const sc_fxnum &a)
2270{
2271    SC_FXNUM_OBSERVER_READ_(a)
2272    c.set_rep(sc_dt::neg_scfx_rep(*a.m_rep));
2273}
2274
2275inline void
2276neg(sc_fxnum &c, const sc_fxnum &a)
2277{
2278    SC_FXNUM_OBSERVER_READ_(a)
2279    delete c.m_rep;
2280    c.m_rep = sc_dt::neg_scfx_rep(*a.m_rep);
2281    c.cast();
2282    SC_FXNUM_OBSERVER_WRITE_(c)
2283}
2284
2285// binary operators
2286#define DEFN_BIN_OP_T(op, fnc, tp) \
2287inline const sc_fxval \
2288operator op (const sc_fxnum &a, tp b) \
2289{ \
2290    SC_FXNUM_OBSERVER_READ_(a) \
2291    sc_fxval tmp(b); \
2292    return sc_fxval(sc_dt::fnc ## _scfx_rep(*a.m_rep, *tmp.get_rep())); \
2293} \
2294 \
2295inline const sc_fxval \
2296operator op (tp a, const sc_fxnum &b) \
2297{ \
2298    SC_FXNUM_OBSERVER_READ_(b) \
2299    sc_fxval tmp(a); \
2300    return sc_fxval(sc_dt::fnc ## _scfx_rep(*tmp.get_rep(), *b.m_rep)); \
2301}
2302
2303#ifndef SC_FX_EXCLUDE_OTHER
2304#define DEFN_BIN_OP_OTHER(op, fnc) \
2305DEFN_BIN_OP_T(op, fnc, int64) \
2306DEFN_BIN_OP_T(op, fnc, uint64) \
2307DEFN_BIN_OP_T(op, fnc, const sc_int_base &) \
2308DEFN_BIN_OP_T(op, fnc, const sc_uint_base &) \
2309DEFN_BIN_OP_T(op, fnc, const sc_signed &) \
2310DEFN_BIN_OP_T(op, fnc, const sc_unsigned &)
2311#else
2312#define DEFN_BIN_OP_OTHER(op, fnc)
2313#endif
2314
2315#define DEFN_BIN_OP(op, fnc) \
2316inline const sc_fxval \
2317operator op (const sc_fxnum &a, const sc_fxnum &b) \
2318{ \
2319    SC_FXNUM_OBSERVER_READ_(a) \
2320    SC_FXNUM_OBSERVER_READ_(b) \
2321    return sc_fxval(sc_dt::fnc ## _scfx_rep(*a.m_rep, *b.m_rep)); \
2322} \
2323 \
2324inline const sc_fxval \
2325operator op (const sc_fxnum &a, const sc_fxval &b) \
2326{ \
2327    SC_FXNUM_OBSERVER_READ_(a) \
2328    return sc_fxval(sc_dt::fnc ## _scfx_rep(*a.m_rep, *b.get_rep())); \
2329} \
2330 \
2331inline const sc_fxval \
2332operator op (const sc_fxval &a, const sc_fxnum &b) \
2333{ \
2334    SC_FXNUM_OBSERVER_READ_(b) \
2335    return sc_fxval(sc_dt::fnc ## _scfx_rep(*a.get_rep(), *b.m_rep)); \
2336} \
2337 \
2338DEFN_BIN_OP_T(op, fnc, int) \
2339DEFN_BIN_OP_T(op, fnc, unsigned int) \
2340DEFN_BIN_OP_T(op, fnc, long) \
2341DEFN_BIN_OP_T(op, fnc, unsigned long) \
2342DEFN_BIN_OP_T(op, fnc, float) \
2343DEFN_BIN_OP_T(op, fnc, double) \
2344DEFN_BIN_OP_T(op, fnc, const char *) \
2345DEFN_BIN_OP_T(op, fnc, const sc_fxval_fast &) \
2346DEFN_BIN_OP_T(op, fnc, const sc_fxnum_fast &) \
2347DEFN_BIN_OP_OTHER(op, fnc)
2348
2349DEFN_BIN_OP(*, mult)
2350DEFN_BIN_OP(+, add)
2351DEFN_BIN_OP(-, sub)
2352// don't use macros
2353//DEFN_BIN_OP(/, div)
2354inline const sc_fxval
2355operator / (const sc_fxnum &a, const sc_fxnum &b)
2356{
2357    SC_FXNUM_OBSERVER_READ_(a)
2358    SC_FXNUM_OBSERVER_READ_(b)
2359    return sc_fxval(sc_dt::div_scfx_rep(*a.m_rep, *b.m_rep));
2360}
2361
2362inline const sc_fxval
2363operator / (const sc_fxnum &a, const sc_fxval &b)
2364{
2365    SC_FXNUM_OBSERVER_READ_(a)
2366    return sc_fxval(sc_dt::div_scfx_rep(*a.m_rep, *b.get_rep()));
2367}
2368
2369inline const sc_fxval
2370operator / (const sc_fxval &a, const sc_fxnum &b)
2371{
2372    SC_FXNUM_OBSERVER_READ_(b)
2373    return sc_fxval(sc_dt::div_scfx_rep(*a.get_rep(), *b.m_rep));
2374}
2375
2376DEFN_BIN_OP_T(/, div, int)
2377DEFN_BIN_OP_T(/, div, unsigned int)
2378DEFN_BIN_OP_T(/, div, long)
2379DEFN_BIN_OP_T(/, div, unsigned long)
2380DEFN_BIN_OP_T(/, div, float)
2381DEFN_BIN_OP_T(/, div, double)
2382DEFN_BIN_OP_T(/, div, const char *)
2383DEFN_BIN_OP_T(/, div, const sc_fxval_fast &)
2384DEFN_BIN_OP_T(/, div, const sc_fxnum_fast &)
2385//DEFN_BIN_OP_OTHER(/, div)
2386
2387DEFN_BIN_OP_T(/, div, int64)
2388DEFN_BIN_OP_T(/, div, uint64)
2389DEFN_BIN_OP_T(/, div, const sc_int_base &)
2390DEFN_BIN_OP_T(/, div, const sc_uint_base &)
2391DEFN_BIN_OP_T(/, div, const sc_signed &)
2392DEFN_BIN_OP_T(/, div, const sc_unsigned &)
2393
2394#undef DEFN_BIN_OP_T
2395#undef DEFN_BIN_OP_OTHER
2396#undef DEFN_BIN_OP
2397
2398inline const sc_fxval
2399operator << (const sc_fxnum &a, int b)
2400{
2401    SC_FXNUM_OBSERVER_READ_(a)
2402    return sc_fxval(sc_dt::lsh_scfx_rep(*a.m_rep, b));
2403}
2404
2405inline const sc_fxval
2406operator >> (const sc_fxnum &a, int b)
2407{
2408    SC_FXNUM_OBSERVER_READ_(a)
2409    return sc_fxval(sc_dt::rsh_scfx_rep(*a.m_rep, b));
2410}
2411
2412// binary functions
2413#define DEFN_BIN_FNC_T(fnc, tp) \
2414inline void \
2415fnc (sc_fxval &c, const sc_fxnum &a, tp b) \
2416{ \
2417    SC_FXNUM_OBSERVER_READ_(a) \
2418    sc_fxval tmp(b); \
2419    c.set_rep(sc_dt::fnc ## _scfx_rep(*a.m_rep, *tmp.get_rep())); \
2420} \
2421 \
2422inline void \
2423fnc (sc_fxval &c, tp a, const sc_fxnum &b) \
2424{ \
2425    SC_FXNUM_OBSERVER_READ_(b) \
2426    sc_fxval tmp(a); \
2427    c.set_rep(sc_dt::fnc ## _scfx_rep(*tmp.get_rep(), *b.m_rep)); \
2428} \
2429 \
2430inline void \
2431fnc (sc_fxnum &c, const sc_fxnum &a, tp b) \
2432{ \
2433    SC_FXNUM_OBSERVER_READ_(a) \
2434    sc_fxval tmp(b); \
2435    delete c.m_rep; \
2436    c.m_rep = sc_dt::fnc ## _scfx_rep(*a.m_rep, *tmp.get_rep()); \
2437    c.cast(); \
2438    SC_FXNUM_OBSERVER_WRITE_(c) \
2439} \
2440 \
2441inline void \
2442fnc (sc_fxnum &c, tp a, const sc_fxnum &b) \
2443{ \
2444    SC_FXNUM_OBSERVER_READ_(b) \
2445    sc_fxval tmp(a); \
2446    delete c.m_rep; \
2447    c.m_rep = sc_dt::fnc ## _scfx_rep(*tmp.get_rep(), *b.m_rep); \
2448    c.cast(); \
2449    SC_FXNUM_OBSERVER_WRITE_(c) \
2450}
2451
2452#define DEFN_BIN_FNC_OTHER(fnc) \
2453DEFN_BIN_FNC_T(fnc, int64) \
2454DEFN_BIN_FNC_T(fnc, uint64) \
2455DEFN_BIN_FNC_T(fnc, const sc_int_base &) \
2456DEFN_BIN_FNC_T(fnc, const sc_uint_base &) \
2457DEFN_BIN_FNC_T(fnc, const sc_signed &) \
2458DEFN_BIN_FNC_T(fnc, const sc_unsigned &)
2459
2460#define DEFN_BIN_FNC(fnc) \
2461inline void \
2462fnc (sc_fxval &c, const sc_fxnum &a, const sc_fxnum &b) \
2463{ \
2464    SC_FXNUM_OBSERVER_READ_(a) \
2465    SC_FXNUM_OBSERVER_READ_(b) \
2466    c.set_rep(sc_dt::fnc ## _scfx_rep(*a.m_rep, *b.m_rep)); \
2467} \
2468 \
2469inline void \
2470fnc (sc_fxnum &c, const sc_fxnum &a, const sc_fxnum &b) \
2471{ \
2472    SC_FXNUM_OBSERVER_READ_(a) \
2473    SC_FXNUM_OBSERVER_READ_(b) \
2474    delete c.m_rep; \
2475    c.m_rep = sc_dt::fnc ## _scfx_rep(*a.m_rep, *b.m_rep); \
2476    c.cast(); \
2477    SC_FXNUM_OBSERVER_WRITE_(c) \
2478} \
2479 \
2480inline void \
2481fnc (sc_fxval &c, const sc_fxnum &a, const sc_fxval &b) \
2482{ \
2483    SC_FXNUM_OBSERVER_READ_(a) \
2484    c.set_rep(sc_dt::fnc ## _scfx_rep(*a.m_rep, *b.get_rep())); \
2485} \
2486 \
2487inline void \
2488fnc (sc_fxval &c, const sc_fxval &a, const sc_fxnum &b) \
2489{ \
2490    SC_FXNUM_OBSERVER_READ_(b) \
2491    c.set_rep(sc_dt::fnc ## _scfx_rep(*a.get_rep(), *b.m_rep)); \
2492} \
2493 \
2494inline void \
2495fnc (sc_fxnum &c, const sc_fxnum &a, const sc_fxval &b) \
2496{ \
2497    SC_FXNUM_OBSERVER_READ_(a) \
2498    delete c.m_rep; \
2499    c.m_rep = sc_dt::fnc ## _scfx_rep(*a.m_rep, *b.get_rep()); \
2500    c.cast(); \
2501    SC_FXNUM_OBSERVER_WRITE_(c) \
2502} \
2503 \
2504inline void \
2505fnc (sc_fxnum &c, const sc_fxval &a, const sc_fxnum &b) \
2506{ \
2507    SC_FXNUM_OBSERVER_READ_(b) \
2508    delete c.m_rep; \
2509    c.m_rep = sc_dt::fnc ## _scfx_rep(*a.get_rep(), *b.m_rep); \
2510    c.cast(); \
2511    SC_FXNUM_OBSERVER_WRITE_(c) \
2512} \
2513 \
2514DEFN_BIN_FNC_T(fnc, int) \
2515DEFN_BIN_FNC_T(fnc, unsigned int) \
2516DEFN_BIN_FNC_T(fnc, long) \
2517DEFN_BIN_FNC_T(fnc, unsigned long) \
2518DEFN_BIN_FNC_T(fnc, float) \
2519DEFN_BIN_FNC_T(fnc, double) \
2520DEFN_BIN_FNC_T(fnc, const char *) \
2521DEFN_BIN_FNC_T(fnc, const sc_fxval_fast &) \
2522DEFN_BIN_FNC_T(fnc, const sc_fxnum_fast &) \
2523DEFN_BIN_FNC_OTHER(fnc)
2524
2525DEFN_BIN_FNC(mult)
2526DEFN_BIN_FNC(div)
2527DEFN_BIN_FNC(add)
2528DEFN_BIN_FNC(sub)
2529
2530#undef DEFN_BIN_FNC_T
2531#undef DEFN_BIN_FNC_OTHER
2532#undef DEFN_BIN_FNC
2533
2534inline void
2535lshift(sc_fxval &c, const sc_fxnum &a, int b)
2536{
2537    SC_FXNUM_OBSERVER_READ_(a)
2538    c.set_rep(sc_dt::lsh_scfx_rep(*a.m_rep, b));
2539}
2540
2541inline void
2542rshift(sc_fxval &c, const sc_fxnum &a, int b)
2543{
2544    SC_FXNUM_OBSERVER_READ_(a)
2545    c.set_rep(sc_dt::rsh_scfx_rep(*a.m_rep, b));
2546}
2547
2548inline void
2549lshift(sc_fxnum &c, const sc_fxnum &a, int b)
2550{
2551    SC_FXNUM_OBSERVER_READ_(a)
2552    delete c.m_rep;
2553    c.m_rep = sc_dt::lsh_scfx_rep(*a.m_rep, b);
2554    c.cast();
2555    SC_FXNUM_OBSERVER_WRITE_(c)
2556}
2557
2558inline void
2559rshift(sc_fxnum &c, const sc_fxnum &a, int b)
2560{
2561    SC_FXNUM_OBSERVER_READ_(a)
2562    delete c.m_rep;
2563    c.m_rep = sc_dt::rsh_scfx_rep(*a.m_rep, b);
2564    c.cast();
2565    SC_FXNUM_OBSERVER_WRITE_(c)
2566}
2567
2568// relational (including equality) operators
2569#define DEFN_REL_OP_T(op, ret, tp) \
2570inline bool \
2571operator op (const sc_fxnum &a, tp b) \
2572{ \
2573    SC_FXNUM_OBSERVER_READ_(a) \
2574    sc_fxval tmp(b); \
2575    int result = sc_dt::cmp_scfx_rep(*a.m_rep, *tmp.get_rep()); \
2576    return (ret); \
2577} \
2578 \
2579inline bool \
2580operator op (tp a, const sc_fxnum &b) \
2581{ \
2582    SC_FXNUM_OBSERVER_READ_(b) \
2583    sc_fxval tmp(a); \
2584    int result = sc_dt::cmp_scfx_rep(*tmp.get_rep(), *b.m_rep); \
2585    return (ret); \
2586}
2587
2588#define DEFN_REL_OP_OTHER(op, ret) \
2589DEFN_REL_OP_T(op, ret, int64) \
2590DEFN_REL_OP_T(op, ret, uint64) \
2591DEFN_REL_OP_T(op, ret, const sc_int_base &) \
2592DEFN_REL_OP_T(op, ret, const sc_uint_base &) \
2593DEFN_REL_OP_T(op, ret, const sc_signed &) \
2594DEFN_REL_OP_T(op, ret, const sc_unsigned &)
2595
2596#define DEFN_REL_OP(op, ret) \
2597inline bool \
2598operator op (const sc_fxnum &a, const sc_fxnum &b) \
2599{ \
2600    SC_FXNUM_OBSERVER_READ_(a) \
2601    SC_FXNUM_OBSERVER_READ_(b) \
2602    int result = sc_dt::cmp_scfx_rep(*a.m_rep, *b.m_rep); \
2603    return (ret); \
2604} \
2605 \
2606inline bool \
2607operator op (const sc_fxnum &a, const sc_fxval &b) \
2608{ \
2609    SC_FXNUM_OBSERVER_READ_(a) \
2610    int result = sc_dt::cmp_scfx_rep(*a.m_rep, *b.get_rep()); \
2611    return (ret); \
2612} \
2613 \
2614inline bool \
2615operator op (const sc_fxval &a, const sc_fxnum &b) \
2616{ \
2617    SC_FXNUM_OBSERVER_READ_(b) \
2618    int result = sc_dt::cmp_scfx_rep(*a.get_rep(), *b.m_rep); \
2619    return (ret); \
2620} \
2621 \
2622DEFN_REL_OP_T(op, ret, int) \
2623DEFN_REL_OP_T(op, ret, unsigned int) \
2624DEFN_REL_OP_T(op, ret, long) \
2625DEFN_REL_OP_T(op, ret, unsigned long) \
2626DEFN_REL_OP_T(op, ret, float) \
2627DEFN_REL_OP_T(op, ret, double) \
2628DEFN_REL_OP_T(op, ret, const char *) \
2629DEFN_REL_OP_T(op, ret, const sc_fxval_fast &) \
2630DEFN_REL_OP_T(op, ret, const sc_fxnum_fast &) \
2631DEFN_REL_OP_OTHER(op, ret)
2632
2633DEFN_REL_OP(<, result < 0)
2634DEFN_REL_OP(<=, result <= 0)
2635DEFN_REL_OP(>, result > 0 && result != 2)
2636DEFN_REL_OP(>=, result >= 0 && result != 2)
2637DEFN_REL_OP(==, result == 0)
2638DEFN_REL_OP(!=, result != 0)
2639
2640#undef DEFN_REL_OP_T
2641#undef DEFN_REL_OP_OTHER
2642#undef DEFN_REL_OP
2643
2644// assignment operators
2645inline sc_fxnum &
2646sc_fxnum::operator = (const sc_fxnum &a)
2647{
2648    if (&a != this) {
2649        SC_FXNUM_OBSERVER_READ_(a)
2650        *m_rep = *a.m_rep;
2651        cast();
2652        SC_FXNUM_OBSERVER_WRITE_(*this)
2653    }
2654    return *this;
2655}
2656
2657inline sc_fxnum &
2658sc_fxnum::operator = (const sc_fxval &a)
2659{
2660    *m_rep = *a.get_rep();
2661    cast();
2662    SC_FXNUM_OBSERVER_WRITE_(*this)
2663    return *this;
2664}
2665
2666#define DEFN_ASN_OP_T(tp) \
2667inline sc_fxnum & \
2668sc_fxnum::operator = (tp a) \
2669{ \
2670    sc_fxval tmp(a); \
2671    *m_rep = *tmp.get_rep(); \
2672    cast(); \
2673    SC_FXNUM_OBSERVER_WRITE_(*this) \
2674    return *this; \
2675}
2676
2677DEFN_ASN_OP_T(int)
2678DEFN_ASN_OP_T(unsigned int)
2679DEFN_ASN_OP_T(long)
2680DEFN_ASN_OP_T(unsigned long)
2681DEFN_ASN_OP_T(float)
2682DEFN_ASN_OP_T(double)
2683DEFN_ASN_OP_T(const char *)
2684DEFN_ASN_OP_T(const sc_fxval_fast &)
2685DEFN_ASN_OP_T(const sc_fxnum_fast &)
2686
2687DEFN_ASN_OP_T(int64)
2688DEFN_ASN_OP_T(uint64)
2689DEFN_ASN_OP_T(const sc_int_base &)
2690DEFN_ASN_OP_T(const sc_uint_base &)
2691DEFN_ASN_OP_T(const sc_signed &)
2692DEFN_ASN_OP_T(const sc_unsigned &)
2693
2694#undef DEFN_ASN_OP_T
2695
2696
2697#define DEFN_ASN_OP_T(op, fnc, tp) \
2698inline sc_fxnum & \
2699sc_fxnum::operator op (tp b) \
2700{ \
2701    SC_FXNUM_OBSERVER_READ_(*this) \
2702    sc_fxval tmp(b); \
2703    scfx_rep *new_rep = sc_dt::fnc ## _scfx_rep(*m_rep, *tmp.get_rep()); \
2704    delete m_rep; \
2705    m_rep = new_rep; \
2706    cast(); \
2707    SC_FXNUM_OBSERVER_WRITE_(*this) \
2708    return *this; \
2709}
2710
2711#define DEFN_ASN_OP_OTHER(op, fnc) \
2712DEFN_ASN_OP_T(op, fnc, int64) \
2713DEFN_ASN_OP_T(op, fnc, uint64) \
2714DEFN_ASN_OP_T(op, fnc, const sc_int_base &) \
2715DEFN_ASN_OP_T(op, fnc, const sc_uint_base &) \
2716DEFN_ASN_OP_T(op, fnc, const sc_signed &) \
2717DEFN_ASN_OP_T(op, fnc, const sc_unsigned &)
2718
2719#define DEFN_ASN_OP(op, fnc) \
2720inline sc_fxnum & \
2721sc_fxnum::operator op (const sc_fxnum &b) \
2722{ \
2723    SC_FXNUM_OBSERVER_READ_(*this) \
2724    SC_FXNUM_OBSERVER_READ_(b) \
2725    scfx_rep *new_rep = sc_dt::fnc ## _scfx_rep(*m_rep, *b.m_rep); \
2726    delete m_rep; \
2727    m_rep = new_rep; \
2728    cast(); \
2729    SC_FXNUM_OBSERVER_WRITE_(*this) \
2730    return *this; \
2731} \
2732 \
2733inline sc_fxnum & \
2734sc_fxnum::operator op (const sc_fxval &b) \
2735{ \
2736    SC_FXNUM_OBSERVER_READ_(*this) \
2737    scfx_rep *new_rep = sc_dt::fnc ## _scfx_rep(*m_rep, *b.get_rep()); \
2738    delete m_rep; \
2739    m_rep = new_rep; \
2740    cast(); \
2741    SC_FXNUM_OBSERVER_WRITE_(*this) \
2742    return *this; \
2743} \
2744 \
2745DEFN_ASN_OP_T(op, fnc, int) \
2746DEFN_ASN_OP_T(op, fnc, unsigned int) \
2747DEFN_ASN_OP_T(op, fnc, long) \
2748DEFN_ASN_OP_T(op, fnc, unsigned long) \
2749DEFN_ASN_OP_T(op, fnc, float) \
2750DEFN_ASN_OP_T(op, fnc, double) \
2751DEFN_ASN_OP_T(op, fnc, const char *) \
2752DEFN_ASN_OP_T(op, fnc, const sc_fxval_fast &) \
2753DEFN_ASN_OP_T(op, fnc, const sc_fxnum_fast &) \
2754DEFN_ASN_OP_OTHER(op, fnc)
2755
2756DEFN_ASN_OP(*=, mult)
2757DEFN_ASN_OP(/=, div)
2758DEFN_ASN_OP(+=, add)
2759DEFN_ASN_OP(-=, sub)
2760
2761#undef DEFN_ASN_OP_T
2762#undef DEFN_ASN_OP_OTHER
2763#undef DEFN_ASN_OP
2764
2765
2766inline sc_fxnum &
2767sc_fxnum::operator <<= (int b)
2768{
2769    SC_FXNUM_OBSERVER_READ_(*this)
2770    m_rep->lshift(b);
2771    cast();
2772    SC_FXNUM_OBSERVER_WRITE_(*this)
2773    return *this;
2774}
2775
2776inline sc_fxnum &
2777sc_fxnum::operator >>= (int b)
2778{
2779    SC_FXNUM_OBSERVER_READ_(*this)
2780    m_rep->rshift(b);
2781    cast();
2782    SC_FXNUM_OBSERVER_WRITE_(*this)
2783    return *this;
2784}
2785
2786// auto-increment and auto-decrement
2787inline const sc_fxval
2788sc_fxnum::operator ++ (int)
2789{
2790    sc_fxval c(*this);
2791    (*this) += 1;
2792    return c;
2793}
2794
2795inline const sc_fxval
2796sc_fxnum::operator -- (int)
2797{
2798    sc_fxval c(*this);
2799    (*this) -= 1;
2800    return c;
2801}
2802
2803inline sc_fxnum &
2804sc_fxnum::operator ++ ()
2805{
2806    (*this) += 1;
2807    return *this;
2808}
2809
2810inline sc_fxnum &
2811sc_fxnum::operator -- ()
2812{
2813    (*this) -= 1;
2814    return *this;
2815}
2816
2817// bit selection
2818inline const sc_fxnum_bitref
2819sc_fxnum::operator [] (int i) const
2820{
2821    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2822    return sc_fxnum_bitref(const_cast<sc_fxnum &>(*this),
2823                           i - m_params.fwl());
2824}
2825
2826inline sc_fxnum_bitref
2827sc_fxnum::operator [] (int i)
2828{
2829    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2830    return sc_fxnum_bitref(*this, i - m_params.fwl());
2831}
2832
2833inline const sc_fxnum_bitref
2834sc_fxnum::bit(int i) const
2835{
2836    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2837    return sc_fxnum_bitref(const_cast<sc_fxnum &>(*this),
2838                            i - m_params.fwl());
2839}
2840
2841inline sc_fxnum_bitref
2842sc_fxnum::bit(int i)
2843{
2844    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2845    return sc_fxnum_bitref(*this, i - m_params.fwl());
2846}
2847
2848// part selection
2849
2850inline const sc_fxnum_subref
2851sc_fxnum::operator () (int i, int j) const
2852{
2853    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2854    SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
2855
2856    return sc_fxnum_subref(const_cast<sc_fxnum &>(*this),
2857                           i - m_params.fwl(), j - m_params.fwl());
2858}
2859
2860inline sc_fxnum_subref
2861sc_fxnum::operator () (int i, int j)
2862{
2863    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2864    SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
2865
2866    return sc_fxnum_subref(*this, i - m_params.fwl(), j - m_params.fwl());
2867}
2868
2869inline const sc_fxnum_subref
2870sc_fxnum::range(int i, int j) const
2871{
2872    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2873    SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
2874
2875    return sc_fxnum_subref(const_cast<sc_fxnum &>(*this),
2876                           i - m_params.fwl(), j - m_params.fwl());
2877}
2878
2879inline sc_fxnum_subref
2880sc_fxnum::range(int i, int j)
2881{
2882    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
2883    SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
2884
2885    return sc_fxnum_subref(*this, i - m_params.fwl(), j - m_params.fwl());
2886}
2887
2888
2889inline const sc_fxnum_subref
2890sc_fxnum::operator () () const
2891{
2892    return this->operator () (m_params.wl() - 1, 0);
2893}
2894
2895inline sc_fxnum_subref
2896sc_fxnum::operator () ()
2897{
2898    return this->operator () (m_params.wl() - 1, 0);
2899}
2900
2901inline const sc_fxnum_subref
2902sc_fxnum::range() const
2903{
2904    return this->range(m_params.wl() - 1, 0);
2905}
2906
2907inline sc_fxnum_subref
2908sc_fxnum::range()
2909{
2910    return this->range(m_params.wl() - 1, 0);
2911}
2912
2913// implicit conversion
2914inline sc_fxnum::operator double() const
2915{
2916    SC_FXNUM_OBSERVER_READ_(*this)
2917    return m_rep->to_double();
2918}
2919
2920// explicit conversion to primitive types
2921inline short
2922sc_fxnum::to_short() const
2923{
2924    SC_FXNUM_OBSERVER_READ_(*this)
2925    return static_cast<short>(m_rep->to_uint64());
2926}
2927
2928inline unsigned short
2929sc_fxnum::to_ushort() const
2930{
2931    SC_FXNUM_OBSERVER_READ_(*this)
2932    return static_cast<unsigned short>(m_rep->to_uint64());
2933}
2934
2935inline int
2936sc_fxnum::to_int() const
2937{
2938    SC_FXNUM_OBSERVER_READ_(*this)
2939    return static_cast<int>(m_rep->to_uint64());
2940}
2941
2942inline int64
2943sc_fxnum::to_int64() const
2944{
2945    SC_FXNUM_OBSERVER_READ_(*this)
2946    return static_cast<int64>(m_rep->to_uint64());
2947}
2948
2949inline unsigned int
2950sc_fxnum::to_uint() const
2951{
2952    SC_FXNUM_OBSERVER_READ_(*this)
2953    return static_cast<unsigned int>(m_rep->to_uint64());
2954}
2955
2956inline uint64
2957sc_fxnum::to_uint64() const
2958{
2959    SC_FXNUM_OBSERVER_READ_(*this)
2960    return m_rep->to_uint64();
2961}
2962
2963inline long
2964sc_fxnum::to_long() const
2965{
2966    SC_FXNUM_OBSERVER_READ_(*this)
2967    return static_cast<long>(m_rep->to_uint64());
2968}
2969
2970inline unsigned long
2971sc_fxnum::to_ulong() const
2972{
2973    SC_FXNUM_OBSERVER_READ_(*this)
2974    return static_cast<unsigned long>(m_rep->to_uint64());
2975}
2976
2977inline float
2978sc_fxnum::to_float() const
2979{
2980    SC_FXNUM_OBSERVER_READ_(*this)
2981    return static_cast<float>(m_rep->to_double());
2982}
2983
2984inline double
2985sc_fxnum::to_double() const
2986{
2987    SC_FXNUM_OBSERVER_READ_(*this)
2988    return m_rep->to_double();
2989}
2990
2991// query value
2992inline bool
2993sc_fxnum::is_neg() const
2994{
2995    SC_FXNUM_OBSERVER_READ_(*this)
2996    return m_rep->is_neg();
2997}
2998
2999inline bool
3000sc_fxnum::is_zero() const
3001{
3002    SC_FXNUM_OBSERVER_READ_(*this)
3003    return m_rep->is_zero();
3004}
3005
3006// internal use only;
3007inline bool
3008sc_fxnum::is_normal() const
3009{
3010    SC_FXNUM_OBSERVER_READ_(*this)
3011    return m_rep->is_normal();
3012}
3013
3014inline bool
3015sc_fxnum::quantization_flag() const
3016{
3017    return m_q_flag;
3018}
3019
3020inline bool
3021sc_fxnum::overflow_flag() const
3022{
3023    return m_o_flag;
3024}
3025
3026
3027inline const sc_fxval
3028sc_fxnum::value() const
3029{
3030    SC_FXNUM_OBSERVER_READ_(*this)
3031    return sc_fxval(new scfx_rep(*m_rep));
3032}
3033
3034// query parameters
3035inline int
3036sc_fxnum::wl() const
3037{
3038    return m_params.wl();
3039}
3040
3041inline int
3042sc_fxnum::iwl() const
3043{
3044    return m_params.iwl();
3045}
3046
3047inline sc_q_mode
3048sc_fxnum::q_mode() const
3049{
3050    return m_params.q_mode();
3051}
3052
3053inline sc_o_mode
3054sc_fxnum::o_mode() const
3055{
3056    return m_params.o_mode();
3057}
3058
3059inline int
3060sc_fxnum::n_bits() const
3061{
3062    return m_params.n_bits();
3063}
3064
3065inline const sc_fxtype_params &
3066sc_fxnum::type_params() const
3067{
3068    return m_params.type_params();
3069}
3070
3071inline const sc_fxcast_switch &
3072sc_fxnum::cast_switch() const
3073{
3074    return m_params.cast_switch();
3075}
3076
3077// internal use only;
3078inline void
3079sc_fxnum::observer_read() const
3080{
3081    SC_FXNUM_OBSERVER_READ_(*this);
3082}
3083
3084// internal use only;
3085inline bool
3086sc_fxnum::get_bit(int i) const
3087{
3088    return m_rep->get_bit(i);
3089}
3090
3091// protected methods and friend functions
3092inline bool
3093sc_fxnum::set_bit(int i, bool high)
3094{
3095    if (high)
3096        return m_rep->set(i, m_params);
3097    else
3098        return m_rep->clear(i, m_params);
3099}
3100
3101inline bool
3102sc_fxnum::get_slice(int i, int j, sc_bv_base &bv) const
3103{
3104    return m_rep->get_slice(i, j, m_params, bv);
3105}
3106
3107inline bool
3108sc_fxnum::set_slice(int i, int j, const sc_bv_base &bv)
3109{
3110    return m_rep->set_slice(i, j, m_params, bv);
3111}
3112
3113inline ::std::ostream &
3114operator << (::std::ostream &os, const sc_fxnum &a)
3115{
3116    a.print(os);
3117    return os;
3118}
3119
3120inline ::std::istream &
3121operator >> (::std::istream &is, sc_fxnum &a)
3122{
3123    a.scan(is);
3124    return is;
3125}
3126
3127
3128// ----------------------------------------------------------------------------
3129// CLASS : sc_fxnum_fast
3130//
3131// Base class for the fixed-point types; limited precision.
3132// ----------------------------------------------------------------------------
3133
3134inline sc_fxnum_fast_observer *
3135sc_fxnum_fast::observer() const
3136{
3137    return m_observer;
3138}
3139
3140
3141// constructors
3142inline sc_fxnum_fast::sc_fxnum_fast(const sc_fxtype_params &type_params_,
3143                                    sc_enc enc_,
3144                                    const sc_fxcast_switch &cast_sw,
3145                                    sc_fxnum_fast_observer *observer_) :
3146    m_val(0.0), m_params(type_params_, enc_, cast_sw), m_q_flag(false),
3147    m_o_flag(false), m_observer(observer_)
3148{
3149    SC_FXNUM_FAST_OBSERVER_DEFAULT_
3150    SC_FXNUM_FAST_OBSERVER_CONSTRUCT_(*this)
3151}
3152
3153inline sc_fxnum_fast::sc_fxnum_fast(const sc_fxnum_fast &a,
3154                                    const sc_fxtype_params &type_params_,
3155                                    sc_enc enc_,
3156                                    const sc_fxcast_switch &cast_sw,
3157                                    sc_fxnum_fast_observer *observer_) :
3158    m_val(a.m_val), m_params(type_params_, enc_, cast_sw), m_q_flag(false),
3159    m_o_flag(false), m_observer(observer_)
3160{
3161    SC_FXNUM_FAST_OBSERVER_DEFAULT_
3162    SC_FXNUM_FAST_OBSERVER_READ_(a)
3163    cast();
3164    SC_FXNUM_FAST_OBSERVER_CONSTRUCT_(*this)
3165    SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3166}
3167
3168#define DEFN_CTOR_T(tp, arg) \
3169inline sc_fxnum_fast::sc_fxnum_fast( \
3170        tp a, const sc_fxtype_params &type_params_, sc_enc enc_, \
3171        const sc_fxcast_switch &cast_sw, \
3172        sc_fxnum_fast_observer *observer_) : \
3173    m_val(arg), m_params(type_params_, enc_, cast_sw), m_q_flag(false), \
3174    m_o_flag(false), m_observer(observer_) \
3175{ \
3176    SC_FXNUM_FAST_OBSERVER_DEFAULT_ \
3177    cast(); \
3178    SC_FXNUM_FAST_OBSERVER_CONSTRUCT_(*this) \
3179    SC_FXNUM_FAST_OBSERVER_WRITE_(*this) \
3180}
3181
3182#define DEFN_CTOR_T_A(tp) DEFN_CTOR_T(tp, static_cast<double>(a))
3183#define DEFN_CTOR_T_B(tp) DEFN_CTOR_T(tp, sc_fxval_fast::from_string(a))
3184#define DEFN_CTOR_T_C(tp) DEFN_CTOR_T(tp, a.to_double())
3185
3186DEFN_CTOR_T_A(int)
3187DEFN_CTOR_T_A(unsigned int)
3188DEFN_CTOR_T_A(long)
3189DEFN_CTOR_T_A(unsigned long)
3190DEFN_CTOR_T_A(float)
3191DEFN_CTOR_T_A(double)
3192DEFN_CTOR_T_B(const char *)
3193DEFN_CTOR_T_C(const sc_fxval &)
3194DEFN_CTOR_T_C(const sc_fxval_fast &)
3195DEFN_CTOR_T_C(const sc_fxnum &)
3196
3197DEFN_CTOR_T_A(int64)
3198DEFN_CTOR_T_A(uint64)
3199DEFN_CTOR_T_C(const sc_int_base &)
3200DEFN_CTOR_T_C(const sc_uint_base &)
3201DEFN_CTOR_T_C(const sc_signed &)
3202DEFN_CTOR_T_C(const sc_unsigned &)
3203
3204#undef DEFN_CTOR_T
3205#undef DEFN_CTOR_T_A
3206#undef DEFN_CTOR_T_B
3207#undef DEFN_CTOR_T_C
3208#undef DEFN_CTOR_T_D
3209#undef DEFN_CTOR_T_E
3210
3211inline sc_fxnum_fast::~sc_fxnum_fast()
3212{
3213    SC_FXNUM_FAST_OBSERVER_DESTRUCT_(*this)
3214}
3215
3216// internal use only;
3217inline double
3218sc_fxnum_fast::get_val() const
3219{
3220    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3221    return m_val;
3222}
3223
3224// unary operators
3225inline const sc_fxval_fast
3226sc_fxnum_fast::operator - () const
3227{
3228    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3229    return sc_fxval_fast(- m_val);
3230}
3231
3232inline const sc_fxval_fast
3233sc_fxnum_fast::operator + () const
3234{
3235    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3236    return sc_fxval_fast(m_val);
3237}
3238
3239// unary functions
3240inline void
3241neg(sc_fxval_fast &c, const sc_fxnum_fast &a)
3242{
3243    SC_FXNUM_FAST_OBSERVER_READ_(a)
3244    c.set_val(- a.m_val);
3245}
3246
3247inline void
3248neg(sc_fxnum_fast &c, const sc_fxnum_fast &a)
3249{
3250    SC_FXNUM_FAST_OBSERVER_READ_(a)
3251    c.m_val = - a.m_val;
3252    c.cast();
3253    SC_FXNUM_FAST_OBSERVER_WRITE_(c)
3254}
3255
3256// binary operators
3257#define DEFN_BIN_OP_T(op, tp) \
3258inline const sc_fxval_fast \
3259operator op (const sc_fxnum_fast &a, tp b) \
3260{ \
3261    SC_FXNUM_FAST_OBSERVER_READ_(a) \
3262    sc_fxval_fast tmp(b); \
3263    return sc_fxval_fast(a.m_val op tmp.get_val()); \
3264} \
3265 \
3266inline const sc_fxval_fast \
3267operator op (tp a, const sc_fxnum_fast &b) \
3268{ \
3269    SC_FXNUM_FAST_OBSERVER_READ_(b) \
3270    sc_fxval_fast tmp(a); \
3271    return sc_fxval_fast(tmp.get_val() op b.m_val); \
3272}
3273
3274#define DEFN_BIN_OP_OTHER(op) \
3275DEFN_BIN_OP_T(op, int64) \
3276DEFN_BIN_OP_T(op, uint64) \
3277DEFN_BIN_OP_T(op, const sc_int_base &) \
3278DEFN_BIN_OP_T(op, const sc_uint_base &) \
3279DEFN_BIN_OP_T(op, const sc_signed &) \
3280DEFN_BIN_OP_T(op, const sc_unsigned &)
3281
3282#define DEFN_BIN_OP(op, dummy) \
3283inline const sc_fxval_fast \
3284operator op (const sc_fxnum_fast &a, const sc_fxnum_fast &b) \
3285{ \
3286    SC_FXNUM_FAST_OBSERVER_READ_(a) \
3287    SC_FXNUM_FAST_OBSERVER_READ_(b) \
3288    return sc_fxval_fast(a.m_val op b.m_val); \
3289} \
3290 \
3291inline const sc_fxval_fast \
3292operator op (const sc_fxnum_fast &a, const sc_fxval_fast &b) \
3293{ \
3294    SC_FXNUM_FAST_OBSERVER_READ_(a) \
3295    return sc_fxval_fast(a.m_val op b.get_val()); \
3296} \
3297 \
3298inline const sc_fxval_fast \
3299operator op (const sc_fxval_fast &a, const sc_fxnum_fast &b) \
3300{ \
3301    SC_FXNUM_FAST_OBSERVER_READ_(b) \
3302    return sc_fxval_fast(a.get_val() op b.m_val); \
3303} \
3304 \
3305DEFN_BIN_OP_T(op, int) \
3306DEFN_BIN_OP_T(op, unsigned int) \
3307DEFN_BIN_OP_T(op, long) \
3308DEFN_BIN_OP_T(op, unsigned long) \
3309DEFN_BIN_OP_T(op, float) \
3310DEFN_BIN_OP_T(op, double) \
3311DEFN_BIN_OP_T(op, const char *) \
3312DEFN_BIN_OP_OTHER(op)
3313
3314DEFN_BIN_OP(*, mult)
3315DEFN_BIN_OP(+, add)
3316DEFN_BIN_OP(-, sub)
3317//DEFN_BIN_OP(/, div)
3318inline const sc_fxval_fast
3319operator / (const sc_fxnum_fast &a, const sc_fxnum_fast &b)
3320{
3321    SC_FXNUM_FAST_OBSERVER_READ_(a)
3322    SC_FXNUM_FAST_OBSERVER_READ_(b)
3323    return sc_fxval_fast(a.m_val / b.m_val);
3324}
3325
3326inline const sc_fxval_fast
3327operator / (const sc_fxnum_fast &a, const sc_fxval_fast &b)
3328{
3329    SC_FXNUM_FAST_OBSERVER_READ_(a)
3330    return sc_fxval_fast(a.m_val / b.get_val());
3331}
3332
3333inline const sc_fxval_fast
3334operator / (const sc_fxval_fast &a, const sc_fxnum_fast &b)
3335{
3336    SC_FXNUM_FAST_OBSERVER_READ_(b)
3337    return sc_fxval_fast(a.get_val() / b.m_val);
3338}
3339
3340DEFN_BIN_OP_T(/, int)
3341DEFN_BIN_OP_T(/, unsigned int)
3342DEFN_BIN_OP_T(/, long)
3343DEFN_BIN_OP_T(/, unsigned long)
3344DEFN_BIN_OP_T(/, float)
3345DEFN_BIN_OP_T(/, double)
3346DEFN_BIN_OP_T(/, const char *)
3347//DEFN_BIN_OP_OTHER(/)
3348
3349DEFN_BIN_OP_T(/, int64)
3350DEFN_BIN_OP_T(/, uint64)
3351DEFN_BIN_OP_T(/, const sc_int_base &)
3352DEFN_BIN_OP_T(/, const sc_uint_base &)
3353DEFN_BIN_OP_T(/, const sc_signed &)
3354DEFN_BIN_OP_T(/, const sc_unsigned &)
3355
3356#undef DEFN_BIN_OP_T
3357#undef DEFN_BIN_OP_OTHER
3358#undef DEFN_BIN_OP
3359
3360inline const sc_fxval_fast
3361operator << (const sc_fxnum_fast &a, int b)
3362{
3363    SC_FXNUM_FAST_OBSERVER_READ_(a)
3364    return sc_fxval_fast(a.m_val  *scfx_pow2(b));
3365}
3366
3367inline const sc_fxval_fast
3368operator >> (const sc_fxnum_fast &a, int b)
3369{
3370    SC_FXNUM_FAST_OBSERVER_READ_(a)
3371    return sc_fxval_fast(a.m_val  *scfx_pow2(-b));
3372}
3373
3374// binary functions
3375#define DEFN_BIN_FNC_T(fnc, op, tp) \
3376inline void \
3377fnc (sc_fxval_fast &c, const sc_fxnum_fast &a, tp b) \
3378{ \
3379    SC_FXNUM_FAST_OBSERVER_READ_(a) \
3380    sc_fxval_fast tmp(b); \
3381    c.set_val(a.m_val op tmp.get_val()); \
3382} \
3383 \
3384inline void \
3385fnc (sc_fxval_fast &c, tp a, const sc_fxnum_fast &b) \
3386{ \
3387    SC_FXNUM_FAST_OBSERVER_READ_(b) \
3388    sc_fxval_fast tmp(a); \
3389    c.set_val(tmp.get_val() op b.m_val); \
3390} \
3391 \
3392inline void \
3393fnc (sc_fxnum_fast &c, const sc_fxnum_fast &a, tp b) \
3394{ \
3395    SC_FXNUM_FAST_OBSERVER_READ_(a) \
3396    sc_fxval_fast tmp(b); \
3397    c.m_val = a.m_val op tmp.get_val(); \
3398    c.cast(); \
3399    SC_FXNUM_FAST_OBSERVER_WRITE_(c) \
3400} \
3401 \
3402inline void \
3403fnc (sc_fxnum_fast &c, tp a, const sc_fxnum_fast &b) \
3404{ \
3405    SC_FXNUM_FAST_OBSERVER_READ_(b) \
3406    sc_fxval_fast tmp(a); \
3407    c.m_val = tmp.get_val() op b.m_val; \
3408    c.cast(); \
3409    SC_FXNUM_FAST_OBSERVER_WRITE_(c) \
3410}
3411
3412#define DEFN_BIN_FNC_OTHER(fnc, op) \
3413DEFN_BIN_FNC_T(fnc, op, int64) \
3414DEFN_BIN_FNC_T(fnc, op, uint64) \
3415DEFN_BIN_FNC_T(fnc, op, const sc_int_base &) \
3416DEFN_BIN_FNC_T(fnc, op, const sc_uint_base &) \
3417DEFN_BIN_FNC_T(fnc, op, const sc_signed &) \
3418DEFN_BIN_FNC_T(fnc, op, const sc_unsigned &)
3419
3420#define DEFN_BIN_FNC(fnc, op) \
3421inline void \
3422fnc (sc_fxval_fast &c, const sc_fxnum_fast &a, const sc_fxnum_fast &b) \
3423{ \
3424    SC_FXNUM_FAST_OBSERVER_READ_(a) \
3425    SC_FXNUM_FAST_OBSERVER_READ_(b) \
3426    c.set_val(a.m_val op b.m_val); \
3427} \
3428 \
3429inline void \
3430fnc (sc_fxnum_fast &c, const sc_fxnum_fast &a, const sc_fxnum_fast &b) \
3431{ \
3432    SC_FXNUM_FAST_OBSERVER_READ_(a) \
3433    SC_FXNUM_FAST_OBSERVER_READ_(b) \
3434    c.m_val = a.m_val op b.m_val; \
3435    c.cast(); \
3436    SC_FXNUM_FAST_OBSERVER_WRITE_(c) \
3437} \
3438 \
3439inline void \
3440fnc (sc_fxval_fast &c, const sc_fxnum_fast &a, const sc_fxval_fast &b) \
3441{ \
3442    SC_FXNUM_FAST_OBSERVER_READ_(a) \
3443    c.set_val(a.m_val op b.get_val()); \
3444} \
3445 \
3446inline void \
3447fnc (sc_fxval_fast &c, const sc_fxval_fast &a, const sc_fxnum_fast &b) \
3448{ \
3449    SC_FXNUM_FAST_OBSERVER_READ_(b) \
3450    c.set_val(a.get_val() op b.m_val); \
3451} \
3452 \
3453inline void \
3454fnc (sc_fxnum_fast &c, const sc_fxnum_fast &a, const sc_fxval_fast &b) \
3455{ \
3456    SC_FXNUM_FAST_OBSERVER_READ_(a) \
3457    c.m_val = a.m_val op b.get_val(); \
3458    c.cast(); \
3459    SC_FXNUM_FAST_OBSERVER_WRITE_(c) \
3460} \
3461 \
3462inline void \
3463fnc (sc_fxnum_fast &c, const sc_fxval_fast &a, const sc_fxnum_fast &b) \
3464{ \
3465    SC_FXNUM_FAST_OBSERVER_READ_(b) \
3466    c.m_val = a.get_val() op b.m_val; \
3467    c.cast(); \
3468    SC_FXNUM_FAST_OBSERVER_WRITE_(c) \
3469} \
3470 \
3471DEFN_BIN_FNC_T(fnc, op, int) \
3472DEFN_BIN_FNC_T(fnc, op, unsigned int) \
3473DEFN_BIN_FNC_T(fnc, op, long) \
3474DEFN_BIN_FNC_T(fnc, op, unsigned long) \
3475DEFN_BIN_FNC_T(fnc, op, float) \
3476DEFN_BIN_FNC_T(fnc, op, double) \
3477DEFN_BIN_FNC_T(fnc, op, const char *) \
3478DEFN_BIN_FNC_T(fnc, op, const sc_fxval &) \
3479DEFN_BIN_FNC_T(fnc, op, const sc_fxnum &) \
3480DEFN_BIN_FNC_OTHER(fnc, op)
3481
3482DEFN_BIN_FNC(mult, *)
3483DEFN_BIN_FNC(div, /)
3484DEFN_BIN_FNC(add, +)
3485DEFN_BIN_FNC(sub, -)
3486
3487#undef DEFN_BIN_FNC_T
3488#undef DEFN_BIN_FNC_OTHER
3489#undef DEFN_BIN_FNC
3490
3491inline void
3492lshift(sc_fxval_fast &c, const sc_fxnum_fast &a, int b)
3493{
3494    SC_FXNUM_FAST_OBSERVER_READ_(a)
3495    c.set_val(a.m_val * scfx_pow2(b));
3496}
3497
3498inline void
3499rshift(sc_fxval_fast &c, const sc_fxnum_fast &a, int b)
3500{
3501    SC_FXNUM_FAST_OBSERVER_READ_(a)
3502    c.set_val(a.m_val * scfx_pow2(-b));
3503}
3504
3505inline void
3506lshift(sc_fxnum_fast &c, const sc_fxnum_fast &a, int b)
3507{
3508    SC_FXNUM_FAST_OBSERVER_READ_(a)
3509    c.m_val = a.m_val * scfx_pow2(b);
3510    c.cast();
3511    SC_FXNUM_FAST_OBSERVER_WRITE_(c)
3512}
3513
3514inline void
3515rshift(sc_fxnum_fast &c, const sc_fxnum_fast &a, int b)
3516{
3517    SC_FXNUM_FAST_OBSERVER_READ_(a)
3518    c.m_val = a.m_val * scfx_pow2(-b);
3519    c.cast();
3520    SC_FXNUM_FAST_OBSERVER_WRITE_(c)
3521}
3522
3523// relational (including equality) operators
3524#define DEFN_REL_OP_T(op, tp) \
3525inline bool \
3526operator op (const sc_fxnum_fast &a, tp b) \
3527{ \
3528    SC_FXNUM_FAST_OBSERVER_READ_(a) \
3529    sc_fxval_fast tmp(b); \
3530    return (a.m_val op tmp.get_val()); \
3531} \
3532 \
3533inline bool \
3534operator op (tp a, const sc_fxnum_fast &b) \
3535{ \
3536    SC_FXNUM_FAST_OBSERVER_READ_(b) \
3537    sc_fxval_fast tmp(a); \
3538    return (tmp.get_val() op b.m_val); \
3539}
3540
3541#define DEFN_REL_OP_OTHER(op) \
3542DEFN_REL_OP_T(op, int64) \
3543DEFN_REL_OP_T(op, uint64) \
3544DEFN_REL_OP_T(op, const sc_int_base &) \
3545DEFN_REL_OP_T(op, const sc_uint_base &) \
3546DEFN_REL_OP_T(op, const sc_signed &) \
3547DEFN_REL_OP_T(op, const sc_unsigned &)
3548
3549#define DEFN_REL_OP(op) \
3550inline bool \
3551operator op (const sc_fxnum_fast &a, const sc_fxnum_fast &b) \
3552{ \
3553    SC_FXNUM_FAST_OBSERVER_READ_(a) \
3554    SC_FXNUM_FAST_OBSERVER_READ_(b) \
3555    return (a.m_val op b.m_val); \
3556} \
3557 \
3558inline bool \
3559operator op (const sc_fxnum_fast &a, const sc_fxval_fast &b) \
3560{ \
3561    SC_FXNUM_FAST_OBSERVER_READ_(a) \
3562    return (a.m_val op b.get_val()); \
3563} \
3564 \
3565inline bool \
3566operator op (const sc_fxval_fast &a, const sc_fxnum_fast &b) \
3567{ \
3568    SC_FXNUM_FAST_OBSERVER_READ_(b) \
3569    return (a.get_val() op b.m_val); \
3570} \
3571 \
3572DEFN_REL_OP_T(op, int) \
3573DEFN_REL_OP_T(op, unsigned int) \
3574DEFN_REL_OP_T(op, long) \
3575DEFN_REL_OP_T(op, unsigned long) \
3576DEFN_REL_OP_T(op, float) \
3577DEFN_REL_OP_T(op, double) \
3578DEFN_REL_OP_T(op, const char *) \
3579DEFN_REL_OP_OTHER(op)
3580
3581DEFN_REL_OP(<)
3582DEFN_REL_OP(<=)
3583DEFN_REL_OP(>)
3584DEFN_REL_OP(>=)
3585DEFN_REL_OP(==)
3586DEFN_REL_OP(!=)
3587
3588#undef DEFN_REL_OP_T
3589#undef DEFN_REL_OP_OTHER
3590#undef DEFN_REL_OP
3591
3592// assignment operators
3593
3594inline sc_fxnum_fast &
3595sc_fxnum_fast::operator = (const sc_fxnum_fast &a)
3596{
3597    if (&a != this) {
3598        SC_FXNUM_FAST_OBSERVER_READ_(a)
3599        m_val = a.m_val;
3600        cast();
3601        SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3602    }
3603    return *this;
3604}
3605
3606inline sc_fxnum_fast &
3607sc_fxnum_fast::operator = (const sc_fxval_fast &a)
3608{
3609    m_val = a.get_val();
3610    cast();
3611    SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3612    return *this;
3613}
3614
3615#define DEFN_ASN_OP_T(tp) \
3616inline sc_fxnum_fast & \
3617sc_fxnum_fast::operator = (tp a) \
3618{ \
3619    sc_fxval_fast tmp(a); \
3620    m_val = tmp.get_val(); \
3621    cast(); \
3622    SC_FXNUM_FAST_OBSERVER_WRITE_(*this) \
3623    return *this; \
3624}
3625
3626DEFN_ASN_OP_T(int)
3627DEFN_ASN_OP_T(unsigned int)
3628DEFN_ASN_OP_T(long)
3629DEFN_ASN_OP_T(unsigned long)
3630DEFN_ASN_OP_T(float)
3631DEFN_ASN_OP_T(double)
3632DEFN_ASN_OP_T(const char *)
3633DEFN_ASN_OP_T(const sc_fxval &)
3634DEFN_ASN_OP_T(const sc_fxnum &)
3635
3636DEFN_ASN_OP_T(int64)
3637DEFN_ASN_OP_T(uint64)
3638DEFN_ASN_OP_T(const sc_int_base &)
3639DEFN_ASN_OP_T(const sc_uint_base &)
3640DEFN_ASN_OP_T(const sc_signed &)
3641DEFN_ASN_OP_T(const sc_unsigned &)
3642
3643#undef DEFN_ASN_OP_T
3644
3645#define DEFN_ASN_OP_T(op, tp) \
3646inline sc_fxnum_fast & \
3647sc_fxnum_fast::operator op (tp b) \
3648{ \
3649    SC_FXNUM_FAST_OBSERVER_READ_(*this) \
3650    sc_fxval_fast tmp(b); \
3651    m_val op tmp.get_val(); \
3652    cast(); \
3653    SC_FXNUM_FAST_OBSERVER_WRITE_(*this) \
3654    return *this; \
3655}
3656
3657#define DEFN_ASN_OP_OTHER(op) \
3658DEFN_ASN_OP_T(op, int64) \
3659DEFN_ASN_OP_T(op, uint64) \
3660DEFN_ASN_OP_T(op, const sc_int_base &) \
3661DEFN_ASN_OP_T(op, const sc_uint_base &) \
3662DEFN_ASN_OP_T(op, const sc_signed &) \
3663DEFN_ASN_OP_T(op, const sc_unsigned &)
3664
3665#define DEFN_ASN_OP(op) \
3666inline sc_fxnum_fast & \
3667sc_fxnum_fast::operator op (const sc_fxnum_fast &b) \
3668{ \
3669    SC_FXNUM_FAST_OBSERVER_READ_(*this) \
3670    SC_FXNUM_FAST_OBSERVER_READ_(b) \
3671    m_val op b.m_val; \
3672    cast(); \
3673    SC_FXNUM_FAST_OBSERVER_WRITE_(*this) \
3674    return *this; \
3675} \
3676 \
3677inline sc_fxnum_fast & \
3678sc_fxnum_fast::operator op (const sc_fxval_fast &b) \
3679{ \
3680    SC_FXNUM_FAST_OBSERVER_READ_(*this) \
3681    m_val op b.get_val(); \
3682    cast(); \
3683    SC_FXNUM_FAST_OBSERVER_WRITE_(*this) \
3684    return *this; \
3685} \
3686 \
3687DEFN_ASN_OP_T(op, int) \
3688DEFN_ASN_OP_T(op, unsigned int) \
3689DEFN_ASN_OP_T(op, long) \
3690DEFN_ASN_OP_T(op, unsigned long) \
3691DEFN_ASN_OP_T(op, float) \
3692DEFN_ASN_OP_T(op, double) \
3693DEFN_ASN_OP_T(op, const char *) \
3694DEFN_ASN_OP_T(op, const sc_fxval &) \
3695DEFN_ASN_OP_T(op, const sc_fxnum &) \
3696DEFN_ASN_OP_OTHER(op)
3697
3698DEFN_ASN_OP(*=)
3699DEFN_ASN_OP(/=)
3700DEFN_ASN_OP(+=)
3701DEFN_ASN_OP(-=)
3702
3703#undef DEFN_ASN_OP_T
3704#undef DEFN_ASN_OP_OTHER
3705#undef DEFN_ASN_OP
3706
3707inline sc_fxnum_fast &
3708sc_fxnum_fast::operator <<= (int b)
3709{
3710    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3711    m_val *= scfx_pow2(b);
3712    cast();
3713    SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3714    return *this;
3715}
3716
3717inline sc_fxnum_fast &
3718sc_fxnum_fast::operator >>= (int b)
3719{
3720    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3721    m_val *= scfx_pow2(-b);
3722    cast();
3723    SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3724    return *this;
3725}
3726
3727// auto-increment and auto-decrement
3728inline const sc_fxval_fast
3729sc_fxnum_fast::operator ++ (int)
3730{
3731    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3732    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3733    double c = m_val;
3734    m_val = m_val + 1;
3735    cast();
3736    SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3737    return sc_fxval_fast(c);
3738}
3739
3740inline const sc_fxval_fast
3741sc_fxnum_fast::operator -- (int)
3742{
3743    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3744    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3745    double c = m_val;
3746    m_val = m_val - 1;
3747    cast();
3748    SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3749    return sc_fxval_fast(c);
3750}
3751
3752inline sc_fxnum_fast &
3753sc_fxnum_fast::operator ++ ()
3754{
3755    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3756    m_val = m_val + 1;
3757    cast();
3758    SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3759    return *this;
3760}
3761
3762inline sc_fxnum_fast &
3763sc_fxnum_fast::operator -- ()
3764{
3765    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3766    m_val = m_val - 1;
3767    cast();
3768    SC_FXNUM_FAST_OBSERVER_WRITE_(*this)
3769    return *this;
3770}
3771
3772// bit selection
3773inline const sc_fxnum_fast_bitref
3774sc_fxnum_fast::operator [] (int i) const
3775{
3776    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3777    return sc_fxnum_fast_bitref(const_cast<sc_fxnum_fast &>(*this),
3778                                i - m_params.fwl());
3779}
3780
3781inline sc_fxnum_fast_bitref
3782sc_fxnum_fast::operator [] (int i)
3783{
3784    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3785    return sc_fxnum_fast_bitref(*this, i - m_params.fwl());
3786}
3787
3788inline const sc_fxnum_fast_bitref
3789sc_fxnum_fast::bit(int i) const
3790{
3791    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3792    return sc_fxnum_fast_bitref(const_cast<sc_fxnum_fast &>(*this),
3793                                i - m_params.fwl());
3794}
3795
3796inline sc_fxnum_fast_bitref
3797sc_fxnum_fast::bit(int i)
3798{
3799    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3800    return sc_fxnum_fast_bitref(*this, i - m_params.fwl());
3801}
3802
3803// part selection
3804inline const sc_fxnum_fast_subref
3805sc_fxnum_fast::operator () (int i, int j) const
3806{
3807    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3808    SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
3809
3810    return sc_fxnum_fast_subref(const_cast<sc_fxnum_fast &>(*this),
3811                                i - m_params.fwl(), j - m_params.fwl());
3812}
3813
3814inline sc_fxnum_fast_subref
3815sc_fxnum_fast::operator () (int i, int j)
3816{
3817    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3818    SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
3819
3820    return sc_fxnum_fast_subref(*this, i - m_params.fwl(), j - m_params.fwl());
3821}
3822
3823inline const sc_fxnum_fast_subref
3824sc_fxnum_fast::range(int i, int j) const
3825{
3826    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3827    SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
3828
3829    return sc_fxnum_fast_subref(const_cast<sc_fxnum_fast &>(*this),
3830                                i - m_params.fwl(), j - m_params.fwl());
3831}
3832
3833inline sc_fxnum_fast_subref
3834sc_fxnum_fast::range(int i, int j)
3835{
3836    SC_ERROR_IF_(i < 0 || i >= m_params.wl(), "index out of range");
3837    SC_ERROR_IF_(j < 0 || j >= m_params.wl(), "index out of range");
3838
3839    return sc_fxnum_fast_subref(*this, i - m_params.fwl(), j - m_params.fwl());
3840}
3841
3842inline const sc_fxnum_fast_subref
3843sc_fxnum_fast::operator () () const
3844{
3845    return this->operator () (m_params.wl() - 1, 0);
3846}
3847
3848inline sc_fxnum_fast_subref
3849sc_fxnum_fast::operator () ()
3850{
3851    return this->operator () (m_params.wl() - 1, 0);
3852}
3853
3854inline const sc_fxnum_fast_subref
3855sc_fxnum_fast::range() const
3856{
3857    return this->range(m_params.wl() - 1, 0);
3858}
3859
3860inline sc_fxnum_fast_subref
3861sc_fxnum_fast::range()
3862{
3863    return this->range(m_params.wl() - 1, 0);
3864}
3865
3866// implicit conversion
3867inline sc_fxnum_fast::operator double() const
3868{
3869    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3870    return m_val;
3871}
3872
3873// explicit conversion to primitive types
3874inline short
3875sc_fxnum_fast::to_short() const
3876{
3877    // SC_FXNUM_FAST_OBSERVER_READ_ in to_uint64
3878    return static_cast<short>(to_uint64());
3879}
3880
3881inline unsigned short
3882sc_fxnum_fast::to_ushort() const
3883{
3884    // SC_FXNUM_FAST_OBSERVER_READ_ in to_uint64
3885    return static_cast<unsigned short>(to_uint64());
3886}
3887
3888inline int
3889sc_fxnum_fast::to_int() const
3890{
3891    // SC_FXNUM_FAST_OBSERVER_READ_ in to_uint64
3892    return static_cast<int>(to_uint64());
3893}
3894
3895inline int64
3896sc_fxnum_fast::to_int64() const
3897{
3898    // SC_FXNUM_FAST_OBSERVER_READ_ in to_uint64
3899    return static_cast<int64>(to_uint64());
3900}
3901
3902inline unsigned int
3903sc_fxnum_fast::to_uint() const
3904{
3905    // SC_FXNUM_FAST_OBSERVER_READ_ in to_uint64
3906    return static_cast<unsigned int>(to_uint64());
3907}
3908
3909inline uint64
3910sc_fxnum_fast::to_uint64() const
3911{
3912    // SC_FXNUM_FAST_OBSERVER_READ_ in is_normal
3913    if (!is_normal()) {
3914        return 0;
3915    }
3916
3917    int exponent;
3918    double mantissa_dbl = frexp(m_val, &exponent);
3919
3920    uint64 mantissa = static_cast<uint64>(fabs(mantissa_dbl) *
3921                                          (UINT64_ONE << 53));
3922    exponent -= 53;
3923
3924    if (!(-64 < exponent && exponent < 64)) {
3925        return 0;
3926    }
3927
3928    mantissa = exponent >= 0 ? mantissa << exponent : mantissa >> -exponent;
3929    return mantissa_dbl >= 0 ? mantissa : -mantissa;
3930}
3931
3932inline long
3933sc_fxnum_fast::to_long() const
3934{
3935    // SC_FXNUM_FAST_OBSERVER_READ_ in to_uint64
3936    return static_cast<long>(to_uint64());
3937}
3938
3939inline unsigned long
3940sc_fxnum_fast::to_ulong() const
3941{
3942    // SC_FXNUM_FAST_OBSERVER_READ_ in to_uint64
3943    return static_cast<unsigned long>(to_uint64());
3944}
3945
3946inline float
3947sc_fxnum_fast::to_float() const
3948{
3949    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3950    return static_cast<float>(m_val);
3951}
3952
3953inline double
3954sc_fxnum_fast::to_double() const
3955{
3956    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3957    return m_val;
3958}
3959
3960// query value
3961inline bool
3962sc_fxnum_fast::is_neg() const
3963{
3964    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3965    scfx_ieee_double id(m_val);
3966    return (id.negative() != 0);
3967}
3968
3969inline bool
3970sc_fxnum_fast::is_zero() const
3971{
3972    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3973    scfx_ieee_double id(m_val);
3974    return id.is_zero();
3975}
3976
3977// internal use only;
3978inline bool
3979sc_fxnum_fast::is_normal() const
3980{
3981    SC_FXNUM_FAST_OBSERVER_READ_(*this)
3982    scfx_ieee_double id(m_val);
3983    return (id.is_normal() || id.is_subnormal() || id.is_zero());
3984}
3985
3986inline bool
3987sc_fxnum_fast::quantization_flag() const
3988{
3989    return m_q_flag;
3990}
3991
3992inline bool
3993sc_fxnum_fast::overflow_flag() const
3994{
3995    return m_o_flag;
3996}
3997
3998inline const sc_fxval_fast
3999sc_fxnum_fast::value() const
4000{
4001    SC_FXNUM_FAST_OBSERVER_READ_(*this)
4002    return sc_fxval_fast(m_val);
4003}
4004
4005// query parameters
4006inline int
4007sc_fxnum_fast::wl() const
4008{
4009    return m_params.wl();
4010}
4011
4012inline int
4013sc_fxnum_fast::iwl() const
4014{
4015    return m_params.iwl();
4016}
4017
4018inline sc_q_mode
4019sc_fxnum_fast::q_mode() const
4020{
4021    return m_params.q_mode();
4022}
4023
4024inline sc_o_mode
4025sc_fxnum_fast::o_mode() const
4026{
4027    return m_params.o_mode();
4028}
4029
4030inline int
4031sc_fxnum_fast::n_bits() const
4032{
4033    return m_params.n_bits();
4034}
4035
4036inline const sc_fxtype_params &
4037sc_fxnum_fast::type_params() const
4038{
4039    return m_params.type_params();
4040}
4041
4042inline const sc_fxcast_switch &
4043sc_fxnum_fast::cast_switch() const
4044{
4045    return m_params.cast_switch();
4046}
4047
4048// internal use only;
4049inline void
4050sc_fxnum_fast::observer_read() const
4051{
4052    SC_FXNUM_FAST_OBSERVER_READ_(*this);
4053}
4054
4055inline ::std::ostream &
4056operator << (::std::ostream &os, const sc_fxnum_fast &a)
4057{
4058    a.print(os);
4059    return os;
4060}
4061
4062inline ::std::istream &
4063operator >> (::std::istream &is, sc_fxnum_fast &a)
4064{
4065    a.scan(is);
4066    return is;
4067}
4068
4069
4070// ----------------------------------------------------------------------------
4071// CLASS : sc_fxval
4072//
4073// Fixed-point value type; arbitrary precision.
4074// ----------------------------------------------------------------------------
4075
4076// public constructors
4077inline sc_fxval::sc_fxval(const sc_fxnum &a, sc_fxval_observer *observer_) :
4078        m_rep(new scfx_rep(*a.get_rep())), m_observer(observer_)
4079{
4080    SC_FXVAL_OBSERVER_DEFAULT_
4081    SC_FXVAL_OBSERVER_CONSTRUCT_(*this)
4082    SC_FXVAL_OBSERVER_WRITE_(*this)
4083}
4084
4085inline sc_fxval::sc_fxval(const sc_fxnum_fast &a,
4086                          sc_fxval_observer *observer_) :
4087    m_rep(new scfx_rep(a.to_double())), m_observer(observer_)
4088{
4089    SC_FXVAL_OBSERVER_DEFAULT_
4090    SC_FXVAL_OBSERVER_CONSTRUCT_(*this)
4091    SC_FXVAL_OBSERVER_WRITE_(*this)
4092}
4093
4094// binary operators
4095#define DEFN_BIN_OP_T(op, fnc, tp) \
4096inline const sc_fxval \
4097operator op (const sc_fxval &a, tp b) \
4098{ \
4099    SC_FXVAL_OBSERVER_READ_(a) \
4100    sc_fxval tmp(b); \
4101    return sc_fxval(sc_dt::fnc ## _scfx_rep(*a.m_rep, *tmp.m_rep)); \
4102} \
4103 \
4104inline const sc_fxval \
4105operator op (tp a, const sc_fxval &b) \
4106{ \
4107    SC_FXVAL_OBSERVER_READ_(b) \
4108    sc_fxval tmp(a); \
4109    return sc_fxval(sc_dt::fnc ## _scfx_rep(*tmp.m_rep, *b.m_rep)); \
4110}
4111
4112#define DEFN_BIN_OP(op, fnc) \
4113DEFN_BIN_OP_T(op, fnc, const sc_fxnum_fast &)
4114
4115DEFN_BIN_OP(*, mult)
4116DEFN_BIN_OP(+, add)
4117DEFN_BIN_OP(-, sub)
4118//DEFN_BIN_OP(/, div)
4119DEFN_BIN_OP_T(/, div, const sc_fxnum_fast &)
4120
4121#undef DEFN_BIN_OP_T
4122#undef DEFN_BIN_OP
4123
4124
4125// binary functions
4126#define DEFN_BIN_FNC_T(fnc, tp) \
4127inline void \
4128fnc (sc_fxval &c, const sc_fxval &a, tp b) \
4129{ \
4130    SC_FXVAL_OBSERVER_READ_(a) \
4131    sc_fxval tmp(b); \
4132    delete c.m_rep; \
4133    c.m_rep = sc_dt::fnc ## _scfx_rep(*a.m_rep, *tmp.m_rep); \
4134    SC_FXVAL_OBSERVER_WRITE_(c) \
4135} \
4136 \
4137inline void \
4138fnc (sc_fxval &c, tp a, const sc_fxval &b) \
4139{ \
4140    SC_FXVAL_OBSERVER_READ_(b) \
4141    sc_fxval tmp(a); \
4142    delete c.m_rep; \
4143    c.m_rep = sc_dt::fnc ## _scfx_rep(*tmp.m_rep, *b.m_rep); \
4144    SC_FXVAL_OBSERVER_WRITE_(c) \
4145}
4146
4147#define DEFN_BIN_FNC(fnc) \
4148DEFN_BIN_FNC_T(fnc, const sc_fxnum_fast &)
4149
4150DEFN_BIN_FNC(mult)
4151DEFN_BIN_FNC(div)
4152DEFN_BIN_FNC(add)
4153DEFN_BIN_FNC(sub)
4154
4155#undef DEFN_BIN_FNC_T
4156#undef DEFN_BIN_FNC
4157
4158
4159// relational (including equality) operators
4160#define DEFN_REL_OP_T(op, ret, tp) \
4161inline bool \
4162operator op (const sc_fxval &a, tp b) \
4163{ \
4164    SC_FXVAL_OBSERVER_READ_(a) \
4165    sc_fxval tmp(b); \
4166    int result = sc_dt::cmp_scfx_rep(*a.m_rep, *tmp.m_rep); \
4167    return (ret); \
4168} \
4169 \
4170inline bool \
4171operator op (tp a, const sc_fxval &b) \
4172{ \
4173    SC_FXVAL_OBSERVER_READ_(b) \
4174    sc_fxval tmp(a); \
4175    int result = sc_dt::cmp_scfx_rep(*tmp.m_rep, *b.m_rep); \
4176    return (ret); \
4177}
4178
4179#define DEFN_REL_OP(op, ret) \
4180DEFN_REL_OP_T(op, ret, const sc_fxnum_fast &)
4181
4182DEFN_REL_OP(<, result < 0)
4183DEFN_REL_OP(<=, result <= 0)
4184DEFN_REL_OP(>, result > 0 && result != 2)
4185DEFN_REL_OP(>=, result >= 0 && result != 2)
4186DEFN_REL_OP(==, result == 0)
4187DEFN_REL_OP(!=, result != 0)
4188
4189#undef DEFN_REL_OP_T
4190#undef DEFN_REL_OP
4191
4192// assignment operators
4193inline sc_fxval &
4194sc_fxval::operator = (const sc_fxnum &a)
4195{
4196    *m_rep = *a.get_rep();
4197    SC_FXVAL_OBSERVER_WRITE_(*this)
4198    return *this;
4199}
4200
4201#define DEFN_ASN_OP_T(tp) \
4202inline sc_fxval & \
4203sc_fxval::operator = (tp b) \
4204{ \
4205    sc_fxval tmp(b); \
4206    *m_rep = *tmp.m_rep; \
4207    SC_FXVAL_OBSERVER_WRITE_(*this) \
4208    return *this; \
4209}
4210
4211DEFN_ASN_OP_T(const sc_fxnum_fast &)
4212
4213#undef DEFN_ASN_OP_T
4214
4215#define DEFN_ASN_OP_T(op, fnc, tp) \
4216inline sc_fxval & \
4217sc_fxval::operator op (tp b) \
4218{ \
4219    SC_FXVAL_OBSERVER_READ_(*this) \
4220    sc_fxval tmp(b); \
4221    scfx_rep *new_rep = sc_dt::fnc ## _scfx_rep(*m_rep, *tmp.m_rep); \
4222    delete m_rep; \
4223    m_rep = new_rep; \
4224    SC_FXVAL_OBSERVER_WRITE_(*this) \
4225    return *this; \
4226}
4227
4228#define DEFN_ASN_OP(op, fnc) \
4229inline sc_fxval & \
4230sc_fxval::operator op (const sc_fxnum &b) \
4231{ \
4232    SC_FXVAL_OBSERVER_READ_(*this) \
4233    scfx_rep *new_rep = sc_dt::fnc ## _scfx_rep(*m_rep, *b.get_rep()); \
4234    delete m_rep; \
4235    m_rep = new_rep; \
4236    SC_FXVAL_OBSERVER_WRITE_(*this) \
4237    return *this; \
4238} \
4239 \
4240DEFN_ASN_OP_T(op, fnc, const sc_fxnum_fast &)
4241
4242DEFN_ASN_OP(*=, mult)
4243DEFN_ASN_OP(/=, div)
4244DEFN_ASN_OP(+=, add)
4245DEFN_ASN_OP(-=, sub)
4246
4247#undef DEFN_ASN_OP_T
4248#undef DEFN_ASN_OP
4249
4250
4251// ----------------------------------------------------------------------------
4252// CLASS : sc_fxval_fast
4253//
4254// Fixed-point value types; limited precision.
4255// ----------------------------------------------------------------------------
4256
4257// public constructors
4258
4259inline
4260sc_fxval_fast::sc_fxval_fast(const sc_fxnum &a,
4261                              sc_fxval_fast_observer *observer_) :
4262    m_val(a.to_double()), m_observer(observer_)
4263{
4264    SC_FXVAL_FAST_OBSERVER_DEFAULT_
4265    SC_FXVAL_FAST_OBSERVER_CONSTRUCT_(*this)
4266    SC_FXVAL_FAST_OBSERVER_WRITE_(*this)
4267}
4268
4269inline sc_fxval_fast::sc_fxval_fast(const sc_fxnum_fast &a,
4270                                    sc_fxval_fast_observer *observer_) :
4271    m_val(a.get_val()), m_observer(observer_)
4272{
4273    SC_FXVAL_FAST_OBSERVER_DEFAULT_
4274    SC_FXVAL_FAST_OBSERVER_CONSTRUCT_(*this)
4275    SC_FXVAL_FAST_OBSERVER_WRITE_(*this)
4276}
4277
4278
4279// binary functions
4280#define DEFN_BIN_FNC_T(fnc, op, tp) \
4281inline void \
4282fnc (sc_fxval_fast &c, const sc_fxval_fast &a, tp b) \
4283{ \
4284    SC_FXVAL_FAST_OBSERVER_READ_(a) \
4285    sc_fxval_fast tmp(b); \
4286    c.m_val = a.m_val op tmp.m_val; \
4287    SC_FXVAL_FAST_OBSERVER_WRITE_(c) \
4288} \
4289 \
4290inline void \
4291fnc (sc_fxval_fast &c, tp a, const sc_fxval_fast &b) \
4292{ \
4293    SC_FXVAL_FAST_OBSERVER_READ_(b) \
4294    sc_fxval_fast tmp(a); \
4295    c.m_val = tmp.m_val op b.m_val; \
4296    SC_FXVAL_FAST_OBSERVER_WRITE_(c) \
4297}
4298
4299#define DEFN_BIN_FNC(fnc, op) \
4300DEFN_BIN_FNC_T(fnc, op, const sc_fxval &) \
4301DEFN_BIN_FNC_T(fnc, op, const sc_fxnum &)
4302
4303DEFN_BIN_FNC(mult, *)
4304DEFN_BIN_FNC(div, /)
4305DEFN_BIN_FNC(add, +)
4306DEFN_BIN_FNC(sub, -)
4307
4308#undef DEFN_BIN_FNC_T
4309#undef DEFN_BIN_FNC
4310
4311
4312// assignment operators
4313inline sc_fxval_fast &
4314sc_fxval_fast::operator = (const sc_fxnum_fast &a)
4315{
4316    m_val = a.get_val();
4317    SC_FXVAL_FAST_OBSERVER_WRITE_(*this)
4318    return *this;
4319}
4320
4321#define DEFN_ASN_OP_T(tp) \
4322inline sc_fxval_fast & \
4323sc_fxval_fast::operator = (tp a) \
4324{ \
4325    sc_fxval_fast tmp(a); \
4326    m_val = tmp.m_val; \
4327    SC_FXVAL_FAST_OBSERVER_WRITE_(*this) \
4328    return *this; \
4329}
4330
4331DEFN_ASN_OP_T(const sc_fxnum &)
4332
4333#undef DEFN_ASN_OP_T
4334
4335#define DEFN_ASN_OP_T(op, tp) \
4336inline sc_fxval_fast & \
4337sc_fxval_fast::operator op (tp b) \
4338{ \
4339    SC_FXVAL_FAST_OBSERVER_READ_(*this) \
4340    sc_fxval_fast tmp(b); \
4341    m_val op tmp.m_val; \
4342    SC_FXVAL_FAST_OBSERVER_WRITE_(*this) \
4343    return *this; \
4344}
4345
4346#define DEFN_ASN_OP(op) \
4347inline sc_fxval_fast & \
4348sc_fxval_fast::operator op (const sc_fxnum_fast &b) \
4349{ \
4350    SC_FXVAL_FAST_OBSERVER_READ_(*this) \
4351    m_val op b.get_val(); \
4352    SC_FXVAL_FAST_OBSERVER_WRITE_(*this) \
4353    return *this; \
4354} \
4355 \
4356DEFN_ASN_OP_T(op, const sc_fxnum &)
4357
4358DEFN_ASN_OP(*=)
4359DEFN_ASN_OP(/=)
4360DEFN_ASN_OP(+=)
4361DEFN_ASN_OP(-=)
4362
4363#undef DEFN_ASN_OP_T
4364#undef DEFN_ASN_OP
4365
4366} // namespace sc_dt
4367
4368#endif // __SYSTEMC_EXT_DT_FX_SC_FXNUM_HH__
4369