Added assembler optimized macros.
[crypto.git] / lib / silcutil / silctypes.h
1 /*
2
3   silctypes.h
4
5   Author: Pekka Riikonen <priikone@silcnet.org>
6
7   Copyright (C) 2002 - 2007 Pekka Riikonen
8
9   This program is free software; you can redistribute it and/or modify
10   it under the terms of the GNU General Public License as published by
11   the Free Software Foundation; version 2 of the License.
12
13   This program is distributed in the hope that it will be useful,
14   but WITHOUT ANY WARRANTY; without even the implied warranty of
15   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16   GNU General Public License for more details.
17
18 */
19
20 /****h* silcutil/SILC Types
21  *
22  * DESCRIPTION
23  *
24  * This header file includes basic types and definitions used in SILC Toolkits.
25  * It contains all types, and many utility macros and functions.
26  *
27  ***/
28
29 #ifndef SILCTYPES_H
30 #define SILCTYPES_H
31
32 /****d* silcutil/SILCTypes/SilcBool
33  *
34  * NAME
35  *
36  *    typedef unigned char SilcBool;
37  *
38  * DESCRIPTION
39  *
40  *    Boolean value, and is always 8-bits.  Represents value 0 or 1.
41  *
42  ***/
43 typedef unsigned char SilcBool;
44
45 /* The bool macro is deprecated.  Use SilcBool instead. */
46 #ifdef SILC_MACOSX
47 #define bool _Bool
48 #endif
49 #ifndef __cplusplus
50 #ifndef bool
51 #define bool unsigned char
52 #endif
53 #endif
54
55 /****d* silcutil/SILCTypes/TRUE
56  *
57  * NAME
58  *
59  *    #define TRUE ...
60  *
61  * DESCRIPTION
62  *
63  *    Boolean true value indicator.
64  *
65  * SOURCE
66  */
67 #ifndef TRUE
68 #define TRUE 1
69 #endif
70 /***/
71
72 /****d* silcutil/SILCTypes/FALSE
73  *
74  * NAME
75  *
76  *    #define FALSE ...
77  *
78  * DESCRIPTION
79  *
80  *    Boolean false value indicator.
81  *
82  * SOURCE
83  */
84 #ifndef FALSE
85 #define FALSE 0
86 #endif
87 /***/
88
89 /* Our offsetof macro */
90 #define silc_offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER)
91
92 /* silc_likely and silc_unlikely GCC branch prediction macros. Use only if
93    you have profiled the code first. */
94 #if __GNUC__ >= 3
95 #define silc_likely(expr) __builtin_expect(!!(expr), 1)
96 #define silc_unlikely(expr) __builtin_expect(!!(expr), 0)
97 #else
98 #define silc_likely(expr) (expr)
99 #define silc_unlikely(expr) (expr)
100 #endif /* __GNUC__ >= 3 */
101
102 #if SILC_SIZEOF_SHORT > 2
103 #error "size of the short must be 2 bytes"
104 #endif
105
106 /****d* silcutil/SILCTypes/SilcUInt8
107  *
108  * NAME
109  *
110  *    typedef unsigned char SilcUInt8;
111  *
112  * DESCRIPTION
113  *
114  *    8-bit unsigned integer.
115  *
116  * SOURCE
117  */
118 typedef unsigned char SilcUInt8;
119 /***/
120
121 /****d* silcutil/SILCTypes/SilcInt8
122  *
123  * NAME
124  *
125  *    typedef signed char SilcInt8;
126  *
127  * DESCRIPTION
128  *
129  *    8-bit signed integer.
130  *
131  * SOURCE
132  */
133 typedef signed char SilcInt8;
134 /***/
135
136 /****d* silcutil/SILCTypes/SilcUInt16
137  *
138  * NAME
139  *
140  *    typedef unsigned short SilcUInt16;
141  *
142  * DESCRIPTION
143  *
144  *    16-bit unsigned integer.  Guaranteed to be 16-bits.
145  *
146  * SOURCE
147  */
148 typedef unsigned short SilcUInt16;
149 /***/
150
151 /****d* silcutil/SILCTypes/SilcInt16
152  *
153  * NAME
154  *
155  *    typedef signed short SilcInt16;
156  *
157  * DESCRIPTION
158  *
159  *    16-bit signed integer.  Guaranteed to be 16-bits.
160  *
161  * SOURCE
162  */
163 typedef signed short SilcInt16;
164 /***/
165
166 /****d* silcutil/SILCTypes/SilcUInt32
167  *
168  * NAME
169  *
170  *    typedef unsigned long SilcUInt32;
171  *
172  * DESCRIPTION
173  *
174  *    32-bit unsigned integer.  Guaranteed to be 32-bits.
175  *
176  * SOURCE
177  */
178 #if SILC_SIZEOF_LONG == 4
179 typedef unsigned long SilcUInt32;
180 typedef signed long SilcInt32;
181 #else
182 #if SILC_SIZEOF_INT == 4
183 typedef unsigned int SilcUInt32;
184 typedef signed int SilcInt32;
185 #else
186 #if SILC_SIZEOF_LONG_LONG >= 4
187 #ifndef WIN32
188 typedef unsigned long long SilcUInt32;
189 typedef signed long long SilcInt32;
190 #endif
191 #endif
192 #endif
193 #endif
194 /***/
195
196 /****d* silcutil/SILCTypes/SilcInt32
197  *
198  * NAME
199  *
200  *    typedef signed long SilcInt32;
201  *
202  * DESCRIPTION
203  *
204  *    32-bit signed integer.  Guaranteed to be 32-bits.
205  *
206  ***/
207
208 /****d* silcutil/SILCTypes/SilcUInt64
209  *
210  * NAME
211  *
212  *    typedef unsigned long long SilcUInt64;
213  *
214  * DESCRIPTION
215  *
216  *    64-bit unsigned integer.  Guaranteed to be 64-bits on systems that
217  *    support it.
218  *
219  * SOURCE
220  */
221 #if SILC_SIZEOF_LONG >= 8
222 typedef unsigned long SilcUInt64;
223 typedef signed long SilcInt64;
224 #else
225 #if SILC_SIZEOF_LONG_LONG >= 8
226 #ifndef WIN32
227 typedef unsigned long long SilcUInt64;
228 typedef signed long long SilcInt64;
229 #else
230 typedef unsigned __int64 SilcUInt64;
231 typedef signed __int64 SilcInt64;
232 #endif
233 #else
234 typedef SilcUInt32 SilcUInt64;
235 typedef SilcInt32 SilcInt64;
236 #endif
237 #endif
238 /***/
239
240 /****d* silcutil/SILCTypes/SilcInt64
241  *
242  * NAME
243  *
244  *    typedef signed long long SilcInt64;
245  *
246  * DESCRIPTION
247  *
248  *    64-bit signed integer.  Guaranteed to be 64-bits on systems that
249  *    support it.
250  *
251  ***/
252
253 #if SILC_SIZEOF_VOID_P < 4
254 typedef SilcUInt32 * void *;
255 #endif
256
257 /****d* silcutil/SILCTypes/SilcSocket
258  *
259  * NAME
260  *
261  *    SilcSocket
262  *
263  * DESCRIPTION
264  *
265  *    Platform specific socket.  On POSIX compliant systems this is simply
266  *    an integer, representing the socket. On other systems it is platform
267  *    specific socket context.  Access it only through routines that can
268  *    handle SilcSocket types, unless you know what you are doing.
269  *
270  * SOURCE
271  */
272 #if defined(SILC_UNIX)
273 typedef int SilcSocket;
274 #elif defined(SILC_WIN32)
275 typedef SOCKET SilcSocket;
276 #elif defined(SILC_SYMBIAN)
277 typedef void * SilcSocket;
278 #endif
279 /***/
280
281 /* Macros */
282
283 #if (defined(SILC_I486) || defined(SILC_X86_64)) && defined(__GNUC__)
284 #define SILC_GET_WORD(cp)                                               \
285 ({                                                                      \
286   SilcUInt32 _result_;                                                  \
287   asm volatile ("movl (%1), %0; bswapl %0"                              \
288                 : "=q" (_result_) : "q" (cp));                          \
289   _result_;                                                             \
290 })
291 #else
292 #define SILC_GET_WORD(cp) ((SilcUInt32)(SilcUInt8)(cp)[0]) << 24        \
293                     | ((SilcUInt32)(SilcUInt8)(cp)[1] << 16)            \
294                     | ((SilcUInt32)(SilcUInt8)(cp)[2] << 8)             \
295                     | ((SilcUInt32)(SilcUInt8)(cp)[3])
296 #endif /* (SILC_I486 || SILC_X86_64) && __GNUC__ */
297
298 /****d* silcutil/SILCTypes/SILC_GET16_MSB
299  *
300  * NAME
301  *
302  *    #define SILC_GET16_MSB(dest, src)
303  *
304  * DESCRIPTION
305  *
306  *    Return two 8-bit bytes, most significant bytes first.
307  *
308  * SOURCE
309  */
310 #if (defined(SILC_I386) || defined(SILC_X86_64)) && defined(__GNUC__)
311 #define SILC_GET16_MSB(l, cp)                           \
312 asm volatile ("movw (%1), %w0; rolw $8, %w0"            \
313               : "=q" (l) : "q" (cp) : "memory", "cc");
314 #else
315 #define SILC_GET16_MSB(l, cp)                           \
316 do {                                                    \
317   (l) = ((SilcUInt32)(SilcUInt8)(cp)[0] << 8)           \
318     | ((SilcUInt32)(SilcUInt8)(cp)[1]);                 \
319 } while(0)
320 #endif /* (SILC_I386 || SILC_X86_64) && __GNUC__ */
321 /***/
322
323 /****d* silcutil/SILCTypes/SILC_GET32_MSB
324  *
325  * NAME
326  *
327  *    #define SILC_GET32_MSB(dest, src)
328  *
329  * DESCRIPTION
330  *
331  *    Return four 8-bit bytes, most significant bytes first.
332  *
333  * SOURCE
334  */
335 #if (defined(SILC_I486) || defined(SILC_X86_64)) && defined(__GNUC__)
336 #define SILC_GET32_MSB(l, cp)                           \
337 asm volatile ("movl (%1), %0; bswapl %0"                \
338               : "=q" (l) : "q" (cp) : "memory", "cc");
339 #else
340 #define SILC_GET32_MSB(l, cp)                           \
341 do {                                                    \
342   (l) = ((SilcUInt32)(SilcUInt8)(cp)[0]) << 24          \
343     | ((SilcUInt32)(SilcUInt8)(cp)[1] << 16)            \
344     | ((SilcUInt32)(SilcUInt8)(cp)[2] << 8)             \
345     | ((SilcUInt32)(SilcUInt8)(cp)[3]);                 \
346 } while(0)
347 #endif /* (SILC_I486 || SILC_X86_64) && __GNUC__ */
348 /***/
349
350 /* Same as upper but XOR the result always. Special purpose macro. */
351 #if (defined(SILC_I486) || defined(SILC_X86_64)) && defined(__GNUC__)
352 #define SILC_GET32_X_MSB(l, cp)                                         \
353 do {                                                                    \
354   register volatile SilcUInt32 _x_;                                     \
355   asm volatile ("movl %1, %3; movl (%2), %0;\n\t"                       \
356                 "bswapl %0; xorl %3, %0"                                \
357                 : "=r" (l) : "0" (l), "r" (cp), "r" (_x_)               \
358                 : "memory", "cc");                                      \
359 } while(0)
360 #else
361 #define SILC_GET32_X_MSB(l, cp)                         \
362   (l) ^= ((SilcUInt32)(SilcUInt8)(cp)[0]) << 24         \
363     | ((SilcUInt32)(SilcUInt8)(cp)[1] << 16)            \
364     | ((SilcUInt32)(SilcUInt8)(cp)[2] << 8)             \
365     | ((SilcUInt32)(SilcUInt8)(cp)[3]);
366 #endif /* (SILC_I486 || SILC_X86_64) && __GNUC__ */
367
368 /****d* silcutil/SILCTypes/SILC_GET64_MSB
369  *
370  * NAME
371  *
372  *    #define SILC_GET64_MSB(dest, src)
373  *
374  * DESCRIPTION
375  *
376  *    Return eight 8-bit bytes, most significant bytes first.
377  *
378  * SOURCE
379  */
380 #if defined(SILC_X86_64) && defined(__GNUC__)
381 #define SILC_GET64_MSB(l, cp)                                   \
382 asm volatile ("movq (%1), %0; bswapq %0"                        \
383               : "=r" (l) : "r" (cp) : "memory", "cc");
384 #else
385 #define SILC_GET64_MSB(l, cp)                                   \
386 do {                                                            \
387   (l) = ((((SilcUInt64)SILC_GET_WORD((cp))) << 32) |            \
388          ((SilcUInt64)SILC_GET_WORD((cp) + 4)));                \
389 } while(0)
390 #endif /* SILC_X86_64 && __GNUC__ */
391 /***/
392
393 /****d* silcutil/SILCTypes/SILC_GET16_LSB
394  *
395  * NAME
396  *
397  *    #define SILC_GET16_MSB(dest, src)
398  *
399  * DESCRIPTION
400  *
401  *    Return two 8-bit bytes, least significant bytes first.
402  *
403  * SOURCE
404  */
405 #if defined(SILC_I386) || defined(SILC_X86_64)
406 #define SILC_GET16_LSB(l, cp) (l) = (*(SilcUInt16 *)(cp))
407 #else
408 #define SILC_GET16_LSB(l, cp)                           \
409 do {                                                    \
410   (l) = ((SilcUInt32)(SilcUInt8)(cp)[0])                \
411     | ((SilcUInt32)(SilcUInt8)(cp)[1] << 8);            \
412 } while(0)
413 #endif /* SILC_I386 || SILC_X86_64 */
414 /***/
415
416 /****d* silcutil/SILCTypes/SILC_GET32_LSB
417  *
418  * NAME
419  *
420  *    #define SILC_GET32_LSB(dest, src)
421  *
422  * DESCRIPTION
423  *
424  *    Return four 8-bit bytes, least significant bytes first.
425  *
426  * SOURCE
427  */
428 #if defined(SILC_I386) || defined(SILC_X86_64)
429 #define SILC_GET32_LSB(l, cp) (l) = (*(SilcUInt32 *)(cp))
430 #else
431 #define SILC_GET32_LSB(l, cp)                           \
432 do {                                                    \
433   (l) = ((SilcUInt32)(SilcUInt8)(cp)[0])                \
434     | ((SilcUInt32)(SilcUInt8)(cp)[1] << 8)             \
435     | ((SilcUInt32)(SilcUInt8)(cp)[2] << 16)            \
436     | ((SilcUInt32)(SilcUInt8)(cp)[3] << 24);           \
437 } while(0)
438 #endif /* SILC_I386 || SILC_X86_64 */
439 /***/
440
441 /* Same as upper but XOR the result always. Special purpose macro. */
442 #if defined(SILC_I386) || defined(SILC_X86_64)
443 #define SILC_GET32_X_LSB(l, cp) (l) ^= (*(SilcUInt32 *)(cp))
444 #else
445 #define SILC_GET32_X_LSB(l, cp)                         \
446   (l) ^= ((SilcUInt32)(SilcUInt8)(cp)[0])               \
447     | ((SilcUInt32)(SilcUInt8)(cp)[1] << 8)             \
448     | ((SilcUInt32)(SilcUInt8)(cp)[2] << 16)            \
449     | ((SilcUInt32)(SilcUInt8)(cp)[3] << 24)
450 #endif /* SILC_I386 || SILC_X86_64 */
451
452 /****d* silcutil/SILCTypes/SILC_PUT16_MSB
453  *
454  * NAME
455  *
456  *    #define SILC_PUT16_MSB(dest, src)
457  *
458  * DESCRIPTION
459  *
460  *    Put two 8-bit bytes, most significant bytes first.
461  *
462  * SOURCE
463  */
464 #if (defined(SILC_I386) || defined(SILC_X86_64)) && defined(__GNUC__)
465 #define SILC_PUT16_MSB(l, cp)                           \
466 asm volatile ("rolw $8, %w1; movw %w1, (%0)"            \
467               : : "q" (cp), "q" (l) : "memory", "cc");
468 #else
469 #define SILC_PUT16_MSB(l, cp)                   \
470 do {                                            \
471   (cp)[0] = (SilcUInt8)((l) >> 8);              \
472   (cp)[1] = (SilcUInt8)(l);                     \
473 } while(0)
474 #endif /* (SILC_I386 || SILC_X86_64) && __GNUC__ */
475 /***/
476
477 /****d* silcutil/SILCTypes/SILC_PUT32_MSB
478  *
479  * NAME
480  *
481  *    #define SILC_PUT32_MSB(dest, src)
482  *
483  * DESCRIPTION
484  *
485  *    Put four 8-bit bytes, most significant bytes first.
486  *
487  * SOURCE
488  */
489 #if (defined(SILC_I486) || defined(SILC_X86_64)) && defined(__GNUC__)
490 #define SILC_PUT32_MSB(l, cp)                           \
491 asm volatile ("bswapl %1; movl %1, (%0); bswapl %1"     \
492               : : "q" (cp), "q" (l) : "memory", "cc");
493 #else
494 #define SILC_PUT32_MSB(l, cp)                   \
495 do {                                            \
496   (cp)[0] = (SilcUInt8)((l) >> 24);             \
497   (cp)[1] = (SilcUInt8)((l) >> 16);             \
498   (cp)[2] = (SilcUInt8)((l) >> 8);              \
499   (cp)[3] = (SilcUInt8)(l);                     \
500 } while(0)
501 #endif /* (SILC_I486 || SILC_X86_64) && __GNUC__ */
502 /***/
503
504 /****d* silcutil/SILCTypes/SILC_PUT64_MSB
505  *
506  * NAME
507  *
508  *    #define SILC_PUT64_MSB(dest, src)
509  *
510  * DESCRIPTION
511  *
512  *    Put eight 8-bit bytes, most significant bytes first.
513  *
514  * SOURCE
515  */
516 #if defined(SILC_X86_64) && defined(__GNUC__)
517 #define SILC_PUT64_MSB(l, cp)                           \
518 asm volatile ("bswapq %1; movq %1, (%0); bswapq %1"     \
519               : : "r" (cp), "r" (l) : "memory", "cc");
520 #else
521 #define SILC_PUT64_MSB(l, cp)                                   \
522 do {                                                            \
523   SILC_PUT32_MSB((SilcUInt32)((SilcUInt64)(l) >> 32), (cp));    \
524   SILC_PUT32_MSB((SilcUInt32)(l), (cp) + 4);                    \
525 } while(0)
526 #endif /* SILC_X86_64 && __GNUC__ */
527 /***/
528
529 /****d* silcutil/SILCTypes/SILC_PUT16_LSB
530  *
531  * NAME
532  *
533  *    #define SILC_PUT16_LSB(dest, src)
534  *
535  * DESCRIPTION
536  *
537  *    Put two 8-bit bytes, least significant bytes first.
538  *
539  * SOURCE
540  */
541 #if defined(SILC_I386) || defined(SILC_X86_64)
542 #define SILC_PUT16_LSB(l, cp) (*(SilcUInt16 *)(cp)) = (l)
543 #else
544 #define SILC_PUT16_LSB(l, cp)                   \
545 do  {                                           \
546   (cp)[0] = (SilcUInt8)(l);                     \
547   (cp)[1] = (SilcUInt8)((l) >> 8);              \
548 } while(0)
549 #endif /* SILC_I386 || SILC_X86_64 */
550 /***/
551
552 /****d* silcutil/SILCTypes/SILC_PUT32_LSB
553  *
554  * NAME
555  *
556  *    #define SILC_PUT32_LSB(dest, src)
557  *
558  * DESCRIPTION
559  *
560  *    Put four 8-bit bytes, least significant bytes first.
561  *
562  * SOURCE
563  */
564 #if defined(SILC_I386) || defined(SILC_X86_64)
565 #define SILC_PUT32_LSB(l, cp) (*(SilcUInt32 *)(cp)) = (l)
566 #else
567 #define SILC_PUT32_LSB(l, cp)                   \
568 do {                                            \
569   (cp)[0] = (SilcUInt8)(l);                     \
570   (cp)[1] = (SilcUInt8)((l) >> 8);              \
571   (cp)[2] = (SilcUInt8)((l) >> 16);             \
572   (cp)[3] = (SilcUInt8)((l) >> 24);             \
573 } while(0)
574 #endif /* SILC_I386 || SILC_X86_64 */
575 /***/
576
577 /****d* silcutil/SILCTypes/SILC_SWAB_16
578  *
579  * NAME
580  *
581  *    #define SILC_SWAB_16(integer)
582  *
583  * DESCRIPTION
584  *
585  *    Swabs 16-bit unsigned integer byte order.  Returns the new value.
586  *
587  * SOURCE
588  */
589 #if (defined(SILC_I386) || defined(SILC_X86_64)) && defined(__GNUC__)
590 #define SILC_SWAB_16(l)                         \
591 ({                                              \
592   SilcUInt16 _result_;                          \
593   asm volatile ("movw %w1, %w0; rolw $8, %w0"   \
594                 : "=q" (_result_): "q" (l));    \
595   _result_;                                     \
596 })
597 #else
598 #define SILC_SWAB_16(l)                                         \
599   ((SilcUInt16)(((SilcUInt16)(l) & (SilcUInt16)0x00FFU) << 8) | \
600                (((SilcUInt16)(l) & (SilcUInt16)0xFF00U) >> 8))
601 #endif /* (SILC_I386 || SILC_X86_64) && __GNUC__ */
602 /***/
603
604 /****d* silcutil/SILCTypes/SILC_SWAB_32
605  *
606  * NAME
607  *
608  *    #define SILC_SWAB_32(integer)
609  *
610  * DESCRIPTION
611  *
612  *    Swabs 32-bit unsigned integer byte order.  Returns the new value.
613  *
614  * SOURCE
615  */
616 #if (defined(SILC_I486) || defined(SILC_X86_64)) && defined(__GNUC__)
617 #define SILC_SWAB_32(l)                         \
618 ({                                              \
619   SilcUInt32 _result_;                          \
620   asm volatile ("movl %1, %0; bswapl %0"        \
621                 : "=q" (_result_): "q" (l));    \
622   _result_;                                     \
623 })
624 #else
625 #define SILC_SWAB_32(l)                                                 \
626   ((SilcUInt32)(((SilcUInt32)(l) & (SilcUInt32)0x000000FFUL) << 24) |   \
627                (((SilcUInt32)(l) & (SilcUInt32)0x0000FF00UL) << 8)  |   \
628                (((SilcUInt32)(l) & (SilcUInt32)0x00FF0000UL) >> 8)  |   \
629                (((SilcUInt32)(l) & (SilcUInt32)0xFF000000UL) >> 24))
630 #endif /* (SILC_I486 || SILC_X86_64) && __GNUC__ */
631 /***/
632
633 /****d* silcutil/SILCTypes/SILC_PTR_TO_32
634  *
635  * NAME
636  *
637  *    #define SILC_PTR_TO_32(ptr)
638  *
639  * DESCRIPTION
640  *
641  *    Type casts a pointer's value into a 32-bit integer.  Use this to
642  *    avoid compiler warnings when type casting pointers to integers
643  *    of different size.
644  *
645  * SOURCE
646  */
647 #if SILC_SIZEOF_VOID_P < 8
648 #define SILC_PTR_TO_32(_ptr__) ((SilcUInt32)(_ptr__))
649 #else
650 #define SILC_PTR_TO_32(_ptr__)                                          \
651   ((SilcUInt32)((SilcUInt64)(_ptr__) & (SilcUInt32)0xFFFFFFFFUL))
652 #endif
653 /***/
654
655 /****d* silcutil/SILCTypes/SILC_PTR_TO_64
656  *
657  * NAME
658  *
659  *    #define SILC_PTR_TO_64(ptr)
660  *
661  * DESCRIPTION
662  *
663  *    Type casts a pointer's value into a 64-bit integer.  Use this to
664  *    avoid compiler warnings when type casting pointers to integers
665  *    of different size.
666  *
667  * SOURCE
668  */
669 #if SILC_SIZEOF_VOID_P < 8
670 #define SILC_PTR_TO_64(_ptr__) ((SilcUInt64)((SilcUInt32)(_ptr__)))
671 #else
672 #define SILC_PTR_TO_64(_ptr__) ((SilcUInt64)((SilcUInt64)(_ptr__)))
673 #endif
674 /***/
675
676 /****d* silcutil/SILCTypes/SILC_32_TO_PTR
677  *
678  * NAME
679  *
680  *    #define SILC_32_TO_PTR(ptr)
681  *
682  * DESCRIPTION
683  *
684  *    Type casts a 32-bit integer value into a pointer.  Use this to
685  *    avoid compiler warnings when type casting integers to pointers of
686  *    different size.
687  *
688  * SOURCE
689  */
690 #if SILC_SIZEOF_VOID_P < 8
691 #define SILC_32_TO_PTR(_ival__) ((void *)((SilcUInt32)(_ival__)))
692 #else
693 #define SILC_32_TO_PTR(_ival__) ((void *)((SilcUInt64)(_ival__)))
694 #endif
695 /***/
696
697 /****d* silcutil/SILCTypes/SILC_64_TO_PTR
698  *
699  * NAME
700  *
701  *    #define SILC_64_TO_PTR(ptr)
702  *
703  * DESCRIPTION
704  *
705  *    Type casts a 64-bit integer value into a pointer.  Use this to
706  *    avoid compiler warnings when type casting integers to pointers of
707  *    different size.
708  *
709  * SOURCE
710  */
711 #if SILC_SIZEOF_VOID_P < 8
712 #define SILC_64_TO_PTR(_ival__)                                         \
713   ((void *)((SilcUInt32)((SilcUInt64)(_ival__) & (SilcUInt32)0xFFFFFFFFUL)))
714 #else
715 #define SILC_64_TO_PTR(_ival__) ((void *)((SilcUInt64)(_ival__)))
716 #endif
717 /***/
718
719 /****d* silcutil/SILCTypes/silc_rol
720  *
721  * NAME
722  *
723  *    static inline SilcUInt32 silc_rol(SilcUInt32 val, int num);
724  *
725  * DESCRIPTION
726  *
727  *    Rotate 32-bit integer's bits to left `num' times.  Bits pushed to the
728  *    left will appear from the right side of the integer, thus rotating.
729  *    Returns the rotated value.
730  *
731  ***/
732 static inline SilcUInt32 silc_rol(SilcUInt32 val, int num)
733 {
734 #if (defined(SILC_I386) || defined(SILC_X86_64)) && defined(__GNUC__)
735   asm volatile ("roll %%cl, %0"
736                 : "=q" (val) : "0" (val), "c" (num));
737   return val;
738 #else
739   return ((val << (SilcUInt32)num) | (val >> (32 - (SilcUInt32)num)));
740 #endif /* (SILC_I486 || SILC_X86_64) && __GNUC__ */
741 }
742
743 /****d* silcutil/SILCTypes/silc_ror
744  *
745  * NAME
746  *
747  *    static inline SilcUInt32 silc_ror(SilcUInt32 val, int num);
748  *
749  * DESCRIPTION
750  *
751  *    Rotate 32-bit integer's bits to right `num' times.  Bits pushed to the
752  *    right will appear from the left side of the integer, thus rotating.
753  *    Returns the rotated value.
754  *
755  ***/
756 static inline SilcUInt32 silc_ror(SilcUInt32 val, int num)
757 {
758 #if (defined(SILC_I386) || defined(SILC_X86_64)) && defined(__GNUC__)
759   asm volatile ("rorl %%cl, %0"
760                 : "=q" (val) : "0" (val), "c" (num));
761   return val;
762 #else
763   return ((val >> (SilcUInt32)num) | (val << (32 - (SilcUInt32)num)));
764 #endif /* (SILC_I486 || SILC_X86_64) && __GNUC__ */
765 }
766
767 /****d* silcutil/SILCTypes/silc_rol64
768  *
769  * NAME
770  *
771  *    static inline SilcUInt64 silc_rol64(SilcUInt64 val, int num);
772  *
773  * DESCRIPTION
774  *
775  *    Rotate 64-bit integer's bits to left `num' times.  Bits pushed to the
776  *    left will appear from the right side of the integer, thus rotating.
777  *    Returns the rotated value.
778  *
779  ***/
780 static inline SilcUInt64 silc_rol64(SilcUInt64 val, int num)
781 {
782 #if defined(SILC_X86_64) && defined(__GNUC__)
783   asm volatile ("rolq %%cl, %0"
784                 : "=q" (val) : "0" (val), "c" (num));
785   return val;
786 #else
787   return ((val << (SilcUInt64)num) | (val >> (64 - (SilcUInt64)num)));
788 #endif /* SILC_X86_64 && __GNUC__ */
789 }
790
791 /****d* silcutil/SILCTypes/silc_ror64
792  *
793  * NAME
794  *
795  *    static inline SilcUInt64 silc_ror64(SilcUInt64 val, int num);
796  *
797  * DESCRIPTION
798  *
799  *    Rotate 64-bit integer's bits to right `num' times.  Bits pushed to the
800  *    right will appear from the left side of the integer, thus rotating.
801  *    Returns the rotated value.
802  *
803  ***/
804 static inline SilcUInt64 silc_ror64(SilcUInt64 val, int num)
805 {
806 #if defined(SILC_X86_64) && defined(__GNUC__)
807   asm volatile ("rorq %%cl, %0"
808                 : "=q" (val) : "0" (val), "c" (num));
809   return val;
810 #else
811   return ((val >> (SilcUInt64)num) | (val << (64 - (SilcUInt64)num)));
812 #endif /* SILC_X86_64 && __GNUC__ */
813 }
814
815 #endif /* SILCTYPES_H */