From ec9ec8af6a59cc0a946fe59778169f9909f215fc Mon Sep 17 00:00:00 2001 From: "David E. O'Brien" Date: Tue, 4 Jun 2002 18:04:27 +0000 Subject: 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 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 --- contrib/gcc/builtins.c | 7 +++++++ 1 file changed, 7 insertions(+) (limited to 'contrib/gcc') diff --git a/contrib/gcc/builtins.c b/contrib/gcc/builtins.c index 7eb878f70386..22e66b6676f9 100644 --- a/contrib/gcc/builtins.c +++ b/contrib/gcc/builtins.c @@ -19,6 +19,8 @@ along with GCC; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +/* $FreeBSD$ */ + #include "config.h" #include "system.h" #include "machmode.h" @@ -2194,6 +2196,11 @@ expand_builtin_memset (exp, target, mode) len_rtx = expand_expr (len, NULL_RTX, VOIDmode, 0); + /* Give up for non-constant lengths. They are broken on at least + i386's. */ + if (GET_CODE (len_rtx) != CONST_INT) + return 0; + dest_mem = get_memory_rtx (dest); set_mem_align (dest_mem, dest_align); dest_addr = clear_storage (dest_mem, len_rtx); -- cgit v1.2.3