All of lore.kernel.org
 help / color / mirror / Atom feed
* about udelay in mips
@ 2011-01-13 10:02 loody
  2011-01-14  5:31 ` wu zhangjin
  0 siblings, 1 reply; 13+ messages in thread
From: loody @ 2011-01-13 10:02 UTC (permalink / raw)
  To: Linux MIPS Mailing List

hi all:
If i trace source in the correct place, I found udelay(100) is
implemented as a loop which decrease 1 per iteration until the count,
100, as 0.
What makes me confused is since the speed of cpus are different and
that will make udelay not precise on different platform, right?

-- 
Regards,
miloody

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

* Re: about udelay in mips
  2011-01-13 10:02 about udelay in mips loody
@ 2011-01-14  5:31 ` wu zhangjin
  2011-01-16 14:38     ` loody
  0 siblings, 1 reply; 13+ messages in thread
From: wu zhangjin @ 2011-01-14  5:31 UTC (permalink / raw)
  To: loody; +Cc: Linux MIPS Mailing List

On Thu, Jan 13, 2011 at 6:02 PM, loody <miloody@gmail.com> wrote:
> hi all:
> If i trace source in the correct place, I found udelay(100) is
> implemented as a loop which decrease 1 per iteration until the count,
> 100, as 0.
> What makes me confused is since the speed of cpus are different and
> that will make udelay not precise on different platform, right?

Yeah, it may be not precise, so, some processors, like Cavium octeon
have added their own timestamp register based delay functions, please
refer to:

arch/mips/cavium-octeon/csrc-octeon.c

The delay_tsc() for X86 defined in arch/x86/lib/delay.c is similar.

But both of them are 64bit timestamp registers.

We can also apply similar method to add the precise delays for the
other CPUs, but we may need to take extra notice:

1. If the CPU only provides 32bit timestamp registers(e.g R4K MIPS),
overflow should be considered.
2. If the CPU support dynamic CPU frequency and the frequency of the
timestamp binds to the CPU's frequency, the scaled down timestamp
should be converted to the real timestamp.

Regards,
Wu Zhangjin

>
> --
> Regards,
> miloody
>
>

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

* Re: about udelay in mips
@ 2011-01-16 14:38     ` loody
  0 siblings, 0 replies; 13+ messages in thread
From: loody @ 2011-01-16 14:38 UTC (permalink / raw)
  Cc: Linux MIPS Mailing List

hi wu, winfred:
Thanks for your reply ;)
2011/1/14 wu zhangjin <wuzhangjin@gmail.com>:
> On Thu, Jan 13, 2011 at 6:02 PM, loody <miloody@gmail.com> wrote:
>> hi all:
>> If i trace source in the correct place, I found udelay(100) is
>> implemented as a loop which decrease 1 per iteration until the count,
>> 100, as 0.
>> What makes me confused is since the speed of cpus are different and
>> that will make udelay not precise on different platform, right?
>
> Yeah, it may be not precise, so, some processors, like Cavium octeon
> have added their own timestamp register based delay functions, please
> refer to:
>
> arch/mips/cavium-octeon/csrc-octeon.c
>
> The delay_tsc() for X86 defined in arch/x86/lib/delay.c is similar.
>
> But both of them are 64bit timestamp registers.
>
> We can also apply similar method to add the precise delays for the
> other CPUs, but we may need to take extra notice:
>
> 1. If the CPU only provides 32bit timestamp registers(e.g R4K MIPS),
> overflow should be considered.
> 2. If the CPU support dynamic CPU frequency and the frequency of the
> timestamp binds to the CPU's frequency, the scaled down timestamp
> should be converted to the real timestamp.
below is the formula about calculating the delay
(us  *   0x000010c7   *   HZ   *   lpj   )) >> 32)
I cannot figure out why we need to multiply 0x10c7, and what lpj mean?
Does lpj mean if jiffies increase 1, how many "subu    %0, 1" may need?
Regards,
miloody

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

