Bug 331043: Add the PR_ROTATE_LEFT32 and PR_ROTATE_RIGHT32 macros for
authorwtc%google.com
Sat, 26 Jan 2008 21:49:18 +0000
changeset 3913 6554ca0c719df6b0684a06e93e14aae9abe45b80
parent 3912 57f0afd165d616d3232dd7f6b390291c6e7c419a
child 3914 55dc426f5cefa2f0cc65ce206597eff416883f6e
push idunknown
push userunknown
push dateunknown
bugs331043
Bug 331043: Add the PR_ROTATE_LEFT32 and PR_ROTATE_RIGHT32 macros for rotating left and right, which are defined using compiler intrinsics, if available. The patch is contributed by Michael Moy <mmoy@yahoo.com>. r=brendan,wtc Modified files: prbit.h plhash.c
lib/ds/plhash.c
pr/include/prbit.h
--- a/lib/ds/plhash.c
+++ b/lib/ds/plhash.c
@@ -519,17 +519,17 @@ PL_HashTableDump(PLHashTable *ht, PLHash
 PR_IMPLEMENT(PLHashNumber)
 PL_HashString(const void *key)
 {
     PLHashNumber h;
     const PRUint8 *s;
 
     h = 0;
     for (s = (const PRUint8*)key; *s; s++)
-        h = (h >> 28) ^ (h << 4) ^ *s;
+        h = PR_ROTATE_LEFT32(h, 4) ^ *s;
     return h;
 }
 
 PR_IMPLEMENT(int)
 PL_CompareStrings(const void *v1, const void *v2)
 {
     return strcmp((const char*)v1, (const char*)v2) == 0;
 }
--- a/pr/include/prbit.h
+++ b/pr/include/prbit.h
@@ -102,10 +102,35 @@ NSPR_API(PRIntn) PR_FloorLog2(PRUint32 i
     if ((j_) >> 4)                  \
 	(_log2) += 4, (j_) >>= 4;   \
     if ((j_) >> 2)                  \
 	(_log2) += 2, (j_) >>= 2;   \
     if ((j_) >> 1)                  \
 	(_log2) += 1;               \
   PR_END_MACRO
 
+/*
+** Macros for rotate left and right. The argument 'a' must be an unsigned
+** 32-bit integer type such as PRUint32.
+**
+** There is no rotate operation in the C Language, so the construct
+** (a >> 28) | (a << 4) is frequently used instead. Most compilers convert
+** this to a rotate instruction, but MSVC doesn't without a little help.
+** To get MSVC to generate a rotate instruction, we have to use the _rotl
+** or _rotr intrinsic and use a pragma to make it inline.
+**
+** Note: MSVC in VS2005 will do an inline rotate instruction on the above
+** construct.
+*/
+
+#if defined(_MSC_VER) && (defined(_X86_) || defined(_AMD64_) || \
+    defined(_M_AMD64))
+#include <stdlib.h>
+#pragma intrinsic(_rotl, _rotr)
+#define PR_ROTATE_LEFT32(a, bits) _rotl(a, bits)
+#define PR_ROTATE_RIGHT32(a, bits) _rotr(a, bits)
+#else
+#define PR_ROTATE_LEFT32(a, bits) (((a) << (bits)) | ((a) >> (32 - (bits))))
+#define PR_ROTATE_RIGHT32(a, bits) (((a) >> (bits)) | ((a) << (32 - (bits))))
+#endif
+
 PR_END_EXTERN_C
 #endif /* prbit_h___ */