Commit | Line | Data |
---|---|---|
1c4b2386 YO |
1 | #ifndef PERL_SEEN_HV_MACRO_H /* compile once */ |
2 | #define PERL_SEEN_HV_MACRO_H | |
3 | ||
4 | #if IVSIZE == 8 | |
5 | #define CAN64BITHASH | |
6 | #endif | |
7 | ||
8 | /*----------------------------------------------------------------------------- | |
9 | * Endianess, misalignment capabilities and util macros | |
10 | * | |
11 | * The following 3 macros are defined in this section. The other macros defined | |
12 | * are only needed to help derive these 3. | |
13 | * | |
14 | * U8TO16_LE(x) Read a little endian unsigned 32-bit int | |
15 | * U8TO32_LE(x) Read a little endian unsigned 32-bit int | |
16 | * U8TO28_LE(x) Read a little endian unsigned 32-bit int | |
17 | * ROTL32(x,r) Rotate x left by r bits | |
18 | * ROTL64(x,r) Rotate x left by r bits | |
19 | * ROTR32(x,r) Rotate x right by r bits | |
20 | * ROTR64(x,r) Rotate x right by r bits | |
21 | */ | |
22 | ||
23 | #ifndef U32_ALIGNMENT_REQUIRED | |
24 | #if (BYTEORDER == 0x1234 || BYTEORDER == 0x12345678) | |
25 | #define U8TO16_LE(ptr) (*((const U16*)(ptr))) | |
26 | #define U8TO32_LE(ptr) (*((const U32*)(ptr))) | |
27 | #define U8TO64_LE(ptr) (*((const U64*)(ptr))) | |
28 | #elif (BYTEORDER == 0x4321 || BYTEORDER == 0x87654321) | |
29 | #if defined(__GNUC__) && (__GNUC__>4 || (__GNUC__==4 && __GNUC_MINOR__>=3)) | |
30 | #define U8TO16_LE(ptr) (__builtin_bswap16(*((U16*)(ptr)))) | |
31 | #define U8TO32_LE(ptr) (__builtin_bswap32(*((U32*)(ptr)))) | |
32 | #define U8TO64_LE(ptr) (__builtin_bswap64(*((U64*)(ptr)))) | |
33 | #endif | |
34 | #endif | |
35 | #endif | |
36 | ||
37 | #ifndef U8TO16_LE | |
38 | /* Without a known fast bswap32 we're just as well off doing this */ | |
39 | #define U8TO16_LE(ptr) ((U32)(ptr)[0]|(U32)(ptr)[1]<<8) | |
40 | #define U8TO32_LE(ptr) ((U32)(ptr)[0]|(U32)(ptr)[1]<<8|(U32)(ptr)[2]<<16|(U32)(ptr)[3]<<24) | |
41 | #define U8TO64_LE(ptr) ((U64)(ptr)[0]|(U64)(ptr)[1]<<8|(U64)(ptr)[2]<<16|(U64)(ptr)[3]<<24|\ | |
42 | (U64)(ptr)[4]<<32|(U64)(ptr)[5]<<40|\ | |
43 | (U64)(ptr)[6]<<48|(U64)(ptr)[7]<<56) | |
44 | #endif | |
45 | ||
46 | #ifdef CAN64BITHASH | |
47 | #ifndef U64TYPE | |
48 | /* This probably isn't going to work, but failing with a compiler error due to | |
49 | lack of uint64_t is no worse than failing right now with an #error. */ | |
50 | #define U64 uint64_t | |
51 | #endif | |
52 | #endif | |
53 | ||
54 | /* Find best way to ROTL32/ROTL64 */ | |
55 | #if defined(_MSC_VER) | |
56 | #include <stdlib.h> /* Microsoft put _rotl declaration in here */ | |
57 | #define ROTL32(x,r) _rotl(x,r) | |
58 | #define ROTR32(x,r) _rotr(x,r) | |
59 | #define ROTL64(x,r) _rotl64(x,r) | |
60 | #define ROTR64(x,r) _rotr64(x,r) | |
61 | #else | |
62 | /* gcc recognises this code and generates a rotate instruction for CPUs with one */ | |
63 | #define ROTL32(x,r) (((U32)(x) << (r)) | ((U32)(x) >> (32 - (r)))) | |
64 | #define ROTR32(x,r) (((U32)(x) << (32 - (r))) | ((U32)(x) >> (r))) | |
65 | #define ROTL64(x,r) ( ( (U64)(x) << (r) ) | ( (U64)(x) >> ( 64 - (r) ) ) ) | |
66 | #define ROTR64(x,r) ( ( (U64)(x) << ( 64 - (r) ) ) | ( (U64)(x) >> (r) ) ) | |
67 | #endif | |
68 | ||
69 | ||
70 | #ifdef UV_IS_QUAD | |
71 | #define ROTL_UV(x,r) ROTL64(x,r) | |
72 | #define ROTR_UV(x,r) ROTL64(x,r) | |
73 | #else | |
74 | #define ROTL_UV(x,r) ROTL32(x,r) | |
75 | #define ROTR_UV(x,r) ROTR32(x,r) | |
76 | #endif | |
77 | #if IVSIZE == 8 | |
78 | #define CAN64BITHASH | |
79 | #endif | |
80 | ||
81 | #endif |