public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
* How can I link the kernel with libgcc ?
@ 2006-03-10  1:44 Carlos Munoz
  2006-03-10  1:45 ` Valdis.Kletnieks
  2006-03-10  2:02 ` Lee Revell
  0 siblings, 2 replies; 20+ messages in thread
From: Carlos Munoz @ 2006-03-10  1:44 UTC (permalink / raw)
  To: linux-kernel

Hi all,

I'm writing an audio driver and the hardware requires floating point 
arithmetic.  When I build the kernel I get the following errors at link 
time:

*** Warning: "__subdf3" [sound/sh/siu_sh7343.ko] undefined!
*** Warning: "__muldf3" [sound/sh/siu_sh7343.ko] undefined!
*** Warning: "__divdf3" [sound/sh/siu_sh7343.ko] undefined!
*** Warning: "__adddf3" [sound/sh/siu_sh7343.ko] undefined!

These symbols are coming from gcc. What I would like to do is link the 
kernel with libgcc to solve this errors. I'm looking at the kernel 
makefiles and it doesn't seem obvious to me how to do it. Does anyone 
know how I can link the kernel with libgcc, or point me in the right 
direction ?

By the way this is for the Renesas SH7343 processor.

Thanks,


Carlos Munoz

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: How can I link the kernel with libgcc ?
  2006-03-10  1:44 How can I link the kernel with libgcc ? Carlos Munoz
@ 2006-03-10  1:45 ` Valdis.Kletnieks
  2006-03-10  2:06   ` Lee Revell
  2006-03-10  2:02 ` Lee Revell
  1 sibling, 1 reply; 20+ messages in thread
From: Valdis.Kletnieks @ 2006-03-10  1:45 UTC (permalink / raw)
  To: Carlos Munoz; +Cc: linux-kernel

[-- Attachment #1: Type: text/plain, Size: 1112 bytes --]

On Thu, 09 Mar 2006 17:44:16 PST, Carlos Munoz said:
> I'm writing an audio driver and the hardware requires floating point 
> arithmetic.  When I build the kernel I get the following errors at link 
> time:

Tough break, that.  You sure you can't figure a way to either push the
floating point out to userspace, or do funky fixed-point math instead?

> These symbols are coming from gcc. What I would like to do is link the 
> kernel with libgcc to solve this errors. I'm looking at the kernel 
> makefiles and it doesn't seem obvious to me how to do it.

You can't find it because you can't do it.  It isn't as simple as linking
against libgcc - there's lots of other issues that make floating point
in the kernel Really Really Hard (for starters, it means you need to save
and restore the FP state across interrupts and scheduling within the kernel).

>                                                            Does anyone
> know how I can link the kernel with libgcc, or point me in the right 
> direction ?

The right direction - either push it to userspace, or find a way to do it
with fixed point math.

[-- Attachment #2: Type: application/pgp-signature, Size: 228 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: How can I link the kernel with libgcc ?
  2006-03-10  1:44 How can I link the kernel with libgcc ? Carlos Munoz
  2006-03-10  1:45 ` Valdis.Kletnieks
@ 2006-03-10  2:02 ` Lee Revell
  1 sibling, 0 replies; 20+ messages in thread
From: Lee Revell @ 2006-03-10  2:02 UTC (permalink / raw)
  To: Carlos Munoz; +Cc: linux-kernel

On Thu, 2006-03-09 at 17:44 -0800, Carlos Munoz wrote:
> Hi all,
> 
> I'm writing an audio driver

This is a better question for the alsa-devel and possibly linux-sh lists
than linux-kernel.

Lee


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: How can I link the kernel with libgcc ?
  2006-03-10  1:45 ` Valdis.Kletnieks
@ 2006-03-10  2:06   ` Lee Revell
  2006-03-10  3:01     ` Carlos Munoz
  0 siblings, 1 reply; 20+ messages in thread
From: Lee Revell @ 2006-03-10  2:06 UTC (permalink / raw)
  To: Valdis.Kletnieks; +Cc: Carlos Munoz, linux-kernel

On Thu, 2006-03-09 at 20:45 -0500, Valdis.Kletnieks@vt.edu wrote:
> On Thu, 09 Mar 2006 17:44:16 PST, Carlos Munoz said:
> > I'm writing an audio driver and the hardware requires floating point 
> > arithmetic.  When I build the kernel I get the following errors at link 
> > time:
> 
> Tough break, that.  You sure you can't figure a way to either push the
> floating point out to userspace

