about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRich Felker <dalias@aerifal.cx>2011-06-12 10:53:42 -0400
committerRich Felker <dalias@aerifal.cx>2011-06-12 10:53:42 -0400
commit2afebbbcd16e8bfc5e008a40b2faf3bd8cf14e88 (patch)
tree5a46fc61e2e4d8138ae41ead4b5377370eca9872
parent382584724308442f03f3d29f7fc6de9e9d140982 (diff)
downloadmusl-2afebbbcd16e8bfc5e008a40b2faf3bd8cf14e88.tar.gz
musl-2afebbbcd16e8bfc5e008a40b2faf3bd8cf14e88.tar.xz
musl-2afebbbcd16e8bfc5e008a40b2faf3bd8cf14e88.zip
malloc: cast size down to int in bin_index functions
even if size_t was 32-bit already, the fact that the value was
unsigned and that gcc is too stupid to figure out it would be positive
as a signed quantity (due to the immediately-prior arithmetic and
conditionals) results in gcc compiling the integer-to-float conversion
as zero extension to 64 bits followed by an "fildll" (64 bit)
instruction rather than a simple "fildl" (32 bit) instruction on x86.
reportedly fildll is very slow on certain p4-class machines; even if
not, the new code is slightly smaller.
-rw-r--r--src/malloc/malloc.c4
1 files changed, 2 insertions, 2 deletions
diff --git a/src/malloc/malloc.c b/src/malloc/malloc.c
index 1a1a51f4..207b6ef2 100644
--- a/src/malloc/malloc.c
+++ b/src/malloc/malloc.c
@@ -120,14 +120,14 @@ static int bin_index(size_t x)
 	x = x / SIZE_ALIGN - 1;
 	if (x <= 32) return x;
 	if (x > 0x1c00) return 63;
-	return ((union { float v; uint32_t r; }){ x }.r>>21) - 496;
+	return ((union { float v; uint32_t r; }){(int)x}.r>>21) - 496;
 }
 
 static int bin_index_up(size_t x)
 {
 	x = x / SIZE_ALIGN - 1;
 	if (x <= 32) return x;
-	return ((union { float v; uint32_t r; }){ x }.r+0x1fffff>>21) - 496;
+	return ((union { float v; uint32_t r; }){(int)x}.r+0x1fffff>>21) - 496;
 }
 
 #if 0