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 82