aboutsummaryrefslogtreecommitdiff
path: root/xdiff
diff options
context:
space:
mode:
authorRené Scharfe <rene.scharfe@lsrfire.ath.cx>2012-05-22 22:36:57 +0200
committerJunio C Hamano <gitster@pobox.com>2012-05-23 09:10:17 -0700
commit8072766cc6756e9218ea7c9433b097b696329407 (patch)
tree03da9315a3f6759bdd7df50163bc765013aca190 /xdiff
parent7e356a979459092d10450e66d8512381e89c2570 (diff)
downloadgit-8072766cc6756e9218ea7c9433b097b696329407.tar.gz
git-8072766cc6756e9218ea7c9433b097b696329407.tar.xz
xdiff: import new 32-bit version of count_masked_bytes()
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 <sunny@sunbase.org> Signed-off-by: Rene Scharfe <rene.scharfe@lsrfire.ath.cx> Signed-off-by: Junio C Hamano <gitster@pobox.com>
Diffstat (limited to 'xdiff')
-rw-r--r--xdiff/xutils.c18
1 files changed, 5 insertions, 13 deletions
diff --git a/xdiff/xutils.c b/xdiff/xutils.c
index 202111779..179bc4fe0 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;
}
}