Date: Thu, 24 Mar 2005 20:45:53 +1100 (EST) From: Bruce Evans <bde@zeta.org.au> To: Vinod Kashyap <vkashyap@amcc.com> Cc: freebsd-amd64@freebsd.org Subject: Re: undefined reference to `memset' Message-ID: <20050324194817.N97600@delplex.bde.org> In-Reply-To: <20050324182524.J97436@delplex.bde.org> References: <IDTR9T00.LMF@hadar.amcc.com> <20050324182524.J97436@delplex.bde.org>
next in thread | previous in thread | raw e-mail | index | archive | help
On Thu, 24 Mar 2005, Bruce Evans wrote: > On Wed, 23 Mar 2005, Vinod Kashyap wrote: > >> If any kernel module has the following, or a similar line in it: >> ----- >> char x[100] = {0}; >> ----- >> building of the GENERIC kernel on FreeBSD 5 -STABLE for amd64 >> as of 03/19/05, fails with the following message at the time of linking: >> "undefined reference to `memset'". >> ... > ... >> Anyone knows what's happening? > > gcc is expecting that memset() is in the library, but the FreeBSD kernel > is freestanding and happens not to have memset() in its library. As to why gcc calls memset() on amd64's but not on i386's: - gcc-3.3.3 doesn't call memset() on amd64's either. - gcc-3.4.2 on amd64's calls memset() starting with an array size of 65. It uses mov[qlwb] for sizes up to 16, then stos[qlwb] up to size 64. gcc-3.3.3 on i386's uses mov[lwb] for sizes up to 8, then stos[lwb] for all larger sizes. - the relevant change seems to be: % Index: i386.c % =================================================================== % RCS file: /home/ncvs/src/contrib/gcc/config/i386/i386.c,v % retrieving revision 1.20 % retrieving revision 1.21 % diff -u -2 -r1.20 -r1.21 % --- i386.c 19 Jun 2004 20:40:00 -0000 1.20 % +++ i386.c 28 Jul 2004 04:47:35 -0000 1.21 % @@ -437,26 +502,36 @@ % ... % +const int x86_rep_movl_optimal = m_386 | m_PENT | m_PPRO | m_K6; % ... Note that rep_movl is considered optimal on i386's but not on amd64's. % @@ -10701,6 +11427,10 @@ % /* In case we don't know anything about the alignment, default to % library version, since it is usually equally fast and result in % - shorter code. */ % - if (!TARGET_INLINE_ALL_STRINGOPS && align < UNITS_PER_WORD) % + shorter code. % + % + Also emit call when we know that the count is large and call overhead % + will not be important. */ % + if (!TARGET_INLINE_ALL_STRINGOPS % + && (align < UNITS_PER_WORD || !TARGET_REP_MOVL_OPTIMAL)) % return 0; % TARGET_REP_MOVL_OPTIMAL is x86_rep_movl_optimal modulo a mask. It is zero for amd64's, so 0 is returned for amd64's here unless you use -mfoo to set TARGET_INLINE_ALL_STRINGOPS. Returning 0 gives the library call instead of a stringop. This is in i386_expand_clrstr(). There is an identical change in i386_expand_movstr() that gives library calls to memcpy() for (at least) copying structs. Bruce
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20050324194817.N97600>