block-sha1: split the different "hacks" to be individually selected
This is to make it easier for them to be selected individually depending on the architecture instead of the other way around i.e. having each architecture select a list of hacks up front. That makes for clearer documentation as well. Signed-off-by: Nicolas Pitre <nico@cam.org> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Nicolas Pitre committed
Aug 12, 2009 at 15:46 UTC
dc52fd29738c2af98f3e986691eca34addfd4914
1 file changed
+18
-5
block-sha1/sha1.c
+18
-5
@@ -11,10 +11,16 @@
11
12
#if defined(__i386__) || defined(__x86_64__)
13
14
+/*
15
+ * Force usage of rol or ror by selecting the one with the smaller constant.
16
+ * It _can_ generate slightly smaller code (a constant of 1 is special), but
17
+ * perhaps more importantly it's possibly faster on any uarch that does a
18
+ * rotate with a loop.
19
+ */
20
+
21
#define SHA_ASM(op, x, n) ({ unsigned int __res; __asm__(op " %1,%0":"=r" (__res):"i" (n), "0" (x)); __res; })
22
#define SHA_ROL(x,n) SHA_ASM("rol", x, n)
23
#define SHA_ROR(x,n) SHA_ASM("ror", x, n)
17
-#define SMALL_REGISTER_SET
24
25
#else
26
@@ -24,9 +30,6 @@
30
31
#endif
32
27
-/* This "rolls" over the 512-bit array */
28
-#define W(x) (array[(x)&15])
29
-
33
/*
34
* If you have 32 registers or more, the compiler can (and should)
35
* try to change the array[] accesses into registers. However, on
@@ -43,13 +46,23 @@
46
* Ben Herrenschmidt reports that on PPC, the C version comes close
47
* to the optimized asm with this (ie on PPC you don't want that
48
* 'volatile', since there are lots of registers).
49
+ *
50
+ * On ARM we get the best code generation by forcing a full memory barrier
51
+ * between each SHA_ROUND, otherwise gcc happily get wild with spilling and
52
+ * the stack frame size simply explode and performance goes down the drain.
53
*/
47
-#ifdef SMALL_REGISTER_SET
54
+
55
+#if defined(__i386__) || defined(__x86_64__)
56
#define setW(x, val) (*(volatile unsigned int *)&W(x) = (val))
57
+#elif defined(__arm__)
58
+ #define setW(x, val) do { W(x) = (val); __asm__("":::"memory"); } while (0)
59
#else
60
#define setW(x, val) (W(x) = (val))
61
#endif
62
63
+/* This "rolls" over the 512-bit array */
64
+#define W(x) (array[(x)&15])
65
+
66
/*
67
* Where do we get the source from? The first 16 iterations get it from
68
* the input data, the next mix it from the 512-bit array.