* Re: about udelay in mips
@ 2011-01-16 14:38     ` loody
  0 siblings, 0 replies; 13+ messages in thread
From: loody @ 2011-01-16 14:38 UTC (permalink / raw)
  Cc: Linux MIPS Mailing List

hi wu, winfred:
Thanks for your reply ;)
2011/1/14 wu zhangjin <wuzhangjin@gmail.com>:
> On Thu, Jan 13, 2011 at 6:02 PM, loody <miloody@gmail.com> wrote:
>> hi all:
>> If i trace source in the correct place, I found udelay(100) is
>> implemented as a loop which decrease 1 per iteration until the count,
>> 100, as 0.
>> What makes me confused is since the speed of cpus are different and
>> that will make udelay not precise on different platform, right?
>
> Yeah, it may be not precise, so, some processors, like Cavium octeon
> have added their own timestamp register based delay functions, please
> refer to:
>
> arch/mips/cavium-octeon/csrc-octeon.c
>
> The delay_tsc() for X86 defined in arch/x86/lib/delay.c is similar.
>
> But both of them are 64bit timestamp registers.
>
> We can also apply similar method to add the precise delays for the
> other CPUs, but we may need to take extra notice:
>
> 1. If the CPU only provides 32bit timestamp registers(e.g R4K MIPS),
> overflow should be considered.
> 2. If the CPU support dynamic CPU frequency and the frequency of the
> timestamp binds to the CPU's frequency, the scaled down timestamp
> should be converted to the real timestamp.
below is the formula about calculating the delay
(us  *   0x000010c7   *   HZ   *   lpj   )) >> 32)
I cannot figure out why we need to multiply 0x10c7, and what lpj mean?
Does lpj mean if jiffies increase 1, how many "subu    %0, 1" may need?
Regards,
miloody

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

* Re: about udelay in mips
  2011-01-16 14:38     ` loody
  (?)
@ 2011-01-16 15:08     ` Geert Uytterhoeven
  -1 siblings, 0 replies; 13+ messages in thread
From: Geert Uytterhoeven @ 2011-01-16 15:08 UTC (permalink / raw)
  To: loody; +Cc: Linux MIPS Mailing List

On Sun, Jan 16, 2011 at 15:38, loody <miloody@gmail.com> wrote:
> hi wu, winfred:
> Thanks for your reply ;)
> 2011/1/14 wu zhangjin <wuzhangjin@gmail.com>:
>> On Thu, Jan 13, 2011 at 6:02 PM, loody <miloody@gmail.com> wrote:
>>> hi all:
>>> If i trace source in the correct place, I found udelay(100) is
>>> implemented as a loop which decrease 1 per iteration until the count,
>>> 100, as 0.
>>> What makes me confused is since the speed of cpus are different and
>>> that will make udelay not precise on different platform, right?
>>
>> Yeah, it may be not precise, so, some processors, like Cavium octeon
>> have added their own timestamp register based delay functions, please
>> refer to:
>>
>> arch/mips/cavium-octeon/csrc-octeon.c
>>
>> The delay_tsc() for X86 defined in arch/x86/lib/delay.c is similar.
>>
>> But both of them are 64bit timestamp registers.
>>
>> We can also apply similar method to add the precise delays for the
>> other CPUs, but we may need to take extra notice:
>>
>> 1. If the CPU only provides 32bit timestamp registers(e.g R4K MIPS),
>> overflow should be considered.
>> 2. If the CPU support dynamic CPU frequency and the frequency of the
>> timestamp binds to the CPU's frequency, the scaled down timestamp
>> should be converted to the real timestamp.
> below is the formula about calculating the delay
> (us  *   0x000010c7   *   HZ   *   lpj   )) >> 32)
> I cannot figure out why we need to multiply 0x10c7, and what lpj mean?
> Does lpj mean if jiffies increase 1, how many "subu    %0, 1" may need?

Yep, lpj = loops per jiffy.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- geert@linux-m68k.org

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

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

* Re: about udelay in mips
  2011-01-16 14:38     ` loody
  (?)
  (?)
@ 2011-01-16 16:34     ` wu zhangjin
  -1 siblings, 0 replies; 13+ messages in thread
From: wu zhangjin @ 2011-01-16 16:34 UTC (permalink / raw)
  To: loody; +Cc: Linux MIPS Mailing List

On Sun, Jan 16, 2011 at 10:38 PM, loody <miloody@gmail.com> wrote:
[...]
> (us  *   0x000010c7   *   HZ   *   lpj   )) >> 32)
> I cannot figure out why we need to multiply 0x10c7, and what lpj mean?
> Does lpj mean if jiffies increase 1, how many "subu    %0, 1" may need?

Yep, lpj is calculated in init/calibrate.c

> Regards,
> miloody
>
>

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

* Re: about udelay in mips
@ 2011-01-19 14:23         ` loody
  0 siblings, 0 replies; 13+ messages in thread
