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