#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 <stdlib.h> /* 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 <stdint.h>
- #define U64 uint64_t
+#include <stdint.h>
+#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
#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
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...]*/
) {
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],
{
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];
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;
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);