Skip to content

Commit

Permalink
xdiff: import new 32-bit version of count_masked_bytes()
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
René Scharfe authored and Junio C Hamano committed May 23, 2012
1 parent 7e356a9 commit 8072766
Showing 1 changed file with 5 additions and 13 deletions.
18 changes: 5 additions & 13 deletions xdiff/xutils.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}

Expand Down

0 comments on commit 8072766

Please sign in to comment.