Audio drivers should never have to directly manipulate the samples -
they just manage the DMA buffers and interrupts and wake up the process
at the right time.  Mixing, routing, volume control, DSP go in
userspace.

Lee


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: How can I link the kernel with libgcc ?
       [not found] <5OEVB-3GX-15@gated-at.bofh.it>
@ 2006-03-10  2:32 ` Robert Hancock
  0 siblings, 0 replies; 20+ messages in thread
From: Robert Hancock @ 2006-03-10  2:32 UTC (permalink / raw)
  To: Carlos Munoz, linux-kernel

Carlos Munoz wrote:
> Hi all,
> 
> I'm writing an audio driver and the hardware requires floating point 
> arithmetic.  When I build the kernel I get the following errors at link 
> time:

Floating point + kernel = no no. If the hardware requires floating point 
manipulations this should go in userspace.

> These symbols are coming from gcc. What I would like to do is link the 
> kernel with libgcc to solve this errors. I'm looking at the kernel 
> makefiles and it doesn't seem obvious to me how to do it. Does anyone 
> know how I can link the kernel with libgcc, or point me in the right 
> direction ?

This is almost certainly a bad idea. The functions inside libgcc are not 
designed to run inside a kernel.

-- 
Robert Hancock      Saskatoon, SK, Canada
To email, remove "nospam" from hancockr@nospamshaw.ca
Home Page: http://www.roberthancock.com/


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: How can I link the kernel with libgcc ?
  2006-03-10  2:06   ` Lee Revell
@ 2006-03-10  3:01     ` Carlos Munoz
  2006-03-10  3:22       ` Lee Revell
                         ` (2 more replies)
  0 siblings, 3 replies; 20+ messages in thread
From: Carlos Munoz @ 2006-03-10  3:01 UTC (permalink / raw)
  To: Lee Revell; +Cc: Valdis.Kletnieks, linux-kernel

Lee Revell wrote:

>On Thu, 2006-03-09 at 20:45 -0500, Valdis.Kletnieks@vt.edu wrote:
>  
>
>>On Thu, 09 Mar 2006 17:44:16 PST, Carlos Munoz said:
>>    
>>
>>>I'm writing an audio driver and the hardware requires floating point 
>>>arithmetic.  When I build the kernel I get the following errors at link 
>>>time:
>>>      
>>>
>>Tough break, that.  You sure you can't figure a way to either push the
>>floating point out to userspace
>>    
>>
>
>Audio drivers should never have to directly manipulate the samples -
>they just manage the DMA buffers and interrupts and wake up the process
>at the right time.  Mixing, routing, volume control, DSP go in
>userspace.
>
>Lee
>
>  
>
Hi Lee,

Unfortunately, the driver needs to populate several coefficient tables 
for the hardware to perform silence suppression and other advance 
features. The values for these tables are calculated using log10 
operations. I don't  see a clean way to push these operations to user 
space without the need for custom applications that build the tables and 
pass them to the driver.

Thanks,


Carlos Munoz

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: How can I link the kernel with libgcc ?
  2006-03-10  3:01     ` Carlos Munoz
