Yip, so the compiler spots these two lines: Ndiv = target / source; Nmod = target % source;
and turns them into Ndiv, Nmod = __aeabi_uldivmod(target, source) Depending on the policy of the kernel developers, you should either implement __aeabi_uldivmod in lib1funcs.asm or use another kernel construct to prevent the optimisation from happening. Googling around brought up this thread: http://comments.gmane.org/gmane.linux.kernel/965262 -- Michael On Tue, Apr 26, 2011 at 1:42 PM, Barry Song <21cn...@gmail.com> wrote: > 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. > > >> >> -- Michael >> >> On Tue, Apr 26, 2011 at 12:45 AM, Barry Song <21cn...@gmail.com> wrote: >>> Hi All, >>> I am using 2011.3 4.5 linaro GCC(armv7-a vfpv3d16) to compile kernel >>> and modules. I select to compile all codecs as modules: >>> "config SND_SOC_ALL_CODECS >>> tristate "Build all ASoC CODEC drivers" >>> " >>> as M and I2C/SPI too. >>> >>> Then in the kernel dir, run "make" to get both vmlinux and modules, I >>> found snd-soc-wm8974.ko, snd-soc-wm8940.ko and snd-soc-wm8510.ko will >>> fail due to "__aeabi_uldivmod undefined". >>> >>> If i comment do_div() in these codec drivers, this issue will >>> disappear. But it is strange there are many codecs which use do_div() >>> too, for example: >>> sound/soc/codecs/max98088.c >>> sound/soc/codecs/max9850.c >>> sound/soc/codecs/wm8350.c >>> sound/soc/codecs/wm8400.c >>> sound/soc/codecs/wm8510.c >>> sound/soc/codecs/wm8580.c >>> sound/soc/codecs/wm8753.c >>> sound/soc/codecs/wm8804.c >>> sound/soc/codecs/wm8900.c >>> sound/soc/codecs/wm8904.c >>> sound/soc/codecs/wm8940.c >>> sound/soc/codecs/wm8955.c >>> sound/soc/codecs/wm8960.c >>> sound/soc/codecs/wm8974.c >>> sound/soc/codecs/wm8978.c >>> sound/soc/codecs/wm8985.c >>> sound/soc/codecs/wm8990.c >>> sound/soc/codecs/wm8991.c >>> sound/soc/codecs/wm8993.c >>> sound/soc/codecs/wm8994.c >>> sound/soc/codecs/wm8995.c >>> sound/soc/codecs/wm9081.c >>> >>> but others can pass the compiling except those 3 modules. Is it due to >>> a wrong optimization by gcc? >>> >>> Other information: >>> 1. old tool-chains we are using can pass the compiling of the 3 modules. >>> 2. If i built all codecs into kernel image, these 3 drivers don't >>> report error while compiling. >>> >>> Thanks >>> Barry >>> >>> _______________________________________________ >>> linaro-toolchain mailing list >>> linaro-toolchain@lists.linaro.org >>> http://lists.linaro.org/mailman/listinfo/linaro-toolchain >>> >> > _______________________________________________ linaro-toolchain mailing list linaro-toolchain@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-toolchain