summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwtc%google.com <devnull@localhost>2008-01-26 21:49:18 +0000
committerwtc%google.com <devnull@localhost>2008-01-26 21:49:18 +0000
commit0d7c1092b426f47c9a5d824f1ed1b0bddd821f06 (patch)
treeb505be1a3a8e8abd3e07860931b1a57d2968681b
parent1304ef6266f9e8a61d5fccb159f4fafe2ba7d59d (diff)
downloadnspr-hg-0d7c1092b426f47c9a5d824f1ed1b0bddd821f06.tar.gz
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
-rw-r--r--lib/ds/plhash.c2
-rw-r--r--pr/include/prbit.h25
2 files changed, 26 insertions, 1 deletions
diff --git a/lib/ds/plhash.c b/lib/ds/plhash.c
index 98ce5959..48825bb3 100644
--- a/lib/ds/plhash.c
+++ b/lib/ds/plhash.c
@@ -524,7 +524,7 @@ PL_HashString(const void *key)
h = 0;
for (s = (const PRUint8*)key; *s; s++)
- h = (h >> 28) ^ (h << 4) ^ *s;
+ h = PR_ROTATE_LEFT32(h, 4) ^ *s;
return h;
}
diff --git a/pr/include/prbit.h b/pr/include/prbit.h
index 379971e8..cda9bd71 100644
--- a/pr/include/prbit.h
+++ b/pr/include/prbit.h
@@ -107,5 +107,30 @@ NSPR_API(PRIntn) PR_FloorLog2(PRUint32 i);
(_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___ */