@ 2006-03-10  3:22       ` Lee Revell
  2006-03-10  3:25       ` Carlos Munoz
  2006-03-10  8:01       ` Arjan van de Ven
  2 siblings, 0 replies; 20+ messages in thread
From: Lee Revell @ 2006-03-10  3:22 UTC (permalink / raw)
  To: Carlos Munoz; +Cc: Valdis.Kletnieks, linux-kernel, alsa-devel

(added alsa-devel to cc:)

On Thu, 2006-03-09 at 19:01 -0800, Carlos Munoz wrote:
> >Audio drivers should never have to directly manipulate the samples -
> >they just manage the DMA buffers and interrupts and wake up the process
> >at the right time.  Mixing, routing, volume control, DSP go in
> >userspace.
>
> Unfortunately, the driver needs to populate several coefficient tables 
> for the hardware to perform silence suppression and other advance 
> features. The values for these tables are calculated using log10 
> operations. I don't  see a clean way to push these operations to user 
> space without the need for custom applications that build the tables and 
> pass them to the driver.

Unless you can do it with fixed point math, or use a static table, you
might have to do just that, with a sysfs interface.  For example the
emu10k1 driver uses an ioctl interface to upload code to the built in
(floating point) DSP.  But new ioctls are frowned upon...

Lee


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: How can I link the kernel with libgcc ?
  2006-03-10  3:01     ` Carlos Munoz
  2006-03-10  3:22       ` Lee Revell
@ 2006-03-10  3:25       ` Carlos Munoz
  2006-03-10  3:25         ` Lee Revell
  2006-03-10 10:18         ` Jes Sorensen
  2006-03-10  8:01       ` Arjan van de Ven
  2 siblings, 2 replies; 20+ messages in thread
From: Carlos Munoz @ 2006-03-10  3:25 UTC (permalink / raw)
  To: Lee Revell, Valdis.Kletnieks; +Cc: Carlos Munoz, linux-kernel

Carlos Munoz wrote:

> Lee Revell wrote:
>
>> On Thu, 2006-03-09 at 20:45 -0500, Valdis.Kletnieks@vt.edu wrote:
>>  
>>
>>> On Thu, 09 Mar 2006 17:44:16 PST, Carlos Munoz said:
>>>   
>>>
>>>> I'm writing an audio driver and the hardware requires floating 
>>>> point arithmetic.  When I build the kernel I get the following 
>>>> errors at link time:
>>>>     
>>>
>>> Tough break, that.  You sure you can't figure a way to either push the
>>> floating point out to userspace
>>>   
>>
>>
>> Audio drivers should never have to directly manipulate the samples -
>> they just manage the DMA buffers and interrupts and wake up the process
>> at the right time.  Mixing, routing, volume control, DSP go in
>> userspace.
>>
>> Lee
>>
>>  
>>
> Hi Lee,
>
> Unfortunately, the driver needs to populate several coefficient tables 
> for the hardware to perform silence suppression and other advance 
> features. The values for these tables are calculated using log10 
> operations. I don't  see a clean way to push these operations to user 
> space without the need for custom applications that build the tables 
> and pass them to the driver.
>
> Thanks,
>
>
> Carlos Munoz
>
Anyway,

I figured out how to get the driver to use floating point operations. I 
included source code (from an open source math library) for the log10 
function in the driver. Then I added the following lines to the file 
arch/sh/kernel/sh_ksyms.c:

DECLARE_EXPORT(__subdf3);
DECLARE_EXPORT(__muldf3);
DECLARE_EXPORT(__divdf3);
DECLARE_EXPORT(__adddf3);
DECLARE_EXPORT(__floatsidf);
DECLARE_EXPORT(__eqdf2);
DECLARE_EXPORT(__fixdfsi);

Everything works now.

Thanks,


Carlos Munoz

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: How can I link the kernel with libgcc ?
  2006-03-10  3:25       ` Carlos Munoz
@ 2006-03-10  3:25         ` Lee Revell
  2006-03-10  3:47           ` Carlos Munoz
  2006-03-10 10:18         ` Jes Sorensen
  1 sibling, 1 reply; 20+ messages in thread
From: Lee Revell @ 2006-03-10  3:25 UTC (permalink / raw)
  To: Carlos Munoz; +Cc: Valdis.Kletnieks, linux-kernel, alsa-devel

On Thu, 2006-03-09 at 19:25 -0800, Carlos Munoz wrote:
> I figured out how to get the driver to use floating point operations.
> I included source code (from an open source math library) for the
> log10 function in the driver. Then I added the following lines to the
> file arch/sh/kernel/sh_ksyms.c: 

Where is the source code to your driver?

Lee


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: How can I link the kernel with libgcc ?
  2006-03-10  3:25         ` Lee Revell
@ 2006-03-10  3:47           ` Carlos Munoz
  2006-03-10 10:37             ` Denis Vlasenko
  0 siblings, 1 reply; 20+ messages in thread
From: Carlos Munoz @ 2006-03-10  3:47 UTC (permalink / raw)
  To: Lee Revell; +Cc: Valdis.Kletnieks, linux-kernel, alsa-devel