From: loody @ 2011-01-19 14:23 UTC (permalink / raw)
  Cc: Linux MIPS Mailing List

hi all:
thanks for your kind help :)

2011/1/17 Winfred Lu <winfred.lu@gmail.com>:
> 2011/1/16 loody <miloody@gmail.com>
>>
>> below is the formula about calculating the delay
>> (us  *   0x000010c7   *   HZ   *   lpj   )) >> 32)
>> I cannot figure out why we need to multiply 0x10c7, and what lpj mean?
>
> 0x10c7 is the rounded up value of (2 ^ 32) / 1,000,000.
>
> The 1,000,000 comes from that 1 second is equal to 1,000,000 micro seconds.
> That the value multiplied by (2 ^ 32) and shifted 32 bit right after is
> equal to
> that the value multiplied by 1.
I found my kernel will compile udelay(xx) as zero no matter what xx I filled in.
below are the dis-assemblies:
(as you can see the v0 = v1 = zero.)
My version is 2.6.30.9:
void __udelay(unsigned long us)
{
        unsigned int lpj = current_cpu_data.udelay_val;

        __delay(((unsigned long long)(us * 0x000010c7 * HZ * lpj)) >> 32);
80306ed0:       00001821        move    v1,zero
80306ed4:       00601021        move    v0,v1
#include <asm/compiler.h>
#include <asm/war.h>

inline void __delay(unsigned int loops)
{
        __asm__ __volatile__ (
80306ed8:       1440ffff        bnez    v0,80306ed8 <__udelay+0x8>
80306edc:       2442ffff        addiu   v0,v0,-1
void __udelay(unsigned long us)

I have double checked the __delay source code of 2.6.33.4
and the dis-assemblies:

void __udelay(unsigned long us)
{
        unsigned int lpj = current_cpu_data.udelay_val;

        __delay((us * 0x000010c7ull * HZ * lpj) >> 32);
802f7310:       3c02804f        lui     v0,0x804f
802f7314:       8c429360        lw      v0,-27808(v0)
802f7318:       3c050010        lui     a1,0x10
802f731c:       34a56256        ori     a1,a1,0x6256
802f7320:       00450019        multu   v0,a1
802f7324:       00002821        move    a1,zero
802f7328:       00001012        mflo    v0
802f732c:       00001810        mfhi    v1
802f7330:       00a20018        mult    a1,v0
802f7334:       70640000        madd    v1,a0
802f7338:       00003012        mflo    a2
802f733c:       00440019        multu   v0,a0
802f7340:       00001810        mfhi    v1
802f7344:       00c31021        addu    v0,a2,v1
#include <asm/compiler.h>
#include <asm/war.h>

inline void __delay(unsigned int loops)
{
        __asm__ __volatile__ (
802f7348:       1440ffff        bnez    v0,802f7348 <__udelay+0x38>
802f734c:       2442ffff        addiu   v0,v0,-1
void __udelay(unsigned long us)
{
        unsigned int lpj = current_cpu_data.udelay_val;

        __delay((us * 0x000010c7ull * HZ * lpj) >> 32);
}
802f7350:       03e00008        jr      ra

Does that mean "unsigned long long" not workable?
appreciate your help,
miloody

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

* Re: about udelay in mips
@ 2011-01-19 14:23         ` loody
  0 siblings, 0 replies; 13+ messages in thread
From: loody @ 2011-01-19 14:23 UTC (permalink / raw)
  Cc: Linux MIPS Mailing List

hi all:
thanks for your kind help :)

2011/1/17 Winfred Lu <winfred.lu@gmail.com>:
> 2011/1/16 loody <miloody@gmail.com>
>>
>> below is the formula about calculating the delay
>> (us  *   0x000010c7   *   HZ   *   lpj   )) >> 32)
>> I cannot figure out why we need to multiply 0x10c7, and what lpj mean?
>
> 0x10c7 is the rounded up value of (2 ^ 32) / 1,000,000.
>
> The 1,000,000 comes from that 1 second is equal to 1,000,000 micro seconds.
> That the value multiplied by (2 ^ 32) and shifted 32 bit right after is
> equal to
> that the value multiplied by 1.
I found my kernel will compile udelay(xx) as zero no matter what xx I filled in.
below are the dis-assemblies:
(as you can see the v0 = v1 = zero.)
My version is 2.6.30.9:
void __udelay(unsigned long us)
{
        unsigned int lpj = current_cpu_data.udelay_val;

        __delay(((unsigned long long)(us * 0x000010c7 * HZ * lpj)) >> 32);
80306ed0:       00001821        move    v1,zero
80306ed4:       00601021        move    v0,v1
#include <asm/compiler.h>
#include <asm/war.h>

inline void __delay(unsigned int loops)
{
        __asm__ __volatile__ (
80306ed8:       1440ffff        bnez    v0,80306ed8 <__udelay+0x8>
80306edc:       2442ffff        addiu   v0,v0,-1
void __udelay(unsigned long us)

I have double checked the __delay source code of 2.6.33.4
and the dis-assemblies:

void __udelay(unsigned long us)
{
        unsigned int lpj = current_cpu_data.udelay_val;

        __delay((us * 0x000010c7ull * HZ * lpj) >> 32);
802f7310:       3c02804f        lui     v0,0x804f
802f7314:       8c429360        lw      v0,-27808(v0)
802f7318:       3c050010        lui     a1,0x10
802f731c:       34a56256        ori     a1,a1,0x6256
802f7320:       00450019        multu   v0,a1
802f7324:       00002821        move    a1,zero
802f7328:       00001012        mflo    v0
802f732c:       00001810        mfhi    v1
802f7330:       00a20018        mult    a1,v0
802f7334:       70640000        madd    v1,a0
802f7338:       00003012        mflo    a2
802f733c:       00440019        multu   v0,a0
802f7340:       00001810        mfhi    v1
802f7344:       00c31021        addu    v0,a2,v1
#include <asm/compiler.h>
#include <asm/war.h>

inline void __delay(unsigned int loops)
{
        __asm__ __volatile__ (
802f7348:       1440ffff        bnez    v0,802f7348 <__udelay+0x38>
802f734c:       2442ffff        addiu   v0,v0,-1
void __udelay(unsigned long us)
{
        unsigned int lpj = current_cpu_data.udelay_val;

        __delay((us * 0x000010c7ull * HZ * lpj) >> 32);
}
802f7350:       03e00008        jr      ra

Does that mean "unsigned long long" not workable?
appreciate your help,
miloody

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

* Fwd: about udelay in mips
  2011-01-19 14:23         ` loody
  (?)
@ 2011-01-27  9:20         ` loody
  2011-01-27 11:28           ` Sergei Shtylyov
  -1 siblings, 1 reply; 13+ messages in thread
From: loody @ 2011-01-27  9:20 UTC (permalink / raw)
  To: gcc-help, Linux MIPS Mailing List

hi all:
I guess there seems be some differences about
"unsigned long long" and "ull" so I forward the letter to gcc-help.
If my guess is correct, what are the differences between them and why
"unsigned long long" cannot let compiler compile the 64-bits
operations as I want?
thanks a lot,
miloody

I found my kernel will compile udelay(xx) as zero no matter what xx I filled in.
below are the dis-assemblies:
(as you can see the v0 = v1 = zero.)
My version is 2.6.30.9:
void __udelay(unsigned long us)
{
       unsigned int lpj = current_cpu_data.udelay_val;

       __delay(((unsigned long long)(us * 0x000010c7 * HZ * lpj)) >> 32);
80306ed0:       00001821        move    v1,zero
80306ed4:       00601021        move    v0,v1
#include <asm/compiler.h>
#include <asm/war.h>

inline void __delay(unsigned int loops)
{
       __asm__ __volatile__ (
80306ed8:       1440ffff        bnez    v0,80306ed8 <__udelay+0x8>
80306edc:       2442ffff        addiu   v0,v0,-1
void __udelay(unsigned long us)

I have double checked the __delay source code of 2.6.33.4
and the dis-assemblies:

void __udelay(unsigned long us)
{
       unsigned int lpj = current_cpu_data.udelay_val;

       __delay((us * 0x000010c7ull * HZ * lpj) >> 32);
802f7310:       3c02804f        lui     v0,0x804f
802f7314:       8c429360        lw      v0,-27808(v0)
802f7318:       3c050010        lui     a1,0x10
802f731c:       34a56256        ori     a1,a1,0x6256
802f7320:       00450019        multu   v0,a1
802f7324:       00002821        move    a1,zero
802f7328:       00001012        mflo    v0
802f732c:       00001810        mfhi    v1
802f7330:       00a20018        mult    a1,v0
802f7334:       70640000        madd    v1,a0
802f7338:       00003012        mflo    a2
802f733c:       00440019        multu   v0,a0
802f7340:       00001810        mfhi    v1
802f7344:       00c31021        addu    v0,a2,v1
#include <asm/compiler.h>
#include <asm/war.h>

inline void __delay(unsigned int loops)
{
       __asm__ __volatile__ (
802f7348:       1440ffff        bnez    v0,802f7348 <__udelay+0x38>
802f734c:       2442ffff        addiu   v0,v0,-1
void __udelay(unsigned long us)
{
       unsigned int lpj = current_cpu_data.udelay_val;

       __delay((us * 0x000010c7ull * HZ * lpj) >> 32);
}
802f7350:       03e00008        jr      ra

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

* Re: Fwd: about udelay in mips
  2011-01-27  9:20         ` Fwd: " loody
@ 2011-01-27 11:28           ` Sergei Shtylyov
  2011-01-27 12:28             ` loody
  0 siblings, 1 reply; 13+ messages in thread
From: Sergei Shtylyov @ 2011-01-27 11:28 UTC (permalink / raw)
  To: loody; +Cc: gcc-help, Linux MIPS Mailing List

Hello.

On 27-01-2011 12:20, loody wrote:

> hi all:
> I guess there seems be some differences about
> "unsigned long long" and "ull" so I forward the letter to gcc-help.
> If my guess is correct, what are the differences between them and why
> "unsigned long long" cannot let compiler compile the 64-bits
> operations as I want?

    Probably because in 2.6.30 you only cast the result of 32-bit multiplies 
to 64 bits. In the 2.6.33 kernel, the mutliplies are 64-bit as the 
0x000010c7ull constant is 64-bit...

> thanks a lot,
> miloody

> I found my kernel will compile udelay(xx) as zero no matter what xx I filled in.
> below are the dis-assemblies:
> (as you can see the v0 = v1 = zero.)
> My version is 2.6.30.9:
> void __udelay(unsigned long us)
> {
>         unsigned int lpj = current_cpu_data.udelay_val;
>
>         __delay(((unsigned long long)(us * 0x000010c7 * HZ * lpj)) >> 32);
> 80306ed0:       00001821        move    v1,zero
> 80306ed4:       00601021        move    v0,v1
> #include<asm/compiler.h>
> #include<asm/war.h>
>
> inline void __delay(unsigned int loops)
> {
>         __asm__ __volatile__ (
> 80306ed8:       1440ffff        bnez    v0,80306ed8 <__udelay+0x8>
> 80306edc:       2442ffff        addiu   v0,v0,-1
> void __udelay(unsigned long us)

> I have double checked the __delay source code of 2.6.33.4
> and the dis-assemblies:

> void __udelay(unsigned long us)
> {
>         unsigned int lpj = current_cpu_data.udelay_val;
>
>         __delay((us * 0x000010c7ull * HZ * lpj) >> 32);
> 802f7310:       3c02804f        lui     v0,0x804f
> 802f7314:       8c429360        lw      v0,-27808(v0)
> 802f7318:       3c050010        lui     a1,0x10
> 802f731c:       34a56256        ori     a1,a1,0x6256
> 802f7320:       00450019        multu   v0,a1
> 802f7324:       00002821        move    a1,zero
> 802f7328:       00001012        mflo    v0
> 802f732c:       00001810        mfhi    v1
> 802f7330:       00a20018        mult    a1,v0
> 802f7334:       70640000        madd    v1,a0
> 802f7338:       00003012        mflo    a2
> 802f733c:       00440019        multu   v0,a0
> 802f7340:       00001810        mfhi    v1
> 802f7344:       00c31021        addu    v0,a2,v1
> #include<asm/compiler.h>
> #include<asm/war.h>
>
> inline void __delay(unsigned int loops)
> {
>         __asm__ __volatile__ (
> 802f7348:       1440ffff        bnez    v0,802f7348 <__udelay+0x38>
> 802f734c:       2442ffff        addiu   v0,v0,-1
> void __udelay(unsigned long us)
> {
>         unsigned int lpj = current_cpu_data.udelay_val;
>
>         __delay((us * 0x000010c7ull * HZ * lpj)>>  32);
> }
> 802f7350:       03e00008        jr      ra

WBR, Sergei

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

* Re: Fwd: about udelay in mips
  2011-01-27 11:28           ` Sergei Shtylyov
@ 2011-01-27 12:28             ` loody
  2011-01-27 21:35               ` Ian Lance Taylor
  0 siblings, 1 reply; 13+ messages in thread
From: loody @ 2011-01-27 12:28 UTC (permalink / raw)
  To: Sergei Shtylyov; +Cc: gcc-help, Linux MIPS Mailing List

hi:
>   Probably because in 2.6.30 you only cast the result of 32-bit multiplies
> to 64 bits. In the 2.6.33 kernel, the mutliplies are 64-bit as the
> 0x000010c7ull constant is 64-bit...

>> void __udelay(unsigned long us)
>> {
>>        unsigned int lpj = current_cpu_data.udelay_val;
>>
>>        __delay(((unsigned long long)(us * 0x000010c7 * HZ * lpj)) >> 32);
so that means (us * 0x000010c7 * HZ * lpj)  is calculated at 32-bits and finally
(unsigned long long) cast it as 64-bits?
if i remember correctly, "64bit cast to 32-bits" is possible get 0
value, since high bits cast out.
But how 34-bits cast to 64-bits will make the value as 0 if original
low 32-bits value is non-zero?
appreciate your reply,
miloody

>> 80306ed0:       00001821        move    v1,zero
>> 80306ed4:       00601021        move    v0,v1
>> #include<asm/compiler.h>
>> #include<asm/war.h>
>>
>> inline void __delay(unsigned int loops)
>> {
>>        __asm__ __volatile__ (
>> 80306ed8:       1440ffff        bnez    v0,80306ed8 <__udelay+0x8>
>> 80306edc:       2442ffff        addiu   v0,v0,-1
>> void __udelay(unsigned long us)
>
>> I have double checked the __delay source code of 2.6.33.4
>> and the dis-assemblies:
>
>> void __udelay(unsigned long us)
>> {
>>        unsigned int lpj = current_cpu_data.udelay_val;
>>
>>        __delay((us * 0x000010c7ull * HZ * lpj) >> 32);
>> 802f7310:       3c02804f        lui     v0,0x804f
>> 802f7314:       8c429360        lw      v0,-27808(v0)
>> 802f7318:       3c050010        lui     a1,0x10
>> 802f731c:       34a56256        ori     a1,a1,0x6256
>> 802f7320:       00450019        multu   v0,a1
>> 802f7324:       00002821        move    a1,zero
>> 802f7328:       00001012        mflo    v0
>> 802f732c:       00001810        mfhi    v1
>> 802f7330:       00a20018        mult    a1,v0
>> 802f7334:       70640000        madd    v1,a0
>> 802f7338:       00003012        mflo    a2
>> 802f733c:       00440019        multu   v0,a0
>> 802f7340:       00001810        mfhi    v1
>> 802f7344:       00c31021        addu    v0,a2,v1
>> #include<asm/compiler.h>
>> #include<asm/war.h>
>>
>> inline void __delay(unsigned int loops)
>> {
>>        __asm__ __volatile__ (
>> 802f7348:       1440ffff        bnez    v0,802f7348 <__udelay+0x38>
>> 802f734c:       2442ffff        addiu   v0,v0,-1
>> void __udelay(unsigned long us)
>> {
>>        unsigned int lpj = current_cpu_data.udelay_val;
>>
>>        __delay((us * 0x000010c7ull * HZ * lpj)>>  32);
>> }
>> 802f7350:       03e00008        jr      ra
>
> WBR, Sergei
>



-- 
Regards,

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

* Re: Fwd: about udelay in mips
  2011-01-27 12:28             ` loody
@ 2011-01-27 21:35               ` Ian Lance Taylor
  2011-01-27 21:42                 ` Maciej W. Rozycki
  0 siblings, 1 reply; 13+ messages in thread
From: Ian Lance Taylor @ 2011-01-27 21:35 UTC (permalink / raw)
  To: loody; +Cc: Sergei Shtylyov, gcc-help, Linux MIPS Mailing List

loody <miloody@gmail.com> writes:

>>   Probably because in 2.6.30 you only cast the result of 32-bit multiplies
>> to 64 bits. In the 2.6.33 kernel, the mutliplies are 64-bit as the
>> 0x000010c7ull constant is 64-bit...
>
>>> void __udelay(unsigned long us)
>>> {
>>>        unsigned int lpj = current_cpu_data.udelay_val;
>>>
>>>        __delay(((unsigned long long)(us * 0x000010c7 * HZ * lpj)) >> 32);
> so that means (us * 0x000010c7 * HZ * lpj)  is calculated at 32-bits and finally
> (unsigned long long) cast it as 64-bits?
> if i remember correctly, "64bit cast to 32-bits" is possible get 0
> value, since high bits cast out.
> But how 34-bits cast to 64-bits will make the value as 0 if original
> low 32-bits value is non-zero?

I don't know the type of HZ.  But assuming it is a constant, then the
rules of C are that the expression
    us * 0x000010c7 * HZ * lpj
gets evaluated in the type "unsigned long".  The fact that you then cast
that "unsigned long" value to "unsigned long long" does not cause the
multiplication to be done in the type "unsigned long long".

You need to write something like
    (unsigned long long) us * 0x000010c7 * HZ * (unsigned long long) lpj
to get the multiplication to be done in the "unsigned long long" type.

This questoin has nothing to do with gcc, by the way, it's a C language
question.

Ian

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

* Re: Fwd: about udelay in mips
  2011-01-27 21:35               ` Ian Lance Taylor
@ 2011-01-27 21:42                 ` Maciej W. Rozycki
  0 siblings, 0 replies; 13+ messages in thread
From: Maciej W. Rozycki @ 2011-01-27 21:42 UTC (permalink / raw)
  To: Ian Lance Taylor
  Cc: loody, Sergei Shtylyov, gcc-help, Linux MIPS Mailing List

On Thu, 27 Jan 2011, Ian Lance Taylor wrote:

> I don't know the type of HZ.  But assuming it is a constant, then the
> rules of C are that the expression
>     us * 0x000010c7 * HZ * lpj
> gets evaluated in the type "unsigned long".  The fact that you then cast
> that "unsigned long" value to "unsigned long long" does not cause the
> multiplication to be done in the type "unsigned long long".
> 
> You need to write something like
>     (unsigned long long) us * 0x000010c7 * HZ * (unsigned long long) lpj
> to get the multiplication to be done in the "unsigned long long" type.

 Though as a matter of coding style, personally I'd rather assigned "us" 
to a local variable of the "unsigned long long" type and performed all the 
calculations on it instead, avoiding any explicit casts and doubts as to 
what type is being used altogether.

  Maciej

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

end of thread, other threads:[~2011-01-27 21:42 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-01-13 10:02 about udelay in mips loody
2011-01-14  5:31 ` wu zhangjin
2011-01-16 14:38   ` loody
2011-01-16 14:38     ` loody
2011-01-16 15:08     ` Geert Uytterhoeven
2011-01-16 16:34     ` wu zhangjin
     [not found]     ` <AANLkTi=zfr5YuwBCcvH2Jas50UxnUtvzp_CDyN25sT5h@mail.gmail.com>
2011-01-19 14:23       ` loody
2011-01-19 14:23         ` loody
2011-01-27  9:20         ` Fwd: " loody
2011-01-27 11:28           ` Sergei Shtylyov
2011-01-27 12:28             ` loody
2011-01-27 21:35               ` Ian Lance Taylor
2011-01-27 21:42                 ` Maciej W. Rozycki

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.