Click
Loading...
Searching...
No Matches
integers.hh
Go to the documentation of this file.
1// -*- c-basic-offset: 4; related-file-name: "../../lib/integers.cc" -*-
2#ifndef CLICK_INTEGERS_HH
3#define CLICK_INTEGERS_HH
4#include <click/glue.hh>
6#if !HAVE___BUILTIN_FFS && HAVE_FFS && HAVE_STRINGS_H
7# include <strings.h>
8#endif
9CLICK_DECLS
10
15#if HAVE_INT64_TYPES && !defined(htonq)
16# if CLICK_BYTE_ORDER != CLICK_LITTLE_ENDIAN && CLICK_BYTE_ORDER != CLICK_BIG_ENDIAN
17inline uint64_t htonq(uint64_t x) __attribute__((error("unknown byte order")));
18# endif
19
21inline uint64_t htonq(uint64_t x) {
22# if CLICK_BYTE_ORDER == CLICK_LITTLE_ENDIAN
23 uint32_t hi = x >> 32;
24 uint32_t lo = x & 0xffffffff;
25 return (((uint64_t)htonl(lo)) << 32) | htonl(hi);
26# elif CLICK_BYTE_ORDER == CLICK_BIG_ENDIAN
27 return x;
28# else
29 return 0;
30# endif
31}
32#endif
33
34#if HAVE_INT64_TYPES && !defined(ntohq)
35# if CLICK_BYTE_ORDER != CLICK_LITTLE_ENDIAN && CLICK_BYTE_ORDER != CLICK_BIG_ENDIAN
36inline uint64_t htonq(uint64_t x) __attribute__((error("unknown byte order")));
37# endif
38
40inline uint64_t ntohq(uint64_t x) {
41# if CLICK_BYTE_ORDER == CLICK_LITTLE_ENDIAN
42 uint32_t hi = x >> 32;
43 uint32_t lo = x & 0xffffffff;
44 return (((uint64_t)ntohl(lo)) << 32) | ntohl(hi);
45# elif CLICK_BYTE_ORDER == CLICK_BIG_ENDIAN
46 return x;
47# else
48 return 0;
49# endif
50}
51#endif
52
58inline unsigned char host_to_net_order(unsigned char x) {
59 return x;
60}
62inline signed char host_to_net_order(signed char x) {
63 return x;
64}
66inline char host_to_net_order(char x) {
67 return x;
68}
70inline short host_to_net_order(short x) {
71 return htons(x);
72}
74inline unsigned short host_to_net_order(unsigned short x) {
75 return htons(x);
76}
78inline int host_to_net_order(int x) {
79 return htonl(x);
80}
82inline unsigned host_to_net_order(unsigned x) {
83 return htonl(x);
84}
85#if SIZEOF_LONG == 4
87inline long host_to_net_order(long x) {
88 return htonl(x);
89}
91inline unsigned long host_to_net_order(unsigned long x) {
92 return htonl(x);
93}
94#endif
95#if HAVE_INT64_TYPES
96# if SIZEOF_LONG == 8
98inline long host_to_net_order(long x) {
99 return htonq(x);
100}
102inline unsigned long host_to_net_order(unsigned long x) {
103 return htonq(x);
104}
105# endif
106# if HAVE_LONG_LONG && SIZEOF_LONG_LONG == 8
108inline long long host_to_net_order(long long x) {
109 return htonq(x);
110}
112inline unsigned long long host_to_net_order(unsigned long long x) {
113 return htonq(x);
114}
115# endif
116# if !HAVE_INT64_IS_LONG && !HAVE_INT64_IS_LONG_LONG
118inline int64_t host_to_net_order(int64_t x) {
119 return htonq(x);
120}
122inline uint64_t host_to_net_order(uint64_t x) {
123 return htonq(x);
124}
125# endif
126#endif
127
133inline unsigned char net_to_host_order(unsigned char x) {
134 return x;
135}
137inline signed char net_to_host_order(signed char x) {
138 return x;
139}
141inline char net_to_host_order(char x) {
142 return x;
143}
145inline short net_to_host_order(short x) {
146 return ntohs(x);
147}
149inline unsigned short net_to_host_order(unsigned short x) {
150 return ntohs(x);
151}
153inline int net_to_host_order(int x) {
154 return ntohl(x);
155}
157inline unsigned net_to_host_order(unsigned x) {
158 return ntohl(x);
159}
160#if SIZEOF_LONG == 4
162inline long net_to_host_order(long x) {
163 return ntohl(x);
164}
166inline unsigned long net_to_host_order(unsigned long x) {
167 return ntohl(x);
168}
169#endif
170#if HAVE_INT64_TYPES
171# if SIZEOF_LONG == 8
173inline long net_to_host_order(long x) {
174 return ntohq(x);
175}
177inline unsigned long net_to_host_order(unsigned long x) {
178 return ntohq(x);
179}
180# endif
181# if HAVE_LONG_LONG && SIZEOF_LONG_LONG == 8
183inline long long net_to_host_order(long long x) {
184 return ntohq(x);
185}
187inline unsigned long long net_to_host_order(unsigned long long x) {
188 return ntohq(x);
189}
190# endif
191# if !HAVE_INT64_IS_LONG && !HAVE_INT64_IS_LONG_LONG
193inline int64_t net_to_host_order(int64_t x) {
194 return ntohq(x);
195}
197inline uint64_t net_to_host_order(uint64_t x) {
198 return ntohq(x);
199}
200# endif
201#endif
202
203
204// MSB is bit #1
205#if HAVE___BUILTIN_CLZ && !HAVE_NO_INTEGER_BUILTINS
210inline int ffs_msb(unsigned x) {
211 return (x ? __builtin_clz(x) + 1 : 0);
212}
213#else
214# define NEED_FFS_MSB_UNSIGNED 1
216int ffs_msb(unsigned x);
217#endif
218
219#if HAVE___BUILTIN_CLZL && !HAVE_NO_INTEGER_BUILTINS
221inline int ffs_msb(unsigned long x) {
222 return (x ? __builtin_clzl(x) + 1 : 0);
223}
224#elif SIZEOF_INT == SIZEOF_LONG
226inline int ffs_msb(unsigned long x) {
227 return ffs_msb(static_cast<unsigned>(x));
228}
229#else
230# define NEED_FFS_MSB_UNSIGNED_LONG 1
232int ffs_msb(unsigned long x);
233#endif
234
235#if HAVE_LONG_LONG && HAVE___BUILTIN_CLZLL && !HAVE_NO_INTEGER_BUILTINS
237inline int ffs_msb(unsigned long long x) {
238 return (x ? __builtin_clzll(x) + 1 : 0);
239}
240#elif HAVE_LONG_LONG && SIZEOF_LONG == SIZEOF_LONG_LONG
242inline int ffs_msb(unsigned long long x) {
243 return ffs_msb(static_cast<unsigned long>(x));
244}
245#elif HAVE_LONG_LONG
246# define NEED_FFS_MSB_UNSIGNED_LONG_LONG 1
248int ffs_msb(unsigned long long x);
249#endif
250
251#if HAVE_INT64_TYPES && !HAVE_INT64_IS_LONG && !HAVE_INT64_IS_LONG_LONG
252# if SIZEOF_LONG >= 8
254inline int ffs_msb(uint64_t x) {
255 return ffs_msb(static_cast<unsigned long>(x));
256}
257# elif HAVE_LONG_LONG && SIZEOF_LONG_LONG >= 8
259inline int ffs_msb(uint64_t x) {
260 return ffs_msb(static_cast<unsigned long long>(x));
261}
262# else
263# define NEED_FFS_MSB_UINT64_T 1
265int ffs_msb(uint64_t x);
266# endif
267#endif
268
269
270// LSB is bit #1
271#if HAVE___BUILTIN_FFS && !HAVE_NO_INTEGER_BUILTINS
276inline int ffs_lsb(unsigned x) {
277 return __builtin_ffs(x);
278}
279#elif HAVE_FFS && !HAVE_NO_INTEGER_BUILTINS
281inline int ffs_lsb(unsigned x) {
282 return ffs(x);
283}
284#else
285# define NEED_FFS_LSB_UNSIGNED 1
287int ffs_lsb(unsigned x);
288#endif
289
290#if HAVE___BUILTIN_FFSL && !HAVE_NO_INTEGER_BUILTINS
292inline int ffs_lsb(unsigned long x) {
293 return __builtin_ffsl(x);
294}
295#elif SIZEOF_INT == SIZEOF_LONG
297inline int ffs_lsb(unsigned long x) {
298 return ffs_lsb(static_cast<unsigned>(x));
299}
300#else
301# define NEED_FFS_LSB_UNSIGNED_LONG 1
303int ffs_lsb(unsigned long x);
304#endif
305
306#if HAVE_LONG_LONG && HAVE___BUILTIN_FFSLL && !HAVE_NO_INTEGER_BUILTINS
308inline int ffs_lsb(unsigned long long x) {
309 return __builtin_ffsll(x);
310}
311#elif HAVE_LONG_LONG && SIZEOF_LONG == SIZEOF_LONG_LONG
313inline int ffs_lsb(unsigned long long x) {
314 return ffs_lsb(static_cast<unsigned long>(x));
315}
316#elif HAVE_LONG_LONG
317# define NEED_FFS_LSB_UNSIGNED_LONG_LONG 1
319int ffs_lsb(unsigned long long x);
320#endif
321
322#if HAVE_INT64_TYPES && !HAVE_INT64_IS_LONG && !HAVE_INT64_IS_LONG_LONG
323# if SIZEOF_LONG >= 8
325inline int ffs_lsb(uint64_t x) {
326 return ffs_lsb(static_cast<unsigned long>(x));
327}
328# elif HAVE_LONG_LONG && SIZEOF_LONG_LONG >= 8
330inline int ffs_lsb(uint64_t x) {
331 return ffs_lsb(static_cast<unsigned long long>(x));
332}
333# else
334# define NEED_FFS_LSB_UINT64_T 1
336int ffs_lsb(uint64_t x);
337# endif
338#endif
339
340
345uint32_t int_sqrt(uint32_t x);
346
347#if HAVE_INT64_TYPES && HAVE_INT64_DIVIDE
349uint64_t int_sqrt(uint64_t x);
350#endif
351
352
354inline uint32_t int_divide(uint32_t a, uint32_t b) {
355 return a / b;
356}
357
359inline int32_t int_divide(int32_t a, uint32_t b) {
360 return a / b;
361}
362
363#if HAVE_INT64_TYPES
365inline uint64_t int_divide(uint64_t a, uint32_t b) {
366# if CLICK_LINUXMODULE && BITS_PER_LONG < 64
367 do_div(a, b);
368 return a;
369# else
370 return a / b;
371# endif
372}
373
375inline int64_t int_divide(int64_t a, uint32_t b) {
376# if CLICK_LINUXMODULE && BITS_PER_LONG < 64
377 if (unlikely(a < 0)) {
378 uint64_t a_abs = -(a + 1);
379 do_div(a_abs, b);
380 return (int64_t) -a_abs - 1;
381 } else {
382 uint64_t &a_unsigned = reinterpret_cast<uint64_t &>(a);
383 do_div(a_unsigned, b);
384 return a_unsigned;
385 }
386# else
387 return a / b;
388# endif
389}
390
391
394template<typename T>
395void int_multiply(T a, T b, T &xlow, T &xhigh)
396{
397 typedef fast_half_integer<T> fasthalf;
398 typedef typename fasthalf::half_type half_type;
399
400 half_type al = fasthalf::low(a), ah = fasthalf::high(a),
401 bl = fasthalf::low(b), bh = fasthalf::high(b);
402
403 T r0 = T(al) * bl;
404 T r3 = T(ah) * bh;
405 T r1 = T(ah) * bl;
406 T r2 = T(al) * bh + fasthalf::high(r0) + r1;
407 if (r2 < r1)
408 r3 += fasthalf::half_value;
409
410 xhigh = r3 + fasthalf::high(r2);
411 xlow = (r2 << fasthalf::half_bits) + fasthalf::low(r0);
412}
413
414template<typename T>
415struct has_fast_int_multiply : public false_type {
416 enum { check_t_integral = integer_traits<T>::is_signed };
417};
418
419#if defined(__i386__) || defined(__x86_64__)
420inline void int_multiply(unsigned a, unsigned b, unsigned &xlow, unsigned &xhigh)
421{
422 __asm__("mul %2" : "=a" (xlow), "=d" (xhigh) : "r" (a), "a" (b) : "cc");
423}
424template<> struct has_fast_int_multiply<unsigned> : public true_type {};
425
426# if SIZEOF_LONG == 4 || (defined(__x86_64__) && SIZEOF_LONG == 8)
427inline void int_multiply(unsigned long a, unsigned long b, unsigned long &xlow, unsigned long &xhigh)
428{
429 __asm__("mul %2" : "=a" (xlow), "=d" (xhigh) : "r" (a), "a" (b) : "cc");
430}
431template<> struct has_fast_int_multiply<unsigned long> : public true_type {};
432# endif
433
434# if defined(__x86_64__) && SIZEOF_LONG_LONG == 8
435inline void int_multiply(unsigned long long a, unsigned long long b, unsigned long long &xlow, unsigned long long &xhigh)
436{
437 __asm__("mul %2" : "=a" (xlow), "=d" (xhigh) : "r" (a), "a" (b) : "cc");
438}
439template<> struct has_fast_int_multiply<unsigned long long> : public true_type {};
440# endif
441#endif
442
443
445inline uint32_t int_remainder(uint32_t a, uint32_t b, uint32_t &quot) {
446 quot = a / b;
447 return a - quot * b;
448}
449
451inline int32_t int_remainder(int32_t a, uint32_t b, int32_t &quot) {
452 if (unlikely(a < 0))
453 quot = -(-(a + 1) / b) - 1;
454 else
455 quot = a / b;
456 return a - quot * b;
457}
458
460inline uint32_t int_remainder(uint64_t a, uint32_t b, uint64_t &quot) {
461# if CLICK_LINUXMODULE && BITS_PER_LONG < 64
462 uint32_t rem = do_div(a, b);
463 quot = a;
464 return rem;
465# else
466 quot = a / b;
467 return a - quot * b;
468# endif
469}
470
472inline uint32_t int_remainder(int64_t a, uint32_t b, int64_t &quot) {
473# if CLICK_LINUXMODULE && BITS_PER_LONG < 64
474 if (unlikely(a < 0)) {
475 uint64_t a_abs = -(a + 1);
476 uint32_t rem = do_div(a_abs, b);
477 quot = (int64_t) -a_abs - 1;
478 return rem ? b - rem : 0;
479 } else {
480 uint64_t &a_unsigned = reinterpret_cast<uint64_t &>(a);
481 uint32_t rem = do_div(a_unsigned, b);
482 quot = a_unsigned;
483 return rem;
484 }
485# else
486 // This arithmetic is about twice as fast on my laptop as the
487 // alternative "div = a / b;
488 // rem = a - (value_type) div * b;
489 // if (rem < 0) div--, rem += b;",
490 // and 3-4x faster than "div = a / b;
491 // rem = a % b;
492 // if (rem < 0) div--, rem += b;".
493 if (unlikely(a < 0))
494 quot = -(-(a + 1) / b) - 1;
495 else
496 quot = a / b;
497 return a - quot * b;
498# endif
499}
500#endif
501
502CLICK_ENDDECLS
503#endif
Type wrapper for the constant false.
Type wrapper for the constant true.
unsigned char host_to_net_order(unsigned char x)
Translate x to network byte order.
Definition integers.hh:58
uint64_t ntohq(uint64_t x)
Return x translated from network to host byte order.
Definition integers.hh:40
void int_multiply(T a, T b, T &xlow, T &xhigh)
Multiply a * b, placing the low-order bits of the result in xlow and the high-order bits in xhigh.
Definition integers.hh:395
int ffs_msb(unsigned x)
Return the index of the most significant bit set in x.
Definition integers.hh:210
uint32_t int_divide(uint32_t a, uint32_t b)
Return a / b.
Definition integers.hh:354
uint32_t int_remainder(uint32_t a, uint32_t b, uint32_t &quot)
Divide a / b, placing quotient in quot and returning remainder.
Definition integers.hh:445
int ffs_lsb(unsigned x)
Return the index of the least significant bit set in x.
Definition integers.hh:276
uint64_t htonq(uint64_t x)
Return x translated from host to network byte order.
Definition integers.hh:21
uint32_t int_sqrt(uint32_t x)
Return the integer approximation of x's square root.
Definition integers.cc:176
unsigned char net_to_host_order(unsigned char x)
Translate x to host byte order.
Definition integers.hh:133
Type transformation for big integers.
Definition type_traits.hh:485
Numeric traits template.
Definition type_traits.hh:244
Type traits structures.