2011/4/27 Michael Hope <michael.h...@linaro.org>: > On Tue, Apr 26, 2011 at 1:48 PM, Barry Song <21cn...@gmail.com> wrote: >> 2011/4/26 Barry Song <21cn...@gmail.com>: >>> Hi Michael, >>> >>> 2011/4/26 Michael Hope <michael.h...@linaro.org>: >>>> Hi Barry. I think the toolchain is operating correctly here. The >>>> current version recognises a divide followed by a modulo and optimises >>>> this into a call to the standard EABI function __aeabi__uldivmod(). >>>> Note the code: >>>> >>>> do_div(Kpart, source); >>>> >>>> K = Kpart & 0xFFFFFFFF; >>>> >>>> /* Check if we need to round */ >>>> if ((K % 10) >= 5) >>>> K += 5; >>>> >>>> This function is provided by libgcc for normal applications. The >>>> kernel provides it's own versions in arch/arm/lib/lib1funcs.s but is >>>> missing __aeabi_uldivmod (note the 'l' for 64 bit). >>> In fact the problem happen ealier: >>> >>> if (Ndiv < 6) { >>> source /= 2; >>> pll_div->pre_div = 1; >>> Ndiv = target / source; >>> } else >>> pll_div->pre_div = 0; >>> >>> if ((Ndiv < 6) || (Ndiv > 12)) >>> printk(KERN_WARNING >>> "WM8974 N value %u outwith recommended range!\n", >>> Ndiv); >>> >>> pll_div->n = Ndiv; >>> Nmod = target % source; >>> Kpart = FIXED_PLL_SIZE * (long long)Nmod; >>> >>> do_div(Kpart, source); >>> >>> If commenting "source /= 2", the problem disappear. >>> >>> >> Or if adding one line before do_div, all will be ok. >> asm("" : "+r"(source)); >> do_div(Kpart, source); > > Hi Barry. I can reproduce the problem in Linaro GCC 4.5-2011.04 and > GCC 4.5.2. It does not exist in GCC 4.6.0. wm8974_set_dai_pll() > inlines the call to pll_factors() and leaves a .globl reference to > __aeabi_uldivmod in the code. This function is never called. > > Marking pll_factors() as __attribute__((noinline)) also works around > the problem. > > I've logged http://gcc.gnu.org/bugzilla/show_bug.cgi?id=48783 upstream > and recorded this as LP: #771551.
Thanks. I am totally thinking it is a gcc bug not an optimization feature. in fact, __aeabi_uldivmod is never called as seen by objdump. It only exists in symbol reference list. > > -- Michael > _______________________________________________ linaro-toolchain mailing list linaro-toolchain@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-toolchain