1 /* fix for MSVC ...evil! */
2 #ifdef _MSC_VER
3    #define CONST64(n) n ## ui64
4    typedef unsigned __int64 ulong64;
5 #else
6    #define CONST64(n) n ## ULL
7    typedef unsigned long long ulong64;
8 #endif
9 
10 /* this is the "32-bit at least" data type
11  * Re-define it to suit your platform but it must be at least 32-bits
12  */
13 #if defined(__x86_64__) || (defined(__sparc__) && defined(__arch64__))
14    typedef unsigned ulong32;
15 #else
16    typedef unsigned long ulong32;
17 #endif
18 
19 /* ---- HELPER MACROS ---- */
20 #ifdef ENDIAN_NEUTRAL
21 
22 #define STORE32L(x, y)                                                                     \
23      { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255);   \
24        (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
25 
26 #define LOAD32L(x, y)                            \
27      { x = ((unsigned long)((y)[3] & 255)<<24) | \
28            ((unsigned long)((y)[2] & 255)<<16) | \
29            ((unsigned long)((y)[1] & 255)<<8)  | \
30            ((unsigned long)((y)[0] & 255)); }
31 
32 #define STORE64L(x, y)                                                                     \
33      { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255);   \
34        (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255);   \
35        (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255);   \
36        (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
37 
38 #define LOAD64L(x, y)                                                       \
39      { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \
40            (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \
41            (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \
42            (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
43 
44 #define STORE32H(x, y)                                                                     \
45      { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255);   \
46        (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); }
47 
48 #define LOAD32H(x, y)                            \
49      { x = ((unsigned long)((y)[0] & 255)<<24) | \
50            ((unsigned long)((y)[1] & 255)<<16) | \
51            ((unsigned long)((y)[2] & 255)<<8)  | \
52            ((unsigned long)((y)[3] & 255)); }
53 
54 #define STORE64H(x, y)                                                                     \
55    { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255);     \
56      (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255);     \
57      (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255);     \
58      (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
59 
60 #define LOAD64H(x, y)                                                      \
61    { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \
62          (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \
63          (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \
64          (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); }
65 
66 #endif /* ENDIAN_NEUTRAL */
67 
68 #ifdef ENDIAN_LITTLE
69 
70 #if !defined(LTC_NO_BSWAP) && (defined(INTEL_CC) || (defined(__GNUC__) && (defined(__DJGPP__) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__i386__) || defined(__x86_64__))))
71 
72 #define STORE32H(x, y)           \
73 asm __volatile__ (               \
74    "bswapl %0     \n\t"          \
75    "movl   %0,(%1)\n\t"          \
76    "bswapl %0     \n\t"          \
77       ::"r"(x), "r"(y));
78 
79 #define LOAD32H(x, y)          \
80 asm __volatile__ (             \
81    "movl (%1),%0\n\t"          \
82    "bswapl %0\n\t"             \
83    :"=r"(x): "r"(y));
84 
85 #else
86 
87 #define STORE32H(x, y)                                                                     \
88      { (y)[0] = (unsigned char)(((x)>>24)&255); (y)[1] = (unsigned char)(((x)>>16)&255);   \
89        (y)[2] = (unsigned char)(((x)>>8)&255); (y)[3] = (unsigned char)((x)&255); }
90 
91 #define LOAD32H(x, y)                            \
92      { x = ((unsigned long)((y)[0] & 255)<<24) | \
93            ((unsigned long)((y)[1] & 255)<<16) | \
94            ((unsigned long)((y)[2] & 255)<<8)  | \
95            ((unsigned long)((y)[3] & 255)); }
96 
97 #endif
98 
99 
100 /* x86_64 processor */
101 #if !defined(LTC_NO_BSWAP) && (defined(__GNUC__) && defined(__x86_64__))
102 
103 #define STORE64H(x, y)           \
104 asm __volatile__ (               \
105    "bswapq %0     \n\t"          \
106    "movq   %0,(%1)\n\t"          \
107    "bswapq %0     \n\t"          \
108       ::"r"(x), "r"(y));
109 
110 #define LOAD64H(x, y)          \
111 asm __volatile__ (             \
112    "movq (%1),%0\n\t"          \
113    "bswapq %0\n\t"             \
114    :"=r"(x): "r"(y));
115 
116 #else
117 
118 #define STORE64H(x, y)                                                                     \
119    { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255);     \
120      (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255);     \
121      (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255);     \
122      (y)[6] = (unsigned char)(((x)>>8)&255); (y)[7] = (unsigned char)((x)&255); }
123 
124 #define LOAD64H(x, y)                                                      \
125    { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48) | \
126          (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32) | \
127          (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16) | \
128          (((ulong64)((y)[6] & 255))<<8)|(((ulong64)((y)[7] & 255))); }
129 
130 #endif
131 
132 #ifdef ENDIAN_32BITWORD
133 
134 #define STORE32L(x, y)        \
135      { ulong32  __t = (x); XMEMCPY(y, &__t, 4); }
136 
137 #define LOAD32L(x, y)         \
138      XMEMCPY(&(x), y, 4);
139 
140 #define STORE64L(x, y)                                                                     \
141      { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255);   \
142        (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255);   \
143        (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255);   \
144        (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
145 
146 #define LOAD64L(x, y)                                                       \
147      { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48)| \
148            (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32)| \
149            (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16)| \
150            (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
151 
152 #else /* 64-bit words then  */
153 
154 #define STORE32L(x, y)        \
155      { ulong32 __t = (x); XMEMCPY(y, &__t, 4); }
156 
157 #define LOAD32L(x, y)         \
158      { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; }
159 
160 #define STORE64L(x, y)        \
161      { ulong64 __t = (x); XMEMCPY(y, &__t, 8); }
162 
163 #define LOAD64L(x, y)         \
164     { XMEMCPY(&(x), y, 8); }
165 
166 #endif /* ENDIAN_64BITWORD */
167 
168 #endif /* ENDIAN_LITTLE */
169 
170 #ifdef ENDIAN_BIG
171 #define STORE32L(x, y)                                                                     \
172      { (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255);   \
173        (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
174 
175 #define LOAD32L(x, y)                            \
176      { x = ((unsigned long)((y)[3] & 255)<<24) | \
177            ((unsigned long)((y)[2] & 255)<<16) | \
178            ((unsigned long)((y)[1] & 255)<<8)  | \
179            ((unsigned long)((y)[0] & 255)); }
180 
181 #define STORE64L(x, y)                                                                     \
182    { (y)[7] = (unsigned char)(((x)>>56)&255); (y)[6] = (unsigned char)(((x)>>48)&255);     \
183      (y)[5] = (unsigned char)(((x)>>40)&255); (y)[4] = (unsigned char)(((x)>>32)&255);     \
184      (y)[3] = (unsigned char)(((x)>>24)&255); (y)[2] = (unsigned char)(((x)>>16)&255);     \
185      (y)[1] = (unsigned char)(((x)>>8)&255); (y)[0] = (unsigned char)((x)&255); }
186 
187 #define LOAD64L(x, y)                                                      \
188    { x = (((ulong64)((y)[7] & 255))<<56)|(((ulong64)((y)[6] & 255))<<48) | \
189          (((ulong64)((y)[5] & 255))<<40)|(((ulong64)((y)[4] & 255))<<32) | \
190          (((ulong64)((y)[3] & 255))<<24)|(((ulong64)((y)[2] & 255))<<16) | \
191          (((ulong64)((y)[1] & 255))<<8)|(((ulong64)((y)[0] & 255))); }
192 
193 #ifdef ENDIAN_32BITWORD
194 
195 #define STORE32H(x, y)        \
196      { ulong32 __t = (x); XMEMCPY(y, &__t, 4); }
197 
198 #define LOAD32H(x, y)         \
199      XMEMCPY(&(x), y, 4);
200 
201 #define STORE64H(x, y)                                                                     \
202      { (y)[0] = (unsigned char)(((x)>>56)&255); (y)[1] = (unsigned char)(((x)>>48)&255);   \
203        (y)[2] = (unsigned char)(((x)>>40)&255); (y)[3] = (unsigned char)(((x)>>32)&255);   \
204        (y)[4] = (unsigned char)(((x)>>24)&255); (y)[5] = (unsigned char)(((x)>>16)&255);   \
205        (y)[6] = (unsigned char)(((x)>>8)&255);  (y)[7] = (unsigned char)((x)&255); }
206 
207 #define LOAD64H(x, y)                                                       \
208      { x = (((ulong64)((y)[0] & 255))<<56)|(((ulong64)((y)[1] & 255))<<48)| \
209            (((ulong64)((y)[2] & 255))<<40)|(((ulong64)((y)[3] & 255))<<32)| \
210            (((ulong64)((y)[4] & 255))<<24)|(((ulong64)((y)[5] & 255))<<16)| \
211            (((ulong64)((y)[6] & 255))<<8)| (((ulong64)((y)[7] & 255))); }
212 
213 #else /* 64-bit words then  */
214 
215 #define STORE32H(x, y)        \
216      { ulong32 __t = (x); XMEMCPY(y, &__t, 4); }
217 
218 #define LOAD32H(x, y)         \
219      { XMEMCPY(&(x), y, 4); x &= 0xFFFFFFFF; }
220 
221 #define STORE64H(x, y)        \
222      { ulong64 __t = (x); XMEMCPY(y, &__t, 8); }
223 
224 #define LOAD64H(x, y)         \
225     { XMEMCPY(&(x), y, 8); }
226 
227 #endif /* ENDIAN_64BITWORD */
228 #endif /* ENDIAN_BIG */
229 
230 #define BSWAP(x)  ( ((x>>24)&0x000000FFUL) | ((x<<24)&0xFF000000UL)  | \
231                     ((x>>8)&0x0000FF00UL)  | ((x<<8)&0x00FF0000UL) )
232 
233 
234 /* 32-bit Rotates */
235 #if defined(_MSC_VER)
236 
237 /* instrinsic rotate */
238 #include <stdlib.h>
239 #pragma intrinsic(_lrotr,_lrotl)
240 #define ROR(x,n) _lrotr(x,n)
241 #define ROL(x,n) _lrotl(x,n)
242 #define RORc(x,n) _lrotr(x,n)
243 #define ROLc(x,n) _lrotl(x,n)
244 
245 #elif !defined(__STRICT_ANSI__) && defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__)) && !defined(INTEL_CC) && !defined(LTC_NO_ASM)
246 
247 static inline unsigned ROL(unsigned word, int i)
248 {
249    asm ("roll %%cl,%0"
250       :"=r" (word)
251       :"0" (word),"c" (i));
252    return word;
253 }
254 
255 static inline unsigned ROR(unsigned word, int i)
256 {
257    asm ("rorl %%cl,%0"
258       :"=r" (word)
259       :"0" (word),"c" (i));
260    return word;
261 }
262 
263 #ifndef LTC_NO_ROLC
264 
265 static inline unsigned ROLc(unsigned word, const int i)
266 {
267    asm ("roll %2,%0"
268       :"=r" (word)
269       :"0" (word),"I" (i));
270    return word;
271 }
272 
273 static inline unsigned RORc(unsigned word, const int i)
274 {
275    asm ("rorl %2,%0"
276       :"=r" (word)
277       :"0" (word),"I" (i));
278    return word;
279 }
280 
281 #else
282 
283 #define ROLc ROL
284 #define RORc ROR
285 
286 #endif
287 
288 #elif !defined(__STRICT_ANSI__) && defined(LTC_PPC32)
289 
290 static inline unsigned ROL(unsigned word, int i)
291 {
292    asm ("rotlw %0,%0,%2"
293       :"=r" (word)
294       :"0" (word),"r" (i));
295    return word;
296 }
297 
298 static inline unsigned ROR(unsigned word, int i)
299 {
300    asm ("rotlw %0,%0,%2"
301       :"=r" (word)
302       :"0" (word),"r" (32-i));
303    return word;
304 }
305 
306 #ifndef LTC_NO_ROLC
307 
308 static inline unsigned ROLc(unsigned word, const int i)
309 {
310    asm ("rotlwi %0,%0,%2"
311       :"=r" (word)
312       :"0" (word),"I" (i));
313    return word;
314 }
315 
316 static inline unsigned RORc(unsigned word, const int i)
317 {
318    asm ("rotrwi %0,%0,%2"
319       :"=r" (word)
320       :"0" (word),"I" (i));
321    return word;
322 }
323 
324 #else
325 
326 #define ROLc ROL
327 #define RORc ROR
328 
329 #endif
330 
331 
332 #else
333 
334 /* rotates the hard way */
335 #define ROL(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
336 #define ROR(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
337 #define ROLc(x, y) ( (((unsigned long)(x)<<(unsigned long)((y)&31)) | (((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
338 #define RORc(x, y) ( ((((unsigned long)(x)&0xFFFFFFFFUL)>>(unsigned long)((y)&31)) | ((unsigned long)(x)<<(unsigned long)(32-((y)&31)))) & 0xFFFFFFFFUL)
339 
340 #endif
341 
342 
343 /* 64-bit Rotates */
344 #if !defined(__STRICT_ANSI__) && defined(__GNUC__) && defined(__x86_64__) && !defined(LTC_NO_ASM)
345 
346 static inline unsigned long ROL64(unsigned long word, int i)
347 {
348    asm("rolq %%cl,%0"
349       :"=r" (word)
350       :"0" (word),"c" (i));
351    return word;
352 }
353 
354 static inline unsigned long ROR64(unsigned long word, int i)
355 {
356    asm("rorq %%cl,%0"
357       :"=r" (word)
358       :"0" (word),"c" (i));
359    return word;
360 }
361 
362 #ifndef LTC_NO_ROLC
363 
364 static inline unsigned long ROL64c(unsigned long word, const int i)
365 {
366    asm("rolq %2,%0"
367       :"=r" (word)
368       :"0" (word),"J" (i));
369    return word;
370 }
371 
372 static inline unsigned long ROR64c(unsigned long word, const int i)
373 {
374    asm("rorq %2,%0"
375       :"=r" (word)
376       :"0" (word),"J" (i));
377    return word;
378 }
379 
380 #else /* LTC_NO_ROLC */
381 
382 #define ROL64c ROL64
383 #define ROR64c ROR64
384 
385 #endif
386 
387 #else /* Not x86_64  */
388 
389 #define ROL64(x, y) \
390     ( (((x)<<((ulong64)(y)&63)) | \
391       (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF))
392 
393 #define ROR64(x, y) \
394     ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \
395       ((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF))
396 
397 #define ROL64c(x, y) \
398     ( (((x)<<((ulong64)(y)&63)) | \
399       (((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)64-((y)&63)))) & CONST64(0xFFFFFFFFFFFFFFFF))
400 
401 #define ROR64c(x, y) \
402     ( ((((x)&CONST64(0xFFFFFFFFFFFFFFFF))>>((ulong64)(y)&CONST64(63))) | \
403       ((x)<<((ulong64)(64-((y)&CONST64(63)))))) & CONST64(0xFFFFFFFFFFFFFFFF))
404 
405 #endif
406 
407 #ifndef MAX
408    #define MAX(x, y) ( ((x)>(y))?(x):(y) )
409 #endif
410 
411 #ifndef MIN
412    #define MIN(x, y) ( ((x)<(y))?(x):(y) )
413 #endif
414 
415 /* extract a byte portably */
416 #ifdef _MSC_VER
417    #define byte(x, n) ((unsigned char)((x) >> (8 * (n))))
418 #else
419    #define byte(x, n) (((x) >> (8 * (n))) & 255)
420 #endif
421 
422 /* $Source$ */
423 /* $Revision$ */
424 /* $Date$ */
425