A Discrete-Event Network Simulator
API
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
int64x64-cairo.h
Go to the documentation of this file.
1 #include "ns3/core-config.h"
2 #if !defined(INT64X64_CAIRO_H) && defined (INT64X64_USE_CAIRO) && !defined(PYTHON_SCAN)
3 #define INT64X64_CAIRO_H
4 
5 #include <stdint.h>
6 #include <math.h>
8 
9 #ifdef __i386__
10 // this assembly code does not appear to work right yet.
11 #define noInt64x64_CAIRO_ASM 1
12 #endif
13 
14 namespace ns3 {
15 
16 class int64x64_t
17 {
18 public:
19  inline int64x64_t ()
20  {
21  _v.hi = 0;
22  _v.lo = 0;
23  }
24  inline int64x64_t (double value)
25  {
26 #define HPCAIRO_MAX_64 18446744073709551615.0
27  double fhi = floor (value);
28  int64_t hi = lround (fhi);
29  uint64_t lo = (uint64_t)((value - fhi) * HPCAIRO_MAX_64);
30  _v.hi = hi;
31  _v.lo = lo;
32 #undef HPCAIRO_MAX_64
33  }
34  inline int64x64_t (int v)
35  {
36  _v.hi = v;
37  _v.lo = 0;
38  }
39  inline int64x64_t (long int v)
40  {
41  _v.hi = v;
42  _v.lo = 0;
43  }
44  inline int64x64_t (long long int v)
45  {
46  _v.hi = v;
47  _v.lo = 0;
48  }
49  inline int64x64_t (unsigned int v)
50  {
51  _v.hi = v;
52  _v.lo = 0;
53  }
54  inline int64x64_t (unsigned long int v)
55  {
56  _v.hi = v;
57  _v.lo = 0;
58  }
59  inline int64x64_t (unsigned long long int v)
60  {
61  _v.hi = v;
62  _v.lo = 0;
63  }
64  inline int64x64_t (int64_t hi, uint64_t lo)
65  {
66  _v.hi = hi;
67  _v.lo = lo;
68  }
69 
70  inline int64x64_t (const int64x64_t &o)
71  : _v (o._v) {}
72  inline int64x64_t &operator = (const int64x64_t &o)
73  {
74  _v = o._v;
75  return *this;
76  }
77 
78  inline double GetDouble (void) const
79  {
80 #define HPCAIRO_MAX_64 18446744073709551615.0
81  bool is_negative = IsNegative ();
82  cairo_int128_t value = is_negative ? _cairo_int128_negate (_v) : _v;
83  double flo = value.lo;
84  flo /= HPCAIRO_MAX_64;
85  double retval = value.hi;
86  retval += flo;
87  retval = is_negative ? -retval : retval;
88  return retval;
89 #undef HPCAIRO_MAX_64
90  }
91  inline int64_t GetHigh (void) const
92  {
93  return (int64_t)_v.hi;
94  }
95  inline uint64_t GetLow (void) const
96  {
97  return _v.lo;
98  }
99 
100  void MulByInvert (const int64x64_t &o);
101 
102  static int64x64_t Invert (uint64_t v);
103 
104 private:
105  friend bool operator == (const int64x64_t &lhs, const int64x64_t &rhs);
106  friend bool operator != (const int64x64_t &lhs, const int64x64_t &rhs);
107  friend bool operator <= (const int64x64_t &lhs, const int64x64_t &rhs);
108  friend bool operator >= (const int64x64_t &lhs, const int64x64_t &rhs);
109  friend bool operator < (const int64x64_t &lhs, const int64x64_t &rhs);
110  friend bool operator > (const int64x64_t &lhs, const int64x64_t &rhs);
111  friend int64x64_t &operator += (int64x64_t &lhs, const int64x64_t &rhs);
112  friend int64x64_t &operator -= (int64x64_t &lhs, const int64x64_t &rhs);
113  friend int64x64_t &operator *= (int64x64_t &lhs, const int64x64_t &rhs);
114  friend int64x64_t &operator /= (int64x64_t &lhs, const int64x64_t &rhs);
115  friend int64x64_t operator + (const int64x64_t &lhs);
116  friend int64x64_t operator - (const int64x64_t &lhs);
117  friend int64x64_t operator ! (const int64x64_t &lhs);
118  void Mul (const int64x64_t &o);
119  void Div (const int64x64_t &o);
120  static cairo_uint128_t Umul (cairo_uint128_t a, cairo_uint128_t b);
121  static cairo_uint128_t Udiv (cairo_uint128_t a, cairo_uint128_t b);
122  static cairo_uint128_t UmulByInvert (cairo_uint128_t a, cairo_uint128_t b);
123  inline bool IsNegative (void) const
124  {
125  int64_t hi = _v.hi;
126  return hi < 0;
127  }
128  inline void Negate (void)
129  {
130  _v.lo = ~_v.lo;
131  _v.hi = ~_v.hi;
132  if (++_v.lo == 0)
133  {
134  ++_v.hi;
135  }
136  }
137  inline int Compare (const int64x64_t &o) const
138  {
139  int status;
140  int64x64_t tmp = *this;
141  tmp -= o;
142  status = (((int64_t)(tmp)._v.hi) < 0) ? -1 :
143  (((tmp)._v.hi == 0 && (tmp)._v.lo == 0)) ? 0 : 1;
144  return status;
145  }
146  cairo_int128_t _v;
147 };
148 
149 inline bool operator == (const int64x64_t &lhs, const int64x64_t &rhs)
150 {
151  return lhs._v.hi == rhs._v.hi && lhs._v.lo == lhs._v.lo;
152 }
153 
154 inline bool operator != (const int64x64_t &lhs, const int64x64_t &rhs)
155 {
156  return !(lhs == rhs);
157 }
158 
159 inline bool operator < (const int64x64_t &lhs, const int64x64_t &rhs)
160 {
161  return lhs.Compare (rhs) < 0;
162 }
163 inline bool operator <= (const int64x64_t &lhs, const int64x64_t &rhs)
164 {
165  return lhs.Compare (rhs) <= 0;
166 }
167 
168 inline bool operator >= (const int64x64_t &lhs, const int64x64_t &rhs)
169 {
170  return lhs.Compare (rhs) >= 0;
171 }
172 inline bool operator > (const int64x64_t &lhs, const int64x64_t &rhs)
173 {
174  return lhs.Compare (rhs) > 0;
175 }
176 inline int64x64_t &operator += (int64x64_t &lhs, const int64x64_t &rhs)
177 {
178 #if Int64x64_CAIRO_ASM
179  asm ("mov 0(%1),%%eax\n\t"
180  "add %%eax,0(%0)\n\t"
181  "mov 4(%1),%%eax\n\t"
182  "adc %%eax,4(%0)\n\t"
183  "mov 8(%1),%%eax\n\t"
184  "adc %%eax,8(%0)\n\t"
185  "mov 12(%1),%%eax\n\t"
186  "adc %%eax,12(%0)\n\t"
187  :
188  : "r" (&lhs._v), "r" (&rhs._v)
189  : "%eax", "cc");
190 #else
191  lhs._v.hi += rhs._v.hi;
192  lhs._v.lo += rhs._v.lo;
193  if (lhs._v.lo < rhs._v.lo)
194  {
195  lhs._v.hi++;
196  }
197 #endif
198  return lhs;
199 }
200 inline int64x64_t &operator -= (int64x64_t &lhs, const int64x64_t &rhs)
201 {
202 #if Int64x64_CAIRO_ASM
203  asm ("mov 0(%1),%%eax\n\t"
204  "sub %%eax,0(%0)\n\t"
205  "mov 4(%1),%%eax\n\t"
206  "sbb %%eax,4(%0)\n\t"
207  "mov 8(%1),%%eax\n\t"
208  "sbb %%eax,8(%0)\n\t"
209  "mov 12(%1),%%eax\n\t"
210  "sbb %%eax,12(%0)\n\t"
211  :
212  : "r" (&lhs._v), "r" (&rhs._v)
213  : "%eax", "cc");
214 #else
215  lhs._v.hi -= rhs._v.hi;
216  lhs._v.lo -= rhs._v.lo;
217  if (lhs._v.lo > rhs._v.lo)
218  {
219  lhs._v.hi--;
220  }
221 #endif
222  return lhs;
223 }
224 inline int64x64_t &operator *= (int64x64_t &lhs, const int64x64_t &rhs)
225 {
226  lhs.Mul (rhs);
227  return lhs;
228 }
229 inline int64x64_t &operator /= (int64x64_t &lhs, const int64x64_t &rhs)
230 {
231  lhs.Div (rhs);
232  return lhs;
233 }
234 
235 inline int64x64_t operator + (const int64x64_t &lhs)
236 {
237  return lhs;
238 }
239 
240 inline int64x64_t operator - (const int64x64_t &lhs)
241 {
242  int64x64_t tmp = lhs;
243  tmp.Negate ();
244  return tmp;
245 }
246 
247 inline int64x64_t operator ! (const int64x64_t &lhs)
248 {
249  return (lhs._v.hi == 0 && lhs._v.lo == 0) ? int64x64_t (1, 0) : int64x64_t ();
250 }
251 
252 } // namespace ns3
253 
254 #endif /* INT64X64_CAIRO_H */