__aeabi_uldivmod undefined for sound/soc/codecs/snd-soc-wm8974.ko, snd-soc-wm8940.ko and snd-soc-wm8510.ko

2011-04-25 Thread Barry Song
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


Re: __aeabi_uldivmod undefined for sound/soc/codecs/snd-soc-wm8974.ko, snd-soc-wm8940.ko and snd-soc-wm8510.ko

2011-04-25 Thread Michael Hope
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 & 0x;

/* 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).

-- 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


Re: __aeabi_uldivmod undefined for sound/soc/codecs/snd-soc-wm8974.ko, snd-soc-wm8940.ko and snd-soc-wm8510.ko

2011-04-25 Thread Barry Song
Hi Michael,

2011/4/26 Michael Hope :
> 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 & 0x;
>
>        /* 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


Re: __aeabi_uldivmod undefined for sound/soc/codecs/snd-soc-wm8974.ko, snd-soc-wm8940.ko and snd-soc-wm8510.ko

2011-04-25 Thread Barry Song
2011/4/26 Barry Song <21cn...@gmail.com>:
> Hi Michael,
>
> 2011/4/26 Michael Hope :
>> 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 & 0x;
>>
>>        /* 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);

>>
>> -- 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


Re: __aeabi_uldivmod undefined for sound/soc/codecs/snd-soc-wm8974.ko, snd-soc-wm8940.ko and snd-soc-wm8510.ko

2011-04-25 Thread Michael Hope
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 :
>> 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 & 0x;
>>
>>        /* 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


Re: __aeabi_uldivmod undefined for sound/soc/codecs/snd-soc-wm8974.ko, snd-soc-wm8940.ko and snd-soc-wm8510.ko

2011-04-25 Thread Nicolas Pitre
On Tue, 26 Apr 2011, Michael Hope wrote:

> 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 & 0x;
> 
> /* 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).

The kernel is omitting this function on purpose.  The idea is to prevent 
people from ever using 64-bit by 64-bit divisions since they are always 
costly and avoidable.

This is why the kernel provides a do_div() macro: to allow for 64-bit 
dividend by only 32-bit divisors. And this stems from the fact that gcc 
has no (or used not to have) patterns to match a division with a 64-bit 
dividend and a 32-bit divisor, hence it promotes the divisor to a 64-bit 
value and perform the costly division that the kernel wants to avoid.

Worse, gcc isn't smart enough to optimize the operation even when the 
divisor is constant, which is quite a common operation in the kernel.  
This is why many years ago I wrote the code for the do_div() version you 
can find in arch/arm/include/asm/div64.h where the division is turned 
into a reciprocal multiplication. For example, despite the amount of 
added C code, do_div(x, 1) now produces the following assembly code 
(where x is assigned to r0-r1):

adr r4, .L0
ldmia   r4, {r4-r5}
umull   r2, r3, r4, r0
mov r2, #0
umlal   r3, r2, r5, r0
umlal   r3, r2, r4, r1
mov r3, #0
umlal   r2, r3, r5, r1
mov r0, r2, lsr #11
orr r0, r0, r3, lsl #21
mov r1, r3, lsr #11
...
.L0:
.word   948328779
.word   879609302

But I digress.  This is just to say that gcc shouldn't pull 
__aeabi_uldivmod in this case because:

1) the division and the modulus are not performed on the same operands;

2) the modulus is performed on a 32-bit variable;

3) the do_div() implementation looks like nothing that gcc could 
   recognize as being a division.

Therefore I don't see how the right pattern could have been matched.


Nicolas

___
linaro-toolchain mailing list
linaro-toolchain@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-toolchain


Re: __aeabi_uldivmod undefined for sound/soc/codecs/snd-soc-wm8974.ko, snd-soc-wm8940.ko and snd-soc-wm8510.ko

2011-04-25 Thread Nicolas Pitre
On Tue, 26 Apr 2011, Michael Hope wrote:

> Yip, so the compiler spots these two lines:
>  Ndiv = target / source;
>  Nmod = target % source;
> 
> and turns them into
>   Ndiv, Nmod = __aeabi_uldivmod(target, source)

Why would gcc do that?  All four variables involved here are of type 
unsigned int, no unsigned long long.  Seems to me that __aeabi_uidivmod 
should have been used here instead.


Nicolas

___
linaro-toolchain mailing list
linaro-toolchain@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-toolchain