[-- Attachment #1: Type: text/plain, Size: 879 bytes --]

Lee Revell wrote:

>On Thu, 2006-03-09 at 19:25 -0800, Carlos Munoz wrote:
>  
>
>>I figured out how to get the driver to use floating point operations.
>>I included source code (from an open source math library) for the
>>log10 function in the driver. Then I added the following lines to the
>>file arch/sh/kernel/sh_ksyms.c: 
>>    
>>
>
>Where is the source code to your driver?
>
>Lee
>
>  
>
Hi Lee,

Be warned. This driver is in the early stages of development. There is 
still a lot of work that needs to be done (interrupt, dma, etc, etc).

You can untar it in the linux/sound directory (it will overwrite the 
Kconfig and Makefile) and it will build (you will need to modify the 
arch/....../kernel/ksyms.c to resolve the undefined symbols, see my 
previous email). It won't do anything useful yet. Please let me know if 
you have any questions.

Thanks,


Carlos Munoz

[-- Attachment #2: siu_sh7343.tar.gz --]
[-- Type: application/x-gzip, Size: 10936 bytes --]

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: How can I link the kernel with libgcc ?
  2006-03-10  3:01     ` Carlos Munoz
  2006-03-10  3:22       ` Lee Revell
  2006-03-10  3:25       ` Carlos Munoz
@ 2006-03-10  8:01       ` Arjan van de Ven
  2 siblings, 0 replies; 20+ messages in thread
From: Arjan van de Ven @ 2006-03-10  8:01 UTC (permalink / raw)
  To: Carlos Munoz; +Cc: Lee Revell, Valdis.Kletnieks, linux-kernel


> Unfortunately, the driver needs to populate several coefficient tables 
> for the hardware to perform silence suppression and other advance 
> features. The values for these tables are calculated using log10 
> operations. I don't  see a clean way to push these operations to user 
> space without the need for custom applications that build the tables and 
> pass them to the driver.


can you calculate these at build time instead and store it as a table in
the .c file ?


^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: How can I link the kernel with libgcc ?
  2006-03-10  3:25       ` Carlos Munoz
  2006-03-10  3:25         ` Lee Revell
@ 2006-03-10 10:18         ` Jes Sorensen
  2006-03-10 18:07           ` Carlos Munoz
  1 sibling, 1 reply; 20+ messages in thread
From: Jes Sorensen @ 2006-03-10 10:18 UTC (permalink / raw)
  To: Carlos Munoz; +Cc: Lee Revell, Valdis.Kletnieks, linux-kernel

>>>>> "Carlos" == Carlos Munoz <carlos@kenati.com> writes:

Carlos> I figured out how to get the driver to use floating point
Carlos> operations. I included source code (from an open source math
Carlos> library) for the log10 function in the driver. Then I added
Carlos> the following lines to the file arch/sh/kernel/sh_ksyms.c:

Bad bad bad!

You shouldn't be using floating point in the kernel at all! Most
architectures do not save the full floating point register set on
entry so if you start messing with the fp registers you may corrupt
user space applications.

You need to either write a customer user space app or use a table as
Arjan suggested.

Cheers,
Jes

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: How can I link the kernel with libgcc ?
  2006-03-10  3:47           ` Carlos Munoz
@ 2006-03-10 10:37             ` Denis Vlasenko
  2006-03-10 11:05               ` Bart Hartgers
  2006-03-10 18:03               ` Carlos Munoz
  0 siblings, 2 replies; 20+ messages in thread
From: Denis Vlasenko @ 2006-03-10 10:37 UTC (permalink / raw)
  To: Carlos Munoz; +Cc: Lee Revell, Valdis.Kletnieks, linux-kernel, alsa-devel

On Friday 10 March 2006 05:47, Carlos Munoz wrote:
> Lee Revell wrote:
> 
> >On Thu, 2006-03-09 at 19:25 -0800, Carlos Munoz wrote:
> >  
> >
> >>I figured out how to get the driver to use floating point operations.
> >>I included source code (from an open source math library) for the
> >>log10 function in the driver. Then I added the following lines to the
> >>file arch/sh/kernel/sh_ksyms.c: 
> >>    
> >>
> >
> >Where is the source code to your driver?
> >
> >Lee
> >
> >  
> >
> Hi Lee,
> 
> Be warned. This driver is in the early stages of development. There is 
> still a lot of work that needs to be done (interrupt, dma, etc, etc).

What? You are using log10 only twice!

        if (!(siu_obj_status & ST_OPEN)) {
		...
                /* = log2(over) */
                ydef[22] = (u_int32_t)(log10((double)(over & 0x0000003f)) /
                                       log10(2));
		...
        }
        else {
		...
                if (coef) {
                        ydef[16] = 0x03045000 | (over << 26) | (tap - 4);
                        ydef[17] = (tap * 2 + 1);
                        /* = log2(over) */
                        ydef[22] = (u_int32_t)
                                (log10((double)(over & 0x0000003f)) / log10(2));
                }

Don't you think that log10((double)(over & 0x0000003f)) / log10(2)
can have only 64 different values depending on the result of (over & 0x3f)?

Obtain them from precomputed uint32_t log10table[64].
--
vda

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: How can I link the kernel with libgcc ?
  2006-03-10 10:37             ` Denis Vlasenko
@ 2006-03-10 11:05               ` Bart Hartgers
  2006-03-10 18:03               ` Carlos Munoz
  1 sibling, 0 replies; 20+ messages in thread
From: Bart Hartgers @ 2006-03-10 11:05 UTC (permalink / raw)
  To: Carlos Munoz
  Cc: Denis Vlasenko, Lee Revell, Valdis.Kletnieks, linux-kernel,
	alsa-devel

Denis Vlasenko wrote:
> On Friday 10 March 2006 05:47, Carlos Munoz wrote:
>> Lee Revell wrote:
> 
> What? You are using log10 only twice!
> 
>         if (!(siu_obj_status & ST_OPEN)) {
> 		...
>                 /* = log2(over) */
>                 ydef[22] = (u_int32_t)(log10((double)(over & 0x0000003f)) /
>                                        log10(2));
> 		...
>         }
>         else {
> 		...
>                 if (coef) {
>                         ydef[16] = 0x03045000 | (over << 26) | (tap - 4);
>                         ydef[17] = (tap * 2 + 1);
>                         /* = log2(over) */
>                         ydef[22] = (u_int32_t)
>                                 (log10((double)(over & 0x0000003f)) / log10(2));
>                 }
> 
> Don't you think that log10((double)(over & 0x0000003f)) / log10(2)
> can have only 64 different values depending on the result of (over & 0x3f)?
> 
> Obtain them from precomputed uint32_t log10table[64].

And since you're actually trying to do log2 [log10(x)/log10(2) =
log2(x)] and casting the result to an integer, aren't you really looking
for the position of the highest 1 bit or something like that? That
doesn't need FP at all.

Groeten,
Bart

> --
> vda
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/


-- 
Bart Hartgers - TUE Eindhoven - http://plasimo.phys.tue.nl/bart/contact/

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: How can I link the kernel with libgcc ?
  2006-03-10 10:37             ` Denis Vlasenko
  2006-03-10 11:05               ` Bart Hartgers
@ 2006-03-10 18:03               ` Carlos Munoz
  2006-03-10 18:33                 ` linux-os (Dick Johnson)
  2006-03-10 19:18                 ` Al Viro
  1 sibling, 2 replies; 20+ messages in thread
From: Carlos Munoz @ 2006-03-10 18:03 UTC (permalink / raw)
  To: Denis Vlasenko; +Cc: Lee Revell, Valdis.Kletnieks, linux-kernel, alsa-devel

Denis Vlasenko wrote:

>On Friday 10 March 2006 05:47, Carlos Munoz wrote:
>  
>
>>Lee Revell wrote:
>>
>>    
>>
>>>On Thu, 2006-03-09 at 19:25 -0800, Carlos Munoz wrote:
>>> 
>>>
>>>      
>>>
>>>>I figured out how to get the driver to use floating point operations.
>>>>I included source code (from an open source math library) for the
>>>>log10 function in the driver. Then I added the following lines to the
>>>>file arch/sh/kernel/sh_ksyms.c: 
>>>>   
>>>>
>>>>        
>>>>
>>>Where is the source code to your driver?
>>>
>>>Lee
>>>
>>> 
>>>
>>>      
>>>
>>Hi Lee,
>>
>>Be warned. This driver is in the early stages of development. There is 
>>still a lot of work that needs to be done (interrupt, dma, etc, etc).
>>    
>>
>
>What? You are using log10 only twice!
>
>        if (!(siu_obj_status & ST_OPEN)) {
>		...
>                /* = log2(over) */
>                ydef[22] = (u_int32_t)(log10((double)(over & 0x0000003f)) /
>                                       log10(2));
>		...
>        }
>        else {
>		...
>                if (coef) {
>                        ydef[16] = 0x03045000 | (over << 26) | (tap - 4);
>                        ydef[17] = (tap * 2 + 1);
>                        /* = log2(over) */
>                        ydef[22] = (u_int32_t)
>                                (log10((double)(over & 0x0000003f)) / log10(2));
>                }
>
>Don't you think that log10((double)(over & 0x0000003f)) / log10(2)
>can have only 64 different values depending on the result of (over & 0x3f)?
>
>Obtain them from precomputed uint32_t log10table[64].
>--
>vda
>  
>
Hi Denis,

Yes, the driver code so far only uses log10 twice, but there will be 
more uses for it as I populate the rest of the tables. However, I think 
its use will be some what limited. I wasn't aware that the floating 
point registers are not saved. I'll investigate a way to create a table 
with pre-calculated log10 values.

Thanks,


Carlos

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: How can I link the kernel with libgcc ?
  2006-03-10 10:18         ` Jes Sorensen
@ 2006-03-10 18:07           ` Carlos Munoz
  0 siblings, 0 replies; 20+ messages in thread
From: Carlos Munoz @ 2006-03-10 18:07 UTC (permalink / raw)
  To: Jes Sorensen; +Cc: Lee Revell, Valdis.Kletnieks, linux-kernel

Jes Sorensen wrote:

>>>>>>"Carlos" == Carlos Munoz <carlos@kenati.com> writes:
>>>>>>            
>>>>>>
>
>Carlos> I figured out how to get the driver to use floating point
>Carlos> operations. I included source code (from an open source math
>Carlos> library) for the log10 function in the driver. Then I added
>Carlos> the following lines to the file arch/sh/kernel/sh_ksyms.c:
>
>Bad bad bad!
>
>You shouldn't be using floating point in the kernel at all! Most
>architectures do not save the full floating point register set on
>entry so if you start messing with the fp registers you may corrupt
>user space applications.
>
>You need to either write a customer user space app or use a table as
>Arjan suggested.
>E_OK
>Cheers,
>Jes
>  
>
Hi Jes,

I wasn't aware that floating point registers are not save. I guess I 
have no choice but to use a table.

Thanks,


Carlos Munoz

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: How can I link the kernel with libgcc ?
  2006-03-10 18:03               ` Carlos Munoz
@ 2006-03-10 18:33                 ` linux-os (Dick Johnson)
  2006-03-10 18:41                   ` Ben Slusky
  2006-03-10 19:18                 ` Al Viro
  1 sibling, 1 reply; 20+ messages in thread
From: linux-os (Dick Johnson) @ 2006-03-10 18:33 UTC (permalink / raw)
  To: Carlos Munoz
  Cc: Denis Vlasenko, Lee Revell, Valdis.Kletnieks, Linux kernel,
	alsa-devel


On Fri, 10 Mar 2006, Carlos Munoz wrote:

> Denis Vlasenko wrote:
>
>> On Friday 10 March 2006 05:47, Carlos Munoz wrote:
>>
>>
>>> Lee Revell wrote:
>>>
>>>
>>>
>>>> On Thu, 2006-03-09 at 19:25 -0800, Carlos Munoz wrote:
>>>>
>>>>
>>>>
>>>>
>>>>> I figured out how to get the driver to use floating point operations.
>>>>> I included source code (from an open source math library) for the
>>>>> log10 function in the driver. Then I added the following lines to the
>>>>> file arch/sh/kernel/sh_ksyms.c:
>>>>>
>>>>>
>>>>>
>>>>>
>>>> Where is the source code to your driver?
>>>>
>>>> Lee
>>>>
>>>>
>>>>
>>>>
>>>>
>>> Hi Lee,
>>>
>>> Be warned. This driver is in the early stages of development. There is
>>> still a lot of work that needs to be done (interrupt, dma, etc, etc).
>>>
>>>
>>
>> What? You are using log10 only twice!
>>
>>        if (!(siu_obj_status & ST_OPEN)) {
>> 		...
>>                /* = log2(over) */
>>                ydef[22] = (u_int32_t)(log10((double)(over & 0x0000003f)) /
>>                                       log10(2));
>> 		...
>>        }
>>        else {
>> 		...
>>                if (coef) {
>>                        ydef[16] = 0x03045000 | (over << 26) | (tap - 4);
>>                        ydef[17] = (tap * 2 + 1);
>>                        /* = log2(over) */
>>                        ydef[22] = (u_int32_t)
>>                                (log10((double)(over & 0x0000003f)) / log10(2));
>>                }
>>
>> Don't you think that log10((double)(over & 0x0000003f)) / log10(2)
>> can have only 64 different values depending on the result of (over & 0x3f)?
>>
>> Obtain them from precomputed uint32_t log10table[64].
>> --
>> vda
>>
>>
> Hi Denis,
>
> Yes, the driver code so far only uses log10 twice, but there will be
> more uses for it as I populate the rest of the tables. However, I think
> its use will be some what limited. I wasn't aware that the floating
> point registers are not saved. I'll investigate a way to create a table
> with pre-calculated log10 values.
>
> Thanks,
>
>
> Carlos

Since the log in base n is the log in any base times a constant,
you can probably use log base 2 (binary bit position) and multiply
the result by a constant, which may simply be shifts and adds.

I assume you are using 16-bit audio. If so, the dynamic range
is only 20 * log10(2^16) = 96.3 dB. That means that attenuation
from mininum to maximum, in 1 dB steps, requires only 94 values.

Your code shows something whacked off at 0x3f = 0->0x40 = 64
20 * log10(64) = 36 dB for only 36 values. Clearly, you don't
need floating point, just some thought ahead of time.

Cheers,
Dick Johnson
Penguin : Linux version 2.6.15.4 on an i686 machine (5589.54 BogoMips).
Warning : 98.36% of all statistics are fiction, book release in April.
_
\x1a\x04

****************************************************************
The information transmitted in this message is confidential and may be privileged.  Any review, retransmission, dissemination, or other use of this information by persons or entities other than the intended recipient is prohibited.  If you are not the intended recipient, please notify Analogic Corporation immediately - by replying to this message or by sending an email to DeliveryErrors@analogic.com - and destroy all copies of this information, including any attachments, without reading or disclosing them.

Thank you.

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: How can I link the kernel with libgcc ?
  2006-03-10 18:33                 ` linux-os (Dick Johnson)
@ 2006-03-10 18:41                   ` Ben Slusky
  0 siblings, 0 replies; 20+ messages in thread
From: Ben Slusky @ 2006-03-10 18:41 UTC (permalink / raw)
  To: linux-os (Dick Johnson)
  Cc: Carlos Munoz, Denis Vlasenko, Lee Revell, Valdis.Kletnieks,
	Linux kernel, alsa-devel

On Fri, 10 Mar 2006 13:33:02 -0500, linux-os (Dick Johnson) wrote:
> 
> On Fri, 10 Mar 2006, Carlos Munoz wrote:
> 
> > Denis Vlasenko wrote:
> >
> >> On Friday 10 March 2006 05:47, Carlos Munoz wrote:
> >>
> >>
> >>> Lee Revell wrote:
> >>>
> >>>
> >>>
> >>>> On Thu, 2006-03-09 at 19:25 -0800, Carlos Munoz wrote:
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>> I figured out how to get the driver to use floating point operations.
> >>>>> I included source code (from an open source math library) for the
> >>>>> log10 function in the driver. Then I added the following lines to the
> >>>>> file arch/sh/kernel/sh_ksyms.c:
> >>>>>
> >>>>>
> >>>>>
> >>>>>
> >>>> Where is the source code to your driver?
> >>>>
> >>>> Lee
> >>>>
> >>>>
> >>>>
> >>>>
> >>>>
> >>> Hi Lee,
> >>>
> >>> Be warned. This driver is in the early stages of development. There is
> >>> still a lot of work that needs to be done (interrupt, dma, etc, etc).
> >>>
> >>>
> >>
> >> What? You are using log10 only twice!
> >>
> >>        if (!(siu_obj_status & ST_OPEN)) {
> >> 		...
> >>                /* = log2(over) */
> >>                ydef[22] = (u_int32_t)(log10((double)(over & 0x0000003f)) /
> >>                                       log10(2));
> >> 		...
> >>        }
> >>        else {
> >> 		...
> >>                if (coef) {
> >>                        ydef[16] = 0x03045000 | (over << 26) | (tap - 4);
> >>                        ydef[17] = (tap * 2 + 1);
> >>                        /* = log2(over) */
> >>                        ydef[22] = (u_int32_t)
> >>                                (log10((double)(over & 0x0000003f)) / log10(2));
> >>                }
> >>
> >> Don't you think that log10((double)(over & 0x0000003f)) / log10(2)
> >> can have only 64 different values depending on the result of (over & 0x3f)?
> >>
> >> Obtain them from precomputed uint32_t log10table[64].
> >> --
> >> vda
> >>
> >>
> > Hi Denis,
> >
> > Yes, the driver code so far only uses log10 twice, but there will be
> > more uses for it as I populate the rest of the tables. However, I think
> > its use will be some what limited. I wasn't aware that the floating
> > point registers are not saved. I'll investigate a way to create a table
> > with pre-calculated log10 values.
> >
> > Thanks,
> >
> >
> > Carlos
> 
> Since the log in base n is the log in any base times a constant,
> you can probably use log base 2 (binary bit position) and multiply
> the result by a constant, which may simply be shifts and adds.
> 
> I assume you are using 16-bit audio. If so, the dynamic range
> is only 20 * log10(2^16) = 96.3 dB. That means that attenuation
> from mininum to maximum, in 1 dB steps, requires only 94 values.
> 
> Your code shows something whacked off at 0x3f = 0->0x40 = 64
> 20 * log10(64) = 36 dB for only 36 values. Clearly, you don't
> need floating point, just some thought ahead of time.
> 
> Cheers,
> Dick Johnson

As Bart pointed out earlier, what this code is really trying to do is not
log10(foo) but int(log2(foo)) for some positive integer foo. This can be
simply expressed as fls(foo)-1 for all foo < 0. No floating point
necessary.

-- 
Ben Slusky                      | Trust is your enemy.
sluskyb@paranoiacs.org          |       -Dan Farmer and
sluskyb@stwing.org              |        Wietse Venema
PGP keyID ADA44B3B      

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: How can I link the kernel with libgcc ?
  2006-03-10 18:03               ` Carlos Munoz
  2006-03-10 18:33                 ` linux-os (Dick Johnson)
@ 2006-03-10 19:18                 ` Al Viro
  2006-03-10 20:04                   ` Carlos Munoz
  1 sibling, 1 reply; 20+ messages in thread
From: Al Viro @ 2006-03-10 19:18 UTC (permalink / raw)
  To: Carlos Munoz
  Cc: Denis Vlasenko, Lee Revell, Valdis.Kletnieks, linux-kernel,
	alsa-devel

On Fri, Mar 10, 2006 at 10:03:58AM -0800, Carlos Munoz wrote:
> >               ydef[22] = (u_int32_t)(log10((double)(over & 0x0000003f)) /
> >                                      log10(2));

You've got to be kidding.  Let's take a good look at that expression:
log10(x)/log10(2) is what?  Right, base-2 logarithm of x.  Then you cast
it to unsigned, i.e. round it down.  In other words, you want to know the
highest bit in (over & 0x3f).  Which is to say, (fls(over & 0x3f) - 1).
Sigh...

^ permalink raw reply	[flat|nested] 20+ messages in thread

* Re: How can I link the kernel with libgcc ?
  2006-03-10 19:18                 ` Al Viro
@ 2006-03-10 20:04                   ` Carlos Munoz
  0 siblings, 0 replies; 20+ messages in thread
From: Carlos Munoz @ 2006-03-10 20:04 UTC (permalink / raw)
  To: Al Viro
  Cc: Denis Vlasenko, Lee Revell, Valdis.Kletnieks, linux-kernel,
	alsa-devel

Al Viro wrote:

>On Fri, Mar 10, 2006 at 10:03:58AM -0800, Carlos Munoz wrote:
>  
>
>>>              ydef[22] = (u_int32_t)(log10((double)(over & 0x0000003f)) /
>>>                                     log10(2));
>>>      
>>>
>
>You've got to be kidding.  Let's take a good look at that expression:
>log10(x)/log10(2) is what?  Right, base-2 logarithm of x.  Then you cast
>it to unsigned, i.e. round it down.  In other words, you want to know the
>highest bit in (over & 0x3f).  Which is to say, (fls(over & 0x3f) - 1).
>Sigh...
>  
>
Hi Al,

You are right, so easy. I will look at the data sheet and make sure the 
same approach can be applied to all places calling for log10 
calculations. I wonder why the data sheet calls for log10 calculations. 
It threw me off... should have know better though.

Thanks,


Carlos Munoz

^ permalink raw reply	[flat|nested] 20+ messages in thread

end of thread, other threads:[~2006-03-10 20:00 UTC | newest]

Thread overview: 20+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-03-10  1:44 How can I link the kernel with libgcc ? Carlos Munoz
2006-03-10  1:45 ` Valdis.Kletnieks
2006-03-10  2:06   ` Lee Revell
2006-03-10  3:01     ` Carlos Munoz
2006-03-10  3:22       ` Lee Revell
2006-03-10  3:25       ` Carlos Munoz
2006-03-10  3:25         ` Lee Revell
2006-03-10  3:47           ` Carlos Munoz
2006-03-10 10:37             ` Denis Vlasenko
2006-03-10 11:05               ` Bart Hartgers
2006-03-10 18:03               ` Carlos Munoz
2006-03-10 18:33                 ` linux-os (Dick Johnson)
2006-03-10 18:41                   ` Ben Slusky
2006-03-10 19:18                 ` Al Viro
2006-03-10 20:04                   ` Carlos Munoz
2006-03-10 10:18         ` Jes Sorensen
2006-03-10 18:07           ` Carlos Munoz
2006-03-10  8:01       ` Arjan van de Ven
2006-03-10  2:02 ` Lee Revell
     [not found] <5OEVB-3GX-15@gated-at.bofh.it>
2006-03-10  2:32 ` Robert Hancock

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox