From 9322ce21eeb4ad92d0cdd37d0d62a69368042fec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Scharfe?= Date: Tue, 22 May 2012 22:36:25 +0200 Subject: xdiff: avoid compiler warnings with XDL_FAST_HASH on 32-bit machines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Import macro REPEAT_BYTE from Linux (arch/x86/include/asm/word-at-a-time.h) to avoid 64-bit integer literals, which cause some 32-bit compilers to print warnings. Reported-by: Øyvind A. Holm Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano diff --git a/xdiff/xutils.c b/xdiff/xutils.c index 1b3b471..277ccdf 100644 --- a/xdiff/xutils.c +++ b/xdiff/xutils.c @@ -280,9 +280,11 @@ static unsigned long xdl_hash_record_with_whitespace(char const **data, #ifdef XDL_FAST_HASH -#define ONEBYTES 0x0101010101010101ul -#define NEWLINEBYTES 0x0a0a0a0a0a0a0a0aul -#define HIGHBITS 0x8080808080808080ul +#define REPEAT_BYTE(x) ((~0ul / 0xff) * (x)) + +#define ONEBYTES REPEAT_BYTE(0x01) +#define NEWLINEBYTES REPEAT_BYTE(0x0a) +#define HIGHBITS REPEAT_BYTE(0x80) /* Return the high bit set in the first byte that is a zero */ static inline unsigned long has_zero(unsigned long a) -- cgit v0.10.2-6-g49f6 From 7e356a979459092d10450e66d8512381e89c2570 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Scharfe?= Date: Tue, 22 May 2012 22:36:39 +0200 Subject: xdiff: avoid more compiler warnings with XDL_FAST_HASH on 32-bit machines MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Hide literals that can cause compiler warnings for 32-bit architectures in expressions that evaluate to small numbers there. Some compilers warn that 0x0001020304050608 won't fit into a 32-bit long, others that shifting right by 56 bits clears a 32-bit value completely. The correct values are calculated in the 64-bit case, which is all that matters in this if-branch. Reported-by: Øyvind A. Holm Signed-off-by: Rene Scharfe Acked-by: Thomas Rast Signed-off-by: Junio C Hamano diff --git a/xdiff/xutils.c b/xdiff/xutils.c index 277ccdf..2021117 100644 --- a/xdiff/xutils.c +++ b/xdiff/xutils.c @@ -301,7 +301,13 @@ static inline long count_masked_bytes(unsigned long mask) * that works for the bytemasks without having to * mask them first. */ - return mask * 0x0001020304050608 >> 56; + /* + * return mask * 0x0001020304050608 >> 56; + * + * Doing it like this avoids warnings on 32-bit machines. + */ + long a = (REPEAT_BYTE(0x01) / 0xff + 1); + return mask * a >> (sizeof(long) * 7); } else { /* * Modified Carl Chatfield G+ version for 32-bit * -- cgit v0.10.2-6-g49f6 From 8072766cc6756e9218ea7c9433b097b696329407 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ren=C3=A9=20Scharfe?= Date: Tue, 22 May 2012 22:36:57 +0200 Subject: xdiff: import new 32-bit version of count_masked_bytes() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Import the latest 32-bit implementation of count_masked_bytes() from Linux (arch/x86/include/asm/word-at-a-time.h). It's shorter and avoids overflows and negative numbers. This fixes test failures on 32-bit, where negative partial results had been shifted right using the "wrong" method (logical shift right instead of arithmetic short right). The compiler is free to chose the method, so it was only wrong in the sense that it didn't work as intended by us. Reported-by: Øyvind A. Holm Signed-off-by: Rene Scharfe Signed-off-by: Junio C Hamano diff --git a/xdiff/xutils.c b/xdiff/xutils.c index 2021117..179bc4f 100644 --- a/xdiff/xutils.c +++ b/xdiff/xutils.c @@ -309,19 +309,11 @@ static inline long count_masked_bytes(unsigned long mask) long a = (REPEAT_BYTE(0x01) / 0xff + 1); return mask * a >> (sizeof(long) * 7); } else { - /* - * Modified Carl Chatfield G+ version for 32-bit * - * - * (a) gives us - * -1 (0, ff), 0 (ffff) or 1 (ffffff) - * (b) gives us - * 0 for 0, 1 for (ff ffff ffffff) - * (a+b+1) gives us - * correct 0-3 bytemask count result - */ - long a = (mask - 256) >> 23; - long b = mask & 1; - return a + b + 1; + /* Carl Chatfield / Jan Achrenius G+ version for 32-bit */ + /* (000000 0000ff 00ffff ffffff) -> ( 1 1 2 3 ) */ + long a = (0x0ff0001 + mask) >> 23; + /* Fix the 1 for 00 case */ + return a & mask; } } -- cgit v0.10.2-6-g49f6