diff options
author | David E. O'Brien <obrien@FreeBSD.org> | 2002-06-04 18:04:27 +0000 |
---|---|---|
committer | David E. O'Brien <obrien@FreeBSD.org> | 2002-06-04 18:04:27 +0000 |
commit | ec9ec8af6a59cc0a946fe59778169f9909f215fc (patch) | |
tree | a9cccfa427db33d82ac3a56d0b13f6eb1c452660 /contrib/gcc/config/i386/libgcc-x86_64-glibc.ver | |
parent | 20120272f2cd9311f0cbab7d0230532c980e7a7e (diff) |
Gcc 3.1 (-O) now generates broken inline code for memset in some cases.
This broke newfs (newfs left some garbage in a bitmap).
The ASM for:
#include <string.h>
int x, foo[100];
main()
{
memset(&foo[0], 0, x);
}
is (at least if you have fixed function alignment):
.file "z.c"
.text
.p2align 2,,3
.globl main
.type main,@function
main:
pushl %ebp
movl %esp, %ebp
pushl %edi
pushl %eax
movl x, %ecx
xorl %eax, %eax
shrl $2, %ecx
movl $foo, %edi
cld
rep
stosl
andl $-16, %esp
<-- the lower bits of `len' should be loaded
near here
testl $2, %edi <-- this seems to be meant to test the 2^1
bit in `len' (not alignment of the pointer
like it actually does). %edi is the wrong
register for holding the bits, since it is
still needed for the pointer.
je .L2
stosw
.L2:
testl $1, %edi <-- similarly for the 2^0 bit.
je .L3
stosb
.L3:
movl -4(%ebp), %edi
leave
ret
.Lfe1:
.size main,.Lfe1-main
.comm foo,400,32
.comm x,4,4
.ident "GCC: (GNU) 3.1 [FreeBSD] 20020509 (prerelease)"
This seems to only result in (len % 3) bytes not being cleared, since gcc
doesn't seem to use the builtin memset unless it knows that the pointer is
aligned. If %edi could be misaligned, then too many bytes would be set.
Submitted by: BDE
Notes
Notes:
svn path=/head/; revision=97826
Diffstat (limited to 'contrib/gcc/config/i386/libgcc-x86_64-glibc.ver')
0 files changed, 0 insertions, 0 deletions