X-Git-Url: https://perl5.git.perl.org/perl5.git/blobdiff_plain/3deca554c91ecb8309424e4f088fdde80e21248b..7f4a9bc72716574716b99e45c11129541a8fbeb7:/zaphod32_hash.h?ds=sidebyside diff --git a/zaphod32_hash.h b/zaphod32_hash.h index ec091f7..c9b60cc 100644 --- a/zaphod32_hash.h +++ b/zaphod32_hash.h @@ -25,29 +25,35 @@ #define ZAPHOD32_WARN2(pat,v0,v1) #endif +/* Find best way to ROTL32/ROTL64 */ #ifndef ROTL32 -#define _ROTL_SIZED(x,r,s) ( ((x) << (r)) | ((x) >> ((s) - (r))) ) -#define _ROTR_SIZED(x,r,s) ( ((x) << ((s) - (r))) | ((x) >> (r)) ) -#define ROTL32(x,r) _ROTL_SIZED(x,r,32) -#define ROTR32(x,r) _ROTR_SIZED(x,r,32) +#if defined(_MSC_VER) +#include /* Microsoft put _rotl declaration in here */ +#define ROTL32(x,r) _rotl(x,r) +#define ROTR32(x,r) _rotr(x,r) +#else +/* gcc recognises this code and generates a rotate instruction for CPUs with one */ +#define ROTL32(x,r) (((U32)(x) << (r)) | ((U32)(x) >> (32 - (r)))) +#define ROTR32(x,r) (((U32)(x) << (32 - (r))) | ((U32)(x) >> (r))) +#endif #endif #ifndef PERL_SEEN_HV_FUNC_H #if !defined(U64) - #include - #define U64 uint64_t +#include +#define U64 uint64_t #endif #if !defined(U32) - #define U32 uint32_t +#define U32 uint32_t #endif #if !defined(U8) - #define U8 unsigned char +#define U8 unsigned char #endif #if !defined(U16) - #define U16 uint16_t +#define U16 uint16_t #endif #ifndef STRLEN @@ -68,14 +74,39 @@ #define STMT_END while(0) #endif -#ifndef U8TO64_LE -#define U8TO64_LE(ptr) (*((const U64 *)(ptr))) +#ifndef ZAPHOD32_ALLOW_UNALIGNED_AND_LITTLE_ENDIAN +/* ZAPHOD32_ALLOW_UNALIGNED_AND_LITTLE_ENDIAN only matters if nothing has defined U8TO64_LE etc, + * and when built with Perl these should be defined before this file is loaded. + */ +#ifdef U32_ALIGNMENT_REQUIRED +#define ZAPHOD32_ALLOW_UNALIGNED_AND_LITTLE_ENDIAN 0 +#else +#define ZAPHOD32_ALLOW_UNALIGNED_AND_LITTLE_ENDIAN 1 #endif +#endif + #ifndef U8TO32_LE +#if ZAPHOD32_ALLOW_UNALIGNED_AND_LITTLE_ENDIAN #define U8TO32_LE(ptr) (*((const U32 *)(ptr))) +#else +#define U8TO32_LE(ptr) (\ + (U32)(ptr)[3] << 24 | \ + (U32)(ptr)[2] << 16 | \ + (U32)(ptr)[1] << 8 | \ + (U32)(ptr)[0] \ +) #endif +#endif + #ifndef U8TO16_LE +#if ZAPHOD32_ALLOW_UNALIGNED_AND_LITTLE_ENDIAN #define U8TO16_LE(ptr) (*((const U16 *)(ptr))) +#else +#define U8TO16_LE(ptr) (\ + (U16)(ptr)[1] << 8 | \ + (U16)(ptr)[0] \ +) +#endif #endif /* This is two marsaglia xor-shift permutes, with a prime-multiple @@ -134,7 +165,7 @@ void zaphod32_seed_state ( const U8 *seed_ch, U8 *state_ch ) { - U32 *seed= (U32 *)seed_ch; + const U32 *seed= (const U32 *)seed_ch; U32 *state= (U32 *)state_ch; /* hex expansion of pi, skipping first two digits. pi= 3.2[43f6...]*/ @@ -184,10 +215,10 @@ U32 zaphod32_hash_with_state( ) { U32 *state= (U32 *)state_ch; const U8 *end; - U32 len = key_len; + STRLEN len = key_len; U32 v0= state[0]; U32 v1= state[1]; - U32 v2= state[2] ^ (0xC41A7AB1 * (key_len + 1)); + U32 v2= state[2] ^ (0xC41A7AB1 * ((U32)key_len + 1)); ZAPHOD32_WARN4("v0=%08x v1=%08x v2=%08x ln=%08x HASH START\n", (unsigned int)state[0], (unsigned int)state[1], @@ -195,24 +226,24 @@ U32 zaphod32_hash_with_state( { switch (len) { default: goto zaphod32_read8; - case 12: v2 += (U32)key[11] << 24; - case 11: v2 += (U32)key[10] << 16; + case 12: v2 += (U32)key[11] << 24; /* FALLTHROUGH */ + case 11: v2 += (U32)key[10] << 16; /* FALLTHROUGH */ case 10: v2 += (U32)U8TO16_LE(key+8); v1 -= U8TO32_LE(key+4); v0 += U8TO32_LE(key+0); goto zaphod32_finalize; - case 9: v2 += (U32)key[8]; + case 9: v2 += (U32)key[8]; /* FALLTHROUGH */ case 8: v1 -= U8TO32_LE(key+4); v0 += U8TO32_LE(key+0); goto zaphod32_finalize; - case 7: v2 += (U32)key[6]; + case 7: v2 += (U32)key[6]; /* FALLTHROUGH */ case 6: v0 += (U32)U8TO16_LE(key+4); v1 -= U8TO32_LE(key+0); goto zaphod32_finalize; - case 5: v0 += (U32)key[4]; + case 5: v0 += (U32)key[4]; /* FALLTHROUGH */ case 4: v1 -= U8TO32_LE(key+0); goto zaphod32_finalize; - case 3: v2 += (U32)key[2]; + case 3: v2 += (U32)key[2]; /* FALLTHROUGH */ case 2: v0 += (U32)U8TO16_LE(key); break; case 1: v0 += (U32)key[0]; @@ -238,7 +269,10 @@ U32 zaphod32_hash_with_state( return v0 ^ v2; } - if (len >= 8) { +/* if (len >= 8) */ /* this block is only reached by a goto above, so this condition + is commented out, but if the above block is removed it would + be necessary to use this. */ + { zaphod32_read8: len = key_len & 0x7; end = key + key_len - len; @@ -257,12 +291,13 @@ zaphod32_read8: v0 += (U32)(key_len) << 24; switch (len & 0x3) { - case 3: v2 += (U32)key[2]; + case 3: v2 += (U32)key[2]; /* FALLTHROUGH */ case 2: v0 += (U32)U8TO16_LE(key); break; case 1: v0 += (U32)key[0]; break; case 0: v2 ^= 0xFF; + break; } zaphod32_finalize: ZAPHOD32_FINALIZE(v0,v1,v2);